uniku 0.3.0 → 0.3.2

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 (52) hide show
  1. package/build/cuid2/cuid2.d.mts +5 -5
  2. package/build/cuid2/cuid2.d.mts.map +1 -1
  3. package/build/cuid2/cuid2.mjs +1 -1
  4. package/build/cuid2/cuid2.mjs.map +1 -1
  5. package/build/ksuid/ksuid.d.mts +6 -6
  6. package/build/ksuid/ksuid.d.mts.map +1 -1
  7. package/build/ksuid/ksuid.mjs +1 -1
  8. package/build/ksuid/ksuid.mjs.map +1 -1
  9. package/build/nanoid/nanoid.d.mts +2 -2
  10. package/build/nanoid/nanoid.mjs.map +1 -1
  11. package/build/objectid/objectid.d.mts +6 -6
  12. package/build/objectid/objectid.d.mts.map +1 -1
  13. package/build/objectid/objectid.mjs +1 -1
  14. package/build/objectid/objectid.mjs.map +1 -1
  15. package/build/tsid/tsid.d.mts +8 -8
  16. package/build/tsid/tsid.d.mts.map +1 -1
  17. package/build/tsid/tsid.mjs +1 -1
  18. package/build/tsid/tsid.mjs.map +1 -1
  19. package/build/typeid/typeid.d.mts +8 -8
  20. package/build/typeid/typeid.d.mts.map +1 -1
  21. package/build/typeid/typeid.mjs.map +1 -1
  22. package/build/ulid/ulid.d.mts +10 -6
  23. package/build/ulid/ulid.d.mts.map +1 -1
  24. package/build/ulid/ulid.mjs +1 -1
  25. package/build/ulid/ulid.mjs.map +1 -1
  26. package/build/uuid/v4.d.mts +5 -6
  27. package/build/uuid/v4.d.mts.map +1 -1
  28. package/build/uuid/v4.mjs +1 -1
  29. package/build/uuid/v4.mjs.map +1 -1
  30. package/build/uuid/v7.d.mts +13 -6
  31. package/build/uuid/v7.d.mts.map +1 -1
  32. package/build/uuid/v7.mjs +1 -1
  33. package/build/uuid/v7.mjs.map +1 -1
  34. package/build/uuid-CnQIYoQi.mjs +2 -0
  35. package/build/uuid-CnQIYoQi.mjs.map +1 -0
  36. package/build/validation-CTNpXm94.mjs +2 -0
  37. package/build/validation-CTNpXm94.mjs.map +1 -0
  38. package/package.json +1 -1
  39. package/src/common/validation.ts +7 -0
  40. package/src/cuid2/cuid2.ts +13 -7
  41. package/src/ksuid/ksuid.ts +26 -17
  42. package/src/nanoid/nanoid.ts +3 -3
  43. package/src/objectid/objectid.ts +32 -17
  44. package/src/tsid/tsid.ts +92 -53
  45. package/src/typeid/typeid.ts +9 -0
  46. package/src/ulid/crockford.ts +2 -2
  47. package/src/ulid/ulid.ts +46 -24
  48. package/src/uuid/common/uuid.ts +12 -1
  49. package/src/uuid/v4.ts +31 -28
  50. package/src/uuid/v7.ts +86 -47
  51. package/build/uuid-BBjwHv7J.mjs +0 -2
  52. package/build/uuid-BBjwHv7J.mjs.map +0 -1
package/src/uuid/v4.ts CHANGED
@@ -1,23 +1,31 @@
1
1
  import { rng } from '../common/random'
2
+ import { isWritableRange } from '../common/validation'
2
3
  import { BufferError, InvalidInputError } from '../errors'
3
- import { formatUuid, parseUuid } from './common/uuid'
4
+ import { formatUuid, formatUuidUnchecked, parseUuid } from './common/uuid'
4
5
 
5
6
  const randomUUID = /*@__PURE__*/ globalThis.crypto.randomUUID.bind(globalThis.crypto)
7
+ const UUID_BYTES = 16
8
+ const reusableBuf = new Uint8Array(UUID_BYTES)
6
9
 
7
10
  export type UuidV4Options = {
8
11
  /**
9
12
  * 16 bytes of random data to use for UUID generation.
10
- * Note: Bytes at index 6 and 8 will be modified in-place to set version/variant bits.
11
13
  */
12
14
  random?: Uint8Array
13
15
  }
14
16
 
15
17
  export type UuidV4 = {
18
+ /** Generate a random UUID v4 string. */
16
19
  (): string
20
+ /** Generate a UUID v4 with explicit options or write its 16 canonical bytes into a caller-owned buffer. */
17
21
  <TBuf extends Uint8Array = Uint8Array>(options: UuidV4Options | undefined, buf: TBuf, offset?: number): TBuf
22
+ /** Generate a UUID v4 string with optional deterministic random bytes. */
18
23
  (options?: UuidV4Options, buf?: undefined, offset?: number): string
24
+ /** Convert a UUID v4 string to its canonical 16-byte representation. */
19
25
  toBytes(id: string): Uint8Array
26
+ /** Convert 16 canonical UUID bytes to a UUID v4 string. */
20
27
  fromBytes(bytes: Uint8Array): string
28
+ /** Return whether a value is a syntactically valid UUID v4 string. */
21
29
  isValid(id: unknown): id is string
22
30
  /** The nil UUID (all zeros) */
23
31
  NIL: string
@@ -27,34 +35,15 @@ export type UuidV4 = {
27
35
 
28
36
  const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
29
37
 
30
- function v4Bytes(rnds: Uint8Array, buf?: Uint8Array, offset = 0): Uint8Array {
31
- if (rnds.length < 16) {
32
- throw new InvalidInputError('UUID_RANDOM_BYTES_TOO_SHORT', 'Random bytes length must be >= 16')
33
- }
34
-
35
- // Set RFC 4122 version (4) and variant (10xx) bits.
36
- // Note: This modifies the input array in-place.
37
- rnds[6] = (rnds[6] & 0x0f) | 0x40
38
- rnds[8] = (rnds[8] & 0x3f) | 0x80
39
-
40
- if (!buf) {
41
- // No output buffer provided - return the modified random bytes directly
42
- return rnds
43
- }
44
-
45
- if (offset < 0 || offset + 16 > buf.length) {
46
- throw new BufferError(
47
- 'UUID_BUFFER_OUT_OF_BOUNDS',
48
- `UUID byte range ${offset}:${offset + 15} is out of buffer bounds`,
49
- )
50
- }
51
-
38
+ function writeV4BytesUnchecked(rnds: Uint8Array, buf: Uint8Array, offset: number): void {
52
39
  // Copy 16 UUID bytes into the provided buffer slice.
53
- for (let i = 0; i < 16; i += 1) {
40
+ for (let i = 0; i < UUID_BYTES; i += 1) {
54
41
  buf[offset + i] = rnds[i]
55
42
  }
56
43
 
57
- return buf
44
+ // Set RFC 4122 version (4) and variant (10xx) bits on owned output only.
45
+ buf[offset + 6] = (buf[offset + 6] & 0x0f) | 0x40
46
+ buf[offset + 8] = (buf[offset + 8] & 0x3f) | 0x80
58
47
  }
59
48
 
60
49
  /*
@@ -78,8 +67,22 @@ function _v4<TBuf extends Uint8Array = Uint8Array>(
78
67
  buf?: TBuf,
79
68
  offset?: number,
80
69
  ): string | TBuf {
81
- const bytes = v4Bytes(options?.random ?? rng(), buf, offset)
82
- return buf ?? formatUuid(bytes)
70
+ const random = options?.random
71
+ if (random && random.length < UUID_BYTES) {
72
+ throw new InvalidInputError('UUID_RANDOM_BYTES_TOO_SHORT', `Random bytes length must be >= ${UUID_BYTES}`)
73
+ }
74
+
75
+ const outputOffset = buf ? (offset ?? 0) : 0
76
+ if (buf && !isWritableRange(buf, outputOffset, UUID_BYTES)) {
77
+ throw new BufferError(
78
+ 'UUID_BUFFER_OUT_OF_BOUNDS',
79
+ `UUID byte range ${outputOffset}:${outputOffset + UUID_BYTES - 1} is out of buffer bounds`,
80
+ )
81
+ }
82
+
83
+ const output = buf ?? reusableBuf
84
+ writeV4BytesUnchecked(random ?? rng(), output, outputOffset)
85
+ return buf ?? formatUuidUnchecked(output)
83
86
  }
84
87
 
85
88
  function isValid(id: unknown): id is string {
package/src/uuid/v7.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { rng } from '../common/random'
2
+ import { isIntegerInRange, isWritableRange } from '../common/validation'
2
3
  import { BufferError, InvalidInputError } from '../errors'
3
- import { formatUuid, parseUuid } from './common/uuid'
4
+ import { formatUuid, formatUuidUnchecked, parseUuid } from './common/uuid'
4
5
 
5
6
  export type UuidV7Options = {
6
7
  /**
@@ -8,17 +9,31 @@ export type UuidV7Options = {
8
9
  * Note: Several bytes will be overwritten with timestamp, version, and variant data.
9
10
  */
10
11
  random?: Uint8Array
12
+ /**
13
+ * Timestamp in milliseconds since Unix epoch.
14
+ * Defaults to Date.now().
15
+ */
11
16
  msecs?: number
17
+ /**
18
+ * Unsigned 32-bit sequence value.
19
+ */
12
20
  seq?: number
13
21
  }
14
22
 
15
23
  export type UuidV7 = {
24
+ /** Generate a time-ordered UUID v7 string. */
16
25
  (): string
26
+ /** Generate a UUID v7 with explicit options or write its 16 canonical bytes into a caller-owned buffer. */
17
27
  <TBuf extends Uint8Array = Uint8Array>(options: UuidV7Options | undefined, buf: TBuf, offset?: number): TBuf
28
+ /** Generate a UUID v7 string with optional timestamp, sequence, or random bytes. */
18
29
  (options?: UuidV7Options, buf?: undefined, offset?: number): string
30
+ /** Convert a UUID v7 string to its canonical 16-byte representation. */
19
31
  toBytes(id: string): Uint8Array
32
+ /** Convert 16 canonical UUID bytes to a UUID v7 string. */
20
33
  fromBytes(bytes: Uint8Array): string
34
+ /** Read the embedded Unix timestamp in milliseconds. */
21
35
  timestamp(id: string): number
36
+ /** Return whether a value is a syntactically valid UUID v7 string. */
22
37
  isValid(id: unknown): id is string
23
38
  /** The nil UUID (all zeros) */
24
39
  NIL: string
@@ -27,10 +42,13 @@ export type UuidV7 = {
27
42
  }
28
43
 
29
44
  const UUID_V7_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
45
+ const UUID_BYTES = 16
46
+ const MAX_MSECS = 0xffffffffffff
47
+ const MAX_SEQ = 0xffffffff
30
48
 
31
49
  // Reusable buffer for string output path - avoids allocation per call.
32
- // Safe because bytes are consumed synchronously by formatUuid().
33
- const reusableBuf = new Uint8Array(16)
50
+ // Safe because bytes are consumed synchronously by formatUuidUnchecked().
51
+ const reusableBuf = new Uint8Array(UUID_BYTES)
34
52
 
35
53
  type V7State = {
36
54
  msecs: number
@@ -47,29 +65,7 @@ type V7State = {
47
65
  */
48
66
  const state: V7State = { msecs: -Infinity, seq: 0 }
49
67
 
50
- function v7Bytes(
51
- rnds: Uint8Array,
52
- msecs: number | undefined,
53
- seq: number | undefined,
54
- buf: Uint8Array,
55
- offset = 0,
56
- ): Uint8Array {
57
- if (rnds.length < 16) {
58
- throw new InvalidInputError('UUID_RANDOM_BYTES_TOO_SHORT', 'Random bytes length must be >= 16')
59
- }
60
-
61
- if (offset < 0 || offset + 16 > buf.length) {
62
- throw new BufferError(
63
- 'UUID_BUFFER_OUT_OF_BOUNDS',
64
- `UUID byte range ${offset}:${offset + 15} is out of buffer bounds`,
65
- )
66
- }
67
-
68
- msecs ??= Date.now()
69
- // Derive a 31-bit sequence if not provided by the caller.
70
- // Uses the same formula as the hot path for consistency.
71
- seq ??= (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]
72
-
68
+ function writeV7BytesUnchecked(rnds: Uint8Array, msecs: number, seq: number, buf: Uint8Array, offset: number): void {
73
69
  // Keep this inline on the UUID v7 hot path. Using writeTimestamp48() here
74
70
  // benchmarked slower than the direct byte writes.
75
71
  buf[offset++] = (msecs / 0x10000000000) & 0xff
@@ -91,8 +87,50 @@ function v7Bytes(
91
87
  buf[offset++] = rnds[13]
92
88
  buf[offset++] = rnds[14]
93
89
  buf[offset++] = rnds[15]
90
+ }
91
+
92
+ function writeV7Bytes(rnds: Uint8Array, msecs: number, seq: number, buf: Uint8Array, offset: number): void {
93
+ if (!isWritableRange(buf, offset, UUID_BYTES)) {
94
+ throw new BufferError(
95
+ 'UUID_BUFFER_OUT_OF_BOUNDS',
96
+ `UUID byte range ${offset}:${offset + UUID_BYTES - 1} is out of buffer bounds`,
97
+ )
98
+ }
99
+ writeV7BytesUnchecked(rnds, msecs, seq, buf, offset)
100
+ }
101
+
102
+ function v7WithOptions<TBuf extends Uint8Array = Uint8Array>(
103
+ options: UuidV7Options,
104
+ buf?: TBuf,
105
+ offset = 0,
106
+ ): string | TBuf {
107
+ const optMsecs = options.msecs
108
+ if (optMsecs !== undefined && !isIntegerInRange(optMsecs, 0, MAX_MSECS)) {
109
+ throw new InvalidInputError(
110
+ 'UUID_TIMESTAMP_OUT_OF_RANGE',
111
+ `Timestamp must be an integer between 0 and ${MAX_MSECS}`,
112
+ )
113
+ }
114
+ const optSeq = options.seq
115
+ if (optSeq !== undefined && !isIntegerInRange(optSeq, 0, MAX_SEQ)) {
116
+ throw new InvalidInputError('UUID_SEQUENCE_OUT_OF_RANGE', `Sequence must be an integer between 0 and ${MAX_SEQ}`)
117
+ }
118
+ const optRandom = options.random
119
+ if (optRandom && optRandom.length < UUID_BYTES) {
120
+ throw new InvalidInputError('UUID_RANDOM_BYTES_TOO_SHORT', `Random bytes length must be >= ${UUID_BYTES}`)
121
+ }
94
122
 
95
- return buf
123
+ const rnds = optRandom ?? rng()
124
+ const msecs = optMsecs ?? Date.now()
125
+ // Derive a 31-bit sequence if not provided by the caller, matching the default hot path.
126
+ const seq = optSeq ?? (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]
127
+
128
+ if (buf) {
129
+ writeV7Bytes(rnds, msecs, seq, buf, offset)
130
+ return buf
131
+ }
132
+ writeV7BytesUnchecked(rnds, msecs, seq, reusableBuf, 0)
133
+ return formatUuidUnchecked(reusableBuf)
96
134
  }
97
135
 
98
136
  /*
@@ -104,31 +142,32 @@ function v7(options?: UuidV7Options, buf?: undefined, offset?: number): string
104
142
  */
105
143
  function v7<TBuf extends Uint8Array = Uint8Array>(options: UuidV7Options | undefined, buf: TBuf, offset?: number): TBuf
106
144
  function v7<TBuf extends Uint8Array = Uint8Array>(options?: UuidV7Options, buf?: TBuf, offset?: number): string | TBuf {
107
- let bytes: Uint8Array
108
-
109
145
  if (options) {
110
- bytes = v7Bytes(options.random ?? rng(), options.msecs, options.seq, buf ?? reusableBuf, buf ? offset : 0)
146
+ return v7WithOptions(options, buf, offset)
147
+ }
148
+
149
+ // HOT PATH: Inline state management and byte generation for best performance
150
+ const now = Date.now()
151
+ const rnds = rng()
152
+
153
+ // Update state (inlined for performance)
154
+ if (now > state.msecs) {
155
+ state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]
156
+ state.msecs = now
111
157
  } else {
112
- // HOT PATH: Inline state management and byte generation for best performance
113
- const now = Date.now()
114
- const rnds = rng()
115
-
116
- // Update state (inlined for performance)
117
- if (now > state.msecs) {
118
- state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]
119
- state.msecs = now
120
- } else {
121
- state.seq = (state.seq + 1) | 0
122
- if (state.seq < 0) {
123
- state.seq = 0
124
- state.msecs++
125
- }
158
+ state.seq = (state.seq + 1) | 0
159
+ if (state.seq < 0) {
160
+ state.seq = 0
161
+ state.msecs++
126
162
  }
127
-
128
- bytes = v7Bytes(rnds, state.msecs, state.seq, buf ?? reusableBuf, buf ? offset : 0)
129
163
  }
130
164
 
131
- return buf ? (bytes as TBuf) : formatUuid(bytes)
165
+ if (buf) {
166
+ writeV7Bytes(rnds, state.msecs, state.seq, buf, offset ?? 0)
167
+ return buf
168
+ }
169
+ writeV7BytesUnchecked(rnds, state.msecs, state.seq, reusableBuf, 0)
170
+ return formatUuidUnchecked(reusableBuf)
132
171
  }
133
172
 
134
173
  function timestamp(id: string): number {
@@ -1,2 +0,0 @@
1
- import{ParseError as e}from"./errors.mjs";function t(e){return e>=48&&e<=57?e-48:e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:-1}const n=[0,0,1,1,2,2,3,3,-1,4,4,5,5,-1,6,6,7,7,-1,8,8,9,9,-1,10,10,11,11,12,12,13,13,14,14,15,15],r=[!0,!1,!0,!1,!0,!1,!0,!1,!1,!0,!1,!0,!1,!1,!0,!1,!0,!1,!1,!0,!1,!0,!1,!1,!0,!1,!0,!1,!0,!1,!0,!1,!0,!1,!0,!1],i=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,`0`));function a(e){return i[e[0]]+i[e[1]]+i[e[2]]+i[e[3]]+`-`+i[e[4]]+i[e[5]]+`-`+i[e[6]]+i[e[7]]+`-`+i[e[8]]+i[e[9]]+`-`+i[e[10]]+i[e[11]]+i[e[12]]+i[e[13]]+i[e[14]]+i[e[15]]}function o(i){if(i.length!==36)throw new e(`UUID_INVALID_LENGTH`,`UUID string must be 36 characters, got ${i.length}`);if(i[8]!==`-`||i[13]!==`-`||i[18]!==`-`||i[23]!==`-`)throw new e(`UUID_INVALID_SEPARATORS`,`UUID string has invalid separators at positions 8, 13, 18, 23. Received: "${i}"`);let a=new Uint8Array(16);for(let o=0;o<36;o+=1){let s=n[o];if(s===-1)continue;let c=t(i.charCodeAt(o));if(c===-1)throw new e(`UUID_INVALID_HEX_CHAR`,`UUID string contains invalid hex character at position ${o}`);r[o]?a[s]=c<<4:a[s]|=c}return a}export{o as n,a as t};
2
- //# sourceMappingURL=uuid-BBjwHv7J.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"uuid-BBjwHv7J.mjs","names":[],"sources":["../src/uuid/common/hex.ts","../src/uuid/common/uuid.ts"],"sourcesContent":["// ASCII code ranges for hex character validation\nconst ASCII_0 = 48 // '0'\nconst ASCII_9 = 57 // '9'\nconst ASCII_A = 65 // 'A'\nconst ASCII_F = 70 // 'F'\nconst ASCII_a = 97 // 'a'\nconst ASCII_f = 102 // 'f'\n\n/**\n * Convert a hex character ASCII code to its numeric value (0-15).\n * Returns -1 for invalid hex characters.\n */\nexport function hexValue(code: number): number {\n if (code >= ASCII_0 && code <= ASCII_9) {\n return code - ASCII_0\n }\n if (code >= ASCII_A && code <= ASCII_F) {\n return code - ASCII_A + 10\n }\n if (code >= ASCII_a && code <= ASCII_f) {\n return code - ASCII_a + 10\n }\n return -1 // Invalid hex character\n}\n","import { ParseError } from '../../errors'\nimport { hexValue } from './hex'\n\nconst UUID_BYTE_LENGTH = 16\nconst UUID_STRING_LENGTH = 36\n\n// Mapping from UUID string position to byte index.\n// -1 indicates a dash position that should be skipped.\n// This avoids intermediate string allocations during parsing.\nconst UUID_CHAR_TO_BYTE: number[] = [\n 0,\n 0,\n 1,\n 1,\n 2,\n 2,\n 3,\n 3, // chars 0-7 → bytes 0-3\n -1, // char 8 is '-'\n 4,\n 4,\n 5,\n 5, // chars 9-12 → bytes 4-5\n -1, // char 13 is '-'\n 6,\n 6,\n 7,\n 7, // chars 14-17 → bytes 6-7\n -1, // char 18 is '-'\n 8,\n 8,\n 9,\n 9, // chars 19-22 → bytes 8-9\n -1, // char 23 is '-'\n 10,\n 10,\n 11,\n 11,\n 12,\n 12,\n 13,\n 13,\n 14,\n 14,\n 15,\n 15, // chars 24-35 → bytes 10-15\n]\n\n// Whether each position is the high nibble (true) or low nibble (false)\nconst UUID_CHAR_IS_HIGH: boolean[] = [\n true,\n false,\n true,\n false,\n true,\n false,\n true,\n false, // chars 0-7\n false, // dash (ignored)\n true,\n false,\n true,\n false, // chars 9-12\n false, // dash\n true,\n false,\n true,\n false, // chars 14-17\n false, // dash\n true,\n false,\n true,\n false, // chars 19-22\n false, // dash\n true,\n false,\n true,\n false,\n true,\n false,\n true,\n false,\n true,\n false,\n true,\n false, // chars 24-35\n]\n\n// Pre-computed lookup table for byte-to-hex conversion (0x00 -> \"00\", 0xff -> \"ff\")\n//\n// Note: this table must remain defined in the same module as `formatUuid`, otherwise the v8 optimizer\n// will cause a performance drop of ~36%.\nconst HEX_TABLE: string[] = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'))\n\nexport function formatUuid(bytes: Uint8Array): string {\n // Direct string concatenation - optimized for V8's string builder.\n // This approach avoids loop overhead and intermediate allocations.\n // See: https://github.com/uuidjs/uuid/pull/434\n return (\n HEX_TABLE[bytes[0]] +\n HEX_TABLE[bytes[1]] +\n HEX_TABLE[bytes[2]] +\n HEX_TABLE[bytes[3]] +\n '-' +\n HEX_TABLE[bytes[4]] +\n HEX_TABLE[bytes[5]] +\n '-' +\n HEX_TABLE[bytes[6]] +\n HEX_TABLE[bytes[7]] +\n '-' +\n HEX_TABLE[bytes[8]] +\n HEX_TABLE[bytes[9]] +\n '-' +\n HEX_TABLE[bytes[10]] +\n HEX_TABLE[bytes[11]] +\n HEX_TABLE[bytes[12]] +\n HEX_TABLE[bytes[13]] +\n HEX_TABLE[bytes[14]] +\n HEX_TABLE[bytes[15]]\n )\n}\n\nexport function parseUuid(value: string): Uint8Array {\n if (value.length !== UUID_STRING_LENGTH) {\n throw new ParseError('UUID_INVALID_LENGTH', `UUID string must be 36 characters, got ${value.length}`)\n }\n\n // Validate separator positions directly (more efficient than full loop)\n if (value[8] !== '-' || value[13] !== '-' || value[18] !== '-' || value[23] !== '-') {\n throw new ParseError(\n 'UUID_INVALID_SEPARATORS',\n `UUID string has invalid separators at positions 8, 13, 18, 23. Received: \"${value}\"`,\n )\n }\n\n // Parse bytes directly from UUID string without intermediate string allocations.\n // This avoids the 9 allocations (5 slices + 4 concatenations) of the naive approach.\n const bytes = new Uint8Array(UUID_BYTE_LENGTH)\n\n for (let i = 0; i < UUID_STRING_LENGTH; i += 1) {\n const byteIdx = UUID_CHAR_TO_BYTE[i]\n if (byteIdx === -1) continue // Skip dash positions\n\n const nibble = hexValue(value.charCodeAt(i))\n if (nibble === -1) {\n throw new ParseError('UUID_INVALID_HEX_CHAR', `UUID string contains invalid hex character at position ${i}`)\n }\n\n if (UUID_CHAR_IS_HIGH[i]) {\n bytes[byteIdx] = nibble << 4\n } else {\n bytes[byteIdx] |= nibble\n }\n }\n\n return bytes\n}\n"],"mappings":"0CAYA,SAAgB,EAAS,EAAsB,CAU7C,OATI,GAAQ,IAAW,GAAQ,GACtB,EAAO,GAEZ,GAAQ,IAAW,GAAQ,GACtB,EAAO,GAAU,GAEtB,GAAQ,IAAW,GAAQ,IACtB,EAAO,GAAU,GAEnB,EACT,CCpBA,MAMM,EAA8B,CAClC,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,EACF,EAGM,EAA+B,CACnC,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,EACF,EAMM,EAAsB,MAAM,KAAK,CAAE,OAAQ,GAAI,GAAI,EAAG,IAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAG,GAAG,CAAC,EAEjG,SAAgB,EAAW,EAA2B,CAIpD,OACE,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,IACA,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,IACA,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,IACA,EAAU,EAAM,IAChB,EAAU,EAAM,IAChB,IACA,EAAU,EAAM,KAChB,EAAU,EAAM,KAChB,EAAU,EAAM,KAChB,EAAU,EAAM,KAChB,EAAU,EAAM,KAChB,EAAU,EAAM,IAEpB,CAEA,SAAgB,EAAU,EAA2B,CACnD,GAAI,EAAM,SAAW,GACnB,MAAM,IAAI,EAAW,sBAAuB,0CAA0C,EAAM,QAAQ,EAItG,GAAI,EAAM,KAAO,KAAO,EAAM,MAAQ,KAAO,EAAM,MAAQ,KAAO,EAAM,MAAQ,IAC9E,MAAM,IAAI,EACR,0BACA,6EAA6E,EAAM,EACrF,EAKF,IAAM,EAAQ,IAAI,WAAW,EAAgB,EAE7C,IAAK,IAAI,EAAI,EAAG,EAAI,GAAoB,GAAK,EAAG,CAC9C,IAAM,EAAU,EAAkB,GAClC,GAAI,IAAY,GAAI,SAEpB,IAAM,EAAS,EAAS,EAAM,WAAW,CAAC,CAAC,EAC3C,GAAI,IAAW,GACb,MAAM,IAAI,EAAW,wBAAyB,0DAA0D,GAAG,EAGzG,EAAkB,GACpB,EAAM,GAAW,GAAU,EAE3B,EAAM,IAAY,CAEtB,CAEA,OAAO,CACT"}