No I/O, by design
The package reads no clock and generates no id. A factory's generators, not an internal crypto.randomUUID()/Date.now(), are how a domain-generated value reaches an entity.
The rule — which fields the domain owns, and that a caller may never supply them — lives in the declaration. The sources are bound once at your composition root. That keeps the entity pure, and lets a test bind fixed generators instead of stubbing globals.
Generators are functions, called once per create, so a factory built at startup still yields a fresh id per entity.
ts
// composition root
const createOrganization = Organization.factory({
id: () => ids.next(),
createdAt: () => clock.now(),
});
// a test — no global stubbing, no fake timers
const createFixed = Organization.factory({
id: () => FIXED_ID,
createdAt: () => FIXED_INSTANT,
});See factory / factoryAsync for the signatures, and Test domain logic for the testing pattern this enables.