Skip to content

📜 Version 4.x History ​

[v4.7.0] - 2026-10-16 ​

🚀 Key Highlights & Developer Experience ​

Tempo v4.7.0 brings first-class Roman Numeral Date Support across parsing and formatting, full format-mask round-tripping, and canonical ISO Week-Numbering Getters (.woy and .yow) — providing developer-friendly date handling for archival publishing, epigraphy, and ISO week-calendar schedules.

NOTE

Summary of Highlights

  • Symmetric Roman Numeral Formatting & Parsing: Format any date token as a Roman numeral using {token:roman} (e.g. {yy:roman}-{mm:roman}-{dd:roman} → XXVI-X-XVI) and round-trip parse it back cleanly with custom format masks.
  • Archival & Epigraphic Date Parsing: Natively parse archival Roman date strings out-of-the-box, such as 14.X.2026, Copyright © MMXXVI, and anno domini MCMXCIV.
  • Strict Guard Pre-Filtering: Guard pre-filter prevents accidental false positives by intelligently differentiating Roman numerals from everyday lowercase English words (did, mix, civil).
  • ISO Week Getters & Tokens: Access ISO week numbering through canonical instance getters .woy (week of year) and .yow (ISO week-numbering year), complemented by {woy}, {woy:raw}, {woy:ord}, and {yow} format tokens.

🌟 New Features & Developer Guide ​

1. Roman Numeral Format Modifiers & Round-Trip Symmetry ​

Formatting dates using Roman numerals is now as simple as adding the :roman modifier to any date component:

typescript
import { Tempo } from '@magmacomputing/tempo';

const t = new Tempo('2026-10-16');

// Format with Roman numerals
const romanDate = t.format('{yy:roman}-{mm:roman}-{dd:roman}');
// 'XXVI-X-XVI'

// Parse it right back with mask symmetry!
const restored = new Tempo(romanDate, { format: '{yy:roman}-{mm:roman}-{dd:roman}' });
console.log(restored.format('iso')); // '2026-10-16'

2. Archival & Inscription Date Lexing ​

Archival dates, book copyright lines, and European-style day-RomanMonth-year strings are recognized automatically by the parser:

typescript
new Tempo('14.X.2026').format('iso'); // '2026-10-14'
new Tempo('MMXXVI').format('iso');     // '2026-01-01'
new Tempo('Copyright © MMXXVI').year;  // 2026
new Tempo('anno domini MCMXCIV').year; // 1994

The lexer introduces dedicated internal tokens:

  • Token.Rm: Roman month numbers (I through XII).
  • Token.Ry: Roman years (1–3999).
  • Token.dRy: Day-RomanMonth-Year structures (14.X.2026).
  • Token.Ryy: Archival year expressions (anno domini MMXXVI, Copyright © MMXXVI).

3. Smart Sequence Guard Validation ​

To avoid false-positive date matches during natural language parsing, Tempo includes enhanced sequence validation:

  • Valid uppercase Roman numerals (MMXXVI, XIV) and separator-adjacent Roman months (14.X.2026) are accepted.
  • Common lowercase English words that coincide with Roman letters (did, mix, civil, dim, id) are rejected by the guard filter, preventing unwanted date triggers in standard prose.

4. Canonical ISO Week-Numbering Getters (.woy & .yow) ​

Working with ISO week-numbering schedules is now clearer with dedicated instance getters:

typescript
const t = new Tempo('2026-01-01');

console.log(t.woy); // 1 (ISO week of year, 1-53)
console.log(t.yow); // 2026 (4-digit ISO week-numbering year)

// Native token formatting
t.format('{yow}-W{woy}');     // '2026-W01'
t.format('Week {woy:ord}');   // 'Week 1st'
t.format('{woy:raw}');        // '1'

Note: Legacy .ww is deprecated in favor of .woy and will be phased out in v5.0.0. Shorthand .wy and .yw remain available for internal compatibility.

5. Object Key Assertion Primitives & Disambiguation ​

Underlying utility helpers provide dedicated property assertion and narrowing primitives:

  • hasKey(obj, key, ...guards): Verifies and narrows a single property key using optional type tags ('string', 'number') or predicate functions.
  • hasKeys(obj, ...keys): Conjunction check verifying all candidate keys exist simultaneously (AND).
  • hasAnyOf(obj, ...keys): Disjunction check verifying at least one candidate key exists (OR).
  • hasNoneOf(obj, ...keys): Exclusion check verifying none of the candidate keys exist (NOT).

[v4.6.0] - 2026-10-11 ​

🚀 Key Highlights & Developer Experience ​

Tempo v4.6.0 introduces the Term Lifecycle Hooks Protocol, enabling domain plugins (such as fiscal quarters, seasons, academic calendars, and custom business cycles) to deeply integrate into Tempo's natural language parser, date arithmetic, range boundary snapping, difference calculation, and token formatting — all with zero overhead on standard ISO operations.

NOTE

Summary of Highlights

  • Term Plugins: Customize parsing, ordinal matching, step arithmetic, range boundaries, date spans (.until()/.since()), and formatting for domain terms (#).
  • Standard & Celestial Terms: Standard terms (#qtr, #szn, #zdc, #tod, #sign) and celestial plugins (#solar, #moon, #tide, #astro) natively implement lifecycle hooks for ordinals, cycle diffs, boundary snapping, and sub-attribute formatting.
  • Written & Negative Ordinals: Parse natural expressions like "first Wednesday of October" or "-2nd day of #qtr.2". Custom ordinals and number words can be registered globally or per-instance, with negative ordinals counting backward from month/cycle ends.
  • Unified Enums & Compatibility: Live enumerators are organized under Tempo.enums.*, while classic static getters remain directly accessible with deprecation notices for seamless backward compatibility.
  • Dialect Precision & Boundary Shorthands: Escaped literal braces cleanly fall back to dialect parsers, and term boundary shortcuts (start, mid, end) provide fluent range snapping.

🌟 New Features & Protocol Architecture ​

1. Well-Known Symbol Lifecycle Protocol (TermHook) ​

  • Protected Protocol Symbols: Protects term hooks against naming collisions and dual-package hazards using cross-realm well-known symbols (Symbol.for('magmacomputing/tempo/term/...')):
    • [TermHook.parse]: Intercepts explicit #term expressions (e.g. new Tempo('#fiscal.q1')).
    • [TermHook.ordinal]: Powers anchored ordinal expressions (e.g. Tempo.from('3rd day of #sprint.2', { anchor })).
    • [TermHook.step]: Enables stepping arithmetic via dictionary mutations (t.add({ '#qtr': 1 }), t.sub({ '#qtr': 1 })).
    • [TermHook.bound]: Snaps boundaries for custom term periods (t.set({ '#term': 'start' | 'mid' | 'end' }), t.set({ start: '#term' }), and t.set('#term.mid')).
    • [TermHook.diff]: Calculates differences in term units (t1.until(t2, '#term'), t1.since(t2, '#term')).
    • [TermHook.format]: Dispatches custom term format tokens (e.g. t.format('{#academic}'), t.format('{#academic:upper}')).

2. Native Term Units in .until() & .since() ​

  • Custom Term Differences: Tempo.Unit and Tempo.Until now accept custom term units (#${string}), providing full IDE autocompletion and compile-time type safety when calculating spans between dates:
    typescript
    const quartersRemaining = t1.until(t2, '#quarter');
    const elapsed = t2.since(t1, '#fiscal');

3. Standard & Celestial Terms Lifecycle Integration ​

  • Natural Range Ordinals: Standard terms (#qtr, #szn, #zdc) implement [TermHook.ordinal], enabling natural ordinal offset expressions like Tempo.from('3rd day of #qtr.2', { anchor }), Tempo.from('-2nd day of #qtr.2', { anchor }), and Tempo.from('last day of #szn.summer', { anchor }) with strict cycle boundary guarding.
  • Term Unit Differences (.until() & .since()): Standard terms implement [TermHook.diff] via resolveRangeDiff(), calculating elapsed cycle intervals:
    typescript
    t1.until(t2, '#qtr'); // 3
    t2.since(t1, '#qtr'); // "-3 #qtr"
  • Hierarchical Token Formatting: Standard terms implement [TermHook.format] via resolveRangeFormat(), resolving top-level keys ({#qtr} → "Q2"), descriptive scopes ({#quarter} → "Second Quarter"), and arbitrary nested sub-attributes ({#qtr.label}, {#szn.symbol}, {#zdc.emoji}, {#sign.animal}, {#tod.hour}) with automatic modifier support ({#qtr.label:upper}).
  • Shared Plugin SDK Utilities: Exported resolveRangeOrdinal, resolveRangeDiff, and resolveRangeFormat via @magmacomputing/tempo/plugin/sdk.
  • Celestial Plugin Support: Celestial terms (#solar, #moon, #tide, #astro) implement lifecycle hooks for boundary snapping, synodic stepping, interval calculations, and astrological/solar formatting.

4. Unified Tempo.enums Namespace & Extensible Ordinals ​

  • Unified Tempo.enums Accessor: Consolidates all live enum dictionaries under Tempo.enums.*. For 100% backward compatibility with existing v4 call sites, legacy static getters on Tempo (ELEMENT, FORMAT, NUMBER, ORDINAL, TIMEZONE, MONTH_DAY, MODE, CACHE, LIMIT) remain available directly on the Tempo class with @deprecated notices.
  • Native Written Word Ordinals: Natively parses natural ordinal expressions like "first Wednesday of October", "second day of next month", "tenth Friday of the year", and "last day of May".
  • ORDINAL Enumerator: Exported through @magmacomputing/tempo/enums and accessible via Tempo.enums.ORDINAL, mapping words to numeric offsets (current: 0, first: 1 through tenth: 10, last: -1).
  • Dynamic & Per-Instance Extensibility: Configure custom ordinals globally via Tempo.init({ registry: { ordinals: { ... } } }) or per-instance via constructor options (new Tempo('...', { registry: { ordinals: { ... } } })). Per-instance ordinals are dynamically compiled into instance regexes without polluting global state.
  • Term Plugin Integration: Directly leveraged by [TermHook.ordinal] for resolving custom term offsets (such as sprint days or fiscal cycles).

5. Shorthand Boundary Mutations ​

  • Direct Snap Shorthands: Term boundary selection (start, mid, end) can be expressed directly via dictionary mutations (t.set({ '#term': 'start' | 'mid' | 'end' }), t.set({ start: '#term' })) or property shorthand (t.set('#term.start'), t.set('#term.mid'), t.set('#term.end')).

6. Dialect Mask Precision & Engine Optimization ​

  • Dialect Literal Brace Escaping: Added hasNativeFormatBraces to strip dialect-specific escaped literals ([...] in Moment/Day.js, '...' in LDML/Luxon) before testing for native {token} masks, ensuring masks with escaped braces cleanly fall back to external dialect formatters.
  • Isolated # Sigil Guards: Hook dispatch occurs strictly for domain term expressions (#), ensuring everyday ISO date parsing, standard formatting, and core unit arithmetic bypass hook execution paths.
  • Complete Backward Compatibility: Existing term plugins continue to function without any modifications.

[v4.5.1] - 2026-10-05 ​

🚀 Key Highlights & Developer Experience ​

Tempo v4.5.1 focuses on Seamless Dynamic Plugin Loading & Sandbox Resilience, ensuring interactive REPLs, browser playgrounds, and dynamically bundled micro-frontends can load and register plugins on-the-fly without friction.


🌟 Improvements & Fixes ​

1. Dynamic Plugin Registry Resilience ​

  • Late-Loaded Plugin Support: When loading plugins asynchronously via import() inside dynamic environments or browser sandboxes, internal plugin tables are protected with extensible metadata symbols.
  • Copy-on-Write Registrations: Registering terms and plugins after initialization safely falls back to copy-on-write updates on non-extensible registry arrays and pluginsDb objects when the parent container permits reassignment (replacing pluginsDb can still throw a TypeError if the owning state itself is frozen).

[v4.5.0] - 2026-10-02 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.5.0 introduces the Structured t.intl Namespace (intl.info & intl.locale), the high-performance Tempo.intl Formatter Hub, and Hierarchical Translation Token Support.


🌟 New Features & Improvements ​

1. Structured t.intl Sub-Namespace (intl.info & intl.locale) ​

  • Clean Regional Metadata (t.intl.info): Regional insights are now cleanly grouped under .info, giving direct access to frozen locale characteristics:
    typescript
    const t = new Tempo('now', { locale: 'en-AU' });
    console.log(t.intl.info.firstDay);        // 1 (Monday)
    console.log(t.intl.info.weekend);         // [6, 7] (Saturday, Sunday)
    console.log(t.intl.info.hourCycle);       // 'h12'
    console.log(t.intl.info.direction);       // 'ltr'
    console.log(t.intl.info.numberingSystem); // 'latn'
  • Native Locale Inspection (t.intl.locale): Inspect the active Intl.Locale instance directly.
  • Backward Compatibility: Top-level convenience properties (like t.intl.firstDay and t.intl.region) remain fully supported throughout the v4.x lifecycle with gentle deprecation notices.

2. Tempo.intl Formatter Hub ​

  • Instant Pre-Bound Formatters: Perform standard internationalization formatting directly through static helpers without manually configuring Intl.* classes:
    typescript
    // Relative Time Formatting
    Tempo.intl.relativeTime(-2, 'days'); // "2 days ago"
    
    // Natural List Formatting
    Tempo.intl.list(['Sydney', 'Tokyo', 'London']); // "Sydney, Tokyo, and London"
    
    // Number & Currency Formatting
    Tempo.intl.number(1234567.89); // "1,234,567.89"
  • Fast Factory Getters: Access cached constructor factories for dtf() (DateTime), rtf() (RelativeTime), lf() (List), and nf() (Number).

3. Advanced Format & Translation Capabilities ​

  • Hierarchical Translations: Formatting strings support nested tokens for namespaced plugin keys (e.g. {geo.sphere:locale}).
  • Combined Timezone Offset Styles: Enhanced time-zone offset formatting modifiers like {offset:iso}, {offset:gmt}, and composite modifiers like {tz:offset:short}.

[v4.4.4] - 2026-09-30 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.4.4 introduces the Reactive Stream Engine (Reactive<T>) in the utility library, ergonomic Type Casting Helpers (cast<T>()), and explicit Tempo.Interval Types.


🌟 New Features & Improvements ​

1. Reactive Stream Engine (Reactive<T>) ​

  • Lightweight Event Streaming: Exported via @magmacomputing/tempo/library and the Plugin SDK, Reactive<T> offers push/pull streaming with zero external dependencies:
    typescript
    import { Reactive } from '@magmacomputing/tempo/library';
    
    const clockStream = new Reactive<string>();
    
    // Subscribe with automatic cleanup via TC39 explicit resource management:
    {
      using sub = clockStream.on((iso) => console.log('Tick:', iso));
      clockStream.cast(new Tempo().iso);
    } // Subscription automatically unsubscribes when exiting block!
  • Async Iteration: Consume events naturally using standard for await (const tick of clockStream) loops.
  • Multicast Fan-Out: High-performance O(1) broadcasting across all active push subscribers and async waiters via stream.cast(value).

2. Ergonomic Type Casting (cast<T>()) ​

  • Replaces awkward (value as unknown as TargetType) double-assertions with a clean runtime and compile-time casting helper:
    typescript
    import { cast } from '@magmacomputing/tempo/library';
    const config = cast<CustomConfig>(rawPayload);

[v4.4.3] - 2026-09-29 ​

🚀 Key Highlights & Performance Boosts ​

Tempo v4.4.3 delivers Massive Parsing Speedups via automated regular expression memoization and introduces the public Tempo.cache.weak Object Cache Facade.


🌟 New Features & Performance ​

1. Public Weak Object Cache (Tempo.cache.weak) ​

  • Attach temporary metadata or computed results to object instances without risking memory leaks:
    typescript
    const cache = Tempo.cache.weak<object, ComputedData>();
    cache.set(domElement, { lastUpdated: new Tempo() });

2. Automated Regular Expression & Date Interning ​

  • Auto-Evicting Regex Cache: Dynamically compiled braced format masks and layout matchers are cached with garbage-collection-friendly weak maps.
  • Up to 120x Faster Parsing Loops: Repeated ISO parsing and timezone offset conversions are memoized, reducing heap pressure by ~99.9% in high-throughput data processing pipelines.

[v4.4.2] - 2026-09-27 ​

🚀 Key Highlights & Fixes ​

Tempo v4.4.2 enhances Global Multi-Script Language Support in the natural language date parsing engine.


🌟 Improvements & Fixes ​

1. Unicode Multi-Script Keyword Matching ​

  • Global Script Support: Natural language relative date parsing (like "next Friday" or localized calendar terms) now uses Unicode character property matching and NFC normalization.
  • Zero False Collision Warnings: Non-Latin scripts (such as Arabic, Japanese, Chinese, Cyrillic, and Hebrew) are preserved accurately without triggering duplicate alias warnings.

[v4.4.1] - 2026-09-20 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.4.1 introduces Braced Format Mask Parsing ({format: '...'}) & Wildcards ({*}), Evaluable<T> dynamic format & dialect configuration, and official launch integration for @magmacomputing/tempo-plugin-dialects.


🌟 New Features & Improvements ​

1. Core Braced Format Mask Parsing & Wildcard Matching ​

  • Parse structured date strings using Tempo's standard braced token format:
    typescript
    const t = new Tempo('24-10-2026', { format: '{dd}-{mm}-{yyyy}' });
    const t2 = Tempo.from('2026/10/24 15:30:45', { format: '{yyyy}/{mm}/{dd} {hh}:{mi}:{ss}' });
  • Candidate Format Arrays: Supply multiple candidate masks to match the first matching format:
    typescript
    const t = new Tempo(input, { format: ['{yyyy}-{mm}-{dd}', '{dd}/{mm}/{yyyy}'] });
  • Wildcard Token {*}: Skip arbitrary substrings or log prefixes without complex regular expressions:
    typescript
    const t = new Tempo('Log entry [2026-10-24 15:30] server-01', {
      format: '{*} [{yyyy}-{mm}-{dd} {hh}:{mi}] {*}'
    });
  • Actionable Dialect Guidance: Passing unbraced masks (e.g. 'yyyy-MM-dd') without the dialects plugin throws clear guidance directing users to @magmacomputing/tempo-plugin-dialects.

2. Dynamic Evaluable<T> Format & Dialect Resolution ​

  • Configuration and call-site options for format and dialect now accept dynamic resolver functions (() => string), seamlessly evaluated at runtime via evaluate():
    typescript
    const t = new Tempo(input, {
      format: () => getUserPreferredFormat()
    });

3. Dialects Plugin Integration (@magmacomputing/tempo-plugin-dialects) ​

  • Official v1.0.0 release of the Dialects plugin enabling Unicode LDML (Luxon/date-fns), POSIX strftime, and Moment.js mask translation, formatting, and parsing.

[v4.4.0] - 2026-09-18 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.4.0 introduces Order-Independent Plugin Auto-Installation (/install) and global pending queues, bringing zero-boilerplate side-effect imports for browser scripts, quick prototypes, and interactive REPLs.


🌟 New Features & Improvements ​

1. Zero-Boilerplate Side-Effect Imports (/install) ​

  • Official and community plugins can now be installed with a single import statement:
    typescript
    import '@magmacomputing/tempo-plugin-geo/install';
    import '@magmacomputing/tempo-plugin-ai/install';
  • Order-Independent Registration ($pendingAutoInstalls): If a bundler or browser module loader evaluates a plugin's /install subpath before { Tempo } has finished initializing, registrations are safely buffered in an ambient queue and automatically drained as soon as Tempo boots.
  • Tree-Shaking Preserved: Standard imports (import { GeoPlugin } from '@magmacomputing/tempo-plugin-geo') retain 100% tree-shakeability with zero automatic side-effects.

[v4.3.0] - 2026-09-16 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.3.0 brings Colocated Plugin Options & Hybrid Factories, deep Intl.LocaleInfo Regional Calendar Context, and a direct Native Temporal Gateway (t.zdt).


🌟 New Features & Improvements ​

1. Colocated Plugin Options & Callable Factories ​

  • Vite / Rollup Style Factory Invocations: Plugins constructed via definePlugin now function as hybrid callable factories. Pass options directly at call-site:
    typescript
    Tempo.init({
      plugins: [
        TickerPlugin({ interval: 1000 }),
        [GeoPlugin, { timeout: 5000 }] // Tuple syntax also fully supported!
      ]
    });
  • Uncalled Plugins Retained: Passing uncalled plugins (plugins: [CelestialPlugin]) continues to work seamlessly without breaking changes.

2. Intl.Locale Info & Culturally Authentic Calendars (t.intl) ​

  • First-Class Regional Metadata: Direct access via t.intl (and Tempo.intl) providing frozen regional insights (firstDay, weekend, hourCycle, direction, numberingSystem), alongside t.intl.locale for native Intl.Locale inspection.
  • Adaptive Week Arithmetic (localeInfo: true): With localeInfo: true, operations like t.set({ week: 'start' }) automatically align to the locale's culturally authentic first day (e.g. Sunday in the US, Monday in the UK, Saturday in Saudi Arabia).
  • Dedicated ISO Invariants: Use isoWeek and wy (t.set({ isoWeek: 'start' })) to guarantee Monday-start snapping regardless of locale settings.
  • Localized Format Tokens: Added {dow:locale}, {hh:locale}, {time:locale}, and localized numeral formatting ({yyyy:locale} producing ٢٠٢٦ in Arabic locales).

3. Direct Native Temporal Gateway (t.zdt) ​

  • Direct read-only getter t.zdt exposing the underlying Temporal.ZonedDateTime instance for zero-overhead access to native Temporal properties (daysInMonth, inLeapYear, offset, hoursInDay) without method ceremony.

4. Day-of-Year Property & Token (t.doy, {doy}) ​

  • Direct t.doy accessor (1..366) and formatting token {doy} with width padding support ({doy:3}).

[v4.2.0] - 2026-09-09 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.2.0 introduces Dynamic Spatial & Namespace Format Tokens and Universal Geographic Context (options.geo).


🌟 New Features & Improvements ​

1. Dynamic Namespace & Spatial Tokens in t.format() ​

  • Format strings can now dynamically interpolate active plugin namespaces and spatial properties:
    typescript
    t.format('{geo.city}, {geo.country} — Fiscal Year: {finance.taxYear}');
  • Supports formatting modifiers such as {geo.country:upper} and {geo.city:title} with graceful fallbacks.

2. Universal Geographic Context & Hemisphere Inferences ​

  • Provide geolocation coordinates directly on instantiation (new Tempo('today', { geo: { lat: -33.86, lng: 151.2 } })).
  • Automatically infers hemisphere (t.sphere: 'north' | 'south' | 'equator') and exposes frozen t.geo configuration.

3. Hardened Static Configuration Resolution ​

  • Decoupled configuration inheritance (extends) strictly to static data payloads, eliminating dynamic execution vectors and hardening supply chain boundaries.

[v4.1.0] - 2026-09-04 ​

🚀 Key Highlights & Architectural Enhancements ​

Tempo v4.1.0 expands enterprise configuration governance and developer ergonomics with Remote & Cascading Configuration Resolution ("extends"), a dedicated pluginOptions Configuration Slot, and Overloaded Tempo.create() with Deterministic Resource Disposal (TC39 using).


🌟 New Features & Improvements ​

1. Remote & Cascading Configuration Resolution (resolveConfig) ​

  • Remote URL Config Fetching: Enhanced resolveConfig() and Tempo.bootstrap() to fetch tempo.config.jsonc and tempo.config.json over http:// and https:// URLs (including http://localhost:... or http://127.0.0.1:... for dev servers, container environments, and central governance APIs).
  • file:// URL Support: Added native support for file:// URLs in Node.js environments via fileURLToPath.
  • Cascading Inheritance ("extends"): Introduced recursive "extends" resolution in configuration files (string URL/path or array of URLs/paths). Parent configurations are resolved and merged under child local overrides.
  • Security Boundaries & Loop Protection: HTTP requests are bounded by a 3-second timeout and 128KB payload size cap to prevent hangs and DoS attacks. Remote configs are restricted to static data-only JSON/JSONC payloads. Circular inheritance is detected and prevented.

2. Dedicated pluginOptions Configuration Slot ​

  • Introduced pluginOptions?: Record<string, any> across BaseOptions, Discovery, and Config.
  • Enforces clean architectural separation:
    • plugins: Strictly reserved for executable code registration (plugins, terms, modules).
    • pluginOptions: Dedicated dictionary holding serializable runtime options and defaults for plugins.
  • Deep, recursive namespace merging across extends inheritance layers.
  • Supplying plain configuration dictionaries directly under plugins is marked @deprecated in favor of pluginOptions.

3. Overloaded Tempo.create() & Deterministic Resource Disposal ​

  • Explicit Resource Management (TC39 using): Tempo.create() returns SandboxTempo subclasses that implement the TC39 Disposable protocol (Symbol.dispose) and expose an isDisposed getter. Disposing a sandbox clears its discovery slot from globalThis and cleans up internal registry state (ClassStates).
  • Scoped Callback Mode (Tempo.create(fn) / Tempo.create(options, fn)): Overloaded Tempo.create() to accept an execution callback, automatically disposing the ephemeral sandbox upon completion (supporting both synchronous results and async Promises via try...finally).
  • Native using Block Scoping: Full support for TypeScript 5.2+ block-scoped disposable sandboxes: { using sb = Tempo.create({ ... }); ... }.

4. Architectural Separation of extends and plugins ​

  • extends: Strictly reserved for configuration inheritance via URLs or file paths (string | string[]), mirroring tsconfig.json and ESLint conventions.
  • plugins: Dedicated for registering executable plugins and terms ((Plugin | Term)[]).
  • Tempo.use() & Deprecation of Tempo.extend(): Standardized Tempo.use(...) as the runtime registration method. Marked Tempo.extend() as @deprecated Use Tempo.use(...) instead. while preserving backwards compatibility.

🐛 Bug Fixes ​

  • Sandbox Symbol.dispose Global State Leakage: Fixed a critical bug where invoking [Symbol.dispose]() on a sandbox class (e.g., via the TC39 using keyword or scoped callback mode) inherited Tempo[Symbol.dispose]() via the prototype chain and inadvertently executed Tempo.init(), wiping the global library configuration and registered plugins. Sandboxed classes now implement an isolated [Symbol.dispose]() that strictly cleans up local sandbox state and discovery slots without mutating global defaults.

[v4.0.0] - 2026-08-27 ​

🚀 Key Highlights & Paradigm Shifts ​

Tempo v4.0.0 is a major architectural milestone introducing Dynamic Functional Context (DFC), a 100% Open-Source Community Core, zero-await Synchronous JSONC Config Discovery, standardized Plugin SDK Facade, and unified {Term: Value} Mutation Payloads.


🚨 Major Breaking Changes ​

  • 100% Open-Source Community Core: Completely removed commercial licensing enforcement, JWT verification, JWS claims validation, domain-locking, and premium plugin gating (license.manager.ts, license.validator.ts, Tempo.license, validateLicenseState, LICENSE enum, and $updateScopeStatus).
  • Commercial Package Decoupling: Relocated all enterprise licensing hooks and commercial plugin management to the @magmacomputing/tempo-pro wrapper package.
  • Config Auto-Discovery Modernization: Dropped .cjs configuration discovery support in favor of modern ES-preferred module extensions (.mts, .ts, .mjs, .js, .jsonc, .json).
  • Tempo.ready() Return Signature: Simplified Tempo.ready() return value to a static 'none' status for community core compatibility.
  • Configuration Namespace Enforcement: Fully excised legacy root-level property access that was deprecated during v3.x.
    • formats configuration key has been entirely removed from top-level Options and Discovery. Use registry: { formats: ... } instead.
    • numbers configuration key has been entirely removed from top-level Options. Use registry: { numbers: ... } instead.

🌟 New Features & Architectural Modernizations ​

1. Dynamic Functional Context (DFC) & Options Evaluation ​

  • Upgraded BaseOptions and Tempo options (timeZone, locale, calendar, sphere) to support Evaluable<T> suppliers (T | (() => T)).
  • Context options are dynamically evaluated on a per-request basis without requiring instantiation or re-building configuration state, perfect for multi-tenant applications (e.g., dynamic request headers or per-tenant session resolvers).

2. Synchronous JSON & JSONC Config Discovery (resolveConfigSync) ​

  • Introduced zero-await static startup configuration discovery (resolveConfigSync()) utilizing parseJSONC for .jsonc and .json files.
  • ESM and TypeScript config modules (.mts, .ts, .mjs, .js) continue to utilize the asynchronous resolveConfig() path.
  • Automatically executed inside Tempo's static { ... } initialization block at module load time.

3. Standardized Plugin SDK Facade (@magmacomputing/tempo/plugin/sdk) ​

  • Standardized plugin development on @magmacomputing/tempo/plugin/sdk, replacing legacy plugin-api imports.
  • Exposes definePlugin, defineTerm, defineModule, defineNamespace, defineRange, and internal evaluation utilities via a single, CDN-friendly facade.

4. Expanded Utility Stack Exports (@magmacomputing/tempo/library) ​

  • Re-exported core evaluation and runtime primitives (Evaluable, AsyncEvaluable, evaluate, evaluateAsync, evaluateConfig, evaluateConfigAsync, dynamicProxy, Pledge, cipher, webToken, enumify) via the @magmacomputing/tempo/library export surface for downstream plugins and custom extensions.

5. API Standardization for Boundary & Mutation Payloads ({Term: Value}) ​

  • Standardized mutation object signatures across .set(), .add(), and plugin payloads to follow the unified {Term: Value} pattern (e.g., .set({ year: 'start' }), .set({ month: 'end' }), .set({ '#qtr': 1 })).
  • Legacy positional syntax (e.g., .set({ start: 'year' })) remains supported transparently for backwards compatibility.

🗑️ API Removals & Cleanups ​

  • Removed Static Accessors: Removed Tempo.formats accessor; use Tempo.registry.formats instead.
  • Removed Deprecated Subpaths: Removed #tempo/license export mapping.

Released under the MIT License.