Files
suaveplan/openspec/archive/2026-04-19-enterprise-timing/proposal.md
2026-05-27 23:29:53 +01:00

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: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