@dxos/keys 0.8.4-staging.ac66bdf99f → 0.9.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.
Files changed (54) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +294 -435
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +289 -433
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/DXN.d.ts +50 -0
  9. package/dist/types/src/DXN.d.ts.map +1 -0
  10. package/dist/types/src/DXN.test.d.ts +2 -0
  11. package/dist/types/src/DXN.test.d.ts.map +1 -0
  12. package/dist/types/src/EID.d.ts +74 -0
  13. package/dist/types/src/EID.d.ts.map +1 -0
  14. package/dist/types/src/EID.test.d.ts +2 -0
  15. package/dist/types/src/EID.test.d.ts.map +1 -0
  16. package/dist/types/src/URI.d.ts +23 -0
  17. package/dist/types/src/URI.d.ts.map +1 -0
  18. package/dist/types/src/entity-id.d.ts +104 -0
  19. package/dist/types/src/entity-id.d.ts.map +1 -0
  20. package/dist/types/src/entity-id.test.d.ts +2 -0
  21. package/dist/types/src/entity-id.test.d.ts.map +1 -0
  22. package/dist/types/src/identity-did.d.ts +6 -4
  23. package/dist/types/src/identity-did.d.ts.map +1 -1
  24. package/dist/types/src/index.d.ts +5 -2
  25. package/dist/types/src/index.d.ts.map +1 -1
  26. package/dist/types/src/parse-id.d.ts +10 -0
  27. package/dist/types/src/parse-id.d.ts.map +1 -0
  28. package/dist/types/src/parse-id.test.d.ts +2 -0
  29. package/dist/types/src/parse-id.test.d.ts.map +1 -0
  30. package/dist/types/src/prng.d.ts.map +1 -1
  31. package/dist/types/src/public-key.d.ts +1 -1
  32. package/dist/types/src/public-key.d.ts.map +1 -1
  33. package/dist/types/src/random-bytes.d.ts.map +1 -1
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +7 -10
  36. package/src/DXN.test.ts +85 -0
  37. package/src/DXN.ts +104 -0
  38. package/src/EID.test.ts +147 -0
  39. package/src/EID.ts +151 -0
  40. package/src/URI.ts +35 -0
  41. package/src/entity-id.test.ts +73 -0
  42. package/src/entity-id.ts +202 -0
  43. package/src/identity-did.test.ts +19 -2
  44. package/src/identity-did.ts +60 -25
  45. package/src/index.ts +6 -2
  46. package/src/parse-id.test.ts +32 -0
  47. package/src/parse-id.ts +32 -0
  48. package/src/public-key.ts +3 -3
  49. package/dist/types/src/dxn.d.ts +0 -129
  50. package/dist/types/src/dxn.d.ts.map +0 -1
  51. package/dist/types/src/object-id.d.ts +0 -65
  52. package/dist/types/src/object-id.d.ts.map +0 -1
  53. package/src/dxn.ts +0 -345
  54. package/src/object-id.ts +0 -131
@@ -0,0 +1,202 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import { type PRNG, type ULIDFactory, monotonicFactory } from 'ulidx';
7
+
8
+ // Crockford Base32 alphabet used by ULID. Excludes I, L, O, U.
9
+ const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
10
+
11
+ // TODO(dmaretskyi): Make brand.
12
+ // export const EntityIdBrand: unique symbol = Symbol('@dxos/echo/EntityId');
13
+ // export const EntityIdSchema = Schema.ULID.pipe(S.brand(EntityIdBrand));
14
+ const EntityIdSchema = Schema.String.pipe(Schema.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
15
+ description: 'A Universally Unique Lexicographically Sortable Identifier',
16
+ pattern: '^[0-7][0-9A-HJKMNP-TV-Z]{25}$',
17
+ });
18
+
19
+ export type EntityId = typeof EntityIdSchema.Type;
20
+
21
+ export interface EntityIdClass extends Schema.SchemaClass<EntityId, string> {
22
+ /**
23
+ * @returns true if the string is a valid EntityId.
24
+ */
25
+ isValid(id: string): id is EntityId;
26
+
27
+ /**
28
+ * Creates an EntityId from a string validating the format.
29
+ */
30
+ make(id: string): EntityId;
31
+
32
+ /**
33
+ * Generates a random EntityId.
34
+ */
35
+ random(): EntityId;
36
+
37
+ /**
38
+ * Derives a deterministic ULID-format EntityId from arbitrary seed values.
39
+ *
40
+ * The same inputs always produce the same id, across processes, isolates, and workers.
41
+ * Unlike `random()`, this method does not call `crypto.getRandomValues()` and is therefore
42
+ * safe to call at module top-level — required for Cloudflare workerd, which forbids random
43
+ * generation in global scope.
44
+ *
45
+ * Intended for stable identity of declarative artefacts (e.g. `Type.Type` entities derived
46
+ * from a `(typename, version)` pair, fixtures, well-known objects). NOT a substitute for
47
+ * `random()` when global uniqueness is required: callers must guarantee seed uniqueness
48
+ * themselves; identical seeds yield identical ids and therefore collide.
49
+ *
50
+ * The result always passes `EntityId.isValid(...)`.
51
+ *
52
+ * @param seed - One or more seed values; coerced to strings and joined.
53
+ *
54
+ * ```ts
55
+ * EntityId.deterministic('org.dxos.type.person', '0.1.0'); // stable across runs
56
+ * ```
57
+ */
58
+ deterministic(...seed: (string | number)[]): EntityId;
59
+
60
+ /**
61
+ * WARNING: To be used only within tests.
62
+ *
63
+ * Disables randomness in EntityId generation, causing the same sequence of IDs to be generated.
64
+ * Do not use in production code as this will cause data collisions.
65
+ * Place this at the top of the test file to ensure that the same sequence of IDs is generated.
66
+ *
67
+ * ```ts
68
+ * EntityId.dangerouslyDisableRandomness();
69
+ *
70
+ * describe('suite', () => {
71
+ * // ...
72
+ * });
73
+ * ```
74
+ *
75
+ * NOTE: The generated IDs depend on the order of EntityId.random() calls, which might be affected by test order, scheduling, etc.
76
+ */
77
+ dangerouslyDisableRandomness(): void;
78
+
79
+ /**
80
+ * WARNING: To be used only within tests.
81
+ *
82
+ * Pins the time component of generated EntityIds and seeds the PRNG used for the random component,
83
+ * causing the same sequence of IDs to be generated across runs.
84
+ * Do not use in production code as this will cause data collisions.
85
+ *
86
+ * @param time - Fixed timestamp (ms since epoch) used as the ULID time component.
87
+ * @param seed - Seed value for the PRNG used for the ULID random component.
88
+ *
89
+ * ```ts
90
+ * EntityId.dangerouslySetSeed(new Date('2025-01-01').getTime(), 42);
91
+ * ```
92
+ *
93
+ * NOTE: The generated IDs depend on the order of EntityId.random() calls, which might be affected by test order, scheduling, etc.
94
+ */
95
+ dangerouslySetSeed(time: number, seed: number): void;
96
+ }
97
+
98
+ /**
99
+ * Randomly generated unique identifier for an object.
100
+ *
101
+ * Follows ULID spec.
102
+ */
103
+ export const EntityId: EntityIdClass = class extends EntityIdSchema {
104
+ static #factory: ULIDFactory = monotonicFactory();
105
+ static #seedTime: number | undefined = undefined;
106
+
107
+ static isValid(id: string): id is EntityId {
108
+ try {
109
+ Schema.decodeSync(EntityId)(id);
110
+ return true;
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+
116
+ static random(): EntityId {
117
+ return this.#factory(this.#seedTime) as EntityId;
118
+ }
119
+
120
+ static deterministic(...seed: (string | number)[]): EntityId {
121
+ const input = seed.map((value) => String(value)).join('\0');
122
+ // FNV-1a 32-bit ×2 → 64 bits of derived entropy, packed into the 80-bit ULID random component.
123
+ let h1 = 0x811c9dc5 >>> 0;
124
+ let h2 = 0x1b873593 >>> 0;
125
+ for (let i = 0; i < input.length; i++) {
126
+ const code = input.charCodeAt(i);
127
+ h1 = Math.imul(h1 ^ code, 0x01000193) >>> 0;
128
+ h2 = Math.imul(h2 ^ ((code << 13) | (code >>> 3)), 0x01000193) >>> 0;
129
+ }
130
+ // 10 chars for the time component, all '0' — pins to the ULID epoch (timestamp 0) so the leading
131
+ // char is in [0-7]. The randomness lives entirely in the 16-char random component below.
132
+ const time = ALPHABET[0].repeat(10);
133
+ let bits = (BigInt(h1) << 32n) | BigInt(h2);
134
+ let rand = '';
135
+ for (let i = 0; i < 16; i++) {
136
+ rand = ALPHABET[Number(bits & 0x1fn)] + rand;
137
+ bits >>= 5n;
138
+ }
139
+ return (time + rand) as EntityId;
140
+ }
141
+
142
+ static dangerouslyDisableRandomness() {
143
+ this.#factory = monotonicFactory(makeTestPRNG());
144
+ this.#seedTime = new Date('2025-01-01').getTime();
145
+ }
146
+
147
+ static dangerouslySetSeed(time: number, seed: number) {
148
+ this.#factory = monotonicFactory(makeTestPRNG(seed));
149
+ this.#seedTime = time;
150
+ }
151
+ };
152
+
153
+ /**
154
+ * Test PRNG that always starts with the same seed and produces the same sequence.
155
+ */
156
+ const makeTestPRNG = (seed: number = 0): PRNG => {
157
+ const rng = new SimplePRNG(seed);
158
+ return () => {
159
+ return rng.next();
160
+ };
161
+ };
162
+
163
+ /**
164
+ * Simple Linear Congruential Generator (LCG) for pseudo-random number generation.
165
+ * Returns numbers in the range [0, 1) (0 inclusive, 1 exclusive).
166
+ */
167
+ export class SimplePRNG {
168
+ #seed: number;
169
+
170
+ // LCG parameters (from Numerical Recipes)
171
+ static readonly #a = 1664525;
172
+ static readonly #c = 1013904223;
173
+ static readonly #m = Math.pow(2, 32);
174
+
175
+ /**
176
+ * Creates a new PRNG instance.
177
+ * @param seed - Initial seed value. If not provided, uses 0.
178
+ */
179
+ constructor(seed: number = 0) {
180
+ this.#seed = seed;
181
+ }
182
+
183
+ /**
184
+ * Generates the next pseudo-random number in the range [0, 1).
185
+ * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
186
+ */
187
+ next(): number {
188
+ // Update seed using LCG formula: (a * seed + c) mod m
189
+ this.#seed = (SimplePRNG.#a * this.#seed + SimplePRNG.#c) % SimplePRNG.#m;
190
+
191
+ // Normalize to [0, 1) range
192
+ return this.#seed / SimplePRNG.#m;
193
+ }
194
+
195
+ /**
196
+ * Resets the generator with a new seed.
197
+ * @param seed - New seed value.
198
+ */
199
+ reset(seed: number): void {
200
+ this.#seed = seed;
201
+ }
202
+ }
@@ -2,11 +2,13 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { expect, test } from 'vitest';
5
+ import * as JSONSchema from 'effect/JSONSchema';
6
+ import * as Schema from 'effect/Schema';
7
+ import { test } from 'vitest';
6
8
 
7
9
  import { IdentityDid } from './identity-did';
8
10
 
9
- test('identity-did', () => {
11
+ test('identity-did', ({ expect }) => {
10
12
  const id = IdentityDid.random();
11
13
 
12
14
  expect(id.length).toBe(42);
@@ -15,3 +17,18 @@ test('identity-did', () => {
15
17
  expect(decoded.length).toBe(IdentityDid.byteLength);
16
18
  expect(IdentityDid.encode(decoded)).toBe(id);
17
19
  });
20
+
21
+ test('identity-did schema', ({ expect }) => {
22
+ const id = IdentityDid.random();
23
+
24
+ // Validates and brands a plain string.
25
+ expect(IdentityDid.make(id)).toBe(id);
26
+ expect(Schema.is(IdentityDid)(id)).toBe(true);
27
+ expect(Schema.is(IdentityDid)('not-a-did')).toBe(false);
28
+
29
+ // Rejects a correctly-prefixed, correctly-sized string that is not valid base-32.
30
+ expect(IdentityDid.isValid(`did:halo:B${'1'.repeat(32)}`)).toBe(false);
31
+
32
+ // Serializes to JSON Schema (a plain string type), unlike Schema.instanceOf.
33
+ expect(() => JSONSchema.make(IdentityDid)).not.toThrow();
34
+ });
@@ -4,11 +4,50 @@
4
4
 
5
5
  import base32Decode from 'base32-decode';
6
6
  import base32Encode from 'base32-encode';
7
+ import * as Schema from 'effect/Schema';
7
8
 
8
9
  import { invariant } from '@dxos/invariant';
9
10
 
10
11
  import { randomBytes } from './random-bytes';
11
12
 
13
+ /**
14
+ * Denotes RFC4648 base-32 format.
15
+ */
16
+ const MULTIBASE_PREFIX = 'B';
17
+
18
+ const DID_PREFIX = 'did:halo:';
19
+
20
+ const DECODED_BYTE_LENGTH = 20;
21
+
22
+ const ENCODED_LENGTH = 42;
23
+
24
+ /**
25
+ * RFC4648 base-32 alphabet (uppercase A–Z and digits 2–7).
26
+ */
27
+ const RFC4648_BASE32_PATTERN = /^[A-Z2-7]+$/;
28
+
29
+ const isValid = (value: unknown): value is IdentityDid => {
30
+ if (
31
+ typeof value !== 'string' ||
32
+ !value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) ||
33
+ value.length !== ENCODED_LENGTH
34
+ ) {
35
+ return false;
36
+ }
37
+
38
+ const encoded = value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length);
39
+ if (!RFC4648_BASE32_PATTERN.test(encoded)) {
40
+ return false;
41
+ }
42
+
43
+ try {
44
+ // Reject inputs that pass the prefix/length check but are not decodable to the expected byte length.
45
+ return base32Decode(encoded, 'RFC4648').byteLength === DECODED_BYTE_LENGTH;
46
+ } catch {
47
+ return false;
48
+ }
49
+ };
50
+
12
51
  /**
13
52
  * A unique identifier for an identity.
14
53
  * Identity DIDs are generated by creating a keypair, and then taking the first 20 bytes of the SHA-256 hash of the public key and encoding them to multibase RFC4648 base-32 format (prefixed with B, see Multibase Table).
@@ -16,34 +55,30 @@ import { randomBytes } from './random-bytes';
16
55
  */
17
56
  export type IdentityDid = string & { __IdentityDid: never };
18
57
 
19
- export const IdentityDid = Object.freeze({
20
- byteLength: 20,
21
- encode: (value: Uint8Array): IdentityDid => {
58
+ export const IdentityDid: Schema.Schema<IdentityDid, string> & {
59
+ byteLength: number;
60
+ encode: (value: Uint8Array) => IdentityDid;
61
+ decode: (value: IdentityDid) => Uint8Array;
62
+ isValid: (value: unknown) => value is IdentityDid;
63
+ make: (value: string) => IdentityDid;
64
+ random: () => IdentityDid;
65
+ } = class extends Schema.String.pipe(Schema.filter(isValid)) {
66
+ static byteLength = DECODED_BYTE_LENGTH;
67
+
68
+ static encode = (value: Uint8Array): IdentityDid => {
22
69
  invariant(value instanceof Uint8Array, 'Invalid type');
23
70
  invariant(value.length === IdentityDid.byteLength, 'Invalid length');
24
-
25
71
  return (DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, 'RFC4648')) as IdentityDid;
26
- },
27
- decode: (value: IdentityDid): Uint8Array => {
28
- invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), 'Invalid multibase32 encoding');
72
+ };
29
73
 
30
- return new Uint8Array(base32Decode(value.slice(10), 'RFC4648'));
31
- },
32
- isValid: (value: string): value is IdentityDid => {
33
- return (
34
- typeof value === 'string' && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH
35
- );
36
- },
37
- random: (): IdentityDid => {
38
- return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
39
- },
40
- });
41
-
42
- /**
43
- * Denotes RFC4648 base-32 format.
44
- */
45
- const MULTIBASE_PREFIX = 'B';
74
+ static decode = (value: IdentityDid): Uint8Array => {
75
+ invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), 'Invalid multibase32 encoding');
76
+ return new Uint8Array(base32Decode(value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length), 'RFC4648'));
77
+ };
46
78
 
47
- const DID_PREFIX = 'did:halo:';
79
+ static isValid = isValid;
48
80
 
49
- const ENCODED_LENGTH = 42;
81
+ static random = (): IdentityDid => {
82
+ return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
83
+ };
84
+ };
package/src/index.ts CHANGED
@@ -2,9 +2,13 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- export * from './dxn';
5
+ export * as DXN from './DXN';
6
+ export * as EID from './EID';
7
+ export * as URI from './URI';
8
+
6
9
  export * from './identity-did';
7
- export * from './object-id';
10
+ export * from './entity-id';
11
+ export * from './parse-id';
8
12
  export * from './public-key';
9
13
  export * from './space-id';
10
14
  export type * from './types';
@@ -0,0 +1,32 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { parseId } from './parse-id';
8
+
9
+ describe('parseId', () => {
10
+ test('space id', () => {
11
+ const id = '123456789012345678901234567890123';
12
+ expect(parseId(id)).toEqual({ spaceId: id });
13
+ });
14
+
15
+ test('object id', () => {
16
+ const id = '12345678901234567890123456';
17
+ expect(parseId(id)).toEqual({ objectId: id });
18
+ });
19
+
20
+ test('fully qualified id', () => {
21
+ const id = '123456789012345678901234567890123:12345678901234567890123456';
22
+ expect(parseId(id)).toEqual({
23
+ spaceId: '123456789012345678901234567890123',
24
+ objectId: '12345678901234567890123456',
25
+ });
26
+ });
27
+
28
+ test('invalid id', () => {
29
+ const id = '123456789012345678901234561234567890123456';
30
+ expect(parseId(id)).toEqual({});
31
+ });
32
+ });
@@ -0,0 +1,32 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type EntityId } from './entity-id';
6
+ import { type SpaceId } from './space-id';
7
+
8
+ export const SPACE_ID_LENGTH = 33;
9
+ export const OBJECT_ID_LENGTH = 26;
10
+ export const FQ_ID_LENGTH = SPACE_ID_LENGTH + OBJECT_ID_LENGTH + 1;
11
+
12
+ export const parseId = (id?: string): { spaceId?: SpaceId; objectId?: EntityId } => {
13
+ if (!id) {
14
+ return {};
15
+ } else if (id.length === SPACE_ID_LENGTH) {
16
+ return {
17
+ spaceId: id as SpaceId,
18
+ };
19
+ } else if (id.length === OBJECT_ID_LENGTH) {
20
+ return {
21
+ objectId: id as EntityId,
22
+ };
23
+ } else if (id.length === FQ_ID_LENGTH && id.indexOf(':') === SPACE_ID_LENGTH) {
24
+ const [spaceId, objectId] = id.split(':');
25
+ return {
26
+ spaceId: spaceId as SpaceId,
27
+ objectId: objectId as EntityId,
28
+ };
29
+ } else {
30
+ return {};
31
+ }
32
+ };
package/src/public-key.ts CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  inspectCustom,
15
15
  truncateKey,
16
16
  } from '@dxos/debug';
17
- import { invariant } from '@dxos/invariant';
17
+ import { assertArgument, invariant } from '@dxos/invariant';
18
18
 
19
19
  import { randomBytes } from './random-bytes';
20
20
 
@@ -149,7 +149,7 @@ export class PublicKey implements Equatable {
149
149
  * @deprecated All keys should be represented as instances of PublicKey.
150
150
  */
151
151
  static bufferize(str: string): Buffer {
152
- invariant(typeof str === 'string', 'Invalid type');
152
+ assertArgument(typeof str === 'string', 'str', 'Invalid type');
153
153
  const buffer = Buffer.from(str, 'hex');
154
154
  // invariant(buffer.length === PUBLIC_KEY_LENGTH || buffer.length === SECRET_KEY_LENGTH,
155
155
  // `Invalid key length: ${buffer.length}`);
@@ -216,7 +216,7 @@ export class PublicKey implements Equatable {
216
216
  return 'B' + base32Encode(this._value, 'RFC4648');
217
217
  }
218
218
 
219
- truncate(length = undefined): string {
219
+ truncate(length?: number): string {
220
220
  return truncateKey(this, length);
221
221
  }
222
222
 
@@ -1,129 +0,0 @@
1
- import * as Schema from 'effect/Schema';
2
- import type { InspectOptionsStylized, inspect } from 'node:util';
3
- import { type DevtoolsFormatter, devtoolsFormatter, inspectCustom } from '@dxos/debug';
4
- import { ObjectId } from './object-id';
5
- import { SpaceId } from './space-id';
6
- /**
7
- * Tags for ECHO DXNs that should resolve the object ID in the local space.
8
- */
9
- export declare const LOCAL_SPACE_TAG = "@";
10
- export declare const DXN_ECHO_REGEXP: RegExp;
11
- export declare const QueueSubspaceTags: Readonly<{
12
- DATA: "data";
13
- TRACE: "trace";
14
- }>;
15
- export type QueueSubspaceTag = (typeof QueueSubspaceTags)[keyof typeof QueueSubspaceTags];
16
- /**
17
- * DXN unambiguously names a resource like an ECHO object, schema definition, plugin, etc.
18
- * Each DXN starts with a dxn prefix, followed by a resource kind.
19
- * Colon Symbol : is used a delimiter between parts.
20
- * DXNs may contain slashes.
21
- * '@' in the place of the space id is used to denote that the DXN should be resolved in the local space.
22
- *
23
- * @example
24
- * ```
25
- * dxn:echo:<space key>:<echo id>
26
- * dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
27
- * dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6
28
- * dxn:type:org.dxos.type.calendar
29
- * dxn:plugin:org.dxos.agent.plugin.functions
30
- * ```
31
- */
32
- export declare class DXN {
33
- #private;
34
- static Schema: Schema.refine<string, typeof Schema.NonEmptyString>;
35
- static hash(dxn: DXN): string;
36
- /**
37
- * Kind constants.
38
- */
39
- static kind: Readonly<{
40
- /**
41
- * dxn:type:<type_name>[:<version>]
42
- */
43
- TYPE: "type";
44
- /**
45
- * dxn:echo:<space_id>:<echo_id>
46
- * dxn:echo:@:<echo_id>
47
- */
48
- ECHO: "echo";
49
- /**
50
- * The subspace tag enables us to partition queues by usage within the context of a space.
51
- * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
52
- * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
53
- * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
54
- */
55
- QUEUE: "queue";
56
- }>;
57
- /**
58
- * Exactly equals.
59
- */
60
- static equals(a: DXN, b: DXN): boolean;
61
- static equalsEchoId(a: DXN, b: DXN): boolean;
62
- static isDXNString(dxn: string): boolean;
63
- static parse(dxn: string): DXN;
64
- static tryParse(dxn: string): DXN | undefined;
65
- /**
66
- * @example `dxn:type:com.example.type.person`
67
- */
68
- static fromTypename(typename: string): DXN;
69
- /**
70
- * @example `dxn:type:com.example.type.person:0.1.0`
71
- */
72
- static fromTypenameAndVersion(typename: string, version: string): DXN;
73
- /**
74
- * @example `dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6`
75
- */
76
- static fromSpaceAndObjectId(spaceId: SpaceId, objectId: ObjectId): DXN;
77
- /**
78
- * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
79
- */
80
- static fromLocalObjectId(id: string): DXN;
81
- static fromQueue(subspaceTag: QueueSubspaceTag, spaceId: SpaceId, queueId: ObjectId, objectId?: ObjectId): DXN;
82
- constructor(kind: string, parts: string[]);
83
- toString(): DXN.String;
84
- toJSON(): string;
85
- /**
86
- * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
87
- */
88
- [inspectCustom](depth: number, options: InspectOptionsStylized, inspectFn: typeof inspect): string;
89
- get [devtoolsFormatter](): DevtoolsFormatter;
90
- get kind(): string;
91
- get parts(): string[];
92
- get typename(): string;
93
- equals(other: DXN): boolean;
94
- hasTypenameOf(typename: string): boolean;
95
- isLocalObjectId(): boolean;
96
- asTypeDXN(): DXN.TypeDXN | undefined;
97
- asEchoDXN(): DXN.EchoDXN | undefined;
98
- asQueueDXN(): DXN.QueueDXN | undefined;
99
- /**
100
- * Produces a new DXN with the given parts appended.
101
- */
102
- extend(parts: string[]): DXN;
103
- }
104
- /**
105
- * API namespace.
106
- */
107
- export declare namespace DXN {
108
- /**
109
- * DXN represented as a javascript string.
110
- */
111
- type String = string & {
112
- __DXNString: never;
113
- };
114
- type TypeDXN = {
115
- type: string;
116
- version?: string;
117
- };
118
- type EchoDXN = {
119
- spaceId?: SpaceId;
120
- echoId: string;
121
- };
122
- type QueueDXN = {
123
- subspaceTag: QueueSubspaceTag;
124
- spaceId: SpaceId;
125
- queueId: string;
126
- objectId?: string;
127
- };
128
- }
129
- //# sourceMappingURL=dxn.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dxn.d.ts","sourceRoot":"","sources":["../../../src/dxn.ts"],"names":[],"mappings":"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"}
@@ -1,65 +0,0 @@
1
- import * as Schema from 'effect/Schema';
2
- declare const ObjectIdSchema: Schema.refine<string, typeof Schema.String>;
3
- export type ObjectId = typeof ObjectIdSchema.Type;
4
- export interface ObjectIdClass extends Schema.SchemaClass<ObjectId, string> {
5
- /**
6
- * @returns true if the string is a valid ObjectId.
7
- */
8
- isValid(id: string): id is ObjectId;
9
- /**
10
- * Creates an ObjectId from a string validating the format.
11
- */
12
- make(id: string): ObjectId;
13
- /**
14
- * Generates a random ObjectId.
15
- */
16
- random(): ObjectId;
17
- /**
18
- * WARNING: To be used only within tests.
19
- *
20
- * Disables randomness in ObjectId generation, causing the same sequence of IDs to be generated.
21
- * Do not use in production code as this will cause data collisions.
22
- * Place this at the top of the test file to ensure that the same sequence of IDs is generated.
23
- *
24
- * ```ts
25
- * ObjectId.dangerouslyDisableRandomness();
26
- *
27
- * describe('suite', () => {
28
- * // ...
29
- * });
30
- * ```
31
- *
32
- * NOTE: The generated IDs depend on the order of ObjectId.random() calls, which might be affected by test order, scheduling, etc.
33
- */
34
- dangerouslyDisableRandomness(): void;
35
- }
36
- /**
37
- * Randomly generated unique identifier for an object.
38
- *
39
- * Follows ULID spec.
40
- */
41
- export declare const ObjectId: ObjectIdClass;
42
- /**
43
- * Simple Linear Congruential Generator (LCG) for pseudo-random number generation.
44
- * Returns numbers in the range [0, 1) (0 inclusive, 1 exclusive).
45
- */
46
- export declare class SimplePRNG {
47
- #private;
48
- /**
49
- * Creates a new PRNG instance.
50
- * @param seed - Initial seed value. If not provided, uses 0.
51
- */
52
- constructor(seed?: number);
53
- /**
54
- * Generates the next pseudo-random number in the range [0, 1).
55
- * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
56
- */
57
- next(): number;
58
- /**
59
- * Resets the generator with a new seed.
60
- * @param seed - New seed value.
61
- */
62
- reset(seed: number): void;
63
- }
64
- export {};
65
- //# sourceMappingURL=object-id.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"object-id.d.ts","sourceRoot":"","sources":["../../../src/object-id.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAMxC,QAAA,MAAM,cAAc,6CAGlB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC;AAElD,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC;IACzE;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,QAAQ,CAAC;IAEpC;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAAC;IAE3B;;OAEG;IACH,MAAM,IAAI,QAAQ,CAAC;IAEnB;;;;;;;;;;;;;;;;OAgBG;IACH,4BAA4B,IAAI,IAAI,CAAC;CACtC;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,aAqBtB,CAAC;AAYF;;;GAGG;AACH,qBAAa,UAAU;;IAQrB;;;OAGG;gBACS,IAAI,GAAE,MAAU;IAI5B;;;OAGG;IACH,IAAI,IAAI,MAAM;IAQd;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAG1B"}