xstate 4.20.2 → 4.22.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/CHANGELOG.md +61 -0
- package/dist/xstate.interpreter.js +1 -1
- package/dist/xstate.js +1 -1
- package/dist/xstate.web.js +2 -2
- package/es/Actor.js +18 -1
- package/es/Machine.d.ts +3 -0
- package/es/Machine.js +2 -4
- package/es/StateNode.d.ts +4 -3
- package/es/StateNode.js +14 -11
- package/es/behaviors.d.ts +37 -0
- package/es/behaviors.js +63 -0
- package/es/interpreter.d.ts +3 -2
- package/es/interpreter.js +36 -16
- package/es/model.d.ts +2 -1
- package/es/types.d.ts +15 -4
- package/es/utils.d.ts +3 -2
- package/es/utils.js +5 -1
- package/lib/Machine.d.ts +3 -0
- package/lib/Machine.js +2 -8
- package/lib/StateNode.d.ts +4 -3
- package/lib/StateNode.js +12 -6
- package/lib/behaviors.d.ts +37 -0
- package/lib/behaviors.js +110 -0
- package/lib/interpreter.d.ts +3 -2
- package/lib/interpreter.js +25 -19
- package/lib/model.d.ts +2 -1
- package/lib/model.js +5 -1
- package/lib/types.d.ts +15 -4
- package/lib/utils.d.ts +3 -2
- package/lib/utils.js +8 -1
- package/package.json +1 -1
package/es/types.d.ts
CHANGED
|
@@ -152,7 +152,7 @@ export interface InvokeMeta {
|
|
|
152
152
|
* @param context The current machine `context`
|
|
153
153
|
* @param event The event that invoked the service
|
|
154
154
|
*/
|
|
155
|
-
export declare type InvokeCreator<TContext, TEvent extends EventObject, TFinalContext = any> = (context: TContext, event: TEvent, meta: InvokeMeta) => PromiseLike<TFinalContext> | StateMachine<TFinalContext, any, any> | Subscribable<EventObject> | InvokeCallback<any, TEvent>;
|
|
155
|
+
export declare type InvokeCreator<TContext, TEvent extends EventObject, TFinalContext = any> = (context: TContext, event: TEvent, meta: InvokeMeta) => PromiseLike<TFinalContext> | StateMachine<TFinalContext, any, any> | Subscribable<EventObject> | InvokeCallback<any, TEvent> | Behavior<any>;
|
|
156
156
|
export interface InvokeDefinition<TContext, TEvent extends EventObject> extends ActivityDefinition<TContext, TEvent> {
|
|
157
157
|
/**
|
|
158
158
|
* The source of the machine to be invoked, or the machine itself.
|
|
@@ -878,7 +878,7 @@ export interface Subscribable<T> {
|
|
|
878
878
|
subscribe(observer: Observer<T>): Subscription;
|
|
879
879
|
subscribe(next: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
|
|
880
880
|
}
|
|
881
|
-
export declare type Spawnable = StateMachine<any, any, any> |
|
|
881
|
+
export declare type Spawnable = StateMachine<any, any, any> | PromiseLike<any> | InvokeCallback | Subscribable<any> | Behavior<any>;
|
|
882
882
|
export declare type ExtractEvent<TEvent extends EventObject, TEventType extends TEvent['type']> = TEvent extends {
|
|
883
883
|
type: TEventType;
|
|
884
884
|
} ? TEvent : never;
|
|
@@ -896,13 +896,24 @@ export interface ActorRef<TEvent extends EventObject, TEmitted = any> extends Su
|
|
|
896
896
|
* @deprecated Use `ActorRef` instead.
|
|
897
897
|
*/
|
|
898
898
|
export declare type SpawnedActorRef<TEvent extends EventObject, TEmitted = any> = ActorRef<TEvent, TEmitted>;
|
|
899
|
-
export declare type ActorRefFrom<T extends StateMachine<any, any, any> | Promise<any>> = T extends StateMachine<infer TContext, any, infer TEvent, infer TTypestate> ? ActorRef<TEvent, State<TContext, TEvent, any, TTypestate>> & {
|
|
899
|
+
export declare type ActorRefFrom<T extends StateMachine<any, any, any> | Promise<any> | Behavior<any>> = T extends StateMachine<infer TContext, any, infer TEvent, infer TTypestate> ? ActorRef<TEvent, State<TContext, TEvent, any, TTypestate>> & {
|
|
900
900
|
/**
|
|
901
901
|
* @deprecated Use `.getSnapshot()` instead.
|
|
902
902
|
*/
|
|
903
903
|
state: State<TContext, TEvent, any, TTypestate>;
|
|
904
|
-
} : T extends Promise<infer U> ? ActorRef<never, U> : never;
|
|
904
|
+
} : T extends Promise<infer U> ? ActorRef<never, U> : T extends Behavior<infer TEvent, infer TEmitted> ? ActorRef<TEvent, TEmitted> : never;
|
|
905
905
|
export declare type AnyInterpreter = Interpreter<any, any, any, any>;
|
|
906
906
|
export declare type InterpreterFrom<T extends StateMachine<any, any, any, any>> = T extends StateMachine<infer TContext, infer TStateSchema, infer TEvent, infer TTypestate> ? Interpreter<TContext, TStateSchema, TEvent, TTypestate> : never;
|
|
907
|
+
export interface ActorContext<TEvent extends EventObject, TEmitted> {
|
|
908
|
+
parent?: ActorRef<any, any>;
|
|
909
|
+
self: ActorRef<TEvent, TEmitted>;
|
|
910
|
+
id: string;
|
|
911
|
+
observers: Set<Observer<TEmitted>>;
|
|
912
|
+
}
|
|
913
|
+
export interface Behavior<TEvent extends EventObject, TEmitted = any> {
|
|
914
|
+
transition: (state: TEmitted, event: TEvent, actorCtx: ActorContext<TEvent, TEmitted>) => TEmitted;
|
|
915
|
+
initialState: TEmitted;
|
|
916
|
+
start?: (actorCtx: ActorContext<TEvent, TEmitted>) => TEmitted;
|
|
917
|
+
}
|
|
907
918
|
export {};
|
|
908
919
|
//# sourceMappingURL=types.d.ts.map
|
package/es/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Event, StateValue, ActionType, Action, EventObject, PropertyMapper, Mapper, EventType, HistoryValue, AssignAction, Condition, Subscribable, StateMachine, ConditionPredicate, SCXML, StateLike, EventData, TransitionConfig, TransitionConfigTarget, NullEvent, SingleOrArray, Guard, InvokeSourceDefinition } from './types';
|
|
1
|
+
import { Event, StateValue, ActionType, Action, EventObject, PropertyMapper, Mapper, EventType, HistoryValue, AssignAction, Condition, Subscribable, StateMachine, ConditionPredicate, SCXML, StateLike, EventData, TransitionConfig, TransitionConfigTarget, NullEvent, SingleOrArray, Guard, InvokeSourceDefinition, Observer, Behavior } from './types';
|
|
2
2
|
import { StateNode } from './StateNode';
|
|
3
|
-
import {
|
|
3
|
+
import { State } from './State';
|
|
4
4
|
import { Actor } from './Actor';
|
|
5
5
|
export declare function keys<T extends object>(value: T): Array<keyof T & string>;
|
|
6
6
|
export declare function matchesState(parentStateId: StateValue, childStateId: StateValue, delimiter?: string): boolean;
|
|
@@ -40,6 +40,7 @@ export declare function toArray<T>(value: T[] | T | undefined): T[];
|
|
|
40
40
|
export declare function mapContext<TContext, TEvent extends EventObject>(mapper: Mapper<TContext, TEvent, any> | PropertyMapper<TContext, TEvent, any>, context: TContext, _event: SCXML.Event<TEvent>): any;
|
|
41
41
|
export declare function isBuiltInEvent(eventType: EventType): boolean;
|
|
42
42
|
export declare function isPromiseLike(value: any): value is PromiseLike<any>;
|
|
43
|
+
export declare function isBehavior(value: any): value is Behavior<any, any>;
|
|
43
44
|
export declare function partition<T, A extends T, B extends T>(items: T[], predicate: (item: T) => item is A): [A[], B[]];
|
|
44
45
|
export declare function updateHistoryStates(hist: HistoryValue, stateValue: StateValue): Record<string, HistoryValue | undefined>;
|
|
45
46
|
export declare function updateHistoryValue(hist: HistoryValue, stateValue: StateValue): HistoryValue;
|
package/es/utils.js
CHANGED
|
@@ -301,6 +301,10 @@ function isPromiseLike(value) {
|
|
|
301
301
|
return false;
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
function isBehavior(value) {
|
|
305
|
+
return value !== null && typeof value === 'object' && 'transition' in value && typeof value.transition === 'function';
|
|
306
|
+
}
|
|
307
|
+
|
|
304
308
|
function partition(items, predicate) {
|
|
305
309
|
var e_6, _a;
|
|
306
310
|
|
|
@@ -617,4 +621,4 @@ function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
|
617
621
|
};
|
|
618
622
|
}
|
|
619
623
|
|
|
620
|
-
export { evaluateGuard, flatten, getEventType, isActor, isArray, isBuiltInEvent, isFunction, isMachine, isObservable, isPromiseLike, isStateLike, isString, keys, mapContext, mapFilterValues, mapValues, matchesState, nestedPath, normalizeTarget, partition, path, pathToStateValue, reportUnhandledExceptionOnInvocation, symbolObservable, toArray, toArrayStrict, toEventObject, toGuard, toInvokeSource, toObserver, toSCXMLEvent, toStatePath, toStatePaths, toStateValue, toTransitionConfigArray, uniqueId, updateContext, updateHistoryStates, updateHistoryValue, warn };
|
|
624
|
+
export { evaluateGuard, flatten, getEventType, isActor, isArray, isBehavior, isBuiltInEvent, isFunction, isMachine, isObservable, isPromiseLike, isStateLike, isString, keys, mapContext, mapFilterValues, mapValues, matchesState, nestedPath, normalizeTarget, partition, path, pathToStateValue, reportUnhandledExceptionOnInvocation, symbolObservable, toArray, toArrayStrict, toEventObject, toGuard, toInvokeSource, toObserver, toSCXMLEvent, toStatePath, toStatePaths, toStateValue, toTransitionConfigArray, uniqueId, updateContext, updateHistoryStates, updateHistoryValue, warn };
|
package/lib/Machine.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { StateMachine, MachineOptions, DefaultContext, MachineConfig, StateSchema, EventObject, AnyEventObject, Typestate } from './types';
|
|
2
2
|
import { Model, ModelContextFrom, ModelEventsFrom } from './model';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use `createMachine(...)` instead.
|
|
5
|
+
*/
|
|
3
6
|
export declare function Machine<TContext = any, TEvent extends EventObject = AnyEventObject>(config: MachineConfig<TContext, any, TEvent>, options?: Partial<MachineOptions<TContext, TEvent>>, initialContext?: TContext): StateMachine<TContext, any, TEvent>;
|
|
4
7
|
export declare function Machine<TContext = DefaultContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = AnyEventObject>(config: MachineConfig<TContext, TStateSchema, TEvent>, options?: Partial<MachineOptions<TContext, TEvent>>, initialContext?: TContext): StateMachine<TContext, TStateSchema, TEvent>;
|
|
5
8
|
export declare function createMachine<TModel extends Model<any, any, any>, TContext = ModelContextFrom<TModel>, TEvent extends EventObject = ModelEventsFrom<TModel>, TTypestate extends Typestate<TContext> = {
|
package/lib/Machine.js
CHANGED
|
@@ -4,16 +4,10 @@ exports.createMachine = exports.Machine = void 0;
|
|
|
4
4
|
var StateNode_1 = require("./StateNode");
|
|
5
5
|
function Machine(config, options, initialContext) {
|
|
6
6
|
if (initialContext === void 0) { initialContext = config.context; }
|
|
7
|
-
|
|
8
|
-
? initialContext()
|
|
9
|
-
: initialContext;
|
|
10
|
-
return new StateNode_1.StateNode(config, options, resolvedInitialContext);
|
|
7
|
+
return new StateNode_1.StateNode(config, options, initialContext);
|
|
11
8
|
}
|
|
12
9
|
exports.Machine = Machine;
|
|
13
10
|
function createMachine(config, options) {
|
|
14
|
-
|
|
15
|
-
? config.context()
|
|
16
|
-
: config.context;
|
|
17
|
-
return new StateNode_1.StateNode(config, options, resolvedInitialContext);
|
|
11
|
+
return new StateNode_1.StateNode(config, options);
|
|
18
12
|
}
|
|
19
13
|
exports.createMachine = createMachine;
|
package/lib/StateNode.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
|
|
|
11
11
|
/**
|
|
12
12
|
* The initial extended state
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
private _context;
|
|
15
15
|
/**
|
|
16
16
|
* The relative key of the state node, which represents its location in the overall state value.
|
|
17
17
|
*/
|
|
@@ -122,7 +122,7 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
|
|
|
122
122
|
/**
|
|
123
123
|
* The initial extended state
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
_context?: Readonly<TContext> | (() => Readonly<TContext>));
|
|
126
126
|
private _init;
|
|
127
127
|
/**
|
|
128
128
|
* Clones this state machine with custom options and context.
|
|
@@ -130,13 +130,14 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
|
|
|
130
130
|
* @param options Options (actions, guards, activities, services) to recursively merge with the existing options.
|
|
131
131
|
* @param context Custom context (will override predefined context)
|
|
132
132
|
*/
|
|
133
|
-
withConfig(options: Partial<MachineOptions<TContext, TEvent>>, context?: TContext
|
|
133
|
+
withConfig(options: Partial<MachineOptions<TContext, TEvent>>, context?: TContext): StateNode<TContext, TStateSchema, TEvent, TTypestate>;
|
|
134
134
|
/**
|
|
135
135
|
* Clones this state machine with custom context.
|
|
136
136
|
*
|
|
137
137
|
* @param context Custom context (will override predefined context, not recursive)
|
|
138
138
|
*/
|
|
139
139
|
withContext(context: TContext): StateNode<TContext, TStateSchema, TEvent, TTypestate>;
|
|
140
|
+
get context(): TContext;
|
|
140
141
|
/**
|
|
141
142
|
* The well-structured state node definition.
|
|
142
143
|
*/
|
package/lib/StateNode.js
CHANGED
|
@@ -99,13 +99,13 @@ var StateNode = /** @class */ (function () {
|
|
|
99
99
|
/**
|
|
100
100
|
* The initial extended state
|
|
101
101
|
*/
|
|
102
|
-
|
|
102
|
+
_context // TODO: this is unsafe, but we're removing it in v5 anyway
|
|
103
103
|
) {
|
|
104
104
|
var _this = this;
|
|
105
|
-
if (
|
|
105
|
+
if (_context === void 0) { _context = config.context; }
|
|
106
106
|
var _a;
|
|
107
107
|
this.config = config;
|
|
108
|
-
this.
|
|
108
|
+
this._context = _context;
|
|
109
109
|
/**
|
|
110
110
|
* The order this state node appears. Corresponds to the implicit SCXML document order.
|
|
111
111
|
*/
|
|
@@ -255,7 +255,6 @@ var StateNode = /** @class */ (function () {
|
|
|
255
255
|
* @param context Custom context (will override predefined context)
|
|
256
256
|
*/
|
|
257
257
|
StateNode.prototype.withConfig = function (options, context) {
|
|
258
|
-
if (context === void 0) { context = this.context; }
|
|
259
258
|
var _a = this.options, actions = _a.actions, activities = _a.activities, guards = _a.guards, services = _a.services, delays = _a.delays;
|
|
260
259
|
return new StateNode(this.config, {
|
|
261
260
|
actions: __assign(__assign({}, actions), options.actions),
|
|
@@ -263,7 +262,7 @@ var StateNode = /** @class */ (function () {
|
|
|
263
262
|
guards: __assign(__assign({}, guards), options.guards),
|
|
264
263
|
services: __assign(__assign({}, services), options.services),
|
|
265
264
|
delays: __assign(__assign({}, delays), options.delays)
|
|
266
|
-
}, context);
|
|
265
|
+
}, context !== null && context !== void 0 ? context : this.context);
|
|
267
266
|
};
|
|
268
267
|
/**
|
|
269
268
|
* Clones this state machine with custom context.
|
|
@@ -273,6 +272,13 @@ var StateNode = /** @class */ (function () {
|
|
|
273
272
|
StateNode.prototype.withContext = function (context) {
|
|
274
273
|
return new StateNode(this.config, this.options, context);
|
|
275
274
|
};
|
|
275
|
+
Object.defineProperty(StateNode.prototype, "context", {
|
|
276
|
+
get: function () {
|
|
277
|
+
return utils_1.isFunction(this._context) ? this._context() : this._context;
|
|
278
|
+
},
|
|
279
|
+
enumerable: false,
|
|
280
|
+
configurable: true
|
|
281
|
+
});
|
|
276
282
|
Object.defineProperty(StateNode.prototype, "definition", {
|
|
277
283
|
/**
|
|
278
284
|
* The well-structured state node definition.
|
|
@@ -716,7 +722,7 @@ var StateNode = /** @class */ (function () {
|
|
|
716
722
|
var resolvedStateValue = utils_1.isString(state)
|
|
717
723
|
? this.resolve(utils_1.pathToStateValue(this.getResolvedPath(state)))
|
|
718
724
|
: this.resolve(state);
|
|
719
|
-
var resolvedContext = context ? context : this.machine.context;
|
|
725
|
+
var resolvedContext = context !== null && context !== void 0 ? context : this.machine.context;
|
|
720
726
|
currentState = this.resolveState(State_1.State.from(resolvedStateValue, resolvedContext));
|
|
721
727
|
}
|
|
722
728
|
if (!environment_1.IS_PRODUCTION && _event.name === WILDCARD) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ActorContext, ActorRef, Behavior, EventObject } from '.';
|
|
2
|
+
/**
|
|
3
|
+
* Returns an actor behavior from a reducer and its initial state.
|
|
4
|
+
*
|
|
5
|
+
* @param transition The pure reducer that returns the next state given the current state and event.
|
|
6
|
+
* @param initialState The initial state of the reducer.
|
|
7
|
+
* @returns An actor behavior
|
|
8
|
+
*/
|
|
9
|
+
export declare function fromReducer<TState, TEvent extends EventObject>(transition: (state: TState, event: TEvent, actorContext: ActorContext<TEvent, TState>) => TState, initialState: TState): Behavior<TEvent, TState>;
|
|
10
|
+
declare type PromiseEvents<T> = {
|
|
11
|
+
type: 'fulfill';
|
|
12
|
+
data: T;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'reject';
|
|
15
|
+
error: unknown;
|
|
16
|
+
};
|
|
17
|
+
declare type PromiseState<T> = {
|
|
18
|
+
status: 'pending';
|
|
19
|
+
data: undefined;
|
|
20
|
+
error: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
status: 'fulfilled';
|
|
23
|
+
data: T;
|
|
24
|
+
error: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
status: 'rejected';
|
|
27
|
+
data: undefined;
|
|
28
|
+
error: any;
|
|
29
|
+
};
|
|
30
|
+
export declare function fromPromise<T>(promiseFn: () => Promise<T>): Behavior<PromiseEvents<T>, PromiseState<T>>;
|
|
31
|
+
interface SpawnBehaviorOptions {
|
|
32
|
+
id?: string;
|
|
33
|
+
parent?: ActorRef<any>;
|
|
34
|
+
}
|
|
35
|
+
export declare function spawnBehavior<TEvent extends EventObject, TEmitted>(behavior: Behavior<TEvent, TEmitted>, options?: SpawnBehaviorOptions): ActorRef<TEvent, TEmitted>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=behaviors.d.ts.map
|
package/lib/behaviors.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.spawnBehavior = exports.fromPromise = exports.fromReducer = void 0;
|
|
4
|
+
var actions_1 = require("./actions");
|
|
5
|
+
var Actor_1 = require("./Actor");
|
|
6
|
+
var utils_1 = require("./utils");
|
|
7
|
+
/**
|
|
8
|
+
* Returns an actor behavior from a reducer and its initial state.
|
|
9
|
+
*
|
|
10
|
+
* @param transition The pure reducer that returns the next state given the current state and event.
|
|
11
|
+
* @param initialState The initial state of the reducer.
|
|
12
|
+
* @returns An actor behavior
|
|
13
|
+
*/
|
|
14
|
+
function fromReducer(transition, initialState) {
|
|
15
|
+
return {
|
|
16
|
+
transition: transition,
|
|
17
|
+
initialState: initialState
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
exports.fromReducer = fromReducer;
|
|
21
|
+
function fromPromise(promiseFn) {
|
|
22
|
+
var initialState = {
|
|
23
|
+
error: undefined,
|
|
24
|
+
data: undefined,
|
|
25
|
+
status: 'pending'
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
transition: function (state, event, _a) {
|
|
29
|
+
var parent = _a.parent, id = _a.id, observers = _a.observers;
|
|
30
|
+
switch (event.type) {
|
|
31
|
+
case 'fulfill':
|
|
32
|
+
parent === null || parent === void 0 ? void 0 : parent.send(actions_1.doneInvoke(id, event.data));
|
|
33
|
+
return {
|
|
34
|
+
error: undefined,
|
|
35
|
+
data: event.data,
|
|
36
|
+
status: 'fulfilled'
|
|
37
|
+
};
|
|
38
|
+
case 'reject':
|
|
39
|
+
parent === null || parent === void 0 ? void 0 : parent.send(actions_1.error(id, event.error));
|
|
40
|
+
observers.forEach(function (observer) {
|
|
41
|
+
observer.error(event.error);
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
error: event.error,
|
|
45
|
+
data: undefined,
|
|
46
|
+
status: 'rejected'
|
|
47
|
+
};
|
|
48
|
+
default:
|
|
49
|
+
return state;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
initialState: initialState,
|
|
53
|
+
start: function (_a) {
|
|
54
|
+
var self = _a.self;
|
|
55
|
+
promiseFn().then(function (data) {
|
|
56
|
+
self.send({ type: 'fulfill', data: data });
|
|
57
|
+
}, function (reason) {
|
|
58
|
+
self.send({ type: 'reject', error: reason });
|
|
59
|
+
});
|
|
60
|
+
return initialState;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
exports.fromPromise = fromPromise;
|
|
65
|
+
function spawnBehavior(behavior, options) {
|
|
66
|
+
if (options === void 0) { options = {}; }
|
|
67
|
+
var state = behavior.initialState;
|
|
68
|
+
var observers = new Set();
|
|
69
|
+
var mailbox = [];
|
|
70
|
+
var flushing = false;
|
|
71
|
+
var flush = function () {
|
|
72
|
+
if (flushing) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
flushing = true;
|
|
76
|
+
while (mailbox.length > 0) {
|
|
77
|
+
var event_1 = mailbox.shift();
|
|
78
|
+
state = behavior.transition(state, event_1, actorCtx);
|
|
79
|
+
observers.forEach(function (observer) { return observer.next(state); });
|
|
80
|
+
}
|
|
81
|
+
flushing = false;
|
|
82
|
+
};
|
|
83
|
+
var actor = Actor_1.toActorRef({
|
|
84
|
+
id: options.id,
|
|
85
|
+
send: function (event) {
|
|
86
|
+
mailbox.push(event);
|
|
87
|
+
flush();
|
|
88
|
+
},
|
|
89
|
+
getSnapshot: function () { return state; },
|
|
90
|
+
subscribe: function (next, handleError, complete) {
|
|
91
|
+
var observer = utils_1.toObserver(next, handleError, complete);
|
|
92
|
+
observers.add(observer);
|
|
93
|
+
observer.next(state);
|
|
94
|
+
return {
|
|
95
|
+
unsubscribe: function () {
|
|
96
|
+
observers.delete(observer);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
var actorCtx = {
|
|
102
|
+
parent: options.parent,
|
|
103
|
+
self: actor,
|
|
104
|
+
id: options.id || 'anonymous',
|
|
105
|
+
observers: observers
|
|
106
|
+
};
|
|
107
|
+
state = behavior.start ? behavior.start(actorCtx) : state;
|
|
108
|
+
return actor;
|
|
109
|
+
}
|
|
110
|
+
exports.spawnBehavior = spawnBehavior;
|
package/lib/interpreter.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { StateMachine, Event, EventObject, DefaultContext, StateSchema, StateValue, InterpreterOptions, SingleOrArray, DoneEvent, MachineOptions, SCXML, EventData, Observer, Spawnable, Typestate } from './types';
|
|
1
|
+
import { StateMachine, Event, EventObject, DefaultContext, StateSchema, StateValue, InterpreterOptions, SingleOrArray, DoneEvent, MachineOptions, SCXML, EventData, Observer, Spawnable, Typestate, ActorRef, ActorRefFrom, Behavior, Subscription } from './types';
|
|
2
2
|
import { State } from './State';
|
|
3
|
-
import { ActorRef, ActorRefFrom, Subscription } from '.';
|
|
4
3
|
export declare type StateListener<TContext, TEvent extends EventObject, TStateSchema extends StateSchema<TContext> = any, TTypestate extends Typestate<TContext> = {
|
|
5
4
|
value: any;
|
|
6
5
|
context: TContext;
|
|
@@ -171,6 +170,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
|
|
|
171
170
|
autoForward?: boolean;
|
|
172
171
|
sync?: boolean;
|
|
173
172
|
}): ActorRef<TChildEvent, State<TChildContext, TChildEvent>>;
|
|
173
|
+
private spawnBehavior;
|
|
174
174
|
private spawnPromise;
|
|
175
175
|
private spawnCallback;
|
|
176
176
|
private spawnObservable;
|
|
@@ -183,6 +183,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
|
|
|
183
183
|
};
|
|
184
184
|
getSnapshot(): State<TContext, TEvent, TStateSchema, TTypestate>;
|
|
185
185
|
}
|
|
186
|
+
export declare function spawn<T extends Behavior<any, any>>(entity: T, nameOrOptions?: string | SpawnOptions): ActorRefFrom<T>;
|
|
186
187
|
export declare function spawn<TC, TE extends EventObject>(entity: StateMachine<TC, any, TE>, nameOrOptions?: string | SpawnOptions): ActorRefFrom<StateMachine<TC, any, TE>>;
|
|
187
188
|
export declare function spawn(entity: Spawnable, nameOrOptions?: string | SpawnOptions): ActorRef<any>;
|
|
188
189
|
/**
|
package/lib/interpreter.js
CHANGED
|
@@ -56,6 +56,7 @@ var stateUtils_1 = require("./stateUtils");
|
|
|
56
56
|
var registry_1 = require("./registry");
|
|
57
57
|
var devTools_1 = require("./devTools");
|
|
58
58
|
var serviceScope = require("./serviceScope");
|
|
59
|
+
var behaviors_1 = require("./behaviors");
|
|
59
60
|
var DEFAULT_SPAWN_OPTIONS = { sync: false, autoForward: false };
|
|
60
61
|
var InterpreterStatus;
|
|
61
62
|
(function (InterpreterStatus) {
|
|
@@ -725,31 +726,28 @@ var Interpreter = /** @class */ (function () {
|
|
|
725
726
|
var resolvedData = data
|
|
726
727
|
? utils_1.mapContext(data, context, _event)
|
|
727
728
|
: undefined;
|
|
729
|
+
if (typeof serviceCreator === 'string') {
|
|
730
|
+
// TODO: warn
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
728
733
|
var source = utils_1.isFunction(serviceCreator)
|
|
729
734
|
? serviceCreator(context, _event.data, {
|
|
730
735
|
data: resolvedData,
|
|
731
736
|
src: invokeSource
|
|
732
737
|
})
|
|
733
738
|
: serviceCreator;
|
|
734
|
-
if (
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
else if (utils_1.isFunction(source)) {
|
|
738
|
-
this.spawnCallback(source, id);
|
|
739
|
-
}
|
|
740
|
-
else if (utils_1.isObservable(source)) {
|
|
741
|
-
this.spawnObservable(source, id);
|
|
739
|
+
if (!source) {
|
|
740
|
+
// TODO: warn?
|
|
741
|
+
return;
|
|
742
742
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
743
|
+
var options = void 0;
|
|
744
|
+
if (utils_1.isMachine(source)) {
|
|
745
|
+
source = resolvedData ? source.withContext(resolvedData) : source;
|
|
746
|
+
options = {
|
|
747
747
|
autoForward: autoForward
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
else {
|
|
751
|
-
// service is string
|
|
748
|
+
};
|
|
752
749
|
}
|
|
750
|
+
this.spawn(source, id, options);
|
|
753
751
|
}
|
|
754
752
|
else {
|
|
755
753
|
this.spawnActivity(activity);
|
|
@@ -808,6 +806,9 @@ var Interpreter = /** @class */ (function () {
|
|
|
808
806
|
else if (utils_1.isMachine(entity)) {
|
|
809
807
|
return this.spawnMachine(entity, __assign(__assign({}, options), { id: name }));
|
|
810
808
|
}
|
|
809
|
+
else if (utils_1.isBehavior(entity)) {
|
|
810
|
+
return this.spawnBehavior(entity, name);
|
|
811
|
+
}
|
|
811
812
|
else {
|
|
812
813
|
throw new Error("Unable to spawn entity \"" + name + "\" of type \"" + typeof entity + "\".");
|
|
813
814
|
}
|
|
@@ -838,10 +839,15 @@ var Interpreter = /** @class */ (function () {
|
|
|
838
839
|
.start();
|
|
839
840
|
return actor;
|
|
840
841
|
};
|
|
842
|
+
Interpreter.prototype.spawnBehavior = function (behavior, id) {
|
|
843
|
+
var actorRef = behaviors_1.spawnBehavior(behavior, { id: id, parent: this });
|
|
844
|
+
this.children.set(id, actorRef);
|
|
845
|
+
return actorRef;
|
|
846
|
+
};
|
|
841
847
|
Interpreter.prototype.spawnPromise = function (promise, id) {
|
|
842
848
|
var _this = this;
|
|
843
849
|
var canceled = false;
|
|
844
|
-
var resolvedData
|
|
850
|
+
var resolvedData;
|
|
845
851
|
promise.then(function (response) {
|
|
846
852
|
if (!canceled) {
|
|
847
853
|
resolvedData = response;
|
|
@@ -912,7 +918,7 @@ var Interpreter = /** @class */ (function () {
|
|
|
912
918
|
var canceled = false;
|
|
913
919
|
var receivers = new Set();
|
|
914
920
|
var listeners = new Set();
|
|
915
|
-
var emitted
|
|
921
|
+
var emitted;
|
|
916
922
|
var receive = function (e) {
|
|
917
923
|
emitted = e;
|
|
918
924
|
listeners.forEach(function (listener) { return listener(e); });
|
|
@@ -962,7 +968,7 @@ var Interpreter = /** @class */ (function () {
|
|
|
962
968
|
};
|
|
963
969
|
Interpreter.prototype.spawnObservable = function (source, id) {
|
|
964
970
|
var _this = this;
|
|
965
|
-
var emitted
|
|
971
|
+
var emitted;
|
|
966
972
|
var subscription = source.subscribe(function (value) {
|
|
967
973
|
emitted = value;
|
|
968
974
|
_this.send(utils_1.toSCXMLEvent(value, { origin: id }));
|
package/lib/model.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssignAction, Assigner, PropertyAssigner, ExtractEvent, EventObject } from './types';
|
|
1
|
+
import type { AssignAction, Assigner, PropertyAssigner, ExtractEvent, EventObject, MachineConfig, StateMachine, MachineOptions } from './types';
|
|
2
2
|
declare type AnyFunction = (...args: any[]) => any;
|
|
3
3
|
declare type Cast<A1 extends any, A2 extends any> = A1 extends A2 ? A1 : A2;
|
|
4
4
|
declare type Compute<A extends any> = {
|
|
@@ -10,6 +10,7 @@ export interface Model<TContext, TEvent extends EventObject, TModelCreators = vo
|
|
|
10
10
|
assign: <TEventType extends TEvent['type'] = TEvent['type']>(assigner: Assigner<TContext, ExtractEvent<TEvent, TEventType>> | PropertyAssigner<TContext, ExtractEvent<TEvent, TEventType>>, eventType?: TEventType) => AssignAction<TContext, ExtractEvent<TEvent, TEventType>>;
|
|
11
11
|
events: Prop<TModelCreators, 'events'>;
|
|
12
12
|
reset: () => AssignAction<TContext, any>;
|
|
13
|
+
createMachine: (config: MachineConfig<TContext, any, TEvent>, implementations?: Partial<MachineOptions<TContext, TEvent>>) => StateMachine<TContext, any, TEvent, any>;
|
|
13
14
|
}
|
|
14
15
|
export declare type ModelContextFrom<TModel extends Model<any, any, any>> = TModel extends Model<infer TContext, any, any> ? TContext : never;
|
|
15
16
|
export declare type ModelEventsFrom<TModel extends Model<any, any, any>> = TModel extends Model<any, infer TEvent, any> ? TEvent : never;
|
package/lib/model.js
CHANGED
|
@@ -34,6 +34,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.createModel = void 0;
|
|
36
36
|
var actions_1 = require("./actions");
|
|
37
|
+
var Machine_1 = require("./Machine");
|
|
37
38
|
var utils_1 = require("./utils");
|
|
38
39
|
function createModel(initialContext, creators) {
|
|
39
40
|
var eventCreators = creators === null || creators === void 0 ? void 0 : creators.events;
|
|
@@ -49,7 +50,10 @@ function createModel(initialContext, creators) {
|
|
|
49
50
|
return (__assign(__assign({}, fn.apply(void 0, __spreadArray([], __read(args)))), { type: eventType }));
|
|
50
51
|
}; })
|
|
51
52
|
: undefined),
|
|
52
|
-
reset: function () { return actions_1.assign(initialContext); }
|
|
53
|
+
reset: function () { return actions_1.assign(initialContext); },
|
|
54
|
+
createMachine: function (config, implementations) {
|
|
55
|
+
return Machine_1.createMachine('context' in config ? config : __assign(__assign({}, config), { context: initialContext }), implementations);
|
|
56
|
+
}
|
|
53
57
|
};
|
|
54
58
|
return model;
|
|
55
59
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -152,7 +152,7 @@ export interface InvokeMeta {
|
|
|
152
152
|
* @param context The current machine `context`
|
|
153
153
|
* @param event The event that invoked the service
|
|
154
154
|
*/
|
|
155
|
-
export declare type InvokeCreator<TContext, TEvent extends EventObject, TFinalContext = any> = (context: TContext, event: TEvent, meta: InvokeMeta) => PromiseLike<TFinalContext> | StateMachine<TFinalContext, any, any> | Subscribable<EventObject> | InvokeCallback<any, TEvent>;
|
|
155
|
+
export declare type InvokeCreator<TContext, TEvent extends EventObject, TFinalContext = any> = (context: TContext, event: TEvent, meta: InvokeMeta) => PromiseLike<TFinalContext> | StateMachine<TFinalContext, any, any> | Subscribable<EventObject> | InvokeCallback<any, TEvent> | Behavior<any>;
|
|
156
156
|
export interface InvokeDefinition<TContext, TEvent extends EventObject> extends ActivityDefinition<TContext, TEvent> {
|
|
157
157
|
/**
|
|
158
158
|
* The source of the machine to be invoked, or the machine itself.
|
|
@@ -878,7 +878,7 @@ export interface Subscribable<T> {
|
|
|
878
878
|
subscribe(observer: Observer<T>): Subscription;
|
|
879
879
|
subscribe(next: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
|
|
880
880
|
}
|
|
881
|
-
export declare type Spawnable = StateMachine<any, any, any> |
|
|
881
|
+
export declare type Spawnable = StateMachine<any, any, any> | PromiseLike<any> | InvokeCallback | Subscribable<any> | Behavior<any>;
|
|
882
882
|
export declare type ExtractEvent<TEvent extends EventObject, TEventType extends TEvent['type']> = TEvent extends {
|
|
883
883
|
type: TEventType;
|
|
884
884
|
} ? TEvent : never;
|
|
@@ -896,13 +896,24 @@ export interface ActorRef<TEvent extends EventObject, TEmitted = any> extends Su
|
|
|
896
896
|
* @deprecated Use `ActorRef` instead.
|
|
897
897
|
*/
|
|
898
898
|
export declare type SpawnedActorRef<TEvent extends EventObject, TEmitted = any> = ActorRef<TEvent, TEmitted>;
|
|
899
|
-
export declare type ActorRefFrom<T extends StateMachine<any, any, any> | Promise<any>> = T extends StateMachine<infer TContext, any, infer TEvent, infer TTypestate> ? ActorRef<TEvent, State<TContext, TEvent, any, TTypestate>> & {
|
|
899
|
+
export declare type ActorRefFrom<T extends StateMachine<any, any, any> | Promise<any> | Behavior<any>> = T extends StateMachine<infer TContext, any, infer TEvent, infer TTypestate> ? ActorRef<TEvent, State<TContext, TEvent, any, TTypestate>> & {
|
|
900
900
|
/**
|
|
901
901
|
* @deprecated Use `.getSnapshot()` instead.
|
|
902
902
|
*/
|
|
903
903
|
state: State<TContext, TEvent, any, TTypestate>;
|
|
904
|
-
} : T extends Promise<infer U> ? ActorRef<never, U> : never;
|
|
904
|
+
} : T extends Promise<infer U> ? ActorRef<never, U> : T extends Behavior<infer TEvent, infer TEmitted> ? ActorRef<TEvent, TEmitted> : never;
|
|
905
905
|
export declare type AnyInterpreter = Interpreter<any, any, any, any>;
|
|
906
906
|
export declare type InterpreterFrom<T extends StateMachine<any, any, any, any>> = T extends StateMachine<infer TContext, infer TStateSchema, infer TEvent, infer TTypestate> ? Interpreter<TContext, TStateSchema, TEvent, TTypestate> : never;
|
|
907
|
+
export interface ActorContext<TEvent extends EventObject, TEmitted> {
|
|
908
|
+
parent?: ActorRef<any, any>;
|
|
909
|
+
self: ActorRef<TEvent, TEmitted>;
|
|
910
|
+
id: string;
|
|
911
|
+
observers: Set<Observer<TEmitted>>;
|
|
912
|
+
}
|
|
913
|
+
export interface Behavior<TEvent extends EventObject, TEmitted = any> {
|
|
914
|
+
transition: (state: TEmitted, event: TEvent, actorCtx: ActorContext<TEvent, TEmitted>) => TEmitted;
|
|
915
|
+
initialState: TEmitted;
|
|
916
|
+
start?: (actorCtx: ActorContext<TEvent, TEmitted>) => TEmitted;
|
|
917
|
+
}
|
|
907
918
|
export {};
|
|
908
919
|
//# sourceMappingURL=types.d.ts.map
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Event, StateValue, ActionType, Action, EventObject, PropertyMapper, Mapper, EventType, HistoryValue, AssignAction, Condition, Subscribable, StateMachine, ConditionPredicate, SCXML, StateLike, EventData, TransitionConfig, TransitionConfigTarget, NullEvent, SingleOrArray, Guard, InvokeSourceDefinition } from './types';
|
|
1
|
+
import { Event, StateValue, ActionType, Action, EventObject, PropertyMapper, Mapper, EventType, HistoryValue, AssignAction, Condition, Subscribable, StateMachine, ConditionPredicate, SCXML, StateLike, EventData, TransitionConfig, TransitionConfigTarget, NullEvent, SingleOrArray, Guard, InvokeSourceDefinition, Observer, Behavior } from './types';
|
|
2
2
|
import { StateNode } from './StateNode';
|
|
3
|
-
import {
|
|
3
|
+
import { State } from './State';
|
|
4
4
|
import { Actor } from './Actor';
|
|
5
5
|
export declare function keys<T extends object>(value: T): Array<keyof T & string>;
|
|
6
6
|
export declare function matchesState(parentStateId: StateValue, childStateId: StateValue, delimiter?: string): boolean;
|
|
@@ -40,6 +40,7 @@ export declare function toArray<T>(value: T[] | T | undefined): T[];
|
|
|
40
40
|
export declare function mapContext<TContext, TEvent extends EventObject>(mapper: Mapper<TContext, TEvent, any> | PropertyMapper<TContext, TEvent, any>, context: TContext, _event: SCXML.Event<TEvent>): any;
|
|
41
41
|
export declare function isBuiltInEvent(eventType: EventType): boolean;
|
|
42
42
|
export declare function isPromiseLike(value: any): value is PromiseLike<any>;
|
|
43
|
+
export declare function isBehavior(value: any): value is Behavior<any, any>;
|
|
43
44
|
export declare function partition<T, A extends T, B extends T>(items: T[], predicate: (item: T) => item is A): [A[], B[]];
|
|
44
45
|
export declare function updateHistoryStates(hist: HistoryValue, stateValue: StateValue): Record<string, HistoryValue | undefined>;
|
|
45
46
|
export declare function updateHistoryValue(hist: HistoryValue, stateValue: StateValue): HistoryValue;
|
package/lib/utils.js
CHANGED
|
@@ -43,7 +43,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
|
43
43
|
return to;
|
|
44
44
|
};
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.toObserver = exports.toInvokeSource = exports.evaluateGuard = exports.reportUnhandledExceptionOnInvocation = exports.normalizeTarget = exports.toTransitionConfigArray = exports.toSCXMLEvent = exports.toEventObject = exports.uniqueId = exports.isActor = exports.isMachine = exports.symbolObservable = exports.isObservable = exports.toGuard = exports.isString = exports.isFunction = exports.isArray = exports.warn = exports.updateContext = exports.updateHistoryValue = exports.updateHistoryStates = exports.partition = exports.isPromiseLike = exports.isBuiltInEvent = exports.mapContext = exports.toArray = exports.toArrayStrict = exports.flatten = exports.pathsToStateValue = exports.toStatePaths = exports.nestedPath = exports.path = exports.mapFilterValues = exports.mapValues = exports.pathToStateValue = exports.toStateValue = exports.isStateLike = exports.toStatePath = exports.getActionType = exports.getEventType = exports.matchesState = exports.keys = void 0;
|
|
46
|
+
exports.toObserver = exports.toInvokeSource = exports.evaluateGuard = exports.reportUnhandledExceptionOnInvocation = exports.normalizeTarget = exports.toTransitionConfigArray = exports.toSCXMLEvent = exports.toEventObject = exports.uniqueId = exports.isActor = exports.isMachine = exports.symbolObservable = exports.isObservable = exports.toGuard = exports.isString = exports.isFunction = exports.isArray = exports.warn = exports.updateContext = exports.updateHistoryValue = exports.updateHistoryStates = exports.partition = exports.isBehavior = exports.isPromiseLike = exports.isBuiltInEvent = exports.mapContext = exports.toArray = exports.toArrayStrict = exports.flatten = exports.pathsToStateValue = exports.toStatePaths = exports.nestedPath = exports.path = exports.mapFilterValues = exports.mapValues = exports.pathToStateValue = exports.toStateValue = exports.isStateLike = exports.toStatePath = exports.getActionType = exports.getEventType = exports.matchesState = exports.keys = void 0;
|
|
47
47
|
var constants_1 = require("./constants");
|
|
48
48
|
var environment_1 = require("./environment");
|
|
49
49
|
function keys(value) {
|
|
@@ -345,6 +345,13 @@ function isPromiseLike(value) {
|
|
|
345
345
|
return false;
|
|
346
346
|
}
|
|
347
347
|
exports.isPromiseLike = isPromiseLike;
|
|
348
|
+
function isBehavior(value) {
|
|
349
|
+
return (value !== null &&
|
|
350
|
+
typeof value === 'object' &&
|
|
351
|
+
'transition' in value &&
|
|
352
|
+
typeof value.transition === 'function');
|
|
353
|
+
}
|
|
354
|
+
exports.isBehavior = isBehavior;
|
|
348
355
|
function partition(items, predicate) {
|
|
349
356
|
var e_6, _a;
|
|
350
357
|
var _b = __read([[], []], 2), truthy = _b[0], falsy = _b[1];
|