@mantaq/core 0.4.0 → 0.5.1

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/README.md CHANGED
@@ -12,7 +12,7 @@ npm install @mantaq/core
12
12
 
13
13
  | Pattern | Correct | Anti-pattern |
14
14
  | --------------- | -------------------------------------------------- | ------------------------------------- |
15
- | Type context | `context: {} as MyContext` | casting in every handler |
15
+ | Type context | `const c: MyContext = {...}`, `context: c` | `as` cast on the context value |
16
16
  | Write context | `const s = context.get(); s.x = y; context.set(s)` | mutate without `set()` |
17
17
  | Type events | `event("ID")<Payload>()` | `event("ID")()` without generic |
18
18
  | Send events | `actor.send(signInEvent.create(data))` | raw `{ type: "ID", payload }` objects |
@@ -81,7 +81,7 @@ See [anderscan.github.io/mantaq](https://anderscan.github.io/mantaq) for full do
81
81
 
82
82
  ### Typed Actor Context
83
83
 
84
- Cast the context type once at the constructor level. Handlers receive the typed context automatically. No casting needed per-handler.
84
+ Declare the context value with its type once, then pass it to the constructor. Handlers receive the typed context automatically. `as` on the context is an anti-pattern: it hides missing fields.
85
85
 
86
86
  ```ts
87
87
  interface AuthContext {
@@ -89,11 +89,13 @@ interface AuthContext {
89
89
  phoneNumber?: string;
90
90
  }
91
91
 
92
+ const initialContext: AuthContext = {};
93
+
92
94
  const actor = new Actor({
93
95
  inputs: [signInEvent],
94
96
  states: [idleState, signingInState],
95
97
  initial: idleState,
96
- context: {} as AuthContext,
98
+ context: initialContext,
97
99
  setup: (m) => {
98
100
  m.on(idleState, signInEvent, (event, opts) => {
99
101
  // ✅ typed — context.get()/set() flow the constructor type
@@ -299,12 +301,13 @@ const doneEvent = event("WORK_DONE")();
299
301
  const failedEvent = event("WORK_FAILED")<{ error: string }>();
300
302
 
301
303
  function createActor() {
304
+ const initialContext: MyContext = { retryCount: 0, maxRetries: 3 };
302
305
  return new Actor({
303
306
  inputs: [startEvent],
304
307
  internal: [doneEvent, failedEvent],
305
308
  states: [idleState, workingState, doneState, errorState],
306
309
  initial: idleState,
307
- context: { retryCount: 0, maxRetries: 3 } as MyContext,
310
+ context: initialContext,
308
311
  setup: (m) => {
309
312
  m.effect(workingState, {
310
313
  name: "attemptWork",
package/dist/index.d.mts CHANGED
@@ -1,28 +1,3 @@
1
- //#region src/event.d.ts
2
- declare function event<const T extends string>(type: T): <Payload extends object | void = void>() => EventRef<T, Payload>;
3
- interface EventRef<T extends string = string, Payload extends object | void = void> {
4
- readonly type: T;
5
- is(anyEvent: unknown): anyEvent is CreatedOfEvent<T, Payload>;
6
- create(): Payload extends void ? {
7
- type: T;
8
- } : void;
9
- create(payload: Payload): Payload extends void ? {
10
- type: T;
11
- } : {
12
- type: T;
13
- payload: Payload;
14
- };
15
- }
16
- type AnyEventRef = EventRef<string, object | void>;
17
- type CreatedOfEvent<T extends string, P> = P extends void ? {
18
- type: T;
19
- } : {
20
- type: T;
21
- payload: P;
22
- };
23
- declare function EventRef<const T extends string, Payload extends object | void = void>(type: T): EventRef<T, Payload>;
24
- //#endregion
25
- //#region src/clock.d.ts
26
1
  interface Clock {
27
2
  setTimeout(ms: number, options: ClockTimerOptions): number;
28
3
  clearTimeout(id: number): void;
@@ -41,27 +16,23 @@ interface ClockIntervalOptions {
41
16
  cb: () => void;
42
17
  signal?: AbortSignal;
43
18
  }
44
- //#endregion
45
- //#region src/context.d.ts
46
- interface Context<T> {
19
+ export interface Context<T> {
47
20
  get(): T;
48
21
  set(value: T): void;
49
22
  }
50
23
  /** Two-way handle over an owner's context: reads see live values, writes flag dirty state upstream. */
51
- declare function Context<T>(options: {
24
+ export declare function Context<T>(options: {
52
25
  get: () => T;
53
26
  set: (value: T) => void;
54
27
  }): Context<T>;
55
- //#endregion
56
- //#region src/state.d.ts
57
- declare function state<const T extends string>(name: T): <Payload = unknown>() => StateRef<T, Payload, false>;
28
+ export declare function state<const T extends string>(name: T): <Payload = unknown>() => StateRef<T, Payload, false>;
58
29
  type AnyStateRef = StateRef<string, unknown, boolean>;
59
30
  interface RegionOptions {
60
31
  initial: string;
61
32
  states: Record<string, AnyStateRef>;
62
33
  }
63
34
  type RegionsOptions = Record<string, RegionOptions>;
64
- interface StateRef<T extends string = string, Payload = unknown, IsFinal extends boolean = false> {
35
+ export interface StateRef<T extends string = string, Payload = unknown, IsFinal extends boolean = false> {
65
36
  readonly name: T;
66
37
  readonly isFinal: IsFinal;
67
38
  /** @internal */ _regions?: RegionsOptions;
@@ -72,17 +43,15 @@ interface StateRef<T extends string = string, Payload = unknown, IsFinal extends
72
43
  payload: Payload;
73
44
  };
74
45
  }
75
- declare function isStateRef(value: unknown): value is StateRef;
76
- declare function StateRef<T extends string, Payload = unknown, IsFinal extends boolean = false>(name: T, options: {
46
+ export declare function isStateRef(value: unknown): value is StateRef;
47
+ export declare function StateRef<T extends string, Payload = unknown, IsFinal extends boolean = false>(name: T, options: {
77
48
  isFinal: IsFinal;
78
49
  }): StateRef<T, Payload, IsFinal>;
79
- //#endregion
80
- //#region src/actor-types.d.ts
81
50
  type CreatedOf<E extends EventRef<string, object | void>> = E extends EventRef<infer Type, infer P> ? CreatedOfEvent<Type, P> : never;
82
51
  type NonFinalStateRef<States extends AnyStateRef[]> = Extract<States[number], {
83
52
  isFinal: false;
84
53
  }>;
85
- interface EffectInput<ActorContext, Payload = unknown> {
54
+ interface EffectInput<ActorContext, Payload = unknown, Emit = InternalEvent> {
86
55
  signal: AbortSignal;
87
56
  state: {
88
57
  name: string;
@@ -90,10 +59,10 @@ interface EffectInput<ActorContext, Payload = unknown> {
90
59
  };
91
60
  event: InternalEvent;
92
61
  context: Context<ActorContext>;
93
- emit: (event: InternalEvent) => void;
62
+ emit: (event: Emit) => void;
94
63
  clock: Clock;
95
64
  }
96
- type EffectFn<ActorContext, Payload = unknown> = (input: EffectInput<ActorContext, Payload>) => void | Promise<void> | {
65
+ type EffectFn<ActorContext, Payload = unknown, Emit = InternalEvent> = (input: EffectInput<ActorContext, Payload, Emit>) => void | Promise<void> | {
97
66
  then(onFulfilled: unknown, onRejected: unknown): unknown;
98
67
  };
99
68
  type ErrorReason = "transition" | "effect" | "budget" | "output" | "internal" | "async" | "unhandled";
@@ -124,8 +93,6 @@ type TransitionResult<AllowedState extends AnyStateRef = AnyStateRef, AllowedEmi
124
93
  payload?: unknown;
125
94
  }>;
126
95
  };
127
- //#endregion
128
- //#region src/actor-internal.d.ts
129
96
  interface Snapshot<C = unknown> {
130
97
  path: string[];
131
98
  context: C;
@@ -153,6 +120,7 @@ interface AnyActor<C = Record<string, unknown>> {
153
120
  context?: C;
154
121
  options?: {
155
122
  transitions?: Record<string, Record<string, unknown>>;
123
+ targets?: Record<string, Record<string, string[]>>;
156
124
  effects?: Record<string, unknown[]>;
157
125
  states?: ReadonlyArray<{
158
126
  name: string;
@@ -162,53 +130,74 @@ interface AnyActor<C = Record<string, unknown>> {
162
130
  inject(event: InternalEvent): void;
163
131
  dispose(): void;
164
132
  }
165
- //#endregion
166
- //#region src/parse-handler.d.ts
167
133
  type RuntimeTransitionHandler<States extends readonly AnyStateRef[], ActorContext> = (event: InternalEvent, options: {
168
134
  context: Context<ActorContext>;
169
135
  actor: AnyActor<ActorContext>;
170
136
  }) => TransitionResult<States[number], string>;
171
- //#endregion
172
- //#region src/builder.d.ts
173
137
  type EventTypeOf<E extends AnyEventRef> = E extends EventRef<infer Type, object | void> ? Type : never;
174
138
  type PayloadOf<S extends AnyStateRef> = S extends StateRef<infer _Name, infer Payload, infer _IsFinal> ? Payload : never;
175
139
  type TransitionHandler<States extends readonly AnyStateRef[], ActorContext> = RuntimeTransitionHandler<States, ActorContext>;
176
140
  interface EffectEntry<ActorContext> {
177
141
  name: string;
142
+ sends?: string[];
178
143
  fn: EffectFn<ActorContext>;
179
144
  }
145
+ type EmitOf<E> = E extends readonly AnyEventRef[] ? CreatedOf<E[number]> : InternalEvent;
146
+ type SendList<I extends readonly AnyEventRef[]> = readonly I[number][] | undefined;
180
147
  interface BuiltMaps<States extends readonly AnyStateRef[], ActorContext> {
181
148
  transitions: Record<string, Record<string, TransitionHandler<States, ActorContext>>>;
149
+ /** Declared `to` state names per `[state][event]`; `Any` keys `onAny`. Static graph for tooling. */
150
+ targets: Record<string, Record<string, string[]>>;
182
151
  effects: Record<string, Array<EffectEntry<ActorContext>>>;
183
152
  }
184
- type HandlerFn<States extends readonly AnyStateRef[], _InputsInternal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> = (event: E extends EventRef<infer Type, infer P> ? CreatedOfEvent<Type, P> : never, opts: {
153
+ /** Handler may only return states listed in `to`; no `to` means it can only stay. */
154
+ type HandlerFn<To extends AnyStateRef, Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> = (event: E extends EventRef<infer Type, infer P> ? CreatedOfEvent<Type, P> : never, opts: {
185
155
  context: Context<ActorContext>;
186
156
  actor: AnyActor<ActorContext>;
187
- }) => TransitionResult<States[number], EventTypeOf<Outputs[number]>>;
157
+ }) => TransitionResult<To, EventTypeOf<Outputs[number]>>;
158
+ interface HandlerOptions<To extends readonly AnyStateRef[], Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> {
159
+ event: E;
160
+ to?: To;
161
+ handler: HandlerFn<NoInfer<To[number]>, Outputs, ActorContext, E>;
162
+ }
188
163
  interface ActorBuilder<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext> {
189
- on<S extends States[number], E extends Inputs[number] | Internal[number]>(stateRef: S, options: {
190
- eventRef: E;
191
- handler: HandlerFn<States, Inputs | Internal, Outputs, ActorContext, E>;
192
- }): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
193
- onAny<E extends Inputs[number] | Internal[number]>(options: {
194
- eventRef: E;
195
- handler: HandlerFn<States, Inputs | Internal, Outputs, ActorContext, E>;
196
- }): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
197
- effect<S extends States[number]>(stateRef: S, definition: {
164
+ on<S extends States[number], E extends Inputs[number] | Internal[number], const To extends readonly States[number][] = readonly []>(stateRef: S, options: HandlerOptions<To, Outputs, ActorContext, E>): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
165
+ onAny<E extends Inputs[number] | Internal[number], const To extends readonly States[number][] = readonly []>(options: HandlerOptions<To, Outputs, ActorContext, E>): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
166
+ /** `sends`: internal events `fn` may emit; `emit` only accepts those. Omit for untyped `emit`. */
167
+ effect<S extends States[number], const E extends SendList<Internal> = undefined>(stateRef: S, definition: {
198
168
  name: string;
199
- fn: EffectFn<ActorContext, PayloadOf<S>>;
169
+ sends?: E;
170
+ fn: EffectFn<ActorContext, PayloadOf<S>, EmitOf<E>>;
200
171
  }): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
201
172
  /** @internal */
202
173
  build(): BuiltMaps<States, ActorContext>;
203
174
  }
204
175
  declare function ActorBuilder<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext>(): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
205
176
  type SetupFn<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext> = (m: ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>) => void;
206
- //#endregion
207
- //#region src/real-clock.d.ts
208
- declare function RealClock(): Clock;
209
- //#endregion
210
- //#region src/virtual-clock.d.ts
211
- interface VirtualClock {
177
+ export declare function event<const T extends string>(type: T): <Payload extends object | void = void>() => EventRef<T, Payload>;
178
+ export interface EventRef<T extends string = string, Payload extends object | void = void> {
179
+ readonly type: T;
180
+ is(anyEvent: unknown): anyEvent is CreatedOfEvent<T, Payload>;
181
+ create(): Payload extends void ? {
182
+ type: T;
183
+ } : void;
184
+ create(payload: Payload): Payload extends void ? {
185
+ type: T;
186
+ } : {
187
+ type: T;
188
+ payload: Payload;
189
+ };
190
+ }
191
+ type AnyEventRef = EventRef<string, object | void>;
192
+ type CreatedOfEvent<T extends string, P> = P extends void ? {
193
+ type: T;
194
+ } : {
195
+ type: T;
196
+ payload: P;
197
+ };
198
+ export declare function EventRef<const T extends string, Payload extends object | void = void>(type: T): EventRef<T, Payload>;
199
+ export declare function RealClock(): Clock;
200
+ export interface VirtualClock {
212
201
  now(): number;
213
202
  setTimeout(ms: number, options: ClockTimerOptions): number;
214
203
  clearTimeout(id: number): void;
@@ -224,11 +213,7 @@ interface VirtualClock {
224
213
  }>;
225
214
  setDrain(fn: () => void): void;
226
215
  }
227
- declare function VirtualClock(): VirtualClock;
228
- //#endregion
229
- //#region src/actor.d.ts
230
- type CreatedOf$1<E extends AnyEventRef$1> = E extends EventRef<infer Type, infer P> ? CreatedOfEvent<Type, P> : never;
231
- type AnyEventRef$1 = AnyEventRef;
216
+ export declare function VirtualClock(): VirtualClock;
232
217
  type InitialState<S extends AnyStateRef> = S extends StateRef<infer _N extends string, infer P, infer _I extends boolean> ? [unknown] extends [P] ? S | {
233
218
  state: S;
234
219
  payload?: P;
@@ -236,7 +221,7 @@ type InitialState<S extends AnyStateRef> = S extends StateRef<infer _N extends s
236
221
  state: S;
237
222
  payload: P;
238
223
  } : never;
239
- interface ActorOptions<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef$1[], Internal extends readonly AnyEventRef$1[], Outputs extends readonly AnyEventRef$1[], ActorContext = Record<string, unknown>> {
224
+ interface ActorOptions<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext = Record<string, unknown>> {
240
225
  inputs: Inputs;
241
226
  outputs?: Outputs;
242
227
  internal?: Internal;
@@ -248,8 +233,9 @@ interface ActorOptions<States extends readonly AnyStateRef[], Inputs extends rea
248
233
  setup: SetupFn<States, Inputs, Internal, Outputs, ActorContext>;
249
234
  regions?: Record<string, AnyActor>;
250
235
  }
251
- interface InternalActorOptions<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef$1[], Internal extends readonly AnyEventRef$1[], Outputs extends readonly AnyEventRef$1[], ActorContext = Record<string, unknown>> extends Omit<ActorOptions<States, Inputs, Internal, Outputs, ActorContext>, "setup"> {
236
+ interface InternalActorOptions<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext = Record<string, unknown>> extends Omit<ActorOptions<States, Inputs, Internal, Outputs, ActorContext>, "setup"> {
252
237
  transitions: TransitionDispatch<States, ActorContext>;
238
+ targets: Record<string, Record<string, string[]>>;
253
239
  effects: Record<string, Array<EffectEntry<ActorContext>>>;
254
240
  }
255
241
  type TransitionDispatch<States extends readonly AnyStateRef[], ActorContext> = Record<string, Record<string, TransitionStepFn<States, ActorContext> | undefined>>;
@@ -257,7 +243,7 @@ type TransitionStepFn<States extends readonly AnyStateRef[], ActorContext> = (ev
257
243
  context: Context<ActorContext>;
258
244
  actor: AnyActor<ActorContext>;
259
245
  }) => TransitionResult<States[number], string>;
260
- interface Actor<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef$1[], Internal extends readonly AnyEventRef$1[] = readonly [], Outputs extends readonly AnyEventRef$1[] = readonly [], ActorContext = Record<string, unknown>> extends AnyActor<ActorContext> {
246
+ export interface Actor<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[] = readonly [], Outputs extends readonly AnyEventRef[] = readonly [], ActorContext = Record<string, unknown>> extends AnyActor<ActorContext> {
261
247
  state: States[number] | ErrorState;
262
248
  readonly clock: Clock;
263
249
  readonly context: ActorContext;
@@ -268,7 +254,7 @@ interface Actor<States extends readonly AnyStateRef[], Inputs extends readonly A
268
254
  }): () => void;
269
255
  settled(): Promise<void>;
270
256
  pendingEffectCount(): number;
271
- send(event: CreatedOf$1<Inputs[number]>): void;
257
+ send(event: CreatedOf<Inputs[number]>): void;
272
258
  recover(target: {
273
259
  state: States[number];
274
260
  context: ActorContext;
@@ -277,12 +263,9 @@ interface Actor<States extends readonly AnyStateRef[], Inputs extends readonly A
277
263
  inject(event: InternalEvent): void;
278
264
  dispose(): void;
279
265
  }
280
- declare function Actor<const States extends readonly AnyStateRef[], const Inputs extends readonly AnyEventRef$1[], const Internal extends readonly AnyEventRef$1[] = readonly [], const Outputs extends readonly AnyEventRef$1[] = readonly [], ActorContext = Record<string, unknown>>(options: ActorOptions<States, Inputs, Internal, Outputs, ActorContext>): Actor<States, Inputs, Internal, Outputs, ActorContext>;
281
- //#endregion
282
- //#region src/index.d.ts
283
- type InternalEvent = {
266
+ export declare function Actor<const States extends readonly AnyStateRef[], const Inputs extends readonly AnyEventRef[], const Internal extends readonly AnyEventRef[] = readonly [], const Outputs extends readonly AnyEventRef[] = readonly [], ActorContext = Record<string, unknown>>(options: ActorOptions<States, Inputs, Internal, Outputs, ActorContext>): Actor<States, Inputs, Internal, Outputs, ActorContext>;
267
+ export type InternalEvent = {
284
268
  type: string;
285
269
  payload?: unknown;
286
270
  };
287
- //#endregion
288
- export { Actor, type ActorBuilder, type ActorOptions, type AnyActor, type AnyEventRef, type AnyStateRef, type BuiltMaps, type Clock, Context, type CreatedOf, type CreatedOfEvent, type EffectFn, type EffectInput, type ErrorInfo, type ErrorReason, type ErrorState, EventRef, type EventTypeOf, type InitialState, InternalEvent, type NonFinalStateRef, type PayloadOf, RealClock, type SetupFn, type Snapshot, StateRef, type TransitionHandler, type TransitionInfo, type TransitionResult, VirtualClock, event, isStateRef, state };
271
+ export type { ActorBuilder, ActorOptions, AnyActor, AnyEventRef, AnyStateRef, BuiltMaps, Clock, CreatedOf, CreatedOfEvent, EffectFn, EffectInput, ErrorInfo, ErrorReason, ErrorState, EventTypeOf, InitialState, NonFinalStateRef, PayloadOf, SetupFn, Snapshot, TransitionHandler, TransitionInfo, TransitionResult };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{Either as e}from"@mantaq/utils";function t(e){let t=e;return typeof t==`function`?t:()=>({})}function n(e){return e}function r(){let e={},r={},i={on(n,{eventRef:r,handler:a}){let o=n.name,s=r.type;return(e[o]??={})[s]=t(a),i},onAny(n){let r=n.eventRef.type;return(e.Any??={})[r]=t(n.handler),i},effect(e,{name:t,fn:a}){return(r[e.name]??=[]).push({name:t,fn:n(a)}),i},build(){return{transitions:e,effects:r}}};return i}function i(e){return{get:e.get,set:e.set}}function a(e){return()=>c(e,{isFinal:!1})}const o=new WeakSet;function s(e){return typeof e==`object`&&!!e&&o.has(e)}function c(e,t){let n={name:e,isFinal:t.isFinal,regions(e){return n._regions=e,n},final(){let e=c(n.name,{isFinal:!0});return e._regions=n._regions,e},create(e){return{state:n,payload:e}}};return o.add(n),n}function l(e){let t=e.state;if(t)return`state`in t?{state:t.state,payload:t.payload}:{state:t,payload:e.payload}}function u(e){if(e instanceof Promise)return!0;let t=e;return typeof t==`object`&&!!t&&typeof t.then==`function`}function d(t){let n=[],r=[],i=t.effects[t.state.name];if(!i)return{pending:n,ran:r};for(let{name:a,fn:o}of i){if(t.abort.signal.aborted)break;let i,s=e.from(()=>(i=o({signal:t.abort.signal,state:{name:t.state.name,payload:t.statePayload},event:t.event,context:t.context,emit:t.emit,clock:t.clock}),!0));if(s[0]!==void 0){t.onError(s[0],t.lastGood);break}if(r.push(a),u(i)){let e=Promise.resolve(i).then(()=>void 0,e=>{t.abort.signal.aborted||t.onError(e,t.lastGood)});n.push(e)}}return{pending:n,ran:r}}function ee(e){return e??{}}function f(){let e=[],t=0,n=!1,r=!1,i=[];function a(){let e=i.splice(0);for(let t of e)t()}function o(i){if(!n){n=!0;try{for(;t<e.length&&!r;){let n=e[t];if(t++,!i(n)){r=!0;break}}}finally{e.length=0,t=0,n=!1,r=!1,a()}}}return{get length(){return e.length-t},push(...t){r||e.push(...t)},clear(){e.length=0,t=0,a()},settled(){return e.length-t===0&&!n?Promise.resolve():new Promise(e=>{i.push(e)})},processCancellable(e){o(e)}}}function p(){let e=Date.now(),t=new Map;function n(e){let n=t.get(e);n&&(n.signal.removeEventListener(`abort`,n.onAbort),t.delete(e))}return{now(){return Date.now()-e},setTimeout(e,{signal:r,cb:i}){if(r?.aborted)return-1;let a=Number(globalThis.setTimeout(()=>{n(a),i()},e));if(r){function e(){globalThis.clearTimeout(a),n(a)}t.set(a,{signal:r,onAbort:e}),r.addEventListener(`abort`,e,{once:!0})}return a},clearTimeout(e){globalThis.clearTimeout(e),n(e)},setInterval(e,{signal:r,cb:i}){if(r?.aborted)return-1;let a=Number(globalThis.setInterval(i,e));if(r){function e(){globalThis.clearInterval(a),n(a)}t.set(a,{signal:r,onAbort:e}),r.addEventListener(`abort`,e,{once:!0})}return a},clearInterval(e){globalThis.clearInterval(e),n(e)}}}function m(e){let{stateRef:t,regions:n,context:r}=e,i=[t.name],a={};for(let[e,t]of Object.entries(n))a[e]=t.snapshot();let o={path:i,context:r,regions:a};return e.payload!==void 0&&(o.payload=e.payload),t.isFinal&&(o.done=!0),e.error!==void 0&&(o.error={...e.error,context:h(e.error.context)}),o}function h(e){return typeof structuredClone==`function`?structuredClone(e):JSON.parse(JSON.stringify(e))}function g(){let t=new Set,n=new Set,r=new Set,i=new Set,a=new Set,o;function s(t){e.from(()=>(t(),!0))}return{change:t,done:n,transition:r,error:i,output:a,seed(e){o=e},addChange(e){t.add(e);let n=o;return n&&s(()=>e(n,n)),()=>t.delete(e)},addDone(e){return n.add(e),()=>n.delete(e)},addTransition(e){return r.add(e),()=>r.delete(e)},addError(e){i.add(e);let t=o?.error;return t&&s(()=>e(t)),()=>i.delete(e)},addOutput(e){return a.add(e),()=>a.delete(e)},emitChange(e){let n=o??e;o=e;for(let r of t)s(()=>r(e,n))},emitDone(){for(let e of n)s(e)},emitTransition(e){for(let t of r)s(()=>t(e))},emitError(e){for(let t of i)s(()=>t(e))},emitOutput(e){for(let t of a)t(e)},clear(){t.clear(),n.clear(),r.clear(),i.clear(),a.clear()}}}function _(e,t){let n=e?()=>{t.entries.delete(t.timerId)}:void 0;return e&&n&&e.addEventListener(`abort`,n,{once:!0}),n}function v(e){e.signal&&e.onAbort&&e.signal.removeEventListener(`abort`,e.onAbort)}function y(){let e=0,t=new Map,n=new Map,r=1,i=new Set;function a(e,t){if(!Number.isFinite(e))throw RangeError(`[VirtualClock] invalid ${t.method} ms value: ${e}`);return!0}function o(e,t){return a(e,{method:t.method}),e<=0?+!!t.interval:e}function s(e){let r=e,i=!1;for(let n of t.values())n.deadline<=e&&n.deadline<=r&&(r=n.deadline,i=!0);for(let t of n.values())t.next<=e&&t.next<=r&&(r=t.next,i=!0);return i?r:void 0}function c(e){let n=[];for(let[r,i]of t)i.deadline===e&&n.push(r);for(let e of n){let n=t.get(e);n&&(v(n),t.delete(e),n.cb())}}function l(t){let r=[];for(let[e,i]of n)i.next===t&&r.push(e);for(let t of r){let r=n.get(t);r&&(r.cb(),n.has(t)&&(r.next=e+r.ms))}}return{now(){return e},setTimeout(n,{signal:i,cb:a,eventName:s}){if(i?.aborted)return-1;let c=r++,l=_(i,{timerId:c,entries:t});return t.set(c,{deadline:e+o(n,{method:`setTimeout`,interval:!1}),cb:a,signal:i,onAbort:l,eventName:s}),c},clearTimeout(e){let n=t.get(e);n&&(v(n),t.delete(e))},setInterval(t,{signal:i,cb:a}){if(i?.aborted)return-1;let s=r++,c=_(i,{timerId:s,entries:n}),l=o(t,{method:`setInterval`,interval:!0});return n.set(s,{ms:l,next:e+l,cb:a,signal:i,onAbort:c}),s},clearInterval(e){let t=n.get(e);t&&(v(t),n.delete(e))},advance(t){a(t,{method:`advance`});let n=e+Math.max(0,t),r=-1,o=0;for(;;){let t=s(n);if(t===void 0)break;if(t===r){if(++o>=1e6)break}else o=0,r=t;e=t,c(t),l(t)}e=n;for(let e of i)e()},hasPending(){return t.size>0||n.size>0},pendingTimers(){let n=[];for(let[r,i]of t)n.push({id:r,deadline:i.deadline,ms:i.deadline-e,eventName:i.eventName});return n},setDrain(e){i.add(e)}}}function b(e){return`state`in e?e.state:e}function x(e,t){if(!e.has(t.candidate.name))throw Error(`[Actor] initial state "${t.candidate.name}" not found in declared states [${[...e].join(`, `)}]`);return!0}function S(t){let n=r();t.setup(n);let a=n.build(),o={...t,transitions:a.transitions,effects:a.effects},u=new Set((t.internal??[]).map(e=>e.type)),_=new Set(t.inputs.map(e=>e.type)),v=t.internalBudget??1e4,y=t.clock??p();y.setDrain?.(Y);let S,C,w=ee(t.context),T,E=!0,D,O={},k=f(),A=g(),j,M=!1,N=[],P,F,I=!1,L=!1,R=c(`__error`,{isFinal:!0}),z=i({get:()=>w,set:e=>{w=e,L=!0,E=!0}}),B=b(t.initial);x(new Set(t.states.map(e=>e.name)),{candidate:B}),S=B;let V=t.initial;if(C=!s(V)&&`payload`in V?V.payload:void 0,D=B,t.regions)for(let[e,n]of Object.entries(t.regions))O[e]=n,n.on(`output`,{fn:e=>{k.push(e),Y()}});let H={get state(){return S},clock:y,get regions(){return O},get context(){return w},get options(){return o},on(e,t){return{change:e=>A.addChange(e),done:e=>A.addDone(e),transition:e=>A.addTransition(e),error:e=>A.addError(e),output:e=>A.addOutput(e)}[e](t.fn)},settled(){return Q()},pendingEffectCount(){return N.length},send(e){I||(G(e),U())},recover:W,snapshot(){return K()},inject(e){ae(e)},dispose(){oe()}};J({type:`__init`},{payloadForState:C}),A.seed(K());function U(){S===D&&!L||(D=S,L=!1,A.emitChange(K()))}function W(e){P===void 0||I||(j?.abort(),j=void 0,k.clear(),k=f(),P=void 0,S=e.state,C=void 0,w=e.context,D=e.state,L=!1,E=!0,T=void 0,F=void 0,N=[],A.emitChange(K()))}function G(e){if(P!==void 0||S.isFinal)return;let t={...e,payload:e.payload??{}},n=S.name,r=F;F={state:S,context:w};try{let r=o.transitions,i=r[S.name]?.[e.type],a=r.Any?.[e.type],s=te(t,{stateTransition:i,anyTransition:a});ne(t,{from:n,handled:!!(i||a),outcome:s}),s.emitted||k.length>0?Y():!i&&!a&&u.has(e.type)&&Z(`unhandled`,{event:e,error:Error(`[Actor] internal event "${e.type}" emitted but no handler in state "${S.name}"`)})}finally{F=r}}function te(e,t){let n=t.stateTransition?re(e,{transition:t.stateTransition}):{applied:!1,target:void 0,effects:void 0};if(P===void 0){let r=ie(e,{transition:t.anyTransition,allowTransition:!n.applied});return{emitted:r.emitted,transitioned:n.applied||r.transitioned,target:n.target??r.target,effects:n.effects??r.effects}}return{emitted:!1,transitioned:!1}}function ne(e,t){P===void 0&&t.handled&&A.emitTransition({event:e,from:t.from,to:t.outcome.target??S.name,transitioned:t.outcome.transitioned,effects:t.outcome.effects??[]})}function re(e,t){let n=!1,r,i;return X(`transition`,{event:e,operation:()=>{let a=t.transition(e,{context:z,actor:$()});if(a.emit&&k.push(...a.emit),a.state){let t=q(e,{step:a});r=t.target,i=t.effects,n=!0}}}),{applied:n,target:r,effects:i}}function ie(e,t){if(t.transition===void 0)return{emitted:!1,transitioned:!1};let n=t.transition,r=!1,i=!1,a,o;return X(`transition`,{event:e,operation:()=>{let s=n(e,{context:z,actor:$()});if(s.state&&t.allowTransition){let t=q(e,{step:s});a=t.target,o=t.effects,i=!0}s.emit&&(k.push(...s.emit),r=!0)}}),{emitted:r,transitioned:i,target:a,effects:o}}function K(){return(T===void 0||E)&&(T=h(w),E=!1),m({stateRef:S,regions:O,context:T,error:P,payload:C})}function q(e,t){if(P!==void 0||!t.step.state)return{};let n=l(t.step);if(!n)return{};if(!s(n.state))return Z(`transition`,{event:e,error:Error(`invalid transition target`)}),{};j?.abort(),S=n.state;let r=S.name;C=n.payload,F={state:S,context:w};let i=J(e,{payloadForState:n.payload});return n.state.isFinal&&P===void 0&&A.emitDone(),{target:r,effects:i}}function J(e,t){if(I)return[];let n=o.effects[S.name];if(!n)return j=void 0,[];let r=new AbortController;j=r;let i=F??{state:S,context:w},a=d({effects:{[S.name]:n},state:S,statePayload:t.payloadForState,event:e,context:z,emit:e=>{P!==void 0||r.signal.aborted||(k.push(e),Y())},clock:y,abort:r,lastGood:i,onError:t=>Z(`effect`,{event:e,error:t})});for(let e of a.pending)N.push(e),e.finally(()=>{let t=N.indexOf(e);t!==-1&&N.splice(t,1)}).catch(()=>{});return a.ran}function Y(){if(!(M||I)){M=!0;try{let e=0;k.processCancellable(t=>{if(P!==void 0)return!1;if(e>=v)return Z(`budget`,{event:t,error:Error(`internal event budget exceeded`)}),!1;if(e++,u.has(t.type)||_.has(t.type))G(t);else if(!X(`output`,{event:t,operation:()=>A.emitOutput(t)}))return!1;return!0})}finally{M=!1,U()}}}function X(t,n){let r=e.from(()=>(n.operation(),!0));return r[0]===void 0||(Z(t,{event:n.event,error:r[0]}),!1)}function Z(e,t){if(P!==void 0)return;let n=t.lastGood??F??{state:S,context:w};P={error:t.error,state:n.state,context:n.context,event:t.event,reason:e},j?.abort(),S=R,C=void 0,D=R,L=!1,A.emitError(P),A.emitChange(K()),A.emitDone()}function ae(e){I||(k.push(e),Y())}function oe(){if(!I){I=!0,j?.abort(),j=void 0;for(let e of Object.values(O))e.dispose();O={},k.clear(),A.clear(),N=[]}}function Q(){return k.settled().then(()=>{if(N.length!==0)return Promise.all(N).then(()=>Q())})}function $(){return H}return H}const C=new Map;function w(e){let t=C.get(e);return t||(t=Symbol(`mantaq:event:${e}`),C.set(e,t)),t}const T=new WeakMap;function E(e){return()=>D(e)}function D(e){let t=w(e),n=function(e){return typeof e==`object`&&!!e&&T.get(e)?.has(t)===!0};function r(n){let r=n===void 0?{type:e}:{type:e,payload:n},i=T.get(r);return i||(i=new Set,T.set(r,i)),i.add(t),r}return{type:e,is:n,create:r}}export{S as Actor,i as Context,D as EventRef,p as RealClock,c as StateRef,y as VirtualClock,E as event,s as isStateRef,a as state};
1
+ import{Either as e}from"@mantaq/utils";function t(e){let t=e;return typeof t==`function`?t:()=>({})}function n(e){return e}function r(){let e={},r={},i={};function a(n,i){let a=i.event.type;(e[n]??={})[a]=t(i.handler),(r[n]??={})[a]=(i.to??[]).map(e=>e.name)}let o={on(e,t){return a(e.name,t),o},onAny(e){return a(`Any`,e),o},effect(e,{name:t,sends:r,fn:a}){return(i[e.name]??=[]).push({name:t,...r&&{sends:r.map(e=>e.type)},fn:n(a)}),o},build(){return{transitions:e,targets:r,effects:i}}};return o}function i(e){return{get:e.get,set:e.set}}function a(e){return()=>c(e,{isFinal:!1})}const o=/* @__PURE__ */ new WeakSet;function s(e){return typeof e==`object`&&!!e&&o.has(e)}function c(e,t){let n={name:e,isFinal:t.isFinal,regions(e){return n._regions=e,n},final(){let e=c(n.name,{isFinal:!0});return e._regions=n._regions,e},create(e){return{state:n,payload:e}}};return o.add(n),n}function l(e){let t=e.state;if(t)return`state`in t?{state:t.state,payload:t.payload}:{state:t,payload:e.payload}}function u(e){if(e instanceof Promise)return!0;let t=e;return typeof t==`object`&&!!t&&typeof t.then==`function`}function ee(t){let n=[],r=[],i=t.effects[t.state.name];if(!i)return{pending:n,ran:r};for(let{name:a,fn:o}of i){if(t.abort.signal.aborted)break;let i,s=e.from(()=>(i=o({signal:t.abort.signal,state:{name:t.state.name,payload:t.statePayload},event:t.event,context:t.context,emit:t.emit,clock:t.clock}),!0));if(s[0]!==void 0){t.onError(s[0],t.lastGood);break}if(r.push(a),u(i)){let e=Promise.resolve(i).then(()=>void 0,e=>{t.abort.signal.aborted||t.onError(e,t.lastGood)});n.push(e)}}return{pending:n,ran:r}}function d(e){return e??{}}function f(){let e=[],t=0,n=!1,r=!1,i=[];function a(){let e=i.splice(0);for(let t of e)t()}function o(i){if(!n){n=!0;try{for(;t<e.length&&!r;){let n=e[t];if(t++,!i(n)){r=!0;break}}}finally{e.length=0,t=0,n=!1,r=!1,a()}}}return{get length(){return e.length-t},push(...t){r||e.push(...t)},clear(){e.length=0,t=0,a()},settled(){return e.length-t===0&&!n?Promise.resolve():new Promise(e=>{i.push(e)})},processCancellable(e){o(e)}}}function p(){let e=Date.now(),t=/* @__PURE__ */ new Map;function n(e){let n=t.get(e);n&&(n.signal.removeEventListener(`abort`,n.onAbort),t.delete(e))}return{now(){return Date.now()-e},setTimeout(e,{signal:r,cb:i}){if(r?.aborted)return-1;let a=Number(globalThis.setTimeout(()=>{n(a),i()},e));if(r){function e(){globalThis.clearTimeout(a),n(a)}t.set(a,{signal:r,onAbort:e}),r.addEventListener(`abort`,e,{once:!0})}return a},clearTimeout(e){globalThis.clearTimeout(e),n(e)},setInterval(e,{signal:r,cb:i}){if(r?.aborted)return-1;let a=Number(globalThis.setInterval(i,e));if(r){function e(){globalThis.clearInterval(a),n(a)}t.set(a,{signal:r,onAbort:e}),r.addEventListener(`abort`,e,{once:!0})}return a},clearInterval(e){globalThis.clearInterval(e),n(e)}}}function te(e){let{stateRef:t,regions:n,context:r}=e,i=[t.name],a={};for(let[e,t]of Object.entries(n))a[e]=t.snapshot();let o={path:i,context:r,regions:a};return e.payload!==void 0&&(o.payload=e.payload),t.isFinal&&(o.done=!0),e.error!==void 0&&(o.error={...e.error,context:m(e.error.context)}),o}function m(e){return typeof structuredClone==`function`?structuredClone(e):JSON.parse(JSON.stringify(e))}function h(){let t=/* @__PURE__ */ new Set,n=/* @__PURE__ */ new Set,r=/* @__PURE__ */ new Set,i=/* @__PURE__ */ new Set,a=/* @__PURE__ */ new Set,o;function s(t){e.from(()=>(t(),!0))}return{change:t,done:n,transition:r,error:i,output:a,seed(e){o=e},addChange(e){t.add(e);let n=o;return n&&s(()=>e(n,n)),()=>t.delete(e)},addDone(e){return n.add(e),()=>n.delete(e)},addTransition(e){return r.add(e),()=>r.delete(e)},addError(e){i.add(e);let t=o?.error;return t&&s(()=>e(t)),()=>i.delete(e)},addOutput(e){return a.add(e),()=>a.delete(e)},emitChange(e){let n=o??e;o=e;for(let r of t)s(()=>r(e,n))},emitDone(){for(let e of n)s(e)},emitTransition(e){for(let t of r)s(()=>t(e))},emitError(e){for(let t of i)s(()=>t(e))},emitOutput(e){for(let t of a)t(e)},clear(){t.clear(),n.clear(),r.clear(),i.clear(),a.clear()}}}function g(e,t){let n=e?()=>{t.entries.delete(t.timerId)}:void 0;return e&&n&&e.addEventListener(`abort`,n,{once:!0}),n}function _(e){e.signal&&e.onAbort&&e.signal.removeEventListener(`abort`,e.onAbort)}function v(){let e=0,t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Map,r=1,i=/* @__PURE__ */ new Set;function a(e,t){if(!Number.isFinite(e))throw RangeError(`[VirtualClock] invalid ${t.method} ms value: ${e}`);return!0}function o(e,t){return a(e,{method:t.method}),e<=0?+!!t.interval:e}function s(e){let r=e,i=!1;for(let n of t.values())n.deadline<=e&&n.deadline<=r&&(r=n.deadline,i=!0);for(let t of n.values())t.next<=e&&t.next<=r&&(r=t.next,i=!0);return i?r:void 0}function c(e){let n=[];for(let[r,i]of t)i.deadline===e&&n.push(r);for(let e of n){let n=t.get(e);n&&(_(n),t.delete(e),n.cb())}}function l(t){let r=[];for(let[e,i]of n)i.next===t&&r.push(e);for(let t of r){let r=n.get(t);r&&(r.cb(),n.has(t)&&(r.next=e+r.ms))}}return{now(){return e},setTimeout(n,{signal:i,cb:a,eventName:s}){if(i?.aborted)return-1;let c=r++,l=g(i,{timerId:c,entries:t});return t.set(c,{deadline:e+o(n,{method:`setTimeout`,interval:!1}),cb:a,signal:i,onAbort:l,eventName:s}),c},clearTimeout(e){let n=t.get(e);n&&(_(n),t.delete(e))},setInterval(t,{signal:i,cb:a}){if(i?.aborted)return-1;let s=r++,c=g(i,{timerId:s,entries:n}),l=o(t,{method:`setInterval`,interval:!0});return n.set(s,{ms:l,next:e+l,cb:a,signal:i,onAbort:c}),s},clearInterval(e){let t=n.get(e);t&&(_(t),n.delete(e))},advance(t){a(t,{method:`advance`});let n=e+Math.max(0,t),r=-1,o=0;for(;;){let t=s(n);if(t===void 0)break;if(t===r){if(++o>=1e6)break}else o=0,r=t;e=t,c(t),l(t)}e=n;for(let e of i)e()},hasPending(){return t.size>0||n.size>0},pendingTimers(){let n=[];for(let[r,i]of t)n.push({id:r,deadline:i.deadline,ms:i.deadline-e,eventName:i.eventName});return n},setDrain(e){i.add(e)}}}function y(e){return`state`in e?e.state:e}function b(e,t){if(!e.has(t.candidate.name))throw Error(`[Actor] initial state "${t.candidate.name}" not found in declared states [${[...e].join(`, `)}]`);return!0}function x(t){let n=r();t.setup(n);let a=n.build(),o={...t,transitions:a.transitions,targets:a.targets,effects:a.effects},u=new Set((t.internal??[]).map(e=>e.type)),g=new Set(t.inputs.map(e=>e.type)),_=t.internalBudget??1e4,v=t.clock??p();v.setDrain?.(Y);let x,S,C=d(t.context),w,T=!0,E,D={},O=f(),k=h(),A,j=!1,M=[],N,P,F=!1,I=!1,L=c(`__error`,{isFinal:!0}),R=i({get:()=>C,set:e=>{C=e,I=!0,T=!0}}),z=y(t.initial);b(new Set(t.states.map(e=>e.name)),{candidate:z}),x=z;let B=t.initial;if(S=!s(B)&&`payload`in B?B.payload:void 0,E=z,t.regions)for(let[e,n]of Object.entries(t.regions))D[e]=n,n.on(`output`,{fn:e=>{O.push(e),Y()}});let V={get state(){return x},clock:v,get regions(){return D},get context(){return C},get options(){return o},on(e,t){return{change:e=>k.addChange(e),done:e=>k.addDone(e),transition:e=>k.addTransition(e),error:e=>k.addError(e),output:e=>k.addOutput(e)}[e](t.fn)},settled(){return Q()},pendingEffectCount(){return M.length},send(e){F||(W(e),H())},recover:U,snapshot(){return K()},inject(e){ae(e)},dispose(){oe()}};J({type:`__init`},{payloadForState:S}),k.seed(K());function H(){(x!==E||I)&&(E=x,I=!1,k.emitChange(K()))}function U(e){N===void 0||F||(A?.abort(),A=void 0,O.clear(),O=f(),N=void 0,x=e.state,S=void 0,C=e.context,E=e.state,I=!1,T=!0,w=void 0,P=void 0,M=[],k.emitChange(K()))}function W(e){if(N!==void 0||x.isFinal)return;let t={...e,payload:e.payload??{}},n=x.name,r=P;P={state:x,context:C};try{let r=o.transitions,i=r[x.name]?.[e.type],a=r.Any?.[e.type],s=G(t,{stateTransition:i,anyTransition:a});ne(t,{from:n,handled:!!(i||a),outcome:s}),s.emitted||O.length>0?Y():!i&&!a&&u.has(e.type)&&Z(`unhandled`,{event:e,error:/* @__PURE__ */ Error(`[Actor] internal event "${e.type}" emitted but no handler in state "${x.name}"`)})}finally{P=r}}function G(e,t){let n=t.stateTransition?re(e,{transition:t.stateTransition}):{applied:!1,target:void 0,effects:void 0};if(N===void 0){let r=ie(e,{transition:t.anyTransition,allowTransition:!n.applied});return{emitted:r.emitted,transitioned:n.applied||r.transitioned,target:n.target??r.target,effects:n.effects??r.effects}}return{emitted:!1,transitioned:!1}}function ne(e,t){N===void 0&&t.handled&&k.emitTransition({event:e,from:t.from,to:t.outcome.target??x.name,transitioned:t.outcome.transitioned,effects:t.outcome.effects??[]})}function re(e,t){let n=!1,r,i;return X(`transition`,{event:e,operation:()=>{let a=t.transition(e,{context:R,actor:$()});if(a.emit&&O.push(...a.emit),a.state){let t=q(e,{step:a});r=t.target,i=t.effects,n=!0}}}),{applied:n,target:r,effects:i}}function ie(e,t){if(t.transition===void 0)return{emitted:!1,transitioned:!1};let n=t.transition,r=!1,i=!1,a,o;return X(`transition`,{event:e,operation:()=>{let s=n(e,{context:R,actor:$()});if(s.state&&t.allowTransition){let t=q(e,{step:s});a=t.target,o=t.effects,i=!0}s.emit&&(O.push(...s.emit),r=!0)}}),{emitted:r,transitioned:i,target:a,effects:o}}function K(){return(w===void 0||T)&&(w=m(C),T=!1),te({stateRef:x,regions:D,context:w,error:N,payload:S})}function q(e,t){if(N!==void 0||!t.step.state)return{};let n=l(t.step);if(!n)return{};if(!s(n.state))return Z(`transition`,{event:e,error:/* @__PURE__ */ Error(`invalid transition target`)}),{};A?.abort(),x=n.state;let r=x.name;S=n.payload,P={state:x,context:C};let i=J(e,{payloadForState:n.payload});return n.state.isFinal&&N===void 0&&k.emitDone(),{target:r,effects:i}}function J(e,t){if(F)return[];let n=o.effects[x.name];if(!n)return A=void 0,[];let r=new AbortController;A=r;let i=P??{state:x,context:C},a=ee({effects:{[x.name]:n},state:x,statePayload:t.payloadForState,event:e,context:R,emit:e=>{N!==void 0||r.signal.aborted||(O.push(e),Y())},clock:v,abort:r,lastGood:i,onError:t=>Z(`effect`,{event:e,error:t})});for(let e of a.pending)M.push(e),e.finally(()=>{let t=M.indexOf(e);t!==-1&&M.splice(t,1)}).catch(()=>{});return a.ran}function Y(){if(!(j||F)){j=!0;try{let e=0;O.processCancellable(t=>{if(N!==void 0)return!1;if(e>=_)return Z(`budget`,{event:t,error:/* @__PURE__ */ Error(`internal event budget exceeded`)}),!1;if(e++,u.has(t.type)||g.has(t.type))W(t);else if(!X(`output`,{event:t,operation:()=>k.emitOutput(t)}))return!1;return!0})}finally{j=!1,H()}}}function X(t,n){let r=e.from(()=>(n.operation(),!0));return r[0]===void 0||(Z(t,{event:n.event,error:r[0]}),!1)}function Z(e,t){if(N!==void 0)return;let n=t.lastGood??P??{state:x,context:C};N={error:t.error,state:n.state,context:n.context,event:t.event,reason:e},A?.abort(),x=L,S=void 0,E=L,I=!1,k.emitError(N),k.emitChange(K()),k.emitDone()}function ae(e){F||(O.push(e),Y())}function oe(){if(!F){F=!0,A?.abort(),A=void 0;for(let e of Object.values(D))e.dispose();D={},O.clear(),k.clear(),M=[]}}function Q(){return O.settled().then(()=>{if(M.length!==0)return Promise.all(M).then(()=>Q())})}function $(){return V}return V}function S(e){return Symbol.for(`mantaq:event:${e}`)}function C(e){return()=>w(e)}function w(e){let t=S(e),n=function(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,t)};function r(n){return Object.defineProperty(n===void 0?{type:e}:{type:e,payload:n},t,{value:!0})}return{type:e,is:n,create:r}}export{x as Actor,i as Context,w as EventRef,p as RealClock,c as StateRef,v as VirtualClock,C as event,s as isStateRef,a as state};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantaq/core",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "State machine runtime with actor model, event system, state hierarchy, effects, and virtual clock.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,15 +24,15 @@
24
24
  "@mantaq/utils": "0.0.4"
25
25
  },
26
26
  "devDependencies": {
27
- "@stryker-mutator/core": "^9",
28
- "@stryker-mutator/vitest-runner": "^9",
27
+ "@stryker-mutator/core": "^10",
28
+ "@stryker-mutator/vitest-runner": "^10",
29
29
  "@types/node": "^26.2.0",
30
30
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
31
- "@vitest/coverage-v8": "4.1.10",
31
+ "@vitest/coverage-v8": "5.0.5",
32
32
  "typescript": "6.0.3",
33
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.8",
34
- "vite-plus": "0.2.8",
35
- "vitest": "4.1.10",
33
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
34
+ "vite-plus": "1.4.0",
35
+ "vitest": "5.0.5",
36
36
  "@mantaq/pbt": "0.0.3"
37
37
  },
38
38
  "scripts": {