cojson 0.19.22 → 0.20.1

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 (223) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +66 -0
  3. package/dist/PeerState.d.ts +6 -1
  4. package/dist/PeerState.d.ts.map +1 -1
  5. package/dist/PeerState.js +18 -3
  6. package/dist/PeerState.js.map +1 -1
  7. package/dist/coValueContentMessage.d.ts +0 -2
  8. package/dist/coValueContentMessage.d.ts.map +1 -1
  9. package/dist/coValueContentMessage.js +0 -8
  10. package/dist/coValueContentMessage.js.map +1 -1
  11. package/dist/coValueCore/SessionMap.d.ts +4 -2
  12. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  13. package/dist/coValueCore/SessionMap.js +30 -0
  14. package/dist/coValueCore/SessionMap.js.map +1 -1
  15. package/dist/coValueCore/coValueCore.d.ts +70 -5
  16. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  17. package/dist/coValueCore/coValueCore.js +302 -31
  18. package/dist/coValueCore/coValueCore.js.map +1 -1
  19. package/dist/coValueCore/verifiedState.d.ts +6 -1
  20. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  21. package/dist/coValueCore/verifiedState.js +9 -0
  22. package/dist/coValueCore/verifiedState.js.map +1 -1
  23. package/dist/coValues/coList.d.ts +4 -2
  24. package/dist/coValues/coList.d.ts.map +1 -1
  25. package/dist/coValues/coList.js +3 -0
  26. package/dist/coValues/coList.js.map +1 -1
  27. package/dist/coValues/group.d.ts.map +1 -1
  28. package/dist/coValues/group.js +3 -6
  29. package/dist/coValues/group.js.map +1 -1
  30. package/dist/config.d.ts +2 -8
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +4 -12
  33. package/dist/config.js.map +1 -1
  34. package/dist/crypto/NapiCrypto.d.ts +1 -2
  35. package/dist/crypto/NapiCrypto.d.ts.map +1 -1
  36. package/dist/crypto/NapiCrypto.js +19 -4
  37. package/dist/crypto/NapiCrypto.js.map +1 -1
  38. package/dist/crypto/RNCrypto.d.ts.map +1 -1
  39. package/dist/crypto/RNCrypto.js +19 -4
  40. package/dist/crypto/RNCrypto.js.map +1 -1
  41. package/dist/crypto/WasmCrypto.d.ts +11 -4
  42. package/dist/crypto/WasmCrypto.d.ts.map +1 -1
  43. package/dist/crypto/WasmCrypto.js +52 -10
  44. package/dist/crypto/WasmCrypto.js.map +1 -1
  45. package/dist/crypto/WasmCryptoEdge.d.ts +1 -0
  46. package/dist/crypto/WasmCryptoEdge.d.ts.map +1 -1
  47. package/dist/crypto/WasmCryptoEdge.js +4 -1
  48. package/dist/crypto/WasmCryptoEdge.js.map +1 -1
  49. package/dist/crypto/crypto.d.ts +3 -3
  50. package/dist/crypto/crypto.d.ts.map +1 -1
  51. package/dist/crypto/crypto.js +6 -1
  52. package/dist/crypto/crypto.js.map +1 -1
  53. package/dist/exports.d.ts +5 -5
  54. package/dist/exports.d.ts.map +1 -1
  55. package/dist/exports.js +4 -3
  56. package/dist/exports.js.map +1 -1
  57. package/dist/ids.d.ts +4 -1
  58. package/dist/ids.d.ts.map +1 -1
  59. package/dist/ids.js +4 -0
  60. package/dist/ids.js.map +1 -1
  61. package/dist/knownState.d.ts +2 -0
  62. package/dist/knownState.d.ts.map +1 -1
  63. package/dist/localNode.d.ts +12 -0
  64. package/dist/localNode.d.ts.map +1 -1
  65. package/dist/localNode.js +14 -0
  66. package/dist/localNode.js.map +1 -1
  67. package/dist/platformUtils.d.ts +3 -0
  68. package/dist/platformUtils.d.ts.map +1 -0
  69. package/dist/platformUtils.js +24 -0
  70. package/dist/platformUtils.js.map +1 -0
  71. package/dist/queue/LinkedList.d.ts +9 -3
  72. package/dist/queue/LinkedList.d.ts.map +1 -1
  73. package/dist/queue/LinkedList.js +30 -1
  74. package/dist/queue/LinkedList.js.map +1 -1
  75. package/dist/queue/OutgoingLoadQueue.d.ts +95 -0
  76. package/dist/queue/OutgoingLoadQueue.d.ts.map +1 -0
  77. package/dist/queue/OutgoingLoadQueue.js +240 -0
  78. package/dist/queue/OutgoingLoadQueue.js.map +1 -0
  79. package/dist/storage/DeletedCoValuesEraserScheduler.d.ts +30 -0
  80. package/dist/storage/DeletedCoValuesEraserScheduler.d.ts.map +1 -0
  81. package/dist/storage/DeletedCoValuesEraserScheduler.js +84 -0
  82. package/dist/storage/DeletedCoValuesEraserScheduler.js.map +1 -0
  83. package/dist/storage/sqlite/client.d.ts +3 -0
  84. package/dist/storage/sqlite/client.d.ts.map +1 -1
  85. package/dist/storage/sqlite/client.js +44 -0
  86. package/dist/storage/sqlite/client.js.map +1 -1
  87. package/dist/storage/sqlite/sqliteMigrations.d.ts.map +1 -1
  88. package/dist/storage/sqlite/sqliteMigrations.js +7 -0
  89. package/dist/storage/sqlite/sqliteMigrations.js.map +1 -1
  90. package/dist/storage/sqliteAsync/client.d.ts +3 -0
  91. package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
  92. package/dist/storage/sqliteAsync/client.js +42 -0
  93. package/dist/storage/sqliteAsync/client.js.map +1 -1
  94. package/dist/storage/storageAsync.d.ts +7 -0
  95. package/dist/storage/storageAsync.d.ts.map +1 -1
  96. package/dist/storage/storageAsync.js +48 -0
  97. package/dist/storage/storageAsync.js.map +1 -1
  98. package/dist/storage/storageSync.d.ts +6 -0
  99. package/dist/storage/storageSync.d.ts.map +1 -1
  100. package/dist/storage/storageSync.js +42 -0
  101. package/dist/storage/storageSync.js.map +1 -1
  102. package/dist/storage/types.d.ts +59 -0
  103. package/dist/storage/types.d.ts.map +1 -1
  104. package/dist/storage/types.js +12 -1
  105. package/dist/storage/types.js.map +1 -1
  106. package/dist/sync.d.ts.map +1 -1
  107. package/dist/sync.js +66 -43
  108. package/dist/sync.js.map +1 -1
  109. package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts +2 -0
  110. package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts.map +1 -0
  111. package/dist/tests/DeletedCoValuesEraserScheduler.test.js +149 -0
  112. package/dist/tests/DeletedCoValuesEraserScheduler.test.js.map +1 -0
  113. package/dist/tests/GarbageCollector.test.js +5 -6
  114. package/dist/tests/GarbageCollector.test.js.map +1 -1
  115. package/dist/tests/LinkedList.test.js +90 -0
  116. package/dist/tests/LinkedList.test.js.map +1 -1
  117. package/dist/tests/OutgoingLoadQueue.test.d.ts +2 -0
  118. package/dist/tests/OutgoingLoadQueue.test.d.ts.map +1 -0
  119. package/dist/tests/OutgoingLoadQueue.test.js +814 -0
  120. package/dist/tests/OutgoingLoadQueue.test.js.map +1 -0
  121. package/dist/tests/StorageApiAsync.test.js +484 -152
  122. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  123. package/dist/tests/StorageApiSync.test.js +505 -136
  124. package/dist/tests/StorageApiSync.test.js.map +1 -1
  125. package/dist/tests/WasmCrypto.test.js +6 -3
  126. package/dist/tests/WasmCrypto.test.js.map +1 -1
  127. package/dist/tests/coValueCore.loadFromStorage.test.js +3 -0
  128. package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
  129. package/dist/tests/coValueCore.test.js +34 -13
  130. package/dist/tests/coValueCore.test.js.map +1 -1
  131. package/dist/tests/coreWasm.test.js +127 -4
  132. package/dist/tests/coreWasm.test.js.map +1 -1
  133. package/dist/tests/crypto.test.js +89 -93
  134. package/dist/tests/crypto.test.js.map +1 -1
  135. package/dist/tests/deleteCoValue.test.d.ts +2 -0
  136. package/dist/tests/deleteCoValue.test.d.ts.map +1 -0
  137. package/dist/tests/deleteCoValue.test.js +313 -0
  138. package/dist/tests/deleteCoValue.test.js.map +1 -0
  139. package/dist/tests/group.removeMember.test.js +18 -30
  140. package/dist/tests/group.removeMember.test.js.map +1 -1
  141. package/dist/tests/knownState.lazyLoading.test.js +3 -0
  142. package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
  143. package/dist/tests/sync.concurrentLoad.test.d.ts +2 -0
  144. package/dist/tests/sync.concurrentLoad.test.d.ts.map +1 -0
  145. package/dist/tests/sync.concurrentLoad.test.js +481 -0
  146. package/dist/tests/sync.concurrentLoad.test.js.map +1 -0
  147. package/dist/tests/sync.deleted.test.d.ts +2 -0
  148. package/dist/tests/sync.deleted.test.d.ts.map +1 -0
  149. package/dist/tests/sync.deleted.test.js +214 -0
  150. package/dist/tests/sync.deleted.test.js.map +1 -0
  151. package/dist/tests/sync.mesh.test.js +3 -2
  152. package/dist/tests/sync.mesh.test.js.map +1 -1
  153. package/dist/tests/sync.storage.test.js +4 -3
  154. package/dist/tests/sync.storage.test.js.map +1 -1
  155. package/dist/tests/sync.test.js +3 -2
  156. package/dist/tests/sync.test.js.map +1 -1
  157. package/dist/tests/testStorage.d.ts +3 -0
  158. package/dist/tests/testStorage.d.ts.map +1 -1
  159. package/dist/tests/testStorage.js +17 -1
  160. package/dist/tests/testStorage.js.map +1 -1
  161. package/dist/tests/testUtils.d.ts +7 -3
  162. package/dist/tests/testUtils.d.ts.map +1 -1
  163. package/dist/tests/testUtils.js +19 -4
  164. package/dist/tests/testUtils.js.map +1 -1
  165. package/package.json +6 -16
  166. package/src/PeerState.ts +26 -3
  167. package/src/coValueContentMessage.ts +0 -14
  168. package/src/coValueCore/SessionMap.ts +43 -1
  169. package/src/coValueCore/coValueCore.ts +415 -27
  170. package/src/coValueCore/verifiedState.ts +26 -3
  171. package/src/coValues/coList.ts +9 -3
  172. package/src/coValues/group.ts +5 -6
  173. package/src/config.ts +4 -13
  174. package/src/crypto/NapiCrypto.ts +29 -13
  175. package/src/crypto/RNCrypto.ts +29 -11
  176. package/src/crypto/WasmCrypto.ts +67 -20
  177. package/src/crypto/WasmCryptoEdge.ts +5 -1
  178. package/src/crypto/crypto.ts +16 -4
  179. package/src/exports.ts +4 -2
  180. package/src/ids.ts +11 -1
  181. package/src/localNode.ts +15 -0
  182. package/src/platformUtils.ts +26 -0
  183. package/src/queue/LinkedList.ts +34 -4
  184. package/src/queue/OutgoingLoadQueue.ts +307 -0
  185. package/src/storage/DeletedCoValuesEraserScheduler.ts +124 -0
  186. package/src/storage/sqlite/client.ts +77 -0
  187. package/src/storage/sqlite/sqliteMigrations.ts +7 -0
  188. package/src/storage/sqliteAsync/client.ts +75 -0
  189. package/src/storage/storageAsync.ts +62 -0
  190. package/src/storage/storageSync.ts +58 -0
  191. package/src/storage/types.ts +69 -0
  192. package/src/sync.ts +78 -46
  193. package/src/tests/DeletedCoValuesEraserScheduler.test.ts +185 -0
  194. package/src/tests/GarbageCollector.test.ts +6 -10
  195. package/src/tests/LinkedList.test.ts +111 -0
  196. package/src/tests/OutgoingLoadQueue.test.ts +1129 -0
  197. package/src/tests/StorageApiAsync.test.ts +572 -162
  198. package/src/tests/StorageApiSync.test.ts +580 -143
  199. package/src/tests/WasmCrypto.test.ts +8 -3
  200. package/src/tests/coValueCore.loadFromStorage.test.ts +6 -0
  201. package/src/tests/coValueCore.test.ts +49 -14
  202. package/src/tests/coreWasm.test.ts +319 -10
  203. package/src/tests/crypto.test.ts +141 -150
  204. package/src/tests/deleteCoValue.test.ts +528 -0
  205. package/src/tests/group.removeMember.test.ts +35 -35
  206. package/src/tests/knownState.lazyLoading.test.ts +6 -0
  207. package/src/tests/sync.concurrentLoad.test.ts +650 -0
  208. package/src/tests/sync.deleted.test.ts +294 -0
  209. package/src/tests/sync.mesh.test.ts +5 -2
  210. package/src/tests/sync.storage.test.ts +6 -3
  211. package/src/tests/sync.test.ts +5 -2
  212. package/src/tests/testStorage.ts +31 -2
  213. package/src/tests/testUtils.ts +31 -10
  214. package/dist/crypto/PureJSCrypto.d.ts +0 -77
  215. package/dist/crypto/PureJSCrypto.d.ts.map +0 -1
  216. package/dist/crypto/PureJSCrypto.js +0 -236
  217. package/dist/crypto/PureJSCrypto.js.map +0 -1
  218. package/dist/tests/PureJSCrypto.test.d.ts +0 -2
  219. package/dist/tests/PureJSCrypto.test.d.ts.map +0 -1
  220. package/dist/tests/PureJSCrypto.test.js +0 -145
  221. package/dist/tests/PureJSCrypto.test.js.map +0 -1
  222. package/src/crypto/PureJSCrypto.ts +0 -429
  223. package/src/tests/PureJSCrypto.test.ts +0 -217
@@ -1,17 +1,19 @@
1
- import { randomUUID } from "node:crypto";
2
- import { unlinkSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { describe, expect, onTestFinished, test, vi } from "vitest";
6
- import { WasmCrypto } from "../crypto/WasmCrypto.js";
7
- import { CoID, LocalNode, RawCoID, RawCoMap, logger } from "../exports.js";
1
+ import { describe, expect, test, vi, afterEach } from "vitest";
2
+ import { CoID, RawCoID, RawCoMap, logger } from "../exports.js";
8
3
  import { CoValueCore } from "../exports.js";
9
4
  import { NewContentMessage } from "../sync.js";
10
5
  import { CoValueKnownState, emptyKnownState } from "../knownState.js";
11
- import { createSyncStorage } from "./testStorage.js";
12
- import { loadCoValueOrFail, randomAgentAndSessionID } from "./testUtils.js";
13
-
14
- const crypto = await WasmCrypto.create();
6
+ import {
7
+ createSyncStorage,
8
+ getAllCoValuesWaitingForDelete,
9
+ getCoValueStoredSessions,
10
+ getDbPath,
11
+ } from "./testStorage.js";
12
+ import {
13
+ fillCoMapWithLargeData,
14
+ loadCoValueOrFail,
15
+ setupTestNode,
16
+ } from "./testUtils.js";
15
17
 
16
18
  /**
17
19
  * Helper function that gets new content since a known state, throwing if:
@@ -35,55 +37,23 @@ function getNewContentSince(
35
37
  return contentMessage;
36
38
  }
37
39
 
38
- async function createFixturesNode(customDbPath?: string) {
39
- const [admin, session] = randomAgentAndSessionID();
40
- const node = new LocalNode(admin.agentSecret, session, crypto);
41
-
42
- // Create a unique database file for each test
43
- const dbPath = customDbPath ?? join(tmpdir(), `test-${randomUUID()}.db`);
44
- const storage = createSyncStorage({
45
- filename: dbPath,
46
- nodeName: "test",
47
- storageName: "test-storage",
48
- });
49
-
50
- onTestFinished(() => {
51
- try {
52
- unlinkSync(dbPath);
53
- } catch {}
54
- });
55
-
56
- node.setStorage(storage);
57
-
58
- return {
59
- fixturesNode: node,
60
- dbPath,
61
- };
62
- }
63
-
64
- async function createTestNode(dbPath?: string) {
65
- const [admin, session] = randomAgentAndSessionID();
66
- const node = new LocalNode(admin.agentSecret, session, crypto);
67
-
68
- const storage = createSyncStorage({
69
- filename: dbPath,
70
- nodeName: "test",
71
- storageName: "test-storage",
72
- });
73
-
74
- return {
75
- node,
76
- storage,
77
- };
78
- }
40
+ afterEach(() => {
41
+ vi.useRealTimers();
42
+ });
79
43
 
80
44
  describe("StorageApiSync", () => {
81
45
  describe("getKnownState", () => {
82
46
  test("should return empty known state for new coValue ID and cache the result", async () => {
83
- const { fixturesNode } = await createFixturesNode();
84
- const { storage } = await createTestNode();
47
+ const fixtures = setupTestNode();
48
+ const client = setupTestNode();
49
+ const { storage } = client.addStorage({
50
+ storage: createSyncStorage({
51
+ nodeName: "test",
52
+ storageName: "test-storage",
53
+ }),
54
+ });
85
55
 
86
- const id = fixturesNode.createGroup().id;
56
+ const id = fixtures.node.createGroup().id;
87
57
  const knownState = storage.getKnownState(id);
88
58
 
89
59
  expect(knownState).toEqual(emptyKnownState(id));
@@ -91,7 +61,13 @@ describe("StorageApiSync", () => {
91
61
  });
92
62
 
93
63
  test("should return separate known state instances for different coValue IDs", async () => {
94
- const { storage } = await createTestNode();
64
+ const client = setupTestNode();
65
+ const { storage } = client.addStorage({
66
+ storage: createSyncStorage({
67
+ nodeName: "test",
68
+ storageName: "test-storage",
69
+ }),
70
+ });
95
71
  const id1 = "test-id-1";
96
72
  const id2 = "test-id-2";
97
73
 
@@ -104,7 +80,13 @@ describe("StorageApiSync", () => {
104
80
 
105
81
  describe("load", () => {
106
82
  test("should fail gracefully when loading non-existent coValue and preserve known state", async () => {
107
- const { storage } = await createTestNode();
83
+ const client = setupTestNode();
84
+ const { storage } = client.addStorage({
85
+ storage: createSyncStorage({
86
+ nodeName: "test",
87
+ storageName: "test-storage",
88
+ }),
89
+ });
108
90
  const id = "non-existent-id";
109
91
  const callback = vi.fn();
110
92
  const done = vi.fn();
@@ -124,15 +106,31 @@ describe("StorageApiSync", () => {
124
106
  });
125
107
 
126
108
  test("should successfully load coValue with header and update known state", async () => {
127
- const { fixturesNode, dbPath } = await createFixturesNode();
128
- const { node, storage } = await createTestNode(dbPath);
109
+ const dbPath = getDbPath();
110
+ const fixtures = setupTestNode();
111
+ fixtures.addStorage({
112
+ storage: createSyncStorage({
113
+ filename: dbPath,
114
+ nodeName: "test",
115
+ storageName: "test-storage",
116
+ }),
117
+ });
118
+
119
+ const client = setupTestNode();
120
+ const { storage } = client.addStorage({
121
+ storage: createSyncStorage({
122
+ filename: dbPath,
123
+ nodeName: "test",
124
+ storageName: "test-storage",
125
+ }),
126
+ });
129
127
  const callback = vi.fn((content) =>
130
- node.syncManager.handleNewContent(content, "storage"),
128
+ client.node.syncManager.handleNewContent(content, "storage"),
131
129
  );
132
130
  const done = vi.fn();
133
131
 
134
132
  // Create a real group and get its content message
135
- const group = fixturesNode.createGroup();
133
+ const group = fixtures.node.createGroup();
136
134
  await group.core.waitForSync();
137
135
 
138
136
  // Get initial known state
@@ -154,7 +152,7 @@ describe("StorageApiSync", () => {
154
152
  const updatedKnownState = storage.getKnownState(group.id);
155
153
  expect(updatedKnownState).toEqual(group.core.knownState());
156
154
 
157
- const groupOnNode = await loadCoValueOrFail(node, group.id);
155
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
158
156
 
159
157
  expect(groupOnNode.core.verified.header).toEqual(
160
158
  group.core.verified.header,
@@ -162,15 +160,31 @@ describe("StorageApiSync", () => {
162
160
  });
163
161
 
164
162
  test("should successfully load coValue with transactions and update known state", async () => {
165
- const { fixturesNode, dbPath } = await createFixturesNode();
166
- const { node, storage } = await createTestNode(dbPath);
163
+ const dbPath = getDbPath();
164
+ const fixtures = setupTestNode();
165
+ fixtures.addStorage({
166
+ storage: createSyncStorage({
167
+ filename: dbPath,
168
+ nodeName: "test",
169
+ storageName: "test-storage",
170
+ }),
171
+ });
172
+
173
+ const client = setupTestNode();
174
+ const { storage } = client.addStorage({
175
+ storage: createSyncStorage({
176
+ filename: dbPath,
177
+ nodeName: "test",
178
+ storageName: "test-storage",
179
+ }),
180
+ });
167
181
  const callback = vi.fn((content) =>
168
- node.syncManager.handleNewContent(content, "storage"),
182
+ client.node.syncManager.handleNewContent(content, "storage"),
169
183
  );
170
184
  const done = vi.fn();
171
185
 
172
186
  // Create a real group and add a member to create transactions
173
- const group = fixturesNode.createGroup();
187
+ const group = fixtures.node.createGroup();
174
188
  group.addMember("everyone", "reader");
175
189
  await group.core.waitForSync();
176
190
 
@@ -185,7 +199,7 @@ describe("StorageApiSync", () => {
185
199
  id: group.id,
186
200
  header: group.core.verified.header,
187
201
  new: expect.objectContaining({
188
- [fixturesNode.currentSessionID]: expect.any(Object),
202
+ [fixtures.node.currentSessionID]: expect.any(Object),
189
203
  }),
190
204
  }),
191
205
  );
@@ -195,17 +209,30 @@ describe("StorageApiSync", () => {
195
209
  const updatedKnownState = storage.getKnownState(group.id);
196
210
  expect(updatedKnownState).toEqual(group.core.knownState());
197
211
 
198
- const groupOnNode = await loadCoValueOrFail(node, group.id);
212
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
199
213
  expect(groupOnNode.get("everyone")).toEqual("reader");
200
214
  });
201
215
  });
202
216
 
203
217
  describe("store", () => {
204
218
  test("should successfully store new coValue with header and update known state", async () => {
205
- const { fixturesNode } = await createFixturesNode();
206
- const { node, storage } = await createTestNode();
219
+ const fixtures = setupTestNode();
220
+ fixtures.addStorage({
221
+ storage: createSyncStorage({
222
+ nodeName: "test",
223
+ storageName: "test-storage",
224
+ }),
225
+ });
226
+
227
+ const client = setupTestNode();
228
+ const { storage } = client.addStorage({
229
+ storage: createSyncStorage({
230
+ nodeName: "test",
231
+ storageName: "test-storage",
232
+ }),
233
+ });
207
234
  // Create a real group and get its content message
208
- const group = fixturesNode.createGroup();
235
+ const group = fixtures.node.createGroup();
209
236
  const contentMessage = getNewContentSince(
210
237
  group.core,
211
238
  emptyKnownState(group.id),
@@ -222,9 +249,9 @@ describe("StorageApiSync", () => {
222
249
  const updatedKnownState = storage.getKnownState(group.id);
223
250
  expect(updatedKnownState).toEqual(group.core.knownState());
224
251
 
225
- node.setStorage(storage);
252
+ client.addStorage({ storage });
226
253
 
227
- const groupOnNode = await loadCoValueOrFail(node, group.id);
254
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
228
255
 
229
256
  expect(groupOnNode.core.verified.header).toEqual(
230
257
  group.core.verified.header,
@@ -232,11 +259,24 @@ describe("StorageApiSync", () => {
232
259
  });
233
260
 
234
261
  test("should successfully store coValue with transactions and update known state", async () => {
235
- const { fixturesNode } = await createFixturesNode();
236
- const { node, storage } = await createTestNode();
262
+ const fixtures = setupTestNode();
263
+ fixtures.addStorage({
264
+ storage: createSyncStorage({
265
+ nodeName: "test",
266
+ storageName: "test-storage",
267
+ }),
268
+ });
269
+
270
+ const client = setupTestNode();
271
+ const { storage } = client.addStorage({
272
+ storage: createSyncStorage({
273
+ nodeName: "test",
274
+ storageName: "test-storage",
275
+ }),
276
+ });
237
277
 
238
278
  // Create a real group and add a member to create transactions
239
- const group = fixturesNode.createGroup();
279
+ const group = fixtures.node.createGroup();
240
280
 
241
281
  group.addMember("everyone", "reader");
242
282
 
@@ -256,17 +296,30 @@ describe("StorageApiSync", () => {
256
296
  const updatedKnownState = storage.getKnownState(group.id);
257
297
  expect(updatedKnownState).toEqual(group.core.knownState());
258
298
 
259
- node.setStorage(storage);
299
+ client.addStorage({ storage });
260
300
 
261
- const groupOnNode = await loadCoValueOrFail(node, group.id);
301
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
262
302
  expect(groupOnNode.get("everyone")).toEqual("reader");
263
303
  });
264
304
 
265
305
  test("should handle correction when header assumption is invalid", async () => {
266
- const { fixturesNode } = await createFixturesNode();
267
- const { node, storage } = await createTestNode();
306
+ const fixtures = setupTestNode();
307
+ fixtures.addStorage({
308
+ storage: createSyncStorage({
309
+ nodeName: "test",
310
+ storageName: "test-storage",
311
+ }),
312
+ });
268
313
 
269
- const group = fixturesNode.createGroup();
314
+ const client = setupTestNode();
315
+ const { storage } = client.addStorage({
316
+ storage: createSyncStorage({
317
+ nodeName: "test",
318
+ storageName: "test-storage",
319
+ }),
320
+ });
321
+
322
+ const group = fixtures.node.createGroup();
270
323
  const knownState = group.core.knownState();
271
324
 
272
325
  group.addMember("everyone", "reader");
@@ -290,17 +343,30 @@ describe("StorageApiSync", () => {
290
343
  const updatedKnownState = storage.getKnownState(group.id);
291
344
  expect(updatedKnownState).toEqual(group.core.knownState());
292
345
 
293
- node.setStorage(storage);
294
- const groupOnNode = await loadCoValueOrFail(node, group.id);
346
+ client.addStorage({ storage });
347
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
295
348
 
296
349
  expect(groupOnNode.get("everyone")).toEqual("reader");
297
350
  });
298
351
 
299
352
  test("should handle correction when new content assumption is invalid", async () => {
300
- const { fixturesNode } = await createFixturesNode();
301
- const { node, storage } = await createTestNode();
353
+ const fixtures = setupTestNode();
354
+ fixtures.addStorage({
355
+ storage: createSyncStorage({
356
+ nodeName: "test",
357
+ storageName: "test-storage",
358
+ }),
359
+ });
302
360
 
303
- const group = fixturesNode.createGroup();
361
+ const client = setupTestNode();
362
+ const { storage } = client.addStorage({
363
+ storage: createSyncStorage({
364
+ nodeName: "test",
365
+ storageName: "test-storage",
366
+ }),
367
+ });
368
+
369
+ const group = fixtures.node.createGroup();
304
370
 
305
371
  const initialContent = getNewContentSince(
306
372
  group.core,
@@ -340,17 +406,30 @@ describe("StorageApiSync", () => {
340
406
  const finalKnownState = storage.getKnownState(group.id);
341
407
  expect(finalKnownState).toEqual(group.core.knownState());
342
408
 
343
- node.setStorage(storage);
344
- const groupOnNode = await loadCoValueOrFail(node, group.id);
409
+ client.addStorage({ storage });
410
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
345
411
 
346
412
  expect(groupOnNode.get("everyone")).toEqual("writer");
347
413
  });
348
414
 
349
415
  test("should log error and fail when correction callback returns undefined", async () => {
350
- const { fixturesNode } = await createFixturesNode();
351
- const { storage } = await createTestNode();
416
+ const fixtures = setupTestNode();
417
+ fixtures.addStorage({
418
+ storage: createSyncStorage({
419
+ nodeName: "test",
420
+ storageName: "test-storage",
421
+ }),
422
+ });
423
+
424
+ const client = setupTestNode();
425
+ const { storage } = client.addStorage({
426
+ storage: createSyncStorage({
427
+ nodeName: "test",
428
+ storageName: "test-storage",
429
+ }),
430
+ });
352
431
 
353
- const group = fixturesNode.createGroup();
432
+ const group = fixtures.node.createGroup();
354
433
 
355
434
  const knownState = group.core.knownState();
356
435
  group.addMember("everyone", "writer");
@@ -385,10 +464,23 @@ describe("StorageApiSync", () => {
385
464
  });
386
465
 
387
466
  test("should log error and fail when correction callback returns invalid content message", async () => {
388
- const { fixturesNode } = await createFixturesNode();
389
- const { storage } = await createTestNode();
467
+ const fixtures = setupTestNode();
468
+ fixtures.addStorage({
469
+ storage: createSyncStorage({
470
+ nodeName: "test",
471
+ storageName: "test-storage",
472
+ }),
473
+ });
390
474
 
391
- const group = fixturesNode.createGroup();
475
+ const client = setupTestNode();
476
+ const { storage } = client.addStorage({
477
+ storage: createSyncStorage({
478
+ nodeName: "test",
479
+ storageName: "test-storage",
480
+ }),
481
+ });
482
+
483
+ const group = fixtures.node.createGroup();
392
484
 
393
485
  const knownState = group.core.knownState();
394
486
  group.addMember("everyone", "writer");
@@ -420,15 +512,39 @@ describe("StorageApiSync", () => {
420
512
  });
421
513
 
422
514
  test("should successfully store coValue with multiple sessions", async () => {
423
- const { fixturesNode, dbPath } = await createFixturesNode();
424
- const { fixturesNode: fixtureNode2 } = await createFixturesNode(dbPath);
425
- const { node, storage } = await createTestNode();
515
+ const dbPath = getDbPath();
516
+
517
+ const fixtures = setupTestNode();
518
+ fixtures.addStorage({
519
+ storage: createSyncStorage({
520
+ filename: dbPath,
521
+ nodeName: "test",
522
+ storageName: "test-storage",
523
+ }),
524
+ });
525
+
526
+ const fixture2 = setupTestNode();
527
+ fixture2.addStorage({
528
+ storage: createSyncStorage({
529
+ filename: dbPath,
530
+ nodeName: "test",
531
+ storageName: "test-storage",
532
+ }),
533
+ });
426
534
 
427
- const coValue = fixturesNode.createCoValue({
535
+ const client = setupTestNode();
536
+ const { storage } = client.addStorage({
537
+ storage: createSyncStorage({
538
+ nodeName: "test",
539
+ storageName: "test-storage",
540
+ }),
541
+ });
542
+
543
+ const coValue = fixtures.node.createCoValue({
428
544
  type: "comap",
429
545
  ruleset: { type: "unsafeAllowAll" },
430
546
  meta: null,
431
- ...crypto.createdNowUnique(),
547
+ ...fixtures.node.crypto.createdNowUnique(),
432
548
  });
433
549
 
434
550
  coValue.makeTransaction(
@@ -443,7 +559,7 @@ describe("StorageApiSync", () => {
443
559
  await coValue.waitForSync();
444
560
 
445
561
  const mapOnNode2 = await loadCoValueOrFail(
446
- fixtureNode2,
562
+ fixture2.node,
447
563
  coValue.id as CoID<RawCoMap>,
448
564
  );
449
565
 
@@ -466,27 +582,216 @@ describe("StorageApiSync", () => {
466
582
 
467
583
  storage.store(contentMessage, correctionCallback);
468
584
 
469
- node.setStorage(storage);
585
+ client.addStorage({ storage });
470
586
 
471
- const finalMap = await loadCoValueOrFail(node, mapOnNode2.id);
587
+ const finalMap = await loadCoValueOrFail(client.node, mapOnNode2.id);
472
588
  expect(finalMap.core.knownState()).toEqual(knownState);
473
589
  });
474
590
  });
475
591
 
592
+ describe("delete flow", () => {
593
+ test("deleteCoValue enqueues the coValue for erasure", async () => {
594
+ const client = setupTestNode();
595
+ const { storage } = client.addStorage({
596
+ storage: createSyncStorage({
597
+ nodeName: "test",
598
+ storageName: "test-storage",
599
+ }),
600
+ });
601
+
602
+ const group = client.node.createGroup();
603
+ const map = group.createMap();
604
+ map.core.deleteCoValue();
605
+ await map.core.waitForSync();
606
+
607
+ const queued = await getAllCoValuesWaitingForDelete(storage);
608
+ expect(queued).toContain(map.id);
609
+ });
610
+
611
+ test("background erasure doesn't run if not enabled", async () => {
612
+ const dbPath = getDbPath();
613
+ const node = setupTestNode();
614
+ const { storage } = node.addStorage({
615
+ storage: createSyncStorage({
616
+ filename: dbPath,
617
+ nodeName: "test",
618
+ storageName: "test-storage",
619
+ }),
620
+ });
621
+
622
+ const group = node.node.createGroup();
623
+ const map = group.createMap();
624
+ map.set("k", "v");
625
+ await map.core.waitForSync();
626
+
627
+ vi.useFakeTimers();
628
+
629
+ map.core.deleteCoValue();
630
+ await map.core.waitForSync();
631
+
632
+ await vi.advanceTimersByTimeAsync(70_000);
633
+
634
+ // Queue drained
635
+ expect(await getAllCoValuesWaitingForDelete(storage)).toContain(map.id);
636
+ });
637
+
638
+ test("background erasure run if enabled", async () => {
639
+ const dbPath = getDbPath();
640
+ const node = setupTestNode();
641
+ const { storage } = node.addStorage({
642
+ storage: createSyncStorage({
643
+ filename: dbPath,
644
+ nodeName: "test",
645
+ storageName: "test-storage",
646
+ }),
647
+ });
648
+
649
+ vi.useFakeTimers();
650
+
651
+ node.node.enableDeletedCoValuesErasure();
652
+
653
+ const group = node.node.createGroup();
654
+ const map = group.createMap();
655
+ map.set("k", "v");
656
+ await map.core.waitForSync();
657
+
658
+ map.core.deleteCoValue();
659
+ await map.core.waitForSync();
660
+
661
+ await vi.advanceTimersByTimeAsync(70_000);
662
+
663
+ // Queue drained
664
+ expect(await getAllCoValuesWaitingForDelete(storage)).not.toContain(
665
+ map.id,
666
+ );
667
+
668
+ const sessionIDs = await getCoValueStoredSessions(storage, map.id);
669
+
670
+ expect(sessionIDs).toHaveLength(1);
671
+ expect(sessionIDs[0]).toMatch(/_session_d[1-9A-HJ-NP-Za-km-z]+\$$/); // Delete session format
672
+ });
673
+
674
+ test("eraseAllDeletedCoValues deletes history but preserves tombstone", async () => {
675
+ const dbPath = getDbPath();
676
+
677
+ const node = setupTestNode();
678
+ const { storage } = node.addStorage({
679
+ storage: createSyncStorage({
680
+ filename: dbPath,
681
+ nodeName: "test",
682
+ storageName: "test-storage",
683
+ }),
684
+ });
685
+
686
+ const group = node.node.createGroup();
687
+ const map = group.createMap();
688
+ map.set("k", "v");
689
+ await map.core.waitForSync();
690
+
691
+ map.core.deleteCoValue();
692
+ await map.core.waitForSync();
693
+
694
+ expect(await getAllCoValuesWaitingForDelete(storage)).toContain(map.id);
695
+
696
+ await storage.eraseAllDeletedCoValues();
697
+
698
+ // Queue drained
699
+ expect(await getAllCoValuesWaitingForDelete(storage)).not.toContain(
700
+ map.id,
701
+ );
702
+
703
+ // Tombstone preserved + history erased when loaded from storage
704
+ const client = setupTestNode();
705
+ const { storage: clientStorage } = client.addStorage({
706
+ storage: createSyncStorage({
707
+ filename: dbPath,
708
+ nodeName: "test",
709
+ storageName: "test-storage",
710
+ }),
711
+ });
712
+
713
+ const loaded = await loadCoValueOrFail(
714
+ client.node,
715
+ map.id as CoID<RawCoMap>,
716
+ );
717
+
718
+ expect(loaded.core.isDeleted).toBe(true);
719
+ expect(loaded.get("k")).toBeUndefined();
720
+
721
+ const sessionIDs = await getCoValueStoredSessions(clientStorage, map.id);
722
+
723
+ expect(sessionIDs).toHaveLength(1);
724
+ expect(sessionIDs[0]).toMatch(/_session_d[1-9A-HJ-NP-Za-km-z]+\$$/); // Delete session format
725
+ });
726
+
727
+ test("eraseAllDeletedCoValues does not break when called while a coValue is streaming from storage", async () => {
728
+ const dbPath = getDbPath();
729
+
730
+ const node = setupTestNode();
731
+
732
+ const storage = createSyncStorage({
733
+ filename: dbPath,
734
+ nodeName: "test",
735
+ storageName: "test-storage",
736
+ });
737
+ node.addStorage({ storage });
738
+
739
+ const group = node.node.createGroup();
740
+ const map = group.createMap();
741
+ fillCoMapWithLargeData(map);
742
+ await map.core.waitForSync();
743
+ map.core.deleteCoValue();
744
+ await map.core.waitForSync();
745
+
746
+ storage.close();
747
+
748
+ const newStorage = createSyncStorage({
749
+ filename: dbPath,
750
+ nodeName: "test",
751
+ storageName: "test-storage",
752
+ });
753
+
754
+ const callback = vi.fn();
755
+
756
+ const loadPromise = new Promise((resolve) => {
757
+ newStorage.load(map.id, callback, resolve);
758
+ });
759
+ await newStorage.eraseAllDeletedCoValues();
760
+
761
+ expect(await loadPromise).toBe(true);
762
+ });
763
+ });
764
+
476
765
  describe("dependencies", () => {
477
766
  test("should load dependencies before dependent coValues and update all known states", async () => {
478
- const { fixturesNode, dbPath } = await createFixturesNode();
479
- const { node, storage } = await createTestNode(dbPath);
767
+ const dbPath = getDbPath();
768
+ const fixtures = setupTestNode();
769
+ fixtures.addStorage({
770
+ storage: createSyncStorage({
771
+ filename: dbPath,
772
+ nodeName: "test",
773
+ storageName: "test-storage",
774
+ }),
775
+ });
776
+
777
+ const client = setupTestNode();
778
+ const { storage } = client.addStorage({
779
+ storage: createSyncStorage({
780
+ filename: dbPath,
781
+ nodeName: "test",
782
+ storageName: "test-storage",
783
+ }),
784
+ });
480
785
 
481
786
  // Create a group and a map owned by that group to create dependencies
482
- const group = fixturesNode.createGroup();
787
+ const group = fixtures.node.createGroup();
483
788
  group.addMember("everyone", "reader");
484
789
  const map = group.createMap({ test: "value" });
485
790
  await group.core.waitForSync();
486
791
  await map.core.waitForSync();
487
792
 
488
793
  const callback = vi.fn((content) =>
489
- node.syncManager.handleNewContent(content, "storage"),
794
+ client.node.syncManager.handleNewContent(content, "storage"),
490
795
  );
491
796
  const done = vi.fn();
492
797
 
@@ -521,24 +826,40 @@ describe("StorageApiSync", () => {
521
826
  expect(updatedGroupKnownState).toEqual(group.core.knownState());
522
827
  expect(updatedMapKnownState).toEqual(map.core.knownState());
523
828
 
524
- node.setStorage(storage);
525
- const mapOnNode = await loadCoValueOrFail(node, map.id);
829
+ client.addStorage({ storage });
830
+ const mapOnNode = await loadCoValueOrFail(client.node, map.id);
526
831
  expect(mapOnNode.get("test")).toEqual("value");
527
832
  });
528
833
 
529
834
  test("should skip loading already loaded dependencies", async () => {
530
- const { fixturesNode, dbPath } = await createFixturesNode();
531
- const { node, storage } = await createTestNode(dbPath);
835
+ const dbPath = getDbPath();
836
+ const fixtures = setupTestNode();
837
+ fixtures.addStorage({
838
+ storage: createSyncStorage({
839
+ filename: dbPath,
840
+ nodeName: "test",
841
+ storageName: "test-storage",
842
+ }),
843
+ });
844
+
845
+ const client = setupTestNode();
846
+ const { storage } = client.addStorage({
847
+ storage: createSyncStorage({
848
+ filename: dbPath,
849
+ nodeName: "test",
850
+ storageName: "test-storage",
851
+ }),
852
+ });
532
853
 
533
854
  // Create a group and a map owned by that group
534
- const group = fixturesNode.createGroup();
855
+ const group = fixtures.node.createGroup();
535
856
  group.addMember("everyone", "reader");
536
857
  const map = group.createMap({ test: "value" });
537
858
  await group.core.waitForSync();
538
859
  await map.core.waitForSync();
539
860
 
540
861
  const callback = vi.fn((content) =>
541
- node.syncManager.handleNewContent(content, "storage"),
862
+ client.node.syncManager.handleNewContent(content, "storage"),
542
863
  );
543
864
  const done = vi.fn();
544
865
 
@@ -574,24 +895,40 @@ describe("StorageApiSync", () => {
574
895
  const finalMapKnownState = storage.getKnownState(map.id);
575
896
  expect(finalMapKnownState).toEqual(map.core.knownState());
576
897
 
577
- node.setStorage(storage);
578
- const mapOnNode = await loadCoValueOrFail(node, map.id);
898
+ client.addStorage({ storage });
899
+ const mapOnNode = await loadCoValueOrFail(client.node, map.id);
579
900
  expect(mapOnNode.get("test")).toEqual("value");
580
901
  });
581
902
 
582
903
  test("should load dependencies again if they were unmounted", async () => {
583
- const { fixturesNode, dbPath } = await createFixturesNode();
584
- const { node, storage } = await createTestNode(dbPath);
904
+ const dbPath = getDbPath();
905
+ const fixtures = setupTestNode();
906
+ fixtures.addStorage({
907
+ storage: createSyncStorage({
908
+ filename: dbPath,
909
+ nodeName: "test",
910
+ storageName: "test-storage",
911
+ }),
912
+ });
913
+
914
+ const client = setupTestNode();
915
+ const { storage } = client.addStorage({
916
+ storage: createSyncStorage({
917
+ filename: dbPath,
918
+ nodeName: "test",
919
+ storageName: "test-storage",
920
+ }),
921
+ });
585
922
 
586
923
  // Create a group and a map owned by that group
587
- const group = fixturesNode.createGroup();
924
+ const group = fixtures.node.createGroup();
588
925
  group.addMember("everyone", "reader");
589
926
  const map = group.createMap({ test: "value" });
590
927
  await group.core.waitForSync();
591
928
  await map.core.waitForSync();
592
929
 
593
930
  const callback = vi.fn((content) =>
594
- node.syncManager.handleNewContent(content, "storage"),
931
+ client.node.syncManager.handleNewContent(content, "storage"),
595
932
  );
596
933
  const done = vi.fn();
597
934
 
@@ -623,19 +960,35 @@ describe("StorageApiSync", () => {
623
960
 
624
961
  expect(done).toHaveBeenCalledWith(true);
625
962
 
626
- node.setStorage(storage);
627
- const mapOnNode = await loadCoValueOrFail(node, map.id);
963
+ client.addStorage({ storage });
964
+ const mapOnNode = await loadCoValueOrFail(client.node, map.id);
628
965
  expect(mapOnNode.get("test")).toEqual("value");
629
966
  });
630
967
  });
631
968
 
632
969
  describe("waitForSync", () => {
633
970
  test("should resolve immediately when coValue is already synced", async () => {
634
- const { fixturesNode, dbPath } = await createFixturesNode();
635
- const { node, storage } = await createTestNode(dbPath);
971
+ const dbPath = getDbPath();
972
+ const fixtures = setupTestNode();
973
+ fixtures.addStorage({
974
+ storage: createSyncStorage({
975
+ filename: dbPath,
976
+ nodeName: "test",
977
+ storageName: "test-storage",
978
+ }),
979
+ });
980
+
981
+ const client = setupTestNode();
982
+ const { storage } = client.addStorage({
983
+ storage: createSyncStorage({
984
+ filename: dbPath,
985
+ nodeName: "test",
986
+ storageName: "test-storage",
987
+ }),
988
+ });
636
989
 
637
990
  // Create a group and add a member
638
- const group = fixturesNode.createGroup();
991
+ const group = fixtures.node.createGroup();
639
992
  group.addMember("everyone", "reader");
640
993
  await group.core.waitForSync();
641
994
 
@@ -647,10 +1000,10 @@ describe("StorageApiSync", () => {
647
1000
  const correctionCallback = vi.fn();
648
1001
  storage.store(contentMessage, correctionCallback);
649
1002
 
650
- node.setStorage(storage);
1003
+ client.addStorage({ storage });
651
1004
 
652
1005
  // Load the group on the new node
653
- const groupOnNode = await loadCoValueOrFail(node, group.id);
1006
+ const groupOnNode = await loadCoValueOrFail(client.node, group.id);
654
1007
 
655
1008
  // Wait for sync should resolve immediately since the coValue is already synced
656
1009
  await expect(
@@ -663,7 +1016,13 @@ describe("StorageApiSync", () => {
663
1016
 
664
1017
  describe("close", () => {
665
1018
  test("should close storage without throwing errors", async () => {
666
- const { storage } = await createTestNode();
1019
+ const client = setupTestNode();
1020
+ const { storage } = client.addStorage({
1021
+ storage: createSyncStorage({
1022
+ nodeName: "test",
1023
+ storageName: "test-storage",
1024
+ }),
1025
+ });
667
1026
 
668
1027
  expect(() => storage.close()).not.toThrow();
669
1028
  });
@@ -671,11 +1030,27 @@ describe("StorageApiSync", () => {
671
1030
 
672
1031
  describe("loadKnownState", () => {
673
1032
  test("should return correct knownState structure for existing CoValue", async () => {
674
- const { fixturesNode, dbPath } = await createFixturesNode();
675
- const { storage } = await createTestNode(dbPath);
1033
+ const dbPath = getDbPath();
1034
+ const fixtures = setupTestNode();
1035
+ fixtures.addStorage({
1036
+ storage: createSyncStorage({
1037
+ filename: dbPath,
1038
+ nodeName: "test",
1039
+ storageName: "test-storage",
1040
+ }),
1041
+ });
1042
+
1043
+ const client = setupTestNode();
1044
+ const { storage } = client.addStorage({
1045
+ storage: createSyncStorage({
1046
+ filename: dbPath,
1047
+ nodeName: "test",
1048
+ storageName: "test-storage",
1049
+ }),
1050
+ });
676
1051
 
677
1052
  // Create a group to have data in the database
678
- const group = fixturesNode.createGroup();
1053
+ const group = fixtures.node.createGroup();
679
1054
  group.addMember("everyone", "reader");
680
1055
  await group.core.waitForSync();
681
1056
 
@@ -692,7 +1067,13 @@ describe("StorageApiSync", () => {
692
1067
  });
693
1068
 
694
1069
  test("should return undefined for non-existent CoValue", async () => {
695
- const { storage } = await createTestNode();
1070
+ const client = setupTestNode();
1071
+ const { storage } = client.addStorage({
1072
+ storage: createSyncStorage({
1073
+ nodeName: "test",
1074
+ storageName: "test-storage",
1075
+ }),
1076
+ });
696
1077
 
697
1078
  const result = await new Promise<CoValueKnownState | undefined>(
698
1079
  (resolve) => {
@@ -704,15 +1085,31 @@ describe("StorageApiSync", () => {
704
1085
  });
705
1086
 
706
1087
  test("should handle CoValue with no sessions (header only)", async () => {
707
- const { fixturesNode, dbPath } = await createFixturesNode();
708
- const { storage } = await createTestNode(dbPath);
1088
+ const dbPath = getDbPath();
1089
+ const fixtures = setupTestNode();
1090
+ fixtures.addStorage({
1091
+ storage: createSyncStorage({
1092
+ filename: dbPath,
1093
+ nodeName: "test",
1094
+ storageName: "test-storage",
1095
+ }),
1096
+ });
1097
+
1098
+ const client = setupTestNode();
1099
+ const { storage } = client.addStorage({
1100
+ storage: createSyncStorage({
1101
+ filename: dbPath,
1102
+ nodeName: "test",
1103
+ storageName: "test-storage",
1104
+ }),
1105
+ });
709
1106
 
710
1107
  // Create a CoValue with just a header (no transactions yet)
711
- const coValue = fixturesNode.createCoValue({
1108
+ const coValue = fixtures.node.createCoValue({
712
1109
  type: "comap",
713
1110
  ruleset: { type: "unsafeAllowAll" },
714
1111
  meta: null,
715
- ...crypto.createdNowUnique(),
1112
+ ...fixtures.node.crypto.createdNowUnique(),
716
1113
  });
717
1114
  await coValue.waitForSync();
718
1115
 
@@ -730,23 +1127,47 @@ describe("StorageApiSync", () => {
730
1127
  });
731
1128
 
732
1129
  test("should handle CoValue with multiple sessions", async () => {
733
- const { fixturesNode, dbPath } = await createFixturesNode();
734
- const { fixturesNode: fixturesNode2 } = await createFixturesNode(dbPath);
735
- const { storage } = await createTestNode(dbPath);
1130
+ const dbPath = getDbPath();
1131
+ const fixtures = setupTestNode();
1132
+ fixtures.addStorage({
1133
+ storage: createSyncStorage({
1134
+ filename: dbPath,
1135
+ nodeName: "test",
1136
+ storageName: "test-storage",
1137
+ }),
1138
+ });
1139
+
1140
+ const fixtures2 = setupTestNode();
1141
+ fixtures2.addStorage({
1142
+ storage: createSyncStorage({
1143
+ filename: dbPath,
1144
+ nodeName: "test",
1145
+ storageName: "test-storage",
1146
+ }),
1147
+ });
1148
+
1149
+ const client = setupTestNode();
1150
+ const { storage } = client.addStorage({
1151
+ storage: createSyncStorage({
1152
+ filename: dbPath,
1153
+ nodeName: "test",
1154
+ storageName: "test-storage",
1155
+ }),
1156
+ });
736
1157
 
737
1158
  // Create a CoValue and have two nodes make transactions
738
- const coValue = fixturesNode.createCoValue({
1159
+ const coValue = fixtures.node.createCoValue({
739
1160
  type: "comap",
740
1161
  ruleset: { type: "unsafeAllowAll" },
741
1162
  meta: null,
742
- ...crypto.createdNowUnique(),
1163
+ ...fixtures.node.crypto.createdNowUnique(),
743
1164
  });
744
1165
 
745
1166
  coValue.makeTransaction([{ key1: "value1" }], "trusting");
746
1167
  await coValue.waitForSync();
747
1168
 
748
1169
  const coValueOnNode2 = await loadCoValueOrFail(
749
- fixturesNode2,
1170
+ fixtures2.node,
750
1171
  coValue.id as CoID<RawCoMap>,
751
1172
  );
752
1173
 
@@ -771,11 +1192,27 @@ describe("StorageApiSync", () => {
771
1192
  });
772
1193
 
773
1194
  test("should use cache when knownState is cached", async () => {
774
- const { fixturesNode, dbPath } = await createFixturesNode();
775
- const { storage } = await createTestNode(dbPath);
1195
+ const dbPath = getDbPath();
1196
+ const fixtures = setupTestNode();
1197
+ fixtures.addStorage({
1198
+ storage: createSyncStorage({
1199
+ filename: dbPath,
1200
+ nodeName: "test",
1201
+ storageName: "test-storage",
1202
+ }),
1203
+ });
1204
+
1205
+ const client = setupTestNode();
1206
+ const { storage } = client.addStorage({
1207
+ storage: createSyncStorage({
1208
+ filename: dbPath,
1209
+ nodeName: "test",
1210
+ storageName: "test-storage",
1211
+ }),
1212
+ });
776
1213
 
777
1214
  // Create a group to have data in the database
778
- const group = fixturesNode.createGroup();
1215
+ const group = fixtures.node.createGroup();
779
1216
  group.addMember("everyone", "reader");
780
1217
  await group.core.waitForSync();
781
1218