๐ณ
Tree-shakable
Your deterministic code is not bundled in production.
Inject time. Control it in tests.
Same ITimeProvider, same call sites. Only the strategy behind .create() changes between production and tests.
import { createTimeProvider } from "@time-provider/core";
import { plugin } from "@time-provider/plugin-native";
const timeProvider = createTimeProvider.for(plugin).create();
class UserService {
constructor(private readonly timeProvider: ITimeProvider<Date>) {}
createUser() {
return { createdAt: this.timeProvider.clock.utcNow() };
}
}import { createTimeProvider } from "@time-provider/core/deterministic";
import { plugin } from "@time-provider/plugin-native/deterministic";
using timeProvider = createTimeProvider
.for(plugin)
.asManual()
.withInitialTime("2026-01-01T00:00:00.000Z")
.create();
let retries = 0;
using handle = timeProvider.scheduler.timers.every({seconds: 1}, () => retries++);
timeProvider.clock.advance({ seconds: 3 });
expect(retries).toBe(3); // synchronous โ no await, no real timers