@ue-too/being 0.14.1 → 0.16.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/index.js CHANGED
@@ -1,5 +1,366 @@
1
- var w=()=>{};class W{_currentState;_states;_context;_statesArray;_stateChangeCallbacks;_happensCallbacks;_timeouts=void 0;_initialState;constructor(j,z,B,q=!0){if(this._states=j,this._currentState="INITIAL",this._initialState=z,this._context=B,this._statesArray=Object.keys(j),this._stateChangeCallbacks=[],this._happensCallbacks=[],q)this.start()}reset(){this.wrapup(),this.switchTo("INITIAL"),this.start()}start(){if(this.currentState!=="INITIAL")return;this._context.setup(),this.switchTo(this._initialState),this._states[this._initialState].uponEnter(this._context,this,this._initialState)}wrapup(){if(this._currentState==="TERMINAL")return;let j=this._currentState;if(j!=="INITIAL")this._states[j].beforeExit(this._context,this,"TERMINAL");this._context.cleanup(),this.switchTo("TERMINAL")}switchTo(j){this._currentState=j}happens(...j){if(this._timeouts)clearTimeout(this._timeouts);if(this._currentState==="INITIAL"||this._currentState==="TERMINAL")return{handled:!1};this._happensCallbacks.forEach((B)=>B(j,this._context));let z=this._states[this._currentState].handles(j,this._context,this);if(z.handled&&z.nextState!==void 0&&z.nextState!==this._currentState){let B=this._currentState;this._states[this._currentState].beforeExit(this._context,this,z.nextState),this.switchTo(z.nextState),this._states[this._currentState].uponEnter(this._context,this,B);for(let q of this._stateChangeCallbacks)q(B,this._currentState)}return z}onStateChange(j){this._stateChangeCallbacks.push(j)}onHappens(j){this._happensCallbacks.push(j)}get currentState(){return this._currentState}setContext(j){this._context=j}get possibleStates(){return this._statesArray}get states(){return this._states}}class H{_eventReactions={};_guards={};_eventGuards={};_delay=void 0;get handlingEvents(){return Object.keys(this._eventReactions)}get guards(){return this._guards}get eventGuards(){return this._eventGuards}get delay(){return this._delay}uponEnter(j,z,B){}beforeExit(j,z,B){}handles(j,z,B){let q=j[0],J=j[1];if(this._eventReactions[q]){let V=this._eventReactions[q].action(z,J,B),Z=this._eventReactions[q].defaultTargetState,U=this._eventGuards[q],$={handled:!0,nextState:Z},Q=V!==void 0?{...$,output:V}:$;if(U){let X=U.find((Y)=>{if(this._guards[Y.guard])return this._guards[Y.guard](z);return!1});return X?{...Q,nextState:X.target}:Q}return Q}return{handled:!1}}}function P(j){return(z)=>j.includes(z)}function C(j){return j}function I(j,z){if(!j.states.includes(j.initialState))throw Error(`Initial state "${j.initialState}" must be in the states array`);for(let q of j.stateDefinitions){if(!j.states.includes(q.name))throw Error(`State definition "${q.name}" is not in the states array`);for(let J of q.transitions){let V=j.events;if(!(String(J.event)in V))throw Error(`Event "${String(J.event)}" in state "${q.name}" is not defined in events`);if(!j.states.includes(J.targetState))throw Error(`Target state "${J.targetState}" in transition from "${q.name}" is not in the states array`);if(J.guards)for(let Z of J.guards){if(!j.states.includes(Z.targetState))throw Error(`Guard target state "${Z.targetState}" is not in the states array`);if(typeof Z.guard==="string"){if(!q.guards||!(Z.guard in q.guards))throw Error(`Guard "${Z.guard}" referenced in state "${q.name}" for event "${String(J.event)}" is not defined in the state's guards section`)}}}}let B={};for(let q of j.stateDefinitions){let J={},V={},Z={};if(q.guards)for(let[Q,X]of Object.entries(q.guards))V[Q]=X;for(let Q of q.transitions){let X=Q.event;if(J[X]={action:Q.action||w,defaultTargetState:Q.targetState},Q.guards&&Q.guards.length>0){let F=[];Q.guards.forEach((Y,G)=>{let L;if(typeof Y.guard==="string"){if(L=Y.guard,!V[L])throw Error(`Guard "${L}" referenced in state "${q.name}" for event "${String(X)}" is not defined in the state's guards section`)}else L=`guard_${q.name}_${String(X)}_${G}`,V[L]=Y.guard;F.push({guard:L,target:Y.targetState})}),Z[X]=F}}class U extends H{eventReactions=J;_guards=V;_eventGuards=Z}let $=new U;if(q.onEnter){let Q=$.uponEnter.bind($);$.uponEnter=(X,F,Y)=>{Q(X,F,Y),q.onEnter(X,Y)}}if(q.onExit){let Q=$.beforeExit.bind($);$.beforeExit=(X,F,Y)=>{Q(X,F,Y),q.onExit(X,Y)}}B[q.name]=$}for(let q of j.states)if(!B[q]){class J extends H{eventReactions={}}B[q]=new J}return new W(B,j.initialState,z,!0)}class _ extends H{_childStateMachineConfig=null;_historyState=null;_context=null;getCurrentChildState(){if(!this._childStateMachineConfig)return null;let z=this._childStateMachineConfig.stateMachine.currentState;return z==="INITIAL"||z==="TERMINAL"?null:z}getStatePath(j){let z=this.getCurrentChildState();if(z===null)return j;return`${j}.${z}`}uponEnter(j,z,B){super.uponEnter(j,z,B),this._context=j;let q=this.getChildStateMachine();this._childStateMachineConfig=q;let J=q.rememberHistory&&this._historyState?this._historyState:q.defaultChildState,V=q.stateMachine;if(V.currentState==="INITIAL")V.start();V.switchTo(J),V.states[J].uponEnter(j,V,"INITIAL")}beforeExit(j,z,B){if(this._childStateMachineConfig?.rememberHistory){let q=this.getCurrentChildState();if(q!==null)this._historyState=q}if(this._childStateMachineConfig){let q=this.getCurrentChildState();if(q!==null)this._childStateMachineConfig.stateMachine.states[q].beforeExit(j,this._childStateMachineConfig.stateMachine,"TERMINAL");this._childStateMachineConfig.stateMachine.wrapup()}super.beforeExit(j,z,B)}handles(j,z,B){if(this._childStateMachineConfig){if(this._childStateMachineConfig.stateMachine.happens(...j).handled)return{handled:!0}}return super.handles(j,z,B)}}class O extends W{getCurrentStatePath(){let j=this.currentState;if(j==="INITIAL"||j==="TERMINAL")return j;let z=this.states[j];if(z instanceof _)return z.getStatePath(j);return j}getActiveStatePath(){let j=this.currentState;if(j==="INITIAL"||j==="TERMINAL")return[j];let z=[j],B=this.states[j];if(B instanceof _){let q=B.getCurrentChildState();if(q!==null)z.push(q)}return z}isInStatePath(j){let z=this.getCurrentStatePath();return z===j||z.startsWith(j+".")}}export{C as createStateMachineSchemaWithInferredStates,I as createStateMachineFromSchema,P as createStateGuard,W as TemplateStateMachine,H as TemplateState,w as NO_OP,O as HierarchicalStateMachine,_ as CompositeState};
1
+ // src/interface.ts
2
+ var NO_OP = () => {};
2
3
 
3
- //# debugId=A4A1425C023A074164756E2164756E21
4
+ class TemplateStateMachine {
5
+ _currentState;
6
+ _states;
7
+ _context;
8
+ _statesArray;
9
+ _stateChangeCallbacks;
10
+ _happensCallbacks;
11
+ _timeouts = undefined;
12
+ _initialState;
13
+ constructor(states, initialState, context, autoStart = true) {
14
+ this._states = states;
15
+ this._currentState = "INITIAL";
16
+ this._initialState = initialState;
17
+ this._context = context;
18
+ this._statesArray = Object.keys(states);
19
+ this._stateChangeCallbacks = [];
20
+ this._happensCallbacks = [];
21
+ if (autoStart) {
22
+ this.start();
23
+ }
24
+ }
25
+ reset() {
26
+ this.wrapup();
27
+ this.switchTo("INITIAL");
28
+ this.start();
29
+ }
30
+ start() {
31
+ if (this.currentState !== "INITIAL") {
32
+ return;
33
+ }
34
+ this._context.setup();
35
+ this.switchTo(this._initialState);
36
+ this._states[this._initialState].uponEnter(this._context, this, this._initialState);
37
+ }
38
+ wrapup() {
39
+ if (this._currentState === "TERMINAL") {
40
+ return;
41
+ }
42
+ const originalState = this._currentState;
43
+ if (originalState !== "INITIAL") {
44
+ this._states[originalState].beforeExit(this._context, this, "TERMINAL");
45
+ }
46
+ this._context.cleanup();
47
+ this.switchTo("TERMINAL");
48
+ }
49
+ switchTo(state) {
50
+ this._currentState = state;
51
+ }
52
+ happens(...args) {
53
+ if (this._timeouts) {
54
+ clearTimeout(this._timeouts);
55
+ }
56
+ if (this._currentState === "INITIAL" || this._currentState === "TERMINAL") {
57
+ return { handled: false };
58
+ }
59
+ this._happensCallbacks.forEach((callback) => callback(args, this._context));
60
+ const result = this._states[this._currentState].handles(args, this._context, this);
61
+ if (result.handled && result.nextState !== undefined && result.nextState !== this._currentState) {
62
+ const originalState = this._currentState;
63
+ this._states[this._currentState].beforeExit(this._context, this, result.nextState);
64
+ this.switchTo(result.nextState);
65
+ this._states[this._currentState].uponEnter(this._context, this, originalState);
66
+ for (const callback of this._stateChangeCallbacks) {
67
+ callback(originalState, this._currentState);
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ onStateChange(callback) {
73
+ this._stateChangeCallbacks.push(callback);
74
+ }
75
+ onHappens(callback) {
76
+ this._happensCallbacks.push(callback);
77
+ }
78
+ get currentState() {
79
+ return this._currentState;
80
+ }
81
+ setContext(context) {
82
+ this._context = context;
83
+ }
84
+ get possibleStates() {
85
+ return this._statesArray;
86
+ }
87
+ get states() {
88
+ return this._states;
89
+ }
90
+ }
91
+
92
+ class TemplateState {
93
+ _eventReactions = {};
94
+ _guards = {};
95
+ _eventGuards = {};
96
+ _delay = undefined;
97
+ _defer = undefined;
98
+ get handlingEvents() {
99
+ return Object.keys(this._eventReactions);
100
+ }
101
+ get guards() {
102
+ return this._guards;
103
+ }
104
+ get eventGuards() {
105
+ return this._eventGuards;
106
+ }
107
+ get eventReactions() {
108
+ return this._eventReactions;
109
+ }
110
+ get delay() {
111
+ return this._delay;
112
+ }
113
+ uponEnter(context, stateMachine, from) {}
114
+ beforeExit(context, stateMachine, to) {}
115
+ handles(args, context, stateMachine) {
116
+ const eventKey = args[0];
117
+ const eventPayload = args[1];
118
+ if (this._defer) {
119
+ const result = this._defer.action(context, eventPayload, eventKey, stateMachine);
120
+ if (result.handled) {
121
+ return result;
122
+ }
123
+ }
124
+ if (this._eventReactions[eventKey]) {
125
+ const output = this._eventReactions[eventKey].action(context, eventPayload, stateMachine);
126
+ const targetState = this._eventReactions[eventKey].defaultTargetState;
127
+ const guardsToEvaluate = this._eventGuards[eventKey];
128
+ const baseResult = {
129
+ handled: true,
130
+ nextState: targetState
131
+ };
132
+ const resultWithOutput = output !== undefined ? { ...baseResult, output } : baseResult;
133
+ if (guardsToEvaluate) {
134
+ const target = guardsToEvaluate.find((guard) => {
135
+ if (this._guards[guard.guard]) {
136
+ return this._guards[guard.guard](context);
137
+ }
138
+ return false;
139
+ });
140
+ const finalResult = target ? { ...resultWithOutput, nextState: target.target } : resultWithOutput;
141
+ return finalResult;
142
+ }
143
+ return resultWithOutput;
144
+ }
145
+ return { handled: false };
146
+ }
147
+ }
148
+ function createStateGuard(set) {
149
+ return (s) => set.includes(s);
150
+ }
151
+ // src/schema-factory.ts
152
+ function createStateMachineSchemaWithInferredStates(schema) {
153
+ return schema;
154
+ }
155
+ function createStateMachineFromSchema(schema, context) {
156
+ if (!schema.states.includes(schema.initialState)) {
157
+ throw new Error(`Initial state "${schema.initialState}" must be in the states array`);
158
+ }
159
+ for (const stateDef of schema.stateDefinitions) {
160
+ if (!schema.states.includes(stateDef.name)) {
161
+ throw new Error(`State definition "${stateDef.name}" is not in the states array`);
162
+ }
163
+ for (const transition of stateDef.transitions) {
164
+ const eventsRecord = schema.events;
165
+ if (!(String(transition.event) in eventsRecord)) {
166
+ throw new Error(`Event "${String(transition.event)}" in state "${stateDef.name}" is not defined in events`);
167
+ }
168
+ if (!schema.states.includes(transition.targetState)) {
169
+ throw new Error(`Target state "${transition.targetState}" in transition from "${stateDef.name}" is not in the states array`);
170
+ }
171
+ if (transition.guards) {
172
+ for (const guard of transition.guards) {
173
+ if (!schema.states.includes(guard.targetState)) {
174
+ throw new Error(`Guard target state "${guard.targetState}" is not in the states array`);
175
+ }
176
+ if (typeof guard.guard === "string") {
177
+ if (!stateDef.guards || !(guard.guard in stateDef.guards)) {
178
+ throw new Error(`Guard "${guard.guard}" referenced in state "${stateDef.name}" for event "${String(transition.event)}" is not defined in the state's guards section`);
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ const stateInstances = {};
186
+ for (const stateDef of schema.stateDefinitions) {
187
+ const eventReactions = {};
188
+ const allGuards = {};
189
+ const eventGuards = {};
190
+ if (stateDef.guards) {
191
+ for (const [guardName, guardFunction] of Object.entries(stateDef.guards)) {
192
+ allGuards[guardName] = guardFunction;
193
+ }
194
+ }
195
+ for (const transition of stateDef.transitions) {
196
+ const eventName = transition.event;
197
+ eventReactions[eventName] = {
198
+ action: transition.action || NO_OP,
199
+ defaultTargetState: transition.targetState
200
+ };
201
+ if (transition.guards && transition.guards.length > 0) {
202
+ const guardMappings = [];
203
+ transition.guards.forEach((guardDef, index) => {
204
+ let guardKey;
205
+ if (typeof guardDef.guard === "string") {
206
+ guardKey = guardDef.guard;
207
+ if (!allGuards[guardKey]) {
208
+ throw new Error(`Guard "${guardKey}" referenced in state "${stateDef.name}" for event "${String(eventName)}" is not defined in the state's guards section`);
209
+ }
210
+ } else {
211
+ guardKey = `guard_${stateDef.name}_${String(eventName)}_${index}`;
212
+ allGuards[guardKey] = guardDef.guard;
213
+ }
214
+ guardMappings.push({
215
+ guard: guardKey,
216
+ target: guardDef.targetState
217
+ });
218
+ });
219
+ eventGuards[eventName] = guardMappings;
220
+ }
221
+ }
222
+
223
+ class DynamicState extends TemplateState {
224
+ _eventReactions = eventReactions;
225
+ _guards = allGuards;
226
+ _eventGuards = eventGuards;
227
+ }
228
+ const stateInstance = new DynamicState;
229
+ if (stateDef.onEnter) {
230
+ const originalOnEnter = stateInstance.uponEnter.bind(stateInstance);
231
+ stateInstance.uponEnter = (ctx, sm, from) => {
232
+ originalOnEnter(ctx, sm, from);
233
+ stateDef.onEnter(ctx, from);
234
+ };
235
+ }
236
+ if (stateDef.onExit) {
237
+ const originalOnExit = stateInstance.beforeExit.bind(stateInstance);
238
+ stateInstance.beforeExit = (ctx, sm, to) => {
239
+ originalOnExit(ctx, sm, to);
240
+ stateDef.onExit(ctx, to);
241
+ };
242
+ }
243
+ stateInstances[stateDef.name] = stateInstance;
244
+ }
245
+ for (const stateName of schema.states) {
246
+ if (!stateInstances[stateName]) {
247
+
248
+ class EmptyState extends TemplateState {
249
+ _eventReactions = {};
250
+ }
251
+ stateInstances[stateName] = new EmptyState;
252
+ }
253
+ }
254
+ return new TemplateStateMachine(stateInstances, schema.initialState, context, true);
255
+ }
256
+ // src/hierarchical.ts
257
+ class CompositeState extends TemplateState {
258
+ _childStateMachineConfig = null;
259
+ _historyState = null;
260
+ _context = null;
261
+ getCurrentChildState() {
262
+ if (!this._childStateMachineConfig) {
263
+ return null;
264
+ }
265
+ const stateMachine = this._childStateMachineConfig.stateMachine;
266
+ const current = stateMachine.currentState;
267
+ return current === "INITIAL" || current === "TERMINAL" ? null : current;
268
+ }
269
+ getStatePath(parentState) {
270
+ const childState = this.getCurrentChildState();
271
+ if (childState === null) {
272
+ return parentState;
273
+ }
274
+ return `${parentState}.${childState}`;
275
+ }
276
+ uponEnter(context, stateMachine, from) {
277
+ super.uponEnter(context, stateMachine, from);
278
+ this._context = context;
279
+ const config = this.getChildStateMachine();
280
+ this._childStateMachineConfig = config;
281
+ const childStateToEnter = config.rememberHistory && this._historyState ? this._historyState : config.defaultChildState;
282
+ const childMachine = config.stateMachine;
283
+ if (childMachine.currentState === "INITIAL") {
284
+ childMachine.start();
285
+ }
286
+ childMachine.switchTo(childStateToEnter);
287
+ const childState = childMachine.states[childStateToEnter];
288
+ childState.uponEnter(context, childMachine, "INITIAL");
289
+ }
290
+ beforeExit(context, stateMachine, to) {
291
+ if (this._childStateMachineConfig?.rememberHistory) {
292
+ const currentChild = this.getCurrentChildState();
293
+ if (currentChild !== null) {
294
+ this._historyState = currentChild;
295
+ }
296
+ }
297
+ if (this._childStateMachineConfig) {
298
+ const currentChild = this.getCurrentChildState();
299
+ if (currentChild !== null) {
300
+ const childState = this._childStateMachineConfig.stateMachine.states[currentChild];
301
+ childState.beforeExit(context, this._childStateMachineConfig.stateMachine, "TERMINAL");
302
+ }
303
+ this._childStateMachineConfig.stateMachine.wrapup();
304
+ }
305
+ super.beforeExit(context, stateMachine, to);
306
+ }
307
+ handles(args, context, stateMachine) {
308
+ if (this._childStateMachineConfig) {
309
+ const childMachine = this._childStateMachineConfig.stateMachine;
310
+ const childResult = childMachine.happens(...args);
311
+ if (childResult.handled) {
312
+ return {
313
+ handled: true
314
+ };
315
+ }
316
+ }
317
+ return super.handles(args, context, stateMachine);
318
+ }
319
+ }
320
+
321
+ class HierarchicalStateMachine extends TemplateStateMachine {
322
+ getCurrentStatePath() {
323
+ const currentState = this.currentState;
324
+ if (currentState === "INITIAL" || currentState === "TERMINAL") {
325
+ return currentState;
326
+ }
327
+ const state = this.states[currentState];
328
+ if (state instanceof CompositeState) {
329
+ return state.getStatePath(currentState);
330
+ }
331
+ return currentState;
332
+ }
333
+ getActiveStatePath() {
334
+ const currentState = this.currentState;
335
+ if (currentState === "INITIAL" || currentState === "TERMINAL") {
336
+ return [currentState];
337
+ }
338
+ const path = [currentState];
339
+ const state = this.states[currentState];
340
+ if (state instanceof CompositeState) {
341
+ const childState = state.getCurrentChildState();
342
+ if (childState !== null) {
343
+ path.push(childState);
344
+ }
345
+ }
346
+ return path;
347
+ }
348
+ isInStatePath(path) {
349
+ const currentPath = this.getCurrentStatePath();
350
+ return currentPath === path || currentPath.startsWith(path + ".");
351
+ }
352
+ }
353
+ export {
354
+ createStateMachineSchemaWithInferredStates,
355
+ createStateMachineFromSchema,
356
+ createStateGuard,
357
+ TemplateStateMachine,
358
+ TemplateState,
359
+ NO_OP,
360
+ HierarchicalStateMachine,
361
+ CompositeState
362
+ };
363
+
364
+ //# debugId=4D129717DB00D55B64756E2164756E21
4
365
 
5
366
  //# sourceMappingURL=index.js.map