@tnid/core 0.0.2 → 0.0.4

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
@@ -1,4 +1,4 @@
1
- # TNID Typescript
1
+ # @tnid/core
2
2
 
3
3
  Type-safe, named, unique identifiers (TNIDs) for TypeScript.
4
4
 
@@ -23,14 +23,12 @@ deno add npm:@tnid/core
23
23
 
24
24
  ## Platform Support
25
25
 
26
- | Platform | Minimum Version |
27
- | -------- | --------------- |
28
- | Node.js | 20+ |
29
- | Deno | 1.0+ |
30
- | Bun | 1.0+ |
31
- | Browsers | ES2020+ |
26
+ Requires `globalThis.crypto` (Web Crypto API):
32
27
 
33
- Requires `globalThis.crypto` (Web Crypto API).
28
+ - Node.js 20+
29
+ - Deno 1.0+
30
+ - Bun 1.0+
31
+ - Modern browsers (ES2020+)
34
32
 
35
33
  ## Quick Start
36
34
 
@@ -65,8 +63,7 @@ const fromUuid: UserId = UserId.parseUuidString(uuid);
65
63
  - **UUID compatible**: Store in any UUID column, use with existing UUID tooling
66
64
  - **Time-ordered (V0)**: Sortable by creation time, like UUIDv7
67
65
  - **High-entropy (V1)**: Maximum randomness, like UUIDv4
68
- - **String-backed**: At runtime, TNIDs are their string representation (e.g.
69
- `user.Br2flcNDfF6LYICnT`). Use as Map keys, in JSON, or compare with `===`
66
+ - **String-backed**: At runtime, TNIDs are their string representation
70
67
 
71
68
  ```typescript
72
69
  const id = UserId.new_v0();
@@ -82,8 +79,6 @@ JSON.stringify({ userId: id }); // {"userId":"user.Br2flcNDfF6LYICnT"}
82
79
  id === otherUserId; // true/false
83
80
  ```
84
81
 
85
- ---
86
-
87
82
  ## API Reference
88
83
 
89
84
  ### Exports
@@ -92,9 +87,9 @@ id === otherUserId; // true/false
92
87
  import {
93
88
  Case, // "lower" | "upper"
94
89
  DynamicTnid, // Runtime TNID operations (type + namespace)
95
- Tnid, // Factory creator function
96
- NamedTnid, // Named TNID interface
97
- TnidType, // Type helper to extract ID type from factory
90
+ Tnid, // NamedTnid creator function
91
+ NamedTnid, // NamedTnid interface
92
+ TnidType, // Type helper to extract ID type
98
93
  // Types only:
99
94
  TnidValue, // Branded string type
100
95
  TnidVariant, // "v0" | "v1" | "v2" | "v3"
@@ -102,11 +97,9 @@ import {
102
97
  } from "@tnid/core";
103
98
  ```
104
99
 
105
- ---
106
-
107
100
  ### `Tnid(name)`
108
101
 
109
- Creates a factory for TNIDs with a specific name. The name is validated at
102
+ Creates a `NamedTnid` for a specific name. The name is validated at
110
103
  **compile time**.
111
104
 
112
105
  ```typescript
@@ -117,90 +110,57 @@ const ItemId = Tnid("item");
117
110
 
118
111
  #### Name Rules
119
112
 
120
- - **Length**: 1-4 characters
121
- - **Valid characters**: `0-4` and `a-z` (31 characters total)
122
- - **Case**: lowercase only
113
+ - 1-4 characters
114
+ - Only `0-4` and `a-z` (31 characters total)
115
+ - Lowercase only
123
116
 
124
117
  ```typescript
125
118
  // Valid names
126
- Tnid("user"); //
127
- Tnid("a"); //
128
- Tnid("1234"); //
129
- Tnid("a1b2"); //
119
+ Tnid("user"); // OK
120
+ Tnid("a"); // OK
121
+ Tnid("1234"); // OK
122
+ Tnid("a1b2"); // OK
130
123
 
131
124
  // Compile errors
132
- Tnid("users"); // too long (max 4)
133
- Tnid("User"); // uppercase not allowed
134
- Tnid("a-b"); // hyphen not allowed
135
- Tnid("5"); // only digits 0-4
136
- Tnid(""); // empty not allowed
125
+ Tnid("users"); // too long (max 4)
126
+ Tnid("User"); // uppercase not allowed
127
+ Tnid("a-b"); // hyphen not allowed
128
+ Tnid("5"); // only digits 0-4
129
+ Tnid(""); // empty not allowed
137
130
  ```
138
131
 
139
- ---
140
-
141
132
  ### `NamedTnid<Name>` (returned by `Tnid()`)
142
133
 
143
- The object returned by `Tnid(name)` has these methods:
144
-
145
- #### Properties
146
-
147
- | Property | Type | Description |
148
- | -------- | ------ | ------------------------------------------ |
149
- | `name` | `Name` | The TNID name this creates IDs for |
150
-
151
- #### Generation Methods
152
-
153
- | Method | Returns | Description |
154
- | ---------------------------------------- | ----------------- | ------------------------------------------------- |
155
- | `new_v0()` | `TnidValue<Name>` | Generate a time-ordered ID (like UUIDv7) |
156
- | `new_v1()` | `TnidValue<Name>` | Generate a high-entropy random ID (like UUIDv4) |
157
- | `v0_from_parts(timestampMs, randomBits)` | `TnidValue<Name>` | Create V0 from explicit parts (for testing) |
158
- | `v1_from_parts(randomBits)` | `TnidValue<Name>` | Create V1 from explicit random bits (for testing) |
159
-
160
- #### Parsing Methods
161
-
162
- | Method | Returns | Throws | Description |
163
- | ----------------------- | ----------------- | -------------------------------- | ----------------------- |
164
- | `parse(s)` | `TnidValue<Name>` | If invalid or name mismatch | Parse a TNID string |
165
- | `parseUuidString(uuid)` | `TnidValue<Name>` | If invalid UUID or name mismatch | Parse a UUID hex string |
166
-
167
- #### Utility Methods
168
-
169
- | Method | Returns | Description |
170
- | ------------------------- | ------------- | -------------------------------------- |
171
- | `variant(id)` | `TnidVariant` | Get the variant (`"v0"`, `"v1"`, etc.) |
172
- | `toUuidString(id, case?)` | `string` | Convert to UUID hex format |
173
- | `nameHex()` | `string` | Get the name as a 5-char hex string |
174
-
175
- #### Example
134
+ #### Generation
176
135
 
177
136
  ```typescript
178
137
  const UserId = Tnid("user");
179
138
  type UserId = TnidType<typeof UserId>;
180
139
 
181
- // Generation
182
- const id: UserId = UserId.new_v0(); // "user.Br2flcNDfF6LYICnT"
183
- const id2: UserId = UserId.new_v1(); // "user.EUBcUw4T9x3KNOll-"
140
+ UserId.new_v0(); // time-ordered ID
141
+ UserId.new_v1(); // high-entropy random ID
142
+ UserId.v0_from_parts(1234567890n, 0n); // V0 with explicit timestamp/random
143
+ UserId.v1_from_parts(0n); // V1 with explicit random bits
144
+ ```
184
145
 
185
- // Parsing
186
- const parsed: UserId = UserId.parse("user.Br2flcNDfF6LYICnT");
187
- const fromUuid: UserId = UserId.parseUuidString(
188
- "d6157329-4640-8e30-8012-345678901234",
189
- );
190
-
191
- // Utilities
192
- UserId.variant(id); // "v0"
193
- UserId.toUuidString(id); // "d6157329-4640-8e30-8012-..."
194
- UserId.toUuidString(id, "upper"); // "D6157329-4640-8E30-8012-..."
195
- UserId.nameHex(); // "d6157"
196
-
197
- // Property
198
- UserId.name; // "user"
146
+ #### Parsing
147
+
148
+ ```typescript
149
+ UserId.parse("user.Br2flcNDfF6LYICnT"); // parse TNID string
150
+ UserId.parseUuidString("d6157329-4640-8e30-..."); // parse UUID hex string
199
151
  ```
200
152
 
201
- ---
153
+ #### Inspection and Conversion
154
+
155
+ ```typescript
156
+ UserId.name; // "user" - the TNID name
157
+ UserId.variant(id); // "v0" or "v1" - get the variant
158
+ UserId.toUuidString(id); // "d6157329-4640-8e30-..." - convert to UUID
159
+ UserId.toUuidString(id, "upper"); // "D6157329-4640-8E30-..." - uppercase UUID
160
+ UserId.nameHex(); // "d6157" - name as 5-char hex
161
+ ```
202
162
 
203
- ### `TnidType<Factory>`
163
+ ### `TnidType<T>`
204
164
 
205
165
  Type helper to extract the `TnidValue` type from a `NamedTnid`.
206
166
 
@@ -216,131 +176,47 @@ function getUser(id: UserId): User { ... }
216
176
  function getPost(id: PostId): Post { ... }
217
177
  ```
218
178
 
219
- ---
220
-
221
179
  ### `DynamicTnid`
222
180
 
223
- For working with TNIDs when the name isn't known at compile time. This is both a
224
- **type** and a **namespace**.
225
-
226
- #### As a Type
227
-
228
- `DynamicTnid` accepts any TNID regardless of name:
181
+ For working with TNIDs when the name isn't known at compile time.
229
182
 
230
183
  ```typescript
184
+ // As a type - accepts any TNID
231
185
  function logAnyId(id: DynamicTnid) {
232
186
  console.log(DynamicTnid.getName(id), id);
233
187
  }
234
188
 
235
- const userId: UserId = UserId.new_v0();
236
- const postId: PostId = PostId.new_v0();
189
+ // Generation with runtime names
190
+ DynamicTnid.new_v0("user"); // time-ordered (alias: new_time_ordered)
191
+ DynamicTnid.new_v1("user"); // high-entropy (alias: new_high_entropy)
237
192
 
238
- logAnyId(userId); // works
239
- logAnyId(postId); // works
240
- ```
193
+ // Generation with explicit values (useful for testing/migrations)
194
+ DynamicTnid.new_v0_with_time("user", new Date("2024-01-15"));
195
+ DynamicTnid.new_v0_with_parts("user", 1705312800000n, 123n);
196
+ DynamicTnid.new_v1_with_random("user", 0x123456789abcdef0123456789n);
241
197
 
242
- #### Namespace Methods
198
+ // Parsing any TNID
199
+ DynamicTnid.parse("post.EUBcUw4T9x3KNOll-");
200
+ DynamicTnid.parse_uuid_string("d6157329-4640-...");
243
201
 
244
- ##### Generation
245
-
246
- | Method | Returns | Description |
247
- | ---------------------------------------------- | ------------- | ------------------------------------------ |
248
- | `new_v0(name)` | `DynamicTnid` | Generate time-ordered ID with runtime name |
249
- | `new_v1(name)` | `DynamicTnid` | Generate high-entropy ID with runtime name |
250
- | `new_time_ordered(name)` | `DynamicTnid` | Alias for `new_v0` |
251
- | `new_high_entropy(name)` | `DynamicTnid` | Alias for `new_v1` |
252
- | `new_v0_with_time(name, date)` | `DynamicTnid` | V0 with specific timestamp |
253
- | `new_v0_with_parts(name, epochMillis, random)` | `DynamicTnid` | V0 with explicit parts |
254
- | `new_v1_with_random(name, randomBits)` | `DynamicTnid` | V1 with explicit random bits |
255
-
256
- ##### Parsing
257
-
258
- | Method | Returns | Throws | Description |
259
- | ------------------------- | ------------- | ---------- | --------------------- |
260
- | `parse(s)` | `DynamicTnid` | If invalid | Parse any TNID string |
261
- | `parse_uuid_string(uuid)` | `DynamicTnid` | If invalid | Parse UUID to TNID |
262
-
263
- ##### Inspection
264
-
265
- | Method | Returns | Description |
266
- | ------------------------- | ------------- | ------------------------ |
267
- | `getName(id)` | `string` | Extract the name portion |
268
- | `getNameHex(id)` | `string` | Get name as 5-char hex |
269
- | `getVariant(id)` | `TnidVariant` | Get the variant |
270
- | `toUuidString(id, case?)` | `string` | Convert to UUID hex |
271
-
272
- #### Example
273
-
274
- ```typescript
275
- // Runtime name - useful for dynamic/generic code
276
- const entityType = "user"; // from config, API, etc.
277
- const id = DynamicTnid.new_v0(entityType);
278
-
279
- // Parse any TNID without knowing its type
280
- const unknown = DynamicTnid.parse("post.EUBcUw4T9x3KNOll-");
281
- console.log(DynamicTnid.getName(unknown)); // "post"
282
- console.log(DynamicTnid.getVariant(unknown)); // "v1"
283
-
284
- // Create with specific timestamp
285
- const backdated = DynamicTnid.new_v0_with_time("log", new Date("2024-01-01"));
286
-
287
- // Convert to UUID
288
- const uuid = DynamicTnid.toUuidString(id);
202
+ // Inspection
203
+ DynamicTnid.getName(id); // "user"
204
+ DynamicTnid.getNameHex(id); // "d6157"
205
+ DynamicTnid.getVariant(id); // "v0" or "v1"
206
+ DynamicTnid.toUuidString(id); // UUID hex string
289
207
  ```
290
208
 
291
- ---
292
-
293
209
  ### `UuidLike`
294
210
 
295
- For working with UUID hex strings that may or may not be valid TNIDs. This is
296
- both a **type** and a **namespace**.
297
-
298
- #### As a Type
299
-
300
- `UuidLike` represents any valid UUID hex string (format:
301
- `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`):
211
+ For working with UUID hex strings that may or may not be valid TNIDs.
302
212
 
303
213
  ```typescript
304
- function storeInDatabase(uuid: UuidLike) { ... }
214
+ UuidLike.fromTnid(id); // convert TNID to UUID string
215
+ UuidLike.parse(s); // parse any UUID (validates format only)
216
+ UuidLike.toTnid(uuid); // convert UUID to TNID (throws if invalid)
217
+ UuidLike.toUpperCase(uuid); // convert to uppercase
305
218
  ```
306
219
 
307
- #### Namespace Methods
308
-
309
- | Method | Returns | Throws | Description |
310
- | ------------------- | ------------- | ------------------- | ----------------------------------- |
311
- | `fromTnid(id)` | `UuidLike` | - | Convert TNID to UUID string |
312
- | `parse(s)` | `UuidLike` | If invalid format | Parse any UUID string (format only) |
313
- | `toTnid(uuid)` | `DynamicTnid` | If not a valid TNID | Convert UUID to TNID |
314
- | `toUpperCase(uuid)` | `UuidLike` | - | Convert to uppercase |
315
-
316
- #### Example
317
-
318
- ```typescript
319
- const UserId = Tnid("user");
320
- const id = UserId.new_v0();
321
-
322
- // TNID to UUID
323
- const uuid: UuidLike = UuidLike.fromTnid(id);
324
- // "d6157329-4640-8e30-8012-345678901234"
325
-
326
- // Parse any UUID (doesn't validate TNID structure)
327
- const anyUuid = UuidLike.parse("550e8400-e29b-41d4-a716-446655440000");
328
-
329
- // Convert back to TNID (validates it's a valid TNID)
330
- try {
331
- const tnid = UuidLike.toTnid(uuid); // works
332
- const fail = UuidLike.toTnid(anyUuid); // throws - not a TNID
333
- } catch (e) {
334
- console.log("Not a valid TNID");
335
- }
336
-
337
- // Case conversion
338
- const upper = UuidLike.toUpperCase(uuid);
339
- // "D6157329-4640-8E30-8012-345678901234"
340
- ```
341
-
342
- ---
343
-
344
220
  ## Variants
345
221
 
346
222
  ### V0 (Time-Ordered)
@@ -349,23 +225,11 @@ const upper = UuidLike.toUpperCase(uuid);
349
225
  - 57 bits: random
350
226
  - **Use case**: When you need chronological sorting (logs, events, feeds)
351
227
 
352
- ```typescript
353
- const id = UserId.new_v0();
354
- // IDs created later sort after earlier ones
355
- ```
356
-
357
228
  ### V1 (High-Entropy)
358
229
 
359
230
  - 100 bits: random
360
231
  - **Use case**: When you need maximum uniqueness/unpredictability
361
232
 
362
- ```typescript
363
- const id = UserId.new_v1();
364
- // Maximum entropy, no time component
365
- ```
366
-
367
- ---
368
-
369
233
  ## Type Safety
370
234
 
371
235
  Different TNID types are completely incompatible at compile time:
@@ -380,44 +244,31 @@ const userId: UserId = UserId.new_v0();
380
244
  const postId: PostId = PostId.new_v0();
381
245
 
382
246
  // Compile errors - types don't match
383
- const wrong1: UserId = postId; //
384
- const wrong2: PostId = userId; //
247
+ const wrong1: UserId = postId; // Error
248
+ const wrong2: PostId = userId; // Error
385
249
  function getUser(id: UserId) { ... }
386
- getUser(postId); //
250
+ getUser(postId); // Error
387
251
 
388
252
  // DynamicTnid accepts any TNID
389
- const dynamic: DynamicTnid = userId; //
390
- const dynamic2: DynamicTnid = postId; //
253
+ const dynamic: DynamicTnid = userId; // OK
254
+ const dynamic2: DynamicTnid = postId; // OK
391
255
  ```
392
256
 
393
- ### Preventing Forgery
394
-
395
257
  Plain strings cannot be assigned to TNID types:
396
258
 
397
259
  ```typescript
398
- const UserId = Tnid("user");
399
- type UserId = TnidType<typeof UserId>;
400
-
401
260
  // Compile errors - plain strings not allowed
402
- const fake1: UserId = "user.Br2flcNDfF6LYICnT"; //
403
- const fake2: UserId = someString; // ✗
261
+ const fake: UserId = "user.Br2flcNDfF6LYICnT"; // Error
404
262
 
405
263
  // Must use parse() or new_*() to get a valid TNID
406
- const valid: UserId = UserId.parse("user.Br2flcNDfF6LYICnT"); //
264
+ const valid: UserId = UserId.parse("user.Br2flcNDfF6LYICnT"); // OK
407
265
  ```
408
266
 
409
- ---
410
-
411
267
  ## UUID Compatibility
412
268
 
413
- TNIDs are valid UUIDv8 identifiers. You can:
414
-
415
- - Store in UUID database columns
416
- - Use with UUID-aware tools and libraries
417
- - Convert freely between TNID and UUID formats
269
+ TNIDs are valid UUIDv8 identifiers:
418
270
 
419
271
  ```typescript
420
- const UserId = Tnid("user");
421
272
  const id = UserId.new_v0();
422
273
 
423
274
  // To UUID
@@ -426,94 +277,14 @@ const uuid = UserId.toUuidString(id);
426
277
 
427
278
  // From UUID
428
279
  const back = UserId.parseUuidString(uuid);
429
- // back === id
430
280
 
431
281
  // Store in database as UUID
432
282
  await db.query("INSERT INTO users (id) VALUES ($1)", [uuid]);
433
-
434
- // Retrieve and convert back
435
- const row = await db.query("SELECT id FROM users WHERE ...");
436
- const userId = UserId.parseUuidString(row.id);
437
- ```
438
-
439
- ---
440
-
441
- ## Common Patterns
442
-
443
- ### Define ID types for your domain
444
-
445
- ```typescript
446
- // ids.ts
447
- import { Tnid, TnidType } from "@tnid/core";
448
-
449
- export const UserId = Tnid("user");
450
- export type UserId = TnidType<typeof UserId>;
451
-
452
- export const PostId = Tnid("post");
453
- export type PostId = TnidType<typeof PostId>;
454
-
455
- export const OrgId = Tnid("org");
456
- export type OrgId = TnidType<typeof OrgId>;
457
- ```
458
-
459
- ### Use in function signatures
460
-
461
- ```typescript
462
- import { PostId, UserId } from "./ids";
463
-
464
- interface Post {
465
- id: PostId;
466
- authorId: UserId;
467
- title: string;
468
- }
469
-
470
- function createPost(authorId: UserId, title: string): Post {
471
- return {
472
- id: PostId.new_v0(),
473
- authorId,
474
- title,
475
- };
476
- }
477
- ```
478
-
479
- ### Generic functions with DynamicTnid
480
-
481
- ```typescript
482
- import { DynamicTnid } from "@tnid/core";
483
-
484
- function logEntity(id: DynamicTnid) {
485
- const name = DynamicTnid.getName(id);
486
- const variant = DynamicTnid.getVariant(id);
487
- console.log(`[${name}:${variant}] ${id}`);
488
- }
489
-
490
- // Works with any TNID
491
- logEntity(userId); // "[user:v0] user.Br2..."
492
- logEntity(postId); // "[post:v1] post.EU..."
493
283
  ```
494
284
 
495
- ### Parsing from external sources
496
-
497
- ```typescript
498
- import { UserId } from "./ids";
499
-
500
- // From API request
501
- app.get("/users/:id", (req, res) => {
502
- try {
503
- const id = UserId.parse(req.params.id);
504
- const user = await getUser(id);
505
- res.json(user);
506
- } catch {
507
- res.status(400).json({ error: "Invalid user ID" });
508
- }
509
- });
510
-
511
- // From database UUID column
512
- const row = await db.query("SELECT id FROM users WHERE email = $1", [email]);
513
- const userId = UserId.parseUuidString(row.id);
514
- ```
285
+ ## Related Packages
515
286
 
516
- ---
287
+ - **@tnid/encryption** - Format-preserving encryption to convert V0 (time-ordered) to V1 (random-looking) IDs
517
288
 
518
289
  ## License
519
290
 
package/esm/dynamic.d.ts CHANGED
@@ -3,34 +3,36 @@ import type { Case, TnidValue, TnidVariant } from "./types.js";
3
3
  export type DynamicTnid = TnidValue<string>;
4
4
  declare function getTnidVariantImpl(id: DynamicTnid): TnidVariant;
5
5
  declare function toUuidStringImpl(id: DynamicTnid, upperCase?: boolean): string;
6
- /** Static methods for working with any TNID regardless of name. */
7
- export declare const DynamicTnid: {
6
+ /** Interface for DynamicTnid static methods. */
7
+ export interface DynamicTnidNamespace {
8
8
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
9
- readonly new_v0: (name: string) => DynamicTnid;
9
+ new_v0(name: string): DynamicTnid;
10
10
  /** Alias for new_v0. */
11
- readonly new_time_ordered: (name: string) => DynamicTnid;
11
+ new_time_ordered(name: string): DynamicTnid;
12
12
  /** Generate a new time-sortable TNID with a specific timestamp. */
13
- readonly new_v0_with_time: (name: string, time: Date) => DynamicTnid;
13
+ new_v0_with_time(name: string, time: Date): DynamicTnid;
14
14
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
15
- readonly new_v0_with_parts: (name: string, epochMillis: bigint, random: bigint) => DynamicTnid;
15
+ new_v0_with_parts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
16
16
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
17
- readonly new_v1: (name: string) => DynamicTnid;
17
+ new_v1(name: string): DynamicTnid;
18
18
  /** Alias for new_v1. */
19
- readonly new_high_entropy: (name: string) => DynamicTnid;
19
+ new_high_entropy(name: string): DynamicTnid;
20
20
  /** Generate a new high-entropy TNID with explicit random bits. */
21
- readonly new_v1_with_random: (name: string, randomBits: bigint) => DynamicTnid;
21
+ new_v1_with_random(name: string, randomBits: bigint): DynamicTnid;
22
22
  /** Parse any valid TNID string. */
23
- readonly parse: (s: string) => DynamicTnid;
23
+ parse(s: string): DynamicTnid;
24
24
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
25
- readonly parse_uuid_string: (uuid: string) => DynamicTnid;
25
+ parse_uuid_string(uuid: string): DynamicTnid;
26
26
  /** Get the name from a TNID. */
27
- readonly getName: (id: DynamicTnid) => string;
27
+ getName(id: DynamicTnid): string;
28
28
  /** Get the name encoded as a 5-character hex string. */
29
- readonly getNameHex: (id: DynamicTnid) => string;
29
+ getNameHex(id: DynamicTnid): string;
30
30
  /** Get the variant of a TNID. */
31
- readonly getVariant: (id: DynamicTnid) => TnidVariant;
31
+ getVariant(id: DynamicTnid): TnidVariant;
32
32
  /** Convert to UUID hex string format. */
33
- readonly toUuidString: (id: DynamicTnid, caseFormat?: Case) => string;
34
- };
33
+ toUuidString(id: DynamicTnid, caseFormat?: Case): string;
34
+ }
35
+ /** Static methods for working with any TNID regardless of name. */
36
+ export declare const DynamicTnid: DynamicTnidNamespace;
35
37
  export { getTnidVariantImpl, toUuidStringImpl, };
36
38
  //# sourceMappingURL=dynamic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,mEAAmE;AACnE,eAAO,MAAM,WAAW;IACtB,kFAAkF;4BACrE,MAAM,KAAG,WAAW;IAYjC,wBAAwB;sCACD,MAAM,KAAG,WAAW;IAI3C,mEAAmE;sCAC5C,MAAM,QAAQ,IAAI,KAAG,WAAW;IAavD,uFAAuF;uCAE/E,MAAM,eACC,MAAM,UACX,MAAM,KACb,WAAW;IAYd,iFAAiF;4BACpE,MAAM,KAAG,WAAW;IAYjC,wBAAwB;sCACD,MAAM,KAAG,WAAW;IAI3C,kEAAkE;wCACzC,MAAM,cAAc,MAAM,KAAG,WAAW;IAYjE,mCAAmC;wBAC1B,MAAM,KAAG,WAAW;IAI7B,6EAA6E;uCACrD,MAAM,KAAG,WAAW;IAI5C,gCAAgC;2BACpB,WAAW,KAAG,MAAM;IAIhC,wDAAwD;8BACzC,WAAW,KAAG,MAAM;IAInC,iCAAiC;8BAClB,WAAW,KAAG,WAAW;IAIxC,yCAAyC;gCACxB,WAAW,eAAc,IAAI,KAAa,MAAM;CAGzD,CAAC;AAGX,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,mEAAmE;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACxD,uFAAuF;IACvF,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAClF,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,kEAAkE;IAClE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,mCAAmC;IACnC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA8GzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
package/esm/dynamic.js CHANGED
@@ -80,9 +80,6 @@ function parseDynamicUuidStringImpl(uuid) {
80
80
  }
81
81
  return valueToTnidString(value);
82
82
  }
83
- // -----------------------------------------------------------------------------
84
- // DynamicTnid Namespace
85
- // -----------------------------------------------------------------------------
86
83
  /** Static methods for working with any TNID regardless of name. */
87
84
  export const DynamicTnid = {
88
85
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
package/esm/uuidlike.d.ts CHANGED
@@ -3,15 +3,17 @@ import type { DynamicTnid } from "./dynamic.js";
3
3
  export type UuidLike = string & {
4
4
  __uuidlike: true;
5
5
  };
6
- /** Wrapper for UUID hex strings that may or may not be valid TNIDs. */
7
- export declare const UuidLike: {
6
+ /** Interface for UuidLike static methods. */
7
+ export interface UuidLikeNamespace {
8
8
  /** Create from a TNID (always valid). */
9
- readonly fromTnid: (id: DynamicTnid) => UuidLike;
9
+ fromTnid(id: DynamicTnid): UuidLike;
10
10
  /** Parse UUID hex string (format validation only, not TNID validation). */
11
- readonly parse: (s: string) => UuidLike;
11
+ parse(s: string): UuidLike;
12
12
  /** Try to convert to DynamicTnid (validates TNID structure). */
13
- readonly toTnid: (uuid: UuidLike) => DynamicTnid;
13
+ toTnid(uuid: UuidLike): DynamicTnid;
14
14
  /** Format as uppercase UUID hex string. */
15
- readonly toUpperCase: (uuid: UuidLike) => UuidLike;
16
- };
15
+ toUpperCase(uuid: UuidLike): UuidLike;
16
+ }
17
+ /** Wrapper for UUID hex strings that may or may not be valid TNIDs. */
18
+ export declare const UuidLike: UuidLikeNamespace;
17
19
  //# sourceMappingURL=uuidlike.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uuidlike.d.ts","sourceRoot":"","sources":["../src/uuidlike.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,oGAAoG;AACpG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,CAAC;AAWrD,uEAAuE;AACvE,eAAO,MAAM,QAAQ;IACnB,yCAAyC;4BAC5B,WAAW,KAAG,QAAQ;IAInC,2EAA2E;wBAClE,MAAM,KAAG,QAAQ;IAQ1B,gEAAgE;4BACnD,QAAQ,KAAG,WAAW;IAanC,2CAA2C;iCACzB,QAAQ,KAAG,QAAQ;CAG7B,CAAC"}
1
+ {"version":3,"file":"uuidlike.d.ts","sourceRoot":"","sources":["../src/uuidlike.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,oGAAoG;AACpG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,CAAC;AAWrD,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,WAAW,GAAG,QAAQ,CAAC;IACpC,2EAA2E;IAC3E,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,gEAAgE;IAChE,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpC,2CAA2C;IAC3C,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACvC;AAED,uEAAuE;AACvE,eAAO,MAAM,QAAQ,EAAE,iBAiCtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tnid/core",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Type-safe, named, unique identifiers (TNIDs) - UUID-compatible IDs with embedded type names",
5
5
  "keywords": [
6
6
  "uuid",
@@ -24,6 +24,10 @@
24
24
  ".": {
25
25
  "import": "./esm/index.js",
26
26
  "require": "./script/index.js"
27
+ },
28
+ "./uuid": {
29
+ "import": "./esm/uuid.js",
30
+ "require": "./script/uuid.js"
27
31
  }
28
32
  },
29
33
  "scripts": {},
@@ -33,5 +37,6 @@
33
37
  "engines": {
34
38
  "node": ">=20"
35
39
  },
40
+ "dependencies": {},
36
41
  "_generatedBy": "dnt@dev"
37
42
  }
@@ -3,34 +3,36 @@ import type { Case, TnidValue, TnidVariant } from "./types.js";
3
3
  export type DynamicTnid = TnidValue<string>;
4
4
  declare function getTnidVariantImpl(id: DynamicTnid): TnidVariant;
5
5
  declare function toUuidStringImpl(id: DynamicTnid, upperCase?: boolean): string;
6
- /** Static methods for working with any TNID regardless of name. */
7
- export declare const DynamicTnid: {
6
+ /** Interface for DynamicTnid static methods. */
7
+ export interface DynamicTnidNamespace {
8
8
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
9
- readonly new_v0: (name: string) => DynamicTnid;
9
+ new_v0(name: string): DynamicTnid;
10
10
  /** Alias for new_v0. */
11
- readonly new_time_ordered: (name: string) => DynamicTnid;
11
+ new_time_ordered(name: string): DynamicTnid;
12
12
  /** Generate a new time-sortable TNID with a specific timestamp. */
13
- readonly new_v0_with_time: (name: string, time: Date) => DynamicTnid;
13
+ new_v0_with_time(name: string, time: Date): DynamicTnid;
14
14
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
15
- readonly new_v0_with_parts: (name: string, epochMillis: bigint, random: bigint) => DynamicTnid;
15
+ new_v0_with_parts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
16
16
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
17
- readonly new_v1: (name: string) => DynamicTnid;
17
+ new_v1(name: string): DynamicTnid;
18
18
  /** Alias for new_v1. */
19
- readonly new_high_entropy: (name: string) => DynamicTnid;
19
+ new_high_entropy(name: string): DynamicTnid;
20
20
  /** Generate a new high-entropy TNID with explicit random bits. */
21
- readonly new_v1_with_random: (name: string, randomBits: bigint) => DynamicTnid;
21
+ new_v1_with_random(name: string, randomBits: bigint): DynamicTnid;
22
22
  /** Parse any valid TNID string. */
23
- readonly parse: (s: string) => DynamicTnid;
23
+ parse(s: string): DynamicTnid;
24
24
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
25
- readonly parse_uuid_string: (uuid: string) => DynamicTnid;
25
+ parse_uuid_string(uuid: string): DynamicTnid;
26
26
  /** Get the name from a TNID. */
27
- readonly getName: (id: DynamicTnid) => string;
27
+ getName(id: DynamicTnid): string;
28
28
  /** Get the name encoded as a 5-character hex string. */
29
- readonly getNameHex: (id: DynamicTnid) => string;
29
+ getNameHex(id: DynamicTnid): string;
30
30
  /** Get the variant of a TNID. */
31
- readonly getVariant: (id: DynamicTnid) => TnidVariant;
31
+ getVariant(id: DynamicTnid): TnidVariant;
32
32
  /** Convert to UUID hex string format. */
33
- readonly toUuidString: (id: DynamicTnid, caseFormat?: Case) => string;
34
- };
33
+ toUuidString(id: DynamicTnid, caseFormat?: Case): string;
34
+ }
35
+ /** Static methods for working with any TNID regardless of name. */
36
+ export declare const DynamicTnid: DynamicTnidNamespace;
35
37
  export { getTnidVariantImpl, toUuidStringImpl, };
36
38
  //# sourceMappingURL=dynamic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,mEAAmE;AACnE,eAAO,MAAM,WAAW;IACtB,kFAAkF;4BACrE,MAAM,KAAG,WAAW;IAYjC,wBAAwB;sCACD,MAAM,KAAG,WAAW;IAI3C,mEAAmE;sCAC5C,MAAM,QAAQ,IAAI,KAAG,WAAW;IAavD,uFAAuF;uCAE/E,MAAM,eACC,MAAM,UACX,MAAM,KACb,WAAW;IAYd,iFAAiF;4BACpE,MAAM,KAAG,WAAW;IAYjC,wBAAwB;sCACD,MAAM,KAAG,WAAW;IAI3C,kEAAkE;wCACzC,MAAM,cAAc,MAAM,KAAG,WAAW;IAYjE,mCAAmC;wBAC1B,MAAM,KAAG,WAAW;IAI7B,6EAA6E;uCACrD,MAAM,KAAG,WAAW;IAI5C,gCAAgC;2BACpB,WAAW,KAAG,MAAM;IAIhC,wDAAwD;8BACzC,WAAW,KAAG,MAAM;IAInC,iCAAiC;8BAClB,WAAW,KAAG,WAAW;IAIxC,yCAAyC;gCACxB,WAAW,eAAc,IAAI,KAAa,MAAM;CAGzD,CAAC;AAGX,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,mEAAmE;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACxD,uFAAuF;IACvF,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAClF,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,kEAAkE;IAClE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,mCAAmC;IACnC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA8GzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
package/script/dynamic.js CHANGED
@@ -85,9 +85,6 @@ function parseDynamicUuidStringImpl(uuid) {
85
85
  }
86
86
  return (0, uuid_js_1.valueToTnidString)(value);
87
87
  }
88
- // -----------------------------------------------------------------------------
89
- // DynamicTnid Namespace
90
- // -----------------------------------------------------------------------------
91
88
  /** Static methods for working with any TNID regardless of name. */
92
89
  exports.DynamicTnid = {
93
90
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
@@ -3,15 +3,17 @@ import type { DynamicTnid } from "./dynamic.js";
3
3
  export type UuidLike = string & {
4
4
  __uuidlike: true;
5
5
  };
6
- /** Wrapper for UUID hex strings that may or may not be valid TNIDs. */
7
- export declare const UuidLike: {
6
+ /** Interface for UuidLike static methods. */
7
+ export interface UuidLikeNamespace {
8
8
  /** Create from a TNID (always valid). */
9
- readonly fromTnid: (id: DynamicTnid) => UuidLike;
9
+ fromTnid(id: DynamicTnid): UuidLike;
10
10
  /** Parse UUID hex string (format validation only, not TNID validation). */
11
- readonly parse: (s: string) => UuidLike;
11
+ parse(s: string): UuidLike;
12
12
  /** Try to convert to DynamicTnid (validates TNID structure). */
13
- readonly toTnid: (uuid: UuidLike) => DynamicTnid;
13
+ toTnid(uuid: UuidLike): DynamicTnid;
14
14
  /** Format as uppercase UUID hex string. */
15
- readonly toUpperCase: (uuid: UuidLike) => UuidLike;
16
- };
15
+ toUpperCase(uuid: UuidLike): UuidLike;
16
+ }
17
+ /** Wrapper for UUID hex strings that may or may not be valid TNIDs. */
18
+ export declare const UuidLike: UuidLikeNamespace;
17
19
  //# sourceMappingURL=uuidlike.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uuidlike.d.ts","sourceRoot":"","sources":["../src/uuidlike.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,oGAAoG;AACpG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,CAAC;AAWrD,uEAAuE;AACvE,eAAO,MAAM,QAAQ;IACnB,yCAAyC;4BAC5B,WAAW,KAAG,QAAQ;IAInC,2EAA2E;wBAClE,MAAM,KAAG,QAAQ;IAQ1B,gEAAgE;4BACnD,QAAQ,KAAG,WAAW;IAanC,2CAA2C;iCACzB,QAAQ,KAAG,QAAQ;CAG7B,CAAC"}
1
+ {"version":3,"file":"uuidlike.d.ts","sourceRoot":"","sources":["../src/uuidlike.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,oGAAoG;AACpG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,CAAC;AAWrD,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,WAAW,GAAG,QAAQ,CAAC;IACpC,2EAA2E;IAC3E,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,gEAAgE;IAChE,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpC,2CAA2C;IAC3C,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACvC;AAED,uEAAuE;AACvE,eAAO,MAAM,QAAQ,EAAE,iBAiCtB,CAAC"}