xstate 5.0.0-beta.32 → 5.0.0-beta.34
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/actions/dist/xstate-actions.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.esm.js +3 -3
- package/actions/dist/xstate-actions.esm.js +3 -3
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.js +31 -20
- package/actors/dist/xstate-actors.development.cjs.js +31 -20
- package/actors/dist/xstate-actors.development.esm.js +31 -20
- package/actors/dist/xstate-actors.esm.js +31 -20
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/interpreter.d.ts +1 -1
- package/dist/declarations/src/stateUtils.d.ts +2 -2
- package/dist/declarations/src/system.d.ts +22 -0
- package/dist/declarations/src/types.d.ts +4 -5
- package/dist/declarations/src/utils.d.ts +0 -1
- package/dist/{interpreter-05e11c15.cjs.js → interpreter-1301970f.cjs.js} +77 -32
- package/dist/{interpreter-a2236840.development.cjs.js → interpreter-70ed62f2.development.cjs.js} +80 -32
- package/dist/{interpreter-d5fa7ce0.esm.js → interpreter-83f7f2d4.esm.js} +78 -33
- package/dist/{interpreter-e4d2487f.development.esm.js → interpreter-dee56dc8.development.esm.js} +81 -33
- package/dist/{raise-6fbd4513.development.esm.js → raise-05f8b2a6.development.esm.js} +52 -33
- package/dist/{raise-90808d65.cjs.js → raise-1dd65455.cjs.js} +52 -33
- package/dist/{raise-b4bfe138.development.cjs.js → raise-38b707c0.development.cjs.js} +52 -33
- package/dist/{raise-6a68d0cc.esm.js → raise-b5cfe1bb.esm.js} +52 -33
- package/dist/{send-e5f0f3f6.esm.js → send-0b5eda0c.esm.js} +15 -9
- package/dist/{send-4163d2af.development.cjs.js → send-3764c866.development.cjs.js} +15 -9
- package/dist/{send-7baeedcb.development.esm.js → send-9526366e.development.esm.js} +15 -9
- package/dist/{send-72e85cc6.cjs.js → send-fe94de2b.cjs.js} +15 -9
- package/dist/xstate.cjs.js +6 -31
- package/dist/xstate.development.cjs.js +6 -31
- package/dist/xstate.development.esm.js +9 -34
- package/dist/xstate.esm.js +9 -34
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.esm.js +2 -2
- package/guards/dist/xstate-guards.esm.js +2 -2
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -149,13 +149,14 @@ function reportUnhandledError(err) {
|
|
|
149
149
|
|
|
150
150
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
let idCounter = 0;
|
|
153
|
+
function createSystem(rootActor) {
|
|
154
154
|
const children = new Map();
|
|
155
155
|
const keyedActors = new Map();
|
|
156
156
|
const reverseKeyedActors = new WeakMap();
|
|
157
|
+
const observers = new Set();
|
|
157
158
|
const system = {
|
|
158
|
-
_bookId: () => `x:${
|
|
159
|
+
_bookId: () => `x:${idCounter++}`,
|
|
159
160
|
_register: (sessionId, actorRef) => {
|
|
160
161
|
children.set(sessionId, actorRef);
|
|
161
162
|
return sessionId;
|
|
@@ -178,6 +179,25 @@ function createSystem() {
|
|
|
178
179
|
}
|
|
179
180
|
keyedActors.set(systemId, actorRef);
|
|
180
181
|
reverseKeyedActors.set(actorRef, systemId);
|
|
182
|
+
},
|
|
183
|
+
inspect: observer => {
|
|
184
|
+
observers.add(observer);
|
|
185
|
+
},
|
|
186
|
+
_sendInspectionEvent: event => {
|
|
187
|
+
const resolvedInspectionEvent = {
|
|
188
|
+
...event,
|
|
189
|
+
rootId: rootActor.sessionId
|
|
190
|
+
};
|
|
191
|
+
observers.forEach(observer => observer.next?.(resolvedInspectionEvent));
|
|
192
|
+
},
|
|
193
|
+
_relay: (source, target, event) => {
|
|
194
|
+
system._sendInspectionEvent({
|
|
195
|
+
type: '@xstate.event',
|
|
196
|
+
sourceRef: source,
|
|
197
|
+
targetRef: target,
|
|
198
|
+
event
|
|
199
|
+
});
|
|
200
|
+
target._send(event);
|
|
181
201
|
}
|
|
182
202
|
};
|
|
183
203
|
return system;
|
|
@@ -405,10 +425,14 @@ class Actor {
|
|
|
405
425
|
logger,
|
|
406
426
|
parent,
|
|
407
427
|
id,
|
|
408
|
-
systemId
|
|
428
|
+
systemId,
|
|
429
|
+
inspect
|
|
409
430
|
} = resolvedOptions;
|
|
410
|
-
|
|
411
|
-
|
|
431
|
+
this.system = parent?.system ?? createSystem(this);
|
|
432
|
+
if (inspect && !parent) {
|
|
433
|
+
// Always inspect at the system-level
|
|
434
|
+
this.system.inspect(toObserver(inspect));
|
|
435
|
+
}
|
|
412
436
|
if (systemId) {
|
|
413
437
|
this._systemId = systemId;
|
|
414
438
|
this.system._set(systemId, this);
|
|
@@ -422,7 +446,7 @@ class Actor {
|
|
|
422
446
|
this.src = resolvedOptions.src;
|
|
423
447
|
this.ref = this;
|
|
424
448
|
this._actorContext = {
|
|
425
|
-
self,
|
|
449
|
+
self: this,
|
|
426
450
|
id: this.id,
|
|
427
451
|
sessionId: this.sessionId,
|
|
428
452
|
logger: this.logger,
|
|
@@ -441,6 +465,10 @@ class Actor {
|
|
|
441
465
|
// Ensure that the send method is bound to this Actor instance
|
|
442
466
|
// if destructured
|
|
443
467
|
this.send = this.send.bind(this);
|
|
468
|
+
this.system._sendInspectionEvent({
|
|
469
|
+
type: '@xstate.actor',
|
|
470
|
+
actorRef: this
|
|
471
|
+
});
|
|
444
472
|
this._initState();
|
|
445
473
|
}
|
|
446
474
|
_initState() {
|
|
@@ -449,7 +477,7 @@ class Actor {
|
|
|
449
477
|
|
|
450
478
|
// array of functions to defer
|
|
451
479
|
|
|
452
|
-
update(snapshot) {
|
|
480
|
+
update(snapshot, event) {
|
|
453
481
|
// Update state
|
|
454
482
|
this._state = snapshot;
|
|
455
483
|
|
|
@@ -471,14 +499,24 @@ class Actor {
|
|
|
471
499
|
this._stopProcedure();
|
|
472
500
|
this._complete();
|
|
473
501
|
this._doneEvent = createDoneActorEvent(this.id, this._state.output);
|
|
474
|
-
this._parent
|
|
502
|
+
if (this._parent) {
|
|
503
|
+
this.system._relay(this, this._parent, this._doneEvent);
|
|
504
|
+
}
|
|
475
505
|
break;
|
|
476
506
|
case 'error':
|
|
477
507
|
this._stopProcedure();
|
|
478
508
|
this._error(this._state.error);
|
|
479
|
-
this._parent
|
|
509
|
+
if (this._parent) {
|
|
510
|
+
this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
|
|
511
|
+
}
|
|
480
512
|
break;
|
|
481
513
|
}
|
|
514
|
+
this.system._sendInspectionEvent({
|
|
515
|
+
type: '@xstate.snapshot',
|
|
516
|
+
actorRef: this,
|
|
517
|
+
event,
|
|
518
|
+
snapshot
|
|
519
|
+
});
|
|
482
520
|
}
|
|
483
521
|
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
484
522
|
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
@@ -511,12 +549,19 @@ class Actor {
|
|
|
511
549
|
this.system._set(this._systemId, this);
|
|
512
550
|
}
|
|
513
551
|
this.status = ActorStatus.Running;
|
|
552
|
+
const initEvent = createInitEvent(this.options.input);
|
|
553
|
+
this.system._sendInspectionEvent({
|
|
554
|
+
type: '@xstate.event',
|
|
555
|
+
sourceRef: this._parent,
|
|
556
|
+
targetRef: this,
|
|
557
|
+
event: initEvent
|
|
558
|
+
});
|
|
514
559
|
const status = this._state.status;
|
|
515
560
|
switch (status) {
|
|
516
561
|
case 'done':
|
|
517
|
-
// a state machine can be "done" upon
|
|
562
|
+
// a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
|
|
518
563
|
// we still need to complete observers, flush deferreds etc
|
|
519
|
-
this.update(this._state);
|
|
564
|
+
this.update(this._state, initEvent);
|
|
520
565
|
// fallthrough
|
|
521
566
|
case 'error':
|
|
522
567
|
// TODO: rethink cleanup of observers, mailbox, etc
|
|
@@ -536,7 +581,7 @@ class Actor {
|
|
|
536
581
|
// TODO: this notifies all subscribers but usually this is redundant
|
|
537
582
|
// there is no real change happening here
|
|
538
583
|
// we need to rethink if this needs to be refactored
|
|
539
|
-
this.update(this._state);
|
|
584
|
+
this.update(this._state, initEvent);
|
|
540
585
|
if (this.options.devTools) {
|
|
541
586
|
this.attachDevTools();
|
|
542
587
|
}
|
|
@@ -564,7 +609,7 @@ class Actor {
|
|
|
564
609
|
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
565
610
|
return;
|
|
566
611
|
}
|
|
567
|
-
this.update(nextState);
|
|
612
|
+
this.update(nextState, event);
|
|
568
613
|
if (event.type === XSTATE_STOP) {
|
|
569
614
|
this._stopProcedure();
|
|
570
615
|
this._complete();
|
|
@@ -650,33 +695,33 @@ class Actor {
|
|
|
650
695
|
}
|
|
651
696
|
|
|
652
697
|
/**
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
* @param event The event to send
|
|
698
|
+
* @internal
|
|
656
699
|
*/
|
|
657
|
-
|
|
658
|
-
if (typeof event === 'string') {
|
|
659
|
-
throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
|
|
660
|
-
}
|
|
700
|
+
_send(event) {
|
|
661
701
|
if (this.status === ActorStatus.Stopped) {
|
|
662
702
|
return;
|
|
663
703
|
}
|
|
664
704
|
this.mailbox.enqueue(event);
|
|
665
705
|
}
|
|
666
706
|
|
|
707
|
+
/**
|
|
708
|
+
* Sends an event to the running Actor to trigger a transition.
|
|
709
|
+
*
|
|
710
|
+
* @param event The event to send
|
|
711
|
+
*/
|
|
712
|
+
send(event) {
|
|
713
|
+
this.system._relay(undefined, this, event);
|
|
714
|
+
}
|
|
715
|
+
|
|
667
716
|
// TODO: make private (and figure out a way to do this within the machine)
|
|
668
|
-
delaySend({
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
717
|
+
delaySend(params) {
|
|
718
|
+
const {
|
|
719
|
+
event,
|
|
720
|
+
id,
|
|
721
|
+
delay
|
|
722
|
+
} = params;
|
|
674
723
|
const timerId = this.clock.setTimeout(() => {
|
|
675
|
-
|
|
676
|
-
to.send(event);
|
|
677
|
-
} else {
|
|
678
|
-
this.send(event);
|
|
679
|
-
}
|
|
724
|
+
this.system._relay(this, params.to ?? this, event);
|
|
680
725
|
}, delay);
|
|
681
726
|
|
|
682
727
|
// TODO: consider the rehydration story here
|
package/dist/{interpreter-a2236840.development.cjs.js → interpreter-70ed62f2.development.cjs.js}
RENAMED
|
@@ -149,13 +149,14 @@ function reportUnhandledError(err) {
|
|
|
149
149
|
|
|
150
150
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
let idCounter = 0;
|
|
153
|
+
function createSystem(rootActor) {
|
|
154
154
|
const children = new Map();
|
|
155
155
|
const keyedActors = new Map();
|
|
156
156
|
const reverseKeyedActors = new WeakMap();
|
|
157
|
+
const observers = new Set();
|
|
157
158
|
const system = {
|
|
158
|
-
_bookId: () => `x:${
|
|
159
|
+
_bookId: () => `x:${idCounter++}`,
|
|
159
160
|
_register: (sessionId, actorRef) => {
|
|
160
161
|
children.set(sessionId, actorRef);
|
|
161
162
|
return sessionId;
|
|
@@ -178,6 +179,25 @@ function createSystem() {
|
|
|
178
179
|
}
|
|
179
180
|
keyedActors.set(systemId, actorRef);
|
|
180
181
|
reverseKeyedActors.set(actorRef, systemId);
|
|
182
|
+
},
|
|
183
|
+
inspect: observer => {
|
|
184
|
+
observers.add(observer);
|
|
185
|
+
},
|
|
186
|
+
_sendInspectionEvent: event => {
|
|
187
|
+
const resolvedInspectionEvent = {
|
|
188
|
+
...event,
|
|
189
|
+
rootId: rootActor.sessionId
|
|
190
|
+
};
|
|
191
|
+
observers.forEach(observer => observer.next?.(resolvedInspectionEvent));
|
|
192
|
+
},
|
|
193
|
+
_relay: (source, target, event) => {
|
|
194
|
+
system._sendInspectionEvent({
|
|
195
|
+
type: '@xstate.event',
|
|
196
|
+
sourceRef: source,
|
|
197
|
+
targetRef: target,
|
|
198
|
+
event
|
|
199
|
+
});
|
|
200
|
+
target._send(event);
|
|
181
201
|
}
|
|
182
202
|
};
|
|
183
203
|
return system;
|
|
@@ -408,10 +428,14 @@ class Actor {
|
|
|
408
428
|
logger,
|
|
409
429
|
parent,
|
|
410
430
|
id,
|
|
411
|
-
systemId
|
|
431
|
+
systemId,
|
|
432
|
+
inspect
|
|
412
433
|
} = resolvedOptions;
|
|
413
|
-
|
|
414
|
-
|
|
434
|
+
this.system = parent?.system ?? createSystem(this);
|
|
435
|
+
if (inspect && !parent) {
|
|
436
|
+
// Always inspect at the system-level
|
|
437
|
+
this.system.inspect(toObserver(inspect));
|
|
438
|
+
}
|
|
415
439
|
if (systemId) {
|
|
416
440
|
this._systemId = systemId;
|
|
417
441
|
this.system._set(systemId, this);
|
|
@@ -425,7 +449,7 @@ class Actor {
|
|
|
425
449
|
this.src = resolvedOptions.src;
|
|
426
450
|
this.ref = this;
|
|
427
451
|
this._actorContext = {
|
|
428
|
-
self,
|
|
452
|
+
self: this,
|
|
429
453
|
id: this.id,
|
|
430
454
|
sessionId: this.sessionId,
|
|
431
455
|
logger: this.logger,
|
|
@@ -444,6 +468,10 @@ class Actor {
|
|
|
444
468
|
// Ensure that the send method is bound to this Actor instance
|
|
445
469
|
// if destructured
|
|
446
470
|
this.send = this.send.bind(this);
|
|
471
|
+
this.system._sendInspectionEvent({
|
|
472
|
+
type: '@xstate.actor',
|
|
473
|
+
actorRef: this
|
|
474
|
+
});
|
|
447
475
|
this._initState();
|
|
448
476
|
}
|
|
449
477
|
_initState() {
|
|
@@ -452,7 +480,7 @@ class Actor {
|
|
|
452
480
|
|
|
453
481
|
// array of functions to defer
|
|
454
482
|
|
|
455
|
-
update(snapshot) {
|
|
483
|
+
update(snapshot, event) {
|
|
456
484
|
// Update state
|
|
457
485
|
this._state = snapshot;
|
|
458
486
|
|
|
@@ -474,14 +502,24 @@ class Actor {
|
|
|
474
502
|
this._stopProcedure();
|
|
475
503
|
this._complete();
|
|
476
504
|
this._doneEvent = createDoneActorEvent(this.id, this._state.output);
|
|
477
|
-
this._parent
|
|
505
|
+
if (this._parent) {
|
|
506
|
+
this.system._relay(this, this._parent, this._doneEvent);
|
|
507
|
+
}
|
|
478
508
|
break;
|
|
479
509
|
case 'error':
|
|
480
510
|
this._stopProcedure();
|
|
481
511
|
this._error(this._state.error);
|
|
482
|
-
this._parent
|
|
512
|
+
if (this._parent) {
|
|
513
|
+
this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
|
|
514
|
+
}
|
|
483
515
|
break;
|
|
484
516
|
}
|
|
517
|
+
this.system._sendInspectionEvent({
|
|
518
|
+
type: '@xstate.snapshot',
|
|
519
|
+
actorRef: this,
|
|
520
|
+
event,
|
|
521
|
+
snapshot
|
|
522
|
+
});
|
|
485
523
|
}
|
|
486
524
|
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
487
525
|
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
@@ -514,12 +552,19 @@ class Actor {
|
|
|
514
552
|
this.system._set(this._systemId, this);
|
|
515
553
|
}
|
|
516
554
|
this.status = ActorStatus.Running;
|
|
555
|
+
const initEvent = createInitEvent(this.options.input);
|
|
556
|
+
this.system._sendInspectionEvent({
|
|
557
|
+
type: '@xstate.event',
|
|
558
|
+
sourceRef: this._parent,
|
|
559
|
+
targetRef: this,
|
|
560
|
+
event: initEvent
|
|
561
|
+
});
|
|
517
562
|
const status = this._state.status;
|
|
518
563
|
switch (status) {
|
|
519
564
|
case 'done':
|
|
520
|
-
// a state machine can be "done" upon
|
|
565
|
+
// a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
|
|
521
566
|
// we still need to complete observers, flush deferreds etc
|
|
522
|
-
this.update(this._state);
|
|
567
|
+
this.update(this._state, initEvent);
|
|
523
568
|
// fallthrough
|
|
524
569
|
case 'error':
|
|
525
570
|
// TODO: rethink cleanup of observers, mailbox, etc
|
|
@@ -539,7 +584,7 @@ class Actor {
|
|
|
539
584
|
// TODO: this notifies all subscribers but usually this is redundant
|
|
540
585
|
// there is no real change happening here
|
|
541
586
|
// we need to rethink if this needs to be refactored
|
|
542
|
-
this.update(this._state);
|
|
587
|
+
this.update(this._state, initEvent);
|
|
543
588
|
if (this.options.devTools) {
|
|
544
589
|
this.attachDevTools();
|
|
545
590
|
}
|
|
@@ -567,7 +612,7 @@ class Actor {
|
|
|
567
612
|
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
568
613
|
return;
|
|
569
614
|
}
|
|
570
|
-
this.update(nextState);
|
|
615
|
+
this.update(nextState, event);
|
|
571
616
|
if (event.type === XSTATE_STOP) {
|
|
572
617
|
this._stopProcedure();
|
|
573
618
|
this._complete();
|
|
@@ -653,14 +698,9 @@ class Actor {
|
|
|
653
698
|
}
|
|
654
699
|
|
|
655
700
|
/**
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
* @param event The event to send
|
|
701
|
+
* @internal
|
|
659
702
|
*/
|
|
660
|
-
|
|
661
|
-
if (typeof event === 'string') {
|
|
662
|
-
throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
|
|
663
|
-
}
|
|
703
|
+
_send(event) {
|
|
664
704
|
if (this.status === ActorStatus.Stopped) {
|
|
665
705
|
// do nothing
|
|
666
706
|
{
|
|
@@ -672,19 +712,27 @@ class Actor {
|
|
|
672
712
|
this.mailbox.enqueue(event);
|
|
673
713
|
}
|
|
674
714
|
|
|
715
|
+
/**
|
|
716
|
+
* Sends an event to the running Actor to trigger a transition.
|
|
717
|
+
*
|
|
718
|
+
* @param event The event to send
|
|
719
|
+
*/
|
|
720
|
+
send(event) {
|
|
721
|
+
if (typeof event === 'string') {
|
|
722
|
+
throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
|
|
723
|
+
}
|
|
724
|
+
this.system._relay(undefined, this, event);
|
|
725
|
+
}
|
|
726
|
+
|
|
675
727
|
// TODO: make private (and figure out a way to do this within the machine)
|
|
676
|
-
delaySend({
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
728
|
+
delaySend(params) {
|
|
729
|
+
const {
|
|
730
|
+
event,
|
|
731
|
+
id,
|
|
732
|
+
delay
|
|
733
|
+
} = params;
|
|
682
734
|
const timerId = this.clock.setTimeout(() => {
|
|
683
|
-
|
|
684
|
-
to.send(event);
|
|
685
|
-
} else {
|
|
686
|
-
this.send(event);
|
|
687
|
-
}
|
|
735
|
+
this.system._relay(this, params.to ?? this, event);
|
|
688
736
|
}, delay);
|
|
689
737
|
|
|
690
738
|
// TODO: consider the rehydration story here
|
|
@@ -147,13 +147,14 @@ function reportUnhandledError(err) {
|
|
|
147
147
|
|
|
148
148
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
let idCounter = 0;
|
|
151
|
+
function createSystem(rootActor) {
|
|
152
152
|
const children = new Map();
|
|
153
153
|
const keyedActors = new Map();
|
|
154
154
|
const reverseKeyedActors = new WeakMap();
|
|
155
|
+
const observers = new Set();
|
|
155
156
|
const system = {
|
|
156
|
-
_bookId: () => `x:${
|
|
157
|
+
_bookId: () => `x:${idCounter++}`,
|
|
157
158
|
_register: (sessionId, actorRef) => {
|
|
158
159
|
children.set(sessionId, actorRef);
|
|
159
160
|
return sessionId;
|
|
@@ -176,6 +177,25 @@ function createSystem() {
|
|
|
176
177
|
}
|
|
177
178
|
keyedActors.set(systemId, actorRef);
|
|
178
179
|
reverseKeyedActors.set(actorRef, systemId);
|
|
180
|
+
},
|
|
181
|
+
inspect: observer => {
|
|
182
|
+
observers.add(observer);
|
|
183
|
+
},
|
|
184
|
+
_sendInspectionEvent: event => {
|
|
185
|
+
const resolvedInspectionEvent = {
|
|
186
|
+
...event,
|
|
187
|
+
rootId: rootActor.sessionId
|
|
188
|
+
};
|
|
189
|
+
observers.forEach(observer => observer.next?.(resolvedInspectionEvent));
|
|
190
|
+
},
|
|
191
|
+
_relay: (source, target, event) => {
|
|
192
|
+
system._sendInspectionEvent({
|
|
193
|
+
type: '@xstate.event',
|
|
194
|
+
sourceRef: source,
|
|
195
|
+
targetRef: target,
|
|
196
|
+
event
|
|
197
|
+
});
|
|
198
|
+
target._send(event);
|
|
179
199
|
}
|
|
180
200
|
};
|
|
181
201
|
return system;
|
|
@@ -403,10 +423,14 @@ class Actor {
|
|
|
403
423
|
logger,
|
|
404
424
|
parent,
|
|
405
425
|
id,
|
|
406
|
-
systemId
|
|
426
|
+
systemId,
|
|
427
|
+
inspect
|
|
407
428
|
} = resolvedOptions;
|
|
408
|
-
|
|
409
|
-
|
|
429
|
+
this.system = parent?.system ?? createSystem(this);
|
|
430
|
+
if (inspect && !parent) {
|
|
431
|
+
// Always inspect at the system-level
|
|
432
|
+
this.system.inspect(toObserver(inspect));
|
|
433
|
+
}
|
|
410
434
|
if (systemId) {
|
|
411
435
|
this._systemId = systemId;
|
|
412
436
|
this.system._set(systemId, this);
|
|
@@ -420,7 +444,7 @@ class Actor {
|
|
|
420
444
|
this.src = resolvedOptions.src;
|
|
421
445
|
this.ref = this;
|
|
422
446
|
this._actorContext = {
|
|
423
|
-
self,
|
|
447
|
+
self: this,
|
|
424
448
|
id: this.id,
|
|
425
449
|
sessionId: this.sessionId,
|
|
426
450
|
logger: this.logger,
|
|
@@ -439,6 +463,10 @@ class Actor {
|
|
|
439
463
|
// Ensure that the send method is bound to this Actor instance
|
|
440
464
|
// if destructured
|
|
441
465
|
this.send = this.send.bind(this);
|
|
466
|
+
this.system._sendInspectionEvent({
|
|
467
|
+
type: '@xstate.actor',
|
|
468
|
+
actorRef: this
|
|
469
|
+
});
|
|
442
470
|
this._initState();
|
|
443
471
|
}
|
|
444
472
|
_initState() {
|
|
@@ -447,7 +475,7 @@ class Actor {
|
|
|
447
475
|
|
|
448
476
|
// array of functions to defer
|
|
449
477
|
|
|
450
|
-
update(snapshot) {
|
|
478
|
+
update(snapshot, event) {
|
|
451
479
|
// Update state
|
|
452
480
|
this._state = snapshot;
|
|
453
481
|
|
|
@@ -469,14 +497,24 @@ class Actor {
|
|
|
469
497
|
this._stopProcedure();
|
|
470
498
|
this._complete();
|
|
471
499
|
this._doneEvent = createDoneActorEvent(this.id, this._state.output);
|
|
472
|
-
this._parent
|
|
500
|
+
if (this._parent) {
|
|
501
|
+
this.system._relay(this, this._parent, this._doneEvent);
|
|
502
|
+
}
|
|
473
503
|
break;
|
|
474
504
|
case 'error':
|
|
475
505
|
this._stopProcedure();
|
|
476
506
|
this._error(this._state.error);
|
|
477
|
-
this._parent
|
|
507
|
+
if (this._parent) {
|
|
508
|
+
this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
|
|
509
|
+
}
|
|
478
510
|
break;
|
|
479
511
|
}
|
|
512
|
+
this.system._sendInspectionEvent({
|
|
513
|
+
type: '@xstate.snapshot',
|
|
514
|
+
actorRef: this,
|
|
515
|
+
event,
|
|
516
|
+
snapshot
|
|
517
|
+
});
|
|
480
518
|
}
|
|
481
519
|
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
482
520
|
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
@@ -509,12 +547,19 @@ class Actor {
|
|
|
509
547
|
this.system._set(this._systemId, this);
|
|
510
548
|
}
|
|
511
549
|
this.status = ActorStatus.Running;
|
|
550
|
+
const initEvent = createInitEvent(this.options.input);
|
|
551
|
+
this.system._sendInspectionEvent({
|
|
552
|
+
type: '@xstate.event',
|
|
553
|
+
sourceRef: this._parent,
|
|
554
|
+
targetRef: this,
|
|
555
|
+
event: initEvent
|
|
556
|
+
});
|
|
512
557
|
const status = this._state.status;
|
|
513
558
|
switch (status) {
|
|
514
559
|
case 'done':
|
|
515
|
-
// a state machine can be "done" upon
|
|
560
|
+
// a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
|
|
516
561
|
// we still need to complete observers, flush deferreds etc
|
|
517
|
-
this.update(this._state);
|
|
562
|
+
this.update(this._state, initEvent);
|
|
518
563
|
// fallthrough
|
|
519
564
|
case 'error':
|
|
520
565
|
// TODO: rethink cleanup of observers, mailbox, etc
|
|
@@ -534,7 +579,7 @@ class Actor {
|
|
|
534
579
|
// TODO: this notifies all subscribers but usually this is redundant
|
|
535
580
|
// there is no real change happening here
|
|
536
581
|
// we need to rethink if this needs to be refactored
|
|
537
|
-
this.update(this._state);
|
|
582
|
+
this.update(this._state, initEvent);
|
|
538
583
|
if (this.options.devTools) {
|
|
539
584
|
this.attachDevTools();
|
|
540
585
|
}
|
|
@@ -562,7 +607,7 @@ class Actor {
|
|
|
562
607
|
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
563
608
|
return;
|
|
564
609
|
}
|
|
565
|
-
this.update(nextState);
|
|
610
|
+
this.update(nextState, event);
|
|
566
611
|
if (event.type === XSTATE_STOP) {
|
|
567
612
|
this._stopProcedure();
|
|
568
613
|
this._complete();
|
|
@@ -648,33 +693,33 @@ class Actor {
|
|
|
648
693
|
}
|
|
649
694
|
|
|
650
695
|
/**
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
* @param event The event to send
|
|
696
|
+
* @internal
|
|
654
697
|
*/
|
|
655
|
-
|
|
656
|
-
if (typeof event === 'string') {
|
|
657
|
-
throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
|
|
658
|
-
}
|
|
698
|
+
_send(event) {
|
|
659
699
|
if (this.status === ActorStatus.Stopped) {
|
|
660
700
|
return;
|
|
661
701
|
}
|
|
662
702
|
this.mailbox.enqueue(event);
|
|
663
703
|
}
|
|
664
704
|
|
|
705
|
+
/**
|
|
706
|
+
* Sends an event to the running Actor to trigger a transition.
|
|
707
|
+
*
|
|
708
|
+
* @param event The event to send
|
|
709
|
+
*/
|
|
710
|
+
send(event) {
|
|
711
|
+
this.system._relay(undefined, this, event);
|
|
712
|
+
}
|
|
713
|
+
|
|
665
714
|
// TODO: make private (and figure out a way to do this within the machine)
|
|
666
|
-
delaySend({
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
715
|
+
delaySend(params) {
|
|
716
|
+
const {
|
|
717
|
+
event,
|
|
718
|
+
id,
|
|
719
|
+
delay
|
|
720
|
+
} = params;
|
|
672
721
|
const timerId = this.clock.setTimeout(() => {
|
|
673
|
-
|
|
674
|
-
to.send(event);
|
|
675
|
-
} else {
|
|
676
|
-
this.send(event);
|
|
677
|
-
}
|
|
722
|
+
this.system._relay(this, params.to ?? this, event);
|
|
678
723
|
}, delay);
|
|
679
724
|
|
|
680
725
|
// TODO: consider the rehydration story here
|
|
@@ -736,4 +781,4 @@ const interpret = createActor;
|
|
|
736
781
|
* @deprecated Use `Actor` instead.
|
|
737
782
|
*/
|
|
738
783
|
|
|
739
|
-
export { Actor as A, InterpreterStatus as I, NULL_EVENT as N, STATE_DELIMITER as S, WILDCARD as W,
|
|
784
|
+
export { Actor as A, InterpreterStatus as I, NULL_EVENT as N, STATE_DELIMITER as S, WILDCARD as W, XSTATE_STOP as X, toTransitionConfigArray as a, createInitEvent as b, createInvokeId as c, createActor as d, matchesState as e, ActorStatus as f, interpret as g, toObserver as h, isErrorActorEvent as i, createErrorActorEvent as j, toStateValue as k, STATE_IDENTIFIER as l, mapValues as m, normalizeTarget as n, toStatePath as o, pathToStateValue as p, createDoneStateEvent as q, resolveReferencedActor as r, resolveOutput as s, toArray as t, XSTATE_INIT as u, isArray as v, createAfterEvent as w, flatten as x, XSTATE_ERROR as y };
|