@dxos/keys 0.8.4-main.d05539e30a → 0.8.4-main.d9fc60f731

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 (44) hide show
  1. package/dist/lib/browser/index.mjs +293 -350
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +289 -348
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/DXN.d.ts +51 -0
  8. package/dist/types/src/DXN.d.ts.map +1 -0
  9. package/dist/types/src/DXN.test.d.ts +2 -0
  10. package/dist/types/src/DXN.test.d.ts.map +1 -0
  11. package/dist/types/src/EID.d.ts +65 -0
  12. package/dist/types/src/EID.d.ts.map +1 -0
  13. package/dist/types/src/EID.test.d.ts +2 -0
  14. package/dist/types/src/EID.test.d.ts.map +1 -0
  15. package/dist/types/src/URI.d.ts +23 -0
  16. package/dist/types/src/URI.d.ts.map +1 -0
  17. package/dist/types/src/entity-id.d.ts +104 -0
  18. package/dist/types/src/entity-id.d.ts.map +1 -0
  19. package/dist/types/src/entity-id.test.d.ts +2 -0
  20. package/dist/types/src/entity-id.test.d.ts.map +1 -0
  21. package/dist/types/src/identity-did.d.ts +6 -4
  22. package/dist/types/src/identity-did.d.ts.map +1 -1
  23. package/dist/types/src/index.d.ts +4 -2
  24. package/dist/types/src/index.d.ts.map +1 -1
  25. package/dist/types/src/parse-id.d.ts +2 -2
  26. package/dist/types/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +6 -6
  28. package/src/DXN.test.ts +97 -0
  29. package/src/DXN.ts +114 -0
  30. package/src/EID.test.ts +158 -0
  31. package/src/EID.ts +176 -0
  32. package/src/URI.ts +35 -0
  33. package/src/entity-id.test.ts +73 -0
  34. package/src/{object-id.ts → entity-id.ts} +70 -22
  35. package/src/identity-did.test.ts +19 -2
  36. package/src/identity-did.ts +60 -25
  37. package/src/index.ts +5 -2
  38. package/src/parse-id.ts +4 -4
  39. package/src/public-key.ts +2 -2
  40. package/dist/types/src/dxn.d.ts +0 -129
  41. package/dist/types/src/dxn.d.ts.map +0 -1
  42. package/dist/types/src/object-id.d.ts +0 -82
  43. package/dist/types/src/object-id.d.ts.map +0 -1
  44. package/src/dxn.ts +0 -345
@@ -16,6 +16,10 @@ var __esm = (fn, res) => function __init() {
16
16
  var __commonJS = (cb, mod) => function __require2() {
17
17
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
18
  };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, { get: all[name], enumerable: true });
22
+ };
19
23
  var __copyProps = (to, from, except, desc) => {
20
24
  if (from && typeof from === "object" || typeof from === "function") {
21
25
  for (let key of __getOwnPropNames(from))
@@ -98,80 +102,174 @@ var require_base32_decode = __commonJS({
98
102
  // src/index.ts
99
103
  init_inject_globals();
100
104
 
101
- // src/dxn.ts
102
- init_inject_globals();
103
- import * as Schema3 from "effect/Schema";
104
- import { devtoolsFormatter, inspectCustom } from "@dxos/debug";
105
- import { assertArgument, invariant as invariant2 } from "@dxos/invariant";
106
-
107
- // src/object-id.ts
105
+ // src/DXN.ts
106
+ var DXN_exports = {};
107
+ __export(DXN_exports, {
108
+ Schema: () => Schema_,
109
+ getName: () => getName,
110
+ getVersion: () => getVersion,
111
+ isDXN: () => isDXN,
112
+ make: () => make,
113
+ tryMake: () => tryMake
114
+ });
108
115
  init_inject_globals();
109
116
  import * as Schema from "effect/Schema";
110
- import { monotonicFactory } from "ulidx";
111
- var ObjectIdSchema = Schema.String.pipe(Schema.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
112
- description: "A Universally Unique Lexicographically Sortable Identifier",
113
- pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
114
- });
115
- var ObjectId = class extends ObjectIdSchema {
116
- static #factory = monotonicFactory();
117
- static #seedTime = void 0;
118
- static isValid(id) {
119
- try {
120
- Schema.decodeSync(ObjectId)(id);
121
- return true;
122
- } catch {
123
- return false;
117
+ var DXN_SPEC_REGEXP = /^dxn:[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z][a-zA-Z0-9]{0,62})(:\d+\.\d+\.\d+)?$/;
118
+ var isDXN = (value) => typeof value === "string" && value.startsWith("dxn:");
119
+ var make = (nsid, version) => parse(version != null ? `dxn:${nsid}:${version}` : `dxn:${nsid}`);
120
+ var tryMake = (dxn) => {
121
+ try {
122
+ return parse(dxn);
123
+ } catch {
124
+ return void 0;
125
+ }
126
+ };
127
+ var parse = (dxn) => {
128
+ const legacyTypeMatch = /^dxn:type:(.+)$/.exec(dxn);
129
+ if (legacyTypeMatch) {
130
+ const normalized = `dxn:${legacyTypeMatch[1]}`;
131
+ if (DXN_SPEC_REGEXP.test(normalized)) {
132
+ return normalized;
124
133
  }
125
134
  }
126
- static random() {
127
- return this.#factory(this.#seedTime);
135
+ if (typeof dxn === "string" && DXN_SPEC_REGEXP.test(dxn)) {
136
+ return dxn;
128
137
  }
129
- static dangerouslyDisableRandomness() {
130
- this.#factory = monotonicFactory(makeTestPRNG());
131
- this.#seedTime = (/* @__PURE__ */ new Date("2025-01-01")).getTime();
132
- }
133
- static dangerouslySetSeed(time, seed) {
134
- this.#factory = monotonicFactory(makeTestPRNG(seed));
135
- this.#seedTime = time;
138
+ throw new Error(`Invalid DXN: ${dxn}`);
139
+ };
140
+ var getName = (dxn) => {
141
+ const match = /^dxn:([^:]+)/.exec(dxn);
142
+ if (!match) {
143
+ throw new Error(`Invalid DXN: ${dxn}`);
136
144
  }
145
+ return match[1];
137
146
  };
138
- var makeTestPRNG = (seed = 0) => {
139
- const rng = new SimplePRNG(seed);
140
- return () => {
141
- return rng.next();
142
- };
147
+ var getVersion = (dxn) => {
148
+ const match = /^dxn:[^:]+:(\d+\.\d+\.\d+)$/.exec(dxn);
149
+ return match?.[1];
143
150
  };
144
- var SimplePRNG = class _SimplePRNG {
145
- #seed;
146
- // LCG parameters (from Numerical Recipes)
147
- static #a = 1664525;
148
- static #c = 1013904223;
149
- static #m = Math.pow(2, 32);
150
- /**
151
- * Creates a new PRNG instance.
152
- * @param seed - Initial seed value. If not provided, uses 0.
153
- */
154
- constructor(seed = 0) {
155
- this.#seed = seed;
151
+ var Schema_ = Schema.String.pipe(Schema.filter((value) => isDXN(value), {
152
+ message: () => "Invalid DXN"
153
+ }), Schema.annotations({
154
+ title: "DXN",
155
+ description: "DXN URI: dxn:<nsid>[:<version>]"
156
+ }));
157
+
158
+ // src/EID.ts
159
+ var EID_exports = {};
160
+ __export(EID_exports, {
161
+ Schema: () => Schema_2,
162
+ equals: () => equals,
163
+ getEntityId: () => getEntityId,
164
+ getSpaceId: () => getSpaceId,
165
+ isEID: () => isEID,
166
+ isLocal: () => isLocal,
167
+ make: () => make2,
168
+ parse: () => parse2,
169
+ tryParse: () => tryParse
170
+ });
171
+ init_inject_globals();
172
+ import * as Schema2 from "effect/Schema";
173
+ var ECHO_URI_REGEXP = /^echo:(?:\/\/[^/]+(?:\/[^/]+)?|(?:\/\/\/|\/)[^/]+)$/;
174
+ var QUALIFIED_RE = /^echo:\/\/([^/]+)\/([^/]+)$/;
175
+ var SPACE_ONLY_RE = /^echo:\/\/([^/]+)$/;
176
+ var LOCAL_RE = /^echo:(?:\/\/\/|\/)([^/]+)$/;
177
+ var LEGACY_LOCAL_RE = /^dxn:echo:@:([^:]+)$/;
178
+ var LEGACY_QUALIFIED_RE = /^dxn:echo:([^:@][^:]*):([^:]+)$/;
179
+ var LEGACY_QUEUE_ITEM_RE = /^dxn:queue:[^:]+:([^:]+):([^:]+):([^:]+)$/;
180
+ var LEGACY_QUEUE_RE = /^dxn:queue:[^:]+:([^:]+):([^:]+)$/;
181
+ var isEID = (value) => typeof value === "string" && (value.startsWith("echo:") || value.startsWith("dxn:echo:") || value.startsWith("dxn:queue:"));
182
+ var parse2 = (uri) => {
183
+ const normalized = normalizeLegacy(uri);
184
+ if (!ECHO_URI_REGEXP.test(normalized)) {
185
+ throw new Error(`Invalid EID: ${uri}`);
186
+ }
187
+ return normalized;
188
+ };
189
+ var tryParse = (uri) => {
190
+ try {
191
+ return parse2(uri);
192
+ } catch {
193
+ return void 0;
156
194
  }
157
- /**
158
- * Generates the next pseudo-random number in the range [0, 1).
159
- * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
160
- */
161
- next() {
162
- this.#seed = (_SimplePRNG.#a * this.#seed + _SimplePRNG.#c) % _SimplePRNG.#m;
163
- return this.#seed / _SimplePRNG.#m;
195
+ };
196
+ var normalizeLegacy = (uri) => {
197
+ if (uri.startsWith("echo:")) {
198
+ return uri;
164
199
  }
165
- /**
166
- * Resets the generator with a new seed.
167
- * @param seed - New seed value.
168
- */
169
- reset(seed) {
170
- this.#seed = seed;
200
+ const localMatch = LEGACY_LOCAL_RE.exec(uri);
201
+ if (localMatch) {
202
+ return `echo:/${localMatch[1]}`;
171
203
  }
204
+ const queueItemMatch = LEGACY_QUEUE_ITEM_RE.exec(uri);
205
+ if (queueItemMatch) {
206
+ return `echo://${queueItemMatch[1]}/${queueItemMatch[3]}`;
207
+ }
208
+ const queueMatch = LEGACY_QUEUE_RE.exec(uri);
209
+ if (queueMatch) {
210
+ return `echo://${queueMatch[1]}/${queueMatch[2]}`;
211
+ }
212
+ const qualifiedMatch = LEGACY_QUALIFIED_RE.exec(uri);
213
+ if (qualifiedMatch) {
214
+ return `echo://${qualifiedMatch[1]}/${qualifiedMatch[2]}`;
215
+ }
216
+ return uri;
172
217
  };
218
+ var make2 = ({ spaceId, entityId }) => {
219
+ let raw;
220
+ if (spaceId != null && entityId != null) {
221
+ raw = `echo://${spaceId}/${entityId}`;
222
+ } else if (entityId != null) {
223
+ raw = `echo:/${entityId}`;
224
+ } else if (spaceId != null) {
225
+ raw = `echo://${spaceId}`;
226
+ } else {
227
+ throw new Error("EID.make requires at least one of spaceId or entityId");
228
+ }
229
+ return parse2(raw);
230
+ };
231
+ var getSpaceId = (uri) => {
232
+ const normalized = parse2(uri);
233
+ const match = QUALIFIED_RE.exec(normalized) ?? SPACE_ONLY_RE.exec(normalized);
234
+ return match?.[1];
235
+ };
236
+ var getEntityId = (uri) => {
237
+ const normalized = parse2(uri);
238
+ const qualMatch = QUALIFIED_RE.exec(normalized);
239
+ if (qualMatch) {
240
+ return qualMatch[2];
241
+ }
242
+ const localMatch = LOCAL_RE.exec(normalized);
243
+ return localMatch?.[1];
244
+ };
245
+ var isLocal = (uri) => {
246
+ const normalized = parse2(uri);
247
+ return LOCAL_RE.test(normalized);
248
+ };
249
+ var equals = (a, b) => parse2(a) === parse2(b);
250
+ var Schema_2 = Schema2.String.pipe(Schema2.filter((value) => isEID(value), {
251
+ message: () => "Invalid EID: must start with echo:, dxn:echo:, or dxn:queue:"
252
+ }), Schema2.annotations({
253
+ title: "EID",
254
+ description: "ECHO object/space URI: echo://<spaceId>[/<objectId>] or echo:/<objectId>"
255
+ }));
173
256
 
174
- // src/space-id.ts
257
+ // src/URI.ts
258
+ var URI_exports = {};
259
+ __export(URI_exports, {
260
+ Schema: () => Schema_3,
261
+ isURI: () => isURI,
262
+ make: () => make3
263
+ });
264
+ init_inject_globals();
265
+ import * as Schema3 from "effect/Schema";
266
+ var make3 = (uri) => uri;
267
+ var isURI = (value) => typeof value === "string" && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value);
268
+ var Schema_3 = Schema3.String.pipe(Schema3.filter((value) => isURI(value), {
269
+ message: () => "Invalid URI"
270
+ }));
271
+
272
+ // src/identity-did.ts
175
273
  init_inject_globals();
176
274
  var import_base32_decode = __toESM(require_base32_decode(), 1);
177
275
 
@@ -238,8 +336,8 @@ function base32Encode(data, variant, options) {
238
336
  return output;
239
337
  }
240
338
 
241
- // src/space-id.ts
242
- import * as Schema2 from "effect/Schema";
339
+ // src/identity-did.ts
340
+ import * as Schema4 from "effect/Schema";
243
341
  import { invariant } from "@dxos/invariant";
244
342
 
245
343
  // src/random-bytes.ts
@@ -251,310 +349,129 @@ var randomBytes = (length) => {
251
349
  return bytes;
252
350
  };
253
351
 
254
- // src/space-id.ts
352
+ // src/identity-did.ts
255
353
  var MULTIBASE_PREFIX = "B";
256
- var ENCODED_LENGTH = 33;
354
+ var DID_PREFIX = "did:halo:";
355
+ var DECODED_BYTE_LENGTH = 20;
356
+ var ENCODED_LENGTH = 42;
357
+ var RFC4648_BASE32_PATTERN = /^[A-Z2-7]+$/;
257
358
  var isValid = (value) => {
258
- return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH;
359
+ if (typeof value !== "string" || !value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) || value.length !== ENCODED_LENGTH) {
360
+ return false;
361
+ }
362
+ const encoded = value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length);
363
+ if (!RFC4648_BASE32_PATTERN.test(encoded)) {
364
+ return false;
365
+ }
366
+ try {
367
+ return (0, import_base32_decode.default)(encoded, "RFC4648").byteLength === DECODED_BYTE_LENGTH;
368
+ } catch {
369
+ return false;
370
+ }
259
371
  };
260
- var SpaceId = class extends Schema2.String.pipe(Schema2.filter(isValid)) {
261
- static byteLength = 20;
372
+ var IdentityDid = class extends Schema4.String.pipe(Schema4.filter(isValid)) {
373
+ static byteLength = DECODED_BYTE_LENGTH;
262
374
  static encode = (value) => {
263
375
  invariant(value instanceof Uint8Array, "Invalid type");
264
- invariant(value.length === SpaceId.byteLength, "Invalid length");
265
- return MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
376
+ invariant(value.length === IdentityDid.byteLength, "Invalid length");
377
+ return DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
266
378
  };
267
379
  static decode = (value) => {
268
- invariant(value.startsWith(MULTIBASE_PREFIX), "Invalid multibase32 encoding");
269
- return new Uint8Array((0, import_base32_decode.default)(value.slice(1), "RFC4648"));
380
+ invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), "Invalid multibase32 encoding");
381
+ return new Uint8Array((0, import_base32_decode.default)(value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length), "RFC4648"));
270
382
  };
271
383
  static isValid = isValid;
272
384
  static random = () => {
273
- return SpaceId.encode(randomBytes(SpaceId.byteLength));
385
+ return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
274
386
  };
275
387
  };
276
388
 
277
- // src/dxn.ts
278
- var LOCAL_SPACE_TAG = "@";
279
- var DXN_ECHO_REGEXP = /@(dxn:[a-zA-Z0-p:@]+)/;
280
- var QueueSubspaceTags = Object.freeze({
281
- DATA: "data",
282
- TRACE: "trace"
389
+ // src/entity-id.ts
390
+ init_inject_globals();
391
+ import * as Schema5 from "effect/Schema";
392
+ import { monotonicFactory } from "ulidx";
393
+ var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
394
+ var EntityIdSchema = Schema5.String.pipe(Schema5.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
395
+ description: "A Universally Unique Lexicographically Sortable Identifier",
396
+ pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
283
397
  });
284
- var DXN = class _DXN {
285
- // TODO(burdon): Rename to DXN (i.e., DXN.DXN).
286
- // TODO(dmaretskyi): Should this be a transformation into the DXN type?
287
- static Schema = Schema3.NonEmptyString.pipe(
288
- Schema3.pattern(/^dxn:([^:]+):(?:[^:]+:?)+[^:]$/),
289
- // TODO(dmaretskyi): To set the format we need to move the annotation IDs out of the echo-schema package.
290
- // FormatAnnotation.set(TypeFormat.DXN),
291
- Schema3.annotations({
292
- title: "DXN",
293
- description: "DXN URI",
294
- examples: [
295
- "dxn:type:com.example.type.my-type",
296
- "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
297
- ]
298
- })
299
- );
300
- static hash(dxn) {
301
- return dxn.toString();
302
- }
303
- /**
304
- * Kind constants.
305
- */
306
- static kind = Object.freeze({
307
- /**
308
- * dxn:type:<type_name>[:<version>]
309
- */
310
- TYPE: "type",
311
- /**
312
- * dxn:echo:<space_id>:<echo_id>
313
- * dxn:echo:@:<echo_id>
314
- */
315
- // TODO(burdon): Rename to OBJECT? (BREAKING CHANGE to update "echo").
316
- // TODO(burdon): Add separate Kind for space?
317
- ECHO: "echo",
318
- /**
319
- * The subspace tag enables us to partition queues by usage within the context of a space.
320
- * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
321
- * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
322
- * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
323
- */
324
- QUEUE: "queue"
325
- });
326
- /**
327
- * Exactly equals.
328
- */
329
- static equals(a, b) {
330
- return a.kind === b.kind && a.parts.length === b.parts.length && a.parts.every((part, i) => part === b.parts[i]);
331
- }
332
- static equalsEchoId(a, b) {
333
- const a1 = a.asEchoDXN();
334
- const b1 = b.asEchoDXN();
335
- return !!a1 && !!b1 && a1.echoId === b1.echoId;
336
- }
337
- // TODO(burdon): Rename isValid.
338
- static isDXNString(dxn) {
339
- return dxn.startsWith("dxn:");
340
- }
341
- static parse(dxn) {
342
- if (typeof dxn !== "string") {
343
- throw new Error(`Invalid DXN: ${dxn}`);
344
- }
345
- const [prefix, kind, ...parts] = dxn.split(":");
346
- if (!(prefix === "dxn")) {
347
- throw new Error(`Invalid DXN: ${dxn}`);
348
- }
349
- if (!(typeof kind === "string" && kind.length > 0)) {
350
- throw new Error(`Invalid DXN: ${dxn}`);
351
- }
352
- if (!(parts.length > 0)) {
353
- throw new Error(`Invalid DXN: ${dxn}`);
354
- }
355
- return new _DXN(kind, parts);
356
- }
357
- static tryParse(dxn) {
398
+ var EntityId = class extends EntityIdSchema {
399
+ static #factory = monotonicFactory();
400
+ static #seedTime = void 0;
401
+ static isValid(id) {
358
402
  try {
359
- return _DXN.parse(dxn);
403
+ Schema5.decodeSync(EntityId)(id);
404
+ return true;
360
405
  } catch {
361
- return void 0;
406
+ return false;
362
407
  }
363
408
  }
364
- /**
365
- * @example `dxn:type:com.example.type.person`
366
- */
367
- static fromTypename(typename) {
368
- return new _DXN(_DXN.kind.TYPE, [
369
- typename
370
- ]);
371
- }
372
- /**
373
- * @example `dxn:type:com.example.type.person:0.1.0`
374
- */
375
- // TODO(dmaretskyi): Consider using @ as the version separator.
376
- static fromTypenameAndVersion(typename, version) {
377
- return new _DXN(_DXN.kind.TYPE, [
378
- typename,
379
- version
380
- ]);
381
- }
382
- /**
383
- * @example `dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6`
384
- */
385
- static fromSpaceAndObjectId(spaceId, objectId) {
386
- assertArgument(SpaceId.isValid(spaceId), `Invalid space ID: ${spaceId}`);
387
- assertArgument(ObjectId.isValid(objectId), "objectId", `Invalid object ID: ${objectId}`);
388
- return new _DXN(_DXN.kind.ECHO, [
389
- spaceId,
390
- objectId
391
- ]);
409
+ static random() {
410
+ return this.#factory(this.#seedTime);
392
411
  }
393
- /**
394
- * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
395
- */
396
- static fromLocalObjectId(id) {
397
- assertArgument(ObjectId.isValid(id), "id", `Invalid object ID: ${id}`);
398
- return new _DXN(_DXN.kind.ECHO, [
399
- LOCAL_SPACE_TAG,
400
- id
401
- ]);
402
- }
403
- static fromQueue(subspaceTag, spaceId, queueId, objectId) {
404
- assertArgument(SpaceId.isValid(spaceId), `Invalid space ID: ${spaceId}`);
405
- assertArgument(ObjectId.isValid(queueId), "queueId", `Invalid queue ID: ${queueId}`);
406
- assertArgument(!objectId || ObjectId.isValid(objectId), "objectId", `Invalid object ID: ${objectId}`);
407
- return new _DXN(_DXN.kind.QUEUE, [
408
- subspaceTag,
409
- spaceId,
410
- queueId,
411
- ...objectId ? [
412
- objectId
413
- ] : []
414
- ]);
415
- }
416
- #kind;
417
- #parts;
418
- constructor(kind, parts) {
419
- assertArgument(parts.length > 0, "parts", `Invalid DXN: ${parts}`);
420
- assertArgument(parts.every((part) => typeof part === "string" && part.length > 0 && part.indexOf(":") === -1), "parts", `Invalid DXN: ${parts}`);
421
- switch (kind) {
422
- case _DXN.kind.TYPE:
423
- if (parts.length > 2) {
424
- throw new Error("Invalid DXN.kind.TYPE");
425
- }
426
- break;
427
- case _DXN.kind.ECHO:
428
- if (parts.length !== 2) {
429
- throw new Error("Invalid DXN.kind.ECHO");
430
- }
431
- break;
412
+ static deterministic(...seed) {
413
+ const input = seed.map((value) => String(value)).join("\0");
414
+ let h1 = 2166136261 >>> 0;
415
+ let h2 = 461845907 >>> 0;
416
+ for (let i = 0; i < input.length; i++) {
417
+ const code = input.charCodeAt(i);
418
+ h1 = Math.imul(h1 ^ code, 16777619) >>> 0;
419
+ h2 = Math.imul(h2 ^ (code << 13 | code >>> 3), 16777619) >>> 0;
420
+ }
421
+ const time = ALPHABET[0].repeat(10);
422
+ let bits = BigInt(h1) << 32n | BigInt(h2);
423
+ let rand = "";
424
+ for (let i = 0; i < 16; i++) {
425
+ rand = ALPHABET[Number(bits & 0x1fn)] + rand;
426
+ bits >>= 5n;
432
427
  }
433
- this.#kind = kind;
434
- this.#parts = parts;
428
+ return time + rand;
435
429
  }
436
- toString() {
437
- return `dxn:${this.#kind}:${this.#parts.join(":")}`;
430
+ static dangerouslyDisableRandomness() {
431
+ this.#factory = monotonicFactory(makeTestPRNG());
432
+ this.#seedTime = (/* @__PURE__ */ new Date("2025-01-01")).getTime();
438
433
  }
439
- toJSON() {
440
- return this.toString();
434
+ static dangerouslySetSeed(time, seed) {
435
+ this.#factory = monotonicFactory(makeTestPRNG(seed));
436
+ this.#seedTime = time;
441
437
  }
438
+ };
439
+ var makeTestPRNG = (seed = 0) => {
440
+ const rng = new SimplePRNG(seed);
441
+ return () => {
442
+ return rng.next();
443
+ };
444
+ };
445
+ var SimplePRNG = class _SimplePRNG {
446
+ #seed;
447
+ // LCG parameters (from Numerical Recipes)
448
+ static #a = 1664525;
449
+ static #c = 1013904223;
450
+ static #m = Math.pow(2, 32);
442
451
  /**
443
- * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
452
+ * Creates a new PRNG instance.
453
+ * @param seed - Initial seed value. If not provided, uses 0.
444
454
  */
445
- [inspectCustom](depth, options, inspectFn) {
446
- const printControlCode = (code) => {
447
- return `\x1B[${code}m`;
448
- };
449
- return printControlCode(inspectFn.colors.blueBright[0]) + this.toString() + printControlCode(inspectFn.colors.reset[0]);
450
- }
451
- get [devtoolsFormatter]() {
452
- return {
453
- header: () => {
454
- return [
455
- "span",
456
- {
457
- style: "font-weight: bold;"
458
- },
459
- this.toString()
460
- ];
461
- }
462
- };
463
- }
464
- get kind() {
465
- return this.#kind;
466
- }
467
- get parts() {
468
- return this.#parts;
469
- }
470
- // TODO(burdon): Should getters fail?
471
- get typename() {
472
- invariant2(this.#kind === _DXN.kind.TYPE);
473
- return this.#parts[0];
474
- }
475
- equals(other) {
476
- return _DXN.equals(this, other);
477
- }
478
- hasTypenameOf(typename) {
479
- return this.#kind === _DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
480
- }
481
- isLocalObjectId() {
482
- return this.#kind === _DXN.kind.ECHO && this.#parts[0] === LOCAL_SPACE_TAG && this.#parts.length === 2;
483
- }
484
- asTypeDXN() {
485
- if (this.kind !== _DXN.kind.TYPE) {
486
- return void 0;
487
- }
488
- const [type, version] = this.#parts;
489
- return {
490
- // TODO(wittjosiah): Should be `typename` for consistency.
491
- type,
492
- version
493
- };
494
- }
495
- asEchoDXN() {
496
- if (this.kind !== _DXN.kind.ECHO) {
497
- return void 0;
498
- }
499
- const [spaceId, echoId] = this.#parts;
500
- return {
501
- spaceId: spaceId === LOCAL_SPACE_TAG ? void 0 : spaceId,
502
- // TODO(burdon): objectId.
503
- echoId
504
- };
455
+ constructor(seed = 0) {
456
+ this.#seed = seed;
505
457
  }
506
- asQueueDXN() {
507
- if (this.kind !== _DXN.kind.QUEUE) {
508
- return void 0;
509
- }
510
- const [subspaceTag, spaceId, queueId, objectId] = this.#parts;
511
- if (typeof queueId !== "string") {
512
- return void 0;
513
- }
514
- return {
515
- subspaceTag,
516
- spaceId,
517
- queueId,
518
- objectId
519
- };
458
+ /**
459
+ * Generates the next pseudo-random number in the range [0, 1).
460
+ * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
461
+ */
462
+ next() {
463
+ this.#seed = (_SimplePRNG.#a * this.#seed + _SimplePRNG.#c) % _SimplePRNG.#m;
464
+ return this.#seed / _SimplePRNG.#m;
520
465
  }
521
466
  /**
522
- * Produces a new DXN with the given parts appended.
467
+ * Resets the generator with a new seed.
468
+ * @param seed - New seed value.
523
469
  */
524
- extend(parts) {
525
- return new _DXN(this.#kind, [
526
- ...this.#parts,
527
- ...parts
528
- ]);
470
+ reset(seed) {
471
+ this.#seed = seed;
529
472
  }
530
473
  };
531
474
 
532
- // src/identity-did.ts
533
- init_inject_globals();
534
- var import_base32_decode2 = __toESM(require_base32_decode(), 1);
535
- import { invariant as invariant3 } from "@dxos/invariant";
536
- var IdentityDid = Object.freeze({
537
- byteLength: 20,
538
- encode: (value) => {
539
- invariant3(value instanceof Uint8Array, "Invalid type");
540
- invariant3(value.length === IdentityDid.byteLength, "Invalid length");
541
- return DID_PREFIX + MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
542
- },
543
- decode: (value) => {
544
- invariant3(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2), "Invalid multibase32 encoding");
545
- return new Uint8Array((0, import_base32_decode2.default)(value.slice(10), "RFC4648"));
546
- },
547
- isValid: (value) => {
548
- return typeof value === "string" && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
549
- },
550
- random: () => {
551
- return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
552
- }
553
- });
554
- var MULTIBASE_PREFIX2 = "B";
555
- var DID_PREFIX = "did:halo:";
556
- var ENCODED_LENGTH2 = 42;
557
-
558
475
  // src/parse-id.ts
559
476
  init_inject_globals();
560
477
  var SPACE_ID_LENGTH = 33;
@@ -584,9 +501,9 @@ var parseId = (id) => {
584
501
 
585
502
  // src/public-key.ts
586
503
  init_inject_globals();
587
- var import_base32_decode3 = __toESM(require_base32_decode(), 1);
588
- import { devtoolsFormatter as devtoolsFormatter2, equalsSymbol, inspectCustom as inspectCustom2, truncateKey } from "@dxos/debug";
589
- import { invariant as invariant4 } from "@dxos/invariant";
504
+ var import_base32_decode2 = __toESM(require_base32_decode(), 1);
505
+ import { devtoolsFormatter, equalsSymbol, inspectCustom, truncateKey } from "@dxos/debug";
506
+ import { assertArgument, invariant as invariant2 } from "@dxos/invariant";
590
507
  var PUBLIC_KEY_LENGTH = 32;
591
508
  var SECRET_KEY_LENGTH = 64;
592
509
  var isLikeArrayBuffer = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ArrayBuffer";
@@ -599,7 +516,7 @@ var PublicKey = class _PublicKey {
599
516
  * @returns PublicKey
600
517
  */
601
518
  static from(source) {
602
- invariant4(source);
519
+ invariant2(source);
603
520
  if (source instanceof _PublicKey) {
604
521
  return source;
605
522
  } else if (source instanceof Buffer2) {
@@ -683,7 +600,7 @@ var PublicKey = class _PublicKey {
683
600
  * @deprecated All keys should be represented as instances of PublicKey.
684
601
  */
685
602
  static bufferize(str) {
686
- invariant4(typeof str === "string", "Invalid type");
603
+ assertArgument(typeof str === "string", "str", "Invalid type");
687
604
  const buffer = Buffer2.from(str, "hex");
688
605
  return buffer;
689
606
  }
@@ -698,7 +615,7 @@ var PublicKey = class _PublicKey {
698
615
  } else if (key instanceof Uint8Array) {
699
616
  key = Buffer2.from(key.buffer, key.byteOffset, key.byteLength);
700
617
  }
701
- invariant4(key instanceof Buffer2, "Invalid type");
618
+ invariant2(key instanceof Buffer2, "Invalid type");
702
619
  return key.toString("hex");
703
620
  }
704
621
  /**
@@ -709,8 +626,8 @@ var PublicKey = class _PublicKey {
709
626
  return key.toHex();
710
627
  }
711
628
  static fromMultibase32(encoded) {
712
- invariant4(encoded.startsWith("B"), "Invalid multibase32 encoding");
713
- return new _PublicKey(new Uint8Array((0, import_base32_decode3.default)(encoded.slice(1), "RFC4648")));
629
+ invariant2(encoded.startsWith("B"), "Invalid multibase32 encoding");
630
+ return new _PublicKey(new Uint8Array((0, import_base32_decode2.default)(encoded.slice(1), "RFC4648")));
714
631
  }
715
632
  constructor(_value) {
716
633
  this._value = _value;
@@ -751,7 +668,7 @@ var PublicKey = class _PublicKey {
751
668
  /**
752
669
  * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
753
670
  */
754
- [inspectCustom2](depth, options, inspectFn) {
671
+ [inspectCustom](depth, options, inspectFn) {
755
672
  if (!options.colors || typeof process.stdout.hasColors !== "function" || !process.stdout.hasColors()) {
756
673
  return `<PublicKey ${this.truncate()}>`;
757
674
  }
@@ -776,7 +693,7 @@ var PublicKey = class _PublicKey {
776
693
  const color = colors[this.getInsecureHash(colors.length)];
777
694
  return `PublicKey(${printControlCode(inspectFn.colors[color][0])}${this.truncate()}${printControlCode(inspectFn.colors.reset[0])})`;
778
695
  }
779
- get [devtoolsFormatter2]() {
696
+ get [devtoolsFormatter]() {
780
697
  return {
781
698
  header: () => {
782
699
  const colors = [
@@ -840,21 +757,47 @@ var PublicKey = class _PublicKey {
840
757
  return this.equals(other);
841
758
  }
842
759
  };
760
+
761
+ // src/space-id.ts
762
+ init_inject_globals();
763
+ var import_base32_decode3 = __toESM(require_base32_decode(), 1);
764
+ import * as Schema6 from "effect/Schema";
765
+ import { invariant as invariant3 } from "@dxos/invariant";
766
+ var MULTIBASE_PREFIX2 = "B";
767
+ var ENCODED_LENGTH2 = 33;
768
+ var isValid2 = (value) => {
769
+ return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
770
+ };
771
+ var SpaceId = class extends Schema6.String.pipe(Schema6.filter(isValid2)) {
772
+ static byteLength = 20;
773
+ static encode = (value) => {
774
+ invariant3(value instanceof Uint8Array, "Invalid type");
775
+ invariant3(value.length === SpaceId.byteLength, "Invalid length");
776
+ return MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
777
+ };
778
+ static decode = (value) => {
779
+ invariant3(value.startsWith(MULTIBASE_PREFIX2), "Invalid multibase32 encoding");
780
+ return new Uint8Array((0, import_base32_decode3.default)(value.slice(1), "RFC4648"));
781
+ };
782
+ static isValid = isValid2;
783
+ static random = () => {
784
+ return SpaceId.encode(randomBytes(SpaceId.byteLength));
785
+ };
786
+ };
843
787
  export {
844
- DXN,
845
- DXN_ECHO_REGEXP,
788
+ DXN_exports as DXN,
789
+ EID_exports as EID,
790
+ EntityId,
846
791
  FQ_ID_LENGTH,
847
792
  IdentityDid,
848
- LOCAL_SPACE_TAG,
849
793
  OBJECT_ID_LENGTH,
850
- ObjectId,
851
794
  PUBLIC_KEY_LENGTH,
852
795
  PublicKey,
853
- QueueSubspaceTags,
854
796
  SECRET_KEY_LENGTH,
855
797
  SPACE_ID_LENGTH,
856
798
  SimplePRNG,
857
799
  SpaceId,
800
+ URI_exports as URI,
858
801
  parseId
859
802
  };
860
803
  //# sourceMappingURL=index.mjs.map