@dxos/keys 0.8.4-main.f9ba587 → 0.8.4-main.fffef41

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.
@@ -82,28 +82,69 @@ var require_base32_decode = __commonJS({
82
82
  });
83
83
 
84
84
  // src/dxn.ts
85
- import { Schema as Schema3 } from "effect";
85
+ import * as Schema3 from "effect/Schema";
86
86
  import { devtoolsFormatter, inspectCustom } from "@dxos/debug";
87
- import { invariant as invariant2 } from "@dxos/invariant";
87
+ import { assertArgument, invariant as invariant2 } from "@dxos/invariant";
88
88
 
89
89
  // src/object-id.ts
90
- import { Schema } from "effect";
91
- import { ulid } from "ulidx";
90
+ import * as Schema from "effect/Schema";
91
+ import { monotonicFactory } from "ulidx";
92
92
  var ObjectIdSchema = Schema.String.pipe(Schema.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
93
- description: "a Universally Unique Lexicographically Sortable Identifier",
93
+ description: "A Universally Unique Lexicographically Sortable Identifier",
94
94
  pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
95
95
  });
96
96
  var ObjectId = class extends ObjectIdSchema {
97
+ static #factory = monotonicFactory();
98
+ static #seedTime = void 0;
97
99
  static isValid(id) {
98
100
  try {
99
101
  Schema.decodeSync(ObjectId)(id);
100
102
  return true;
101
- } catch (err) {
103
+ } catch {
102
104
  return false;
103
105
  }
104
106
  }
105
107
  static random() {
106
- return ulid();
108
+ return this.#factory(this.#seedTime);
109
+ }
110
+ static dangerouslyDisableRandomness() {
111
+ this.#factory = monotonicFactory(makeTestPRNG());
112
+ this.#seedTime = (/* @__PURE__ */ new Date("2025-01-01")).getTime();
113
+ }
114
+ };
115
+ var makeTestPRNG = () => {
116
+ const rng = new SimplePRNG();
117
+ return () => {
118
+ return rng.next();
119
+ };
120
+ };
121
+ var SimplePRNG = class _SimplePRNG {
122
+ #seed;
123
+ // LCG parameters (from Numerical Recipes)
124
+ static #a = 1664525;
125
+ static #c = 1013904223;
126
+ static #m = Math.pow(2, 32);
127
+ /**
128
+ * Creates a new PRNG instance.
129
+ * @param seed - Initial seed value. If not provided, uses 0.
130
+ */
131
+ constructor(seed = 0) {
132
+ this.#seed = seed;
133
+ }
134
+ /**
135
+ * Generates the next pseudo-random number in the range [0, 1).
136
+ * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
137
+ */
138
+ next() {
139
+ this.#seed = (_SimplePRNG.#a * this.#seed + _SimplePRNG.#c) % _SimplePRNG.#m;
140
+ return this.#seed / _SimplePRNG.#m;
141
+ }
142
+ /**
143
+ * Resets the generator with a new seed.
144
+ * @param seed - New seed value.
145
+ */
146
+ reset(seed) {
147
+ this.#seed = seed;
107
148
  }
108
149
  };
109
150
 
@@ -170,7 +211,7 @@ function base32Encode(data, variant, options) {
170
211
  }
171
212
 
172
213
  // src/space-id.ts
173
- import { Schema as Schema2 } from "effect";
214
+ import * as Schema2 from "effect/Schema";
174
215
  import { invariant } from "@dxos/invariant";
175
216
 
176
217
  // src/random-bytes.ts
@@ -189,114 +230,107 @@ var isValid = (value) => {
189
230
  return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH;
190
231
  };
191
232
  var SpaceId = class extends Schema2.String.pipe(Schema2.filter(isValid)) {
192
- static {
193
- this.byteLength = 20;
194
- }
195
- static {
196
- this.encode = (value) => {
197
- invariant(value instanceof Uint8Array, "Invalid type", {
198
- F: __dxlog_file,
199
- L: 43,
200
- S: this,
201
- A: [
202
- "value instanceof Uint8Array",
203
- "'Invalid type'"
204
- ]
205
- });
206
- invariant(value.length === SpaceId.byteLength, "Invalid length", {
207
- F: __dxlog_file,
208
- L: 44,
209
- S: this,
210
- A: [
211
- "value.length === SpaceId.byteLength",
212
- "'Invalid length'"
213
- ]
214
- });
215
- return MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
216
- };
217
- }
218
- static {
219
- this.decode = (value) => {
220
- invariant(value.startsWith(MULTIBASE_PREFIX), "Invalid multibase32 encoding", {
221
- F: __dxlog_file,
222
- L: 49,
223
- S: this,
224
- A: [
225
- "value.startsWith(MULTIBASE_PREFIX)",
226
- "'Invalid multibase32 encoding'"
227
- ]
228
- });
229
- return new Uint8Array((0, import_base32_decode.default)(value.slice(1), "RFC4648"));
230
- };
231
- }
232
- static {
233
- this.isValid = isValid;
234
- }
235
- static {
236
- this.random = () => {
237
- return SpaceId.encode(randomBytes(SpaceId.byteLength));
238
- };
239
- }
233
+ static byteLength = 20;
234
+ static encode = (value) => {
235
+ invariant(value instanceof Uint8Array, "Invalid type", {
236
+ F: __dxlog_file,
237
+ L: 43,
238
+ S: this,
239
+ A: [
240
+ "value instanceof Uint8Array",
241
+ "'Invalid type'"
242
+ ]
243
+ });
244
+ invariant(value.length === SpaceId.byteLength, "Invalid length", {
245
+ F: __dxlog_file,
246
+ L: 44,
247
+ S: this,
248
+ A: [
249
+ "value.length === SpaceId.byteLength",
250
+ "'Invalid length'"
251
+ ]
252
+ });
253
+ return MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
254
+ };
255
+ static decode = (value) => {
256
+ invariant(value.startsWith(MULTIBASE_PREFIX), "Invalid multibase32 encoding", {
257
+ F: __dxlog_file,
258
+ L: 49,
259
+ S: this,
260
+ A: [
261
+ "value.startsWith(MULTIBASE_PREFIX)",
262
+ "'Invalid multibase32 encoding'"
263
+ ]
264
+ });
265
+ return new Uint8Array((0, import_base32_decode.default)(value.slice(1), "RFC4648"));
266
+ };
267
+ static isValid = isValid;
268
+ static random = () => {
269
+ return SpaceId.encode(randomBytes(SpaceId.byteLength));
270
+ };
240
271
  };
241
272
 
242
273
  // src/dxn.ts
243
274
  var __dxlog_file2 = "/__w/dxos/dxos/packages/common/keys/src/dxn.ts";
244
275
  var LOCAL_SPACE_TAG = "@";
276
+ var DXN_ECHO_REGEXP = /@(dxn:[a-zA-Z0-p:@]+)/;
245
277
  var QueueSubspaceTags = Object.freeze({
246
278
  DATA: "data",
247
279
  TRACE: "trace"
248
280
  });
249
281
  var DXN = class _DXN {
250
- static {
251
- // TODO(dmaretskyi): Should this be a transformation into the DXN type?
252
- this.Schema = Schema3.NonEmptyString.pipe(
253
- Schema3.pattern(/^dxn:([^:]+):(?:[^:]+:?)+[^:]$/),
254
- // TODO(dmaretskyi): To set the format we need to move the annotation IDs out of the echo-schema package.
255
- // FormatAnnotation.set(FormatEnum.DXN),
256
- Schema3.annotations({
257
- title: "DXN",
258
- description: "DXN URI",
259
- examples: [
260
- "dxn:type:example.com/type/MyType",
261
- "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
262
- ]
263
- })
264
- );
265
- }
282
+ // TODO(burdon): Rename to DXN (i.e., DXN.DXN).
283
+ // TODO(dmaretskyi): Should this be a transformation into the DXN type?
284
+ static Schema = Schema3.NonEmptyString.pipe(
285
+ Schema3.pattern(/^dxn:([^:]+):(?:[^:]+:?)+[^:]$/),
286
+ // TODO(dmaretskyi): To set the format we need to move the annotation IDs out of the echo-schema package.
287
+ // FormatAnnotation.set(FormatEnum.DXN),
288
+ Schema3.annotations({
289
+ title: "DXN",
290
+ description: "DXN URI",
291
+ examples: [
292
+ "dxn:type:example.com/type/MyType",
293
+ "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
294
+ ]
295
+ })
296
+ );
266
297
  static hash(dxn) {
267
298
  return dxn.toString();
268
299
  }
269
- static {
300
+ /**
301
+ * Kind constants.
302
+ */
303
+ static kind = Object.freeze({
270
304
  /**
271
- * Kind constants.
305
+ * dxn:type:<type_name>[:<version>]
272
306
  */
273
- this.kind = Object.freeze({
274
- /**
275
- * dxn:type:<type name>[:<version>]
276
- */
277
- TYPE: "type",
278
- /**
279
- * dxn:echo:<space id>:<echo id>
280
- * dxn:echo:@:<echo id>
281
- */
282
- // TODO(burdon): Rename to OBJECT? (BREAKING CHANGE).
283
- // TODO(burdon): Add separate Kind for space.
284
- ECHO: "echo",
285
- /**
286
- * The subspace tag enables us to partition queues by usage within the context of a space.
287
- * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
288
- * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
289
- * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
290
- */
291
- QUEUE: "queue"
292
- });
293
- }
294
- get kind() {
295
- return this.#kind;
296
- }
307
+ TYPE: "type",
308
+ /**
309
+ * dxn:echo:<space_id>:<echo_id>
310
+ * dxn:echo:@:<echo_id>
311
+ */
312
+ // TODO(burdon): Rename to OBJECT? (BREAKING CHANGE to update "echo").
313
+ // TODO(burdon): Add separate Kind for space?
314
+ ECHO: "echo",
315
+ /**
316
+ * The subspace tag enables us to partition queues by usage within the context of a space.
317
+ * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
318
+ * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
319
+ * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
320
+ */
321
+ QUEUE: "queue"
322
+ });
323
+ /**
324
+ * Exactly equals.
325
+ */
297
326
  static equals(a, b) {
298
327
  return a.kind === b.kind && a.parts.length === b.parts.length && a.parts.every((part, i) => part === b.parts[i]);
299
328
  }
329
+ static equalsEchoId(a, b) {
330
+ const a1 = a.asEchoDXN();
331
+ const b1 = b.asEchoDXN();
332
+ return !!a1 && !!b1 && a1.echoId === b1.echoId;
333
+ }
300
334
  // TODO(burdon): Rename isValid.
301
335
  static isDXNString(dxn) {
302
336
  return dxn.startsWith("dxn:");
@@ -320,12 +354,12 @@ var DXN = class _DXN {
320
354
  static tryParse(dxn) {
321
355
  try {
322
356
  return _DXN.parse(dxn);
323
- } catch (error) {
357
+ } catch {
324
358
  return void 0;
325
359
  }
326
360
  }
327
361
  /**
328
- * @example `dxn:type:example.com/type/Contact`
362
+ * @example `dxn:type:example.com/type/Person`
329
363
  */
330
364
  static fromTypename(typename) {
331
365
  return new _DXN(_DXN.kind.TYPE, [
@@ -333,7 +367,7 @@ var DXN = class _DXN {
333
367
  ]);
334
368
  }
335
369
  /**
336
- * @example `dxn:type:example.com/type/Contact:0.1.0`
370
+ * @example `dxn:type:example.com/type/Person:0.1.0`
337
371
  */
338
372
  // TODO(dmaretskyi): Consider using @ as the version separator.
339
373
  static fromTypenameAndVersion(typename, version) {
@@ -343,42 +377,30 @@ var DXN = class _DXN {
343
377
  ]);
344
378
  }
345
379
  /**
380
+ * @example `dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6`
381
+ */
382
+ static fromSpaceAndObjectId(spaceId, objectId) {
383
+ assertArgument(SpaceId.isValid(spaceId), `Invalid space ID: ${spaceId}`);
384
+ assertArgument(ObjectId.isValid(objectId), "objectId", `Invalid object ID: ${objectId}`);
385
+ return new _DXN(_DXN.kind.ECHO, [
386
+ spaceId,
387
+ objectId
388
+ ]);
389
+ }
390
+ /**
346
391
  * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
347
392
  */
348
393
  static fromLocalObjectId(id) {
394
+ assertArgument(ObjectId.isValid(id), "id", `Invalid object ID: ${id}`);
349
395
  return new _DXN(_DXN.kind.ECHO, [
350
396
  LOCAL_SPACE_TAG,
351
397
  id
352
398
  ]);
353
399
  }
354
400
  static fromQueue(subspaceTag, spaceId, queueId, objectId) {
355
- invariant2(SpaceId.isValid(spaceId), void 0, {
356
- F: __dxlog_file2,
357
- L: 150,
358
- S: this,
359
- A: [
360
- "SpaceId.isValid(spaceId)",
361
- ""
362
- ]
363
- });
364
- invariant2(ObjectId.isValid(queueId), void 0, {
365
- F: __dxlog_file2,
366
- L: 151,
367
- S: this,
368
- A: [
369
- "ObjectId.isValid(queueId)",
370
- ""
371
- ]
372
- });
373
- invariant2(!objectId || ObjectId.isValid(objectId), void 0, {
374
- F: __dxlog_file2,
375
- L: 152,
376
- S: this,
377
- A: [
378
- "!objectId || ObjectId.isValid(objectId)",
379
- ""
380
- ]
381
- });
401
+ assertArgument(SpaceId.isValid(spaceId), `Invalid space ID: ${spaceId}`);
402
+ assertArgument(ObjectId.isValid(queueId), "queueId", `Invalid queue ID: ${queueId}`);
403
+ assertArgument(!objectId || ObjectId.isValid(objectId), "objectId", `Invalid object ID: ${objectId}`);
382
404
  return new _DXN(_DXN.kind.QUEUE, [
383
405
  subspaceTag,
384
406
  spaceId,
@@ -391,33 +413,17 @@ var DXN = class _DXN {
391
413
  #kind;
392
414
  #parts;
393
415
  constructor(kind, parts) {
394
- invariant2(parts.length > 0, void 0, {
395
- F: __dxlog_file2,
396
- L: 161,
397
- S: this,
398
- A: [
399
- "parts.length > 0",
400
- ""
401
- ]
402
- });
403
- invariant2(parts.every((part) => typeof part === "string" && part.length > 0 && part.indexOf(":") === -1), void 0, {
404
- F: __dxlog_file2,
405
- L: 162,
406
- S: this,
407
- A: [
408
- "parts.every((part) => typeof part === 'string' && part.length > 0 && part.indexOf(':') === -1)",
409
- ""
410
- ]
411
- });
416
+ assertArgument(parts.length > 0, "parts", `Invalid DXN: ${parts}`);
417
+ assertArgument(parts.every((part) => typeof part === "string" && part.length > 0 && part.indexOf(":") === -1), "parts", `Invalid DXN: ${parts}`);
412
418
  switch (kind) {
413
419
  case _DXN.kind.TYPE:
414
420
  if (parts.length > 2) {
415
- throw new Error('Invalid "type" DXN');
421
+ throw new Error("Invalid DXN.kind.TYPE");
416
422
  }
417
423
  break;
418
424
  case _DXN.kind.ECHO:
419
425
  if (parts.length !== 2) {
420
- throw new Error('Invalid "echo" DXN');
426
+ throw new Error("Invalid DXN.kind.ECHO");
421
427
  }
422
428
  break;
423
429
  }
@@ -452,6 +458,9 @@ var DXN = class _DXN {
452
458
  }
453
459
  };
454
460
  }
461
+ get kind() {
462
+ return this.#kind;
463
+ }
455
464
  get parts() {
456
465
  return this.#parts;
457
466
  }
@@ -459,7 +468,7 @@ var DXN = class _DXN {
459
468
  get typename() {
460
469
  invariant2(this.#kind === _DXN.kind.TYPE, void 0, {
461
470
  F: __dxlog_file2,
462
- L: 217,
471
+ L: 250,
463
472
  S: this,
464
473
  A: [
465
474
  "this.#kind === DXN.kind.TYPE",
@@ -468,6 +477,9 @@ var DXN = class _DXN {
468
477
  });
469
478
  return this.#parts[0];
470
479
  }
480
+ equals(other) {
481
+ return _DXN.equals(this, other);
482
+ }
471
483
  hasTypenameOf(typename) {
472
484
  return this.#kind === _DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
473
485
  }
@@ -480,6 +492,7 @@ var DXN = class _DXN {
480
492
  }
481
493
  const [type, version] = this.#parts;
482
494
  return {
495
+ // TODO(wittjosiah): Should be `typename` for consistency.
483
496
  type,
484
497
  version
485
498
  };
@@ -491,6 +504,7 @@ var DXN = class _DXN {
491
504
  const [spaceId, echoId] = this.#parts;
492
505
  return {
493
506
  spaceId: spaceId === LOCAL_SPACE_TAG ? void 0 : spaceId,
507
+ // TODO(burdon): objectId.
494
508
  echoId
495
509
  };
496
510
  }
@@ -509,6 +523,15 @@ var DXN = class _DXN {
509
523
  objectId
510
524
  };
511
525
  }
526
+ /**
527
+ * Produces a new DXN with the given parts appended.
528
+ */
529
+ extend(parts) {
530
+ return new _DXN(this.#kind, [
531
+ ...this.#parts,
532
+ ...parts
533
+ ]);
534
+ }
512
535
  };
513
536
 
514
537
  // src/identity-did.ts
@@ -570,9 +593,8 @@ var PUBLIC_KEY_LENGTH = 32;
570
593
  var SECRET_KEY_LENGTH = 64;
571
594
  var isLikeArrayBuffer = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ArrayBuffer";
572
595
  var PublicKey = class _PublicKey {
573
- static {
574
- this.ZERO = _PublicKey.from("00".repeat(PUBLIC_KEY_LENGTH));
575
- }
596
+ _value;
597
+ static ZERO = _PublicKey.from("00".repeat(PUBLIC_KEY_LENGTH));
576
598
  /**
577
599
  * Creates new instance of PublicKey automatically determining the input format.
578
600
  * @param source A Buffer, or Uint8Array, or hex encoded string, or something with an `asUint8Array` method on it
@@ -581,7 +603,7 @@ var PublicKey = class _PublicKey {
581
603
  static from(source) {
582
604
  invariant4(source, void 0, {
583
605
  F: __dxlog_file4,
584
- L: 49,
606
+ L: 50,
585
607
  S: this,
586
608
  A: [
587
609
  "source",
@@ -673,7 +695,7 @@ var PublicKey = class _PublicKey {
673
695
  static bufferize(str) {
674
696
  invariant4(typeof str === "string", "Invalid type", {
675
697
  F: __dxlog_file4,
676
- L: 152,
698
+ L: 153,
677
699
  S: this,
678
700
  A: [
679
701
  "typeof str === 'string'",
@@ -696,7 +718,7 @@ var PublicKey = class _PublicKey {
696
718
  }
697
719
  invariant4(key instanceof Buffer, "Invalid type", {
698
720
  F: __dxlog_file4,
699
- L: 171,
721
+ L: 172,
700
722
  S: this,
701
723
  A: [
702
724
  "key instanceof Buffer",
@@ -715,7 +737,7 @@ var PublicKey = class _PublicKey {
715
737
  static fromMultibase32(encoded) {
716
738
  invariant4(encoded.startsWith("B"), "Invalid multibase32 encoding", {
717
739
  F: __dxlog_file4,
718
- L: 184,
740
+ L: 185,
719
741
  S: this,
720
742
  A: [
721
743
  "encoded.startsWith('B')",
@@ -854,6 +876,7 @@ var PublicKey = class _PublicKey {
854
876
  };
855
877
  export {
856
878
  DXN,
879
+ DXN_ECHO_REGEXP,
857
880
  IdentityDid,
858
881
  LOCAL_SPACE_TAG,
859
882
  ObjectId,
@@ -861,6 +884,7 @@ export {
861
884
  PublicKey,
862
885
  QueueSubspaceTags,
863
886
  SECRET_KEY_LENGTH,
887
+ SimplePRNG,
864
888
  SpaceId
865
889
  };
866
890
  //# sourceMappingURL=index.mjs.map