Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
aadb7da
chore: prepare Release D (v2.9.0)
magmacomputing May 2, 2026
79d3cac
fix doco
magmacomputing May 2, 2026
e462af7
1st draft PR
magmacomputing May 3, 2026
2af7698
2nd draft PR review
magmacomputing May 3, 2026
945d845
3rd draft PR review
magmacomputing May 3, 2026
a22e7c7
hasOwn
magmacomputing May 3, 2026
fed3f71
all hasOwn
magmacomputing May 3, 2026
ef10d08
ci.yml
magmacomputing May 3, 2026
0e6a546
aliasEngine heirarchy
magmacomputing May 4, 2026
1d3e29e
Alias warning via Logify
magmacomputing May 4, 2026
1e60a99
extending AliasEngine
magmacomputing May 4, 2026
e83c8d2
monday 6:22
magmacomputing May 4, 2026
74ae34b
my AliasEngine
magmacomputing May 5, 2026
8194de7
new capture-group name syntax
magmacomputing May 5, 2026
0edbe9c
test-cases
magmacomputing May 5, 2026
8eafe0c
pre-discrete
magmacomputing May 5, 2026
a65a174
pre for-of
magmacomputing May 5, 2026
7898eaf
pre alias-resolve
magmacomputing May 5, 2026
03670a0
pre test-fails
magmacomputing May 5, 2026
103fb5c
ready for review
magmacomputing May 6, 2026
9e6beb6
migration phase2.1
magmacomputing May 6, 2026
40545f8
ready for AliasMigration review
magmacomputing May 6, 2026
3a5d834
Merge origin/main into release/D: resolve conflicts keeping release/D…
Copilot May 6, 2026
6f5276c
Merge origin/main into release/D: resolve conflicts keeping release/D…
Copilot May 6, 2026
ec9e905
pre collapse alias
magmacomputing May 6, 2026
1611506
align setEvents|setPeriods
magmacomputing May 6, 2026
c2fabf2
PR 1st review
magmacomputing May 6, 2026
9d4b68d
PR 2nd review
magmacomputing May 6, 2026
66e81ef
PR 3rd review
magmacomputing May 6, 2026
dd34f02
PR 4th review
magmacomputing May 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
name: Test with parse.preFilter enabled
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.ref == 'refs/heads/release-c-layout-order-planner' || github.event.pull_request.base.ref == 'main'
if: (github.event_name == 'push' || github.event_name == 'pull_request') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release/D' || github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'release/D')
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
Expand Down
49 changes: 5 additions & 44 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/tempo/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export default defineConfig({
base: '/magma/',
title: "Tempo",
description: "The Professional Date-Time Library for Temporal",
srcDir: './doc',
srcDir: '.',
srcExclude: ['**/plan/**', '**/archive/**', '**/bench/**', '**/scratch/**', 'CHANGELOG.md'],
markdown: {
math: true
},
Expand Down
16 changes: 16 additions & 0 deletions packages/tempo/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.9.0] - 2026-05-06

### Added
- **Centralized Alias Architecture**: Finalized the migration to a unified `AliasEngine`. All event and period aliases are now managed through a centralized registry, providing a single source of truth across global and local contexts.
- **Rich Alias Results**: Alias resolution now returns a structured `AliasResult` object containing exhaustive metadata, including the source (global/local), type (Event/Period), and specific resolution flags.
- **Hardened Clock Snapping**: Standardized the resolution path for clock-like aliases (e.g. `8:00`). The engine now ensures absolute sub-second precision clearing (milliseconds, microseconds, and nanoseconds) when snapping to a time-string alias.
- **Optimized Lifecycle Monitoring**: Implemented a version counter in the `AliasEngine`. Mutation operations now trigger a version increment, allowing `Tempo` instances to efficiently detect registry changes and rebuild internal regex patterns without expensive deep-cloning.

### Changed
- **Parser Context Consolidation**: Extracted the "host" facade construction from the main parsing loop into a dedicated `getResolutionContext` helper, improving maintainability and reducing Parser complexity.
- **Decoupled Term Registration**: Refactored `Tempo.extend` and term-based alias registration to bypass legacy raw registries, while maintaining backward compatibility via a mirrored metadata view.

### Fixed
- **Documentation Server Stability**: Resolved VitePress 404 errors by correcting the `srcDir` configuration and implemented `srcExclude` to prevent build failures from dead links in non-documentation folders.


## [2.8.0] - 2026-04-30

Expand Down
1 change: 1 addition & 0 deletions packages/tempo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ For granular "Lite" builds, see the [Full Installation Guide](https://magmacompu
## ✨ Why Tempo?
* **🏗️ Future Standard**: Built natively on the TC39 `Temporal` proposal. Inherit the reliability of the future standard.
* **🗣️ Natural Language**: Resolve complex terms like `#quarter.last` or "two days ago" with zero configuration.
* **🧠 Functional Aliases**: Extend the parser with custom logic using a powerful resolution context for relative date math.
* **🔄 Cycle Persistence**: Shift by semantic terms (Quarters, Seasons) while preserving your relative day-of-period offset.
* **⚡ Zero-Cost Parsing**: Lazy evaluation and smart matching ensure instantiation overhead is near-zero.
* **🛡️ Monorepo Resilient**: Built for stability in complex environments with proxy-protected registries.
Expand Down
14 changes: 13 additions & 1 deletion packages/tempo/doc/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,19 @@ The **Guarded-Lazy** strategy ensures that even with hundreds of custom plugins,
1. **Longest-Token Matching**: To prevent partial matching (e.g., matching `qtr` inside `quarter`), the guard uses a "Scan-and-Consume" loop that prioritizes the longest available token.
2. **Unified Wordlist**: The guard automatically ingests all registered Terms, Timezones, Month names, and Custom Events into a single high-speed lookup Set.
3. **High-Speed Gatekeeper**: By avoiding complex backtracking regexes, the gatekeeper provides predictable $O(1)$ performance even as the plugin list grows.
4. **Auto-Lazy**: Valid inputs that pass the guard automatically switch the instance to `mode: 'defer'`, deferring the full $O(N)$ parse work until a property is actually read.
4. **Versioned Registry (v2.9.0)**: To avoid redundant wordlist rebuilding, the Guard now monitors a `#version` counter on the alias registry. The wordlist is only rebuilt when a mutation actually occurs.
5. **Auto-Lazy**: Valid inputs that pass the guard automatically switch the instance to `mode: 'defer'`, deferring the full $O(N)$ parse work until a property is actually read.

---

## 🧩 Centralized Alias Management (v2.9.0)
As of **v2.9.0**, Tempo has consolidated all Event and Period alias logic into a dedicated **`AliasEngine`**.

### How it works:
- **Hierarchical Registry**: Aliases are managed in a prototype-aware chain. A local `Tempo` instance can have its own private aliases that shadow global ones, all while sharing the same underlying resolution logic.
- **Rich Metadata**: Every resolution returns a structured `AliasResult`, providing the Parser with immediate knowledge of the alias's origin (global vs local), type, and clock-snapping requirements.
- **Clock Snapping**: Time-based aliases (e.g. `8:00`) are automatically "snapped" to absolute precision, clearing sub-second drift (ms, us, ns) during the resolution phase.
- **Decoupled Registration**: By moving away from legacy raw objects, the registry is now protected against accidental mutation and supports efficient, version-aware monitoring.

### 📈 Validation & Performance
The efficiency of the Master Guard and the success of the Zero-Cost objective have been validated via local benchmarking:
Expand Down
17 changes: 17 additions & 0 deletions packages/tempo/doc/releases/v2.x.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
# 📜 Version 2.x History


## [v2.9.0] - 2026-05-06
### 🏗️ Alias Architecture Stabilization
- **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 `AliasResult` objects, 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.

### ⚙️ Parser & Registry Refinement
- **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.

### 📚 Documentation Fixes
- **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.

---

## [v2.8.0] - 2026-04-30
### 🚨 Immutability System Refined
- The project evaluated mutation-throwing Proxies for all immutable objects, but reverted to using `Object.freeze` for stability and compatibility.
Expand Down
2 changes: 1 addition & 1 deletion packages/tempo/doc/tempo.modularity.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Adds support for semantic terms like `qtr`, `szn`, `zdc`, and `per`. There are t
#### 1. The Side-Effect (Standard Activation)
Fastest way to enable all standard terms in a Core environment.
```typescript
import '@magmacomputing/tempo/term/standard'; // One-line activation
import '@magmacomputing/tempo/term'; // One-line activation
```

#### 2. The Explicit Module (Uniform Sync)
Expand Down
32 changes: 31 additions & 1 deletion packages/tempo/doc/tempo.parse.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,37 @@ Tempo.init({
const t = new Tempo('party');
```

### 🧠 Functional Alias Context
When you use a function as an alias value, Tempo provides a powerful **Resolution Context** (the `this` binding). This context mimics a lightweight Tempo instance, allowing you to perform relative date math during resolution.

Available methods in the context:
* **`this.add(duration)`**: Add a duration to the current anchor.
* **`this.subtract(duration)`**: Subtract a duration.
* **`this.with(values)`**: Set specific fields (year, month, day, etc.).
* **`this.set(input)`**: Recursively parse another string or value relative to the anchor.
* **`this.toNow()`**: Get the current system time.
* **`this.toDateTime()`**: Get the current anchor as a native `Temporal.ZonedDateTime`.
* **`this.hh`, `this.mi`, `this.ss`**: Accessors for current time units.

#### Example: Complex Functional Alias
```typescript
Tempo.init({
event: {
// Resolve "bedtime" to 10pm on the same day
'bedtime': function() {
return this.with({ hour: 22, minute: 0, second: 0 });
},
// Resolve "meeting" to 2 hours after whatever was just parsed
'meeting': function() {
return this.add({ hours: 2 });
}
}
});
```

---

## 🛡️ Performance: The Master Guard
Tempo uses a "Scan-and-Consume" engine called the **Master Guard**. This allows it to check your input string against dozens of patterns (weekdays, months, custom events) in a single pass, ensuring that parsing remains $O(1)$ relative to the number of plugins you have active.
Tempo uses a "Scan-and-Consume" engine called the **Master Guard**. This allows it to check your input string against dozens of patterns (weekdays, months, custom events) in a single pass.

In version **2.9.0**, the Master Guard has been optimized with a **Versioned Registry**. The engine now tracks a `#version` counter on the alias registry, ensuring that the guard's pattern list is only rebuilt when a mutation actually occurs. This provides near-instant validation for high-volume parsing tasks.
19 changes: 12 additions & 7 deletions packages/tempo/doc/tempo.term.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Hemisphere-aware: southern-hemisphere configs shift the quarter boundaries by si
const t = new Tempo('15-Feb-2025');

t.term.qtr // → 'Q1'
t.term.quarter // → { key: 'Q1', day: 1, month: 1, fiscal: 2025, sphere: 'North' }
t.term.quarter // → { key: 'Q1', day: 1, month: 1, fiscal: 2025, sphere: 'north' }
```

```ts
Expand All @@ -54,17 +54,14 @@ t.term.qtr // → 'Q3' (southern hemisphere)
### `szn` / `season` — Meteorological Seasons

Maps the current date to the appropriate meteorological season.
Hemisphere-aware (northern / southern boundaries differ), and the full `season` scope additionally includes the corresponding **Chinese season** for the date.
Hemisphere-aware (northern / southern boundaries differ).

```ts
const t = new Tempo('01-Jul-2025');

t.term.szn // → 'Winter' (northern hemisphere)
t.term.season
// → { key: 'Winter', day: 22, month: 12, symbol: 'Snowflake', sphere: 'North' }

t.term.season.CN
// → { key: 'Summer', symbol: 'Sun', ... }
// → { key: 'Winter', day: 22, month: 12, symbol: 'Snowflake', sphere: 'north' }
```

```ts
Expand Down Expand Up @@ -132,7 +129,7 @@ In **Tempo Full**, all standard terms are enabled by default. In **Tempo Core**,
### 1. Standard Activation (Recommended)
The fastest way to enable all built-in terms (`qtr`, `szn`, `zdc`, `per`).
```typescript
import '@magmacomputing/tempo/term/standard'; // One-line side-effect activation
import '@magmacomputing/tempo/term'; // One-line side-effect activation
```

### 2. Explicit Module (Uniform Sync)
Expand Down Expand Up @@ -210,6 +207,14 @@ export const MySeasonTerm = defineTerm({
A `Range` object must include a `key` and any subset of the date-time fields below.
`getTermRange` sorts ranges in descending chronological order and returns the **first range whose boundary the instance has reached or passed**.

### 🔄 Sync to Alias Engine
When a term plugin defines `ranges` with string-based `key` values, Tempo automatically synchronizes these keys with the internal **Alias Engine**.

* **Period Scopes**: Ranges defined in a `period` scope (like `midnight` or `morning`) are registered as **Period Aliases**.
* **Event Scopes**: Ranges defined in an `event` scope are registered as **Event Aliases**.

This synchronization happens during `Tempo.extend()` and `Tempo.init()`, ensuring that any named range boundaries are immediately available for use in the natural-language parsing engine. For example, if you define a custom term with a range key `"bedtime"`, you can immediately create a new instance using `new Tempo('bedtime')`.

```ts
type Range = {
key: PropertyKey; // identifier returned when keyOnly = true
Expand Down
Loading
Loading