@beignet/core
Version:
Core framework primitives for Beignet
74 lines (68 loc) • 1.91 kB
text/typescript
/**
* App-facing ID generation port.
*
* Use this when deterministic IDs matter in use-case tests or when production
* infrastructure owns ID generation.
*/
export interface IdGeneratorPort {
/**
* Return the next ID.
*/
nextId(): string;
}
/**
* Mutable sequential ID generator used by tests and simple examples.
*/
export interface SequenceIdGeneratorPort extends IdGeneratorPort {
/**
* Reset the next sequence value.
*/
reset(next?: number): void;
}
/**
* Create an ID generator backed by `globalThis.crypto.randomUUID()`.
*
* The factory itself does not read from `crypto`; the returned generator's
* `nextId()` method throws if the current runtime does not expose
* `globalThis.crypto.randomUUID()`.
*
* @returns An ID generator that returns UUID strings from `nextId()`.
*/
export function createUuidIdGenerator(): IdGeneratorPort {
return {
nextId: () => {
if (typeof globalThis.crypto?.randomUUID !== "function") {
throw new Error(
"createUuidIdGenerator requires globalThis.crypto.randomUUID(). Provide a custom IdGeneratorPort in this runtime.",
);
}
return globalThis.crypto.randomUUID();
},
};
}
/**
* Create a deterministic sequence ID generator for tests and examples.
*
* @example
* ```ts
* const ids = createSequenceIdGenerator({ prefix: "post", start: 10 });
* ids.nextId(); // "post_10"
* ids.nextId(); // "post_11"
* ```
*
* @param options - Optional ID prefix and starting sequence number.
* @returns A mutable sequence ID generator.
*/
export function createSequenceIdGenerator(
options: { prefix?: string; start?: number } = {},
): SequenceIdGeneratorPort {
const prefix = options.prefix ?? "id";
const start = options.start ?? 1;
let next = start;
return {
nextId: () => `${prefix}_${next++}`,
reset: (value = start) => {
next = value;
},
};
}