@dxos/echo-pipeline 0.8.1 → 0.8.2-main.10c050d

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 (182) hide show
  1. package/dist/lib/browser/{chunk-32WDI3LB.mjs → chunk-3XSXS5EX.mjs} +15 -21
  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 +1380 -516
  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 +202 -22
  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-TC2PRBEU.cjs → chunk-SG2PL5RH.cjs} +18 -24
  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 +1381 -525
  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 +207 -31
  26. package/dist/lib/node/testing/index.cjs.map +4 -4
  27. package/dist/lib/node-esm/{chunk-UKOLB3LW.mjs → chunk-3BZP75TJ.mjs} +15 -21
  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 +1380 -516
  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 +202 -22
  39. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  40. package/dist/types/src/automerge/automerge-host.d.ts +6 -4
  41. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  42. package/dist/types/src/automerge/collection-synchronizer.d.ts +1 -1
  43. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  44. package/dist/types/src/automerge/echo-data-monitor.d.ts +6 -6
  45. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
  46. package/dist/types/src/automerge/echo-network-adapter.d.ts +4 -1
  47. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  48. package/dist/types/src/automerge/heads-store.d.ts +2 -2
  49. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  50. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +1 -1
  51. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  52. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  53. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  54. package/dist/types/src/automerge/network-protocol.d.ts +1 -1
  55. package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
  56. package/dist/types/src/automerge/space-collection.d.ts +1 -1
  57. package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
  58. package/dist/types/src/common/feeds.d.ts.map +1 -1
  59. package/dist/types/src/common/space-id.d.ts.map +1 -1
  60. package/dist/types/src/db-host/automerge-metrics.d.ts +1 -1
  61. package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
  62. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  63. package/dist/types/src/db-host/database-root.d.ts +7 -7
  64. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  65. package/dist/types/src/db-host/documents-iterator.d.ts +1 -1
  66. package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -1
  67. package/dist/types/src/db-host/documents-synchronizer.d.ts +4 -4
  68. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  69. package/dist/types/src/db-host/echo-host.d.ts +13 -2
  70. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  71. package/dist/types/src/db-host/index.d.ts +0 -1
  72. package/dist/types/src/db-host/index.d.ts.map +1 -1
  73. package/dist/types/src/db-host/query-service.d.ts +2 -0
  74. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  75. package/dist/types/src/db-host/space-state-manager.d.ts +4 -3
  76. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  77. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  78. package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
  79. package/dist/types/src/filter/filter-match.d.ts +13 -0
  80. package/dist/types/src/filter/filter-match.d.ts.map +1 -0
  81. package/dist/types/src/filter/filter-match.test.d.ts +2 -0
  82. package/dist/types/src/filter/filter-match.test.d.ts.map +1 -0
  83. package/dist/types/src/filter/index.d.ts +2 -0
  84. package/dist/types/src/filter/index.d.ts.map +1 -0
  85. package/dist/types/src/index.d.ts +1 -0
  86. package/dist/types/src/index.d.ts.map +1 -1
  87. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  88. package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
  89. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  90. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  91. package/dist/types/src/query/errors.d.ts +23 -0
  92. package/dist/types/src/query/errors.d.ts.map +1 -0
  93. package/dist/types/src/query/index.d.ts +5 -0
  94. package/dist/types/src/query/index.d.ts.map +1 -0
  95. package/dist/types/src/query/plan.d.ts +132 -0
  96. package/dist/types/src/query/plan.d.ts.map +1 -0
  97. package/dist/types/src/query/query-executor.d.ts +83 -0
  98. package/dist/types/src/query/query-executor.d.ts.map +1 -0
  99. package/dist/types/src/query/query-planner.d.ts +33 -0
  100. package/dist/types/src/query/query-planner.d.ts.map +1 -0
  101. package/dist/types/src/query/query-planner.test.d.ts +2 -0
  102. package/dist/types/src/query/query-planner.test.d.ts.map +1 -0
  103. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  104. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  105. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  106. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  107. package/dist/types/src/space/space.d.ts.map +1 -1
  108. package/dist/types/src/testing/change-metadata.d.ts.map +1 -1
  109. package/dist/types/src/testing/index.d.ts +2 -0
  110. package/dist/types/src/testing/index.d.ts.map +1 -1
  111. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  112. package/dist/types/src/testing/test-data.d.ts +18 -0
  113. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  114. package/dist/types/src/testing/test-network-adapter.d.ts +3 -2
  115. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  116. package/dist/types/src/testing/test-schema.d.ts +39 -0
  117. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  118. package/dist/types/src/util.d.ts +2 -2
  119. package/dist/types/src/util.d.ts.map +1 -1
  120. package/dist/types/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +43 -34
  122. package/src/automerge/automerge-host.test.ts +7 -7
  123. package/src/automerge/automerge-host.ts +58 -60
  124. package/src/automerge/automerge-repo.test.ts +65 -65
  125. package/src/automerge/collection-synchronizer.test.ts +1 -1
  126. package/src/automerge/collection-synchronizer.ts +11 -10
  127. package/src/automerge/echo-data-monitor.ts +21 -20
  128. package/src/automerge/echo-network-adapter.test.ts +1 -1
  129. package/src/automerge/echo-network-adapter.ts +25 -18
  130. package/src/automerge/heads-store.ts +4 -3
  131. package/src/automerge/leveldb-storage-adapter.ts +1 -1
  132. package/src/automerge/mesh-echo-replicator-connection.ts +6 -5
  133. package/src/automerge/mesh-echo-replicator.ts +2 -2
  134. package/src/automerge/network-protocol.ts +2 -1
  135. package/src/automerge/space-collection.ts +2 -1
  136. package/src/db-host/automerge-metrics.ts +2 -1
  137. package/src/db-host/data-service.ts +4 -3
  138. package/src/db-host/database-root.ts +17 -22
  139. package/src/db-host/documents-iterator.ts +9 -8
  140. package/src/db-host/documents-synchronizer.test.ts +2 -2
  141. package/src/db-host/documents-synchronizer.ts +20 -18
  142. package/src/db-host/echo-host.ts +44 -15
  143. package/src/db-host/index.ts +0 -1
  144. package/src/db-host/query-service.ts +43 -37
  145. package/src/db-host/space-state-manager.ts +14 -4
  146. package/src/edge/echo-edge-replicator.test.ts +3 -3
  147. package/src/edge/echo-edge-replicator.ts +9 -8
  148. package/src/edge/inflight-request-limiter.ts +4 -4
  149. package/src/filter/filter-match.test.ts +101 -0
  150. package/src/filter/filter-match.ts +174 -0
  151. package/src/filter/index.ts +5 -0
  152. package/src/index.ts +1 -0
  153. package/src/metadata/metadata-store.ts +13 -13
  154. package/src/pipeline/pipeline-stress.test.ts +9 -9
  155. package/src/pipeline/pipeline.ts +13 -13
  156. package/src/pipeline/timeframe-clock.ts +5 -5
  157. package/src/query/errors.ts +7 -0
  158. package/src/query/index.ts +8 -0
  159. package/src/query/plan.ts +179 -0
  160. package/src/query/query-executor.ts +648 -0
  161. package/src/query/query-planner.test.ts +613 -0
  162. package/src/query/query-planner.ts +470 -0
  163. package/src/space/admission-discovery-extension.ts +2 -2
  164. package/src/space/control-pipeline.ts +8 -8
  165. package/src/space/space-manager.ts +5 -4
  166. package/src/space/space-protocol.browser.test.ts +1 -0
  167. package/src/space/space-protocol.test.ts +1 -0
  168. package/src/space/space-protocol.ts +4 -4
  169. package/src/space/space.ts +5 -5
  170. package/src/testing/index.ts +2 -0
  171. package/src/testing/test-agent-builder.ts +6 -6
  172. package/src/testing/test-data.ts +127 -0
  173. package/src/testing/test-network-adapter.ts +15 -12
  174. package/src/testing/test-replicator.ts +2 -2
  175. package/src/testing/test-schema.ts +53 -0
  176. package/src/util.ts +7 -3
  177. package/dist/lib/browser/chunk-32WDI3LB.mjs.map +0 -7
  178. package/dist/lib/node/chunk-TC2PRBEU.cjs.map +0 -7
  179. package/dist/lib/node-esm/chunk-UKOLB3LW.mjs.map +0 -7
  180. package/dist/types/src/db-host/query-state.d.ts +0 -41
  181. package/dist/types/src/db-host/query-state.d.ts.map +0 -1
  182. package/src/db-host/query-state.ts +0 -217
@@ -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-32WDI3LB.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";
@@ -31,8 +36,8 @@ import { SpaceId as SpaceId2 } from "@dxos/keys";
31
36
  import { log as log7 } from "@dxos/log";
32
37
 
33
38
  // packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts
39
+ import { next as A } from "@automerge/automerge";
34
40
  import { UpdateScheduler } from "@dxos/async";
35
- import { next as A } from "@dxos/automerge/automerge";
36
41
  import { Resource } from "@dxos/context";
37
42
  import { invariant } from "@dxos/invariant";
38
43
  import { log } from "@dxos/log";
@@ -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) {
@@ -52,15 +53,15 @@ var DocumentsSynchronizer = class extends Resource {
52
53
  documentIds
53
54
  }, {
54
55
  F: __dxlog_file,
55
- L: 49,
56
+ L: 50,
56
57
  S: this,
57
58
  C: (f, a) => f(...a)
58
59
  });
59
60
  return;
60
61
  }
61
62
  for (const documentId of documentIds) {
62
- const doc = this._params.repo.find(documentId);
63
- doc.whenReady().then(() => {
63
+ this._params.repo.find(documentId).then(async (doc) => {
64
+ await doc.whenReady();
64
65
  this._startSync(doc);
65
66
  this._pendingUpdates.add(doc.documentId);
66
67
  this._sendUpdatesJob.trigger();
@@ -70,7 +71,7 @@ var DocumentsSynchronizer = class extends Resource {
70
71
  error
71
72
  }, {
72
73
  F: __dxlog_file,
73
- L: 63,
74
+ L: 64,
74
75
  S: this,
75
76
  C: (f, a) => f(...a)
76
77
  });
@@ -99,7 +100,7 @@ var DocumentsSynchronizer = class extends Resource {
99
100
  update(updates) {
100
101
  for (const { documentId, mutation, isNew } of updates) {
101
102
  if (isNew) {
102
- const doc = this._params.repo.find(documentId);
103
+ const { handle: doc } = this._params.repo.findWithProgress(documentId);
103
104
  doc.update((doc2) => A.loadIncremental(doc2, mutation));
104
105
  this._startSync(doc);
105
106
  } else {
@@ -113,7 +114,7 @@ var DocumentsSynchronizer = class extends Resource {
113
114
  documentId: doc.documentId
114
115
  }, {
115
116
  F: __dxlog_file,
116
- L: 102,
117
+ L: 103,
117
118
  S: this,
118
119
  C: (f, a) => f(...a)
119
120
  });
@@ -156,17 +157,18 @@ var DocumentsSynchronizer = class extends Resource {
156
157
  const syncState = this._syncStates.get(documentId);
157
158
  invariant(syncState, "Sync state for document not found", {
158
159
  F: __dxlog_file,
159
- L: 143,
160
+ L: 144,
160
161
  S: this,
161
162
  A: [
162
163
  "syncState",
163
164
  "'Sync state for document not found'"
164
165
  ]
165
166
  });
166
- const doc = syncState.handle.docSync();
167
- if (!doc) {
167
+ const handle = syncState.handle;
168
+ if (!handle || !handle.isReady() || !handle.doc()) {
168
169
  return;
169
170
  }
171
+ const doc = handle.doc();
170
172
  const mutation = syncState.lastSentHead ? A.saveSince(doc, syncState.lastSentHead) : A.save(doc);
171
173
  if (mutation.length === 0) {
172
174
  return;
@@ -178,7 +180,7 @@ var DocumentsSynchronizer = class extends Resource {
178
180
  const syncState = this._syncStates.get(documentId);
179
181
  invariant(syncState, "Sync state for document not found", {
180
182
  F: __dxlog_file,
181
- L: 158,
183
+ L: 160,
182
184
  S: this,
183
185
  A: [
184
186
  "syncState",
@@ -197,10 +199,11 @@ var DocumentsSynchronizer = class extends Resource {
197
199
  };
198
200
 
199
201
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
202
+ import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@automerge/automerge";
203
+ import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
200
204
  import { Event as Event2, asyncTimeout } from "@dxos/async";
201
- import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@dxos/automerge/automerge";
202
- import { Repo, interpretAsDocumentId } from "@dxos/automerge/automerge-repo";
203
205
  import { Context, Resource as Resource4, cancelWithContext } from "@dxos/context";
206
+ import { DatabaseDirectory } from "@dxos/echo-protocol";
204
207
  import { invariant as invariant3 } from "@dxos/invariant";
205
208
  import { PublicKey } from "@dxos/keys";
206
209
  import { log as log4 } from "@dxos/log";
@@ -209,8 +212,8 @@ import { trace as trace2 } from "@dxos/tracing";
209
212
  import { bufferToArray } from "@dxos/util";
210
213
 
211
214
  // packages/core/echo/echo-pipeline/src/automerge/collection-synchronizer.ts
215
+ import { next as am } from "@automerge/automerge";
212
216
  import { asyncReturn, Event, scheduleTask, scheduleTaskInterval } from "@dxos/async";
213
- import { next as am } from "@dxos/automerge/automerge";
214
217
  import { Resource as Resource2 } from "@dxos/context";
215
218
  import { log as log2 } from "@dxos/log";
216
219
  import { trace } from "@dxos/tracing";
@@ -263,7 +266,7 @@ var CollectionSynchronizer = class extends Resource2 {
263
266
  state
264
267
  }, {
265
268
  F: __dxlog_file2,
266
- L: 75,
269
+ L: 76,
267
270
  S: this,
268
271
  C: (f, a) => f(...a)
269
272
  });
@@ -282,7 +285,7 @@ var CollectionSynchronizer = class extends Resource2 {
282
285
  collectionId
283
286
  }, {
284
287
  F: __dxlog_file2,
285
- L: 89,
288
+ L: 90,
286
289
  S: this,
287
290
  C: (f, a) => f(...a)
288
291
  });
@@ -365,7 +368,7 @@ var CollectionSynchronizer = class extends Resource2 {
365
368
  state
366
369
  }, {
367
370
  F: __dxlog_file2,
368
- L: 170,
371
+ L: 171,
369
372
  S: this,
370
373
  C: (f, a) => f(...a)
371
374
  });
@@ -461,8 +464,8 @@ var getSpanName = (peerId) => {
461
464
  };
462
465
 
463
466
  // packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
467
+ import { NetworkAdapter } from "@automerge/automerge-repo";
464
468
  import { synchronized, Trigger } from "@dxos/async";
465
- import { NetworkAdapter } from "@dxos/automerge/automerge-repo";
466
469
  import { LifecycleState } from "@dxos/context";
467
470
  import { invariant as invariant2 } from "@dxos/invariant";
468
471
  import { log as log3 } from "@dxos/log";
@@ -483,12 +486,13 @@ function _ts_decorate2(decorators, target, key, desc) {
483
486
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
484
487
  var EchoNetworkAdapter = class extends NetworkAdapter {
485
488
  constructor(_params) {
486
- super();
487
- this._params = _params;
488
- this._replicators = /* @__PURE__ */ new Set();
489
- this._connections = /* @__PURE__ */ new Map();
490
- this._lifecycleState = LifecycleState.CLOSED;
491
- this._connected = 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();
490
+ }
491
+ isReady() {
492
+ return this._lifecycleState === LifecycleState.OPEN;
493
+ }
494
+ whenReady() {
495
+ return this._ready.wait();
492
496
  }
493
497
  connect(peerId, peerMetadata) {
494
498
  this.peerId = peerId;
@@ -505,15 +509,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
505
509
  return;
506
510
  }
507
511
  this._lifecycleState = LifecycleState.OPEN;
508
- log3("emit ready", void 0, {
509
- F: __dxlog_file3,
510
- L: 82,
511
- S: this,
512
- C: (f, a) => f(...a)
513
- });
514
- this.emit("ready", {
515
- network: this
516
- });
512
+ this._ready.wake();
517
513
  }
518
514
  async close() {
519
515
  if (this._lifecycleState === LifecycleState.CLOSED) {
@@ -523,6 +519,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
523
519
  await replicator.disconnect();
524
520
  }
525
521
  this._replicators.clear();
522
+ this._ready.reset();
526
523
  this._lifecycleState = LifecycleState.CLOSED;
527
524
  }
528
525
  async whenConnected() {
@@ -533,7 +530,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
533
530
  async addReplicator(replicator) {
534
531
  invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
535
532
  F: __dxlog_file3,
536
- L: 108,
533
+ L: 115,
537
534
  S: this,
538
535
  A: [
539
536
  "this._lifecycleState === LifecycleState.OPEN",
@@ -542,7 +539,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
542
539
  });
543
540
  invariant2(this.peerId, void 0, {
544
541
  F: __dxlog_file3,
545
- L: 109,
542
+ L: 116,
546
543
  S: this,
547
544
  A: [
548
545
  "this.peerId",
@@ -551,7 +548,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
551
548
  });
552
549
  invariant2(!this._replicators.has(replicator), void 0, {
553
550
  F: __dxlog_file3,
554
- L: 110,
551
+ L: 117,
555
552
  S: this,
556
553
  A: [
557
554
  "!this._replicators.has(replicator)",
@@ -575,7 +572,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
575
572
  async removeReplicator(replicator) {
576
573
  invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
577
574
  F: __dxlog_file3,
578
- L: 129,
575
+ L: 136,
579
576
  S: this,
580
577
  A: [
581
578
  "this._lifecycleState === LifecycleState.OPEN",
@@ -584,7 +581,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
584
581
  });
585
582
  invariant2(this._replicators.has(replicator), void 0, {
586
583
  F: __dxlog_file3,
587
- L: 130,
584
+ L: 137,
588
585
  S: this,
589
586
  A: [
590
587
  "this._replicators.has(replicator)",
@@ -640,7 +637,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
640
637
  if (connectionEntry.isOpen) {
641
638
  log3.catch(err, void 0, {
642
639
  F: __dxlog_file3,
643
- L: 190,
640
+ L: 197,
644
641
  S: this,
645
642
  C: (f, a) => f(...a)
646
643
  });
@@ -661,13 +658,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
661
658
  peerId: connection.peerId
662
659
  }, {
663
660
  F: __dxlog_file3,
664
- L: 208,
661
+ L: 215,
665
662
  S: this,
666
663
  C: (f, a) => f(...a)
667
664
  });
668
665
  invariant2(!this._connections.has(connection.peerId), void 0, {
669
666
  F: __dxlog_file3,
670
- L: 209,
667
+ L: 216,
671
668
  S: this,
672
669
  A: [
673
670
  "!this._connections.has(connection.peerId as PeerId)",
@@ -696,7 +693,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
696
693
  if (connectionEntry.isOpen) {
697
694
  log3.catch(err, void 0, {
698
695
  F: __dxlog_file3,
699
- L: 228,
696
+ L: 235,
700
697
  S: this,
701
698
  C: (f, a) => f(...a)
702
699
  });
@@ -707,7 +704,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
707
704
  peerId: connection.peerId
708
705
  }, {
709
706
  F: __dxlog_file3,
710
- L: 233,
707
+ L: 240,
711
708
  S: this,
712
709
  C: (f, a) => f(...a)
713
710
  });
@@ -739,14 +736,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
739
736
  peerId: connection.peerId
740
737
  }, {
741
738
  F: __dxlog_file3,
742
- L: 261,
739
+ L: 268,
743
740
  S: this,
744
741
  C: (f, a) => f(...a)
745
742
  });
746
743
  const entry = this._connections.get(connection.peerId);
747
744
  invariant2(entry, void 0, {
748
745
  F: __dxlog_file3,
749
- L: 263,
746
+ L: 270,
750
747
  S: this,
751
748
  A: [
752
749
  "entry",
@@ -763,14 +760,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
763
760
  peerId: connection.peerId
764
761
  }, {
765
762
  F: __dxlog_file3,
766
- L: 269,
763
+ L: 276,
767
764
  S: this,
768
765
  C: (f, a) => f(...a)
769
766
  });
770
767
  const entry = this._connections.get(connection.peerId);
771
768
  invariant2(entry, void 0, {
772
769
  F: __dxlog_file3,
773
- L: 271,
770
+ L: 278,
774
771
  S: this,
775
772
  A: [
776
773
  "entry",
@@ -784,13 +781,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
784
781
  this._params.monitor?.recordPeerDisconnected(connection.peerId);
785
782
  void entry.reader.cancel().catch((err) => log3.catch(err, void 0, {
786
783
  F: __dxlog_file3,
787
- L: 277,
784
+ L: 284,
788
785
  S: this,
789
786
  C: (f, a) => f(...a)
790
787
  }));
791
788
  void entry.writer.abort().catch((err) => log3.catch(err, void 0, {
792
789
  F: __dxlog_file3,
793
- L: 278,
790
+ L: 285,
794
791
  S: this,
795
792
  C: (f, a) => f(...a)
796
793
  }));
@@ -847,8 +844,7 @@ var HeadsStore = class {
847
844
  import { LifecycleState as LifecycleState2, Resource as Resource3 } from "@dxos/context";
848
845
  var LevelDBStorageAdapter = class extends Resource3 {
849
846
  constructor(_params) {
850
- super();
851
- this._params = _params;
847
+ super(), this._params = _params;
852
848
  }
853
849
  async load(keyArray) {
854
850
  try {
@@ -957,6 +953,12 @@ function _ts_decorate3(decorators, target, key, desc) {
957
953
  return c > 3 && r && Object.defineProperty(target, key, r), r;
958
954
  }
959
955
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
956
+ var FIND_PARAMS = {
957
+ allowableStates: [
958
+ "ready",
959
+ "requesting"
960
+ ]
961
+ };
960
962
  var AutomergeHost = class extends Resource4 {
961
963
  constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
962
964
  super();
@@ -1056,7 +1058,7 @@ var AutomergeHost = class extends Resource4 {
1056
1058
  handle = this._repo.handles[documentId];
1057
1059
  }
1058
1060
  if (!handle) {
1059
- handle = this._repo.find(documentId);
1061
+ handle = await this._repo.find(documentId, FIND_PARAMS);
1060
1062
  }
1061
1063
  if (!handle.isReady()) {
1062
1064
  if (!opts?.timeout) {
@@ -1112,12 +1114,12 @@ var AutomergeHost = class extends Resource4 {
1112
1114
  await Promise.all(headsToWait.map(async (entry, index) => {
1113
1115
  const handle = await this.loadDoc(Context.default(void 0, {
1114
1116
  F: __dxlog_file4,
1115
- L: 282
1117
+ L: 288
1116
1118
  }), entry.documentId);
1117
1119
  await waitForHeads(handle, entry.heads);
1118
1120
  }));
1119
1121
  }
1120
- await this._repo.flush(documentIds.filter((documentId) => !!this._repo.handles[documentId]));
1122
+ await this._repo.flush(documentIds.filter((documentId) => this._repo.handles[documentId] && this._repo.handles[documentId].isReady()));
1121
1123
  }
1122
1124
  async reIndexHeads(documentIds) {
1123
1125
  for (const documentId of documentIds) {
@@ -1125,46 +1127,30 @@ var AutomergeHost = class extends Resource4 {
1125
1127
  documentId
1126
1128
  }, {
1127
1129
  F: __dxlog_file4,
1128
- L: 294,
1130
+ L: 302,
1129
1131
  S: this,
1130
1132
  C: (f, a) => f(...a)
1131
1133
  });
1132
- const handle = this._repo.find(documentId);
1133
- await handle.whenReady([
1134
- "ready",
1135
- "requesting"
1136
- ]);
1137
- if (handle.inState([
1138
- "requesting"
1139
- ])) {
1134
+ const handle = await this._repo.find(documentId, FIND_PARAMS);
1135
+ if (!handle.isReady()) {
1140
1136
  log4.warn("document is not available locally, skipping", {
1141
1137
  documentId
1142
1138
  }, {
1143
1139
  F: __dxlog_file4,
1144
- L: 298,
1140
+ L: 305,
1145
1141
  S: this,
1146
1142
  C: (f, a) => f(...a)
1147
1143
  });
1148
1144
  continue;
1149
1145
  }
1150
- const doc = handle.docSync();
1151
- invariant3(doc, void 0, {
1152
- F: __dxlog_file4,
1153
- L: 303,
1154
- S: this,
1155
- A: [
1156
- "doc",
1157
- ""
1158
- ]
1159
- });
1160
- const heads = getHeads(doc);
1146
+ const heads = handle.heads();
1161
1147
  const batch = this._db.batch();
1162
1148
  this._headsStore.setHeads(documentId, heads, batch);
1163
1149
  await batch.write();
1164
1150
  }
1165
1151
  log4.info("done re-indexing heads", void 0, {
1166
1152
  F: __dxlog_file4,
1167
- L: 310,
1153
+ L: 314,
1168
1154
  S: this,
1169
1155
  C: (f, a) => f(...a)
1170
1156
  });
@@ -1190,16 +1176,16 @@ var AutomergeHost = class extends Resource4 {
1190
1176
  }
1191
1177
  async _beforeSave({ path, batch }) {
1192
1178
  const handle = this._repo.handles[path[0]];
1193
- if (!handle) {
1179
+ if (!handle || !handle.isReady()) {
1194
1180
  return;
1195
1181
  }
1196
- const doc = handle.docSync();
1182
+ const doc = handle.doc();
1197
1183
  if (!doc) {
1198
1184
  return;
1199
1185
  }
1200
1186
  const heads = getHeads(doc);
1201
1187
  this._headsStore.setHeads(handle.documentId, heads, batch);
1202
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
1188
+ const spaceKey = DatabaseDirectory.getSpaceKey(doc) ?? void 0;
1203
1189
  const objectIds = Object.keys(doc.objects ?? {});
1204
1190
  const encodedIds = objectIds.map((objectId) => objectPointerCodec.encode({
1205
1191
  documentId: handle.documentId,
@@ -1227,7 +1213,7 @@ var AutomergeHost = class extends Resource4 {
1227
1213
  async _afterSave(path) {
1228
1214
  this._indexMetadataStore.notifyMarkedDirty();
1229
1215
  const documentId = path[0];
1230
- const document = this._repo.handles[documentId]?.docSync();
1216
+ const document = this._repo.handles[documentId]?.doc();
1231
1217
  if (document) {
1232
1218
  const heads = getHeads(document);
1233
1219
  this._onHeadsChanged(documentId, heads);
@@ -1247,9 +1233,12 @@ var AutomergeHost = class extends Resource4 {
1247
1233
  return false;
1248
1234
  }
1249
1235
  async _getContainingSpaceForDocument(documentId) {
1250
- const doc = this._repo.handles[documentId]?.docSync();
1251
- if (doc) {
1252
- const spaceKeyHex = getSpaceKeyFromDoc(doc);
1236
+ const handle = this._repo.handles[documentId];
1237
+ if (handle.state === "loading") {
1238
+ await handle.whenReady();
1239
+ }
1240
+ if (handle && handle.isReady() && handle.doc()) {
1241
+ const spaceKeyHex = DatabaseDirectory.getSpaceKey(handle.doc());
1253
1242
  if (spaceKeyHex) {
1254
1243
  return PublicKey.from(spaceKeyHex);
1255
1244
  }
@@ -1264,7 +1253,10 @@ var AutomergeHost = class extends Resource4 {
1264
1253
  * Flush documents to disk.
1265
1254
  */
1266
1255
  async flush({ documentIds } = {}) {
1267
- 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
+ });
1268
1260
  await this._repo.flush(loadedDocuments);
1269
1261
  }
1270
1262
  async getHeads(documentIds) {
@@ -1272,9 +1264,9 @@ var AutomergeHost = class extends Resource4 {
1272
1264
  const storeRequestIds = [];
1273
1265
  const storeResultIndices = [];
1274
1266
  for (const documentId of documentIds) {
1275
- const doc = this._repo.handles[documentId]?.docSync();
1276
- if (doc) {
1277
- result.push(getHeads(doc));
1267
+ const handle = this._repo.handles[documentId];
1268
+ if (handle && handle.isReady() && handle.doc()) {
1269
+ result.push(getHeads(handle.doc()));
1278
1270
  } else {
1279
1271
  storeRequestIds.push(documentId);
1280
1272
  storeResultIndices.push(result.length);
@@ -1379,12 +1371,12 @@ var AutomergeHost = class extends Resource4 {
1379
1371
  count: toReplicate.length
1380
1372
  }, {
1381
1373
  F: __dxlog_file4,
1382
- L: 549,
1374
+ L: 557,
1383
1375
  S: this,
1384
1376
  C: (f, a) => f(...a)
1385
1377
  });
1386
1378
  for (const documentId of toReplicate) {
1387
- this._repo.find(documentId);
1379
+ this._repo.findWithProgress(documentId);
1388
1380
  }
1389
1381
  }
1390
1382
  _onHeadsChanged(documentId, heads) {
@@ -1421,19 +1413,12 @@ _ts_decorate3([
1421
1413
  AutomergeHost = _ts_decorate3([
1422
1414
  trace2.resource()
1423
1415
  ], AutomergeHost);
1424
- var getSpaceKeyFromDoc = (doc) => {
1425
- const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
1426
- if (rawSpaceKey == null) {
1427
- return null;
1428
- }
1429
- return String(rawSpaceKey);
1430
- };
1431
1416
  var waitForHeads = async (handle, heads) => {
1432
1417
  const unavailableHeads = new Set(heads);
1433
1418
  await handle.whenReady();
1434
1419
  await Event2.wrap(handle, "change").waitForCondition(() => {
1435
1420
  for (const changeHash of unavailableHeads.values()) {
1436
- if (changeIsPresentInDoc(handle.docSync(), changeHash)) {
1421
+ if (changeIsPresentInDoc(handle.doc(), changeHash)) {
1437
1422
  unavailableHeads.delete(changeHash);
1438
1423
  }
1439
1424
  }
@@ -1446,7 +1431,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
1446
1431
  var decodeCollectionState = (state) => {
1447
1432
  invariant3(typeof state === "object" && state !== null, "Invalid state", {
1448
1433
  F: __dxlog_file4,
1449
- L: 610,
1434
+ L: 608,
1450
1435
  S: void 0,
1451
1436
  A: [
1452
1437
  "typeof state === 'object' && state !== null",
@@ -1466,8 +1451,8 @@ import { log as log6 } from "@dxos/log";
1466
1451
  import { ComplexSet, defaultMap as defaultMap2 } from "@dxos/util";
1467
1452
 
1468
1453
  // packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts
1469
- import * as A2 from "@dxos/automerge/automerge";
1470
- import { cbor } from "@dxos/automerge/automerge-repo";
1454
+ import * as A2 from "@automerge/automerge";
1455
+ import { cbor } from "@automerge/automerge-repo";
1471
1456
  import { Resource as Resource5 } from "@dxos/context";
1472
1457
  import { invariant as invariant4 } from "@dxos/invariant";
1473
1458
  import { log as log5 } from "@dxos/log";
@@ -1476,11 +1461,7 @@ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipelin
1476
1461
  var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
1477
1462
  var MeshReplicatorConnection = class extends Resource5 {
1478
1463
  constructor(_params) {
1479
- super();
1480
- this._params = _params;
1481
- this.remoteDeviceKey = null;
1482
- this._remotePeerId = null;
1483
- this._isEnabled = false;
1464
+ super(), this._params = _params, this.remoteDeviceKey = null, this._remotePeerId = null, this._isEnabled = false;
1484
1465
  let readableStreamController;
1485
1466
  this.readable = new ReadableStream({
1486
1467
  start: (controller) => {
@@ -1492,7 +1473,7 @@ var MeshReplicatorConnection = class extends Resource5 {
1492
1473
  write: async (message, controller) => {
1493
1474
  invariant4(this._isEnabled, "Writing to a disabled connection", {
1494
1475
  F: __dxlog_file5,
1495
- L: 50,
1476
+ L: 51,
1496
1477
  S: this,
1497
1478
  A: [
1498
1479
  "this._isEnabled",
@@ -1525,7 +1506,7 @@ var MeshReplicatorConnection = class extends Resource5 {
1525
1506
  remotePeerId: remotePeerId.toHex()
1526
1507
  }, {
1527
1508
  F: __dxlog_file5,
1528
- L: 79,
1509
+ L: 80,
1529
1510
  S: this,
1530
1511
  C: (f, a) => f(...a)
1531
1512
  });
@@ -1552,7 +1533,7 @@ var MeshReplicatorConnection = class extends Resource5 {
1552
1533
  get peerId() {
1553
1534
  invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
1554
1535
  F: __dxlog_file5,
1555
- L: 105,
1536
+ L: 106,
1556
1537
  S: this,
1557
1538
  A: [
1558
1539
  "this._remotePeerId != null",
@@ -1577,7 +1558,7 @@ var MeshReplicatorConnection = class extends Resource5 {
1577
1558
  enable() {
1578
1559
  invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
1579
1560
  F: __dxlog_file5,
1580
- L: 126,
1561
+ L: 127,
1581
1562
  S: this,
1582
1563
  A: [
1583
1564
  "this._remotePeerId != null",
@@ -1608,7 +1589,7 @@ var logSendSync = (message) => {
1608
1589
  };
1609
1590
  }, {
1610
1591
  F: __dxlog_file5,
1611
- L: 139,
1592
+ L: 140,
1612
1593
  S: void 0,
1613
1594
  C: (f, a) => f(...a)
1614
1595
  });
@@ -1623,7 +1604,7 @@ var getSpaceIdFromCollectionId = (collectionId) => {
1623
1604
  const spaceId = collectionId.split(":")[1];
1624
1605
  invariant5(SpaceId.isValid(spaceId), void 0, {
1625
1606
  F: __dxlog_file6,
1626
- L: 15,
1607
+ L: 16,
1627
1608
  S: void 0,
1628
1609
  A: [
1629
1610
  "SpaceId.isValid(spaceId)",
@@ -1889,7 +1870,7 @@ var EchoDataMonitor = class {
1889
1870
  this._localTimeSeries = createLocalTimeSeries();
1890
1871
  this._storageAverages = createStorageAverages();
1891
1872
  this._replicationAverages = createNetworkAverages();
1892
- this._sizeByMessageType = {};
1873
+ this._sizeByMessage = {};
1893
1874
  this._lastReceivedMessages = new CircularBuffer(100);
1894
1875
  this._lastSentMessages = new CircularBuffer(100);
1895
1876
  this._connectionsCount = 0;
@@ -1927,8 +1908,8 @@ var EchoDataMonitor = class {
1927
1908
  countPerSecond: this._replicationAverages.sentPerSecond.average(),
1928
1909
  failedPerSecond: this._replicationAverages.sendsFailedPerSecond.average()
1929
1910
  },
1930
- countByMessageType: this._computeMessageHistogram("type"),
1931
- avgSizeByMessageType: mapValues(this._sizeByMessageType, (summary) => summary.average())
1911
+ countByMessage: this._computeMessageHistogram("type"),
1912
+ avgSizeByMessage: mapValues(this._sizeByMessage, (summary) => summary.average())
1932
1913
  }
1933
1914
  };
1934
1915
  }
@@ -2133,7 +2114,7 @@ var EchoDataMonitor = class {
2133
2114
  messageCounts.failed++;
2134
2115
  }
2135
2116
  _getStatsForType(message) {
2136
- const messageSize = this._sizeByMessageType[message.type] ??= createSlidingWindow();
2117
+ const messageSize = this._sizeByMessage[message.type] ??= createSlidingWindow();
2137
2118
  const messageCounts = this._activeCounters.byType[message.type] ??= createMessageCounter();
2138
2119
  return {
2139
2120
  messageCounts,
@@ -2253,7 +2234,7 @@ var DataServiceImpl = class {
2253
2234
  ready();
2254
2235
  }).catch((err) => log7.catch(err, void 0, {
2255
2236
  F: __dxlog_file8,
2256
- L: 70,
2237
+ L: 71,
2257
2238
  S: this,
2258
2239
  C: (f, a) => f(...a)
2259
2240
  }));
@@ -2264,7 +2245,7 @@ var DataServiceImpl = class {
2264
2245
  const synchronizer = this._subscriptions.get(request.subscriptionId);
2265
2246
  invariant7(synchronizer, "Subscription not found", {
2266
2247
  F: __dxlog_file8,
2267
- L: 77,
2248
+ L: 78,
2268
2249
  S: this,
2269
2250
  A: [
2270
2251
  "synchronizer",
@@ -2285,7 +2266,7 @@ var DataServiceImpl = class {
2285
2266
  const synchronizer = this._subscriptions.get(request.subscriptionId);
2286
2267
  invariant7(synchronizer, "Subscription not found", {
2287
2268
  F: __dxlog_file8,
2288
- L: 92,
2269
+ L: 93,
2289
2270
  S: this,
2290
2271
  A: [
2291
2272
  "synchronizer",
@@ -2330,7 +2311,7 @@ var DataServiceImpl = class {
2330
2311
  const spaceId = request.spaceId;
2331
2312
  invariant7(SpaceId2.isValid(spaceId), void 0, {
2332
2313
  F: __dxlog_file8,
2333
- L: 132,
2314
+ L: 133,
2334
2315
  S: this,
2335
2316
  A: [
2336
2317
  "SpaceId.isValid(spaceId)",
@@ -2372,18 +2353,18 @@ var DataServiceImpl = class {
2372
2353
  };
2373
2354
 
2374
2355
  // packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
2375
- import { LifecycleState as LifecycleState4, Resource as Resource9 } from "@dxos/context";
2356
+ import { LifecycleState as LifecycleState5, Resource as Resource9 } from "@dxos/context";
2376
2357
  import { todo } from "@dxos/debug";
2377
- import { createIdFromSpaceKey as createIdFromSpaceKey3, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
2358
+ import { createIdFromSpaceKey as createIdFromSpaceKey2, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
2378
2359
  import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
2379
- import { invariant as invariant11 } from "@dxos/invariant";
2360
+ import { invariant as invariant13 } from "@dxos/invariant";
2380
2361
  import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
2381
- import { trace as trace6 } from "@dxos/tracing";
2362
+ import { trace as trace5 } from "@dxos/tracing";
2382
2363
 
2383
2364
  // packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts
2384
- import * as A3 from "@dxos/automerge/automerge";
2365
+ import * as A3 from "@automerge/automerge";
2385
2366
  import { Context as Context2 } from "@dxos/context";
2386
- import { SpaceDocVersion } from "@dxos/echo-protocol";
2367
+ import { DatabaseDirectory as DatabaseDirectory2, SpaceDocVersion } from "@dxos/echo-protocol";
2387
2368
  import { invariant as invariant8 } from "@dxos/invariant";
2388
2369
  import { log as log8 } from "@dxos/log";
2389
2370
  import { ObjectPointerVersion, objectPointerCodec as objectPointerCodec2 } from "@dxos/protocols";
@@ -2400,12 +2381,12 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2400
2381
  const { documentId, objectId } = objectPointerCodec2.decode(id);
2401
2382
  const handle = await automergeHost.loadDoc(Context2.default(void 0, {
2402
2383
  F: __dxlog_file9,
2403
- L: 30
2384
+ L: 31
2404
2385
  }), documentId);
2405
- let doc = handle.docSync();
2386
+ let doc = handle.doc();
2406
2387
  invariant8(doc, void 0, {
2407
2388
  F: __dxlog_file9,
2408
- L: 33,
2389
+ L: 34,
2409
2390
  S: this,
2410
2391
  A: [
2411
2392
  "doc",
@@ -2424,7 +2405,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2424
2405
  originalHeads: currentHeads
2425
2406
  }, {
2426
2407
  F: __dxlog_file9,
2427
- L: 44,
2408
+ L: 45,
2428
2409
  S: this,
2429
2410
  C: (f, a) => f(...a)
2430
2411
  });
@@ -2438,7 +2419,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2438
2419
  }
2439
2420
  let newId = id;
2440
2421
  if (objectPointerCodec2.getVersion(id) === ObjectPointerVersion.V0) {
2441
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
2422
+ const spaceKey = DatabaseDirectory2.getSpaceKey(doc) ?? void 0;
2442
2423
  newId = objectPointerCodec2.encode({
2443
2424
  documentId,
2444
2425
  objectId,
@@ -2459,7 +2440,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2459
2440
  error
2460
2441
  }, {
2461
2442
  F: __dxlog_file9,
2462
- L: 70,
2443
+ L: 71,
2463
2444
  S: this,
2464
2445
  C: (f, a) => f(...a)
2465
2446
  });
@@ -2469,219 +2450,1042 @@ var createSelectedDocumentsIterator = (automergeHost) => (
2469
2450
  );
2470
2451
 
2471
2452
  // packages/core/echo/echo-pipeline/src/db-host/query-service.ts
2453
+ import { getHeads as getHeads3 } from "@automerge/automerge";
2454
+ import { Schema } from "effect";
2472
2455
  import { DeferredTask } from "@dxos/async";
2473
- import { getHeads as getHeads3 } from "@dxos/automerge/automerge";
2474
2456
  import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
2475
2457
  import { Context as Context4, Resource as Resource7 } from "@dxos/context";
2476
- 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";
2477
2461
  import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
2478
- import { trace as trace5 } from "@dxos/tracing";
2462
+ import { trace as trace4 } from "@dxos/tracing";
2479
2463
 
2480
- // packages/core/echo/echo-pipeline/src/db-host/query-state.ts
2481
- import { Context as Context3, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
2482
- import { createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
2483
- 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";
2484
2470
  import { DXN, PublicKey as PublicKey3 } from "@dxos/keys";
2471
+ import { log as log9 } from "@dxos/log";
2485
2472
  import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
2486
- import { trace as trace4 } from "@dxos/tracing";
2487
- import { isNonNullable as isNonNullable2 } from "@dxos/util";
2488
- function _ts_decorate5(decorators, target, key, desc) {
2489
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2490
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2491
- 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;
2492
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2493
- }
2494
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-state.ts";
2495
- var QueryState = class extends Resource6 {
2496
- get active() {
2497
- 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
+ };
2498
2515
  }
2499
- constructor(_params) {
2500
- super();
2501
- this._params = _params;
2502
- this._results = [];
2503
- this._firstRun = true;
2504
- this.metrics = {
2505
- objectsReturned: 0,
2506
- objectsReturnedFromIndex: 0,
2507
- documentsLoaded: 0,
2508
- executionTime: 0,
2509
- indexQueryTime: 0,
2510
- 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
2511
2554
  };
2512
- 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
+ }
2513
2729
  }
2514
- getResults() {
2515
- 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
+ }
2516
2749
  }
2517
- // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/db.md#generic-database-attributes
2518
- async execQuery() {
2519
- const filter = this._params.request.filter;
2520
- const beginQuery = performance.now();
2521
- const hits = filter.objectIds && filter.objectIds?.length > 0 ? [] : await this._params.indexer.execQuery(filterToIndexQuery(filter));
2522
- if (this._firstRun) {
2523
- this.metrics.indexQueryTime = performance.now() - beginQuery;
2524
- }
2525
- const beginFilter = performance.now();
2526
- const results = (await Promise.all(hits.map(async (result) => {
2527
- if (this._firstRun) {
2528
- this.metrics.objectsReturnedFromIndex++;
2529
- }
2530
- const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(result.id);
2531
- let spaceKey;
2532
- if (spaceKeyInIndex !== void 0) {
2533
- spaceKey = spaceKeyInIndex;
2534
- } else {
2535
- if (this._firstRun) {
2536
- 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
2537
2767
  }
2538
- const handle = await this._params.automergeHost.loadDoc(Context3.default(void 0, {
2539
- F: __dxlog_file10,
2540
- L: 117
2541
- }), documentId);
2542
- if (this._ctx.disposed) {
2543
- 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: {}
2544
2790
  }
2545
- spaceKey = getSpaceKeyFromDoc(handle.docSync());
2546
2791
  }
2547
- if (!spaceKey) {
2548
- 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
+ ]);
2549
2802
  }
2550
- if (this._params.request.filter.options?.spaces?.length && !this._params.request.filter.options.spaces.some((key) => key.equals(spaceKey))) {
2551
- 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
+ ]);
2552
2809
  }
2553
- if (this._firstRun) {
2554
- this.metrics.objectsReturned++;
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
+ ]);
2555
2827
  }
2556
- return {
2557
- id: objectId,
2558
- documentId,
2559
- spaceId: await createIdFromSpaceKey2(PublicKey3.from(spaceKey)),
2560
- spaceKey: PublicKey3.from(spaceKey),
2561
- rank: result.rank
2562
- };
2563
- }))).filter(isNonNullable2);
2564
- if (this._firstRun) {
2565
- this.metrics.documentLoadTime = performance.now() - beginFilter;
2566
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
+ ]);
2875
+ }
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) {
2567
3039
  if (this._ctx.disposed) {
2568
3040
  return {
2569
- changed: false
3041
+ workingSet,
3042
+ trace: ExecutionTrace.makeEmpty()
2570
3043
  };
2571
3044
  }
2572
- 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));
2573
- if (this._firstRun) {
2574
- 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}`);
2575
3069
  }
2576
- this._firstRun = false;
2577
- if (areResultsUnchanged) {
2578
- return {
2579
- changed: false
2580
- };
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}`);
2581
3167
  }
2582
- this._results = results;
2583
3168
  return {
2584
- changed: true
3169
+ workingSet,
3170
+ trace: trace6
2585
3171
  };
2586
3172
  }
2587
- };
2588
- _ts_decorate5([
2589
- trace4.info({
2590
- depth: null
2591
- })
2592
- ], QueryState.prototype, "filter", void 0);
2593
- _ts_decorate5([
2594
- trace4.info()
2595
- ], QueryState.prototype, "metrics", void 0);
2596
- _ts_decorate5([
2597
- trace4.info()
2598
- ], QueryState.prototype, "active", null);
2599
- _ts_decorate5([
2600
- trace4.span({
2601
- showInBrowserTimeline: true,
2602
- op: "db.query",
2603
- attributes: {
2604
- "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}`);
2605
3328
  }
2606
- })
2607
- ], QueryState.prototype, "execQuery", null);
2608
- QueryState = _ts_decorate5([
2609
- trace4.resource()
2610
- ], QueryState);
2611
- var filterToIndexQuery = (filter) => {
2612
- invariant9(!(filter.type && (filter.or ?? []).length > 0), "Cannot mix type and or filters.", {
2613
- F: __dxlog_file10,
2614
- L: 184,
2615
- S: void 0,
2616
- A: [
2617
- "!(filter.type && (filter.or ?? []).length > 0)",
2618
- "'Cannot mix type and or filters.'"
2619
- ]
2620
- });
2621
- invariant9((filter.or ?? []).every((subFilter) => !(subFilter.type && (subFilter.or ?? []).length > 0)), "Cannot mix type and or filters.", {
2622
- F: __dxlog_file10,
2623
- L: 185,
2624
- S: void 0,
2625
- A: [
2626
- "(filter.or ?? []).every((subFilter) => !(subFilter.type && (subFilter.or ?? []).length > 0))",
2627
- "'Cannot mix type and or filters.'"
2628
- ]
2629
- });
2630
- if (filter.type || (filter.or ?? []).length > 0 && (filter.or ?? []).every((subFilter) => !subFilter.not && subFilter.type)) {
2631
3329
  return {
2632
- typenames: filter.type && filter.type.length > 0 ? filter.type.map((type) => dxnToIndexerTypename(DXN.parse(type))) : (filter.or ?? []).flatMap((f) => f.type?.map((type) => dxnToIndexerTypename(DXN.parse(type))) ?? []).filter(isNonNullable2),
2633
- 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"
2634
3342
  };
2635
- } 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
+ }
2636
3349
  return {
2637
- typenames: []
3350
+ workingSet: [
3351
+ ...results.values()
3352
+ ],
3353
+ trace: trace6
2638
3354
  };
2639
3355
  }
2640
- };
2641
- var dxnToIndexerTypename = (dxn) => {
2642
- switch (dxn.kind) {
2643
- case DXN.kind.TYPE:
2644
- return dxn.parts[0];
2645
- case DXN.kind.ECHO:
2646
- return dxn.parts[1];
2647
- default:
2648
- 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
+ };
2649
3455
  }
2650
3456
  };
2651
3457
 
2652
3458
  // packages/core/echo/echo-pipeline/src/db-host/query-service.ts
2653
- 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";
2654
3460
  var QueryServiceImpl = class extends Resource7 {
2655
3461
  // TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
2656
3462
  constructor(_params) {
2657
- super();
2658
- this._params = _params;
2659
- this._queries = /* @__PURE__ */ new Set();
2660
- this._updateQueries = new DeferredTask(this._ctx, async () => {
3463
+ super(), this._params = _params, this._queries = /* @__PURE__ */ new Set(), this._updateQueries = new DeferredTask(this._ctx, async () => {
2661
3464
  await Promise.all(Array.from(this._queries).map(async (query) => {
2662
3465
  try {
2663
- const { changed } = await query.state.execQuery();
3466
+ const { changed } = await query.executor.execQuery();
2664
3467
  if (changed) {
2665
- query.sendResults(query.state.getResults());
3468
+ query.sendResults(query.executor.getResults());
2666
3469
  }
2667
3470
  } catch (err) {
2668
- log9.catch(err, void 0, {
2669
- F: __dxlog_file11,
2670
- L: 52,
3471
+ log10.catch(err, void 0, {
3472
+ F: __dxlog_file12,
3473
+ L: 57,
2671
3474
  S: this,
2672
3475
  C: (f, a) => f(...a)
2673
3476
  });
2674
3477
  }
2675
3478
  }));
2676
3479
  });
2677
- trace5.diagnostic({
3480
+ trace4.diagnostic({
2678
3481
  id: "active-queries",
2679
3482
  name: "Active Queries",
2680
3483
  fetch: () => {
2681
3484
  return Array.from(this._queries).map((query) => {
2682
3485
  return {
2683
- filter: JSON.stringify(query.state.filter),
2684
- 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)
2685
3489
  };
2686
3490
  });
2687
3491
  }
@@ -2694,24 +3498,19 @@ var QueryServiceImpl = class extends Resource7 {
2694
3498
  await Promise.all(Array.from(this._queries).map((query) => query.close()));
2695
3499
  }
2696
3500
  async setConfig(config) {
2697
- if (this._params.indexer.initialized) {
2698
- log9.warn("Indexer already initialized.", void 0, {
2699
- F: __dxlog_file11,
2700
- L: 86,
2701
- S: this,
2702
- C: (f, a) => f(...a)
2703
- });
2704
- return;
2705
- }
2706
- this._params.indexer.setConfig(config);
3501
+ await this._params.indexer.setConfig(config);
2707
3502
  }
2708
3503
  execQuery(request) {
2709
3504
  return new Stream2(({ next, close, ctx }) => {
2710
- const query = {
2711
- state: new QueryState({
3505
+ const parsedQuery = QueryAST.Query.pipe(Schema.decodeUnknownSync)(JSON.parse(request.query));
3506
+ const queryEntry = {
3507
+ executor: new QueryExecutor({
2712
3508
  indexer: this._params.indexer,
2713
3509
  automergeHost: this._params.automergeHost,
2714
- request
3510
+ queryId: request.queryId ?? raise(new Error("query id required")),
3511
+ query: parsedQuery,
3512
+ reactivity: request.reactivity,
3513
+ spaceStateManager: this._params.spaceStateManager
2715
3514
  }),
2716
3515
  sendResults: (results) => {
2717
3516
  if (ctx.disposed) {
@@ -2724,37 +3523,30 @@ var QueryServiceImpl = class extends Resource7 {
2724
3523
  },
2725
3524
  close: async () => {
2726
3525
  close();
2727
- await query.state.close();
2728
- this._queries.delete(query);
3526
+ await queryEntry.executor.close();
3527
+ this._queries.delete(queryEntry);
2729
3528
  }
2730
3529
  };
2731
- this._queries.add(query);
3530
+ this._queries.add(queryEntry);
2732
3531
  queueMicrotask(async () => {
2733
- await query.state.open();
3532
+ await queryEntry.executor.open();
2734
3533
  try {
2735
- const { changed } = await query.state.execQuery();
2736
- if (changed) {
2737
- query.sendResults(query.state.getResults());
2738
- }
3534
+ await queryEntry.executor.execQuery();
3535
+ queryEntry.sendResults(queryEntry.executor.getResults());
2739
3536
  } catch (error) {
2740
- log9.catch(error, void 0, {
2741
- F: __dxlog_file11,
2742
- L: 123,
2743
- S: this,
2744
- C: (f, a) => f(...a)
2745
- });
3537
+ close(error);
2746
3538
  }
2747
3539
  });
2748
- return query.close;
3540
+ return queryEntry.close;
2749
3541
  });
2750
3542
  }
2751
3543
  /**
2752
3544
  * Re-index all loaded documents.
2753
3545
  */
2754
3546
  async reindex() {
2755
- log9.info("Reindexing all documents...", void 0, {
2756
- F: __dxlog_file11,
2757
- L: 135,
3547
+ log10.info("Reindexing all documents...", void 0, {
3548
+ F: __dxlog_file12,
3549
+ L: 141,
2758
3550
  S: this,
2759
3551
  C: (f, a) => f(...a)
2760
3552
  });
@@ -2765,21 +3557,21 @@ var QueryServiceImpl = class extends Resource7 {
2765
3557
  ids.set(id, heads);
2766
3558
  }
2767
3559
  if (ids.size % 100 === 0) {
2768
- log9.info("Collected documents...", {
3560
+ log10.info("Collected documents...", {
2769
3561
  count: ids.size
2770
3562
  }, {
2771
- F: __dxlog_file11,
2772
- L: 143,
3563
+ F: __dxlog_file12,
3564
+ L: 149,
2773
3565
  S: this,
2774
3566
  C: (f, a) => f(...a)
2775
3567
  });
2776
3568
  }
2777
3569
  }
2778
- log9.info("Marking all documents as dirty...", {
3570
+ log10.info("Marking all documents as dirty...", {
2779
3571
  count: ids.size
2780
3572
  }, {
2781
- F: __dxlog_file11,
2782
- L: 147,
3573
+ F: __dxlog_file12,
3574
+ L: 153,
2783
3575
  S: this,
2784
3576
  C: (f, a) => f(...a)
2785
3577
  });
@@ -2794,11 +3586,11 @@ var createDocumentsIterator = (automergeHost) => (
2794
3586
  async function* getAllDocuments() {
2795
3587
  const visited = /* @__PURE__ */ new Set();
2796
3588
  async function* getObjectsFromHandle(handle) {
2797
- if (visited.has(handle.documentId)) {
3589
+ if (visited.has(handle.documentId) || !handle.isReady()) {
2798
3590
  return;
2799
3591
  }
2800
- const doc = handle.docSync();
2801
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
3592
+ const doc = handle.doc();
3593
+ const spaceKey = DatabaseDirectory4.getSpaceKey(doc) ?? void 0;
2802
3594
  if (doc.objects) {
2803
3595
  yield Object.entries(doc.objects).map(([objectId, object]) => {
2804
3596
  return {
@@ -2819,8 +3611,8 @@ var createDocumentsIterator = (automergeHost) => (
2819
3611
  continue;
2820
3612
  }
2821
3613
  const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
2822
- F: __dxlog_file11,
2823
- L: 189
3614
+ F: __dxlog_file12,
3615
+ L: 195
2824
3616
  }), urlString);
2825
3617
  for await (const result of getObjectsFromHandle(linkHandle)) {
2826
3618
  yield result;
@@ -2842,20 +3634,21 @@ var createDocumentsIterator = (automergeHost) => (
2842
3634
  );
2843
3635
 
2844
3636
  // packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts
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 { interpretAsDocumentId as interpretAsDocumentId3 } from "@dxos/automerge/automerge-repo";
2848
- 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";
2849
3642
 
2850
3643
  // packages/core/echo/echo-pipeline/src/db-host/database-root.ts
2851
- import { interpretAsDocumentId as interpretAsDocumentId2 } from "@dxos/automerge/automerge-repo";
2852
- import { SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
2853
- import { invariant as invariant10 } from "@dxos/invariant";
3644
+ import { interpretAsDocumentId as interpretAsDocumentId2 } from "@automerge/automerge-repo";
3645
+ import { DatabaseDirectory as DatabaseDirectory5, SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
3646
+ import { invariant as invariant11 } from "@dxos/invariant";
2854
3647
 
2855
3648
  // packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts
2856
- import * as A4 from "@dxos/automerge/automerge";
2857
- import { log as log10 } from "@dxos/log";
2858
- var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
3649
+ import * as A4 from "@automerge/automerge";
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";
2859
3652
  var measureDocMetrics = (doc) => {
2860
3653
  const snapshot = A4.save(doc);
2861
3654
  const start = Date.now();
@@ -2866,11 +3659,11 @@ var measureDocMetrics = (doc) => {
2866
3659
  const mutationCount = A4.getAllChanges(doc).length;
2867
3660
  const getAllChangesEnd = Date.now();
2868
3661
  if (getAllChangesEnd - getAllChangesStart > 300) {
2869
- log10.warn("getAllChanges took too long", {
3662
+ log11.warn("getAllChanges took too long", {
2870
3663
  elapsed: getAllChangesEnd - getAllChangesStart
2871
3664
  }, {
2872
- F: __dxlog_file12,
2873
- L: 30,
3665
+ F: __dxlog_file13,
3666
+ L: 31,
2874
3667
  S: void 0,
2875
3668
  C: (f, a) => f(...a)
2876
3669
  });
@@ -2883,7 +3676,7 @@ var measureDocMetrics = (doc) => {
2883
3676
  };
2884
3677
 
2885
3678
  // packages/core/echo/echo-pipeline/src/db-host/database-root.ts
2886
- 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";
2887
3680
  var DatabaseRoot = class {
2888
3681
  static mapLinks(doc, mapping) {
2889
3682
  doc.change((d) => {
@@ -2908,47 +3701,47 @@ var DatabaseRoot = class {
2908
3701
  return this._rootHandle.url;
2909
3702
  }
2910
3703
  get isLoaded() {
2911
- return !!this._rootHandle.docSync();
3704
+ return this._rootHandle.isReady();
2912
3705
  }
2913
3706
  get handle() {
2914
3707
  return this._rootHandle;
2915
3708
  }
2916
- docSync() {
2917
- return this._rootHandle.docSync() ?? null;
3709
+ doc() {
3710
+ return this._rootHandle.isReady() ? this._rootHandle.doc() : null;
2918
3711
  }
2919
3712
  getVersion() {
2920
- const doc = this.docSync();
3713
+ const doc = this.doc();
2921
3714
  if (!doc) {
2922
3715
  return null;
2923
3716
  }
2924
3717
  return doc.version ?? SpaceDocVersion2.LEGACY;
2925
3718
  }
2926
3719
  getSpaceKey() {
2927
- const doc = this.docSync();
3720
+ const doc = this.doc();
2928
3721
  if (!doc) {
2929
3722
  return null;
2930
3723
  }
2931
- return getSpaceKeyFromDoc(doc);
3724
+ return DatabaseDirectory5.getSpaceKey(doc);
2932
3725
  }
2933
3726
  getInlineObjectCount() {
2934
- const doc = this.docSync();
3727
+ const doc = this.doc();
2935
3728
  if (!doc) {
2936
3729
  return null;
2937
3730
  }
2938
3731
  return Object.keys(doc.objects ?? {}).length;
2939
3732
  }
2940
3733
  getLinkedObjectCount() {
2941
- const doc = this.docSync();
3734
+ const doc = this.doc();
2942
3735
  if (!doc) {
2943
3736
  return null;
2944
3737
  }
2945
3738
  return Object.keys(doc.links ?? {}).length;
2946
3739
  }
2947
3740
  getAllLinkedDocuments() {
2948
- const doc = this.docSync();
2949
- invariant10(doc, void 0, {
2950
- F: __dxlog_file13,
2951
- L: 93,
3741
+ const doc = this.doc();
3742
+ invariant11(doc, void 0, {
3743
+ F: __dxlog_file14,
3744
+ L: 88,
2952
3745
  S: this,
2953
3746
  A: [
2954
3747
  "doc",
@@ -2958,7 +3751,7 @@ var DatabaseRoot = class {
2958
3751
  return Object.values(doc.links ?? {}).map((s) => s.toString());
2959
3752
  }
2960
3753
  measureMetrics() {
2961
- const doc = this.docSync();
3754
+ const doc = this.doc();
2962
3755
  if (!doc) {
2963
3756
  return null;
2964
3757
  }
@@ -2967,7 +3760,7 @@ var DatabaseRoot = class {
2967
3760
  };
2968
3761
 
2969
3762
  // packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts
2970
- 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";
2971
3764
  var SpaceStateManager = class extends Resource8 {
2972
3765
  constructor() {
2973
3766
  super(...arguments);
@@ -2992,6 +3785,22 @@ var SpaceStateManager = class extends Resource8 {
2992
3785
  getSpaceRootDocumentId(spaceId) {
2993
3786
  return this._rootBySpace.get(spaceId);
2994
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
+ }
2995
3804
  async assignRootToSpace(spaceId, handle) {
2996
3805
  let root;
2997
3806
  if (this._roots.has(handle.documentId)) {
@@ -3010,8 +3819,8 @@ var SpaceStateManager = class extends Resource8 {
3010
3819
  }
3011
3820
  this._rootBySpace.set(spaceId, root.handle.documentId);
3012
3821
  const ctx = new Context5(void 0, {
3013
- F: __dxlog_file14,
3014
- L: 62
3822
+ F: __dxlog_file15,
3823
+ L: 72
3015
3824
  });
3016
3825
  this._perRootContext.set(root.handle.documentId, ctx);
3017
3826
  await root.handle.whenReady();
@@ -3044,19 +3853,20 @@ var SpaceDocumentListUpdatedEvent = class {
3044
3853
  };
3045
3854
 
3046
3855
  // packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
3047
- var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
3048
- var INDEXER_CONFIG = {
3049
- enabled: true,
3050
- indexes: [
3051
- {
3052
- kind: IndexKind.Kind.SCHEMA_MATCH
3053
- }
3054
- ]
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
3055
3861
  };
3056
3862
  var EchoHost = class extends Resource9 {
3057
- constructor({ kv, peerIdProvider, getSpaceKeyByRootDocumentId }) {
3863
+ constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
3058
3864
  super();
3059
3865
  this._spaceStateManager = new SpaceStateManager();
3866
+ const indexingConfig = {
3867
+ ...DEFAULT_INDEXING_CONFIG,
3868
+ ...indexing
3869
+ };
3060
3870
  this._indexMetadataStore = new IndexMetadataStore({
3061
3871
  db: kv.sublevel("index-metadata")
3062
3872
  });
@@ -3077,10 +3887,32 @@ var EchoHost = class extends Resource9 {
3077
3887
  loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
3078
3888
  indexCooldownTime: false ? 0 : void 0
3079
3889
  });
3080
- 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
+ });
3081
3912
  this._queryService = new QueryServiceImpl({
3082
3913
  automergeHost: this._automergeHost,
3083
- indexer: this._indexer
3914
+ indexer: this._indexer,
3915
+ spaceStateManager: this._spaceStateManager
3084
3916
  });
3085
3917
  this._dataService = new DataServiceImpl({
3086
3918
  automergeHost: this._automergeHost,
@@ -3089,7 +3921,7 @@ var EchoHost = class extends Resource9 {
3089
3921
  await this._indexer.updateIndexes();
3090
3922
  }
3091
3923
  });
3092
- trace6.diagnostic({
3924
+ trace5.diagnostic({
3093
3925
  id: "echo-stats",
3094
3926
  name: "Echo Stats",
3095
3927
  fetch: async () => {
@@ -3099,7 +3931,7 @@ var EchoHost = class extends Resource9 {
3099
3931
  };
3100
3932
  }
3101
3933
  });
3102
- trace6.diagnostic({
3934
+ trace5.diagnostic({
3103
3935
  id: "database-roots",
3104
3936
  name: "Database Roots",
3105
3937
  fetch: async () => {
@@ -3112,7 +3944,7 @@ var EchoHost = class extends Resource9 {
3112
3944
  }));
3113
3945
  }
3114
3946
  });
3115
- trace6.diagnostic({
3947
+ trace5.diagnostic({
3116
3948
  id: "database-root-metrics",
3117
3949
  name: "Database Roots (with metrics)",
3118
3950
  fetch: async () => {
@@ -3156,8 +3988,8 @@ var EchoHost = class extends Resource9 {
3156
3988
  });
3157
3989
  }
3158
3990
  async _close(ctx) {
3159
- await this._spaceStateManager.close();
3160
3991
  await this._queryService.close(ctx);
3992
+ await this._spaceStateManager.close(ctx);
3161
3993
  await this._indexer.close(ctx);
3162
3994
  await this._automergeHost.close();
3163
3995
  }
@@ -3192,16 +4024,16 @@ var EchoHost = class extends Resource9 {
3192
4024
  * Create new space root.
3193
4025
  */
3194
4026
  async createSpaceRoot(spaceKey) {
3195
- invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
3196
- F: __dxlog_file15,
3197
- L: 224,
4027
+ invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
4028
+ F: __dxlog_file16,
4029
+ L: 252,
3198
4030
  S: this,
3199
4031
  A: [
3200
4032
  "this._lifecycleState === LifecycleState.OPEN",
3201
4033
  ""
3202
4034
  ]
3203
4035
  });
3204
- const spaceId = await createIdFromSpaceKey3(spaceKey);
4036
+ const spaceId = await createIdFromSpaceKey2(spaceKey);
3205
4037
  const automergeRoot = this._automergeHost.createDoc({
3206
4038
  version: SpaceDocVersion3.CURRENT,
3207
4039
  access: {
@@ -3220,16 +4052,17 @@ var EchoHost = class extends Resource9 {
3220
4052
  }
3221
4053
  // TODO(dmaretskyi): Change to document id.
3222
4054
  async openSpaceRoot(spaceId, automergeUrl) {
3223
- invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
3224
- F: __dxlog_file15,
3225
- L: 243,
4055
+ invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
4056
+ F: __dxlog_file16,
4057
+ L: 271,
3226
4058
  S: this,
3227
4059
  A: [
3228
4060
  "this._lifecycleState === LifecycleState.OPEN",
3229
4061
  ""
3230
4062
  ]
3231
4063
  });
3232
- const handle = this._automergeHost.repo.find(automergeUrl);
4064
+ const handle = await this._automergeHost.repo.find(automergeUrl, FIND_PARAMS);
4065
+ await handle.whenReady();
3233
4066
  return this._spaceStateManager.assignRootToSpace(spaceId, handle);
3234
4067
  }
3235
4068
  // TODO(dmaretskyi): Change to document id.
@@ -3251,12 +4084,12 @@ var EchoHost = class extends Resource9 {
3251
4084
  };
3252
4085
 
3253
4086
  // packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts
4087
+ import { cbor as cbor2 } from "@automerge/automerge-repo";
3254
4088
  import { Mutex, scheduleTask as scheduleTask2, scheduleMicroTask } from "@dxos/async";
3255
- import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
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];
4159
+ }
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;
3354
4164
  }
3355
- return value;
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
- }
3376
- function err(e) {
3377
- error = error !== empty ? new _disposeSuppressedError(error, e) : e;
3378
- return next();
3379
4210
  }
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,28 +4230,32 @@ 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,
3405
- L: 60,
4237
+ F: __dxlog_file18,
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,
3412
- L: 63
4244
+ F: __dxlog_file18,
4245
+ L: 64
3413
4246
  });
3414
4247
  this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
3415
4248
  this._ctx && scheduleMicroTask(this._ctx, () => this._handleReconnect());
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,41 +4310,47 @@ 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,
3491
- L: 124,
4342
+ invariant14(this._context, void 0, {
4343
+ F: __dxlog_file18,
4344
+ L: 125,
3492
4345
  S: this,
3493
4346
  A: [
3494
4347
  "this._context",
3495
4348
  ""
3496
4349
  ]
3497
4350
  });
3498
- invariant12(!this._connections.has(spaceId), void 0, {
3499
- F: __dxlog_file17,
3500
- L: 125,
4351
+ invariant14(!this._connections.has(spaceId), void 0, {
4352
+ F: __dxlog_file18,
4353
+ L: 126,
3501
4354
  S: this,
3502
4355
  A: [
3503
4356
  "!this._connections.has(spaceId)",
@@ -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,
3530
- L: 148,
4382
+ F: __dxlog_file18,
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,9 +4448,9 @@ var EdgeReplicatorConnection = class extends Resource11 {
3590
4448
  });
3591
4449
  }
3592
4450
  async _open(ctx) {
3593
- log12("opening...", void 0, {
3594
- F: __dxlog_file17,
3595
- L: 251,
4451
+ log13("opening...", void 0, {
4452
+ F: __dxlog_file18,
4453
+ L: 252,
3596
4454
  S: this,
3597
4455
  C: (f, a) => f(...a)
3598
4456
  });
@@ -3603,9 +4461,9 @@ 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,
3608
- L: 266,
4464
+ log13("closing...", void 0, {
4465
+ F: __dxlog_file18,
4466
+ L: 267,
3609
4467
  S: this,
3610
4468
  C: (f, a) => f(...a)
3611
4469
  });
@@ -3614,9 +4472,9 @@ 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,
3619
- L: 275,
4475
+ invariant14(this._remotePeerId, "Not connected", {
4476
+ F: __dxlog_file18,
4477
+ L: 276,
3620
4478
  S: this,
3621
4479
  A: [
3622
4480
  "this._remotePeerId",
@@ -3635,13 +4493,13 @@ 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,
3644
- L: 290,
4501
+ F: __dxlog_file18,
4502
+ L: 291,
3645
4503
  S: this,
3646
4504
  C: (f, a) => f(...a)
3647
4505
  });
@@ -3661,13 +4519,13 @@ 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,
3670
- L: 319,
4527
+ F: __dxlog_file18,
4528
+ L: 320,
3671
4529
  S: this,
3672
4530
  C: (f, a) => f(...a)
3673
4531
  });
@@ -3684,13 +4542,13 @@ 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,
3693
- L: 348,
4550
+ F: __dxlog_file18,
4551
+ L: 349,
3694
4552
  S: this,
3695
4553
  C: (f, a) => f(...a)
3696
4554
  });
@@ -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,14 +4594,18 @@ export {
3735
4594
  EchoDataMonitor,
3736
4595
  EchoEdgeReplicator,
3737
4596
  EchoHost,
4597
+ ExecutionTrace,
4598
+ FIND_PARAMS,
3738
4599
  LevelDBStorageAdapter,
3739
4600
  MOCK_AUTH_PROVIDER,
3740
4601
  MOCK_AUTH_VERIFIER,
3741
4602
  MeshEchoReplicator,
3742
4603
  MetadataStore,
3743
4604
  Pipeline,
4605
+ QueryExecutor,
4606
+ QueryPlan,
4607
+ QueryPlanner,
3744
4608
  QueryServiceImpl,
3745
- QueryState,
3746
4609
  Space,
3747
4610
  SpaceDocumentListUpdatedEvent,
3748
4611
  SpaceManager,
@@ -3756,9 +4619,10 @@ export {
3756
4619
  deriveCollectionIdFromSpaceId,
3757
4620
  diffCollectionState,
3758
4621
  encodingOptions,
4622
+ filterMatchObject,
4623
+ filterMatchValue,
3759
4624
  findInlineObjectOfType,
3760
4625
  getSpaceIdFromCollectionId,
3761
- getSpaceKeyFromDoc,
3762
4626
  hasInvitationExpired,
3763
4627
  mapFeedIndexesToTimeframe,
3764
4628
  mapTimeframeToFeedIndexes,