@dxos/echo-pipeline 0.8.2-main.fbd8ed0 → 0.8.2-staging.4d6ad0f

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 (155) hide show
  1. package/dist/lib/browser/{chunk-TPEBUDNJ.mjs → chunk-3XSXS5EX.mjs} +7 -13
  2. package/dist/lib/browser/chunk-3XSXS5EX.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
  4. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-TQJTKNMS.mjs +126 -0
  6. package/dist/lib/browser/chunk-TQJTKNMS.mjs.map +7 -0
  7. package/dist/lib/browser/filter/index.mjs +11 -0
  8. package/dist/lib/browser/filter/index.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +1255 -392
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/testing/index.mjs +192 -11
  13. package/dist/lib/browser/testing/index.mjs.map +4 -4
  14. package/dist/lib/node/chunk-HOPOFWAL.cjs +147 -0
  15. package/dist/lib/node/chunk-HOPOFWAL.cjs.map +7 -0
  16. package/dist/lib/node/chunk-Q7SFCCGT.cjs +33 -0
  17. package/dist/lib/node/chunk-Q7SFCCGT.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-QD3U65NM.cjs → chunk-SG2PL5RH.cjs} +10 -16
  19. package/dist/lib/node/chunk-SG2PL5RH.cjs.map +7 -0
  20. package/dist/lib/node/filter/index.cjs +32 -0
  21. package/dist/lib/node/filter/index.cjs.map +7 -0
  22. package/dist/lib/node/index.cjs +1255 -401
  23. package/dist/lib/node/index.cjs.map +4 -4
  24. package/dist/lib/node/meta.json +1 -1
  25. package/dist/lib/node/testing/index.cjs +197 -20
  26. package/dist/lib/node/testing/index.cjs.map +4 -4
  27. package/dist/lib/node-esm/{chunk-S5YERQ4D.mjs → chunk-3BZP75TJ.mjs} +7 -13
  28. package/dist/lib/node-esm/chunk-3BZP75TJ.mjs.map +7 -0
  29. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  30. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  31. package/dist/lib/node-esm/chunk-RVK35BS7.mjs +126 -0
  32. package/dist/lib/node-esm/chunk-RVK35BS7.mjs.map +7 -0
  33. package/dist/lib/node-esm/filter/index.mjs +11 -0
  34. package/dist/lib/node-esm/filter/index.mjs.map +7 -0
  35. package/dist/lib/node-esm/index.mjs +1255 -392
  36. package/dist/lib/node-esm/index.mjs.map +4 -4
  37. package/dist/lib/node-esm/meta.json +1 -1
  38. package/dist/lib/node-esm/testing/index.mjs +192 -11
  39. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  40. package/dist/types/src/automerge/automerge-host.d.ts +1 -2
  41. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  42. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  43. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
  44. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  45. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  46. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  47. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  48. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  49. package/dist/types/src/db-host/database-root.d.ts +5 -5
  50. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  51. package/dist/types/src/db-host/documents-iterator.d.ts +1 -1
  52. package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -1
  53. package/dist/types/src/db-host/documents-synchronizer.d.ts +2 -2
  54. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  55. package/dist/types/src/db-host/echo-host.d.ts +12 -1
  56. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  57. package/dist/types/src/db-host/index.d.ts +0 -1
  58. package/dist/types/src/db-host/index.d.ts.map +1 -1
  59. package/dist/types/src/db-host/query-service.d.ts +2 -0
  60. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  61. package/dist/types/src/db-host/space-state-manager.d.ts +3 -2
  62. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  63. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  64. package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
  65. package/dist/types/src/filter/filter-match.d.ts +13 -0
  66. package/dist/types/src/filter/filter-match.d.ts.map +1 -0
  67. package/dist/types/src/filter/filter-match.test.d.ts +2 -0
  68. package/dist/types/src/filter/filter-match.test.d.ts.map +1 -0
  69. package/dist/types/src/filter/index.d.ts +2 -0
  70. package/dist/types/src/filter/index.d.ts.map +1 -0
  71. package/dist/types/src/index.d.ts +1 -0
  72. package/dist/types/src/index.d.ts.map +1 -1
  73. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  74. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  75. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  76. package/dist/types/src/query/errors.d.ts +23 -0
  77. package/dist/types/src/query/errors.d.ts.map +1 -0
  78. package/dist/types/src/query/index.d.ts +5 -0
  79. package/dist/types/src/query/index.d.ts.map +1 -0
  80. package/dist/types/src/query/plan.d.ts +132 -0
  81. package/dist/types/src/query/plan.d.ts.map +1 -0
  82. package/dist/types/src/query/query-executor.d.ts +83 -0
  83. package/dist/types/src/query/query-executor.d.ts.map +1 -0
  84. package/dist/types/src/query/query-planner.d.ts +33 -0
  85. package/dist/types/src/query/query-planner.d.ts.map +1 -0
  86. package/dist/types/src/query/query-planner.test.d.ts +2 -0
  87. package/dist/types/src/query/query-planner.test.d.ts.map +1 -0
  88. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  89. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  90. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  91. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  92. package/dist/types/src/space/space.d.ts.map +1 -1
  93. package/dist/types/src/testing/index.d.ts +2 -0
  94. package/dist/types/src/testing/index.d.ts.map +1 -1
  95. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  96. package/dist/types/src/testing/test-data.d.ts +18 -0
  97. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  98. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  99. package/dist/types/src/testing/test-schema.d.ts +39 -0
  100. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  101. package/dist/types/src/util.d.ts +2 -2
  102. package/dist/types/src/util.d.ts.map +1 -1
  103. package/package.json +43 -35
  104. package/src/automerge/automerge-host.ts +29 -38
  105. package/src/automerge/automerge-repo.test.ts +1 -1
  106. package/src/automerge/collection-synchronizer.ts +8 -8
  107. package/src/automerge/echo-data-monitor.ts +12 -12
  108. package/src/automerge/echo-network-adapter.ts +12 -12
  109. package/src/automerge/heads-store.ts +1 -1
  110. package/src/automerge/mesh-echo-replicator-connection.ts +3 -3
  111. package/src/automerge/mesh-echo-replicator.ts +2 -2
  112. package/src/db-host/data-service.ts +2 -2
  113. package/src/db-host/database-root.ts +6 -7
  114. package/src/db-host/documents-iterator.ts +5 -5
  115. package/src/db-host/documents-synchronizer.ts +11 -11
  116. package/src/db-host/echo-host.ts +40 -14
  117. package/src/db-host/index.ts +0 -1
  118. package/src/db-host/query-service.ts +38 -33
  119. package/src/db-host/space-state-manager.ts +13 -3
  120. package/src/edge/echo-edge-replicator.ts +7 -7
  121. package/src/edge/inflight-request-limiter.ts +4 -4
  122. package/src/filter/filter-match.test.ts +101 -0
  123. package/src/filter/filter-match.ts +174 -0
  124. package/src/filter/index.ts +5 -0
  125. package/src/index.ts +1 -0
  126. package/src/metadata/metadata-store.ts +13 -13
  127. package/src/pipeline/pipeline-stress.test.ts +9 -9
  128. package/src/pipeline/pipeline.ts +13 -13
  129. package/src/pipeline/timeframe-clock.ts +5 -5
  130. package/src/query/errors.ts +7 -0
  131. package/src/query/index.ts +8 -0
  132. package/src/query/plan.ts +179 -0
  133. package/src/query/query-executor.ts +648 -0
  134. package/src/query/query-planner.test.ts +613 -0
  135. package/src/query/query-planner.ts +470 -0
  136. package/src/space/admission-discovery-extension.ts +2 -2
  137. package/src/space/control-pipeline.ts +8 -8
  138. package/src/space/space-manager.ts +3 -3
  139. package/src/space/space-protocol.browser.test.ts +1 -0
  140. package/src/space/space-protocol.test.ts +1 -0
  141. package/src/space/space-protocol.ts +4 -4
  142. package/src/space/space.ts +5 -5
  143. package/src/testing/index.ts +2 -0
  144. package/src/testing/test-agent-builder.ts +6 -6
  145. package/src/testing/test-data.ts +127 -0
  146. package/src/testing/test-network-adapter.ts +7 -7
  147. package/src/testing/test-replicator.ts +2 -2
  148. package/src/testing/test-schema.ts +53 -0
  149. package/src/util.ts +7 -3
  150. package/dist/lib/browser/chunk-TPEBUDNJ.mjs.map +0 -7
  151. package/dist/lib/node/chunk-QD3U65NM.cjs.map +0 -7
  152. package/dist/lib/node-esm/chunk-S5YERQ4D.mjs.map +0 -7
  153. package/dist/types/src/db-host/query-state.d.ts +0 -41
  154. package/dist/types/src/db-host/query-state.d.ts.map +0 -1
  155. package/src/db-host/query-state.ts +0 -224
@@ -1,4 +1,8 @@
1
1
  import "@dxos/node-std/globals";
2
+ import {
3
+ filterMatchObject,
4
+ filterMatchValue
5
+ } from "./chunk-TQJTKNMS.mjs";
2
6
  import {
3
7
  AuthExtension,
4
8
  AuthStatus,
@@ -21,7 +25,8 @@ import {
21
25
  mapTimeframeToFeedIndexes,
22
26
  startAfter,
23
27
  valueEncoding
24
- } from "./chunk-TPEBUDNJ.mjs";
28
+ } from "./chunk-3XSXS5EX.mjs";
29
+ import "./chunk-CGS2ULMK.mjs";
25
30
 
26
31
  // packages/core/echo/echo-pipeline/src/db-host/data-service.ts
27
32
  import { UpdateScheduler as UpdateScheduler2 } from "@dxos/async";
@@ -40,11 +45,7 @@ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline
40
45
  var MAX_UPDATE_FREQ = 10;
41
46
  var DocumentsSynchronizer = class extends Resource {
42
47
  constructor(_params) {
43
- super();
44
- this._params = _params;
45
- this._syncStates = /* @__PURE__ */ new Map();
46
- this._pendingUpdates = /* @__PURE__ */ new Set();
47
- this._sendUpdatesJob = void 0;
48
+ super(), this._params = _params, this._syncStates = /* @__PURE__ */ new Map(), this._pendingUpdates = /* @__PURE__ */ new Set(), this._sendUpdatesJob = void 0;
48
49
  }
49
50
  addDocuments(documentIds, retryCounter = 0) {
50
51
  if (retryCounter > 3) {
@@ -202,6 +203,7 @@ import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "
202
203
  import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
203
204
  import { Event as Event2, asyncTimeout } from "@dxos/async";
204
205
  import { Context, Resource as Resource4, cancelWithContext } from "@dxos/context";
206
+ import { DatabaseDirectory } from "@dxos/echo-protocol";
205
207
  import { invariant as invariant3 } from "@dxos/invariant";
206
208
  import { PublicKey } from "@dxos/keys";
207
209
  import { log as log4 } from "@dxos/log";
@@ -484,13 +486,7 @@ function _ts_decorate2(decorators, target, key, desc) {
484
486
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
485
487
  var EchoNetworkAdapter = class extends NetworkAdapter {
486
488
  constructor(_params) {
487
- super();
488
- this._params = _params;
489
- this._replicators = /* @__PURE__ */ new Set();
490
- this._connections = /* @__PURE__ */ new Map();
491
- this._lifecycleState = LifecycleState.CLOSED;
492
- this._connected = new Trigger();
493
- this._ready = new Trigger();
489
+ super(), this._params = _params, this._replicators = /* @__PURE__ */ new Set(), this._connections = /* @__PURE__ */ new Map(), this._lifecycleState = LifecycleState.CLOSED, this._connected = new Trigger(), this._ready = new Trigger();
494
490
  }
495
491
  isReady() {
496
492
  return this._lifecycleState === LifecycleState.OPEN;
@@ -848,8 +844,7 @@ var HeadsStore = class {
848
844
  import { LifecycleState as LifecycleState2, Resource as Resource3 } from "@dxos/context";
849
845
  var LevelDBStorageAdapter = class extends Resource3 {
850
846
  constructor(_params) {
851
- super();
852
- this._params = _params;
847
+ super(), this._params = _params;
853
848
  }
854
849
  async load(keyArray) {
855
850
  try {
@@ -1190,7 +1185,7 @@ var AutomergeHost = class extends Resource4 {
1190
1185
  }
1191
1186
  const heads = getHeads(doc);
1192
1187
  this._headsStore.setHeads(handle.documentId, heads, batch);
1193
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
1188
+ const spaceKey = DatabaseDirectory.getSpaceKey(doc) ?? void 0;
1194
1189
  const objectIds = Object.keys(doc.objects ?? {});
1195
1190
  const encodedIds = objectIds.map((objectId) => objectPointerCodec.encode({
1196
1191
  documentId: handle.documentId,
@@ -1243,7 +1238,7 @@ var AutomergeHost = class extends Resource4 {
1243
1238
  await handle.whenReady();
1244
1239
  }
1245
1240
  if (handle && handle.isReady() && handle.doc()) {
1246
- const spaceKeyHex = getSpaceKeyFromDoc(handle.doc());
1241
+ const spaceKeyHex = DatabaseDirectory.getSpaceKey(handle.doc());
1247
1242
  if (spaceKeyHex) {
1248
1243
  return PublicKey.from(spaceKeyHex);
1249
1244
  }
@@ -1258,7 +1253,10 @@ var AutomergeHost = class extends Resource4 {
1258
1253
  * Flush documents to disk.
1259
1254
  */
1260
1255
  async flush({ documentIds } = {}) {
1261
- const loadedDocuments = documentIds?.filter((documentId) => !!this._repo.handles[documentId]);
1256
+ const loadedDocuments = documentIds?.filter((documentId) => {
1257
+ const handle = this._repo.handles[documentId];
1258
+ return handle && handle.isReady();
1259
+ });
1262
1260
  await this._repo.flush(loadedDocuments);
1263
1261
  }
1264
1262
  async getHeads(documentIds) {
@@ -1373,7 +1371,7 @@ var AutomergeHost = class extends Resource4 {
1373
1371
  count: toReplicate.length
1374
1372
  }, {
1375
1373
  F: __dxlog_file4,
1376
- L: 556,
1374
+ L: 557,
1377
1375
  S: this,
1378
1376
  C: (f, a) => f(...a)
1379
1377
  });
@@ -1415,13 +1413,6 @@ _ts_decorate3([
1415
1413
  AutomergeHost = _ts_decorate3([
1416
1414
  trace2.resource()
1417
1415
  ], AutomergeHost);
1418
- var getSpaceKeyFromDoc = (doc) => {
1419
- const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
1420
- if (rawSpaceKey == null) {
1421
- return null;
1422
- }
1423
- return String(rawSpaceKey);
1424
- };
1425
1416
  var waitForHeads = async (handle, heads) => {
1426
1417
  const unavailableHeads = new Set(heads);
1427
1418
  await handle.whenReady();
@@ -1440,7 +1431,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
1440
1431
  var decodeCollectionState = (state) => {
1441
1432
  invariant3(typeof state === "object" && state !== null, "Invalid state", {
1442
1433
  F: __dxlog_file4,
1443
- L: 617,
1434
+ L: 608,
1444
1435
  S: void 0,
1445
1436
  A: [
1446
1437
  "typeof state === 'object' && state !== null",
@@ -1470,11 +1461,7 @@ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipelin
1470
1461
  var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
1471
1462
  var MeshReplicatorConnection = class extends Resource5 {
1472
1463
  constructor(_params) {
1473
- super();
1474
- this._params = _params;
1475
- this.remoteDeviceKey = null;
1476
- this._remotePeerId = null;
1477
- this._isEnabled = false;
1464
+ super(), this._params = _params, this.remoteDeviceKey = null, this._remotePeerId = null, this._isEnabled = false;
1478
1465
  let readableStreamController;
1479
1466
  this.readable = new ReadableStream({
1480
1467
  start: (controller) => {
@@ -2366,18 +2353,18 @@ var DataServiceImpl = class {
2366
2353
  };
2367
2354
 
2368
2355
  // packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
2369
- import { LifecycleState as LifecycleState4, Resource as Resource9 } from "@dxos/context";
2356
+ import { LifecycleState as LifecycleState5, Resource as Resource9 } from "@dxos/context";
2370
2357
  import { todo } from "@dxos/debug";
2371
- import { createIdFromSpaceKey as createIdFromSpaceKey3, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
2358
+ import { createIdFromSpaceKey as createIdFromSpaceKey2, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
2372
2359
  import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
2373
- import { invariant as invariant11 } from "@dxos/invariant";
2360
+ import { invariant as invariant13 } from "@dxos/invariant";
2374
2361
  import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
2375
- import { trace as trace6 } from "@dxos/tracing";
2362
+ import { trace as trace5 } from "@dxos/tracing";
2376
2363
 
2377
2364
  // packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts
2378
2365
  import * as A3 from "@automerge/automerge";
2379
2366
  import { Context as Context2 } from "@dxos/context";
2380
- import { SpaceDocVersion } from "@dxos/echo-protocol";
2367
+ import { DatabaseDirectory as DatabaseDirectory2, SpaceDocVersion } from "@dxos/echo-protocol";
2381
2368
  import { invariant as invariant8 } from "@dxos/invariant";
2382
2369
  import { log as log8 } from "@dxos/log";
2383
2370
  import { ObjectPointerVersion, objectPointerCodec as objectPointerCodec2 } from "@dxos/protocols";
@@ -2432,7 +2419,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2432
2419
  }
2433
2420
  let newId = id;
2434
2421
  if (objectPointerCodec2.getVersion(id) === ObjectPointerVersion.V0) {
2435
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
2422
+ const spaceKey = DatabaseDirectory2.getSpaceKey(doc) ?? void 0;
2436
2423
  newId = objectPointerCodec2.encode({
2437
2424
  documentId,
2438
2425
  objectId,
@@ -2464,223 +2451,1041 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2464
2451
 
2465
2452
  // packages/core/echo/echo-pipeline/src/db-host/query-service.ts
2466
2453
  import { getHeads as getHeads3 } from "@automerge/automerge";
2454
+ import { Schema } from "effect";
2467
2455
  import { DeferredTask } from "@dxos/async";
2468
2456
  import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
2469
2457
  import { Context as Context4, Resource as Resource7 } from "@dxos/context";
2470
- import { log as log9 } from "@dxos/log";
2458
+ import { raise } from "@dxos/debug";
2459
+ import { DatabaseDirectory as DatabaseDirectory4, QueryAST } from "@dxos/echo-protocol";
2460
+ import { log as log10 } from "@dxos/log";
2471
2461
  import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
2472
- import { trace as trace5 } from "@dxos/tracing";
2462
+ import { trace as trace4 } from "@dxos/tracing";
2473
2463
 
2474
- // packages/core/echo/echo-pipeline/src/db-host/query-state.ts
2475
- import { Context as Context3, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
2476
- import { createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
2477
- import { invariant as invariant9 } from "@dxos/invariant";
2464
+ // packages/core/echo/echo-pipeline/src/query/query-executor.ts
2465
+ import { Match } from "effect";
2466
+ import { Context as Context3, ContextDisposedError, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
2467
+ import { DatabaseDirectory as DatabaseDirectory3, isEncodedReference, ObjectStructure } from "@dxos/echo-protocol";
2468
+ import { EscapedPropPath } from "@dxos/indexing";
2469
+ import { invariant as invariant10 } from "@dxos/invariant";
2478
2470
  import { DXN, PublicKey as PublicKey3 } from "@dxos/keys";
2471
+ import { log as log9 } from "@dxos/log";
2479
2472
  import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
2480
- import { trace as trace4 } from "@dxos/tracing";
2481
- import { isNonNullable as isNonNullable2 } from "@dxos/util";
2482
- function _ts_decorate5(decorators, target, key, desc) {
2483
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2484
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2485
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2486
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2487
- }
2488
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-state.ts";
2489
- var QueryState = class extends Resource6 {
2490
- get active() {
2491
- return this._lifecycleState === LifecycleState3.OPEN;
2473
+ import { getDeep, isNonNullable as isNonNullable2 } from "@dxos/util";
2474
+
2475
+ // packages/core/echo/echo-pipeline/src/query/query-planner.ts
2476
+ import { invariant as invariant9 } from "@dxos/invariant";
2477
+
2478
+ // packages/core/echo/echo-pipeline/src/query/errors.ts
2479
+ import { BaseError } from "@dxos/errors";
2480
+ var QueryError = class extends BaseError.extend("QUERY_ERROR") {
2481
+ };
2482
+
2483
+ // packages/core/echo/echo-pipeline/src/query/plan.ts
2484
+ (function(QueryPlan2) {
2485
+ QueryPlan2.Plan = Object.freeze({
2486
+ make: (steps) => ({
2487
+ steps
2488
+ })
2489
+ });
2490
+ QueryPlan2.FilterStep = Object.freeze({
2491
+ isNoop: (step) => {
2492
+ switch (step.filter.type) {
2493
+ case "object": {
2494
+ return step.filter.typename === null && (step.filter.id === void 0 || step.filter.id.length === 0) && (step.filter.props === void 0 || Object.keys(step.filter.props).length === 0) && (step.filter.foreignKeys === void 0 || step.filter.foreignKeys.length === 0);
2495
+ }
2496
+ default:
2497
+ return false;
2498
+ }
2499
+ }
2500
+ });
2501
+ })(QueryPlan || (QueryPlan = {}));
2502
+ var QueryPlan;
2503
+
2504
+ // packages/core/echo/echo-pipeline/src/query/query-planner.ts
2505
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-planner.ts";
2506
+ var DEFAULT_OPTIONS = {
2507
+ defaultTextSearchKind: "full-text"
2508
+ };
2509
+ var QueryPlanner = class {
2510
+ constructor(options) {
2511
+ this._options = {
2512
+ ...DEFAULT_OPTIONS,
2513
+ ...options
2514
+ };
2492
2515
  }
2493
- constructor(_params) {
2494
- super();
2495
- this._params = _params;
2496
- this._results = [];
2497
- this._firstRun = true;
2498
- this.metrics = {
2499
- objectsReturned: 0,
2500
- objectsReturnedFromIndex: 0,
2501
- documentsLoaded: 0,
2502
- executionTime: 0,
2503
- indexQueryTime: 0,
2504
- documentLoadTime: 0
2516
+ createPlan(query) {
2517
+ let plan = this._generate(query, {
2518
+ ...DEFAULT_CONTEXT,
2519
+ originalQuery: query
2520
+ });
2521
+ plan = this._optimizeEmptyFilters(plan);
2522
+ plan = this._optimizeSoloUnions(plan);
2523
+ return plan;
2524
+ }
2525
+ _generate(query, context) {
2526
+ switch (query.type) {
2527
+ case "options":
2528
+ return this._generateOptionsClause(query, context);
2529
+ case "select":
2530
+ return this._generateSelectClause(query, context);
2531
+ case "filter":
2532
+ return this._generateFilterClause(query, context);
2533
+ case "incoming-references":
2534
+ return this._generateIncomingReferencesClause(query, context);
2535
+ case "relation":
2536
+ return this._generateRelationClause(query, context);
2537
+ case "relation-traversal":
2538
+ return this._generateRelationTraversalClause(query, context);
2539
+ case "reference-traversal":
2540
+ return this._generateReferenceTraversalClause(query, context);
2541
+ case "union":
2542
+ return this._generateUnionClause(query, context);
2543
+ default:
2544
+ throw new QueryError(`Unsupported query type: ${query.type}`, {
2545
+ context: {
2546
+ query: context.originalQuery
2547
+ }
2548
+ });
2549
+ }
2550
+ }
2551
+ _generateOptionsClause(query, context) {
2552
+ const newContext = {
2553
+ ...context
2505
2554
  };
2506
- this.filter = _params.request.filter;
2555
+ if (query.options.spaceIds) {
2556
+ newContext.selectionSpaces = query.options.spaceIds;
2557
+ }
2558
+ if (query.options.deleted) {
2559
+ newContext.deletedHandling = query.options.deleted;
2560
+ }
2561
+ return this._generate(query.query, newContext);
2562
+ }
2563
+ _generateSelectClause(query, context) {
2564
+ return this._generateSelectionFromFilter(query.filter, context);
2565
+ }
2566
+ // TODO(dmaretskyi): This can be rewritten as a function of (filter[]) -> (selection ? undefined, rest: filter[]) that recurses onto itself.
2567
+ // TODO(dmaretskyi): If the tip of the query ast is a [select, ...filter] shape we can reorder the filters so the query is most efficient.
2568
+ _generateSelectionFromFilter(filter, context) {
2569
+ switch (filter.type) {
2570
+ case "object": {
2571
+ if (context.selectionInverted && filter.id === void 0 && filter.typename === null && Object.keys(filter.props).length === 0) {
2572
+ return QueryPlan.Plan.make([
2573
+ {
2574
+ _tag: "ClearWorkingSetStep"
2575
+ },
2576
+ ...this._generateDeletedHandlingSteps(context)
2577
+ ]);
2578
+ }
2579
+ if (context.selectionInverted) {
2580
+ throw new QueryError("Query too complex", {
2581
+ context: {
2582
+ query: context.originalQuery
2583
+ }
2584
+ });
2585
+ }
2586
+ if (filter.id && filter.id?.length > 0) {
2587
+ return QueryPlan.Plan.make([
2588
+ {
2589
+ _tag: "SelectStep",
2590
+ spaces: context.selectionSpaces,
2591
+ selector: {
2592
+ _tag: "IdSelector",
2593
+ objectIds: filter.id
2594
+ }
2595
+ },
2596
+ ...this._generateDeletedHandlingSteps(context),
2597
+ {
2598
+ _tag: "FilterStep",
2599
+ filter: {
2600
+ ...filter,
2601
+ id: void 0
2602
+ }
2603
+ }
2604
+ ]);
2605
+ } else if (filter.typename) {
2606
+ return QueryPlan.Plan.make([
2607
+ {
2608
+ _tag: "SelectStep",
2609
+ spaces: context.selectionSpaces,
2610
+ selector: {
2611
+ _tag: "TypeSelector",
2612
+ typename: [
2613
+ filter.typename
2614
+ ],
2615
+ inverted: false
2616
+ }
2617
+ },
2618
+ ...this._generateDeletedHandlingSteps(context),
2619
+ {
2620
+ _tag: "FilterStep",
2621
+ filter: {
2622
+ ...filter,
2623
+ typename: null
2624
+ }
2625
+ }
2626
+ ]);
2627
+ } else {
2628
+ return QueryPlan.Plan.make([
2629
+ {
2630
+ _tag: "SelectStep",
2631
+ spaces: context.selectionSpaces,
2632
+ selector: {
2633
+ _tag: "WildcardSelector"
2634
+ }
2635
+ },
2636
+ ...this._generateDeletedHandlingSteps(context),
2637
+ {
2638
+ _tag: "FilterStep",
2639
+ filter: {
2640
+ ...filter
2641
+ }
2642
+ }
2643
+ ]);
2644
+ }
2645
+ }
2646
+ case "text-search": {
2647
+ return QueryPlan.Plan.make([
2648
+ {
2649
+ _tag: "SelectStep",
2650
+ spaces: context.selectionSpaces,
2651
+ selector: {
2652
+ _tag: "TextSelector",
2653
+ text: filter.text,
2654
+ searchKind: filter.searchKind ?? this._options.defaultTextSearchKind
2655
+ }
2656
+ },
2657
+ ...this._generateDeletedHandlingSteps(context)
2658
+ ]);
2659
+ }
2660
+ case "compare":
2661
+ throw new QueryError("Query too complex", {
2662
+ context: {
2663
+ query: context.originalQuery
2664
+ }
2665
+ });
2666
+ case "in":
2667
+ throw new QueryError("Query too complex", {
2668
+ context: {
2669
+ query: context.originalQuery
2670
+ }
2671
+ });
2672
+ case "range":
2673
+ throw new QueryError("Query too complex", {
2674
+ context: {
2675
+ query: context.originalQuery
2676
+ }
2677
+ });
2678
+ case "not":
2679
+ return this._generateSelectionFromFilter(filter.filter, {
2680
+ ...context,
2681
+ selectionInverted: !context.selectionInverted
2682
+ });
2683
+ case "and":
2684
+ throw new QueryError("Query too complex", {
2685
+ context: {
2686
+ query: context.originalQuery
2687
+ }
2688
+ });
2689
+ case "or":
2690
+ if (filter.filters.every(isTrivialTypenameFilter)) {
2691
+ const typenames = filter.filters.map((f) => {
2692
+ invariant9(f.type === "object" && f.typename !== null, void 0, {
2693
+ F: __dxlog_file10,
2694
+ L: 189,
2695
+ S: this,
2696
+ A: [
2697
+ "f.type === 'object' && f.typename !== null",
2698
+ ""
2699
+ ]
2700
+ });
2701
+ return f.typename;
2702
+ });
2703
+ return QueryPlan.Plan.make([
2704
+ {
2705
+ _tag: "SelectStep",
2706
+ spaces: context.selectionSpaces,
2707
+ selector: {
2708
+ _tag: "TypeSelector",
2709
+ typename: typenames,
2710
+ inverted: context.selectionInverted
2711
+ }
2712
+ },
2713
+ ...this._generateDeletedHandlingSteps(context)
2714
+ ]);
2715
+ } else {
2716
+ throw new QueryError("Query too complex", {
2717
+ context: {
2718
+ query: context.originalQuery
2719
+ }
2720
+ });
2721
+ }
2722
+ default:
2723
+ throw new QueryError(`Unsupported filter type: ${filter.type}`, {
2724
+ context: {
2725
+ query: context.originalQuery
2726
+ }
2727
+ });
2728
+ }
2507
2729
  }
2508
- getResults() {
2509
- return this._results;
2730
+ _generateDeletedHandlingSteps(context) {
2731
+ switch (context.deletedHandling) {
2732
+ case "include":
2733
+ return [];
2734
+ case "exclude":
2735
+ return [
2736
+ {
2737
+ _tag: "FilterDeletedStep",
2738
+ mode: "only-non-deleted"
2739
+ }
2740
+ ];
2741
+ case "only":
2742
+ return [
2743
+ {
2744
+ _tag: "FilterDeletedStep",
2745
+ mode: "only-deleted"
2746
+ }
2747
+ ];
2748
+ }
2510
2749
  }
2511
- // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/db.md#generic-database-attributes
2512
- async execQuery() {
2513
- const filter = this._params.request.filter;
2514
- const beginQuery = performance.now();
2515
- const hits = filter.objectIds && filter.objectIds?.length > 0 ? [] : await this._params.indexer.execQuery(filterToIndexQuery(filter));
2516
- if (this._firstRun) {
2517
- this.metrics.indexQueryTime = performance.now() - beginQuery;
2518
- }
2519
- const beginFilter = performance.now();
2520
- const results = (await Promise.all(hits.map(async (result) => {
2521
- if (this._firstRun) {
2522
- this.metrics.objectsReturnedFromIndex++;
2523
- }
2524
- const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(result.id);
2525
- let spaceKey;
2526
- if (spaceKeyInIndex !== void 0) {
2527
- spaceKey = spaceKeyInIndex;
2528
- } else {
2529
- if (this._firstRun) {
2530
- this.metrics.documentsLoaded++;
2750
+ _generateUnionClause(query, context) {
2751
+ return QueryPlan.Plan.make([
2752
+ {
2753
+ _tag: "UnionStep",
2754
+ plans: query.queries.map((query2) => this._generate(query2, context))
2755
+ }
2756
+ ]);
2757
+ }
2758
+ _generateReferenceTraversalClause(query, context) {
2759
+ return QueryPlan.Plan.make([
2760
+ ...this._generate(query.anchor, context).steps,
2761
+ {
2762
+ _tag: "TraverseStep",
2763
+ traversal: {
2764
+ _tag: "ReferenceTraversal",
2765
+ direction: "outgoing",
2766
+ property: query.property
2531
2767
  }
2532
- const handle = await this._params.automergeHost.loadDoc(Context3.default(void 0, {
2533
- F: __dxlog_file10,
2534
- L: 118
2535
- }), documentId);
2536
- if (this._ctx.disposed) {
2537
- return;
2768
+ },
2769
+ ...this._generateDeletedHandlingSteps(context)
2770
+ ]);
2771
+ }
2772
+ _generateIncomingReferencesClause(query, context) {
2773
+ return QueryPlan.Plan.make([
2774
+ ...this._generate(query.anchor, context).steps,
2775
+ {
2776
+ _tag: "TraverseStep",
2777
+ traversal: {
2778
+ _tag: "ReferenceTraversal",
2779
+ direction: "incoming",
2780
+ property: query.property
2781
+ }
2782
+ },
2783
+ ...this._generateDeletedHandlingSteps(context),
2784
+ {
2785
+ _tag: "FilterStep",
2786
+ filter: {
2787
+ type: "object",
2788
+ typename: query.typename,
2789
+ props: {}
2538
2790
  }
2539
- spaceKey = getSpaceKeyFromDoc(handle.doc());
2540
2791
  }
2541
- if (!spaceKey) {
2542
- return;
2792
+ ]);
2793
+ }
2794
+ _generateRelationTraversalClause(query, context) {
2795
+ switch (query.direction) {
2796
+ case "source": {
2797
+ return QueryPlan.Plan.make([
2798
+ ...this._generate(query.anchor, context).steps,
2799
+ createRelationTraversalStep("relation-to-source"),
2800
+ ...this._generateDeletedHandlingSteps(context)
2801
+ ]);
2543
2802
  }
2544
- if (this._params.request.filter.options?.spaces?.length && !this._params.request.filter.options.spaces.some((key) => key.equals(spaceKey))) {
2545
- return;
2803
+ case "target": {
2804
+ return QueryPlan.Plan.make([
2805
+ ...this._generate(query.anchor, context).steps,
2806
+ createRelationTraversalStep("relation-to-target"),
2807
+ ...this._generateDeletedHandlingSteps(context)
2808
+ ]);
2546
2809
  }
2547
- const spaceId = await createIdFromSpaceKey2(PublicKey3.from(spaceKey));
2548
- if (this._params.request.filter.options?.spaceIds?.length && !this._params.request.filter.options.spaceIds.includes(spaceId)) {
2549
- return;
2810
+ case "both": {
2811
+ const anchorPlan = this._generate(query.anchor, context);
2812
+ return QueryPlan.Plan.make([
2813
+ ...anchorPlan.steps,
2814
+ {
2815
+ _tag: "UnionStep",
2816
+ plans: [
2817
+ QueryPlan.Plan.make([
2818
+ createRelationTraversalStep("relation-to-source")
2819
+ ]),
2820
+ QueryPlan.Plan.make([
2821
+ createRelationTraversalStep("relation-to-target")
2822
+ ])
2823
+ ]
2824
+ },
2825
+ ...this._generateDeletedHandlingSteps(context)
2826
+ ]);
2550
2827
  }
2551
- if (this._firstRun) {
2552
- this.metrics.objectsReturned++;
2828
+ }
2829
+ }
2830
+ _generateRelationClause(query, context) {
2831
+ switch (query.direction) {
2832
+ case "outgoing": {
2833
+ return QueryPlan.Plan.make([
2834
+ ...this._generate(query.anchor, context).steps,
2835
+ createRelationTraversalStep("source-to-relation"),
2836
+ ...this._generateDeletedHandlingSteps(context),
2837
+ {
2838
+ _tag: "FilterStep",
2839
+ filter: query.filter ?? NOOP_FILTER
2840
+ }
2841
+ ]);
2842
+ }
2843
+ case "incoming": {
2844
+ return QueryPlan.Plan.make([
2845
+ ...this._generate(query.anchor, context).steps,
2846
+ createRelationTraversalStep("target-to-relation"),
2847
+ ...this._generateDeletedHandlingSteps(context),
2848
+ {
2849
+ _tag: "FilterStep",
2850
+ filter: query.filter ?? NOOP_FILTER
2851
+ }
2852
+ ]);
2853
+ }
2854
+ case "both": {
2855
+ const anchorPlan = this._generate(query.anchor, context);
2856
+ return QueryPlan.Plan.make([
2857
+ ...anchorPlan.steps,
2858
+ {
2859
+ _tag: "UnionStep",
2860
+ plans: [
2861
+ QueryPlan.Plan.make([
2862
+ createRelationTraversalStep("source-to-relation")
2863
+ ]),
2864
+ QueryPlan.Plan.make([
2865
+ createRelationTraversalStep("target-to-relation")
2866
+ ])
2867
+ ]
2868
+ },
2869
+ ...this._generateDeletedHandlingSteps(context),
2870
+ {
2871
+ _tag: "FilterStep",
2872
+ filter: query.filter ?? NOOP_FILTER
2873
+ }
2874
+ ]);
2553
2875
  }
2554
- return {
2555
- id: objectId,
2556
- documentId,
2557
- spaceId,
2558
- spaceKey: PublicKey3.from(spaceKey),
2559
- rank: result.rank
2560
- };
2561
- }))).filter(isNonNullable2);
2562
- if (this._firstRun) {
2563
- this.metrics.documentLoadTime = performance.now() - beginFilter;
2564
2876
  }
2877
+ }
2878
+ _generateFilterClause(query, context) {
2879
+ return QueryPlan.Plan.make([
2880
+ ...this._generate(query.selection, context).steps,
2881
+ {
2882
+ _tag: "FilterStep",
2883
+ filter: query.filter
2884
+ }
2885
+ ]);
2886
+ }
2887
+ /**
2888
+ * Removes filter steps that have no predicates.
2889
+ */
2890
+ _optimizeEmptyFilters(plan) {
2891
+ return QueryPlan.Plan.make(plan.steps.filter((step) => {
2892
+ if (step._tag === "FilterStep") {
2893
+ return !QueryPlan.FilterStep.isNoop(step);
2894
+ } else {
2895
+ return true;
2896
+ }
2897
+ }).map((step) => {
2898
+ if (step._tag === "UnionStep") {
2899
+ return {
2900
+ _tag: "UnionStep",
2901
+ plans: step.plans.map((plan2) => this._optimizeEmptyFilters(plan2))
2902
+ };
2903
+ } else {
2904
+ return step;
2905
+ }
2906
+ }));
2907
+ }
2908
+ /**
2909
+ * Removes union steps that have only one child.
2910
+ */
2911
+ _optimizeSoloUnions(plan) {
2912
+ return plan;
2913
+ }
2914
+ };
2915
+ var DEFAULT_CONTEXT = {
2916
+ originalQuery: null,
2917
+ selectionSpaces: [],
2918
+ deletedHandling: "exclude",
2919
+ selectionInverted: false
2920
+ };
2921
+ var NOOP_FILTER = {
2922
+ type: "object",
2923
+ typename: null,
2924
+ id: [],
2925
+ props: {}
2926
+ };
2927
+ var createRelationTraversalStep = (direction) => ({
2928
+ _tag: "TraverseStep",
2929
+ traversal: {
2930
+ _tag: "RelationTraversal",
2931
+ direction
2932
+ }
2933
+ });
2934
+ var isTrivialTypenameFilter = (filter) => {
2935
+ return filter.type === "object" && filter.typename !== null && Object.keys(filter.props).length === 0 && (filter.id === void 0 || filter.id.length === 0) && (filter.foreignKeys === void 0 || filter.foreignKeys.length === 0);
2936
+ };
2937
+
2938
+ // packages/core/echo/echo-pipeline/src/query/query-executor.ts
2939
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-executor.ts";
2940
+ var ExecutionTrace = Object.freeze({
2941
+ makeEmpty: () => ({
2942
+ name: "Empty",
2943
+ details: "",
2944
+ objectCount: 0,
2945
+ documentsLoaded: 0,
2946
+ indexHits: 0,
2947
+ indexQueryTime: 0,
2948
+ documentLoadTime: 0,
2949
+ executionTime: 0,
2950
+ children: []
2951
+ }),
2952
+ format: (trace6) => {
2953
+ const go = (trace7, indent) => {
2954
+ return [
2955
+ `${" ".repeat(indent)} - ${trace7.name}(${trace7.details})`,
2956
+ `${" ".repeat(indent)} objects: ${trace7.objectCount} docs: ${trace7.documentsLoaded} index hits: ${trace7.indexHits} | total: ${trace7.executionTime.toFixed(0)}ms index: ${trace7.indexQueryTime.toFixed(0)}ms load: ${trace7.documentLoadTime.toFixed(0)}ms`,
2957
+ "",
2958
+ ...trace7.children.map((child) => go(child, indent + 2))
2959
+ ].join("\n");
2960
+ };
2961
+ return go(trace6, 0);
2962
+ }
2963
+ });
2964
+ var QueryExecutor = class extends Resource6 {
2965
+ constructor(options) {
2966
+ super();
2967
+ this._trace = ExecutionTrace.makeEmpty();
2968
+ this._lastResultSet = [];
2969
+ this._indexer = options.indexer;
2970
+ this._automergeHost = options.automergeHost;
2971
+ this._spaceStateManager = options.spaceStateManager;
2972
+ this._id = options.queryId;
2973
+ this._query = options.query;
2974
+ this._reactivity = options.reactivity;
2975
+ const queryPlanner = new QueryPlanner();
2976
+ this._plan = queryPlanner.createPlan(this._query);
2977
+ }
2978
+ get query() {
2979
+ return this._query;
2980
+ }
2981
+ get plan() {
2982
+ return this._plan;
2983
+ }
2984
+ get trace() {
2985
+ return this._trace;
2986
+ }
2987
+ async _open(ctx) {
2988
+ }
2989
+ async _close(ctx) {
2990
+ }
2991
+ getResults() {
2992
+ return this._lastResultSet.map((item) => ({
2993
+ id: item.objectId,
2994
+ documentId: item.documentId,
2995
+ spaceId: item.spaceId,
2996
+ // TODO(dmaretskyi): Plumb through the rank.
2997
+ rank: 0
2998
+ }));
2999
+ }
3000
+ async execQuery() {
3001
+ invariant10(this._lifecycleState === LifecycleState3.OPEN, void 0, {
3002
+ F: __dxlog_file11,
3003
+ L: 171,
3004
+ S: this,
3005
+ A: [
3006
+ "this._lifecycleState === LifecycleState.OPEN",
3007
+ ""
3008
+ ]
3009
+ });
3010
+ const prevResultSet = this._lastResultSet;
3011
+ const { workingSet, trace: trace6 } = await this._execPlan(this._plan, this._lastResultSet);
3012
+ this._lastResultSet = workingSet;
3013
+ trace6.name = "Root";
3014
+ trace6.details = JSON.stringify({
3015
+ id: this._id
3016
+ });
3017
+ this._trace = trace6;
3018
+ const changed = prevResultSet.length !== workingSet.length || prevResultSet.some((item, index) => workingSet[index].objectId !== item.objectId || workingSet[index].spaceId !== item.spaceId || workingSet[index].documentId !== item.documentId);
3019
+ return {
3020
+ changed
3021
+ };
3022
+ }
3023
+ async _execPlan(plan, workingSet) {
3024
+ const trace6 = ExecutionTrace.makeEmpty();
3025
+ for (const step of plan.steps) {
3026
+ if (this._ctx.disposed) {
3027
+ throw new ContextDisposedError();
3028
+ }
3029
+ const result = await this._execStep(step, workingSet);
3030
+ workingSet = result.workingSet;
3031
+ trace6.children.push(result.trace);
3032
+ }
3033
+ return {
3034
+ workingSet,
3035
+ trace: trace6
3036
+ };
3037
+ }
3038
+ async _execStep(step, workingSet) {
2565
3039
  if (this._ctx.disposed) {
2566
3040
  return {
2567
- changed: false
3041
+ workingSet,
3042
+ trace: ExecutionTrace.makeEmpty()
2568
3043
  };
2569
3044
  }
2570
- const areResultsUnchanged = !this._firstRun && this._results.length === results.length && this._results.every((oldResult) => results.some((result) => result.id === oldResult.id)) && results.every((result) => this._results.some((oldResult) => oldResult.id === result.id));
2571
- if (this._firstRun) {
2572
- this.metrics.executionTime = performance.now() - beginQuery;
3045
+ let newWorkingSet, trace6;
3046
+ const begin = performance.now();
3047
+ switch (step._tag) {
3048
+ case "ClearWorkingSetStep":
3049
+ newWorkingSet = [];
3050
+ trace6 = ExecutionTrace.makeEmpty();
3051
+ break;
3052
+ case "SelectStep":
3053
+ ({ workingSet: newWorkingSet, trace: trace6 } = await this._execSelectStep(step, workingSet));
3054
+ break;
3055
+ case "FilterStep":
3056
+ ({ workingSet: newWorkingSet, trace: trace6 } = await this._execFilterStep(step, workingSet));
3057
+ break;
3058
+ case "FilterDeletedStep":
3059
+ ({ workingSet: newWorkingSet, trace: trace6 } = await this._execFilterDeletedStep(step, workingSet));
3060
+ break;
3061
+ case "UnionStep":
3062
+ ({ workingSet: newWorkingSet, trace: trace6 } = await this._execUnionStep(step, workingSet));
3063
+ break;
3064
+ case "TraverseStep":
3065
+ ({ workingSet: newWorkingSet, trace: trace6 } = await this._execTraverseStep(step, workingSet));
3066
+ break;
3067
+ default:
3068
+ throw new Error(`Unknown step type: ${step._tag}`);
2573
3069
  }
2574
- this._firstRun = false;
2575
- if (areResultsUnchanged) {
2576
- return {
2577
- changed: false
2578
- };
3070
+ trace6.executionTime = performance.now() - begin;
3071
+ return {
3072
+ workingSet: newWorkingSet,
3073
+ trace: trace6
3074
+ };
3075
+ }
3076
+ async _execSelectStep(step, workingSet) {
3077
+ workingSet = [
3078
+ ...workingSet
3079
+ ];
3080
+ const trace6 = {
3081
+ ...ExecutionTrace.makeEmpty(),
3082
+ name: "Select",
3083
+ details: JSON.stringify(step.selector)
3084
+ };
3085
+ switch (step.selector._tag) {
3086
+ case "WildcardSelector": {
3087
+ const beginIndexQuery = performance.now();
3088
+ const indexHits = await this._indexer.execQuery({
3089
+ typenames: [],
3090
+ inverted: false
3091
+ });
3092
+ trace6.indexHits = +indexHits.length;
3093
+ trace6.indexQueryTime += performance.now() - beginIndexQuery;
3094
+ if (this._ctx.disposed) {
3095
+ return {
3096
+ workingSet,
3097
+ trace: trace6
3098
+ };
3099
+ }
3100
+ const documentLoadStart = performance.now();
3101
+ const results = await this._loadDocumentsAfterIndexQuery(indexHits);
3102
+ trace6.documentsLoaded += results.length;
3103
+ trace6.documentLoadTime += performance.now() - documentLoadStart;
3104
+ workingSet.push(...results.filter(isNonNullable2).filter((item) => step.spaces.includes(item.spaceId)));
3105
+ trace6.objectCount = workingSet.length;
3106
+ break;
3107
+ }
3108
+ case "IdSelector": {
3109
+ const beginLoad = performance.now();
3110
+ const items = await Promise.all(step.selector.objectIds.map((id) => this._loadFromDXN(DXN.fromLocalObjectId(id), {
3111
+ sourceSpaceId: step.spaces[0]
3112
+ })));
3113
+ trace6.documentLoadTime += performance.now() - beginLoad;
3114
+ workingSet.push(...items.filter(isNonNullable2));
3115
+ trace6.objectCount = workingSet.length;
3116
+ break;
3117
+ }
3118
+ case "TypeSelector": {
3119
+ const beginIndexQuery = performance.now();
3120
+ const indexHits = await this._indexer.execQuery({
3121
+ typenames: step.selector.typename,
3122
+ inverted: step.selector.inverted
3123
+ });
3124
+ trace6.indexHits = +indexHits.length;
3125
+ trace6.indexQueryTime += performance.now() - beginIndexQuery;
3126
+ if (this._ctx.disposed) {
3127
+ return {
3128
+ workingSet,
3129
+ trace: trace6
3130
+ };
3131
+ }
3132
+ const documentLoadStart = performance.now();
3133
+ const results = await this._loadDocumentsAfterIndexQuery(indexHits);
3134
+ trace6.documentsLoaded += results.length;
3135
+ trace6.documentLoadTime += performance.now() - documentLoadStart;
3136
+ workingSet.push(...results.filter(isNonNullable2).filter((item) => step.spaces.includes(item.spaceId)));
3137
+ trace6.objectCount = workingSet.length;
3138
+ break;
3139
+ }
3140
+ case "TextSelector": {
3141
+ const beginIndexQuery = performance.now();
3142
+ const indexHits = await this._indexer.execQuery({
3143
+ typenames: [],
3144
+ text: {
3145
+ query: step.selector.text,
3146
+ kind: Match.type().pipe(Match.withReturnType(), Match.when("full-text", () => "text"), Match.when("vector", () => "vector"), Match.orElseAbsurd)(step.selector.searchKind)
3147
+ }
3148
+ });
3149
+ trace6.indexHits = +indexHits.length;
3150
+ trace6.indexQueryTime += performance.now() - beginIndexQuery;
3151
+ if (this._ctx.disposed) {
3152
+ return {
3153
+ workingSet,
3154
+ trace: trace6
3155
+ };
3156
+ }
3157
+ const documentLoadStart = performance.now();
3158
+ const results = await this._loadDocumentsAfterIndexQuery(indexHits);
3159
+ trace6.documentsLoaded += results.length;
3160
+ trace6.documentLoadTime += performance.now() - documentLoadStart;
3161
+ workingSet.push(...results.filter(isNonNullable2).filter((item) => step.spaces.includes(item.spaceId)));
3162
+ trace6.objectCount = workingSet.length;
3163
+ break;
3164
+ }
3165
+ default:
3166
+ throw new Error(`Unknown selector type: ${step.selector._tag}`);
2579
3167
  }
2580
- this._results = results;
2581
3168
  return {
2582
- changed: true
3169
+ workingSet,
3170
+ trace: trace6
2583
3171
  };
2584
3172
  }
2585
- };
2586
- _ts_decorate5([
2587
- trace4.info({
2588
- depth: null
2589
- })
2590
- ], QueryState.prototype, "filter", void 0);
2591
- _ts_decorate5([
2592
- trace4.info()
2593
- ], QueryState.prototype, "metrics", void 0);
2594
- _ts_decorate5([
2595
- trace4.info()
2596
- ], QueryState.prototype, "active", null);
2597
- _ts_decorate5([
2598
- trace4.span({
2599
- showInBrowserTimeline: true,
2600
- op: "db.query",
2601
- attributes: {
2602
- "db.system": "echo"
3173
+ async _execFilterStep(step, workingSet) {
3174
+ const result = workingSet.filter((item) => filterMatchObject(step.filter, {
3175
+ id: item.objectId,
3176
+ spaceId: item.spaceId,
3177
+ doc: item.doc
3178
+ }));
3179
+ return {
3180
+ workingSet: result,
3181
+ trace: {
3182
+ ...ExecutionTrace.makeEmpty(),
3183
+ name: "Filter",
3184
+ details: JSON.stringify(step.filter),
3185
+ objectCount: result.length
3186
+ }
3187
+ };
3188
+ }
3189
+ async _execFilterDeletedStep(step, workingSet) {
3190
+ const expected = step.mode === "only-deleted";
3191
+ const result = workingSet.filter((item) => ObjectStructure.isDeleted(item.doc) === expected);
3192
+ return {
3193
+ workingSet: result,
3194
+ trace: {
3195
+ ...ExecutionTrace.makeEmpty(),
3196
+ name: "FilterDeleted",
3197
+ details: step.mode,
3198
+ objectCount: result.length
3199
+ }
3200
+ };
3201
+ }
3202
+ // TODO(dmaretskyi): This needs to be completed.
3203
+ async _execTraverseStep(step, workingSet) {
3204
+ const trace6 = {
3205
+ ...ExecutionTrace.makeEmpty(),
3206
+ name: "Traverse",
3207
+ details: JSON.stringify(step.traversal)
3208
+ };
3209
+ const newWorkingSet = [];
3210
+ switch (step.traversal._tag) {
3211
+ case "ReferenceTraversal": {
3212
+ switch (step.traversal.direction) {
3213
+ case "outgoing": {
3214
+ const property = EscapedPropPath.unescape(step.traversal.property);
3215
+ const refs = workingSet.map((item) => {
3216
+ const ref = getDeep(item.doc.data, property);
3217
+ if (!isEncodedReference(ref)) {
3218
+ return null;
3219
+ }
3220
+ try {
3221
+ return {
3222
+ ref: DXN.parse(ref["/"]),
3223
+ spaceId: item.spaceId
3224
+ };
3225
+ } catch {
3226
+ log9.warn("Invalid reference", {
3227
+ ref: ref["/"]
3228
+ }, {
3229
+ F: __dxlog_file11,
3230
+ L: 421,
3231
+ S: this,
3232
+ C: (f, a) => f(...a)
3233
+ });
3234
+ return null;
3235
+ }
3236
+ }).filter(isNonNullable2);
3237
+ const beginLoad = performance.now();
3238
+ const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
3239
+ sourceSpaceId: spaceId
3240
+ })));
3241
+ trace6.documentLoadTime += performance.now() - beginLoad;
3242
+ newWorkingSet.push(...items.filter(isNonNullable2));
3243
+ trace6.objectCount = newWorkingSet.length;
3244
+ break;
3245
+ }
3246
+ case "incoming": {
3247
+ const indexHits = await this._indexer.execQuery({
3248
+ typenames: [],
3249
+ inverted: false,
3250
+ graph: {
3251
+ kind: "inbound-reference",
3252
+ property: step.traversal.property,
3253
+ anchors: workingSet.map((item) => item.objectId)
3254
+ }
3255
+ });
3256
+ trace6.indexHits += indexHits.length;
3257
+ const documentLoadStart = performance.now();
3258
+ const results = await this._loadDocumentsAfterIndexQuery(indexHits);
3259
+ trace6.documentsLoaded += results.length;
3260
+ trace6.documentLoadTime += performance.now() - documentLoadStart;
3261
+ newWorkingSet.push(...results.filter(isNonNullable2));
3262
+ trace6.objectCount = newWorkingSet.length;
3263
+ break;
3264
+ }
3265
+ }
3266
+ break;
3267
+ }
3268
+ case "RelationTraversal": {
3269
+ switch (step.traversal.direction) {
3270
+ case "relation-to-source":
3271
+ case "relation-to-target": {
3272
+ const refs = workingSet.map((item) => {
3273
+ const ref = step.traversal.direction === "relation-to-source" ? ObjectStructure.getRelationSource(item.doc) : ObjectStructure.getRelationTarget(item.doc);
3274
+ if (!isEncodedReference(ref)) {
3275
+ return null;
3276
+ }
3277
+ try {
3278
+ return {
3279
+ ref: DXN.parse(ref["/"]),
3280
+ spaceId: item.spaceId
3281
+ };
3282
+ } catch {
3283
+ log9.warn("Invalid reference", {
3284
+ ref: ref["/"]
3285
+ }, {
3286
+ F: __dxlog_file11,
3287
+ L: 483,
3288
+ S: this,
3289
+ C: (f, a) => f(...a)
3290
+ });
3291
+ return null;
3292
+ }
3293
+ }).filter(isNonNullable2);
3294
+ const beginLoad = performance.now();
3295
+ const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
3296
+ sourceSpaceId: spaceId
3297
+ })));
3298
+ trace6.documentLoadTime += performance.now() - beginLoad;
3299
+ newWorkingSet.push(...items.filter(isNonNullable2));
3300
+ trace6.objectCount = newWorkingSet.length;
3301
+ break;
3302
+ }
3303
+ case "source-to-relation":
3304
+ case "target-to-relation": {
3305
+ const indexHits = await this._indexer.execQuery({
3306
+ typenames: [],
3307
+ inverted: false,
3308
+ graph: {
3309
+ kind: step.traversal.direction === "source-to-relation" ? "relation-source" : "relation-target",
3310
+ anchors: workingSet.map((item) => item.objectId),
3311
+ property: null
3312
+ }
3313
+ });
3314
+ trace6.indexHits += indexHits.length;
3315
+ const documentLoadStart = performance.now();
3316
+ const results = await this._loadDocumentsAfterIndexQuery(indexHits);
3317
+ trace6.documentsLoaded += results.length;
3318
+ trace6.documentLoadTime += performance.now() - documentLoadStart;
3319
+ newWorkingSet.push(...results.filter(isNonNullable2));
3320
+ trace6.objectCount = newWorkingSet.length;
3321
+ break;
3322
+ }
3323
+ }
3324
+ break;
3325
+ }
3326
+ default:
3327
+ throw new Error(`Unknown traversal type: ${step.traversal._tag}`);
2603
3328
  }
2604
- })
2605
- ], QueryState.prototype, "execQuery", null);
2606
- QueryState = _ts_decorate5([
2607
- trace4.resource()
2608
- ], QueryState);
2609
- var filterToIndexQuery = (filter) => {
2610
- const { type = [], or = [] } = filter;
2611
- invariant9(!(type.length > 0 && or.length > 0), "Cannot mix type and or filters.", {
2612
- F: __dxlog_file10,
2613
- L: 194,
2614
- S: void 0,
2615
- A: [
2616
- "!(type.length > 0 && or.length > 0)",
2617
- "'Cannot mix type and or filters.'"
2618
- ]
2619
- });
2620
- invariant9(or.every((subFilter) => !((subFilter.type ?? []).length > 0 && (subFilter.or ?? []).length > 0)), "Cannot mix type and or filters.", {
2621
- F: __dxlog_file10,
2622
- L: 195,
2623
- S: void 0,
2624
- A: [
2625
- "or.every((subFilter) => !((subFilter.type ?? []).length > 0 && (subFilter.or ?? []).length > 0))",
2626
- "'Cannot mix type and or filters.'"
2627
- ]
2628
- });
2629
- if (type.length > 0 || or.length > 0 && (or ?? []).every((subFilter) => !subFilter.not && subFilter.type)) {
2630
3329
  return {
2631
- typenames: type.length > 0 ? type.map((type2) => dxnToIndexerTypename(DXN.parse(type2))) : or.flatMap((f) => (f.type ?? []).map((type2) => dxnToIndexerTypename(DXN.parse(type2))) ?? []).filter(isNonNullable2),
2632
- inverted: filter.not
3330
+ workingSet: newWorkingSet,
3331
+ trace: trace6
3332
+ };
3333
+ }
3334
+ async _execUnionStep(step, workingSet) {
3335
+ const results = /* @__PURE__ */ new Map();
3336
+ const resultSets = await Promise.all(step.plans.map((plan) => this._execPlan(plan, [
3337
+ ...workingSet
3338
+ ])));
3339
+ const trace6 = {
3340
+ ...ExecutionTrace.makeEmpty(),
3341
+ name: "Union"
2633
3342
  };
2634
- } else {
3343
+ for (const resultSet of resultSets) {
3344
+ for (const item of resultSet.workingSet) {
3345
+ results.set(`${item.spaceId}:${item.documentId}:${item.objectId}`, item);
3346
+ }
3347
+ trace6.children.push(resultSet.trace);
3348
+ }
2635
3349
  return {
2636
- typenames: []
3350
+ workingSet: [
3351
+ ...results.values()
3352
+ ],
3353
+ trace: trace6
2637
3354
  };
2638
3355
  }
2639
- };
2640
- var dxnToIndexerTypename = (dxn) => {
2641
- switch (dxn.kind) {
2642
- case DXN.kind.TYPE:
2643
- return dxn.parts[0];
2644
- case DXN.kind.ECHO:
2645
- return dxn.parts[1];
2646
- default:
2647
- throw new Error(`Invalid DXN kind: ${dxn.kind}`);
3356
+ async _loadDocumentsAfterIndexQuery(indexHits) {
3357
+ return Promise.all(indexHits.map(async (hit) => {
3358
+ return this._loadFromIndexHit(hit);
3359
+ }));
3360
+ }
3361
+ async _loadFromIndexHit(hit) {
3362
+ const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(hit.id);
3363
+ const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
3364
+ F: __dxlog_file11,
3365
+ L: 571
3366
+ }), documentId);
3367
+ const doc = handle.doc();
3368
+ if (!doc) {
3369
+ return null;
3370
+ }
3371
+ const spaceKey = spaceKeyInIndex ?? DatabaseDirectory3.getSpaceKey(doc);
3372
+ if (!spaceKey) {
3373
+ return null;
3374
+ }
3375
+ const object = DatabaseDirectory3.getInlineObject(doc, objectId);
3376
+ if (!object) {
3377
+ return null;
3378
+ }
3379
+ return {
3380
+ objectId,
3381
+ documentId,
3382
+ spaceId: await createIdFromSpaceKey(PublicKey3.from(spaceKey)),
3383
+ doc: object
3384
+ };
3385
+ }
3386
+ async _loadFromDXN(dxn, { sourceSpaceId }) {
3387
+ const echoDxn = dxn.asEchoDXN();
3388
+ if (!echoDxn) {
3389
+ log9.warn("unable to resolve DXN", {
3390
+ dxn
3391
+ }, {
3392
+ F: __dxlog_file11,
3393
+ L: 598,
3394
+ S: this,
3395
+ C: (f, a) => f(...a)
3396
+ });
3397
+ return null;
3398
+ }
3399
+ const spaceId = echoDxn.spaceId ?? sourceSpaceId;
3400
+ const spaceRoot = this._spaceStateManager.getRootBySpaceId(spaceId);
3401
+ if (!spaceRoot) {
3402
+ log9.warn("no space state found for", {
3403
+ spaceId
3404
+ }, {
3405
+ F: __dxlog_file11,
3406
+ L: 606,
3407
+ S: this,
3408
+ C: (f, a) => f(...a)
3409
+ });
3410
+ return null;
3411
+ }
3412
+ const dbDirectory = spaceRoot.doc();
3413
+ if (!dbDirectory) {
3414
+ log9.warn("no space state found for", {
3415
+ spaceId
3416
+ }, {
3417
+ F: __dxlog_file11,
3418
+ L: 611,
3419
+ S: this,
3420
+ C: (f, a) => f(...a)
3421
+ });
3422
+ return null;
3423
+ }
3424
+ const inlineObject = DatabaseDirectory3.getInlineObject(dbDirectory, echoDxn.echoId);
3425
+ if (inlineObject) {
3426
+ return {
3427
+ objectId: echoDxn.echoId,
3428
+ documentId: spaceRoot.documentId,
3429
+ spaceId,
3430
+ doc: inlineObject
3431
+ };
3432
+ }
3433
+ const link = DatabaseDirectory3.getLink(dbDirectory, echoDxn.echoId);
3434
+ if (!link) {
3435
+ return null;
3436
+ }
3437
+ const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
3438
+ F: __dxlog_file11,
3439
+ L: 630
3440
+ }), link);
3441
+ const doc = handle.doc();
3442
+ if (!doc) {
3443
+ return null;
3444
+ }
3445
+ const object = DatabaseDirectory3.getInlineObject(doc, echoDxn.echoId);
3446
+ if (!object) {
3447
+ return null;
3448
+ }
3449
+ return {
3450
+ objectId: echoDxn.echoId,
3451
+ documentId: handle.documentId,
3452
+ spaceId,
3453
+ doc: object
3454
+ };
2648
3455
  }
2649
3456
  };
2650
3457
 
2651
3458
  // packages/core/echo/echo-pipeline/src/db-host/query-service.ts
2652
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
3459
+ var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
2653
3460
  var QueryServiceImpl = class extends Resource7 {
2654
3461
  // TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
2655
3462
  constructor(_params) {
2656
- super();
2657
- this._params = _params;
2658
- this._queries = /* @__PURE__ */ new Set();
2659
- this._updateQueries = new DeferredTask(this._ctx, async () => {
3463
+ super(), this._params = _params, this._queries = /* @__PURE__ */ new Set(), this._updateQueries = new DeferredTask(this._ctx, async () => {
2660
3464
  await Promise.all(Array.from(this._queries).map(async (query) => {
2661
3465
  try {
2662
- const { changed } = await query.state.execQuery();
3466
+ const { changed } = await query.executor.execQuery();
2663
3467
  if (changed) {
2664
- query.sendResults(query.state.getResults());
3468
+ query.sendResults(query.executor.getResults());
2665
3469
  }
2666
3470
  } catch (err) {
2667
- log9.catch(err, void 0, {
2668
- F: __dxlog_file11,
2669
- L: 53,
3471
+ log10.catch(err, void 0, {
3472
+ F: __dxlog_file12,
3473
+ L: 57,
2670
3474
  S: this,
2671
3475
  C: (f, a) => f(...a)
2672
3476
  });
2673
3477
  }
2674
3478
  }));
2675
3479
  });
2676
- trace5.diagnostic({
3480
+ trace4.diagnostic({
2677
3481
  id: "active-queries",
2678
3482
  name: "Active Queries",
2679
3483
  fetch: () => {
2680
3484
  return Array.from(this._queries).map((query) => {
2681
3485
  return {
2682
- filter: JSON.stringify(query.state.filter),
2683
- metrics: query.state.metrics
3486
+ query: JSON.stringify(query.executor.query),
3487
+ plan: JSON.stringify(query.executor.plan),
3488
+ trace: JSON.stringify(query.executor.trace)
2684
3489
  };
2685
3490
  });
2686
3491
  }
@@ -2693,24 +3498,19 @@ var QueryServiceImpl = class extends Resource7 {
2693
3498
  await Promise.all(Array.from(this._queries).map((query) => query.close()));
2694
3499
  }
2695
3500
  async setConfig(config) {
2696
- if (this._params.indexer.initialized) {
2697
- log9.warn("Indexer already initialized.", void 0, {
2698
- F: __dxlog_file11,
2699
- L: 87,
2700
- S: this,
2701
- C: (f, a) => f(...a)
2702
- });
2703
- return;
2704
- }
2705
- void this._params.indexer.setConfig(config);
3501
+ await this._params.indexer.setConfig(config);
2706
3502
  }
2707
3503
  execQuery(request) {
2708
3504
  return new Stream2(({ next, close, ctx }) => {
2709
- const query = {
2710
- state: new QueryState({
3505
+ const parsedQuery = QueryAST.Query.pipe(Schema.decodeUnknownSync)(JSON.parse(request.query));
3506
+ const queryEntry = {
3507
+ executor: new QueryExecutor({
2711
3508
  indexer: this._params.indexer,
2712
3509
  automergeHost: this._params.automergeHost,
2713
- request
3510
+ queryId: request.queryId ?? raise(new Error("query id required")),
3511
+ query: parsedQuery,
3512
+ reactivity: request.reactivity,
3513
+ spaceStateManager: this._params.spaceStateManager
2714
3514
  }),
2715
3515
  sendResults: (results) => {
2716
3516
  if (ctx.disposed) {
@@ -2723,37 +3523,30 @@ var QueryServiceImpl = class extends Resource7 {
2723
3523
  },
2724
3524
  close: async () => {
2725
3525
  close();
2726
- await query.state.close();
2727
- this._queries.delete(query);
3526
+ await queryEntry.executor.close();
3527
+ this._queries.delete(queryEntry);
2728
3528
  }
2729
3529
  };
2730
- this._queries.add(query);
3530
+ this._queries.add(queryEntry);
2731
3531
  queueMicrotask(async () => {
2732
- await query.state.open();
3532
+ await queryEntry.executor.open();
2733
3533
  try {
2734
- const { changed } = await query.state.execQuery();
2735
- if (changed) {
2736
- query.sendResults(query.state.getResults());
2737
- }
3534
+ await queryEntry.executor.execQuery();
3535
+ queryEntry.sendResults(queryEntry.executor.getResults());
2738
3536
  } catch (error) {
2739
- log9.catch(error, void 0, {
2740
- F: __dxlog_file11,
2741
- L: 124,
2742
- S: this,
2743
- C: (f, a) => f(...a)
2744
- });
3537
+ close(error);
2745
3538
  }
2746
3539
  });
2747
- return query.close;
3540
+ return queryEntry.close;
2748
3541
  });
2749
3542
  }
2750
3543
  /**
2751
3544
  * Re-index all loaded documents.
2752
3545
  */
2753
3546
  async reindex() {
2754
- log9.info("Reindexing all documents...", void 0, {
2755
- F: __dxlog_file11,
2756
- L: 136,
3547
+ log10.info("Reindexing all documents...", void 0, {
3548
+ F: __dxlog_file12,
3549
+ L: 141,
2757
3550
  S: this,
2758
3551
  C: (f, a) => f(...a)
2759
3552
  });
@@ -2764,21 +3557,21 @@ var QueryServiceImpl = class extends Resource7 {
2764
3557
  ids.set(id, heads);
2765
3558
  }
2766
3559
  if (ids.size % 100 === 0) {
2767
- log9.info("Collected documents...", {
3560
+ log10.info("Collected documents...", {
2768
3561
  count: ids.size
2769
3562
  }, {
2770
- F: __dxlog_file11,
2771
- L: 144,
3563
+ F: __dxlog_file12,
3564
+ L: 149,
2772
3565
  S: this,
2773
3566
  C: (f, a) => f(...a)
2774
3567
  });
2775
3568
  }
2776
3569
  }
2777
- log9.info("Marking all documents as dirty...", {
3570
+ log10.info("Marking all documents as dirty...", {
2778
3571
  count: ids.size
2779
3572
  }, {
2780
- F: __dxlog_file11,
2781
- L: 148,
3573
+ F: __dxlog_file12,
3574
+ L: 153,
2782
3575
  S: this,
2783
3576
  C: (f, a) => f(...a)
2784
3577
  });
@@ -2797,7 +3590,7 @@ var createDocumentsIterator = (automergeHost) => (
2797
3590
  return;
2798
3591
  }
2799
3592
  const doc = handle.doc();
2800
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
3593
+ const spaceKey = DatabaseDirectory4.getSpaceKey(doc) ?? void 0;
2801
3594
  if (doc.objects) {
2802
3595
  yield Object.entries(doc.objects).map(([objectId, object]) => {
2803
3596
  return {
@@ -2818,8 +3611,8 @@ var createDocumentsIterator = (automergeHost) => (
2818
3611
  continue;
2819
3612
  }
2820
3613
  const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
2821
- F: __dxlog_file11,
2822
- L: 190
3614
+ F: __dxlog_file12,
3615
+ L: 195
2823
3616
  }), urlString);
2824
3617
  for await (const result of getObjectsFromHandle(linkHandle)) {
2825
3618
  yield result;
@@ -2844,17 +3637,18 @@ var createDocumentsIterator = (automergeHost) => (
2844
3637
  import { interpretAsDocumentId as interpretAsDocumentId3 } from "@automerge/automerge-repo";
2845
3638
  import isEqual from "lodash.isequal";
2846
3639
  import { Event as Event3, UpdateScheduler as UpdateScheduler3 } from "@dxos/async";
2847
- import { Resource as Resource8, Context as Context5 } from "@dxos/context";
3640
+ import { Resource as Resource8, Context as Context5, LifecycleState as LifecycleState4 } from "@dxos/context";
3641
+ import { invariant as invariant12 } from "@dxos/invariant";
2848
3642
 
2849
3643
  // packages/core/echo/echo-pipeline/src/db-host/database-root.ts
2850
3644
  import { interpretAsDocumentId as interpretAsDocumentId2 } from "@automerge/automerge-repo";
2851
- import { SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
2852
- import { invariant as invariant10 } from "@dxos/invariant";
3645
+ import { DatabaseDirectory as DatabaseDirectory5, SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
3646
+ import { invariant as invariant11 } from "@dxos/invariant";
2853
3647
 
2854
3648
  // packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts
2855
3649
  import * as A4 from "@automerge/automerge";
2856
- import { log as log10 } from "@dxos/log";
2857
- var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
3650
+ import { log as log11 } from "@dxos/log";
3651
+ var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
2858
3652
  var measureDocMetrics = (doc) => {
2859
3653
  const snapshot = A4.save(doc);
2860
3654
  const start = Date.now();
@@ -2865,10 +3659,10 @@ var measureDocMetrics = (doc) => {
2865
3659
  const mutationCount = A4.getAllChanges(doc).length;
2866
3660
  const getAllChangesEnd = Date.now();
2867
3661
  if (getAllChangesEnd - getAllChangesStart > 300) {
2868
- log10.warn("getAllChanges took too long", {
3662
+ log11.warn("getAllChanges took too long", {
2869
3663
  elapsed: getAllChangesEnd - getAllChangesStart
2870
3664
  }, {
2871
- F: __dxlog_file12,
3665
+ F: __dxlog_file13,
2872
3666
  L: 31,
2873
3667
  S: void 0,
2874
3668
  C: (f, a) => f(...a)
@@ -2882,7 +3676,7 @@ var measureDocMetrics = (doc) => {
2882
3676
  };
2883
3677
 
2884
3678
  // packages/core/echo/echo-pipeline/src/db-host/database-root.ts
2885
- var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
3679
+ var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
2886
3680
  var DatabaseRoot = class {
2887
3681
  static mapLinks(doc, mapping) {
2888
3682
  doc.change((d) => {
@@ -2927,7 +3721,7 @@ var DatabaseRoot = class {
2927
3721
  if (!doc) {
2928
3722
  return null;
2929
3723
  }
2930
- return getSpaceKeyFromDoc(doc);
3724
+ return DatabaseDirectory5.getSpaceKey(doc);
2931
3725
  }
2932
3726
  getInlineObjectCount() {
2933
3727
  const doc = this.doc();
@@ -2945,9 +3739,9 @@ var DatabaseRoot = class {
2945
3739
  }
2946
3740
  getAllLinkedDocuments() {
2947
3741
  const doc = this.doc();
2948
- invariant10(doc, void 0, {
2949
- F: __dxlog_file13,
2950
- L: 89,
3742
+ invariant11(doc, void 0, {
3743
+ F: __dxlog_file14,
3744
+ L: 88,
2951
3745
  S: this,
2952
3746
  A: [
2953
3747
  "doc",
@@ -2966,7 +3760,7 @@ var DatabaseRoot = class {
2966
3760
  };
2967
3761
 
2968
3762
  // packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts
2969
- var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
3763
+ var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
2970
3764
  var SpaceStateManager = class extends Resource8 {
2971
3765
  constructor() {
2972
3766
  super(...arguments);
@@ -2991,6 +3785,22 @@ var SpaceStateManager = class extends Resource8 {
2991
3785
  getSpaceRootDocumentId(spaceId) {
2992
3786
  return this._rootBySpace.get(spaceId);
2993
3787
  }
3788
+ getRootBySpaceId(spaceId) {
3789
+ invariant12(this._lifecycleState === LifecycleState4.OPEN, void 0, {
3790
+ F: __dxlog_file15,
3791
+ L: 44,
3792
+ S: this,
3793
+ A: [
3794
+ "this._lifecycleState === LifecycleState.OPEN",
3795
+ ""
3796
+ ]
3797
+ });
3798
+ const documentId = this._rootBySpace.get(spaceId);
3799
+ if (!documentId) {
3800
+ return void 0;
3801
+ }
3802
+ return this._roots.get(documentId);
3803
+ }
2994
3804
  async assignRootToSpace(spaceId, handle) {
2995
3805
  let root;
2996
3806
  if (this._roots.has(handle.documentId)) {
@@ -3009,8 +3819,8 @@ var SpaceStateManager = class extends Resource8 {
3009
3819
  }
3010
3820
  this._rootBySpace.set(spaceId, root.handle.documentId);
3011
3821
  const ctx = new Context5(void 0, {
3012
- F: __dxlog_file14,
3013
- L: 62
3822
+ F: __dxlog_file15,
3823
+ L: 72
3014
3824
  });
3015
3825
  this._perRootContext.set(root.handle.documentId, ctx);
3016
3826
  await root.handle.whenReady();
@@ -3043,19 +3853,20 @@ var SpaceDocumentListUpdatedEvent = class {
3043
3853
  };
3044
3854
 
3045
3855
  // packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
3046
- var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
3047
- var INDEXER_CONFIG = {
3048
- enabled: true,
3049
- indexes: [
3050
- {
3051
- kind: IndexKind.Kind.SCHEMA_MATCH
3052
- }
3053
- ]
3856
+ var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
3857
+ var DEFAULT_INDEXING_CONFIG = {
3858
+ // TODO(dmaretskyi): Disabled by default since embedding generation is expensive.
3859
+ fullText: false,
3860
+ vector: false
3054
3861
  };
3055
3862
  var EchoHost = class extends Resource9 {
3056
- constructor({ kv, peerIdProvider, getSpaceKeyByRootDocumentId }) {
3863
+ constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
3057
3864
  super();
3058
3865
  this._spaceStateManager = new SpaceStateManager();
3866
+ const indexingConfig = {
3867
+ ...DEFAULT_INDEXING_CONFIG,
3868
+ ...indexing
3869
+ };
3059
3870
  this._indexMetadataStore = new IndexMetadataStore({
3060
3871
  db: kv.sublevel("index-metadata")
3061
3872
  });
@@ -3076,10 +3887,32 @@ var EchoHost = class extends Resource9 {
3076
3887
  loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
3077
3888
  indexCooldownTime: false ? 0 : void 0
3078
3889
  });
3079
- void this._indexer.setConfig(INDEXER_CONFIG);
3890
+ void this._indexer.setConfig({
3891
+ enabled: true,
3892
+ indexes: [
3893
+ //
3894
+ {
3895
+ kind: IndexKind.Kind.SCHEMA_MATCH
3896
+ },
3897
+ {
3898
+ kind: IndexKind.Kind.GRAPH
3899
+ },
3900
+ ...indexingConfig.fullText ? [
3901
+ {
3902
+ kind: IndexKind.Kind.FULL_TEXT
3903
+ }
3904
+ ] : [],
3905
+ ...indexingConfig.vector ? [
3906
+ {
3907
+ kind: IndexKind.Kind.VECTOR
3908
+ }
3909
+ ] : []
3910
+ ]
3911
+ });
3080
3912
  this._queryService = new QueryServiceImpl({
3081
3913
  automergeHost: this._automergeHost,
3082
- indexer: this._indexer
3914
+ indexer: this._indexer,
3915
+ spaceStateManager: this._spaceStateManager
3083
3916
  });
3084
3917
  this._dataService = new DataServiceImpl({
3085
3918
  automergeHost: this._automergeHost,
@@ -3088,7 +3921,7 @@ var EchoHost = class extends Resource9 {
3088
3921
  await this._indexer.updateIndexes();
3089
3922
  }
3090
3923
  });
3091
- trace6.diagnostic({
3924
+ trace5.diagnostic({
3092
3925
  id: "echo-stats",
3093
3926
  name: "Echo Stats",
3094
3927
  fetch: async () => {
@@ -3098,7 +3931,7 @@ var EchoHost = class extends Resource9 {
3098
3931
  };
3099
3932
  }
3100
3933
  });
3101
- trace6.diagnostic({
3934
+ trace5.diagnostic({
3102
3935
  id: "database-roots",
3103
3936
  name: "Database Roots",
3104
3937
  fetch: async () => {
@@ -3111,7 +3944,7 @@ var EchoHost = class extends Resource9 {
3111
3944
  }));
3112
3945
  }
3113
3946
  });
3114
- trace6.diagnostic({
3947
+ trace5.diagnostic({
3115
3948
  id: "database-root-metrics",
3116
3949
  name: "Database Roots (with metrics)",
3117
3950
  fetch: async () => {
@@ -3155,8 +3988,8 @@ var EchoHost = class extends Resource9 {
3155
3988
  });
3156
3989
  }
3157
3990
  async _close(ctx) {
3158
- await this._spaceStateManager.close();
3159
3991
  await this._queryService.close(ctx);
3992
+ await this._spaceStateManager.close(ctx);
3160
3993
  await this._indexer.close(ctx);
3161
3994
  await this._automergeHost.close();
3162
3995
  }
@@ -3191,16 +4024,16 @@ var EchoHost = class extends Resource9 {
3191
4024
  * Create new space root.
3192
4025
  */
3193
4026
  async createSpaceRoot(spaceKey) {
3194
- invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
3195
- F: __dxlog_file15,
3196
- L: 226,
4027
+ invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
4028
+ F: __dxlog_file16,
4029
+ L: 252,
3197
4030
  S: this,
3198
4031
  A: [
3199
4032
  "this._lifecycleState === LifecycleState.OPEN",
3200
4033
  ""
3201
4034
  ]
3202
4035
  });
3203
- const spaceId = await createIdFromSpaceKey3(spaceKey);
4036
+ const spaceId = await createIdFromSpaceKey2(spaceKey);
3204
4037
  const automergeRoot = this._automergeHost.createDoc({
3205
4038
  version: SpaceDocVersion3.CURRENT,
3206
4039
  access: {
@@ -3219,9 +4052,9 @@ var EchoHost = class extends Resource9 {
3219
4052
  }
3220
4053
  // TODO(dmaretskyi): Change to document id.
3221
4054
  async openSpaceRoot(spaceId, automergeUrl) {
3222
- invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
3223
- F: __dxlog_file15,
3224
- L: 245,
4055
+ invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
4056
+ F: __dxlog_file16,
4057
+ L: 271,
3225
4058
  S: this,
3226
4059
  A: [
3227
4060
  "this._lifecycleState === LifecycleState.OPEN",
@@ -3255,8 +4088,8 @@ import { cbor as cbor2 } from "@automerge/automerge-repo";
3255
4088
  import { Mutex, scheduleTask as scheduleTask2, scheduleMicroTask } from "@dxos/async";
3256
4089
  import { Context as Context6, Resource as Resource11 } from "@dxos/context";
3257
4090
  import { randomUUID } from "@dxos/crypto";
3258
- import { invariant as invariant12 } from "@dxos/invariant";
3259
- import { log as log12 } from "@dxos/log";
4091
+ import { invariant as invariant14 } from "@dxos/invariant";
4092
+ import { log as log13 } from "@dxos/log";
3260
4093
  import { EdgeService } from "@dxos/protocols";
3261
4094
  import { buf } from "@dxos/protocols/buf";
3262
4095
  import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
@@ -3265,14 +4098,11 @@ import { bufferToArray as bufferToArray2 } from "@dxos/util";
3265
4098
  // packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts
3266
4099
  import { Trigger as Trigger2 } from "@dxos/async";
3267
4100
  import { Resource as Resource10 } from "@dxos/context";
3268
- import { log as log11 } from "@dxos/log";
3269
- var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
4101
+ import { log as log12 } from "@dxos/log";
4102
+ var __dxlog_file17 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
3270
4103
  var InflightRequestLimiter = class extends Resource10 {
3271
4104
  constructor(_config) {
3272
- super();
3273
- this._config = _config;
3274
- this._inflightRequestBalance = 0;
3275
- this._requestBarrier = new Trigger2();
4105
+ super(), this._config = _config, this._inflightRequestBalance = 0, this._requestBarrier = new Trigger2();
3276
4106
  }
3277
4107
  async _open() {
3278
4108
  this._inflightRequestBalance = 0;
@@ -3295,8 +4125,8 @@ var InflightRequestLimiter = class extends Resource10 {
3295
4125
  if (this._inflightRequestBalance === this._config.maxInflightRequests) {
3296
4126
  this._requestBarrier.reset();
3297
4127
  this._resetBalanceTimeout = setTimeout(() => {
3298
- log11.warn("Request balance has not changed during specified timeout, resetting request limiter.", void 0, {
3299
- F: __dxlog_file16,
4128
+ log12.warn("Request balance has not changed during specified timeout, resetting request limiter.", void 0, {
4129
+ F: __dxlog_file17,
3300
4130
  L: 52,
3301
4131
  S: this,
3302
4132
  C: (f, a) => f(...a)
@@ -3319,69 +4149,72 @@ var InflightRequestLimiter = class extends Resource10 {
3319
4149
  };
3320
4150
 
3321
4151
  // packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts
3322
- function _using_ctx() {
3323
- var _disposeSuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed) {
3324
- var err = new Error();
3325
- err.name = "SuppressedError";
3326
- err.suppressed = suppressed;
3327
- err.error = error;
3328
- return err;
3329
- }, empty = {}, stack = [];
3330
- function using(isAwait, value) {
3331
- if (value != null) {
3332
- if (Object(value) !== value) {
3333
- throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
3334
- }
3335
- if (isAwait) {
3336
- var dispose = value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
3337
- }
3338
- if (dispose == null) {
3339
- dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
3340
- }
3341
- if (typeof dispose !== "function") {
3342
- throw new TypeError(`Property [Symbol.dispose] is not a function.`);
3343
- }
3344
- stack.push({
3345
- v: value,
3346
- d: dispose,
3347
- a: isAwait
3348
- });
3349
- } else if (isAwait) {
3350
- stack.push({
3351
- d: value,
3352
- a: isAwait
3353
- });
4152
+ function _ts_add_disposable_resource(env, value, async) {
4153
+ if (value !== null && value !== void 0) {
4154
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4155
+ var dispose, inner;
4156
+ if (async) {
4157
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
4158
+ dispose = value[Symbol.asyncDispose];
3354
4159
  }
3355
- return value;
4160
+ if (dispose === void 0) {
4161
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
4162
+ dispose = value[Symbol.dispose];
4163
+ if (async) inner = dispose;
4164
+ }
4165
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
4166
+ if (inner) dispose = function() {
4167
+ try {
4168
+ inner.call(this);
4169
+ } catch (e) {
4170
+ return Promise.reject(e);
4171
+ }
4172
+ };
4173
+ env.stack.push({
4174
+ value,
4175
+ dispose,
4176
+ async
4177
+ });
4178
+ } else if (async) {
4179
+ env.stack.push({
4180
+ async: true
4181
+ });
3356
4182
  }
3357
- return {
3358
- e: empty,
3359
- u: using.bind(null, false),
3360
- a: using.bind(null, true),
3361
- d: function() {
3362
- var error = this.e;
3363
- function next() {
3364
- while (resource = stack.pop()) {
3365
- try {
3366
- var resource, disposalResult = resource.d && resource.d.call(resource.v);
3367
- if (resource.a) {
3368
- return Promise.resolve(disposalResult).then(next, err);
3369
- }
3370
- } catch (e) {
3371
- return err(e);
3372
- }
4183
+ return value;
4184
+ }
4185
+ function _ts_dispose_resources(env) {
4186
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
4187
+ var e = new Error(message);
4188
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
4189
+ };
4190
+ return (_ts_dispose_resources = function _ts_dispose_resources2(env2) {
4191
+ function fail(e) {
4192
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
4193
+ env2.hasError = true;
4194
+ }
4195
+ var r, s = 0;
4196
+ function next() {
4197
+ while (r = env2.stack.pop()) {
4198
+ try {
4199
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
4200
+ if (r.dispose) {
4201
+ var result = r.dispose.call(r.value);
4202
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
4203
+ fail(e);
4204
+ return next();
4205
+ });
4206
+ } else s |= 1;
4207
+ } catch (e) {
4208
+ fail(e);
3373
4209
  }
3374
- if (error !== empty) throw error;
3375
4210
  }
3376
- function err(e) {
3377
- error = error !== empty ? new _disposeSuppressedError(error, e) : e;
3378
- return next();
3379
- }
3380
- return next();
4211
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
4212
+ if (env2.hasError) throw env2.error;
3381
4213
  }
3382
- };
4214
+ return next();
4215
+ })(env);
3383
4216
  }
3384
- var __dxlog_file17 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts";
4217
+ var __dxlog_file18 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts";
3385
4218
  var INITIAL_RESTART_DELAY = 500;
3386
4219
  var RESTART_DELAY_JITTER = 250;
3387
4220
  var MAX_RESTART_DELAY = 5e3;
@@ -3397,18 +4230,18 @@ var EchoEdgeReplicator = class {
3397
4230
  this._sharePolicyEnabled = !disableSharePolicy;
3398
4231
  }
3399
4232
  async connect(context) {
3400
- log12.info("connecting...", {
4233
+ log13.info("connecting...", {
3401
4234
  peerId: context.peerId,
3402
4235
  connectedSpaces: this._connectedSpaces.size
3403
4236
  }, {
3404
- F: __dxlog_file17,
4237
+ F: __dxlog_file18,
3405
4238
  L: 61,
3406
4239
  S: this,
3407
4240
  C: (f, a) => f(...a)
3408
4241
  });
3409
4242
  this._context = context;
3410
4243
  this._ctx = Context6.default(void 0, {
3411
- F: __dxlog_file17,
4244
+ F: __dxlog_file18,
3412
4245
  L: 64
3413
4246
  });
3414
4247
  this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
@@ -3416,9 +4249,13 @@ var EchoEdgeReplicator = class {
3416
4249
  }));
3417
4250
  }
3418
4251
  async _handleReconnect() {
4252
+ const env = {
4253
+ stack: [],
4254
+ error: void 0,
4255
+ hasError: false
4256
+ };
3419
4257
  try {
3420
- var _usingCtx = _using_ctx();
3421
- const _guard = _usingCtx.u(await this._mutex.acquire());
4258
+ const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
3422
4259
  const spaces = [
3423
4260
  ...this._connectedSpaces
3424
4261
  ];
@@ -3431,31 +4268,41 @@ var EchoEdgeReplicator = class {
3431
4268
  await this._openConnection(spaceId);
3432
4269
  }
3433
4270
  }
3434
- } catch (_) {
3435
- _usingCtx.e = _;
4271
+ } catch (e) {
4272
+ env.error = e;
4273
+ env.hasError = true;
3436
4274
  } finally {
3437
- _usingCtx.d();
4275
+ _ts_dispose_resources(env);
3438
4276
  }
3439
4277
  }
3440
4278
  async disconnect() {
4279
+ const env = {
4280
+ stack: [],
4281
+ error: void 0,
4282
+ hasError: false
4283
+ };
3441
4284
  try {
3442
- var _usingCtx = _using_ctx();
3443
- const _guard = _usingCtx.u(await this._mutex.acquire());
4285
+ const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
3444
4286
  await this._ctx?.dispose();
3445
4287
  for (const connection of this._connections.values()) {
3446
4288
  await connection.close();
3447
4289
  }
3448
4290
  this._connections.clear();
3449
- } catch (_) {
3450
- _usingCtx.e = _;
4291
+ } catch (e) {
4292
+ env.error = e;
4293
+ env.hasError = true;
3451
4294
  } finally {
3452
- _usingCtx.d();
4295
+ _ts_dispose_resources(env);
3453
4296
  }
3454
4297
  }
3455
4298
  async connectToSpace(spaceId) {
4299
+ const env = {
4300
+ stack: [],
4301
+ error: void 0,
4302
+ hasError: false
4303
+ };
3456
4304
  try {
3457
- var _usingCtx = _using_ctx();
3458
- const _guard = _usingCtx.u(await this._mutex.acquire());
4305
+ const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
3459
4306
  if (this._connectedSpaces.has(spaceId)) {
3460
4307
  return;
3461
4308
  }
@@ -3463,31 +4310,37 @@ var EchoEdgeReplicator = class {
3463
4310
  if (this._context !== null) {
3464
4311
  await this._openConnection(spaceId);
3465
4312
  }
3466
- } catch (_) {
3467
- _usingCtx.e = _;
4313
+ } catch (e) {
4314
+ env.error = e;
4315
+ env.hasError = true;
3468
4316
  } finally {
3469
- _usingCtx.d();
4317
+ _ts_dispose_resources(env);
3470
4318
  }
3471
4319
  }
3472
4320
  async disconnectFromSpace(spaceId) {
4321
+ const env = {
4322
+ stack: [],
4323
+ error: void 0,
4324
+ hasError: false
4325
+ };
3473
4326
  try {
3474
- var _usingCtx = _using_ctx();
3475
- const _guard = _usingCtx.u(await this._mutex.acquire());
4327
+ const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
3476
4328
  this._connectedSpaces.delete(spaceId);
3477
4329
  const connection = this._connections.get(spaceId);
3478
4330
  if (connection) {
3479
4331
  await connection.close();
3480
4332
  this._connections.delete(spaceId);
3481
4333
  }
3482
- } catch (_) {
3483
- _usingCtx.e = _;
4334
+ } catch (e) {
4335
+ env.error = e;
4336
+ env.hasError = true;
3484
4337
  } finally {
3485
- _usingCtx.d();
4338
+ _ts_dispose_resources(env);
3486
4339
  }
3487
4340
  }
3488
4341
  async _openConnection(spaceId, reconnects = 0) {
3489
- invariant12(this._context, void 0, {
3490
- F: __dxlog_file17,
4342
+ invariant14(this._context, void 0, {
4343
+ F: __dxlog_file18,
3491
4344
  L: 125,
3492
4345
  S: this,
3493
4346
  A: [
@@ -3495,8 +4348,8 @@ var EchoEdgeReplicator = class {
3495
4348
  ""
3496
4349
  ]
3497
4350
  });
3498
- invariant12(!this._connections.has(spaceId), void 0, {
3499
- F: __dxlog_file17,
4351
+ invariant14(!this._connections.has(spaceId), void 0, {
4352
+ F: __dxlog_file18,
3500
4353
  L: 126,
3501
4354
  S: this,
3502
4355
  A: [
@@ -3521,21 +4374,25 @@ var EchoEdgeReplicator = class {
3521
4374
  return;
3522
4375
  }
3523
4376
  const restartDelay = Math.min(MAX_RESTART_DELAY, INITIAL_RESTART_DELAY * reconnects) + Math.random() * RESTART_DELAY_JITTER;
3524
- log12.info("connection restart scheduled", {
4377
+ log13.info("connection restart scheduled", {
3525
4378
  spaceId,
3526
4379
  reconnects,
3527
4380
  restartDelay
3528
4381
  }, {
3529
- F: __dxlog_file17,
4382
+ F: __dxlog_file18,
3530
4383
  L: 149,
3531
4384
  S: this,
3532
4385
  C: (f, a) => f(...a)
3533
4386
  });
3534
4387
  restartScheduled = true;
3535
4388
  scheduleTask2(this._ctx, async () => {
4389
+ const env = {
4390
+ stack: [],
4391
+ error: void 0,
4392
+ hasError: false
4393
+ };
3536
4394
  try {
3537
- var _usingCtx = _using_ctx();
3538
- const _guard = _usingCtx.u(await this._mutex.acquire());
4395
+ const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
3539
4396
  if (this._connections.get(spaceId) !== connection) {
3540
4397
  return;
3541
4398
  }
@@ -3546,10 +4403,11 @@ var EchoEdgeReplicator = class {
3546
4403
  return;
3547
4404
  }
3548
4405
  await this._openConnection(spaceId, reconnects + 1);
3549
- } catch (_) {
3550
- _usingCtx.e = _;
4406
+ } catch (e) {
4407
+ env.error = e;
4408
+ env.hasError = true;
3551
4409
  } finally {
3552
- _usingCtx.d();
4410
+ _ts_dispose_resources(env);
3553
4411
  }
3554
4412
  }, restartDelay);
3555
4413
  }
@@ -3590,8 +4448,8 @@ var EdgeReplicatorConnection = class extends Resource11 {
3590
4448
  });
3591
4449
  }
3592
4450
  async _open(ctx) {
3593
- log12("opening...", void 0, {
3594
- F: __dxlog_file17,
4451
+ log13("opening...", void 0, {
4452
+ F: __dxlog_file18,
3595
4453
  L: 252,
3596
4454
  S: this,
3597
4455
  C: (f, a) => f(...a)
@@ -3603,8 +4461,8 @@ var EdgeReplicatorConnection = class extends Resource11 {
3603
4461
  await this._onRemoteConnected();
3604
4462
  }
3605
4463
  async _close() {
3606
- log12("closing...", void 0, {
3607
- F: __dxlog_file17,
4464
+ log13("closing...", void 0, {
4465
+ F: __dxlog_file18,
3608
4466
  L: 267,
3609
4467
  S: this,
3610
4468
  C: (f, a) => f(...a)
@@ -3614,8 +4472,8 @@ var EdgeReplicatorConnection = class extends Resource11 {
3614
4472
  await this._onRemoteDisconnected();
3615
4473
  }
3616
4474
  get peerId() {
3617
- invariant12(this._remotePeerId, "Not connected", {
3618
- F: __dxlog_file17,
4475
+ invariant14(this._remotePeerId, "Not connected", {
4476
+ F: __dxlog_file18,
3619
4477
  L: 276,
3620
4478
  S: this,
3621
4479
  A: [
@@ -3635,12 +4493,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
3635
4493
  documentId: params.documentId,
3636
4494
  peerId: this._remotePeerId
3637
4495
  });
3638
- log12.verbose("document not found locally for share policy check", {
4496
+ log13.verbose("document not found locally for share policy check", {
3639
4497
  documentId: params.documentId,
3640
4498
  acceptDocument: remoteDocumentExists,
3641
4499
  remoteId: this._remotePeerId
3642
4500
  }, {
3643
- F: __dxlog_file17,
4501
+ F: __dxlog_file18,
3644
4502
  L: 291,
3645
4503
  S: this,
3646
4504
  C: (f, a) => f(...a)
@@ -3661,12 +4519,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
3661
4519
  return;
3662
4520
  }
3663
4521
  const payload = cbor2.decode(message.payload.value);
3664
- log12.verbose("received", {
4522
+ log13.verbose("received", {
3665
4523
  type: payload.type,
3666
4524
  documentId: payload.type === "sync" && payload.documentId,
3667
4525
  remoteId: this._remotePeerId
3668
4526
  }, {
3669
- F: __dxlog_file17,
4527
+ F: __dxlog_file18,
3670
4528
  L: 320,
3671
4529
  S: this,
3672
4530
  C: (f, a) => f(...a)
@@ -3684,12 +4542,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
3684
4542
  }
3685
4543
  async _sendMessage(message) {
3686
4544
  message.targetId = this._targetServiceId;
3687
- log12.verbose("sending...", {
4545
+ log13.verbose("sending...", {
3688
4546
  type: message.type,
3689
4547
  documentId: message.type === "sync" && message.documentId,
3690
4548
  remoteId: this._remotePeerId
3691
4549
  }, {
3692
- F: __dxlog_file17,
4550
+ F: __dxlog_file18,
3693
4551
  L: 349,
3694
4552
  S: this,
3695
4553
  C: (f, a) => f(...a)
@@ -3710,11 +4568,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
3710
4568
  var isForbiddenErrorMessage = (message) => message.type === "error" && message.message === "Forbidden";
3711
4569
 
3712
4570
  // packages/core/echo/echo-pipeline/src/util.ts
3713
- import { decodeReference } from "@dxos/echo-protocol";
4571
+ import { decodeReference, ObjectStructure as ObjectStructure2 } from "@dxos/echo-protocol";
3714
4572
  var findInlineObjectOfType = (spaceDoc, typename) => {
3715
4573
  for (const id in spaceDoc.objects ?? {}) {
3716
4574
  const obj = spaceDoc.objects[id];
3717
- if (obj.system.type && decodeReference(obj.system.type).objectId === typename) {
4575
+ const objType = ObjectStructure2.getTypeReference(obj);
4576
+ if (objType && decodeReference(objType).objectId === typename) {
3718
4577
  return [
3719
4578
  id,
3720
4579
  obj
@@ -3735,6 +4594,7 @@ export {
3735
4594
  EchoDataMonitor,
3736
4595
  EchoEdgeReplicator,
3737
4596
  EchoHost,
4597
+ ExecutionTrace,
3738
4598
  FIND_PARAMS,
3739
4599
  LevelDBStorageAdapter,
3740
4600
  MOCK_AUTH_PROVIDER,
@@ -3742,8 +4602,10 @@ export {
3742
4602
  MeshEchoReplicator,
3743
4603
  MetadataStore,
3744
4604
  Pipeline,
4605
+ QueryExecutor,
4606
+ QueryPlan,
4607
+ QueryPlanner,
3745
4608
  QueryServiceImpl,
3746
- QueryState,
3747
4609
  Space,
3748
4610
  SpaceDocumentListUpdatedEvent,
3749
4611
  SpaceManager,
@@ -3757,9 +4619,10 @@ export {
3757
4619
  deriveCollectionIdFromSpaceId,
3758
4620
  diffCollectionState,
3759
4621
  encodingOptions,
4622
+ filterMatchObject,
4623
+ filterMatchValue,
3760
4624
  findInlineObjectOfType,
3761
4625
  getSpaceIdFromCollectionId,
3762
- getSpaceKeyFromDoc,
3763
4626
  hasInvitationExpired,
3764
4627
  mapFeedIndexesToTimeframe,
3765
4628
  mapTimeframeToFeedIndexes,