π Version 3.x History β
[v3.10.0] - 2026-07-19 β
β¨ What's New β
Format Token Modifiers & Custom Tokens Introduced new capabilities for chained formatting modifiers and finalized the complete architecture for Custom Format Tokens. Developers can now register custom zero-overhead logic evaluators (like Fiscal Years or native Intl bridges) that seamlessly hook into the t.format() engine.
π Documentation Enhancements β
- Cookbook Refactoring: Trimmed architectural "bloat" from the Cookbook (including Localized Parsing, Slick Mutations, and Custom Tokens). This content has been moved into dedicated Core Concepts guides (
tempo.parse.md,tempo.mutate.md,tempo.format.md) to provide a much punchier, fast-paced onboarding experience for new users, while keeping deep-dive details just one click away.
[v3.9.0] - 2026-07-14 β
β¨ What's New β
Historical Era Support Introduced first-class support for historical dates. The new {era} formatting token automatically resolves to localized BC/AD or BCE/CE designations. Additionally, the core Tempo class now exposes .era and .eon zero-cost getters, providing immediate access to the underlying historical date components.
Typographical Auto-Meridiem Expanded the {h12} token modifiers with a new :space option. When chaining modifiers (like {h12:space:dots}), Tempo will now gracefully inject a readability space before the auto-appended meridiem, yielding typographically correct strings like "10:30 a.m." instead of "10:30a.m.".
π Documentation Enhancements β
- Educational Guides: Created a brand new
tempo.getters.mddocument in the Core Concepts section, serving as the definitive guide to Tempo's zero-cost lazy-evaluation properties. - Ecosystem Alignment: Updated
tempo.config.mdto remove deprecated plugin references, replacing them with accurate examples from the currenttempo-workspace(FinanceNamespaceandAstroTerm).
πͺ² Bug Fixes & Stability β
- Core Typings: Resolved
anyleakage inTempocore methods by injecting strict overloads foruntil()andsince()directly intotempo.class.ts, ensuring full IDE type-inference flows through to.format(). - Documentation Badges: Standardized the Shields.io badge layout across the monorepo to use
<p>tags withinline-blockstyling, fixing horizontal alignment issues caused by VitePress CSS overrides and eliminating malformed HTML<table>hydration errors. - Vue Compiler Hydration: Fixed a rogue unclosed
</p>tag in the Ticker plugin documentation that was silently causing downstream Vue SFC parsing errors during VitePress compilation. - CLI Pipeline: Validated the
magma-clibuild pipeline to correctly propagate non-zero exit codes during workspace orchestration operations, preventing silent failures.
[v3.8.0] - 2026-07-11 β
β¨ What's New β
Interval Primitive Introduced Interval as a first-class, tree-shakeable core primitive. It provides mathematically pure, high-performance boundary evaluations (overlaps, abuts, contains) and set operations (union, intersection) for Temporal points. Interval is accessible ergonomically via Tempo.Interval or independently as a named export for strict tree-shaking purists.
Namespace Architecture Introduced the defineNamespace plugin factory. While Terms (like quarter or season) teach Tempo how to parse natural language, Namespaces provide a clean way to attach grouped business logic directly to the Tempo instance without polluting the global scope. For example, t.finance.isFiscalYearStart() or t.finance.taxYear keeps financial computations neatly isolated from standard date mechanics.
ποΈ Internal Refactoring β
- Strict Plugin Discrimination: The plugin registry now enforces strict
'type'discrimination ('plugin' | 'namespace' | 'term' | 'module') across all plugin factories, replacing brittle object-sniffing and making introspection significantly more robust. - Documentation Architecture: The documentation source code has been completely reorganized into numbered sub-directories (
1-getting-started,2-core-concepts, etc.) to map 1:1 with the visual VitePress sidebar.
[v3.7.1] - 2026-07-09 β
πͺ² Bug Fix β
- License Admin Isolation: Improved license handling so administrative access is tracked separately, reducing incorrect license/permission information appearing in the app.
- Admin Cache Protection: Prevented outdated role information from lingering after license updates.
[v3.7.0] - 2026-07-08 β
β¨ What's New β Runtime Version Registry β
Tempo now features a fully automated runtime version registry accessible via Tempo.versions. This allows developers to instantly query exactly which core modules, terms, and community plugins are loaded into their current Tempo environment and what versions they are running. This system is completely zero-burden for plugin authors, utilizing a virtual build pipeline to auto-inject version strings without requiring manual updates or magic strings.
ποΈ Internal Refactoring β
- Architectural Security: The internal state management (including term registries and configuration variables) has been modernized to use true ECMAScript private fields (
#), ensuring that Tempo's runtime state is strictly impenetrable from the outside.
[v3.6.0] - 2026-07-05 β
β¨ What's New β Shorthand Mutation Keys β
Added native support for Tempo's shorthand format tokens (e.g., mi, ss, yy, ww) across both .add() and .set() mutations, streamlining developer experience and aligning TypeScript definitions with the underlying runtime engine.
β¨ What's New β Shorthand Duration Keys β
Expanded shorthand token support directly into the DurationModule. You can now seamlessly use shorthand keys for duration instantiation (Tempo.duration({ mi: 5 })), comparisons (t.until(other, 'mi')), and strict balancing (t.until(other).balance({ largestUnit: 'mi' })), bringing total API consistency across the core library.
[v3.5.2] - 2026-07-04 β
β¨ What's New β Minified Global Bundles β
The build pipeline now natively produces highly optimized, minified IIFE bundles (*.min.js) for both Tempo Core and all Community Plugins, significantly reducing payload size for developers using CDN <script> tags.
Additionally, the browser-global export strategy has been re-architected. Both the core library and all <script> tag plugins now elegantly attach to a single, collision-free window.Magma namespace (e.g., window.Magma.Tempo and window.Magma.plugins.astro), dramatically improving developer experience and eliminating global variable pollution.
β¨ What's New β Timezone Formatting Modifiers β
The {tz} format token now natively supports a full suite of lowercase modifiers (:z, :zz, :zzz, :zzzz, :zzzzz)! This seamlessly outputs various localized timezone names and standard offset formats directly from the native Intl engine, eliminating the need to rely purely on raw IANA Timezone IDs for UI rendering.
ποΈ Internal Refactoring β
- Module Augmentation Typings: Hardened the "batteries-included"
tempo.index.tsentry point by explicitly exporting core module types (e.g.DurationModule,FormatModule). This forces TypeScript to preserve their module augmentations in the compiled.d.tsbundle, guaranteeing that methods like.until()and.since()correctly appear in IDE autocomplete out-of-the-box.
[v3.5.1] - 2026-06-28 β
ποΈ Internal Refactoring β
- Term Registration Resilience: Hardened
Tempo.extendwith structural deduplication to safely ignore redundant registrations of identical core terms. This prevents edge-case term collisions (e.g.,qtr) in mixed module-loader environments like Vitest where Node ESM and Vite may evaluate plugins multiple times.
[v3.5.0] - 2026-06-28 β
β¨ What's New β Unified Plugin API β
Tempo v3.5.0 introduces a brand new barrel export for plugin developers: @magmacomputing/tempo/plugin-api.
This new endpoint centralizes all plugin-authoring utilities (defineModule, definePlugin, defineTerm) and internal types into a single location. This architecture significantly cleans up application-level code by formally separating end-user imports from Plugin Developer imports.
If you are developing a custom plugin, you simply update your imports:
// Old Way
// import { defineModule } from '@magmacomputing/tempo/plugin';
// New Way
import { defineModule } from '@magmacomputing/tempo/plugin-api';π Documentation & Ecosystem β
- Static vs Smart CDNs: We have completely overhauled the installation documentation to clarify the distinction between using Smart CDNs (like
esm.shwhich automatically resolve dependencies) for prototyping, versus Static CDNs (with manualimportmapconfigurations) for hardened production environments. - Evergreen Temporal Wording: Removed explicit version claims for upcoming Node.js native
Temporalsupport, future-proofing our guides against shifting V8 release timelines.
[v3.4.0] - 2026-06-26 β
β¨ What's New β Dynamic Format Tokens β
Tempo's formatting engine now supports completely custom format evaluators via the registry.tokens configuration. This allows you to define your own syntax tokens that execute complex math or delegate deeply localized formatting directly to the native Intl API.
Tempo.init({
locale: 'fr-FR',
registry: {
tokens: {
'wkd-fr': (zdt, { config }) => {
const dtOptions = config?.intl?.dateTimeFormat ?? {};
return zdt.toLocaleString(config?.locale ?? 'en', { ...dtOptions, weekday: 'long' });
}
}
}
});
const t = new Tempo('2024-05-20');
t.format('{wkd-fr}'); // "lundi"β¨ Compound Token Modifiers β
The compound date tokens ({dmy}, {mdy}, {ymd}) now support the :yy modifier to easily truncate their internal year components to 2 digits.
t.format('{dmy:yy}'); // "200524"This officially supersedes the legacy *6 tokens (e.g., {dmy6}) which have now been deprecated from documentation to keep the API clean, though they remain fully supported in the engine for backwards compatibility.
[v3.3.1] - 2026-06-22 β
β¨ What's New β Slick Object Mutations β
Tempo has always allowed jumping to boundaries using the Slick Shorthand (#qtr.>2q1) or semantic strings (next Friday). v3.3.1 extends this power directly to .set() object properties.
You can now use SLICK_KEYS (yy, mm, ww, dd, hh, mi, ss, wkd) as object keys in .set(), passing a directional string payload:
const t = new Tempo('2024-05-20'); // Monday
// Jump forward two months
t.set({ mm: '>2' }); // July 20
// Jump to the next Friday
t.set({ wkd: '>Fri' }); // May 24
// "Double-negation" math is fully supported:
t.set({ mm: '<-3' }); // Equivalent to >3This makes relative programmatic date construction cleaner and keeps numeric jumps distinct from absolute assignments.
β‘ Extended Shorthand Modifiers β
The Slick Regex parser has been upgraded to natively support equality logic and aliases. Modifiers like >=, <=, =, + (alias for >), and - (alias for <) are now fully supported for both numeric offsets and semantic loops (like wkd).
// Jump to next Monday, or stay on Monday if today is Monday
t.set({ wkd: '>=Mon' });[v3.3.0] - 2026-06-21 β
β¨ What's New β Localized Modifier Registry β
Tempo's relative-date keywords (next, last, this, ago, hence) were previously hardcoded as English-only constructs built into the core regex engine. v3.3.0 opens this up completely.
You can now register your own locale-specific words for any directional operator using registry.modifiers. These words integrate transparently with all standard parsing paths β prefix position, suffix position, and the high-performance # slick shorthand:
Tempo.init({
locale: 'fr-FR', // teaches Tempo French months & weekdays via Intl
registry: {
modifiers: {
'>': ['prochain', 'suivant'], // "next" synonyms
'<': ['dernier', 'passΓ©'], // "last / previous" synonyms
'=': ['ce', 'cette'], // "this" synonyms
}
}
});
new Tempo('vendredi prochain'); // β
"next Friday" β fully French
new Tempo('1 mai prochain'); // β
"next May 1st"
new Tempo('#qtr.dernier'); // β
"previous quarter" via slick shorthandEnglish keywords (next, last, ago, hence, this) remain active by default and are additively merged β you never lose built-in behaviour when adding your own.
ποΈ Internal Refactoring β
Frozen Default Registry Fixed: The internal
Defaultconfiguration object is wrapped in a deep-freeze Proxy (secure()). Previously, everyTempo.init()call silently failed to writeformats,locales, andmodifiersinto the frozen registry sub-object, logging threesetPropertywarnings per call and abandoning the writes. The registry is now correctly shallow-cloned into a mutable copy on initialization.Lexer Token Cleanup: All hardcoded English modifier keywords have been stripped from the core regex tokens (
Match.modifier,Match.shorthand,Match.slick). The engine now operates purely on symbolic operators (>,<,=,+,-) internally and resolves all natural-language words through the registry at runtime.Pre-filter Guard Accuracy: Refined the numeric-safety guard bypass to trigger only when the input actually contains a registered modifier keyword. Previously the guard was bypassed unconditionally whenever modifier config was present, which could silently accept invalid nanosecond epoch strings.
β‘ Slick Modifier Semantics β
Localized slick modifiers behave identically to their symbolic counterparts. #qtr.prochain is an exact alias for #qtr.>:
- From inside Q2 (any day from April 1 to June 29) β July 1 (start of Q3)
- From June 30 (last day of Q2) β July 1 (start of Q3)
- From July 1 (first day of Q3) β October 1 (start of Q4)
This mirrors how next Friday works: from any non-Friday you get the very next Friday; if you are already on Friday, you get the following Friday. Fully deterministic β "next" always means "the start of the next occurrence of this term".
[v3.2.3] - 2026-06-20 β
β¨ What's New β Project Scaffolding β
tempo.config.tsPattern: Introduced centralized project configuration via a discoverabletempo.config.ts/tempo.config.jsfile. This mirrors thevite.config.ts/tailwind.config.jsconvention β one file, one place, loaded once.Tempo.bootstrap(): A new async entry point that auto-discovers and loads yourtempo.config.tsbefore any domain logic runs. Safe toawaitat application startup.- CLI Scaffold:
npx @magmacomputing/tempo scaffold:allbootstraps atempo.config.tsand HTML sandbox into your project in seconds.
[v3.2.2] - 2026-06-18 β
β¨ What's New β
- Compact Date Tokens: New 6-digit compact format tokens
{dmy6},{mdy6},{ymd6}(e.g.200626), plus ISO week-of-year helpers{yywy}and{yyww}. {wy}Rename: The former{ww}token is now{wy}(week-of-year) to eliminate visual ambiguity with structural format tokens.
ποΈ Internal Refactoring β
- Recursive
deepMergeHardened: The Intl options merge pipeline now uses a fully recursivedeepMergerather than a shallow spread, preventing nested keys likeintl.dateTimeFormatfrom clobberingintl.relativeTimeFormat. - Prototype Pollution Guards: Added strict guards against
__proto__,constructor, andprototypekey assignments indeepMergeanddeepFreezeutilities.
[v3.2.1] - 2026-06-17 β
β¨ What's New β
- Ordinal Localization Fallback: Added support for custom
Intl.PluralRulesdictionaries. By supplying anordinaldictionary inside your globallocalesregistry, Tempo natively evaluates the active plural category (e.g.,'one','other') and appends the localized suffix automatically (such as'1er'and'15e'for French).
π Documentation & Ecosystem β
- Improved Cookbook Ergonomics: Extensively reorganized the
tempo.cookbook.mdto make it easier to read. Related functionality is now logically grouped togetherβfor example, merging native and semantic.add()math examples, and expanding on boundary.set()capabilities. - Clarified Configurations: Updated
tempo.config.mdto remove outdated properties and explicitly document nested options likeintl.durationFormat. - REPL Traps: Added prominent warnings to the documentation about the strict idempotency of
Tempo.init(), helping new developers avoid silent configuration failures in hot-reload and REPL environments.
ποΈ Internal Refactoring β
- Alias Collision Prevention: Hardened the sandbox alias detection engine to prevent redundant collision warnings in the console when
Tempo.initis invoked in sandboxed contexts.
[v3.2.0] - 2026-06-16 β
β¨ What's New β
- Multi-lingual Parsing: The
localeconfiguration property now officially accepts an array of strings (string | string[]). This enables theParseModuleto intelligently extract terminology from multiple languages simultaneously, generating a single engine capable of parsing dates from any of the specified locales interchangeably. - Intl.DateTimeFormatOptions Passthrough: The
.format()method now officially supports passing a nativeIntl.DateTimeFormatOptionsobject. This provides a highly flexible, "humanized" wrapper around the rigidTemporalAPI for complex cultural formatting (e.g., Arabic numerals, Japanese Reiwa eras). - BigInt Overload for Epoch Nanoseconds: The
{nano}formatting token (epoch nanoseconds) correctly coerces to and returns a precision-preservingBigIntinstead of a string, bypassing standardNumberlimits.
π Documentation & Ecosystem β
- Domain-Locked Licensing: Stabilized the premium plugin licensing engine with a robust domain-locked validation mechanism.
- SSR & VitePress Fixes: Fixed
Temporal is not definedcrashes during SSR builds and simplified our documentation pipeline by removing heavy Markdown plugins. - New Locale Guides: Added comprehensive Internationalization (
tempo.locale.md) guides to the primary navigation structure.
ποΈ Internal Refactoring β
- O(1) Locale Traceability: Upgraded the internal dictionary architecture. The Normalizer can now resolve the winning language of a matched token in pure
O(1)time without any expensive Regex sub-capture scanning. - Polyfill Formatting Bypass: Bypassed a known bug in the
Temporalpolyfill'stoLocaleString()method that incorrectly dropped Kanji constraints in Japanese formatting contexts, guaranteeing preciseIntlfallback correctness. - Parser Map Safety: Architecturally split the internal reverse-lookup into distinct
monthMapandweekdayMapdictionaries, eliminating the risk of cross-locale abbreviation collisions (e.g., if "mai" is a month in one language but a weekday in another).
[v3.1.0] - 2026-06-13 β
β¨ What's New β
- Chained Formatting Modifiers: A powerful new format modifier engine (
{mon:locale:upper}) allowing dynamic casing (:upper,:lower), ordinal suffixes (:ord), and deep localization (:locale) dynamically via the nativeIntlAPI. - Auto-Localization Engine: Global configurations for
format: { localize: true }andparse: { localize: true }provide a massive leap forward in out-of-the-box internationalization. Tempo can now intelligently parse localized input (months, weekdays, relative terms like 'demain') and automatically format localized output using memoized, high-performanceIntlstrategies. - Global
localesRegistry: Centralized management for augmenting specific term strings per locale globally across instances viaTempo.init({ locale: 'fr-FR', registry: { locales: { ... } } }).
ποΈ Internal Refactoring β
- Intl Instantiation: Upgraded internal architectures to memoize and pool
Intl.DateTimeFormatobjects seamlessly, ensuring parsing localization generation and output formatting impose virtually zero performance hit on hot execution paths. - Term Localization: Upgraded the Term formatting resolution pipeline to support falling back across a strict precedence: Global Registry > Plugin Bundled Dictionary > term's existing label/value.
[v3.0.0] - 2026-06-08 β
π¨ Major Breaking Changes β
- Term Registry Consolidation: Removed the legacy and deprecated
termproperty from theDiscoveryconfiguration object. All Term-based plugins must now be registered via theterms(plural) array. - Shorthand Configuration Removal: Removed support for shorthand root-level properties in the
Discoveryobject that have been superseded by nested configuration groups:relativeTimeshorthand has been removed; useintl.relativeTimeinstead.termshorthand has been removed; usetermsinstead.
- Strict Parsing Mode: The parser now enforces a stricter
guardcheck by default, reducing the likelihood of "false positive" matches on ambiguous strings. - Ticker Module Extraction: To lighten the core bundle, the
TickerPluginhas been extracted into its own standalone premium plugin (@magmacomputing/tempo-plugin-ticker). It is protected by a License Key via the Tempo Registry.
β¨ What's New β
- Formatting Module Additions: Added new compact date tokens (
{dmy},{mdy},{ymd}) for generating 8-digit compact date strings (e.g.24102026).{hhmiss}has been renamed to{hms}for consistency. - Ordinal Tokens: Uppercase variants of standard date tokens (
{DAY},{WW},{MM}) now output their ordinal string representation (e.g.,24th,1st,2nd).
π¦ Migration Path for Tempo.ticker() Users β
If you are upgrading from v2.x and your application relies on Tempo.ticker(), you will need to update your integration:
- Install the Plugin:
npm install @magmacomputing/tempo-plugin-ticker - Activate your License: Obtain your free JWT license key.π Go to the Tempo License Registry π
Manage your subscriptions and retrieve your license key. - Register the Plugin: Wire the key into your application and extend Tempo:javascript
import { Tempo } from '@magmacomputing/tempo'; import { TickerPlugin } from '@magmacomputing/tempo-plugin-ticker'; // Wire your license key Tempo.init({ license: 'YOUR_JWT_KEY' }); // Register the extracted plugin Tempo.extend(TickerPlugin);
ποΈ Internal Refactoring β
- Zero-Fallback Initialization: Cleaned up the
Tempo.init()bootstrap logic to remove legacy compatibility layers, resulting in a cleaner internal state and reduced bundle size. - Build Pipelines: Fully synchronized build pipelines and TS declarations to ensure
vitestandtscoperate seamlessly across local and premium workspaces.