@rxova/journey-core 1.0.0 → 1.0.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
@@ -38,17 +38,17 @@ const checkout = createLinearJourney<CheckoutStepId, CheckoutContext, CheckoutTe
38
38
  steps: [
39
39
  { id: "account", metadata: { title: "Account" } },
40
40
  { id: "shipping", metadata: { title: "Shipping" } },
41
- { id: "review", metadata: { title: "Review" } }
41
+ { id: "review", metadata: { title: "Review" } },
42
42
  ],
43
43
  context: {
44
44
  email: "",
45
- shippingId: null
46
- }
45
+ shippingId: null,
46
+ },
47
47
  });
48
48
 
49
49
  checkout.context.update((context) => ({
50
50
  ...context,
51
- email: "ada@example.com"
51
+ email: "ada@example.com",
52
52
  }));
53
53
 
54
54
  await checkout.navigate.goToNextStep();
@@ -60,7 +60,7 @@ needed:
60
60
  ```ts
61
61
  createLinearJourney({
62
62
  steps: ["account", "shipping", "review"],
63
- context: {}
63
+ context: {},
64
64
  });
65
65
  ```
66
66
 
@@ -78,9 +78,9 @@ const result = await checkout.navigate.goToNextStep({
78
78
  commit: ({ result: shipping, updateContext }) => {
79
79
  updateContext((context) => ({
80
80
  ...context,
81
- shippingId: shipping.id
81
+ shippingId: shipping.id,
82
82
  }));
83
- }
83
+ },
84
84
  });
85
85
 
86
86
  if (!result.ok) {
@@ -120,16 +120,16 @@ const machine = createLinearJourney({
120
120
  steps: [
121
121
  {
122
122
  id: "payment",
123
- onLeave: ({ snapshot }) => analytics.track("payment_left", snapshot.context)
123
+ onLeave: ({ snapshot }) => analytics.track("payment_left", snapshot.context),
124
124
  },
125
125
  {
126
126
  id: "receipt",
127
127
  onEnter: async ({ snapshot, updateContext }) => {
128
128
  const receipt = await loadReceipt(snapshot.context);
129
129
  updateContext((context) => ({ ...context, receiptId: receipt.id }));
130
- }
131
- }
132
- ]
130
+ },
131
+ },
132
+ ],
133
133
  });
134
134
  ```
135
135
 
@@ -216,7 +216,7 @@ one edge so a single slow third-party call does not set the budget for the whole
216
216
 
217
217
  For larger graphs, `withGraphTypes<Bag>()` pins the types once and `GraphStep<Bag>` lets each step live in its own file, and
218
218
  `defineWork<Bag, "EVENT">()` reads a work entry's result type off its `run` instead of restating it
219
- in the bag. See the [Graph guide](https://rxova.org/docs/core/usage/graph).
219
+ in the bag. See the [Graph guide](https://rxova.dev/docs/core/usage/graph).
220
220
 
221
221
  ## Connectors
222
222
 
@@ -234,13 +234,13 @@ machine.context.update(
234
234
  immerConnector<CheckoutContext>((draft) => {
235
235
  draft.cart.items.push(item);
236
236
  draft.cart.total += item.price;
237
- })
237
+ }),
238
238
  );
239
239
  ```
240
240
 
241
241
  It also works with the `updateContext` passed to hooks and transactional commits. Immer remains an
242
242
  optional peer, so consumers that do not import this connector do not install or bundle it. See the
243
- [Immer connector guide](https://rxova.org/docs/core/connectors/immer) for replacement recipes,
243
+ [Immer connector guide](https://rxova.dev/docs/core/connectors/immer) for replacement recipes,
244
244
  freezing, draftability, and transactional behavior.
245
245
 
246
246
  ## Plugins
@@ -254,9 +254,9 @@ import { createAnalyticsPlugin } from "@rxova/journey-core/plugins";
254
254
  const machine = createLinearJourney(definition, {
255
255
  plugins: [
256
256
  createAnalyticsPlugin({
257
- track: (event) => analytics.track(event.name, event.payload)
258
- })
259
- ]
257
+ track: (event) => analytics.track(event.name, event.payload),
258
+ }),
259
+ ],
260
260
  });
261
261
  ```
262
262
 
@@ -266,13 +266,13 @@ transitions and cycles without creating a machine.
266
266
 
267
267
  ## Documentation
268
268
 
269
- - [Quickstart](https://rxova.org/docs/core/getting-started)
270
- - [Linear journeys](https://rxova.org/docs/core/usage/linear)
271
- - [Async behavior](https://rxova.org/docs/core/async)
272
- - [Machine API](https://rxova.org/docs/core/api/machine-api)
273
- - [Snapshot](https://rxova.org/docs/core/snapshot)
274
- - [Pre-1.0 migration](https://rxova.org/docs/core/pre-1-0-migration)
275
- - [Stability contract](https://rxova.org/docs/core/stability)
269
+ - [Quickstart](https://rxova.dev/docs/core/getting-started)
270
+ - [Linear journeys](https://rxova.dev/docs/core/usage/linear)
271
+ - [Async behavior](https://rxova.dev/docs/core/async)
272
+ - [Machine API](https://rxova.dev/docs/core/api/machine-api)
273
+ - [Snapshot](https://rxova.dev/docs/core/snapshot)
274
+ - [Pre-1.0 migration](https://rxova.dev/docs/core/pre-1-0-migration)
275
+ - [Stability contract](https://rxova.dev/docs/core/stability)
276
276
 
277
277
  ## License
278
278
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connectors/immer/immer.ts"],
4
- "sourcesContent": ["import { produce } from \"immer\";\nimport type { ContextUpdater } from \"../../core/types\";\nimport type { ImmerContextRecipe } from \"./immer.types\";\n\nexport type { ImmerContextRecipe } from \"./immer.types\";\n\n/**\n * Converts a synchronous Immer recipe into a Journey context updater.\n *\n * Pass the result to `machine.context.update`, a hook's `updateContext`, or a\n * transactional work commit. Immer supplies structural sharing and applies its\n * normal draftability and auto-freezing behavior.\n */\nexport function immerConnector<TContext>(\n recipe: ImmerContextRecipe<TContext>\n): ContextUpdater<TContext> {\n return (previous) => produce(previous, recipe);\n}\n"],
4
+ "sourcesContent": ["import { produce } from \"immer\";\nimport type { ContextUpdater } from \"../../core/types\";\nimport type { ImmerContextRecipe } from \"./immer.types\";\n\nexport type { ImmerContextRecipe } from \"./immer.types\";\n\n/**\n * Converts a synchronous Immer recipe into a Journey context updater.\n *\n * Pass the result to `machine.context.update`, a hook's `updateContext`, or a\n * transactional work commit. Immer supplies structural sharing and applies its\n * normal draftability and auto-freezing behavior.\n */\nexport function immerConnector<TContext>(\n recipe: ImmerContextRecipe<TContext>,\n): ContextUpdater<TContext> {\n return (previous) => produce(previous, recipe);\n}\n"],
5
5
  "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAwB,iBAajB,SAASF,EACdG,EAC0B,CAC1B,OAAQC,MAAa,WAAQA,EAAUD,CAAM,CAC/C",
6
6
  "names": ["immer_exports", "__export", "immerConnector", "__toCommonJS", "import_immer", "recipe", "previous"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connectors/immer/immer.ts"],
4
- "sourcesContent": ["import { produce } from \"immer\";\nimport type { ContextUpdater } from \"../../core/types\";\nimport type { ImmerContextRecipe } from \"./immer.types\";\n\nexport type { ImmerContextRecipe } from \"./immer.types\";\n\n/**\n * Converts a synchronous Immer recipe into a Journey context updater.\n *\n * Pass the result to `machine.context.update`, a hook's `updateContext`, or a\n * transactional work commit. Immer supplies structural sharing and applies its\n * normal draftability and auto-freezing behavior.\n */\nexport function immerConnector<TContext>(\n recipe: ImmerContextRecipe<TContext>\n): ContextUpdater<TContext> {\n return (previous) => produce(previous, recipe);\n}\n"],
4
+ "sourcesContent": ["import { produce } from \"immer\";\nimport type { ContextUpdater } from \"../../core/types\";\nimport type { ImmerContextRecipe } from \"./immer.types\";\n\nexport type { ImmerContextRecipe } from \"./immer.types\";\n\n/**\n * Converts a synchronous Immer recipe into a Journey context updater.\n *\n * Pass the result to `machine.context.update`, a hook's `updateContext`, or a\n * transactional work commit. Immer supplies structural sharing and applies its\n * normal draftability and auto-freezing behavior.\n */\nexport function immerConnector<TContext>(\n recipe: ImmerContextRecipe<TContext>,\n): ContextUpdater<TContext> {\n return (previous) => produce(previous, recipe);\n}\n"],
5
5
  "mappings": "AAAA,OAAS,WAAAA,MAAe,QAajB,SAASC,EACdC,EAC0B,CAC1B,OAAQC,GAAaH,EAAQG,EAAUD,CAAM,CAC/C",
6
6
  "names": ["produce", "immerConnector", "recipe", "previous"]
7
7
  }
@@ -38,9 +38,3 @@ export declare const LOADING_ASYNC: StepAsyncState;
38
38
  export declare const hasOwn: (target: object, key: string) => boolean;
39
39
  /** Subscriber exceptions are isolated so one listener cannot break the pipeline. */
40
40
  export declare function reportListenerError(error: unknown): void;
41
- /**
42
- * Object.is over own enumerable keys — for flat snapshot sub-objects. The
43
- * key check is load-bearing: equal key counts alone would call `{a: undefined}`
44
- * and `{b: undefined}` equal, since both read `undefined` at every compared key.
45
- */
46
- export declare const shallowEqual: (a: Readonly<Record<string, unknown>>, b: Readonly<Record<string, unknown>>) => boolean;
@@ -38,9 +38,3 @@ export declare const LOADING_ASYNC: StepAsyncState;
38
38
  export declare const hasOwn: (target: object, key: string) => boolean;
39
39
  /** Subscriber exceptions are isolated so one listener cannot break the pipeline. */
40
40
  export declare function reportListenerError(error: unknown): void;
41
- /**
42
- * Object.is over own enumerable keys — for flat snapshot sub-objects. The
43
- * key check is load-bearing: equal key counts alone would call `{a: undefined}`
44
- * and `{b: undefined}` equal, since both read `undefined` at every compared key.
45
- */
46
- export declare const shallowEqual: (a: Readonly<Record<string, unknown>>, b: Readonly<Record<string, unknown>>) => boolean;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var j=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var ce=(n,e)=>{for(var t in e)j(n,t,{get:e[t],enumerable:!0})},he=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of pe(e))!de.call(n,s)&&s!==t&&j(n,s,{get:()=>e[s],enumerable:!(r=le(e,s))||r.enumerable});return n};var ge=n=>he(j({},"__esModule",{value:!0}),n);var be={};ce(be,{JourneyError:()=>m,analyzeStructure:()=>ue,createGraphJourney:()=>F,createLinearJourney:()=>U,defineWork:()=>ae,isJourneyError:()=>Q,withGraphTypes:()=>oe,withLinearTypes:()=>re});module.exports=ge(be);var m=class extends Error{constructor(e,t,r={},s){super(`journey: ${t}`,s===void 0?void 0:{cause:s}),this.name="JourneyError",this.code=e,this.stepId=r.stepId,this.event=r.event,this.pluginName=r.pluginName}},Q=n=>n instanceof m;var R=(n,e)=>`${n.length}:${n}${e}`,Y=n=>n.label??`${n.event}[${n.index}] (${n.from} -> ${n.to})`,K=n=>n===null?null:{event:n.event,from:n.from,to:n.to,label:n.label??null,index:n.index},x=Object.freeze({isLoading:!1,isSuccess:!0,isError:!1,error:null}),A=Object.freeze({isLoading:!0,isSuccess:!1,isError:!1,error:null}),S=(n,e)=>Object.hasOwn(n,e);function D(n){console.error("[journey] subscriber threw:",n)}var E=(n,e)=>{let t=Object.keys(n);return t.length!==Object.keys(e).length?!1:t.every(r=>S(e,r)&&Object.is(n[r],e[r]))};function C(n){return{getSnapshot:()=>n.store.getSnapshot(),controls:{start:()=>n.start(),pause:()=>n.pause(),resume:()=>n.resume(),complete:e=>n.complete(e),terminate:e=>n.terminate(e),restart:()=>n.restart()},dispose:()=>n.dispose(),navigate:{goToStepById:e=>n.goToStepById(e),goToPreviousStep:e=>n.goToPreviousStep(e),goToNextStep:e=>n.goToNextStep(e),goToLastVisitedStep:()=>n.goToLastVisitedStep()},subscriptions:{subscribe:e=>n.store.subscribe(e),subscribeEvent:(e,t)=>n.store.subscribeEvent(e,t)},context:{update:e=>n.updateContext(e)},async:{clearError:()=>n.clearAsyncError()},plugins:n.pluginApis}}var G=()=>{let n=globalThis;if(typeof n.__DEV__=="boolean")return n.__DEV__;let e=n.process?.env?.NODE_ENV;return e===void 0||e==="development"},q=(n,e)=>{if(!(!G()||typeof console>"u")){if(e===void 0){console.warn(n);return}console.warn("%s",n,e)}};var N=class{constructor(e,t){this.listeners=new Set;this.eventListeners=new Map;this.disposed=!1;this.snapshot=e,this.onListenerError=t}report(e){if(!this.onListenerError){D(e);return}try{this.onListenerError(e)}catch(t){D(t)}}getSnapshot(){return this.snapshot}publish(e){if(!Object.is(this.snapshot,e)){this.snapshot=e;for(let t of[...this.listeners])try{t()}catch(r){this.report(r)}}}subscribe(e){return this.disposed?()=>{}:(this.listeners.add(e),()=>{this.listeners.delete(e)})}subscribeEvent(e,t){if(this.disposed)return()=>{};let r=this.eventListeners.get(e);return r||(r=new Set,this.eventListeners.set(e,r)),r.add(t),()=>{r.delete(t)}}emit(e,t){let r=this.eventListeners.get(e);if(r)for(let s of[...r])try{s(t)}catch(a){this.report(a)}}dispose(){this.disposed=!0,this.listeners.clear(),this.eventListeners.clear()}};var B=n=>typeof n=="object"&&n!==null&&G()?Object.freeze(n):n,fe=Object.freeze({}),Z=Object.freeze({}),w=(n,e)=>e!=null&&E(n,e)?e:Object.freeze(n),I=(n,e,t=Object.is)=>e!==void 0&&e.length===n.length&&n.every((r,s)=>t(r,e[s]))?e:Object.freeze([...n]),ye=(n,e)=>n===void 0?"none":e?"passed":"failed",P=class{constructor(e){this.pluginApis={};this.status="idle";this.timeline=[];this.currentIndex=-1;this.outcome=null;this.visitCounts=new Map;this.entryAsync=x;this.pending=null;this.disposed=!1;this.restoreSeed=null;this.generation=0;this.raiseQueue=[];this.processingRaised=!1;this.lastPluginExtensions={};this.lastSnapshot=null;this.transitionListeners=new Set;this.disposeCallbacks=[];this.snapshotDerivers=new Map;this.config=e,this.frozenStepOrder=Object.freeze([...e.stepIds]),this.restoreSeed=e.restore??null,this.context=B(e.restore?e.restore.context:e.initialContext),this.store=new N(this.buildSnapshot(),e.onListenerError),this.setupPlugins(),this.store.publish(this.buildSnapshot()),e.autoStart&&this.start()}start(){return this.disposed||this.status!=="idle"?!1:(this.setStatus("running"),this.enterInitialStep(),!0)}pause(){return this.disposed||this.status!=="running"||this.pending?!1:(this.setStatus("paused"),!0)}resume(){return this.disposed||this.status!=="paused"?!1:(this.setStatus("running"),!0)}complete(e){return this.disposed||this.status!=="running"||this.pending?!1:(this.outcome=Object.freeze({type:"completed",payload:e}),this.setStatus("completed"),!0)}terminate(e){return this.disposed||this.status==="terminated"?!1:(this.generation+=1,this.pending=null,this.entryAsync=x,this.raiseQueue=[],this.outcome=Object.freeze({type:"terminated",payload:e}),this.setStatus("terminated"),!0)}restart(){return this.disposed||this.status!=="completed"&&this.status!=="terminated"?!1:(this.generation+=1,this.pending=null,this.raiseQueue=[],this.timeline=[],this.currentIndex=-1,this.context=B(this.config.initialContext),this.outcome=null,this.visitCounts=new Map,this.entryAsync=x,this.setStatus("running"),this.enterInitialStep(),!0)}dispose(){if(!this.disposed){this.disposed=!0,this.generation+=1,this.pending=null,this.raiseQueue=[];for(let e of this.disposeCallbacks.splice(0))try{e()}catch{}this.transitionListeners.clear(),this.store.dispose()}}updateContext(e){if(this.disposed)return;let t=this.context;this.context=B(e(t));let r=this.publish();this.store.emit("contextChange",{snapshot:r,previous:t,current:this.context})}clearAsyncError(){this.disposed||!this.entryAsync.isError||(this.entryAsync=x,this.publish())}goToStepById(e){let t=this.checkNavigable();if(t)return this.blocked(t,e);if(!S(this.config.steps,e))return this.blocked({ok:!1,reason:"invalid-target"},e);if(e===this.currentStepId())return this.blocked({ok:!1,reason:"no-op"},e);if(this.config.kind==="graph"){let r=this.config.transitions.find(s=>s.from===this.currentStepId()&&s.to===e&&this.isEnabled(s));return r?this.runNavigation(e,{kind:"append"},this.eventFor(r),r):this.blocked({ok:!1,reason:"invalid-target"},e)}return this.runNavigation(e,{kind:"append"},null,null)}goToPreviousStep(e=1){let t=this.checkNavigable();if(t)return this.blocked(t,null);if(this.currentIndex<=0)return this.blocked({ok:!1,reason:"out-of-bounds"},null);let r=Math.max(0,this.currentIndex-Math.max(1,Math.floor(e))),s=this.timeline[r];return this.runNavigation(s,{kind:"pointer",index:r},null,null,void 0,"backward")}goToNextStep(e){let t=this.checkNavigable();if(t)return this.blocked(t,null);if(this.currentIndex<this.timeline.length-1){let r=this.currentIndex+1,s=this.timeline[r];return this.runNavigation(s,{kind:"pointer",index:r},null,null,e,"forward")}if(this.config.kind==="linear"){let r=this.config.stepIds.indexOf(this.currentStepId()??""),s=this.config.stepIds[r+1];return s===void 0?this.blocked({ok:!1,reason:"out-of-bounds"},null):this.runNavigation(s,{kind:"append"},null,null,e,"forward")}return this.blocked({ok:!1,reason:"out-of-bounds"},null)}goToLastVisitedStep(){let e=this.checkNavigable();if(e)return this.blocked(e,null);let t=this.timeline.length-1;if(this.currentIndex>=t)return this.blocked({ok:!1,reason:"no-op"},null);let r=this.timeline[t];return this.runNavigation(r,{kind:"pointer",index:t},null,null)}goToStepByIndex(e){let t=Number.isInteger(e)?this.config.stepIds[e]:void 0;return t===void 0?this.blocked({ok:!1,reason:"invalid-target"},null):this.goToStepById(t)}send(e,t,r){let s=this.checkNavigable();if(s)return this.blocked(s,null);let a=t===void 0?{type:e}:{type:e,payload:t},u=this.currentStepId(),o=r??(u===null?void 0:this.config.eventWork?.[R(u,e)]);if(o)return this.sendWithWork(e,a,o);let i=this.resolveTransition(e);return i?this.runNavigation(i.to,{kind:"append"},a,i):this.blocked({ok:!1,reason:"no-enabled-transition"},null)}async sendWithWork(e,t,r){let s=this.generation,a=this.currentStepId();if(a===null)return this.blocked({ok:!1,reason:"not-running"},null);let u=this.context,o=!1,i;this.pending={phase:"working",from:a,to:null},this.entryAsync=A,this.publish();try{let d={snapshot:this.store.getSnapshot(),from:a,event:t,handlers:this.config.handlers};if(i=await this.withTimeout(Promise.resolve(r.run(d)),`send work(${r.label??`${e} from ${a}`})`,r.timeoutMs),!this.isCurrent(s))return this.staleResult();let c=r.commit?.({...d,result:i,updateContext:h=>{u=h(u),o=!0}});if(typeof c=="object"&&c!==null&&"then"in c)throw new m("async-commit","send work commit must be synchronous")}catch(d){if(!this.isCurrent(s))return this.staleResult();this.pending=null,this.entryAsync=Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:d});let c=this.publish();return this.store.emit("error",{snapshot:c,error:d,phase:"work",stepId:a}),this.blocked({ok:!1,reason:"error",error:d},null)}if(!this.isCurrent(s))return this.staleResult();let l=this.resolveTransition(e,u,i);return l?this.commitAndSettle(a,l.to,{kind:"append"},t,l,s,u,o,"jump"):(this.pending=null,this.entryAsync=x,this.publish(),this.blocked({ok:!1,reason:"no-enabled-transition"},null))}setupPlugins(){let e={getSnapshot:()=>this.store.getSnapshot(),structure:Object.freeze({kind:this.config.kind,stepIds:Object.freeze([...this.config.stepIds]),initial:this.config.initial,transitions:Object.freeze(this.config.transitions.map(t=>Object.freeze({event:t.event,from:t.from,to:t.to,guarded:t.when!==void 0,label:t.label??null,index:t.index})))}),onTransition:t=>(this.transitionListeners.add(t),()=>this.transitionListeners.delete(t)),onNavigationBlocked:t=>this.store.subscribeEvent("navigationBlocked",t),onStatusChange:t=>this.store.subscribeEvent("statusChange",t),onContextChange:t=>this.store.subscribeEvent("contextChange",t),onError:t=>this.store.subscribeEvent("error",t),onDispose:t=>{this.disposeCallbacks.push(t)},reportError:t=>this.store.report(t)};try{for(let t of this.config.plugins){if(S(this.pluginApis,t.name))throw new m("duplicate-plugin-name",`duplicate plugin name "${t.name}"`,{pluginName:t.name});let r=t.setup(e);this.pluginApis[t.name]=r.api,r.deriveSnapshot&&this.snapshotDerivers.set(t.name,r.deriveSnapshot)}}catch(t){throw this.dispose(),t}}currentStepId(){return this.currentIndex>=0?this.timeline[this.currentIndex]:null}eventFor(e){return{type:e.event}}isEnabled(e,t=this.context,r){if(!e.when)return!0;try{return e.when({context:t,handlers:this.config.handlers,result:r})}catch{return!1}}resolveTransition(e,t=this.context,r){return this.config.transitions.find(s=>s.event===e&&s.from===this.currentStepId()&&this.isEnabled(s,t,r))}checkNavigable(){return this.disposed?{ok:!1,reason:"disposed"}:this.status!=="running"?{ok:!1,reason:"not-running"}:this.pending?{ok:!1,reason:"transitioning"}:null}setStatus(e){let t=this.status;this.status=e;let r=this.publish();this.store.emit("statusChange",{snapshot:r,previous:t,current:e}),this.refreshPluginSnapshot()}refreshPluginSnapshot(){this.snapshotDerivers.size>0&&this.publish()}blocked(e,t){if(e.reason!=="disposed"){let r={snapshot:this.store.getSnapshot(),reason:e.reason,from:this.currentStepId(),to:t};"error"in e&&(r.error=e.error),this.store.emit("navigationBlocked",r)}return Promise.resolve({...e,from:this.currentStepId(),to:t})}hookArgs(e,t,r,s){return{snapshot:this.store.getSnapshot(),from:e,to:t,event:r,transition:s,updateContext:a=>this.updateContext(a),raise:a=>{this.config.kind!=="graph"||this.disposed||this.raiseQueue.push(a)}}}async invokeEffect(e,t,r,s){if(!e)return null;try{return await this.withTimeout(Promise.resolve(e(t)),r,s),null}catch(a){return{error:a}}}withTimeout(e,t,r){let s=r??this.config.defaultTimeoutMs;return s===void 0?e:new Promise((a,u)=>{let o=setTimeout(()=>u(new Error(`journey: ${t} timed out after ${s}ms`)),s);e.then(i=>{clearTimeout(o),a(i)},i=>{clearTimeout(o),u(i)})})}async enterInitialStep(){let e=this.generation,t=this.restoreSeed;if(this.restoreSeed=null,t){let s=t.timeline[t.currentIndex];this.pending={phase:"entering",from:null,to:s},this.timeline=[...t.timeline],this.currentIndex=t.currentIndex;for(let a of t.timeline)this.visitCounts.set(a,(this.visitCounts.get(a)??0)+1);this.commitEntry(null,s,"jump"),await this.runEntryEffects(null,s,null,null,e);return}let r=this.config.startAt??this.config.initial;this.pending={phase:"entering",from:null,to:r},this.timeline=[r],this.currentIndex=0,this.commitEntry(null,r,"jump"),await this.runEntryEffects(null,r,null,null,e)}async runNavigation(e,t,r,s,a,u){let o=this.generation,i=this.currentStepId(),l=this.context,d=!1;if(a&&i!==null&&u){this.pending={phase:"working",from:i,to:e},this.entryAsync=A,this.publish();try{let c={snapshot:this.store.getSnapshot(),from:i,to:e,direction:u},h=await this.withTimeout(Promise.resolve(a.run(c)),`${u} navigation work(${i} -> ${e})`,a.timeoutMs);if(!this.isCurrent(o))return this.staleResult();let f=a.commit?.({...c,result:h,updateContext:y=>{l=y(l),d=!0}});if(typeof f=="object"&&f!==null&&"then"in f)throw new m("async-commit","navigation work commit must be synchronous")}catch(c){if(!this.isCurrent(o))return this.staleResult();this.pending=null,this.entryAsync=Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:c});let h=this.publish();return this.store.emit("error",{snapshot:h,error:c,phase:"work",stepId:i}),this.blocked({ok:!1,reason:"error",error:c},e)}}return this.isCurrent(o)?this.commitAndSettle(i,e,t,r,s,o,l,d,u??"jump"):this.staleResult()}async commitAndSettle(e,t,r,s,a,u,o,i,l){let d=this.context;r.kind==="pointer"?this.currentIndex=r.index:(this.timeline=[...this.timeline.slice(0,this.currentIndex+1),t],this.currentIndex=this.timeline.length-1),i&&(this.context=B(o));let c=e===null?void 0:this.config.steps[e];return this.pending={phase:c?.onLeave?"leaving":"entering",from:e,to:t},this.commitEntry(e,t,l,i?{previous:d,current:o}:void 0,c?.onLeave!==void 0||a?.onTransition!==void 0),await this.runEntryEffects(e,t,s,a,u),{ok:!0,from:e,to:t}}commitEntry(e,t,r,s,a=!1){this.visitCounts.set(t,(this.visitCounts.get(t)??0)+1);let u=this.config.steps[t];this.entryAsync=a||u?.onEnter?A:x;let o=this.publish();s&&this.store.emit("contextChange",{snapshot:o,...s}),e!==null&&this.store.emit("stepLeave",{snapshot:o,from:e,to:t}),this.store.emit("stepEnter",{snapshot:o,from:e,to:t,direction:r})}async runEntryEffects(e,t,r,s,a){let u=e===null?void 0:this.config.steps[e],o=this.config.steps[t],i=K(s),l=[],d=await this.invokeEffect(u?.onLeave,this.hookArgs(e,t,r,i),`onLeave(${e??""})`);if(!this.isCurrent(a))return;d&&e!==null&&l.push({error:d.error,phase:"leave",stepId:e}),this.pending={phase:"entering",from:e,to:t},this.publish();let c=await this.invokeEffect(s?.onTransition,this.hookArgs(e,t,r,i),`onTransition(${s?Y(s):r?.type??""})`,s?.timeoutMs);if(!this.isCurrent(a))return;c&&l.push({error:c.error,phase:"transition",stepId:t});let h=await this.invokeEffect(o?.onEnter,this.hookArgs(e,t,r,i),`onEnter(${t})`);if(!this.isCurrent(a))return;h&&l.push({error:h.error,phase:"enter",stepId:t}),this.entryAsync=l[0]?Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:l[0].error}):x,this.pending=null;let f=this.publish();for(let y of l)this.store.emit("error",{snapshot:f,error:y.error,phase:y.phase,stepId:y.stepId});for(let y of[...this.transitionListeners])try{y({from:e,to:t,snapshot:f})}catch{}this.refreshPluginSnapshot(),this.processRaisedEvents(a)}async processRaisedEvents(e){if(this.processingRaised||!this.isCurrent(e))return;this.processingRaised=!0;let t=0;try{for(;this.raiseQueue.length>0&&this.isCurrent(e);){if(this.status!=="running"){this.raiseQueue=[];return}if(t+=1,t>25){this.raiseQueue=[],this.store.emit("error",{snapshot:this.store.getSnapshot(),error:new Error(`journey: raised-event cascade exceeded ${25} events; queue dropped`),phase:"raise",stepId:this.currentStepId()});return}let r=this.raiseQueue.shift();await this.send(r.type,r.payload)}}finally{this.processingRaised=!1}}isCurrent(e){return!this.disposed&&e===this.generation}staleResult(){let e=this.currentStepId();return this.disposed?{ok:!1,reason:"disposed",from:e,to:null}:{ok:!1,reason:"not-running",from:e,to:null}}publish(){let e=this.buildSnapshot();return this.store.publish(e),e}buildSnapshot(){let e=this.lastSnapshot,t=this.currentStepId(),r={},s=0;for(let h of this.config.stepIds){let f=(this.visitCounts.get(h)??0)>0;r[h]=f,f&&(s+=1)}let a=e?.history,u=a!=null&&E(a.visited,r)?a.visited:Object.freeze(r),o={status:this.status,context:this.context,transition:w({pending:this.pending!==null,phase:this.pending?.phase??null,from:this.pending?.from??null,to:this.pending?.to??null},e?.transition),history:w({timeline:I(this.timeline,a?.timeline),currentIndex:this.currentIndex,visited:u,canGoBack:this.currentIndex>0,canGoForward:this.currentIndex>=0&&this.currentIndex<this.timeline.length-1},a),machine:w({outcome:this.outcome},e?.machine)},i=t===null?null:{id:t,metadata:this.config.steps[t]?.metadata??fe,isFirstTimeVisit:(this.visitCounts.get(t)??0)===1,async:this.entryAsync},l;if(this.config.kind==="linear"){let h=e?.type==="linear"?e:null,f=t===null?-1:this.config.stepIds.indexOf(t);l={...o,type:"linear",currentStep:i===null?null:w({...i,index:f,isFirstStep:f===0,isLastStep:f===this.config.stepIds.length-1},h?.currentStep),steps:w({totalSteps:this.config.stepIds.length,stepOrder:this.frozenStepOrder,visitedStepCount:s},h?.steps),plugins:Z}}else{let h=[],f=[],y=[],g=[],p=new Map,T=new Set,b=!1;if(t!==null)for(let v of this.config.transitions){if(v.from!==t)continue;b=!0,h.includes(v.event)||h.push(v.event);let J=p.get(v.event)??0;p.set(v.event,J+1);let O=this.isEnabled(v),V=O&&!T.has(v.event);V&&T.add(v.event),g.push(Object.freeze({event:v.event,to:v.to,priority:J,guard:ye(v.when,O),enabled:O,selected:V})),O&&(f.includes(v.event)||f.push(v.event),y.includes(v.to)||y.push(v.to))}let k=e?.type==="graph"?e:null;l={...o,type:"graph",currentStep:i===null?null:w({...i,isTerminal:!b},k?.currentStep),steps:w({totalSteps:this.config.stepIds.length,visitedStepCount:s},k?.steps),declaredEvents:I(h,k?.declaredEvents),availableEvents:I(f,k?.availableEvents),availableSteps:I(y,k?.availableSteps),outgoingTransitions:I(g,k?.outgoingTransitions,(v,J)=>E(v,J)),plugins:Z}}if(this.snapshotDerivers.size>0){let h={};for(let[y,g]of this.snapshotDerivers)try{h[y]=g(l,this.lastPluginExtensions[y])}catch(p){this.store.report(p),S(this.lastPluginExtensions,y)&&(h[y]=this.lastPluginExtensions[y])}this.lastPluginExtensions=h;let f=e?.plugins;l={...l,plugins:f!=null&&E(f,h)?f:Object.freeze(h)}}let d=Object.freeze(l),c=e!==null&&E(d,e)?e:d;return this.lastSnapshot=c,c}};var ee=["context","transition","status"];function te(n){return typeof n!="number"||!Number.isFinite(n)?0:Math.max(0,Math.trunc(n))}function ne(n,e){return{status:n.status,context:n.context,timeline:n.history.timeline,currentIndex:n.history.currentIndex,savedAt:e}}var me=new Set(["idle","running","paused","completed","terminated"]),ve=["__proto__","constructor","prototype"];function W(n,e=0){if(e>50||n===null||typeof n!="object")return n;if(Array.isArray(n))return n.map(r=>W(r,e+1));let t={};for(let[r,s]of Object.entries(n))ve.includes(r)||(t[r]=W(s,e+1));return t}function $(n){if(n===null)return null;let e;try{e=JSON.parse(n)}catch{return null}if(typeof e!="object"||e===null)return null;let t=e;return typeof t.status!="string"||!me.has(t.status)||!Array.isArray(t.timeline)||!t.timeline.every(r=>typeof r=="string")||typeof t.currentIndex!="number"||!Number.isInteger(t.currentIndex)||typeof t.savedAt!="number"||!Number.isFinite(t.savedAt)?null:{status:t.status,context:W(t.context),timeline:t.timeline,currentIndex:t.currentIndex,savedAt:t.savedAt}}function z(n){if(n.storage)return n.storage;let e;try{e=globalThis.localStorage}catch(t){throw new m("storage-unavailable","localStorage access was blocked by the environment; pass persist.storage explicitly",{},t)}if(!e)throw new m("storage-unavailable","persist.storage is required when localStorage is unavailable");return e}function L(n,e){let t;try{t=z(n).getItem(n.key)}catch{return null}let r=$(t);if(!r||r.status!=="running"&&r.status!=="paused"||!Number.isInteger(r.currentIndex)||r.currentIndex<0||r.currentIndex>=r.timeline.length)return null;for(let s of r.timeline)if(typeof s!="string"||!e(s))return null;return r}var _={status:"idle",lastSavedAt:null,error:null};function Te(n){let e=n.now??Date.now,t=te(n.debounceMs),r=new Set(n.saveOn??ee),s=0;return{name:"persistence",setup(a){s+=1,s>1&&q(`journey: persistence plugin instance shared by ${s} machines; they overwrite key "${n.key}". Create one per machine.`);let u=null,o=_,i=null,l=!1,d=p=>{u=p,o={status:"saved",lastSavedAt:p.savedAt,error:null}},c=p=>{o={...o,status:"error",error:p},a.reportError(p)},h=()=>{let p=ne(a.getSnapshot(),e());o={...o,status:"saving"};let T;try{T=n.storage.setItem(n.key,JSON.stringify(p))}catch(b){throw o={...o,status:"error",error:b},b}if(T!==void 0)return T.then(()=>d(p),c);d(p)},f=()=>{i!==null&&(clearTimeout(i),i=null)},y=()=>{i=null;try{let p=h()}catch(p){c(p)}},g=p=>{if(!(l||!r.has(p))){if(t===0){h();return}f(),o={...o,status:"pending"},i=setTimeout(y,t)}};return a.onContextChange(()=>g("context")),a.onTransition(()=>g("transition")),a.onStatusChange(({current:p})=>{if(p==="terminated"&&n.clearOnTerminate){f(),u=null,o=_,n.storage.removeItem(n.key);return}g("status")}),a.onDispose(()=>{l=!0,f()}),{api:{inspectPersistedState:()=>u,getPersistenceState:()=>o,readPersisted:()=>$(n.storage.getItem(n.key)),clearPersisted:()=>{f(),u=null,o=_;try{n.storage.removeItem(n.key)}catch(p){c(p)}},flushPersisted:async()=>{f();try{await h()}catch(p){c(p)}}},deriveSnapshot:(p,T)=>T===o?T:o}}}}function M(n){return Te({key:n.key,storage:z(n)})}function U(n,e={}){if(n.steps.length===0)throw new m("empty-definition","a linear journey needs at least one step");let t=[],r={};for(let o of n.steps){let i=typeof o=="string"?{id:o}:o;if(S(r,i.id))throw new m("duplicate-step-id",`duplicate step id "${i.id}"`,{stepId:i.id});t.push(i.id);let l={metadata:i.metadata??{}};i.onEnter&&(l.onEnter=i.onEnter),i.onLeave&&(l.onLeave=i.onLeave),r[i.id]=l}if(e.startAt!==void 0&&!S(r,e.startAt))throw new m("unknown-step",`startAt references unknown step "${e.startAt}"`,{stepId:e.startAt});let s=e.persist&&e.startAt===void 0?L(e.persist,o=>S(r,o)):null,a=new P({kind:"linear",stepIds:t,steps:r,initial:t[0],...e.startAt!==void 0?{startAt:e.startAt}:{},initialContext:n.context,...s?{restore:{context:s.context,timeline:s.timeline,currentIndex:s.currentIndex}}:{},transitions:[],handlers:void 0,autoStart:e.autoStart??!0,defaultTimeoutMs:e.defaultTimeoutMs,...e.onListenerError!==void 0?{onListenerError:e.onListenerError}:{},plugins:[...e.persist?[M(e.persist)]:[],...e.plugins??[]]}),u=C(a);return{...u,navigate:{...u.navigate,goToStepByIndex:o=>a.goToStepByIndex(o)}}}var re=()=>(n,e={})=>U(n,e);var se=(n,e,t)=>{if(typeof n!="string"||n.length===0)throw new m("invalid-label",`${e} must declare "label" as a non-empty string`,t);return n},ie=(n,e,t)=>{if(typeof n!="number"||!Number.isFinite(n)||n<=0)throw new m("invalid-timeout",`${e} must declare "timeoutMs" as a finite number greater than 0`,t);return n};function H(n){let e=Object.keys(n.steps);if(e.length===0)throw new m("empty-definition","a graph journey needs at least one step");if(!e.includes(n.initial))throw new m("unknown-initial-step",`initial step "${n.initial}" is not a declared step`,{stepId:n.initial});let t={};for(let u of e){let o=n.steps[u],i={metadata:o.metadata??{}};o.onEnter&&(i.onEnter=o.onEnter),o.onLeave&&(i.onLeave=o.onLeave),t[u]=i}let r=[],s={},a=(u,o,i,l)=>{if(!e.includes(i.to))throw new m("dangling-transition",`transition "${u}" references unknown step "${i.to}"`,{event:u,stepId:i.to});let d=`transition "${u}"[${l}] on step "${o}"`,c={event:u,from:o,to:i.to,index:l};i.when&&(c.when=i.when),i.onTransition&&(c.onTransition=i.onTransition),i.label!==void 0&&(c.label=se(i.label,d,{event:u,stepId:o})),i.timeoutMs!==void 0&&(c.timeoutMs=ie(i.timeoutMs,d,{event:u,stepId:o})),r.push(c)};for(let u of e){let o=n.steps[u]?.on;if(o)for(let[i,l]of Object.entries(o)){if(l===void 0)continue;if(typeof l=="string"){a(i,u,{to:l},0);continue}if(Array.isArray(l)){l.forEach((f,y)=>a(i,u,f,y));continue}let d=l,c=`work on "${i}" on step "${u}"`,h={run:d.run};d.commit&&(h.commit=d.commit),d.label!==void 0&&(h.label=se(d.label,c,{event:i,stepId:u})),d.timeoutMs!==void 0&&(h.timeoutMs=ie(d.timeoutMs,c,{event:i,stepId:u})),s[R(u,i)]=h,d.candidates.forEach((f,y)=>a(i,u,f,y))}}return{stepIds:e,steps:t,transitions:r,eventWork:s}}function F(n,e={}){let{stepIds:t,steps:r,transitions:s,eventWork:a}=H(n);if(e.startAt!==void 0&&!S(r,e.startAt))throw new m("unknown-step",`startAt references unknown step "${e.startAt}"`,{stepId:e.startAt});let u=e.persist&&e.startAt===void 0?L(e.persist,l=>S(r,l)):null,o=new P({kind:"graph",stepIds:t,steps:r,initial:n.initial,...e.startAt!==void 0?{startAt:e.startAt}:{},initialContext:n.context,...u?{restore:{context:u.context,timeline:u.timeline,currentIndex:u.currentIndex}}:{},transitions:s,...Object.keys(a).length>0?{eventWork:a}:{},handlers:e.handlers??n.handlers,autoStart:e.autoStart??!0,defaultTimeoutMs:e.defaultTimeoutMs,...e.onListenerError!==void 0?{onListenerError:e.onListenerError}:{},plugins:[...e.persist?[M(e.persist)]:[],...e.plugins??[]]});return{...C(o),send:(l,d)=>o.send(l,d)}}var oe=()=>(n,e={})=>F(n,e);var ae=()=>n=>n;function Se(n){let e=[],t=[...n.stepIds],r=new Set,s=new Set;n.transitions.forEach((g,p)=>{let T=`${g.from} ${g.event}`;if(s.has(T)){r.add(p),e.push({code:"shadowed-transition",severity:"warning",from:g.from,event:g.event,message:`Transition "${g.from}.${g.event}" is shadowed by an earlier unconditional candidate.`});return}g.guarded||s.add(T)});let a=n.transitions.filter((g,p)=>!r.has(p)),u=g=>a.filter(p=>p.from===g),o=new Set,i=[n.initial];for(;i.length>0;){let g=i.pop();if(!o.has(g)){o.add(g);for(let p of u(g))i.push(p.to)}}for(let g of t)o.has(g)||e.push({code:"unreachable-step",severity:"warning",stepId:g,message:`Step "${g}" is unreachable from the initial step "${n.initial}".`});let l=t.filter(g=>u(g).length===0),d=new Set,c=new Set,h=[],f=g=>{c.add(g),h.push(g);for(let p of u(g)){let T=h.indexOf(p.to);if(T>=0){let b=[...h.slice(T),p.to],k=b.join(" ");d.has(k)||(d.add(k),e.push({code:"cycle-detected",severity:"warning",from:p.from,event:p.event,steps:b,message:`Cycle detected: ${b.join(" -> ")}.`}));continue}c.has(p.to)||f(p.to)}h.pop()};f(n.initial);let y=l.some(g=>o.has(g));return y||e.push({code:"no-terminal-path",severity:"warning",stepId:n.initial,message:`No terminal step is reachable from the initial step "${n.initial}".`}),{issues:e,summary:{stepCount:t.length,reachableStepCount:o.size,unreachableStepCount:t.length-o.size,terminalStepIds:l,cycleCount:d.size,shadowedTransitionCount:r.size,terminalPathExists:y}}}function ue(n){let{stepIds:e,transitions:t}=H(n),r={kind:"graph",stepIds:e,initial:n.initial,transitions:t.map(s=>({event:s.event,from:s.from,to:s.to,guarded:s.when!==void 0,label:s.label??null,index:s.index}))};return Se(r)}0&&(module.exports={JourneyError,analyzeStructure,createGraphJourney,createLinearJourney,defineWork,isJourneyError,withGraphTypes,withLinearTypes});
1
+ "use strict";var j=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var de=(n,e)=>{for(var t in e)j(n,t,{get:e[t],enumerable:!0})},he=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of pe(e))!ce.call(n,s)&&s!==t&&j(n,s,{get:()=>e[s],enumerable:!(r=le(e,s))||r.enumerable});return n};var fe=n=>he(j({},"__esModule",{value:!0}),n);var be={};de(be,{JourneyError:()=>m,analyzeStructure:()=>ue,createGraphJourney:()=>F,createLinearJourney:()=>H,defineWork:()=>ae,isJourneyError:()=>Q,withGraphTypes:()=>oe,withLinearTypes:()=>re});module.exports=fe(be);var m=class extends Error{constructor(e,t,r={},s){super(`journey: ${t}`,s===void 0?void 0:{cause:s}),this.name="JourneyError",this.code=e,this.stepId=r.stepId,this.event=r.event,this.pluginName=r.pluginName}},Q=n=>n instanceof m;var A=(n,e)=>`${n.length}:${n}${e}`,Y=n=>n.label??`${n.event}[${n.index}] (${n.from} -> ${n.to})`,K=n=>n===null?null:{event:n.event,from:n.from,to:n.to,label:n.label??null,index:n.index},x=Object.freeze({isLoading:!1,isSuccess:!0,isError:!1,error:null}),R=Object.freeze({isLoading:!0,isSuccess:!1,isError:!1,error:null}),S=(n,e)=>Object.hasOwn(n,e);function D(n){console.error("[journey] subscriber threw:",n)}function C(n){return{getSnapshot:()=>n.store.getSnapshot(),controls:{start:()=>n.start(),pause:()=>n.pause(),resume:()=>n.resume(),complete:e=>n.complete(e),terminate:e=>n.terminate(e),restart:()=>n.restart()},dispose:()=>n.dispose(),navigate:{goToStepById:e=>n.goToStepById(e),goToPreviousStep:e=>n.goToPreviousStep(e),goToNextStep:e=>n.goToNextStep(e),goToLastVisitedStep:()=>n.goToLastVisitedStep()},subscriptions:{subscribe:e=>n.store.subscribe(e),subscribeEvent:(e,t)=>n.store.subscribeEvent(e,t)},context:{update:e=>n.updateContext(e)},async:{clearError:()=>n.clearAsyncError()},plugins:n.pluginApis}}var G=()=>{let n=globalThis;if(typeof n.__DEV__=="boolean")return n.__DEV__;let e=n.process?.env?.NODE_ENV;return e===void 0||e==="development"},q=(n,e)=>{if(!(!G()||typeof console>"u")){if(e===void 0){console.warn(n);return}console.warn("%s",n,e)}};var w=(n,e)=>{if(Object.is(n,e))return!0;if(typeof n!="object"||n===null||typeof e!="object"||e===null||Array.isArray(n)!==Array.isArray(e))return!1;let t=n,r=e,s=Object.keys(t);return s.length!==Object.keys(r).length?!1:s.every(a=>Object.hasOwn(r,a)&&Object.is(t[a],r[a]))};var N=class{constructor(e,t){this.listeners=new Set;this.eventListeners=new Map;this.disposed=!1;this.snapshot=e,this.onListenerError=t}report(e){if(!this.onListenerError){D(e);return}try{this.onListenerError(e)}catch(t){D(t)}}getSnapshot(){return this.snapshot}publish(e){if(!Object.is(this.snapshot,e)){this.snapshot=e;for(let t of[...this.listeners])try{t()}catch(r){this.report(r)}}}subscribe(e){return this.disposed?()=>{}:(this.listeners.add(e),()=>{this.listeners.delete(e)})}subscribeEvent(e,t){if(this.disposed)return()=>{};let r=this.eventListeners.get(e);return r||(r=new Set,this.eventListeners.set(e,r)),r.add(t),()=>{r.delete(t)}}emit(e,t){let r=this.eventListeners.get(e);if(r)for(let s of[...r])try{s(t)}catch(a){this.report(a)}}dispose(){this.disposed=!0,this.listeners.clear(),this.eventListeners.clear()}};var B=n=>typeof n=="object"&&n!==null&&G()?Object.freeze(n):n,ge=Object.freeze({}),Z=Object.freeze({}),E=(n,e)=>e!=null&&w(n,e)?e:Object.freeze(n),P=(n,e,t=Object.is)=>e!==void 0&&e.length===n.length&&n.every((r,s)=>t(r,e[s]))?e:Object.freeze([...n]),ye=(n,e)=>n===void 0?"none":e?"passed":"failed",I=class{constructor(e){this.pluginApis={};this.status="idle";this.timeline=[];this.currentIndex=-1;this.outcome=null;this.visitCounts=new Map;this.entryAsync=x;this.pending=null;this.disposed=!1;this.restoreSeed=null;this.generation=0;this.raiseQueue=[];this.processingRaised=!1;this.lastPluginExtensions={};this.lastSnapshot=null;this.transitionListeners=new Set;this.disposeCallbacks=[];this.snapshotDerivers=new Map;this.config=e,this.frozenStepOrder=Object.freeze([...e.stepIds]),this.restoreSeed=e.restore??null,this.context=B(e.restore?e.restore.context:e.initialContext),this.store=new N(this.buildSnapshot(),e.onListenerError),this.setupPlugins(),this.store.publish(this.buildSnapshot()),e.autoStart&&this.start()}start(){return this.disposed||this.status!=="idle"?!1:(this.setStatus("running"),this.enterInitialStep(),!0)}pause(){return this.disposed||this.status!=="running"||this.pending?!1:(this.setStatus("paused"),!0)}resume(){return this.disposed||this.status!=="paused"?!1:(this.setStatus("running"),!0)}complete(e){return this.disposed||this.status!=="running"||this.pending?!1:(this.outcome=Object.freeze({type:"completed",payload:e}),this.setStatus("completed"),!0)}terminate(e){return this.disposed||this.status==="terminated"?!1:(this.generation+=1,this.pending=null,this.entryAsync=x,this.raiseQueue=[],this.outcome=Object.freeze({type:"terminated",payload:e}),this.setStatus("terminated"),!0)}restart(){return this.disposed||this.status!=="completed"&&this.status!=="terminated"?!1:(this.generation+=1,this.pending=null,this.raiseQueue=[],this.timeline=[],this.currentIndex=-1,this.context=B(this.config.initialContext),this.outcome=null,this.visitCounts=new Map,this.entryAsync=x,this.setStatus("running"),this.enterInitialStep(),!0)}dispose(){if(!this.disposed){this.disposed=!0,this.generation+=1,this.pending=null,this.raiseQueue=[];for(let e of this.disposeCallbacks.splice(0))try{e()}catch{}this.transitionListeners.clear(),this.store.dispose()}}updateContext(e){if(this.disposed)return;let t=this.context;this.context=B(e(t));let r=this.publish();this.store.emit("contextChange",{snapshot:r,previous:t,current:this.context})}clearAsyncError(){this.disposed||!this.entryAsync.isError||(this.entryAsync=x,this.publish())}goToStepById(e){let t=this.checkNavigable();if(t)return this.blocked(t,e);if(!S(this.config.steps,e))return this.blocked({ok:!1,reason:"invalid-target"},e);if(e===this.currentStepId())return this.blocked({ok:!1,reason:"no-op"},e);if(this.config.kind==="graph"){let r=this.config.transitions.find(s=>s.from===this.currentStepId()&&s.to===e&&this.isEnabled(s));return r?this.runNavigation(e,{kind:"append"},this.eventFor(r),r):this.blocked({ok:!1,reason:"invalid-target"},e)}return this.runNavigation(e,{kind:"append"},null,null)}goToPreviousStep(e=1){let t=this.checkNavigable();if(t)return this.blocked(t,null);if(this.currentIndex<=0)return this.blocked({ok:!1,reason:"out-of-bounds"},null);let r=Math.max(0,this.currentIndex-Math.max(1,Math.floor(e))),s=this.timeline[r];return this.runNavigation(s,{kind:"pointer",index:r},null,null,void 0,"backward")}goToNextStep(e){let t=this.checkNavigable();if(t)return this.blocked(t,null);if(this.currentIndex<this.timeline.length-1){let r=this.currentIndex+1,s=this.timeline[r];return this.runNavigation(s,{kind:"pointer",index:r},null,null,e,"forward")}if(this.config.kind==="linear"){let r=this.config.stepIds.indexOf(this.currentStepId()??""),s=this.config.stepIds[r+1];return s===void 0?this.blocked({ok:!1,reason:"out-of-bounds"},null):this.runNavigation(s,{kind:"append"},null,null,e,"forward")}return this.blocked({ok:!1,reason:"out-of-bounds"},null)}goToLastVisitedStep(){let e=this.checkNavigable();if(e)return this.blocked(e,null);let t=this.timeline.length-1;if(this.currentIndex>=t)return this.blocked({ok:!1,reason:"no-op"},null);let r=this.timeline[t];return this.runNavigation(r,{kind:"pointer",index:t},null,null)}goToStepByIndex(e){let t=Number.isInteger(e)?this.config.stepIds[e]:void 0;return t===void 0?this.blocked({ok:!1,reason:"invalid-target"},null):this.goToStepById(t)}send(e,t,r){let s=this.checkNavigable();if(s)return this.blocked(s,null);let a=t===void 0?{type:e}:{type:e,payload:t},u=this.currentStepId(),o=r??(u===null?void 0:this.config.eventWork?.[A(u,e)]);if(o)return this.sendWithWork(e,a,o);let i=this.resolveTransition(e);return i?this.runNavigation(i.to,{kind:"append"},a,i):this.blocked({ok:!1,reason:"no-enabled-transition"},null)}async sendWithWork(e,t,r){let s=this.generation,a=this.currentStepId();if(a===null)return this.blocked({ok:!1,reason:"not-running"},null);let u=this.context,o=!1,i;this.pending={phase:"working",from:a,to:null},this.entryAsync=R,this.publish();try{let c={snapshot:this.store.getSnapshot(),from:a,event:t,handlers:this.config.handlers};if(i=await this.withTimeout(Promise.resolve(r.run(c)),`send work(${r.label??`${e} from ${a}`})`,r.timeoutMs),!this.isCurrent(s))return this.staleResult();let d=r.commit?.({...c,result:i,updateContext:h=>{u=h(u),o=!0}});if(typeof d=="object"&&d!==null&&"then"in d)throw new m("async-commit","send work commit must be synchronous")}catch(c){if(!this.isCurrent(s))return this.staleResult();this.pending=null,this.entryAsync=Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:c});let d=this.publish();return this.store.emit("error",{snapshot:d,error:c,phase:"work",stepId:a}),this.blocked({ok:!1,reason:"error",error:c},null)}if(!this.isCurrent(s))return this.staleResult();let l=this.resolveTransition(e,u,i);return l?this.commitAndSettle(a,l.to,{kind:"append"},t,l,s,u,o,"jump"):(this.pending=null,this.entryAsync=x,this.publish(),this.blocked({ok:!1,reason:"no-enabled-transition"},null))}setupPlugins(){let e={getSnapshot:()=>this.store.getSnapshot(),structure:Object.freeze({kind:this.config.kind,stepIds:Object.freeze([...this.config.stepIds]),initial:this.config.initial,transitions:Object.freeze(this.config.transitions.map(t=>Object.freeze({event:t.event,from:t.from,to:t.to,guarded:t.when!==void 0,label:t.label??null,index:t.index})))}),onTransition:t=>(this.transitionListeners.add(t),()=>this.transitionListeners.delete(t)),onNavigationBlocked:t=>this.store.subscribeEvent("navigationBlocked",t),onStatusChange:t=>this.store.subscribeEvent("statusChange",t),onContextChange:t=>this.store.subscribeEvent("contextChange",t),onError:t=>this.store.subscribeEvent("error",t),onDispose:t=>{this.disposeCallbacks.push(t)},reportError:t=>this.store.report(t)};try{for(let t of this.config.plugins){if(S(this.pluginApis,t.name))throw new m("duplicate-plugin-name",`duplicate plugin name "${t.name}"`,{pluginName:t.name});let r=t.setup(e);this.pluginApis[t.name]=r.api,r.deriveSnapshot&&this.snapshotDerivers.set(t.name,r.deriveSnapshot)}}catch(t){throw this.dispose(),t}}currentStepId(){return this.currentIndex>=0?this.timeline[this.currentIndex]:null}eventFor(e){return{type:e.event}}isEnabled(e,t=this.context,r){if(!e.when)return!0;try{return e.when({context:t,handlers:this.config.handlers,result:r})}catch{return!1}}resolveTransition(e,t=this.context,r){return this.config.transitions.find(s=>s.event===e&&s.from===this.currentStepId()&&this.isEnabled(s,t,r))}checkNavigable(){return this.disposed?{ok:!1,reason:"disposed"}:this.status!=="running"?{ok:!1,reason:"not-running"}:this.pending?{ok:!1,reason:"transitioning"}:null}setStatus(e){let t=this.status;this.status=e;let r=this.publish();this.store.emit("statusChange",{snapshot:r,previous:t,current:e}),this.refreshPluginSnapshot()}refreshPluginSnapshot(){this.snapshotDerivers.size>0&&this.publish()}blocked(e,t){if(e.reason!=="disposed"){let r={snapshot:this.store.getSnapshot(),reason:e.reason,from:this.currentStepId(),to:t};"error"in e&&(r.error=e.error),this.store.emit("navigationBlocked",r)}return Promise.resolve({...e,from:this.currentStepId(),to:t})}hookArgs(e,t,r,s){return{snapshot:this.store.getSnapshot(),from:e,to:t,event:r,transition:s,updateContext:a=>this.updateContext(a),raise:a=>{this.config.kind!=="graph"||this.disposed||this.raiseQueue.push(a)}}}async invokeEffect(e,t,r,s){if(!e)return null;try{return await this.withTimeout(Promise.resolve(e(t)),r,s),null}catch(a){return{error:a}}}withTimeout(e,t,r){let s=r??this.config.defaultTimeoutMs;return s===void 0?e:new Promise((a,u)=>{let o=setTimeout(()=>u(new Error(`journey: ${t} timed out after ${s}ms`)),s);e.then(i=>{clearTimeout(o),a(i)},i=>{clearTimeout(o),u(i)})})}async enterInitialStep(){let e=this.generation,t=this.restoreSeed;if(this.restoreSeed=null,t){let s=t.timeline[t.currentIndex];this.pending={phase:"entering",from:null,to:s},this.timeline=[...t.timeline],this.currentIndex=t.currentIndex;for(let a of t.timeline)this.visitCounts.set(a,(this.visitCounts.get(a)??0)+1);this.commitEntry(null,s,"jump"),await this.runEntryEffects(null,s,null,null,e);return}let r=this.config.startAt??this.config.initial;this.pending={phase:"entering",from:null,to:r},this.timeline=[r],this.currentIndex=0,this.commitEntry(null,r,"jump"),await this.runEntryEffects(null,r,null,null,e)}async runNavigation(e,t,r,s,a,u){let o=this.generation,i=this.currentStepId(),l=this.context,c=!1;if(a&&i!==null&&u){this.pending={phase:"working",from:i,to:e},this.entryAsync=R,this.publish();try{let d={snapshot:this.store.getSnapshot(),from:i,to:e,direction:u},h=await this.withTimeout(Promise.resolve(a.run(d)),`${u} navigation work(${i} -> ${e})`,a.timeoutMs);if(!this.isCurrent(o))return this.staleResult();let g=a.commit?.({...d,result:h,updateContext:y=>{l=y(l),c=!0}});if(typeof g=="object"&&g!==null&&"then"in g)throw new m("async-commit","navigation work commit must be synchronous")}catch(d){if(!this.isCurrent(o))return this.staleResult();this.pending=null,this.entryAsync=Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:d});let h=this.publish();return this.store.emit("error",{snapshot:h,error:d,phase:"work",stepId:i}),this.blocked({ok:!1,reason:"error",error:d},e)}}return this.isCurrent(o)?this.commitAndSettle(i,e,t,r,s,o,l,c,u??"jump"):this.staleResult()}async commitAndSettle(e,t,r,s,a,u,o,i,l){let c=this.context;r.kind==="pointer"?this.currentIndex=r.index:(this.timeline=[...this.timeline.slice(0,this.currentIndex+1),t],this.currentIndex=this.timeline.length-1),i&&(this.context=B(o));let d=e===null?void 0:this.config.steps[e];return this.pending={phase:d?.onLeave?"leaving":"entering",from:e,to:t},this.commitEntry(e,t,l,i?{previous:c,current:o}:void 0,d?.onLeave!==void 0||a?.onTransition!==void 0),await this.runEntryEffects(e,t,s,a,u),{ok:!0,from:e,to:t}}commitEntry(e,t,r,s,a=!1){this.visitCounts.set(t,(this.visitCounts.get(t)??0)+1);let u=this.config.steps[t];this.entryAsync=a||u?.onEnter?R:x;let o=this.publish();s&&this.store.emit("contextChange",{snapshot:o,...s}),e!==null&&this.store.emit("stepLeave",{snapshot:o,from:e,to:t}),this.store.emit("stepEnter",{snapshot:o,from:e,to:t,direction:r})}async runEntryEffects(e,t,r,s,a){let u=e===null?void 0:this.config.steps[e],o=this.config.steps[t],i=K(s),l=[],c=await this.invokeEffect(u?.onLeave,this.hookArgs(e,t,r,i),`onLeave(${e??""})`);if(!this.isCurrent(a))return;c&&e!==null&&l.push({error:c.error,phase:"leave",stepId:e}),this.pending={phase:"entering",from:e,to:t},this.publish();let d=await this.invokeEffect(s?.onTransition,this.hookArgs(e,t,r,i),`onTransition(${s?Y(s):r?.type??""})`,s?.timeoutMs);if(!this.isCurrent(a))return;d&&l.push({error:d.error,phase:"transition",stepId:t});let h=await this.invokeEffect(o?.onEnter,this.hookArgs(e,t,r,i),`onEnter(${t})`);if(!this.isCurrent(a))return;h&&l.push({error:h.error,phase:"enter",stepId:t}),this.entryAsync=l[0]?Object.freeze({isLoading:!1,isSuccess:!1,isError:!0,error:l[0].error}):x,this.pending=null;let g=this.publish();for(let y of l)this.store.emit("error",{snapshot:g,error:y.error,phase:y.phase,stepId:y.stepId});for(let y of[...this.transitionListeners])try{y({from:e,to:t,snapshot:g})}catch{}this.refreshPluginSnapshot(),this.processRaisedEvents(a)}async processRaisedEvents(e){if(this.processingRaised||!this.isCurrent(e))return;this.processingRaised=!0;let t=0;try{for(;this.raiseQueue.length>0&&this.isCurrent(e);){if(this.status!=="running"){this.raiseQueue=[];return}if(t+=1,t>25){this.raiseQueue=[],this.store.emit("error",{snapshot:this.store.getSnapshot(),error:new Error(`journey: raised-event cascade exceeded ${25} events; queue dropped`),phase:"raise",stepId:this.currentStepId()});return}let r=this.raiseQueue.shift();await this.send(r.type,r.payload)}}finally{this.processingRaised=!1}}isCurrent(e){return!this.disposed&&e===this.generation}staleResult(){let e=this.currentStepId();return this.disposed?{ok:!1,reason:"disposed",from:e,to:null}:{ok:!1,reason:"not-running",from:e,to:null}}publish(){let e=this.buildSnapshot();return this.store.publish(e),e}buildSnapshot(){let e=this.lastSnapshot,t=this.currentStepId(),r={},s=0;for(let h of this.config.stepIds){let g=(this.visitCounts.get(h)??0)>0;r[h]=g,g&&(s+=1)}let a=e?.history,u=a!=null&&w(a.visited,r)?a.visited:Object.freeze(r),o={status:this.status,context:this.context,transition:E({pending:this.pending!==null,phase:this.pending?.phase??null,from:this.pending?.from??null,to:this.pending?.to??null},e?.transition),history:E({timeline:P(this.timeline,a?.timeline),currentIndex:this.currentIndex,visited:u,canGoBack:this.currentIndex>0,canGoForward:this.currentIndex>=0&&this.currentIndex<this.timeline.length-1},a),machine:E({outcome:this.outcome},e?.machine)},i=t===null?null:{id:t,metadata:this.config.steps[t]?.metadata??ge,isFirstTimeVisit:(this.visitCounts.get(t)??0)===1,async:this.entryAsync},l;if(this.config.kind==="linear"){let h=e?.type==="linear"?e:null,g=t===null?-1:this.config.stepIds.indexOf(t);l={...o,type:"linear",currentStep:i===null?null:E({...i,index:g,isFirstStep:g===0,isLastStep:g===this.config.stepIds.length-1},h?.currentStep),steps:E({totalSteps:this.config.stepIds.length,stepOrder:this.frozenStepOrder,visitedStepCount:s},h?.steps),plugins:Z}}else{let h=[],g=[],y=[],f=[],p=new Map,v=new Set,b=!1;if(t!==null)for(let T of this.config.transitions){if(T.from!==t)continue;b=!0,h.includes(T.event)||h.push(T.event);let O=p.get(T.event)??0;p.set(T.event,O+1);let J=this.isEnabled(T),V=J&&!v.has(T.event);V&&v.add(T.event),f.push(Object.freeze({event:T.event,to:T.to,priority:O,guard:ye(T.when,J),enabled:J,selected:V})),J&&(g.includes(T.event)||g.push(T.event),y.includes(T.to)||y.push(T.to))}let k=e?.type==="graph"?e:null;l={...o,type:"graph",currentStep:i===null?null:E({...i,isTerminal:!b},k?.currentStep),steps:E({totalSteps:this.config.stepIds.length,visitedStepCount:s},k?.steps),declaredEvents:P(h,k?.declaredEvents),availableEvents:P(g,k?.availableEvents),availableSteps:P(y,k?.availableSteps),outgoingTransitions:P(f,k?.outgoingTransitions,(T,O)=>w(T,O)),plugins:Z}}if(this.snapshotDerivers.size>0){let h={};for(let[y,f]of this.snapshotDerivers)try{h[y]=f(l,this.lastPluginExtensions[y])}catch(p){this.store.report(p),S(this.lastPluginExtensions,y)&&(h[y]=this.lastPluginExtensions[y])}this.lastPluginExtensions=h;let g=e?.plugins;l={...l,plugins:g!=null&&w(g,h)?g:Object.freeze(h)}}let c=Object.freeze(l),d=e!==null&&w(c,e)?e:c;return this.lastSnapshot=d,d}};var ee=["context","transition","status"];function te(n){return typeof n!="number"||!Number.isFinite(n)?0:Math.max(0,Math.trunc(n))}function ne(n,e){return{status:n.status,context:n.context,timeline:n.history.timeline,currentIndex:n.history.currentIndex,savedAt:e}}var me=new Set(["idle","running","paused","completed","terminated"]),Te=["__proto__","constructor","prototype"];function $(n,e=0){if(e>50||n===null||typeof n!="object")return n;if(Array.isArray(n))return n.map(r=>$(r,e+1));let t={};for(let[r,s]of Object.entries(n))Te.includes(r)||(t[r]=$(s,e+1));return t}function W(n){if(n===null)return null;let e;try{e=JSON.parse(n)}catch{return null}if(typeof e!="object"||e===null)return null;let t=e;return typeof t.status!="string"||!me.has(t.status)||!Array.isArray(t.timeline)||!t.timeline.every(r=>typeof r=="string")||typeof t.currentIndex!="number"||!Number.isInteger(t.currentIndex)||typeof t.savedAt!="number"||!Number.isFinite(t.savedAt)?null:{status:t.status,context:$(t.context),timeline:t.timeline,currentIndex:t.currentIndex,savedAt:t.savedAt}}function z(n){if(n.storage)return n.storage;let e;try{e=globalThis.localStorage}catch(t){throw new m("storage-unavailable","localStorage access was blocked by the environment; pass persist.storage explicitly",{},t)}if(!e)throw new m("storage-unavailable","persist.storage is required when localStorage is unavailable");return e}function L(n,e){let t;try{t=z(n).getItem(n.key)}catch{return null}let r=W(t);if(!r||r.status!=="running"&&r.status!=="paused"||!Number.isInteger(r.currentIndex)||r.currentIndex<0||r.currentIndex>=r.timeline.length)return null;for(let s of r.timeline)if(typeof s!="string"||!e(s))return null;return r}var _={status:"idle",lastSavedAt:null,error:null};function ve(n){let e=n.now??Date.now,t=te(n.debounceMs),r=new Set(n.saveOn??ee),s=0;return{name:"persistence",setup(a){s+=1,s>1&&q(`journey: persistence plugin instance shared by ${s} machines; they overwrite key "${n.key}". Create one per machine.`);let u=null,o=_,i=null,l=!1,c=p=>{u=p,o={status:"saved",lastSavedAt:p.savedAt,error:null}},d=p=>{o={...o,status:"error",error:p},a.reportError(p)},h=()=>{let p=ne(a.getSnapshot(),e());o={...o,status:"saving"};let v;try{v=n.storage.setItem(n.key,JSON.stringify(p))}catch(b){throw o={...o,status:"error",error:b},b}if(v!==void 0)return v.then(()=>c(p),d);c(p)},g=()=>{i!==null&&(clearTimeout(i),i=null)},y=()=>{i=null;try{let p=h()}catch(p){d(p)}},f=p=>{if(!(l||!r.has(p))){if(t===0){h();return}g(),o={...o,status:"pending"},i=setTimeout(y,t)}};return a.onContextChange(()=>f("context")),a.onTransition(()=>f("transition")),a.onStatusChange(({current:p})=>{if(p==="terminated"&&n.clearOnTerminate){g(),u=null,o=_,n.storage.removeItem(n.key);return}f("status")}),a.onDispose(()=>{l=!0,g()}),{api:{inspectPersistedState:()=>u,getPersistenceState:()=>o,readPersisted:()=>W(n.storage.getItem(n.key)),clearPersisted:()=>{g(),u=null,o=_;try{n.storage.removeItem(n.key)}catch(p){d(p)}},flushPersisted:async()=>{g();try{await h()}catch(p){d(p)}}},deriveSnapshot:(p,v)=>v===o?v:o}}}}function M(n){return ve({key:n.key,storage:z(n)})}function H(n,e={}){if(n.steps.length===0)throw new m("empty-definition","a linear journey needs at least one step");let t=[],r={};for(let o of n.steps){let i=typeof o=="string"?{id:o}:o;if(S(r,i.id))throw new m("duplicate-step-id",`duplicate step id "${i.id}"`,{stepId:i.id});t.push(i.id);let l={metadata:i.metadata??{}};i.onEnter&&(l.onEnter=i.onEnter),i.onLeave&&(l.onLeave=i.onLeave),r[i.id]=l}if(e.startAt!==void 0&&!S(r,e.startAt))throw new m("unknown-step",`startAt references unknown step "${e.startAt}"`,{stepId:e.startAt});let s=e.persist&&e.startAt===void 0?L(e.persist,o=>S(r,o)):null,a=new I({kind:"linear",stepIds:t,steps:r,initial:t[0],...e.startAt!==void 0?{startAt:e.startAt}:{},initialContext:n.context,...s?{restore:{context:s.context,timeline:s.timeline,currentIndex:s.currentIndex}}:{},transitions:[],handlers:void 0,autoStart:e.autoStart??!0,defaultTimeoutMs:e.defaultTimeoutMs,...e.onListenerError!==void 0?{onListenerError:e.onListenerError}:{},plugins:[...e.persist?[M(e.persist)]:[],...e.plugins??[]]}),u=C(a);return{...u,navigate:{...u.navigate,goToStepByIndex:o=>a.goToStepByIndex(o)}}}var re=()=>(n,e={})=>H(n,e);var se=(n,e,t)=>{if(typeof n!="string"||n.length===0)throw new m("invalid-label",`${e} must declare "label" as a non-empty string`,t);return n},ie=(n,e,t)=>{if(typeof n!="number"||!Number.isFinite(n)||n<=0)throw new m("invalid-timeout",`${e} must declare "timeoutMs" as a finite number greater than 0`,t);return n};function U(n){let e=Object.keys(n.steps);if(e.length===0)throw new m("empty-definition","a graph journey needs at least one step");if(!e.includes(n.initial))throw new m("unknown-initial-step",`initial step "${n.initial}" is not a declared step`,{stepId:n.initial});let t={};for(let u of e){let o=n.steps[u],i={metadata:o.metadata??{}};o.onEnter&&(i.onEnter=o.onEnter),o.onLeave&&(i.onLeave=o.onLeave),t[u]=i}let r=[],s={},a=(u,o,i,l)=>{if(!e.includes(i.to))throw new m("dangling-transition",`transition "${u}" references unknown step "${i.to}"`,{event:u,stepId:i.to});let c=`transition "${u}"[${l}] on step "${o}"`,d={event:u,from:o,to:i.to,index:l};i.when&&(d.when=i.when),i.onTransition&&(d.onTransition=i.onTransition),i.label!==void 0&&(d.label=se(i.label,c,{event:u,stepId:o})),i.timeoutMs!==void 0&&(d.timeoutMs=ie(i.timeoutMs,c,{event:u,stepId:o})),r.push(d)};for(let u of e){let o=n.steps[u]?.on;if(o)for(let[i,l]of Object.entries(o)){if(l===void 0)continue;if(typeof l=="string"){a(i,u,{to:l},0);continue}if(Array.isArray(l)){l.forEach((g,y)=>a(i,u,g,y));continue}let c=l,d=`work on "${i}" on step "${u}"`,h={run:c.run};c.commit&&(h.commit=c.commit),c.label!==void 0&&(h.label=se(c.label,d,{event:i,stepId:u})),c.timeoutMs!==void 0&&(h.timeoutMs=ie(c.timeoutMs,d,{event:i,stepId:u})),s[A(u,i)]=h,c.candidates.forEach((g,y)=>a(i,u,g,y))}}return{stepIds:e,steps:t,transitions:r,eventWork:s}}function F(n,e={}){let{stepIds:t,steps:r,transitions:s,eventWork:a}=U(n);if(e.startAt!==void 0&&!S(r,e.startAt))throw new m("unknown-step",`startAt references unknown step "${e.startAt}"`,{stepId:e.startAt});let u=e.persist&&e.startAt===void 0?L(e.persist,l=>S(r,l)):null,o=new I({kind:"graph",stepIds:t,steps:r,initial:n.initial,...e.startAt!==void 0?{startAt:e.startAt}:{},initialContext:n.context,...u?{restore:{context:u.context,timeline:u.timeline,currentIndex:u.currentIndex}}:{},transitions:s,...Object.keys(a).length>0?{eventWork:a}:{},handlers:e.handlers??n.handlers,autoStart:e.autoStart??!0,defaultTimeoutMs:e.defaultTimeoutMs,...e.onListenerError!==void 0?{onListenerError:e.onListenerError}:{},plugins:[...e.persist?[M(e.persist)]:[],...e.plugins??[]]});return{...C(o),send:(l,c)=>o.send(l,c)}}var oe=()=>(n,e={})=>F(n,e);var ae=()=>n=>n;function Se(n){let e=[],t=[...n.stepIds],r=new Set,s=new Set;n.transitions.forEach((f,p)=>{let v=`${f.from} ${f.event}`;if(s.has(v)){r.add(p),e.push({code:"shadowed-transition",severity:"warning",from:f.from,event:f.event,message:`Transition "${f.from}.${f.event}" is shadowed by an earlier unconditional candidate.`});return}f.guarded||s.add(v)});let a=n.transitions.filter((f,p)=>!r.has(p)),u=f=>a.filter(p=>p.from===f),o=new Set,i=[n.initial];for(;i.length>0;){let f=i.pop();if(!o.has(f)){o.add(f);for(let p of u(f))i.push(p.to)}}for(let f of t)o.has(f)||e.push({code:"unreachable-step",severity:"warning",stepId:f,message:`Step "${f}" is unreachable from the initial step "${n.initial}".`});let l=t.filter(f=>u(f).length===0),c=new Set,d=new Set,h=[],g=f=>{d.add(f),h.push(f);for(let p of u(f)){let v=h.indexOf(p.to);if(v>=0){let b=[...h.slice(v),p.to],k=b.join(" ");c.has(k)||(c.add(k),e.push({code:"cycle-detected",severity:"warning",from:p.from,event:p.event,steps:b,message:`Cycle detected: ${b.join(" -> ")}.`}));continue}d.has(p.to)||g(p.to)}h.pop()};g(n.initial);let y=l.some(f=>o.has(f));return y||e.push({code:"no-terminal-path",severity:"warning",stepId:n.initial,message:`No terminal step is reachable from the initial step "${n.initial}".`}),{issues:e,summary:{stepCount:t.length,reachableStepCount:o.size,unreachableStepCount:t.length-o.size,terminalStepIds:l,cycleCount:c.size,shadowedTransitionCount:r.size,terminalPathExists:y}}}function ue(n){let{stepIds:e,transitions:t}=U(n),r={kind:"graph",stepIds:e,initial:n.initial,transitions:t.map(s=>({event:s.event,from:s.from,to:s.to,guarded:s.when!==void 0,label:s.label??null,index:s.index}))};return Se(r)}0&&(module.exports={JourneyError,analyzeStructure,createGraphJourney,createLinearJourney,defineWork,isJourneyError,withGraphTypes,withLinearTypes});
2
2
  //# sourceMappingURL=index.cjs.map