@dxos/echo-protocol 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33

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.
@@ -12,13 +12,15 @@ import { visitValues } from "@dxos/util";
12
12
  import { assertArgument } from "@dxos/invariant";
13
13
  import { DXN, LOCAL_SPACE_TAG } from "@dxos/keys";
14
14
  var Reference = class _Reference {
15
- static {
16
- /**
17
- * Protocol references to runtime registered types.
18
- * @deprecated
19
- */
20
- this.TYPE_PROTOCOL = "protobuf";
21
- }
15
+ _objectId;
16
+ _protocol;
17
+ _host;
18
+ _dxn;
19
+ /**
20
+ * Protocol references to runtime registered types.
21
+ * @deprecated
22
+ */
23
+ static TYPE_PROTOCOL = "protobuf";
22
24
  static fromDXN(dxn) {
23
25
  switch (dxn.kind) {
24
26
  case DXN.kind.TYPE:
@@ -33,8 +35,8 @@ var Reference = class _Reference {
33
35
  return new _Reference(dxn.parts[0], void 0, dxn.parts[0], dxn);
34
36
  }
35
37
  }
36
- static fromValue(value) {
37
- return new _Reference(value.objectId, value.protocol, value.host);
38
+ static fromValue(value2) {
39
+ return new _Reference(value2.objectId, value2.protocol, value2.host);
38
40
  }
39
41
  /**
40
42
  * Reference an object in the local space.
@@ -122,28 +124,35 @@ var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
122
124
  var encodeReference = (reference) => ({
123
125
  "/": reference.toDXN().toString()
124
126
  });
125
- var decodeReference = (value) => {
126
- if (typeof value !== "object" || value === null || typeof value["/"] !== "string") {
127
+ var decodeReference = (value2) => {
128
+ if (typeof value2 !== "object" || value2 === null || typeof value2["/"] !== "string") {
127
129
  throw new Error("Invalid reference");
128
130
  }
129
- const dxnString = value["/"];
131
+ const dxnString = value2["/"];
130
132
  if (dxnString.length % 2 === 0 && dxnString.slice(0, dxnString.length / 2) === dxnString.slice(dxnString.length / 2) && dxnString.includes("dxn:echo")) {
131
133
  throw new Error("Automerge bug detected!");
132
134
  }
133
135
  return Reference.fromDXN(DXN.parse(dxnString));
134
136
  };
135
- var isEncodedReference = (value) => typeof value === "object" && value !== null && Object.keys(value).length === 1 && typeof value["/"] === "string";
137
+ var isEncodedReference = (value2) => typeof value2 === "object" && value2 !== null && Object.keys(value2).length === 1 && typeof value2["/"] === "string";
136
138
  var EncodedReference = Object.freeze({
137
139
  isEncodedReference,
138
- getReferenceString: (value) => {
139
- assertArgument(isEncodedReference(value), "invalid reference");
140
- return value["/"];
140
+ getReferenceString: (value2) => {
141
+ assertArgument(isEncodedReference(value2), "value", "invalid reference");
142
+ return value2["/"];
141
143
  },
142
- toDXN: (value) => {
143
- return DXN.parse(EncodedReference.getReferenceString(value));
144
+ toDXN: (value2) => {
145
+ return DXN.parse(EncodedReference.getReferenceString(value2));
144
146
  },
145
147
  fromDXN: (dxn) => {
146
- return encodeReference(Reference.fromDXN(dxn));
148
+ return {
149
+ "/": dxn.toString()
150
+ };
151
+ },
152
+ fromLegacyTypename: (typename) => {
153
+ return {
154
+ "/": DXN.fromTypename(typename).toString()
155
+ };
147
156
  }
148
157
  });
149
158
 
@@ -159,15 +168,7 @@ var DatabaseDirectory = Object.freeze({
159
168
  return null;
160
169
  }
161
170
  const rawKey = String(rawSpaceKey);
162
- invariant(!rawKey.startsWith("0x"), "Space key must not start with 0x", {
163
- F: __dxlog_file,
164
- L: 66,
165
- S: void 0,
166
- A: [
167
- "!rawKey.startsWith('0x')",
168
- "'Space key must not start with 0x'"
169
- ]
170
- });
171
+ invariant(!rawKey.startsWith("0x"), "Space key must not start with 0x", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 17, S: void 0, A: ["!rawKey.startsWith('0x')", "'Space key must not start with 0x'"] });
171
172
  return rawKey;
172
173
  },
173
174
  getInlineObject: (doc, id) => {
@@ -196,15 +197,7 @@ var ObjectStructure = Object.freeze({
196
197
  */
197
198
  getEntityKind: (object) => {
198
199
  const kind = object.system?.kind ?? "object";
199
- invariant(kind === "object" || kind === "relation", "Invalid kind", {
200
- F: __dxlog_file,
201
- L: 124,
202
- S: void 0,
203
- A: [
204
- "kind === 'object' || kind === 'relation'",
205
- "'Invalid kind'"
206
- ]
207
- });
200
+ invariant(kind === "object" || kind === "relation", "Invalid kind", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 45, S: void 0, A: ["kind === 'object' || kind === 'relation'", "'Invalid kind'"] });
208
201
  return kind;
209
202
  },
210
203
  isDeleted: (object) => {
@@ -216,29 +209,35 @@ var ObjectStructure = Object.freeze({
216
209
  getRelationTarget: (object) => {
217
210
  return object.system?.target;
218
211
  },
212
+ getParent: (object) => {
213
+ return object.system?.parent;
214
+ },
219
215
  /**
220
216
  * @returns All references in the data section of the object.
221
217
  */
222
218
  getAllOutgoingReferences: (object) => {
223
219
  const references = [];
224
- const visit2 = (path, value) => {
225
- if (isEncodedReference(value)) {
220
+ const visit2 = (path, value2) => {
221
+ if (isEncodedReference(value2)) {
226
222
  references.push({
227
223
  path,
228
- reference: value
224
+ reference: value2
229
225
  });
230
226
  } else {
231
- visitValues(value, (value2, key) => visit2([
227
+ visitValues(value2, (value3, key) => visit2([
232
228
  ...path,
233
229
  String(key)
234
- ], value2));
230
+ ], value3));
235
231
  }
236
232
  };
237
- visitValues(object.data, (value, key) => visit2([
233
+ visitValues(object.data, (value2, key) => visit2([
238
234
  String(key)
239
- ], value));
235
+ ], value2));
240
236
  return references;
241
237
  },
238
+ getTags: (object) => {
239
+ return object.meta.tags ?? [];
240
+ },
242
241
  makeObject: ({ type, data, keys }) => {
243
242
  return {
244
243
  system: {
@@ -274,37 +273,63 @@ var ObjectStructure = Object.freeze({
274
273
  var PROPERTY_ID = "id";
275
274
  var DATA_NAMESPACE = "data";
276
275
 
277
- // src/space-doc-version.ts
278
- var SpaceDocVersion = Object.freeze({
276
+ // src/echo-feed-codec.ts
277
+ import { FeedProtocol } from "@dxos/protocols";
278
+ var ATTR_META = "@meta";
279
+ var EchoFeedCodec = class _EchoFeedCodec {
280
+ static #encoder = new TextEncoder();
281
+ static #decoder = new TextDecoder();
279
282
  /**
280
- * For the documents created before the versioning was introduced.
283
+ * Prepares a value for feed storage (strips queue position from metadata) and encodes to bytes.
281
284
  */
282
- LEGACY: 0,
285
+ static encode(value2) {
286
+ const prepared = _EchoFeedCodec.#stripQueuePosition(value2);
287
+ return _EchoFeedCodec.#encoder.encode(JSON.stringify(prepared));
288
+ }
283
289
  /**
284
- * Current version.
290
+ * Decodes feed block bytes to a JSON value.
291
+ * If position is provided, injects queue position into the decoded object's metadata.
285
292
  */
286
- CURRENT: 1
287
- });
288
-
289
- // src/space-id.ts
290
- import { subtleCrypto } from "@dxos/crypto";
291
- import { PublicKey, SpaceId } from "@dxos/keys";
292
- import { ComplexMap } from "@dxos/util";
293
- var SPACE_IDS_CACHE = new ComplexMap(PublicKey.hash);
294
- var createIdFromSpaceKey = async (spaceKey) => {
295
- const cachedValue = SPACE_IDS_CACHE.get(spaceKey);
296
- if (cachedValue !== void 0) {
297
- return cachedValue;
293
+ static decode(data, position) {
294
+ const decoded = JSON.parse(_EchoFeedCodec.#decoder.decode(data));
295
+ if (position !== void 0 && typeof decoded === "object" && decoded !== null) {
296
+ _EchoFeedCodec.#setQueuePosition(decoded, position);
297
+ }
298
+ return decoded;
299
+ }
300
+ static #stripQueuePosition(value2) {
301
+ if (typeof value2 !== "object" || value2 === null) {
302
+ return value2;
303
+ }
304
+ const obj = structuredClone(value2);
305
+ const meta = obj[ATTR_META];
306
+ if (meta?.keys?.some((key) => key.source === FeedProtocol.KEY_QUEUE_POSITION)) {
307
+ meta.keys = meta.keys.filter((key) => key.source !== FeedProtocol.KEY_QUEUE_POSITION);
308
+ }
309
+ return obj;
310
+ }
311
+ static #setQueuePosition(obj, position) {
312
+ obj[ATTR_META] ??= {
313
+ keys: []
314
+ };
315
+ obj[ATTR_META].keys ??= [];
316
+ const keys = obj[ATTR_META].keys;
317
+ for (let i = 0; i < keys.length; i++) {
318
+ if (keys[i].source === FeedProtocol.KEY_QUEUE_POSITION) {
319
+ keys.splice(i, 1);
320
+ i--;
321
+ }
322
+ }
323
+ keys.push({
324
+ source: FeedProtocol.KEY_QUEUE_POSITION,
325
+ id: position.toString()
326
+ });
298
327
  }
299
- const digest = await subtleCrypto.digest("SHA-256", spaceKey.asUint8Array());
300
- const bytes = new Uint8Array(digest).slice(0, SpaceId.byteLength);
301
- const spaceId = SpaceId.encode(bytes);
302
- SPACE_IDS_CACHE.set(spaceKey, spaceId);
303
- return spaceId;
304
328
  };
305
329
 
306
330
  // src/foreign-key.ts
307
- import { Schema, SchemaAST } from "effect";
331
+ import * as Schema from "effect/Schema";
332
+ import * as SchemaAST from "effect/SchemaAST";
308
333
  var ForeignKey_ = Schema.Struct({
309
334
  /**
310
335
  * Name of the foreign database/system.
@@ -315,9 +340,9 @@ var ForeignKey_ = Schema.Struct({
315
340
  * Id within the foreign database.
316
341
  */
317
342
  // TODO(wittjosiah): This annotation is currently used to ensure id field shows up in forms.
318
- // TODO(dmaretskyi): `false` is not a valid value for the annotation.
343
+ // TODO(dmaretskyi): `false` is not a valid value for the annotation. Use a different annotation.
319
344
  id: Schema.String.annotations({
320
- [SchemaAST.IdentifierAnnotationId]: false
345
+ [SchemaAST.IdentifierAnnotationId]: "false"
321
346
  })
322
347
  });
323
348
  var ForeignKey = ForeignKey_;
@@ -327,30 +352,45 @@ var ast_exports = {};
327
352
  __export(ast_exports, {
328
353
  Filter: () => Filter,
329
354
  FilterAnd: () => FilterAnd,
355
+ FilterChildOf: () => FilterChildOf,
330
356
  FilterCompare: () => FilterCompare,
357
+ FilterContains: () => FilterContains,
331
358
  FilterIn: () => FilterIn,
332
359
  FilterNot: () => FilterNot,
333
360
  FilterObject: () => FilterObject,
334
361
  FilterOr: () => FilterOr,
335
362
  FilterRange: () => FilterRange,
363
+ FilterTag: () => FilterTag,
336
364
  FilterTextSearch: () => FilterTextSearch,
365
+ FilterTimestamp: () => FilterTimestamp,
366
+ Order: () => Order,
367
+ OrderDirection: () => OrderDirection,
337
368
  Query: () => Query,
338
369
  QueryFilterClause: () => QueryFilterClause,
370
+ QueryFromClause: () => QueryFromClause,
371
+ QueryFromClause_: () => QueryFromClause_,
372
+ QueryHierarchyTraversalClause: () => QueryHierarchyTraversalClause,
339
373
  QueryIncomingReferencesClause: () => QueryIncomingReferencesClause,
374
+ QueryLimitClause: () => QueryLimitClause,
340
375
  QueryOptions: () => QueryOptions,
341
376
  QueryOptionsClause: () => QueryOptionsClause,
377
+ QueryOrderClause: () => QueryOrderClause,
342
378
  QueryReferenceTraversalClause: () => QueryReferenceTraversalClause,
343
379
  QueryRelationClause: () => QueryRelationClause,
344
380
  QueryRelationTraversalClause: () => QueryRelationTraversalClause,
345
381
  QuerySelectClause: () => QuerySelectClause,
346
382
  QuerySetDifferenceClause: () => QuerySetDifferenceClause,
347
383
  QueryUnionClause: () => QueryUnionClause,
384
+ Scope: () => Scope,
385
+ fold: () => fold,
386
+ map: () => map,
348
387
  visit: () => visit
349
388
  });
350
- import { Schema as Schema2 } from "effect";
389
+ import * as Match from "effect/Match";
390
+ import * as Schema2 from "effect/Schema";
351
391
  import { DXN as DXN2, ObjectId } from "@dxos/keys";
352
392
  var TypenameSpecifier = Schema2.Union(DXN2.Schema, Schema2.Null).annotations({
353
- description: "DXN or null. Null means any type will match"
393
+ description: "DXN or null; null matches any type"
354
394
  });
355
395
  var FilterObject_ = Schema2.Struct({
356
396
  type: Schema2.Literal("object"),
@@ -383,12 +423,29 @@ var FilterIn_ = Schema2.Struct({
383
423
  values: Schema2.Array(Schema2.Any)
384
424
  });
385
425
  var FilterIn = FilterIn_;
426
+ var FilterContains_ = Schema2.Struct({
427
+ type: Schema2.Literal("contains"),
428
+ value: Schema2.Any
429
+ });
430
+ var FilterContains = FilterContains_;
431
+ var FilterTag_ = Schema2.Struct({
432
+ type: Schema2.Literal("tag"),
433
+ tag: Schema2.String
434
+ });
435
+ var FilterTag = FilterTag_;
386
436
  var FilterRange_ = Schema2.Struct({
387
437
  type: Schema2.Literal("range"),
388
438
  from: Schema2.Any,
389
439
  to: Schema2.Any
390
440
  });
391
441
  var FilterRange = FilterRange_;
442
+ var FilterTimestamp_ = Schema2.Struct({
443
+ type: Schema2.Literal("timestamp"),
444
+ field: Schema2.Literal("createdAt", "updatedAt"),
445
+ operator: Schema2.Literal("gt", "gte", "lt", "lte"),
446
+ value: Schema2.Number
447
+ });
448
+ var FilterTimestamp = FilterTimestamp_;
392
449
  var FilterTextSearch_ = Schema2.Struct({
393
450
  type: Schema2.Literal("text-search"),
394
451
  text: Schema2.String,
@@ -410,7 +467,17 @@ var FilterOr_ = Schema2.Struct({
410
467
  filters: Schema2.Array(Schema2.suspend(() => Filter))
411
468
  });
412
469
  var FilterOr = FilterOr_;
413
- var Filter = Schema2.Union(FilterObject, FilterTextSearch, FilterCompare, FilterIn, FilterRange, FilterNot, FilterAnd, FilterOr);
470
+ var FilterChildOf_ = Schema2.Struct({
471
+ type: Schema2.Literal("child-of"),
472
+ /** Parent DXNs to match children of. */
473
+ parents: Schema2.Array(DXN2.Schema),
474
+ /** Whether to match transitively (grandchildren, etc.). Defaults to true. */
475
+ transitive: Schema2.Boolean
476
+ });
477
+ var FilterChildOf = FilterChildOf_;
478
+ var Filter = Schema2.Union(FilterObject, FilterCompare, FilterIn, FilterContains, FilterTag, FilterRange, FilterTimestamp, FilterTextSearch, FilterChildOf, FilterNot, FilterAnd, FilterOr).annotations({
479
+ identifier: "org.dxos.schema.filter"
480
+ });
414
481
  var QuerySelectClause_ = Schema2.Struct({
415
482
  type: Schema2.Literal("select"),
416
483
  filter: Schema2.suspend(() => Filter)
@@ -431,7 +498,11 @@ var QueryReferenceTraversalClause = QueryReferenceTraversalClause_;
431
498
  var QueryIncomingReferencesClause_ = Schema2.Struct({
432
499
  type: Schema2.Literal("incoming-references"),
433
500
  anchor: Schema2.suspend(() => Query),
434
- property: Schema2.String,
501
+ /**
502
+ * Property path where the reference is located.
503
+ * If null, matches references from any property.
504
+ */
505
+ property: Schema2.NullOr(Schema2.String),
435
506
  typename: TypenameSpecifier
436
507
  });
437
508
  var QueryIncomingReferencesClause = QueryIncomingReferencesClause_;
@@ -453,6 +524,16 @@ var QueryRelationTraversalClause_ = Schema2.Struct({
453
524
  direction: Schema2.Literal("source", "target", "both")
454
525
  });
455
526
  var QueryRelationTraversalClause = QueryRelationTraversalClause_;
527
+ var QueryHierarchyTraversalClause_ = Schema2.Struct({
528
+ type: Schema2.Literal("hierarchy-traversal"),
529
+ anchor: Schema2.suspend(() => Query),
530
+ /**
531
+ * to-parent: traverse from child to parent.
532
+ * to-children: traverse from parent to children.
533
+ */
534
+ direction: Schema2.Literal("to-parent", "to-children")
535
+ });
536
+ var QueryHierarchyTraversalClause = QueryHierarchyTraversalClause_;
456
537
  var QueryUnionClause_ = Schema2.Struct({
457
538
  type: Schema2.Literal("union"),
458
539
  queries: Schema2.Array(Schema2.suspend(() => Query))
@@ -464,50 +545,261 @@ var QuerySetDifferenceClause_ = Schema2.Struct({
464
545
  exclude: Schema2.suspend(() => Query)
465
546
  });
466
547
  var QuerySetDifferenceClause = QuerySetDifferenceClause_;
548
+ var OrderDirection = Schema2.Literal("asc", "desc");
549
+ var Order_ = Schema2.Union(Schema2.Struct({
550
+ // How database wants to order them (in practice - by id).
551
+ kind: Schema2.Literal("natural")
552
+ }), Schema2.Struct({
553
+ kind: Schema2.Literal("property"),
554
+ property: Schema2.String,
555
+ direction: OrderDirection
556
+ }), Schema2.Struct({
557
+ // Order by relevance rank (for FTS/vector search results).
558
+ // Default direction is 'desc' (higher rank = better match first).
559
+ kind: Schema2.Literal("rank"),
560
+ direction: OrderDirection
561
+ }));
562
+ var Order = Order_;
563
+ var QueryOrderClause_ = Schema2.Struct({
564
+ type: Schema2.Literal("order"),
565
+ query: Schema2.suspend(() => Query),
566
+ order: Schema2.Array(Order)
567
+ });
568
+ var QueryOrderClause = QueryOrderClause_;
467
569
  var QueryOptionsClause_ = Schema2.Struct({
468
570
  type: Schema2.Literal("options"),
469
571
  query: Schema2.suspend(() => Query),
470
572
  options: Schema2.suspend(() => QueryOptions)
471
573
  });
472
574
  var QueryOptionsClause = QueryOptionsClause_;
473
- var Query_ = Schema2.Union(QuerySelectClause, QueryFilterClause, QueryReferenceTraversalClause, QueryIncomingReferencesClause, QueryRelationClause, QueryRelationTraversalClause, QueryUnionClause, QuerySetDifferenceClause, QueryOptionsClause);
575
+ var QueryLimitClause_ = Schema2.Struct({
576
+ type: Schema2.Literal("limit"),
577
+ query: Schema2.suspend(() => Query),
578
+ limit: Schema2.Number
579
+ });
580
+ var QueryLimitClause = QueryLimitClause_;
581
+ var QueryFromClause_ = Schema2.Struct({
582
+ type: Schema2.Literal("from"),
583
+ query: Schema2.suspend(() => Query),
584
+ from: Schema2.Union(Schema2.TaggedStruct("scope", {
585
+ scope: Schema2.suspend(() => Scope)
586
+ }), Schema2.TaggedStruct("query", {
587
+ query: Schema2.suspend(() => Query)
588
+ }))
589
+ });
590
+ var QueryFromClause = QueryFromClause_;
591
+ var Query_ = Schema2.Union(QuerySelectClause, QueryFilterClause, QueryReferenceTraversalClause, QueryIncomingReferencesClause, QueryRelationClause, QueryRelationTraversalClause, QueryHierarchyTraversalClause, QueryUnionClause, QuerySetDifferenceClause, QueryOrderClause, QueryOptionsClause, QueryLimitClause, QueryFromClause).annotations({
592
+ identifier: "org.dxos.schema.query"
593
+ });
474
594
  var Query = Query_;
475
595
  var QueryOptions = Schema2.Struct({
596
+ /**
597
+ * Nested select statements will use this option to filter deleted objects.
598
+ */
599
+ deleted: Schema2.optional(Schema2.Literal("include", "exclude", "only")),
600
+ /**
601
+ * Diagnostics-only label for logs / tooling (not used by execution semantics).
602
+ */
603
+ debugLabel: Schema2.optional(Schema2.String)
604
+ });
605
+ var Scope = Schema2.Struct({
606
+ /**
607
+ * The nested select statemets will select from the given spaces.
608
+ *
609
+ * NOTE: Spaces and queues are unioned together if both are specified.
610
+ */
476
611
  spaceIds: Schema2.optional(Schema2.Array(Schema2.String)),
477
- deleted: Schema2.optional(Schema2.Literal("include", "exclude", "only"))
612
+ /**
613
+ * If true, the nested select statements will select from all queues in the spaces specified by `spaceIds`.
614
+ */
615
+ allQueuesFromSpaces: Schema2.optional(Schema2.Boolean),
616
+ /**
617
+ * The nested select statemets will select from the given queues.
618
+ *
619
+ * NOTE: Spaces and queues are unioned together if both are specified.
620
+ */
621
+ queues: Schema2.optional(Schema2.Array(DXN2.Schema))
478
622
  });
479
623
  var visit = (query, visitor) => {
480
- switch (query.type) {
481
- case "filter":
482
- visit(query.selection, visitor);
483
- break;
484
- case "reference-traversal":
485
- visit(query.anchor, visitor);
486
- break;
487
- case "incoming-references":
488
- visit(query.anchor, visitor);
489
- break;
490
- case "relation":
491
- visit(query.anchor, visitor);
492
- break;
493
- case "options":
494
- visit(query.query, visitor);
495
- break;
496
- case "relation-traversal":
497
- visit(query.anchor, visitor);
498
- break;
499
- case "union":
500
- query.queries.forEach((q) => visit(q, visitor));
501
- break;
502
- case "set-difference":
503
- visit(query.source, visitor);
504
- visit(query.exclude, visitor);
505
- break;
624
+ visitor(query);
625
+ Match.value(query).pipe(Match.when({
626
+ type: "filter"
627
+ }, ({ selection }) => visit(selection, visitor)), Match.when({
628
+ type: "reference-traversal"
629
+ }, ({ anchor }) => visit(anchor, visitor)), Match.when({
630
+ type: "incoming-references"
631
+ }, ({ anchor }) => visit(anchor, visitor)), Match.when({
632
+ type: "relation"
633
+ }, ({ anchor }) => visit(anchor, visitor)), Match.when({
634
+ type: "options"
635
+ }, ({ query: query2 }) => visit(query2, visitor)), Match.when({
636
+ type: "relation-traversal"
637
+ }, ({ anchor }) => visit(anchor, visitor)), Match.when({
638
+ type: "hierarchy-traversal"
639
+ }, ({ anchor }) => visit(anchor, visitor)), Match.when({
640
+ type: "union"
641
+ }, ({ queries }) => queries.forEach((q) => visit(q, visitor))), Match.when({
642
+ type: "set-difference"
643
+ }, ({ source, exclude }) => {
644
+ visit(source, visitor);
645
+ visit(exclude, visitor);
646
+ }), Match.when({
647
+ type: "order"
648
+ }, ({ query: query2 }) => visit(query2, visitor)), Match.when({
649
+ type: "limit"
650
+ }, ({ query: query2 }) => visit(query2, visitor)), Match.when({
651
+ type: "from"
652
+ }, (node) => {
653
+ visit(node.query, visitor);
654
+ if (node.from._tag === "query") {
655
+ visit(node.from.query, visitor);
656
+ }
657
+ }), Match.when({
658
+ type: "select"
659
+ }, () => {
660
+ }), Match.exhaustive);
661
+ };
662
+ var map = (query, mapper) => {
663
+ const mapped = Match.value(query).pipe(Match.when({
664
+ type: "filter"
665
+ }, (node) => ({
666
+ ...node,
667
+ selection: map(node.selection, mapper)
668
+ })), Match.when({
669
+ type: "reference-traversal"
670
+ }, (node) => ({
671
+ ...node,
672
+ anchor: map(node.anchor, mapper)
673
+ })), Match.when({
674
+ type: "incoming-references"
675
+ }, (node) => ({
676
+ ...node,
677
+ anchor: map(node.anchor, mapper)
678
+ })), Match.when({
679
+ type: "relation"
680
+ }, (node) => ({
681
+ ...node,
682
+ anchor: map(node.anchor, mapper)
683
+ })), Match.when({
684
+ type: "relation-traversal"
685
+ }, (node) => ({
686
+ ...node,
687
+ anchor: map(node.anchor, mapper)
688
+ })), Match.when({
689
+ type: "hierarchy-traversal"
690
+ }, (node) => ({
691
+ ...node,
692
+ anchor: map(node.anchor, mapper)
693
+ })), Match.when({
694
+ type: "options"
695
+ }, (node) => ({
696
+ ...node,
697
+ query: map(node.query, mapper)
698
+ })), Match.when({
699
+ type: "order"
700
+ }, (node) => ({
701
+ ...node,
702
+ query: map(node.query, mapper)
703
+ })), Match.when({
704
+ type: "limit"
705
+ }, (node) => ({
706
+ ...node,
707
+ query: map(node.query, mapper)
708
+ })), Match.when({
709
+ type: "from"
710
+ }, (node) => ({
711
+ ...node,
712
+ query: map(node.query, mapper),
713
+ ...node.from._tag === "query" ? {
714
+ from: {
715
+ _tag: "query",
716
+ query: map(node.from.query, mapper)
717
+ }
718
+ } : {}
719
+ })), Match.when({
720
+ type: "union"
721
+ }, (node) => ({
722
+ ...node,
723
+ queries: node.queries.map((q) => map(q, mapper))
724
+ })), Match.when({
725
+ type: "set-difference"
726
+ }, (node) => ({
727
+ ...node,
728
+ source: map(node.source, mapper),
729
+ exclude: map(node.exclude, mapper)
730
+ })), Match.when({
731
+ type: "select"
732
+ }, (node) => node), Match.exhaustive);
733
+ return mapper(mapped);
734
+ };
735
+ var fold = (query, reducer) => {
736
+ return Match.value(query).pipe(Match.withReturnType(), Match.when({
737
+ type: "filter"
738
+ }, ({ selection }) => fold(selection, reducer)), Match.when({
739
+ type: "reference-traversal"
740
+ }, ({ anchor }) => fold(anchor, reducer)), Match.when({
741
+ type: "incoming-references"
742
+ }, ({ anchor }) => fold(anchor, reducer)), Match.when({
743
+ type: "relation"
744
+ }, ({ anchor }) => fold(anchor, reducer)), Match.when({
745
+ type: "options"
746
+ }, ({ query: query2 }) => fold(query2, reducer)), Match.when({
747
+ type: "relation-traversal"
748
+ }, ({ anchor }) => fold(anchor, reducer)), Match.when({
749
+ type: "hierarchy-traversal"
750
+ }, ({ anchor }) => fold(anchor, reducer)), Match.when({
751
+ type: "union"
752
+ }, ({ queries }) => queries.flatMap((q) => fold(q, reducer))), Match.when({
753
+ type: "set-difference"
754
+ }, ({ source, exclude }) => fold(source, reducer).concat(fold(exclude, reducer))), Match.when({
755
+ type: "order"
756
+ }, ({ query: query2 }) => fold(query2, reducer)), Match.when({
757
+ type: "limit"
758
+ }, ({ query: query2 }) => fold(query2, reducer)), Match.when({
759
+ type: "from"
760
+ }, (node) => {
761
+ const results = fold(node.query, reducer);
762
+ if (node.from._tag === "query") {
763
+ return results.concat(fold(node.from.query, reducer));
764
+ }
765
+ return results;
766
+ }), Match.when({
767
+ type: "select"
768
+ }, () => []), Match.exhaustive);
769
+ };
770
+
771
+ // src/space-doc-version.ts
772
+ var SpaceDocVersion = Object.freeze({
773
+ /**
774
+ * For the documents created before the versioning was introduced.
775
+ */
776
+ LEGACY: 0,
777
+ /**
778
+ * Current version.
779
+ */
780
+ CURRENT: 1
781
+ });
782
+
783
+ // src/space-id.ts
784
+ import { subtleCrypto } from "@dxos/crypto";
785
+ import { PublicKey, SpaceId } from "@dxos/keys";
786
+ import { ComplexMap } from "@dxos/util";
787
+ var SPACE_IDS_CACHE = new ComplexMap(PublicKey.hash);
788
+ var createIdFromSpaceKey = async (spaceKey) => {
789
+ const cachedValue = SPACE_IDS_CACHE.get(spaceKey);
790
+ if (cachedValue !== void 0) {
791
+ return cachedValue;
506
792
  }
793
+ const digest = await subtleCrypto.digest("SHA-256", spaceKey.asUint8Array());
794
+ const bytes = new Uint8Array(digest).slice(0, SpaceId.byteLength);
795
+ const spaceId = SpaceId.encode(bytes);
796
+ SPACE_IDS_CACHE.set(spaceKey, spaceId);
797
+ return spaceId;
507
798
  };
508
799
  export {
509
800
  DATA_NAMESPACE,
510
801
  DatabaseDirectory,
802
+ EchoFeedCodec,
511
803
  EncodedReference,
512
804
  ForeignKey,
513
805
  ObjectStructure,