@dxos/echo-pipeline 0.8.2-staging.7ac8446 → 0.8.2

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
@@ -2,9 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { onTestFinished, describe, expect, test } from 'vitest';
6
-
7
- import { asyncTimeout, sleep } from '@dxos/async';
8
5
  import {
9
6
  change,
10
7
  clone,
@@ -16,7 +13,7 @@ import {
16
13
  next as A,
17
14
  save,
18
15
  saveSince,
19
- } from '@dxos/automerge/automerge';
16
+ } from '@automerge/automerge';
20
17
  import {
21
18
  type AutomergeUrl,
22
19
  type DocHandle,
@@ -28,7 +25,10 @@ import {
28
25
  type PeerId,
29
26
  Repo,
30
27
  type SharePolicy,
31
- } from '@dxos/automerge/automerge-repo';
28
+ } from '@automerge/automerge-repo';
29
+ import { onTestFinished, describe, expect, test } from 'vitest';
30
+
31
+ import { asyncTimeout, sleep } from '@dxos/async';
32
32
  import { randomBytes } from '@dxos/crypto';
33
33
  import { PublicKey } from '@dxos/keys';
34
34
  import { createTestLevel } from '@dxos/kv-store/testing';
@@ -36,6 +36,7 @@ import { TestBuilder as TeleportBuilder, TestPeer as TeleportPeer } from '@dxos/
36
36
  import { openAndClose } from '@dxos/test-utils';
37
37
  import { isNonNullable, range } from '@dxos/util';
38
38
 
39
+ import { FIND_PARAMS } from './automerge-host';
39
40
  import { EchoNetworkAdapter } from './echo-network-adapter';
40
41
  import { LevelDBStorageAdapter } from './leveldb-storage-adapter';
41
42
  import { MeshEchoReplicator } from './mesh-echo-replicator';
@@ -51,7 +52,7 @@ describe('AutomergeRepo', () => {
51
52
  let valueDuringChange: string | undefined;
52
53
 
53
54
  handle.addListener('change', (doc) => {
54
- valueDuringChange = handle.docSync()!.field;
55
+ valueDuringChange = handle.doc()!.field;
55
56
  });
56
57
 
57
58
  handle.change((doc: any) => {
@@ -115,7 +116,7 @@ describe('AutomergeRepo', () => {
115
116
  const [host] = repos;
116
117
  await connectAdapters(adapters);
117
118
  const url = 'automerge:3JN8F3Z4dUWEEKKFN7WE9gEGvVUT';
118
- const handle = host.find(url as AutomergeUrl);
119
+ const handle = await host.find(url as AutomergeUrl, FIND_PARAMS);
119
120
  await handle.whenReady(['requesting']);
120
121
  });
121
122
 
@@ -132,7 +133,7 @@ describe('AutomergeRepo', () => {
132
133
 
133
134
  {
134
135
  const repo = new Repo({ network: [], storage });
135
- const handle = repo.find(url as AutomergeUrl);
136
+ const handle = await repo.find(url as AutomergeUrl);
136
137
 
137
138
  let requestingState = false;
138
139
  queueMicrotask(async () => {
@@ -157,8 +158,7 @@ describe('AutomergeRepo', () => {
157
158
  doc.text = text;
158
159
  });
159
160
 
160
- const docOnClient = client.find<any>(handle.url);
161
- expect((await asyncTimeout(docOnClient.doc(), 1000))!.text).to.equal(text);
161
+ expect((await asyncTimeout(client.find<any>(handle.url), 1000))!.doc().text).to.equal(text);
162
162
  });
163
163
 
164
164
  test('share policy gets enabled afterwards', async () => {
@@ -177,16 +177,13 @@ describe('AutomergeRepo', () => {
177
177
  });
178
178
 
179
179
  {
180
- const docOnClient = client.find(handle.url);
181
- await asyncTimeout(docOnClient.whenReady(['unavailable']), 1000);
180
+ await client.find(handle.url, { allowableStates: ['unavailable'] });
182
181
  }
183
182
 
184
183
  sharePolicy = true;
185
184
 
186
185
  {
187
- const docOnClient = client.find(handle.url);
188
- // TODO(mykola): We expect the document to be available here, but it's not.
189
- await asyncTimeout(docOnClient.whenReady(['unavailable']), 1000);
186
+ await client.find(handle.url, { allowableStates: ['unavailable'] });
190
187
  }
191
188
  });
192
189
 
@@ -206,26 +203,26 @@ describe('AutomergeRepo', () => {
206
203
 
207
204
  const firstHandle = host.create();
208
205
  firstHandle.change((doc: any) => (doc.text = 'Hello world'));
209
- await host.find(firstHandle.url).whenReady();
206
+ await host.find(firstHandle.url);
210
207
  allowedDocs.push(firstHandle.documentId);
211
208
 
212
209
  await connectAdapters(adapters);
213
210
 
214
211
  {
215
- const firstDocOnClient = client.find<any>(firstHandle.url);
212
+ const firstDocOnClient = await client.find<any>(firstHandle.url);
216
213
  await asyncTimeout(firstDocOnClient.whenReady(), 1000);
217
- expect(firstDocOnClient.docSync()!.text).to.equal('Hello world');
214
+ expect(firstDocOnClient.doc()!.text).to.equal('Hello world');
218
215
  }
219
216
 
220
217
  const secondHandle = host.create();
221
218
  secondHandle.change((doc: any) => (doc.text = 'Hello world'));
222
- await host.find(secondHandle.url).whenReady();
219
+ await host.find(secondHandle.url);
223
220
  allowedDocs.push(secondHandle.documentId);
224
221
 
225
222
  {
226
- const secondDocOnClient = client.find<any>(secondHandle.url);
223
+ const secondDocOnClient = await client.find<any>(secondHandle.url);
227
224
  await asyncTimeout(secondDocOnClient.whenReady(), 1000);
228
- expect(secondDocOnClient.docSync()!.text).to.equal('Hello world');
225
+ expect(secondDocOnClient.doc()!.text).to.equal('Hello world');
229
226
  }
230
227
  });
231
228
 
@@ -239,14 +236,15 @@ describe('AutomergeRepo', () => {
239
236
  await connectAdapters(adapters);
240
237
 
241
238
  const handle = host.create();
242
- const docOnClient = client.find<any>(handle.url);
239
+ const docOnClient = await client.find<any>(handle.url, FIND_PARAMS);
243
240
  {
244
241
  const sanityText = 'Hello world';
245
242
  handle.change((doc: any) => {
246
243
  doc.sanityText = sanityText;
247
244
  });
245
+ await asyncTimeout(docOnClient.whenReady(), 1000);
248
246
 
249
- expect((await asyncTimeout(docOnClient.doc(), 1000))!.sanityText).to.equal(sanityText);
247
+ expect(docOnClient.doc().sanityText).to.equal(sanityText);
250
248
  }
251
249
 
252
250
  // Disrupt connection.
@@ -259,7 +257,8 @@ describe('AutomergeRepo', () => {
259
257
  });
260
258
 
261
259
  await sleep(100);
262
- expect((await asyncTimeout(docOnClient.doc(), 1000))!.offlineText).to.be.undefined;
260
+ await asyncTimeout(docOnClient.whenReady(), 1000);
261
+ expect(docOnClient.doc().offlineText).to.be.undefined;
263
262
  }
264
263
 
265
264
  // Re-establish connection.
@@ -272,8 +271,9 @@ describe('AutomergeRepo', () => {
272
271
  doc.onlineText = onlineText;
273
272
  });
274
273
  await sleep(100);
275
- expect((await asyncTimeout(docOnClient.doc(), 1000))!.onlineText).to.equal(onlineText);
276
- expect((await asyncTimeout(docOnClient.doc(), 1000))!.offlineText).to.equal(offlineText);
274
+ await asyncTimeout(docOnClient.whenReady(), 1000);
275
+ expect(docOnClient.doc().onlineText).to.equal(onlineText);
276
+ expect(docOnClient.doc().offlineText).to.equal(offlineText);
277
277
  }
278
278
  });
279
279
 
@@ -297,9 +297,9 @@ describe('AutomergeRepo', () => {
297
297
 
298
298
  // If we wait here for replication to finish naturally, the test will pass.
299
299
 
300
- const docD = repoD.find(docA.url);
300
+ const docD = await repoD.find(docA.url);
301
301
 
302
- await docD.whenReady();
302
+ await asyncTimeout(docD.whenReady(), 1000);
303
303
  });
304
304
 
305
305
  test('replication though a 3 peer chain', async () => {
@@ -319,9 +319,9 @@ describe('AutomergeRepo', () => {
319
319
  doc.text = 'Hello world';
320
320
  });
321
321
 
322
- const _ = repoB.find(docA.url);
323
- const docC = repoC.find(docA.url);
324
- await docC.whenReady();
322
+ const _ = repoB.find(docA.url, FIND_PARAMS);
323
+ const docC = await repoC.find(docA.url, FIND_PARAMS);
324
+ await asyncTimeout(docC.whenReady(), 1000);
325
325
  });
326
326
 
327
327
  test('replicate document after request', async () => {
@@ -338,7 +338,7 @@ describe('AutomergeRepo', () => {
338
338
  doc.text = 'Hello world';
339
339
  });
340
340
 
341
- const docB = client.find(docA.url);
341
+ const docB = await client.find(docA.url, { allowableStates: ['unavailable'] });
342
342
 
343
343
  // Request document from repoB.
344
344
  await asyncTimeout(docB.whenReady([unavailable]), 1_000);
@@ -373,11 +373,12 @@ describe('AutomergeRepo', () => {
373
373
  await connectAdapters(adapters);
374
374
 
375
375
  // Load doc on peer1
376
- const hostHandle = peer1.find<any>(url as AutomergeUrl);
376
+ const hostHandle = await peer1.find<any>(url as AutomergeUrl);
377
377
 
378
378
  // Doc should be pushed to peer2
379
- await expect.poll(() => hostHandle.docSync()!.text).not.toBeUndefined();
380
- await expect.poll(() => peer2.handles[hostHandle.documentId].docSync()).toEqual(hostHandle.docSync());
379
+ await hostHandle.whenReady();
380
+ await expect.poll(() => hostHandle.doc()!.text).not.toBeUndefined();
381
+ await expect.poll(() => peer2.handles[hostHandle.documentId].doc()).toEqual(hostHandle.doc());
381
382
  });
382
383
 
383
384
  test('client cold-starts and syncs doc from a Repo', async () => {
@@ -390,8 +391,8 @@ describe('AutomergeRepo', () => {
390
391
  };
391
392
 
392
393
  // Sync handshake.
393
- let syncedHeads = getHeads(serverHandle.docSync()!);
394
- receiveByClient(save(serverHandle.docSync()!));
394
+ let syncedHeads = getHeads(serverHandle.doc()!);
395
+ receiveByClient(save(serverHandle.doc()!));
395
396
 
396
397
  serverHandle.on('change', ({ doc }) => {
397
398
  // Note: This is mock of a sync protocol between client and server.
@@ -420,7 +421,7 @@ describe('AutomergeRepo', () => {
420
421
  test('client creates doc and syncs with a Repo', async () => {
421
422
  const repo = new Repo({ network: [] });
422
423
  const receiveByServer = async (blob: Uint8Array, docId: DocumentId) => {
423
- const serverHandle = repo.find(docId);
424
+ const serverHandle = await repo.find(docId, FIND_PARAMS);
424
425
  serverHandle.update((doc) => {
425
426
  return A.loadIncremental(doc, blob);
426
427
  });
@@ -445,8 +446,8 @@ describe('AutomergeRepo', () => {
445
446
  });
446
447
  await sendDoc(clientDoc);
447
448
 
448
- await repo.find(documentId).whenReady();
449
- expect(repo.find<any>(documentId).docSync()!.field).to.deep.equal(value);
449
+ const serverHandle = await repo.find<any>(documentId);
450
+ expect(serverHandle.doc()!.field).to.deep.equal(value);
450
451
  }
451
452
  });
452
453
 
@@ -456,7 +457,7 @@ describe('AutomergeRepo', () => {
456
457
  await connectAdapters(adapters);
457
458
 
458
459
  const handleA = repoA.create<any>();
459
- const handleB = repoB.find<any>(handleA.url);
460
+ const handleB = await repoB.find<any>(handleA.url);
460
461
 
461
462
  const text = 'Hello world';
462
463
  handleA.update((doc: any) => {
@@ -465,10 +466,11 @@ describe('AutomergeRepo', () => {
465
466
  });
466
467
  });
467
468
 
468
- expect(handleA.docSync()!.text).to.equal(text);
469
+ expect(handleA.doc()!.text).to.equal(text);
469
470
 
471
+ await sleep(100);
470
472
  await asyncTimeout(handleB.whenReady(), 1000);
471
- expect(handleB.docSync()!.text).to.equal(text);
473
+ expect(handleB.doc()!.text).to.equal(text);
472
474
  });
473
475
  });
474
476
 
@@ -493,11 +495,10 @@ describe('AutomergeRepo', () => {
493
495
  await expect
494
496
  .poll(
495
497
  async () => {
496
- const docOnPeer2 = peer2.repo.find<any>(handle.url);
497
- const doc = await asyncTimeout(docOnPeer2.doc(), 1000);
498
- return doc!.text;
498
+ const docOnPeer2 = await peer2.repo.find<any>(handle.url);
499
+ return docOnPeer2.doc()!.text;
499
500
  },
500
- { timeout: 1_000 },
501
+ { timeout: 5_000 },
501
502
  )
502
503
  .toEqual(text);
503
504
  }
@@ -510,17 +511,18 @@ describe('AutomergeRepo', () => {
510
511
  handle.change((doc: any) => {
511
512
  doc.offlineText = offlineText;
512
513
  });
513
- const docOnPeer2 = peer2.repo.find<any>(handle.url);
514
+ const docOnPeer2 = await peer2.repo.find<any>(handle.url);
514
515
  await sleep(100);
515
- expect((await asyncTimeout(docOnPeer2.doc(), 1000))!.offlineText).to.be.undefined;
516
+ await asyncTimeout(docOnPeer2.whenReady(), 1000);
517
+ expect(docOnPeer2.doc()!.offlineText).to.be.undefined;
516
518
  }
517
519
 
518
520
  {
519
521
  // Wait for offline changes to be synced after reconnect.
520
- const docOnPeer2 = peer2.repo.find<any>(handle.url);
522
+ const docOnPeer2 = await peer2.repo.find<any>(handle.url);
521
523
  await docChangeAfterAction(docOnPeer2, () => connectPeers(spaceKey, teleportBuilder, peer1, peer2));
522
524
  await docOnPeer2.whenReady();
523
- expect((await asyncTimeout(docOnPeer2.doc(), 1000))!.offlineText).to.eq(offlineText);
525
+ expect(docOnPeer2.doc()!.offlineText).to.eq(offlineText);
524
526
 
525
527
  // Test connection.
526
528
  const onlineText = 'This has been written after the connection was re-established';
@@ -530,7 +532,7 @@ describe('AutomergeRepo', () => {
530
532
  });
531
533
  });
532
534
  await docOnPeer2.whenReady();
533
- expect((await asyncTimeout(docOnPeer2.doc(), 1000))!.onlineText).to.eq(onlineText);
535
+ expect(docOnPeer2.doc()!.onlineText).to.eq(onlineText);
534
536
  }
535
537
  });
536
538
 
@@ -556,11 +558,11 @@ describe('AutomergeRepo', () => {
556
558
  });
557
559
  await connectPeers(spaceKey, teleportBuilder, peerWithDocs.peer, peer2);
558
560
 
559
- const shouldNotFindDoc = peer2.repo.find(docNotInRemoteCollection.url);
560
- const shouldFindDoc = peer2.repo.find(docInRemoteCollection.url);
561
+ const shouldNotFindDoc = await peer2.repo.find(docNotInRemoteCollection.url, FIND_PARAMS);
562
+ const shouldFindDoc = await peer2.repo.find(docInRemoteCollection.url, FIND_PARAMS);
561
563
  await shouldFindDoc.whenReady();
562
- expect(shouldFindDoc.docSync()).to.deep.eq(docInRemoteCollection.docSync());
563
- await shouldNotFindDoc.whenReady(['unavailable']);
564
+ expect(shouldFindDoc.doc()).to.deep.eq(docInRemoteCollection.doc());
565
+ await asyncTimeout(shouldNotFindDoc.whenReady(['unavailable']), 1000);
564
566
  });
565
567
 
566
568
  /**
@@ -590,12 +592,12 @@ describe('AutomergeRepo', () => {
590
592
  await connectPeers(spaceKey, teleportBuilder, peerWithDocs.peer, peer2);
591
593
  await connectPeers(anotherSpaceKey, teleportBuilder, peer2, peerFromAnotherSpace);
592
594
 
593
- const loadedDocument = peer2.repo.find(document.url);
594
- await loadedDocument.whenReady();
595
+ const loadedDocument = await peer2.repo.find(document.url, FIND_PARAMS);
596
+ await asyncTimeout(loadedDocument.whenReady(), 1000);
595
597
 
596
598
  await sleep(200);
597
- const doc = peerFromAnotherSpace.repo.find(document.url);
598
- await doc.whenReady(['unavailable']);
599
+ const doc = await peerFromAnotherSpace.repo.find(document.url, { allowableStates: ['unavailable'] });
600
+ await asyncTimeout(doc.whenReady(['unavailable']), 1000);
599
601
  });
600
602
 
601
603
  test('collection-sync with chain of peers', async () => {
@@ -624,12 +626,12 @@ describe('AutomergeRepo', () => {
624
626
  await connectPeers(spaceKey, teleportBuilder, peerWithDocs.peer, peer2);
625
627
  await connectPeers(spaceKey, teleportBuilder, peer2, peer3);
626
628
 
627
- const loadedDocument = peer2.repo.find(document.url);
629
+ const loadedDocument = await peer2.repo.find(document.url, FIND_PARAMS);
628
630
  await loadedDocument.whenReady();
629
631
 
630
- const doc = peer3.repo.find(document.url);
632
+ const doc = await peer3.repo.find(document.url, FIND_PARAMS);
631
633
  await doc.whenReady();
632
- expect(doc.docSync()).to.deep.eq(document.docSync());
634
+ expect(doc.doc()).to.deep.eq(document.doc());
633
635
  });
634
636
  });
635
637
 
@@ -692,8 +694,6 @@ const createRepoTopology = async <Peers extends string[], Peer extends string =
692
694
 
693
695
  const connectAdapters = async (pairs: [TestAdapter, TestAdapter][], options?: { noEmitPeerCandidate?: boolean }) => {
694
696
  for (const pair of pairs) {
695
- pair[0].ready();
696
- pair[1].ready();
697
697
  await pair[0].onConnect.wait();
698
698
  await pair[1].onConnect.wait();
699
699
  if (!options?.noEmitPeerCandidate) {
@@ -2,10 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import type { PeerId } from '@automerge/automerge-repo';
5
6
  import { onTestFinished, describe, expect, test } from 'vitest';
6
7
 
7
8
  import { sleep } from '@dxos/async';
8
- import type { PeerId } from '@dxos/automerge/automerge-repo';
9
9
 
10
10
  import { CollectionSynchronizer, diffCollectionState, type CollectionState } from './collection-synchronizer';
11
11
 
@@ -2,9 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { next as am } from '@automerge/automerge';
6
+ import type { DocumentId, PeerId } from '@automerge/automerge-repo';
7
+
5
8
  import { asyncReturn, Event, scheduleTask, scheduleTaskInterval } from '@dxos/async';
6
- import { next as am } from '@dxos/automerge/automerge';
7
- import type { DocumentId, PeerId } from '@dxos/automerge/automerge-repo';
8
9
  import { Resource, type Context } from '@dxos/context';
9
10
  import { log } from '@dxos/log';
10
11
  import { trace } from '@dxos/tracing';
@@ -69,7 +70,7 @@ export class CollectionSynchronizer extends Resource {
69
70
  return this._perCollectionStates.get(collectionId)?.localState;
70
71
  }
71
72
 
72
- setLocalCollectionState(collectionId: string, state: CollectionState) {
73
+ setLocalCollectionState(collectionId: string, state: CollectionState): void {
73
74
  this._activeCollections.add(collectionId);
74
75
 
75
76
  log('setLocalCollectionState', { collectionId, state });
@@ -83,7 +84,7 @@ export class CollectionSynchronizer extends Resource {
83
84
  });
84
85
  }
85
86
 
86
- clearLocalCollectionState(collectionId: string) {
87
+ clearLocalCollectionState(collectionId: string): void {
87
88
  this._activeCollections.delete(collectionId);
88
89
  this._perCollectionStates.delete(collectionId);
89
90
  log('clearLocalCollectionState', { collectionId });
@@ -93,7 +94,7 @@ export class CollectionSynchronizer extends Resource {
93
94
  return this._getOrCreatePerCollectionState(collectionId).remoteStates;
94
95
  }
95
96
 
96
- refreshCollection(collectionId: string) {
97
+ refreshCollection(collectionId: string): void {
97
98
  let scheduleAnotherRefresh = false;
98
99
  const state = this._getOrCreatePerCollectionState(collectionId);
99
100
  for (const peerId of this._connectedPeers) {
@@ -115,7 +116,7 @@ export class CollectionSynchronizer extends Resource {
115
116
  /**
116
117
  * Callback when a connection to a peer is established.
117
118
  */
118
- onConnectionOpen(peerId: PeerId) {
119
+ onConnectionOpen(peerId: PeerId): void {
119
120
  const spanId = getSpanName(peerId);
120
121
  trace.spanStart({
121
122
  id: spanId,
@@ -144,7 +145,7 @@ export class CollectionSynchronizer extends Resource {
144
145
  /**
145
146
  * Callback when a connection to a peer is closed.
146
147
  */
147
- onConnectionClosed(peerId: PeerId) {
148
+ onConnectionClosed(peerId: PeerId): void {
148
149
  this._connectedPeers.delete(peerId);
149
150
 
150
151
  for (const perCollectionState of this._perCollectionStates.values()) {
@@ -155,7 +156,7 @@ export class CollectionSynchronizer extends Resource {
155
156
  /**
156
157
  * Callback when a peer queries the state of a collection.
157
158
  */
158
- onCollectionStateQueried(collectionId: string, peerId: PeerId) {
159
+ onCollectionStateQueried(collectionId: string, peerId: PeerId): void {
159
160
  const perCollectionState = this._getOrCreatePerCollectionState(collectionId);
160
161
 
161
162
  if (perCollectionState.localState) {
@@ -166,7 +167,7 @@ export class CollectionSynchronizer extends Resource {
166
167
  /**
167
168
  * Callback when a peer sends the state of a collection.
168
169
  */
169
- onRemoteStateReceived(collectionId: string, peerId: PeerId, state: CollectionState) {
170
+ onRemoteStateReceived(collectionId: string, peerId: PeerId, state: CollectionState): void {
170
171
  log('onRemoteStateReceived', { collectionId, peerId, state });
171
172
  validateCollectionState(state);
172
173
  const perCollectionState = this._getOrCreatePerCollectionState(collectionId);
@@ -200,7 +201,7 @@ export class CollectionSynchronizer extends Resource {
200
201
  }));
201
202
  }
202
203
 
203
- private _refreshInterestedPeers(collectionId: string) {
204
+ private _refreshInterestedPeers(collectionId: string): void {
204
205
  for (const peerId of this._connectedPeers) {
205
206
  if (this._shouldSyncCollection(collectionId, peerId)) {
206
207
  this._getOrCreatePerCollectionState(collectionId).interestedPeers.add(peerId);
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { type Message } from '@dxos/automerge/automerge-repo';
5
+ import { type Message } from '@automerge/automerge-repo';
6
+
6
7
  import { type TimeAware, trace } from '@dxos/tracing';
7
8
  import { CircularBuffer, mapValues, SlidingWindowSummary, type SlidingWindowSummaryConfig } from '@dxos/util';
8
9
 
@@ -26,7 +27,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
26
27
  private readonly _localTimeSeries = createLocalTimeSeries();
27
28
  private readonly _storageAverages = createStorageAverages();
28
29
  private readonly _replicationAverages = createNetworkAverages();
29
- private readonly _sizeByMessageType: { [type: string]: SlidingWindowSummary } = {};
30
+ private readonly _sizeByMessage: { [type: string]: SlidingWindowSummary } = {};
30
31
  private readonly _lastReceivedMessages = new CircularBuffer<StoredMessage>(100);
31
32
  private readonly _lastSentMessages = new CircularBuffer<StoredMessage>(100);
32
33
 
@@ -34,7 +35,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
34
35
 
35
36
  constructor(private readonly _params: EchoDataMonitorOptions = { timeSeriesLength: 30 }) {}
36
37
 
37
- public tick(timeMs: number) {
38
+ public tick(timeMs: number): void {
38
39
  this._advanceTimeWindow(timeMs - this._lastTick);
39
40
  this._lastTick = timeMs;
40
41
  }
@@ -68,8 +69,8 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
68
69
  countPerSecond: this._replicationAverages.sentPerSecond.average(),
69
70
  failedPerSecond: this._replicationAverages.sendsFailedPerSecond.average(),
70
71
  },
71
- countByMessageType: this._computeMessageHistogram('type'),
72
- avgSizeByMessageType: mapValues(this._sizeByMessageType, (summary) => summary.average()),
72
+ countByMessage: this._computeMessageHistogram('type'),
73
+ avgSizeByMessage: mapValues(this._sizeByMessage, (summary) => summary.average()),
73
74
  },
74
75
  };
75
76
  }
@@ -99,7 +100,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
99
100
  return this._computeMessageHistogram('peerId');
100
101
  }
101
102
 
102
- private _advanceTimeWindow(millisPassed: number) {
103
+ private _advanceTimeWindow(millisPassed: number): void {
103
104
  const oldMetrics = Object.freeze(this._activeCounters);
104
105
  this._activeCounters = createLocalCounters();
105
106
  this._lastCompleteCounters = oldMetrics;
@@ -114,7 +115,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
114
115
  }
115
116
  }
116
117
 
117
- private _addToTimeSeries<T extends object>(values: T, timeSeries: TimeSeries<T>) {
118
+ private _addToTimeSeries<T extends object>(values: T, timeSeries: TimeSeries<T>): void {
118
119
  for (const [key, value] of Object.entries(values)) {
119
120
  const values: (typeof value)[] = (timeSeries as any)[key];
120
121
  values.push(value);
@@ -124,7 +125,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
124
125
  }
125
126
  }
126
127
 
127
- private _reportPerSecondRate(metrics: LocalCounters) {
128
+ private _reportPerSecondRate(metrics: LocalCounters): void {
128
129
  const toReport: [string, number, SlidingWindowSummary][] = [
129
130
  ['storage.load', metrics.storage.loadedChunks, this._storageAverages.loadsPerSecond],
130
131
  ['storage.store', metrics.storage.storedChunks, this._storageAverages.storesPerSecond],
@@ -143,17 +144,17 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
143
144
  this._replicationAverages.sendsFailedPerSecond.record(metrics.replication.failed);
144
145
  }
145
146
 
146
- public recordPeerConnected(peerId: string) {
147
+ public recordPeerConnected(peerId: string): void {
147
148
  this._activeCounters.byPeerId[peerId] = createMessageCounter();
148
149
  this._connectionsCount++;
149
150
  }
150
151
 
151
- public recordPeerDisconnected(peerId: string) {
152
+ public recordPeerDisconnected(peerId: string): void {
152
153
  this._connectionsCount--;
153
154
  delete this._activeCounters.byPeerId[peerId];
154
155
  }
155
156
 
156
- public recordBytesStored(count: number) {
157
+ public recordBytesStored(count: number): void {
157
158
  this._activeCounters.storage.storedChunks++;
158
159
  this._activeCounters.storage.storedBytes += count;
159
160
  this._storageAverages.storedChunkSize.record(count);
@@ -168,14 +169,14 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
168
169
  this._storageAverages.storeDuration.record(durationMs);
169
170
  }
170
171
 
171
- public recordBytesLoaded(count: number) {
172
+ public recordBytesLoaded(count: number): void {
172
173
  this._activeCounters.storage.loadedChunks++;
173
174
  this._activeCounters.storage.loadedBytes += count;
174
175
  this._storageAverages.loadedChunkSize.record(count);
175
176
  trace.metrics.distribution('dxos.echo.storage.bytes-loaded', count, { unit: 'bytes' });
176
177
  }
177
178
 
178
- public recordMessageSent(message: Message, duration: number) {
179
+ public recordMessageSent(message: Message, duration: number): void {
179
180
  let metricsGroupName;
180
181
  const bytes = getByteCount(message);
181
182
  const tags = { type: message.type };
@@ -196,7 +197,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
196
197
  this._lastSentMessages.push({ type: message.type, peerId: message.targetId });
197
198
  }
198
199
 
199
- public recordMessageReceived(message: Message) {
200
+ public recordMessageReceived(message: Message): void {
200
201
  const bytes = getByteCount(message);
201
202
  const tags = { type: message.type };
202
203
  if (isAutomergeProtocolMessage(message)) {
@@ -212,7 +213,7 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
212
213
  this._lastReceivedMessages.push({ type: message.type, peerId: message.senderId });
213
214
  }
214
215
 
215
- public recordMessageSendingFailed(message: Message) {
216
+ public recordMessageSendingFailed(message: Message): void {
216
217
  const tags = { type: message.type, success: false };
217
218
  if (isAutomergeProtocolMessage(message)) {
218
219
  this._activeCounters.replication.failed++;
@@ -224,8 +225,8 @@ export class EchoDataMonitor implements StorageAdapterDataMonitor, NetworkDataMo
224
225
  messageCounts.failed++;
225
226
  }
226
227
 
227
- private _getStatsForType(message: Message) {
228
- const messageSize = (this._sizeByMessageType[message.type] ??= createSlidingWindow());
228
+ private _getStatsForType(message: Message): { messageCounts: MessageCounts; messageSize: SlidingWindowSummary } {
229
+ const messageSize = (this._sizeByMessage[message.type] ??= createSlidingWindow());
229
230
  const messageCounts = (this._activeCounters.byType[message.type] ??= createMessageCounter());
230
231
  return { messageCounts, messageSize };
231
232
  }
@@ -269,7 +270,7 @@ type MessageCounts = {
269
270
  type MessageCountTimeSeries = TimeSeries<MessageCounts>;
270
271
 
271
272
  type MessageAttributeHistogram = {
272
- [messageType: string]: {
273
+ [Message: string]: {
273
274
  received: number;
274
275
  sent: number;
275
276
  };
@@ -287,8 +288,8 @@ export type EchoDataStats = {
287
288
  connections: number;
288
289
  receivedMessages: BaseDataOpStats;
289
290
  sentMessages: TimedDataOpStats & { failedPerSecond: number };
290
- avgSizeByMessageType: { [messageType: string]: number };
291
- countByMessageType: MessageAttributeHistogram;
291
+ avgSizeByMessage: { [Message: string]: number };
292
+ countByMessage: MessageAttributeHistogram;
292
293
  };
293
294
  };
294
295
 
@@ -2,10 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { cbor, type PeerId } from '@automerge/automerge-repo';
5
6
  import { onTestFinished, describe, expect, test } from 'vitest';
6
7
 
7
8
  import { sleep, Trigger, waitForCondition } from '@dxos/async';
8
- import { cbor, type PeerId } from '@dxos/automerge/automerge-repo';
9
9
  import { invariant } from '@dxos/invariant';
10
10
  import { PublicKey } from '@dxos/keys';
11
11
  import { type SyncMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/automerge';