@statewalker/fsm 0.24.0 → 0.25.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/dist/index.js CHANGED
@@ -204,9 +204,9 @@ var FsmProcess = class extends FsmBaseClass {
204
204
  } finally {
205
205
  this.running = false;
206
206
  }
207
- if (this.nextEvent !== void 0) {
208
- await new Promise((r) => setImmediate(r));
209
- return this.dispatch(this.nextEvent);
207
+ const nextEvent = this.nextEvent;
208
+ if (nextEvent !== void 0) {
209
+ return Promise.resolve().then(() => this.dispatch(nextEvent));
210
210
  }
211
211
  }
212
212
  return !(this.status & STATUS_FINISHED);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statewalker/fsm",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "HFSM Implementation",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/statewalker/statewalker-fsm",
package/src/FsmProcess.ts CHANGED
@@ -83,9 +83,9 @@ export class FsmProcess extends FsmBaseClass {
83
83
  } finally {
84
84
  this.running = false;
85
85
  }
86
- if (this.nextEvent !== undefined) {
87
- await new Promise((r) => setImmediate(r));
88
- return this.dispatch(this.nextEvent);
86
+ const nextEvent = this.nextEvent;
87
+ if (nextEvent !== undefined) {
88
+ return Promise.resolve().then(() => this.dispatch(nextEvent));
89
89
  }
90
90
  }
91
91
  return !(this.status & STATUS_FINISHED);
@@ -72,16 +72,12 @@ export type FsmStateModule<
72
72
  | ((...stack: FsmStateStore[]) => FsmStateContext)
73
73
  | (new (...stack: FsmStateStore[]) => FsmStateContext);
74
74
  // trigger?: (context: FsmStateContext) => AsyncGenerator<string>;
75
- trigger?: (
76
- context: FsmStateContext,
77
- onEvent: (event: string) => void,
78
- ) => void | (() => void);
75
+ trigger?: (context: FsmStateContext) => AsyncIterator<string>;
79
76
  handler?: (
80
77
  context: FsmStateContext,
81
78
  ) => void | (() => void) | Promise<void | (() => void)>;
82
79
  };
83
80
 
84
-
85
81
  export function newModuleContext<
86
82
  C = Record<string, unknown>,
87
83
  S = Record<string, unknown>,
@@ -103,8 +99,6 @@ function isClass<T extends Array<unknown>, R = unknown>(
103
99
  value: unknown,
104
100
  ): value is new (...args: T) => R {
105
101
  if (!isFunction(value)) return false;
106
- // console.log('============')
107
- // console.log('???', value, value?.prototype, value?.prototype?.constructor);
108
102
  return value?.prototype?.constructor?.toString().match(/^class/);
109
103
  }
110
104
 
@@ -127,6 +121,7 @@ export function newStateHandlers<
127
121
  FsmStateContext
128
122
  >(),
129
123
  ) {
124
+ const triggers = new Map<unknown, () => void>();
130
125
  return (state: FsmState) => {
131
126
  const stack: FsmStateStore[] = [];
132
127
  for (let s: FsmState | undefined = state.parent; !!s; s = s.parent) {
@@ -161,20 +156,35 @@ export function newStateHandlers<
161
156
  }
162
157
 
163
158
  // Initialize triggers
164
- if (module.trigger) {
159
+ if (module.trigger && !triggers.has(module.trigger)) {
165
160
  const process = state.process;
166
- // Set trigger
167
- let notify = async (event: string) => {
168
- if (event && isStateTransitionEnabled(process, event)) {
169
- process.dispatch(event);
161
+ const iterator = module.trigger(stateContext);
162
+ let finalize: undefined | (() => void);
163
+ const end = new Promise<{ done: boolean; value?: string }>(
164
+ (r) => (finalize = () => r({ done: true })),
165
+ );
166
+ registrations.push(() => triggers.delete(module.trigger));
167
+ registrations.push(finalize);
168
+ registrations.push(() => iterator?.return?.(void 0));
169
+ (async () => {
170
+ try {
171
+ while (true) {
172
+ const { done, value: event } = await Promise.race([
173
+ iterator.next(),
174
+ end,
175
+ ]);
176
+ if (done) break;
177
+ if (event && isStateTransitionEnabled(process, event)) {
178
+ process.dispatch(event);
179
+ }
180
+ }
181
+ } finally {
182
+ finalize?.();
170
183
  }
171
- };
172
- const cleanup = module.trigger(stateContext, notify);
173
- registrations.push(() => {
174
- notify = async () => {};
175
- cleanup?.();
176
- });
184
+ })();
177
185
  }
186
+
187
+ // Run actions associated with this event
178
188
  if (module.handler) {
179
189
  const cleanup = module.handler(stateContext);
180
190
  registrations.push(cleanup);