4.6 KiB
4.6 KiB
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:observabilitytslib→catalog:build
Dev deps (via catalog):
vitest,@vitest/coverage-istanbul→catalog:testingfast-check→catalog:testingmitata→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 aDecayinstance with.tick(elapsed),.reset(),.valuegetterDecayOptions,DecayFunction,Decay(types)
Scheduler module (src/scheduler/)
createScheduler(opts?)— returns aSchedulerwith.schedule(fn, delay),.cancel(id),.drain(signal?),.dispose()SchedulerOptions,SchedulerHandle,Scheduler(types)
Stopwatch module (src/stopwatch/)
createStopwatch(opts?)— returns aStopwatchwith.start(),.stop(),.reset(),.lap(),.elapsedgetter,.lapsgetterStopwatchOptions,StopwatchLap,Stopwatch(types)
Throttle module (src/throttle/)
throttle(fn, wait, opts?)— leading/trailing edge configurabledebounce(fn, wait, opts?)— with.flush()and.cancel()methods on the returned functionThrottleOptions,DebounceOptions,ThrottledFunction,DebouncedFunction(types)
Timer module (src/timer/)
createTimer(opts)— interval-based with.start(),.stop(),.reset(),.tickeventcreateCountdown(duration, opts?)— countdown with.start(),.pause(),.resume(),.stop(),.remaininggetterTimerOptions,CountdownOptions,Timer,Countdown(types)
Vector clock module (src/vector-clock/)
createVectorClock(nodeId, opts?)— returns aVectorClockwith.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
TimingErrorextendsSuaveplanErrorwith codes underTIMING.*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?),Countdownstart/pause all honourAbortSignal
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)
throttle10 000 events at 16ms windowcreateVectorClockmerge 1 000 nodescreateSchedulerdrain 1 000 tasks
Impact
- Adds one new package:
packages/universal/timing - Adds one new spec capability:
timing - No existing package consumers on genesis yet