@dxos/keys 0.8.3-main.672df60 → 0.8.3-main.7f5a14c

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.
@@ -29,16 +29,16 @@ __export(node_exports, {
29
29
  SpaceId: () => SpaceId
30
30
  });
31
31
  module.exports = __toCommonJS(node_exports);
32
- var import_invariant = require("@dxos/invariant");
32
+ var import_effect = require("effect");
33
33
  var import_debug = require("@dxos/debug");
34
+ var import_invariant = require("@dxos/invariant");
35
+ var import_effect2 = require("effect");
36
+ var import_ulidx = require("ulidx");
37
+ var import_effect3 = require("effect");
34
38
  var import_invariant2 = require("@dxos/invariant");
35
- var import_effect = require("effect");
36
39
  var import_invariant3 = require("@dxos/invariant");
37
- var import_effect2 = require("effect");
38
40
  var import_debug2 = require("@dxos/debug");
39
41
  var import_invariant4 = require("@dxos/invariant");
40
- var import_effect3 = require("effect");
41
- var import_ulidx = require("ulidx");
42
42
  var __create = Object.create;
43
43
  var __defProp2 = Object.defineProperty;
44
44
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -118,6 +118,23 @@ var require_base32_decode = __commonJS({
118
118
  };
119
119
  }
120
120
  });
121
+ var ObjectIdSchema = import_effect2.Schema.String.pipe(import_effect2.Schema.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
122
+ description: "a Universally Unique Lexicographically Sortable Identifier",
123
+ pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
124
+ });
125
+ var ObjectId = class extends ObjectIdSchema {
126
+ static isValid(id) {
127
+ try {
128
+ import_effect2.Schema.decodeSync(ObjectId)(id);
129
+ return true;
130
+ } catch (err) {
131
+ return false;
132
+ }
133
+ }
134
+ static random() {
135
+ return (0, import_ulidx.ulid)();
136
+ }
137
+ };
121
138
  var import_base32_decode = __toESM(require_base32_decode(), 1);
122
139
  function toDataView(data) {
123
140
  if (data instanceof Int8Array || data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
@@ -180,673 +197,659 @@ var randomBytes = (length) => {
180
197
  webCrypto.getRandomValues(bytes);
181
198
  return bytes;
182
199
  };
183
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/keys/src/identity-did.ts";
184
- var IdentityDid = Object.freeze({
185
- byteLength: 20,
186
- encode: (value) => {
187
- (0, import_invariant.invariant)(value instanceof Uint8Array, "Invalid type", {
188
- F: __dxlog_file,
189
- L: 22,
190
- S: void 0,
191
- A: [
192
- "value instanceof Uint8Array",
193
- "'Invalid type'"
194
- ]
195
- });
196
- (0, import_invariant.invariant)(value.length === IdentityDid.byteLength, "Invalid length", {
197
- F: __dxlog_file,
198
- L: 23,
199
- S: void 0,
200
- A: [
201
- "value.length === IdentityDid.byteLength",
202
- "'Invalid length'"
203
- ]
204
- });
205
- return DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
206
- },
207
- decode: (value) => {
208
- (0, import_invariant.invariant)(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), "Invalid multibase32 encoding", {
209
- F: __dxlog_file,
210
- L: 28,
211
- S: void 0,
212
- A: [
213
- "value.startsWith(DID_PREFIX + MULTIBASE_PREFIX)",
214
- "'Invalid multibase32 encoding'"
215
- ]
216
- });
217
- return new Uint8Array((0, import_base32_decode.default)(value.slice(10), "RFC4648"));
218
- },
219
- isValid: (value) => {
220
- return typeof value === "string" && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH;
221
- },
222
- random: () => {
223
- return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
200
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/keys/src/space-id.ts";
201
+ var MULTIBASE_PREFIX = "B";
202
+ var ENCODED_LENGTH = 33;
203
+ var isValid = (value) => {
204
+ return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH;
205
+ };
206
+ var SpaceId = class extends import_effect3.Schema.String.pipe(import_effect3.Schema.filter(isValid)) {
207
+ static {
208
+ this.byteLength = 20;
209
+ }
210
+ static {
211
+ this.encode = (value) => {
212
+ (0, import_invariant2.invariant)(value instanceof Uint8Array, "Invalid type", {
213
+ F: __dxlog_file,
214
+ L: 43,
215
+ S: this,
216
+ A: [
217
+ "value instanceof Uint8Array",
218
+ "'Invalid type'"
219
+ ]
220
+ });
221
+ (0, import_invariant2.invariant)(value.length === SpaceId.byteLength, "Invalid length", {
222
+ F: __dxlog_file,
223
+ L: 44,
224
+ S: this,
225
+ A: [
226
+ "value.length === SpaceId.byteLength",
227
+ "'Invalid length'"
228
+ ]
229
+ });
230
+ return MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
231
+ };
232
+ }
233
+ static {
234
+ this.decode = (value) => {
235
+ (0, import_invariant2.invariant)(value.startsWith(MULTIBASE_PREFIX), "Invalid multibase32 encoding", {
236
+ F: __dxlog_file,
237
+ L: 49,
238
+ S: this,
239
+ A: [
240
+ "value.startsWith(MULTIBASE_PREFIX)",
241
+ "'Invalid multibase32 encoding'"
242
+ ]
243
+ });
244
+ return new Uint8Array((0, import_base32_decode.default)(value.slice(1), "RFC4648"));
245
+ };
246
+ }
247
+ static {
248
+ this.isValid = isValid;
249
+ }
250
+ static {
251
+ this.random = () => {
252
+ return SpaceId.encode(randomBytes(SpaceId.byteLength));
253
+ };
224
254
  }
255
+ };
256
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/common/keys/src/dxn.ts";
257
+ var LOCAL_SPACE_TAG = "@";
258
+ var QueueSubspaceTags = Object.freeze({
259
+ DATA: "data",
260
+ TRACE: "trace"
225
261
  });
226
- var MULTIBASE_PREFIX = "B";
227
- var DID_PREFIX = "did:halo:";
228
- var ENCODED_LENGTH = 42;
229
- var import_base32_decode2 = __toESM(require_base32_decode(), 1);
230
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/common/keys/src/public-key.ts";
231
- var PUBLIC_KEY_LENGTH = 32;
232
- var SECRET_KEY_LENGTH = 64;
233
- var isLikeArrayBuffer = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ArrayBuffer";
234
- var PublicKey = class _PublicKey {
262
+ var DXN = class _DXN {
235
263
  static {
236
- this.ZERO = _PublicKey.from("00".repeat(PUBLIC_KEY_LENGTH));
264
+ this.Schema = import_effect.Schema.NonEmptyString.pipe(
265
+ import_effect.Schema.pattern(/^dxn:([^:]+):(?:[^:]+:?)+[^:]$/),
266
+ // TODO(dmaretskyi): To set the format we need to move the annotation IDs out of the echo-schema package.
267
+ // FormatAnnotation.set(FormatEnum.DXN),
268
+ import_effect.Schema.annotations({
269
+ title: "DXN",
270
+ description: "DXN URI",
271
+ examples: [
272
+ "dxn:type:example.com/type/MyType",
273
+ "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
274
+ ]
275
+ })
276
+ );
237
277
  }
238
- /**
239
- * Creates new instance of PublicKey automatically determining the input format.
240
- * @param source A Buffer, or Uint8Array, or hex encoded string, or something with an `asUint8Array` method on it
241
- * @returns PublicKey
242
- */
243
- static from(source) {
244
- (0, import_invariant2.invariant)(source, void 0, {
245
- F: __dxlog_file2,
246
- L: 49,
247
- S: this,
248
- A: [
249
- "source",
250
- ""
251
- ]
278
+ static hash(dxn) {
279
+ return dxn.toString();
280
+ }
281
+ static {
282
+ this.kind = Object.freeze({
283
+ /**
284
+ * dxn:type:<type name>[:<version>]
285
+ */
286
+ TYPE: "type",
287
+ /**
288
+ * dxn:echo:<space id>:<echo id>
289
+ * dxn:echo:@:<echo id>
290
+ */
291
+ // TODO(burdon): Rename to OBJECT? (BREAKING CHANGE).
292
+ // TODO(burdon): Add separate Kind for space.
293
+ ECHO: "echo",
294
+ /**
295
+ * The subspace tag enables us to partition queues by usage within the context of a space.
296
+ * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
297
+ * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
298
+ * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
299
+ */
300
+ QUEUE: "queue"
252
301
  });
253
- if (source instanceof _PublicKey) {
254
- return source;
255
- } else if (source instanceof Buffer) {
256
- return new _PublicKey(new Uint8Array(source.buffer, source.byteOffset, source.byteLength));
257
- } else if (source instanceof Uint8Array) {
258
- return new _PublicKey(source);
259
- } else if (source instanceof ArrayBuffer || isLikeArrayBuffer(source)) {
260
- return new _PublicKey(new Uint8Array(source));
261
- } else if (typeof source === "string") {
262
- return _PublicKey.fromHex(source);
263
- } else if (source.asUint8Array) {
264
- return new _PublicKey(source.asUint8Array());
265
- } else {
266
- throw new TypeError(`Unable to create PublicKey from ${source}`);
267
- }
268
302
  }
269
- /**
270
- * Same as `PublicKey.from` but does not throw and instead returns a `{ key: PublicKey }` or `{ error: Error }`
271
- * @param source Same PublicKeyLike argument as for `PublicKey.from`
272
- * @returns PublicKey
273
- */
274
- static safeFrom(source) {
275
- if (!source) {
276
- return void 0;
277
- }
278
- try {
279
- const key = _PublicKey.from(source);
280
- return key;
281
- } catch (err) {
282
- return void 0;
283
- }
303
+ get kind() {
304
+ return this.#kind;
284
305
  }
285
- /**
286
- * Creates new instance of PublicKey from hex string.
287
- */
288
- static fromHex(hex) {
289
- if (hex.startsWith("0x")) {
290
- hex = hex.slice(2);
291
- }
292
- const buf = Buffer.from(hex, "hex");
293
- return new _PublicKey(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength));
306
+ static equals(a, b) {
307
+ return a.kind === b.kind && a.parts.length === b.parts.length && a.parts.every((part, i) => part === b.parts[i]);
294
308
  }
295
- /**
296
- * Creates a new key.
297
- */
298
- static random() {
299
- return _PublicKey.from(randomBytes(PUBLIC_KEY_LENGTH));
309
+ // TODO(burdon): Rename isValid.
310
+ static isDXNString(dxn) {
311
+ return dxn.startsWith("dxn:");
300
312
  }
301
- static randomOfLength(length) {
302
- return _PublicKey.from(randomBytes(length));
313
+ static parse(dxn) {
314
+ if (typeof dxn !== "string") {
315
+ throw new Error(`Invalid DXN: ${dxn}`);
316
+ }
317
+ const [prefix, kind, ...parts] = dxn.split(":");
318
+ if (!(prefix === "dxn")) {
319
+ throw new Error(`Invalid DXN: ${dxn}`);
320
+ }
321
+ if (!(typeof kind === "string" && kind.length > 0)) {
322
+ throw new Error(`Invalid DXN: ${dxn}`);
323
+ }
324
+ if (!(parts.length > 0)) {
325
+ throw new Error(`Invalid DXN: ${dxn}`);
326
+ }
327
+ return new _DXN(kind, parts);
303
328
  }
304
- static *randomSequence() {
305
- for (let i = 0; i < 1e4; i++) {
306
- yield _PublicKey.random();
329
+ static tryParse(dxn) {
330
+ try {
331
+ return _DXN.parse(dxn);
332
+ } catch (error) {
333
+ return void 0;
307
334
  }
308
- throw new Error("Too many keys requested");
309
335
  }
310
336
  /**
311
- * Tests if provided values is an instance of PublicKey.
337
+ * @example `dxn:type:example.com/type/Contact`
312
338
  */
313
- static isPublicKey(value) {
314
- return value instanceof _PublicKey;
339
+ static fromTypename(typename) {
340
+ return new _DXN(_DXN.kind.TYPE, [
341
+ typename
342
+ ]);
315
343
  }
316
344
  /**
317
- * Asserts that provided values is an instance of PublicKey.
345
+ * @example `dxn:type:example.com/type/Contact:0.1.0`
318
346
  */
319
- static assertValidPublicKey(value) {
320
- if (!this.isPublicKey(value)) {
321
- throw new TypeError("Invalid PublicKey");
322
- }
347
+ // TODO(dmaretskyi): Consider using @ as the version separator.
348
+ static fromTypenameAndVersion(typename, version) {
349
+ return new _DXN(_DXN.kind.TYPE, [
350
+ typename,
351
+ version
352
+ ]);
323
353
  }
324
354
  /**
325
- * Tests two keys for equality.
355
+ * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
326
356
  */
327
- static equals(left, right) {
328
- return _PublicKey.from(left).equals(right);
357
+ static fromLocalObjectId(id) {
358
+ return new _DXN(_DXN.kind.ECHO, [
359
+ LOCAL_SPACE_TAG,
360
+ id
361
+ ]);
329
362
  }
330
- /**
331
- * @param str string representation of key.
332
- * @return Key buffer.
333
- * @deprecated All keys should be represented as instances of PublicKey.
334
- */
335
- static bufferize(str) {
336
- (0, import_invariant2.invariant)(typeof str === "string", "Invalid type", {
363
+ static fromQueue(subspaceTag, spaceId, queueId, objectId) {
364
+ (0, import_invariant.invariant)(SpaceId.isValid(spaceId), void 0, {
365
+ F: __dxlog_file2,
366
+ L: 150,
367
+ S: this,
368
+ A: [
369
+ "SpaceId.isValid(spaceId)",
370
+ ""
371
+ ]
372
+ });
373
+ (0, import_invariant.invariant)(ObjectId.isValid(queueId), void 0, {
374
+ F: __dxlog_file2,
375
+ L: 151,
376
+ S: this,
377
+ A: [
378
+ "ObjectId.isValid(queueId)",
379
+ ""
380
+ ]
381
+ });
382
+ (0, import_invariant.invariant)(!objectId || ObjectId.isValid(objectId), void 0, {
337
383
  F: __dxlog_file2,
338
384
  L: 152,
339
385
  S: this,
340
386
  A: [
341
- "typeof str === 'string'",
342
- "'Invalid type'"
387
+ "!objectId || ObjectId.isValid(objectId)",
388
+ ""
343
389
  ]
344
390
  });
345
- const buffer = Buffer.from(str, "hex");
346
- return buffer;
391
+ return new _DXN(_DXN.kind.QUEUE, [
392
+ subspaceTag,
393
+ spaceId,
394
+ queueId,
395
+ ...objectId ? [
396
+ objectId
397
+ ] : []
398
+ ]);
347
399
  }
348
- /**
349
- * @param key key like data structure (but not PublicKey which should use toString).
350
- * @return Hex string representation of key.
351
- * @deprecated All keys should be represented as instances of PublicKey.
352
- */
353
- static stringify(key) {
354
- if (key instanceof _PublicKey) {
355
- key = key.asBuffer();
356
- } else if (key instanceof Uint8Array) {
357
- key = Buffer.from(key.buffer, key.byteOffset, key.byteLength);
358
- }
359
- (0, import_invariant2.invariant)(key instanceof Buffer, "Invalid type", {
400
+ #kind;
401
+ #parts;
402
+ constructor(kind, parts) {
403
+ (0, import_invariant.invariant)(parts.length > 0, void 0, {
360
404
  F: __dxlog_file2,
361
- L: 171,
405
+ L: 161,
362
406
  S: this,
363
407
  A: [
364
- "key instanceof Buffer",
365
- "'Invalid type'"
408
+ "parts.length > 0",
409
+ ""
366
410
  ]
367
411
  });
368
- return key.toString("hex");
369
- }
370
- /**
371
- * To be used with ComplexMap and ComplexSet.
372
- * Returns a scalar representation for this key.
373
- */
374
- static hash(key) {
375
- return key.toHex();
376
- }
377
- static fromMultibase32(encoded) {
378
- (0, import_invariant2.invariant)(encoded.startsWith("B"), "Invalid multibase32 encoding", {
412
+ (0, import_invariant.invariant)(parts.every((part) => typeof part === "string" && part.length > 0 && part.indexOf(":") === -1), void 0, {
379
413
  F: __dxlog_file2,
380
- L: 184,
414
+ L: 162,
381
415
  S: this,
382
416
  A: [
383
- "encoded.startsWith('B')",
384
- "'Invalid multibase32 encoding'"
417
+ "parts.every((part) => typeof part === 'string' && part.length > 0 && part.indexOf(':') === -1)",
418
+ ""
385
419
  ]
386
420
  });
387
- return new _PublicKey(new Uint8Array((0, import_base32_decode2.default)(encoded.slice(1), "RFC4648")));
388
- }
389
- constructor(_value) {
390
- this._value = _value;
391
- if (!(_value instanceof Uint8Array)) {
392
- throw new TypeError(`Expected Uint8Array, got: ${_value}`);
421
+ switch (kind) {
422
+ case _DXN.kind.TYPE:
423
+ if (parts.length > 2) {
424
+ throw new Error('Invalid "type" DXN');
425
+ }
426
+ break;
427
+ case _DXN.kind.ECHO:
428
+ if (parts.length !== 2) {
429
+ throw new Error('Invalid "echo" DXN');
430
+ }
431
+ break;
393
432
  }
433
+ this.#kind = kind;
434
+ this.#parts = parts;
394
435
  }
395
- toString() {
396
- return this.toHex();
397
- }
398
- toJSON() {
399
- return this.toHex();
400
- }
401
- toJSONL() {
402
- return this.truncate();
436
+ get parts() {
437
+ return this.#parts;
403
438
  }
404
- get length() {
405
- return this._value.length;
439
+ // TODO(burdon): Should getters fail?
440
+ get typename() {
441
+ (0, import_invariant.invariant)(this.#kind === _DXN.kind.TYPE, void 0, {
442
+ F: __dxlog_file2,
443
+ L: 188,
444
+ S: this,
445
+ A: [
446
+ "this.#kind === DXN.kind.TYPE",
447
+ ""
448
+ ]
449
+ });
450
+ return this.#parts[0];
406
451
  }
407
- toHex() {
408
- return this.asBuffer().toString("hex");
452
+ hasTypenameOf(typename) {
453
+ return this.#kind === _DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
409
454
  }
410
- toMultibase32() {
411
- return "B" + base32Encode(this._value, "RFC4648");
455
+ isLocalObjectId() {
456
+ return this.#kind === _DXN.kind.ECHO && this.#parts[0] === LOCAL_SPACE_TAG && this.#parts.length === 2;
412
457
  }
413
- truncate(length = void 0) {
414
- return (0, import_debug.truncateKey)(this, length);
458
+ asTypeDXN() {
459
+ if (this.kind !== _DXN.kind.TYPE) {
460
+ return void 0;
461
+ }
462
+ const [type, version] = this.#parts;
463
+ return {
464
+ type,
465
+ version
466
+ };
415
467
  }
416
- asBuffer() {
417
- return Buffer.from(this._value.buffer, this._value.byteOffset, this._value.byteLength);
468
+ asEchoDXN() {
469
+ if (this.kind !== _DXN.kind.ECHO) {
470
+ return void 0;
471
+ }
472
+ const [spaceId, echoId] = this.#parts;
473
+ return {
474
+ spaceId: spaceId === LOCAL_SPACE_TAG ? void 0 : spaceId,
475
+ echoId
476
+ };
418
477
  }
419
- asUint8Array() {
420
- return this._value;
478
+ asQueueDXN() {
479
+ if (this.kind !== _DXN.kind.QUEUE) {
480
+ return void 0;
481
+ }
482
+ const [subspaceTag, spaceId, queueId, objectId] = this.#parts;
483
+ if (typeof queueId !== "string") {
484
+ return void 0;
485
+ }
486
+ return {
487
+ subspaceTag,
488
+ spaceId,
489
+ queueId,
490
+ objectId
491
+ };
421
492
  }
422
- getInsecureHash(modulo) {
423
- return Math.abs(this._value.reduce((acc, val) => acc ^ val | 0, 0)) % modulo;
493
+ toString() {
494
+ return `dxn:${this.#kind}:${this.#parts.join(":")}`;
424
495
  }
425
496
  /**
426
497
  * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
427
498
  */
428
499
  [import_debug.inspectCustom](depth, options, inspectFn) {
429
- if (!options.colors || typeof process.stdout.hasColors !== "function" || !process.stdout.hasColors()) {
430
- return `<PublicKey ${this.truncate()}>`;
431
- }
432
500
  const printControlCode = (code) => {
433
501
  return `\x1B[${code}m`;
434
502
  };
435
- const colors = [
436
- "red",
437
- "green",
438
- "yellow",
439
- "blue",
440
- "magenta",
441
- "cyan",
442
- "redBright",
443
- "greenBright",
444
- "yellowBright",
445
- "blueBright",
446
- "magentaBright",
447
- "cyanBright",
448
- "whiteBright"
449
- ];
450
- const color = colors[this.getInsecureHash(colors.length)];
451
- return `PublicKey(${printControlCode(inspectFn.colors[color][0])}${this.truncate()}${printControlCode(inspectFn.colors.reset[0])})`;
503
+ return printControlCode(inspectFn.colors.blueBright[0]) + this.toString() + printControlCode(inspectFn.colors.reset[0]);
452
504
  }
453
505
  get [import_debug.devtoolsFormatter]() {
454
506
  return {
455
507
  header: () => {
456
- const colors = [
457
- "darkred",
458
- "green",
459
- "orange",
460
- "blue",
461
- "darkmagenta",
462
- "darkcyan",
463
- "red",
464
- "green",
465
- "orange",
466
- "blue",
467
- "magenta",
468
- "darkcyan",
469
- "black"
470
- ];
471
- const color = colors[this.getInsecureHash(colors.length)];
472
508
  return [
473
509
  "span",
474
- {},
475
- [
476
- "span",
477
- {},
478
- "PublicKey("
479
- ],
480
- [
481
- "span",
482
- {
483
- style: `color: ${color};`
484
- },
485
- this.truncate()
486
- ],
487
- [
488
- "span",
489
- {},
490
- ")"
491
- ]
510
+ {
511
+ style: "font-weight: bold;"
512
+ },
513
+ this.toString()
492
514
  ];
493
515
  }
494
516
  };
495
517
  }
496
- /**
497
- * Test this key for equality with some other key.
498
- */
499
- equals(other) {
500
- const otherConverted = _PublicKey.from(other);
501
- if (this._value.length !== otherConverted._value.length) {
502
- return false;
503
- }
504
- let equal = true;
505
- for (let i = 0; i < this._value.length; i++) {
506
- equal &&= this._value[i] === otherConverted._value[i];
507
- }
508
- return equal;
509
- }
510
- [import_debug.equalsSymbol](other) {
511
- if (!_PublicKey.isPublicKey(other)) {
512
- return false;
513
- }
514
- return this.equals(other);
515
- }
516
- };
517
- var import_base32_decode3 = __toESM(require_base32_decode(), 1);
518
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/common/keys/src/space-id.ts";
519
- var MULTIBASE_PREFIX2 = "B";
520
- var ENCODED_LENGTH2 = 33;
521
- var isValid = (value) => {
522
- return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
523
518
  };
524
- var SpaceId = class extends import_effect.Schema.String.pipe(import_effect.Schema.filter(isValid)) {
525
- static {
526
- this.byteLength = 20;
527
- }
528
- static {
529
- this.encode = (value) => {
530
- (0, import_invariant3.invariant)(value instanceof Uint8Array, "Invalid type", {
531
- F: __dxlog_file3,
532
- L: 43,
533
- S: this,
534
- A: [
535
- "value instanceof Uint8Array",
536
- "'Invalid type'"
537
- ]
538
- });
539
- (0, import_invariant3.invariant)(value.length === SpaceId.byteLength, "Invalid length", {
540
- F: __dxlog_file3,
541
- L: 44,
542
- S: this,
543
- A: [
544
- "value.length === SpaceId.byteLength",
545
- "'Invalid length'"
546
- ]
547
- });
548
- return MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
549
- };
550
- }
551
- static {
552
- this.decode = (value) => {
553
- (0, import_invariant3.invariant)(value.startsWith(MULTIBASE_PREFIX2), "Invalid multibase32 encoding", {
554
- F: __dxlog_file3,
555
- L: 49,
556
- S: this,
557
- A: [
558
- "value.startsWith(MULTIBASE_PREFIX)",
559
- "'Invalid multibase32 encoding'"
560
- ]
561
- });
562
- return new Uint8Array((0, import_base32_decode3.default)(value.slice(1), "RFC4648"));
563
- };
519
+ var import_base32_decode2 = __toESM(require_base32_decode(), 1);
520
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/common/keys/src/identity-did.ts";
521
+ var IdentityDid = Object.freeze({
522
+ byteLength: 20,
523
+ encode: (value) => {
524
+ (0, import_invariant3.invariant)(value instanceof Uint8Array, "Invalid type", {
525
+ F: __dxlog_file3,
526
+ L: 22,
527
+ S: void 0,
528
+ A: [
529
+ "value instanceof Uint8Array",
530
+ "'Invalid type'"
531
+ ]
532
+ });
533
+ (0, import_invariant3.invariant)(value.length === IdentityDid.byteLength, "Invalid length", {
534
+ F: __dxlog_file3,
535
+ L: 23,
536
+ S: void 0,
537
+ A: [
538
+ "value.length === IdentityDid.byteLength",
539
+ "'Invalid length'"
540
+ ]
541
+ });
542
+ return DID_PREFIX + MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
543
+ },
544
+ decode: (value) => {
545
+ (0, import_invariant3.invariant)(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2), "Invalid multibase32 encoding", {
546
+ F: __dxlog_file3,
547
+ L: 28,
548
+ S: void 0,
549
+ A: [
550
+ "value.startsWith(DID_PREFIX + MULTIBASE_PREFIX)",
551
+ "'Invalid multibase32 encoding'"
552
+ ]
553
+ });
554
+ return new Uint8Array((0, import_base32_decode2.default)(value.slice(10), "RFC4648"));
555
+ },
556
+ isValid: (value) => {
557
+ return typeof value === "string" && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
558
+ },
559
+ random: () => {
560
+ return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
564
561
  }
562
+ });
563
+ var MULTIBASE_PREFIX2 = "B";
564
+ var DID_PREFIX = "did:halo:";
565
+ var ENCODED_LENGTH2 = 42;
566
+ var import_base32_decode3 = __toESM(require_base32_decode(), 1);
567
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/common/keys/src/public-key.ts";
568
+ var PUBLIC_KEY_LENGTH = 32;
569
+ var SECRET_KEY_LENGTH = 64;
570
+ var isLikeArrayBuffer = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ArrayBuffer";
571
+ var PublicKey = class _PublicKey {
565
572
  static {
566
- this.isValid = isValid;
573
+ this.ZERO = _PublicKey.from("00".repeat(PUBLIC_KEY_LENGTH));
567
574
  }
568
- static {
569
- this.random = () => {
570
- return SpaceId.encode(randomBytes(SpaceId.byteLength));
571
- };
575
+ /**
576
+ * Creates new instance of PublicKey automatically determining the input format.
577
+ * @param source A Buffer, or Uint8Array, or hex encoded string, or something with an `asUint8Array` method on it
578
+ * @returns PublicKey
579
+ */
580
+ static from(source) {
581
+ (0, import_invariant4.invariant)(source, void 0, {
582
+ F: __dxlog_file4,
583
+ L: 49,
584
+ S: this,
585
+ A: [
586
+ "source",
587
+ ""
588
+ ]
589
+ });
590
+ if (source instanceof _PublicKey) {
591
+ return source;
592
+ } else if (source instanceof Buffer) {
593
+ return new _PublicKey(new Uint8Array(source.buffer, source.byteOffset, source.byteLength));
594
+ } else if (source instanceof Uint8Array) {
595
+ return new _PublicKey(source);
596
+ } else if (source instanceof ArrayBuffer || isLikeArrayBuffer(source)) {
597
+ return new _PublicKey(new Uint8Array(source));
598
+ } else if (typeof source === "string") {
599
+ return _PublicKey.fromHex(source);
600
+ } else if (source.asUint8Array) {
601
+ return new _PublicKey(source.asUint8Array());
602
+ } else {
603
+ throw new TypeError(`Unable to create PublicKey from ${source}`);
604
+ }
572
605
  }
573
- };
574
- var ObjectIdSchema = import_effect3.Schema.String.pipe(import_effect3.Schema.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
575
- description: "a Universally Unique Lexicographically Sortable Identifier",
576
- pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
577
- });
578
- var ObjectId = class extends ObjectIdSchema {
579
- static isValid(id) {
606
+ /**
607
+ * Same as `PublicKey.from` but does not throw and instead returns a `{ key: PublicKey }` or `{ error: Error }`
608
+ * @param source Same PublicKeyLike argument as for `PublicKey.from`
609
+ * @returns PublicKey
610
+ */
611
+ static safeFrom(source) {
612
+ if (!source) {
613
+ return void 0;
614
+ }
580
615
  try {
581
- import_effect3.Schema.decodeSync(ObjectId)(id);
582
- return true;
616
+ const key = _PublicKey.from(source);
617
+ return key;
583
618
  } catch (err) {
584
- return false;
619
+ return void 0;
585
620
  }
586
621
  }
587
- static random() {
588
- return (0, import_ulidx.ulid)();
589
- }
590
- };
591
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/common/keys/src/dxn.ts";
592
- var LOCAL_SPACE_TAG = "@";
593
- var QueueSubspaceTags = Object.freeze({
594
- DATA: "data",
595
- TRACE: "trace"
596
- });
597
- var DXN = class _DXN {
598
- static {
599
- this.Schema = import_effect2.Schema.NonEmptyString.pipe(
600
- import_effect2.Schema.pattern(/^dxn:([^:]+):(?:[^:]+:?)+[^:]$/),
601
- // TODO(dmaretskyi): To set the format we need to move the annotation IDs out of the echo-schema package.
602
- // FormatAnnotation.set(FormatEnum.DXN),
603
- import_effect2.Schema.annotations({
604
- title: "DXN",
605
- description: "DXN URI",
606
- examples: [
607
- "dxn:type:example.com/type/MyType",
608
- "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
609
- ]
610
- })
611
- );
612
- }
613
- static {
614
- this.kind = Object.freeze({
615
- /**
616
- * dxn:type:<type name>[:<version>]
617
- */
618
- TYPE: "type",
619
- /**
620
- * dxn:echo:<space id>:<echo id>
621
- * dxn:echo:@:<echo id>
622
- */
623
- // TODO(burdon): Rename to OBJECT? (BREAKING CHANGE).
624
- // TODO(burdon): Add separate Kind for space.
625
- ECHO: "echo",
626
- /**
627
- * The subspace tag enables us to partition queues by usage within the context of a space.
628
- * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
629
- * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
630
- * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
631
- */
632
- QUEUE: "queue"
633
- });
634
- }
635
- get kind() {
636
- return this.#kind;
622
+ /**
623
+ * Creates new instance of PublicKey from hex string.
624
+ */
625
+ static fromHex(hex) {
626
+ if (hex.startsWith("0x")) {
627
+ hex = hex.slice(2);
628
+ }
629
+ const buf = Buffer.from(hex, "hex");
630
+ return new _PublicKey(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength));
637
631
  }
638
- static equals(a, b) {
639
- return a.kind === b.kind && a.parts.length === b.parts.length && a.parts.every((part, i) => part === b.parts[i]);
632
+ /**
633
+ * Creates a new key.
634
+ */
635
+ static random() {
636
+ return _PublicKey.from(randomBytes(PUBLIC_KEY_LENGTH));
640
637
  }
641
- // TODO(burdon): Rename isValid.
642
- static isDXNString(dxn) {
643
- return dxn.startsWith("dxn:");
638
+ static randomOfLength(length) {
639
+ return _PublicKey.from(randomBytes(length));
644
640
  }
645
- static parse(dxn) {
646
- if (typeof dxn !== "string") {
647
- throw new Error(`Invalid DXN: ${dxn}`);
648
- }
649
- const [prefix, kind, ...parts] = dxn.split(":");
650
- if (!(prefix === "dxn")) {
651
- throw new Error(`Invalid DXN: ${dxn}`);
652
- }
653
- if (!(typeof kind === "string" && kind.length > 0)) {
654
- throw new Error(`Invalid DXN: ${dxn}`);
655
- }
656
- if (!(parts.length > 0)) {
657
- throw new Error(`Invalid DXN: ${dxn}`);
641
+ static *randomSequence() {
642
+ for (let i = 0; i < 1e4; i++) {
643
+ yield _PublicKey.random();
658
644
  }
659
- return new _DXN(kind, parts);
645
+ throw new Error("Too many keys requested");
660
646
  }
661
- static tryParse(dxn) {
662
- try {
663
- return _DXN.parse(dxn);
664
- } catch (error) {
665
- return void 0;
666
- }
647
+ /**
648
+ * Tests if provided values is an instance of PublicKey.
649
+ */
650
+ static isPublicKey(value) {
651
+ return value instanceof _PublicKey;
667
652
  }
668
653
  /**
669
- * @example `dxn:type:example.com/type/Contact`
654
+ * Asserts that provided values is an instance of PublicKey.
670
655
  */
671
- static fromTypename(typename) {
672
- return new _DXN(_DXN.kind.TYPE, [
673
- typename
674
- ]);
656
+ static assertValidPublicKey(value) {
657
+ if (!this.isPublicKey(value)) {
658
+ throw new TypeError("Invalid PublicKey");
659
+ }
675
660
  }
676
661
  /**
677
- * @example `dxn:type:example.com/type/Contact:0.1.0`
662
+ * Tests two keys for equality.
678
663
  */
679
- // TODO(dmaretskyi): Consider using @ as the version separator.
680
- static fromTypenameAndVersion(typename, version) {
681
- return new _DXN(_DXN.kind.TYPE, [
682
- typename,
683
- version
684
- ]);
664
+ static equals(left, right) {
665
+ return _PublicKey.from(left).equals(right);
685
666
  }
686
667
  /**
687
- * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
668
+ * @param str string representation of key.
669
+ * @return Key buffer.
670
+ * @deprecated All keys should be represented as instances of PublicKey.
688
671
  */
689
- static fromLocalObjectId(id) {
690
- return new _DXN(_DXN.kind.ECHO, [
691
- LOCAL_SPACE_TAG,
692
- id
693
- ]);
694
- }
695
- static fromQueue(subspaceTag, spaceId, queueId, objectId) {
696
- (0, import_invariant4.invariant)(SpaceId.isValid(spaceId), void 0, {
697
- F: __dxlog_file4,
698
- L: 146,
699
- S: this,
700
- A: [
701
- "SpaceId.isValid(spaceId)",
702
- ""
703
- ]
704
- });
705
- (0, import_invariant4.invariant)(ObjectId.isValid(queueId), void 0, {
706
- F: __dxlog_file4,
707
- L: 147,
708
- S: this,
709
- A: [
710
- "ObjectId.isValid(queueId)",
711
- ""
712
- ]
713
- });
714
- (0, import_invariant4.invariant)(!objectId || ObjectId.isValid(objectId), void 0, {
672
+ static bufferize(str) {
673
+ (0, import_invariant4.invariant)(typeof str === "string", "Invalid type", {
715
674
  F: __dxlog_file4,
716
- L: 148,
675
+ L: 152,
717
676
  S: this,
718
677
  A: [
719
- "!objectId || ObjectId.isValid(objectId)",
720
- ""
678
+ "typeof str === 'string'",
679
+ "'Invalid type'"
721
680
  ]
722
681
  });
723
- return new _DXN(_DXN.kind.QUEUE, [
724
- subspaceTag,
725
- spaceId,
726
- queueId,
727
- ...objectId ? [
728
- objectId
729
- ] : []
730
- ]);
682
+ const buffer = Buffer.from(str, "hex");
683
+ return buffer;
731
684
  }
732
- #kind;
733
- #parts;
734
- constructor(kind, parts) {
735
- (0, import_invariant4.invariant)(parts.length > 0, void 0, {
736
- F: __dxlog_file4,
737
- L: 157,
738
- S: this,
739
- A: [
740
- "parts.length > 0",
741
- ""
742
- ]
743
- });
744
- (0, import_invariant4.invariant)(parts.every((part) => typeof part === "string" && part.length > 0 && part.indexOf(":") === -1), void 0, {
685
+ /**
686
+ * @param key key like data structure (but not PublicKey which should use toString).
687
+ * @return Hex string representation of key.
688
+ * @deprecated All keys should be represented as instances of PublicKey.
689
+ */
690
+ static stringify(key) {
691
+ if (key instanceof _PublicKey) {
692
+ key = key.asBuffer();
693
+ } else if (key instanceof Uint8Array) {
694
+ key = Buffer.from(key.buffer, key.byteOffset, key.byteLength);
695
+ }
696
+ (0, import_invariant4.invariant)(key instanceof Buffer, "Invalid type", {
745
697
  F: __dxlog_file4,
746
- L: 158,
698
+ L: 171,
747
699
  S: this,
748
700
  A: [
749
- "parts.every((part) => typeof part === 'string' && part.length > 0 && part.indexOf(':') === -1)",
750
- ""
701
+ "key instanceof Buffer",
702
+ "'Invalid type'"
751
703
  ]
752
704
  });
753
- switch (kind) {
754
- case _DXN.kind.TYPE:
755
- if (parts.length > 2) {
756
- throw new Error('Invalid "type" DXN');
757
- }
758
- break;
759
- case _DXN.kind.ECHO:
760
- if (parts.length !== 2) {
761
- throw new Error('Invalid "echo" DXN');
762
- }
763
- break;
764
- }
765
- this.#kind = kind;
766
- this.#parts = parts;
705
+ return key.toString("hex");
767
706
  }
768
- get parts() {
769
- return this.#parts;
707
+ /**
708
+ * To be used with ComplexMap and ComplexSet.
709
+ * Returns a scalar representation for this key.
710
+ */
711
+ static hash(key) {
712
+ return key.toHex();
770
713
  }
771
- // TODO(burdon): Should getters fail?
772
- get typename() {
773
- (0, import_invariant4.invariant)(this.#kind === _DXN.kind.TYPE, void 0, {
714
+ static fromMultibase32(encoded) {
715
+ (0, import_invariant4.invariant)(encoded.startsWith("B"), "Invalid multibase32 encoding", {
774
716
  F: __dxlog_file4,
775
717
  L: 184,
776
718
  S: this,
777
719
  A: [
778
- "this.#kind === DXN.kind.TYPE",
779
- ""
720
+ "encoded.startsWith('B')",
721
+ "'Invalid multibase32 encoding'"
780
722
  ]
781
723
  });
782
- return this.#parts[0];
724
+ return new _PublicKey(new Uint8Array((0, import_base32_decode3.default)(encoded.slice(1), "RFC4648")));
783
725
  }
784
- hasTypenameOf(typename) {
785
- return this.#kind === _DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
726
+ constructor(_value) {
727
+ this._value = _value;
728
+ if (!(_value instanceof Uint8Array)) {
729
+ throw new TypeError(`Expected Uint8Array, got: ${_value}`);
730
+ }
786
731
  }
787
- isLocalObjectId() {
788
- return this.#kind === _DXN.kind.ECHO && this.#parts[0] === LOCAL_SPACE_TAG && this.#parts.length === 2;
732
+ toString() {
733
+ return this.toHex();
789
734
  }
790
- asTypeDXN() {
791
- if (this.kind !== _DXN.kind.TYPE) {
792
- return void 0;
793
- }
794
- const [type, version] = this.#parts;
795
- return {
796
- type,
797
- version
798
- };
735
+ toJSON() {
736
+ return this.toHex();
799
737
  }
800
- asEchoDXN() {
801
- if (this.kind !== _DXN.kind.ECHO) {
802
- return void 0;
803
- }
804
- const [spaceId, echoId] = this.#parts;
805
- return {
806
- spaceId: spaceId === LOCAL_SPACE_TAG ? void 0 : spaceId,
807
- echoId
808
- };
738
+ toJSONL() {
739
+ return this.truncate();
809
740
  }
810
- asQueueDXN() {
811
- if (this.kind !== _DXN.kind.QUEUE) {
812
- return void 0;
813
- }
814
- const [subspaceTag, spaceId, queueId, objectId] = this.#parts;
815
- if (typeof queueId !== "string") {
816
- return void 0;
817
- }
818
- return {
819
- subspaceTag,
820
- spaceId,
821
- queueId,
822
- objectId
823
- };
741
+ get length() {
742
+ return this._value.length;
824
743
  }
825
- toString() {
826
- return `dxn:${this.#kind}:${this.#parts.join(":")}`;
744
+ toHex() {
745
+ return this.asBuffer().toString("hex");
746
+ }
747
+ toMultibase32() {
748
+ return "B" + base32Encode(this._value, "RFC4648");
749
+ }
750
+ truncate(length = void 0) {
751
+ return (0, import_debug2.truncateKey)(this, length);
752
+ }
753
+ asBuffer() {
754
+ return Buffer.from(this._value.buffer, this._value.byteOffset, this._value.byteLength);
755
+ }
756
+ asUint8Array() {
757
+ return this._value;
758
+ }
759
+ getInsecureHash(modulo) {
760
+ return Math.abs(this._value.reduce((acc, val) => acc ^ val | 0, 0)) % modulo;
827
761
  }
828
762
  /**
829
763
  * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
830
764
  */
831
765
  [import_debug2.inspectCustom](depth, options, inspectFn) {
766
+ if (!options.colors || typeof process.stdout.hasColors !== "function" || !process.stdout.hasColors()) {
767
+ return `<PublicKey ${this.truncate()}>`;
768
+ }
832
769
  const printControlCode = (code) => {
833
770
  return `\x1B[${code}m`;
834
771
  };
835
- return printControlCode(inspectFn.colors.blueBright[0]) + this.toString() + printControlCode(inspectFn.colors.reset[0]);
772
+ const colors = [
773
+ "red",
774
+ "green",
775
+ "yellow",
776
+ "blue",
777
+ "magenta",
778
+ "cyan",
779
+ "redBright",
780
+ "greenBright",
781
+ "yellowBright",
782
+ "blueBright",
783
+ "magentaBright",
784
+ "cyanBright",
785
+ "whiteBright"
786
+ ];
787
+ const color = colors[this.getInsecureHash(colors.length)];
788
+ return `PublicKey(${printControlCode(inspectFn.colors[color][0])}${this.truncate()}${printControlCode(inspectFn.colors.reset[0])})`;
836
789
  }
837
790
  get [import_debug2.devtoolsFormatter]() {
838
791
  return {
839
792
  header: () => {
793
+ const colors = [
794
+ "darkred",
795
+ "green",
796
+ "orange",
797
+ "blue",
798
+ "darkmagenta",
799
+ "darkcyan",
800
+ "red",
801
+ "green",
802
+ "orange",
803
+ "blue",
804
+ "magenta",
805
+ "darkcyan",
806
+ "black"
807
+ ];
808
+ const color = colors[this.getInsecureHash(colors.length)];
840
809
  return [
841
810
  "span",
842
- {
843
- style: "font-weight: bold;"
844
- },
845
- this.toString()
811
+ {},
812
+ [
813
+ "span",
814
+ {},
815
+ "PublicKey("
816
+ ],
817
+ [
818
+ "span",
819
+ {
820
+ style: `color: ${color};`
821
+ },
822
+ this.truncate()
823
+ ],
824
+ [
825
+ "span",
826
+ {},
827
+ ")"
828
+ ]
846
829
  ];
847
830
  }
848
831
  };
849
832
  }
833
+ /**
834
+ * Test this key for equality with some other key.
835
+ */
836
+ equals(other) {
837
+ const otherConverted = _PublicKey.from(other);
838
+ if (this._value.length !== otherConverted._value.length) {
839
+ return false;
840
+ }
841
+ let equal = true;
842
+ for (let i = 0; i < this._value.length; i++) {
843
+ equal &&= this._value[i] === otherConverted._value[i];
844
+ }
845
+ return equal;
846
+ }
847
+ [import_debug2.equalsSymbol](other) {
848
+ if (!_PublicKey.isPublicKey(other)) {
849
+ return false;
850
+ }
851
+ return this.equals(other);
852
+ }
850
853
  };
851
854
  // Annotate the CommonJS export names for ESM import in node:
852
855
  0 && (module.exports = {