@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
@@ -14,6 +14,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
14
14
  var __commonJS = (cb, mod) => function __require2() {
15
15
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
16
16
  };
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
17
21
  var __copyProps = (to, from, except, desc) => {
18
22
  if (from && typeof from === "object" || typeof from === "function") {
19
23
  for (let key of __getOwnPropNames(from))
@@ -81,74 +85,144 @@ var require_base32_decode = __commonJS({
81
85
  }
82
86
  });
83
87
 
84
- // src/dxn.ts
85
- import * as Schema3 from "effect/Schema";
86
- import { devtoolsFormatter, inspectCustom } from "@dxos/debug";
87
- import { assertArgument, invariant as invariant2 } from "@dxos/invariant";
88
-
89
- // src/object-id.ts
90
- import * as Schema from "effect/Schema";
91
- import { monotonicFactory } from "ulidx";
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",
94
- pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
88
+ // src/DXN.ts
89
+ var DXN_exports = {};
90
+ __export(DXN_exports, {
91
+ Schema: () => Schema_,
92
+ getName: () => getName,
93
+ getVersion: () => getVersion,
94
+ isDXN: () => isDXN,
95
+ make: () => make,
96
+ tryMake: () => tryMake
95
97
  });
96
- var ObjectId = class extends ObjectIdSchema {
97
- static #factory = monotonicFactory();
98
- static #seedTime = void 0;
99
- static isValid(id) {
100
- try {
101
- Schema.decodeSync(ObjectId)(id);
102
- return true;
103
- } catch {
104
- return false;
105
- }
98
+ import * as Schema from "effect/Schema";
99
+ 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+)?$/;
100
+ var isDXN = (value) => typeof value === "string" && value.startsWith("dxn:");
101
+ var make = (nsid, version) => parse(version != null ? `dxn:${nsid}:${version}` : `dxn:${nsid}`);
102
+ var tryMake = (dxn) => {
103
+ try {
104
+ return parse(dxn);
105
+ } catch {
106
+ return void 0;
106
107
  }
107
- static random() {
108
- return this.#factory(this.#seedTime);
108
+ };
109
+ var parse = (dxn) => {
110
+ if (typeof dxn === "string" && DXN_SPEC_REGEXP.test(dxn)) {
111
+ return dxn;
109
112
  }
110
- static dangerouslyDisableRandomness() {
111
- this.#factory = monotonicFactory(makeTestPRNG());
112
- this.#seedTime = (/* @__PURE__ */ new Date("2025-01-01")).getTime();
113
+ throw new Error(`Invalid DXN: ${dxn}`);
114
+ };
115
+ var getName = (dxn) => {
116
+ const match = /^dxn:([^:]+)/.exec(dxn);
117
+ if (!match) {
118
+ throw new Error(`Invalid DXN: ${dxn}`);
113
119
  }
120
+ return match[1];
114
121
  };
115
- var makeTestPRNG = () => {
116
- const rng = new SimplePRNG();
117
- return () => {
118
- return rng.next();
119
- };
122
+ var getVersion = (dxn) => {
123
+ const match = /^dxn:[^:]+:(\d+\.\d+\.\d+)$/.exec(dxn);
124
+ return match?.[1];
120
125
  };
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;
126
+ var Schema_ = Schema.String.pipe(Schema.filter((value) => isDXN(value), {
127
+ message: () => "Invalid DXN"
128
+ }), Schema.annotations({
129
+ title: "DXN",
130
+ description: "DXN URI: dxn:<nsid>[:<version>]"
131
+ }));
132
+
133
+ // src/EID.ts
134
+ var EID_exports = {};
135
+ __export(EID_exports, {
136
+ Schema: () => Schema_2,
137
+ equals: () => equals,
138
+ getEntityId: () => getEntityId,
139
+ getSpaceId: () => getSpaceId,
140
+ isEID: () => isEID,
141
+ isLocal: () => isLocal,
142
+ make: () => make2,
143
+ parse: () => parse2,
144
+ toLocal: () => toLocal,
145
+ tryParse: () => tryParse
146
+ });
147
+ import * as Schema2 from "effect/Schema";
148
+ var ECHO_URI_REGEXP = /^echo:(?:\/\/[^/]+(?:\/[^/]+)?|(?:\/\/\/|\/)[^/]+)$/;
149
+ var QUALIFIED_RE = /^echo:\/\/([^/]+)\/([^/]+)$/;
150
+ var SPACE_ONLY_RE = /^echo:\/\/([^/]+)$/;
151
+ var LOCAL_RE = /^echo:(?:\/\/\/|\/)([^/]+)$/;
152
+ var isEID = (value) => typeof value === "string" && value.startsWith("echo:");
153
+ var parse2 = (uri) => {
154
+ if (!ECHO_URI_REGEXP.test(uri)) {
155
+ throw new Error(`Invalid EID: ${uri}`);
156
+ }
157
+ return uri;
158
+ };
159
+ var tryParse = (uri) => {
160
+ try {
161
+ return parse2(uri);
162
+ } catch {
163
+ return void 0;
148
164
  }
149
165
  };
166
+ var make2 = ({ spaceId, entityId }) => {
167
+ let raw;
168
+ if (spaceId != null && entityId != null) {
169
+ raw = `echo://${spaceId}/${entityId}`;
170
+ } else if (entityId != null) {
171
+ raw = `echo:/${entityId}`;
172
+ } else if (spaceId != null) {
173
+ raw = `echo://${spaceId}`;
174
+ } else {
175
+ throw new Error("EID.make requires at least one of spaceId or entityId");
176
+ }
177
+ return parse2(raw);
178
+ };
179
+ var getSpaceId = (uri) => {
180
+ const normalized = parse2(uri);
181
+ const match = QUALIFIED_RE.exec(normalized) ?? SPACE_ONLY_RE.exec(normalized);
182
+ return match?.[1];
183
+ };
184
+ var getEntityId = (uri) => {
185
+ const normalized = parse2(uri);
186
+ const qualMatch = QUALIFIED_RE.exec(normalized);
187
+ if (qualMatch) {
188
+ return qualMatch[2];
189
+ }
190
+ const localMatch = LOCAL_RE.exec(normalized);
191
+ return localMatch?.[1];
192
+ };
193
+ var isLocal = (uri) => {
194
+ const normalized = parse2(uri);
195
+ return LOCAL_RE.test(normalized);
196
+ };
197
+ var toLocal = (uri) => {
198
+ const entityId = getEntityId(uri);
199
+ return entityId != null ? make2({
200
+ entityId
201
+ }) : parse2(uri);
202
+ };
203
+ var equals = (a, b) => parse2(a) === parse2(b);
204
+ var Schema_2 = Schema2.String.pipe(Schema2.filter((value) => isEID(value), {
205
+ message: () => "Invalid EID: must start with echo:"
206
+ }), Schema2.annotations({
207
+ title: "EID",
208
+ description: "ECHO object/space URI: echo://<spaceId>[/<objectId>] or echo:/<objectId>"
209
+ }));
150
210
 
151
- // src/space-id.ts
211
+ // src/URI.ts
212
+ var URI_exports = {};
213
+ __export(URI_exports, {
214
+ Schema: () => Schema_3,
215
+ isURI: () => isURI,
216
+ make: () => make3
217
+ });
218
+ import * as Schema3 from "effect/Schema";
219
+ var make3 = (uri) => uri;
220
+ var isURI = (value) => typeof value === "string" && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value);
221
+ var Schema_3 = Schema3.String.pipe(Schema3.filter((value) => isURI(value), {
222
+ message: () => "Invalid URI"
223
+ }));
224
+
225
+ // src/identity-did.ts
152
226
  var import_base32_decode = __toESM(require_base32_decode(), 1);
153
227
 
154
228
  // ../../../node_modules/.pnpm/to-data-view@2.0.0/node_modules/to-data-view/index.js
@@ -210,8 +284,8 @@ function base32Encode(data, variant, options) {
210
284
  return output;
211
285
  }
212
286
 
213
- // src/space-id.ts
214
- import * as Schema2 from "effect/Schema";
287
+ // src/identity-did.ts
288
+ import * as Schema4 from "effect/Schema";
215
289
  import { invariant } from "@dxos/invariant";
216
290
 
217
291
  // src/random-bytes.ts
@@ -222,373 +296,158 @@ var randomBytes = (length) => {
222
296
  return bytes;
223
297
  };
224
298
 
225
- // src/space-id.ts
226
- var __dxlog_file = "/__w/dxos/dxos/packages/common/keys/src/space-id.ts";
299
+ // src/identity-did.ts
227
300
  var MULTIBASE_PREFIX = "B";
228
- var ENCODED_LENGTH = 33;
301
+ var DID_PREFIX = "did:halo:";
302
+ var DECODED_BYTE_LENGTH = 20;
303
+ var ENCODED_LENGTH = 42;
304
+ var RFC4648_BASE32_PATTERN = /^[A-Z2-7]+$/;
229
305
  var isValid = (value) => {
230
- return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH;
306
+ if (typeof value !== "string" || !value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) || value.length !== ENCODED_LENGTH) {
307
+ return false;
308
+ }
309
+ const encoded = value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length);
310
+ if (!RFC4648_BASE32_PATTERN.test(encoded)) {
311
+ return false;
312
+ }
313
+ try {
314
+ return (0, import_base32_decode.default)(encoded, "RFC4648").byteLength === DECODED_BYTE_LENGTH;
315
+ } catch {
316
+ return false;
317
+ }
231
318
  };
232
- var SpaceId = class extends Schema2.String.pipe(Schema2.filter(isValid)) {
233
- static byteLength = 20;
319
+ var IdentityDid = class extends Schema4.String.pipe(Schema4.filter(isValid)) {
320
+ static byteLength = DECODED_BYTE_LENGTH;
234
321
  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");
322
+ invariant(value instanceof Uint8Array, "Invalid type");
323
+ invariant(value.length === IdentityDid.byteLength, "Invalid length");
324
+ return DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, "RFC4648");
254
325
  };
255
326
  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"));
327
+ invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), "Invalid multibase32 encoding");
328
+ return new Uint8Array((0, import_base32_decode.default)(value.slice(DID_PREFIX.length + MULTIBASE_PREFIX.length), "RFC4648"));
266
329
  };
267
330
  static isValid = isValid;
268
331
  static random = () => {
269
- return SpaceId.encode(randomBytes(SpaceId.byteLength));
332
+ return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
270
333
  };
271
334
  };
272
335
 
273
- // src/dxn.ts
274
- var __dxlog_file2 = "/__w/dxos/dxos/packages/common/keys/src/dxn.ts";
275
- var LOCAL_SPACE_TAG = "@";
276
- var DXN_ECHO_REGEXP = /@(dxn:[a-zA-Z0-p:@]+)/;
277
- var QueueSubspaceTags = Object.freeze({
278
- DATA: "data",
279
- TRACE: "trace"
336
+ // src/entity-id.ts
337
+ import * as Schema5 from "effect/Schema";
338
+ import { monotonicFactory } from "ulidx";
339
+ var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
340
+ var EntityIdSchema = Schema5.String.pipe(Schema5.pattern(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i)).annotations({
341
+ description: "A Universally Unique Lexicographically Sortable Identifier",
342
+ pattern: "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
280
343
  });
281
- var DXN = class _DXN {
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(TypeFormat.DXN),
288
- Schema3.annotations({
289
- title: "DXN",
290
- description: "DXN URI",
291
- examples: [
292
- "dxn:type:com.example.type.my-type",
293
- "dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6"
294
- ]
295
- })
296
- );
297
- static hash(dxn) {
298
- return dxn.toString();
299
- }
300
- /**
301
- * Kind constants.
302
- */
303
- static kind = Object.freeze({
304
- /**
305
- * dxn:type:<type_name>[:<version>]
306
- */
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
- */
326
- static equals(a, b) {
327
- return a.kind === b.kind && a.parts.length === b.parts.length && a.parts.every((part, i) => part === b.parts[i]);
328
- }
329
- static equalsEchoId(a, b) {
330
- const a1 = a.asEchoDXN();
331
- const b1 = b.asEchoDXN();
332
- return !!a1 && !!b1 && a1.echoId === b1.echoId;
344
+ var EntityId = class extends EntityIdSchema {
345
+ static #factory = monotonicFactory();
346
+ static #seedTime = void 0;
347
+ static isValid(id) {
348
+ try {
349
+ Schema5.decodeSync(EntityId)(id);
350
+ return true;
351
+ } catch {
352
+ return false;
353
+ }
333
354
  }
334
- // TODO(burdon): Rename isValid.
335
- static isDXNString(dxn) {
336
- return dxn.startsWith("dxn:");
355
+ static random() {
356
+ return this.#factory(this.#seedTime);
337
357
  }
338
- static parse(dxn) {
339
- if (typeof dxn !== "string") {
340
- throw new Error(`Invalid DXN: ${dxn}`);
358
+ static deterministic(...seed) {
359
+ const input = seed.map((value) => String(value)).join("\0");
360
+ let h1 = 2166136261 >>> 0;
361
+ let h2 = 461845907 >>> 0;
362
+ for (let i = 0; i < input.length; i++) {
363
+ const code = input.charCodeAt(i);
364
+ h1 = Math.imul(h1 ^ code, 16777619) >>> 0;
365
+ h2 = Math.imul(h2 ^ (code << 13 | code >>> 3), 16777619) >>> 0;
341
366
  }
342
- const [prefix, kind, ...parts] = dxn.split(":");
343
- if (!(prefix === "dxn")) {
344
- throw new Error(`Invalid DXN: ${dxn}`);
345
- }
346
- if (!(typeof kind === "string" && kind.length > 0)) {
347
- throw new Error(`Invalid DXN: ${dxn}`);
348
- }
349
- if (!(parts.length > 0)) {
350
- throw new Error(`Invalid DXN: ${dxn}`);
351
- }
352
- return new _DXN(kind, parts);
353
- }
354
- static tryParse(dxn) {
355
- try {
356
- return _DXN.parse(dxn);
357
- } catch {
358
- return void 0;
367
+ const time = ALPHABET[0].repeat(10);
368
+ let bits = BigInt(h1) << 32n | BigInt(h2);
369
+ let rand = "";
370
+ for (let i = 0; i < 16; i++) {
371
+ rand = ALPHABET[Number(bits & 0x1fn)] + rand;
372
+ bits >>= 5n;
359
373
  }
374
+ return time + rand;
360
375
  }
361
- /**
362
- * @example `dxn:type:com.example.type.person`
363
- */
364
- static fromTypename(typename) {
365
- return new _DXN(_DXN.kind.TYPE, [
366
- typename
367
- ]);
376
+ static dangerouslyDisableRandomness() {
377
+ this.#factory = monotonicFactory(makeTestPRNG());
378
+ this.#seedTime = (/* @__PURE__ */ new Date("2025-01-01")).getTime();
368
379
  }
369
- /**
370
- * @example `dxn:type:com.example.type.person:0.1.0`
371
- */
372
- // TODO(dmaretskyi): Consider using @ as the version separator.
373
- static fromTypenameAndVersion(typename, version) {
374
- return new _DXN(_DXN.kind.TYPE, [
375
- typename,
376
- version
377
- ]);
380
+ static dangerouslySetSeed(time, seed) {
381
+ this.#factory = monotonicFactory(makeTestPRNG(seed));
382
+ this.#seedTime = time;
378
383
  }
384
+ };
385
+ var makeTestPRNG = (seed = 0) => {
386
+ const rng = new SimplePRNG(seed);
387
+ return () => {
388
+ return rng.next();
389
+ };
390
+ };
391
+ var SimplePRNG = class _SimplePRNG {
392
+ #seed;
393
+ // LCG parameters (from Numerical Recipes)
394
+ static #a = 1664525;
395
+ static #c = 1013904223;
396
+ static #m = Math.pow(2, 32);
379
397
  /**
380
- * @example `dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6`
398
+ * Creates a new PRNG instance.
399
+ * @param seed - Initial seed value. If not provided, uses 0.
381
400
  */
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
- ]);
401
+ constructor(seed = 0) {
402
+ this.#seed = seed;
389
403
  }
390
404
  /**
391
- * @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
405
+ * Generates the next pseudo-random number in the range [0, 1).
406
+ * @returns A pseudo-random number between 0 (inclusive) and 1 (exclusive).
392
407
  */
393
- static fromLocalObjectId(id) {
394
- assertArgument(ObjectId.isValid(id), "id", `Invalid object ID: ${id}`);
395
- return new _DXN(_DXN.kind.ECHO, [
396
- LOCAL_SPACE_TAG,
397
- id
398
- ]);
399
- }
400
- static fromQueue(subspaceTag, spaceId, queueId, objectId) {
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}`);
404
- return new _DXN(_DXN.kind.QUEUE, [
405
- subspaceTag,
406
- spaceId,
407
- queueId,
408
- ...objectId ? [
409
- objectId
410
- ] : []
411
- ]);
412
- }
413
- #kind;
414
- #parts;
415
- constructor(kind, parts) {
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}`);
418
- switch (kind) {
419
- case _DXN.kind.TYPE:
420
- if (parts.length > 2) {
421
- throw new Error("Invalid DXN.kind.TYPE");
422
- }
423
- break;
424
- case _DXN.kind.ECHO:
425
- if (parts.length !== 2) {
426
- throw new Error("Invalid DXN.kind.ECHO");
427
- }
428
- break;
429
- }
430
- this.#kind = kind;
431
- this.#parts = parts;
432
- }
433
- toString() {
434
- return `dxn:${this.#kind}:${this.#parts.join(":")}`;
435
- }
436
- toJSON() {
437
- return this.toString();
408
+ next() {
409
+ this.#seed = (_SimplePRNG.#a * this.#seed + _SimplePRNG.#c) % _SimplePRNG.#m;
410
+ return this.#seed / _SimplePRNG.#m;
438
411
  }
439
412
  /**
440
- * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
413
+ * Resets the generator with a new seed.
414
+ * @param seed - New seed value.
441
415
  */
442
- [inspectCustom](depth, options, inspectFn) {
443
- const printControlCode = (code) => {
444
- return `\x1B[${code}m`;
445
- };
446
- return printControlCode(inspectFn.colors.blueBright[0]) + this.toString() + printControlCode(inspectFn.colors.reset[0]);
447
- }
448
- get [devtoolsFormatter]() {
449
- return {
450
- header: () => {
451
- return [
452
- "span",
453
- {
454
- style: "font-weight: bold;"
455
- },
456
- this.toString()
457
- ];
458
- }
459
- };
460
- }
461
- get kind() {
462
- return this.#kind;
463
- }
464
- get parts() {
465
- return this.#parts;
466
- }
467
- // TODO(burdon): Should getters fail?
468
- get typename() {
469
- invariant2(this.#kind === _DXN.kind.TYPE, void 0, {
470
- F: __dxlog_file2,
471
- L: 249,
472
- S: this,
473
- A: [
474
- "this.#kind === DXN.kind.TYPE",
475
- ""
476
- ]
477
- });
478
- return this.#parts[0];
479
- }
480
- equals(other) {
481
- return _DXN.equals(this, other);
482
- }
483
- hasTypenameOf(typename) {
484
- return this.#kind === _DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
485
- }
486
- isLocalObjectId() {
487
- return this.#kind === _DXN.kind.ECHO && this.#parts[0] === LOCAL_SPACE_TAG && this.#parts.length === 2;
416
+ reset(seed) {
417
+ this.#seed = seed;
488
418
  }
489
- asTypeDXN() {
490
- if (this.kind !== _DXN.kind.TYPE) {
491
- return void 0;
492
- }
493
- const [type, version] = this.#parts;
419
+ };
420
+
421
+ // src/parse-id.ts
422
+ var SPACE_ID_LENGTH = 33;
423
+ var OBJECT_ID_LENGTH = 26;
424
+ var FQ_ID_LENGTH = SPACE_ID_LENGTH + OBJECT_ID_LENGTH + 1;
425
+ var parseId = (id) => {
426
+ if (!id) {
427
+ return {};
428
+ } else if (id.length === SPACE_ID_LENGTH) {
494
429
  return {
495
- // TODO(wittjosiah): Should be `typename` for consistency.
496
- type,
497
- version
430
+ spaceId: id
498
431
  };
499
- }
500
- asEchoDXN() {
501
- if (this.kind !== _DXN.kind.ECHO) {
502
- return void 0;
503
- }
504
- const [spaceId, echoId] = this.#parts;
432
+ } else if (id.length === OBJECT_ID_LENGTH) {
505
433
  return {
506
- spaceId: spaceId === LOCAL_SPACE_TAG ? void 0 : spaceId,
507
- // TODO(burdon): objectId.
508
- echoId
434
+ objectId: id
509
435
  };
510
- }
511
- asQueueDXN() {
512
- if (this.kind !== _DXN.kind.QUEUE) {
513
- return void 0;
514
- }
515
- const [subspaceTag, spaceId, queueId, objectId] = this.#parts;
516
- if (typeof queueId !== "string") {
517
- return void 0;
518
- }
436
+ } else if (id.length === FQ_ID_LENGTH && id.indexOf(":") === SPACE_ID_LENGTH) {
437
+ const [spaceId, objectId] = id.split(":");
519
438
  return {
520
- subspaceTag,
521
439
  spaceId,
522
- queueId,
523
440
  objectId
524
441
  };
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
- ]);
442
+ } else {
443
+ return {};
534
444
  }
535
445
  };
536
446
 
537
- // src/identity-did.ts
538
- var import_base32_decode2 = __toESM(require_base32_decode(), 1);
539
- import { invariant as invariant3 } from "@dxos/invariant";
540
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/keys/src/identity-did.ts";
541
- var IdentityDid = Object.freeze({
542
- byteLength: 20,
543
- encode: (value) => {
544
- invariant3(value instanceof Uint8Array, "Invalid type", {
545
- F: __dxlog_file3,
546
- L: 22,
547
- S: void 0,
548
- A: [
549
- "value instanceof Uint8Array",
550
- "'Invalid type'"
551
- ]
552
- });
553
- invariant3(value.length === IdentityDid.byteLength, "Invalid length", {
554
- F: __dxlog_file3,
555
- L: 23,
556
- S: void 0,
557
- A: [
558
- "value.length === IdentityDid.byteLength",
559
- "'Invalid length'"
560
- ]
561
- });
562
- return DID_PREFIX + MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
563
- },
564
- decode: (value) => {
565
- invariant3(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2), "Invalid multibase32 encoding", {
566
- F: __dxlog_file3,
567
- L: 28,
568
- S: void 0,
569
- A: [
570
- "value.startsWith(DID_PREFIX + MULTIBASE_PREFIX)",
571
- "'Invalid multibase32 encoding'"
572
- ]
573
- });
574
- return new Uint8Array((0, import_base32_decode2.default)(value.slice(10), "RFC4648"));
575
- },
576
- isValid: (value) => {
577
- return typeof value === "string" && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
578
- },
579
- random: () => {
580
- return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
581
- }
582
- });
583
- var MULTIBASE_PREFIX2 = "B";
584
- var DID_PREFIX = "did:halo:";
585
- var ENCODED_LENGTH2 = 42;
586
-
587
447
  // src/public-key.ts
588
- var import_base32_decode3 = __toESM(require_base32_decode(), 1);
589
- import { devtoolsFormatter as devtoolsFormatter2, equalsSymbol, inspectCustom as inspectCustom2, truncateKey } from "@dxos/debug";
590
- import { invariant as invariant4 } from "@dxos/invariant";
591
- var __dxlog_file4 = "/__w/dxos/dxos/packages/common/keys/src/public-key.ts";
448
+ var import_base32_decode2 = __toESM(require_base32_decode(), 1);
449
+ import { devtoolsFormatter, equalsSymbol, inspectCustom, truncateKey } from "@dxos/debug";
450
+ import { assertArgument, invariant as invariant2 } from "@dxos/invariant";
592
451
  var PUBLIC_KEY_LENGTH = 32;
593
452
  var SECRET_KEY_LENGTH = 64;
594
453
  var isLikeArrayBuffer = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ArrayBuffer";
@@ -601,15 +460,7 @@ var PublicKey = class _PublicKey {
601
460
  * @returns PublicKey
602
461
  */
603
462
  static from(source) {
604
- invariant4(source, void 0, {
605
- F: __dxlog_file4,
606
- L: 49,
607
- S: this,
608
- A: [
609
- "source",
610
- ""
611
- ]
612
- });
463
+ invariant2(source);
613
464
  if (source instanceof _PublicKey) {
614
465
  return source;
615
466
  } else if (source instanceof Buffer) {
@@ -693,15 +544,7 @@ var PublicKey = class _PublicKey {
693
544
  * @deprecated All keys should be represented as instances of PublicKey.
694
545
  */
695
546
  static bufferize(str) {
696
- invariant4(typeof str === "string", "Invalid type", {
697
- F: __dxlog_file4,
698
- L: 152,
699
- S: this,
700
- A: [
701
- "typeof str === 'string'",
702
- "'Invalid type'"
703
- ]
704
- });
547
+ assertArgument(typeof str === "string", "str", "Invalid type");
705
548
  const buffer = Buffer.from(str, "hex");
706
549
  return buffer;
707
550
  }
@@ -716,15 +559,7 @@ var PublicKey = class _PublicKey {
716
559
  } else if (key instanceof Uint8Array) {
717
560
  key = Buffer.from(key.buffer, key.byteOffset, key.byteLength);
718
561
  }
719
- invariant4(key instanceof Buffer, "Invalid type", {
720
- F: __dxlog_file4,
721
- L: 171,
722
- S: this,
723
- A: [
724
- "key instanceof Buffer",
725
- "'Invalid type'"
726
- ]
727
- });
562
+ invariant2(key instanceof Buffer, "Invalid type");
728
563
  return key.toString("hex");
729
564
  }
730
565
  /**
@@ -735,16 +570,8 @@ var PublicKey = class _PublicKey {
735
570
  return key.toHex();
736
571
  }
737
572
  static fromMultibase32(encoded) {
738
- invariant4(encoded.startsWith("B"), "Invalid multibase32 encoding", {
739
- F: __dxlog_file4,
740
- L: 184,
741
- S: this,
742
- A: [
743
- "encoded.startsWith('B')",
744
- "'Invalid multibase32 encoding'"
745
- ]
746
- });
747
- return new _PublicKey(new Uint8Array((0, import_base32_decode3.default)(encoded.slice(1), "RFC4648")));
573
+ invariant2(encoded.startsWith("B"), "Invalid multibase32 encoding");
574
+ return new _PublicKey(new Uint8Array((0, import_base32_decode2.default)(encoded.slice(1), "RFC4648")));
748
575
  }
749
576
  constructor(_value) {
750
577
  this._value = _value;
@@ -770,7 +597,7 @@ var PublicKey = class _PublicKey {
770
597
  toMultibase32() {
771
598
  return "B" + base32Encode(this._value, "RFC4648");
772
599
  }
773
- truncate(length = void 0) {
600
+ truncate(length) {
774
601
  return truncateKey(this, length);
775
602
  }
776
603
  asBuffer() {
@@ -785,7 +612,7 @@ var PublicKey = class _PublicKey {
785
612
  /**
786
613
  * Used by Node.js to get textual representation of this object when it's printed with a `console.log` statement.
787
614
  */
788
- [inspectCustom2](depth, options, inspectFn) {
615
+ [inspectCustom](depth, options, inspectFn) {
789
616
  if (!options.colors || typeof process.stdout.hasColors !== "function" || !process.stdout.hasColors()) {
790
617
  return `<PublicKey ${this.truncate()}>`;
791
618
  }
@@ -810,7 +637,7 @@ var PublicKey = class _PublicKey {
810
637
  const color = colors[this.getInsecureHash(colors.length)];
811
638
  return `PublicKey(${printControlCode(inspectFn.colors[color][0])}${this.truncate()}${printControlCode(inspectFn.colors.reset[0])})`;
812
639
  }
813
- get [devtoolsFormatter2]() {
640
+ get [devtoolsFormatter]() {
814
641
  return {
815
642
  header: () => {
816
643
  const colors = [
@@ -874,17 +701,46 @@ var PublicKey = class _PublicKey {
874
701
  return this.equals(other);
875
702
  }
876
703
  };
704
+
705
+ // src/space-id.ts
706
+ var import_base32_decode3 = __toESM(require_base32_decode(), 1);
707
+ import * as Schema6 from "effect/Schema";
708
+ import { invariant as invariant3 } from "@dxos/invariant";
709
+ var MULTIBASE_PREFIX2 = "B";
710
+ var ENCODED_LENGTH2 = 33;
711
+ var isValid2 = (value) => {
712
+ return typeof value === "string" && value.startsWith(MULTIBASE_PREFIX2) && value.length === ENCODED_LENGTH2;
713
+ };
714
+ var SpaceId = class extends Schema6.String.pipe(Schema6.filter(isValid2)) {
715
+ static byteLength = 20;
716
+ static encode = (value) => {
717
+ invariant3(value instanceof Uint8Array, "Invalid type");
718
+ invariant3(value.length === SpaceId.byteLength, "Invalid length");
719
+ return MULTIBASE_PREFIX2 + base32Encode(value, "RFC4648");
720
+ };
721
+ static decode = (value) => {
722
+ invariant3(value.startsWith(MULTIBASE_PREFIX2), "Invalid multibase32 encoding");
723
+ return new Uint8Array((0, import_base32_decode3.default)(value.slice(1), "RFC4648"));
724
+ };
725
+ static isValid = isValid2;
726
+ static random = () => {
727
+ return SpaceId.encode(randomBytes(SpaceId.byteLength));
728
+ };
729
+ };
877
730
  export {
878
- DXN,
879
- DXN_ECHO_REGEXP,
731
+ DXN_exports as DXN,
732
+ EID_exports as EID,
733
+ EntityId,
734
+ FQ_ID_LENGTH,
880
735
  IdentityDid,
881
- LOCAL_SPACE_TAG,
882
- ObjectId,
736
+ OBJECT_ID_LENGTH,
883
737
  PUBLIC_KEY_LENGTH,
884
738
  PublicKey,
885
- QueueSubspaceTags,
886
739
  SECRET_KEY_LENGTH,
740
+ SPACE_ID_LENGTH,
887
741
  SimplePRNG,
888
- SpaceId
742
+ SpaceId,
743
+ URI_exports as URI,
744
+ parseId
889
745
  };
890
746
  //# sourceMappingURL=index.mjs.map