on-zero 0.6.18 → 0.6.19
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/asyncTasks.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +1 -28
- package/dist/cjs/createZeroClient.connection.test.cjs +11 -40
- package/dist/cjs/createZeroClient.connection.test.native.js +11 -40
- package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +1 -29
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroDirectServer.cjs +1 -1
- package/dist/cjs/createZeroDirectServer.native.js +1 -1
- package/dist/cjs/createZeroDirectServer.native.js.map +1 -1
- package/dist/cjs/createZeroServer.test.cjs +6 -0
- package/dist/cjs/createZeroServer.test.native.js +6 -0
- package/dist/cjs/createZeroServer.test.native.js.map +1 -1
- package/dist/cjs/createZeroServerCore.cjs +29 -1
- package/dist/cjs/createZeroServerCore.native.js +153 -1
- package/dist/cjs/createZeroServerCore.native.js.map +1 -1
- package/dist/cjs/httpPull/transport.test.cjs +127 -15
- package/dist/cjs/httpPull/transport.test.native.js +161 -16
- package/dist/cjs/httpPull/transport.test.native.js.map +1 -1
- package/dist/cjs/httpPullTransport.cjs +48 -18
- package/dist/cjs/httpPullTransport.native.js +57 -20
- package/dist/cjs/httpPullTransport.native.js.map +1 -1
- package/dist/cjs/modelRegistry.cjs +7 -4
- package/dist/cjs/modelRegistry.native.js +8 -4
- package/dist/cjs/modelRegistry.native.js.map +1 -1
- package/dist/cjs/mutations.cjs +15 -11
- package/dist/cjs/mutations.native.js +17 -11
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/state.cjs +2 -3
- package/dist/cjs/state.native.js +2 -3
- package/dist/cjs/state.native.js.map +1 -1
- package/dist/cjs/syncHost.cjs +2 -1
- package/dist/cjs/syncHost.native.js +2 -1
- package/dist/cjs/syncHost.native.js.map +1 -1
- package/dist/cjs/usePermission.test.cjs +4 -2
- package/dist/cjs/usePermission.test.native.js +4 -2
- package/dist/cjs/usePermission.test.native.js.map +1 -1
- package/dist/esm/asyncTasks.mjs.map +1 -1
- package/dist/esm/asyncTasks.native.js.map +1 -1
- package/dist/esm/createZeroClient.connection.test.mjs +11 -40
- package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.connection.test.native.js +11 -40
- package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +2 -29
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +2 -30
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroDirectServer.mjs +2 -2
- package/dist/esm/createZeroDirectServer.mjs.map +1 -1
- package/dist/esm/createZeroDirectServer.native.js +2 -2
- package/dist/esm/createZeroDirectServer.native.js.map +1 -1
- package/dist/esm/createZeroServer.test.mjs +6 -0
- package/dist/esm/createZeroServer.test.mjs.map +1 -1
- package/dist/esm/createZeroServer.test.native.js +6 -0
- package/dist/esm/createZeroServer.test.native.js.map +1 -1
- package/dist/esm/createZeroServerCore.mjs +29 -1
- package/dist/esm/createZeroServerCore.mjs.map +1 -1
- package/dist/esm/createZeroServerCore.native.js +153 -1
- package/dist/esm/createZeroServerCore.native.js.map +1 -1
- package/dist/esm/httpPull/transport.test.mjs +127 -15
- package/dist/esm/httpPull/transport.test.mjs.map +1 -1
- package/dist/esm/httpPull/transport.test.native.js +161 -16
- package/dist/esm/httpPull/transport.test.native.js.map +1 -1
- package/dist/esm/httpPullTransport.mjs +48 -18
- package/dist/esm/httpPullTransport.mjs.map +1 -1
- package/dist/esm/httpPullTransport.native.js +57 -20
- package/dist/esm/httpPullTransport.native.js.map +1 -1
- package/dist/esm/modelRegistry.mjs +7 -4
- package/dist/esm/modelRegistry.mjs.map +1 -1
- package/dist/esm/modelRegistry.native.js +8 -4
- package/dist/esm/modelRegistry.native.js.map +1 -1
- package/dist/esm/mutations.mjs +15 -11
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +17 -11
- package/dist/esm/mutations.native.js.map +1 -1
- package/dist/esm/state.mjs +2 -3
- package/dist/esm/state.mjs.map +1 -1
- package/dist/esm/state.native.js +2 -3
- package/dist/esm/state.native.js.map +1 -1
- package/dist/esm/syncHost.mjs +2 -1
- package/dist/esm/syncHost.mjs.map +1 -1
- package/dist/esm/syncHost.native.js +2 -1
- package/dist/esm/syncHost.native.js.map +1 -1
- package/dist/esm/usePermission.test.mjs +6 -4
- package/dist/esm/usePermission.test.mjs.map +1 -1
- package/dist/esm/usePermission.test.native.js +6 -4
- package/dist/esm/usePermission.test.native.js.map +1 -1
- package/package.json +2 -2
- package/src/asyncTasks.ts +4 -1
- package/src/createZeroClient.connection.test.tsx +11 -35
- package/src/createZeroClient.tsx +7 -40
- package/src/createZeroDirectServer.ts +2 -2
- package/src/createZeroServer.test.ts +10 -0
- package/src/createZeroServerCore.ts +38 -1
- package/src/httpPull/transport.test.ts +143 -16
- package/src/httpPullTransport.ts +67 -30
- package/src/modelRegistry.ts +9 -4
- package/src/mutations.ts +19 -15
- package/src/state.ts +3 -3
- package/src/syncHost.ts +2 -2
- package/src/usePermission.test.ts +9 -3
- package/test-fixtures/server-return-types.ts +13 -1
- package/types/asyncTasks.d.ts +5 -1
- package/types/asyncTasks.d.ts.map +1 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroServerCore.d.ts.map +1 -1
- package/types/httpPullTransport.d.ts +13 -0
- package/types/httpPullTransport.d.ts.map +1 -1
- package/types/modelRegistry.d.ts.map +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/state.d.ts +2 -2
- package/types/state.d.ts.map +1 -1
- package/types/syncHost.d.ts +1 -1
- package/types/syncHost.d.ts.map +1 -1
|
@@ -113,7 +113,16 @@ function withTransactionLifecycle(database, lifecycle) {
|
|
|
113
113
|
const value = await database.transaction(async (tx, hooks) => {
|
|
114
114
|
lifecycle.beginAttempt();
|
|
115
115
|
try {
|
|
116
|
-
const result = await callback(tx,
|
|
116
|
+
const result = await callback(tx, {
|
|
117
|
+
...hooks,
|
|
118
|
+
async updateClientMutationID() {
|
|
119
|
+
const result2 = await hooks.updateClientMutationID();
|
|
120
|
+
if (input && input.mutationID < result2.lastMutationID) {
|
|
121
|
+
throw new ExpectedDuplicateMutation(input.clientID, input.mutationID, result2.lastMutationID);
|
|
122
|
+
}
|
|
123
|
+
return result2;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
117
126
|
lifecycle.completeAttempt();
|
|
118
127
|
return result;
|
|
119
128
|
} catch (error) {
|
|
@@ -125,11 +134,30 @@ function withTransactionLifecycle(database, lifecycle) {
|
|
|
125
134
|
return value;
|
|
126
135
|
} catch (error) {
|
|
127
136
|
lifecycle.rollbackTransaction();
|
|
137
|
+
if (error instanceof ExpectedDuplicateMutation) {
|
|
138
|
+
return {
|
|
139
|
+
id: {
|
|
140
|
+
clientID: error.clientID,
|
|
141
|
+
id: error.mutationID
|
|
142
|
+
},
|
|
143
|
+
result: {
|
|
144
|
+
error: "alreadyProcessed",
|
|
145
|
+
details: error.message
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
128
149
|
throw error;
|
|
129
150
|
}
|
|
130
151
|
}
|
|
131
152
|
};
|
|
132
153
|
}
|
|
154
|
+
class ExpectedDuplicateMutation extends Error {
|
|
155
|
+
constructor(clientID, mutationID, expectedMutationID) {
|
|
156
|
+
super(`Ignoring mutation from ${clientID} with ID ${mutationID} as it was already processed. Expected: ${expectedMutationID}`);
|
|
157
|
+
this.clientID = clientID;
|
|
158
|
+
this.mutationID = mutationID;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
133
161
|
async function parseAlreadyProcessed(request, response) {
|
|
134
162
|
const mutations = alreadyProcessedMutations(response);
|
|
135
163
|
if (mutations.length === 0) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["PushProcessor","handleQueryRequest","zeroHandleQueryRequest","runAsyncTaskEntries","createAsyncTaskCollector","createZeroDirectServerRuntime","resolveServerQuery","createMutators","runWithAuthScope","runWithQueryContext","createZeroServerCore","createDatabase","createServerActions","defaultAllowAdminRole","defaultMutateAuthData","models","mutations","mutationValidators","persistAlreadyProcessed","queries","schema","validateMutation","validateQuery","permissions","server","handleMutationRequest","authData","request","scheduleBackgroundTask","skipAsyncTasks","tasks","recoveryRequest","clone","mutators","enqueueTask","can","environment","processor","withTransactionLifecycle","lifecycle","response","process","parsed","parseAlreadyProcessed","committed","length","entries","map","entry","task","background","asyncTasks","Error","handler","name","args","userID","id","database","transaction","callback","input","value","tx","hooks","beginAttempt","result","completeAttempt","error","rollbackAttempt","commitTransaction","rollbackTransaction","alreadyProcessedMutations","upstreamSchema","URL","url","searchParams","get","body","json","clientGroupID","Array","isArray","filter","mutation"
|
|
1
|
+
{"version":3,"names":["PushProcessor","handleQueryRequest","zeroHandleQueryRequest","runAsyncTaskEntries","createAsyncTaskCollector","createZeroDirectServerRuntime","resolveServerQuery","createMutators","runWithAuthScope","runWithQueryContext","createZeroServerCore","createDatabase","createServerActions","defaultAllowAdminRole","defaultMutateAuthData","models","mutations","mutationValidators","persistAlreadyProcessed","queries","schema","validateMutation","validateQuery","permissions","server","handleMutationRequest","authData","request","scheduleBackgroundTask","skipAsyncTasks","tasks","recoveryRequest","clone","mutators","enqueueTask","can","environment","processor","withTransactionLifecycle","lifecycle","response","process","parsed","parseAlreadyProcessed","committed","length","entries","map","entry","task","background","asyncTasks","Error","handler","name","args","userID","id","database","transaction","callback","input","value","tx","hooks","beginAttempt","result","updateClientMutationID","result2","mutationID","lastMutationID","ExpectedDuplicateMutation","clientID","completeAttempt","error","rollbackAttempt","commitTransaction","rollbackTransaction","details","message","constructor","expectedMutationID","alreadyProcessedMutations","upstreamSchema","URL","url","searchParams","get","body","json","clientGroupID","Array","isArray","filter","mutation"],"sources":["../../src/createZeroServerCore.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -4,11 +4,130 @@ import { createAsyncTaskCollector, createZeroDirectServerRuntime, resolveServerQ
|
|
|
4
4
|
import { createMutators } from "./helpers/createMutators.native.js";
|
|
5
5
|
import { runWithAuthScope } from "./helpers/mutatorContext.native.js";
|
|
6
6
|
import { runWithQueryContext } from "./helpers/queryContext.native.js";
|
|
7
|
+
function _assert_this_initialized(self) {
|
|
8
|
+
if (self === void 0) {
|
|
9
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
10
|
+
}
|
|
11
|
+
return self;
|
|
12
|
+
}
|
|
13
|
+
function _call_super(_this, derived, args) {
|
|
14
|
+
derived = _get_prototype_of(derived);
|
|
15
|
+
return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
|
|
16
|
+
}
|
|
17
|
+
function _class_call_check(instance, Constructor) {
|
|
18
|
+
if (!(instance instanceof Constructor)) {
|
|
19
|
+
throw new TypeError("Cannot call a class as a function");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function _construct(Parent, args, Class) {
|
|
23
|
+
if (_is_native_reflect_construct()) {
|
|
24
|
+
_construct = Reflect.construct;
|
|
25
|
+
} else {
|
|
26
|
+
_construct = function construct(Parent2, args2, Class2) {
|
|
27
|
+
var a = [null];
|
|
28
|
+
a.push.apply(a, args2);
|
|
29
|
+
var Constructor = Function.bind.apply(Parent2, a);
|
|
30
|
+
var instance = new Constructor();
|
|
31
|
+
if (Class2) _set_prototype_of(instance, Class2.prototype);
|
|
32
|
+
return instance;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return _construct.apply(null, arguments);
|
|
36
|
+
}
|
|
37
|
+
function _define_property(obj, key, value) {
|
|
38
|
+
if (key in obj) {
|
|
39
|
+
Object.defineProperty(obj, key, {
|
|
40
|
+
value,
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
obj[key] = value;
|
|
47
|
+
}
|
|
48
|
+
return obj;
|
|
49
|
+
}
|
|
50
|
+
function _get_prototype_of(o) {
|
|
51
|
+
_get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o2) {
|
|
52
|
+
return o2.__proto__ || Object.getPrototypeOf(o2);
|
|
53
|
+
};
|
|
54
|
+
return _get_prototype_of(o);
|
|
55
|
+
}
|
|
56
|
+
function _inherits(subClass, superClass) {
|
|
57
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
58
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
59
|
+
}
|
|
60
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
61
|
+
constructor: {
|
|
62
|
+
value: subClass,
|
|
63
|
+
writable: true,
|
|
64
|
+
configurable: true
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
if (superClass) _set_prototype_of(subClass, superClass);
|
|
68
|
+
}
|
|
69
|
+
function _instanceof(left, right) {
|
|
70
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
71
|
+
return !!right[Symbol.hasInstance](left);
|
|
72
|
+
} else {
|
|
73
|
+
return left instanceof right;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function _is_native_function(fn) {
|
|
77
|
+
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|
78
|
+
}
|
|
79
|
+
function _possible_constructor_return(self, call) {
|
|
80
|
+
if (call && (_type_of(call) === "object" || typeof call === "function")) {
|
|
81
|
+
return call;
|
|
82
|
+
}
|
|
83
|
+
return _assert_this_initialized(self);
|
|
84
|
+
}
|
|
85
|
+
function _set_prototype_of(o, p) {
|
|
86
|
+
_set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o2, p2) {
|
|
87
|
+
o2.__proto__ = p2;
|
|
88
|
+
return o2;
|
|
89
|
+
};
|
|
90
|
+
return _set_prototype_of(o, p);
|
|
91
|
+
}
|
|
7
92
|
function _type_of(obj) {
|
|
8
93
|
"@swc/helpers - typeof";
|
|
9
94
|
|
|
10
95
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
11
96
|
}
|
|
97
|
+
function _wrap_native_super(Class) {
|
|
98
|
+
var _cache = typeof Map === "function" ? /* @__PURE__ */new Map() : void 0;
|
|
99
|
+
_wrap_native_super = function wrapNativeSuper(Class2) {
|
|
100
|
+
if (Class2 === null || !_is_native_function(Class2)) return Class2;
|
|
101
|
+
if (typeof Class2 !== "function") {
|
|
102
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
103
|
+
}
|
|
104
|
+
if (typeof _cache !== "undefined") {
|
|
105
|
+
if (_cache.has(Class2)) return _cache.get(Class2);
|
|
106
|
+
_cache.set(Class2, Wrapper);
|
|
107
|
+
}
|
|
108
|
+
function Wrapper() {
|
|
109
|
+
return _construct(Class2, arguments, _get_prototype_of(this).constructor);
|
|
110
|
+
}
|
|
111
|
+
Wrapper.prototype = Object.create(Class2.prototype, {
|
|
112
|
+
constructor: {
|
|
113
|
+
value: Wrapper,
|
|
114
|
+
enumerable: false,
|
|
115
|
+
writable: true,
|
|
116
|
+
configurable: true
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return _set_prototype_of(Wrapper, Class2);
|
|
120
|
+
};
|
|
121
|
+
return _wrap_native_super(Class);
|
|
122
|
+
}
|
|
123
|
+
function _is_native_reflect_construct() {
|
|
124
|
+
try {
|
|
125
|
+
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
126
|
+
} catch (_) {}
|
|
127
|
+
return (_is_native_reflect_construct = function () {
|
|
128
|
+
return !!result;
|
|
129
|
+
})();
|
|
130
|
+
}
|
|
12
131
|
function createZeroServerCore(param) {
|
|
13
132
|
var {
|
|
14
133
|
createDatabase,
|
|
@@ -130,7 +249,16 @@ function withTransactionLifecycle(database, lifecycle) {
|
|
|
130
249
|
var value = await database.transaction(async function (tx, hooks) {
|
|
131
250
|
lifecycle.beginAttempt();
|
|
132
251
|
try {
|
|
133
|
-
var result = await callback(tx,
|
|
252
|
+
var result = await callback(tx, {
|
|
253
|
+
...hooks,
|
|
254
|
+
async updateClientMutationID() {
|
|
255
|
+
var result2 = await hooks.updateClientMutationID();
|
|
256
|
+
if (input && input.mutationID < result2.lastMutationID) {
|
|
257
|
+
throw new ExpectedDuplicateMutation(input.clientID, input.mutationID, result2.lastMutationID);
|
|
258
|
+
}
|
|
259
|
+
return result2;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
134
262
|
lifecycle.completeAttempt();
|
|
135
263
|
return result;
|
|
136
264
|
} catch (error) {
|
|
@@ -142,11 +270,35 @@ function withTransactionLifecycle(database, lifecycle) {
|
|
|
142
270
|
return value;
|
|
143
271
|
} catch (error) {
|
|
144
272
|
lifecycle.rollbackTransaction();
|
|
273
|
+
if (_instanceof(error, ExpectedDuplicateMutation)) {
|
|
274
|
+
return {
|
|
275
|
+
id: {
|
|
276
|
+
clientID: error.clientID,
|
|
277
|
+
id: error.mutationID
|
|
278
|
+
},
|
|
279
|
+
result: {
|
|
280
|
+
error: "alreadyProcessed",
|
|
281
|
+
details: error.message
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
145
285
|
throw error;
|
|
146
286
|
}
|
|
147
287
|
}
|
|
148
288
|
};
|
|
149
289
|
}
|
|
290
|
+
var ExpectedDuplicateMutation = /* @__PURE__ */function (Error1) {
|
|
291
|
+
"use strict";
|
|
292
|
+
|
|
293
|
+
_inherits(ExpectedDuplicateMutation2, Error1);
|
|
294
|
+
function ExpectedDuplicateMutation2(clientID, mutationID, expectedMutationID) {
|
|
295
|
+
_class_call_check(this, ExpectedDuplicateMutation2);
|
|
296
|
+
var _this;
|
|
297
|
+
_this = _call_super(this, ExpectedDuplicateMutation2, [`Ignoring mutation from ${clientID} with ID ${mutationID} as it was already processed. Expected: ${expectedMutationID}`]), _define_property(_this, "clientID", void 0), _define_property(_this, "mutationID", void 0), _this.clientID = clientID, _this.mutationID = mutationID;
|
|
298
|
+
return _this;
|
|
299
|
+
}
|
|
300
|
+
return ExpectedDuplicateMutation2;
|
|
301
|
+
}(_wrap_native_super(Error));
|
|
150
302
|
async function parseAlreadyProcessed(request, response) {
|
|
151
303
|
var mutations = alreadyProcessedMutations(response);
|
|
152
304
|
if (mutations.length === 0) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["PushProcessor","handleQueryRequest","zeroHandleQueryRequest","runAsyncTaskEntries","createAsyncTaskCollector","createZeroDirectServerRuntime","resolveServerQuery","createMutators","runWithAuthScope","runWithQueryContext","
|
|
1
|
+
{"version":3,"names":["PushProcessor","handleQueryRequest","zeroHandleQueryRequest","runAsyncTaskEntries","createAsyncTaskCollector","createZeroDirectServerRuntime","resolveServerQuery","createMutators","runWithAuthScope","runWithQueryContext","_assert_this_initialized","self","ReferenceError","_call_super","_this","derived","args","_get_prototype_of","_possible_constructor_return","_is_native_reflect_construct","Reflect","construct","constructor","apply","_class_call_check","instance","Constructor","TypeError","_construct","Parent","Class","Parent2","args2","Class2","a","push","Function","bind","_set_prototype_of","prototype","arguments","_define_property","obj","key","value","Object","defineProperty","enumerable","configurable","writable","o","setPrototypeOf","getPrototypeOf","o2","__proto__","_inherits","subClass","superClass","create","_instanceof","left","right","Symbol","hasInstance","_is_native_function","fn","toString","call","indexOf","_type_of","p","p2","_wrap_native_super","_cache","Map","wrapNativeSuper","has","get","set","Wrapper","result","Boolean","valueOf","_","createZeroServerCore","param","createDatabase","createServerActions","defaultAllowAdminRole","defaultMutateAuthData","models","mutations","mutationValidators","persistAlreadyProcessed","queries","schema","validateMutation","validateQuery","permissions","server","handleMutationRequest","param2","authData","request","scheduleBackgroundTask","skipAsyncTasks","tasks","recoveryRequest","clone","mutators","enqueueTask","can","environment","processor","withTransactionLifecycle","lifecycle","response","process","parsed","parseAlreadyProcessed","committed","length","entries","map","entry","task","background","asyncTasks","Error","handler","name"],"sources":["../../src/createZeroServerCore.ts"],"sourcesContent":[null],"mappings":"AAAA,SAAAA,aAAA,EAAAC,kBAAA,IAAAC,sBAAA;AAAA,SACEC,mBAAA;AAAA,SACAC,wBAAsB,EAAAC,6BAAA,EAAAC,kBAAA;AAAA,SACjBC,cAAA;AAEP,SAASC,gBAAA,4CAA2B;AACpC,SAAAC,mBAAA;AAAA,SACEC,yBAAAC,IAAA;EACA,IAAAA,IAAA;IACA,UAAAC,cAAA;EAAA;EAKF,OAASD,IAAA;AACT;AACA,SAASE,YAAAC,KAAA,EAAAC,OAAA,EAA2BC,IAAA;EA4C7BD,OAAS,GAAAE,iBAAA,CAIdF,OAAA;EACA,OAAAG,4BAAA,CAAAJ,KAAA,EAAAK,4BAAA,KAAAC,OAAA,CAAAC,SAAA,CAAAN,OAAA,EAAAC,IAAA,QAAAC,iBAAA,CAAAH,KAAA,EAAAQ,WAAA,IAAAP,OAAA,CAAAQ,KAAA,CAAAT,KAAA,EAAAE,IAAA;AAAA;AACA,SACAQ,iBAAwBA,CAAAC,QAAA,EAAAC,WAAA;EACxB,MAAAD,QAAA,YAAAC,WAAA;IACA,UAAAC,SAAA;EACA;AAAW;AACX,SACAC,WAAAC,MAAA,EAAAb,IAAA,EAAAc,KAAA;EACA,IAAAX,4BAAA;IACAS,UAAA,GAAAR,OAAA,CAAAC,SAAA;EACA;IACuDO,UAAA,YAAAP,UAAAU,OAAA,EAAAC,KAAA,EAAAC,MAAA;MACvD,IAAQC,CAAA,IACN,KACA;MACAA,CAAA,CAAAC,IAAA,CAAAZ,KAAA,CAAAW,CAAA,EAAAF,KAAA;MACA,IAAAN,WAAA,GAAAU,QAAA,CAAAC,IAAA,CAAAd,KAAA,CAAAQ,OAAA,EAAAG,CAAA;MACA,IAAAT,QAAA,OAAAC,WAAA;MACA,IAAAO,MAAW,EAAAK,iBAAA,CAAAb,QAAA,EAAAQ,MAAA,CAAAM,SAAA;MACX,OAAAd,QAAA;IACA;EAAA;EACA,OACAG,UAAA,CAAAL,KAAA,OAAAiB,SAAA;AAAA;AAGF,SAAMC,iBAAAC,GAAA,EAAAC,GAAwB,EAAAC,KAAO;EAAA,IACnCD,GAAA,IAAAD,GAAA;IACAG,MAAA,CAAAC,cAAA,CAAAJ,GAAA,EAAAC,GAAA;MACAC,KAAA;MACAG,UAAA;MACFC,YAAoC;MAClCC,QAAM;IACN;EACA;IAAgCP,GAC9B,CAAAC,GAAA,IAAAC,KAAa;EAAM;EACF,OACjBF,GAAA;AAAA;AACa,SACbzB,kBAAAiC,CAAA;EAAAjC,iBACA,GAAA4B,MAAA,CAAAM,cAAA,GAAAN,MAAA,CAAAO,cAAA,YAAAA,eAAAC,EAAA;IAAA,OACAA,EAAA,CAAAC,SAAA,IAAAT,MAAA,CAAAO,cAAA,CAAAC,EAAA;EAAA;EACA,OACDpC,iBAAA,CAAAiC,CAAA;AACD;AAAsB,SACpBK,UAAAC,QAAA,EAAAC,UAAyB;EAAiC,IAC5D,OAAAA,UAAA,mBAAAA,UAAA;IACA,MAAM,IAAA9B,SAAW,qDAAyC;EAE1D;EACE6B,QAAA,CAAAjB,SAAM,GAASM,MAAM,CAAAa,MAAA,CAAAD,UAAA,IAAsBA,UAAA,CAAAlB,SAAiB;IAC5DjB,WAAI,EAAQ;MACdsB,KAAA,EAAAY,QAAA;MAEAP,QAAK;MACHD,YAAM;IAA0C;EAC3C;EAC8C,IACnDS,UAAE,EAAAnB,iBAAA,CAAAkB,QAAA,EAAAC,UAAA;AACF;AAAyE,SAC3EE,YAAAC,IAAA,EAAAC,KAAA;EAEA,IAAAA,KAAO,mBAAAC,MAAA,oBAAAD,KAAA,CAAAC,MAAA,CAAAC,WAAA;IAAA,OACL,EAAAF,KAAA,CAAAC,MAAA,CAAAC,WAAA,EAAAH,IAAA;EAAA,OACA;IACF,OAAAA,IAAA,YAAAC,KAAA;EACF;AAEA;AAAkC,SAChCG,oBAAAC,EAAA;EAAA,OACA7B,QAAA,CAAA8B,QAAA,CAAAC,IAAA,CAAAF,EAAA,EAAAG,OAAA;AAAA;AAKA,SAAKlD,4BAASA,CAAAP,IAAA,EAAAwD,IAAA;EACZ,IAAAA,IAAA,KAAME,QAAI,CAAAF,IAAA,yBAAAA,IAAA;IAAA,OACRA,IAAA;EAAA;EAEF,OACFzD,wBAAA,CAAAC,IAAA;AAEA;AACqB,SACjB2B,kBAAAY,CAAA,EAAAoB,CAAA;EAAAhC,iBACA,GAAAO,MAAA,CAAAM,cAAA,aAAAA,eAAAE,EAAA,EAAAkB,EAAA;IAAAlB,EACA,CAAAC,SAAA,GAAAiB,EAAA;IAAA,OACAlB,EAAA;EAAA;EACA,OACAf,iBAAA,CAAAY,CAAA,EAAAoB,CAAA;AAAA;AAGJ,SAAAD,QAAMA,CAAA3B,GAAS;EACf,uBAAiB;;EAAM,OACnBA,GAAA,WAAUoB,MAAA,KAA6B,eAAApB,GAAA,CAAApB,WAAA,KAAAwC,MAAA,qBAAApB,GAAA;AAAA;AACzC,SAAA8B,mBAAA1C,KAAA;EAAA,IAAA2C,MAEE,UAAWC,GAAA,KACP,4BAAuB,IAASA,GAAA,EAAQ,QAAO;EACYF,kBAAA,YAAAG,gBAAA1C,MAAA;IACnE,IAAAA,MAAA,cAAA+B,mBAAA,CAAA/B,MAAA,UAAAA,MAAA;IAEA,WAASA,MAAA,KAAS;MACpB,UAAAN,SAAA;IAEA;IACE,WAAA8C,MAAA;MACA,IAAAA,MAAA,CAAAG,GAAA,CAAA3C,MAAA,UAAAwC,MAAA,CAAAI,GAAA,CAAA5C,MAAA;MACAwC,MAAG,CAAAK,GAAA,CAAA7C,MAAA,EAAA8C,OAAA;IACL;IACF,SAAAA,QAAA;MAQA,OAASnD,UAAA,CAAAK,MAAA,EAAAO,SACP,EAAAvB,iBAEoB,OAAAK,WAAA;IACpB;IACEyD,OAAM,CAAAxC,SAAA,GAAYM,MAAA,CAAAa,MAAU,CAAAzB,MAAO,CAAAM,SAAA;MACjCjB,WAAI;QACFsB,KAAA,EAAMmC,OAAQ;QACZhC,UAAA,EAAU;QACVE,QAAI;QACFD,YAAM;MAA4B;IAC7B;IAED,OAAAV,iBAAM,CAAAyC,OAAS,EAAM9C,MAAM;EAC3B;EACE,OAAAuC,kBAAM,CAAI1C,KAAA;AAAA;AACF,SAAAX,4BACAA,CAAA;EAAA;IACC,IAAA6D,MAAA,IACTC,OAAA,CAAA1C,SAAA,CAAA2C,OAAA,CAAAf,IAAA,CAAA/C,OAAA,CAAAC,SAAA,CAAA4D,OAAA;EAEF,SAAAE,CAAA,GAAO;EACT,QAAAhE,4BACD,YAAAA,CAAA;IACD,SAAA6D,MAAA;EACA;AAAO;AAEP,SAAAI,oBAAUA,CAAAC,KAAA;EACV;IAAAC,cAAM;IAAAC,mBAAA;IAAAC,qBAAA;IAAAC,qBAAA;IAAAC,MAAA;IAAAC,SAAA,EAAAC,kBAAA;IAAAC,uBAAA;IAAAC,OAAA;IAAAC,MAAA;IAAAC,gBAAA;IAAAC;EAAA,IAAAZ,KAAA;EAAA;IAAAa,WACR;IAAAC;EAAA,IAAA9F,6BAAA;IAAAiF,cACM;IACRC,mBAAU;IACVC,qBAAO;IAAAC,qBACO;IACdC,MAAA;IACAC,SAAI,EAAAC,kBAAiB;IACnBE,OAAA;IAAOC,MAAA;IACDC,gBACF;IAAgBC;EACN;EACZ,IAAAG,qBACQ,kBAAAA,CAAAC,MAAA;IAAA;MAAAC,QACN;MAAAC,OAAO;MAAAC,sBAAA;MAAAC;IAAA,IAAAJ,MAAA;IAAA,IAAAK,KAAA,GACPtG,wBAAe;IAAA,IAAAuG,eACjB,GAAAJ,OAAA,CAAAK,KAAA;IAAA,IAAAC,QACF,GAAAtG,cAAA;MAAAuG,WACF,EAAAJ,KAAA,CAAAI,WAAA;MACAC,GAAA,EAAAb,WAAM,CAAAa,GAAA;MACRxB,mBAAA;MACFyB,WAAA;MACFtB,MAAA;MACFY,QAAA;MAEMN,gBAAA;MACJJ;IAKE;IAAA,IACEqB,SAAA,OAAAjH,aAA0B,CAAAkH,wBAA8B,CAAA5B,cAAA,IAAAoB,KAAA,CAAAS,SAAA;IAC1D,IAAAC,QAAA,SAAAH,SAAA,CAAAI,OAAA,CAAAR,QAAA,EAAAN,OAAA;IANS,IAAAV,uBAAA;MACA,IAAAyB,MAAA,SAAAC,qBAAA,CAAAZ,eAAA,EAAAS,QAAA;MAMX,IAAAE,MAAA,QAAAzB,uBAAA,CAAAyB,MAAA;IACF;IAEA,KAAAb,cAAe,IAAAC,KAAA,CAAAc,SACb,CAAAC,MACA;MAEA,IAAMC,OAAA,GAAYhB,KAAA,CAAAc,SAAA,CAAAG,GAAA,WAA0BC,KAAQ;QAChD;UAEE,GAAAA,KAAA;UACDC,IAAA,WAAAA,CAAA,EAAgB;YAEf,OAAQrH,gBAAmB,CAAA8F,QAAA,EAAAsB,KAAA,CAAAC,IAAA;UAC7B;QAEJ,CAAO;MACL;MACA,MAAA1H,mBAAA,CAAAuH,OAAA;QACAI,UAAA,EAAAtB;MACF;IACF;IAEA,OAAS;MACHY,QAAC;MACLW,UAAM,EAAArB,KAAa,CAAAc;IACnB;EAEA;EACE,IAAAvH,kBAAiB,kBAAAA,CAAoBoG,MAAA,EAAU;IAC/C;MAAMC,QAAM;MAAAC;IAA8B,IAAAF,MAAA;IAC1C,KAAAP,OAAM;MACN,MACG,IAACkC,KACF,2HAIkB;IAGrB;IACH,IAAAC,OAAA,YAAAA,CAAAC,IAAA,EAAAlH,IAAA","ignoreList":[]}
|
|
@@ -434,22 +434,132 @@ describe("zero-http transport", () => {
|
|
|
434
434
|
cleanup();
|
|
435
435
|
view.destroy();
|
|
436
436
|
});
|
|
437
|
-
test("
|
|
438
|
-
const
|
|
437
|
+
test("pull and push 500 reconnects keep socket opens on their current Zero attempt", async () => {
|
|
438
|
+
const lifecycle = [];
|
|
439
|
+
const zeroLogs = [];
|
|
440
|
+
let failPull = false;
|
|
441
|
+
let failPush = false;
|
|
439
442
|
const fetch = vi.fn(async (input, init) => {
|
|
440
443
|
const request = recordRequest(input, init);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
+
if (request.path === "/pull") {
|
|
445
|
+
if (failPull) {
|
|
446
|
+
failPull = false;
|
|
447
|
+
return jsonResponse({
|
|
448
|
+
error: "injected pull outage"
|
|
449
|
+
}, {
|
|
450
|
+
status: 500
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return jsonResponse({
|
|
454
|
+
cookie: request.body.cookie,
|
|
455
|
+
unchanged: true
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
if (failPush) {
|
|
459
|
+
failPush = false;
|
|
460
|
+
return jsonResponse({
|
|
461
|
+
error: "injected push outage"
|
|
462
|
+
}, {
|
|
463
|
+
status: 500
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
const mutation2 = request.body.mutations[0];
|
|
467
|
+
return jsonResponse({
|
|
468
|
+
pushResponse: {
|
|
469
|
+
mutations: [{
|
|
470
|
+
id: {
|
|
471
|
+
clientID: mutation2.clientID,
|
|
472
|
+
id: mutation2.id
|
|
473
|
+
},
|
|
474
|
+
result: {}
|
|
475
|
+
}]
|
|
476
|
+
}
|
|
477
|
+
});
|
|
444
478
|
});
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
479
|
+
const transport = installHttpPullTransport({
|
|
480
|
+
origin: ORIGIN,
|
|
481
|
+
fetch,
|
|
482
|
+
lifecycle: event => lifecycle.push(event)
|
|
483
|
+
});
|
|
484
|
+
transports.push(transport);
|
|
485
|
+
const zero = createZero({
|
|
486
|
+
logSink: {
|
|
487
|
+
log: (_level, context, ...args) => {
|
|
488
|
+
zeroLogs.push({
|
|
489
|
+
context: context ?? {},
|
|
490
|
+
args
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
await eventually(() => expect(zero.connection.state.current.name).toBe("connected"));
|
|
496
|
+
failPull = true;
|
|
497
|
+
await transport.pull().catch(() => {});
|
|
498
|
+
await eventually(() => expect(lifecycle.filter(event => event.type === "open")).toHaveLength(2), 5e3);
|
|
499
|
+
failPush = true;
|
|
500
|
+
const mutation = zero.mutate.project.create({
|
|
501
|
+
id: "p1",
|
|
502
|
+
ownerId: "u1",
|
|
503
|
+
name: "after reconnect"
|
|
504
|
+
});
|
|
505
|
+
await mutation.client;
|
|
506
|
+
await mutation.server.catch(() => {});
|
|
507
|
+
await eventually(() => expect(lifecycle.filter(event => event.type === "open")).toHaveLength(3), 5e3);
|
|
508
|
+
await eventually(() => expect(zero.connection.state.current.name).toBe("connected"), 5e3);
|
|
509
|
+
const opens = lifecycle.filter(event => event.type === "open");
|
|
510
|
+
expect(opens.map(({
|
|
511
|
+
generation,
|
|
512
|
+
activeGeneration
|
|
513
|
+
}) => [generation, activeGeneration])).toEqual([[1, 1], [2, 2], [3, 3]]);
|
|
514
|
+
expect(zeroLogs.some(({
|
|
515
|
+
args
|
|
516
|
+
}) => args.some(arg => String(arg).includes("connect start time is undefined")))).toBe(false);
|
|
517
|
+
});
|
|
518
|
+
test("a replacement socket supersedes stale open and connected events for the same client", async () => {
|
|
519
|
+
vi.useFakeTimers();
|
|
520
|
+
const lifecycle = [];
|
|
521
|
+
const transport = installHttpPullTransport({
|
|
522
|
+
origin: ORIGIN,
|
|
523
|
+
fetch: vi.fn(async () => jsonResponse({
|
|
524
|
+
cookie: null,
|
|
525
|
+
unchanged: true
|
|
526
|
+
})),
|
|
527
|
+
lifecycle: event => lifecycle.push(event)
|
|
528
|
+
});
|
|
529
|
+
transports.push(transport);
|
|
530
|
+
let connectStart = Date.now();
|
|
531
|
+
const errors = [];
|
|
532
|
+
const attachStockLifecycle = socket => {
|
|
533
|
+
socket.addEventListener("open", () => {
|
|
534
|
+
if (connectStart === void 0) {
|
|
535
|
+
errors.push("Got open event but connect start time is undefined.");
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
socket.addEventListener("message", event => {
|
|
539
|
+
const message = JSON.parse(String(event.data));
|
|
540
|
+
if (message[0] === "connected") connectStart = void 0;
|
|
541
|
+
});
|
|
542
|
+
};
|
|
543
|
+
const stale = openRawSocketWithMessages({
|
|
544
|
+
wsid: "stale"
|
|
545
|
+
}).socket;
|
|
546
|
+
attachStockLifecycle(stale);
|
|
547
|
+
const current = openRawSocketWithMessages({
|
|
548
|
+
wsid: "current"
|
|
549
|
+
}).socket;
|
|
550
|
+
attachStockLifecycle(current);
|
|
551
|
+
await vi.advanceTimersByTimeAsync(1);
|
|
552
|
+
expect(lifecycle.filter(event => event.type === "open").map(({
|
|
553
|
+
generation,
|
|
554
|
+
activeGeneration,
|
|
555
|
+
wsid
|
|
556
|
+
}) => [generation, activeGeneration, wsid])).toEqual([[2, 2, "current"]]);
|
|
557
|
+
expect(lifecycle).toContainEqual(expect.objectContaining({
|
|
558
|
+
type: "superseded",
|
|
559
|
+
generation: 1,
|
|
560
|
+
wsid: "stale"
|
|
561
|
+
}));
|
|
562
|
+
expect(errors).toEqual([]);
|
|
453
563
|
});
|
|
454
564
|
test("non-origin WebSockets pass through to the native implementation", () => {
|
|
455
565
|
const previous = globalThis.WebSocket;
|
|
@@ -565,7 +675,9 @@ function createZero(options = {}) {
|
|
|
565
675
|
storageKey: `zero-http-test-${++storageID}`,
|
|
566
676
|
mutators: zeroHttpFixtureMutators,
|
|
567
677
|
pingTimeoutMs: options.pingTimeoutMs,
|
|
568
|
-
onClientStateNotFound: options.onClientStateNotFound
|
|
678
|
+
onClientStateNotFound: options.onClientStateNotFound,
|
|
679
|
+
logLevel: options.logSink ? "debug" : void 0,
|
|
680
|
+
logSink: options.logSink
|
|
569
681
|
});
|
|
570
682
|
zeros.push(zero);
|
|
571
683
|
return zero;
|
|
@@ -630,7 +742,7 @@ function openRawSocketWithMessages(opts) {
|
|
|
630
742
|
url.searchParams.set("userID", "u1");
|
|
631
743
|
url.searchParams.set("baseCookie", "");
|
|
632
744
|
url.searchParams.set("lmid", "0");
|
|
633
|
-
url.searchParams.set("wsid", "ws-test");
|
|
745
|
+
url.searchParams.set("wsid", opts?.wsid ?? "ws-test");
|
|
634
746
|
const messages = [];
|
|
635
747
|
const socket = new WebSocket(url, encodeSecProtocol(["initConnection", {
|
|
636
748
|
desiredQueriesPatch: opts?.desiredQueriesPatch ?? []
|