@mantaq/core 0.5.2 → 0.5.4
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.d.mts +18 -5
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -133,6 +133,10 @@ interface AnyActor<C = Record<string, unknown>> {
|
|
|
133
133
|
type RuntimeTransitionHandler<States extends readonly AnyStateRef[], ActorContext> = (event: InternalEvent, options: {
|
|
134
134
|
context: Context<ActorContext>;
|
|
135
135
|
actor: AnyActor<ActorContext>;
|
|
136
|
+
state: {
|
|
137
|
+
name: string;
|
|
138
|
+
payload: unknown;
|
|
139
|
+
};
|
|
136
140
|
}) => TransitionResult<States[number], string>;
|
|
137
141
|
type EventTypeOf<E extends AnyEventRef> = E extends EventRef<infer Type, object | void> ? Type : never;
|
|
138
142
|
type PayloadOf<S extends AnyStateRef> = S extends StateRef<infer _Name, infer Payload, infer _IsFinal> ? Payload : never;
|
|
@@ -150,19 +154,24 @@ interface BuiltMaps<States extends readonly AnyStateRef[], ActorContext> {
|
|
|
150
154
|
targets: Record<string, Record<string, string[]>>;
|
|
151
155
|
effects: Record<string, Array<EffectEntry<ActorContext>>>;
|
|
152
156
|
}
|
|
157
|
+
type StateInput<S> = S extends AnyStateRef ? {
|
|
158
|
+
name: S["name"];
|
|
159
|
+
payload: PayloadOf<S>;
|
|
160
|
+
} : never;
|
|
153
161
|
/** 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: {
|
|
162
|
+
type HandlerFn<Current extends AnyStateRef, To extends AnyStateRef, Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> = (event: E extends EventRef<infer Type, infer P> ? CreatedOfEvent<Type, P> : never, opts: {
|
|
155
163
|
context: Context<ActorContext>;
|
|
156
164
|
actor: AnyActor<ActorContext>;
|
|
165
|
+
state: StateInput<Current>;
|
|
157
166
|
}) => TransitionResult<To, EventTypeOf<Outputs[number]>>;
|
|
158
|
-
interface HandlerOptions<To extends readonly AnyStateRef[], Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> {
|
|
167
|
+
interface HandlerOptions<Current extends AnyStateRef, To extends readonly AnyStateRef[], Outputs extends readonly AnyEventRef[], ActorContext, E extends AnyEventRef> {
|
|
159
168
|
event: E;
|
|
160
169
|
to?: To;
|
|
161
|
-
handler: HandlerFn<NoInfer<To[number]>, Outputs, ActorContext, E>;
|
|
170
|
+
handler: HandlerFn<Current, NoInfer<To[number]>, Outputs, ActorContext, E>;
|
|
162
171
|
}
|
|
163
172
|
interface ActorBuilder<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext> {
|
|
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>;
|
|
173
|
+
on<S extends States[number], E extends Inputs[number] | Internal[number], const To extends readonly States[number][] = readonly []>(stateRef: S, options: HandlerOptions<S, To, Outputs, ActorContext, E>): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
|
|
174
|
+
onAny<E extends Inputs[number] | Internal[number], const To extends readonly States[number][] = readonly []>(options: HandlerOptions<States[number], To, Outputs, ActorContext, E>): ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>;
|
|
166
175
|
/** `sends`: internal events `fn` may emit; `emit` only accepts those. Omit for untyped `emit`. */
|
|
167
176
|
effect<S extends States[number], const E extends SendList<Internal> = undefined>(stateRef: S, definition: {
|
|
168
177
|
name: string;
|
|
@@ -242,6 +251,10 @@ type TransitionDispatch<States extends readonly AnyStateRef[], ActorContext> = R
|
|
|
242
251
|
type TransitionStepFn<States extends readonly AnyStateRef[], ActorContext> = (event: InternalEvent, options: {
|
|
243
252
|
context: Context<ActorContext>;
|
|
244
253
|
actor: AnyActor<ActorContext>;
|
|
254
|
+
state: {
|
|
255
|
+
name: string;
|
|
256
|
+
payload: unknown;
|
|
257
|
+
};
|
|
245
258
|
}) => TransitionResult<States[number], string>;
|
|
246
259
|
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> {
|
|
247
260
|
state: States[number] | ErrorState;
|
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={};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};
|
|
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 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=/* @__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 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=/* @__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 _(){if(typeof globalThis.AbortController==`function`)return new globalThis.AbortController;let e=[],t={aborted:!1,reason:void 0,onabort:void 0,addEventListener(t,n,r){t===`abort`&&!e.some(e=>e.fn===n)&&e.push({fn:n,once:r?.once===!0,removed:!1})},removeEventListener(t,n){if(t===`abort`){for(let t of e)t.fn===n&&(t.removed=!0);e=e.filter(e=>e.fn!==n)}},throwIfAborted(){if(t.aborted)throw t.reason}};function n(n){if(t.aborted)return;t.aborted=!0,t.reason=n===void 0?/* @__PURE__ */ Error(`This operation was aborted`):n;let r={type:`abort`,target:t},i=e;e=i.filter(e=>!e.once);let a=[];try{t.onabort?.(r)}catch(e){a.push(e)}for(let e of i)if(!e.removed)try{e.fn(r)}catch(e){a.push(e)}if(a.length>0)throw a[0]}return v({signal:t,abort:n})}function v(e){return e}function y(e,t){let n=e?()=>{t.entries.delete(t.timerId)}:void 0;return e&&n&&e.addEventListener(`abort`,n,{once:!0}),n}function b(e){e.signal&&e.onAbort&&e.signal.removeEventListener(`abort`,e.onAbort)}function x(){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&&(b(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=y(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&&(b(n),t.delete(e))},setInterval(t,{signal:i,cb:a}){if(i?.aborted)return-1;let s=r++,c=y(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&&(b(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 te(e){return`state`in e?e.state:e}function ne(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,targets:a.targets,effects:a.effects},u=new Set((t.internal??[]).map(e=>e.type)),v=new Set(t.inputs.map(e=>e.type)),y=t.internalBudget??1e4,b=t.clock??p();b.setDrain?.(Y);let x,S,C=ee(t.context),w,T=!0,E,D={},O=f(),k=g(),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=te(t.initial);ne(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:b,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){oe(e)},dispose(){se()}};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});re(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?ie(e,{transition:t.stateTransition}):{applied:!1,target:void 0,effects:void 0};if(N===void 0){let r=ae(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 re(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 ie(e,t){let n=!1,r,i;return X(`transition`,{event:e,operation:()=>{let a=t.transition(e,{context:R,actor:$(),state:{name:x.name,payload:S}});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 ae(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:$(),state:{name:x.name,payload:S}});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=h(C),T=!1),m({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=_();A=r;let i=P??{state:x,context:C},a=d({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:b,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>=y)return Z(`budget`,{event:t,error:/* @__PURE__ */ Error(`internal event budget exceeded`)}),!1;if(e++,u.has(t.type)||v.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 oe(e){F||(O.push(e),Y())}function se(){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 C(e){return Symbol.for(`mantaq:event:${e}`)}function w(e){return()=>T(e)}function T(e){let t=C(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{S as Actor,i as Context,T as EventRef,p as RealClock,c as StateRef,x as VirtualClock,w 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.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "State machine runtime with actor model, event system, state hierarchy, effects, and virtual clock.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@mantaq/utils": "0.0.
|
|
24
|
+
"@mantaq/utils": "0.0.5"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@stryker-mutator/core": "^10",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
|
|
34
34
|
"vite-plus": "1.4.0",
|
|
35
35
|
"vitest": "5.0.5",
|
|
36
|
-
"@mantaq/pbt": "0.0.
|
|
36
|
+
"@mantaq/pbt": "0.0.4"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "vp pack",
|