UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

73 lines (67 loc) 1.75 kB
/** * App-facing time source. * * Use this port anywhere deterministic time matters, such as use-case tests, * scheduled work, idempotency windows, or audit timestamps. */ export interface ClockPort { /** * Return the current time according to this clock. */ now(): Date; } /** * Mutable clock implementation used by tests. */ export interface FrozenClockPort extends ClockPort { /** * Replace the current time. */ setNow(value: Date | string | number): void; /** * Move the current time forward by the given number of milliseconds. */ advance(milliseconds: number): void; } function toDate(value: Date | string | number): Date { return value instanceof Date ? new Date(value.getTime()) : new Date(value); } /** * Create a clock backed by `new Date()`. * * Use this as the default production `ClockPort` when the app does not need a * provider-specific time source. * * @returns A clock that reads the current system time. */ export function createSystemClock(): ClockPort { return { now: () => new Date(), }; } /** * Create a mutable clock for deterministic tests. * * @example * ```ts * const clock = createFrozenClock("2026-01-01T00:00:00.000Z"); * clock.advance(1000); * ``` * * @param initial - Initial time for the clock. Defaults to Unix epoch. * @returns A clock whose time can be replaced or advanced. */ export function createFrozenClock( initial: Date | string | number = new Date(0), ): FrozenClockPort { let current = toDate(initial); return { now: () => new Date(current.getTime()), setNow: (value) => { current = toDate(value); }, advance: (milliseconds) => { current = new Date(current.getTime() + milliseconds); }, }; }