coaction 1.1.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 +158 -25
- package/dist/index.mjs +158 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -80,23 +80,86 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
80
80
|
throw new Error("transport is required");
|
|
81
81
|
}
|
|
82
82
|
asyncClientStore.transport = transport;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
let syncingPromise = null;
|
|
84
|
+
let awaitingReconnectSync = false;
|
|
85
|
+
let reconnectSequenceBaseline = null;
|
|
86
|
+
const fullSync = async (allowLowerSequence = false) => {
|
|
87
|
+
if (!syncingPromise) {
|
|
88
|
+
syncingPromise = (async () => {
|
|
89
|
+
const latest = await transport.emit("fullSync");
|
|
90
|
+
if (typeof latest.sequence !== "number" || typeof latest.state !== "string") {
|
|
91
|
+
throw new Error("Invalid fullSync payload");
|
|
92
|
+
}
|
|
93
|
+
const canApplyLowerSequence = allowLowerSequence && awaitingReconnectSync && reconnectSequenceBaseline !== null && reconnectSequenceBaseline === internal.sequence;
|
|
94
|
+
if (latest.sequence < internal.sequence && !canApplyLowerSequence) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
asyncClientStore.apply(JSON.parse(latest.state));
|
|
98
|
+
internal.sequence = latest.sequence;
|
|
99
|
+
awaitingReconnectSync = false;
|
|
100
|
+
reconnectSequenceBaseline = null;
|
|
101
|
+
})().finally(() => {
|
|
102
|
+
syncingPromise = null;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return syncingPromise;
|
|
87
106
|
};
|
|
88
107
|
if (typeof transport.onConnect !== "function") {
|
|
89
108
|
throw new Error("transport.onConnect is required");
|
|
90
109
|
}
|
|
91
|
-
transport.onConnect?.(
|
|
92
|
-
|
|
110
|
+
transport.onConnect?.(() => {
|
|
111
|
+
awaitingReconnectSync = true;
|
|
112
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
113
|
+
void fullSync(true).catch((error) => {
|
|
114
|
+
if (process.env.NODE_ENV === "development") {
|
|
115
|
+
console.error(error);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
93
118
|
});
|
|
94
119
|
transport.listen("update", async (options) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
120
|
+
let shouldFullSync = false;
|
|
121
|
+
let allowLowerSequence = false;
|
|
122
|
+
try {
|
|
123
|
+
if (typeof options.sequence !== "number") {
|
|
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) {
|
|
138
|
+
asyncClientStore.apply(void 0, options.patches);
|
|
139
|
+
internal.sequence = options.sequence;
|
|
140
|
+
awaitingReconnectSync = false;
|
|
141
|
+
reconnectSequenceBaseline = null;
|
|
142
|
+
return;
|
|
143
|
+
} else {
|
|
144
|
+
shouldFullSync = true;
|
|
145
|
+
allowLowerSequence = awaitingReconnectSync;
|
|
146
|
+
}
|
|
147
|
+
if (shouldFullSync) {
|
|
148
|
+
await fullSync(allowLowerSequence);
|
|
149
|
+
}
|
|
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
|
+
}
|
|
160
|
+
if (process.env.NODE_ENV === "development") {
|
|
161
|
+
console.error(error);
|
|
162
|
+
}
|
|
100
163
|
}
|
|
101
164
|
});
|
|
102
165
|
return wrapStore(asyncClientStore, () => asyncClientStore.getState());
|
|
@@ -131,6 +194,7 @@ var isObject = (value) => typeof value === "object" && value !== null;
|
|
|
131
194
|
var isStateFactory = (value) => typeof value === "function";
|
|
132
195
|
var hasGetState = (value) => (typeof value === "object" || typeof value === "function") && value !== null && typeof value.getState === "function";
|
|
133
196
|
var hasBindState = (value) => isObject(value) && !!value[bindSymbol];
|
|
197
|
+
var formatInvalidStateMessage = (type, stateOrFn, key) => `Invalid state ${type} encountered in makeState: ${key ? `for key ${key}, ` : ""}${typeof stateOrFn}`;
|
|
134
198
|
var getInitialState = (store, createState, internal) => {
|
|
135
199
|
const makeState = (stateOrFn, key) => {
|
|
136
200
|
let state;
|
|
@@ -140,9 +204,7 @@ var getInitialState = (store, createState, internal) => {
|
|
|
140
204
|
state = stateOrFn;
|
|
141
205
|
} else {
|
|
142
206
|
if (process.env.NODE_ENV !== "production") {
|
|
143
|
-
throw new Error(
|
|
144
|
-
`Invalid state value encountered in makeState: ${key ? `for key ${key}, ` : ""}${typeof stateOrFn}`
|
|
145
|
-
);
|
|
207
|
+
throw new Error(formatInvalidStateMessage("value", stateOrFn, key));
|
|
146
208
|
}
|
|
147
209
|
return {};
|
|
148
210
|
}
|
|
@@ -169,6 +231,12 @@ var getInitialState = (store, createState, internal) => {
|
|
|
169
231
|
delete state[bindSymbol];
|
|
170
232
|
return rawState;
|
|
171
233
|
}
|
|
234
|
+
if (!isObject(state)) {
|
|
235
|
+
if (process.env.NODE_ENV !== "production") {
|
|
236
|
+
throw new Error(formatInvalidStateMessage("result", state, key));
|
|
237
|
+
}
|
|
238
|
+
return {};
|
|
239
|
+
}
|
|
172
240
|
return state;
|
|
173
241
|
};
|
|
174
242
|
return store.isSliceStore ? Object.entries(createState).reduce(
|
|
@@ -189,6 +257,15 @@ var isEqual = (x, y) => {
|
|
|
189
257
|
}
|
|
190
258
|
return x !== x && y !== y;
|
|
191
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
|
+
};
|
|
192
269
|
var areShallowEqualWithArray = (prev, next) => {
|
|
193
270
|
if (prev === null || next === null || prev.length !== next.length) {
|
|
194
271
|
return false;
|
|
@@ -204,14 +281,27 @@ var areShallowEqualWithArray = (prev, next) => {
|
|
|
204
281
|
var mergeObject = (target, source, isSlice) => {
|
|
205
282
|
if (isSlice) {
|
|
206
283
|
if (typeof source === "object" && source !== null) {
|
|
207
|
-
for (const key
|
|
208
|
-
if (
|
|
209
|
-
|
|
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
|
+
}
|
|
291
|
+
const sourceValue = source[key];
|
|
292
|
+
if (typeof sourceValue !== "object" || sourceValue === null) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const targetValue = target[key];
|
|
296
|
+
if (typeof targetValue === "object" && targetValue !== null) {
|
|
297
|
+
assignOwnEnumerable(targetValue, sourceValue);
|
|
210
298
|
}
|
|
211
299
|
}
|
|
212
300
|
}
|
|
213
301
|
} else {
|
|
214
|
-
|
|
302
|
+
if (typeof source === "object" && source !== null) {
|
|
303
|
+
assignOwnEnumerable(target, source);
|
|
304
|
+
}
|
|
215
305
|
}
|
|
216
306
|
};
|
|
217
307
|
var uuid = () => {
|
|
@@ -260,6 +350,20 @@ var createSelectorWithArray = createSelectorCreatorWithArray();
|
|
|
260
350
|
|
|
261
351
|
// src/getRawState.ts
|
|
262
352
|
var clientExecuteSyncTimeoutMs = 1500;
|
|
353
|
+
var transportErrorMarker = "__coactionTransportError__";
|
|
354
|
+
var isTransportErrorEnvelope = (value) => {
|
|
355
|
+
if (typeof value !== "object" || value === null) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
return value[transportErrorMarker] === true && typeof value.message === "string";
|
|
359
|
+
};
|
|
360
|
+
var isLegacyTransportErrorEnvelope = (value) => {
|
|
361
|
+
if (typeof value !== "object" || value === null) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
const candidate = value;
|
|
365
|
+
return typeof candidate.$$Error === "string" && candidate.$$Error.length > 0 && Object.keys(candidate).length === 1;
|
|
366
|
+
};
|
|
263
367
|
var getRawState = (store, internal, initialState, options) => {
|
|
264
368
|
const rawState = {};
|
|
265
369
|
const handle = (_rawState, _initialState, sliceKey) => {
|
|
@@ -338,7 +442,9 @@ var getRawState = (store, internal, initialState, options) => {
|
|
|
338
442
|
};
|
|
339
443
|
}
|
|
340
444
|
const keys = sliceKey ? [sliceKey, key] : [key];
|
|
341
|
-
return store.transport.emit("execute", keys, args).then(async (
|
|
445
|
+
return store.transport.emit("execute", keys, args).then(async (response) => {
|
|
446
|
+
const result = Array.isArray(response) ? response[0] : response;
|
|
447
|
+
const sequence = Array.isArray(response) ? typeof response[1] === "number" ? response[1] : internal.sequence : internal.sequence;
|
|
342
448
|
if (internal.sequence < sequence) {
|
|
343
449
|
if (process.env.NODE_ENV === "development") {
|
|
344
450
|
console.warn(
|
|
@@ -378,16 +484,31 @@ var getRawState = (store, internal, initialState, options) => {
|
|
|
378
484
|
timeoutId = setTimeout(() => {
|
|
379
485
|
void store.transport.emit("fullSync").then((latest) => {
|
|
380
486
|
const next = latest;
|
|
487
|
+
if (typeof next.state !== "string" || typeof next.sequence !== "number") {
|
|
488
|
+
throw new Error("Invalid fullSync payload");
|
|
489
|
+
}
|
|
381
490
|
store.apply(JSON.parse(next.state));
|
|
382
491
|
internal.sequence = next.sequence;
|
|
383
|
-
|
|
492
|
+
if (internal.sequence >= sequence) {
|
|
493
|
+
finishResolve();
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
finishReject(
|
|
497
|
+
new Error(
|
|
498
|
+
`Stale fullSync sequence: expected >= ${sequence}, got ${internal.sequence}`
|
|
499
|
+
)
|
|
500
|
+
);
|
|
384
501
|
}).catch((error) => {
|
|
385
502
|
finishReject(error);
|
|
386
503
|
});
|
|
387
504
|
}, clientExecuteSyncTimeoutMs);
|
|
388
505
|
});
|
|
389
506
|
}
|
|
390
|
-
if (result
|
|
507
|
+
if (isTransportErrorEnvelope(result)) {
|
|
508
|
+
done?.(result);
|
|
509
|
+
throw new Error(result.message);
|
|
510
|
+
}
|
|
511
|
+
if (isLegacyTransportErrorEnvelope(result)) {
|
|
391
512
|
done?.(result);
|
|
392
513
|
throw new Error(result.$$Error);
|
|
393
514
|
}
|
|
@@ -556,7 +677,11 @@ var handleState = (store, internal, options) => {
|
|
|
556
677
|
}
|
|
557
678
|
}
|
|
558
679
|
}
|
|
559
|
-
return [
|
|
680
|
+
return [
|
|
681
|
+
internal.rootState,
|
|
682
|
+
finalPatches.patches,
|
|
683
|
+
finalPatches.inversePatches
|
|
684
|
+
];
|
|
560
685
|
}) => {
|
|
561
686
|
if (store.share === "client") {
|
|
562
687
|
throw new Error(
|
|
@@ -665,6 +790,7 @@ var getErrorMessage = (error) => {
|
|
|
665
790
|
}
|
|
666
791
|
return String(error);
|
|
667
792
|
};
|
|
793
|
+
var transportErrorMarker2 = "__coactionTransportError__";
|
|
668
794
|
var handleMainTransport = (store, internal, storeTransport, workerType, checkEnablePatches) => {
|
|
669
795
|
const transport = storeTransport ?? (workerType === "SharedWorkerInternal" || workerType === "WebWorkerInternal" ? (0, import_data_transport2.createTransport)(workerType, {
|
|
670
796
|
prefix: store.name
|
|
@@ -690,12 +816,19 @@ var handleMainTransport = (store, internal, storeTransport, workerType, checkEna
|
|
|
690
816
|
if (typeof base !== "function") {
|
|
691
817
|
throw new Error("The function is not found");
|
|
692
818
|
}
|
|
693
|
-
|
|
819
|
+
const result = await base(...args);
|
|
820
|
+
return [result, internal.sequence];
|
|
694
821
|
} catch (error) {
|
|
695
822
|
if (process.env.NODE_ENV === "development") {
|
|
696
823
|
console.error(error);
|
|
697
824
|
}
|
|
698
|
-
return [
|
|
825
|
+
return [
|
|
826
|
+
{
|
|
827
|
+
[transportErrorMarker2]: true,
|
|
828
|
+
message: getErrorMessage(error)
|
|
829
|
+
},
|
|
830
|
+
internal.sequence
|
|
831
|
+
];
|
|
699
832
|
}
|
|
700
833
|
});
|
|
701
834
|
transport.listen("fullSync", async () => {
|
|
@@ -727,7 +860,7 @@ var create = (createState, options = {}) => {
|
|
|
727
860
|
listeners: /* @__PURE__ */ new Set()
|
|
728
861
|
};
|
|
729
862
|
const name = options.name ?? defaultName;
|
|
730
|
-
const shouldTrackName =
|
|
863
|
+
const shouldTrackName = share2 === "main" && process.env.NODE_ENV !== "test";
|
|
731
864
|
const releaseStoreName = () => {
|
|
732
865
|
if (shouldTrackName) {
|
|
733
866
|
namespaceMap.delete(name);
|
package/dist/index.mjs
CHANGED
|
@@ -52,23 +52,86 @@ var createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
|
52
52
|
throw new Error("transport is required");
|
|
53
53
|
}
|
|
54
54
|
asyncClientStore.transport = transport;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
let syncingPromise = null;
|
|
56
|
+
let awaitingReconnectSync = false;
|
|
57
|
+
let reconnectSequenceBaseline = null;
|
|
58
|
+
const fullSync = async (allowLowerSequence = false) => {
|
|
59
|
+
if (!syncingPromise) {
|
|
60
|
+
syncingPromise = (async () => {
|
|
61
|
+
const latest = await transport.emit("fullSync");
|
|
62
|
+
if (typeof latest.sequence !== "number" || typeof latest.state !== "string") {
|
|
63
|
+
throw new Error("Invalid fullSync payload");
|
|
64
|
+
}
|
|
65
|
+
const canApplyLowerSequence = allowLowerSequence && awaitingReconnectSync && reconnectSequenceBaseline !== null && reconnectSequenceBaseline === internal.sequence;
|
|
66
|
+
if (latest.sequence < internal.sequence && !canApplyLowerSequence) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
asyncClientStore.apply(JSON.parse(latest.state));
|
|
70
|
+
internal.sequence = latest.sequence;
|
|
71
|
+
awaitingReconnectSync = false;
|
|
72
|
+
reconnectSequenceBaseline = null;
|
|
73
|
+
})().finally(() => {
|
|
74
|
+
syncingPromise = null;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return syncingPromise;
|
|
59
78
|
};
|
|
60
79
|
if (typeof transport.onConnect !== "function") {
|
|
61
80
|
throw new Error("transport.onConnect is required");
|
|
62
81
|
}
|
|
63
|
-
transport.onConnect?.(
|
|
64
|
-
|
|
82
|
+
transport.onConnect?.(() => {
|
|
83
|
+
awaitingReconnectSync = true;
|
|
84
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
85
|
+
void fullSync(true).catch((error) => {
|
|
86
|
+
if (process.env.NODE_ENV === "development") {
|
|
87
|
+
console.error(error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
65
90
|
});
|
|
66
91
|
transport.listen("update", async (options) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
92
|
+
let shouldFullSync = false;
|
|
93
|
+
let allowLowerSequence = false;
|
|
94
|
+
try {
|
|
95
|
+
if (typeof options.sequence !== "number") {
|
|
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) {
|
|
110
|
+
asyncClientStore.apply(void 0, options.patches);
|
|
111
|
+
internal.sequence = options.sequence;
|
|
112
|
+
awaitingReconnectSync = false;
|
|
113
|
+
reconnectSequenceBaseline = null;
|
|
114
|
+
return;
|
|
115
|
+
} else {
|
|
116
|
+
shouldFullSync = true;
|
|
117
|
+
allowLowerSequence = awaitingReconnectSync;
|
|
118
|
+
}
|
|
119
|
+
if (shouldFullSync) {
|
|
120
|
+
await fullSync(allowLowerSequence);
|
|
121
|
+
}
|
|
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
|
+
}
|
|
132
|
+
if (process.env.NODE_ENV === "development") {
|
|
133
|
+
console.error(error);
|
|
134
|
+
}
|
|
72
135
|
}
|
|
73
136
|
});
|
|
74
137
|
return wrapStore(asyncClientStore, () => asyncClientStore.getState());
|
|
@@ -103,6 +166,7 @@ var isObject = (value) => typeof value === "object" && value !== null;
|
|
|
103
166
|
var isStateFactory = (value) => typeof value === "function";
|
|
104
167
|
var hasGetState = (value) => (typeof value === "object" || typeof value === "function") && value !== null && typeof value.getState === "function";
|
|
105
168
|
var hasBindState = (value) => isObject(value) && !!value[bindSymbol];
|
|
169
|
+
var formatInvalidStateMessage = (type, stateOrFn, key) => `Invalid state ${type} encountered in makeState: ${key ? `for key ${key}, ` : ""}${typeof stateOrFn}`;
|
|
106
170
|
var getInitialState = (store, createState, internal) => {
|
|
107
171
|
const makeState = (stateOrFn, key) => {
|
|
108
172
|
let state;
|
|
@@ -112,9 +176,7 @@ var getInitialState = (store, createState, internal) => {
|
|
|
112
176
|
state = stateOrFn;
|
|
113
177
|
} else {
|
|
114
178
|
if (process.env.NODE_ENV !== "production") {
|
|
115
|
-
throw new Error(
|
|
116
|
-
`Invalid state value encountered in makeState: ${key ? `for key ${key}, ` : ""}${typeof stateOrFn}`
|
|
117
|
-
);
|
|
179
|
+
throw new Error(formatInvalidStateMessage("value", stateOrFn, key));
|
|
118
180
|
}
|
|
119
181
|
return {};
|
|
120
182
|
}
|
|
@@ -141,6 +203,12 @@ var getInitialState = (store, createState, internal) => {
|
|
|
141
203
|
delete state[bindSymbol];
|
|
142
204
|
return rawState;
|
|
143
205
|
}
|
|
206
|
+
if (!isObject(state)) {
|
|
207
|
+
if (process.env.NODE_ENV !== "production") {
|
|
208
|
+
throw new Error(formatInvalidStateMessage("result", state, key));
|
|
209
|
+
}
|
|
210
|
+
return {};
|
|
211
|
+
}
|
|
144
212
|
return state;
|
|
145
213
|
};
|
|
146
214
|
return store.isSliceStore ? Object.entries(createState).reduce(
|
|
@@ -164,6 +232,15 @@ var isEqual = (x, y) => {
|
|
|
164
232
|
}
|
|
165
233
|
return x !== x && y !== y;
|
|
166
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
|
+
};
|
|
167
244
|
var areShallowEqualWithArray = (prev, next) => {
|
|
168
245
|
if (prev === null || next === null || prev.length !== next.length) {
|
|
169
246
|
return false;
|
|
@@ -179,14 +256,27 @@ var areShallowEqualWithArray = (prev, next) => {
|
|
|
179
256
|
var mergeObject = (target, source, isSlice) => {
|
|
180
257
|
if (isSlice) {
|
|
181
258
|
if (typeof source === "object" && source !== null) {
|
|
182
|
-
for (const key
|
|
183
|
-
if (
|
|
184
|
-
|
|
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
|
+
}
|
|
266
|
+
const sourceValue = source[key];
|
|
267
|
+
if (typeof sourceValue !== "object" || sourceValue === null) {
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const targetValue = target[key];
|
|
271
|
+
if (typeof targetValue === "object" && targetValue !== null) {
|
|
272
|
+
assignOwnEnumerable(targetValue, sourceValue);
|
|
185
273
|
}
|
|
186
274
|
}
|
|
187
275
|
}
|
|
188
276
|
} else {
|
|
189
|
-
|
|
277
|
+
if (typeof source === "object" && source !== null) {
|
|
278
|
+
assignOwnEnumerable(target, source);
|
|
279
|
+
}
|
|
190
280
|
}
|
|
191
281
|
};
|
|
192
282
|
var uuid = () => {
|
|
@@ -235,6 +325,20 @@ var createSelectorWithArray = createSelectorCreatorWithArray();
|
|
|
235
325
|
|
|
236
326
|
// src/getRawState.ts
|
|
237
327
|
var clientExecuteSyncTimeoutMs = 1500;
|
|
328
|
+
var transportErrorMarker = "__coactionTransportError__";
|
|
329
|
+
var isTransportErrorEnvelope = (value) => {
|
|
330
|
+
if (typeof value !== "object" || value === null) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
return value[transportErrorMarker] === true && typeof value.message === "string";
|
|
334
|
+
};
|
|
335
|
+
var isLegacyTransportErrorEnvelope = (value) => {
|
|
336
|
+
if (typeof value !== "object" || value === null) {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
const candidate = value;
|
|
340
|
+
return typeof candidate.$$Error === "string" && candidate.$$Error.length > 0 && Object.keys(candidate).length === 1;
|
|
341
|
+
};
|
|
238
342
|
var getRawState = (store, internal, initialState, options) => {
|
|
239
343
|
const rawState = {};
|
|
240
344
|
const handle = (_rawState, _initialState, sliceKey) => {
|
|
@@ -313,7 +417,9 @@ var getRawState = (store, internal, initialState, options) => {
|
|
|
313
417
|
};
|
|
314
418
|
}
|
|
315
419
|
const keys = sliceKey ? [sliceKey, key] : [key];
|
|
316
|
-
return store.transport.emit("execute", keys, args).then(async (
|
|
420
|
+
return store.transport.emit("execute", keys, args).then(async (response) => {
|
|
421
|
+
const result = Array.isArray(response) ? response[0] : response;
|
|
422
|
+
const sequence = Array.isArray(response) ? typeof response[1] === "number" ? response[1] : internal.sequence : internal.sequence;
|
|
317
423
|
if (internal.sequence < sequence) {
|
|
318
424
|
if (process.env.NODE_ENV === "development") {
|
|
319
425
|
console.warn(
|
|
@@ -353,16 +459,31 @@ var getRawState = (store, internal, initialState, options) => {
|
|
|
353
459
|
timeoutId = setTimeout(() => {
|
|
354
460
|
void store.transport.emit("fullSync").then((latest) => {
|
|
355
461
|
const next = latest;
|
|
462
|
+
if (typeof next.state !== "string" || typeof next.sequence !== "number") {
|
|
463
|
+
throw new Error("Invalid fullSync payload");
|
|
464
|
+
}
|
|
356
465
|
store.apply(JSON.parse(next.state));
|
|
357
466
|
internal.sequence = next.sequence;
|
|
358
|
-
|
|
467
|
+
if (internal.sequence >= sequence) {
|
|
468
|
+
finishResolve();
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
finishReject(
|
|
472
|
+
new Error(
|
|
473
|
+
`Stale fullSync sequence: expected >= ${sequence}, got ${internal.sequence}`
|
|
474
|
+
)
|
|
475
|
+
);
|
|
359
476
|
}).catch((error) => {
|
|
360
477
|
finishReject(error);
|
|
361
478
|
});
|
|
362
479
|
}, clientExecuteSyncTimeoutMs);
|
|
363
480
|
});
|
|
364
481
|
}
|
|
365
|
-
if (result
|
|
482
|
+
if (isTransportErrorEnvelope(result)) {
|
|
483
|
+
done?.(result);
|
|
484
|
+
throw new Error(result.message);
|
|
485
|
+
}
|
|
486
|
+
if (isLegacyTransportErrorEnvelope(result)) {
|
|
366
487
|
done?.(result);
|
|
367
488
|
throw new Error(result.$$Error);
|
|
368
489
|
}
|
|
@@ -534,7 +655,11 @@ var handleState = (store, internal, options) => {
|
|
|
534
655
|
}
|
|
535
656
|
}
|
|
536
657
|
}
|
|
537
|
-
return [
|
|
658
|
+
return [
|
|
659
|
+
internal.rootState,
|
|
660
|
+
finalPatches.patches,
|
|
661
|
+
finalPatches.inversePatches
|
|
662
|
+
];
|
|
538
663
|
}) => {
|
|
539
664
|
if (store.share === "client") {
|
|
540
665
|
throw new Error(
|
|
@@ -643,6 +768,7 @@ var getErrorMessage = (error) => {
|
|
|
643
768
|
}
|
|
644
769
|
return String(error);
|
|
645
770
|
};
|
|
771
|
+
var transportErrorMarker2 = "__coactionTransportError__";
|
|
646
772
|
var handleMainTransport = (store, internal, storeTransport, workerType, checkEnablePatches) => {
|
|
647
773
|
const transport = storeTransport ?? (workerType === "SharedWorkerInternal" || workerType === "WebWorkerInternal" ? createTransport2(workerType, {
|
|
648
774
|
prefix: store.name
|
|
@@ -668,12 +794,19 @@ var handleMainTransport = (store, internal, storeTransport, workerType, checkEna
|
|
|
668
794
|
if (typeof base !== "function") {
|
|
669
795
|
throw new Error("The function is not found");
|
|
670
796
|
}
|
|
671
|
-
|
|
797
|
+
const result = await base(...args);
|
|
798
|
+
return [result, internal.sequence];
|
|
672
799
|
} catch (error) {
|
|
673
800
|
if (process.env.NODE_ENV === "development") {
|
|
674
801
|
console.error(error);
|
|
675
802
|
}
|
|
676
|
-
return [
|
|
803
|
+
return [
|
|
804
|
+
{
|
|
805
|
+
[transportErrorMarker2]: true,
|
|
806
|
+
message: getErrorMessage(error)
|
|
807
|
+
},
|
|
808
|
+
internal.sequence
|
|
809
|
+
];
|
|
677
810
|
}
|
|
678
811
|
});
|
|
679
812
|
transport.listen("fullSync", async () => {
|
|
@@ -705,7 +838,7 @@ var create = (createState, options = {}) => {
|
|
|
705
838
|
listeners: /* @__PURE__ */ new Set()
|
|
706
839
|
};
|
|
707
840
|
const name = options.name ?? defaultName;
|
|
708
|
-
const shouldTrackName =
|
|
841
|
+
const shouldTrackName = share2 === "main" && process.env.NODE_ENV !== "test";
|
|
709
842
|
const releaseStoreName = () => {
|
|
710
843
|
if (shouldTrackName) {
|
|
711
844
|
namespaceMap.delete(name);
|