@typed/id 1.0.0-beta.3 → 1.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +171 -65
  2. package/dist/Cuid.d.ts +128 -13
  3. package/dist/Cuid.d.ts.map +1 -1
  4. package/dist/Cuid.js +135 -41
  5. package/dist/DateTimes.d.ts +66 -3
  6. package/dist/DateTimes.d.ts.map +1 -1
  7. package/dist/DateTimes.js +72 -5
  8. package/dist/Ids.d.ts +173 -30
  9. package/dist/Ids.d.ts.map +1 -1
  10. package/dist/Ids.js +162 -19
  11. package/dist/Ksuid.d.ts +51 -1
  12. package/dist/Ksuid.d.ts.map +1 -1
  13. package/dist/Ksuid.js +59 -7
  14. package/dist/NanoId.d.ts +47 -0
  15. package/dist/NanoId.d.ts.map +1 -1
  16. package/dist/NanoId.js +48 -1
  17. package/dist/RandomValues.d.ts +63 -4
  18. package/dist/RandomValues.d.ts.map +1 -1
  19. package/dist/RandomValues.js +74 -10
  20. package/dist/Ulid.d.ts +49 -1
  21. package/dist/Ulid.d.ts.map +1 -1
  22. package/dist/Ulid.js +54 -4
  23. package/dist/Uuid4.d.ts +47 -0
  24. package/dist/Uuid4.d.ts.map +1 -1
  25. package/dist/Uuid4.js +48 -1
  26. package/dist/Uuid5.d.ts +178 -6
  27. package/dist/Uuid5.d.ts.map +1 -1
  28. package/dist/Uuid5.js +152 -15
  29. package/dist/Uuid7.d.ts +121 -15
  30. package/dist/Uuid7.d.ts.map +1 -1
  31. package/dist/Uuid7.js +124 -16
  32. package/dist/__tests__/helpers.d.ts +7 -0
  33. package/dist/__tests__/helpers.d.ts.map +1 -0
  34. package/dist/__tests__/helpers.js +19 -0
  35. package/dist/__tests__/public-contract.type-test.d.ts +2 -0
  36. package/dist/__tests__/public-contract.type-test.d.ts.map +1 -0
  37. package/dist/__tests__/public-contract.type-test.js +3 -0
  38. package/dist/_sha.d.ts +32 -0
  39. package/dist/_sha.d.ts.map +1 -1
  40. package/dist/_sha.js +32 -0
  41. package/dist/_uuid-stringify.d.ts +15 -0
  42. package/dist/_uuid-stringify.d.ts.map +1 -1
  43. package/dist/_uuid-stringify.js +15 -0
  44. package/package.json +65 -11
  45. package/src/Cuid.ts +0 -124
  46. package/src/DateTimes.ts +0 -36
  47. package/src/Id.test.ts +0 -230
  48. package/src/Ids.ts +0 -128
  49. package/src/Ksuid.ts +0 -74
  50. package/src/NanoId.ts +0 -33
  51. package/src/RandomValues.ts +0 -33
  52. package/src/Ulid.ts +0 -51
  53. package/src/Uuid4.ts +0 -24
  54. package/src/Uuid5.ts +0 -71
  55. package/src/Uuid7.ts +0 -104
  56. package/src/_sha.ts +0 -11
  57. package/src/_uuid-stringify.ts +0 -30
  58. package/src/index.ts +0 -10
@@ -1,19 +1,83 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Layer from "effect/Layer";
3
3
  import * as Random from "effect/Random";
4
- import * as ServiceMap from "effect/ServiceMap";
5
- export class RandomValues extends ServiceMap.Service()("@typed/id/RandomValues", {
6
- make: Effect.succeed((length) => Effect.sync(() => crypto.getRandomValues(new Uint8Array(length)))),
4
+ import * as Context from "effect/Context";
5
+ const allocate = (length, fill) => {
6
+ const view = new Uint8Array(length);
7
+ fill(view);
8
+ return view;
9
+ };
10
+ const fillFromWebCrypto = (view) => {
11
+ const webCrypto = globalThis.crypto;
12
+ if (typeof webCrypto?.getRandomValues !== "function") {
13
+ throw new TypeError("RandomValues.Default requires globalThis.crypto.getRandomValues. Provide RandomValues.Random or a custom RandomValues service for unsupported runtimes.");
14
+ }
15
+ void webCrypto.getRandomValues(view);
16
+ };
17
+ const fromRandom = (random) => RandomValues.of((length) => Effect.sync(() => allocate(length, (view) => {
18
+ for (let i = 0; i < length; ++i)
19
+ view[i] = random.nextIntUnsafe();
20
+ })));
21
+ /**
22
+ * Effect service that produces fresh byte arrays of an exact requested length.
23
+ * @remarks
24
+ * ## Why
25
+ * Entropy is an explicit dependency so secure production generation and reproducible tests use the same typed generator APIs.
26
+ * `RandomValues.Default` requires `globalThis.crypto.getRandomValues`; an unavailable implementation or thrown platform error is an Effect defect because the service's typed error channel is `never`.
27
+ * ## Ownership and lifetime
28
+ * A Layer owns the entropy source; every call allocates and transfers ownership of a fresh mutable byte array to the caller.
29
+ * @example
30
+ * ```ts
31
+ * import { RandomValues } from "@typed/id/RandomValues"
32
+ * import { Effect } from "effect"
33
+ * const bytes = Effect.provide(RandomValues.call(16), RandomValues.Default)
34
+ * ```
35
+ * @category Services
36
+ * @since 1.0.0
37
+ */
38
+ export class RandomValues extends Context.Service()("@typed/id/RandomValues", {
39
+ make: Effect.succeed((length) => Effect.sync(() => allocate(length, fillFromWebCrypto))),
7
40
  }) {
8
- static call = (length) => RandomValues.asEffect().pipe(Effect.flatMap((randomValues) => randomValues(length)));
41
+ /**
42
+ * Requests a fresh byte array from the current RandomValues service.
43
+ * @remarks
44
+ * ## Why
45
+ * The static call preserves literal length in the type while keeping the entropy source in Effect's service channel.
46
+ * ## Ownership and lifetime
47
+ * Each invocation allocates a new buffer owned by the caller and acquires no persistent resource.
48
+ * @example
49
+ * ```ts
50
+ * import { RandomValues } from "@typed/id/RandomValues"
51
+ * import { Effect } from "effect"
52
+ * const bytes = RandomValues.call(32).pipe(Effect.provide(RandomValues.Default))
53
+ * ```
54
+ * @category Services
55
+ * @since 1.0.0
56
+ */
57
+ static call = (length) => RandomValues.pipe(Effect.flatMap((randomValues) => randomValues(length)));
58
+ /**
59
+ * Provides cryptographic bytes from `globalThis.crypto.getRandomValues`.
60
+ * @remarks
61
+ * ## Why
62
+ * Production IDs need platform entropy. Missing `globalThis.crypto.getRandomValues` and platform exceptions are Effect defects, not typed errors, rather than silently weakening randomness.
63
+ * ## Ownership and lifetime
64
+ * The Layer owns no mutable generator state; each request returns a fresh buffer. The runtime must provide Web Crypto or the request defects.
65
+ * @category Layers
66
+ * @since 1.0.0
67
+ */
9
68
  static Default = Layer.effect(RandomValues, RandomValues.make);
69
+ /**
70
+ * Provides reproducible bytes from Effect Random.
71
+ * @remarks
72
+ * ## Why
73
+ * Deterministic tests and simulations need replaceable entropy; this Layer is not cryptographically secure.
74
+ * ## Ownership and lifetime
75
+ * The provided Effect Random service owns sequence state for the Layer lifetime; each request returns a fresh buffer.
76
+ * @category Layers
77
+ * @since 1.0.0
78
+ */
10
79
  static Random = Layer.effect(RandomValues, Effect.gen(function* () {
11
80
  const random = yield* Random.Random;
12
- return RandomValues.of((length) => Effect.sync(() => {
13
- const view = new Uint8Array(length);
14
- for (let i = 0; i < length; ++i)
15
- view[i] = random.nextIntUnsafe();
16
- return view;
17
- }));
81
+ return fromRandom(random);
18
82
  }));
19
83
  }
package/dist/Ulid.d.ts CHANGED
@@ -1,9 +1,57 @@
1
+ import * as Cause from "effect/Cause";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Schema from "effect/Schema";
3
4
  import { DateTimes } from "./DateTimes.js";
4
5
  import { RandomValues } from "./RandomValues.js";
6
+ /**
7
+ * Effect Schema and branded string type for canonical ULID values.
8
+ * @remarks
9
+ * ## Why
10
+ * The schema validates values at transport boundaries; encoded time does not imply a total order across independent generators.
11
+ * ## Ownership and lifetime
12
+ * This module-level schema value acquires no resources and is shared; no runtime freezing guarantee is implied.
13
+ * @example
14
+ * ```ts
15
+ * import { Ulid } from "@typed/id/Ulid"
16
+ * const id = Ulid.make("01ARZ3NDEKTSV4RRFFQ69G5FAV")
17
+ * ```
18
+ * @category Schemas
19
+ * @since 1.0.0
20
+ */
5
21
  export declare const Ulid: Schema.brand<Schema.String, "@typed/id/ULID">;
6
22
  export type Ulid = typeof Ulid.Type;
23
+ /**
24
+ * Tests whether a string is a canonical ULID.
25
+ * @remarks
26
+ * ## Why
27
+ * Runtime refinement restores trust after serialization has erased the TypeScript brand.
28
+ * ## Ownership and lifetime
29
+ * This pure predicate acquires no resources and retains no input.
30
+ * @example
31
+ * ```ts
32
+ * import { isUlid } from "@typed/id/Ulid"
33
+ * isUlid("01ARZ3NDEKTSV4RRFFQ69G5FAV")
34
+ * ```
35
+ * @category Refinements
36
+ * @since 1.0.0
37
+ */
7
38
  export declare const isUlid: (value: string) => value is Ulid;
8
- export declare const ulid: Effect.Effect<Ulid, never, RandomValues | DateTimes>;
39
+ /**
40
+ * Generates a ULID from the current millisecond time and random bytes.
41
+ * @remarks
42
+ * ## Why
43
+ * Time and entropy remain explicit services; unsafe, negative, or out-of-range 48-bit timestamps fail with `IllegalArgumentError`.
44
+ * ## Ownership and lifetime
45
+ * The Effect acquires no persistent resources and uses DateTimes and RandomValues only for the invocation.
46
+ * @example
47
+ * ```ts
48
+ * import { ulid } from "@typed/id/Ulid"
49
+ * import { Ids } from "@typed/id/Ids"
50
+ * import { Effect } from "effect"
51
+ * const id = Effect.provide(ulid, Ids.Default)
52
+ * ```
53
+ * @category Generators
54
+ * @since 1.0.0
55
+ */
56
+ export declare const ulid: Effect.Effect<Ulid, Cause.IllegalArgumentError, RandomValues | DateTimes>;
9
57
  //# sourceMappingURL=Ulid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Ulid.d.ts","sourceRoot":"","sources":["../src/Ulid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,IAAI,+CAGhB,CAAC;AACF,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC;AAEpC,eAAO,MAAM,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,IAAsB,CAAC;AAWxE,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS,CAUrE,CAAC"}
1
+ {"version":3,"file":"Ulid.d.ts","sourceRoot":"","sources":["../src/Ulid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,+CAGhB,CAAC;AACF,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC;AAEpC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,IAAsB,CAAC;AAWxE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,oBAAoB,EAAE,YAAY,GAAG,SAAS,CAWvF,CAAC"}
package/dist/Ulid.js CHANGED
@@ -1,8 +1,39 @@
1
+ import * as Cause from "effect/Cause";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Schema from "effect/Schema";
3
4
  import { DateTimes } from "./DateTimes.js";
4
5
  import { RandomValues } from "./RandomValues.js";
6
+ /**
7
+ * Effect Schema and branded string type for canonical ULID values.
8
+ * @remarks
9
+ * ## Why
10
+ * The schema validates values at transport boundaries; encoded time does not imply a total order across independent generators.
11
+ * ## Ownership and lifetime
12
+ * This module-level schema value acquires no resources and is shared; no runtime freezing guarantee is implied.
13
+ * @example
14
+ * ```ts
15
+ * import { Ulid } from "@typed/id/Ulid"
16
+ * const id = Ulid.make("01ARZ3NDEKTSV4RRFFQ69G5FAV")
17
+ * ```
18
+ * @category Schemas
19
+ * @since 1.0.0
20
+ */
5
21
  export const Ulid = Schema.String.pipe(Schema.check(Schema.isULID()), Schema.brand("@typed/id/ULID"));
22
+ /**
23
+ * Tests whether a string is a canonical ULID.
24
+ * @remarks
25
+ * ## Why
26
+ * Runtime refinement restores trust after serialization has erased the TypeScript brand.
27
+ * ## Ownership and lifetime
28
+ * This pure predicate acquires no resources and retains no input.
29
+ * @example
30
+ * ```ts
31
+ * import { isUlid } from "@typed/id/Ulid"
32
+ * isUlid("01ARZ3NDEKTSV4RRFFQ69G5FAV")
33
+ * ```
34
+ * @category Refinements
35
+ * @since 1.0.0
36
+ */
6
37
  export const isUlid = Schema.is(Ulid);
7
38
  // Crockford's Base32
8
39
  const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
@@ -10,11 +41,30 @@ const ENCODING_LEN = ENCODING.length;
10
41
  const TIME_MAX = 2 ** 48 - 1;
11
42
  const TIME_LEN = 10;
12
43
  const RANDOM_LEN = 16;
13
- export const ulid = Effect.zipWith(DateTimes.now, RandomValues.call(16), (now, seed) => {
14
- if (now > TIME_MAX) {
15
- throw new Error("Cannot generate ULID due to timestamp overflow");
44
+ /**
45
+ * Generates a ULID from the current millisecond time and random bytes.
46
+ * @remarks
47
+ * ## Why
48
+ * Time and entropy remain explicit services; unsafe, negative, or out-of-range 48-bit timestamps fail with `IllegalArgumentError`.
49
+ * ## Ownership and lifetime
50
+ * The Effect acquires no persistent resources and uses DateTimes and RandomValues only for the invocation.
51
+ * @example
52
+ * ```ts
53
+ * import { ulid } from "@typed/id/Ulid"
54
+ * import { Ids } from "@typed/id/Ids"
55
+ * import { Effect } from "effect"
56
+ * const id = Effect.provide(ulid, Ids.Default)
57
+ * ```
58
+ * @category Generators
59
+ * @since 1.0.0
60
+ */
61
+ export const ulid = Effect.gen(function* () {
62
+ const now = yield* DateTimes.now;
63
+ if (!Number.isSafeInteger(now) || now < 0 || now > TIME_MAX) {
64
+ return yield* new Cause.IllegalArgumentError(`ULID timestamp must be a safe integer between 0 and ${TIME_MAX}, received ${now}`);
16
65
  }
17
- return Ulid.makeUnsafe(encodeTime(now, TIME_LEN) + encodeRandom(seed));
66
+ const seed = yield* RandomValues.call(16);
67
+ return Ulid.make(encodeTime(now, TIME_LEN) + encodeRandom(seed));
18
68
  });
19
69
  function encodeTime(now, len) {
20
70
  let str = "";
package/dist/Uuid4.d.ts CHANGED
@@ -1,8 +1,55 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Schema from "effect/Schema";
3
3
  import { RandomValues } from "./RandomValues.js";
4
+ /**
5
+ * Effect Schema and branded string type for RFC UUID version 4 values.
6
+ * @remarks
7
+ * ## Why
8
+ * The schema verifies version and variant bits before restoring the compile-time brand after transport.
9
+ * ## Ownership and lifetime
10
+ * This module-level schema value acquires no resources and is shared; no runtime freezing guarantee is implied.
11
+ * @example
12
+ * ```ts
13
+ * import { Uuid4 } from "@typed/id/Uuid4"
14
+ * const id = Uuid4.make("550e8400-e29b-41d4-a716-446655440000")
15
+ * ```
16
+ * @category Schemas
17
+ * @since 1.0.0
18
+ */
4
19
  export declare const Uuid4: Schema.brand<Schema.String, "@typed/id/UUID4">;
5
20
  export type Uuid4 = typeof Uuid4.Type;
21
+ /**
22
+ * Tests whether a string is an RFC UUID version 4 value.
23
+ * @remarks
24
+ * ## Why
25
+ * Runtime refinement restores trust after serialization has erased the TypeScript brand.
26
+ * ## Ownership and lifetime
27
+ * This pure predicate acquires no resources and retains no input.
28
+ * @example
29
+ * ```ts
30
+ * import { isUuid4 } from "@typed/id/Uuid4"
31
+ * isUuid4("550e8400-e29b-41d4-a716-446655440000")
32
+ * ```
33
+ * @category Refinements
34
+ * @since 1.0.0
35
+ */
6
36
  export declare const isUuid4: (value: string) => value is Uuid4;
37
+ /**
38
+ * Generates an RFC UUID version 4 from 16 fresh random bytes.
39
+ * @remarks
40
+ * ## Why
41
+ * Effectful generation exposes entropy as a service and explicitly sets version and variant bits; custom services must return a usable fresh buffer.
42
+ * ## Ownership and lifetime
43
+ * The invocation mutates only its fresh byte buffer, acquires no persistent resource, and returns an immutable string.
44
+ * @example
45
+ * ```ts
46
+ * import { uuid4 } from "@typed/id/Uuid4"
47
+ * import { RandomValues } from "@typed/id/RandomValues"
48
+ * import { Effect } from "effect"
49
+ * const id = Effect.provide(uuid4, RandomValues.Default)
50
+ * ```
51
+ * @category Generators
52
+ * @since 1.0.0
53
+ */
7
54
  export declare const uuid4: Effect.Effect<Uuid4, never, RandomValues>;
8
55
  //# sourceMappingURL=Uuid4.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Uuid4.d.ts","sourceRoot":"","sources":["../src/Uuid4.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,KAAK,gDAGjB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC,eAAO,MAAM,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,KAAwB,CAAC;AAI3E,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAQ3D,CAAC"}
1
+ {"version":3,"file":"Uuid4.d.ts","sourceRoot":"","sources":["../src/Uuid4.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK,gDAGjB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,KAAwB,CAAC;AAI3E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAQ3D,CAAC"}
package/dist/Uuid4.js CHANGED
@@ -2,11 +2,58 @@ import * as Effect from "effect/Effect";
2
2
  import * as Schema from "effect/Schema";
3
3
  import { uuidStringify } from "./_uuid-stringify.js";
4
4
  import { RandomValues } from "./RandomValues.js";
5
+ /**
6
+ * Effect Schema and branded string type for RFC UUID version 4 values.
7
+ * @remarks
8
+ * ## Why
9
+ * The schema verifies version and variant bits before restoring the compile-time brand after transport.
10
+ * ## Ownership and lifetime
11
+ * This module-level schema value acquires no resources and is shared; no runtime freezing guarantee is implied.
12
+ * @example
13
+ * ```ts
14
+ * import { Uuid4 } from "@typed/id/Uuid4"
15
+ * const id = Uuid4.make("550e8400-e29b-41d4-a716-446655440000")
16
+ * ```
17
+ * @category Schemas
18
+ * @since 1.0.0
19
+ */
5
20
  export const Uuid4 = Schema.String.pipe(Schema.check(Schema.isUUID(4)), Schema.brand("@typed/id/UUID4"));
21
+ /**
22
+ * Tests whether a string is an RFC UUID version 4 value.
23
+ * @remarks
24
+ * ## Why
25
+ * Runtime refinement restores trust after serialization has erased the TypeScript brand.
26
+ * ## Ownership and lifetime
27
+ * This pure predicate acquires no resources and retains no input.
28
+ * @example
29
+ * ```ts
30
+ * import { isUuid4 } from "@typed/id/Uuid4"
31
+ * isUuid4("550e8400-e29b-41d4-a716-446655440000")
32
+ * ```
33
+ * @category Refinements
34
+ * @since 1.0.0
35
+ */
6
36
  export const isUuid4 = Schema.is(Uuid4);
37
+ /**
38
+ * Generates an RFC UUID version 4 from 16 fresh random bytes.
39
+ * @remarks
40
+ * ## Why
41
+ * Effectful generation exposes entropy as a service and explicitly sets version and variant bits; custom services must return a usable fresh buffer.
42
+ * ## Ownership and lifetime
43
+ * The invocation mutates only its fresh byte buffer, acquires no persistent resource, and returns an immutable string.
44
+ * @example
45
+ * ```ts
46
+ * import { uuid4 } from "@typed/id/Uuid4"
47
+ * import { RandomValues } from "@typed/id/RandomValues"
48
+ * import { Effect } from "effect"
49
+ * const id = Effect.provide(uuid4, RandomValues.Default)
50
+ * ```
51
+ * @category Generators
52
+ * @since 1.0.0
53
+ */
7
54
  export const uuid4 = Effect.map(RandomValues.call(16), (seed) => {
8
55
  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
9
56
  seed[6] = (seed[6] & 0x0f) | 0x40;
10
57
  seed[8] = (seed[8] & 0x3f) | 0x80;
11
- return Uuid4.makeUnsafe(uuidStringify(seed));
58
+ return Uuid4.make(uuidStringify(seed));
12
59
  });
package/dist/Uuid5.d.ts CHANGED
@@ -1,21 +1,193 @@
1
+ import * as Cause from "effect/Cause";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Schema from "effect/Schema";
4
+ /**
5
+ * Effect Schema and branded string type for RFC UUID version 5 values.
6
+ * @remarks
7
+ * ## Why
8
+ * The schema verifies UUID version and variant at transport boundaries before restoring the compile-time brand.
9
+ * ## Ownership and lifetime
10
+ * This module-level schema value acquires no resources and is shared; no runtime freezing guarantee is implied.
11
+ * @example
12
+ * ```ts
13
+ * import { Uuid5 } from "@typed/id/Uuid5"
14
+ * import { Schema } from "effect"
15
+ * const id = Schema.decodeUnknownSync(Uuid5)("21f7f8de-8051-5b89-8680-0195ef798b6a")
16
+ * ```
17
+ * @category Schemas
18
+ * @since 1.0.0
19
+ */
3
20
  export declare const Uuid5: Schema.brand<Schema.String, "@typed/id/UUID5">;
4
21
  export type Uuid5 = typeof Uuid5.Type;
22
+ /**
23
+ * Tests whether a string is an RFC UUID version 5 value.
24
+ * @remarks
25
+ * ## Why
26
+ * Runtime refinement restores trust after serialization has erased the TypeScript brand.
27
+ * ## Ownership and lifetime
28
+ * This pure predicate acquires no resources and retains no input.
29
+ * @example
30
+ * ```ts
31
+ * import { isUuid5 } from "@typed/id/Uuid5"
32
+ * isUuid5("21f7f8de-8051-5b89-8680-0195ef798b6a")
33
+ * ```
34
+ * @category Refinements
35
+ * @since 1.0.0
36
+ */
5
37
  export declare const isUuid5: (value: string) => value is Uuid5;
38
+ /**
39
+ * The exact 16 namespace bytes used in UUID version 5 hashing.
40
+ * @remarks
41
+ * ## Why
42
+ * Namespace bytes are part of deterministic identity; caller canonicalization of names and namespace selection must remain explicit.
43
+ * ## Ownership and lifetime
44
+ * This type acquires no resources. Callers own and may mutate their byte array; generation reads exactly 16 bytes.
45
+ * @category Models
46
+ * @since 1.0.0
47
+ */
6
48
  export type Uuid5Namespace = Uint8Array;
49
+ /**
50
+ * Standard RFC UUID version 5 namespaces, returned as fresh mutable copies.
51
+ * @remarks
52
+ * ## Why
53
+ * Copy-on-access protects canonical constants while allowing callers to own and safely modify their selected namespace bytes.
54
+ * ## Ownership and lifetime
55
+ * The module owns canonical bytes for its lifetime; every property access transfers a fresh 16-byte copy to the caller.
56
+ * @example
57
+ * ```ts
58
+ * import { Uuid5Namespace } from "@typed/id/Uuid5"
59
+ * const namespace = Uuid5Namespace.DNS
60
+ * ```
61
+ * @category Namespaces
62
+ * @since 1.0.0
63
+ */
7
64
  export declare const Uuid5Namespace: {
65
+ /**
66
+ * Returns a fresh copy of the RFC DNS namespace bytes.
67
+ * @remarks
68
+ * ## Why
69
+ * DNS names need a stable namespace distinct from URLs, OIDs, and X.500 names.
70
+ * ## Ownership and lifetime
71
+ * Each access allocates a mutable byte array owned by the caller.
72
+ * @category Namespaces
73
+ * @since 1.0.0
74
+ */
8
75
  readonly DNS: Uint8Array<ArrayBuffer>;
76
+ /**
77
+ * Returns a fresh copy of the RFC URL namespace bytes.
78
+ * @remarks
79
+ * ## Why
80
+ * URL names need a stable namespace distinct from DNS, OID, and X.500 names.
81
+ * ## Ownership and lifetime
82
+ * Each access allocates a mutable byte array owned by the caller.
83
+ * @category Namespaces
84
+ * @since 1.0.0
85
+ */
9
86
  readonly URL: Uint8Array<ArrayBuffer>;
87
+ /**
88
+ * Returns a fresh copy of the RFC OID namespace bytes.
89
+ * @remarks
90
+ * ## Why
91
+ * Object identifiers need a stable namespace distinct from DNS, URL, and X.500 names.
92
+ * ## Ownership and lifetime
93
+ * Each access allocates a mutable byte array owned by the caller.
94
+ * @category Namespaces
95
+ * @since 1.0.0
96
+ */
10
97
  readonly OID: Uint8Array<ArrayBuffer>;
98
+ /**
99
+ * Returns a fresh copy of the RFC X.500 namespace bytes.
100
+ * @remarks
101
+ * ## Why
102
+ * X.500 names need a stable namespace distinct from DNS, URL, and OID names.
103
+ * ## Ownership and lifetime
104
+ * Each access allocates a mutable byte array owned by the caller.
105
+ * @category Namespaces
106
+ * @since 1.0.0
107
+ */
11
108
  readonly X500: Uint8Array<ArrayBuffer>;
12
109
  };
110
+ /**
111
+ * Derives a deterministic UUID version 5 from a UTF-8 name and 16-byte namespace.
112
+ * @remarks
113
+ * ## Why
114
+ * Determinism is exact for the same name bytes and namespace. Invalid namespace length fails in the typed channel with `IllegalArgumentError`; missing Web Crypto or a rejected SHA-1 digest is an Effect defect, not a typed error.
115
+ * ## Ownership and lifetime
116
+ * Each Effect acquires no persistent resources, reads but does not retain the namespace, and uses Web Crypto `subtle.digest` for the invocation.
117
+ * @example
118
+ * ```ts
119
+ * import { uuid5, Uuid5Namespace } from "@typed/id/Uuid5"
120
+ * const id = uuid5("example.com", Uuid5Namespace.DNS)
121
+ * ```
122
+ * @category Generators
123
+ * @since 1.0.0
124
+ */
13
125
  export declare const uuid5: {
14
- (namespace: Uuid5Namespace): (name: string) => Effect.Effect<Uuid5>;
15
- (name: string, namespace: Uuid5Namespace): Effect.Effect<Uuid5>;
126
+ (namespace: Uuid5Namespace): (name: string) => Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
127
+ (name: string, namespace: Uuid5Namespace): Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
16
128
  };
17
- export declare const dnsUuid5: (name: string) => Effect.Effect<Uuid5>;
18
- export declare const urlUuid5: (name: string) => Effect.Effect<Uuid5>;
19
- export declare const oidUuid5: (name: string) => Effect.Effect<Uuid5>;
20
- export declare const x500Uuid5: (name: string) => Effect.Effect<Uuid5>;
129
+ /**
130
+ * Derives deterministic UUID version 5 values in the standard DNS namespace.
131
+ * @remarks
132
+ * ## Why
133
+ * The pre-bound helper prevents accidental namespace selection drift for DNS identities.
134
+ * ## Ownership and lifetime
135
+ * This function acquires no persistent resources and uses a captured namespace copy for module lifetime.
136
+ * @example
137
+ * ```ts
138
+ * import { dnsUuid5 } from "@typed/id/Uuid5"
139
+ * const id = dnsUuid5("example.com")
140
+ * ```
141
+ * @category Generators
142
+ * @since 1.0.0
143
+ */
144
+ export declare const dnsUuid5: (name: string) => Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
145
+ /**
146
+ * Derives deterministic UUID version 5 values in the standard URL namespace.
147
+ * @remarks
148
+ * ## Why
149
+ * The pre-bound helper prevents accidental namespace selection drift for URL identities.
150
+ * ## Ownership and lifetime
151
+ * This function acquires no persistent resources and uses a captured namespace copy for module lifetime.
152
+ * @example
153
+ * ```ts
154
+ * import { urlUuid5 } from "@typed/id/Uuid5"
155
+ * const id = urlUuid5("https://example.com")
156
+ * ```
157
+ * @category Generators
158
+ * @since 1.0.0
159
+ */
160
+ export declare const urlUuid5: (name: string) => Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
161
+ /**
162
+ * Derives deterministic UUID version 5 values in the standard OID namespace.
163
+ * @remarks
164
+ * ## Why
165
+ * The pre-bound helper prevents accidental namespace selection drift for object identifiers.
166
+ * ## Ownership and lifetime
167
+ * This function acquires no persistent resources and uses a captured namespace copy for module lifetime.
168
+ * @example
169
+ * ```ts
170
+ * import { oidUuid5 } from "@typed/id/Uuid5"
171
+ * const id = oidUuid5("1.3.6.1.4.1")
172
+ * ```
173
+ * @category Generators
174
+ * @since 1.0.0
175
+ */
176
+ export declare const oidUuid5: (name: string) => Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
177
+ /**
178
+ * Derives deterministic UUID version 5 values in the standard X.500 namespace.
179
+ * @remarks
180
+ * ## Why
181
+ * The pre-bound helper prevents accidental namespace selection drift for X.500 identities.
182
+ * ## Ownership and lifetime
183
+ * This function acquires no persistent resources and uses a captured namespace copy for module lifetime.
184
+ * @example
185
+ * ```ts
186
+ * import { x500Uuid5 } from "@typed/id/Uuid5"
187
+ * const id = x500Uuid5("CN=example")
188
+ * ```
189
+ * @category Generators
190
+ * @since 1.0.0
191
+ */
192
+ export declare const x500Uuid5: (name: string) => Effect.Effect<Uuid5, Cause.IllegalArgumentError>;
21
193
  //# sourceMappingURL=Uuid5.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Uuid5.d.ts","sourceRoot":"","sources":["../src/Uuid5.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,eAAO,MAAM,KAAK,gDAGjB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC,eAAO,MAAM,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,KAAwB,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC;AAKxC,eAAO,MAAM,cAAc;;;;;CAgBjB,CAAC;AAEX,eAAO,MAAM,KAAK,EAAE;IAClB,CAAC,SAAS,EAAE,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;CA0BhE,CAAC;AAEH,eAAO,MAAM,QAAQ,SA7BiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CA6BnB,CAAC;AAClD,eAAO,MAAM,QAAQ,SA9BiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CA8BnB,CAAC;AAClD,eAAO,MAAM,QAAQ,SA/BiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CA+BnB,CAAC;AAClD,eAAO,MAAM,SAAS,SAhCgB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAgCjB,CAAC"}
1
+ {"version":3,"file":"Uuid5.d.ts","sourceRoot":"","sources":["../src/Uuid5.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,KAAK,gDAGjB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,KAAwB,CAAC;AAE3E;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC;AAkBxC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,EAAE;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;CAcvC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK,EAAE;IAClB,CAAC,SAAS,EAAE,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAChG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;CAmC5F,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,SArDiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAqD/C,CAAC;AAClD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,SArEiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAqE/C,CAAC;AAClD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,SArFiB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAqF/C,CAAC;AAClD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,SArGgB,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAqG7C,CAAC"}