cojson-storage-do-sqlite 0.18.28

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 (39) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +9 -0
  3. package/LICENSE.txt +19 -0
  4. package/README.md +4 -0
  5. package/dist/index.d.ts +15 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +37 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/tests/dosqlite.d.ts +89 -0
  10. package/dist/tests/dosqlite.d.ts.map +1 -0
  11. package/dist/tests/dosqlite.js +489 -0
  12. package/dist/tests/dosqlite.js.map +1 -0
  13. package/dist/tests/dosqlite.test.d.ts +2 -0
  14. package/dist/tests/dosqlite.test.d.ts.map +1 -0
  15. package/dist/tests/dosqlite.test.js +284 -0
  16. package/dist/tests/dosqlite.test.js.map +1 -0
  17. package/dist/tests/messagesTestUtils.d.ts +10 -0
  18. package/dist/tests/messagesTestUtils.d.ts.map +1 -0
  19. package/dist/tests/messagesTestUtils.js +42 -0
  20. package/dist/tests/messagesTestUtils.js.map +1 -0
  21. package/dist/tests/testUtils.d.ts +10 -0
  22. package/dist/tests/testUtils.d.ts.map +1 -0
  23. package/dist/tests/testUtils.js +88 -0
  24. package/dist/tests/testUtils.js.map +1 -0
  25. package/dist/tests/vitest.config.d.ts +3 -0
  26. package/dist/tests/vitest.config.d.ts.map +1 -0
  27. package/dist/tests/vitest.config.js +8 -0
  28. package/dist/tests/vitest.config.js.map +1 -0
  29. package/package.json +28 -0
  30. package/src/index.ts +60 -0
  31. package/src/tests/dosqlite.test.ts +338 -0
  32. package/src/tests/dosqlite.ts +771 -0
  33. package/src/tests/messagesTestUtils.ts +72 -0
  34. package/src/tests/testUtils.ts +112 -0
  35. package/src/tests/tsconfig.json +43 -0
  36. package/src/tests/vitest.config.ts +8 -0
  37. package/src/tests/worker-configuration.d.ts +9681 -0
  38. package/src/tests/wrangler.jsonc +20 -0
  39. package/tsconfig.json +17 -0
@@ -0,0 +1,771 @@
1
+ import "jazz-tools/load-edge-wasm";
2
+ import { env, DurableObject, WorkerEntrypoint } from "cloudflare:workers";
3
+ import {
4
+ LocalNode,
5
+ RawCoID,
6
+ StorageApiSync,
7
+ SyncMessage,
8
+ cojsonInternals,
9
+ } from "cojson";
10
+ import { WasmCrypto } from "cojson/crypto/WasmCrypto";
11
+
12
+ import { toSimplifiedMessages } from "./messagesTestUtils.js";
13
+ import { getDurableObjectSqlStorage } from "../index.js";
14
+
15
+ const Crypto = await WasmCrypto.create();
16
+
17
+ // Adopted from cojson-storage-sqlite/src/tests/testUtils.js
18
+ export function trackMessages() {
19
+ const messages: {
20
+ from: "client" | "server" | "storage";
21
+ msg: SyncMessage;
22
+ }[] = [];
23
+
24
+ const originalLoad = StorageApiSync.prototype.load;
25
+ const originalStore = StorageApiSync.prototype.store;
26
+
27
+ StorageApiSync.prototype.load = async function (id, callback, done) {
28
+ messages.push({
29
+ from: "client",
30
+ msg: {
31
+ action: "load",
32
+ id: id as RawCoID,
33
+ header: false,
34
+ sessions: {},
35
+ },
36
+ });
37
+ return originalLoad.call(
38
+ this,
39
+ id,
40
+ (msg) => {
41
+ messages.push({
42
+ from: "storage",
43
+ msg,
44
+ });
45
+ callback(msg);
46
+ },
47
+ done,
48
+ );
49
+ };
50
+
51
+ StorageApiSync.prototype.store = function (data, correctionCallback) {
52
+ messages.push({
53
+ from: "client",
54
+ msg: data,
55
+ });
56
+
57
+ return originalStore.call(this, data, (msg) => {
58
+ messages.push({
59
+ from: "storage",
60
+ msg: {
61
+ action: "known",
62
+ isCorrection: true,
63
+ ...msg,
64
+ },
65
+ });
66
+
67
+ const correctionMessages = correctionCallback(msg);
68
+
69
+ if (correctionMessages) {
70
+ for (const msg of correctionMessages) {
71
+ messages.push({
72
+ from: "client",
73
+ msg,
74
+ });
75
+ }
76
+ }
77
+
78
+ return correctionMessages;
79
+ });
80
+ };
81
+
82
+ const restore = () => {
83
+ StorageApiSync.prototype.load = originalLoad;
84
+ StorageApiSync.prototype.store = originalStore;
85
+ messages.length = 0;
86
+ };
87
+
88
+ return {
89
+ messages,
90
+ restore,
91
+ };
92
+ }
93
+
94
+ function waitFor(
95
+ callback: () => boolean | undefined | Promise<boolean | undefined>,
96
+ ) {
97
+ return new Promise<void>((resolve, reject) => {
98
+ const checkPassed = async () => {
99
+ try {
100
+ return { ok: await callback(), error: null };
101
+ } catch (error) {
102
+ return { ok: false, error };
103
+ }
104
+ };
105
+
106
+ let retries = 0;
107
+
108
+ const interval = setInterval(async () => {
109
+ const { ok, error } = await checkPassed();
110
+
111
+ if (ok !== false) {
112
+ clearInterval(interval);
113
+ resolve();
114
+ }
115
+
116
+ if (++retries > 10) {
117
+ clearInterval(interval);
118
+ reject(error);
119
+ }
120
+ }, 100);
121
+ });
122
+ }
123
+
124
+ /**
125
+ * Due to issues with @cloudflare/vitest-pool-workers and loading wasm modules
126
+ * implementing the test logic in the durable object and running full server
127
+ * with wrangler.
128
+ *
129
+ */
130
+ export class DoSqlStoreTest extends DurableObject {
131
+ /**
132
+ * Test case from cojson-storage-sqlite: "should sync and load data from storage"
133
+ */
134
+ async storeLoadTest() {
135
+ const agentSecret = Crypto.newRandomAgentSecret();
136
+
137
+ const node1 = new LocalNode(
138
+ agentSecret,
139
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
140
+ Crypto,
141
+ );
142
+ const node1Sync = trackMessages();
143
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
144
+ node1.setStorage(storage1);
145
+ const group = node1.createGroup();
146
+
147
+ const map = group.createMap();
148
+
149
+ map.set("hello", "world");
150
+
151
+ await new Promise((resolve) => setTimeout(resolve, 200));
152
+
153
+ const messageRes1 = toSimplifiedMessages(
154
+ {
155
+ Map: map.core,
156
+ Group: group.core,
157
+ },
158
+ node1Sync.messages,
159
+ );
160
+
161
+ node1Sync.restore();
162
+
163
+ const node2 = new LocalNode(
164
+ agentSecret,
165
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
166
+ Crypto,
167
+ );
168
+
169
+ const node2Sync = trackMessages();
170
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
171
+ node2.setStorage(storage2);
172
+
173
+ const map2 = await node2.load(map.id);
174
+ if (map2 === "unavailable") {
175
+ throw new Error("Map is unavailable");
176
+ }
177
+
178
+ const messageRes2 = toSimplifiedMessages(
179
+ {
180
+ Map: map.core,
181
+ Group: group.core,
182
+ },
183
+ node2Sync.messages,
184
+ );
185
+
186
+ node2Sync.restore();
187
+
188
+ return {
189
+ messageRes1,
190
+ messageRes2,
191
+
192
+ map2Hello: map2.get("hello"),
193
+ };
194
+ }
195
+
196
+ /**
197
+ * Test case from cojson-storage-sqlite: "should send an empty content message if there is no content"
198
+ */
199
+ async storeLoadEmptyTest() {
200
+ const agentSecret = Crypto.newRandomAgentSecret();
201
+
202
+ const node1 = new LocalNode(
203
+ agentSecret,
204
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
205
+ Crypto,
206
+ );
207
+
208
+ const node1Sync = trackMessages();
209
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
210
+ node1.setStorage(storage1);
211
+
212
+ const group = node1.createGroup();
213
+
214
+ const map = group.createMap();
215
+
216
+ await new Promise((resolve) => setTimeout(resolve, 200));
217
+
218
+ const messageRes1 = toSimplifiedMessages(
219
+ {
220
+ Map: map.core,
221
+ Group: group.core,
222
+ },
223
+ node1Sync.messages,
224
+ );
225
+
226
+ node1Sync.restore();
227
+
228
+ const node2 = new LocalNode(
229
+ agentSecret,
230
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
231
+ Crypto,
232
+ );
233
+
234
+ const node2Sync = trackMessages();
235
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
236
+ node2.setStorage(storage2);
237
+
238
+ const map2 = await node2.load(map.id);
239
+ if (map2 === "unavailable") {
240
+ throw new Error("Map is unavailable");
241
+ }
242
+
243
+ const messageRes2 = toSimplifiedMessages(
244
+ {
245
+ Map: map.core,
246
+ Group: group.core,
247
+ },
248
+ node2Sync.messages,
249
+ );
250
+
251
+ node2Sync.restore();
252
+ return {
253
+ messageRes1,
254
+ messageRes2,
255
+ };
256
+ }
257
+
258
+ /**
259
+ * Test case from cojson-storage-sqlite: "should load dependencies correctly (group inheritance)"
260
+ */
261
+ async loadDependenciesTest() {
262
+ const agentSecret = Crypto.newRandomAgentSecret();
263
+
264
+ const node1 = new LocalNode(
265
+ agentSecret,
266
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
267
+ Crypto,
268
+ );
269
+
270
+ const node1Sync = trackMessages();
271
+
272
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
273
+ node1.setStorage(storage1);
274
+
275
+ const group = node1.createGroup();
276
+ const parentGroup = node1.createGroup();
277
+
278
+ group.extend(parentGroup);
279
+
280
+ const map = group.createMap();
281
+
282
+ map.set("hello", "world");
283
+
284
+ await new Promise((resolve) => setTimeout(resolve, 200));
285
+
286
+ const messageRes1 = toSimplifiedMessages(
287
+ {
288
+ Map: map.core,
289
+ Group: group.core,
290
+ ParentGroup: parentGroup.core,
291
+ },
292
+ node1Sync.messages,
293
+ );
294
+ node1Sync.restore();
295
+
296
+ const node2 = new LocalNode(
297
+ agentSecret,
298
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
299
+ Crypto,
300
+ );
301
+
302
+ const node2Sync = trackMessages();
303
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
304
+ node2.setStorage(storage2);
305
+
306
+ await node2.load(map.id);
307
+
308
+ const mapLoaded = !!node2.expectCoValueLoaded(map.id);
309
+ const groupLoaded = !!node2.expectCoValueLoaded(group.id);
310
+ const parentGroupLoaded = !!node2.expectCoValueLoaded(parentGroup.id);
311
+
312
+ const messageRes2 = toSimplifiedMessages(
313
+ {
314
+ Map: map.core,
315
+ Group: group.core,
316
+ ParentGroup: parentGroup.core,
317
+ },
318
+ node2Sync.messages,
319
+ );
320
+ return {
321
+ messageRes1,
322
+ messageRes2,
323
+ mapLoaded,
324
+ groupLoaded,
325
+ parentGroupLoaded,
326
+ };
327
+ }
328
+
329
+ /**
330
+ * Test case from cojson-storage-sqlite: "should not send the same dependency value twice"
331
+ */
332
+ async duplicateDependencyTest() {
333
+ const agentSecret = Crypto.newRandomAgentSecret();
334
+
335
+ const node1 = new LocalNode(
336
+ agentSecret,
337
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
338
+ Crypto,
339
+ );
340
+
341
+ const node1Sync = trackMessages();
342
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
343
+ node1.setStorage(storage1);
344
+
345
+ const group = node1.createGroup();
346
+ const parentGroup = node1.createGroup();
347
+
348
+ group.extend(parentGroup);
349
+
350
+ const mapFromParent = parentGroup.createMap();
351
+ const map = group.createMap();
352
+
353
+ map.set("hello", "world");
354
+ mapFromParent.set("hello", "world");
355
+
356
+ await new Promise((resolve) => setTimeout(resolve, 200));
357
+
358
+ node1Sync.restore();
359
+
360
+ const node2 = new LocalNode(
361
+ agentSecret,
362
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
363
+ Crypto,
364
+ );
365
+
366
+ const node2Sync = trackMessages();
367
+
368
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
369
+ node2.setStorage(storage2);
370
+
371
+ await node2.load(map.id);
372
+ await node2.load(mapFromParent.id);
373
+
374
+ const mapLoaded = !!node2.expectCoValueLoaded(map.id);
375
+ const mapFromParentLoaded = !!node2.expectCoValueLoaded(mapFromParent.id);
376
+ const groupLoaded = !!node2.expectCoValueLoaded(group.id);
377
+ const parentGroupLoaded = !!node2.expectCoValueLoaded(parentGroup.id);
378
+
379
+ const messageRes1 = toSimplifiedMessages(
380
+ {
381
+ Map: map.core,
382
+ Group: group.core,
383
+ ParentGroup: parentGroup.core,
384
+ MapFromParent: mapFromParent.core,
385
+ },
386
+ node2Sync.messages,
387
+ );
388
+
389
+ return {
390
+ messageRes1,
391
+ mapLoaded,
392
+ mapFromParentLoaded,
393
+ groupLoaded,
394
+ parentGroupLoaded,
395
+ };
396
+ }
397
+
398
+ /**
399
+ * Test case from cojson-storage-sqlite: "should recover from data loss"
400
+ */
401
+ async dataLossRecoverTest() {
402
+ const agentSecret = Crypto.newRandomAgentSecret();
403
+
404
+ const node1 = new LocalNode(
405
+ agentSecret,
406
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
407
+ Crypto,
408
+ );
409
+
410
+ const node1Sync = trackMessages();
411
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
412
+ node1.setStorage(storage1);
413
+
414
+ const group = node1.createGroup();
415
+
416
+ const map = group.createMap();
417
+
418
+ map.set("0", 0);
419
+
420
+ await new Promise((resolve) => setTimeout(resolve, 200));
421
+
422
+ const originalStore = StorageApiSync.prototype.store;
423
+ StorageApiSync.prototype.store = () => false;
424
+
425
+ map.set("1", 1);
426
+ map.set("2", 2);
427
+
428
+ await new Promise((resolve) => setTimeout(resolve, 200));
429
+
430
+ StorageApiSync.prototype.store = originalStore;
431
+
432
+ map.set("3", 3);
433
+
434
+ await new Promise((resolve) => setTimeout(resolve, 200));
435
+
436
+ const messageRes1 = toSimplifiedMessages(
437
+ {
438
+ Map: map.core,
439
+ Group: group.core,
440
+ },
441
+ node1Sync.messages,
442
+ );
443
+
444
+ node1Sync.restore();
445
+
446
+ const node2 = new LocalNode(
447
+ agentSecret,
448
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
449
+ Crypto,
450
+ );
451
+
452
+ const node2Sync = trackMessages();
453
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
454
+ node2.setStorage(storage2);
455
+
456
+ const map2 = await node2.load(map.id);
457
+
458
+ if (map2 === "unavailable") {
459
+ throw new Error("Map is unavailable");
460
+ }
461
+
462
+ const mapContent = map2.toJSON();
463
+
464
+ const messageRes2 = toSimplifiedMessages(
465
+ {
466
+ Map: map.core,
467
+ Group: group.core,
468
+ },
469
+ node2Sync.messages,
470
+ );
471
+
472
+ return {
473
+ messageRes1,
474
+ messageRes2,
475
+ mapContent,
476
+ };
477
+ }
478
+
479
+ /**
480
+ * Test case from cojson-storage-sqlite: "should recover missing dependencies from storage"
481
+ */
482
+ async recoverMissingDependenciesTest() {
483
+ const agentSecret = Crypto.newRandomAgentSecret();
484
+
485
+ const account = LocalNode.internalCreateAccount({
486
+ crypto: Crypto,
487
+ });
488
+ const node1 = account.core.node;
489
+
490
+ const serverNode = new LocalNode(
491
+ agentSecret,
492
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
493
+ Crypto,
494
+ );
495
+
496
+ const [serverPeer, clientPeer] = cojsonInternals.connectedPeers(
497
+ node1.agentSecret,
498
+ serverNode.agentSecret,
499
+ {
500
+ peer1role: "server",
501
+ peer2role: "client",
502
+ },
503
+ );
504
+
505
+ node1.syncManager.addPeer(serverPeer);
506
+ serverNode.syncManager.addPeer(clientPeer);
507
+
508
+ // manual mock
509
+ const originalStore = StorageApiSync.prototype.store;
510
+ StorageApiSync.prototype.store = function (data, correctionCallback) {
511
+ if ([group.core.id, account.core.id as string].includes(data.id)) {
512
+ return false;
513
+ }
514
+ return originalStore.call(this, data, correctionCallback);
515
+ };
516
+
517
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
518
+ node1.setStorage(storage1);
519
+
520
+ const group = node1.createGroup();
521
+ group.addMember("everyone", "writer");
522
+
523
+ const map = group.createMap();
524
+
525
+ map.set("0", 0);
526
+
527
+ StorageApiSync.prototype.store = originalStore;
528
+
529
+ await new Promise((resolve) => setTimeout(resolve, 200));
530
+
531
+ const node2 = new LocalNode(
532
+ Crypto.newRandomAgentSecret(),
533
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
534
+ Crypto,
535
+ );
536
+
537
+ const [serverPeer2, clientPeer2] = cojsonInternals.connectedPeers(
538
+ node1.agentSecret,
539
+ serverNode.agentSecret,
540
+ {
541
+ peer1role: "server",
542
+ peer2role: "client",
543
+ },
544
+ );
545
+
546
+ node2.syncManager.addPeer(serverPeer2);
547
+ serverNode.syncManager.addPeer(clientPeer2);
548
+
549
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
550
+ node2.setStorage(storage2);
551
+
552
+ const map2 = await node2.load(map.id);
553
+
554
+ if (map2 === "unavailable") {
555
+ throw new Error("Map is unavailable");
556
+ }
557
+
558
+ const mapContent = map2.toJSON();
559
+
560
+ return {
561
+ mapContent,
562
+ };
563
+ }
564
+
565
+ /**
566
+ * Test case from cojson-storage-sqlite: "should sync multiple sessions in a single content message"
567
+ */
568
+ async multipleSessionsSingleContentMessageTest() {
569
+ const agentSecret = Crypto.newRandomAgentSecret();
570
+
571
+ const node1 = new LocalNode(
572
+ agentSecret,
573
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
574
+ Crypto,
575
+ );
576
+
577
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
578
+ node1.setStorage(storage1);
579
+
580
+ const group = node1.createGroup();
581
+
582
+ const map = group.createMap();
583
+
584
+ map.set("hello", "world");
585
+
586
+ await new Promise((resolve) => setTimeout(resolve, 200));
587
+
588
+ node1.gracefulShutdown();
589
+
590
+ const node2 = new LocalNode(
591
+ agentSecret,
592
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
593
+ Crypto,
594
+ );
595
+
596
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
597
+ node2.setStorage(storage2);
598
+
599
+ const map2 = await node2.load(map.id);
600
+ if (map2 === "unavailable") {
601
+ throw new Error("Map is unavailable");
602
+ }
603
+
604
+ const map2Hello = map2.get("hello");
605
+
606
+ map2.set("hello", "world2");
607
+
608
+ await map2.core.waitForSync();
609
+
610
+ node2.gracefulShutdown();
611
+
612
+ const node3 = new LocalNode(
613
+ agentSecret,
614
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
615
+ Crypto,
616
+ );
617
+
618
+ const node3Sync = trackMessages();
619
+
620
+ const storage3 = getDurableObjectSqlStorage(this.ctx.storage);
621
+ node3.setStorage(storage3);
622
+
623
+ const map3 = await node3.load(map.id);
624
+ if (map3 === "unavailable") {
625
+ throw new Error("Map is unavailable");
626
+ }
627
+
628
+ const map3Hello = map3.get("hello");
629
+
630
+ const messageRes1 = toSimplifiedMessages(
631
+ {
632
+ Map: map.core,
633
+ Group: group.core,
634
+ },
635
+ node3Sync.messages,
636
+ );
637
+ node3Sync.restore();
638
+
639
+ return {
640
+ messageRes1,
641
+ map2Hello,
642
+ map3Hello,
643
+ };
644
+ }
645
+
646
+ /**
647
+ * Test case from cojson-storage-sqlite: "large coValue upload streaming"
648
+ */
649
+ async largeCoValueUploadTest() {
650
+ const agentSecret = Crypto.newRandomAgentSecret();
651
+
652
+ const node1 = new LocalNode(
653
+ agentSecret,
654
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
655
+ Crypto,
656
+ );
657
+
658
+ const storage1 = getDurableObjectSqlStorage(this.ctx.storage);
659
+ node1.setStorage(storage1);
660
+
661
+ const group = node1.createGroup();
662
+ const largeMap = group.createMap();
663
+
664
+ const dataSize = 1 * 1024 * 200;
665
+ const chunkSize = 1024; // 1KB chunks
666
+ const chunks = dataSize / chunkSize;
667
+
668
+ const value = "a".repeat(chunkSize);
669
+
670
+ for (let i = 0; i < chunks; i++) {
671
+ const key = `key${i}`;
672
+ largeMap.set(key, value, "trusting");
673
+ }
674
+
675
+ await largeMap.core.waitForSync();
676
+
677
+ node1.gracefulShutdown();
678
+
679
+ const node2 = new LocalNode(
680
+ agentSecret,
681
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
682
+ Crypto,
683
+ );
684
+
685
+ const node2Sync = trackMessages();
686
+
687
+ const storage2 = getDurableObjectSqlStorage(this.ctx.storage);
688
+ node2.setStorage(storage2);
689
+
690
+ const largeMapOnNode2 = await node2.load(largeMap.id);
691
+
692
+ if (largeMapOnNode2 === "unavailable") {
693
+ throw new Error("Map is unavailable");
694
+ }
695
+
696
+ await waitFor(() => {
697
+ if (
698
+ JSON.stringify(largeMapOnNode2.core.knownState()) !==
699
+ JSON.stringify(largeMap.core.knownState())
700
+ ) {
701
+ throw new Error("Map states are not equal");
702
+ }
703
+ return true;
704
+ });
705
+
706
+ const messageRes1 = toSimplifiedMessages(
707
+ {
708
+ Map: largeMap.core,
709
+ Group: group.core,
710
+ },
711
+ node2Sync.messages,
712
+ );
713
+
714
+ return {
715
+ messageRes1,
716
+ };
717
+ }
718
+ }
719
+
720
+ export default class EntryPoint extends WorkerEntrypoint {
721
+ async fetch(request: Request) {
722
+ if (request.method !== "POST") {
723
+ return new Response("Method not allowed", { status: 405 });
724
+ }
725
+ const path = new URL(request.url).pathname;
726
+ const body = await request.json();
727
+ if (
728
+ !(
729
+ typeof body === "object" &&
730
+ body !== null &&
731
+ "doId" in body &&
732
+ typeof body.doId === "string"
733
+ )
734
+ ) {
735
+ throw new Error("Invalid request body");
736
+ }
737
+
738
+ const stub = env.DoSqlStoreTest.getByName(
739
+ body.doId,
740
+ ) as DurableObjectStub<DoSqlStoreTest>;
741
+
742
+ if (path === "/sync-and-load") {
743
+ const res = await stub.storeLoadTest();
744
+ // @ts-expect-error ts2589 the type initiation is too deep
745
+ return Response.json(res);
746
+ } else if (path === "/sync-and-load-empty") {
747
+ const res = await stub.storeLoadEmptyTest();
748
+ return Response.json(res);
749
+ } else if (path === "/group-load") {
750
+ const res = await stub.loadDependenciesTest();
751
+ return Response.json(res);
752
+ } else if (path === "/group-load-duplicate") {
753
+ const res = await stub.duplicateDependencyTest();
754
+ return Response.json(res);
755
+ } else if (path === "/data-loss-recovery") {
756
+ const res = await stub.dataLossRecoverTest();
757
+ return Response.json(res);
758
+ } else if (path === "/missing-dependency-recovery") {
759
+ const res = await stub.recoverMissingDependenciesTest();
760
+ return Response.json(res);
761
+ } else if (path === "/multiple-sessions") {
762
+ const res = await stub.multipleSessionsSingleContentMessageTest();
763
+ return Response.json(res);
764
+ } else if (path === "/large-covalue-upload") {
765
+ const res = await stub.largeCoValueUploadTest();
766
+ return Response.json(res);
767
+ } else {
768
+ return new Response("Invalid test method", { status: 400 });
769
+ }
770
+ }
771
+ }