on-zero 0.4.30 → 0.4.32
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/createZeroClient.authData.test.cjs +67 -0
- package/dist/cjs/createZeroClient.authData.test.native.js +72 -0
- package/dist/cjs/createZeroClient.authData.test.native.js.map +1 -0
- package/dist/cjs/createZeroClient.cjs +41 -26
- package/dist/cjs/createZeroClient.native.js +47 -26
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroServer.cjs +35 -33
- package/dist/cjs/createZeroServer.native.js +36 -34
- package/dist/cjs/createZeroServer.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.cjs +101 -0
- package/dist/cjs/helpers/recoverZeroClient.native.js +130 -0
- package/dist/cjs/helpers/recoverZeroClient.native.js.map +1 -0
- package/dist/cjs/helpers/recoverZeroClient.test.cjs +201 -0
- package/dist/cjs/helpers/recoverZeroClient.test.native.js +256 -0
- package/dist/cjs/helpers/recoverZeroClient.test.native.js.map +1 -0
- package/dist/cjs/index.cjs +4 -1
- package/dist/cjs/index.native.js +3 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/multiInstance.test.cjs +4 -3
- package/dist/cjs/multiInstance.test.native.js +6 -6
- package/dist/cjs/multiInstance.test.native.js.map +1 -1
- package/dist/esm/createZeroClient.authData.test.mjs +68 -0
- package/dist/esm/createZeroClient.authData.test.mjs.map +1 -0
- package/dist/esm/createZeroClient.authData.test.native.js +70 -0
- package/dist/esm/createZeroClient.authData.test.native.js.map +1 -0
- package/dist/esm/createZeroClient.mjs +42 -27
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +48 -27
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroServer.mjs +35 -33
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +36 -34
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.mjs +74 -0
- package/dist/esm/helpers/recoverZeroClient.mjs.map +1 -0
- package/dist/esm/helpers/recoverZeroClient.native.js +100 -0
- package/dist/esm/helpers/recoverZeroClient.native.js.map +1 -0
- package/dist/esm/helpers/recoverZeroClient.test.mjs +202 -0
- package/dist/esm/helpers/recoverZeroClient.test.mjs.map +1 -0
- package/dist/esm/helpers/recoverZeroClient.test.native.js +254 -0
- package/dist/esm/helpers/recoverZeroClient.test.native.js.map +1 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/multiInstance.test.mjs +4 -3
- package/dist/esm/multiInstance.test.mjs.map +1 -1
- package/dist/esm/multiInstance.test.native.js +6 -6
- package/dist/esm/multiInstance.test.native.js.map +1 -1
- package/package.json +2 -2
- package/src/createZeroClient.authData.test.tsx +73 -0
- package/src/createZeroClient.tsx +60 -47
- package/src/createZeroServer.ts +48 -44
- package/src/helpers/recoverZeroClient.test.ts +172 -0
- package/src/helpers/recoverZeroClient.ts +173 -0
- package/src/index.ts +5 -0
- package/src/multiInstance.test.tsx +5 -3
- package/src/multiInstanceNested.test.tsx +1 -1
- package/src/types.ts +6 -1
- package/types/createZeroClient.authData.test.d.ts +5 -0
- package/types/createZeroClient.authData.test.d.ts.map +1 -0
- package/types/createZeroClient.d.ts +3 -2
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroServer.d.ts +4 -4
- package/types/createZeroServer.d.ts.map +1 -1
- package/types/helpers/recoverZeroClient.d.ts +17 -0
- package/types/helpers/recoverZeroClient.d.ts.map +1 -0
- package/types/helpers/recoverZeroClient.test.d.ts +2 -0
- package/types/helpers/recoverZeroClient.test.d.ts.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/types.d.ts +6 -0
- package/types/types.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","createZeroServer_exports","__export","createZeroServer","module","exports","import_zero","require","import_pg","import_server","import_pg2","import_helpers","import_pg3","import_createPermissions","import_createMutators","import_mutatorContext","import_queryContext","import_modelRegistry","import_run","import_state","import_where","import_zeroRunner","param","createServerActions","database","pool","externalPool","schema","models","queries","mutations","mutationValidators","validateQuery","validateMutation","defaultAllowAdminRole","defaultMutateAuthData","setSchema","setEnvironment","dbString","assertString","pgPool","Pool","connectionString","ssl","includes","rejectUnauthorized","on","error","console","message","client","zeroDb","zeroNodePg","permissions","createPermissions","environment","adminRoleMode","processor","PushProcessor","handleMutationRequest","param2","authData","request","skipAsyncTasks","asyncTasks","mutators","createMutators","can","response","process","length","Promise","all","map","task","runWithAuthScope","catch","err","handleQueryRequest","Error","
|
|
1
|
+
{"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","createZeroServer_exports","__export","createZeroServer","module","exports","import_zero","require","import_pg","import_server","import_pg2","import_helpers","import_pg3","import_createPermissions","import_createMutators","import_mutatorContext","import_queryContext","import_modelRegistry","import_run","import_state","import_where","import_zeroRunner","param","createServerActions","database","pool","externalPool","schema","models","queries","mutations","mutationValidators","validateQuery","validateMutation","defaultAllowAdminRole","defaultMutateAuthData","setSchema","setEnvironment","dbString","assertString","pgPool","Pool","connectionString","ssl","includes","rejectUnauthorized","on","error","console","message","client","zeroDb","zeroNodePg","permissions","createPermissions","environment","adminRoleMode","processor","PushProcessor","handleMutationRequest","param2","authData","request","skipAsyncTasks","asyncTasks","mutators","createMutators","can","response","process","length","Promise","all","map","task","runWithAuthScope","catch","err","handleQueryRequest","Error","handler","name","args","startsWith","table","slice","objOrId","perm","getMutationsPermissions","setEvaluatingPermission","getZQL","where","eb","buildPermissionQuery","one","queryName","params","_$query","mustGetQuery","fn","ctx","userID","id","runWithQueryContext","runMutate","modelName","mutatorName","mutatorArg","options","scoped","getScopedAuthData","modelMutators","mutator","transaction","tx","resolvedAuth","promise","t","awaitEffects","mutate","Proxy","get","_","_2","arg","query2","isInZeroMutation","mutatorContext","output","dummyTransactionInput","query","cb","run","setCustomQueries","setRunner","queryObj","clientGroupID","clientID","mutationID","upstreamSchema"],"sources":["../../src/createZeroServer.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all) __defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: () => from[key],
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
|
|
21
|
+
value: true
|
|
22
|
+
}), mod);
|
|
23
|
+
var recoverZeroClient_exports = {};
|
|
24
|
+
__export(recoverZeroClient_exports, {
|
|
25
|
+
composeRecoveryLogSink: () => composeRecoveryLogSink,
|
|
26
|
+
makeZeroRecovery: () => makeZeroRecovery,
|
|
27
|
+
resetRecoveryStateForTests: () => resetRecoveryStateForTests
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(recoverZeroClient_exports);
|
|
30
|
+
const RECOVER_GUARD_MS = 6e4;
|
|
31
|
+
const LOCAL_STORE_LOST = "Expected IndexedDB not found";
|
|
32
|
+
let reloadScheduled = false;
|
|
33
|
+
const pendingDeletes = [];
|
|
34
|
+
function recoveryGuardOpen(reasonKey) {
|
|
35
|
+
try {
|
|
36
|
+
const key = `on-zero-recover-${reasonKey}`;
|
|
37
|
+
const last = Number(window.sessionStorage.getItem(key) || 0);
|
|
38
|
+
if (Date.now() - last < RECOVER_GUARD_MS) return false;
|
|
39
|
+
window.sessionStorage.setItem(key, String(Date.now()));
|
|
40
|
+
} catch {}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
function recover(deps, reasonKey, message, dropLocalState) {
|
|
44
|
+
if (typeof window === "undefined") return;
|
|
45
|
+
if (dropLocalState) {
|
|
46
|
+
pendingDeletes.push(Promise.resolve().then(deps.deleteLocalState).catch(() => {}));
|
|
47
|
+
}
|
|
48
|
+
if (reloadScheduled) return;
|
|
49
|
+
if (!recoveryGuardOpen(reasonKey)) {
|
|
50
|
+
console.error(`[on-zero] ${message} \u2014 already recovered once, not reloading`);
|
|
51
|
+
deps.zeroEvents.emit({
|
|
52
|
+
type: "fatal",
|
|
53
|
+
reason: message
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
reloadScheduled = true;
|
|
58
|
+
console.warn(`[on-zero] ${message} \u2014 recovering`);
|
|
59
|
+
deps.zeroEvents.emit({
|
|
60
|
+
type: "recovering",
|
|
61
|
+
reason: message
|
|
62
|
+
});
|
|
63
|
+
const doReload = deps.reload ?? (() => window.location.reload());
|
|
64
|
+
Promise.resolve().then(() => Promise.allSettled(pendingDeletes)).then(() => deps.beforeReload?.()).catch(() => {}).finally(doReload);
|
|
65
|
+
}
|
|
66
|
+
function makeZeroRecovery(deps) {
|
|
67
|
+
return {
|
|
68
|
+
onUpdateNeeded(reason) {
|
|
69
|
+
const dropLocalState = reason.type === "SchemaVersionNotSupported";
|
|
70
|
+
recover(deps, reason.type, `update needed (${reason.message || reason.type})`, dropLocalState);
|
|
71
|
+
},
|
|
72
|
+
onClientStateNotFound() {
|
|
73
|
+
recover(deps, "client-state-not-found", "client state not found", true);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function logToConsole(level, context, ...args) {
|
|
78
|
+
const prefix = context ? Object.entries(context).map(([key, value]) => value === void 0 ? key : `${key}=${value}`).join(" ") : "";
|
|
79
|
+
const method = level === "debug" ? "debug" : level;
|
|
80
|
+
console[method](...(prefix ? [prefix] : []), ...args);
|
|
81
|
+
}
|
|
82
|
+
function composeRecoveryLogSink(deps, consumerLogSink) {
|
|
83
|
+
const consumerFlush = consumerLogSink?.flush;
|
|
84
|
+
return {
|
|
85
|
+
log(level, context, ...args) {
|
|
86
|
+
if (consumerLogSink) consumerLogSink.log(level, context, ...args);else logToConsole(level, context, ...args);
|
|
87
|
+
if (level !== "error") return;
|
|
88
|
+
const text = args.map(arg => typeof arg === "string" ? arg : arg && typeof arg === "object" && "message" in arg ? String(arg.message) : "").join(" ");
|
|
89
|
+
if (text.includes(LOCAL_STORE_LOST)) {
|
|
90
|
+
recover(deps, "local-store", "local store lost", true);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
// call through the consumer sink so a class-based sink keeps its `this`,
|
|
94
|
+
// rather than handing Zero a detached method reference.
|
|
95
|
+
flush: consumerFlush ? () => consumerFlush.call(consumerLogSink) : void 0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function resetRecoveryStateForTests() {
|
|
99
|
+
reloadScheduled = false;
|
|
100
|
+
pendingDeletes.length = 0;
|
|
101
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: () => from[key],
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
|
|
23
|
+
value: true
|
|
24
|
+
}), mod);
|
|
25
|
+
var recoverZeroClient_exports = {};
|
|
26
|
+
__export(recoverZeroClient_exports, {
|
|
27
|
+
composeRecoveryLogSink: () => composeRecoveryLogSink,
|
|
28
|
+
makeZeroRecovery: () => makeZeroRecovery,
|
|
29
|
+
resetRecoveryStateForTests: () => resetRecoveryStateForTests
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(recoverZeroClient_exports);
|
|
32
|
+
function _type_of(obj) {
|
|
33
|
+
"@swc/helpers - typeof";
|
|
34
|
+
|
|
35
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
36
|
+
}
|
|
37
|
+
var RECOVER_GUARD_MS = 6e4;
|
|
38
|
+
var LOCAL_STORE_LOST = "Expected IndexedDB not found";
|
|
39
|
+
var reloadScheduled = false;
|
|
40
|
+
var pendingDeletes = [];
|
|
41
|
+
function recoveryGuardOpen(reasonKey) {
|
|
42
|
+
try {
|
|
43
|
+
var key = `on-zero-recover-${reasonKey}`;
|
|
44
|
+
var last = Number(window.sessionStorage.getItem(key) || 0);
|
|
45
|
+
if (Date.now() - last < RECOVER_GUARD_MS) return false;
|
|
46
|
+
window.sessionStorage.setItem(key, String(Date.now()));
|
|
47
|
+
} catch (e) {}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
function recover(deps, reasonKey, message, dropLocalState) {
|
|
51
|
+
if (typeof window === "undefined") return;
|
|
52
|
+
if (dropLocalState) {
|
|
53
|
+
pendingDeletes.push(Promise.resolve().then(deps.deleteLocalState).catch(function () {}));
|
|
54
|
+
}
|
|
55
|
+
if (reloadScheduled) return;
|
|
56
|
+
if (!recoveryGuardOpen(reasonKey)) {
|
|
57
|
+
console.error(`[on-zero] ${message} \u2014 already recovered once, not reloading`);
|
|
58
|
+
deps.zeroEvents.emit({
|
|
59
|
+
type: "fatal",
|
|
60
|
+
reason: message
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
reloadScheduled = true;
|
|
65
|
+
console.warn(`[on-zero] ${message} \u2014 recovering`);
|
|
66
|
+
deps.zeroEvents.emit({
|
|
67
|
+
type: "recovering",
|
|
68
|
+
reason: message
|
|
69
|
+
});
|
|
70
|
+
var _deps_reload;
|
|
71
|
+
var doReload = (_deps_reload = deps.reload) !== null && _deps_reload !== void 0 ? _deps_reload : function () {
|
|
72
|
+
return window.location.reload();
|
|
73
|
+
};
|
|
74
|
+
Promise.resolve().then(function () {
|
|
75
|
+
return Promise.allSettled(pendingDeletes);
|
|
76
|
+
}).then(function () {
|
|
77
|
+
var _deps_beforeReload;
|
|
78
|
+
return (_deps_beforeReload = deps.beforeReload) === null || _deps_beforeReload === void 0 ? void 0 : _deps_beforeReload.call(deps);
|
|
79
|
+
}).catch(function () {}).finally(doReload);
|
|
80
|
+
}
|
|
81
|
+
function makeZeroRecovery(deps) {
|
|
82
|
+
return {
|
|
83
|
+
onUpdateNeeded(reason) {
|
|
84
|
+
var dropLocalState = reason.type === "SchemaVersionNotSupported";
|
|
85
|
+
recover(deps, reason.type, `update needed (${reason.message || reason.type})`, dropLocalState);
|
|
86
|
+
},
|
|
87
|
+
onClientStateNotFound() {
|
|
88
|
+
recover(deps, "client-state-not-found", "client state not found", true);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function logToConsole(level, context) {
|
|
93
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
94
|
+
args[_key - 2] = arguments[_key];
|
|
95
|
+
}
|
|
96
|
+
var prefix = context ? Object.entries(context).map(function (param) {
|
|
97
|
+
var [key, value] = param;
|
|
98
|
+
return value === void 0 ? key : `${key}=${value}`;
|
|
99
|
+
}).join(" ") : "";
|
|
100
|
+
var method = level === "debug" ? "debug" : level;
|
|
101
|
+
console[method](...(prefix ? [prefix] : []), ...args);
|
|
102
|
+
}
|
|
103
|
+
function composeRecoveryLogSink(deps, consumerLogSink) {
|
|
104
|
+
var consumerFlush = consumerLogSink === null || consumerLogSink === void 0 ? void 0 : consumerLogSink.flush;
|
|
105
|
+
return {
|
|
106
|
+
log(level, context) {
|
|
107
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
108
|
+
args[_key - 2] = arguments[_key];
|
|
109
|
+
}
|
|
110
|
+
if (consumerLogSink) consumerLogSink.log(level, context, ...args);else logToConsole(level, context, ...args);
|
|
111
|
+
if (level !== "error") return;
|
|
112
|
+
var text = args.map(function (arg) {
|
|
113
|
+
return typeof arg === "string" ? arg : arg && (typeof arg === "undefined" ? "undefined" : _type_of(arg)) === "object" && "message" in arg ? String(arg.message) : "";
|
|
114
|
+
}).join(" ");
|
|
115
|
+
if (text.includes(LOCAL_STORE_LOST)) {
|
|
116
|
+
recover(deps, "local-store", "local store lost", true);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
// call through the consumer sink so a class-based sink keeps its `this`,
|
|
120
|
+
// rather than handing Zero a detached method reference.
|
|
121
|
+
flush: consumerFlush ? function () {
|
|
122
|
+
return consumerFlush.call(consumerLogSink);
|
|
123
|
+
} : void 0
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function resetRecoveryStateForTests() {
|
|
127
|
+
reloadScheduled = false;
|
|
128
|
+
pendingDeletes.length = 0;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=recoverZeroClient.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","recoverZeroClient_exports","__export","composeRecoveryLogSink","makeZeroRecovery","resetRecoveryStateForTests","module","exports","_type_of","obj","Symbol","constructor","RECOVER_GUARD_MS","LOCAL_STORE_LOST","reloadScheduled","pendingDeletes","recoveryGuardOpen","reasonKey","key","last","Number","window","sessionStorage","getItem","Date","now","setItem","String","e","recover","deps","message","dropLocalState","push","Promise","resolve","then","deleteLocalState","catch","console","error","zeroEvents","emit","type","reason","warn","_deps_reload","doReload","reload","location","allSettled","_deps_beforeReload","beforeReload","call","finally","onUpdateNeeded","onClientStateNotFound","logToConsole","level","context","_len","arguments","length","args","Array","_key","prefix","Object","entries","map","param","join","method","consumerLogSink","consumerFlush","flush"],"sources":["../../../src/helpers/recoverZeroClient.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
var import_helpers = require("@take-out/helpers");
|
|
2
|
+
var import_zero = require("@rocicorp/zero");
|
|
3
|
+
var import_vitest = require("vitest");
|
|
4
|
+
var import_recoverZeroClient = require("./recoverZeroClient.cjs");
|
|
5
|
+
let emitterSeq = 0;
|
|
6
|
+
function setup() {
|
|
7
|
+
const events = [];
|
|
8
|
+
const zeroEvents = (0, import_helpers.createEmitter)(`test-recover-${emitterSeq++}`, null);
|
|
9
|
+
zeroEvents.listen(event => {
|
|
10
|
+
if (event) events.push(event);
|
|
11
|
+
});
|
|
12
|
+
const deleteLocalState = import_vitest.vi.fn(() => Promise.resolve());
|
|
13
|
+
const reload = import_vitest.vi.fn();
|
|
14
|
+
const deps = {
|
|
15
|
+
deleteLocalState,
|
|
16
|
+
zeroEvents,
|
|
17
|
+
reload
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
deps,
|
|
21
|
+
deleteLocalState,
|
|
22
|
+
reload,
|
|
23
|
+
events
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function flush() {
|
|
27
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
28
|
+
}
|
|
29
|
+
(0, import_vitest.beforeEach)(() => {
|
|
30
|
+
window.sessionStorage.clear();
|
|
31
|
+
(0, import_recoverZeroClient.resetRecoveryStateForTests)();
|
|
32
|
+
});
|
|
33
|
+
(0, import_vitest.describe)("zero recovery", () => {
|
|
34
|
+
(0, import_vitest.test)("SchemaVersionNotSupported drops local state and reloads, emitting recovering", async () => {
|
|
35
|
+
const {
|
|
36
|
+
deps,
|
|
37
|
+
deleteLocalState,
|
|
38
|
+
reload,
|
|
39
|
+
events
|
|
40
|
+
} = setup();
|
|
41
|
+
(0, import_recoverZeroClient.makeZeroRecovery)(deps).onUpdateNeeded({
|
|
42
|
+
type: import_zero.UpdateNeededReasonType.SchemaVersionNotSupported
|
|
43
|
+
});
|
|
44
|
+
(0, import_vitest.expect)(events).toEqual([{
|
|
45
|
+
type: "recovering",
|
|
46
|
+
reason: import_vitest.expect.stringContaining("SchemaVersionNotSupported")
|
|
47
|
+
}]);
|
|
48
|
+
await flush();
|
|
49
|
+
(0, import_vitest.expect)(deleteLocalState).toHaveBeenCalledTimes(1);
|
|
50
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
51
|
+
});
|
|
52
|
+
(0, import_vitest.test)("NewClientGroup / VersionNotSupported reload WITHOUT deleting (sibling-tab safe)", async () => {
|
|
53
|
+
const {
|
|
54
|
+
deps,
|
|
55
|
+
deleteLocalState,
|
|
56
|
+
reload
|
|
57
|
+
} = setup();
|
|
58
|
+
const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(deps);
|
|
59
|
+
recovery.onUpdateNeeded({
|
|
60
|
+
type: import_zero.UpdateNeededReasonType.NewClientGroup
|
|
61
|
+
});
|
|
62
|
+
await flush();
|
|
63
|
+
(0, import_recoverZeroClient.resetRecoveryStateForTests)();
|
|
64
|
+
recovery.onUpdateNeeded({
|
|
65
|
+
type: import_zero.UpdateNeededReasonType.VersionNotSupported
|
|
66
|
+
});
|
|
67
|
+
await flush();
|
|
68
|
+
(0, import_vitest.expect)(deleteLocalState).not.toHaveBeenCalled();
|
|
69
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(2);
|
|
70
|
+
});
|
|
71
|
+
(0, import_vitest.test)("onClientStateNotFound drops local state and reloads", async () => {
|
|
72
|
+
const {
|
|
73
|
+
deps,
|
|
74
|
+
deleteLocalState,
|
|
75
|
+
reload
|
|
76
|
+
} = setup();
|
|
77
|
+
(0, import_recoverZeroClient.makeZeroRecovery)(deps).onClientStateNotFound();
|
|
78
|
+
await flush();
|
|
79
|
+
(0, import_vitest.expect)(deleteLocalState).toHaveBeenCalledTimes(1);
|
|
80
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
81
|
+
});
|
|
82
|
+
(0, import_vitest.test)("combined client: every instance deletes its own store, but only ONE reload", async () => {
|
|
83
|
+
const a = setup();
|
|
84
|
+
const b = setup();
|
|
85
|
+
(0, import_recoverZeroClient.makeZeroRecovery)(a.deps).onClientStateNotFound();
|
|
86
|
+
(0, import_recoverZeroClient.makeZeroRecovery)(b.deps).onClientStateNotFound();
|
|
87
|
+
await flush();
|
|
88
|
+
(0, import_vitest.expect)(a.deleteLocalState).toHaveBeenCalledTimes(1);
|
|
89
|
+
(0, import_vitest.expect)(b.deleteLocalState).toHaveBeenCalledTimes(1);
|
|
90
|
+
(0, import_vitest.expect)(a.reload.mock.calls.length + b.reload.mock.calls.length).toBe(1);
|
|
91
|
+
});
|
|
92
|
+
(0, import_vitest.test)("a second trigger in the same page-load adds no extra reload or fatal", async () => {
|
|
93
|
+
const {
|
|
94
|
+
deps,
|
|
95
|
+
reload,
|
|
96
|
+
events
|
|
97
|
+
} = setup();
|
|
98
|
+
const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(deps);
|
|
99
|
+
recovery.onClientStateNotFound();
|
|
100
|
+
recovery.onUpdateNeeded({
|
|
101
|
+
type: import_zero.UpdateNeededReasonType.NewClientGroup
|
|
102
|
+
});
|
|
103
|
+
await flush();
|
|
104
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
105
|
+
(0, import_vitest.expect)(events.filter(event => event.type === "fatal")).toEqual([]);
|
|
106
|
+
});
|
|
107
|
+
(0, import_vitest.test)("after a reload, a re-failing reason emits fatal instead of reloading again", async () => {
|
|
108
|
+
const {
|
|
109
|
+
deps,
|
|
110
|
+
reload,
|
|
111
|
+
events
|
|
112
|
+
} = setup();
|
|
113
|
+
const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(deps);
|
|
114
|
+
recovery.onClientStateNotFound();
|
|
115
|
+
await flush();
|
|
116
|
+
(0, import_recoverZeroClient.resetRecoveryStateForTests)();
|
|
117
|
+
recovery.onClientStateNotFound();
|
|
118
|
+
await flush();
|
|
119
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
120
|
+
(0, import_vitest.expect)(events.some(event => event.type === "fatal")).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
(0, import_vitest.test)("after a reload, a different reason still recovers", async () => {
|
|
123
|
+
const {
|
|
124
|
+
deps,
|
|
125
|
+
reload
|
|
126
|
+
} = setup();
|
|
127
|
+
const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(deps);
|
|
128
|
+
recovery.onClientStateNotFound();
|
|
129
|
+
await flush();
|
|
130
|
+
(0, import_recoverZeroClient.resetRecoveryStateForTests)();
|
|
131
|
+
recovery.onUpdateNeeded({
|
|
132
|
+
type: import_zero.UpdateNeededReasonType.SchemaVersionNotSupported
|
|
133
|
+
});
|
|
134
|
+
await flush();
|
|
135
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(2);
|
|
136
|
+
});
|
|
137
|
+
(0, import_vitest.test)("logSink recovers on local-store-lost and forwards to the consumer sink", async () => {
|
|
138
|
+
const {
|
|
139
|
+
deps,
|
|
140
|
+
deleteLocalState,
|
|
141
|
+
reload
|
|
142
|
+
} = setup();
|
|
143
|
+
const consumer = {
|
|
144
|
+
log: import_vitest.vi.fn()
|
|
145
|
+
};
|
|
146
|
+
const sink = (0, import_recoverZeroClient.composeRecoveryLogSink)(deps, consumer);
|
|
147
|
+
sink.log("error", void 0, "Error during persist: Expected IndexedDB not found");
|
|
148
|
+
(0, import_vitest.expect)(consumer.log).toHaveBeenCalledTimes(1);
|
|
149
|
+
await flush();
|
|
150
|
+
(0, import_vitest.expect)(deleteLocalState).toHaveBeenCalledTimes(1);
|
|
151
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
152
|
+
});
|
|
153
|
+
(0, import_vitest.test)("logSink with no consumer preserves console output and still watches", async () => {
|
|
154
|
+
const {
|
|
155
|
+
deps,
|
|
156
|
+
deleteLocalState,
|
|
157
|
+
reload
|
|
158
|
+
} = setup();
|
|
159
|
+
const infoSpy = import_vitest.vi.spyOn(console, "info").mockImplementation(() => {});
|
|
160
|
+
const sink = (0, import_recoverZeroClient.composeRecoveryLogSink)(deps);
|
|
161
|
+
sink.log("info", {
|
|
162
|
+
worker: "sync"
|
|
163
|
+
}, "connected");
|
|
164
|
+
(0, import_vitest.expect)(infoSpy).toHaveBeenCalledWith("worker=sync", "connected");
|
|
165
|
+
infoSpy.mockRestore();
|
|
166
|
+
sink.log("error", void 0, "Expected IndexedDB not found");
|
|
167
|
+
await flush();
|
|
168
|
+
(0, import_vitest.expect)(deleteLocalState).toHaveBeenCalledTimes(1);
|
|
169
|
+
(0, import_vitest.expect)(reload).toHaveBeenCalledTimes(1);
|
|
170
|
+
});
|
|
171
|
+
(0, import_vitest.test)("logSink flush calls through the consumer sink (preserves its this)", async () => {
|
|
172
|
+
const {
|
|
173
|
+
deps
|
|
174
|
+
} = setup();
|
|
175
|
+
class ClassSink {
|
|
176
|
+
flushed = false;
|
|
177
|
+
log() {}
|
|
178
|
+
flush() {
|
|
179
|
+
this.flushed = true;
|
|
180
|
+
return Promise.resolve();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const consumer = new ClassSink();
|
|
184
|
+
const sink = (0, import_recoverZeroClient.composeRecoveryLogSink)(deps, consumer);
|
|
185
|
+
await sink.flush?.();
|
|
186
|
+
(0, import_vitest.expect)(consumer.flushed).toBe(true);
|
|
187
|
+
});
|
|
188
|
+
(0, import_vitest.test)("logSink ignores non-error level and non-matching messages", async () => {
|
|
189
|
+
const {
|
|
190
|
+
deps,
|
|
191
|
+
deleteLocalState,
|
|
192
|
+
reload
|
|
193
|
+
} = setup();
|
|
194
|
+
const sink = (0, import_recoverZeroClient.composeRecoveryLogSink)(deps);
|
|
195
|
+
sink.log("info", void 0, "Expected IndexedDB not found");
|
|
196
|
+
sink.log("error", void 0, "some unrelated error");
|
|
197
|
+
await flush();
|
|
198
|
+
(0, import_vitest.expect)(deleteLocalState).not.toHaveBeenCalled();
|
|
199
|
+
(0, import_vitest.expect)(reload).not.toHaveBeenCalled();
|
|
200
|
+
});
|
|
201
|
+
});
|