coaction 1.5.0 → 2.1.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/README.md +59 -17
- package/dist/index.d.mts +435 -306
- package/dist/index.d.ts +435 -306
- package/dist/index.js +1857 -1180
- package/dist/index.mjs +1748 -1161
- package/package.json +33 -27
package/dist/index.js
CHANGED
|
@@ -1,1188 +1,1865 @@
|
|
|
1
|
-
"
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
3
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
9
|
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let mutative = require("mutative");
|
|
25
|
+
let data_transport = require("data-transport");
|
|
26
|
+
let alien_signals = require("alien-signals");
|
|
27
|
+
let alien_signals_system = require("alien-signals/system");
|
|
28
|
+
alien_signals_system = __toESM(alien_signals_system);
|
|
29
|
+
//#region packages/core/src/global.ts
|
|
30
|
+
const getGlobal = () => {
|
|
31
|
+
let _global;
|
|
32
|
+
if (typeof window !== "undefined") _global = window;
|
|
33
|
+
else if (typeof global !== "undefined") _global = global;
|
|
34
|
+
else if (typeof self !== "undefined") _global = self;
|
|
35
|
+
else _global = {};
|
|
36
|
+
return _global;
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region packages/core/src/constant.ts
|
|
40
|
+
const WorkerType = getGlobal().SharedWorkerGlobalScope ? "SharedWorkerInternal" : globalThis.WorkerGlobalScope ? "WebWorkerInternal" : null;
|
|
41
|
+
const bindSymbol = Symbol("bind");
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region packages/core/src/wrapStore.ts
|
|
44
|
+
/**
|
|
45
|
+
* Convert a store object into Coaction's callable store shape.
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* Framework bindings use this to attach selector-aware readers while
|
|
49
|
+
* preserving the underlying store API on the returned function object. Most
|
|
50
|
+
* applications should call {@link create} instead of using `wrapStore()`
|
|
51
|
+
* directly.
|
|
52
|
+
*/
|
|
53
|
+
const wrapStore = (store, getState = () => store.getState()) => {
|
|
54
|
+
const { name, ..._store } = store;
|
|
55
|
+
return Object.assign({ [name]: (...args) => getState(...args) }[name], _store);
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region packages/core/src/utils.ts
|
|
59
|
+
const isEqual = (x, y) => {
|
|
60
|
+
if (x === y) return x !== 0 || y !== 0 || 1 / x === 1 / y;
|
|
61
|
+
return x !== x && y !== y;
|
|
62
|
+
};
|
|
63
|
+
const isUnsafeKey = (key) => key === "__proto__" || key === "prototype" || key === "constructor";
|
|
64
|
+
const isUnsafePathSegment = (segment) => typeof segment === "string" && isUnsafeKey(segment);
|
|
65
|
+
var UnsafePatchPathError = class extends Error {
|
|
66
|
+
name = "UnsafePatchPathError";
|
|
67
|
+
};
|
|
68
|
+
var StateSchemaError = class extends Error {
|
|
69
|
+
name = "StateSchemaError";
|
|
70
|
+
};
|
|
71
|
+
const isStateSchemaError = (error) => error instanceof StateSchemaError || error instanceof Error && error.name === "StateSchemaError";
|
|
72
|
+
const hasUnsafePatchPath = (path) => {
|
|
73
|
+
return (Array.isArray(path) ? path : typeof path === "string" ? path.split("/").filter(Boolean).map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~")) : []).some(isUnsafePathSegment);
|
|
74
|
+
};
|
|
75
|
+
const formatPatchPath = (path) => Array.isArray(path) ? path.map((segment) => String(segment)).join(".") : String(path);
|
|
76
|
+
const getUnsafePatchPaths = (patches) => patches?.filter((patch) => hasUnsafePatchPath(patch.path)) ?? [];
|
|
77
|
+
const assertSafePatches = (patches, source = "patches") => {
|
|
78
|
+
const unsafePatches = getUnsafePatchPaths(patches);
|
|
79
|
+
if (!unsafePatches.length) return;
|
|
80
|
+
const paths = unsafePatches.map((patch) => `'${formatPatchPath(patch.path)}'`).join(", ");
|
|
81
|
+
throw new UnsafePatchPathError(`Unsafe patch path${unsafePatches.length > 1 ? "s" : ""} ${paths} cannot be applied from ${source}.`);
|
|
82
|
+
};
|
|
83
|
+
const warnDroppedUnsafePatches = (unsafePatches, source) => {
|
|
84
|
+
if (process.env.NODE_ENV !== "development" || !unsafePatches.length) return;
|
|
85
|
+
const paths = unsafePatches.map((patch) => `'${formatPatchPath(patch.path)}'`).join(", ");
|
|
86
|
+
console.warn(`Coaction dropped unsafe patch path${unsafePatches.length > 1 ? "s" : ""} ${paths} from ${source}.`);
|
|
87
|
+
};
|
|
88
|
+
const sanitizePatches = (patches, options = {}) => {
|
|
89
|
+
if (options.warnOnDropped) warnDroppedUnsafePatches(getUnsafePatchPaths(patches), options.source ?? "patches");
|
|
90
|
+
return patches?.filter((patch) => !hasUnsafePatchPath(patch.path)).map((patch) => Object.prototype.hasOwnProperty.call(patch, "value") ? {
|
|
91
|
+
...patch,
|
|
92
|
+
value: sanitizeReplacementState(patch.value)
|
|
93
|
+
} : patch);
|
|
94
|
+
};
|
|
95
|
+
const sanitizeCheckedPatches = (patches, source) => {
|
|
96
|
+
assertSafePatches(patches, source);
|
|
97
|
+
return sanitizePatches(patches) ?? [];
|
|
98
|
+
};
|
|
99
|
+
const createRootReplacementPatches = (currentState, nextState) => {
|
|
100
|
+
const patches = [];
|
|
101
|
+
const inversePatches = [];
|
|
102
|
+
const nextKeys = new Set(getOwnEnumerableKeys(nextState));
|
|
103
|
+
for (const key of getOwnEnumerableKeys(currentState)) {
|
|
104
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
105
|
+
if (nextKeys.has(key)) continue;
|
|
106
|
+
patches.push({
|
|
107
|
+
op: "remove",
|
|
108
|
+
path: [key]
|
|
109
|
+
});
|
|
110
|
+
inversePatches.push({
|
|
111
|
+
op: "add",
|
|
112
|
+
path: [key],
|
|
113
|
+
value: currentState[key]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
for (const key of nextKeys) {
|
|
117
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
118
|
+
if (!Object.prototype.hasOwnProperty.call(currentState, key)) {
|
|
119
|
+
patches.push({
|
|
120
|
+
op: "add",
|
|
121
|
+
path: [key],
|
|
122
|
+
value: nextState[key]
|
|
123
|
+
});
|
|
124
|
+
inversePatches.push({
|
|
125
|
+
op: "remove",
|
|
126
|
+
path: [key]
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (Object.is(currentState[key], nextState[key])) continue;
|
|
131
|
+
patches.push({
|
|
132
|
+
op: "replace",
|
|
133
|
+
path: [key],
|
|
134
|
+
value: nextState[key]
|
|
135
|
+
});
|
|
136
|
+
inversePatches.push({
|
|
137
|
+
op: "replace",
|
|
138
|
+
path: [key],
|
|
139
|
+
value: currentState[key]
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
patches,
|
|
144
|
+
inversePatches
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
const createRootStateFromPatches = (currentState, patches) => {
|
|
148
|
+
const nextState = sanitizeReplacementState(currentState);
|
|
149
|
+
const seen = /* @__PURE__ */ new WeakMap();
|
|
150
|
+
for (const patch of patches) {
|
|
151
|
+
if (!Array.isArray(patch.path) || patch.path.length !== 1 || ![
|
|
152
|
+
"add",
|
|
153
|
+
"remove",
|
|
154
|
+
"replace"
|
|
155
|
+
].includes(patch.op)) return;
|
|
156
|
+
const key = patch.path[0];
|
|
157
|
+
if (patch.op === "remove") {
|
|
158
|
+
delete nextState[key];
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
nextState[key] = sanitizeReplacementState(patch.value, seen);
|
|
162
|
+
}
|
|
163
|
+
return nextState;
|
|
164
|
+
};
|
|
165
|
+
const applyRootReplacementWithPatches = (store, nextState, options = {}) => {
|
|
166
|
+
const { patches, inversePatches } = createRootReplacementPatches(store.getPureState(), nextState);
|
|
167
|
+
const finalPatches = store.patch ? store.patch({
|
|
168
|
+
patches,
|
|
169
|
+
inversePatches
|
|
170
|
+
}) : {
|
|
171
|
+
patches,
|
|
172
|
+
inversePatches
|
|
173
|
+
};
|
|
174
|
+
const safePatches = sanitizeCheckedPatches(finalPatches.patches, "store.patch()");
|
|
175
|
+
const safeInversePatches = sanitizeCheckedPatches(finalPatches.inversePatches, "store.patch() inverse patches");
|
|
176
|
+
if (safePatches.length) {
|
|
177
|
+
const applyExactReplacement = options.applyExactReplacement;
|
|
178
|
+
const exactReplacementState = applyExactReplacement ? createRootStateFromPatches(store.getPureState(), safePatches) : void 0;
|
|
179
|
+
if (applyExactReplacement && exactReplacementState) applyExactReplacement(exactReplacementState);
|
|
180
|
+
else store.apply(store.getPureState(), safePatches);
|
|
181
|
+
}
|
|
182
|
+
return [
|
|
183
|
+
store.getPureState(),
|
|
184
|
+
safePatches,
|
|
185
|
+
safeInversePatches
|
|
186
|
+
];
|
|
187
|
+
};
|
|
188
|
+
const setOwnEnumerable = (target, key, value) => {
|
|
189
|
+
if (typeof key === "string" && isUnsafeKey(key)) return;
|
|
190
|
+
target[key] = value;
|
|
191
|
+
};
|
|
192
|
+
const getOwnEnumerableKeys = (source) => {
|
|
193
|
+
if (typeof source !== "object" || source === null) return [];
|
|
194
|
+
return Reflect.ownKeys(source).filter((key) => Object.prototype.propertyIsEnumerable.call(source, key));
|
|
195
|
+
};
|
|
196
|
+
const getOwnSchemaKeys = (source) => {
|
|
197
|
+
if (typeof source !== "object" || source === null) return [];
|
|
198
|
+
return Reflect.ownKeys(source).filter((key) => !(typeof key === "string" && isUnsafeKey(key)));
|
|
199
|
+
};
|
|
200
|
+
const formatSchemaPath = (path) => path.length ? path.map((key) => String(key)).join(".") : "<root>";
|
|
201
|
+
const assertKnownSchemaKey = (knownKeys, key, path) => {
|
|
202
|
+
if (typeof key === "string" && isUnsafeKey(key)) return;
|
|
203
|
+
if (knownKeys.has(key)) return;
|
|
204
|
+
throw new StateSchemaError(`Unknown state key '${formatSchemaPath([...path, key])}' cannot be added after store initialization. Coaction state schema is fixed.`);
|
|
205
|
+
};
|
|
206
|
+
const assertKnownSliceObject = (key, value) => {
|
|
207
|
+
if (typeof value === "object" && value !== null) return;
|
|
208
|
+
throw new StateSchemaError(`State slice '${String(key)}' must remain an object after store initialization. Coaction slice schema is fixed.`);
|
|
209
|
+
};
|
|
210
|
+
const assertKnownSlicePresent = (source, key) => {
|
|
211
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) return;
|
|
212
|
+
throw new StateSchemaError(`State slice '${String(key)}' cannot be removed after store initialization. Coaction slice schema is fixed.`);
|
|
213
|
+
};
|
|
214
|
+
const createStateSchema = (rootState, isSliceStore) => {
|
|
215
|
+
const rootKeys = new Set(getOwnSchemaKeys(rootState));
|
|
216
|
+
if (!isSliceStore) return { rootKeys };
|
|
217
|
+
const sliceKeys = /* @__PURE__ */ new Map();
|
|
218
|
+
if (typeof rootState === "object" && rootState !== null) {
|
|
219
|
+
const rootRecord = rootState;
|
|
220
|
+
rootKeys.forEach((key) => {
|
|
221
|
+
const slice = rootRecord[key];
|
|
222
|
+
if (typeof slice === "object" && slice !== null) sliceKeys.set(key, new Set(getOwnSchemaKeys(slice)));
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
rootKeys,
|
|
227
|
+
sliceKeys
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
const assertKnownStateShape = (source, rootState, schema, isSliceStore, options = {}) => {
|
|
231
|
+
if (typeof source !== "object" || source === null) return;
|
|
232
|
+
const rootKeys = schema?.rootKeys ?? new Set(getOwnSchemaKeys(rootState));
|
|
233
|
+
const sourceRecord = source;
|
|
234
|
+
const knownSliceEntries = schema?.sliceKeys;
|
|
235
|
+
if (isSliceStore && options.requireSliceRoots && knownSliceEntries) knownSliceEntries.forEach((_, key) => {
|
|
236
|
+
assertKnownSlicePresent(sourceRecord, key);
|
|
237
|
+
});
|
|
238
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
239
|
+
assertKnownSchemaKey(rootKeys, key, []);
|
|
240
|
+
if (!isSliceStore) continue;
|
|
241
|
+
const slice = sourceRecord[key];
|
|
242
|
+
const knownSliceKeys = schema?.sliceKeys?.get(key) ?? (typeof rootState === "object" && rootState !== null && typeof rootState[key] === "object" && rootState[key] !== null ? new Set(getOwnSchemaKeys(rootState[key])) : void 0);
|
|
243
|
+
if (!knownSliceKeys) continue;
|
|
244
|
+
assertKnownSliceObject(key, slice);
|
|
245
|
+
for (const sliceKey of getOwnEnumerableKeys(slice)) assertKnownSchemaKey(knownSliceKeys, sliceKey, [key]);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
const isArrayIndexKey$2 = (key) => {
|
|
249
|
+
if (typeof key !== "string") return false;
|
|
250
|
+
const index = Number(key);
|
|
251
|
+
return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
|
|
252
|
+
};
|
|
253
|
+
const assignOwnEnumerable = (target, source, seen = /* @__PURE__ */ new WeakMap()) => {
|
|
254
|
+
if (!seen.has(source)) seen.set(source, target);
|
|
255
|
+
for (const key of getOwnEnumerableKeys(source)) setOwnEnumerable(target, key, sanitizeReplacementState(source[key], seen));
|
|
256
|
+
};
|
|
257
|
+
const replaceOwnEnumerable = (target, source) => {
|
|
258
|
+
const seen = /* @__PURE__ */ new WeakMap();
|
|
259
|
+
seen.set(source, target);
|
|
260
|
+
const nextKeys = /* @__PURE__ */ new Set();
|
|
261
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
262
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
263
|
+
if (typeof source[key] === "function") continue;
|
|
264
|
+
nextKeys.add(key);
|
|
265
|
+
}
|
|
266
|
+
for (const key of getOwnEnumerableKeys(target)) if (!nextKeys.has(key)) delete target[key];
|
|
267
|
+
nextKeys.forEach((key) => {
|
|
268
|
+
setOwnEnumerable(target, key, sanitizeReplacementState(source[key], seen));
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
const cloneOwnEnumerable = (source) => {
|
|
272
|
+
const target = {};
|
|
273
|
+
assignOwnEnumerable(target, source);
|
|
274
|
+
return target;
|
|
275
|
+
};
|
|
276
|
+
const sanitizeReplacementState = (source, seen = /* @__PURE__ */ new WeakMap()) => {
|
|
277
|
+
if (typeof source !== "object" || source === null) return source;
|
|
278
|
+
const cached = seen.get(source);
|
|
279
|
+
if (cached) return cached;
|
|
280
|
+
if (Array.isArray(source)) {
|
|
281
|
+
const target = [];
|
|
282
|
+
target.length = source.length;
|
|
283
|
+
seen.set(source, target);
|
|
284
|
+
for (let index = 0; index < source.length; index += 1) if (Object.prototype.hasOwnProperty.call(source, index)) target[index] = sanitizeReplacementState(source[index], seen);
|
|
285
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
286
|
+
if (isArrayIndexKey$2(key) || typeof key === "string" && isUnsafeKey(key)) continue;
|
|
287
|
+
const value = source[key];
|
|
288
|
+
if (typeof value === "function") continue;
|
|
289
|
+
setOwnEnumerable(target, key, sanitizeReplacementState(value, seen));
|
|
290
|
+
}
|
|
291
|
+
return target;
|
|
292
|
+
}
|
|
293
|
+
const prototype = Object.getPrototypeOf(source);
|
|
294
|
+
if (prototype !== Object.prototype && prototype !== null) return source;
|
|
295
|
+
const target = Object.create(prototype);
|
|
296
|
+
seen.set(source, target);
|
|
297
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
298
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
299
|
+
const value = source[key];
|
|
300
|
+
if (typeof value === "function") continue;
|
|
301
|
+
setOwnEnumerable(target, key, sanitizeReplacementState(value, seen));
|
|
302
|
+
}
|
|
303
|
+
return target;
|
|
304
|
+
};
|
|
305
|
+
const sanitizeInitialStateValue = (source, seen = /* @__PURE__ */ new WeakMap()) => {
|
|
306
|
+
if (typeof source !== "object" || source === null) return source;
|
|
307
|
+
const cached = seen.get(source);
|
|
308
|
+
if (cached) return cached;
|
|
309
|
+
if (Array.isArray(source)) {
|
|
310
|
+
const target = [];
|
|
311
|
+
target.length = source.length;
|
|
312
|
+
seen.set(source, target);
|
|
313
|
+
for (let index = 0; index < source.length; index += 1) if (Object.prototype.hasOwnProperty.call(source, index)) target[index] = sanitizeInitialStateValue(source[index], seen);
|
|
314
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
315
|
+
if (isArrayIndexKey$2(key) || typeof key === "string" && isUnsafeKey(key)) continue;
|
|
316
|
+
setOwnEnumerable(target, key, sanitizeInitialStateValue(source[key], seen));
|
|
317
|
+
}
|
|
318
|
+
return target;
|
|
319
|
+
}
|
|
320
|
+
const prototype = Object.getPrototypeOf(source);
|
|
321
|
+
if (prototype !== Object.prototype && prototype !== null) return source;
|
|
322
|
+
const target = Object.create(prototype);
|
|
323
|
+
seen.set(source, target);
|
|
324
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
325
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
326
|
+
setOwnEnumerable(target, key, sanitizeInitialStateValue(source[key], seen));
|
|
327
|
+
}
|
|
328
|
+
return target;
|
|
329
|
+
};
|
|
330
|
+
const areShallowEqualWithArray = (prev, next) => {
|
|
331
|
+
if (prev === null || next === null || prev.length !== next.length) return false;
|
|
332
|
+
const { length } = prev;
|
|
333
|
+
for (let i = 0; i < length; i += 1) {
|
|
334
|
+
if (Object.prototype.hasOwnProperty.call(prev, i) !== Object.prototype.hasOwnProperty.call(next, i)) return false;
|
|
335
|
+
if (!isEqual(prev[i], next[i])) return false;
|
|
336
|
+
}
|
|
337
|
+
return true;
|
|
338
|
+
};
|
|
339
|
+
const mergeObject = (target, source, isSlice) => {
|
|
340
|
+
if (isSlice) {
|
|
341
|
+
if (typeof source === "object" && source !== null) for (const key of getOwnEnumerableKeys(source)) {
|
|
342
|
+
if (typeof key === "string" && isUnsafeKey(key)) continue;
|
|
343
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) continue;
|
|
344
|
+
const sourceValue = source[key];
|
|
345
|
+
if (typeof sourceValue !== "object" || sourceValue === null) continue;
|
|
346
|
+
const targetValue = target[key];
|
|
347
|
+
if (typeof targetValue === "object" && targetValue !== null) assignOwnEnumerable(targetValue, sourceValue);
|
|
348
|
+
}
|
|
349
|
+
} else if (typeof source === "object" && source !== null) assignOwnEnumerable(target, source);
|
|
350
|
+
};
|
|
351
|
+
const uuid = () => {
|
|
352
|
+
let timestamp = (/* @__PURE__ */ new Date()).getTime();
|
|
353
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
354
|
+
const randomNum = (timestamp + Math.random() * 16) % 16 | 0;
|
|
355
|
+
timestamp = Math.floor(timestamp / 16);
|
|
356
|
+
return (char === "x" ? randomNum : randomNum & 3 | 8).toString(16);
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region packages/core/src/sharedState.ts
|
|
361
|
+
const formatPropertyPath = (path) => path.length ? path.map((key) => String(key)).join(".") : "<root>";
|
|
362
|
+
const isPlainObject = (value) => {
|
|
363
|
+
const prototype = Object.getPrototypeOf(value);
|
|
364
|
+
return prototype === Object.prototype || prototype === null;
|
|
365
|
+
};
|
|
366
|
+
const isArrayIndexKey$1 = (key, length) => {
|
|
367
|
+
if (key === "") return false;
|
|
368
|
+
const index = Number(key);
|
|
369
|
+
return Number.isInteger(index) && index >= 0 && index < length && String(index) === key;
|
|
370
|
+
};
|
|
371
|
+
const findSymbolKeyViolation = (value, path = [], seen = /* @__PURE__ */ new WeakSet()) => {
|
|
372
|
+
if (typeof value !== "object" || value === null) return;
|
|
373
|
+
if (seen.has(value)) return;
|
|
374
|
+
seen.add(value);
|
|
375
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
376
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
377
|
+
const nextPath = [...path, key];
|
|
378
|
+
if (typeof key === "symbol") return {
|
|
379
|
+
type: "symbol-key",
|
|
380
|
+
path: nextPath
|
|
381
|
+
};
|
|
382
|
+
const descriptor = descriptors[key];
|
|
383
|
+
if (descriptor && Object.prototype.hasOwnProperty.call(descriptor, "value")) {
|
|
384
|
+
const violation = findSymbolKeyViolation(descriptor.value, nextPath, seen);
|
|
385
|
+
if (violation) return violation;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
const findJsonViolation = (value, path = [], ancestors = /* @__PURE__ */ new WeakSet()) => {
|
|
390
|
+
switch (typeof value) {
|
|
391
|
+
case "symbol": return {
|
|
392
|
+
type: "symbol-value",
|
|
393
|
+
path
|
|
394
|
+
};
|
|
395
|
+
case "bigint": return {
|
|
396
|
+
type: "bigint",
|
|
397
|
+
path
|
|
398
|
+
};
|
|
399
|
+
case "undefined": return {
|
|
400
|
+
type: "undefined",
|
|
401
|
+
path
|
|
402
|
+
};
|
|
403
|
+
case "function": return {
|
|
404
|
+
type: "function",
|
|
405
|
+
path
|
|
406
|
+
};
|
|
407
|
+
case "number": return Number.isFinite(value) ? void 0 : {
|
|
408
|
+
type: "non-finite-number",
|
|
409
|
+
path
|
|
410
|
+
};
|
|
411
|
+
default: break;
|
|
412
|
+
}
|
|
413
|
+
if (typeof value !== "object" || value === null) return;
|
|
414
|
+
if (ancestors.has(value)) return {
|
|
415
|
+
type: "circular-reference",
|
|
416
|
+
path
|
|
417
|
+
};
|
|
418
|
+
if (Array.isArray(value)) {
|
|
419
|
+
ancestors.add(value);
|
|
420
|
+
for (let index = 0; index < value.length; index += 1) if (!Object.prototype.hasOwnProperty.call(value, index)) return {
|
|
421
|
+
type: "array-hole",
|
|
422
|
+
path: [...path, index]
|
|
423
|
+
};
|
|
424
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
425
|
+
const nextPath = [...path, key];
|
|
426
|
+
if (typeof key === "symbol") return {
|
|
427
|
+
type: "symbol-key",
|
|
428
|
+
path: nextPath
|
|
429
|
+
};
|
|
430
|
+
if (!isArrayIndexKey$1(key, value.length)) return {
|
|
431
|
+
type: "array-property",
|
|
432
|
+
path: nextPath
|
|
433
|
+
};
|
|
434
|
+
const violation = findJsonViolation(value[Number(key)], nextPath, ancestors);
|
|
435
|
+
if (violation) return violation;
|
|
436
|
+
}
|
|
437
|
+
ancestors.delete(value);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (!isPlainObject(value)) return {
|
|
441
|
+
type: "non-plain-object",
|
|
442
|
+
path
|
|
443
|
+
};
|
|
444
|
+
if (typeof value.toJSON === "function") return {
|
|
445
|
+
type: "to-json",
|
|
446
|
+
path
|
|
447
|
+
};
|
|
448
|
+
ancestors.add(value);
|
|
449
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
450
|
+
const nextPath = [...path, key];
|
|
451
|
+
if (typeof key === "symbol") return {
|
|
452
|
+
type: "symbol-key",
|
|
453
|
+
path: nextPath
|
|
454
|
+
};
|
|
455
|
+
const child = value[key];
|
|
456
|
+
const violation = findJsonViolation(child, nextPath, ancestors);
|
|
457
|
+
if (violation) return violation;
|
|
458
|
+
}
|
|
459
|
+
ancestors.delete(value);
|
|
460
|
+
};
|
|
461
|
+
const getViolationLabel = (violation) => {
|
|
462
|
+
switch (violation.type) {
|
|
463
|
+
case "bigint": return "BigInt-valued state";
|
|
464
|
+
case "undefined": return "Undefined-valued state";
|
|
465
|
+
case "function": return "Function-valued state";
|
|
466
|
+
case "non-finite-number": return "NaN or infinite number state";
|
|
467
|
+
case "non-plain-object": return "Non-plain object state";
|
|
468
|
+
case "circular-reference": return "Circular state reference";
|
|
469
|
+
case "array-hole": return "Sparse array state";
|
|
470
|
+
case "array-property": return "Non-index array property state";
|
|
471
|
+
case "to-json": return "Custom toJSON state";
|
|
472
|
+
default: return;
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
const validateSharedActionPaths = (state) => {
|
|
476
|
+
const violation = findSymbolKeyViolation(state);
|
|
477
|
+
if (!violation) return;
|
|
478
|
+
throw new Error(`Symbol-keyed state is not supported in shared store mode because transport synchronization uses JSON and string action paths. Found symbol key at ${formatPropertyPath(violation.path)}.`);
|
|
479
|
+
};
|
|
480
|
+
const validateSharedStateSerializable = (state) => {
|
|
481
|
+
const violation = findJsonViolation(state);
|
|
482
|
+
if (!violation) return;
|
|
483
|
+
if (violation.type === "symbol-key") throw new Error(`Symbol-keyed state is not supported in shared store mode because transport synchronization uses JSON and string action paths. Found symbol key at ${formatPropertyPath(violation.path)}.`);
|
|
484
|
+
if (violation.type === "symbol-value") throw new Error(`Symbol-valued state is not supported in shared store mode because transport synchronization uses JSON. Found symbol value at ${formatPropertyPath(violation.path)}.`);
|
|
485
|
+
throw new Error(`${getViolationLabel(violation)} is not supported in shared store mode because transport synchronization uses JSON. Found unsupported value at ${formatPropertyPath(violation.path)}.`);
|
|
486
|
+
};
|
|
487
|
+
//#endregion
|
|
488
|
+
//#region packages/core/src/asyncClientStore.ts
|
|
489
|
+
const parseFullSyncState$1 = (state) => {
|
|
490
|
+
const parsed = JSON.parse(state);
|
|
491
|
+
if (typeof parsed !== "object" || parsed === null) throw new Error("Invalid fullSync payload");
|
|
492
|
+
return sanitizeReplacementState(parsed);
|
|
493
|
+
};
|
|
494
|
+
const clientApplyErrorMessage = "apply() cannot be called in the client store. Client stores are mirrors; use a store method to update the main store instead.";
|
|
495
|
+
const createAsyncClientStore = (createStore, asyncStoreClientOption) => {
|
|
496
|
+
const { store: asyncClientStore, internal } = createStore({ share: "client" });
|
|
497
|
+
let isApplyingClientState = false;
|
|
498
|
+
const previousAssertMutationAllowed = internal.assertMutationAllowed;
|
|
499
|
+
internal.assertMutationAllowed = (operation) => {
|
|
500
|
+
if (operation === "apply" && !isApplyingClientState) throw new Error(clientApplyErrorMessage);
|
|
501
|
+
previousAssertMutationAllowed?.(operation);
|
|
502
|
+
};
|
|
503
|
+
const baseApply = asyncClientStore.apply.bind(asyncClientStore);
|
|
504
|
+
asyncClientStore.apply = (state, patches) => {
|
|
505
|
+
if (!isApplyingClientState) throw new Error(clientApplyErrorMessage);
|
|
506
|
+
return baseApply(state, patches);
|
|
507
|
+
};
|
|
508
|
+
internal.applyClientState = (...args) => {
|
|
509
|
+
isApplyingClientState = true;
|
|
510
|
+
try {
|
|
511
|
+
baseApply(...args);
|
|
512
|
+
} finally {
|
|
513
|
+
isApplyingClientState = false;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const isSharedWorker = typeof SharedWorker !== "undefined" && asyncStoreClientOption.worker instanceof SharedWorker;
|
|
517
|
+
const transport = asyncStoreClientOption.worker ? (0, data_transport.createTransport)(isSharedWorker ? "SharedWorkerClient" : "WebWorkerClient", {
|
|
518
|
+
worker: asyncStoreClientOption.worker,
|
|
519
|
+
prefix: asyncClientStore.name
|
|
520
|
+
}) : asyncStoreClientOption.clientTransport;
|
|
521
|
+
if (!transport) throw new Error("transport is required");
|
|
522
|
+
asyncClientStore.transport = transport;
|
|
523
|
+
let syncingPromise = null;
|
|
524
|
+
let awaitingReconnectSync = false;
|
|
525
|
+
let reconnectSequenceBaseline = null;
|
|
526
|
+
const fullSync = async (allowLowerSequence = false) => {
|
|
527
|
+
if (!syncingPromise) syncingPromise = (async () => {
|
|
528
|
+
const latest = await transport.emit("fullSync");
|
|
529
|
+
if (typeof latest !== "object" || latest === null || typeof latest.sequence !== "number" || typeof latest.state !== "string") throw new Error("Invalid fullSync payload");
|
|
530
|
+
const canApplyLowerSequence = allowLowerSequence && awaitingReconnectSync && reconnectSequenceBaseline !== null && reconnectSequenceBaseline === internal.sequence;
|
|
531
|
+
if (latest.sequence < internal.sequence && !canApplyLowerSequence) return;
|
|
532
|
+
internal.applyClientState(parseFullSyncState$1(latest.state));
|
|
533
|
+
internal.sequence = latest.sequence;
|
|
534
|
+
awaitingReconnectSync = false;
|
|
535
|
+
reconnectSequenceBaseline = null;
|
|
536
|
+
})().finally(() => {
|
|
537
|
+
syncingPromise = null;
|
|
538
|
+
});
|
|
539
|
+
return syncingPromise;
|
|
540
|
+
};
|
|
541
|
+
if (typeof transport.onConnect !== "function") throw new Error("transport.onConnect is required");
|
|
542
|
+
transport.onConnect?.(() => {
|
|
543
|
+
awaitingReconnectSync = true;
|
|
544
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
545
|
+
fullSync(true).catch((error) => {
|
|
546
|
+
if (process.env.NODE_ENV === "development") console.error(error);
|
|
547
|
+
});
|
|
548
|
+
});
|
|
549
|
+
transport.listen("update", async (options) => {
|
|
550
|
+
let shouldFullSync = false;
|
|
551
|
+
let allowLowerSequence = false;
|
|
552
|
+
try {
|
|
553
|
+
if (typeof options.sequence !== "number") shouldFullSync = true;
|
|
554
|
+
else if (options.sequence <= internal.sequence) if (awaitingReconnectSync) {
|
|
555
|
+
shouldFullSync = true;
|
|
556
|
+
allowLowerSequence = true;
|
|
557
|
+
} else if (options.sequence === 0 && internal.sequence > 0) {
|
|
558
|
+
awaitingReconnectSync = true;
|
|
559
|
+
reconnectSequenceBaseline = internal.sequence;
|
|
560
|
+
shouldFullSync = true;
|
|
561
|
+
allowLowerSequence = true;
|
|
562
|
+
} else return;
|
|
563
|
+
else if (options.sequence === internal.sequence + 1) {
|
|
564
|
+
assertSafePatches(options.patches, "client transport update");
|
|
565
|
+
internal.applyClientState(void 0, options.patches);
|
|
566
|
+
internal.sequence = options.sequence;
|
|
567
|
+
awaitingReconnectSync = false;
|
|
568
|
+
reconnectSequenceBaseline = null;
|
|
569
|
+
return;
|
|
570
|
+
} else {
|
|
571
|
+
shouldFullSync = true;
|
|
572
|
+
allowLowerSequence = awaitingReconnectSync;
|
|
573
|
+
}
|
|
574
|
+
if (shouldFullSync) await fullSync(allowLowerSequence);
|
|
575
|
+
} catch (error) {
|
|
576
|
+
if (!shouldFullSync) try {
|
|
577
|
+
await fullSync(awaitingReconnectSync);
|
|
578
|
+
} catch (syncError) {
|
|
579
|
+
if (process.env.NODE_ENV === "development") console.error(syncError);
|
|
580
|
+
}
|
|
581
|
+
if (process.env.NODE_ENV === "development") console.error(error);
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
return wrapStore(asyncClientStore, () => asyncClientStore.getState());
|
|
585
|
+
};
|
|
586
|
+
const emit = (store, internal, patches) => {
|
|
587
|
+
const safePatches = sanitizePatches(patches, {
|
|
588
|
+
source: "transport emit",
|
|
589
|
+
warnOnDropped: true
|
|
590
|
+
});
|
|
591
|
+
if (store.transport && safePatches?.length) {
|
|
592
|
+
validateSharedStateSerializable(internal.rootState);
|
|
593
|
+
internal.sequence += 1;
|
|
594
|
+
store.transport.emit({
|
|
595
|
+
name: "update",
|
|
596
|
+
respond: false
|
|
597
|
+
}, {
|
|
598
|
+
patches: safePatches,
|
|
599
|
+
sequence: internal.sequence
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
const handleDraft = (store, internal) => {
|
|
604
|
+
internal.rootState = internal.backupState;
|
|
605
|
+
const [nextState, patches, inversePatches] = internal.finalizeDraft();
|
|
606
|
+
if (store.share === "main") validateSharedStateSerializable(nextState);
|
|
607
|
+
const safePatches = sanitizeCheckedPatches((store.patch ? store.patch({
|
|
608
|
+
patches,
|
|
609
|
+
inversePatches
|
|
610
|
+
}) : {
|
|
611
|
+
patches,
|
|
612
|
+
inversePatches
|
|
613
|
+
}).patches, "store.patch()");
|
|
614
|
+
if (safePatches.length) {
|
|
615
|
+
store.apply(internal.rootState, safePatches);
|
|
616
|
+
emit(store, internal, safePatches);
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region packages/core/src/getInitialState.ts
|
|
621
|
+
const isObject = (value) => typeof value === "object" && value !== null;
|
|
622
|
+
const isStateFactory = (value) => typeof value === "function";
|
|
623
|
+
const hasGetState = (value) => (typeof value === "object" || typeof value === "function") && value !== null && typeof value.getState === "function";
|
|
624
|
+
const hasBindState = (value) => isObject(value) && !!value[bindSymbol];
|
|
625
|
+
const formatInvalidStateMessage = (type, stateOrFn, key) => `Invalid state ${type} encountered in makeState: ${typeof key !== "undefined" ? `for key ${String(key)}, ` : ""}${typeof stateOrFn}`;
|
|
626
|
+
const getInitialState = (store, createState, internal) => {
|
|
627
|
+
const makeState = (stateOrFn, key) => {
|
|
628
|
+
let state;
|
|
629
|
+
if (isStateFactory(stateOrFn)) state = stateOrFn(store.setState, store.getState, store);
|
|
630
|
+
else if (isObject(stateOrFn)) state = stateOrFn;
|
|
631
|
+
else {
|
|
632
|
+
if (process.env.NODE_ENV !== "production") throw new Error(formatInvalidStateMessage("value", stateOrFn, key));
|
|
633
|
+
return {};
|
|
634
|
+
}
|
|
635
|
+
if (hasGetState(state)) state = state.getState();
|
|
636
|
+
else if (typeof state === "function") state = state();
|
|
637
|
+
if (hasBindState(state)) {
|
|
638
|
+
if (store.isSliceStore) throw new Error("Third-party state binding does not support Slices mode. Please inject a whole store instead.");
|
|
639
|
+
const binder = state[bindSymbol];
|
|
640
|
+
const rawState = binder.bind(state);
|
|
641
|
+
binder.handleStore(store, rawState, state, internal, key);
|
|
642
|
+
delete state[bindSymbol];
|
|
643
|
+
return rawState;
|
|
644
|
+
}
|
|
645
|
+
if (!isObject(state)) {
|
|
646
|
+
if (process.env.NODE_ENV !== "production") throw new Error(formatInvalidStateMessage("result", state, key));
|
|
647
|
+
return {};
|
|
648
|
+
}
|
|
649
|
+
return state;
|
|
650
|
+
};
|
|
651
|
+
if (!store.isSliceStore) return makeState(createState);
|
|
652
|
+
return getOwnEnumerableKeys(createState).reduce((stateTree, key) => {
|
|
653
|
+
if (typeof key === "string" && isUnsafeKey(key)) return stateTree;
|
|
654
|
+
setOwnEnumerable(stateTree, key, makeState(createState[key], key));
|
|
655
|
+
return stateTree;
|
|
656
|
+
}, {});
|
|
657
|
+
};
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region packages/core/src/getRawStateClientAction.ts
|
|
660
|
+
const transportErrorMarker$1 = "__coactionTransportError__";
|
|
661
|
+
const parseFullSyncState = (state) => {
|
|
662
|
+
const parsed = JSON.parse(state);
|
|
663
|
+
if (typeof parsed !== "object" || parsed === null) throw new Error("Invalid fullSync payload");
|
|
664
|
+
return sanitizeReplacementState(parsed);
|
|
665
|
+
};
|
|
666
|
+
const isTransportErrorEnvelope = (value) => {
|
|
667
|
+
if (typeof value !== "object" || value === null) return false;
|
|
668
|
+
return value[transportErrorMarker$1] === true && typeof value.message === "string";
|
|
669
|
+
};
|
|
670
|
+
const isLegacyTransportErrorEnvelope = (value) => {
|
|
671
|
+
if (typeof value !== "object" || value === null) return false;
|
|
672
|
+
const candidate = value;
|
|
673
|
+
return typeof candidate.$$Error === "string" && candidate.$$Error.length > 0 && Object.keys(candidate).length === 1;
|
|
674
|
+
};
|
|
675
|
+
const createClientAction = ({ clientExecuteSyncTimeoutMs, internal, key, store, sliceKey }) => {
|
|
676
|
+
return (...args) => {
|
|
677
|
+
internal.assertAlive?.(`action ${key}`);
|
|
678
|
+
let actionId;
|
|
679
|
+
let done;
|
|
680
|
+
if (store.trace) {
|
|
681
|
+
actionId = uuid();
|
|
682
|
+
store.trace({
|
|
683
|
+
method: key,
|
|
684
|
+
parameters: args,
|
|
685
|
+
id: actionId,
|
|
686
|
+
sliceKey
|
|
687
|
+
});
|
|
688
|
+
done = (result) => {
|
|
689
|
+
store.trace({
|
|
690
|
+
method: key,
|
|
691
|
+
id: actionId,
|
|
692
|
+
result,
|
|
693
|
+
sliceKey
|
|
694
|
+
});
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
const traceAction = (run) => {
|
|
698
|
+
try {
|
|
699
|
+
const result = run();
|
|
700
|
+
if (result instanceof Promise) return result.then((value) => {
|
|
701
|
+
done?.(value);
|
|
702
|
+
return value;
|
|
703
|
+
}, (error) => {
|
|
704
|
+
done?.(error);
|
|
705
|
+
throw error;
|
|
706
|
+
});
|
|
707
|
+
done?.(result);
|
|
708
|
+
return result;
|
|
709
|
+
} catch (error) {
|
|
710
|
+
done?.(error);
|
|
711
|
+
throw error;
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
if (typeof sliceKey === "symbol") throw new Error("Symbol-keyed slice actions are not supported in client store mode.");
|
|
715
|
+
const keys = typeof sliceKey !== "undefined" ? [String(sliceKey), key] : [key];
|
|
716
|
+
return traceAction(() => store.transport.emit("execute", keys, args).then(async (response) => {
|
|
717
|
+
const result = Array.isArray(response) ? response[0] : response;
|
|
718
|
+
const sequence = Array.isArray(response) ? typeof response[1] === "number" ? response[1] : internal.sequence : internal.sequence;
|
|
719
|
+
if (internal.sequence < sequence) {
|
|
720
|
+
if (process.env.NODE_ENV === "development") console.warn(`The sequence of the action is not consistent.`, sequence, internal.sequence);
|
|
721
|
+
await new Promise((resolve, reject) => {
|
|
722
|
+
let settled = false;
|
|
723
|
+
let unsubscribe = () => {};
|
|
724
|
+
const timeoutRef = {};
|
|
725
|
+
const cleanup = () => {
|
|
726
|
+
unsubscribe();
|
|
727
|
+
if (typeof timeoutRef.current !== "undefined") clearTimeout(timeoutRef.current);
|
|
728
|
+
};
|
|
729
|
+
const finishResolve = () => {
|
|
730
|
+
if (settled) return;
|
|
731
|
+
settled = true;
|
|
732
|
+
cleanup();
|
|
733
|
+
resolve();
|
|
734
|
+
};
|
|
735
|
+
const finishReject = (error) => {
|
|
736
|
+
if (settled) return;
|
|
737
|
+
settled = true;
|
|
738
|
+
cleanup();
|
|
739
|
+
reject(error);
|
|
740
|
+
};
|
|
741
|
+
unsubscribe = store.subscribe(() => {
|
|
742
|
+
if (internal.sequence >= sequence) finishResolve();
|
|
743
|
+
});
|
|
744
|
+
timeoutRef.current = setTimeout(() => {
|
|
745
|
+
store.transport.emit("fullSync").then((latest) => {
|
|
746
|
+
if (typeof latest !== "object" || latest === null) throw new Error("Invalid fullSync payload");
|
|
747
|
+
const next = latest;
|
|
748
|
+
if (typeof next.state !== "string" || typeof next.sequence !== "number") throw new Error("Invalid fullSync payload");
|
|
749
|
+
if (next.sequence >= sequence) {
|
|
750
|
+
(internal.applyClientState ?? store.apply.bind(store))(parseFullSyncState(next.state));
|
|
751
|
+
internal.sequence = next.sequence;
|
|
752
|
+
finishResolve();
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
finishReject(/* @__PURE__ */ new Error(`Stale fullSync sequence: expected >= ${sequence}, got ${next.sequence}`));
|
|
756
|
+
}).catch((error) => {
|
|
757
|
+
finishReject(error);
|
|
758
|
+
});
|
|
759
|
+
}, clientExecuteSyncTimeoutMs);
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
if (isTransportErrorEnvelope(result)) throw new Error(result.message);
|
|
763
|
+
if (isLegacyTransportErrorEnvelope(result)) throw new Error(result.$$Error);
|
|
764
|
+
return result;
|
|
765
|
+
}));
|
|
766
|
+
};
|
|
767
|
+
};
|
|
768
|
+
//#endregion
|
|
769
|
+
//#region packages/core/src/getRawStateLocalAction.ts
|
|
770
|
+
const getActionTarget = (store, sliceKey) => {
|
|
771
|
+
return typeof sliceKey !== "undefined" ? store.getState()[sliceKey] : store.getState();
|
|
772
|
+
};
|
|
773
|
+
const createLocalAction = ({ fn, internal, key, options, store, sliceKey }) => {
|
|
774
|
+
return (...args) => {
|
|
775
|
+
internal.assertAlive?.(`action ${String(key)}`);
|
|
776
|
+
let actionId;
|
|
777
|
+
let done;
|
|
778
|
+
if (store.trace) {
|
|
779
|
+
actionId = uuid();
|
|
780
|
+
store.trace({
|
|
781
|
+
method: String(key),
|
|
782
|
+
parameters: args,
|
|
783
|
+
id: actionId,
|
|
784
|
+
sliceKey
|
|
785
|
+
});
|
|
786
|
+
done = (result) => {
|
|
787
|
+
store.trace({
|
|
788
|
+
method: String(key),
|
|
789
|
+
id: actionId,
|
|
790
|
+
result,
|
|
791
|
+
sliceKey
|
|
792
|
+
});
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
const traceAction = (run) => {
|
|
796
|
+
try {
|
|
797
|
+
const result = run();
|
|
798
|
+
if (result instanceof Promise) return result.then((value) => {
|
|
799
|
+
done?.(value);
|
|
800
|
+
return value;
|
|
801
|
+
}, (error) => {
|
|
802
|
+
done?.(error);
|
|
803
|
+
throw error;
|
|
804
|
+
});
|
|
805
|
+
done?.(result);
|
|
806
|
+
return result;
|
|
807
|
+
} catch (error) {
|
|
808
|
+
done?.(error);
|
|
809
|
+
throw error;
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
const enablePatches = store.transport ?? options.enablePatches;
|
|
813
|
+
return traceAction(() => {
|
|
814
|
+
if (internal.mutableInstance && !internal.isBatching && enablePatches) {
|
|
815
|
+
let result;
|
|
816
|
+
const handleResult = (isDrafted) => {
|
|
817
|
+
handleDraft(store, internal);
|
|
818
|
+
if (isDrafted) {
|
|
819
|
+
internal.backupState = internal.rootState;
|
|
820
|
+
const [draft, finalize] = (0, mutative.create)(internal.rootState, { enablePatches: true });
|
|
821
|
+
internal.finalizeDraft = finalize;
|
|
822
|
+
internal.rootState = draft;
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const isDrafted = (0, mutative.isDraft)(internal.rootState);
|
|
826
|
+
if (isDrafted) handleResult();
|
|
827
|
+
internal.backupState = internal.rootState;
|
|
828
|
+
const [draft, finalize] = (0, mutative.create)(internal.rootState, { enablePatches: true });
|
|
829
|
+
internal.finalizeDraft = finalize;
|
|
830
|
+
internal.rootState = draft;
|
|
831
|
+
let asyncResult;
|
|
832
|
+
try {
|
|
833
|
+
result = fn.apply(getActionTarget(store, sliceKey), args);
|
|
834
|
+
if (result instanceof Promise) asyncResult = result;
|
|
835
|
+
} finally {
|
|
836
|
+
if (!asyncResult) handleResult(isDrafted);
|
|
837
|
+
}
|
|
838
|
+
if (asyncResult) return asyncResult.then((value) => {
|
|
839
|
+
handleResult(isDrafted);
|
|
840
|
+
return value;
|
|
841
|
+
}, (error) => {
|
|
842
|
+
handleResult(isDrafted);
|
|
843
|
+
throw error;
|
|
844
|
+
});
|
|
845
|
+
return result;
|
|
846
|
+
}
|
|
847
|
+
if (internal.mutableInstance && internal.actMutable) return internal.actMutable(() => {
|
|
848
|
+
return fn.apply(getActionTarget(store, sliceKey), args);
|
|
849
|
+
});
|
|
850
|
+
return fn.apply(getActionTarget(store, sliceKey), args);
|
|
851
|
+
});
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
//#endregion
|
|
855
|
+
//#region packages/core/src/computed.ts
|
|
856
|
+
const isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
579
857
|
var Computed = class {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
};
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
858
|
+
deps;
|
|
859
|
+
fn;
|
|
860
|
+
constructor(deps, fn) {
|
|
861
|
+
this.deps = deps;
|
|
862
|
+
this.fn = fn;
|
|
863
|
+
}
|
|
864
|
+
createGetter({ internal }) {
|
|
865
|
+
const memoByReceiver = /* @__PURE__ */ new WeakMap();
|
|
866
|
+
const lastArgs = /* @__PURE__ */ new WeakMap();
|
|
867
|
+
const lastResult = /* @__PURE__ */ new WeakMap();
|
|
868
|
+
const fallbackReceiver = {};
|
|
869
|
+
const evaluate = (receiver) => {
|
|
870
|
+
const args = this.deps(internal.module);
|
|
871
|
+
if (!lastArgs.has(receiver) || !areShallowEqualWithArray(lastArgs.get(receiver), args)) lastResult.set(receiver, this.fn.apply(receiver, args));
|
|
872
|
+
lastArgs.set(receiver, args);
|
|
873
|
+
return lastResult.get(receiver);
|
|
874
|
+
};
|
|
875
|
+
return function() {
|
|
876
|
+
const receiver = typeof this === "object" && this !== null ? this : fallbackReceiver;
|
|
877
|
+
if (internal.isBatching) return evaluate(receiver);
|
|
878
|
+
let accessor = memoByReceiver.get(receiver);
|
|
879
|
+
if (!accessor) {
|
|
880
|
+
accessor = (0, alien_signals.computed)(() => evaluate(receiver));
|
|
881
|
+
memoByReceiver.set(receiver, accessor);
|
|
882
|
+
}
|
|
883
|
+
return accessor();
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
const createCachedGetter = (internal, getter) => {
|
|
888
|
+
const accessors = /* @__PURE__ */ new WeakMap();
|
|
889
|
+
const fallbackReceiver = {};
|
|
890
|
+
return function() {
|
|
891
|
+
const receiver = typeof this === "object" && this !== null ? this : fallbackReceiver;
|
|
892
|
+
if (internal.isBatching) return getter.call(receiver);
|
|
893
|
+
let accessor = accessors.get(receiver);
|
|
894
|
+
if (!accessor) {
|
|
895
|
+
accessor = (0, alien_signals.computed)(() => getter.call(receiver));
|
|
896
|
+
accessors.set(receiver, accessor);
|
|
897
|
+
}
|
|
898
|
+
return accessor();
|
|
899
|
+
};
|
|
900
|
+
};
|
|
901
|
+
const createTrackedStateReader = (internal, read, initialValue) => {
|
|
902
|
+
const slotSignal = (0, alien_signals.signal)(initialValue);
|
|
903
|
+
const slotVersionSignal = (0, alien_signals.signal)(0);
|
|
904
|
+
let slotVersion = 0;
|
|
905
|
+
(internal.signalSlots ??= /* @__PURE__ */ new Set()).add({ refresh: () => {
|
|
906
|
+
const nextValue = read();
|
|
907
|
+
slotSignal(nextValue);
|
|
908
|
+
if (internal.mutableInstance && isObjectLike(nextValue)) {
|
|
909
|
+
slotVersion += 1;
|
|
910
|
+
slotVersionSignal(slotVersion);
|
|
911
|
+
}
|
|
912
|
+
} });
|
|
913
|
+
return () => {
|
|
914
|
+
const currentValue = slotSignal();
|
|
915
|
+
if (internal.mutableInstance && isObjectLike(currentValue)) slotVersionSignal();
|
|
916
|
+
return read();
|
|
917
|
+
};
|
|
918
|
+
};
|
|
919
|
+
const refreshSignalSlots = (internal) => {
|
|
920
|
+
if (!internal.signalSlots?.size) return;
|
|
921
|
+
(0, alien_signals.startBatch)();
|
|
922
|
+
try {
|
|
923
|
+
internal.signalSlots.forEach((slot) => slot.refresh());
|
|
924
|
+
} finally {
|
|
925
|
+
(0, alien_signals.endBatch)();
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region packages/core/src/getRawStateStateProperty.ts
|
|
930
|
+
const assertImmutableStateMutationAllowed = (internal) => {
|
|
931
|
+
if (internal.mutableInstance || internal.isBatching) return;
|
|
932
|
+
throw new Error("Direct state mutation is not allowed in immutable Coaction stores. Wrap mutations in set(() => { ... }).");
|
|
933
|
+
};
|
|
934
|
+
const readonlyProxyCache = /* @__PURE__ */ new WeakMap();
|
|
935
|
+
const isReadonlyProxyable = (value) => {
|
|
936
|
+
if (typeof value !== "object" || value === null) return false;
|
|
937
|
+
if (Array.isArray(value)) return true;
|
|
938
|
+
const prototype = Object.getPrototypeOf(value);
|
|
939
|
+
return prototype === Object.prototype || prototype === null;
|
|
940
|
+
};
|
|
941
|
+
const getReadonlyProxyCache = (internal) => {
|
|
942
|
+
let cache = readonlyProxyCache.get(internal);
|
|
943
|
+
if (!cache) {
|
|
944
|
+
cache = /* @__PURE__ */ new WeakMap();
|
|
945
|
+
readonlyProxyCache.set(internal, cache);
|
|
946
|
+
}
|
|
947
|
+
return cache;
|
|
948
|
+
};
|
|
949
|
+
const getPublicStateObject = (internal, value, sliceKey) => {
|
|
950
|
+
if (value === internal.rootState) return internal.module;
|
|
951
|
+
if (typeof sliceKey === "undefined" || typeof internal.rootState !== "object" || internal.rootState === null || typeof internal.module !== "object" || internal.module === null) return;
|
|
952
|
+
const rootState = internal.rootState;
|
|
953
|
+
const module = internal.module;
|
|
954
|
+
if (rootState[sliceKey] === value) return module[sliceKey];
|
|
955
|
+
};
|
|
956
|
+
const toReadonlyStateValue = (internal, value, sliceKey) => {
|
|
957
|
+
if (internal.mutableInstance || internal.isBatching || !isReadonlyProxyable(value)) return value;
|
|
958
|
+
const publicValue = getPublicStateObject(internal, value, sliceKey);
|
|
959
|
+
if (publicValue) return publicValue;
|
|
960
|
+
const cache = getReadonlyProxyCache(internal);
|
|
961
|
+
const cached = cache.get(value);
|
|
962
|
+
if (cached) return cached;
|
|
963
|
+
const proxy = new Proxy(value, {
|
|
964
|
+
get(target, key, receiver) {
|
|
965
|
+
return toReadonlyStateValue(internal, Reflect.get(target, key, receiver), sliceKey);
|
|
966
|
+
},
|
|
967
|
+
set() {
|
|
968
|
+
assertImmutableStateMutationAllowed(internal);
|
|
969
|
+
return false;
|
|
970
|
+
},
|
|
971
|
+
deleteProperty() {
|
|
972
|
+
assertImmutableStateMutationAllowed(internal);
|
|
973
|
+
return false;
|
|
974
|
+
},
|
|
975
|
+
defineProperty() {
|
|
976
|
+
assertImmutableStateMutationAllowed(internal);
|
|
977
|
+
return false;
|
|
978
|
+
},
|
|
979
|
+
setPrototypeOf() {
|
|
980
|
+
assertImmutableStateMutationAllowed(internal);
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
});
|
|
984
|
+
cache.set(value, proxy);
|
|
985
|
+
return proxy;
|
|
986
|
+
};
|
|
987
|
+
const prepareStateDescriptor = ({ descriptor, initialStateSeen, internal, key, rawState, sliceKey }) => {
|
|
988
|
+
const isComputed = descriptor.value instanceof Computed;
|
|
989
|
+
const readStateValue = () => typeof sliceKey !== "undefined" ? internal.rootState[sliceKey][key] : internal.rootState[key];
|
|
990
|
+
const initialValue = isComputed ? descriptor.value : sanitizeInitialStateValue(descriptor.value, initialStateSeen);
|
|
991
|
+
if (internal.mutableInstance) Object.defineProperty(rawState, key, {
|
|
992
|
+
get: () => internal.mutableInstance[key],
|
|
993
|
+
set: (value) => {
|
|
994
|
+
internal.mutableInstance[key] = value;
|
|
995
|
+
},
|
|
996
|
+
configurable: true,
|
|
997
|
+
enumerable: descriptor.enumerable
|
|
998
|
+
});
|
|
999
|
+
else if (!isComputed) Object.defineProperty(rawState, key, {
|
|
1000
|
+
value: initialValue,
|
|
1001
|
+
configurable: true,
|
|
1002
|
+
enumerable: descriptor.enumerable,
|
|
1003
|
+
writable: true
|
|
1004
|
+
});
|
|
1005
|
+
if (isComputed) {
|
|
1006
|
+
if (internal.mutableInstance) throw new Error("Computed is not supported with mutable instance");
|
|
1007
|
+
descriptor.get = descriptor.value.createGetter({ internal });
|
|
1008
|
+
} else if (typeof sliceKey !== "undefined") {
|
|
1009
|
+
const read = createTrackedStateReader(internal, readStateValue, initialValue);
|
|
1010
|
+
descriptor.get = () => toReadonlyStateValue(internal, read(), sliceKey);
|
|
1011
|
+
descriptor.set = (value) => {
|
|
1012
|
+
assertImmutableStateMutationAllowed(internal);
|
|
1013
|
+
internal.rootState[sliceKey][key] = value;
|
|
1014
|
+
};
|
|
1015
|
+
} else {
|
|
1016
|
+
const read = createTrackedStateReader(internal, readStateValue, initialValue);
|
|
1017
|
+
descriptor.get = () => toReadonlyStateValue(internal, read());
|
|
1018
|
+
descriptor.set = (value) => {
|
|
1019
|
+
assertImmutableStateMutationAllowed(internal);
|
|
1020
|
+
internal.rootState[key] = value;
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
delete descriptor.value;
|
|
1024
|
+
delete descriptor.writable;
|
|
1025
|
+
};
|
|
1026
|
+
const prepareAccessorDescriptor = ({ descriptor, internal }) => {
|
|
1027
|
+
if (internal.mutableInstance || typeof descriptor.get !== "function") return;
|
|
1028
|
+
descriptor.get = createCachedGetter(internal, descriptor.get);
|
|
1029
|
+
};
|
|
1030
|
+
//#endregion
|
|
1031
|
+
//#region packages/core/src/getRawState.ts
|
|
1032
|
+
const defaultClientExecuteSyncTimeoutMs = 1500;
|
|
1033
|
+
const lockPublicStateObject = (state) => {
|
|
1034
|
+
Object.freeze(state);
|
|
1035
|
+
return state;
|
|
1036
|
+
};
|
|
1037
|
+
const getClientExecuteSyncTimeoutMs = (options) => {
|
|
1038
|
+
const timeout = options.executeSyncTimeoutMs;
|
|
1039
|
+
if (typeof timeout === "undefined") return defaultClientExecuteSyncTimeoutMs;
|
|
1040
|
+
if (!Number.isFinite(timeout) || timeout < 0) throw new Error("executeSyncTimeoutMs must be a finite number greater than or equal to 0");
|
|
1041
|
+
return timeout;
|
|
1042
|
+
};
|
|
1043
|
+
const getRawState = (store, internal, initialState, options) => {
|
|
1044
|
+
const clientExecuteSyncTimeoutMs = getClientExecuteSyncTimeoutMs(options);
|
|
1045
|
+
const rawState = {};
|
|
1046
|
+
const handle = (_rawState, _initialState, sliceKey) => {
|
|
1047
|
+
internal.mutableInstance = internal.toMutableRaw?.(_initialState);
|
|
1048
|
+
const initialStateSeen = /* @__PURE__ */ new WeakMap();
|
|
1049
|
+
initialStateSeen.set(_initialState, _rawState);
|
|
1050
|
+
const safeDescriptors = {};
|
|
1051
|
+
const descriptors = Object.getOwnPropertyDescriptors(_initialState);
|
|
1052
|
+
Reflect.ownKeys(descriptors).forEach((key) => {
|
|
1053
|
+
if (typeof key === "string" && isUnsafeKey(key)) return;
|
|
1054
|
+
safeDescriptors[key] = Reflect.get(descriptors, key);
|
|
1055
|
+
});
|
|
1056
|
+
Reflect.ownKeys(safeDescriptors).forEach((key) => {
|
|
1057
|
+
const descriptor = safeDescriptors[key];
|
|
1058
|
+
if (typeof descriptor === "undefined") return;
|
|
1059
|
+
if (!Object.prototype.hasOwnProperty.call(descriptor, "value")) {
|
|
1060
|
+
prepareAccessorDescriptor({
|
|
1061
|
+
descriptor,
|
|
1062
|
+
internal
|
|
1063
|
+
});
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
if (Object.prototype.hasOwnProperty.call(descriptor, "value")) {
|
|
1067
|
+
if (typeof descriptor.value !== "function") {
|
|
1068
|
+
prepareStateDescriptor({
|
|
1069
|
+
descriptor,
|
|
1070
|
+
initialStateSeen,
|
|
1071
|
+
internal,
|
|
1072
|
+
key,
|
|
1073
|
+
rawState: _rawState,
|
|
1074
|
+
sliceKey
|
|
1075
|
+
});
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
if (store.share === "client") {
|
|
1079
|
+
if (typeof key !== "string") return;
|
|
1080
|
+
descriptor.value = createClientAction({
|
|
1081
|
+
clientExecuteSyncTimeoutMs,
|
|
1082
|
+
internal,
|
|
1083
|
+
key,
|
|
1084
|
+
store,
|
|
1085
|
+
sliceKey
|
|
1086
|
+
});
|
|
1087
|
+
} else descriptor.value = createLocalAction({
|
|
1088
|
+
fn: descriptor.value,
|
|
1089
|
+
internal,
|
|
1090
|
+
key,
|
|
1091
|
+
options,
|
|
1092
|
+
store,
|
|
1093
|
+
sliceKey
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
return lockPublicStateObject(Object.defineProperties({}, safeDescriptors));
|
|
1098
|
+
};
|
|
1099
|
+
if (store.isSliceStore) {
|
|
1100
|
+
internal.module = {};
|
|
1101
|
+
getOwnEnumerableKeys(initialState).forEach((key) => {
|
|
1102
|
+
if (typeof key === "string" && isUnsafeKey(key)) return;
|
|
1103
|
+
const sliceRawState = {};
|
|
1104
|
+
setOwnEnumerable(rawState, key, sliceRawState);
|
|
1105
|
+
setOwnEnumerable(internal.module, key, handle(sliceRawState, initialState[key], key));
|
|
1106
|
+
});
|
|
1107
|
+
lockPublicStateObject(internal.module);
|
|
1108
|
+
} else internal.module = handle(rawState, initialState);
|
|
1109
|
+
return rawState;
|
|
1110
|
+
};
|
|
1111
|
+
//#endregion
|
|
1112
|
+
//#region packages/core/src/handleState.ts
|
|
1113
|
+
const handleState = (store, internal, options) => {
|
|
1114
|
+
const defaultUpdater = (next) => {
|
|
1115
|
+
const merge = (_next = next) => {
|
|
1116
|
+
assertKnownStateShape(_next, internal.rootState, internal.stateSchema, store.isSliceStore);
|
|
1117
|
+
mergeObject(internal.rootState, _next, store.isSliceStore);
|
|
1118
|
+
};
|
|
1119
|
+
const fn = typeof next === "function" ? () => {
|
|
1120
|
+
const returnValue = next(internal.module);
|
|
1121
|
+
if (returnValue instanceof Promise) {
|
|
1122
|
+
returnValue.catch(() => void 0);
|
|
1123
|
+
throw new Error("setState with async function is not supported");
|
|
1124
|
+
}
|
|
1125
|
+
if (typeof returnValue === "object" && returnValue !== null) merge(returnValue);
|
|
1126
|
+
} : merge;
|
|
1127
|
+
if (!(store.transport ?? options.enablePatches) && internal.mutableInstance) {
|
|
1128
|
+
if (internal.actMutable) {
|
|
1129
|
+
internal.actMutable(() => {
|
|
1130
|
+
fn.apply(null);
|
|
1131
|
+
});
|
|
1132
|
+
return [];
|
|
1133
|
+
}
|
|
1134
|
+
fn.apply(null);
|
|
1135
|
+
return [];
|
|
1136
|
+
}
|
|
1137
|
+
internal.backupState = internal.rootState;
|
|
1138
|
+
let patches;
|
|
1139
|
+
let inversePatches;
|
|
1140
|
+
try {
|
|
1141
|
+
const result = (0, mutative.create)(internal.rootState, (draft) => {
|
|
1142
|
+
internal.rootState = draft;
|
|
1143
|
+
return fn.apply(null);
|
|
1144
|
+
}, { enablePatches: true });
|
|
1145
|
+
assertKnownStateShape(result[0], internal.backupState, internal.stateSchema, store.isSliceStore, { requireSliceRoots: true });
|
|
1146
|
+
if (store.share === "main") validateSharedStateSerializable(result[0]);
|
|
1147
|
+
patches = result[1];
|
|
1148
|
+
inversePatches = result[2];
|
|
1149
|
+
} finally {
|
|
1150
|
+
internal.rootState = internal.backupState;
|
|
1151
|
+
}
|
|
1152
|
+
const finalPatches = store.patch ? store.patch({
|
|
1153
|
+
patches,
|
|
1154
|
+
inversePatches
|
|
1155
|
+
}) : {
|
|
1156
|
+
patches,
|
|
1157
|
+
inversePatches
|
|
1158
|
+
};
|
|
1159
|
+
const safePatches = sanitizeCheckedPatches(finalPatches.patches, "store.patch()");
|
|
1160
|
+
const safeInversePatches = sanitizeCheckedPatches(finalPatches.inversePatches, "store.patch() inverse patches");
|
|
1161
|
+
if (safePatches.length) store.apply(internal.rootState, safePatches);
|
|
1162
|
+
return [
|
|
1163
|
+
internal.rootState,
|
|
1164
|
+
safePatches,
|
|
1165
|
+
safeInversePatches
|
|
1166
|
+
];
|
|
1167
|
+
};
|
|
1168
|
+
const setState = (next, updater = defaultUpdater) => {
|
|
1169
|
+
internal.assertAlive?.("setState");
|
|
1170
|
+
internal.assertMutationAllowed?.("setState");
|
|
1171
|
+
if (store.share === "client") throw new Error(`setState() cannot be called in the client store. To update the state, please trigger a store method with setState() instead.`);
|
|
1172
|
+
if (internal.isBatching) throw new Error("setState cannot be called within the updater");
|
|
1173
|
+
if (next === null) return [];
|
|
1174
|
+
if (typeof next === "object") assertKnownStateShape(next, internal.rootState, internal.stateSchema, store.isSliceStore);
|
|
1175
|
+
internal.isBatching = true;
|
|
1176
|
+
if (!store.share && !options.enablePatches && !internal.mutableInstance && updater === defaultUpdater) try {
|
|
1177
|
+
if (typeof next === "function") try {
|
|
1178
|
+
internal.backupState = internal.rootState;
|
|
1179
|
+
const nextState = (0, mutative.create)(internal.rootState, (draft) => {
|
|
1180
|
+
internal.rootState = draft;
|
|
1181
|
+
const returnValue = next(internal.module);
|
|
1182
|
+
if (returnValue instanceof Promise) {
|
|
1183
|
+
returnValue.catch(() => void 0);
|
|
1184
|
+
throw new Error("setState with async function is not supported");
|
|
1185
|
+
}
|
|
1186
|
+
if (typeof returnValue === "object" && returnValue !== null) {
|
|
1187
|
+
assertKnownStateShape(returnValue, internal.rootState, internal.stateSchema, store.isSliceStore);
|
|
1188
|
+
mergeObject(internal.rootState, returnValue, store.isSliceStore);
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
assertKnownStateShape(nextState, internal.backupState, internal.stateSchema, store.isSliceStore, { requireSliceRoots: true });
|
|
1192
|
+
internal.rootState = nextState;
|
|
1193
|
+
} catch (error) {
|
|
1194
|
+
internal.rootState = internal.backupState;
|
|
1195
|
+
throw error;
|
|
1196
|
+
}
|
|
1197
|
+
else {
|
|
1198
|
+
const copy = cloneOwnEnumerable(internal.rootState);
|
|
1199
|
+
if (store.isSliceStore) {
|
|
1200
|
+
const nextRecord = next;
|
|
1201
|
+
const copyRecord = copy;
|
|
1202
|
+
for (const key of getOwnEnumerableKeys(nextRecord)) {
|
|
1203
|
+
if (!Object.prototype.hasOwnProperty.call(copyRecord, key)) continue;
|
|
1204
|
+
const sourceValue = nextRecord[key];
|
|
1205
|
+
if (typeof sourceValue !== "object" || sourceValue === null) continue;
|
|
1206
|
+
const targetValue = copyRecord[key];
|
|
1207
|
+
if (typeof targetValue !== "object" || targetValue === null) continue;
|
|
1208
|
+
const sliceCopy = cloneOwnEnumerable(targetValue);
|
|
1209
|
+
mergeObject(sliceCopy, sourceValue);
|
|
1210
|
+
setOwnEnumerable(copyRecord, key, sliceCopy);
|
|
1211
|
+
}
|
|
1212
|
+
} else mergeObject(copy, next);
|
|
1213
|
+
assertKnownStateShape(copy, internal.rootState, internal.stateSchema, store.isSliceStore, { requireSliceRoots: true });
|
|
1214
|
+
internal.rootState = copy;
|
|
1215
|
+
}
|
|
1216
|
+
refreshSignalSlots(internal);
|
|
1217
|
+
if (internal.updateImmutable) internal.updateImmutable(internal.rootState);
|
|
1218
|
+
else internal.listeners.forEach((listener) => listener());
|
|
1219
|
+
return [];
|
|
1220
|
+
} finally {
|
|
1221
|
+
internal.isBatching = false;
|
|
1222
|
+
}
|
|
1223
|
+
let result;
|
|
1224
|
+
try {
|
|
1225
|
+
const isDrafted = internal.mutableInstance && (0, mutative.isDraft)(internal.rootState);
|
|
1226
|
+
if (isDrafted) handleDraft(store, internal);
|
|
1227
|
+
result = updater(next);
|
|
1228
|
+
if (internal.mutableInstance) assertKnownStateShape(internal.rootState, internal.backupState ?? internal.rootState, internal.stateSchema, store.isSliceStore, { requireSliceRoots: true });
|
|
1229
|
+
if (store.share === "main") validateSharedStateSerializable(internal.rootState);
|
|
1230
|
+
if (isDrafted) {
|
|
1231
|
+
internal.backupState = internal.rootState;
|
|
1232
|
+
const [draft, finalize] = (0, mutative.create)(internal.rootState, { enablePatches: true });
|
|
1233
|
+
internal.finalizeDraft = finalize;
|
|
1234
|
+
internal.rootState = draft;
|
|
1235
|
+
}
|
|
1236
|
+
} finally {
|
|
1237
|
+
internal.isBatching = false;
|
|
1238
|
+
}
|
|
1239
|
+
if (result?.length) result = [
|
|
1240
|
+
result[0],
|
|
1241
|
+
sanitizeCheckedPatches(result[1], "setState updater result"),
|
|
1242
|
+
sanitizeCheckedPatches(result[2], "setState updater inverse result")
|
|
1243
|
+
];
|
|
1244
|
+
emit(store, internal, result?.[1]);
|
|
1245
|
+
return result;
|
|
1246
|
+
};
|
|
1247
|
+
const getState = (deps, selector) => deps && selector ? new Computed(deps, selector) : internal.module;
|
|
1248
|
+
return {
|
|
1249
|
+
setState,
|
|
1250
|
+
getState
|
|
1251
|
+
};
|
|
1252
|
+
};
|
|
1253
|
+
//#endregion
|
|
1254
|
+
//#region packages/core/src/applyMiddlewares.ts
|
|
1255
|
+
const isStoreLike = (value) => {
|
|
1256
|
+
if (!value || typeof value !== "object") return false;
|
|
1257
|
+
const candidate = value;
|
|
1258
|
+
return typeof candidate.setState === "function" && typeof candidate.getState === "function" && typeof candidate.subscribe === "function" && typeof candidate.destroy === "function" && typeof candidate.apply === "function" && typeof candidate.getPureState === "function";
|
|
1259
|
+
};
|
|
1260
|
+
const applyMiddlewares = (store, middlewares) => {
|
|
1261
|
+
return middlewares.reduce((store, middleware, index) => {
|
|
1262
|
+
if (process.env.NODE_ENV === "development") {
|
|
1263
|
+
if (typeof middleware !== "function") throw new Error(`middlewares[${index}] should be a function`);
|
|
1264
|
+
}
|
|
1265
|
+
const nextStore = middleware(store);
|
|
1266
|
+
if (process.env.NODE_ENV === "development") {
|
|
1267
|
+
if (!isStoreLike(nextStore)) throw new Error(`middlewares[${index}] should return a store-like object`);
|
|
1268
|
+
}
|
|
1269
|
+
return nextStore;
|
|
1270
|
+
}, store);
|
|
1271
|
+
};
|
|
1272
|
+
//#endregion
|
|
1273
|
+
//#region packages/core/src/handleMainTransport.ts
|
|
1274
|
+
const getErrorMessage = (error) => {
|
|
1275
|
+
if (error instanceof Error) return error.message;
|
|
1276
|
+
return String(error);
|
|
1277
|
+
};
|
|
1278
|
+
const transportErrorMarker = "__coactionTransportError__";
|
|
1279
|
+
const handleMainTransport = (store, internal, storeTransport, workerType, checkEnablePatches) => {
|
|
1280
|
+
const transport = storeTransport ?? (workerType === "SharedWorkerInternal" || workerType === "WebWorkerInternal" ? (0, data_transport.createTransport)(workerType, { prefix: store.name }) : void 0);
|
|
1281
|
+
if (!transport) return;
|
|
1282
|
+
if (typeof transport.onConnect !== "function") throw new Error("transport.onConnect is required");
|
|
1283
|
+
if (checkEnablePatches) throw new Error(`enablePatches: true is required for the transport`);
|
|
1284
|
+
transport.listen("execute", async (keys, args) => {
|
|
1285
|
+
let base = store.getState();
|
|
1286
|
+
try {
|
|
1287
|
+
for (const key of keys) {
|
|
1288
|
+
if (isUnsafePathSegment(key) || typeof base !== "object" && typeof base !== "function" || base === null || !Object.prototype.hasOwnProperty.call(base, key)) throw new Error("The function is not found");
|
|
1289
|
+
const obj = base;
|
|
1290
|
+
base = base[key];
|
|
1291
|
+
if (typeof base === "function") base = base.bind(obj);
|
|
1292
|
+
}
|
|
1293
|
+
if (typeof base !== "function") throw new Error("The function is not found");
|
|
1294
|
+
return [await base(...args), internal.sequence];
|
|
1295
|
+
} catch (error) {
|
|
1296
|
+
if (process.env.NODE_ENV === "development") console.error(error);
|
|
1297
|
+
return [{
|
|
1298
|
+
[transportErrorMarker]: true,
|
|
1299
|
+
message: getErrorMessage(error)
|
|
1300
|
+
}, internal.sequence];
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
transport.listen("fullSync", async () => {
|
|
1304
|
+
validateSharedStateSerializable(internal.rootState);
|
|
1305
|
+
return {
|
|
1306
|
+
state: JSON.stringify(internal.rootState),
|
|
1307
|
+
sequence: internal.sequence
|
|
1308
|
+
};
|
|
1309
|
+
});
|
|
1310
|
+
store.transport = transport;
|
|
1311
|
+
};
|
|
1312
|
+
//#endregion
|
|
1313
|
+
//#region packages/core/src/lifecycle.ts
|
|
1314
|
+
const readyStores = /* @__PURE__ */ new WeakSet();
|
|
1315
|
+
const readyCallbacks = /* @__PURE__ */ new WeakMap();
|
|
1316
|
+
const onStoreReady = (store, callback) => {
|
|
1317
|
+
if (readyStores.has(store)) {
|
|
1318
|
+
callback();
|
|
1319
|
+
return () => void 0;
|
|
1320
|
+
}
|
|
1321
|
+
let callbacks = readyCallbacks.get(store);
|
|
1322
|
+
if (!callbacks) {
|
|
1323
|
+
callbacks = /* @__PURE__ */ new Set();
|
|
1324
|
+
readyCallbacks.set(store, callbacks);
|
|
1325
|
+
}
|
|
1326
|
+
callbacks.add(callback);
|
|
1327
|
+
return () => {
|
|
1328
|
+
callbacks?.delete(callback);
|
|
1329
|
+
};
|
|
1330
|
+
};
|
|
1331
|
+
const markStoreReady = (store) => {
|
|
1332
|
+
readyStores.add(store);
|
|
1333
|
+
const callbacks = readyCallbacks.get(store);
|
|
1334
|
+
if (!callbacks) return;
|
|
1335
|
+
readyCallbacks.delete(store);
|
|
1336
|
+
callbacks.forEach((callback) => callback());
|
|
1337
|
+
callbacks.clear();
|
|
1338
|
+
};
|
|
1339
|
+
//#endregion
|
|
1340
|
+
//#region packages/core/src/create.ts
|
|
1341
|
+
const namespaceMap = /* @__PURE__ */ new Map();
|
|
1342
|
+
let hasWarnedAmbiguousFunctionMap = false;
|
|
1343
|
+
const isMainWorkerType = (workerType) => workerType === "SharedWorkerInternal" || workerType === "WebWorkerInternal";
|
|
1344
|
+
const isClientWorkerType = (workerType) => workerType === "SharedWorkerClient" || workerType === "WebWorkerClient";
|
|
1345
|
+
const validateCreateModeOptions = (options) => {
|
|
1346
|
+
const storeTransport = options.transport;
|
|
1347
|
+
const clientTransport = options.clientTransport;
|
|
1348
|
+
const worker = options.worker;
|
|
1349
|
+
const explicitWorkerType = options.workerType;
|
|
1350
|
+
if (storeTransport && clientTransport) throw new Error("transport and clientTransport cannot be used together, please use one authority model per store.");
|
|
1351
|
+
if (storeTransport && worker) throw new Error("transport and worker cannot be used together, please use one authority model per store.");
|
|
1352
|
+
if (clientTransport && worker) throw new Error("clientTransport and worker cannot be used together, please use one client transport source.");
|
|
1353
|
+
if (isMainWorkerType(explicitWorkerType) && (clientTransport || worker)) throw new Error("main workerType cannot be combined with client transport settings.");
|
|
1354
|
+
if (isClientWorkerType(explicitWorkerType) && storeTransport) throw new Error("client workerType cannot be combined with transport.");
|
|
1355
|
+
};
|
|
1356
|
+
const warnAmbiguousFunctionMap = () => {
|
|
1357
|
+
if (hasWarnedAmbiguousFunctionMap || process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test") return;
|
|
1358
|
+
hasWarnedAmbiguousFunctionMap = true;
|
|
1359
|
+
console.warn([
|
|
1360
|
+
`sliceMode: 'auto' inferred slices from an object of functions.`,
|
|
1361
|
+
`This shape is ambiguous with a single store that only contains methods.`,
|
|
1362
|
+
`Use create({ ping() {} }, { sliceMode: 'single' }) for a plain method store,`,
|
|
1363
|
+
`or create({ counter: (set) => ({ count: 0 }) }, { sliceMode: 'slices' }) for slices.`
|
|
1364
|
+
].join(" "));
|
|
1365
|
+
};
|
|
1366
|
+
/**
|
|
1367
|
+
* Create a local store, the main side of a shared store, or a client mirror of
|
|
1368
|
+
* a shared store.
|
|
1369
|
+
*
|
|
1370
|
+
* @remarks
|
|
1371
|
+
* - Pass a {@link Slice} function for a single store.
|
|
1372
|
+
* - Pass an object of slice factories for a slices store.
|
|
1373
|
+
* - When an object input only contains functions, prefer explicit `sliceMode`
|
|
1374
|
+
* to avoid ambiguous inference.
|
|
1375
|
+
* - When `clientTransport` or `worker` is provided, returned store methods
|
|
1376
|
+
* become promise-returning methods because execution happens on the main
|
|
1377
|
+
* shared store.
|
|
1378
|
+
* - New semantics should prefer explicit helpers or variants over adding more
|
|
1379
|
+
* ambiguous `create()` input forms.
|
|
1380
|
+
*/
|
|
1381
|
+
const create = (createState, options = {}) => {
|
|
1382
|
+
const checkEnablePatches = Object.hasOwnProperty.call(options, "enablePatches") && !options.enablePatches;
|
|
1383
|
+
validateCreateModeOptions(options);
|
|
1384
|
+
const workerType = options.workerType ?? WorkerType;
|
|
1385
|
+
const storeTransport = options.transport;
|
|
1386
|
+
const share = workerType === "WebWorkerInternal" || workerType === "SharedWorkerInternal" || storeTransport ? "main" : void 0;
|
|
1387
|
+
const createStore = ({ share }) => {
|
|
1388
|
+
const store = {};
|
|
1389
|
+
const internal = {
|
|
1390
|
+
sequence: 0,
|
|
1391
|
+
isBatching: false,
|
|
1392
|
+
listeners: /* @__PURE__ */ new Set()
|
|
1393
|
+
};
|
|
1394
|
+
internal.notifyStateChange = () => {
|
|
1395
|
+
refreshSignalSlots(internal);
|
|
1396
|
+
internal.listeners.forEach((listener) => listener());
|
|
1397
|
+
};
|
|
1398
|
+
const name = options.name ?? "default";
|
|
1399
|
+
const shouldTrackName = share === "main" && process.env.NODE_ENV !== "test";
|
|
1400
|
+
const releaseStoreName = () => {
|
|
1401
|
+
if (shouldTrackName) namespaceMap.delete(name);
|
|
1402
|
+
};
|
|
1403
|
+
if (shouldTrackName) {
|
|
1404
|
+
if (namespaceMap.get(name)) throw new Error(`Store name '${name}' is not unique.`);
|
|
1405
|
+
namespaceMap.set(name, true);
|
|
1406
|
+
}
|
|
1407
|
+
try {
|
|
1408
|
+
const { setState, getState } = handleState(store, internal, options);
|
|
1409
|
+
const subscribe = (listener) => {
|
|
1410
|
+
internal.assertAlive?.("subscribe");
|
|
1411
|
+
internal.listeners.add(listener);
|
|
1412
|
+
return () => internal.listeners.delete(listener);
|
|
1413
|
+
};
|
|
1414
|
+
let isDestroyed = false;
|
|
1415
|
+
internal.assertAlive = (operation) => {
|
|
1416
|
+
if (isDestroyed) throw new Error(`${operation} cannot be called after store.destroy().`);
|
|
1417
|
+
};
|
|
1418
|
+
const destroy = () => {
|
|
1419
|
+
if (isDestroyed) return;
|
|
1420
|
+
isDestroyed = true;
|
|
1421
|
+
internal.listeners.clear();
|
|
1422
|
+
store.transport?.dispose();
|
|
1423
|
+
releaseStoreName();
|
|
1424
|
+
};
|
|
1425
|
+
const apply = (state = internal.rootState, patches) => {
|
|
1426
|
+
internal.assertAlive?.("apply");
|
|
1427
|
+
internal.assertMutationAllowed?.("apply");
|
|
1428
|
+
assertSafePatches(patches, "store.apply()");
|
|
1429
|
+
const safePatches = sanitizePatches(patches);
|
|
1430
|
+
const baseState = state === internal.module ? internal.rootState : state;
|
|
1431
|
+
const nextState = sanitizeReplacementState(safePatches ? (0, mutative.apply)(baseState, safePatches) : baseState);
|
|
1432
|
+
assertKnownStateShape(nextState, internal.rootState, internal.stateSchema, store.isSliceStore, { requireSliceRoots: true });
|
|
1433
|
+
if (store.share === "main") validateSharedStateSerializable(nextState);
|
|
1434
|
+
internal.rootState = nextState;
|
|
1435
|
+
refreshSignalSlots(internal);
|
|
1436
|
+
if (internal.updateImmutable) internal.updateImmutable(internal.rootState);
|
|
1437
|
+
else internal.listeners.forEach((listener) => listener());
|
|
1438
|
+
};
|
|
1439
|
+
const getPureState = () => internal.rootState;
|
|
1440
|
+
const isFunctionMapObject = () => {
|
|
1441
|
+
if (typeof createState === "object" && createState !== null) {
|
|
1442
|
+
const values = getOwnEnumerableKeys(createState).map((key) => createState[key]);
|
|
1443
|
+
return values.length > 0 && values.every((value) => typeof value === "function");
|
|
1444
|
+
}
|
|
1445
|
+
return false;
|
|
1446
|
+
};
|
|
1447
|
+
const getIsSliceStore = () => {
|
|
1448
|
+
const sliceMode = options.sliceMode ?? "auto";
|
|
1449
|
+
if (sliceMode === "single") return false;
|
|
1450
|
+
if (sliceMode === "slices") {
|
|
1451
|
+
if (!isFunctionMapObject()) throw new Error(`sliceMode: 'slices' requires createState to be an object of slice functions.`);
|
|
1452
|
+
return true;
|
|
1453
|
+
}
|
|
1454
|
+
if (isFunctionMapObject()) {
|
|
1455
|
+
warnAmbiguousFunctionMap();
|
|
1456
|
+
return true;
|
|
1457
|
+
}
|
|
1458
|
+
return false;
|
|
1459
|
+
};
|
|
1460
|
+
const isSliceStore = getIsSliceStore();
|
|
1461
|
+
Object.assign(store, {
|
|
1462
|
+
name,
|
|
1463
|
+
share: share ?? false,
|
|
1464
|
+
setState,
|
|
1465
|
+
getState,
|
|
1466
|
+
subscribe,
|
|
1467
|
+
destroy,
|
|
1468
|
+
apply,
|
|
1469
|
+
isSliceStore,
|
|
1470
|
+
getPureState
|
|
1471
|
+
});
|
|
1472
|
+
const middlewareStore = applyMiddlewares(store, options.middlewares ?? []);
|
|
1473
|
+
if (middlewareStore !== store) Object.assign(store, middlewareStore);
|
|
1474
|
+
const initialState = getInitialState(store, createState, internal);
|
|
1475
|
+
if (share) validateSharedActionPaths(initialState);
|
|
1476
|
+
store.getInitialState = () => initialState;
|
|
1477
|
+
internal.rootState = getRawState(store, internal, initialState, options);
|
|
1478
|
+
internal.stateSchema = createStateSchema(internal.rootState, store.isSliceStore);
|
|
1479
|
+
if (share) validateSharedStateSerializable(internal.rootState);
|
|
1480
|
+
markStoreReady(store);
|
|
1481
|
+
return {
|
|
1482
|
+
store,
|
|
1483
|
+
internal
|
|
1484
|
+
};
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
releaseStoreName();
|
|
1487
|
+
throw error;
|
|
1488
|
+
}
|
|
1489
|
+
};
|
|
1490
|
+
if (options.clientTransport || options.worker || options.workerType === "WebWorkerClient" || options.workerType === "SharedWorkerClient") {
|
|
1491
|
+
if (checkEnablePatches) throw new Error(`enablePatches: true is required for the async store`);
|
|
1492
|
+
return wrapStore(createAsyncClientStore(createStore, options));
|
|
1493
|
+
}
|
|
1494
|
+
const { store, internal } = createStore({ share });
|
|
1495
|
+
handleMainTransport(store, internal, storeTransport, workerType, checkEnablePatches);
|
|
1496
|
+
return wrapStore(store);
|
|
1497
|
+
};
|
|
1498
|
+
//#endregion
|
|
1499
|
+
//#region packages/core/src/binder.ts
|
|
1500
|
+
const createExternalStoreAdapter = ({ handleState, handleStore }) => ((state) => {
|
|
1501
|
+
const { copyState, key, bind } = handleState(state);
|
|
1502
|
+
const value = typeof key !== "undefined" ? copyState[key] : copyState;
|
|
1503
|
+
Object.defineProperty(value, bindSymbol, {
|
|
1504
|
+
configurable: true,
|
|
1505
|
+
enumerable: typeof key !== "undefined",
|
|
1506
|
+
value: {
|
|
1507
|
+
handleStore,
|
|
1508
|
+
bind
|
|
1509
|
+
}
|
|
1510
|
+
});
|
|
1511
|
+
return copyState;
|
|
1512
|
+
});
|
|
1513
|
+
/**
|
|
1514
|
+
* Build an adapter helper for bridging an external store implementation into
|
|
1515
|
+
* Coaction.
|
|
1516
|
+
*
|
|
1517
|
+
* @remarks
|
|
1518
|
+
* Official bindings use this to integrate stores such as Redux, Jotai, Pinia,
|
|
1519
|
+
* Zustand, MobX, and Valtio. Binder-backed integrations are whole-store
|
|
1520
|
+
* adapters; they are not compatible with Coaction slices mode.
|
|
1521
|
+
*/
|
|
1522
|
+
function createBinder({ handleState, handleStore }) {
|
|
1523
|
+
return createExternalStoreAdapter({
|
|
1524
|
+
handleState,
|
|
1525
|
+
handleStore
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Define a whole-store adapter for integrating an external state runtime with
|
|
1530
|
+
* Coaction.
|
|
1531
|
+
*
|
|
1532
|
+
* @remarks
|
|
1533
|
+
* This is the stable 2.x name for adapter authors. `createBinder()` remains as
|
|
1534
|
+
* a compatibility alias for existing official and community integrations.
|
|
1535
|
+
*/
|
|
1536
|
+
function defineExternalStoreAdapter(options) {
|
|
1537
|
+
return createExternalStoreAdapter(options);
|
|
1182
1538
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1539
|
+
//#endregion
|
|
1540
|
+
//#region packages/core/src/reactiveTracker.ts
|
|
1541
|
+
const ReactiveFlags = alien_signals_system.ReactiveFlags;
|
|
1542
|
+
const unwatch = (node) => {
|
|
1543
|
+
if (!(node.flags & ReactiveFlags.Mutable)) {
|
|
1544
|
+
node.depsTail = void 0;
|
|
1545
|
+
node.flags = 0;
|
|
1546
|
+
purgeDeps(node);
|
|
1547
|
+
const sub = node.subs;
|
|
1548
|
+
if (sub !== void 0) unlink(sub);
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
if (node.depsTail !== void 0) {
|
|
1552
|
+
node.depsTail = void 0;
|
|
1553
|
+
node.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
|
|
1554
|
+
purgeDeps(node);
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
const unlink = (link, sub = link.sub) => {
|
|
1558
|
+
const dep = link.dep;
|
|
1559
|
+
const prevDep = link.prevDep;
|
|
1560
|
+
const nextDep = link.nextDep;
|
|
1561
|
+
const nextSub = link.nextSub;
|
|
1562
|
+
const prevSub = link.prevSub;
|
|
1563
|
+
if (nextDep !== void 0) nextDep.prevDep = prevDep;
|
|
1564
|
+
else sub.depsTail = prevDep;
|
|
1565
|
+
if (prevDep !== void 0) prevDep.nextDep = nextDep;
|
|
1566
|
+
else sub.deps = nextDep;
|
|
1567
|
+
if (nextSub !== void 0) nextSub.prevSub = prevSub;
|
|
1568
|
+
else dep.subsTail = prevSub;
|
|
1569
|
+
if (prevSub !== void 0) prevSub.nextSub = nextSub;
|
|
1570
|
+
else if ((dep.subs = nextSub) === void 0) unwatch(dep);
|
|
1571
|
+
return nextDep;
|
|
1572
|
+
};
|
|
1573
|
+
const purgeDeps = (sub) => {
|
|
1574
|
+
const depsTail = sub.depsTail;
|
|
1575
|
+
let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps;
|
|
1576
|
+
while (dep !== void 0) dep = unlink(dep, sub);
|
|
1577
|
+
};
|
|
1578
|
+
const createReactiveTracker = () => {
|
|
1579
|
+
let version = 0;
|
|
1580
|
+
let disposed = false;
|
|
1581
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1582
|
+
const node = {
|
|
1583
|
+
deps: void 0,
|
|
1584
|
+
depsTail: void 0,
|
|
1585
|
+
subs: void 0,
|
|
1586
|
+
subsTail: void 0,
|
|
1587
|
+
flags: ReactiveFlags.Watching,
|
|
1588
|
+
fn: () => {
|
|
1589
|
+
if (disposed) return;
|
|
1590
|
+
version += 1;
|
|
1591
|
+
listeners.forEach((listener) => listener());
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
const dispose = () => {
|
|
1595
|
+
if (disposed) return;
|
|
1596
|
+
disposed = true;
|
|
1597
|
+
listeners.clear();
|
|
1598
|
+
node.depsTail = void 0;
|
|
1599
|
+
purgeDeps(node);
|
|
1600
|
+
node.flags = 0;
|
|
1601
|
+
};
|
|
1602
|
+
return {
|
|
1603
|
+
getSnapshot: () => version,
|
|
1604
|
+
subscribe(listener) {
|
|
1605
|
+
if (disposed) return () => void 0;
|
|
1606
|
+
listeners.add(listener);
|
|
1607
|
+
return () => {
|
|
1608
|
+
listeners.delete(listener);
|
|
1609
|
+
};
|
|
1610
|
+
},
|
|
1611
|
+
track(fn) {
|
|
1612
|
+
if (disposed) return fn();
|
|
1613
|
+
node.depsTail = void 0;
|
|
1614
|
+
node.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck;
|
|
1615
|
+
const prevSub = (0, alien_signals.setActiveSub)(node);
|
|
1616
|
+
try {
|
|
1617
|
+
return fn();
|
|
1618
|
+
} finally {
|
|
1619
|
+
(0, alien_signals.setActiveSub)(prevSub);
|
|
1620
|
+
node.flags &= ~ReactiveFlags.RecursedCheck;
|
|
1621
|
+
purgeDeps(node);
|
|
1622
|
+
}
|
|
1623
|
+
},
|
|
1624
|
+
dispose
|
|
1625
|
+
};
|
|
1626
|
+
};
|
|
1627
|
+
//#endregion
|
|
1628
|
+
//#region packages/core/src/replaceExternalStoreState.ts
|
|
1629
|
+
const replaceExternalStoreState = (store, internal, source, { syncImmutable = true } = {}) => {
|
|
1630
|
+
const [, patches, inversePatches] = (0, mutative.create)(internal.rootState, (draft) => {
|
|
1631
|
+
replaceOwnEnumerable(draft, source);
|
|
1632
|
+
}, { enablePatches: true });
|
|
1633
|
+
const safePatches = sanitizeCheckedPatches((store.patch ? store.patch({
|
|
1634
|
+
patches,
|
|
1635
|
+
inversePatches
|
|
1636
|
+
}) : {
|
|
1637
|
+
patches,
|
|
1638
|
+
inversePatches
|
|
1639
|
+
}).patches, "store.patch()");
|
|
1640
|
+
if (!safePatches.length) return;
|
|
1641
|
+
const updateImmutable = internal.updateImmutable;
|
|
1642
|
+
if (!syncImmutable) internal.updateImmutable = void 0;
|
|
1643
|
+
try {
|
|
1644
|
+
store.apply(internal.rootState, safePatches);
|
|
1645
|
+
} finally {
|
|
1646
|
+
internal.updateImmutable = updateImmutable;
|
|
1647
|
+
}
|
|
1648
|
+
emit(store, internal, safePatches);
|
|
1649
|
+
};
|
|
1650
|
+
//#endregion
|
|
1651
|
+
//#region packages/core/src/externalMutableAdapterUtils.ts
|
|
1652
|
+
const getMutableAdapterOwnEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
1653
|
+
const isMutableAdapterUnsafeKey = (key) => typeof key === "string" && isUnsafeKey(key);
|
|
1654
|
+
const isArrayIndexKey = (key) => {
|
|
1655
|
+
if (typeof key !== "string") return false;
|
|
1656
|
+
const index = Number(key);
|
|
1657
|
+
return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
|
|
1658
|
+
};
|
|
1659
|
+
const isObjectRecord = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
1660
|
+
const assertCanSetMutableAdapterPublicStateKey = (publicState, key) => {
|
|
1661
|
+
if (Object.prototype.hasOwnProperty.call(publicState, key)) return;
|
|
1662
|
+
if (Object.isExtensible(publicState)) return;
|
|
1663
|
+
throw new StateSchemaError(`Unknown state key '${String(key)}' cannot be added after store initialization. Coaction state schema is fixed.`);
|
|
1664
|
+
};
|
|
1665
|
+
const ensureMutableAdapterRawDescriptor = (rawState, mutableState, publicState, key) => {
|
|
1666
|
+
if (rawState === mutableState) return;
|
|
1667
|
+
const rawDescriptor = Object.getOwnPropertyDescriptor(rawState, key);
|
|
1668
|
+
if (rawDescriptor?.get && rawDescriptor.set) return;
|
|
1669
|
+
const publicDescriptor = Object.getOwnPropertyDescriptor(publicState, key);
|
|
1670
|
+
if (!publicDescriptor || rawDescriptor?.configurable === false) return;
|
|
1671
|
+
Object.defineProperty(rawState, key, {
|
|
1672
|
+
get: () => mutableState[key],
|
|
1673
|
+
set: (value) => {
|
|
1674
|
+
mutableState[key] = value;
|
|
1675
|
+
},
|
|
1676
|
+
configurable: true,
|
|
1677
|
+
enumerable: publicDescriptor.enumerable
|
|
1678
|
+
});
|
|
1679
|
+
};
|
|
1680
|
+
const replaceMutableAdapterState = (rawState, mutableState, publicState, source) => {
|
|
1681
|
+
const nextKeys = /* @__PURE__ */ new Set();
|
|
1682
|
+
for (const key of getMutableAdapterOwnEnumerableKeys(source)) {
|
|
1683
|
+
if (isMutableAdapterUnsafeKey(key)) continue;
|
|
1684
|
+
if (typeof source[key] === "function") continue;
|
|
1685
|
+
nextKeys.add(key);
|
|
1686
|
+
}
|
|
1687
|
+
nextKeys.forEach((key) => {
|
|
1688
|
+
assertCanSetMutableAdapterPublicStateKey(publicState, key);
|
|
1689
|
+
});
|
|
1690
|
+
for (const key of getMutableAdapterOwnEnumerableKeys(rawState)) {
|
|
1691
|
+
if (isMutableAdapterUnsafeKey(key)) {
|
|
1692
|
+
delete rawState[key];
|
|
1693
|
+
delete mutableState[key];
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
if (typeof rawState[key] === "function") continue;
|
|
1697
|
+
if (!nextKeys.has(key)) {
|
|
1698
|
+
delete rawState[key];
|
|
1699
|
+
delete mutableState[key];
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
const rawSeen = /* @__PURE__ */ new WeakMap();
|
|
1703
|
+
const mutableSeen = /* @__PURE__ */ new WeakMap();
|
|
1704
|
+
const publicSeen = /* @__PURE__ */ new WeakMap();
|
|
1705
|
+
rawSeen.set(source, rawState);
|
|
1706
|
+
mutableSeen.set(source, mutableState);
|
|
1707
|
+
publicSeen.set(source, publicState);
|
|
1708
|
+
nextKeys.forEach((key) => {
|
|
1709
|
+
ensureMutableAdapterRawDescriptor(rawState, mutableState, publicState, key);
|
|
1710
|
+
rawState[key] = sanitizeReplacementState(source[key], rawSeen);
|
|
1711
|
+
mutableState[key] = sanitizeReplacementState(source[key], mutableSeen);
|
|
1712
|
+
publicState[key] = sanitizeReplacementState(source[key], publicSeen);
|
|
1713
|
+
});
|
|
1714
|
+
};
|
|
1715
|
+
const applyMutableAdapterPatches = (baseState, patches, rawState, mutableState, publicState) => {
|
|
1716
|
+
assertSafePatches(patches, "mutable adapter apply()");
|
|
1717
|
+
replaceMutableAdapterState(rawState, mutableState, publicState, (0, mutative.apply)(toMutableAdapterSnapshot(baseState === publicState ? rawState : baseState), patches));
|
|
1718
|
+
};
|
|
1719
|
+
const toMutableAdapterSnapshot = (value, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
1720
|
+
if (Array.isArray(value)) {
|
|
1721
|
+
if (visited.has(value)) return visited.get(value);
|
|
1722
|
+
const next = [];
|
|
1723
|
+
next.length = value.length;
|
|
1724
|
+
visited.set(value, next);
|
|
1725
|
+
for (let index = 0; index < value.length; index += 1) if (Object.prototype.hasOwnProperty.call(value, index)) next[index] = toMutableAdapterSnapshot(value[index], visited);
|
|
1726
|
+
const source = value;
|
|
1727
|
+
const target = next;
|
|
1728
|
+
for (const key of getMutableAdapterOwnEnumerableKeys(value)) {
|
|
1729
|
+
if (isArrayIndexKey(key) || isMutableAdapterUnsafeKey(key)) continue;
|
|
1730
|
+
const child = source[key];
|
|
1731
|
+
if (typeof child !== "function") target[key] = toMutableAdapterSnapshot(child, visited);
|
|
1732
|
+
}
|
|
1733
|
+
return next;
|
|
1734
|
+
}
|
|
1735
|
+
if (typeof value === "object" && value !== null) {
|
|
1736
|
+
if (!isObjectRecord(value)) return value;
|
|
1737
|
+
if (visited.has(value)) return visited.get(value);
|
|
1738
|
+
const next = {};
|
|
1739
|
+
visited.set(value, next);
|
|
1740
|
+
for (const key of getMutableAdapterOwnEnumerableKeys(value)) {
|
|
1741
|
+
if (isMutableAdapterUnsafeKey(key)) continue;
|
|
1742
|
+
const child = value[key];
|
|
1743
|
+
if (typeof child !== "function") next[key] = toMutableAdapterSnapshot(child, visited);
|
|
1744
|
+
}
|
|
1745
|
+
return next;
|
|
1746
|
+
}
|
|
1747
|
+
return value;
|
|
1748
|
+
};
|
|
1749
|
+
const snapshotMutableAdapterPureState = (store) => toMutableAdapterSnapshot(store.getPureState());
|
|
1750
|
+
const isEqualMutableAdapterSnapshot = (left, right, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
1751
|
+
if (Object.is(left, right)) return true;
|
|
1752
|
+
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
|
|
1753
|
+
const leftIsArray = Array.isArray(left);
|
|
1754
|
+
const rightIsArray = Array.isArray(right);
|
|
1755
|
+
if (leftIsArray || rightIsArray) {
|
|
1756
|
+
if (!leftIsArray || !rightIsArray || left.length !== right.length) return false;
|
|
1757
|
+
} else if (!isObjectRecord(left) || !isObjectRecord(right)) return false;
|
|
1758
|
+
let seenTargets = visited.get(left);
|
|
1759
|
+
if (!seenTargets) {
|
|
1760
|
+
seenTargets = /* @__PURE__ */ new WeakSet();
|
|
1761
|
+
visited.set(left, seenTargets);
|
|
1762
|
+
} else if (seenTargets.has(right)) return true;
|
|
1763
|
+
seenTargets.add(right);
|
|
1764
|
+
const leftRecord = left;
|
|
1765
|
+
const rightRecord = right;
|
|
1766
|
+
const leftKeys = getMutableAdapterOwnEnumerableKeys(left);
|
|
1767
|
+
const rightKeys = getMutableAdapterOwnEnumerableKeys(right);
|
|
1768
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
1769
|
+
for (const key of leftKeys) {
|
|
1770
|
+
if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;
|
|
1771
|
+
if (!isEqualMutableAdapterSnapshot(leftRecord[key], rightRecord[key], visited)) return false;
|
|
1772
|
+
}
|
|
1773
|
+
return true;
|
|
1774
|
+
};
|
|
1775
|
+
//#endregion
|
|
1776
|
+
exports.StateSchemaError = StateSchemaError;
|
|
1777
|
+
exports.UnsafePatchPathError = UnsafePatchPathError;
|
|
1778
|
+
exports.applyMutableAdapterPatches = applyMutableAdapterPatches;
|
|
1779
|
+
exports.applyRootReplacementWithPatches = applyRootReplacementWithPatches;
|
|
1780
|
+
exports.assertSafePatches = assertSafePatches;
|
|
1781
|
+
Object.defineProperty(exports, "computed", {
|
|
1782
|
+
enumerable: true,
|
|
1783
|
+
get: function() {
|
|
1784
|
+
return alien_signals.computed;
|
|
1785
|
+
}
|
|
1786
|
+
});
|
|
1787
|
+
exports.create = create;
|
|
1788
|
+
exports.createBinder = createBinder;
|
|
1789
|
+
exports.createReactiveTracker = createReactiveTracker;
|
|
1790
|
+
exports.createRootReplacementPatches = createRootReplacementPatches;
|
|
1791
|
+
exports.defineExternalStoreAdapter = defineExternalStoreAdapter;
|
|
1792
|
+
Object.defineProperty(exports, "effect", {
|
|
1793
|
+
enumerable: true,
|
|
1794
|
+
get: function() {
|
|
1795
|
+
return alien_signals.effect;
|
|
1796
|
+
}
|
|
1797
|
+
});
|
|
1798
|
+
Object.defineProperty(exports, "effectScope", {
|
|
1799
|
+
enumerable: true,
|
|
1800
|
+
get: function() {
|
|
1801
|
+
return alien_signals.effectScope;
|
|
1802
|
+
}
|
|
1803
|
+
});
|
|
1804
|
+
Object.defineProperty(exports, "endBatch", {
|
|
1805
|
+
enumerable: true,
|
|
1806
|
+
get: function() {
|
|
1807
|
+
return alien_signals.endBatch;
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
exports.getMutableAdapterOwnEnumerableKeys = getMutableAdapterOwnEnumerableKeys;
|
|
1811
|
+
Object.defineProperty(exports, "isComputed", {
|
|
1812
|
+
enumerable: true,
|
|
1813
|
+
get: function() {
|
|
1814
|
+
return alien_signals.isComputed;
|
|
1815
|
+
}
|
|
1816
|
+
});
|
|
1817
|
+
Object.defineProperty(exports, "isEffect", {
|
|
1818
|
+
enumerable: true,
|
|
1819
|
+
get: function() {
|
|
1820
|
+
return alien_signals.isEffect;
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
Object.defineProperty(exports, "isEffectScope", {
|
|
1824
|
+
enumerable: true,
|
|
1825
|
+
get: function() {
|
|
1826
|
+
return alien_signals.isEffectScope;
|
|
1827
|
+
}
|
|
1828
|
+
});
|
|
1829
|
+
exports.isEqualMutableAdapterSnapshot = isEqualMutableAdapterSnapshot;
|
|
1830
|
+
exports.isMutableAdapterUnsafeKey = isMutableAdapterUnsafeKey;
|
|
1831
|
+
Object.defineProperty(exports, "isSignal", {
|
|
1832
|
+
enumerable: true,
|
|
1833
|
+
get: function() {
|
|
1834
|
+
return alien_signals.isSignal;
|
|
1835
|
+
}
|
|
1836
|
+
});
|
|
1837
|
+
exports.isStateSchemaError = isStateSchemaError;
|
|
1838
|
+
exports.onStoreReady = onStoreReady;
|
|
1839
|
+
exports.replaceExternalStoreState = replaceExternalStoreState;
|
|
1840
|
+
exports.replaceMutableAdapterState = replaceMutableAdapterState;
|
|
1841
|
+
exports.replaceOwnEnumerable = replaceOwnEnumerable;
|
|
1842
|
+
exports.sanitizeInitialStateValue = sanitizeInitialStateValue;
|
|
1843
|
+
exports.sanitizePatches = sanitizePatches;
|
|
1844
|
+
exports.sanitizeReplacementState = sanitizeReplacementState;
|
|
1845
|
+
Object.defineProperty(exports, "signal", {
|
|
1846
|
+
enumerable: true,
|
|
1847
|
+
get: function() {
|
|
1848
|
+
return alien_signals.signal;
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
exports.snapshotMutableAdapterPureState = snapshotMutableAdapterPureState;
|
|
1852
|
+
Object.defineProperty(exports, "startBatch", {
|
|
1853
|
+
enumerable: true,
|
|
1854
|
+
get: function() {
|
|
1855
|
+
return alien_signals.startBatch;
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
exports.toMutableAdapterSnapshot = toMutableAdapterSnapshot;
|
|
1859
|
+
Object.defineProperty(exports, "trigger", {
|
|
1860
|
+
enumerable: true,
|
|
1861
|
+
get: function() {
|
|
1862
|
+
return alien_signals.trigger;
|
|
1863
|
+
}
|
|
1188
1864
|
});
|
|
1865
|
+
exports.wrapStore = wrapStore;
|