@chainfuse/helpers 4.0.5 → 4.1.0

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.
package/README.md CHANGED
@@ -16,12 +16,28 @@ import helpers from '@chainfuse/helpers';
16
16
  // TODO: DEMONSTRATE API
17
17
  ```
18
18
 
19
- ## UUIDv8
20
-
21
- Based on UUIDv7 but with added values to prevent unnecessary lookups
22
-
23
- `01f3ffff-fc18-8bb7-9120-cabc55668d92`
24
-
25
- | 01f3ffff-fc18 | 8 | bb7 | 9 | 12 | 0 | cabc55668d92 |
26
- | ----------------------------------------- | ------------ | --------------------------------- | -------------------------------- | ---------------------------------------- | ----------- | -------------- |
27
- | 48bit Timestamp (Unix epoch milliseconds) | UUID Version | Suffix random (`000` if director) | variant (2 bits) + 2 random bits | `DOCombinedLocations` (`00` if anywhere) | `ShardType` | 48 random bits |
19
+ ## SuruID
20
+
21
+ In Japanese, する (suru) is a versatile, irregular verb meaning "to do"
22
+
23
+ | Format | Example |
24
+ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25
+ | hex | `11f3fffffc18001000004522706e3aa036a0ea9c0d7d27581ebf4876defd304469119f0f4cfc41b0fb96d6b1e18900ec` |
26
+ | SQLite Blob | `1724325525525224016006934112110581605416023415613125398830191721182222534868105171591576252651762511502141772251370236` |
27
+ | JS Buffer Array | `[17,243,255,255,252,24,0,16,0,0,69,34,112,110,58,160,54,160,234,156,13,125,39,88,30,191,72,118,222,253,48,68,105,17,159,15,76,252,65,176,251,150,214,177,225,137,0,236]` |
28
+ | base64 | `EfP///wYABAAAEUicG46oDag6pwNfSdYHr9Idt79MERpEZ8PTPxBsPuW1rHhiQDs` |
29
+ | base64url | `EfP___wYABAAAEUicG46oDag6pwNfSdYHr9Idt79MERpEZ8PTPxBsPuW1rHhiQDs` |
30
+
31
+ ### Breakdown
32
+
33
+ | Offset (bits) | Size (bits) | Field | (Hex) Example | Notes |
34
+ | ------------- | ----------- | ------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
35
+ | 0 | 4 | Version | `1` | Masked into timestamp's top nibble |
36
+ | 4 | 44 | Timestamp | ~~`0`~~`1f3fffffc18` | Lower 44 bits of 48bit epoch milliseconds (max date value `2527-06-23T06:20:44.415Z`) |
37
+ | 48 | 12 | System Type | `001` | `D0SystemType` TS Enum |
38
+ | 60 | 12 | Location | `000` | `D0CombinedLocations` TS Enum |
39
+ | 72 | 8 | Shard Type | `00` | `D0ShardType` TS Enum |
40
+ | 80 | 44 | Suffix random | `4522706e3aa` | Fresh entropy per ID to ensure uniqueness even if other fields match |
41
+ | 124 | 4 | Environment | `0` | `D0Environment` TS Enum |
42
+ | 128 | 256 | Stable random | `36a0ea9c0d7d27581ebf4876defd304469119f0f4cfc41b0fb96d6b1e18900ec` | Stable per logical entity; correlates related IDs without DB lookups |
43
+ | **Total** | **384** |
@@ -1,7 +1,6 @@
1
1
  import type { UndefinedProperties } from '@chainfuse/types';
2
2
  import { type PrefixedUuid, type UuidExport, type UUIDExtract } from '@chainfuse/types/d1';
3
3
  import * as z from 'zod/mini';
4
- import type { Version8Options } from './uuid8.mjs';
5
4
  export type UuidExportBlobInput = Buffer | UuidExport['blob'];
6
5
  export declare class BufferHelpers {
7
6
  static bigintToBuffer(number: bigint): Promise<ArrayBuffer>;
@@ -30,8 +29,6 @@ export declare class BufferHelpers {
30
29
  }, z.core.$strip>;
31
30
  static generateUuid7(_options?: z.input<Awaited<typeof this.v7OptionsBase>>): Promise<UuidExport>;
32
31
  static generateUuid7Sync(_options?: z.input<Awaited<typeof this.v7OptionsBase>>): UuidExport;
33
- static generateUuid8(options?: Omit<Version8Options, 'random' | 'rng'>): Promise<UuidExport>;
34
- static generateUuid8Sync(options?: Omit<Version8Options, 'random' | 'rng'>): UuidExport;
35
32
  static uuidConvert(input: undefined): Promise<UndefinedProperties<UuidExport>>;
36
33
  static uuidConvert(prefixedUtf: PrefixedUuid): Promise<UuidExport>;
37
34
  static uuidConvert(input: UuidExport['utf8']): Promise<UuidExport>;
package/dist/buffers.mjs CHANGED
@@ -1,10 +1,9 @@
1
- import { UUIDExtract7, UUIDExtract8 } from '@chainfuse/types/d1';
2
- import { PrefixedUuidRaw } from '@chainfuse/types/zod';
1
+ import { UUIDExtract7 } from '@chainfuse/types/d1';
2
+ import { PrefixedUuidRaw } from '@chainfuse/types/zod-mini';
3
3
  import { v7 as uuidv7 } from 'uuid';
4
4
  import * as z from 'zod/mini';
5
5
  import { BufferHelpersInternals } from "./bufferInternals.mjs";
6
6
  import { CryptoHelpers } from './crypto.mjs';
7
- import { v8 as uuidv8 } from './uuid8.mjs';
8
7
  export class BufferHelpers {
9
8
  static bigintToBuffer(number) {
10
9
  const hexString = number.toString(16);
@@ -116,42 +115,6 @@ export class BufferHelpers {
116
115
  base64url,
117
116
  };
118
117
  }
119
- static generateUuid8(options) {
120
- return Promise.all([import('./uuid8.mjs'), CryptoHelpers.secretBytes(16)]).then(([{ v8: uuidv8 }, random]) => {
121
- const uuid = uuidv8({
122
- // @ts-expect-error they're the exact same
123
- random,
124
- ...options,
125
- });
126
- const uuidHex = uuid.replaceAll('-', '');
127
- return this.hexToBuffer(uuidHex).then((blob) => Promise.all([this.bufferToBase64(blob, false), this.bufferToBase64(blob, true)]).then(([base64, base64url]) => ({
128
- utf8: uuid,
129
- hex: uuidHex,
130
- blob,
131
- base64,
132
- base64url,
133
- })));
134
- });
135
- }
136
- static generateUuid8Sync(options) {
137
- const random = CryptoHelpers.secretBytesSync(16);
138
- const uuid = uuidv8({
139
- // @ts-expect-error they're the exact same
140
- random,
141
- ...options,
142
- });
143
- const uuidHex = uuid.replaceAll('-', '');
144
- const blob = this.hexToBufferSync(uuidHex);
145
- const base64 = this.bufferToBase64Sync(blob, false);
146
- const base64url = this.bufferToBase64Sync(blob, true);
147
- return {
148
- utf8: uuid,
149
- hex: uuidHex,
150
- blob,
151
- base64,
152
- base64url,
153
- };
154
- }
155
118
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
156
119
  static uuidConvert(input) {
157
120
  if (input) {
@@ -328,29 +291,11 @@ export class BufferHelpers {
328
291
  .safeParseAsync(_hex)
329
292
  .then(async ({ success: hexSuccess, data: hex }) => {
330
293
  if (hexSuccess) {
331
- const [{ success: utf8v7Success }, { success: utf8v8Success }] = await Promise.all([z.uuid({ version: 'v7' }).safeParseAsync(utf8), z.uuid({ version: 'v8' }).safeParseAsync(utf8)]);
332
- if (utf8v7Success || utf8v8Success) {
333
- if (utf8v8Success) {
334
- const suffix_hex = hex.substring(13, 16);
335
- const suffix_buffer = await BufferHelpers.hexToBuffer(suffix_hex);
336
- return UUIDExtract8.parseAsync({
337
- date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
338
- location: parseInt(hex.slice(17, 19), 16),
339
- shardType: parseInt(hex.slice(19, 20), 16),
340
- suffix: suffix_hex === '000'
341
- ? undefined
342
- : {
343
- hex: suffix_hex,
344
- base64: await BufferHelpers.bufferToBase64(suffix_buffer, false),
345
- base64url: await BufferHelpers.bufferToBase64(suffix_buffer, true),
346
- },
347
- });
348
- }
349
- else {
350
- return UUIDExtract7.parseAsync({
351
- date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
352
- });
353
- }
294
+ const { success: utf8v7Success } = await z.uuid({ version: 'v7' }).safeParseAsync(utf8);
295
+ if (utf8v7Success) {
296
+ return UUIDExtract7.parseAsync({
297
+ date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
298
+ });
354
299
  }
355
300
  else {
356
301
  throw new Error('Unsupported UUID version provided');
@@ -369,29 +314,10 @@ export class BufferHelpers {
369
314
  const { success: hexSuccess, data: hex } = z.hex().check(z.length(32)).safeParse(_hex);
370
315
  if (hexSuccess) {
371
316
  const { success: utf8v7Success } = z.uuid({ version: 'v7' }).safeParse(utf8);
372
- const { success: utf8v8Success } = z.uuid({ version: 'v8' }).safeParse(utf8);
373
- if (utf8v7Success || utf8v8Success) {
374
- if (utf8v8Success) {
375
- const suffix_hex = hex.substring(13, 16);
376
- const suffix_buffer = BufferHelpers.hexToBufferSync(suffix_hex);
377
- return UUIDExtract8.parse({
378
- date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
379
- location: parseInt(hex.slice(17, 19), 16),
380
- shardType: parseInt(hex.slice(19, 20), 16),
381
- suffix: suffix_hex === '000'
382
- ? undefined
383
- : {
384
- hex: suffix_hex,
385
- base64: BufferHelpers.bufferToBase64Sync(suffix_buffer, false),
386
- base64url: BufferHelpers.bufferToBase64Sync(suffix_buffer, true),
387
- },
388
- });
389
- }
390
- else {
391
- return UUIDExtract7.parse({
392
- date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
393
- });
394
- }
317
+ if (utf8v7Success) {
318
+ return UUIDExtract7.parse({
319
+ date: Number(BigInt(`0x${hex.substring(0, 12)}`)),
320
+ });
395
321
  }
396
322
  else {
397
323
  throw new Error('Unsupported UUID version provided');
@@ -0,0 +1,88 @@
1
+ import { DOJurisdictions, DOLocations } from '@chainfuse/types';
2
+ import { D0Environment, D0ShardType, D0SystemType, D0Version } from '@chainfuse/types/d0';
3
+ import { type ZodPartial, type ZodSuruId } from '@chainfuse/types/zod-mini';
4
+ import * as z from 'zod/mini';
5
+ export declare class SuruId {
6
+ static extractOutputBase: z.ZodMiniObject<{
7
+ version: z.ZodMiniEnum<typeof D0Version>;
8
+ date: z.ZodMiniDate<Date>;
9
+ systemType: z.ZodMiniEnum<typeof D0SystemType>;
10
+ shardType: z.ZodMiniEnum<typeof D0ShardType>;
11
+ suffixRandom: z.ZodMiniObject<{
12
+ hex: z.ZodMiniCustomStringFormat<"hex">;
13
+ base64: z.ZodMiniBase64;
14
+ base64url: z.ZodMiniBase64URL;
15
+ }, z.core.$strip>;
16
+ environment: z.ZodMiniEnum<typeof D0Environment>;
17
+ stableRandom: z.ZodMiniObject<{
18
+ hex: z.ZodMiniCustomStringFormat<"hex">;
19
+ base64: z.ZodMiniBase64;
20
+ base64url: z.ZodMiniBase64URL;
21
+ }, z.core.$strip>;
22
+ }, z.core.$strip>;
23
+ static extractOutput: z.ZodMiniObject<{
24
+ version: z.ZodMiniEnum<typeof D0Version>;
25
+ date: z.ZodMiniDate<Date>;
26
+ systemType: z.ZodMiniEnum<typeof D0SystemType>;
27
+ shardType: z.ZodMiniEnum<typeof D0ShardType>;
28
+ suffixRandom: z.ZodMiniObject<{
29
+ hex: z.ZodMiniCustomStringFormat<"hex">;
30
+ base64: z.ZodMiniBase64;
31
+ base64url: z.ZodMiniBase64URL;
32
+ }, z.core.$strip>;
33
+ environment: z.ZodMiniEnum<typeof D0Environment>;
34
+ stableRandom: z.ZodMiniObject<{
35
+ hex: z.ZodMiniCustomStringFormat<"hex">;
36
+ base64: z.ZodMiniBase64;
37
+ base64url: z.ZodMiniBase64URL;
38
+ }, z.core.$strip>;
39
+ locationJurisdiction: z.ZodMiniNullable<z.ZodMiniEnum<typeof DOJurisdictions>>;
40
+ locationHint: z.ZodMiniNullable<z.ZodMiniEnum<typeof DOLocations>>;
41
+ }, z.core.$strip>;
42
+ static convertOutput: z.ZodMiniObject<{
43
+ hex: z.ZodMiniCustomStringFormat<"hex">;
44
+ blob: z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>;
45
+ base64: z.ZodMiniBase64;
46
+ base64url: z.ZodMiniBase64URL;
47
+ }, z.core.$strip>;
48
+ static createInputBase: z.ZodMiniObject<{
49
+ version: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0Version>>;
50
+ date: z.ZodMiniDefault<z.ZodMiniDate<Date>>;
51
+ shardType: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0ShardType>>;
52
+ suffixRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
53
+ stableRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
54
+ systemType: z.ZodMiniEnum<typeof D0SystemType>;
55
+ environment: z.ZodMiniEnum<typeof D0Environment>;
56
+ }, z.core.$strip>;
57
+ static createInput: z.ZodMiniUnion<readonly [z.ZodMiniObject<{
58
+ version: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0Version>>;
59
+ date: z.ZodMiniDefault<z.ZodMiniDate<Date>>;
60
+ shardType: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0ShardType>>;
61
+ suffixRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
62
+ stableRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
63
+ systemType: z.ZodMiniEnum<typeof D0SystemType>;
64
+ environment: z.ZodMiniEnum<typeof D0Environment>;
65
+ locationJurisdiction: z.ZodMiniDefault<z.ZodMiniNullable<z.ZodMiniEnum<typeof DOJurisdictions>>>;
66
+ locationHint: z.ZodMiniDefault<z.ZodMiniNull>;
67
+ }, z.core.$strip>, z.ZodMiniObject<{
68
+ version: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0Version>>;
69
+ date: z.ZodMiniDefault<z.ZodMiniDate<Date>>;
70
+ shardType: z.ZodMiniDefault<z.ZodMiniEnum<typeof D0ShardType>>;
71
+ suffixRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
72
+ stableRandom: z.ZodMiniDefault<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Buffer<ArrayBufferLike>>>, z.ZodMiniPipe<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBuffer>>>, z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniPipe<z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, ArrayBuffer>>, z.ZodMiniPipe<z.ZodMiniCustom<SharedArrayBuffer, SharedArrayBuffer>, z.ZodMiniTransform<ArrayBufferLike, SharedArrayBuffer>>]>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, ArrayBufferLike>>, z.ZodMiniPipe<z.ZodMiniTuple<readonly [z.ZodMiniNumberFormat], z.ZodMiniNumberFormat>, z.ZodMiniTransform<Uint8Array<ArrayBufferLike>, [number, ...number[]]>>]>>;
73
+ systemType: z.ZodMiniEnum<typeof D0SystemType>;
74
+ environment: z.ZodMiniEnum<typeof D0Environment>;
75
+ locationJurisdiction: z.ZodMiniDefault<z.ZodMiniNull>;
76
+ locationHint: z.ZodMiniDefault<z.ZodMiniNullable<z.ZodMiniEnum<typeof DOLocations>>>;
77
+ }, z.core.$strip>]>;
78
+ static suruCreate(_input: z.input<typeof this.createInput>): Promise<z.output<typeof this.convertOutput>>;
79
+ static suruCreateSync(_input: z.input<typeof this.createInput>): z.output<typeof this.convertOutput>;
80
+ static suruConvert<O extends typeof this.convertOutput = typeof this.convertOutput>(_input: undefined): Promise<z.output<ZodPartial<O>>>;
81
+ static suruConvert<I extends z.input<typeof ZodSuruId> = z.input<typeof ZodSuruId>, O extends typeof this.convertOutput = typeof this.convertOutput>(_input: I): Promise<z.output<O>>;
82
+ static suruConvertSync<O extends typeof this.convertOutput = typeof this.convertOutput>(_input: undefined): z.output<ZodPartial<O>>;
83
+ static suruConvertSync<I extends z.input<typeof ZodSuruId> = z.input<typeof ZodSuruId>, O extends typeof this.convertOutput = typeof this.convertOutput>(_input: I): z.output<O>;
84
+ static suruExtract<O extends typeof this.extractOutput = typeof this.extractOutput, UO extends z.output<ZodPartial<O>> = z.output<ZodPartial<O>>>(_input: undefined): Promise<UO>;
85
+ static suruExtract<I extends z.input<typeof ZodSuruId> = z.input<typeof ZodSuruId>, O extends typeof this.extractOutput = typeof this.extractOutput>(_input: I): Promise<z.output<O>>;
86
+ static suruExtractSync<O extends typeof this.extractOutput = typeof this.extractOutput, UO extends z.output<ZodPartial<O>> = z.output<ZodPartial<O>>>(_input: undefined): UO;
87
+ static suruExtractSync<I extends z.input<typeof ZodSuruId> = z.input<typeof ZodSuruId>, O extends typeof this.extractOutput = typeof this.extractOutput>(_input: I): z.output<O>;
88
+ }
package/dist/suru.mjs ADDED
@@ -0,0 +1,390 @@
1
+ import { DOJurisdictions, DOLocations } from '@chainfuse/types';
2
+ import { D0CombinedLocations, D0Environment, D0ShardType, D0SystemType, D0Version } from '@chainfuse/types/d0';
3
+ import { ZodBlob, ZodBlobExport } from '@chainfuse/types/zod-mini';
4
+ import * as z from 'zod/mini';
5
+ import { BufferHelpers } from "./buffers.mjs";
6
+ import { CryptoHelpers } from "./crypto.mjs";
7
+ export class SuruId {
8
+ static extractOutputBase = z.object({
9
+ version: z.enum(D0Version),
10
+ date: z.date().check(z.minimum(new Date(0)), z.maximum(new Date(Number(BigInt('0x0fffffffffff'))))),
11
+ systemType: z.enum(D0SystemType),
12
+ shardType: z.enum(D0ShardType),
13
+ // Location
14
+ suffixRandom: z.object({
15
+ hex: z.hex().check(z.trim(), z.toLowerCase(), z.length(11)),
16
+ base64: z.base64().check(z.trim(), z.maxLength(Math.ceil((11 * (4 / 6)) / 4) * 4)),
17
+ base64url: z.base64url().check(z.trim(), z.maxLength(Math.round(11 * (4 / 6)))),
18
+ }),
19
+ environment: z.enum(D0Environment),
20
+ stableRandom: z.object({
21
+ hex: z.hex().check(z.trim(), z.toLowerCase(), z.length(64)),
22
+ base64: z.base64().check(z.trim(), z.maxLength(Math.ceil((64 * (4 / 6)) / 4) * 4)),
23
+ base64url: z.base64url().check(z.trim(), z.maxLength(Math.round(64 * (4 / 6)))),
24
+ }),
25
+ });
26
+ static extractOutput = z.extend(SuruId.extractOutputBase, {
27
+ locationJurisdiction: z.nullable(z.enum(DOJurisdictions)),
28
+ locationHint: z.nullable(z.enum(DOLocations)),
29
+ });
30
+ static convertOutput = z.object({
31
+ hex: z.hex().check(z.trim(), z.toLowerCase(), z.length(96)),
32
+ blob: ZodBlobExport,
33
+ base64: z.base64().check(z.trim(), z.maxLength(64)),
34
+ base64url: z.base64url().check(z.trim(), z.maxLength(64)),
35
+ });
36
+ static createInputBase = z.object({
37
+ ...this.extractOutputBase.def.shape,
38
+ version: z._default(this.extractOutputBase.def.shape.version, D0Version.v1),
39
+ date: z._default(this.extractOutputBase.def.shape.date, () => new Date()),
40
+ // systemType
41
+ shardType: z._default(this.extractOutputBase.def.shape.shardType, D0ShardType.None),
42
+ // Location
43
+ suffixRandom: z._default(ZodBlob, () => CryptoHelpers.secretBytesSync(Math.ceil(44 / 8))).check(z.refine((b) => b.byteLength === Math.ceil(44 / 8))),
44
+ // environment
45
+ stableRandom: z._default(ZodBlob, () => CryptoHelpers.secretBytesSync(256 / 8)).check(z.refine((b) => b.byteLength === 256 / 8)),
46
+ });
47
+ static createInput = z.union([
48
+ z.extend(SuruId.createInputBase, {
49
+ locationJurisdiction: z._default(z.nullable(z.enum(DOJurisdictions)), null),
50
+ locationHint: z._default(z.null(), null),
51
+ }),
52
+ z.extend(SuruId.createInputBase, {
53
+ locationJurisdiction: z._default(z.null(), null),
54
+ locationHint: z._default(z.nullable(z.enum(DOLocations)), null),
55
+ }),
56
+ ]);
57
+ static suruCreate(_input) {
58
+ return SuruId.createInput.parseAsync(_input).then(async (input) => {
59
+ // Pack fields into hex
60
+ let hex = '';
61
+ // Version (4 bytes)
62
+ hex += Number(input.version).toString(16);
63
+ // Timestamp (11 bytes, pad to 12 chars, mask top nibble for version)
64
+ hex += input.date.getTime().toString(16).padStart(12, '0').slice(-11);
65
+ // System Type (3 bytes)
66
+ hex += input.systemType.toString(16).padStart(3, '0').slice(-3);
67
+ // Location (3 bytes)
68
+ hex += (input.locationJurisdiction ? D0CombinedLocations[input.locationJurisdiction] : input.locationHint ? D0CombinedLocations[input.locationHint] : D0CombinedLocations.none).toString(16).padStart(3, '0').slice(-3);
69
+ // Shard Type (2 bytes)
70
+ hex += input.shardType.toString(16).padStart(2, '0').slice(-2);
71
+ // Suffix random (11 bytes)
72
+ hex += (await BufferHelpers.bufferToHex(input.suffixRandom.buffer)).padStart(11, '0').slice(-11);
73
+ // Environment (1 byte)
74
+ hex += input.environment.toString(16).slice(-3);
75
+ // Stable random (32 bytes)
76
+ hex += (await BufferHelpers.bufferToHex(input.stableRandom.buffer)).padStart(64, '0').slice(-64);
77
+ const blob = await BufferHelpers.hexToBuffer(hex);
78
+ const [base64, base64url] = await Promise.all([BufferHelpers.bufferToBase64(blob, false), BufferHelpers.bufferToBase64(blob, true)]);
79
+ return this.convertOutput.parseAsync({
80
+ hex,
81
+ blob: Array.from(new Uint8Array(blob)),
82
+ base64,
83
+ base64url,
84
+ });
85
+ });
86
+ }
87
+ static suruCreateSync(_input) {
88
+ const input = SuruId.createInput.parse(_input);
89
+ // Pack fields into hex
90
+ let hex = '';
91
+ // Version (4 bytes)
92
+ hex += Number(input.version).toString(16);
93
+ // Timestamp (11 bytes, pad to 12 chars, mask top nibble for version)
94
+ hex += input.date.getTime().toString(16).padStart(12, '0').slice(-11);
95
+ // System Type (3 bytes)
96
+ hex += input.systemType.toString(16).padStart(3, '0').slice(-3);
97
+ // Location (3 bytes)
98
+ hex += (input.locationJurisdiction ? D0CombinedLocations[input.locationJurisdiction] : input.locationHint ? D0CombinedLocations[input.locationHint] : D0CombinedLocations.none).toString(16).padStart(3, '0').slice(-3);
99
+ // Shard Type (2 bytes)
100
+ hex += input.shardType.toString(16).padStart(2, '0').slice(-2);
101
+ // Suffix random (11 bytes)
102
+ hex += BufferHelpers.bufferToHexSync(input.suffixRandom.buffer).padStart(11, '0').slice(-11);
103
+ // Environment (1 byte)
104
+ hex += input.environment.toString(16).slice(-3);
105
+ // Stable random (32 bytes)
106
+ hex += BufferHelpers.bufferToHexSync(input.stableRandom.buffer).padStart(64, '0').slice(-64);
107
+ const blob = BufferHelpers.hexToBufferSync(hex);
108
+ return this.convertOutput.parse({
109
+ hex,
110
+ blob: Array.from(new Uint8Array(blob)),
111
+ base64: BufferHelpers.bufferToBase64Sync(blob, false),
112
+ base64url: BufferHelpers.bufferToBase64Sync(blob, true),
113
+ });
114
+ }
115
+ static suruConvert(_input) {
116
+ if (_input) {
117
+ // hex
118
+ return Promise.any([
119
+ SuruId.convertOutput.def.shape.hex.parseAsync(_input).then((hex) => BufferHelpers.hexToBuffer(hex).then((blob) => Promise.all([BufferHelpers.bufferToBase64(blob, false), BufferHelpers.bufferToBase64(blob, true)]).then(([base64, base64url]) => this.convertOutput.parseAsync({
120
+ hex,
121
+ blob: Array.from(new Uint8Array(blob)),
122
+ base64,
123
+ base64url,
124
+ })))),
125
+ ZodBlob.parseAsync(_input).then((blob) => Promise.all([BufferHelpers.bufferToHex(blob.buffer), BufferHelpers.bufferToBase64(blob.buffer, false), BufferHelpers.bufferToBase64(blob.buffer, true)]).then(([hex, base64, base64url]) => this.convertOutput.parseAsync({
126
+ hex,
127
+ blob: Array.from(new Uint8Array(blob)),
128
+ base64,
129
+ base64url,
130
+ }))),
131
+ ]).catch(() => Promise.any([
132
+ SuruId.convertOutput.def.shape.base64.parseAsync(_input).then((base64) => BufferHelpers.base64ToBuffer(base64).then((blob) => Promise.all([BufferHelpers.bufferToHex(blob), BufferHelpers.bufferToBase64(blob, true)]).then(([hex, base64url]) => this.convertOutput.parseAsync({
133
+ hex,
134
+ blob: Array.from(new Uint8Array(blob)),
135
+ base64,
136
+ base64url,
137
+ })))),
138
+ SuruId.convertOutput.def.shape.base64url.parseAsync(_input).then((base64url) => BufferHelpers.base64ToBuffer(base64url).then((blob) => Promise.all([BufferHelpers.bufferToHex(blob), BufferHelpers.bufferToBase64(blob, false)]).then(([hex, base64]) => this.convertOutput.parseAsync({
139
+ hex,
140
+ blob: Array.from(new Uint8Array(blob)),
141
+ base64,
142
+ base64url,
143
+ })))),
144
+ ]));
145
+ }
146
+ else {
147
+ // eslint-disable-next-line @typescript-eslint/require-await
148
+ return (async () => ({
149
+ hex: undefined,
150
+ blob: undefined,
151
+ base64: undefined,
152
+ base64url: undefined,
153
+ }))();
154
+ }
155
+ }
156
+ static suruConvertSync(_input) {
157
+ if (_input) {
158
+ try {
159
+ const hex = SuruId.convertOutput.def.shape.hex.parse(_input);
160
+ const blob = BufferHelpers.hexToBufferSync(hex);
161
+ const base64 = BufferHelpers.bufferToBase64Sync(blob, false);
162
+ const base64url = BufferHelpers.bufferToBase64Sync(blob, true);
163
+ return this.convertOutput.parse({
164
+ hex,
165
+ blob: Array.from(new Uint8Array(blob)),
166
+ base64,
167
+ base64url,
168
+ });
169
+ }
170
+ catch {
171
+ try {
172
+ const blob = ZodBlob.parse(_input);
173
+ const hex = BufferHelpers.bufferToHexSync(blob.buffer);
174
+ const base64 = BufferHelpers.bufferToBase64Sync(blob.buffer, false);
175
+ const base64url = BufferHelpers.bufferToBase64Sync(blob.buffer, true);
176
+ return this.convertOutput.parse({
177
+ hex,
178
+ blob: Array.from(new Uint8Array(blob)),
179
+ base64,
180
+ base64url,
181
+ });
182
+ }
183
+ catch {
184
+ try {
185
+ const base64 = SuruId.convertOutput.def.shape.base64.parse(_input);
186
+ const blob = BufferHelpers.base64ToBufferSync(base64);
187
+ const hex = BufferHelpers.bufferToHexSync(blob);
188
+ const base64url = BufferHelpers.bufferToBase64Sync(blob, true);
189
+ return this.convertOutput.parse({
190
+ hex,
191
+ blob: Array.from(new Uint8Array(blob)),
192
+ base64,
193
+ base64url,
194
+ });
195
+ }
196
+ catch {
197
+ const base64url = SuruId.convertOutput.def.shape.base64url.parse(_input);
198
+ const blob = BufferHelpers.base64ToBufferSync(base64url);
199
+ const hex = BufferHelpers.bufferToHexSync(blob);
200
+ const base64 = BufferHelpers.bufferToBase64Sync(blob, false);
201
+ return this.convertOutput.parse({
202
+ hex,
203
+ blob: Array.from(new Uint8Array(blob)),
204
+ base64,
205
+ base64url,
206
+ });
207
+ }
208
+ }
209
+ }
210
+ }
211
+ else {
212
+ return {
213
+ hex: undefined,
214
+ blob: undefined,
215
+ base64: undefined,
216
+ base64url: undefined,
217
+ };
218
+ }
219
+ }
220
+ static suruExtract(_input) {
221
+ if (_input) {
222
+ return this.suruConvert(_input).then(async ({ hex }) => {
223
+ // Extract fields from hex string (96 chars total)
224
+ let offset = 0;
225
+ // Version (1 char = 4 bits)
226
+ const version = parseInt(hex.slice(offset, offset + 1), 16);
227
+ offset += 1;
228
+ // Timestamp (11 chars)
229
+ const timestamp = parseInt(hex.slice(offset, offset + 11), 16);
230
+ const date = new Date(timestamp);
231
+ offset += 11;
232
+ // System Type (3 chars)
233
+ const systemType = parseInt(hex.slice(offset, offset + 3), 16);
234
+ offset += 3;
235
+ // Location (3 chars)
236
+ const locationValue = parseInt(hex.slice(offset, offset + 3), 16);
237
+ offset += 3;
238
+ // Find jurisdiction and hint from location value
239
+ let locationJurisdiction = null;
240
+ let locationHint = null;
241
+ // Map D0CombinedLocations values to jurisdiction/location enums
242
+ // Find the location key that matches the value
243
+ const locationKey = Object.entries(D0CombinedLocations).find(([, enumValue]) => Number(enumValue) === locationValue)?.[0];
244
+ if (locationKey && locationKey !== 'none') {
245
+ // Check if it's a jurisdiction
246
+ if (Object.values(DOJurisdictions).includes(locationKey)) {
247
+ locationJurisdiction = locationKey;
248
+ }
249
+ // Check if it's a location hint
250
+ if (Object.values(DOLocations).includes(locationKey)) {
251
+ locationHint = locationKey;
252
+ }
253
+ }
254
+ // Shard Type (2 chars)
255
+ const shardType = parseInt(hex.slice(offset, offset + 2), 16);
256
+ offset += 2;
257
+ // Suffix random (11 chars)
258
+ const suffixRandomHex = hex.slice(offset, offset + 11);
259
+ const suffixRandomBuffer = await BufferHelpers.hexToBuffer(suffixRandomHex);
260
+ const [suffixRandomBase64, suffixRandomBase64Url] = await Promise.all([BufferHelpers.bufferToBase64(suffixRandomBuffer, false), BufferHelpers.bufferToBase64(suffixRandomBuffer, true)]);
261
+ offset += 11;
262
+ // Environment (1 char)
263
+ const environment = parseInt(hex.slice(offset, offset + 1), 16);
264
+ offset += 1;
265
+ // Stable random (64 chars)
266
+ const stableRandomHex = hex.slice(offset, offset + 64);
267
+ const stableRandomBuffer = await BufferHelpers.hexToBuffer(stableRandomHex);
268
+ const [stableRandomBase64, stableRandomBase64Url] = await Promise.all([BufferHelpers.bufferToBase64(stableRandomBuffer, false), BufferHelpers.bufferToBase64(stableRandomBuffer, true)]);
269
+ return this.extractOutput.parseAsync({
270
+ version,
271
+ date,
272
+ systemType,
273
+ shardType,
274
+ locationJurisdiction,
275
+ locationHint,
276
+ suffixRandom: {
277
+ hex: suffixRandomHex,
278
+ base64: suffixRandomBase64,
279
+ base64url: suffixRandomBase64Url,
280
+ },
281
+ environment,
282
+ stableRandom: {
283
+ hex: stableRandomHex,
284
+ base64: stableRandomBase64,
285
+ base64url: stableRandomBase64Url,
286
+ },
287
+ });
288
+ });
289
+ }
290
+ else {
291
+ // eslint-disable-next-line @typescript-eslint/require-await
292
+ return (async () => ({
293
+ version: undefined,
294
+ date: undefined,
295
+ systemType: undefined,
296
+ shardType: undefined,
297
+ locationJurisdiction: undefined,
298
+ locationHint: undefined,
299
+ suffixRandom: undefined,
300
+ environment: undefined,
301
+ stableRandom: undefined,
302
+ }))();
303
+ }
304
+ }
305
+ static suruExtractSync(_input) {
306
+ if (_input) {
307
+ const { hex } = this.suruConvertSync(_input);
308
+ // Extract fields from hex string (96 chars total)
309
+ let offset = 0;
310
+ // Version (1 char = 4 bits)
311
+ const version = parseInt(hex.slice(offset, offset + 1), 16);
312
+ offset += 1;
313
+ // Timestamp (11 chars)
314
+ const timestamp = parseInt(hex.slice(offset, offset + 11), 16);
315
+ const date = new Date(timestamp);
316
+ offset += 11;
317
+ // System Type (3 chars)
318
+ const systemType = parseInt(hex.slice(offset, offset + 3), 16);
319
+ offset += 3;
320
+ // Location (3 chars)
321
+ const locationValue = parseInt(hex.slice(offset, offset + 3), 16);
322
+ offset += 3;
323
+ // Find jurisdiction and hint from location value
324
+ let locationJurisdiction = null;
325
+ let locationHint = null;
326
+ // Map D0CombinedLocations values to jurisdiction/location enums
327
+ // Find the location key that matches the value
328
+ const locationKey = Object.entries(D0CombinedLocations).find(([, enumValue]) => Number(enumValue) === locationValue)?.[0];
329
+ if (locationKey && locationKey !== 'none') {
330
+ // Check if it's a jurisdiction
331
+ if (Object.values(DOJurisdictions).includes(locationKey)) {
332
+ locationJurisdiction = locationKey;
333
+ }
334
+ // Check if it's a location hint
335
+ if (Object.values(DOLocations).includes(locationKey)) {
336
+ locationHint = locationKey;
337
+ }
338
+ }
339
+ // Shard Type (2 chars)
340
+ const shardType = parseInt(hex.slice(offset, offset + 2), 16);
341
+ offset += 2;
342
+ // Suffix random (11 chars)
343
+ const suffixRandomHex = hex.slice(offset, offset + 11);
344
+ const suffixRandomBuffer = BufferHelpers.hexToBufferSync(suffixRandomHex);
345
+ const suffixRandomBase64 = BufferHelpers.bufferToBase64Sync(suffixRandomBuffer, false);
346
+ const suffixRandomBase64Url = BufferHelpers.bufferToBase64Sync(suffixRandomBuffer, true);
347
+ offset += 11;
348
+ // Environment (1 char)
349
+ const environment = parseInt(hex.slice(offset, offset + 1), 16);
350
+ offset += 1;
351
+ // Stable random (64 chars)
352
+ const stableRandomHex = hex.slice(offset, offset + 64);
353
+ const stableRandomBuffer = BufferHelpers.hexToBufferSync(stableRandomHex);
354
+ const stableRandomBase64 = BufferHelpers.bufferToBase64Sync(stableRandomBuffer, false);
355
+ const stableRandomBase64Url = BufferHelpers.bufferToBase64Sync(stableRandomBuffer, true);
356
+ return this.extractOutput.parse({
357
+ version,
358
+ date,
359
+ systemType,
360
+ shardType,
361
+ locationJurisdiction,
362
+ locationHint,
363
+ suffixRandom: {
364
+ hex: suffixRandomHex,
365
+ base64: suffixRandomBase64,
366
+ base64url: suffixRandomBase64Url,
367
+ },
368
+ environment,
369
+ stableRandom: {
370
+ hex: stableRandomHex,
371
+ base64: stableRandomBase64,
372
+ base64url: stableRandomBase64Url,
373
+ },
374
+ });
375
+ }
376
+ else {
377
+ return {
378
+ version: undefined,
379
+ date: undefined,
380
+ systemType: undefined,
381
+ shardType: undefined,
382
+ locationJurisdiction: undefined,
383
+ locationHint: undefined,
384
+ suffixRandom: undefined,
385
+ environment: undefined,
386
+ stableRandom: undefined,
387
+ };
388
+ }
389
+ }
390
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chainfuse/helpers",
3
- "version": "4.0.5",
3
+ "version": "4.1.0",
4
4
  "description": "",
5
5
  "author": "ChainFuse",
6
6
  "homepage": "https://github.com/ChainFuse/packages/tree/main/packages/helpers#readme",
@@ -72,26 +72,22 @@
72
72
  "./net": {
73
73
  "import": "./dist/net.mjs",
74
74
  "types": "./dist/net.d.mts"
75
- },
76
- "./uuid8": {
77
- "import": "./dist/uuid8.mjs",
78
- "types": "./dist/uuid8.d.mts"
79
75
  }
80
76
  },
81
77
  "prettier": "@demosjarco/prettier-config",
82
78
  "dependencies": {
83
- "@chainfuse/types": "^3.0.8",
79
+ "@chainfuse/types": "^4.0.1",
84
80
  "@discordjs/rest": "^2.6.0",
85
81
  "chalk": "^5.6.2",
86
82
  "cloudflare": "^5.1.0",
87
83
  "drizzle-orm": "^0.44.5",
88
84
  "strip-ansi": "^7.1.2",
89
85
  "uuid": "^13.0.0",
90
- "zod": "^4.1.8"
86
+ "zod": "^4.1.11"
91
87
  },
92
88
  "devDependencies": {
93
- "@cloudflare/workers-types": "^4.20250913.0",
94
- "@types/node": "^22.18.4"
89
+ "@cloudflare/workers-types": "^4.20250923.0",
90
+ "@types/node": "^22.18.6"
95
91
  },
96
- "gitHead": "3bcadb3f4996a6725b5530d2dccd72dd0681c6b8"
92
+ "gitHead": "ab58de73242e411360ae80368ee2f69a5798c653"
97
93
  }
package/dist/uuid8.d.mts DELETED
@@ -1,37 +0,0 @@
1
- import { DOCombinedLocations } from '@chainfuse/types';
2
- import { ShardType } from '@chainfuse/types/d0';
3
- import * as z from 'zod/mini';
4
- export declare const v8Options: z.ZodMiniUnion<readonly [z.ZodMiniObject<{
5
- msecs: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniNumberFormat, z.ZodMiniPipe<z.ZodMiniDate<Date>, z.ZodMiniTransform<number, Date>>]>>;
6
- seq: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
7
- location: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniEnum<typeof DOCombinedLocations>>, z.ZodMiniTransform<string, DOCombinedLocations>>]>;
8
- shardType: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniEnum<typeof ShardType>>, z.ZodMiniTransform<string, ShardType>>]>;
9
- suffix: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>, z.ZodMiniTransform<string, Uint8Array<ArrayBuffer>>>]>;
10
- random: z.ZodMiniOptional<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
11
- }, z.core.$strip>, z.ZodMiniObject<{
12
- msecs: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniNumberFormat, z.ZodMiniPipe<z.ZodMiniDate<Date>, z.ZodMiniTransform<number, Date>>]>>;
13
- seq: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
14
- location: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniEnum<typeof DOCombinedLocations>>, z.ZodMiniTransform<string, DOCombinedLocations>>]>;
15
- shardType: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniEnum<typeof ShardType>>, z.ZodMiniTransform<string, ShardType>>]>;
16
- suffix: z.ZodMiniUnion<readonly [z.ZodMiniDefault<z.ZodMiniCustomStringFormat<"hex">>, z.ZodMiniPipe<z.ZodMiniDefault<z.ZodMiniCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>, z.ZodMiniTransform<string, Uint8Array<ArrayBuffer>>>]>;
17
- rng: z.ZodMiniOptional<z.ZodMiniPipe<z.ZodMiniUnknown, z.ZodMiniTransform<() => Uint8Array, unknown>>>;
18
- }, z.core.$strip>]>;
19
- export type Version8Options = z.input<typeof v8Options>;
20
- /**
21
- * Generates a UUID version 8 with custom fields for location, shard type, and suffix.
22
- *
23
- * This function creates a UUID v8 by starting with a UUID v7 and then injecting custom fields into specific positions to encode regional information, shard types, and additional suffixes for distributed system identification.
24
- *
25
- * @param options - Configuration options for UUID generation
26
- * @param options.msecs - RFC "timestamp" field - milliseconds since epoch or Date object
27
- * @param options.seq - 32-bit sequence number (0 - 0xffffffff) for uniqueness within same millisecond
28
- * @param options.location - Location identifier as hex string or DOCombinedLocations enum
29
- * @param options.shardType - Shard type as hex string or ShardType enum
30
- * @param options.suffix - Custom suffix as hex string or Uint8Array of 2 bytes
31
- * @param options.random - Array of 16 random bytes for UUID generation
32
- * @param options.rng - Alternative random number generator function
33
- *
34
- * @returns A UUID v8 string with embedded location, shard type, and suffix information
35
- */
36
- export declare function v8(_options?: Version8Options): string;
37
- export default v8;
package/dist/uuid8.mjs DELETED
@@ -1,78 +0,0 @@
1
- import { DOCombinedLocations } from '@chainfuse/types';
2
- import { ShardType } from '@chainfuse/types/d0';
3
- import { v7 } from 'uuid';
4
- import * as z from 'zod/mini';
5
- import { BufferHelpersInternals } from "./bufferInternals.mjs";
6
- import { Helpers } from "./common.mjs";
7
- const v8OptionsBase = z.object({
8
- /**
9
- * RFC "timestamp" field
10
- */
11
- msecs: z.optional(z.union([
12
- z.int().check(z.nonnegative()),
13
- // Allow converting from Date object
14
- z.pipe(z.date(), z.transform((date) => date.getTime())),
15
- ])),
16
- /**
17
- * 32-bit sequence Number between 0 - 0xffffffff. This may be provided to help ensure uniqueness for UUIDs generated within the same millisecond time interval. Default = random value.
18
- */
19
- seq: z.optional(z.int().check(z.minimum(0), z.maximum(0xffffffff))),
20
- location: z.union([
21
- //
22
- z._default(z.hex().check(z.length(2)), '00'),
23
- z.pipe(z._default(z.enum(DOCombinedLocations), DOCombinedLocations.none), z.transform((l) => l.toString(16).padStart(2, '0').slice(-2))),
24
- ]),
25
- shardType: z.union([
26
- //
27
- z._default(z.hex().check(z.length(1)), '0'),
28
- z.pipe(z._default(z.enum(ShardType), ShardType.Director), z.transform((st) => st.toString(16).padStart(1, '0'))),
29
- ]),
30
- suffix: z.union([
31
- z._default(z.hex().check(z.length(3)), '000'),
32
- // It's technically 1.5 bytes, but we round up to nearest integer
33
- z.pipe(z._default(z.instanceof(Uint8Array).check(z.refine((arr) => arr.byteLength === 2, { message: 'suffix must be a Uint8Array of 2 bytes' })), new Uint8Array(2)), z.transform((arr) => BufferHelpersInternals.browser_bufferToHex(arr.buffer).padStart(3, '0').slice(-3))),
34
- ]),
35
- });
36
- export const v8Options = z.union([
37
- z.extend(v8OptionsBase, {
38
- /**
39
- * Array of 16 random bytes (0-255) used to generate other fields
40
- */
41
- random: z.optional(z.instanceof(Uint8Array).check(z.refine((arr) => arr.byteLength === 16, { message: '`random` must be a Uint8Array of 16 random bytes' }))),
42
- }),
43
- z.extend(v8OptionsBase, {
44
- /**
45
- * Alternative to options.random, a Function that returns an Array of 16 random bytes (0-255)
46
- */
47
- rng: z.optional(z.pipe(z.unknown(), z.transform((fn) => fn))),
48
- }),
49
- ]);
50
- /**
51
- * Generates a UUID version 8 with custom fields for location, shard type, and suffix.
52
- *
53
- * This function creates a UUID v8 by starting with a UUID v7 and then injecting custom fields into specific positions to encode regional information, shard types, and additional suffixes for distributed system identification.
54
- *
55
- * @param options - Configuration options for UUID generation
56
- * @param options.msecs - RFC "timestamp" field - milliseconds since epoch or Date object
57
- * @param options.seq - 32-bit sequence number (0 - 0xffffffff) for uniqueness within same millisecond
58
- * @param options.location - Location identifier as hex string or DOCombinedLocations enum
59
- * @param options.shardType - Shard type as hex string or ShardType enum
60
- * @param options.suffix - Custom suffix as hex string or Uint8Array of 2 bytes
61
- * @param options.random - Array of 16 random bytes for UUID generation
62
- * @param options.rng - Alternative random number generator function
63
- *
64
- * @returns A UUID v8 string with embedded location, shard type, and suffix information
65
- */
66
- export function v8(_options) {
67
- const options = v8Options.parse(_options ?? {});
68
- // 36 character string including hyphens
69
- const uuid7 = v7(options);
70
- // Swap version
71
- const uuid8 = Helpers.replaceByIndex(uuid7, 14, 15, '8');
72
- // Inject
73
- const uuid8Suffix = Helpers.replaceByIndex(uuid8, 15, 18, options.suffix);
74
- const uuid8SuffixLocation = Helpers.replaceByIndex(uuid8Suffix, 20, 22, options.location);
75
- const uuid8SuffixLocationShard = Helpers.replaceByIndex(uuid8SuffixLocation, 22, 23, options.shardType);
76
- return uuid8SuffixLocationShard;
77
- }
78
- export default v8;