Skip to content

Commit 4b468d9

Browse files
Release/d (#26)
* chore: prepare Release D (v2.9.0) * fix doco * 1st draft PR * 2nd draft PR review * 3rd draft PR review * hasOwn * all hasOwn * ci.yml * aliasEngine heirarchy * Alias warning via Logify * extending AliasEngine * monday 6:22 * my AliasEngine * new capture-group name syntax * test-cases * pre-discrete * pre for-of * pre alias-resolve * pre test-fails * ready for review * migration phase2.1 * ready for AliasMigration review * Merge origin/main into release/D: resolve conflicts keeping release/D version Agent-Logs-Url: https://github.com/magmacomputing/magma/sessions/984a79e1-3587-4d46-a02c-2e09df728e9e Co-authored-by: magmacomputing <6935496+magmacomputing@users.noreply.github.com> * pre collapse alias * align setEvents|setPeriods * PR 1st review * PR 2nd review * PR 3rd review * PR 4th review --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: magmacomputing <6935496+magmacomputing@users.noreply.github.com>
1 parent ed17bfc commit 4b468d9

40 files changed

Lines changed: 885 additions & 548 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
name: Test with parse.preFilter enabled
3939
runs-on: ubuntu-latest
4040
timeout-minutes: 30
41-
if: github.ref == 'refs/heads/release-c-layout-order-planner' || github.event.pull_request.base.ref == 'main'
41+
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')
4242
steps:
4343
- uses: actions/checkout@v4
4444
- name: Set up Node.js

package-lock.json

Lines changed: 5 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tempo/.vitepress/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export default defineConfig({
1212
base: '/magma/',
1313
title: "Tempo",
1414
description: "The Professional Date-Time Library for Temporal",
15-
srcDir: './doc',
15+
srcDir: '.',
16+
srcExclude: ['**/plan/**', '**/archive/**', '**/bench/**', '**/scratch/**', 'CHANGELOG.md'],
1617
markdown: {
1718
math: true
1819
},

packages/tempo/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [2.9.0] - 2026-05-06
9+
10+
### Added
11+
- **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.
12+
- **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.
13+
- **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.
14+
- **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.
15+
16+
### Changed
17+
- **Parser Context Consolidation**: Extracted the "host" facade construction from the main parsing loop into a dedicated `getResolutionContext` helper, improving maintainability and reducing Parser complexity.
18+
- **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.
19+
20+
### Fixed
21+
- **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.
22+
723

824
## [2.8.0] - 2026-04-30
925

packages/tempo/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ For granular "Lite" builds, see the [Full Installation Guide](https://magmacompu
9090
## ✨ Why Tempo?
9191
* **🏗️ Future Standard**: Built natively on the TC39 `Temporal` proposal. Inherit the reliability of the future standard.
9292
* **🗣️ Natural Language**: Resolve complex terms like `#quarter.last` or "two days ago" with zero configuration.
93+
* **🧠 Functional Aliases**: Extend the parser with custom logic using a powerful resolution context for relative date math.
9394
* **🔄 Cycle Persistence**: Shift by semantic terms (Quarters, Seasons) while preserving your relative day-of-period offset.
9495
* **⚡ Zero-Cost Parsing**: Lazy evaluation and smart matching ensure instantiation overhead is near-zero.
9596
* **🛡️ Monorepo Resilient**: Built for stability in complex environments with proxy-protected registries.

packages/tempo/doc/architecture.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,19 @@ The **Guarded-Lazy** strategy ensures that even with hundreds of custom plugins,
130130
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.
131131
2. **Unified Wordlist**: The guard automatically ingests all registered Terms, Timezones, Month names, and Custom Events into a single high-speed lookup Set.
132132
3. **High-Speed Gatekeeper**: By avoiding complex backtracking regexes, the gatekeeper provides predictable $O(1)$ performance even as the plugin list grows.
133-
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.
133+
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.
134+
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.
135+
136+
---
137+
138+
## 🧩 Centralized Alias Management (v2.9.0)
139+
As of **v2.9.0**, Tempo has consolidated all Event and Period alias logic into a dedicated **`AliasEngine`**.
140+
141+
### How it works:
142+
- **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.
143+
- **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.
144+
- **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.
145+
- **Decoupled Registration**: By moving away from legacy raw objects, the registry is now protected against accidental mutation and supports efficient, version-aware monitoring.
134146

135147
### 📈 Validation & Performance
136148
The efficiency of the Master Guard and the success of the Zero-Cost objective have been validated via local benchmarking:

packages/tempo/doc/releases/v2.x.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
# 📜 Version 2.x History
22

33

4+
## [v2.9.0] - 2026-05-06
5+
### 🏗️ Alias Architecture Stabilization
6+
- **Unified Alias Engine**: Completed the architectural migration to the `AliasEngine`, centralizing all registration and resolution logic for Events and Periods.
7+
- **Rich Metadata Results**: Enhanced the resolution engine to return structured `AliasResult` objects, providing better traceability and granular control over alias-driven parses.
8+
- **Hardened Clock Snapping**: Finalized the standardization of clock-like alias resolution, ensuring consistent sub-second precision clearing for all static and functional time aliases.
9+
- **Performance Optimized Monitoring**: Introduced a lightweight version-tracking system to detect registry mutations, enabling `O(1)` change detection during the Tempo lifecycle.
10+
11+
### ⚙️ Parser & Registry Refinement
12+
- **Consolidated Host Context**: Modularized the construction of the functional alias "pseudo-Tempo" context, improving separation of concerns in the parsing pipeline.
13+
- **Legacy Decoupling**: Successfully decoupled term-based alias registration from internal raw objects, moving toward a more encapsulated and secure registry design.
14+
15+
### 📚 Documentation Fixes
16+
- **VitePress 404 Patch**: Corrected root directory resolution to fix "404 Not Found" errors on the landing page.
17+
- **Build Resilience**: Implemented targeted folder exclusion to prevent build-time dead-link errors in non-public directories.
18+
19+
---
20+
421
## [v2.8.0] - 2026-04-30
522
### 🚨 Immutability System Refined
623
- The project evaluated mutation-throwing Proxies for all immutable objects, but reverted to using `Object.freeze` for stability and compatibility.

packages/tempo/doc/tempo.modularity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Adds support for semantic terms like `qtr`, `szn`, `zdc`, and `per`. There are t
5757
#### 1. The Side-Effect (Standard Activation)
5858
Fastest way to enable all standard terms in a Core environment.
5959
```typescript
60-
import '@magmacomputing/tempo/term/standard'; // One-line activation
60+
import '@magmacomputing/tempo/term'; // One-line activation
6161
```
6262

6363
#### 2. The Explicit Module (Uniform Sync)

packages/tempo/doc/tempo.parse.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,37 @@ Tempo.init({
111111
const t = new Tempo('party');
112112
```
113113

114+
### 🧠 Functional Alias Context
115+
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.
116+
117+
Available methods in the context:
118+
* **`this.add(duration)`**: Add a duration to the current anchor.
119+
* **`this.subtract(duration)`**: Subtract a duration.
120+
* **`this.with(values)`**: Set specific fields (year, month, day, etc.).
121+
* **`this.set(input)`**: Recursively parse another string or value relative to the anchor.
122+
* **`this.toNow()`**: Get the current system time.
123+
* **`this.toDateTime()`**: Get the current anchor as a native `Temporal.ZonedDateTime`.
124+
* **`this.hh`, `this.mi`, `this.ss`**: Accessors for current time units.
125+
126+
#### Example: Complex Functional Alias
127+
```typescript
128+
Tempo.init({
129+
event: {
130+
// Resolve "bedtime" to 10pm on the same day
131+
'bedtime': function() {
132+
return this.with({ hour: 22, minute: 0, second: 0 });
133+
},
134+
// Resolve "meeting" to 2 hours after whatever was just parsed
135+
'meeting': function() {
136+
return this.add({ hours: 2 });
137+
}
138+
}
139+
});
140+
```
141+
114142
---
115143

116144
## 🛡️ Performance: The Master Guard
117-
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.
145+
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.
146+
147+
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.

packages/tempo/doc/tempo.term.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Hemisphere-aware: southern-hemisphere configs shift the quarter boundaries by si
4242
const t = new Tempo('15-Feb-2025');
4343

4444
t.term.qtr // → 'Q1'
45-
t.term.quarter // → { key: 'Q1', day: 1, month: 1, fiscal: 2025, sphere: 'North' }
45+
t.term.quarter // → { key: 'Q1', day: 1, month: 1, fiscal: 2025, sphere: 'north' }
4646
```
4747

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

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

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

6262
t.term.szn // → 'Winter' (northern hemisphere)
6363
t.term.season
64-
// → { key: 'Winter', day: 22, month: 12, symbol: 'Snowflake', sphere: 'North' }
65-
66-
t.term.season.CN
67-
// → { key: 'Summer', symbol: 'Sun', ... }
64+
// → { key: 'Winter', day: 22, month: 12, symbol: 'Snowflake', sphere: 'north' }
6865
```
6966

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

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

210+
### 🔄 Sync to Alias Engine
211+
When a term plugin defines `ranges` with string-based `key` values, Tempo automatically synchronizes these keys with the internal **Alias Engine**.
212+
213+
* **Period Scopes**: Ranges defined in a `period` scope (like `midnight` or `morning`) are registered as **Period Aliases**.
214+
* **Event Scopes**: Ranges defined in an `event` scope are registered as **Event Aliases**.
215+
216+
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')`.
217+
213218
```ts
214219
type Range = {
215220
key: PropertyKey; // identifier returned when keyOnly = true

0 commit comments

Comments
 (0)