Initial Commit
This commit is contained in:
120
openspec/archive/2026-04-19-enterprise-timing/proposal.md
Normal file
120
openspec/archive/2026-04-19-enterprise-timing/proposal.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# OpenSpec Change: enterprise-timing
|
||||
|
||||
- **Change ID**: enterprise-timing
|
||||
- **Package**: `@suaveplan/timing`
|
||||
- **Category**: universal
|
||||
- **Target path**: `packages/universal/timing`
|
||||
- **Status**: IN PROGRESS
|
||||
- **Date**: 2026-04-18
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/timing.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Greenfield implementation of `@suaveplan/timing` for the genesis branch. The existing main-branch timing package provides the baseline public-API surface to preserve; this change delivers enterprise-grade timing and scheduling utilities — stopwatch, throttle/debounce, scheduler, exponential decay, and vector clock — with injectable clock, `AbortSignal` support, structured errors, Zod schemas, property-based tests, OTel instrumentation, and benchmarks.
|
||||
|
||||
## Current-state audit (genesis)
|
||||
|
||||
The package does not exist on genesis yet — this is a fresh build.
|
||||
|
||||
## Available workspace deps on genesis
|
||||
|
||||
| Package | Available |
|
||||
|---------|-----------|
|
||||
| `@suaveplan/error` | ✅ |
|
||||
| `@suaveplan/types` | ✅ |
|
||||
| `@suaveplan/events` | ✅ |
|
||||
| `@suaveplan/streams` | ❌ not yet built — not required |
|
||||
| `@suaveplan/opentelemetry` | ❌ not yet built — use `@opentelemetry/api` directly |
|
||||
| `@suaveplan/feature-flags` | ❌ not yet built — skip |
|
||||
| `@suaveplan/schema-registry` | ❌ not yet built — export Zod schemas directly |
|
||||
|
||||
External deps (via catalog):
|
||||
|
||||
- `zod` → `catalog:forms`
|
||||
- `@opentelemetry/api` → `catalog:observability`
|
||||
- `tslib` → `catalog:build`
|
||||
|
||||
Dev deps (via catalog):
|
||||
|
||||
- `vitest`, `@vitest/coverage-istanbul` → `catalog:testing`
|
||||
- `fast-check` → `catalog:testing`
|
||||
- `mitata` → `catalog:testing`
|
||||
|
||||
## Preserved public API surface (from main branch)
|
||||
|
||||
All of the following must be re-exported from the genesis build.
|
||||
|
||||
### Decay module (`src/decay/`)
|
||||
|
||||
- `createDecay(opts)` — returns a `Decay` instance with `.tick(elapsed)`, `.reset()`, `.value` getter
|
||||
- `DecayOptions`, `DecayFunction`, `Decay` (types)
|
||||
|
||||
### Scheduler module (`src/scheduler/`)
|
||||
|
||||
- `createScheduler(opts?)` — returns a `Scheduler` with `.schedule(fn, delay)`, `.cancel(id)`, `.drain(signal?)`, `.dispose()`
|
||||
- `SchedulerOptions`, `SchedulerHandle`, `Scheduler` (types)
|
||||
|
||||
### Stopwatch module (`src/stopwatch/`)
|
||||
|
||||
- `createStopwatch(opts?)` — returns a `Stopwatch` with `.start()`, `.stop()`, `.reset()`, `.lap()`, `.elapsed` getter, `.laps` getter
|
||||
- `StopwatchOptions`, `StopwatchLap`, `Stopwatch` (types)
|
||||
|
||||
### Throttle module (`src/throttle/`)
|
||||
|
||||
- `throttle(fn, wait, opts?)` — leading/trailing edge configurable
|
||||
- `debounce(fn, wait, opts?)` — with `.flush()` and `.cancel()` methods on the returned function
|
||||
- `ThrottleOptions`, `DebounceOptions`, `ThrottledFunction`, `DebouncedFunction` (types)
|
||||
|
||||
### Timer module (`src/timer/`)
|
||||
|
||||
- `createTimer(opts)` — interval-based with `.start()`, `.stop()`, `.reset()`, `.tick` event
|
||||
- `createCountdown(duration, opts?)` — countdown with `.start()`, `.pause()`, `.resume()`, `.stop()`, `.remaining` getter
|
||||
- `TimerOptions`, `CountdownOptions`, `Timer`, `Countdown` (types)
|
||||
|
||||
### Vector clock module (`src/vector-clock/`)
|
||||
|
||||
- `createVectorClock(nodeId, opts?)` — returns a `VectorClock` with `.increment()`, `.update(remote)`, `.compare(other)`, `.toJSON()`, `.fromJSON(raw)`
|
||||
- `vectorClockCompare(a, b)` → `'before' | 'after' | 'concurrent' | 'equal'`
|
||||
- `VectorClockOptions`, `VectorClockState`, `VectorClock` (types)
|
||||
|
||||
## New additions for genesis
|
||||
|
||||
### Structured errors
|
||||
|
||||
- `TimingError` extends `SuaveplanError` with codes under `TIMING.*` namespace
|
||||
- Codes: `TIMING.SCHEDULER.DISPOSED`, `TIMING.COUNTDOWN.INVALID_DURATION`, `TIMING.VECTOR_CLOCK.UNKNOWN_NODE`
|
||||
|
||||
### Zod schemas
|
||||
|
||||
- `SchedulerOptionsSchema`, `StopwatchOptionsSchema`, `TimerOptionsSchema`, `CountdownOptionsSchema`, `VectorClockOptionsSchema`
|
||||
|
||||
### Injectable clock
|
||||
|
||||
- All time-reading functions accept optional `{ clock?: Clock }` from `@suaveplan/types`
|
||||
- Scheduler and timer use injected clock for deterministic tests
|
||||
|
||||
### AbortSignal support
|
||||
|
||||
- `Scheduler.drain(signal?)`, `Countdown` start/pause all honour `AbortSignal`
|
||||
|
||||
### OTel instrumentation
|
||||
|
||||
- Histograms for stopwatch elapsed, scheduler queue depth; counters for timer ticks
|
||||
|
||||
### Property-based tests (fast-check)
|
||||
|
||||
- Vector-clock ordering: transitivity, anti-symmetry
|
||||
- Throttle: output count ≤ ceil(events / wait)
|
||||
- Decay: monotonically decreasing (or increasing) toward target
|
||||
|
||||
### Benchmarks (mitata)
|
||||
|
||||
- `throttle` 10 000 events at 16ms window
|
||||
- `createVectorClock` merge 1 000 nodes
|
||||
- `createScheduler` drain 1 000 tasks
|
||||
|
||||
## Impact
|
||||
|
||||
- Adds one new package: `packages/universal/timing`
|
||||
- Adds one new spec capability: `timing`
|
||||
- No existing package consumers on genesis yet
|
||||
Reference in New Issue
Block a user