- Unified Alias Engine: Completed the architectural migration to the
AliasEngine, centralizing all registration and resolution logic for Events and Periods. - Rich Metadata Results: Enhanced the resolution engine to return structured
AliasResultobjects, providing better traceability and granular control over alias-driven parses. - Hardened Clock Snapping: Finalized the standardization of clock-like alias resolution, ensuring consistent sub-second precision clearing for all static and functional time aliases.
- Performance Optimized Monitoring: Introduced a lightweight version-tracking system to detect registry mutations, enabling
O(1)change detection during the Tempo lifecycle.
- Consolidated Host Context: Modularized the construction of the functional alias "pseudo-Tempo" context, improving separation of concerns in the parsing pipeline.
- Legacy Decoupling: Successfully decoupled term-based alias registration from internal raw objects, moving toward a more encapsulated and secure registry design.
- VitePress 404 Patch: Corrected root directory resolution to fix "404 Not Found" errors on the landing page.
- Build Resilience: Implemented targeted folder exclusion to prevent build-time dead-link errors in non-public directories.
- The project evaluated mutation-throwing Proxies for all immutable objects, but reverted to using
Object.freezefor stability and compatibility. - All core objects remain protected with
Object.freeze. No mutation-throwing Proxies are used for core objects. - See plan for architectural and migration details.
- Added Parse Planner: Introduced
planner.layoutOrderto explicitly control the parsing priority of date layouts (likemdyoriso). - Pre-Filtering Optimization: Moved
parsePrefiltertoplanner.preFilter. LegacyparsePrefilterconfigurations remain fully backward compatible.
- MonthDay Auto-Detection: Hardened the
monthDayoptions resolver so that boolean shortcuts (e.g.monthDay: true) and manual overrides are properly tracked and never overwritten by auto-detection heuristics. - Sandbox Factory Stability: Fixed bugs in the
Tempo.create()sandbox where period alias collisions were failing silently;console.warnis now properly emitted when aliases overlap in local sandboxes. - Symbol Discovery Isolation: Patched the
$setConfigresolution flow to correctly merge custom formats provided via discovery symbols before evaluating global option extensions.
- Grouped Options: Consolidated regional parsing and relative time options into nested objects for improved discoverability and additive merging support.
mdyLocalesandmdyLayouts→monthDay: { locales, layouts }rtfFormatandrtfStyle→relativeTime: { format, style }
- Internal Hardening: Added
isMonthDayinternal detection to more accurately resolve parse-order layouts in regional contexts.
- Event Registry Overrides: Fixed
$setEventslogic to ensure user-defined event aliases correctly override or merge with built-in patterns without duplication or stale matches. - TimeZone Fallback Resilience: Enhanced the IANA TimeZone fallback mechanism with a cleaned-up, prioritized list of regional aliases.
- Intl.Locale Debugging: Improved diagnostic logging for
Intl.Localeresolution to assist in cross-environment consistency issues. - Ticker Stabilization: Further refined async generator pulse counts and termination logic.
- Performance Benchmarking: Integrated a dedicated
bench/suite into the CI pipeline to monitor performance impact on core parsing and mutation logic. - Workflow Optimization: Refactored the GitHub Actions workflow for better test isolation and Node.js 24 compatibility.
- New Features
Added normalizeUtcOffset utility for transforming informal UTC-offset strings to standard format. Added layoutOrder option to customize parsing element precedence.
-
Breaking Changes
-
Season Scope Simplification: Removed the Chinese-specific object previously attached to all
term.seasonscope's output. For Chinese season interpretation, create a dedicatedTempoinstance with{timeZone: 'Asia/Shanghai'}or{timeZone: '+08:00'}. Note that Chinese zodiac will still be supported onterm.zodiac.CNas before. -
Bug Fixes
Fixed layout pattern resolution ordering to respect intended sequence. Enhanced timezone normalization for UTC offset handling.
- Documentation
Updated architecture documentation and configuration guidance. Clarified plugin/module callback parameter ordering in examples. Added v2.6.0 migration guide for season changes.
- Added Sandbox Factory pattern for isolated Tempo configurations via Tempo.create(options).
- User-defined aliases now evaluated before built-in aliases for custom precedence.
- Support for shorthand duration construction: new Tempo({ hours: 2 }).
- Debug option now accepts numeric log levels for granular control.
- Added fortnight event and half-hour period aliases.
- Improved compact time/date parsing for 6 and 8-digit inputs.
- Enhanced installation guidance with Temporal polyfill details.
- New modularity documentation and sandbox factory pattern guide.
- Added parsing cookbook with digit-only string precedence examples.
- Layout Order Resolver: Extracted layout-ordering decision logic into a dedicated
engine.layoutmodule (src/engine/engine.layout.ts), improving internal modularity and enabling future per-input classification support. The resolver maintains 100% behavior parity with prior ordering semantics (locale-baseddmy↔mdyswaps). - Layout Controller Framework: Introduced a minimal but extensible controller-map structure to support future input classifications (e.g., "6 digits only", "contains colon"). Currently ships with a single default classification that mirrors the existing layout order, ensuring zero overhead today and a clear path for Release B/C enhancements.
- Sandbox Factory Mode: Introduced
Tempo.create(), a static factory method that generates a completely isolatedTemposubclass. Each sandbox maintains its own independent configuration, registry, and plugin state while inheriting from the parent, enabling multi-tenant or modular configurations within a single process without global state collisions.
- Modular Separation: Extracted the core ordering logic from
Tempo.#swapLayout, improving code organization and unit testability without affecting public APIs. - Symbol-Based Safety: Protected the default layout classification key with a
Symbol('default'), reducing accidental tampering risk and improving internal API robustness. - Determinism Coverage: Added comprehensive tests for layout order resolution, classification fallback, and multi-pair swap handling to ensure predictable behavior across locales and configurations.
- Module Path Flattening: Relocated core modules (e.g.,
mutate,duration) fromsrc/plugin/module/to a top-levelsrc/module/directory. This simplifies the internal architecture and provides cleaner internal import paths, reflecting their role as core library features rather than just "plugins".
- Layout Order Tracing: Added optional debug emission to show the final resolved layout order when
debug: trueis set, helping developers understand parse-order decisions.
- Standalone Logic: Extracted the natural language engine into a dedicated
parse()function, enabling independent datetime string resolution without requiring a full Tempo instance. - Noise Filtering: Introduced a configurable
ignoreoption to strip "noise words" during parsing, significantly increasing the robustness of the natural language interpreter. - Backtracking Security: Implemented a centralized regex safety guard (
Match.backtrack) in the snippet registry to block potentially malicious patterns and prevent catastrophic backtracking.
- Ecosystem Installation: Released a comprehensive installation guide covering Node.js (npm/pnpm/yarn), Deno, standard browser ESM, and specialized "Lite" build configurations.
- Interactive Demo: Enhanced the browser-based playground with a live timezone selector and real-time clock updates to demonstrate Temporal integration.
- Quick Start Refinement: Streamlined the README and configuration documentation to highlight simplified entry points and noise-filtering capabilities.
- State Management: Optimized the internal parser state machine to reduce memory pressure and improve resolution speed for complex strings.
- Type Safety: Hardened the TypeScript definitions for all
parseandtermresolution functions, ensuring strict type-checking without consumer-side casting. - Automatic Context Sync: The engine now automatically synchronizes the hemisphere (sphere) configuration whenever the timezone is updated.
- Resilience: Hardened the resolution loop with safety-valves to prevent infinite loops during extreme date-range traversals and improved parse-error detection to prevent silent state corruption.
- Isomorphic Export Architecture: Refactored
tempo.entry.tsand Rollup configuration to ensure the browser ESM bundle exportsTempoas both a default and a named export. This guarantees thatimport { Tempo } from '@magmacomputing/tempo'functions identically across Node.js and browser environments without throwing resolution errors. - Dependency Resolution: Added
jsbiexplicitly to all documentationimportmapexamples to correctly resolve@js-temporal/polyfillinternal bare module references and eliminateFailed to resolve module specifier "jsbi"errors. - Documentation & UI: Fixed orphaned markdown script tags, formatted HTML browser usage blocks, and completely revamped the browser test UI pages with a premium jazzy aesthetic.
- Singleton Resilience: Replaced
instanceofchecks inTempoRuntimewith a cross-bundle brand check, ensuring singletons are correctly adopted across bundle boundaries and HMR reloads. - Unified Discovery: Consolidated internal storage for term and extension plugins into a single, validated
pluginsDbstructure. - Resolved Shadowing: Eliminated parameter shadowing in runtime hook methods to ensure reliable event emission.
- Chronological Stability: Enforced chronological sorting in
resolveCycleWindowfor accurate cycle anchor identification. - Absolute vs Relative Years: Normalized year handling to allow templates to mix relative offsets and absolute historical years seamlessly.
- Standards Mode: Modernized all public demonstration files with proper HTML5 skeletons and metadata.
- Contextual Guidance: Updated architecture docs and READMEs with accurate module paths and functional importmap examples.
- Immutable Compatibility: Added redefinition guards to
TickerModuleto prevent errors on already-frozen classes. - ESM Integrity: Bundled
tslibinto granular ESM builds to resolve resolution failures in standard browser environments.
- Modular Parsing: Initial decoupling of the parse engine to support standalone usage.
- Layout Snippets: Introduced pattern-based layout customization for granular formatting control.
- Project Governance: Integrated the MIT license and established a dedicated release history.
- Match Propagation: Ensured parse results correctly propagate through instance clones.
- Drift Resolution: Corrected timezone and calendar drift during intensive mutation cycles.
- Knowledge Architecture: Reorganized navigation into focused tracks: Cookbook, Advanced Reference, and Utility Library.
- API Reference: Expanded constructor documentation and added guidance for custom enum implementations.
- Diagnostics: Improved internal module-loading error messages for easier troubleshooting.
- Globalized module and serialization registries using
Symbol.for()onglobalThisto ensure state consistency across module reloads, HMR, and bundled distributions. - Implemented secure, local Proxy wrapping for registries to prevent closure persistence across library reloads.
- Fixed static property reflection for decorated classes by implementing recursive prototype chain traversal in
getAccessors. - Refined prototype walking logic to prevent leaks from
Object.prototypeandFunction.prototype.
- Achieved 100% build parity and test coverage in the production distribution (
test:dist). - Reduced NPM package size by nearly 50% by excluding non-essential documentation and image assets from the public package.
- Hardened Rollup build paths to be context-aware and defensive against missing artifacts.
- Redesigned the documentation landing page with a custom, high-performance Hero section and a live Tempo-driven analog clock.
- Harmonized branding across README and documentation sites with "Tempo Blue" styling.
- Fixed routing and asset resolution for GitHub Pages deployments using VitePress base-path helpers.
- Stabilized the mutation engine (
.add(),.set()) to correctly accumulate and preserve parse results across instance clones. - Implemented robust parse result propagation in
MutateModuleusing the internalstate.matchesregistry. - Standardized cross-module state access using the
[sym.$Internal]symbol, enabling safe cloning without violating private encapsulation. - Resolved timezone and calendar drift during complex mutations by enforcing authoritative state-merging in the mutation pipeline.
- Successfully decoupled internal parsing logic into
ParseModule, reducing core class complexity. - Implemented a hybrid static
Tempo.parseconfiguration/method pattern to maintain full backward compatibility while supporting modular delegation. - Hardened the
interpretutility to ensure reliable method dispatching even when modules are loaded lazily or via HMR.
- Upgraded GitHub Actions pipeline to Node.js 24 to resolve deprecation warnings.
- Restored separate "Full" and "Core" test suite isolation in local and workspace Vitest configurations.
- Standardized documentation build order to ensure artifacts are compiled before generation.
- Achieved 100% Test Pass Rate (384/384) across all environments and distribution bundles.
- VitePress Migration: Launched a modern documentation system with integrated TypeDoc API references.
- Loading Patterns: Introduced interactive browser demos for ESM, IIFE, and granular module resolution.
- Standardized README: Refreshed the main project entry point with improved formatting and developer guides.
- Plugin Refactor: Migrated the plugin system to a flexible object-based API for better extensibility.
- Cache Optimization: Enhanced memoization performance across the core engine.
- Modular Exports: Streamlined library entry points to improve tree-shaking and reduce bundle sizes.
- High Precision: Expanded Temporal utility functions with native support for nanosecond-precision calculations.
Tempo v2.1.2 is a major milestone, delivering a more reactive architecture and rock-solid stability.
Tempo is now split into core and optional modules, allowing you to include only what you need. This reduces bundle size for users who only need the basic engine.
Internal logging now uses context-aware Symbols. This decouples the logging logic from the core engine, allowing for cleaner diagnostics without performance overhead.
- Added
Tempo.duration()static method for convenient duration creation without instantiating a full Tempo date object first.
Plugins now support automatic registration.
- The full
@magmacomputing/tempopackage includes all modules by default. - Core users (
@magmacomputing/tempo/core) can activate features simply by importing the corresponding module (e.g.,import '@magmacomputing/tempo/ticker').
The engine passes all regression tests, ensuring complete stability across:
- Parsing complex date strings.
- Calculation and relative math.
- Formatting routines.
Terms (like Quarters and Seasons) are now fully integrated:
- Use
#inset()to jump to boundaries (e.g.,t.set({ start: '#quarter' })). - Use
{#term}informat()to embed semantic labels (e.g. "Second Quarter") directly into strings (e.g.,t.format('Today is {yyyy}-{mm}-{dd} in the {#quarter}').
A category-first feature. Shift dates by semantic "steps" with .add({ '#quarter': 1 }). Tempo preserves your relative duration within the term, jumping across gaps and handling overflows with mathematical precision.
Term ranges now return fully functional, frozen Tempo instances for start and end. This allows for seamless chaining:
t.term.qtr.start.format('{dd} {mmm}')Fully stabilized the Ticker subsystem:
- Resolved async generator hangs.
- Synchronized pulse counts (
$N$ pulses forlimit: N), guaranteeing 100% predictable reactive streams.
- Re-engineered pattern generation for
$O(1)$ instance creation. - Improved support for custom layout literals in local/one-off parsers.
- Significant refinements to the natural language engine for even more intuitive relative-date handling ("next Friday", "two days ago", etc.).