@dxos/echo-pipeline 0.8.3 → 0.8.4-main.1c7ec43d41

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 (239) hide show
  1. package/dist/lib/{browser/chunk-35I6ERLG.mjs → neutral/chunk-VIHYDCCC.mjs} +313 -709
  2. package/dist/lib/neutral/chunk-VIHYDCCC.mjs.map +7 -0
  3. package/dist/lib/neutral/chunk-YBC6ONBZ.mjs +247 -0
  4. package/dist/lib/neutral/chunk-YBC6ONBZ.mjs.map +7 -0
  5. package/dist/lib/{browser → neutral}/filter/index.mjs +3 -2
  6. package/dist/lib/neutral/index.mjs +7065 -0
  7. package/dist/lib/neutral/index.mjs.map +7 -0
  8. package/dist/lib/neutral/meta.json +1 -0
  9. package/dist/lib/{browser → neutral}/testing/index.mjs +90 -311
  10. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  11. package/dist/types/src/automerge/automerge-host-subduction.test.d.ts +2 -0
  12. package/dist/types/src/automerge/automerge-host-subduction.test.d.ts.map +1 -0
  13. package/dist/types/src/automerge/automerge-host.d.ts +99 -54
  14. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  15. package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts +2 -0
  16. package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts.map +1 -0
  17. package/dist/types/src/automerge/automerge-repo.test.d.ts +1 -1
  18. package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -1
  19. package/dist/types/src/automerge/automerge-subduction.test.d.ts +2 -0
  20. package/dist/types/src/automerge/automerge-subduction.test.d.ts.map +1 -0
  21. package/dist/types/src/automerge/collection-synchronizer.d.ts +25 -4
  22. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  23. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
  24. package/dist/types/src/automerge/echo-network-adapter.d.ts +23 -10
  25. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  26. package/dist/types/src/automerge/echo-replicator.d.ts +38 -15
  27. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
  28. package/dist/types/src/automerge/handle-state.d.ts +52 -0
  29. package/dist/types/src/automerge/handle-state.d.ts.map +1 -0
  30. package/dist/types/src/automerge/heads-store.d.ts +9 -2
  31. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  32. package/dist/types/src/automerge/index.d.ts +2 -1
  33. package/dist/types/src/automerge/index.d.ts.map +1 -1
  34. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +9 -5
  35. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  36. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +9 -8
  37. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  38. package/dist/types/src/automerge/mesh-echo-replicator.d.ts +6 -5
  39. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  40. package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
  41. package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
  42. package/dist/types/src/common/codec.d.ts +1 -1
  43. package/dist/types/src/common/codec.d.ts.map +1 -1
  44. package/dist/types/src/common/feeds.d.ts.map +1 -1
  45. package/dist/types/src/common/space-id.d.ts.map +1 -1
  46. package/dist/types/src/db-host/automerge-data-source.d.ts +35 -0
  47. package/dist/types/src/db-host/automerge-data-source.d.ts.map +1 -0
  48. package/dist/types/src/db-host/automerge-data-source.test.d.ts +2 -0
  49. package/dist/types/src/db-host/automerge-data-source.test.d.ts.map +1 -0
  50. package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
  51. package/dist/types/src/db-host/data-service.d.ts +8 -7
  52. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  53. package/dist/types/src/db-host/database-root.d.ts +9 -3
  54. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  55. package/dist/types/src/db-host/documents-synchronizer.d.ts +9 -8
  56. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  57. package/dist/types/src/db-host/echo-host.d.ts +62 -27
  58. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  59. package/dist/types/src/db-host/index.d.ts +2 -0
  60. package/dist/types/src/db-host/index.d.ts.map +1 -1
  61. package/dist/types/src/db-host/invalidation-hint.d.ts +19 -0
  62. package/dist/types/src/db-host/invalidation-hint.d.ts.map +1 -0
  63. package/dist/types/src/db-host/local-queue-service.d.ts +19 -0
  64. package/dist/types/src/db-host/local-queue-service.d.ts.map +1 -0
  65. package/dist/types/src/db-host/query-invalidation.test.d.ts +2 -0
  66. package/dist/types/src/db-host/query-invalidation.test.d.ts.map +1 -0
  67. package/dist/types/src/db-host/query-service.d.ts +19 -11
  68. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  69. package/dist/types/src/db-host/queue-data-source.d.ts +38 -0
  70. package/dist/types/src/db-host/queue-data-source.d.ts.map +1 -0
  71. package/dist/types/src/db-host/queue-service.test.d.ts +2 -0
  72. package/dist/types/src/db-host/queue-service.test.d.ts.map +1 -0
  73. package/dist/types/src/db-host/space-state-manager.d.ts +4 -3
  74. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  75. package/dist/types/src/db-host/stub.d.ts +11 -0
  76. package/dist/types/src/db-host/stub.d.ts.map +1 -0
  77. package/dist/types/src/edge/echo-edge-replicator.d.ts +10 -7
  78. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  79. package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts +39 -0
  80. package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts.map +1 -0
  81. package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts +2 -0
  82. package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts.map +1 -0
  83. package/dist/types/src/edge/index.d.ts +1 -0
  84. package/dist/types/src/edge/index.d.ts.map +1 -1
  85. package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
  86. package/dist/types/src/filter/filter-match.d.ts +4 -1
  87. package/dist/types/src/filter/filter-match.d.ts.map +1 -1
  88. package/dist/types/src/metadata/metadata-store.d.ts +1 -1
  89. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  90. package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
  91. package/dist/types/src/pipeline/pipeline.d.ts +3 -3
  92. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  93. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  94. package/dist/types/src/query/errors.d.ts +22 -10
  95. package/dist/types/src/query/errors.d.ts.map +1 -1
  96. package/dist/types/src/query/plan.d.ts +66 -8
  97. package/dist/types/src/query/plan.d.ts.map +1 -1
  98. package/dist/types/src/query/query-executor.d.ts +66 -11
  99. package/dist/types/src/query/query-executor.d.ts.map +1 -1
  100. package/dist/types/src/query/query-planner.d.ts +12 -1
  101. package/dist/types/src/query/query-planner.d.ts.map +1 -1
  102. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  103. package/dist/types/src/space/auth.d.ts +3 -3
  104. package/dist/types/src/space/auth.d.ts.map +1 -1
  105. package/dist/types/src/space/control-pipeline.d.ts +5 -4
  106. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  107. package/dist/types/src/space/space-manager.d.ts +8 -8
  108. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  109. package/dist/types/src/space/space-protocol.d.ts +10 -9
  110. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  111. package/dist/types/src/space/space.d.ts +6 -6
  112. package/dist/types/src/space/space.d.ts.map +1 -1
  113. package/dist/types/src/testing/change-metadata.d.ts.map +1 -1
  114. package/dist/types/src/testing/index.d.ts +0 -2
  115. package/dist/types/src/testing/index.d.ts.map +1 -1
  116. package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
  117. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  118. package/dist/types/src/testing/test-feed-builder.d.ts.map +1 -1
  119. package/dist/types/src/testing/test-network-adapter.d.ts +1 -1
  120. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  121. package/dist/types/src/testing/test-replicator.d.ts +14 -13
  122. package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
  123. package/dist/types/src/util.d.ts +1 -1
  124. package/dist/types/src/util.d.ts.map +1 -1
  125. package/dist/types/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +56 -54
  127. package/src/automerge/automerge-host-subduction.test.ts +247 -0
  128. package/src/automerge/automerge-host.test.ts +65 -39
  129. package/src/automerge/automerge-host.ts +589 -206
  130. package/src/automerge/automerge-repo-subduction.test.ts +1049 -0
  131. package/src/automerge/automerge-repo.test.ts +349 -91
  132. package/src/automerge/automerge-subduction.test.ts +330 -0
  133. package/src/automerge/collection-synchronizer.test.ts +53 -17
  134. package/src/automerge/collection-synchronizer.ts +119 -36
  135. package/src/automerge/echo-data-monitor.ts +1 -1
  136. package/src/automerge/echo-network-adapter.test.ts +5 -4
  137. package/src/automerge/echo-network-adapter.ts +74 -30
  138. package/src/automerge/echo-replicator.ts +41 -15
  139. package/src/automerge/handle-state.ts +62 -0
  140. package/src/automerge/heads-store.ts +42 -3
  141. package/src/automerge/index.ts +2 -1
  142. package/src/automerge/leveldb-storage-adapter.ts +40 -11
  143. package/src/automerge/mesh-echo-replicator-connection.ts +12 -8
  144. package/src/automerge/mesh-echo-replicator.ts +15 -11
  145. package/src/automerge/storage-adapter.test.ts +1 -1
  146. package/src/common/space-id.ts +1 -1
  147. package/src/db-host/automerge-data-source.test.ts +299 -0
  148. package/src/db-host/automerge-data-source.ts +187 -0
  149. package/src/db-host/data-service.ts +25 -26
  150. package/src/db-host/database-root.ts +20 -8
  151. package/src/db-host/documents-synchronizer.test.ts +143 -14
  152. package/src/db-host/documents-synchronizer.ts +72 -55
  153. package/src/db-host/echo-host.ts +348 -96
  154. package/src/db-host/index.ts +2 -0
  155. package/src/db-host/invalidation-hint.ts +50 -0
  156. package/src/db-host/local-queue-service.ts +127 -0
  157. package/src/db-host/query-invalidation.test.ts +270 -0
  158. package/src/db-host/query-service.ts +111 -106
  159. package/src/db-host/queue-data-source.ts +160 -0
  160. package/src/db-host/queue-service.test.ts +145 -0
  161. package/src/db-host/space-state-manager.ts +12 -10
  162. package/src/db-host/stub.ts +33 -0
  163. package/src/edge/echo-edge-replicator.test.ts +12 -10
  164. package/src/edge/echo-edge-replicator.ts +144 -58
  165. package/src/edge/echo-edge-subduction-replicator.test.ts +158 -0
  166. package/src/edge/echo-edge-subduction-replicator.ts +377 -0
  167. package/src/edge/index.ts +1 -0
  168. package/src/filter/filter-match.test.ts +68 -32
  169. package/src/filter/filter-match.ts +184 -20
  170. package/src/metadata/metadata-store.ts +11 -8
  171. package/src/pipeline/pipeline-stress.test.ts +1 -1
  172. package/src/pipeline/pipeline.test.ts +2 -2
  173. package/src/pipeline/pipeline.ts +9 -7
  174. package/src/query/errors.ts +3 -1
  175. package/src/query/plan.ts +82 -8
  176. package/src/query/query-executor.ts +1199 -164
  177. package/src/query/query-planner.test.ts +993 -81
  178. package/src/query/query-planner.ts +467 -27
  179. package/src/space/admission-discovery-extension.ts +3 -3
  180. package/src/space/auth.ts +6 -6
  181. package/src/space/control-pipeline.test.ts +5 -4
  182. package/src/space/control-pipeline.ts +16 -13
  183. package/src/space/space-manager.browser.test.ts +1 -1
  184. package/src/space/space-manager.ts +16 -20
  185. package/src/space/space-protocol.browser.test.ts +15 -14
  186. package/src/space/space-protocol.test.ts +15 -14
  187. package/src/space/space-protocol.ts +22 -18
  188. package/src/space/space.test.ts +3 -3
  189. package/src/space/space.ts +11 -11
  190. package/src/testing/index.ts +0 -2
  191. package/src/testing/test-agent-builder.ts +3 -3
  192. package/src/testing/test-network-adapter.ts +24 -3
  193. package/src/testing/test-replicator.ts +19 -20
  194. package/src/util.ts +7 -3
  195. package/dist/lib/browser/chunk-35I6ERLG.mjs.map +0 -7
  196. package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
  197. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
  198. package/dist/lib/browser/chunk-TQJTKNMS.mjs +0 -126
  199. package/dist/lib/browser/chunk-TQJTKNMS.mjs.map +0 -7
  200. package/dist/lib/browser/index.mjs +0 -4743
  201. package/dist/lib/browser/index.mjs.map +0 -7
  202. package/dist/lib/browser/meta.json +0 -1
  203. package/dist/lib/browser/testing/index.mjs.map +0 -7
  204. package/dist/lib/node/chunk-HOPOFWAL.cjs +0 -147
  205. package/dist/lib/node/chunk-HOPOFWAL.cjs.map +0 -7
  206. package/dist/lib/node/chunk-JXX6LF5U.cjs +0 -2084
  207. package/dist/lib/node/chunk-JXX6LF5U.cjs.map +0 -7
  208. package/dist/lib/node/chunk-Q7SFCCGT.cjs +0 -33
  209. package/dist/lib/node/chunk-Q7SFCCGT.cjs.map +0 -7
  210. package/dist/lib/node/filter/index.cjs +0 -32
  211. package/dist/lib/node/filter/index.cjs.map +0 -7
  212. package/dist/lib/node/index.cjs +0 -4699
  213. package/dist/lib/node/index.cjs.map +0 -7
  214. package/dist/lib/node/meta.json +0 -1
  215. package/dist/lib/node/testing/index.cjs +0 -753
  216. package/dist/lib/node/testing/index.cjs.map +0 -7
  217. package/dist/lib/node-esm/chunk-5BHLPT24.mjs +0 -2067
  218. package/dist/lib/node-esm/chunk-5BHLPT24.mjs.map +0 -7
  219. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  220. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  221. package/dist/lib/node-esm/chunk-RVK35BS7.mjs +0 -126
  222. package/dist/lib/node-esm/chunk-RVK35BS7.mjs.map +0 -7
  223. package/dist/lib/node-esm/filter/index.mjs +0 -11
  224. package/dist/lib/node-esm/filter/index.mjs.map +0 -7
  225. package/dist/lib/node-esm/index.mjs +0 -4743
  226. package/dist/lib/node-esm/index.mjs.map +0 -7
  227. package/dist/lib/node-esm/meta.json +0 -1
  228. package/dist/lib/node-esm/testing/index.mjs +0 -742
  229. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  230. package/dist/types/src/db-host/documents-iterator.d.ts +0 -7
  231. package/dist/types/src/db-host/documents-iterator.d.ts.map +0 -1
  232. package/dist/types/src/testing/test-data.d.ts +0 -18
  233. package/dist/types/src/testing/test-data.d.ts.map +0 -1
  234. package/dist/types/src/testing/test-schema.d.ts +0 -37
  235. package/dist/types/src/testing/test-schema.d.ts.map +0 -1
  236. package/src/db-host/documents-iterator.ts +0 -74
  237. package/src/testing/test-data.ts +0 -127
  238. package/src/testing/test-schema.ts +0 -53
  239. /package/dist/lib/{browser → neutral}/filter/index.mjs.map +0 -0
package/package.json CHANGED
@@ -1,38 +1,35 @@
1
1
  {
2
2
  "name": "@dxos/echo-pipeline",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-main.1c7ec43d41",
4
4
  "description": "ECHO database.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
7
11
  "license": "MIT",
8
12
  "author": "info@dxos.org",
9
- "sideEffects": true,
13
+ "sideEffects": false,
10
14
  "type": "module",
11
15
  "exports": {
12
16
  ".": {
17
+ "source": "./src/index.ts",
13
18
  "types": "./dist/types/src/index.d.ts",
14
- "browser": "./dist/lib/browser/index.mjs",
15
- "node": "./dist/lib/node-esm/index.mjs"
19
+ "default": "./dist/lib/neutral/index.mjs"
16
20
  },
17
21
  "./testing": {
22
+ "source": "./src/testing/index.ts",
18
23
  "types": "./dist/types/src/testing/index.d.ts",
19
- "browser": "./dist/lib/browser/testing/index.mjs",
20
- "node": "./dist/lib/node-esm/testing/index.mjs"
24
+ "default": "./dist/lib/neutral/testing/index.mjs"
21
25
  },
22
26
  "./filter": {
27
+ "source": "./src/filter/index.ts",
23
28
  "types": "./dist/types/src/filter/index.d.ts",
24
- "browser": "./dist/lib/browser/filter/index.mjs",
25
- "node": "./dist/lib/node-esm/filter/index.mjs"
29
+ "default": "./dist/lib/neutral/filter/index.mjs"
26
30
  }
27
31
  },
28
32
  "types": "dist/types/src/index.d.ts",
29
- "typesVersions": {
30
- "*": {
31
- "testing": [
32
- "dist/types/src/testing/index.d.ts"
33
- ]
34
- }
35
- },
36
33
  "files": [
37
34
  "testing.d.ts",
38
35
  "testing.js",
@@ -40,51 +37,56 @@
40
37
  "src"
41
38
  ],
42
39
  "dependencies": {
43
- "@automerge/automerge": "3.0.0-beta.4",
44
- "@automerge/automerge-repo": "2.0.1",
40
+ "@automerge/automerge": "3.2.6",
41
+ "@automerge/automerge-repo": "2.6.0-subduction.17",
42
+ "@automerge/automerge-subduction": "0.11.0",
43
+ "@effect/sql": "0.49.0",
44
+ "@effect/sql-sqlite-node": "0.50.1",
45
+ "bs58check": "^4.0.0",
45
46
  "crc-32": "^1.2.2",
46
- "effect": "3.14.21",
47
+ "effect": "3.20.0",
48
+ "fast-deep-equal": "^3.1.3",
47
49
  "level-transcoder": "^1.0.1",
48
- "lodash.isequal": "^4.5.0",
49
- "@dxos/codec-protobuf": "0.8.3",
50
- "@dxos/credentials": "0.8.3",
51
- "@dxos/context": "0.8.3",
52
- "@dxos/async": "0.8.3",
53
- "@dxos/crypto": "0.8.3",
54
- "@dxos/debug": "0.8.3",
55
- "@dxos/echo": "0.8.3",
56
- "@dxos/echo-protocol": "0.8.3",
57
- "@dxos/edge-client": "0.8.3",
58
- "@dxos/echo-schema": "0.8.3",
59
- "@dxos/feed-store": "0.8.3",
60
- "@dxos/errors": "0.8.3",
61
- "@dxos/indexing": "0.8.3",
62
- "@dxos/hypercore": "0.8.3",
63
- "@dxos/invariant": "0.8.3",
64
- "@dxos/keyring": "0.8.3",
65
- "@dxos/keys": "0.8.3",
66
- "@dxos/kv-store": "0.8.3",
67
- "@dxos/log": "0.8.3",
68
- "@dxos/messaging": "0.8.3",
69
- "@dxos/network-manager": "0.8.3",
70
- "@dxos/node-std": "0.8.3",
71
- "@dxos/teleport": "0.8.3",
72
- "@dxos/protocols": "0.8.3",
73
- "@dxos/random-access-storage": "0.8.3",
74
- "@dxos/teleport-extension-automerge-replicator": "0.8.3",
75
- "@dxos/teleport-extension-gossip": "0.8.3",
76
- "@dxos/teleport-extension-object-sync": "0.8.3",
77
- "@dxos/teleport-extension-replicator": "0.8.3",
78
- "@dxos/timeframe": "0.8.3",
79
- "@dxos/tracing": "0.8.3",
80
- "@dxos/util": "0.8.3",
81
- "@dxos/typings": "0.8.3"
50
+ "@dxos/async": "0.8.4-main.1c7ec43d41",
51
+ "@dxos/codec-protobuf": "0.8.4-main.1c7ec43d41",
52
+ "@dxos/credentials": "0.8.4-main.1c7ec43d41",
53
+ "@dxos/context": "0.8.4-main.1c7ec43d41",
54
+ "@dxos/crypto": "0.8.4-main.1c7ec43d41",
55
+ "@dxos/debug": "0.8.4-main.1c7ec43d41",
56
+ "@dxos/echo": "0.8.4-main.1c7ec43d41",
57
+ "@dxos/echo-protocol": "0.8.4-main.1c7ec43d41",
58
+ "@dxos/edge-client": "0.8.4-main.1c7ec43d41",
59
+ "@dxos/errors": "0.8.4-main.1c7ec43d41",
60
+ "@dxos/effect": "0.8.4-main.1c7ec43d41",
61
+ "@dxos/feed": "0.8.4-main.1c7ec43d41",
62
+ "@dxos/feed-store": "0.8.4-main.1c7ec43d41",
63
+ "@dxos/hypercore": "0.8.4-main.1c7ec43d41",
64
+ "@dxos/index-core": "0.8.4-main.1c7ec43d41",
65
+ "@dxos/invariant": "0.8.4-main.1c7ec43d41",
66
+ "@dxos/keyring": "0.8.4-main.1c7ec43d41",
67
+ "@dxos/kv-store": "0.8.4-main.1c7ec43d41",
68
+ "@dxos/keys": "0.8.4-main.1c7ec43d41",
69
+ "@dxos/messaging": "0.8.4-main.1c7ec43d41",
70
+ "@dxos/network-manager": "0.8.4-main.1c7ec43d41",
71
+ "@dxos/node-std": "0.8.4-main.1c7ec43d41",
72
+ "@dxos/log": "0.8.4-main.1c7ec43d41",
73
+ "@dxos/protocols": "0.8.4-main.1c7ec43d41",
74
+ "@dxos/random-access-storage": "0.8.4-main.1c7ec43d41",
75
+ "@dxos/sql-sqlite": "0.8.4-main.1c7ec43d41",
76
+ "@dxos/teleport": "0.8.4-main.1c7ec43d41",
77
+ "@dxos/teleport-extension-automerge-replicator": "0.8.4-main.1c7ec43d41",
78
+ "@dxos/teleport-extension-gossip": "0.8.4-main.1c7ec43d41",
79
+ "@dxos/teleport-extension-object-sync": "0.8.4-main.1c7ec43d41",
80
+ "@dxos/timeframe": "0.8.4-main.1c7ec43d41",
81
+ "@dxos/teleport-extension-replicator": "0.8.4-main.1c7ec43d41",
82
+ "@dxos/tracing": "0.8.4-main.1c7ec43d41",
83
+ "@dxos/typings": "0.8.4-main.1c7ec43d41",
84
+ "@dxos/util": "0.8.4-main.1c7ec43d41"
82
85
  },
83
86
  "devDependencies": {
84
- "@types/lodash.isequal": "^4.5.0",
85
87
  "fast-check": "^3.19.0",
86
88
  "get-port-please": "^3.1.1",
87
- "@dxos/test-utils": "0.8.3"
89
+ "@dxos/test-utils": "0.8.4-main.1c7ec43d41"
88
90
  },
89
91
  "publishConfig": {
90
92
  "access": "public"
@@ -0,0 +1,247 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { getHeads } from '@automerge/automerge';
6
+ import * as Automerge from '@automerge/automerge';
7
+ import { type DocumentId, type Heads, generateAutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';
8
+ import { describe, onTestFinished, test } from 'vitest';
9
+
10
+ import { sleep } from '@dxos/async';
11
+ import { Context } from '@dxos/context';
12
+ import { PublicKey } from '@dxos/keys';
13
+ import type { LevelDB } from '@dxos/kv-store';
14
+ import { createTestLevel } from '@dxos/kv-store/testing';
15
+ import { openAndClose } from '@dxos/test-utils';
16
+ import { range } from '@dxos/util';
17
+
18
+ import { TestReplicationNetwork } from '../testing';
19
+ import { AutomergeHost } from './automerge-host';
20
+
21
+ describe('AutomergeHost with Subduction', () => {
22
+ test('can create documents', async ({ expect }) => {
23
+ const level = await createLevel();
24
+ const host = await setupAutomergeHost({ level });
25
+ const handle = await host.createDoc<any>();
26
+ handle.change((doc: any) => {
27
+ doc.text = 'Hello world';
28
+ });
29
+ await host.flush(Context.default());
30
+ expect(handle.doc()!.text).toEqual('Hello world');
31
+ });
32
+
33
+ test('changes are preserved in storage', async ({ expect }) => {
34
+ const level = await createLevel();
35
+ const host = await setupAutomergeHost({ level });
36
+ const handle = await host.createDoc<any>();
37
+ handle.change((doc: any) => {
38
+ doc.text = 'Hello world';
39
+ });
40
+ const url = handle.url;
41
+
42
+ await host.flush(Context.default());
43
+ await host.close();
44
+
45
+ const host2 = await setupAutomergeHost({ level });
46
+ const handle2 = await host2.loadDoc<any>(Context.default(), url);
47
+ await handle2.whenReady();
48
+ expect(handle2.doc()!.text).toEqual('Hello world');
49
+ await host2.flush(Context.default());
50
+ });
51
+
52
+ test('load resolves when document is created from binary', async ({ expect }) => {
53
+ const level = await createLevel();
54
+ const host = await setupAutomergeHost({ level });
55
+
56
+ const document = Automerge.from({ text: 'Hello world' });
57
+ const binary = Automerge.save(document);
58
+ const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
59
+
60
+ const loadPromise = host.loadDoc(Context.default(), documentId);
61
+
62
+ const createdHandle = await host.createDoc(binary, { preserveHistory: true, documentId });
63
+
64
+ const loadedHandle = await loadPromise;
65
+ expect(loadedHandle.doc()).toEqual(createdHandle.doc());
66
+ });
67
+
68
+ test('query single document heads', async ({ expect }) => {
69
+ const tmpPath = `/tmp/dxos-${PublicKey.random().toHex()}`;
70
+
71
+ const level = await createLevel(tmpPath);
72
+ const host = await setupAutomergeHost({ level });
73
+ const handle = await host.createDoc({ text: 'Hello world' });
74
+ const expectedHeads = getHeads(handle.doc()!);
75
+ await host.flush(Context.default());
76
+
77
+ expect(await host.getHeads([handle.documentId])).toEqual([expectedHeads]);
78
+ await host.close();
79
+ await level.close();
80
+
81
+ {
82
+ const host = await setupAutomergeHost({ level: await createLevel(tmpPath) });
83
+ expect(await host.getHeads([handle.documentId])).toEqual([expectedHeads]);
84
+ }
85
+ });
86
+
87
+ test('query multiple document heads', async ({ expect }) => {
88
+ const tmpPath = `/tmp/dxos-${PublicKey.random().toHex()}`;
89
+
90
+ const level = await createLevel(tmpPath);
91
+ const host = await setupAutomergeHost({ level });
92
+ const handles = await Promise.all(range(2, () => host.createDoc({ text: 'Hello world' })));
93
+ const expectedHeads: (Heads | undefined)[] = handles.map((handle) => getHeads(handle.doc()!));
94
+ await host.flush(Context.default());
95
+
96
+ const ids = handles.map((handle) => handle.documentId);
97
+ ids.splice(1, 0, 'non-existent-id' as DocumentId);
98
+ expectedHeads.splice(1, 0, undefined);
99
+
100
+ expect(await host.getHeads(ids)).toEqual(expectedHeads);
101
+ await host.close();
102
+ await level.close();
103
+
104
+ {
105
+ const level = await createLevel(tmpPath);
106
+ const host = await setupAutomergeHost({ level });
107
+ expect(await host.getHeads(ids)).toEqual(expectedHeads);
108
+ await host.close();
109
+ await level.close();
110
+ }
111
+ });
112
+
113
+ test('loads remote document over replication network', { timeout: 5_000 }, async ({ expect }) => {
114
+ const level1 = await createLevel();
115
+ const host1 = await setupAutomergeHost({ level: level1 });
116
+
117
+ const level2 = await createLevel();
118
+ const host2 = await setupAutomergeHost({ level: level2 });
119
+ const handle = await host2.createDoc({ text: 'Hello from Subduction' });
120
+ await host2.flush(Context.default());
121
+ await waitForSubductionSave();
122
+
123
+ const network = await new TestReplicationNetwork().open();
124
+ try {
125
+ await host1.addReplicator(Context.default(), await network.createReplicator());
126
+ await host2.addReplicator(Context.default(), await network.createReplicator());
127
+
128
+ const loaded = await host1.loadDoc<{ text: string }>(Context.default(), handle.documentId, { timeout: 1_000 });
129
+ expect(loaded.doc()!.text).toEqual('Hello from Subduction');
130
+ } finally {
131
+ await host1.close();
132
+ await host2.close();
133
+ await network.close();
134
+ }
135
+ });
136
+
137
+ test('collection synchronization', { timeout: 5_000 }, async ({ expect }) => {
138
+ const NUM_DOCUMENTS = 10;
139
+
140
+ const level1 = await createLevel();
141
+ const host1 = await setupAutomergeHost({ level: level1 });
142
+
143
+ const level2 = await createLevel();
144
+ const host2 = await setupAutomergeHost({ level: level2 });
145
+ const documentIds: DocumentId[] = [];
146
+ for (const i of range(NUM_DOCUMENTS)) {
147
+ const handle = await host2.createDoc({ docIndex: i });
148
+ documentIds.push(handle.documentId);
149
+ }
150
+ await host2.flush(Context.default());
151
+ await waitForSubductionSave();
152
+
153
+ const network = await new TestReplicationNetwork().open();
154
+ try {
155
+ await host1.addReplicator(Context.default(), await network.createReplicator());
156
+ await host2.addReplicator(Context.default(), await network.createReplicator());
157
+
158
+ const collectionId = 'test-collection';
159
+ await host1.updateLocalCollectionState(collectionId, documentIds);
160
+ await host2.updateLocalCollectionState(collectionId, documentIds);
161
+
162
+ for (const documentId of documentIds) {
163
+ await expect
164
+ .poll(() => host1.getHeads([documentId]), { timeout: 1_000 })
165
+ .toEqual(await host2.getHeads([documentId]));
166
+ }
167
+ } finally {
168
+ await host1.close();
169
+ await host2.close();
170
+ await network.close();
171
+ }
172
+ });
173
+
174
+ test('collection synchronization is bidirectional', { timeout: 10_000 }, async ({ expect }) => {
175
+ const host1DocumentIds: DocumentId[] = [];
176
+ const host2DocumentIds: DocumentId[] = [];
177
+
178
+ const level1 = await createLevel();
179
+ const host1 = await setupAutomergeHost({ level: level1 });
180
+ for (const i of range(3)) {
181
+ const handle = await host1.createDoc({ host: 1, docIndex: i });
182
+ host1DocumentIds.push(handle.documentId);
183
+ }
184
+ await host1.flush(Context.default());
185
+
186
+ const level2 = await createLevel();
187
+ const host2 = await setupAutomergeHost({ level: level2 });
188
+ for (const i of range(3)) {
189
+ const handle = await host2.createDoc({ host: 2, docIndex: i });
190
+ host2DocumentIds.push(handle.documentId);
191
+ }
192
+ await host2.flush(Context.default());
193
+ await waitForSubductionSave();
194
+
195
+ const network = await new TestReplicationNetwork().open();
196
+ try {
197
+ await host1.addReplicator(Context.default(), await network.createReplicator());
198
+ await host2.addReplicator(Context.default(), await network.createReplicator());
199
+
200
+ const host1CollectionId = 'test-host1-collection';
201
+ await host1.updateLocalCollectionState(host1CollectionId, host1DocumentIds);
202
+ await host2.updateLocalCollectionState(host1CollectionId, host1DocumentIds);
203
+
204
+ for (const documentId of host1DocumentIds) {
205
+ await expect
206
+ .poll(() => host2.getHeads([documentId]), { timeout: 1_000 })
207
+ .toEqual(await host1.getHeads([documentId]));
208
+ }
209
+
210
+ const host2CollectionId = 'test-host2-collection';
211
+ await host1.updateLocalCollectionState(host2CollectionId, host2DocumentIds);
212
+ await host2.updateLocalCollectionState(host2CollectionId, host2DocumentIds);
213
+
214
+ for (const documentId of host2DocumentIds) {
215
+ await expect
216
+ .poll(() => host1.getHeads([documentId]), { timeout: 1_000 })
217
+ .toEqual(await host2.getHeads([documentId]));
218
+ }
219
+ } finally {
220
+ await host1.close();
221
+ await host2.close();
222
+ await network.close();
223
+ }
224
+ });
225
+ });
226
+
227
+ const createLevel = async (tmpPath?: string) => {
228
+ const level = createTestLevel(tmpPath);
229
+ await openAndClose(level);
230
+ return level;
231
+ };
232
+
233
+ const waitForSubductionSave = async () => {
234
+ await sleep(150);
235
+ };
236
+
237
+ const setupAutomergeHost = async ({ level }: { level: LevelDB }) => {
238
+ const host = new AutomergeHost({
239
+ db: level,
240
+ useSubduction: true,
241
+ });
242
+ await host.open();
243
+ onTestFinished(async () => {
244
+ await host.close();
245
+ });
246
+ return host;
247
+ };
@@ -2,127 +2,154 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { getHeads } from '@automerge/automerge';
6
- import type { DocumentId, Heads } from '@automerge/automerge-repo';
7
- import { onTestFinished, describe, expect, test } from 'vitest';
5
+ import * as A from '@automerge/automerge';
6
+ import { type DocumentId, type Heads, generateAutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';
7
+ import { describe, expect, onTestFinished, test } from 'vitest';
8
8
 
9
- import { IndexMetadataStore } from '@dxos/indexing';
9
+ import { Context } from '@dxos/context';
10
+ import { PublicKey } from '@dxos/keys';
10
11
  import type { LevelDB } from '@dxos/kv-store';
11
12
  import { createTestLevel } from '@dxos/kv-store/testing';
12
13
  import { openAndClose } from '@dxos/test-utils';
13
14
  import { range } from '@dxos/util';
14
15
 
15
- import { AutomergeHost } from './automerge-host';
16
16
  import { TestReplicationNetwork } from '../testing';
17
+ import { AutomergeHost } from './automerge-host';
17
18
 
18
19
  describe('AutomergeHost', () => {
19
20
  test('can create documents', async () => {
20
21
  const level = await createLevel();
21
22
  const host = await setupAutomergeHost({ level });
22
- const handle = host.repo.create<any>();
23
+ const handle = await host.createDoc<any>();
23
24
  handle.change((doc: any) => {
24
25
  doc.text = 'Hello world';
25
26
  });
26
- await host.repo.flush();
27
+ await host.flush(Context.default());
27
28
  expect(handle.doc()!.text).toEqual('Hello world');
28
29
  });
29
30
 
30
31
  test('changes are preserved in storage', async () => {
31
32
  const level = await createLevel();
32
-
33
33
  const host = await setupAutomergeHost({ level });
34
- const handle = host.repo.create();
34
+ const handle = await host.createDoc<any>();
35
35
  handle.change((doc: any) => {
36
36
  doc.text = 'Hello world';
37
37
  });
38
38
  const url = handle.url;
39
39
 
40
- await host.repo.flush();
40
+ await host.flush(Context.default());
41
41
  await host.close();
42
42
 
43
43
  const host2 = await setupAutomergeHost({ level });
44
- const handle2 = await host2.repo.find<any>(url);
44
+ const handle2 = await host2.loadDoc<any>(Context.default(), url);
45
45
  await handle2.whenReady();
46
46
  expect(handle2.doc()!.text).toEqual('Hello world');
47
- await host2.repo.flush();
47
+ await host2.flush(Context.default());
48
48
  });
49
49
 
50
- test('query single document heads', async () => {
50
+ test('load resolves when document is created from binary', async () => {
51
51
  const level = await createLevel();
52
+ const host = await setupAutomergeHost({ level });
53
+
54
+ // Create a document to get its binary representation
55
+ const document = A.from({ text: 'Hello world' });
56
+ const binary = A.save(document);
57
+ const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
58
+
59
+ // Start loading a non-existent document (should hang until created)
60
+ const loadPromise = host.loadDoc(Context.default(), documentId);
61
+
62
+ // Create the document from binary - this should resolve the load
63
+ const createdHandle = await host.createDoc(binary, { preserveHistory: true, documentId });
64
+
65
+ // The load should now resolve
66
+ const loadedHandle = await loadPromise;
67
+ expect(loadedHandle.doc()).toEqual(createdHandle.doc());
68
+ });
52
69
 
70
+ test('query single document heads', async () => {
71
+ const tmpPath = `/tmp/dxos-${PublicKey.random().toHex()}`;
72
+
73
+ const level = await createLevel(tmpPath);
53
74
  const host = await setupAutomergeHost({ level });
54
- const handle = host.createDoc({ text: 'Hello world' });
55
- const expectedHeads = getHeads(handle.doc()!);
56
- await host.flush();
75
+ const handle = await host.createDoc({ text: 'Hello world' });
76
+ const expectedHeads = A.getHeads(handle.doc()!);
77
+ await host.flush(Context.default());
57
78
 
58
79
  expect(await host.getHeads([handle.documentId])).toEqual([expectedHeads]);
80
+ await host.close();
81
+ await level.close();
59
82
 
60
83
  // Simulate a restart.
61
84
  {
62
- const host = await setupAutomergeHost({ level });
85
+ const host = await setupAutomergeHost({ level: await createLevel(tmpPath) });
63
86
  expect(await host.getHeads([handle.documentId])).toEqual([expectedHeads]);
64
87
  }
65
88
  });
66
89
 
67
90
  test('query multiple document heads', async () => {
68
- const level = await createLevel();
91
+ const tmpPath = `/tmp/dxos-${PublicKey.random().toHex()}`;
69
92
 
93
+ const level = await createLevel(tmpPath);
70
94
  const host = await setupAutomergeHost({ level });
71
- const handles = range(2, () => host.createDoc({ text: 'Hello world' }));
72
- const expectedHeads: (Heads | undefined)[] = handles.map((handle) => getHeads(handle.doc()!));
73
- await host.flush();
95
+ const handles = await Promise.all(range(2, () => host.createDoc({ text: 'Hello world' })));
96
+ const expectedHeads: (Heads | undefined)[] = handles.map((handle) => A.getHeads(handle.doc()!));
97
+ await host.flush(Context.default());
74
98
 
75
99
  const ids = handles.map((handle) => handle.documentId);
76
100
  ids.splice(1, 0, 'non-existent-id' as DocumentId);
77
101
  expectedHeads.splice(1, 0, undefined);
78
102
 
79
103
  expect(await host.getHeads(ids)).toEqual(expectedHeads);
104
+ await host.close();
105
+ await level.close();
80
106
 
81
107
  // Simulate a restart.
82
108
  {
109
+ const level = await createLevel(tmpPath);
83
110
  const host = await setupAutomergeHost({ level });
84
111
  expect(await host.getHeads(ids)).toEqual(expectedHeads);
112
+ await host.close();
113
+ await level.close();
85
114
  }
86
115
  });
87
116
 
88
- test('collection synchronization', async () => {
117
+ test('collection synchronization', { timeout: 30_000 }, async () => {
89
118
  const NUM_DOCUMENTS = 10;
90
119
 
91
120
  const level1 = await createLevel();
92
121
  const host1 = await setupAutomergeHost({ level: level1 });
93
122
 
94
123
  const level2 = await createLevel();
124
+ const host2 = await setupAutomergeHost({ level: level2 });
95
125
  const documentIds: DocumentId[] = [];
96
- {
97
- const host2 = await setupAutomergeHost({ level: level2 });
98
- for (const i of range(NUM_DOCUMENTS)) {
99
- const handle = host2.createDoc({ docIndex: i });
100
- documentIds.push(handle.documentId);
101
- }
102
- await host2.flush();
103
- await host2.close();
126
+ for (const i of range(NUM_DOCUMENTS)) {
127
+ const handle = await host2.createDoc({ docIndex: i });
128
+ documentIds.push(handle.documentId);
104
129
  }
130
+ await host2.flush(Context.default());
105
131
 
106
- const host2 = await setupAutomergeHost({ level: level2 });
132
+ const network = await new TestReplicationNetwork().open();
133
+ await host1.addReplicator(Context.default(), await network.createReplicator());
134
+ await host2.addReplicator(Context.default(), await network.createReplicator());
107
135
 
108
136
  const collectionId = 'test-collection';
109
137
  await host1.updateLocalCollectionState(collectionId, documentIds);
110
138
  await host2.updateLocalCollectionState(collectionId, documentIds);
111
139
 
112
- await using network = await new TestReplicationNetwork().open();
113
- await host1.addReplicator(await network.createReplicator());
114
- await host2.addReplicator(await network.createReplicator());
115
-
116
140
  for (const documentId of documentIds) {
117
- await expect.poll(() => host1.getHeads([documentId])).toEqual(await host2.getHeads([documentId]));
141
+ await expect
142
+ .poll(() => host1.getHeads([documentId]), { timeout: 20_000 })
143
+ .toEqual(await host2.getHeads([documentId]));
118
144
  }
119
145
 
120
146
  await host1.close();
121
147
  await host2.close();
148
+ await network.close();
122
149
  });
123
150
 
124
- const createLevel = async () => {
125
- const level = createTestLevel();
151
+ const createLevel = async (tmpPath?: string) => {
152
+ const level = createTestLevel(tmpPath);
126
153
  await openAndClose(level);
127
154
  return level;
128
155
  };
@@ -131,7 +158,6 @@ describe('AutomergeHost', () => {
131
158
  const setupAutomergeHost = async ({ level }: { level: LevelDB }) => {
132
159
  const host = new AutomergeHost({
133
160
  db: level,
134
- indexMetadataStore: new IndexMetadataStore({ db: level.sublevel('index-metadata') }),
135
161
  });
136
162
  await host.open();
137
163
  onTestFinished(async () => {