coaction 1.2.0 → 1.3.0
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/index.js +63 -14
- package/dist/index.mjs +63 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -81,18 +81,23 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
81
81
|
}
|
|
82
82
|
asyncClientStore.transport = transport;
|
|
83
83
|
let syncingPromise = null;
|
|
84
|
-
|
|
84
|
+
let awaitingReconnectSync = false;
|
|
85
|
+
let reconnectSequenceBaseline = null;
|
|
86
|
+
const fullSync = async (allowLowerSequence = false) => {
|
|
85
87
|
if (!syncingPromise) {
|
|
86
88
|
syncingPromise = (async () => {
|
|
87
89
|
const latest = await transport.emit("fullSync");
|
|
88
90
|
if (typeof latest.sequence !== "number" || typeof latest.state !== "string") {
|
|
89
91
|
throw new Error("Invalid fullSync payload");
|
|
90
92
|
}
|
|
91
|
-
|
|
93
|
+
const canApplyLowerSequence = allowLowerSequence && awaitingReconnectSync && reconnectSequenceBaseline !== null && reconnectSequenceBaseline === internal.sequence;
|
|
94
|
+
if (latest.sequence < internal.sequence && !canApplyLowerSequence) {
|
|
92
95
|
return;
|
|
93
96
|
}
|
|
94
97
|
asyncClientStore.apply(JSON.parse(latest.state));
|
|
95
98
|
internal.sequence = latest.sequence;
|
|
99
|
+
awaitingReconnectSync = false;
|
|
100
|
+
reconnectSequenceBaseline = null;
|
|
96
101
|
})().finally(() => {
|
|
97
102
|
syncingPromise = null;
|
|
98
103
|
});
|
|
@@ -103,28 +108,55 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
103
108
|
throw new Error("transport.onConnect is required");
|
|
104
109
|
}
|
|
105
110
|
transport.onConnect?.(() => {
|
|
106
|
-
|
|
111
|
+
awaitingReconnectSync = true;
|
|
112
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
113
|
+
void fullSync(true).catch((error) => {
|
|
107
114
|
if (process.env.NODE_ENV === "development") {
|
|
108
115
|
console.error(error);
|
|
109
116
|
}
|
|
110
117
|
});
|
|
111
118
|
});
|
|
112
119
|
transport.listen("update", async (options) => {
|
|
120
|
+
let shouldFullSync = false;
|
|
121
|
+
let allowLowerSequence = false;
|
|
113
122
|
try {
|
|
114
123
|
if (typeof options.sequence !== "number") {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
shouldFullSync = true;
|
|
125
|
+
} else if (options.sequence <= internal.sequence) {
|
|
126
|
+
if (awaitingReconnectSync) {
|
|
127
|
+
shouldFullSync = true;
|
|
128
|
+
allowLowerSequence = true;
|
|
129
|
+
} else if (options.sequence === 0 && internal.sequence > 0) {
|
|
130
|
+
awaitingReconnectSync = true;
|
|
131
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
132
|
+
shouldFullSync = true;
|
|
133
|
+
allowLowerSequence = true;
|
|
134
|
+
} else {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
} else if (options.sequence === internal.sequence + 1) {
|
|
123
138
|
asyncClientStore.apply(void 0, options.patches);
|
|
139
|
+
internal.sequence = options.sequence;
|
|
140
|
+
awaitingReconnectSync = false;
|
|
141
|
+
reconnectSequenceBaseline = null;
|
|
142
|
+
return;
|
|
124
143
|
} else {
|
|
125
|
-
|
|
144
|
+
shouldFullSync = true;
|
|
145
|
+
allowLowerSequence = awaitingReconnectSync;
|
|
146
|
+
}
|
|
147
|
+
if (shouldFullSync) {
|
|
148
|
+
await fullSync(allowLowerSequence);
|
|
126
149
|
}
|
|
127
150
|
} catch (error) {
|
|
151
|
+
if (!shouldFullSync) {
|
|
152
|
+
try {
|
|
153
|
+
await fullSync(awaitingReconnectSync);
|
|
154
|
+
} catch (syncError) {
|
|
155
|
+
if (process.env.NODE_ENV === "development") {
|
|
156
|
+
console.error(syncError);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
128
160
|
if (process.env.NODE_ENV === "development") {
|
|
129
161
|
console.error(error);
|
|
130
162
|
}
|
|
@@ -225,6 +257,15 @@ var isEqual = (x, y) => {
|
|
|
225
257
|
}
|
|
226
258
|
return x !== x && y !== y;
|
|
227
259
|
};
|
|
260
|
+
var isUnsafeKey = (key) => key === "__proto__" || key === "prototype" || key === "constructor";
|
|
261
|
+
var assignOwnEnumerable = (target, source) => {
|
|
262
|
+
for (const key of Object.keys(source)) {
|
|
263
|
+
if (isUnsafeKey(key)) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
target[key] = source[key];
|
|
267
|
+
}
|
|
268
|
+
};
|
|
228
269
|
var areShallowEqualWithArray = (prev, next) => {
|
|
229
270
|
if (prev === null || next === null || prev.length !== next.length) {
|
|
230
271
|
return false;
|
|
@@ -241,18 +282,26 @@ var mergeObject = (target, source, isSlice) => {
|
|
|
241
282
|
if (isSlice) {
|
|
242
283
|
if (typeof source === "object" && source !== null) {
|
|
243
284
|
for (const key of Object.keys(source)) {
|
|
285
|
+
if (isUnsafeKey(key)) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
244
291
|
const sourceValue = source[key];
|
|
245
292
|
if (typeof sourceValue !== "object" || sourceValue === null) {
|
|
246
293
|
continue;
|
|
247
294
|
}
|
|
248
295
|
const targetValue = target[key];
|
|
249
296
|
if (typeof targetValue === "object" && targetValue !== null) {
|
|
250
|
-
|
|
297
|
+
assignOwnEnumerable(targetValue, sourceValue);
|
|
251
298
|
}
|
|
252
299
|
}
|
|
253
300
|
}
|
|
254
301
|
} else {
|
|
255
|
-
|
|
302
|
+
if (typeof source === "object" && source !== null) {
|
|
303
|
+
assignOwnEnumerable(target, source);
|
|
304
|
+
}
|
|
256
305
|
}
|
|
257
306
|
};
|
|
258
307
|
var uuid = () => {
|
package/dist/index.mjs
CHANGED
|
@@ -53,18 +53,23 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
53
53
|
}
|
|
54
54
|
asyncClientStore.transport = transport;
|
|
55
55
|
let syncingPromise = null;
|
|
56
|
-
|
|
56
|
+
let awaitingReconnectSync = false;
|
|
57
|
+
let reconnectSequenceBaseline = null;
|
|
58
|
+
const fullSync = async (allowLowerSequence = false) => {
|
|
57
59
|
if (!syncingPromise) {
|
|
58
60
|
syncingPromise = (async () => {
|
|
59
61
|
const latest = await transport.emit("fullSync");
|
|
60
62
|
if (typeof latest.sequence !== "number" || typeof latest.state !== "string") {
|
|
61
63
|
throw new Error("Invalid fullSync payload");
|
|
62
64
|
}
|
|
63
|
-
|
|
65
|
+
const canApplyLowerSequence = allowLowerSequence && awaitingReconnectSync && reconnectSequenceBaseline !== null && reconnectSequenceBaseline === internal.sequence;
|
|
66
|
+
if (latest.sequence < internal.sequence && !canApplyLowerSequence) {
|
|
64
67
|
return;
|
|
65
68
|
}
|
|
66
69
|
asyncClientStore.apply(JSON.parse(latest.state));
|
|
67
70
|
internal.sequence = latest.sequence;
|
|
71
|
+
awaitingReconnectSync = false;
|
|
72
|
+
reconnectSequenceBaseline = null;
|
|
68
73
|
})().finally(() => {
|
|
69
74
|
syncingPromise = null;
|
|
70
75
|
});
|
|
@@ -75,28 +80,55 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
75
80
|
throw new Error("transport.onConnect is required");
|
|
76
81
|
}
|
|
77
82
|
transport.onConnect?.(() => {
|
|
78
|
-
|
|
83
|
+
awaitingReconnectSync = true;
|
|
84
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
85
|
+
void fullSync(true).catch((error) => {
|
|
79
86
|
if (process.env.NODE_ENV === "development") {
|
|
80
87
|
console.error(error);
|
|
81
88
|
}
|
|
82
89
|
});
|
|
83
90
|
});
|
|
84
91
|
transport.listen("update", async (options) => {
|
|
92
|
+
let shouldFullSync = false;
|
|
93
|
+
let allowLowerSequence = false;
|
|
85
94
|
try {
|
|
86
95
|
if (typeof options.sequence !== "number") {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
shouldFullSync = true;
|
|
97
|
+
} else if (options.sequence <= internal.sequence) {
|
|
98
|
+
if (awaitingReconnectSync) {
|
|
99
|
+
shouldFullSync = true;
|
|
100
|
+
allowLowerSequence = true;
|
|
101
|
+
} else if (options.sequence === 0 && internal.sequence > 0) {
|
|
102
|
+
awaitingReconnectSync = true;
|
|
103
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
104
|
+
shouldFullSync = true;
|
|
105
|
+
allowLowerSequence = true;
|
|
106
|
+
} else {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
} else if (options.sequence === internal.sequence + 1) {
|
|
95
110
|
asyncClientStore.apply(void 0, options.patches);
|
|
111
|
+
internal.sequence = options.sequence;
|
|
112
|
+
awaitingReconnectSync = false;
|
|
113
|
+
reconnectSequenceBaseline = null;
|
|
114
|
+
return;
|
|
96
115
|
} else {
|
|
97
|
-
|
|
116
|
+
shouldFullSync = true;
|
|
117
|
+
allowLowerSequence = awaitingReconnectSync;
|
|
118
|
+
}
|
|
119
|
+
if (shouldFullSync) {
|
|
120
|
+
await fullSync(allowLowerSequence);
|
|
98
121
|
}
|
|
99
122
|
} catch (error) {
|
|
123
|
+
if (!shouldFullSync) {
|
|
124
|
+
try {
|
|
125
|
+
await fullSync(awaitingReconnectSync);
|
|
126
|
+
} catch (syncError) {
|
|
127
|
+
if (process.env.NODE_ENV === "development") {
|
|
128
|
+
console.error(syncError);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
100
132
|
if (process.env.NODE_ENV === "development") {
|
|
101
133
|
console.error(error);
|
|
102
134
|
}
|
|
@@ -200,6 +232,15 @@ var isEqual = (x, y) => {
|
|
|
200
232
|
}
|
|
201
233
|
return x !== x && y !== y;
|
|
202
234
|
};
|
|
235
|
+
var isUnsafeKey = (key) => key === "__proto__" || key === "prototype" || key === "constructor";
|
|
236
|
+
var assignOwnEnumerable = (target, source) => {
|
|
237
|
+
for (const key of Object.keys(source)) {
|
|
238
|
+
if (isUnsafeKey(key)) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
target[key] = source[key];
|
|
242
|
+
}
|
|
243
|
+
};
|
|
203
244
|
var areShallowEqualWithArray = (prev, next) => {
|
|
204
245
|
if (prev === null || next === null || prev.length !== next.length) {
|
|
205
246
|
return false;
|
|
@@ -216,18 +257,26 @@ var mergeObject = (target, source, isSlice) => {
|
|
|
216
257
|
if (isSlice) {
|
|
217
258
|
if (typeof source === "object" && source !== null) {
|
|
218
259
|
for (const key of Object.keys(source)) {
|
|
260
|
+
if (isUnsafeKey(key)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
219
266
|
const sourceValue = source[key];
|
|
220
267
|
if (typeof sourceValue !== "object" || sourceValue === null) {
|
|
221
268
|
continue;
|
|
222
269
|
}
|
|
223
270
|
const targetValue = target[key];
|
|
224
271
|
if (typeof targetValue === "object" && targetValue !== null) {
|
|
225
|
-
|
|
272
|
+
assignOwnEnumerable(targetValue, sourceValue);
|
|
226
273
|
}
|
|
227
274
|
}
|
|
228
275
|
}
|
|
229
276
|
} else {
|
|
230
|
-
|
|
277
|
+
if (typeof source === "object" && source !== null) {
|
|
278
|
+
assignOwnEnumerable(target, source);
|
|
279
|
+
}
|
|
231
280
|
}
|
|
232
281
|
};
|
|
233
282
|
var uuid = () => {
|