on-zero 0.16.19 → 0.16.20
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/dist/cjs/createUseQuery.cjs +2 -1
- package/dist/cjs/createUseQuery.native.js +2 -1
- package/dist/cjs/createUseQuery.native.js.map +1 -1
- package/dist/cjs/createUseQueryDirect.cjs +2 -1
- package/dist/cjs/createUseQueryDirect.native.js +2 -1
- package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +75 -9
- package/dist/cjs/createZeroClient.native.js +151 -81
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroClient.recovery.test.cjs +351 -10
- package/dist/cjs/createZeroClient.recovery.test.native.js +412 -12
- package/dist/cjs/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/cjs/generate.cjs +16 -11
- package/dist/cjs/generate.native.js +16 -11
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/generate.test.cjs +22 -0
- package/dist/cjs/generate.test.native.js +22 -0
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.cjs +542 -52
- package/dist/cjs/helpers/recoverZeroClient.native.js +721 -59
- package/dist/cjs/helpers/recoverZeroClient.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.test.cjs +318 -0
- package/dist/cjs/helpers/recoverZeroClient.test.native.js +361 -0
- package/dist/cjs/helpers/recoverZeroClient.test.native.js.map +1 -1
- package/dist/cjs/kvStore.cjs +30 -0
- package/dist/cjs/kvStore.native.js +34 -0
- package/dist/cjs/kvStore.native.js.map +1 -0
- package/dist/cjs/queryJson.cjs +58 -0
- package/dist/cjs/queryJson.native.js +86 -0
- package/dist/cjs/queryJson.native.js.map +1 -0
- package/dist/cjs/resolveQuery.cjs +2 -0
- package/dist/cjs/resolveQuery.native.js +2 -0
- package/dist/cjs/resolveQuery.native.js.map +1 -1
- package/dist/cjs/useQuery.empty.test.cjs +11 -1
- package/dist/cjs/useQuery.empty.test.native.js +23 -1
- package/dist/cjs/useQuery.empty.test.native.js.map +1 -1
- package/dist/cjs/useQuery.ssr.test.cjs +22 -1
- package/dist/cjs/useQuery.ssr.test.native.js +30 -1
- package/dist/cjs/useQuery.ssr.test.native.js.map +1 -1
- package/dist/esm/createUseQuery.mjs +2 -1
- package/dist/esm/createUseQuery.mjs.map +1 -1
- package/dist/esm/createUseQuery.native.js +2 -1
- package/dist/esm/createUseQuery.native.js.map +1 -1
- package/dist/esm/createUseQueryDirect.mjs +2 -1
- package/dist/esm/createUseQueryDirect.mjs.map +1 -1
- package/dist/esm/createUseQueryDirect.native.js +2 -1
- package/dist/esm/createUseQueryDirect.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +76 -10
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +152 -82
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.mjs +352 -11
- package/dist/esm/createZeroClient.recovery.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.native.js +413 -13
- package/dist/esm/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/esm/generate.mjs +16 -11
- package/dist/esm/generate.mjs.map +1 -1
- package/dist/esm/generate.native.js +16 -11
- package/dist/esm/generate.native.js.map +1 -1
- package/dist/esm/generate.test.mjs +22 -0
- package/dist/esm/generate.test.mjs.map +1 -1
- package/dist/esm/generate.test.native.js +22 -0
- package/dist/esm/generate.test.native.js.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.mjs +542 -54
- package/dist/esm/helpers/recoverZeroClient.mjs.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.native.js +721 -61
- package/dist/esm/helpers/recoverZeroClient.native.js.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.test.mjs +319 -1
- package/dist/esm/helpers/recoverZeroClient.test.mjs.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.test.native.js +362 -1
- package/dist/esm/helpers/recoverZeroClient.test.native.js.map +1 -1
- package/dist/esm/kvStore.mjs +5 -0
- package/dist/esm/kvStore.mjs.map +1 -0
- package/dist/esm/kvStore.native.js +6 -0
- package/dist/esm/kvStore.native.js.map +1 -0
- package/dist/esm/queryJson.mjs +32 -0
- package/dist/esm/queryJson.mjs.map +1 -0
- package/dist/esm/queryJson.native.js +57 -0
- package/dist/esm/queryJson.native.js.map +1 -0
- package/dist/esm/resolveQuery.mjs +2 -0
- package/dist/esm/resolveQuery.mjs.map +1 -1
- package/dist/esm/resolveQuery.native.js +2 -0
- package/dist/esm/resolveQuery.native.js.map +1 -1
- package/dist/esm/useQuery.empty.test.mjs +12 -2
- package/dist/esm/useQuery.empty.test.mjs.map +1 -1
- package/dist/esm/useQuery.empty.test.native.js +24 -2
- package/dist/esm/useQuery.empty.test.native.js.map +1 -1
- package/dist/esm/useQuery.ssr.test.mjs +23 -2
- package/dist/esm/useQuery.ssr.test.mjs.map +1 -1
- package/dist/esm/useQuery.ssr.test.native.js +31 -2
- package/dist/esm/useQuery.ssr.test.native.js.map +1 -1
- package/package.json +11 -3
- package/src/createUseQuery.tsx +2 -1
- package/src/createUseQueryDirect.tsx +2 -1
- package/src/createZeroClient.recovery.test.tsx +370 -7
- package/src/createZeroClient.tsx +100 -10
- package/src/generate.test.ts +31 -0
- package/src/generate.ts +22 -10
- package/src/helpers/recoverZeroClient.test.ts +323 -0
- package/src/helpers/recoverZeroClient.ts +896 -78
- package/src/kvStore.native.ts +7 -0
- package/src/kvStore.ts +7 -0
- package/src/queryJson.ts +46 -0
- package/src/resolveQuery.ts +2 -0
- package/src/useQuery.empty.test.tsx +16 -2
- package/src/useQuery.ssr.test.ts +23 -2
- package/types/createUseQuery.d.ts.map +1 -1
- package/types/createUseQueryDirect.d.ts.map +1 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroClient.recovery.test.d.ts.map +1 -1
- package/types/generate.d.ts.map +1 -1
- package/types/helpers/recoverZeroClient.d.ts +6 -0
- package/types/helpers/recoverZeroClient.d.ts.map +1 -1
- package/types/kvStore.d.ts +2 -0
- package/types/kvStore.d.ts.map +1 -0
- package/types/kvStore.native.d.ts +3 -0
- package/types/kvStore.native.d.ts.map +1 -0
- package/types/queryJson.d.ts +3 -0
- package/types/queryJson.d.ts.map +1 -0
- package/types/resolveQuery.d.ts.map +1 -1
|
@@ -6,35 +6,63 @@ var import_createZeroClient = require("./createZeroClient.cjs");
|
|
|
6
6
|
var import_recoverZeroClient = require("./helpers/recoverZeroClient.cjs");
|
|
7
7
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
const fakeZero = import_vitest.vi.hoisted(() => {
|
|
9
|
+
const group = {
|
|
10
|
+
current: "g1"
|
|
11
|
+
};
|
|
9
12
|
class FakeZero {
|
|
10
13
|
constructor(options) {
|
|
11
14
|
this.options = options;
|
|
12
15
|
instances.push(this);
|
|
16
|
+
this.clientGroupID = Promise.resolve(group.current);
|
|
17
|
+
const listeners = /* @__PURE__ */new Set();
|
|
18
|
+
this.connection = {
|
|
19
|
+
state: {
|
|
20
|
+
current: {
|
|
21
|
+
name: "closed"
|
|
22
|
+
},
|
|
23
|
+
subscribe: listener => {
|
|
24
|
+
listeners.add(listener);
|
|
25
|
+
return () => {
|
|
26
|
+
listeners.delete(listener);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
connect: import_vitest.vi.fn()
|
|
31
|
+
};
|
|
32
|
+
this.__connectionListeners = listeners;
|
|
13
33
|
}
|
|
14
34
|
context = {};
|
|
15
|
-
connection
|
|
16
|
-
state: {
|
|
17
|
-
current: {
|
|
18
|
-
name: "closed"
|
|
19
|
-
},
|
|
20
|
-
subscribe: () => () => {}
|
|
21
|
-
},
|
|
22
|
-
connect: import_vitest.vi.fn()
|
|
23
|
-
};
|
|
35
|
+
connection;
|
|
24
36
|
delete = import_vitest.vi.fn(async () => ({
|
|
25
37
|
errors: []
|
|
26
38
|
}));
|
|
27
39
|
close = import_vitest.vi.fn();
|
|
28
40
|
run = import_vitest.vi.fn(async () => []);
|
|
41
|
+
mutate = {
|
|
42
|
+
note: {
|
|
43
|
+
insert: import_vitest.vi.fn(() => ({
|
|
44
|
+
client: Promise.resolve({}),
|
|
45
|
+
server: Promise.resolve({})
|
|
46
|
+
}))
|
|
47
|
+
}
|
|
48
|
+
};
|
|
29
49
|
preload = import_vitest.vi.fn(() => ({
|
|
30
50
|
cleanup: () => {},
|
|
31
51
|
complete: Promise.resolve()
|
|
32
52
|
}));
|
|
53
|
+
clientGroupID;
|
|
33
54
|
}
|
|
34
55
|
const instances = [];
|
|
56
|
+
function setConnectionState(instance, name) {
|
|
57
|
+
instance.connection.state.current.name = name;
|
|
58
|
+
const listeners = instance.__connectionListeners;
|
|
59
|
+
for (const listener of [...listeners]) listener();
|
|
60
|
+
}
|
|
35
61
|
return {
|
|
36
62
|
FakeZero,
|
|
37
|
-
instances
|
|
63
|
+
instances,
|
|
64
|
+
group,
|
|
65
|
+
setConnectionState
|
|
38
66
|
};
|
|
39
67
|
});
|
|
40
68
|
import_vitest.vi.mock("@rocicorp/zero", async importOriginal => {
|
|
@@ -64,6 +92,7 @@ let root;
|
|
|
64
92
|
window.sessionStorage.clear();
|
|
65
93
|
(0, import_recoverZeroClient.resetRecoveryStateForTests)();
|
|
66
94
|
fakeZero.instances.length = 0;
|
|
95
|
+
fakeZero.group.current = "g1";
|
|
67
96
|
container = document.createElement("div");
|
|
68
97
|
root = null;
|
|
69
98
|
});
|
|
@@ -421,4 +450,316 @@ async function mount() {
|
|
|
421
450
|
(0, import_vitest.expect)(await isolated.waitForZero()).toBe(connection.zero);
|
|
422
451
|
(0, import_vitest.expect)(first.close).toHaveBeenCalledOnce();
|
|
423
452
|
await connection.close();
|
|
453
|
+
});
|
|
454
|
+
function makeTransitionClient(instanceName) {
|
|
455
|
+
return (0, import_createZeroClient.createZeroClient)({
|
|
456
|
+
schema,
|
|
457
|
+
models: {},
|
|
458
|
+
groupedQueries: {},
|
|
459
|
+
instanceName
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
function collectClientEvents(client2) {
|
|
463
|
+
const events = [];
|
|
464
|
+
const off = client2.zeroEvents.listen(event => {
|
|
465
|
+
if (event) events.push(event);
|
|
466
|
+
});
|
|
467
|
+
return {
|
|
468
|
+
events,
|
|
469
|
+
off
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
async function mountTransitionClient(client2, userID) {
|
|
473
|
+
const el = document.createElement("div");
|
|
474
|
+
const mountedRoot = (0, import_client.createRoot)(el);
|
|
475
|
+
await (0, import_react.act)(async () => {
|
|
476
|
+
mountedRoot.render(/* @__PURE__ */(0, import_jsx_runtime.jsx)(client2.ProvideZero, {
|
|
477
|
+
cacheURL: "http://127.0.0.1:7777/zero",
|
|
478
|
+
userID,
|
|
479
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)("span", {
|
|
480
|
+
children: "ok"
|
|
481
|
+
})
|
|
482
|
+
}));
|
|
483
|
+
await Promise.resolve();
|
|
484
|
+
});
|
|
485
|
+
return {
|
|
486
|
+
el,
|
|
487
|
+
root: mountedRoot,
|
|
488
|
+
instance: fakeZero.instances.at(-1)
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
async function unmountTransitionClient(mounted) {
|
|
492
|
+
await (0, import_react.act)(async () => {
|
|
493
|
+
mounted.root.unmount();
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function withoutPageReload() {
|
|
497
|
+
const originalLocation = globalThis.location;
|
|
498
|
+
Object.defineProperty(globalThis, "location", {
|
|
499
|
+
configurable: true,
|
|
500
|
+
value: void 0
|
|
501
|
+
});
|
|
502
|
+
return () => {
|
|
503
|
+
Object.defineProperty(globalThis, "location", {
|
|
504
|
+
configurable: true,
|
|
505
|
+
value: originalLocation
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
(0, import_vitest.test)("two providers ride one group transition and keep querying and mutating", async () => {
|
|
510
|
+
const restoreLocation = withoutPageReload();
|
|
511
|
+
const clientA = makeTransitionClient("transition-two-a");
|
|
512
|
+
const clientB = makeTransitionClient("transition-two-b");
|
|
513
|
+
const collectedA = collectClientEvents(clientA);
|
|
514
|
+
const collectedB = collectClientEvents(clientB);
|
|
515
|
+
const mountedA = await mountTransitionClient(clientA, "transition-user");
|
|
516
|
+
const mountedB = await mountTransitionClient(clientB, "transition-user");
|
|
517
|
+
const firstA = mountedA.instance;
|
|
518
|
+
const firstB = mountedB.instance;
|
|
519
|
+
const countBefore = fakeZero.instances.length;
|
|
520
|
+
try {
|
|
521
|
+
firstA.options.onUpdateNeeded({
|
|
522
|
+
type: "NewClientGroup"
|
|
523
|
+
});
|
|
524
|
+
firstB.options.onUpdateNeeded({
|
|
525
|
+
type: "NewClientGroup"
|
|
526
|
+
});
|
|
527
|
+
await (0, import_react.act)(async () => {
|
|
528
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
529
|
+
});
|
|
530
|
+
(0, import_vitest.expect)(fakeZero.instances).toHaveLength(countBefore + 2);
|
|
531
|
+
const secondA = fakeZero.instances[countBefore];
|
|
532
|
+
const secondB = fakeZero.instances[countBefore + 1];
|
|
533
|
+
(0, import_vitest.expect)(secondA).not.toBe(firstA);
|
|
534
|
+
(0, import_vitest.expect)(secondB).not.toBe(firstB);
|
|
535
|
+
(0, import_vitest.expect)(firstA.close).toHaveBeenCalledTimes(1);
|
|
536
|
+
(0, import_vitest.expect)(firstB.close).toHaveBeenCalledTimes(1);
|
|
537
|
+
(0, import_vitest.expect)((0, import_recoverZeroClient.isGroupTransitionOpen)()).toBe(true);
|
|
538
|
+
await (0, import_react.act)(async () => {
|
|
539
|
+
fakeZero.setConnectionState(secondA, "connected");
|
|
540
|
+
fakeZero.setConnectionState(secondB, "connected");
|
|
541
|
+
await Promise.resolve();
|
|
542
|
+
});
|
|
543
|
+
await import_vitest.vi.waitFor(() => (0, import_vitest.expect)((0, import_recoverZeroClient.isGroupTransitionOpen)()).toBe(false));
|
|
544
|
+
const allEvents = [...collectedA.events, ...collectedB.events];
|
|
545
|
+
(0, import_vitest.expect)(allEvents.filter(event => event.type === "recovering")).toHaveLength(1);
|
|
546
|
+
(0, import_vitest.expect)(allEvents.filter(event => event.type === "fatal")).toHaveLength(0);
|
|
547
|
+
(0, import_vitest.expect)(firstA.delete).not.toHaveBeenCalled();
|
|
548
|
+
(0, import_vitest.expect)(firstB.delete).not.toHaveBeenCalled();
|
|
549
|
+
await clientA.zero.run({});
|
|
550
|
+
await clientB.zero.run({});
|
|
551
|
+
(0, import_vitest.expect)(secondA.run).toHaveBeenCalled();
|
|
552
|
+
(0, import_vitest.expect)(secondB.run).toHaveBeenCalled();
|
|
553
|
+
clientA.zero.mutate.note.insert({
|
|
554
|
+
id: "a1"
|
|
555
|
+
});
|
|
556
|
+
clientB.zero.mutate.note.insert({
|
|
557
|
+
id: "b1"
|
|
558
|
+
});
|
|
559
|
+
(0, import_vitest.expect)(secondA.mutate.note.insert).toHaveBeenCalledTimes(1);
|
|
560
|
+
(0, import_vitest.expect)(secondB.mutate.note.insert).toHaveBeenCalledTimes(1);
|
|
561
|
+
} finally {
|
|
562
|
+
collectedA.off();
|
|
563
|
+
collectedB.off();
|
|
564
|
+
await unmountTransitionClient(mountedA);
|
|
565
|
+
await unmountTransitionClient(mountedB);
|
|
566
|
+
restoreLocation();
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
(0, import_vitest.test)("a second registry change after recovery remints again without fatal", async () => {
|
|
570
|
+
const restoreLocation = withoutPageReload();
|
|
571
|
+
const clientA = makeTransitionClient("transition-second-a");
|
|
572
|
+
const clientB = makeTransitionClient("transition-second-b");
|
|
573
|
+
const collectedA = collectClientEvents(clientA);
|
|
574
|
+
const collectedB = collectClientEvents(clientB);
|
|
575
|
+
const mountedA = await mountTransitionClient(clientA, "transition-second-user");
|
|
576
|
+
const mountedB = await mountTransitionClient(clientB, "transition-second-user");
|
|
577
|
+
try {
|
|
578
|
+
const fireBoth = instances => {
|
|
579
|
+
instances[0].options.onUpdateNeeded({
|
|
580
|
+
type: "NewClientGroup"
|
|
581
|
+
});
|
|
582
|
+
instances[1].options.onUpdateNeeded({
|
|
583
|
+
type: "NewClientGroup"
|
|
584
|
+
});
|
|
585
|
+
};
|
|
586
|
+
const settleRemints = async countBefore2 => {
|
|
587
|
+
await (0, import_react.act)(async () => {
|
|
588
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
589
|
+
});
|
|
590
|
+
(0, import_vitest.expect)(fakeZero.instances).toHaveLength(countBefore2 + 2);
|
|
591
|
+
const next = fakeZero.instances.slice(countBefore2);
|
|
592
|
+
await (0, import_react.act)(async () => {
|
|
593
|
+
for (const instance of next) fakeZero.setConnectionState(instance, "connected");
|
|
594
|
+
await Promise.resolve();
|
|
595
|
+
});
|
|
596
|
+
await import_vitest.vi.waitFor(() => (0, import_vitest.expect)((0, import_recoverZeroClient.isGroupTransitionOpen)()).toBe(false));
|
|
597
|
+
return next;
|
|
598
|
+
};
|
|
599
|
+
const countBeforeFirst = fakeZero.instances.length;
|
|
600
|
+
fireBoth(fakeZero.instances.slice(-2));
|
|
601
|
+
await settleRemints(countBeforeFirst);
|
|
602
|
+
fakeZero.group.current = "g2";
|
|
603
|
+
const countBefore = fakeZero.instances.length;
|
|
604
|
+
fireBoth(fakeZero.instances.slice(-2));
|
|
605
|
+
const third = await settleRemints(countBefore);
|
|
606
|
+
const allEvents = [...collectedA.events, ...collectedB.events];
|
|
607
|
+
(0, import_vitest.expect)(allEvents.filter(event => event.type === "recovering")).toHaveLength(2);
|
|
608
|
+
(0, import_vitest.expect)(allEvents.filter(event => event.type === "fatal")).toHaveLength(0);
|
|
609
|
+
await clientA.zero.run({});
|
|
610
|
+
await clientB.zero.run({});
|
|
611
|
+
(0, import_vitest.expect)(third[0].run).toHaveBeenCalled();
|
|
612
|
+
(0, import_vitest.expect)(third[1].run).toHaveBeenCalled();
|
|
613
|
+
} finally {
|
|
614
|
+
collectedA.off();
|
|
615
|
+
collectedB.off();
|
|
616
|
+
await unmountTransitionClient(mountedA);
|
|
617
|
+
await unmountTransitionClient(mountedB);
|
|
618
|
+
restoreLocation();
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
(0, import_vitest.test)("negative control: an incompatible schema emits exactly one terminal error, never a loop", async () => {
|
|
622
|
+
const restoreLocation = withoutPageReload();
|
|
623
|
+
const consoleError = import_vitest.vi.spyOn(console, "error").mockImplementation(() => {});
|
|
624
|
+
const clientA = makeTransitionClient("transition-negative-a");
|
|
625
|
+
const clientB = makeTransitionClient("transition-negative-b");
|
|
626
|
+
const collectedA = collectClientEvents(clientA);
|
|
627
|
+
const collectedB = collectClientEvents(clientB);
|
|
628
|
+
const mountedA = await mountTransitionClient(clientA, "transition-negative-user");
|
|
629
|
+
const mountedB = await mountTransitionClient(clientB, "transition-negative-user");
|
|
630
|
+
const firstA = mountedA.instance;
|
|
631
|
+
const firstB = mountedB.instance;
|
|
632
|
+
const countBefore = fakeZero.instances.length;
|
|
633
|
+
try {
|
|
634
|
+
firstA.options.onUpdateNeeded({
|
|
635
|
+
type: "SchemaVersionNotSupported"
|
|
636
|
+
});
|
|
637
|
+
firstB.options.onUpdateNeeded({
|
|
638
|
+
type: "SchemaVersionNotSupported"
|
|
639
|
+
});
|
|
640
|
+
await (0, import_react.act)(async () => {
|
|
641
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
642
|
+
});
|
|
643
|
+
(0, import_vitest.expect)(firstA.delete).toHaveBeenCalledTimes(1);
|
|
644
|
+
(0, import_vitest.expect)(firstB.delete).toHaveBeenCalledTimes(1);
|
|
645
|
+
(0, import_vitest.expect)(fakeZero.instances).toHaveLength(countBefore + 2);
|
|
646
|
+
const secondA = fakeZero.instances[countBefore];
|
|
647
|
+
const secondB = fakeZero.instances[countBefore + 1];
|
|
648
|
+
(0, import_vitest.expect)((0, import_recoverZeroClient.isGroupTransitionOpen)()).toBe(true);
|
|
649
|
+
secondA.options.onUpdateNeeded({
|
|
650
|
+
type: "SchemaVersionNotSupported"
|
|
651
|
+
});
|
|
652
|
+
await (0, import_react.act)(async () => {
|
|
653
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
654
|
+
});
|
|
655
|
+
const allEvents = () => [...collectedA.events, ...collectedB.events];
|
|
656
|
+
(0, import_vitest.expect)(allEvents().filter(event => event.type === "fatal")).toHaveLength(1);
|
|
657
|
+
const [fatal] = allEvents().filter(event => event.type === "fatal");
|
|
658
|
+
(0, import_vitest.expect)(fatal).toMatchObject({
|
|
659
|
+
reasonKey: "SchemaVersionNotSupported",
|
|
660
|
+
reason: import_vitest.expect.stringContaining("g1")
|
|
661
|
+
});
|
|
662
|
+
(0, import_vitest.expect)(consoleError).toHaveBeenCalledTimes(1);
|
|
663
|
+
(0, import_vitest.expect)(consoleError.mock.calls[0][0]).toContain("g1");
|
|
664
|
+
secondB.options.onUpdateNeeded({
|
|
665
|
+
type: "SchemaVersionNotSupported"
|
|
666
|
+
});
|
|
667
|
+
secondA.options.onUpdateNeeded({
|
|
668
|
+
type: "SchemaVersionNotSupported"
|
|
669
|
+
});
|
|
670
|
+
await (0, import_react.act)(async () => {
|
|
671
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
672
|
+
});
|
|
673
|
+
(0, import_vitest.expect)(allEvents().filter(event => event.type === "fatal")).toHaveLength(1);
|
|
674
|
+
(0, import_vitest.expect)(consoleError).toHaveBeenCalledTimes(1);
|
|
675
|
+
(0, import_vitest.expect)(fakeZero.instances).toHaveLength(countBefore + 2);
|
|
676
|
+
} finally {
|
|
677
|
+
collectedA.off();
|
|
678
|
+
collectedB.off();
|
|
679
|
+
await unmountTransitionClient(mountedA);
|
|
680
|
+
await unmountTransitionClient(mountedB);
|
|
681
|
+
restoreLocation();
|
|
682
|
+
consoleError.mockRestore();
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
(0, import_vitest.test)("concurrent update signals across providers schedule a single reload", async () => {
|
|
686
|
+
const reloadPage = import_vitest.vi.fn();
|
|
687
|
+
const originalLocation = globalThis.location;
|
|
688
|
+
Object.defineProperty(globalThis, "location", {
|
|
689
|
+
configurable: true,
|
|
690
|
+
value: {
|
|
691
|
+
href: "http://localhost/reload-test",
|
|
692
|
+
reload: reloadPage
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
const scheduleA = import_vitest.vi.fn();
|
|
696
|
+
const scheduleB = import_vitest.vi.fn();
|
|
697
|
+
const clientA = makeTransitionClient("transition-reload-a");
|
|
698
|
+
const clientB = makeTransitionClient("transition-reload-b");
|
|
699
|
+
const collectedA = collectClientEvents(clientA);
|
|
700
|
+
const collectedB = collectClientEvents(clientB);
|
|
701
|
+
const elA = document.createElement("div");
|
|
702
|
+
const elB = document.createElement("div");
|
|
703
|
+
const rootA = (0, import_client.createRoot)(elA);
|
|
704
|
+
const rootB = (0, import_client.createRoot)(elB);
|
|
705
|
+
try {
|
|
706
|
+
await (0, import_react.act)(async () => {
|
|
707
|
+
rootA.render(/* @__PURE__ */(0, import_jsx_runtime.jsx)(clientA.ProvideZero, {
|
|
708
|
+
cacheURL: "http://127.0.0.1:7777/zero",
|
|
709
|
+
userID: "transition-reload-user",
|
|
710
|
+
scheduleReload: scheduleA,
|
|
711
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)("span", {
|
|
712
|
+
children: "ok"
|
|
713
|
+
})
|
|
714
|
+
}));
|
|
715
|
+
await Promise.resolve();
|
|
716
|
+
});
|
|
717
|
+
await (0, import_react.act)(async () => {
|
|
718
|
+
rootB.render(/* @__PURE__ */(0, import_jsx_runtime.jsx)(clientB.ProvideZero, {
|
|
719
|
+
cacheURL: "http://127.0.0.1:7777/zero",
|
|
720
|
+
userID: "transition-reload-user",
|
|
721
|
+
scheduleReload: scheduleB,
|
|
722
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)("span", {
|
|
723
|
+
children: "ok"
|
|
724
|
+
})
|
|
725
|
+
}));
|
|
726
|
+
await Promise.resolve();
|
|
727
|
+
});
|
|
728
|
+
const firstA = fakeZero.instances.at(-2);
|
|
729
|
+
const firstB = fakeZero.instances.at(-1);
|
|
730
|
+
firstA.options.onUpdateNeeded({
|
|
731
|
+
type: "NewClientGroup"
|
|
732
|
+
});
|
|
733
|
+
firstB.options.onUpdateNeeded({
|
|
734
|
+
type: "NewClientGroup"
|
|
735
|
+
});
|
|
736
|
+
await (0, import_react.act)(async () => {
|
|
737
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
738
|
+
});
|
|
739
|
+
(0, import_vitest.expect)(scheduleA.mock.calls.length + scheduleB.mock.calls.length).toBe(1);
|
|
740
|
+
(0, import_vitest.expect)(reloadPage).not.toHaveBeenCalled();
|
|
741
|
+
const allEvents = [...collectedA.events, ...collectedB.events];
|
|
742
|
+
(0, import_vitest.expect)(allEvents.filter(event => event.type === "fatal")).toHaveLength(0);
|
|
743
|
+
const ctx = (scheduleA.mock.calls[0] ?? scheduleB.mock.calls[0])[0];
|
|
744
|
+
await (0, import_react.act)(async () => {
|
|
745
|
+
await ctx.performReload();
|
|
746
|
+
});
|
|
747
|
+
(0, import_vitest.expect)(reloadPage).toHaveBeenCalledTimes(1);
|
|
748
|
+
(0, import_vitest.expect)((0, import_recoverZeroClient.isGroupTransitionOpen)()).toBe(false);
|
|
749
|
+
const marker = window.sessionStorage.getItem("on-zero-recover-http://localhost/reload-test-NewClientGroup");
|
|
750
|
+
(0, import_vitest.expect)(marker).toContain("g1");
|
|
751
|
+
} finally {
|
|
752
|
+
collectedA.off();
|
|
753
|
+
collectedB.off();
|
|
754
|
+
await (0, import_react.act)(async () => {
|
|
755
|
+
rootA.unmount();
|
|
756
|
+
});
|
|
757
|
+
await (0, import_react.act)(async () => {
|
|
758
|
+
rootB.unmount();
|
|
759
|
+
});
|
|
760
|
+
Object.defineProperty(globalThis, "location", {
|
|
761
|
+
configurable: true,
|
|
762
|
+
value: originalLocation
|
|
763
|
+
});
|
|
764
|
+
}
|
|
424
765
|
});
|