Skip to content

Feature/format#53

Merged
magmacomputing merged 4 commits into
mainfrom
feature/format
Jul 4, 2026
Merged

Feature/format#53
magmacomputing merged 4 commits into
mainfrom
feature/format

Conversation

@magmacomputing

@magmacomputing magmacomputing commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added a live plugin catalog page with Community, Premium, and Coming Soon sections, plus install-copy actions for community plugins.
    • Added unified browser global bundles and new minified builds for script-tag usage.
  • Bug Fixes

    • Improved relative time formatting to respect numeric options more consistently.
    • Expanded timezone formatting support, including additional output styles.
  • Documentation

    • Updated installation, formatting, ecosystem, and release notes pages to reflect the latest plugin and browser usage flows.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@magmacomputing, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dd3d6a7d-0642-4678-9b5d-3fc7e4eb873c

📥 Commits

Reviewing files that changed from the base of the PR and between 91e75af and 01604c4.

📒 Files selected for processing (4)
  • packages/tempo/CHANGELOG.md
  • packages/tempo/doc/releases/v3.x.md
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/module/module.format.ts
📝 Walkthrough

Walkthrough

This PR bumps Tempo/library/root package versions to 3.5.2, adds a numeric option to relative-time formatting, adds new timezone locale-format tokens, introduces a Magma-named minified global IIFE bundle build, adds a VitePress plugin catalog page/component, and adjusts plugin API re-exports plus documentation/changelog.

Changes

Tempo 3.5.2 release changes

Layer / File(s) Summary
Relative time numeric option
packages/library/src/common/international.library.ts, packages/tempo/src/module/module.duration.ts
getRTF/getRelativeTime gain a numeric parameter (default 'always'), and duration()'s since-formatting path derives and forwards numeric from config/options.
Timezone locale format tokens
packages/tempo/src/module/module.format.ts, packages/tempo/doc/tempo.format.md
mon/mmm/wkd/www locale formatting switches to getDTF with explicit timeZone/calendar; new z/zz/zzz/zzzz/zzzzz timezone tokens added and documented.
Magma global bundle build
packages/tempo/rollup.config.js, packages/tempo/CHANGELOG.md, packages/tempo/doc/releases/v3.x.md, packages/tempo/doc/installation.md, packages/tempo/README.md
IIFE global name renamed _TempoExportMagma; new minified IIFE/ESM bundle build entries added; changelog, release notes, installation guide, and README updated to reflect the unified window.Magma namespace.
Plugin ecosystem catalog page
packages/tempo/.vitepress/theme/components/CatalogList.vue, packages/tempo/.vitepress/theme/index.ts, packages/tempo/doc/ecosystem.md, packages/tempo/.vitepress/config.ts
New CatalogList.vue fetches plugin data from Firestore and renders community/premium/coming-soon sections; registered globally via theme index.ts; new ecosystem.md doc page renders it; sidebar nav updated to link to it.
Plugin API export surface changes
packages/tempo/src/plugin/plugin.index.ts, packages/tempo/src/plugin-api.index.ts, packages/tempo/src/tempo.entry.ts, packages/tempo/src/tempo.index.ts
Removes definePremiumPlugin/definePremiumTerm re-exports; adds defineTerm/defineRange/getTermRange re-exports; exposes pluginApi namespace from entry; adds core type re-exports to preserve module augmentations.
Version bumps and release documentation
package.json, packages/library/package.json, packages/tempo/package.json, packages/tempo/src/tempo.version.ts, packages/tempo/doc/releases/index.md, .editorconfig
Version bumped to 3.5.2 across manifests and TEMPO_VERSION; release index reordered; repo-wide editorconfig formatting rules added.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant TempoBundle as tempo.bundle.min.js
  participant PluginBundle as community plugin bundle
  participant Magma as window.Magma
  Browser->>TempoBundle: load script
  TempoBundle->>Magma: attach Tempo core
  Browser->>PluginBundle: load script
  PluginBundle->>Magma: attach plugins
  Browser->>Magma: extract { Tempo, plugins }
  Browser->>Browser: Tempo.extend(plugins.astro)
Loading
sequenceDiagram
  participant CatalogList
  participant Firestore as Firestore REST endpoint
  participant EcosystemPage as ecosystem.md
  EcosystemPage->>CatalogList: render <CatalogList />
  CatalogList->>Firestore: fetch plugin documents on mount
  Firestore-->>CatalogList: document fields
  CatalogList->>CatalogList: map to Plugin list, filter by status/price
  CatalogList-->>EcosystemPage: render community/premium/coming-soon sections
Loading

Possibly related PRs

  • magmacomputing/magma#33: Modifies the same getRelativeTime/since-formatting pipeline and premium licensing/plugin-term export surface.
  • magmacomputing/magma#34: Also changes the relative-time "since" formatting path in module.duration.ts around rtOptions selection.
  • magmacomputing/magma#51: Introduced plugin-api.index.ts, which this PR further extends with new re-exports wired into tempo.entry.ts.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague to describe the substantial formatting, docs, and plugin ecosystem changes in this PR. Rename it to a concise, specific summary of the main change, such as the new plugin ecosystem and formatting updates.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
packages/tempo/src/plugin-api.index.ts (1)

17-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant named re-export.

Line 18's export { defineTerm, defineRange, getTermRange } from './plugin/term/term.index.js'; duplicates what line 17's export * from './plugin/term/term.index.js'; already re-exports. Runtime-wise this is harmless (explicit named exports simply shadow the star export for the same names), but it's dead weight that can confuse readers about the intended public surface.

♻️ Suggested cleanup
 export * from './plugin/term/term.index.js';
-export { defineTerm, defineRange, getTermRange } from './plugin/term/term.index.js';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tempo/src/plugin-api.index.ts` around lines 17 - 18, The plugin API
entrypoint has a redundant named re-export because plugin-api.index.ts already
uses export * from './plugin/term/term.index.js' to expose defineTerm,
defineRange, and getTermRange. Clean up the public surface by removing the
explicit named export line and keep only the star re-export, or otherwise make
the export strategy consistent so plugin-api.index.ts does not duplicate the
same symbols.
packages/tempo/src/module/module.format.ts (1)

313-352: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hoist duplicated dtOptions computation.

const dtOptions = config?.intl?.dateTimeFormat ?? {}; is recomputed identically in the locale, zzzz, and zzzzz cases (lines 314, 341, 348). Since it doesn't depend on mod or token, hoisting it once above the modifier for loop avoids the repeated lookup/allocation per modifier evaluated.

♻️ Suggested refactor
+		const dtOptions = config?.intl?.dateTimeFormat ?? {};
 		for (const mod of modifiers) {
 			switch (mod.toLowerCase()) {
 				...
 				case 'locale': {
 					try {
 						if (token.startsWith('#') && isTempo(obj)) {
 							...
 						} else {
-							const dtOptions = config?.intl?.dateTimeFormat ?? {};
 							const tzOpts = { ...dtOptions, timeZone: zdt.timeZoneId, calendar: zdt.calendarId };
 							...
 				case 'zzzz':
 					if (token === 'tz') {
-						const dtOptions = config?.intl?.dateTimeFormat ?? {};
 						const parts = getDTF(config?.locale, { ...dtOptions, timeZone: zdt.timeZoneId, timeZoneName: 'short' }).formatToParts(zdt.epochMilliseconds);
 						...
 				case 'zzzzz':
 					if (token === 'tz') {
-						const dtOptions = config?.intl?.dateTimeFormat ?? {};
 						const parts = getDTF(config?.locale, { ...dtOptions, timeZone: zdt.timeZoneId, timeZoneName: 'long' }).formatToParts(zdt.epochMilliseconds);
 						...
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tempo/src/module/module.format.ts` around lines 313 - 352, Hoist the
repeated dtOptions lookup in the formatting switch so it is computed once
instead of inside each locale/timezone branch. In module.format.ts, move const
dtOptions = config?.intl?.dateTimeFormat ?? {} to the shared scope above the
modifier loop in the formatter logic, then reuse it in the locale, zzzz, and
zzzzz cases; this keeps behavior unchanged while removing duplicated work.
packages/tempo/src/module/module.duration.ts (1)

213-215: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the repeated option-resolution chain.

Lines 213-214 duplicate the same 7-step fallback pattern (rtOptions?.X || rtConfig?.X || opts['intl']?.relativeTimeFormat?.X || opts['rtfX'] || this.config...) for style and now numeric. Extracting a small helper would reduce duplication and make future option additions (e.g. locale overrides) easier to maintain.

♻️ Suggested refactor
+		const resolveRtfOption = <T,>(key: 'style' | 'numeric', fallback: T): T =>
+			rtOptions?.[key] ?? rtConfig?.[key] ?? opts['intl']?.relativeTimeFormat?.[key]
+			?? opts[`rtf${key[0].toUpperCase()}${key.slice(1)}`]
+			?? (this as any).config.intl?.relativeTimeFormat?.[key]
+			?? (this as any).config[`rtf${key[0].toUpperCase()}${key.slice(1)}`]
+			?? fallback;
+
 		const getFormatted = (val: number, u: any) => {
 			const su = singular(u);
 			if (isFunction(rtf)) return rtf(val, su);
 			if (rtf instanceof Intl.RelativeTimeFormat) return rtf.format(val, su);
-			const style = rtOptions?.style || rtConfig?.style || opts['intl']?.relativeTimeFormat?.style || opts['rtfStyle'] || (this as any).config.intl?.relativeTimeFormat?.style || (this as any).config['rtfStyle'] || 'narrow';
-			const numeric = rtOptions?.numeric || rtConfig?.numeric || opts['intl']?.relativeTimeFormat?.numeric || opts['rtfNumeric'] || (this as any).config.intl?.relativeTimeFormat?.numeric || (this as any).config['rtfNumeric'] || 'always';
+			const style = resolveRtfOption('style', 'narrow');
+			const numeric = resolveRtfOption('numeric', 'always');
 			return getRelativeTime(val, su as Intl.RelativeTimeFormatUnit, locale, style, numeric);
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tempo/src/module/module.duration.ts` around lines 213 - 215, The
relative-time option resolution in module.duration.ts repeats the same fallback
chain for both style and numeric, so extract that logic into a small helper and
reuse it from the duration formatting path. Use the existing symbols in this
area, especially the getRelativeTime call and the rtOptions/rtConfig/opts
resolution flow, so future option additions only need one place to update. Keep
the helper focused on resolving a single option key from the same precedence
order.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/tempo/src/module/module.duration.ts`:
- Around line 213-215: The relative-time option resolution in module.duration.ts
repeats the same fallback chain for both style and numeric, so extract that
logic into a small helper and reuse it from the duration formatting path. Use
the existing symbols in this area, especially the getRelativeTime call and the
rtOptions/rtConfig/opts resolution flow, so future option additions only need
one place to update. Keep the helper focused on resolving a single option key
from the same precedence order.

In `@packages/tempo/src/module/module.format.ts`:
- Around line 313-352: Hoist the repeated dtOptions lookup in the formatting
switch so it is computed once instead of inside each locale/timezone branch. In
module.format.ts, move const dtOptions = config?.intl?.dateTimeFormat ?? {} to
the shared scope above the modifier loop in the formatter logic, then reuse it
in the locale, zzzz, and zzzzz cases; this keeps behavior unchanged while
removing duplicated work.

In `@packages/tempo/src/plugin-api.index.ts`:
- Around line 17-18: The plugin API entrypoint has a redundant named re-export
because plugin-api.index.ts already uses export * from
'./plugin/term/term.index.js' to expose defineTerm, defineRange, and
getTermRange. Clean up the public surface by removing the explicit named export
line and keep only the star re-export, or otherwise make the export strategy
consistent so plugin-api.index.ts does not duplicate the same symbols.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 40d69a98-2f60-4bb0-849c-6776706a68d8

📥 Commits

Reviewing files that changed from the base of the PR and between f3c9729 and 91e75af.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/tempo/public/plugin-logo.svg is excluded by !**/*.svg
📒 Files selected for processing (23)
  • .editorconfig
  • package.json
  • packages/library/package.json
  • packages/library/src/common/international.library.ts
  • packages/tempo/.vitepress/config.ts
  • packages/tempo/.vitepress/theme/components/CatalogList.vue
  • packages/tempo/.vitepress/theme/index.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/README.md
  • packages/tempo/doc/ecosystem.md
  • packages/tempo/doc/installation.md
  • packages/tempo/doc/releases/index.md
  • packages/tempo/doc/releases/v3.x.md
  • packages/tempo/doc/tempo.format.md
  • packages/tempo/package.json
  • packages/tempo/rollup.config.js
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/plugin-api.index.ts
  • packages/tempo/src/plugin/plugin.index.ts
  • packages/tempo/src/tempo.entry.ts
  • packages/tempo/src/tempo.index.ts
  • packages/tempo/src/tempo.version.ts

@magmacomputing magmacomputing merged commit 3fd0756 into main Jul 4, 2026
2 checks passed
@magmacomputing magmacomputing deleted the feature/format branch July 4, 2026 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant