xstate 6.0.0-alpha.2 → 6.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{StateMachine-8d22a79c.development.cjs.js → StateMachine-0770ac71.development.cjs.js} +1 -1
- package/dist/{StateMachine-2dcdb1f5.esm.js → StateMachine-8249d511.esm.js} +1 -1
- package/dist/{StateMachine-64813f46.cjs.js → StateMachine-e1048cd6.cjs.js} +1 -1
- package/dist/{StateMachine-2ea0a7fa.development.esm.js → StateMachine-e6ad61d0.development.esm.js} +1 -1
- package/dist/declarations/src/StateMachine.d.ts +4 -4
- package/dist/declarations/src/createActor.d.ts +0 -2
- package/dist/declarations/src/index.d.ts +1 -3
- package/dist/declarations/src/serialize.d.ts +13 -8
- package/dist/declarations/src/types.d.ts +0 -4
- package/dist/declarations/src/types.v6.d.ts +11 -9
- package/dist/{index-f6ef20d1.development.cjs.js → index-269d256d.development.cjs.js} +10 -689
- package/dist/{index-e61170ba.development.esm.js → index-66ff64a6.development.esm.js} +11 -685
- package/dist/{index-93edd3bd.esm.js → index-a7e3d8b3.esm.js} +11 -685
- package/dist/{index-9cb3b3a0.cjs.js → index-dda021d5.cjs.js} +10 -689
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +1 -1
- package/dist/xstate-actors.esm.js +1 -1
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +2 -2
- package/dist/xstate-graph.development.cjs.js +2 -2
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +85 -32
- package/dist/xstate.cjs.mjs +0 -5
- package/dist/xstate.development.cjs.js +85 -32
- package/dist/xstate.development.cjs.mjs +0 -5
- package/dist/xstate.development.esm.js +87 -29
- package/dist/xstate.esm.js +87 -29
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/declarations/src/atom.d.ts +0 -81
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Reactivity interop between actors and atoms.
|
|
5
|
-
*
|
|
6
|
-
* `Actor#get()` calls this hook (when installed) so that computed atoms can
|
|
7
|
-
* track actor reads as dependencies. The hook is installed by `atom.ts` on
|
|
8
|
-
* module evaluation, which only happens when atoms are actually used — apps
|
|
9
|
-
* that never import atoms don't bundle the reactive system.
|
|
10
|
-
*/
|
|
11
|
-
let onActorRead;
|
|
12
|
-
function installActorReadHook(hook) {
|
|
13
|
-
onActorRead = hook;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
3
|
class Mailbox {
|
|
17
4
|
constructor(_process) {
|
|
18
5
|
this._process = _process;
|
|
@@ -205,10 +192,9 @@ function createAttachedLogic(attach) {
|
|
|
205
192
|
self,
|
|
206
193
|
system
|
|
207
194
|
}) => {
|
|
208
|
-
// Don't attach if the target doesn't exist
|
|
209
|
-
// Atoms have no `getSnapshot` / lifecycle, so they always attach.
|
|
195
|
+
// Don't attach if the target doesn't exist or is stopped.
|
|
210
196
|
const target = state.input.actor;
|
|
211
|
-
if (!target ||
|
|
197
|
+
if (!target || target.getSnapshot().status === 'stopped') {
|
|
212
198
|
return;
|
|
213
199
|
}
|
|
214
200
|
const subscription = attach(state.input, {
|
|
@@ -310,620 +296,6 @@ function createListenerLogic() {
|
|
|
310
296
|
// Singleton logic instance
|
|
311
297
|
const listenerLogic = /* #__PURE__ */createListenerLogic();
|
|
312
298
|
|
|
313
|
-
/* eslint-disable */
|
|
314
|
-
// Adapted from Alien Signals
|
|
315
|
-
// https://github.com/stackblitz/alien-signals/
|
|
316
|
-
|
|
317
|
-
let ReactiveFlags = /*#__PURE__*/function (ReactiveFlags) {
|
|
318
|
-
ReactiveFlags[ReactiveFlags["None"] = 0] = "None";
|
|
319
|
-
ReactiveFlags[ReactiveFlags["Mutable"] = 1] = "Mutable";
|
|
320
|
-
ReactiveFlags[ReactiveFlags["Watching"] = 2] = "Watching";
|
|
321
|
-
ReactiveFlags[ReactiveFlags["RecursedCheck"] = 4] = "RecursedCheck";
|
|
322
|
-
ReactiveFlags[ReactiveFlags["Recursed"] = 8] = "Recursed";
|
|
323
|
-
ReactiveFlags[ReactiveFlags["Dirty"] = 16] = "Dirty";
|
|
324
|
-
ReactiveFlags[ReactiveFlags["Pending"] = 32] = "Pending";
|
|
325
|
-
return ReactiveFlags;
|
|
326
|
-
}({});
|
|
327
|
-
function createReactiveSystem({
|
|
328
|
-
update,
|
|
329
|
-
notify,
|
|
330
|
-
unwatched
|
|
331
|
-
}) {
|
|
332
|
-
return {
|
|
333
|
-
link,
|
|
334
|
-
unlink,
|
|
335
|
-
propagate,
|
|
336
|
-
checkDirty,
|
|
337
|
-
shallowPropagate
|
|
338
|
-
};
|
|
339
|
-
function link(dep, sub, version) {
|
|
340
|
-
const prevDep = sub.depsTail;
|
|
341
|
-
if (prevDep !== undefined && prevDep.dep === dep) {
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
const nextDep = prevDep !== undefined ? prevDep.nextDep : sub.deps;
|
|
345
|
-
if (nextDep !== undefined && nextDep.dep === dep) {
|
|
346
|
-
nextDep.version = version;
|
|
347
|
-
sub.depsTail = nextDep;
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
const prevSub = dep.subsTail;
|
|
351
|
-
if (prevSub !== undefined && prevSub.version === version && prevSub.sub === sub) {
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
const newLink = sub.depsTail = dep.subsTail = {
|
|
355
|
-
version,
|
|
356
|
-
dep,
|
|
357
|
-
sub,
|
|
358
|
-
prevDep,
|
|
359
|
-
nextDep,
|
|
360
|
-
prevSub,
|
|
361
|
-
nextSub: undefined
|
|
362
|
-
};
|
|
363
|
-
if (nextDep !== undefined) {
|
|
364
|
-
nextDep.prevDep = newLink;
|
|
365
|
-
}
|
|
366
|
-
if (prevDep !== undefined) {
|
|
367
|
-
prevDep.nextDep = newLink;
|
|
368
|
-
} else {
|
|
369
|
-
sub.deps = newLink;
|
|
370
|
-
}
|
|
371
|
-
if (prevSub !== undefined) {
|
|
372
|
-
prevSub.nextSub = newLink;
|
|
373
|
-
} else {
|
|
374
|
-
dep.subs = newLink;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
function unlink(link, sub = link.sub) {
|
|
378
|
-
const dep = link.dep;
|
|
379
|
-
const prevDep = link.prevDep;
|
|
380
|
-
const nextDep = link.nextDep;
|
|
381
|
-
const nextSub = link.nextSub;
|
|
382
|
-
const prevSub = link.prevSub;
|
|
383
|
-
if (nextDep !== undefined) {
|
|
384
|
-
nextDep.prevDep = prevDep;
|
|
385
|
-
} else {
|
|
386
|
-
sub.depsTail = prevDep;
|
|
387
|
-
}
|
|
388
|
-
if (prevDep !== undefined) {
|
|
389
|
-
prevDep.nextDep = nextDep;
|
|
390
|
-
} else {
|
|
391
|
-
sub.deps = nextDep;
|
|
392
|
-
}
|
|
393
|
-
if (nextSub !== undefined) {
|
|
394
|
-
nextSub.prevSub = prevSub;
|
|
395
|
-
} else {
|
|
396
|
-
dep.subsTail = prevSub;
|
|
397
|
-
}
|
|
398
|
-
if (prevSub !== undefined) {
|
|
399
|
-
prevSub.nextSub = nextSub;
|
|
400
|
-
} else if ((dep.subs = nextSub) === undefined) {
|
|
401
|
-
unwatched(dep);
|
|
402
|
-
}
|
|
403
|
-
return nextDep;
|
|
404
|
-
}
|
|
405
|
-
function propagate(link) {
|
|
406
|
-
let next = link.nextSub;
|
|
407
|
-
let stack;
|
|
408
|
-
top: do {
|
|
409
|
-
const sub = link.sub;
|
|
410
|
-
let flags = sub.flags;
|
|
411
|
-
if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed | ReactiveFlags.Dirty | ReactiveFlags.Pending))) {
|
|
412
|
-
sub.flags = flags | ReactiveFlags.Pending;
|
|
413
|
-
} else if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))) {
|
|
414
|
-
flags = ReactiveFlags.None;
|
|
415
|
-
} else if (!(flags & ReactiveFlags.RecursedCheck)) {
|
|
416
|
-
sub.flags = flags & ~ReactiveFlags.Recursed | ReactiveFlags.Pending;
|
|
417
|
-
} else if (!(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) && isValidLink(link, sub)) {
|
|
418
|
-
sub.flags = flags | (ReactiveFlags.Recursed | ReactiveFlags.Pending);
|
|
419
|
-
flags &= ReactiveFlags.Mutable;
|
|
420
|
-
} else {
|
|
421
|
-
flags = ReactiveFlags.None;
|
|
422
|
-
}
|
|
423
|
-
if (flags & ReactiveFlags.Watching) {
|
|
424
|
-
notify(sub);
|
|
425
|
-
}
|
|
426
|
-
if (flags & ReactiveFlags.Mutable) {
|
|
427
|
-
const subSubs = sub.subs;
|
|
428
|
-
if (subSubs !== undefined) {
|
|
429
|
-
const nextSub = (link = subSubs).nextSub;
|
|
430
|
-
if (nextSub !== undefined) {
|
|
431
|
-
stack = {
|
|
432
|
-
value: next,
|
|
433
|
-
prev: stack
|
|
434
|
-
};
|
|
435
|
-
next = nextSub;
|
|
436
|
-
}
|
|
437
|
-
continue;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
if ((link = next) !== undefined) {
|
|
441
|
-
next = link.nextSub;
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
while (stack !== undefined) {
|
|
445
|
-
link = stack.value;
|
|
446
|
-
stack = stack.prev;
|
|
447
|
-
if (link !== undefined) {
|
|
448
|
-
next = link.nextSub;
|
|
449
|
-
continue top;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
break;
|
|
453
|
-
} while (true);
|
|
454
|
-
}
|
|
455
|
-
function checkDirty(link, sub) {
|
|
456
|
-
let stack;
|
|
457
|
-
let checkDepth = 0;
|
|
458
|
-
let dirty = false;
|
|
459
|
-
top: do {
|
|
460
|
-
const dep = link.dep;
|
|
461
|
-
const flags = dep.flags;
|
|
462
|
-
if (sub.flags & ReactiveFlags.Dirty) {
|
|
463
|
-
dirty = true;
|
|
464
|
-
} else if ((flags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) === (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) {
|
|
465
|
-
if (update(dep)) {
|
|
466
|
-
const subs = dep.subs;
|
|
467
|
-
if (subs.nextSub !== undefined) {
|
|
468
|
-
shallowPropagate(subs);
|
|
469
|
-
}
|
|
470
|
-
dirty = true;
|
|
471
|
-
}
|
|
472
|
-
} else if ((flags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) === (ReactiveFlags.Mutable | ReactiveFlags.Pending)) {
|
|
473
|
-
if (link.nextSub !== undefined || link.prevSub !== undefined) {
|
|
474
|
-
stack = {
|
|
475
|
-
value: link,
|
|
476
|
-
prev: stack
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
link = dep.deps;
|
|
480
|
-
sub = dep;
|
|
481
|
-
++checkDepth;
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
if (!dirty) {
|
|
485
|
-
const nextDep = link.nextDep;
|
|
486
|
-
if (nextDep !== undefined) {
|
|
487
|
-
link = nextDep;
|
|
488
|
-
continue;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
while (checkDepth--) {
|
|
492
|
-
const firstSub = sub.subs;
|
|
493
|
-
const hasMultipleSubs = firstSub.nextSub !== undefined;
|
|
494
|
-
if (hasMultipleSubs) {
|
|
495
|
-
link = stack.value;
|
|
496
|
-
stack = stack.prev;
|
|
497
|
-
} else {
|
|
498
|
-
link = firstSub;
|
|
499
|
-
}
|
|
500
|
-
if (dirty) {
|
|
501
|
-
if (update(sub)) {
|
|
502
|
-
if (hasMultipleSubs) {
|
|
503
|
-
shallowPropagate(firstSub);
|
|
504
|
-
}
|
|
505
|
-
sub = link.sub;
|
|
506
|
-
continue;
|
|
507
|
-
}
|
|
508
|
-
dirty = false;
|
|
509
|
-
} else {
|
|
510
|
-
sub.flags &= ~ReactiveFlags.Pending;
|
|
511
|
-
}
|
|
512
|
-
sub = link.sub;
|
|
513
|
-
const nextDep = link.nextDep;
|
|
514
|
-
if (nextDep !== undefined) {
|
|
515
|
-
link = nextDep;
|
|
516
|
-
continue top;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
return dirty;
|
|
520
|
-
} while (true);
|
|
521
|
-
}
|
|
522
|
-
function shallowPropagate(link) {
|
|
523
|
-
do {
|
|
524
|
-
const sub = link.sub;
|
|
525
|
-
const flags = sub.flags;
|
|
526
|
-
if ((flags & (ReactiveFlags.Pending | ReactiveFlags.Dirty)) === ReactiveFlags.Pending) {
|
|
527
|
-
sub.flags = flags | ReactiveFlags.Dirty;
|
|
528
|
-
if ((flags & (ReactiveFlags.Watching | ReactiveFlags.RecursedCheck)) === ReactiveFlags.Watching) {
|
|
529
|
-
notify(sub);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
} while ((link = link.nextSub) !== undefined);
|
|
533
|
-
}
|
|
534
|
-
function isValidLink(checkLink, sub) {
|
|
535
|
-
let link = sub.depsTail;
|
|
536
|
-
while (link !== undefined) {
|
|
537
|
-
if (link === checkLink) {
|
|
538
|
-
return true;
|
|
539
|
-
}
|
|
540
|
-
link = link.prevDep;
|
|
541
|
-
}
|
|
542
|
-
return false;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Nominal brand (phantom, compile-time only) marking a value as an XState atom.
|
|
548
|
-
* Real atoms get the runtime brand ({@link $$atom}) in `createAtom`; this type
|
|
549
|
-
* brand keeps atom-only APIs (e.g. `enq.subscribeTo`) from structurally
|
|
550
|
-
* accepting plain readables like `actor.select(...)` that would be dispatched
|
|
551
|
-
* down the non-atom path at runtime.
|
|
552
|
-
*/
|
|
553
|
-
|
|
554
|
-
/** Brand marking an object as an atom, so it can be detected structurally. */
|
|
555
|
-
const $$atom = /* #__PURE__ */Symbol.for('xstate.atom');
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Returns `true` if the value is an atom (writable, computed, async, or
|
|
559
|
-
* reducer). Lets actor-consuming APIs (e.g. `enq.subscribeTo`) accept atoms
|
|
560
|
-
* directly.
|
|
561
|
-
*/
|
|
562
|
-
function isAtom(value) {
|
|
563
|
-
return !!value && typeof value === 'object' && $$atom in value;
|
|
564
|
-
}
|
|
565
|
-
const queuedEffects = [];
|
|
566
|
-
let cycle = 0;
|
|
567
|
-
// Initialized lazily on first atom creation (instead of at module evaluation)
|
|
568
|
-
// so the reactive system stays tree-shakeable for apps that never use atoms —
|
|
569
|
-
|
|
570
|
-
// would be retained by consumer bundlers even when atoms are unused.
|
|
571
|
-
let link;
|
|
572
|
-
let unlink;
|
|
573
|
-
let propagate;
|
|
574
|
-
let checkDirty;
|
|
575
|
-
let shallowPropagate;
|
|
576
|
-
let reactiveSystemInstalled = false;
|
|
577
|
-
function ensureReactiveSystem() {
|
|
578
|
-
if (reactiveSystemInstalled) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
reactiveSystemInstalled = true;
|
|
582
|
-
({
|
|
583
|
-
link,
|
|
584
|
-
unlink,
|
|
585
|
-
propagate,
|
|
586
|
-
checkDirty,
|
|
587
|
-
shallowPropagate
|
|
588
|
-
} = createReactiveSystem({
|
|
589
|
-
update(atom) {
|
|
590
|
-
return atom._update();
|
|
591
|
-
},
|
|
592
|
-
notify(effect) {
|
|
593
|
-
queuedEffects[queuedEffectsLength++] = effect;
|
|
594
|
-
effect.flags &= ~ReactiveFlags.Watching;
|
|
595
|
-
},
|
|
596
|
-
unwatched(atom) {
|
|
597
|
-
if (atom.depsTail !== undefined) {
|
|
598
|
-
atom.depsTail = undefined;
|
|
599
|
-
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
|
|
600
|
-
purgeDeps(atom);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}));
|
|
604
|
-
}
|
|
605
|
-
let notifyIndex = 0;
|
|
606
|
-
let queuedEffectsLength = 0;
|
|
607
|
-
let activeSub;
|
|
608
|
-
function purgeDeps(sub) {
|
|
609
|
-
const depsTail = sub.depsTail;
|
|
610
|
-
let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps;
|
|
611
|
-
while (dep !== undefined) {
|
|
612
|
-
dep = unlink(dep, sub);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
function flush() {
|
|
616
|
-
while (notifyIndex < queuedEffectsLength) {
|
|
617
|
-
const effect = queuedEffects[notifyIndex];
|
|
618
|
-
queuedEffects[notifyIndex++] = undefined;
|
|
619
|
-
effect.notify();
|
|
620
|
-
}
|
|
621
|
-
notifyIndex = 0;
|
|
622
|
-
queuedEffectsLength = 0;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
/** The current state of an async atom. */
|
|
626
|
-
|
|
627
|
-
/** Options passed to an async atom getter. */
|
|
628
|
-
|
|
629
|
-
function compareAsyncAtomState(a, b) {
|
|
630
|
-
if (a.status !== b.status) {
|
|
631
|
-
return false;
|
|
632
|
-
}
|
|
633
|
-
if (a.status === 'done' && b.status === 'done') {
|
|
634
|
-
return Object.is(a.data, b.data);
|
|
635
|
-
}
|
|
636
|
-
if (a.status === 'error' && b.status === 'error') {
|
|
637
|
-
return Object.is(a.error, b.error);
|
|
638
|
-
}
|
|
639
|
-
// both 'pending'
|
|
640
|
-
return true;
|
|
641
|
-
}
|
|
642
|
-
function updateAsyncAtom(atom, nextValue) {
|
|
643
|
-
if (atom._update(nextValue)) {
|
|
644
|
-
const subs = atom.subs;
|
|
645
|
-
if (subs !== undefined) {
|
|
646
|
-
propagate(subs);
|
|
647
|
-
shallowPropagate(subs);
|
|
648
|
-
flush();
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* Creates a read-only atom whose value is loaded from an async getter.
|
|
655
|
-
*
|
|
656
|
-
* The getter receives an `AbortSignal`; when the async atom recomputes, the
|
|
657
|
-
* previous signal is aborted and stale resolutions are ignored.
|
|
658
|
-
*/
|
|
659
|
-
function createAsyncAtom(getValue, options) {
|
|
660
|
-
const ref = {};
|
|
661
|
-
let currentController;
|
|
662
|
-
let currentRunId = 0;
|
|
663
|
-
const atom = createAtom(() => {
|
|
664
|
-
currentController?.abort();
|
|
665
|
-
const controller = new AbortController();
|
|
666
|
-
const runId = ++currentRunId;
|
|
667
|
-
currentController = controller;
|
|
668
|
-
getValue({
|
|
669
|
-
signal: controller.signal
|
|
670
|
-
}).then(data => {
|
|
671
|
-
if (runId !== currentRunId || controller.signal.aborted) {
|
|
672
|
-
return;
|
|
673
|
-
}
|
|
674
|
-
updateAsyncAtom(ref.current, {
|
|
675
|
-
status: 'done',
|
|
676
|
-
data
|
|
677
|
-
});
|
|
678
|
-
}, error => {
|
|
679
|
-
if (runId !== currentRunId || controller.signal.aborted) {
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
updateAsyncAtom(ref.current, {
|
|
683
|
-
status: 'error',
|
|
684
|
-
error
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
return {
|
|
688
|
-
status: 'pending'
|
|
689
|
-
};
|
|
690
|
-
}, {
|
|
691
|
-
compare: compareAsyncAtomState,
|
|
692
|
-
...options
|
|
693
|
-
});
|
|
694
|
-
ref.current = atom;
|
|
695
|
-
return atom;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
/**
|
|
699
|
-
* Mirror atoms that bump a version whenever a tracked actor emits a snapshot,
|
|
700
|
-
* letting computed atoms depend on `actor.get()` reads.
|
|
701
|
-
*
|
|
702
|
-
* The hook is installed lazily on first atom creation (not at module
|
|
703
|
-
* evaluation) so that it remains tree-shakeable for apps that never use atoms —
|
|
704
|
-
* any tracked read necessarily happens inside an atom computation, so first-use
|
|
705
|
-
* installation is always early enough.
|
|
706
|
-
*/
|
|
707
|
-
let actorInteropInstalled = false;
|
|
708
|
-
function ensureActorInterop() {
|
|
709
|
-
if (actorInteropInstalled) {
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
actorInteropInstalled = true;
|
|
713
|
-
const actorVersions = new WeakMap();
|
|
714
|
-
installActorReadHook(actorRef => {
|
|
715
|
-
if (activeSub === undefined) {
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
718
|
-
let version = actorVersions.get(actorRef);
|
|
719
|
-
if (version === undefined) {
|
|
720
|
-
version = createAtom(0);
|
|
721
|
-
actorVersions.set(actorRef, version);
|
|
722
|
-
actorRef.subscribe({
|
|
723
|
-
next: () => version.set(v => v + 1),
|
|
724
|
-
error: () => {}
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
version.get();
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
/**
|
|
732
|
-
* Creates an atom.
|
|
733
|
-
*
|
|
734
|
-
* Pass a value for a writable atom or a getter for a computed read-only atom.
|
|
735
|
-
*/
|
|
736
|
-
|
|
737
|
-
function createAtom(valueOrFn, optionsOrInput) {
|
|
738
|
-
ensureReactiveSystem();
|
|
739
|
-
ensureActorInterop();
|
|
740
|
-
const isComputed = typeof valueOrFn === 'function';
|
|
741
|
-
const getter = valueOrFn;
|
|
742
|
-
|
|
743
|
-
// Create plain object atom
|
|
744
|
-
const atom = {
|
|
745
|
-
_snapshot: isComputed ? undefined : valueOrFn,
|
|
746
|
-
subs: undefined,
|
|
747
|
-
subsTail: undefined,
|
|
748
|
-
deps: undefined,
|
|
749
|
-
depsTail: undefined,
|
|
750
|
-
flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,
|
|
751
|
-
get() {
|
|
752
|
-
if (activeSub !== undefined) {
|
|
753
|
-
link(atom, activeSub, cycle);
|
|
754
|
-
}
|
|
755
|
-
return atom._snapshot;
|
|
756
|
-
},
|
|
757
|
-
subscribe(observerOrFn) {
|
|
758
|
-
const observer = typeof observerOrFn === 'function' ? {
|
|
759
|
-
next: observerOrFn
|
|
760
|
-
} : observerOrFn;
|
|
761
|
-
const observed = {
|
|
762
|
-
current: false
|
|
763
|
-
};
|
|
764
|
-
const e = effect(() => {
|
|
765
|
-
atom.get();
|
|
766
|
-
if (!observed.current) {
|
|
767
|
-
observed.current = true;
|
|
768
|
-
} else {
|
|
769
|
-
const prevSub = activeSub;
|
|
770
|
-
activeSub = undefined;
|
|
771
|
-
try {
|
|
772
|
-
observer.next?.(atom._snapshot);
|
|
773
|
-
} catch (err) {
|
|
774
|
-
reportUnhandledError(err);
|
|
775
|
-
} finally {
|
|
776
|
-
activeSub = prevSub;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// If the observer synchronously updates any of our deps we'll be
|
|
780
|
-
// marked as dirty preventing this effect from re-running. Request
|
|
781
|
-
// the value again to reconcile any dirty deps.
|
|
782
|
-
atom.get();
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
return {
|
|
786
|
-
unsubscribe: () => {
|
|
787
|
-
e.stop();
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
},
|
|
791
|
-
_update(getValue) {
|
|
792
|
-
const prevSub = activeSub;
|
|
793
|
-
const compare = optionsOrInput?.compare ?? Object.is;
|
|
794
|
-
activeSub = atom;
|
|
795
|
-
++cycle;
|
|
796
|
-
atom.depsTail = undefined;
|
|
797
|
-
if (isComputed) {
|
|
798
|
-
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;
|
|
799
|
-
}
|
|
800
|
-
try {
|
|
801
|
-
const oldValue = atom._snapshot;
|
|
802
|
-
const newValue = typeof getValue === 'function' ? getValue(oldValue) : getValue === undefined && isComputed ? getter(oldValue) : getValue;
|
|
803
|
-
if (oldValue === undefined || !compare(oldValue, newValue)) {
|
|
804
|
-
atom._snapshot = newValue;
|
|
805
|
-
return true;
|
|
806
|
-
}
|
|
807
|
-
return false;
|
|
808
|
-
} finally {
|
|
809
|
-
activeSub = prevSub;
|
|
810
|
-
if (isComputed) {
|
|
811
|
-
atom.flags &= ~ReactiveFlags.RecursedCheck;
|
|
812
|
-
}
|
|
813
|
-
purgeDeps(atom);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
};
|
|
817
|
-
if (isComputed) {
|
|
818
|
-
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
|
|
819
|
-
atom.get = function () {
|
|
820
|
-
const flags = atom.flags;
|
|
821
|
-
if (flags & ReactiveFlags.Dirty || flags & ReactiveFlags.Pending && checkDirty(atom.deps, atom)) {
|
|
822
|
-
if (atom._update()) {
|
|
823
|
-
const subs = atom.subs;
|
|
824
|
-
if (subs !== undefined) {
|
|
825
|
-
shallowPropagate(subs);
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
} else if (flags & ReactiveFlags.Pending) {
|
|
829
|
-
atom.flags = flags & ~ReactiveFlags.Pending;
|
|
830
|
-
}
|
|
831
|
-
if (activeSub !== undefined) {
|
|
832
|
-
link(atom, activeSub, cycle);
|
|
833
|
-
}
|
|
834
|
-
return atom._snapshot;
|
|
835
|
-
};
|
|
836
|
-
} else {
|
|
837
|
-
atom.set = function (valueOrFn) {
|
|
838
|
-
if (atom._update(valueOrFn)) {
|
|
839
|
-
const subs = atom.subs;
|
|
840
|
-
if (subs !== undefined) {
|
|
841
|
-
propagate(subs);
|
|
842
|
-
shallowPropagate(subs);
|
|
843
|
-
flush();
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
};
|
|
847
|
-
}
|
|
848
|
-
atom[$$atom] = true;
|
|
849
|
-
return atom;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
/**
|
|
853
|
-
* Creates an inert atom config that can be instantiated later.
|
|
854
|
-
*
|
|
855
|
-
* Useful for framework hooks that need to create a stable local atom from
|
|
856
|
-
* component input.
|
|
857
|
-
*/
|
|
858
|
-
|
|
859
|
-
function createAtomConfig(initialValueOrFn, options) {
|
|
860
|
-
return {
|
|
861
|
-
createAtom(input) {
|
|
862
|
-
const initialValue = typeof initialValueOrFn === 'function' ? initialValueOrFn(input) : initialValueOrFn;
|
|
863
|
-
return createAtom(initialValue, options);
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
/** Creates an atom whose updates are handled by a reducer function. */
|
|
869
|
-
function createReducerAtom(initialValue, reducer, options) {
|
|
870
|
-
const atom = createAtom(initialValue, options);
|
|
871
|
-
return {
|
|
872
|
-
[$$atom]: true,
|
|
873
|
-
get: atom.get.bind(atom),
|
|
874
|
-
subscribe: atom.subscribe.bind(atom),
|
|
875
|
-
send(event) {
|
|
876
|
-
const prevSub = activeSub;
|
|
877
|
-
activeSub = undefined;
|
|
878
|
-
let nextState;
|
|
879
|
-
try {
|
|
880
|
-
nextState = reducer(atom.get(), event);
|
|
881
|
-
} finally {
|
|
882
|
-
activeSub = prevSub;
|
|
883
|
-
}
|
|
884
|
-
atom.set(nextState);
|
|
885
|
-
}
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
function effect(fn) {
|
|
889
|
-
const run = () => {
|
|
890
|
-
const prevSub = activeSub;
|
|
891
|
-
activeSub = effectObj;
|
|
892
|
-
++cycle;
|
|
893
|
-
effectObj.depsTail = undefined;
|
|
894
|
-
effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck;
|
|
895
|
-
try {
|
|
896
|
-
return fn();
|
|
897
|
-
} finally {
|
|
898
|
-
activeSub = prevSub;
|
|
899
|
-
effectObj.flags &= ~ReactiveFlags.RecursedCheck;
|
|
900
|
-
purgeDeps(effectObj);
|
|
901
|
-
}
|
|
902
|
-
};
|
|
903
|
-
const effectObj = {
|
|
904
|
-
deps: undefined,
|
|
905
|
-
depsTail: undefined,
|
|
906
|
-
subs: undefined,
|
|
907
|
-
subsTail: undefined,
|
|
908
|
-
flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,
|
|
909
|
-
notify() {
|
|
910
|
-
const flags = this.flags;
|
|
911
|
-
if (flags & ReactiveFlags.Dirty || flags & ReactiveFlags.Pending && checkDirty(this.deps, this)) {
|
|
912
|
-
run();
|
|
913
|
-
} else {
|
|
914
|
-
this.flags = ReactiveFlags.Watching;
|
|
915
|
-
}
|
|
916
|
-
},
|
|
917
|
-
stop() {
|
|
918
|
-
this.flags = ReactiveFlags.None;
|
|
919
|
-
this.depsTail = undefined;
|
|
920
|
-
purgeDeps(this);
|
|
921
|
-
}
|
|
922
|
-
};
|
|
923
|
-
run();
|
|
924
|
-
return effectObj;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
299
|
/**
|
|
928
300
|
* Creates actor logic for subscribing to lifecycle events (done/error/snapshot)
|
|
929
301
|
* from another actor. Used internally by `enq.subscribeTo()`.
|
|
@@ -941,15 +313,6 @@ function createSubscriptionLogic() {
|
|
|
941
313
|
error,
|
|
942
314
|
snapshot: onSnapshot
|
|
943
315
|
} = mappers;
|
|
944
|
-
|
|
945
|
-
// Atoms emit a raw value (no `status`) and have no done/error lifecycle —
|
|
946
|
-
// pass the value straight to the `snapshot` mapper.
|
|
947
|
-
if (isAtom(actor)) {
|
|
948
|
-
if (!onSnapshot) {
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
return actor.subscribe(value => relayMappedToParent(self, system, () => onSnapshot(value)));
|
|
952
|
-
}
|
|
953
316
|
return actor.subscribe({
|
|
954
317
|
next: snapshot => {
|
|
955
318
|
if (snapshot.status === 'done' && done) {
|
|
@@ -1517,27 +880,13 @@ function formatRouteTransitions(rootStateNode) {
|
|
|
1517
880
|
if ('$unserializable' in routeConfig) {
|
|
1518
881
|
throw new Error(`State "${sn.id}" has a route that is not serializable. Re-provide the route function when reviving this machine.`);
|
|
1519
882
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
const userGuard = routeConfig.guard;
|
|
883
|
+
const {
|
|
884
|
+
guard: _guard,
|
|
885
|
+
...routeOptions
|
|
886
|
+
} = routeConfig;
|
|
1525
887
|
const transition = {
|
|
1526
|
-
...
|
|
1527
|
-
guard:
|
|
1528
|
-
if (!routeMatches(args)) return false;
|
|
1529
|
-
if (typeof userGuard === 'function') return userGuard(args);
|
|
1530
|
-
if (typeof userGuard === 'string') {
|
|
1531
|
-
const guardImpl = args.guards?.[userGuard];
|
|
1532
|
-
if (!guardImpl) {
|
|
1533
|
-
// A typo'd guard name must fail loudly — silently passing
|
|
1534
|
-
// would allow the route and corrupt machine behavior.
|
|
1535
|
-
throw new Error(`Guard '${userGuard}' is not implemented in machine '${rootStateNode.machine.id}'. Available guards: ${Object.keys(args.guards ?? {}).map(key => `'${key}'`).join(', ') || '(none)'}.` );
|
|
1536
|
-
}
|
|
1537
|
-
return guardImpl(args);
|
|
1538
|
-
}
|
|
1539
|
-
return true;
|
|
1540
|
-
} : routeMatches,
|
|
888
|
+
...routeOptions,
|
|
889
|
+
guard: routeMatches,
|
|
1541
890
|
target: `#${routeId}`
|
|
1542
891
|
};
|
|
1543
892
|
routeTransitions.push(formatTransition(rootStateNode, 'xstate.route', transition));
|
|
@@ -2535,24 +1884,7 @@ function evaluateCandidate(candidate, event, snapshot, stateNode, self) {
|
|
|
2535
1884
|
delays: stateNode.machine.implementations.delays,
|
|
2536
1885
|
_snapshot: snapshot
|
|
2537
1886
|
};
|
|
2538
|
-
|
|
2539
|
-
const guardParams = typeof guardConfig?.params === 'function' ? guardConfig.params({
|
|
2540
|
-
context: snapshot.context,
|
|
2541
|
-
event
|
|
2542
|
-
}) : guardConfig?.params;
|
|
2543
|
-
let guardPassed = true;
|
|
2544
|
-
if (typeof guardConfig === 'function') {
|
|
2545
|
-
guardPassed = guardConfig(guardArgs, guardParams);
|
|
2546
|
-
} else if (typeof guardConfig?.type === 'string') {
|
|
2547
|
-
const guardImpl = stateNode.machine.implementations.guards[guardConfig.type];
|
|
2548
|
-
if (!guardImpl) {
|
|
2549
|
-
// A typo'd guard name must fail loudly — silently passing would
|
|
2550
|
-
// take the guarded transition and corrupt machine behavior.
|
|
2551
|
-
throw new Error(`Guard '${guardConfig.type}' is not implemented in machine '${stateNode.machine.id}'. Available guards: ${Object.keys(stateNode.machine.implementations.guards).map(key => `'${key}'`).join(', ') || '(none)'}.` );
|
|
2552
|
-
}
|
|
2553
|
-
guardPassed = guardImpl(guardArgs, guardParams);
|
|
2554
|
-
}
|
|
2555
|
-
if (!guardPassed) {
|
|
1887
|
+
if (!candidate.guard(guardArgs)) {
|
|
2556
1888
|
return false;
|
|
2557
1889
|
}
|
|
2558
1890
|
}
|
|
@@ -3854,7 +3186,7 @@ class Actor {
|
|
|
3854
3186
|
complete: observer.complete
|
|
3855
3187
|
});
|
|
3856
3188
|
},
|
|
3857
|
-
get: () => selector(this.
|
|
3189
|
+
get: () => selector(this.getSnapshot())
|
|
3858
3190
|
};
|
|
3859
3191
|
}
|
|
3860
3192
|
|
|
@@ -4143,15 +3475,9 @@ class Actor {
|
|
|
4143
3475
|
* @see {@link Actor.getPersistedSnapshot} to persist the internal state of an actor (which is more than just a snapshot).
|
|
4144
3476
|
*/
|
|
4145
3477
|
getSnapshot() {
|
|
4146
|
-
return this.get();
|
|
4147
|
-
}
|
|
4148
|
-
|
|
4149
|
-
/** Read the actor's current snapshot as an atom value. */
|
|
4150
|
-
get() {
|
|
4151
3478
|
if (!this._snapshot) {
|
|
4152
3479
|
throw new Error(`Snapshot can't be read while the actor initializes itself`);
|
|
4153
3480
|
}
|
|
4154
|
-
onActorRead?.(this);
|
|
4155
3481
|
return this._snapshot;
|
|
4156
3482
|
}
|
|
4157
3483
|
}
|
|
@@ -4956,10 +4282,7 @@ exports.TimeoutError = TimeoutError;
|
|
|
4956
4282
|
exports.XSTATE_INIT = XSTATE_INIT;
|
|
4957
4283
|
exports.checkStateIn = checkStateIn;
|
|
4958
4284
|
exports.createActor = createActor;
|
|
4959
|
-
exports.createAsyncAtom = createAsyncAtom;
|
|
4960
4285
|
exports.createAsyncLogic = createAsyncLogic;
|
|
4961
|
-
exports.createAtom = createAtom;
|
|
4962
|
-
exports.createAtomConfig = createAtomConfig;
|
|
4963
4286
|
exports.createCallbackLogic = createCallbackLogic;
|
|
4964
4287
|
exports.createEmptyActor = createEmptyActor;
|
|
4965
4288
|
exports.createEventObservableLogic = createEventObservableLogic;
|
|
@@ -4970,7 +4293,6 @@ exports.createListenerLogic = createListenerLogic;
|
|
|
4970
4293
|
exports.createLogic = createLogic;
|
|
4971
4294
|
exports.createMachineSnapshot = createMachineSnapshot;
|
|
4972
4295
|
exports.createObservableLogic = createObservableLogic;
|
|
4973
|
-
exports.createReducerAtom = createReducerAtom;
|
|
4974
4296
|
exports.createSubscriptionLogic = createSubscriptionLogic;
|
|
4975
4297
|
exports.evaluateCandidate = evaluateCandidate;
|
|
4976
4298
|
exports.formatRouteTransitions = formatRouteTransitions;
|
|
@@ -4984,7 +4306,6 @@ exports.getProperAncestors = getProperAncestors;
|
|
|
4984
4306
|
exports.getStateNodeByPath = getStateNodeByPath;
|
|
4985
4307
|
exports.getStateNodes = getStateNodes;
|
|
4986
4308
|
exports.initialMicrostep = initialMicrostep;
|
|
4987
|
-
exports.isAtom = isAtom;
|
|
4988
4309
|
exports.isAtomicStateNode = isAtomicStateNode;
|
|
4989
4310
|
exports.isInFinalState = isInFinalState;
|
|
4990
4311
|
exports.isMachineSnapshot = isMachineSnapshot;
|