cojson 0.20.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +21 -0
- package/dist/GarbageCollector.d.ts +3 -3
- package/dist/GarbageCollector.d.ts.map +1 -1
- package/dist/GarbageCollector.js +4 -4
- package/dist/GarbageCollector.js.map +1 -1
- package/dist/PeerState.d.ts +6 -1
- package/dist/PeerState.d.ts.map +1 -1
- package/dist/PeerState.js +18 -3
- package/dist/PeerState.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +26 -5
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +115 -50
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValues/coList.d.ts +1 -0
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +3 -0
- package/dist/coValues/coList.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/exports.d.ts +3 -3
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +2 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +12 -0
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +51 -3
- package/dist/localNode.js.map +1 -1
- package/dist/queue/LinkedList.d.ts +9 -3
- package/dist/queue/LinkedList.d.ts.map +1 -1
- package/dist/queue/LinkedList.js +30 -1
- package/dist/queue/LinkedList.js.map +1 -1
- package/dist/queue/OutgoingLoadQueue.d.ts +95 -0
- package/dist/queue/OutgoingLoadQueue.d.ts.map +1 -0
- package/dist/queue/OutgoingLoadQueue.js +240 -0
- package/dist/queue/OutgoingLoadQueue.js.map +1 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +34 -41
- package/dist/sync.js.map +1 -1
- package/dist/tests/LinkedList.test.js +90 -0
- package/dist/tests/LinkedList.test.js.map +1 -1
- package/dist/tests/OutgoingLoadQueue.test.d.ts +2 -0
- package/dist/tests/OutgoingLoadQueue.test.d.ts.map +1 -0
- package/dist/tests/OutgoingLoadQueue.test.js +814 -0
- package/dist/tests/OutgoingLoadQueue.test.js.map +1 -0
- package/dist/tests/coValueCore.loadFromStorage.test.js +87 -0
- package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
- package/dist/tests/knownState.lazyLoading.test.js +44 -0
- package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
- package/dist/tests/sync.concurrentLoad.test.d.ts +2 -0
- package/dist/tests/sync.concurrentLoad.test.d.ts.map +1 -0
- package/dist/tests/sync.concurrentLoad.test.js +481 -0
- package/dist/tests/sync.concurrentLoad.test.js.map +1 -0
- package/dist/tests/sync.garbageCollection.test.js +87 -3
- package/dist/tests/sync.garbageCollection.test.js.map +1 -1
- package/dist/tests/sync.multipleServers.test.js +0 -62
- package/dist/tests/sync.multipleServers.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +156 -0
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +1 -1
- package/dist/tests/testStorage.d.ts.map +1 -1
- package/dist/tests/testStorage.js +3 -1
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/tests/testUtils.d.ts +1 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +2 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +4 -4
- package/src/GarbageCollector.ts +4 -3
- package/src/PeerState.ts +26 -3
- package/src/coValueCore/coValueCore.ts +129 -53
- package/src/coValues/coList.ts +4 -0
- package/src/config.ts +4 -4
- package/src/exports.ts +2 -2
- package/src/localNode.ts +65 -4
- package/src/queue/LinkedList.ts +34 -4
- package/src/queue/OutgoingLoadQueue.ts +307 -0
- package/src/sync.ts +37 -43
- package/src/tests/LinkedList.test.ts +111 -0
- package/src/tests/OutgoingLoadQueue.test.ts +1129 -0
- package/src/tests/coValueCore.loadFromStorage.test.ts +108 -0
- package/src/tests/knownState.lazyLoading.test.ts +52 -0
- package/src/tests/sync.concurrentLoad.test.ts +650 -0
- package/src/tests/sync.garbageCollection.test.ts +115 -3
- package/src/tests/sync.multipleServers.test.ts +0 -65
- package/src/tests/sync.peerReconciliation.test.ts +199 -0
- package/src/tests/sync.storage.test.ts +1 -1
- package/src/tests/testStorage.ts +3 -1
- package/src/tests/testUtils.ts +3 -1
|
@@ -470,6 +470,114 @@ describe("CoValueCore.loadFromStorage", () => {
|
|
|
470
470
|
});
|
|
471
471
|
});
|
|
472
472
|
|
|
473
|
+
describe("when state is garbageCollected", () => {
|
|
474
|
+
test("should load from storage even if storage state is not unknown", () => {
|
|
475
|
+
const { state, node, header, id } = setup();
|
|
476
|
+
const loadSpy = vi.fn();
|
|
477
|
+
const storage = createMockStorage({ load: loadSpy });
|
|
478
|
+
node.setStorage(storage);
|
|
479
|
+
|
|
480
|
+
// First, simulate that storage was previously accessed and marked available
|
|
481
|
+
state.markFoundInPeer("storage", state.loadingState);
|
|
482
|
+
|
|
483
|
+
// Then set the CoValue to garbageCollected state (simulating GC)
|
|
484
|
+
// This is what happens when a GC'd CoValueCore shell is created
|
|
485
|
+
state.setGarbageCollectedState({
|
|
486
|
+
id,
|
|
487
|
+
header: true,
|
|
488
|
+
sessions: {},
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
// Verify we're in garbageCollected state
|
|
492
|
+
expect(state.loadingState).toBe("garbageCollected");
|
|
493
|
+
|
|
494
|
+
// Now call loadFromStorage - it should proceed to load
|
|
495
|
+
state.loadFromStorage();
|
|
496
|
+
|
|
497
|
+
// Should have called storage.load because we need full content
|
|
498
|
+
expect(loadSpy).toHaveBeenCalledTimes(1);
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
test("should load from storage when garbageCollected and storage state is unknown", () => {
|
|
502
|
+
const { state, node, id } = setup();
|
|
503
|
+
const loadSpy = vi.fn();
|
|
504
|
+
const storage = createMockStorage({ load: loadSpy });
|
|
505
|
+
node.setStorage(storage);
|
|
506
|
+
|
|
507
|
+
// Set the CoValue to garbageCollected state
|
|
508
|
+
state.setGarbageCollectedState({
|
|
509
|
+
id,
|
|
510
|
+
header: true,
|
|
511
|
+
sessions: {},
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
expect(state.loadingState).toBe("garbageCollected");
|
|
515
|
+
expect(state.getLoadingStateForPeer("storage")).toBe("unknown");
|
|
516
|
+
|
|
517
|
+
state.loadFromStorage();
|
|
518
|
+
|
|
519
|
+
expect(loadSpy).toHaveBeenCalledTimes(1);
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
describe("when state is onlyKnownState", () => {
|
|
524
|
+
test("should load from storage to get full content", () => {
|
|
525
|
+
const { state, node, id } = setup();
|
|
526
|
+
const loadSpy = vi.fn();
|
|
527
|
+
const storage = createMockStorage({
|
|
528
|
+
load: loadSpy,
|
|
529
|
+
loadKnownState: (id, callback) => {
|
|
530
|
+
// Simulate storage finding knownState
|
|
531
|
+
callback({
|
|
532
|
+
id,
|
|
533
|
+
header: true,
|
|
534
|
+
sessions: { session1: 5 },
|
|
535
|
+
});
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
node.setStorage(storage);
|
|
539
|
+
|
|
540
|
+
// First, call getKnownStateFromStorage to set onlyKnownState
|
|
541
|
+
state.getKnownStateFromStorage((knownState) => {
|
|
542
|
+
expect(knownState).toBeDefined();
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Verify we're in onlyKnownState
|
|
546
|
+
expect(state.loadingState).toBe("onlyKnownState");
|
|
547
|
+
|
|
548
|
+
// Now call loadFromStorage - it should proceed to load full content
|
|
549
|
+
state.loadFromStorage();
|
|
550
|
+
|
|
551
|
+
expect(loadSpy).toHaveBeenCalledTimes(1);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
test("should load from storage when onlyKnownState and storage state is unknown", () => {
|
|
555
|
+
const { state, node, id } = setup();
|
|
556
|
+
const loadSpy = vi.fn();
|
|
557
|
+
const storage = createMockStorage({
|
|
558
|
+
load: loadSpy,
|
|
559
|
+
loadKnownState: (id, callback) => {
|
|
560
|
+
callback({
|
|
561
|
+
id,
|
|
562
|
+
header: true,
|
|
563
|
+
sessions: {},
|
|
564
|
+
});
|
|
565
|
+
},
|
|
566
|
+
});
|
|
567
|
+
node.setStorage(storage);
|
|
568
|
+
|
|
569
|
+
// Set onlyKnownState via getKnownStateFromStorage
|
|
570
|
+
state.getKnownStateFromStorage(() => {});
|
|
571
|
+
|
|
572
|
+
expect(state.loadingState).toBe("onlyKnownState");
|
|
573
|
+
expect(state.getLoadingStateForPeer("storage")).toBe("unknown");
|
|
574
|
+
|
|
575
|
+
state.loadFromStorage();
|
|
576
|
+
|
|
577
|
+
expect(loadSpy).toHaveBeenCalledTimes(1);
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
|
|
473
581
|
describe("edge cases and integration", () => {
|
|
474
582
|
test("should handle transition from unknown to pending to available", async () => {
|
|
475
583
|
const { state, node, header } = setup();
|
|
@@ -222,4 +222,56 @@ describe("CoValueCore.getKnownStateFromStorage", () => {
|
|
|
222
222
|
|
|
223
223
|
expect(doneSpy).toHaveBeenCalledWith(undefined);
|
|
224
224
|
});
|
|
225
|
+
|
|
226
|
+
test("sets onlyKnownState and caches lastKnownState when storage returns data", () => {
|
|
227
|
+
const { node, coValue, id } = setup();
|
|
228
|
+
const storageKnownState = {
|
|
229
|
+
id,
|
|
230
|
+
header: true,
|
|
231
|
+
sessions: { session1: 5 },
|
|
232
|
+
};
|
|
233
|
+
const loadKnownStateSpy = vi.fn((id, callback) => {
|
|
234
|
+
callback(storageKnownState);
|
|
235
|
+
});
|
|
236
|
+
const storage = createMockStorage({ loadKnownState: loadKnownStateSpy });
|
|
237
|
+
node.setStorage(storage);
|
|
238
|
+
|
|
239
|
+
// Initially unknown
|
|
240
|
+
expect(coValue.loadingState).toBe("unknown");
|
|
241
|
+
|
|
242
|
+
const doneSpy = vi.fn();
|
|
243
|
+
coValue.getKnownStateFromStorage(doneSpy);
|
|
244
|
+
|
|
245
|
+
// After storage returns data, should be onlyKnownState
|
|
246
|
+
expect(coValue.loadingState).toBe("onlyKnownState");
|
|
247
|
+
|
|
248
|
+
// knownState() should return the cached lastKnownState
|
|
249
|
+
expect(coValue.knownState()).toEqual(storageKnownState);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
test("returns cached lastKnownState on subsequent calls without hitting storage", () => {
|
|
253
|
+
const { node, coValue, id } = setup();
|
|
254
|
+
const storageKnownState = {
|
|
255
|
+
id,
|
|
256
|
+
header: true,
|
|
257
|
+
sessions: { session1: 5 },
|
|
258
|
+
};
|
|
259
|
+
const loadKnownStateSpy = vi.fn((id, callback) => {
|
|
260
|
+
callback(storageKnownState);
|
|
261
|
+
});
|
|
262
|
+
const storage = createMockStorage({ loadKnownState: loadKnownStateSpy });
|
|
263
|
+
node.setStorage(storage);
|
|
264
|
+
|
|
265
|
+
// First call - hits storage
|
|
266
|
+
const doneSpy1 = vi.fn();
|
|
267
|
+
coValue.getKnownStateFromStorage(doneSpy1);
|
|
268
|
+
expect(loadKnownStateSpy).toHaveBeenCalledTimes(1);
|
|
269
|
+
expect(doneSpy1).toHaveBeenCalledWith(storageKnownState);
|
|
270
|
+
|
|
271
|
+
// Second call - should use cached lastKnownState, not hit storage
|
|
272
|
+
const doneSpy2 = vi.fn();
|
|
273
|
+
coValue.getKnownStateFromStorage(doneSpy2);
|
|
274
|
+
expect(loadKnownStateSpy).toHaveBeenCalledTimes(1); // Still 1, not 2
|
|
275
|
+
expect(doneSpy2).toHaveBeenCalledWith(storageKnownState);
|
|
276
|
+
});
|
|
225
277
|
});
|