@rxova/journey-core 0.6.2 → 0.6.3

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/types/journey.types.ts", "../src/machine-helpers.ts", "../src/persistence.ts", "../src/machine.ts", "../src/transitions.ts"],
4
- "sourcesContent": ["export { createJourneyMachine } from \"./machine\";\nexport { createPersistenceController } from \"./persistence\";\nexport { createTransitions, tx } from \"./transitions\";\nexport {\n JOURNEY_EVENT,\n JOURNEY_ASYNC_PHASE,\n JOURNEY_STATUS,\n JOURNEY_WILDCARD,\n type JourneyBuiltInEvent,\n type JourneyBuiltInFrom,\n type JourneyDefaultEventType,\n type JourneyAsyncPhase,\n type JourneyStatus,\n type JourneyAsyncState,\n type JourneyStepAsyncState,\n type JourneyEvent,\n type JourneyEventPayloadMap,\n type JourneyMachineEventType,\n type JourneyMachinePayloadMap,\n type JourneyDefinition,\n type JourneyMachineOptions,\n type JourneyGoToEvent,\n type JourneyGoToStepByIdEventType,\n type JourneyMachine,\n type JourneyObservationEvent,\n type JourneyPayloadFor,\n type JourneySendEvent,\n type JourneyPersistedSnapshot,\n type JourneyPersistedState,\n type JourneyPersistenceOptions,\n type JourneyStepDefinition,\n type JourneyStorage,\n type JourneySendResult,\n type JourneySnapshot,\n type JourneyTerminal,\n type JourneyTransition,\n type JourneyTransitionArgs,\n type JourneyTransitionTarget\n} from \"./types\";\n", "import type { JourneyPersistenceOptions } from \"./persistence.types\";\nimport type { JourneyTransition } from \"./transitions.types\";\n\n/** Terminal outcomes reached when a journey completes or is explicitly terminated. */\nexport type JourneyTerminal = \"COMPLETE\" | \"TERMINATED\";\n\n/** Runtime machine status constants. */\nexport const JOURNEY_STATUS = {\n RUNNING: \"running\",\n COMPLETE: \"complete\",\n TERMINATED: \"terminated\"\n} as const;\n\n/** Union of possible runtime machine statuses. */\nexport type JourneyStatus = (typeof JOURNEY_STATUS)[keyof typeof JOURNEY_STATUS];\n\n/** Wildcard step identifier used by transitions that match from any step. */\nexport const JOURNEY_WILDCARD = \"*\" as const;\n\n/** Built-in event constants that are part of core machine behavior. */\nexport const JOURNEY_EVENT = {\n GO_TO_STEP_BY_ID: \"goToStepById\"\n} as const;\n\n/** Machine event types that are always recognized by core. */\nexport type JourneyBuiltInEvent = (typeof JOURNEY_EVENT)[keyof typeof JOURNEY_EVENT];\n/** Event literal type for the built-in go-to-step command. */\nexport type JourneyGoToStepByIdEventType = typeof JOURNEY_EVENT.GO_TO_STEP_BY_ID;\n/** Wildcard origin marker for transitions. */\nexport type JourneyBuiltInFrom = typeof JOURNEY_WILDCARD;\n/** Default transition event names supported by machine convenience APIs. */\nexport type JourneyDefaultEventType =\n | \"goToNextStep\"\n | \"goToPreviousStep\"\n | \"terminateJourney\"\n | \"completeJourney\";\n\n/** Async lifecycle phases tracked per step while guards/effects run. */\nexport const JOURNEY_ASYNC_PHASE = {\n IDLE: \"idle\",\n EVALUATING_WHEN: \"evaluating-when\",\n RUNNING_EFFECT: \"running-effect\",\n ERROR: \"error\"\n} as const;\n\n/** Union of supported async lifecycle phases. */\nexport type JourneyAsyncPhase = (typeof JOURNEY_ASYNC_PHASE)[keyof typeof JOURNEY_ASYNC_PHASE];\n\n/** Async execution state for a single step. */\nexport type JourneyStepAsyncState = {\n phase: JourneyAsyncPhase;\n eventType: string | null;\n transitionId: string | null;\n error: unknown | null;\n};\n\n/** Aggregated async state for the machine, keyed by step id. */\nexport type JourneyAsyncState<TStepId extends string> = {\n isLoading: boolean;\n byStep: Record<TStepId, JourneyStepAsyncState>;\n};\n\n/** Minimal event shape used across runtime boundaries. */\nexport type JourneyBaseEvent = {\n type: string;\n payload?: unknown;\n};\n\n/** Optional event payload map by event type. */\nexport type JourneyEventPayloadMap<TEventType extends string> = Partial<\n Record<TEventType | JourneyBuiltInEvent, unknown>\n>;\n\n/** Resolves payload type for a specific event type from the provided payload map. */\nexport type JourneyPayloadFor<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TEvent extends TEventType | JourneyBuiltInEvent\n> = TEvent extends keyof TPayloadMap ? TPayloadMap[TEvent] : unknown;\n\n/** Event-type union accepted by machine `.send()`, including built-in convenience events. */\nexport type JourneyMachineEventType<TEventType extends string> =\n | TEventType\n | JourneyDefaultEventType;\n\n/** Payload map available to machine `.send()`, including built-in convenience events. */\nexport type JourneyMachinePayloadMap<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = TPayloadMap & JourneyEventPayloadMap<JourneyDefaultEventType>;\n\ntype JourneyPayloadForDefaultEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TDefaultEvent extends JourneyDefaultEventType\n> = JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TDefaultEvent\n>;\n\n/** Built-in direct-navigation event that targets a specific step id. */\nexport type JourneyGoToEvent<TStepId extends string, TPayload = unknown> = {\n type: JourneyGoToStepByIdEventType;\n stepId: TStepId;\n payload?: TPayload;\n};\n\n/** Event union available to transitions and guards for the declared event type set. */\nexport type JourneyEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<TEventType, TPayloadMap, JourneyGoToStepByIdEventType>\n >\n | {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n }[TEventType];\n\ntype JourneyDefaultMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in JourneyDefaultEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TType\n >;\n };\n}[JourneyDefaultEventType];\n\ntype JourneyCustomMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n}[TEventType];\n\n/** Event union accepted by `JourneyMachine.send`. */\nexport type JourneySendEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n >\n | JourneyDefaultMachineEvent<TEventType, TPayloadMap>\n | JourneyCustomMachineEvent<TEventType, TPayloadMap>;\n\n/**\n * Step definition with optional metadata and optional typed extension fields.\n * Use `TStepExtra` to explicitly model additional per-step properties.\n */\nexport type JourneyStepDefinition<\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n meta?: TStepMeta;\n} & TStepExtra;\n\n/** Serializable runtime snapshot of the journey state. */\nexport type JourneySnapshot<TContext, TStepId extends string, TStepMeta = unknown> = {\n currentStepId: TStepId;\n history: {\n timeline: readonly TStepId[];\n index: number;\n };\n context: TContext;\n visited: Record<TStepId, boolean>;\n stepMeta: Record<TStepId, TStepMeta>;\n status: JourneyStatus;\n async: JourneyAsyncState<TStepId>;\n};\n\n/** Full machine definition used to create a journey machine instance. */\nexport type JourneyDefinition<\n TContext,\n TStepId extends string = string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n initial: TStepId;\n context: TContext;\n steps: Record<TStepId, JourneyStepDefinition<TStepMeta, TStepExtra>>;\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[];\n};\n\n/** Optional machine features (for example, persistence configuration). */\nexport type JourneyMachineOptions<TContext, TStepId extends string, TStepMeta = unknown> = {\n persistence?: JourneyPersistenceOptions<TContext, TStepId, TStepMeta>;\n};\n\n/** Result returned from send/navigation APIs. */\nexport type JourneySendResult<TContext, TStepId extends string, TStepMeta = unknown> = {\n transitioned: boolean;\n transitionId?: string;\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>;\n};\n\n/** Observation events emitted by the machine lifecycle/event stream. */\nexport type JourneyObservationEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> =\n | {\n type: \"transition.start\";\n from: TStepId;\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>;\n timestamp: number;\n }\n | {\n type: \"transition.success\";\n from: TStepId;\n to: TStepId | JourneyTerminal;\n eventType: string;\n transitionId: string | null;\n timestamp: number;\n }\n | {\n type: \"transition.error\";\n from: TStepId;\n eventType: string;\n transitionId: string | null;\n error: unknown;\n timestamp: number;\n }\n | {\n type: \"step.exit\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"step.enter\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.complete\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.close\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"navigation.previous\";\n from: TStepId;\n to: TStepId;\n requestedSteps: number;\n appliedSteps: number;\n timestamp: number;\n }\n | {\n type: \"navigation.lastVisited\";\n from: TStepId;\n to: TStepId;\n timestamp: number;\n }\n | {\n type: \"metadata.updated\";\n stepId: TStepId;\n previous: TStepMeta;\n next: TStepMeta;\n timestamp: number;\n };\n\n/** Runtime machine API for reading snapshots, sending events, and controlling flow. */\nexport type JourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> = {\n getSnapshot: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n send: (\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToNextStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n terminateJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"terminateJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n completeJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"completeJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToPreviousStep: (steps?: number) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToLastVisitedStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n updateContext: (\n updater: (context: TContext) => TContext\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n updateStepMetadata: (\n stepId: TStepId,\n updater: (metadata: TStepMeta) => TStepMeta\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n clearStepError: (stepId?: TStepId) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n resetMachine: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n subscribe: (listener: () => void) => () => void;\n subscribeEvent: (\n listener: (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n ) => () => void;\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_WILDCARD } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyGoToEvent,\n JourneyGoToStepByIdEventType,\n JourneyMachineEventType,\n JourneyMachinePayloadMap,\n JourneyPayloadFor,\n JourneySendEvent,\n JourneySendResult,\n JourneySnapshot,\n JourneyStatus,\n JourneyStepAsyncState,\n JourneyTerminal,\n JourneyTransition\n} from \"./types\";\n\nexport const assertStepExists = <TStepId extends string>(\n steps: Record<TStepId, unknown>,\n stepId: TStepId,\n message: string\n) => {\n if (!(stepId in steps)) {\n throw new Error(message);\n }\n};\n\nexport const normalizeStepCount = (steps?: number): number => {\n if (typeof steps !== \"number\" || !Number.isFinite(steps)) {\n return 1;\n }\n return Math.max(1, Math.trunc(steps));\n};\n\nexport const now = (): number => Date.now();\n\nconst unique = <T>(items: readonly T[]): T[] => [...new Set(items)];\n\nconst normalizeVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n stepIds: readonly TStepId[]\n): Record<TStepId, boolean> =>\n Object.fromEntries(stepIds.map((stepId) => [stepId, visited[stepId] === true])) as Record<\n TStepId,\n boolean\n >;\n\nexport const buildVisitedFromTimeline = <TStepId extends string>(\n timeline: readonly TStepId[],\n stepIds?: readonly TStepId[]\n): Record<TStepId, boolean> => {\n const resolvedStepIds = stepIds ?? unique(timeline);\n const visited = Object.fromEntries(resolvedStepIds.map((stepId) => [stepId, false])) as Record<\n TStepId,\n boolean\n >;\n\n for (const stepId of timeline) {\n visited[stepId] = true;\n }\n\n return visited;\n};\n\nexport const appendVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n current: TStepId\n): Record<TStepId, boolean> => ({\n ...visited,\n [current]: true\n});\n\nexport const isPromiseLike = <T>(value: T | PromiseLike<T>): value is PromiseLike<T> =>\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof (value as { then: unknown }).then === \"function\";\n\nexport const buildIdleStepAsyncState = (): JourneyStepAsyncState => ({\n phase: JOURNEY_ASYNC_PHASE.IDLE,\n eventType: null,\n transitionId: null,\n error: null\n});\n\nexport const buildInitialAsyncState = <TStepId extends string>(\n steps: Record<TStepId, unknown>\n): JourneyAsyncState<TStepId> => {\n const byStep = Object.fromEntries(\n Object.keys(steps).map((stepId) => [stepId, buildIdleStepAsyncState()])\n ) as Record<TStepId, JourneyStepAsyncState>;\n\n return {\n isLoading: false,\n byStep\n };\n};\n\nexport const isGoToStepByIdEvent = <\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n): event is JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n> => event.type === JOURNEY_EVENT.GO_TO_STEP_BY_ID && \"stepId\" in event;\n\nexport const isTerminalTarget = <TStepId extends string>(\n target: TStepId | JourneyTerminal\n): target is JourneyTerminal => target === \"COMPLETE\" || target === \"TERMINATED\";\n\nexport const validateJourneyTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n steps: Record<TStepId, unknown>\n) => {\n const stepRegistry = steps as Record<string, unknown>;\n\n for (const [index, transition] of transitions.entries()) {\n if (!transition || typeof transition !== \"object\") {\n throw new Error(`Journey transition at index ${index} must be an object.`);\n }\n\n if (typeof transition.from !== \"string\" || typeof transition.event !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define string \"from\" and \"event\".`\n );\n }\n\n if (transition.from !== JOURNEY_WILDCARD && !(transition.from in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} references unknown from step \"${transition.from}\".`\n );\n }\n\n if (transition.event === \"completeJourney\" || transition.event === \"terminateJourney\") {\n if (\"to\" in transition && transition.to !== undefined) {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" cannot define \"to\".`\n );\n }\n continue;\n }\n\n if (typeof transition.to !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" must define string \"to\".`\n );\n }\n\n if (!isTerminalTarget(transition.to) && !(transition.to in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} points to unknown step \"${transition.to}\".`\n );\n }\n }\n};\n\nexport const buildSendResult = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n transitioned: boolean,\n transitionId?: string\n): JourneySendResult<TContext, TStepId, TStepMeta> =>\n transitionId ? { transitioned, transitionId, snapshot } : { transitioned, snapshot };\n\nexport const buildSnapshot = <TContext, TStepId extends string, TStepMeta>(\n timeline: readonly TStepId[],\n index: number,\n context: TContext,\n status: JourneyStatus,\n asyncState: JourneyAsyncState<TStepId>,\n stepMeta: Record<TStepId, TStepMeta>,\n visited?: Record<TStepId, boolean>\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n if (timeline.length === 0) {\n throw new Error(\"Journey timeline cannot be empty.\");\n }\n const safeIndex = Math.max(0, Math.min(Math.trunc(index), timeline.length - 1));\n const currentStepId = timeline[safeIndex] as TStepId;\n const stepIds = Object.keys(stepMeta) as TStepId[];\n return {\n status,\n currentStepId,\n history: {\n timeline: [...timeline],\n index: safeIndex\n },\n context,\n visited: visited\n ? normalizeVisited(visited, stepIds)\n : buildVisitedFromTimeline(timeline, stepIds),\n stepMeta: { ...stepMeta },\n async: asyncState\n };\n};\n\nexport const selectTransition = async <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TStepMeta\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n event: JourneyEvent<TStepId, TEventType, TPayloadMap>,\n hooks?: {\n onAsyncGuardStart?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardSuccess?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardError?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n error: unknown\n ) => void;\n }\n): Promise<JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> | null> => {\n for (const transition of transitions) {\n const fromMatches =\n transition.from === JOURNEY_WILDCARD || transition.from === snapshot.currentStepId;\n const eventMatches = transition.event === event.type;\n\n if (!fromMatches || !eventMatches) {\n continue;\n }\n\n if (!transition.when) {\n return transition;\n }\n\n const guardResult = transition.when({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event\n });\n const asyncGuard = isPromiseLike(guardResult);\n if (asyncGuard) {\n hooks?.onAsyncGuardStart?.(transition);\n }\n\n let allowed: boolean;\n try {\n allowed = await guardResult;\n } catch (error) {\n if (asyncGuard) {\n hooks?.onAsyncGuardError?.(transition, error);\n }\n throw error;\n }\n\n if (asyncGuard) {\n hooks?.onAsyncGuardSuccess?.(transition);\n }\n\n if (allowed) {\n return transition;\n }\n }\n\n return null;\n};\n\nexport const transitionSnapshot = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n nextCurrent: TStepId,\n nextContext: TContext\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const baseTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n let nextTimeline = baseTimeline;\n if (nextCurrent !== snapshot.currentStepId) {\n nextTimeline = [...baseTimeline, nextCurrent];\n }\n\n const nextIndex = nextTimeline.length - 1;\n const visited = appendVisited(snapshot.visited, nextCurrent);\n\n return buildSnapshot(\n nextTimeline,\n nextIndex,\n nextContext,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n visited\n );\n};\n", "import { JOURNEY_STATUS } from \"./types/journey.types\";\nimport type {\n JourneyPersistedSnapshot,\n JourneyPersistedState,\n JourneyStorage,\n ResolvedPersistence\n} from \"./types/persistence.types\";\nimport type { JourneyMachineOptions, JourneySnapshot, JourneyStatus } from \"./types/journey.types\";\nimport { buildInitialAsyncState, buildSnapshot, buildVisitedFromTimeline } from \"./machine-helpers\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst isStatusValue = (value: unknown): value is JourneyStatus =>\n value === JOURNEY_STATUS.RUNNING ||\n value === JOURNEY_STATUS.COMPLETE ||\n value === JOURNEY_STATUS.TERMINATED;\n\nconst resolveDefaultStorage = (): JourneyStorage | null => {\n const localStorageCandidate = (globalThis as { localStorage?: Partial<JourneyStorage> })\n .localStorage;\n\n if (\n !localStorageCandidate ||\n typeof localStorageCandidate.getItem !== \"function\" ||\n typeof localStorageCandidate.setItem !== \"function\" ||\n typeof localStorageCandidate.removeItem !== \"function\"\n ) {\n return null;\n }\n\n return localStorageCandidate as JourneyStorage;\n};\n\nconst resolvePersistence = <TContext, TStepId extends string, TStepMeta>(\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>[\"persistence\"]\n): ResolvedPersistence<TContext, TStepId, TStepMeta> | null => {\n if (!options) {\n return null;\n }\n\n const storage = options.storage ?? resolveDefaultStorage();\n if (!storage) {\n return null;\n }\n\n return {\n key: options.key,\n storage,\n version: options.version ?? 1,\n clearOnReset: options.clearOnReset ?? true,\n serialize: options.serialize ?? JSON.stringify,\n deserialize: options.deserialize ?? JSON.parse,\n ...(options.migrate ? { migrate: options.migrate } : {}),\n ...(options.onError ? { onError: options.onError } : {})\n };\n};\n\nconst coercePersistedSnapshot = <TContext, TStepId extends string, TStepMeta>(\n value: unknown,\n steps: Record<TStepId, unknown>,\n fallbackContext: TContext,\n fallbackStepMeta: Record<TStepId, TStepMeta>\n): {\n snapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta>;\n needsRewrite: boolean;\n} | null => {\n if (!isRecord(value)) {\n return null;\n }\n\n let needsRewrite = false;\n\n const rawHistory = isRecord(value.history) ? value.history : null;\n if (!rawHistory) {\n needsRewrite = true;\n }\n\n const rawTimeline = rawHistory?.timeline ?? value.timeline;\n const timeline = Array.isArray(rawTimeline)\n ? (rawTimeline.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[])\n : [];\n\n const currentStepIdValue =\n typeof value.currentStepId === \"string\" && value.currentStepId in steps\n ? (value.currentStepId as TStepId)\n : typeof value.current === \"string\" && value.current in steps\n ? (value.current as TStepId)\n : null;\n\n if (timeline.length === 0) {\n if (!currentStepIdValue) {\n return null;\n }\n timeline.push(currentStepIdValue);\n needsRewrite = true;\n }\n\n let index = timeline.length - 1;\n const rawIndex = rawHistory?.index ?? value.index;\n if (typeof rawIndex === \"number\" && Number.isFinite(rawIndex)) {\n index = Math.max(0, Math.min(Math.trunc(rawIndex), timeline.length - 1));\n if (index !== rawIndex) {\n needsRewrite = true;\n }\n } else if (currentStepIdValue) {\n const inferredIndex = timeline.lastIndexOf(currentStepIdValue);\n if (inferredIndex >= 0) {\n index = inferredIndex;\n needsRewrite = true;\n }\n }\n\n const status = isStatusValue(value.status) ? value.status : JOURNEY_STATUS.RUNNING;\n if (!isStatusValue(value.status)) {\n needsRewrite = true;\n }\n\n const stepIds = Object.keys(steps) as TStepId[];\n const visitedSource = value.visited;\n const visitedFromRecord = isRecord(visitedSource)\n ? (Object.fromEntries(\n stepIds.map((stepId) => [stepId, visitedSource[stepId] === true])\n ) as Record<TStepId, boolean>)\n : null;\n const visitedFromArray = Array.isArray(visitedSource)\n ? buildVisitedFromTimeline(\n visitedSource.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[],\n stepIds\n )\n : null;\n\n let visited = buildVisitedFromTimeline(timeline, stepIds);\n if (visitedFromRecord) {\n const visitedRecord = visitedSource as Record<string, unknown>;\n visited = visitedFromRecord;\n const hasMissingOrInvalidStep = stepIds.some(\n (stepId) => typeof visitedRecord[stepId] !== \"boolean\"\n );\n if (hasMissingOrInvalidStep) {\n needsRewrite = true;\n }\n } else if (visitedFromArray) {\n visited = visitedFromArray;\n needsRewrite = true;\n } else {\n needsRewrite = true;\n }\n\n const rawStepMeta = isRecord(value.stepMeta) ? value.stepMeta : null;\n if (!rawStepMeta) {\n needsRewrite = true;\n }\n\n const stepMeta = Object.fromEntries(\n Object.keys(steps).map((stepId) => {\n const typedStepId = stepId as TStepId;\n const rawValue = rawStepMeta ? rawStepMeta[stepId] : undefined;\n if (rawValue === undefined) {\n return [typedStepId, fallbackStepMeta[typedStepId]];\n }\n return [typedStepId, rawValue as TStepMeta];\n })\n ) as Record<TStepId, TStepMeta>;\n\n return {\n snapshot: {\n currentStepId: timeline[index] as TStepId,\n history: {\n timeline,\n index\n },\n context: (\"context\" in value ? value.context : fallbackContext) as TContext,\n status,\n visited,\n stepMeta\n },\n needsRewrite\n };\n};\n\n/**\n * Creates a persistence controller for snapshots, including hydration,\n * serialization, and storage error handling.\n */\nexport const createPersistenceController = <TContext, TStepId extends string, TStepMeta>(args: {\n initial: TStepId;\n context: TContext;\n stepMeta: Record<TStepId, TStepMeta>;\n steps: Record<TStepId, unknown>;\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>;\n}) => {\n const { initial, context, stepMeta, steps, options } = args;\n const persistence = resolvePersistence(options?.persistence);\n\n const reportPersistenceError = (error: unknown) => {\n persistence?.onError?.(error);\n };\n\n const persistSnapshot = (snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>) => {\n if (!persistence) {\n return;\n }\n\n try {\n const persistedState: JourneyPersistedState<TContext, TStepId, TStepMeta> = {\n version: persistence.version,\n snapshot: {\n currentStepId: snapshot.currentStepId,\n history: {\n timeline: [...snapshot.history.timeline],\n index: snapshot.history.index\n },\n context: snapshot.context,\n status: snapshot.status,\n visited: { ...snapshot.visited },\n stepMeta: { ...snapshot.stepMeta }\n }\n };\n persistence.storage.setItem(persistence.key, persistence.serialize(persistedState));\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const removePersistedSnapshot = () => {\n if (!persistence) {\n return;\n }\n\n try {\n persistence.storage.removeItem(persistence.key);\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const hydrateSnapshot = (): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const initialSnapshot = buildSnapshot(\n [initial],\n 0,\n context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(steps),\n stepMeta\n );\n if (!persistence) {\n return initialSnapshot;\n }\n\n try {\n const rawPersisted = persistence.storage.getItem(persistence.key);\n if (!rawPersisted) {\n return initialSnapshot;\n }\n\n const parsed = persistence.deserialize(rawPersisted);\n if (!isRecord(parsed)) {\n return initialSnapshot;\n }\n\n const persistedVersion = parsed.version;\n if (typeof persistedVersion !== \"number\") {\n return initialSnapshot;\n }\n\n let persistedSnapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta> | null = null;\n let shouldRewritePersisted = false;\n\n if (persistedVersion === persistence.version) {\n const coerced = coercePersistedSnapshot(parsed.snapshot, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = Boolean(coerced?.needsRewrite);\n } else if (persistence.migrate) {\n const migrated = persistence.migrate(parsed.snapshot, persistedVersion);\n const coerced = coercePersistedSnapshot(migrated, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = persistedSnapshot !== null;\n }\n\n if (!persistedSnapshot) {\n return initialSnapshot;\n }\n\n const hydratedSnapshot = buildSnapshot(\n persistedSnapshot.history.timeline,\n persistedSnapshot.history.index,\n persistedSnapshot.context,\n persistedSnapshot.status,\n buildInitialAsyncState(steps),\n persistedSnapshot.stepMeta,\n persistedSnapshot.visited\n );\n\n if (shouldRewritePersisted) {\n persistSnapshot(hydratedSnapshot);\n }\n\n return hydratedSnapshot;\n } catch (error) {\n reportPersistenceError(error);\n return initialSnapshot;\n }\n };\n\n return {\n clearOnReset: persistence?.clearOnReset ?? true,\n hydrateSnapshot,\n persistSnapshot,\n removePersistedSnapshot\n };\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_STATUS } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyAsyncPhase,\n JourneyDefaultEventType,\n JourneyDefinition,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyMachine,\n JourneyMachineOptions,\n JourneyObservationEvent,\n JourneySendResult,\n JourneyStepDefinition,\n JourneyTransition,\n JourneyTerminal\n} from \"./types\";\nimport {\n assertStepExists,\n buildIdleStepAsyncState,\n buildInitialAsyncState,\n buildSendResult,\n buildSnapshot,\n isGoToStepByIdEvent,\n isPromiseLike,\n isTerminalTarget,\n normalizeStepCount,\n now,\n selectTransition,\n transitionSnapshot,\n validateJourneyTransitions\n} from \"./machine-helpers\";\nimport { createPersistenceController } from \"./persistence\";\n\n/**\n * Creates a journey machine from a journey definition.\n * Validates steps/transitions, hydrates persisted state (if configured),\n * and returns an API for sending events and reading snapshots.\n */\nexport function createJourneyMachine<\n TContext,\n TStepMeta = unknown,\n TSteps extends Record<string, JourneyStepDefinition<TStepMeta>> = Record<\n string,\n JourneyStepDefinition<TStepMeta>\n >,\n TPayloadMap extends JourneyEventPayloadMap<JourneyDefaultEventType> = Record<never, never>\n>(\n journey: {\n initial: Extract<keyof TSteps, string>;\n context: TContext;\n steps: TSteps;\n transitions: readonly JourneyTransition<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap\n >[];\n },\n options?: JourneyMachineOptions<TContext, Extract<keyof TSteps, string>, TStepMeta>\n): JourneyMachine<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap,\n TStepMeta\n>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> {\n if (!journey.steps || typeof journey.steps !== \"object\") {\n throw new Error(\"Journey steps must be a record object.\");\n }\n\n if (!Array.isArray(journey.transitions)) {\n throw new Error(\"Journey transitions must be an array.\");\n }\n\n assertStepExists(\n journey.steps,\n journey.initial,\n `Journey initial step \"${journey.initial}\" does not exist in steps registry.`\n );\n\n validateJourneyTransitions(journey.transitions, journey.steps);\n\n const buildStepMeta = (): Record<TStepId, TStepMeta> => {\n const stepMeta = {} as Record<TStepId, TStepMeta>;\n for (const stepId of Object.keys(journey.steps) as TStepId[]) {\n stepMeta[stepId] = journey.steps[stepId].meta as TStepMeta;\n }\n return stepMeta;\n };\n\n const { clearOnReset, hydrateSnapshot, persistSnapshot, removePersistedSnapshot } =\n createPersistenceController({\n initial: journey.initial,\n context: journey.context,\n stepMeta: buildStepMeta(),\n steps: journey.steps,\n ...(options ? { options } : {})\n });\n\n let snapshot = hydrateSnapshot();\n snapshot = {\n ...snapshot,\n async: buildInitialAsyncState(journey.steps)\n };\n\n const listeners = new Set<() => void>();\n const eventListeners = new Set<\n (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n >();\n let actionQueue: Promise<void> = Promise.resolve();\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const emit = (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => {\n for (const listener of eventListeners) {\n listener(event);\n }\n };\n\n const queue = <T>(runner: () => Promise<T>): Promise<T> => {\n const resultPromise = actionQueue.then(runner, runner);\n actionQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n return resultPromise;\n };\n\n const isAsyncLoadingPhase = (phase: JourneyAsyncPhase): boolean =>\n phase === JOURNEY_ASYNC_PHASE.EVALUATING_WHEN || phase === JOURNEY_ASYNC_PHASE.RUNNING_EFFECT;\n\n const updateStepAsync = (\n stepId: TStepId,\n updater: (\n current: JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => {\n const current = snapshot.async.byStep[stepId] ?? buildIdleStepAsyncState();\n const next = updater(current);\n if (\n current.phase === next.phase &&\n current.eventType === next.eventType &&\n current.transitionId === next.transitionId &&\n current.error === next.error\n ) {\n return;\n }\n\n const nextByStep = {\n ...snapshot.async.byStep,\n [stepId]: next\n };\n const isLoading = Object.values(nextByStep).some((state) => isAsyncLoadingPhase(state.phase));\n snapshot = {\n ...snapshot,\n async: {\n isLoading,\n byStep: nextByStep\n }\n };\n notify();\n };\n\n const setStepLoading = (\n stepId: TStepId,\n phase: JourneyAsyncPhase,\n eventType: string,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase,\n eventType,\n transitionId: transitionId ?? null,\n error: null\n }));\n };\n\n const setStepIdle = (stepId: TStepId) => {\n updateStepAsync(stepId, () => buildIdleStepAsyncState());\n };\n\n const setStepError = (\n stepId: TStepId,\n eventType: string,\n error: unknown,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase: JOURNEY_ASYNC_PHASE.ERROR,\n eventType,\n transitionId: transitionId ?? null,\n error\n }));\n };\n\n const applyPreviousNavigation = (\n requestedSteps?: number,\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const steps = normalizeStepCount(requestedSteps);\n if (snapshot.history.index === 0) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n const nextIndex = Math.max(0, snapshot.history.index - steps);\n const appliedSteps = snapshot.history.index - nextIndex;\n if (appliedSteps <= 0) {\n return buildSendResult(snapshot, false);\n }\n\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n nextIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"navigation.previous\",\n from,\n to: snapshot.currentStepId,\n requestedSteps: steps,\n appliedSteps,\n timestamp: now()\n });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const applyLastVisitedNavigation = (\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const targetIndex = snapshot.history.timeline.length - 1;\n if (snapshot.history.index >= targetIndex) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n targetIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({ type: \"navigation.lastVisited\", from, to: snapshot.currentStepId, timestamp: now() });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const machine: JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> = {\n getSnapshot: () => snapshot,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n subscribeEvent: (listener) => {\n eventListeners.add(listener);\n return () => {\n eventListeners.delete(listener);\n };\n },\n resetMachine: () => {\n snapshot = buildSnapshot(\n [journey.initial],\n 0,\n journey.context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(journey.steps),\n buildStepMeta()\n );\n if (clearOnReset) {\n removePersistedSnapshot();\n } else {\n persistSnapshot(snapshot);\n }\n notify();\n return snapshot;\n },\n updateContext: (updater) => {\n snapshot = {\n ...snapshot,\n context: updater(snapshot.context)\n };\n persistSnapshot(snapshot);\n notify();\n return snapshot;\n },\n updateStepMetadata: (stepId, updater) => {\n if (!(stepId in journey.steps)) {\n return snapshot;\n }\n\n const previousMeta = snapshot.stepMeta[stepId];\n const nextMeta = updater(previousMeta);\n if (Object.is(previousMeta, nextMeta)) {\n return snapshot;\n }\n\n snapshot = {\n ...snapshot,\n stepMeta: {\n ...snapshot.stepMeta,\n [stepId]: nextMeta\n }\n };\n persistSnapshot(snapshot);\n notify();\n emit({\n type: \"metadata.updated\",\n stepId,\n previous: previousMeta,\n next: nextMeta,\n timestamp: now()\n });\n return snapshot;\n },\n clearStepError: (stepId) => {\n const resolvedStep = stepId ?? snapshot.currentStepId;\n if (!(resolvedStep in journey.steps)) {\n return snapshot;\n }\n\n setStepIdle(resolvedStep);\n return snapshot;\n },\n goToPreviousStep: (steps) =>\n queue(async () => {\n const result = applyPreviousNavigation(steps, \"goToPreviousStep\");\n return result;\n }),\n goToLastVisitedStep: () =>\n queue(async () => {\n const result = applyLastVisitedNavigation(\"goToLastVisitedStep\");\n return result;\n }),\n goToNextStep: () => machine.send({ type: \"goToNextStep\" }),\n terminateJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"terminateJourney\" })\n : machine.send({ type: \"terminateJourney\", payload }),\n completeJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"completeJourney\" })\n : machine.send({ type: \"completeJourney\", payload }),\n send: (event) =>\n queue(async () => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const fromStep = snapshot.currentStepId;\n\n if (isGoToStepByIdEvent(event)) {\n assertStepExists(\n journey.steps,\n event.stepId,\n `Cannot goToStepById unknown step \"${event.stepId}\".`\n );\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n setStepIdle(fromStep);\n\n const beforeCurrent = snapshot.currentStepId;\n const nextSnapshot = transitionSnapshot(snapshot, event.stepId, snapshot.context);\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n\n snapshot = nextSnapshot;\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n transitionId: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n timestamp: now()\n });\n\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, JOURNEY_EVENT.GO_TO_STEP_BY_ID);\n }\n\n const transitionEvent = event as JourneyEvent<TStepId, TEventType, TPayloadMap>;\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n\n let transition;\n try {\n transition = await selectTransition(journey.transitions, snapshot, transitionEvent, {\n onAsyncGuardStart: (currentTransition) => {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.EVALUATING_WHEN,\n transitionEvent.type,\n currentTransition.id\n );\n },\n onAsyncGuardSuccess: () => {\n setStepIdle(fromStep);\n },\n onAsyncGuardError: (currentTransition, error) => {\n setStepError(fromStep, transitionEvent.type, error, currentTransition.id);\n }\n });\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (!transition) {\n if (event.type === \"goToPreviousStep\" || event.type === \"back\") {\n const fallbackResult = applyPreviousNavigation(1, event.type);\n if (fallbackResult.transitioned) {\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: fallbackResult.snapshot.currentStepId,\n eventType: event.type,\n transitionId: null,\n timestamp: now()\n });\n }\n return fallbackResult;\n }\n\n return buildSendResult(snapshot, false);\n }\n\n let nextContext = snapshot.context;\n if (transition.effect) {\n const effectResultPromise = transition.effect({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event: transitionEvent\n });\n if (isPromiseLike(effectResultPromise)) {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.RUNNING_EFFECT,\n transitionEvent.type,\n transition.id\n );\n }\n\n let effectResult: TContext | void;\n try {\n effectResult = await effectResultPromise;\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error, transition.id);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (effectResult !== undefined) {\n nextContext = effectResult;\n }\n }\n\n setStepIdle(fromStep);\n\n const target: TStepId | JourneyTerminal =\n transition.event === \"completeJourney\"\n ? \"COMPLETE\"\n : transition.event === \"terminateJourney\"\n ? \"TERMINATED\"\n : (transition.to as TStepId | JourneyTerminal);\n\n if (isTerminalTarget(target)) {\n const normalizedTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n snapshot = {\n ...snapshot,\n history: {\n timeline: normalizedTimeline,\n index: normalizedTimeline.length - 1\n },\n context: nextContext,\n status: target === \"COMPLETE\" ? JOURNEY_STATUS.COMPLETE : JOURNEY_STATUS.TERMINATED\n };\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: target,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n emit({\n type: target === \"COMPLETE\" ? \"journey.complete\" : \"journey.close\",\n stepId: snapshot.currentStepId,\n timestamp: now()\n });\n\n return buildSendResult(snapshot, true, transition.id);\n }\n\n const resolvedTarget = target;\n\n assertStepExists(\n journey.steps,\n resolvedTarget,\n `Transition points to unknown step \"${resolvedTarget}\".`\n );\n\n const beforeCurrent = snapshot.currentStepId;\n if (beforeCurrent !== resolvedTarget) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n snapshot = transitionSnapshot(snapshot, resolvedTarget, nextContext);\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n if (beforeCurrent !== snapshot.currentStepId) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, transition.id);\n })\n };\n\n return machine;\n}\n", "import { JOURNEY_WILDCARD } from \"./types/journey.types\";\nimport type { JourneyEventPayloadMap } from \"./types/journey.types\";\nimport type {\n EventBuilder,\n JourneyEventTransition,\n JourneyTransition,\n JourneyTransitionArgs,\n JourneyTransitionTarget,\n TransitionBranch,\n TransitionConfig\n} from \"./types/transitions.types\";\n\nconst createEventBuilder = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType\n): EventBuilder<TContext, TStepId, TEventType, TPayloadMap> => {\n if (event === \"completeJourney\") {\n return {\n complete: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"completeJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n if (event === \"terminateJourney\") {\n return {\n terminate: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n return {\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">,\n to\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n choose: (\n ...branches: Array<TransitionBranch<TContext, TStepId, TEventType, TPayloadMap>>\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n branches.map(\n (branch) =>\n ({\n ...branch,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n )\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n};\n\nconst buildTerminalTransition = <\n TContext,\n TStepId extends string,\n TEventType extends \"completeJourney\" | \"terminateJourney\"\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType,\n config: TransitionConfig<TContext, TStepId, TEventType, Record<never, never>> = {}\n): JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>> =>\n ({\n ...config,\n from,\n event\n }) as JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>>;\n\nexport const tx = {\n from: <TStepId extends string, TContext = unknown>(from: TStepId) => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(from, event),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"terminateJourney\", config)\n }),\n any: <TContext = unknown, TStepId extends string = string>() => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(\n JOURNEY_WILDCARD,\n event\n ),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"terminateJourney\", config)\n }),\n when: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >(\n predicate: (\n args: JourneyTransitionArgs<TContext, TStepId, TEventType, TPayloadMap>\n ) => boolean | Promise<boolean>\n ) => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to,\n when: predicate\n })\n }),\n otherwise: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >() => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to\n })\n })\n};\n\nexport const createTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n ...items: Array<\n | JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n | readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[]\n >\n): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n items.flatMap((item) => (Array.isArray(item) ? [...item] : [item]));\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export { createJourneyMachine } from \"./machine\";\nexport { createPersistenceController } from \"./persistence\";\nexport { createTransitions, tx } from \"./transitions\";\nexport {\n JOURNEY_EVENT,\n JOURNEY_ASYNC_PHASE,\n JOURNEY_STATUS,\n JOURNEY_WILDCARD,\n type JourneyBuiltInEvent,\n type JourneyBuiltInFrom,\n type JourneyDefaultEventType,\n type JourneyAsyncPhase,\n type JourneyStatus,\n type JourneyAsyncState,\n type JourneyStepAsyncState,\n type JourneyEvent,\n type JourneyEventPayloadMap,\n type JourneyMachineEventType,\n type JourneyMachinePayloadMap,\n type JourneyDefinition,\n type JourneyMachineOptions,\n type JourneyGoToEvent,\n type JourneyGoToStepByIdEventType,\n type JourneyMachine,\n type JourneyObservationEvent,\n type JourneyPayloadFor,\n type JourneySendEvent,\n type JourneyPersistedSnapshot,\n type JourneyPersistedState,\n type JourneyPersistenceOptions,\n type JourneyStepDefinition,\n type JourneyStorage,\n type JourneySendResult,\n type JourneySnapshot,\n type JourneyTerminal,\n type JourneyTransition,\n type JourneyTransitionArgs,\n type JourneyTransitionTarget\n} from \"./types\";\n", "import type { JourneyPersistenceOptions } from \"./persistence.types\";\nimport type { JourneyTransition } from \"./transitions.types\";\n\n/** Terminal outcomes reached when a journey completes or is explicitly terminated. */\nexport type JourneyTerminal = \"COMPLETE\" | \"TERMINATED\";\n\n/** Runtime machine status constants. */\nexport const JOURNEY_STATUS = {\n RUNNING: \"running\",\n COMPLETE: \"complete\",\n TERMINATED: \"terminated\"\n} as const;\n\n/** Union of possible runtime machine statuses. */\nexport type JourneyStatus = (typeof JOURNEY_STATUS)[keyof typeof JOURNEY_STATUS];\n\n/** Wildcard step identifier used by transitions that match from any step. */\nexport const JOURNEY_WILDCARD = \"*\" as const;\n\n/** Built-in event constants that are part of core machine behavior. */\nexport const JOURNEY_EVENT = {\n GO_TO_STEP_BY_ID: \"goToStepById\"\n} as const;\n\n/** Machine event types that are always recognized by core. */\nexport type JourneyBuiltInEvent = (typeof JOURNEY_EVENT)[keyof typeof JOURNEY_EVENT];\n/** Event literal type for the built-in go-to-step command. */\nexport type JourneyGoToStepByIdEventType = typeof JOURNEY_EVENT.GO_TO_STEP_BY_ID;\n/** Wildcard origin marker for transitions. */\nexport type JourneyBuiltInFrom = typeof JOURNEY_WILDCARD;\n/** Default transition event names supported by machine convenience APIs. */\nexport type JourneyDefaultEventType =\n | \"goToNextStep\"\n | \"goToPreviousStep\"\n | \"terminateJourney\"\n | \"completeJourney\";\n\n/** Async lifecycle phases tracked per step while guards/effects run. */\nexport const JOURNEY_ASYNC_PHASE = {\n IDLE: \"idle\",\n EVALUATING_WHEN: \"evaluating-when\",\n RUNNING_EFFECT: \"running-effect\",\n ERROR: \"error\"\n} as const;\n\n/** Union of supported async lifecycle phases. */\nexport type JourneyAsyncPhase = (typeof JOURNEY_ASYNC_PHASE)[keyof typeof JOURNEY_ASYNC_PHASE];\n\n/** Async execution state for a single step. */\nexport type JourneyStepAsyncState = {\n phase: JourneyAsyncPhase;\n eventType: string | null;\n transitionId: string | null;\n error: unknown | null;\n};\n\n/** Aggregated async state for the machine, keyed by step id. */\nexport type JourneyAsyncState<TStepId extends string> = {\n isLoading: boolean;\n byStep: Record<TStepId, JourneyStepAsyncState>;\n};\n\n/** Minimal event shape used across runtime boundaries. */\nexport type JourneyBaseEvent = {\n type: string;\n payload?: unknown;\n};\n\n/** Optional event payload map by event type. */\nexport type JourneyEventPayloadMap<TEventType extends string> = Partial<\n Record<TEventType | JourneyBuiltInEvent, unknown>\n>;\n\n/** Resolves payload type for a specific event type from the provided payload map. */\nexport type JourneyPayloadFor<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TEvent extends TEventType | JourneyBuiltInEvent\n> = TEvent extends keyof TPayloadMap ? TPayloadMap[TEvent] : unknown;\n\n/** Event-type union accepted by machine `.send()`, including built-in convenience events. */\nexport type JourneyMachineEventType<TEventType extends string> =\n | TEventType\n | JourneyDefaultEventType;\n\n/** Payload map available to machine `.send()`, including built-in convenience events. */\nexport type JourneyMachinePayloadMap<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = TPayloadMap & JourneyEventPayloadMap<JourneyDefaultEventType>;\n\ntype JourneyPayloadForDefaultEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TDefaultEvent extends JourneyDefaultEventType\n> = JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TDefaultEvent\n>;\n\n/** Built-in direct-navigation event that targets a specific step id. */\nexport type JourneyGoToEvent<TStepId extends string, TPayload = unknown> = {\n type: JourneyGoToStepByIdEventType;\n stepId: TStepId;\n payload?: TPayload;\n};\n\n/** Event union available to transitions and guards for the declared event type set. */\nexport type JourneyEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<TEventType, TPayloadMap, JourneyGoToStepByIdEventType>\n >\n | {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n }[TEventType];\n\ntype JourneyDefaultMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in JourneyDefaultEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TType\n >;\n };\n}[JourneyDefaultEventType];\n\ntype JourneyCustomMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n}[TEventType];\n\n/** Event union accepted by `JourneyMachine.send`. */\nexport type JourneySendEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n >\n | JourneyDefaultMachineEvent<TEventType, TPayloadMap>\n | JourneyCustomMachineEvent<TEventType, TPayloadMap>;\n\n/**\n * Step definition with optional metadata and optional typed extension fields.\n * Use `TStepExtra` to explicitly model additional per-step properties.\n */\nexport type JourneyStepDefinition<\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n meta?: TStepMeta;\n} & TStepExtra;\n\n/** Serializable runtime snapshot of the journey state. */\nexport type JourneySnapshot<TContext, TStepId extends string, TStepMeta = unknown> = {\n currentStepId: TStepId;\n history: {\n timeline: readonly TStepId[];\n index: number;\n };\n context: TContext;\n visited: Record<TStepId, boolean>;\n stepMeta: Record<TStepId, TStepMeta>;\n status: JourneyStatus;\n async: JourneyAsyncState<TStepId>;\n};\n\n/** Full machine definition used to create a journey machine instance. */\nexport type JourneyDefinition<\n TContext,\n TStepId extends string = string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n initial: TStepId;\n context: TContext;\n steps: Record<TStepId, JourneyStepDefinition<TStepMeta, TStepExtra>>;\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[];\n};\n\n/** Optional machine features (for example, persistence configuration). */\nexport type JourneyMachineOptions<TContext, TStepId extends string, TStepMeta = unknown> = {\n persistence?: JourneyPersistenceOptions<TContext, TStepId, TStepMeta>;\n};\n\n/** Result returned from send/navigation APIs. */\nexport type JourneySendResult<TContext, TStepId extends string, TStepMeta = unknown> = {\n transitioned: boolean;\n transitionId?: string;\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>;\n};\n\n/** Observation events emitted by the machine lifecycle/event stream. */\nexport type JourneyObservationEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> =\n | {\n type: \"transition.start\";\n from: TStepId;\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>;\n timestamp: number;\n }\n | {\n type: \"transition.success\";\n from: TStepId;\n to: TStepId | JourneyTerminal;\n eventType: string;\n transitionId: string | null;\n timestamp: number;\n }\n | {\n type: \"transition.error\";\n from: TStepId;\n eventType: string;\n transitionId: string | null;\n error: unknown;\n timestamp: number;\n }\n | {\n type: \"step.exit\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"step.enter\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.complete\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.close\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"navigation.previous\";\n from: TStepId;\n to: TStepId;\n requestedSteps: number;\n appliedSteps: number;\n timestamp: number;\n }\n | {\n type: \"navigation.lastVisited\";\n from: TStepId;\n to: TStepId;\n timestamp: number;\n }\n | {\n type: \"metadata.updated\";\n stepId: TStepId;\n previous: TStepMeta;\n next: TStepMeta;\n timestamp: number;\n };\n\n/** Runtime machine API for reading snapshots, sending events, and controlling flow. */\nexport type JourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> = {\n getSnapshot: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n send: (\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToNextStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n terminateJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"terminateJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n completeJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"completeJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToPreviousStep: (steps?: number) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToLastVisitedStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n updateContext: (\n updater: (context: TContext) => TContext\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n updateStepMetadata: (\n stepId: TStepId,\n updater: (metadata: TStepMeta) => TStepMeta\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n clearStepError: (stepId?: TStepId) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n resetMachine: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n subscribe: (listener: () => void) => () => void;\n subscribeEvent: (\n listener: (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n ) => () => void;\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_WILDCARD } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyGoToEvent,\n JourneyGoToStepByIdEventType,\n JourneyMachineEventType,\n JourneyMachinePayloadMap,\n JourneyPayloadFor,\n JourneySendEvent,\n JourneySendResult,\n JourneySnapshot,\n JourneyStatus,\n JourneyStepAsyncState,\n JourneyTerminal,\n JourneyTransition\n} from \"./types\";\n\nexport const assertStepExists = <TStepId extends string>(\n steps: Record<TStepId, unknown>,\n stepId: TStepId,\n message: string\n) => {\n if (!(stepId in steps)) {\n throw new Error(message);\n }\n};\n\nexport const normalizeStepCount = (steps?: number): number => {\n if (typeof steps !== \"number\" || !Number.isFinite(steps)) {\n return 1;\n }\n return Math.max(1, Math.trunc(steps));\n};\n\nexport const now = (): number => Date.now();\n\nconst unique = <T>(items: readonly T[]): T[] => [...new Set(items)];\n\nconst normalizeVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n stepIds: readonly TStepId[]\n): Record<TStepId, boolean> =>\n Object.fromEntries(stepIds.map((stepId) => [stepId, visited[stepId] === true])) as Record<\n TStepId,\n boolean\n >;\n\nexport const buildVisitedFromTimeline = <TStepId extends string>(\n timeline: readonly TStepId[],\n stepIds?: readonly TStepId[]\n): Record<TStepId, boolean> => {\n const resolvedStepIds = stepIds ?? unique(timeline);\n const visited = Object.fromEntries(resolvedStepIds.map((stepId) => [stepId, false])) as Record<\n TStepId,\n boolean\n >;\n\n for (const stepId of timeline) {\n visited[stepId] = true;\n }\n\n return visited;\n};\n\nexport const appendVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n current: TStepId\n): Record<TStepId, boolean> => ({\n ...visited,\n [current]: true\n});\n\nexport const isPromiseLike = <T>(value: T | PromiseLike<T>): value is PromiseLike<T> =>\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof (value as { then: unknown }).then === \"function\";\n\nexport const buildIdleStepAsyncState = (): JourneyStepAsyncState => ({\n phase: JOURNEY_ASYNC_PHASE.IDLE,\n eventType: null,\n transitionId: null,\n error: null\n});\n\nexport const buildInitialAsyncState = <TStepId extends string>(\n steps: Record<TStepId, unknown>\n): JourneyAsyncState<TStepId> => {\n const byStep = Object.fromEntries(\n Object.keys(steps).map((stepId) => [stepId, buildIdleStepAsyncState()])\n ) as Record<TStepId, JourneyStepAsyncState>;\n\n return {\n isLoading: false,\n byStep\n };\n};\n\nexport const isGoToStepByIdEvent = <\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n): event is JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n> => event.type === JOURNEY_EVENT.GO_TO_STEP_BY_ID && \"stepId\" in event;\n\nexport const isTerminalTarget = <TStepId extends string>(\n target: TStepId | JourneyTerminal\n): target is JourneyTerminal => target === \"COMPLETE\" || target === \"TERMINATED\";\n\nexport const validateJourneyTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n steps: Record<TStepId, unknown>\n) => {\n const stepRegistry = steps as Record<string, unknown>;\n\n for (const [index, transition] of transitions.entries()) {\n if (!transition || typeof transition !== \"object\") {\n throw new Error(`Journey transition at index ${index} must be an object.`);\n }\n\n if (typeof transition.from !== \"string\" || typeof transition.event !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define string \"from\" and \"event\".`\n );\n }\n\n if (transition.from !== JOURNEY_WILDCARD && !(transition.from in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} references unknown from step \"${transition.from}\".`\n );\n }\n\n if (transition.event === \"completeJourney\" || transition.event === \"terminateJourney\") {\n if (\"to\" in transition && transition.to !== undefined) {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" cannot define \"to\".`\n );\n }\n continue;\n }\n\n if (typeof transition.to !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" must define string \"to\".`\n );\n }\n\n if (!isTerminalTarget(transition.to) && !(transition.to in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} points to unknown step \"${transition.to}\".`\n );\n }\n }\n};\n\nexport const buildSendResult = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n transitioned: boolean,\n transitionId?: string\n): JourneySendResult<TContext, TStepId, TStepMeta> =>\n transitionId ? { transitioned, transitionId, snapshot } : { transitioned, snapshot };\n\nexport const buildSnapshot = <TContext, TStepId extends string, TStepMeta>(\n timeline: readonly TStepId[],\n index: number,\n context: TContext,\n status: JourneyStatus,\n asyncState: JourneyAsyncState<TStepId>,\n stepMeta: Record<TStepId, TStepMeta>,\n visited?: Record<TStepId, boolean>\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n if (timeline.length === 0) {\n throw new Error(\"Journey timeline cannot be empty.\");\n }\n const safeIndex = Math.max(0, Math.min(Math.trunc(index), timeline.length - 1));\n const currentStepId = timeline[safeIndex] as TStepId;\n const stepIds = Object.keys(stepMeta) as TStepId[];\n return {\n status,\n currentStepId,\n history: {\n timeline: [...timeline],\n index: safeIndex\n },\n context,\n visited: visited\n ? normalizeVisited(visited, stepIds)\n : buildVisitedFromTimeline(timeline, stepIds),\n stepMeta: { ...stepMeta },\n async: asyncState\n };\n};\n\nexport const selectTransition = async <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TStepMeta\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n event: JourneyEvent<TStepId, TEventType, TPayloadMap>,\n hooks?: {\n onAsyncGuardStart?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardSuccess?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardError?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n error: unknown\n ) => void;\n }\n): Promise<JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> | null> => {\n for (const transition of transitions) {\n const fromMatches =\n transition.from === JOURNEY_WILDCARD || transition.from === snapshot.currentStepId;\n const eventMatches = transition.event === event.type;\n\n if (!fromMatches || !eventMatches) {\n continue;\n }\n\n if (!transition.when) {\n return transition;\n }\n\n const guardResult = transition.when({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event\n });\n const asyncGuard = isPromiseLike(guardResult);\n if (asyncGuard) {\n hooks?.onAsyncGuardStart?.(transition);\n }\n\n let allowed: boolean;\n try {\n allowed = await guardResult;\n } catch (error) {\n if (asyncGuard) {\n hooks?.onAsyncGuardError?.(transition, error);\n }\n throw error;\n }\n\n if (asyncGuard) {\n hooks?.onAsyncGuardSuccess?.(transition);\n }\n\n if (allowed) {\n return transition;\n }\n }\n\n return null;\n};\n\nexport const transitionSnapshot = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n nextCurrent: TStepId,\n nextContext: TContext\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const baseTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n let nextTimeline = baseTimeline;\n if (nextCurrent !== snapshot.currentStepId) {\n nextTimeline = [...baseTimeline, nextCurrent];\n }\n\n const nextIndex = nextTimeline.length - 1;\n const visited = appendVisited(snapshot.visited, nextCurrent);\n\n return buildSnapshot(\n nextTimeline,\n nextIndex,\n nextContext,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n visited\n );\n};\n", "import { JOURNEY_STATUS } from \"./types/journey.types\";\nimport type {\n JourneyPersistedSnapshot,\n JourneyPersistedState,\n JourneyStorage,\n ResolvedPersistence\n} from \"./types/persistence.types\";\nimport type { JourneyMachineOptions, JourneySnapshot, JourneyStatus } from \"./types/journey.types\";\nimport { buildInitialAsyncState, buildSnapshot, buildVisitedFromTimeline } from \"./machine-helpers\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst isStatusValue = (value: unknown): value is JourneyStatus =>\n value === JOURNEY_STATUS.RUNNING ||\n value === JOURNEY_STATUS.COMPLETE ||\n value === JOURNEY_STATUS.TERMINATED;\n\nconst resolveDefaultStorage = (): JourneyStorage | null => {\n const localStorageCandidate = (globalThis as { localStorage?: Partial<JourneyStorage> })\n .localStorage;\n\n if (\n !localStorageCandidate ||\n typeof localStorageCandidate.getItem !== \"function\" ||\n typeof localStorageCandidate.setItem !== \"function\" ||\n typeof localStorageCandidate.removeItem !== \"function\"\n ) {\n return null;\n }\n\n return localStorageCandidate as JourneyStorage;\n};\n\nconst resolvePersistence = <TContext, TStepId extends string, TStepMeta>(\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>[\"persistence\"]\n): ResolvedPersistence<TContext, TStepId, TStepMeta> | null => {\n if (!options) {\n return null;\n }\n\n const storage = options.storage ?? resolveDefaultStorage();\n if (!storage) {\n return null;\n }\n\n return {\n key: options.key,\n storage,\n version: options.version ?? 1,\n clearOnReset: options.clearOnReset ?? true,\n serialize: options.serialize ?? JSON.stringify,\n deserialize: options.deserialize ?? JSON.parse,\n ...(options.migrate ? { migrate: options.migrate } : {}),\n ...(options.onError ? { onError: options.onError } : {})\n };\n};\n\nconst coercePersistedSnapshot = <TContext, TStepId extends string, TStepMeta>(\n value: unknown,\n steps: Record<TStepId, unknown>,\n fallbackContext: TContext,\n fallbackStepMeta: Record<TStepId, TStepMeta>\n): {\n snapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta>;\n needsRewrite: boolean;\n} | null => {\n if (!isRecord(value)) {\n return null;\n }\n\n let needsRewrite = false;\n\n const rawHistory = isRecord(value.history) ? value.history : null;\n if (!rawHistory) {\n needsRewrite = true;\n }\n\n const rawTimeline = rawHistory?.timeline ?? value.timeline;\n const timeline = Array.isArray(rawTimeline)\n ? (rawTimeline.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[])\n : [];\n\n const currentStepIdValue =\n typeof value.currentStepId === \"string\" && value.currentStepId in steps\n ? (value.currentStepId as TStepId)\n : typeof value.current === \"string\" && value.current in steps\n ? (value.current as TStepId)\n : null;\n\n if (timeline.length === 0) {\n if (!currentStepIdValue) {\n return null;\n }\n timeline.push(currentStepIdValue);\n needsRewrite = true;\n }\n\n let index = timeline.length - 1;\n const rawIndex = rawHistory?.index ?? value.index;\n if (typeof rawIndex === \"number\" && Number.isFinite(rawIndex)) {\n index = Math.max(0, Math.min(Math.trunc(rawIndex), timeline.length - 1));\n if (index !== rawIndex) {\n needsRewrite = true;\n }\n } else if (currentStepIdValue) {\n const inferredIndex = timeline.lastIndexOf(currentStepIdValue);\n if (inferredIndex >= 0) {\n index = inferredIndex;\n needsRewrite = true;\n }\n }\n\n const status = isStatusValue(value.status) ? value.status : JOURNEY_STATUS.RUNNING;\n if (!isStatusValue(value.status)) {\n needsRewrite = true;\n }\n\n const stepIds = Object.keys(steps) as TStepId[];\n const visitedSource = value.visited;\n const visitedFromRecord = isRecord(visitedSource)\n ? (Object.fromEntries(\n stepIds.map((stepId) => [stepId, visitedSource[stepId] === true])\n ) as Record<TStepId, boolean>)\n : null;\n const visitedFromArray = Array.isArray(visitedSource)\n ? buildVisitedFromTimeline(\n visitedSource.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[],\n stepIds\n )\n : null;\n\n let visited = buildVisitedFromTimeline(timeline, stepIds);\n if (visitedFromRecord) {\n const visitedRecord = visitedSource as Record<string, unknown>;\n visited = visitedFromRecord;\n const hasMissingOrInvalidStep = stepIds.some(\n (stepId) => typeof visitedRecord[stepId] !== \"boolean\"\n );\n if (hasMissingOrInvalidStep) {\n needsRewrite = true;\n }\n } else if (visitedFromArray) {\n visited = visitedFromArray;\n needsRewrite = true;\n } else {\n needsRewrite = true;\n }\n\n const rawStepMeta = isRecord(value.stepMeta) ? value.stepMeta : null;\n if (!rawStepMeta) {\n needsRewrite = true;\n }\n\n const stepMeta = Object.fromEntries(\n Object.keys(steps).map((stepId) => {\n const typedStepId = stepId as TStepId;\n const rawValue = rawStepMeta ? rawStepMeta[stepId] : undefined;\n if (rawValue === undefined) {\n return [typedStepId, fallbackStepMeta[typedStepId]];\n }\n return [typedStepId, rawValue as TStepMeta];\n })\n ) as Record<TStepId, TStepMeta>;\n\n return {\n snapshot: {\n currentStepId: timeline[index] as TStepId,\n history: {\n timeline,\n index\n },\n context: (\"context\" in value ? value.context : fallbackContext) as TContext,\n status,\n visited,\n stepMeta\n },\n needsRewrite\n };\n};\n\n/**\n * Creates a persistence controller for snapshots, including hydration,\n * serialization, and storage error handling.\n */\nexport const createPersistenceController = <TContext, TStepId extends string, TStepMeta>(args: {\n initial: TStepId;\n context: TContext;\n stepMeta: Record<TStepId, TStepMeta>;\n steps: Record<TStepId, unknown>;\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>;\n}) => {\n const { initial, context, stepMeta, steps, options } = args;\n const persistence = resolvePersistence(options?.persistence);\n\n const reportPersistenceError = (error: unknown) => {\n persistence?.onError?.(error);\n };\n\n const persistSnapshot = (snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>) => {\n if (!persistence) {\n return;\n }\n\n try {\n const persistedState: JourneyPersistedState<TContext, TStepId, TStepMeta> = {\n version: persistence.version,\n snapshot: {\n currentStepId: snapshot.currentStepId,\n history: {\n timeline: [...snapshot.history.timeline],\n index: snapshot.history.index\n },\n context: snapshot.context,\n status: snapshot.status,\n visited: { ...snapshot.visited },\n stepMeta: { ...snapshot.stepMeta }\n }\n };\n persistence.storage.setItem(persistence.key, persistence.serialize(persistedState));\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const removePersistedSnapshot = () => {\n if (!persistence) {\n return;\n }\n\n try {\n persistence.storage.removeItem(persistence.key);\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const hydrateSnapshot = (): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const initialSnapshot = buildSnapshot(\n [initial],\n 0,\n context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(steps),\n stepMeta\n );\n if (!persistence) {\n return initialSnapshot;\n }\n\n try {\n const rawPersisted = persistence.storage.getItem(persistence.key);\n if (!rawPersisted) {\n return initialSnapshot;\n }\n\n const parsed = persistence.deserialize(rawPersisted);\n if (!isRecord(parsed)) {\n return initialSnapshot;\n }\n\n const persistedVersion = parsed.version;\n if (typeof persistedVersion !== \"number\") {\n return initialSnapshot;\n }\n\n let persistedSnapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta> | null = null;\n let shouldRewritePersisted = false;\n\n if (persistedVersion === persistence.version) {\n const coerced = coercePersistedSnapshot(parsed.snapshot, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = Boolean(coerced?.needsRewrite);\n } else if (persistence.migrate) {\n const migrated = persistence.migrate(parsed.snapshot, persistedVersion);\n const coerced = coercePersistedSnapshot(migrated, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = persistedSnapshot !== null;\n }\n\n if (!persistedSnapshot) {\n return initialSnapshot;\n }\n\n const hydratedSnapshot = buildSnapshot(\n persistedSnapshot.history.timeline,\n persistedSnapshot.history.index,\n persistedSnapshot.context,\n persistedSnapshot.status,\n buildInitialAsyncState(steps),\n persistedSnapshot.stepMeta,\n persistedSnapshot.visited\n );\n\n if (shouldRewritePersisted) {\n persistSnapshot(hydratedSnapshot);\n }\n\n return hydratedSnapshot;\n } catch (error) {\n reportPersistenceError(error);\n return initialSnapshot;\n }\n };\n\n return {\n clearOnReset: persistence?.clearOnReset ?? true,\n hydrateSnapshot,\n persistSnapshot,\n removePersistedSnapshot\n };\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_STATUS } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyAsyncPhase,\n JourneyDefaultEventType,\n JourneyDefinition,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyMachine,\n JourneyMachineOptions,\n JourneyObservationEvent,\n JourneySendResult,\n JourneyStepDefinition,\n JourneyTransition,\n JourneyTerminal\n} from \"./types\";\nimport {\n assertStepExists,\n buildIdleStepAsyncState,\n buildInitialAsyncState,\n buildSendResult,\n buildSnapshot,\n isGoToStepByIdEvent,\n isPromiseLike,\n isTerminalTarget,\n normalizeStepCount,\n now,\n selectTransition,\n transitionSnapshot,\n validateJourneyTransitions\n} from \"./machine-helpers\";\nimport { createPersistenceController } from \"./persistence\";\n\n/**\n * Creates a journey machine from a journey definition.\n * Validates steps/transitions, hydrates persisted state (if configured),\n * and returns an API for sending events and reading snapshots.\n */\nexport function createJourneyMachine<\n TContext,\n TStepMeta = unknown,\n TSteps extends Record<string, JourneyStepDefinition<TStepMeta>> = Record<\n string,\n JourneyStepDefinition<TStepMeta>\n >,\n TPayloadMap extends JourneyEventPayloadMap<JourneyDefaultEventType> = Record<never, never>\n>(\n journey: {\n initial: Extract<keyof TSteps, string>;\n context: TContext;\n steps: TSteps;\n transitions: readonly JourneyTransition<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap\n >[];\n },\n options?: JourneyMachineOptions<TContext, Extract<keyof TSteps, string>, TStepMeta>\n): JourneyMachine<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap,\n TStepMeta\n>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> {\n if (!journey.steps || typeof journey.steps !== \"object\") {\n throw new Error(\"Journey steps must be a record object.\");\n }\n\n if (!Array.isArray(journey.transitions)) {\n throw new Error(\"Journey transitions must be an array.\");\n }\n\n assertStepExists(\n journey.steps,\n journey.initial,\n `Journey initial step \"${journey.initial}\" does not exist in steps registry.`\n );\n\n validateJourneyTransitions(journey.transitions, journey.steps);\n\n const buildStepMeta = (): Record<TStepId, TStepMeta> => {\n const stepMeta = {} as Record<TStepId, TStepMeta>;\n for (const stepId of Object.keys(journey.steps) as TStepId[]) {\n stepMeta[stepId] = journey.steps[stepId].meta as TStepMeta;\n }\n return stepMeta;\n };\n\n const { clearOnReset, hydrateSnapshot, persistSnapshot, removePersistedSnapshot } =\n createPersistenceController({\n initial: journey.initial,\n context: journey.context,\n stepMeta: buildStepMeta(),\n steps: journey.steps,\n ...(options ? { options } : {})\n });\n\n let snapshot = hydrateSnapshot();\n snapshot = {\n ...snapshot,\n async: buildInitialAsyncState(journey.steps)\n };\n\n const listeners = new Set<() => void>();\n const eventListeners = new Set<\n (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n >();\n let actionQueue: Promise<void> = Promise.resolve();\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const emit = (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => {\n for (const listener of eventListeners) {\n listener(event);\n }\n };\n\n const queue = <T>(runner: () => Promise<T>): Promise<T> => {\n const resultPromise = actionQueue.then(runner, runner);\n actionQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n return resultPromise;\n };\n\n const isAsyncLoadingPhase = (phase: JourneyAsyncPhase): boolean =>\n phase === JOURNEY_ASYNC_PHASE.EVALUATING_WHEN || phase === JOURNEY_ASYNC_PHASE.RUNNING_EFFECT;\n\n const updateStepAsync = (\n stepId: TStepId,\n updater: (\n current: JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => {\n const current = snapshot.async.byStep[stepId] ?? buildIdleStepAsyncState();\n const next = updater(current);\n if (\n current.phase === next.phase &&\n current.eventType === next.eventType &&\n current.transitionId === next.transitionId &&\n current.error === next.error\n ) {\n return;\n }\n\n const nextByStep = {\n ...snapshot.async.byStep,\n [stepId]: next\n };\n const isLoading = Object.values(nextByStep).some((state) => isAsyncLoadingPhase(state.phase));\n snapshot = {\n ...snapshot,\n async: {\n isLoading,\n byStep: nextByStep\n }\n };\n notify();\n };\n\n const setStepLoading = (\n stepId: TStepId,\n phase: JourneyAsyncPhase,\n eventType: string,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase,\n eventType,\n transitionId: transitionId ?? null,\n error: null\n }));\n };\n\n const setStepIdle = (stepId: TStepId) => {\n updateStepAsync(stepId, () => buildIdleStepAsyncState());\n };\n\n const setStepError = (\n stepId: TStepId,\n eventType: string,\n error: unknown,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase: JOURNEY_ASYNC_PHASE.ERROR,\n eventType,\n transitionId: transitionId ?? null,\n error\n }));\n };\n\n const applyPreviousNavigation = (\n requestedSteps?: number,\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const steps = normalizeStepCount(requestedSteps);\n if (snapshot.history.index === 0) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n const nextIndex = Math.max(0, snapshot.history.index - steps);\n const appliedSteps = snapshot.history.index - nextIndex;\n if (appliedSteps <= 0) {\n return buildSendResult(snapshot, false);\n }\n\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n nextIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"navigation.previous\",\n from,\n to: snapshot.currentStepId,\n requestedSteps: steps,\n appliedSteps,\n timestamp: now()\n });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const applyLastVisitedNavigation = (\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const targetIndex = snapshot.history.timeline.length - 1;\n if (snapshot.history.index >= targetIndex) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n targetIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({ type: \"navigation.lastVisited\", from, to: snapshot.currentStepId, timestamp: now() });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const machine: JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> = {\n getSnapshot: () => snapshot,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n subscribeEvent: (listener) => {\n eventListeners.add(listener);\n return () => {\n eventListeners.delete(listener);\n };\n },\n resetMachine: () => {\n snapshot = buildSnapshot(\n [journey.initial],\n 0,\n journey.context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(journey.steps),\n buildStepMeta()\n );\n if (clearOnReset) {\n removePersistedSnapshot();\n } else {\n persistSnapshot(snapshot);\n }\n notify();\n return snapshot;\n },\n updateContext: (updater) => {\n snapshot = {\n ...snapshot,\n context: updater(snapshot.context)\n };\n persistSnapshot(snapshot);\n notify();\n return snapshot;\n },\n updateStepMetadata: (stepId, updater) => {\n if (!(stepId in journey.steps)) {\n return snapshot;\n }\n\n const previousMeta = snapshot.stepMeta[stepId];\n const nextMeta = updater(previousMeta);\n if (Object.is(previousMeta, nextMeta)) {\n return snapshot;\n }\n\n snapshot = {\n ...snapshot,\n stepMeta: {\n ...snapshot.stepMeta,\n [stepId]: nextMeta\n }\n };\n persistSnapshot(snapshot);\n notify();\n emit({\n type: \"metadata.updated\",\n stepId,\n previous: previousMeta,\n next: nextMeta,\n timestamp: now()\n });\n return snapshot;\n },\n clearStepError: (stepId) => {\n const resolvedStep = stepId ?? snapshot.currentStepId;\n if (!(resolvedStep in journey.steps)) {\n return snapshot;\n }\n\n setStepIdle(resolvedStep);\n return snapshot;\n },\n goToPreviousStep: (steps) =>\n queue(async () => {\n const result = applyPreviousNavigation(steps, \"goToPreviousStep\");\n return result;\n }),\n goToLastVisitedStep: () =>\n queue(async () => {\n const result = applyLastVisitedNavigation(\"goToLastVisitedStep\");\n return result;\n }),\n goToNextStep: () => machine.send({ type: \"goToNextStep\" }),\n terminateJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"terminateJourney\" })\n : machine.send({ type: \"terminateJourney\", payload }),\n completeJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"completeJourney\" })\n : machine.send({ type: \"completeJourney\", payload }),\n send: (event) =>\n queue(async () => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const fromStep = snapshot.currentStepId;\n\n if (isGoToStepByIdEvent(event)) {\n assertStepExists(\n journey.steps,\n event.stepId,\n `Cannot goToStepById unknown step \"${event.stepId}\".`\n );\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n setStepIdle(fromStep);\n\n const beforeCurrent = snapshot.currentStepId;\n const nextSnapshot = transitionSnapshot(snapshot, event.stepId, snapshot.context);\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n\n snapshot = nextSnapshot;\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n transitionId: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n timestamp: now()\n });\n\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, JOURNEY_EVENT.GO_TO_STEP_BY_ID);\n }\n\n const transitionEvent = event as JourneyEvent<TStepId, TEventType, TPayloadMap>;\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n\n let transition;\n try {\n transition = await selectTransition(journey.transitions, snapshot, transitionEvent, {\n onAsyncGuardStart: (currentTransition) => {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.EVALUATING_WHEN,\n transitionEvent.type,\n currentTransition.id\n );\n },\n onAsyncGuardSuccess: () => {\n setStepIdle(fromStep);\n },\n onAsyncGuardError: (currentTransition, error) => {\n setStepError(fromStep, transitionEvent.type, error, currentTransition.id);\n }\n });\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (!transition) {\n if (event.type === \"goToPreviousStep\" || event.type === \"back\") {\n const fallbackResult = applyPreviousNavigation(1, event.type);\n if (fallbackResult.transitioned) {\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: fallbackResult.snapshot.currentStepId,\n eventType: event.type,\n transitionId: null,\n timestamp: now()\n });\n }\n return fallbackResult;\n }\n\n return buildSendResult(snapshot, false);\n }\n\n let nextContext = snapshot.context;\n if (transition.effect) {\n const effectResultPromise = transition.effect({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event: transitionEvent\n });\n if (isPromiseLike(effectResultPromise)) {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.RUNNING_EFFECT,\n transitionEvent.type,\n transition.id\n );\n }\n\n let effectResult: TContext | void;\n try {\n effectResult = await effectResultPromise;\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error, transition.id);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (effectResult !== undefined) {\n nextContext = effectResult;\n }\n }\n\n setStepIdle(fromStep);\n\n const target: TStepId | JourneyTerminal =\n transition.event === \"completeJourney\"\n ? \"COMPLETE\"\n : transition.event === \"terminateJourney\"\n ? \"TERMINATED\"\n : (transition.to as TStepId | JourneyTerminal);\n\n if (isTerminalTarget(target)) {\n const normalizedTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n snapshot = {\n ...snapshot,\n history: {\n timeline: normalizedTimeline,\n index: normalizedTimeline.length - 1\n },\n context: nextContext,\n status: target === \"COMPLETE\" ? JOURNEY_STATUS.COMPLETE : JOURNEY_STATUS.TERMINATED\n };\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: target,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n emit({\n type: target === \"COMPLETE\" ? \"journey.complete\" : \"journey.close\",\n stepId: snapshot.currentStepId,\n timestamp: now()\n });\n\n return buildSendResult(snapshot, true, transition.id);\n }\n\n const resolvedTarget = target;\n\n assertStepExists(\n journey.steps,\n resolvedTarget,\n `Transition points to unknown step \"${resolvedTarget}\".`\n );\n\n const beforeCurrent = snapshot.currentStepId;\n if (beforeCurrent !== resolvedTarget) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n snapshot = transitionSnapshot(snapshot, resolvedTarget, nextContext);\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n if (beforeCurrent !== snapshot.currentStepId) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, transition.id);\n })\n };\n\n return machine;\n}\n", "import { JOURNEY_WILDCARD } from \"./types/journey.types\";\nimport type { JourneyEventPayloadMap } from \"./types/journey.types\";\nimport type {\n EventBuilder,\n JourneyEventTransition,\n JourneyTransition,\n JourneyTransitionArgs,\n JourneyTransitionTarget,\n TransitionBranch,\n TransitionConfig\n} from \"./types/transitions.types\";\n\nconst createEventBuilder = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType\n): EventBuilder<TContext, TStepId, TEventType, TPayloadMap> => {\n if (event === \"completeJourney\") {\n return {\n complete: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"completeJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n if (event === \"terminateJourney\") {\n return {\n terminate: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n return {\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">,\n to\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n choose: (\n ...branches: Array<TransitionBranch<TContext, TStepId, TEventType, TPayloadMap>>\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n branches.map(\n (branch) =>\n ({\n ...branch,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n )\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n};\n\nconst buildTerminalTransition = <\n TContext,\n TStepId extends string,\n TEventType extends \"completeJourney\" | \"terminateJourney\"\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType,\n config: TransitionConfig<TContext, TStepId, TEventType, Record<never, never>> = {}\n): JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>> =>\n ({\n ...config,\n from,\n event\n }) as JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>>;\n\n/**\n * Fluent helpers for building journey transitions with type-safe branches.\n */\nexport const tx = {\n from: <TStepId extends string, TContext = unknown>(from: TStepId) => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(from, event),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"terminateJourney\", config)\n }),\n any: <TContext = unknown, TStepId extends string = string>() => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(\n JOURNEY_WILDCARD,\n event\n ),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"terminateJourney\", config)\n }),\n when: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >(\n predicate: (\n args: JourneyTransitionArgs<TContext, TStepId, TEventType, TPayloadMap>\n ) => boolean | Promise<boolean>\n ) => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to,\n when: predicate\n })\n }),\n otherwise: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >() => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to\n })\n })\n};\n\n/**\n * Flattens transition items and transition arrays into a single transition list.\n */\nexport const createTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n ...items: Array<\n | JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n | readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[]\n >\n): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n items.flatMap((item) => (Array.isArray(item) ? [...item] : [item]));\n"],
5
+ "mappings": "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",
6
6
  "names": ["index_exports", "__export", "JOURNEY_ASYNC_PHASE", "JOURNEY_EVENT", "JOURNEY_STATUS", "JOURNEY_WILDCARD", "createJourneyMachine", "createPersistenceController", "createTransitions", "tx", "__toCommonJS", "JOURNEY_STATUS", "JOURNEY_WILDCARD", "JOURNEY_EVENT", "JOURNEY_ASYNC_PHASE", "assertStepExists", "steps", "stepId", "message", "normalizeStepCount", "now", "unique", "items", "normalizeVisited", "visited", "stepIds", "buildVisitedFromTimeline", "timeline", "resolvedStepIds", "appendVisited", "current", "isPromiseLike", "value", "buildIdleStepAsyncState", "JOURNEY_ASYNC_PHASE", "buildInitialAsyncState", "isGoToStepByIdEvent", "event", "JOURNEY_EVENT", "isTerminalTarget", "target", "validateJourneyTransitions", "transitions", "stepRegistry", "index", "transition", "JOURNEY_WILDCARD", "buildSendResult", "snapshot", "transitioned", "transitionId", "buildSnapshot", "context", "status", "asyncState", "stepMeta", "safeIndex", "currentStepId", "selectTransition", "hooks", "fromMatches", "eventMatches", "guardResult", "asyncGuard", "allowed", "error", "transitionSnapshot", "nextCurrent", "nextContext", "baseTimeline", "nextTimeline", "nextIndex", "isRecord", "value", "isStatusValue", "JOURNEY_STATUS", "resolveDefaultStorage", "localStorageCandidate", "resolvePersistence", "options", "storage", "coercePersistedSnapshot", "steps", "fallbackContext", "fallbackStepMeta", "needsRewrite", "rawHistory", "rawTimeline", "timeline", "step", "currentStepIdValue", "index", "rawIndex", "inferredIndex", "status", "stepIds", "visitedSource", "visitedFromRecord", "stepId", "visitedFromArray", "buildVisitedFromTimeline", "visited", "visitedRecord", "rawStepMeta", "stepMeta", "typedStepId", "rawValue", "createPersistenceController", "args", "initial", "context", "persistence", "reportPersistenceError", "error", "persistSnapshot", "snapshot", "persistedState", "removePersistedSnapshot", "hydrateSnapshot", "initialSnapshot", "buildSnapshot", "buildInitialAsyncState", "rawPersisted", "parsed", "persistedVersion", "persistedSnapshot", "shouldRewritePersisted", "coerced", "migrated", "hydratedSnapshot", "createJourneyMachine", "journey", "options", "assertStepExists", "validateJourneyTransitions", "buildStepMeta", "stepMeta", "stepId", "clearOnReset", "hydrateSnapshot", "persistSnapshot", "removePersistedSnapshot", "createPersistenceController", "snapshot", "buildInitialAsyncState", "listeners", "eventListeners", "actionQueue", "notify", "listener", "emit", "event", "queue", "runner", "resultPromise", "isAsyncLoadingPhase", "phase", "JOURNEY_ASYNC_PHASE", "updateStepAsync", "updater", "current", "buildIdleStepAsyncState", "next", "nextByStep", "isLoading", "state", "setStepLoading", "eventType", "transitionId", "setStepIdle", "setStepError", "error", "applyPreviousNavigation", "requestedSteps", "JOURNEY_STATUS", "buildSendResult", "steps", "normalizeStepCount", "from", "nextIndex", "appliedSteps", "now", "buildSnapshot", "applyLastVisitedNavigation", "targetIndex", "machine", "previousMeta", "nextMeta", "resolvedStep", "payload", "fromStep", "isGoToStepByIdEvent", "beforeCurrent", "nextSnapshot", "transitionSnapshot", "JOURNEY_EVENT", "transitionEvent", "transition", "selectTransition", "currentTransition", "fallbackResult", "nextContext", "effectResultPromise", "isPromiseLike", "effectResult", "target", "isTerminalTarget", "normalizedTimeline", "resolvedTarget", "createEventBuilder", "from", "event", "config", "to", "branches", "branch", "buildTerminalTransition", "tx", "JOURNEY_WILDCARD", "predicate", "createTransitions", "items", "item"]
7
7
  }
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/types/journey.types.ts", "../src/machine-helpers.ts", "../src/persistence.ts", "../src/machine.ts", "../src/transitions.ts"],
4
- "sourcesContent": ["import type { JourneyPersistenceOptions } from \"./persistence.types\";\nimport type { JourneyTransition } from \"./transitions.types\";\n\n/** Terminal outcomes reached when a journey completes or is explicitly terminated. */\nexport type JourneyTerminal = \"COMPLETE\" | \"TERMINATED\";\n\n/** Runtime machine status constants. */\nexport const JOURNEY_STATUS = {\n RUNNING: \"running\",\n COMPLETE: \"complete\",\n TERMINATED: \"terminated\"\n} as const;\n\n/** Union of possible runtime machine statuses. */\nexport type JourneyStatus = (typeof JOURNEY_STATUS)[keyof typeof JOURNEY_STATUS];\n\n/** Wildcard step identifier used by transitions that match from any step. */\nexport const JOURNEY_WILDCARD = \"*\" as const;\n\n/** Built-in event constants that are part of core machine behavior. */\nexport const JOURNEY_EVENT = {\n GO_TO_STEP_BY_ID: \"goToStepById\"\n} as const;\n\n/** Machine event types that are always recognized by core. */\nexport type JourneyBuiltInEvent = (typeof JOURNEY_EVENT)[keyof typeof JOURNEY_EVENT];\n/** Event literal type for the built-in go-to-step command. */\nexport type JourneyGoToStepByIdEventType = typeof JOURNEY_EVENT.GO_TO_STEP_BY_ID;\n/** Wildcard origin marker for transitions. */\nexport type JourneyBuiltInFrom = typeof JOURNEY_WILDCARD;\n/** Default transition event names supported by machine convenience APIs. */\nexport type JourneyDefaultEventType =\n | \"goToNextStep\"\n | \"goToPreviousStep\"\n | \"terminateJourney\"\n | \"completeJourney\";\n\n/** Async lifecycle phases tracked per step while guards/effects run. */\nexport const JOURNEY_ASYNC_PHASE = {\n IDLE: \"idle\",\n EVALUATING_WHEN: \"evaluating-when\",\n RUNNING_EFFECT: \"running-effect\",\n ERROR: \"error\"\n} as const;\n\n/** Union of supported async lifecycle phases. */\nexport type JourneyAsyncPhase = (typeof JOURNEY_ASYNC_PHASE)[keyof typeof JOURNEY_ASYNC_PHASE];\n\n/** Async execution state for a single step. */\nexport type JourneyStepAsyncState = {\n phase: JourneyAsyncPhase;\n eventType: string | null;\n transitionId: string | null;\n error: unknown | null;\n};\n\n/** Aggregated async state for the machine, keyed by step id. */\nexport type JourneyAsyncState<TStepId extends string> = {\n isLoading: boolean;\n byStep: Record<TStepId, JourneyStepAsyncState>;\n};\n\n/** Minimal event shape used across runtime boundaries. */\nexport type JourneyBaseEvent = {\n type: string;\n payload?: unknown;\n};\n\n/** Optional event payload map by event type. */\nexport type JourneyEventPayloadMap<TEventType extends string> = Partial<\n Record<TEventType | JourneyBuiltInEvent, unknown>\n>;\n\n/** Resolves payload type for a specific event type from the provided payload map. */\nexport type JourneyPayloadFor<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TEvent extends TEventType | JourneyBuiltInEvent\n> = TEvent extends keyof TPayloadMap ? TPayloadMap[TEvent] : unknown;\n\n/** Event-type union accepted by machine `.send()`, including built-in convenience events. */\nexport type JourneyMachineEventType<TEventType extends string> =\n | TEventType\n | JourneyDefaultEventType;\n\n/** Payload map available to machine `.send()`, including built-in convenience events. */\nexport type JourneyMachinePayloadMap<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = TPayloadMap & JourneyEventPayloadMap<JourneyDefaultEventType>;\n\ntype JourneyPayloadForDefaultEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TDefaultEvent extends JourneyDefaultEventType\n> = JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TDefaultEvent\n>;\n\n/** Built-in direct-navigation event that targets a specific step id. */\nexport type JourneyGoToEvent<TStepId extends string, TPayload = unknown> = {\n type: JourneyGoToStepByIdEventType;\n stepId: TStepId;\n payload?: TPayload;\n};\n\n/** Event union available to transitions and guards for the declared event type set. */\nexport type JourneyEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<TEventType, TPayloadMap, JourneyGoToStepByIdEventType>\n >\n | {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n }[TEventType];\n\ntype JourneyDefaultMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in JourneyDefaultEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TType\n >;\n };\n}[JourneyDefaultEventType];\n\ntype JourneyCustomMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n}[TEventType];\n\n/** Event union accepted by `JourneyMachine.send`. */\nexport type JourneySendEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n >\n | JourneyDefaultMachineEvent<TEventType, TPayloadMap>\n | JourneyCustomMachineEvent<TEventType, TPayloadMap>;\n\n/**\n * Step definition with optional metadata and optional typed extension fields.\n * Use `TStepExtra` to explicitly model additional per-step properties.\n */\nexport type JourneyStepDefinition<\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n meta?: TStepMeta;\n} & TStepExtra;\n\n/** Serializable runtime snapshot of the journey state. */\nexport type JourneySnapshot<TContext, TStepId extends string, TStepMeta = unknown> = {\n currentStepId: TStepId;\n history: {\n timeline: readonly TStepId[];\n index: number;\n };\n context: TContext;\n visited: Record<TStepId, boolean>;\n stepMeta: Record<TStepId, TStepMeta>;\n status: JourneyStatus;\n async: JourneyAsyncState<TStepId>;\n};\n\n/** Full machine definition used to create a journey machine instance. */\nexport type JourneyDefinition<\n TContext,\n TStepId extends string = string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n initial: TStepId;\n context: TContext;\n steps: Record<TStepId, JourneyStepDefinition<TStepMeta, TStepExtra>>;\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[];\n};\n\n/** Optional machine features (for example, persistence configuration). */\nexport type JourneyMachineOptions<TContext, TStepId extends string, TStepMeta = unknown> = {\n persistence?: JourneyPersistenceOptions<TContext, TStepId, TStepMeta>;\n};\n\n/** Result returned from send/navigation APIs. */\nexport type JourneySendResult<TContext, TStepId extends string, TStepMeta = unknown> = {\n transitioned: boolean;\n transitionId?: string;\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>;\n};\n\n/** Observation events emitted by the machine lifecycle/event stream. */\nexport type JourneyObservationEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> =\n | {\n type: \"transition.start\";\n from: TStepId;\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>;\n timestamp: number;\n }\n | {\n type: \"transition.success\";\n from: TStepId;\n to: TStepId | JourneyTerminal;\n eventType: string;\n transitionId: string | null;\n timestamp: number;\n }\n | {\n type: \"transition.error\";\n from: TStepId;\n eventType: string;\n transitionId: string | null;\n error: unknown;\n timestamp: number;\n }\n | {\n type: \"step.exit\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"step.enter\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.complete\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.close\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"navigation.previous\";\n from: TStepId;\n to: TStepId;\n requestedSteps: number;\n appliedSteps: number;\n timestamp: number;\n }\n | {\n type: \"navigation.lastVisited\";\n from: TStepId;\n to: TStepId;\n timestamp: number;\n }\n | {\n type: \"metadata.updated\";\n stepId: TStepId;\n previous: TStepMeta;\n next: TStepMeta;\n timestamp: number;\n };\n\n/** Runtime machine API for reading snapshots, sending events, and controlling flow. */\nexport type JourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> = {\n getSnapshot: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n send: (\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToNextStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n terminateJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"terminateJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n completeJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"completeJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToPreviousStep: (steps?: number) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToLastVisitedStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n updateContext: (\n updater: (context: TContext) => TContext\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n updateStepMetadata: (\n stepId: TStepId,\n updater: (metadata: TStepMeta) => TStepMeta\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n clearStepError: (stepId?: TStepId) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n resetMachine: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n subscribe: (listener: () => void) => () => void;\n subscribeEvent: (\n listener: (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n ) => () => void;\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_WILDCARD } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyGoToEvent,\n JourneyGoToStepByIdEventType,\n JourneyMachineEventType,\n JourneyMachinePayloadMap,\n JourneyPayloadFor,\n JourneySendEvent,\n JourneySendResult,\n JourneySnapshot,\n JourneyStatus,\n JourneyStepAsyncState,\n JourneyTerminal,\n JourneyTransition\n} from \"./types\";\n\nexport const assertStepExists = <TStepId extends string>(\n steps: Record<TStepId, unknown>,\n stepId: TStepId,\n message: string\n) => {\n if (!(stepId in steps)) {\n throw new Error(message);\n }\n};\n\nexport const normalizeStepCount = (steps?: number): number => {\n if (typeof steps !== \"number\" || !Number.isFinite(steps)) {\n return 1;\n }\n return Math.max(1, Math.trunc(steps));\n};\n\nexport const now = (): number => Date.now();\n\nconst unique = <T>(items: readonly T[]): T[] => [...new Set(items)];\n\nconst normalizeVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n stepIds: readonly TStepId[]\n): Record<TStepId, boolean> =>\n Object.fromEntries(stepIds.map((stepId) => [stepId, visited[stepId] === true])) as Record<\n TStepId,\n boolean\n >;\n\nexport const buildVisitedFromTimeline = <TStepId extends string>(\n timeline: readonly TStepId[],\n stepIds?: readonly TStepId[]\n): Record<TStepId, boolean> => {\n const resolvedStepIds = stepIds ?? unique(timeline);\n const visited = Object.fromEntries(resolvedStepIds.map((stepId) => [stepId, false])) as Record<\n TStepId,\n boolean\n >;\n\n for (const stepId of timeline) {\n visited[stepId] = true;\n }\n\n return visited;\n};\n\nexport const appendVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n current: TStepId\n): Record<TStepId, boolean> => ({\n ...visited,\n [current]: true\n});\n\nexport const isPromiseLike = <T>(value: T | PromiseLike<T>): value is PromiseLike<T> =>\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof (value as { then: unknown }).then === \"function\";\n\nexport const buildIdleStepAsyncState = (): JourneyStepAsyncState => ({\n phase: JOURNEY_ASYNC_PHASE.IDLE,\n eventType: null,\n transitionId: null,\n error: null\n});\n\nexport const buildInitialAsyncState = <TStepId extends string>(\n steps: Record<TStepId, unknown>\n): JourneyAsyncState<TStepId> => {\n const byStep = Object.fromEntries(\n Object.keys(steps).map((stepId) => [stepId, buildIdleStepAsyncState()])\n ) as Record<TStepId, JourneyStepAsyncState>;\n\n return {\n isLoading: false,\n byStep\n };\n};\n\nexport const isGoToStepByIdEvent = <\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n): event is JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n> => event.type === JOURNEY_EVENT.GO_TO_STEP_BY_ID && \"stepId\" in event;\n\nexport const isTerminalTarget = <TStepId extends string>(\n target: TStepId | JourneyTerminal\n): target is JourneyTerminal => target === \"COMPLETE\" || target === \"TERMINATED\";\n\nexport const validateJourneyTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n steps: Record<TStepId, unknown>\n) => {\n const stepRegistry = steps as Record<string, unknown>;\n\n for (const [index, transition] of transitions.entries()) {\n if (!transition || typeof transition !== \"object\") {\n throw new Error(`Journey transition at index ${index} must be an object.`);\n }\n\n if (typeof transition.from !== \"string\" || typeof transition.event !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define string \"from\" and \"event\".`\n );\n }\n\n if (transition.from !== JOURNEY_WILDCARD && !(transition.from in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} references unknown from step \"${transition.from}\".`\n );\n }\n\n if (transition.event === \"completeJourney\" || transition.event === \"terminateJourney\") {\n if (\"to\" in transition && transition.to !== undefined) {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" cannot define \"to\".`\n );\n }\n continue;\n }\n\n if (typeof transition.to !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" must define string \"to\".`\n );\n }\n\n if (!isTerminalTarget(transition.to) && !(transition.to in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} points to unknown step \"${transition.to}\".`\n );\n }\n }\n};\n\nexport const buildSendResult = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n transitioned: boolean,\n transitionId?: string\n): JourneySendResult<TContext, TStepId, TStepMeta> =>\n transitionId ? { transitioned, transitionId, snapshot } : { transitioned, snapshot };\n\nexport const buildSnapshot = <TContext, TStepId extends string, TStepMeta>(\n timeline: readonly TStepId[],\n index: number,\n context: TContext,\n status: JourneyStatus,\n asyncState: JourneyAsyncState<TStepId>,\n stepMeta: Record<TStepId, TStepMeta>,\n visited?: Record<TStepId, boolean>\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n if (timeline.length === 0) {\n throw new Error(\"Journey timeline cannot be empty.\");\n }\n const safeIndex = Math.max(0, Math.min(Math.trunc(index), timeline.length - 1));\n const currentStepId = timeline[safeIndex] as TStepId;\n const stepIds = Object.keys(stepMeta) as TStepId[];\n return {\n status,\n currentStepId,\n history: {\n timeline: [...timeline],\n index: safeIndex\n },\n context,\n visited: visited\n ? normalizeVisited(visited, stepIds)\n : buildVisitedFromTimeline(timeline, stepIds),\n stepMeta: { ...stepMeta },\n async: asyncState\n };\n};\n\nexport const selectTransition = async <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TStepMeta\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n event: JourneyEvent<TStepId, TEventType, TPayloadMap>,\n hooks?: {\n onAsyncGuardStart?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardSuccess?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardError?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n error: unknown\n ) => void;\n }\n): Promise<JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> | null> => {\n for (const transition of transitions) {\n const fromMatches =\n transition.from === JOURNEY_WILDCARD || transition.from === snapshot.currentStepId;\n const eventMatches = transition.event === event.type;\n\n if (!fromMatches || !eventMatches) {\n continue;\n }\n\n if (!transition.when) {\n return transition;\n }\n\n const guardResult = transition.when({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event\n });\n const asyncGuard = isPromiseLike(guardResult);\n if (asyncGuard) {\n hooks?.onAsyncGuardStart?.(transition);\n }\n\n let allowed: boolean;\n try {\n allowed = await guardResult;\n } catch (error) {\n if (asyncGuard) {\n hooks?.onAsyncGuardError?.(transition, error);\n }\n throw error;\n }\n\n if (asyncGuard) {\n hooks?.onAsyncGuardSuccess?.(transition);\n }\n\n if (allowed) {\n return transition;\n }\n }\n\n return null;\n};\n\nexport const transitionSnapshot = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n nextCurrent: TStepId,\n nextContext: TContext\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const baseTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n let nextTimeline = baseTimeline;\n if (nextCurrent !== snapshot.currentStepId) {\n nextTimeline = [...baseTimeline, nextCurrent];\n }\n\n const nextIndex = nextTimeline.length - 1;\n const visited = appendVisited(snapshot.visited, nextCurrent);\n\n return buildSnapshot(\n nextTimeline,\n nextIndex,\n nextContext,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n visited\n );\n};\n", "import { JOURNEY_STATUS } from \"./types/journey.types\";\nimport type {\n JourneyPersistedSnapshot,\n JourneyPersistedState,\n JourneyStorage,\n ResolvedPersistence\n} from \"./types/persistence.types\";\nimport type { JourneyMachineOptions, JourneySnapshot, JourneyStatus } from \"./types/journey.types\";\nimport { buildInitialAsyncState, buildSnapshot, buildVisitedFromTimeline } from \"./machine-helpers\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst isStatusValue = (value: unknown): value is JourneyStatus =>\n value === JOURNEY_STATUS.RUNNING ||\n value === JOURNEY_STATUS.COMPLETE ||\n value === JOURNEY_STATUS.TERMINATED;\n\nconst resolveDefaultStorage = (): JourneyStorage | null => {\n const localStorageCandidate = (globalThis as { localStorage?: Partial<JourneyStorage> })\n .localStorage;\n\n if (\n !localStorageCandidate ||\n typeof localStorageCandidate.getItem !== \"function\" ||\n typeof localStorageCandidate.setItem !== \"function\" ||\n typeof localStorageCandidate.removeItem !== \"function\"\n ) {\n return null;\n }\n\n return localStorageCandidate as JourneyStorage;\n};\n\nconst resolvePersistence = <TContext, TStepId extends string, TStepMeta>(\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>[\"persistence\"]\n): ResolvedPersistence<TContext, TStepId, TStepMeta> | null => {\n if (!options) {\n return null;\n }\n\n const storage = options.storage ?? resolveDefaultStorage();\n if (!storage) {\n return null;\n }\n\n return {\n key: options.key,\n storage,\n version: options.version ?? 1,\n clearOnReset: options.clearOnReset ?? true,\n serialize: options.serialize ?? JSON.stringify,\n deserialize: options.deserialize ?? JSON.parse,\n ...(options.migrate ? { migrate: options.migrate } : {}),\n ...(options.onError ? { onError: options.onError } : {})\n };\n};\n\nconst coercePersistedSnapshot = <TContext, TStepId extends string, TStepMeta>(\n value: unknown,\n steps: Record<TStepId, unknown>,\n fallbackContext: TContext,\n fallbackStepMeta: Record<TStepId, TStepMeta>\n): {\n snapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta>;\n needsRewrite: boolean;\n} | null => {\n if (!isRecord(value)) {\n return null;\n }\n\n let needsRewrite = false;\n\n const rawHistory = isRecord(value.history) ? value.history : null;\n if (!rawHistory) {\n needsRewrite = true;\n }\n\n const rawTimeline = rawHistory?.timeline ?? value.timeline;\n const timeline = Array.isArray(rawTimeline)\n ? (rawTimeline.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[])\n : [];\n\n const currentStepIdValue =\n typeof value.currentStepId === \"string\" && value.currentStepId in steps\n ? (value.currentStepId as TStepId)\n : typeof value.current === \"string\" && value.current in steps\n ? (value.current as TStepId)\n : null;\n\n if (timeline.length === 0) {\n if (!currentStepIdValue) {\n return null;\n }\n timeline.push(currentStepIdValue);\n needsRewrite = true;\n }\n\n let index = timeline.length - 1;\n const rawIndex = rawHistory?.index ?? value.index;\n if (typeof rawIndex === \"number\" && Number.isFinite(rawIndex)) {\n index = Math.max(0, Math.min(Math.trunc(rawIndex), timeline.length - 1));\n if (index !== rawIndex) {\n needsRewrite = true;\n }\n } else if (currentStepIdValue) {\n const inferredIndex = timeline.lastIndexOf(currentStepIdValue);\n if (inferredIndex >= 0) {\n index = inferredIndex;\n needsRewrite = true;\n }\n }\n\n const status = isStatusValue(value.status) ? value.status : JOURNEY_STATUS.RUNNING;\n if (!isStatusValue(value.status)) {\n needsRewrite = true;\n }\n\n const stepIds = Object.keys(steps) as TStepId[];\n const visitedSource = value.visited;\n const visitedFromRecord = isRecord(visitedSource)\n ? (Object.fromEntries(\n stepIds.map((stepId) => [stepId, visitedSource[stepId] === true])\n ) as Record<TStepId, boolean>)\n : null;\n const visitedFromArray = Array.isArray(visitedSource)\n ? buildVisitedFromTimeline(\n visitedSource.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[],\n stepIds\n )\n : null;\n\n let visited = buildVisitedFromTimeline(timeline, stepIds);\n if (visitedFromRecord) {\n const visitedRecord = visitedSource as Record<string, unknown>;\n visited = visitedFromRecord;\n const hasMissingOrInvalidStep = stepIds.some(\n (stepId) => typeof visitedRecord[stepId] !== \"boolean\"\n );\n if (hasMissingOrInvalidStep) {\n needsRewrite = true;\n }\n } else if (visitedFromArray) {\n visited = visitedFromArray;\n needsRewrite = true;\n } else {\n needsRewrite = true;\n }\n\n const rawStepMeta = isRecord(value.stepMeta) ? value.stepMeta : null;\n if (!rawStepMeta) {\n needsRewrite = true;\n }\n\n const stepMeta = Object.fromEntries(\n Object.keys(steps).map((stepId) => {\n const typedStepId = stepId as TStepId;\n const rawValue = rawStepMeta ? rawStepMeta[stepId] : undefined;\n if (rawValue === undefined) {\n return [typedStepId, fallbackStepMeta[typedStepId]];\n }\n return [typedStepId, rawValue as TStepMeta];\n })\n ) as Record<TStepId, TStepMeta>;\n\n return {\n snapshot: {\n currentStepId: timeline[index] as TStepId,\n history: {\n timeline,\n index\n },\n context: (\"context\" in value ? value.context : fallbackContext) as TContext,\n status,\n visited,\n stepMeta\n },\n needsRewrite\n };\n};\n\n/**\n * Creates a persistence controller for snapshots, including hydration,\n * serialization, and storage error handling.\n */\nexport const createPersistenceController = <TContext, TStepId extends string, TStepMeta>(args: {\n initial: TStepId;\n context: TContext;\n stepMeta: Record<TStepId, TStepMeta>;\n steps: Record<TStepId, unknown>;\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>;\n}) => {\n const { initial, context, stepMeta, steps, options } = args;\n const persistence = resolvePersistence(options?.persistence);\n\n const reportPersistenceError = (error: unknown) => {\n persistence?.onError?.(error);\n };\n\n const persistSnapshot = (snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>) => {\n if (!persistence) {\n return;\n }\n\n try {\n const persistedState: JourneyPersistedState<TContext, TStepId, TStepMeta> = {\n version: persistence.version,\n snapshot: {\n currentStepId: snapshot.currentStepId,\n history: {\n timeline: [...snapshot.history.timeline],\n index: snapshot.history.index\n },\n context: snapshot.context,\n status: snapshot.status,\n visited: { ...snapshot.visited },\n stepMeta: { ...snapshot.stepMeta }\n }\n };\n persistence.storage.setItem(persistence.key, persistence.serialize(persistedState));\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const removePersistedSnapshot = () => {\n if (!persistence) {\n return;\n }\n\n try {\n persistence.storage.removeItem(persistence.key);\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const hydrateSnapshot = (): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const initialSnapshot = buildSnapshot(\n [initial],\n 0,\n context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(steps),\n stepMeta\n );\n if (!persistence) {\n return initialSnapshot;\n }\n\n try {\n const rawPersisted = persistence.storage.getItem(persistence.key);\n if (!rawPersisted) {\n return initialSnapshot;\n }\n\n const parsed = persistence.deserialize(rawPersisted);\n if (!isRecord(parsed)) {\n return initialSnapshot;\n }\n\n const persistedVersion = parsed.version;\n if (typeof persistedVersion !== \"number\") {\n return initialSnapshot;\n }\n\n let persistedSnapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta> | null = null;\n let shouldRewritePersisted = false;\n\n if (persistedVersion === persistence.version) {\n const coerced = coercePersistedSnapshot(parsed.snapshot, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = Boolean(coerced?.needsRewrite);\n } else if (persistence.migrate) {\n const migrated = persistence.migrate(parsed.snapshot, persistedVersion);\n const coerced = coercePersistedSnapshot(migrated, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = persistedSnapshot !== null;\n }\n\n if (!persistedSnapshot) {\n return initialSnapshot;\n }\n\n const hydratedSnapshot = buildSnapshot(\n persistedSnapshot.history.timeline,\n persistedSnapshot.history.index,\n persistedSnapshot.context,\n persistedSnapshot.status,\n buildInitialAsyncState(steps),\n persistedSnapshot.stepMeta,\n persistedSnapshot.visited\n );\n\n if (shouldRewritePersisted) {\n persistSnapshot(hydratedSnapshot);\n }\n\n return hydratedSnapshot;\n } catch (error) {\n reportPersistenceError(error);\n return initialSnapshot;\n }\n };\n\n return {\n clearOnReset: persistence?.clearOnReset ?? true,\n hydrateSnapshot,\n persistSnapshot,\n removePersistedSnapshot\n };\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_STATUS } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyAsyncPhase,\n JourneyDefaultEventType,\n JourneyDefinition,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyMachine,\n JourneyMachineOptions,\n JourneyObservationEvent,\n JourneySendResult,\n JourneyStepDefinition,\n JourneyTransition,\n JourneyTerminal\n} from \"./types\";\nimport {\n assertStepExists,\n buildIdleStepAsyncState,\n buildInitialAsyncState,\n buildSendResult,\n buildSnapshot,\n isGoToStepByIdEvent,\n isPromiseLike,\n isTerminalTarget,\n normalizeStepCount,\n now,\n selectTransition,\n transitionSnapshot,\n validateJourneyTransitions\n} from \"./machine-helpers\";\nimport { createPersistenceController } from \"./persistence\";\n\n/**\n * Creates a journey machine from a journey definition.\n * Validates steps/transitions, hydrates persisted state (if configured),\n * and returns an API for sending events and reading snapshots.\n */\nexport function createJourneyMachine<\n TContext,\n TStepMeta = unknown,\n TSteps extends Record<string, JourneyStepDefinition<TStepMeta>> = Record<\n string,\n JourneyStepDefinition<TStepMeta>\n >,\n TPayloadMap extends JourneyEventPayloadMap<JourneyDefaultEventType> = Record<never, never>\n>(\n journey: {\n initial: Extract<keyof TSteps, string>;\n context: TContext;\n steps: TSteps;\n transitions: readonly JourneyTransition<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap\n >[];\n },\n options?: JourneyMachineOptions<TContext, Extract<keyof TSteps, string>, TStepMeta>\n): JourneyMachine<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap,\n TStepMeta\n>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> {\n if (!journey.steps || typeof journey.steps !== \"object\") {\n throw new Error(\"Journey steps must be a record object.\");\n }\n\n if (!Array.isArray(journey.transitions)) {\n throw new Error(\"Journey transitions must be an array.\");\n }\n\n assertStepExists(\n journey.steps,\n journey.initial,\n `Journey initial step \"${journey.initial}\" does not exist in steps registry.`\n );\n\n validateJourneyTransitions(journey.transitions, journey.steps);\n\n const buildStepMeta = (): Record<TStepId, TStepMeta> => {\n const stepMeta = {} as Record<TStepId, TStepMeta>;\n for (const stepId of Object.keys(journey.steps) as TStepId[]) {\n stepMeta[stepId] = journey.steps[stepId].meta as TStepMeta;\n }\n return stepMeta;\n };\n\n const { clearOnReset, hydrateSnapshot, persistSnapshot, removePersistedSnapshot } =\n createPersistenceController({\n initial: journey.initial,\n context: journey.context,\n stepMeta: buildStepMeta(),\n steps: journey.steps,\n ...(options ? { options } : {})\n });\n\n let snapshot = hydrateSnapshot();\n snapshot = {\n ...snapshot,\n async: buildInitialAsyncState(journey.steps)\n };\n\n const listeners = new Set<() => void>();\n const eventListeners = new Set<\n (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n >();\n let actionQueue: Promise<void> = Promise.resolve();\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const emit = (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => {\n for (const listener of eventListeners) {\n listener(event);\n }\n };\n\n const queue = <T>(runner: () => Promise<T>): Promise<T> => {\n const resultPromise = actionQueue.then(runner, runner);\n actionQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n return resultPromise;\n };\n\n const isAsyncLoadingPhase = (phase: JourneyAsyncPhase): boolean =>\n phase === JOURNEY_ASYNC_PHASE.EVALUATING_WHEN || phase === JOURNEY_ASYNC_PHASE.RUNNING_EFFECT;\n\n const updateStepAsync = (\n stepId: TStepId,\n updater: (\n current: JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => {\n const current = snapshot.async.byStep[stepId] ?? buildIdleStepAsyncState();\n const next = updater(current);\n if (\n current.phase === next.phase &&\n current.eventType === next.eventType &&\n current.transitionId === next.transitionId &&\n current.error === next.error\n ) {\n return;\n }\n\n const nextByStep = {\n ...snapshot.async.byStep,\n [stepId]: next\n };\n const isLoading = Object.values(nextByStep).some((state) => isAsyncLoadingPhase(state.phase));\n snapshot = {\n ...snapshot,\n async: {\n isLoading,\n byStep: nextByStep\n }\n };\n notify();\n };\n\n const setStepLoading = (\n stepId: TStepId,\n phase: JourneyAsyncPhase,\n eventType: string,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase,\n eventType,\n transitionId: transitionId ?? null,\n error: null\n }));\n };\n\n const setStepIdle = (stepId: TStepId) => {\n updateStepAsync(stepId, () => buildIdleStepAsyncState());\n };\n\n const setStepError = (\n stepId: TStepId,\n eventType: string,\n error: unknown,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase: JOURNEY_ASYNC_PHASE.ERROR,\n eventType,\n transitionId: transitionId ?? null,\n error\n }));\n };\n\n const applyPreviousNavigation = (\n requestedSteps?: number,\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const steps = normalizeStepCount(requestedSteps);\n if (snapshot.history.index === 0) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n const nextIndex = Math.max(0, snapshot.history.index - steps);\n const appliedSteps = snapshot.history.index - nextIndex;\n if (appliedSteps <= 0) {\n return buildSendResult(snapshot, false);\n }\n\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n nextIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"navigation.previous\",\n from,\n to: snapshot.currentStepId,\n requestedSteps: steps,\n appliedSteps,\n timestamp: now()\n });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const applyLastVisitedNavigation = (\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const targetIndex = snapshot.history.timeline.length - 1;\n if (snapshot.history.index >= targetIndex) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n targetIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({ type: \"navigation.lastVisited\", from, to: snapshot.currentStepId, timestamp: now() });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const machine: JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> = {\n getSnapshot: () => snapshot,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n subscribeEvent: (listener) => {\n eventListeners.add(listener);\n return () => {\n eventListeners.delete(listener);\n };\n },\n resetMachine: () => {\n snapshot = buildSnapshot(\n [journey.initial],\n 0,\n journey.context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(journey.steps),\n buildStepMeta()\n );\n if (clearOnReset) {\n removePersistedSnapshot();\n } else {\n persistSnapshot(snapshot);\n }\n notify();\n return snapshot;\n },\n updateContext: (updater) => {\n snapshot = {\n ...snapshot,\n context: updater(snapshot.context)\n };\n persistSnapshot(snapshot);\n notify();\n return snapshot;\n },\n updateStepMetadata: (stepId, updater) => {\n if (!(stepId in journey.steps)) {\n return snapshot;\n }\n\n const previousMeta = snapshot.stepMeta[stepId];\n const nextMeta = updater(previousMeta);\n if (Object.is(previousMeta, nextMeta)) {\n return snapshot;\n }\n\n snapshot = {\n ...snapshot,\n stepMeta: {\n ...snapshot.stepMeta,\n [stepId]: nextMeta\n }\n };\n persistSnapshot(snapshot);\n notify();\n emit({\n type: \"metadata.updated\",\n stepId,\n previous: previousMeta,\n next: nextMeta,\n timestamp: now()\n });\n return snapshot;\n },\n clearStepError: (stepId) => {\n const resolvedStep = stepId ?? snapshot.currentStepId;\n if (!(resolvedStep in journey.steps)) {\n return snapshot;\n }\n\n setStepIdle(resolvedStep);\n return snapshot;\n },\n goToPreviousStep: (steps) =>\n queue(async () => {\n const result = applyPreviousNavigation(steps, \"goToPreviousStep\");\n return result;\n }),\n goToLastVisitedStep: () =>\n queue(async () => {\n const result = applyLastVisitedNavigation(\"goToLastVisitedStep\");\n return result;\n }),\n goToNextStep: () => machine.send({ type: \"goToNextStep\" }),\n terminateJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"terminateJourney\" })\n : machine.send({ type: \"terminateJourney\", payload }),\n completeJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"completeJourney\" })\n : machine.send({ type: \"completeJourney\", payload }),\n send: (event) =>\n queue(async () => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const fromStep = snapshot.currentStepId;\n\n if (isGoToStepByIdEvent(event)) {\n assertStepExists(\n journey.steps,\n event.stepId,\n `Cannot goToStepById unknown step \"${event.stepId}\".`\n );\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n setStepIdle(fromStep);\n\n const beforeCurrent = snapshot.currentStepId;\n const nextSnapshot = transitionSnapshot(snapshot, event.stepId, snapshot.context);\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n\n snapshot = nextSnapshot;\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n transitionId: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n timestamp: now()\n });\n\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, JOURNEY_EVENT.GO_TO_STEP_BY_ID);\n }\n\n const transitionEvent = event as JourneyEvent<TStepId, TEventType, TPayloadMap>;\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n\n let transition;\n try {\n transition = await selectTransition(journey.transitions, snapshot, transitionEvent, {\n onAsyncGuardStart: (currentTransition) => {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.EVALUATING_WHEN,\n transitionEvent.type,\n currentTransition.id\n );\n },\n onAsyncGuardSuccess: () => {\n setStepIdle(fromStep);\n },\n onAsyncGuardError: (currentTransition, error) => {\n setStepError(fromStep, transitionEvent.type, error, currentTransition.id);\n }\n });\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (!transition) {\n if (event.type === \"goToPreviousStep\" || event.type === \"back\") {\n const fallbackResult = applyPreviousNavigation(1, event.type);\n if (fallbackResult.transitioned) {\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: fallbackResult.snapshot.currentStepId,\n eventType: event.type,\n transitionId: null,\n timestamp: now()\n });\n }\n return fallbackResult;\n }\n\n return buildSendResult(snapshot, false);\n }\n\n let nextContext = snapshot.context;\n if (transition.effect) {\n const effectResultPromise = transition.effect({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event: transitionEvent\n });\n if (isPromiseLike(effectResultPromise)) {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.RUNNING_EFFECT,\n transitionEvent.type,\n transition.id\n );\n }\n\n let effectResult: TContext | void;\n try {\n effectResult = await effectResultPromise;\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error, transition.id);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (effectResult !== undefined) {\n nextContext = effectResult;\n }\n }\n\n setStepIdle(fromStep);\n\n const target: TStepId | JourneyTerminal =\n transition.event === \"completeJourney\"\n ? \"COMPLETE\"\n : transition.event === \"terminateJourney\"\n ? \"TERMINATED\"\n : (transition.to as TStepId | JourneyTerminal);\n\n if (isTerminalTarget(target)) {\n const normalizedTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n snapshot = {\n ...snapshot,\n history: {\n timeline: normalizedTimeline,\n index: normalizedTimeline.length - 1\n },\n context: nextContext,\n status: target === \"COMPLETE\" ? JOURNEY_STATUS.COMPLETE : JOURNEY_STATUS.TERMINATED\n };\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: target,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n emit({\n type: target === \"COMPLETE\" ? \"journey.complete\" : \"journey.close\",\n stepId: snapshot.currentStepId,\n timestamp: now()\n });\n\n return buildSendResult(snapshot, true, transition.id);\n }\n\n const resolvedTarget = target;\n\n assertStepExists(\n journey.steps,\n resolvedTarget,\n `Transition points to unknown step \"${resolvedTarget}\".`\n );\n\n const beforeCurrent = snapshot.currentStepId;\n if (beforeCurrent !== resolvedTarget) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n snapshot = transitionSnapshot(snapshot, resolvedTarget, nextContext);\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n if (beforeCurrent !== snapshot.currentStepId) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, transition.id);\n })\n };\n\n return machine;\n}\n", "import { JOURNEY_WILDCARD } from \"./types/journey.types\";\nimport type { JourneyEventPayloadMap } from \"./types/journey.types\";\nimport type {\n EventBuilder,\n JourneyEventTransition,\n JourneyTransition,\n JourneyTransitionArgs,\n JourneyTransitionTarget,\n TransitionBranch,\n TransitionConfig\n} from \"./types/transitions.types\";\n\nconst createEventBuilder = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType\n): EventBuilder<TContext, TStepId, TEventType, TPayloadMap> => {\n if (event === \"completeJourney\") {\n return {\n complete: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"completeJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n if (event === \"terminateJourney\") {\n return {\n terminate: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n return {\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">,\n to\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n choose: (\n ...branches: Array<TransitionBranch<TContext, TStepId, TEventType, TPayloadMap>>\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n branches.map(\n (branch) =>\n ({\n ...branch,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n )\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n};\n\nconst buildTerminalTransition = <\n TContext,\n TStepId extends string,\n TEventType extends \"completeJourney\" | \"terminateJourney\"\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType,\n config: TransitionConfig<TContext, TStepId, TEventType, Record<never, never>> = {}\n): JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>> =>\n ({\n ...config,\n from,\n event\n }) as JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>>;\n\nexport const tx = {\n from: <TStepId extends string, TContext = unknown>(from: TStepId) => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(from, event),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"terminateJourney\", config)\n }),\n any: <TContext = unknown, TStepId extends string = string>() => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(\n JOURNEY_WILDCARD,\n event\n ),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"terminateJourney\", config)\n }),\n when: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >(\n predicate: (\n args: JourneyTransitionArgs<TContext, TStepId, TEventType, TPayloadMap>\n ) => boolean | Promise<boolean>\n ) => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to,\n when: predicate\n })\n }),\n otherwise: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >() => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to\n })\n })\n};\n\nexport const createTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n ...items: Array<\n | JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n | readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[]\n >\n): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n items.flatMap((item) => (Array.isArray(item) ? [...item] : [item]));\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { JourneyPersistenceOptions } from \"./persistence.types\";\nimport type { JourneyTransition } from \"./transitions.types\";\n\n/** Terminal outcomes reached when a journey completes or is explicitly terminated. */\nexport type JourneyTerminal = \"COMPLETE\" | \"TERMINATED\";\n\n/** Runtime machine status constants. */\nexport const JOURNEY_STATUS = {\n RUNNING: \"running\",\n COMPLETE: \"complete\",\n TERMINATED: \"terminated\"\n} as const;\n\n/** Union of possible runtime machine statuses. */\nexport type JourneyStatus = (typeof JOURNEY_STATUS)[keyof typeof JOURNEY_STATUS];\n\n/** Wildcard step identifier used by transitions that match from any step. */\nexport const JOURNEY_WILDCARD = \"*\" as const;\n\n/** Built-in event constants that are part of core machine behavior. */\nexport const JOURNEY_EVENT = {\n GO_TO_STEP_BY_ID: \"goToStepById\"\n} as const;\n\n/** Machine event types that are always recognized by core. */\nexport type JourneyBuiltInEvent = (typeof JOURNEY_EVENT)[keyof typeof JOURNEY_EVENT];\n/** Event literal type for the built-in go-to-step command. */\nexport type JourneyGoToStepByIdEventType = typeof JOURNEY_EVENT.GO_TO_STEP_BY_ID;\n/** Wildcard origin marker for transitions. */\nexport type JourneyBuiltInFrom = typeof JOURNEY_WILDCARD;\n/** Default transition event names supported by machine convenience APIs. */\nexport type JourneyDefaultEventType =\n | \"goToNextStep\"\n | \"goToPreviousStep\"\n | \"terminateJourney\"\n | \"completeJourney\";\n\n/** Async lifecycle phases tracked per step while guards/effects run. */\nexport const JOURNEY_ASYNC_PHASE = {\n IDLE: \"idle\",\n EVALUATING_WHEN: \"evaluating-when\",\n RUNNING_EFFECT: \"running-effect\",\n ERROR: \"error\"\n} as const;\n\n/** Union of supported async lifecycle phases. */\nexport type JourneyAsyncPhase = (typeof JOURNEY_ASYNC_PHASE)[keyof typeof JOURNEY_ASYNC_PHASE];\n\n/** Async execution state for a single step. */\nexport type JourneyStepAsyncState = {\n phase: JourneyAsyncPhase;\n eventType: string | null;\n transitionId: string | null;\n error: unknown | null;\n};\n\n/** Aggregated async state for the machine, keyed by step id. */\nexport type JourneyAsyncState<TStepId extends string> = {\n isLoading: boolean;\n byStep: Record<TStepId, JourneyStepAsyncState>;\n};\n\n/** Minimal event shape used across runtime boundaries. */\nexport type JourneyBaseEvent = {\n type: string;\n payload?: unknown;\n};\n\n/** Optional event payload map by event type. */\nexport type JourneyEventPayloadMap<TEventType extends string> = Partial<\n Record<TEventType | JourneyBuiltInEvent, unknown>\n>;\n\n/** Resolves payload type for a specific event type from the provided payload map. */\nexport type JourneyPayloadFor<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TEvent extends TEventType | JourneyBuiltInEvent\n> = TEvent extends keyof TPayloadMap ? TPayloadMap[TEvent] : unknown;\n\n/** Event-type union accepted by machine `.send()`, including built-in convenience events. */\nexport type JourneyMachineEventType<TEventType extends string> =\n | TEventType\n | JourneyDefaultEventType;\n\n/** Payload map available to machine `.send()`, including built-in convenience events. */\nexport type JourneyMachinePayloadMap<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = TPayloadMap & JourneyEventPayloadMap<JourneyDefaultEventType>;\n\ntype JourneyPayloadForDefaultEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TDefaultEvent extends JourneyDefaultEventType\n> = JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TDefaultEvent\n>;\n\n/** Built-in direct-navigation event that targets a specific step id. */\nexport type JourneyGoToEvent<TStepId extends string, TPayload = unknown> = {\n type: JourneyGoToStepByIdEventType;\n stepId: TStepId;\n payload?: TPayload;\n};\n\n/** Event union available to transitions and guards for the declared event type set. */\nexport type JourneyEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<TEventType, TPayloadMap, JourneyGoToStepByIdEventType>\n >\n | {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n }[TEventType];\n\ntype JourneyDefaultMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in JourneyDefaultEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n TType\n >;\n };\n}[JourneyDefaultEventType];\n\ntype JourneyCustomMachineEvent<\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n> = {\n [TType in TEventType]: {\n type: TType;\n payload?: JourneyPayloadFor<TEventType, TPayloadMap, TType>;\n };\n}[TEventType];\n\n/** Event union accepted by `JourneyMachine.send`. */\nexport type JourneySendEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>\n> =\n | JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n >\n | JourneyDefaultMachineEvent<TEventType, TPayloadMap>\n | JourneyCustomMachineEvent<TEventType, TPayloadMap>;\n\n/**\n * Step definition with optional metadata and optional typed extension fields.\n * Use `TStepExtra` to explicitly model additional per-step properties.\n */\nexport type JourneyStepDefinition<\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n meta?: TStepMeta;\n} & TStepExtra;\n\n/** Serializable runtime snapshot of the journey state. */\nexport type JourneySnapshot<TContext, TStepId extends string, TStepMeta = unknown> = {\n currentStepId: TStepId;\n history: {\n timeline: readonly TStepId[];\n index: number;\n };\n context: TContext;\n visited: Record<TStepId, boolean>;\n stepMeta: Record<TStepId, TStepMeta>;\n status: JourneyStatus;\n async: JourneyAsyncState<TStepId>;\n};\n\n/** Full machine definition used to create a journey machine instance. */\nexport type JourneyDefinition<\n TContext,\n TStepId extends string = string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown,\n TStepExtra extends object = Record<never, never>\n> = {\n initial: TStepId;\n context: TContext;\n steps: Record<TStepId, JourneyStepDefinition<TStepMeta, TStepExtra>>;\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[];\n};\n\n/** Optional machine features (for example, persistence configuration). */\nexport type JourneyMachineOptions<TContext, TStepId extends string, TStepMeta = unknown> = {\n persistence?: JourneyPersistenceOptions<TContext, TStepId, TStepMeta>;\n};\n\n/** Result returned from send/navigation APIs. */\nexport type JourneySendResult<TContext, TStepId extends string, TStepMeta = unknown> = {\n transitioned: boolean;\n transitionId?: string;\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>;\n};\n\n/** Observation events emitted by the machine lifecycle/event stream. */\nexport type JourneyObservationEvent<\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> =\n | {\n type: \"transition.start\";\n from: TStepId;\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>;\n timestamp: number;\n }\n | {\n type: \"transition.success\";\n from: TStepId;\n to: TStepId | JourneyTerminal;\n eventType: string;\n transitionId: string | null;\n timestamp: number;\n }\n | {\n type: \"transition.error\";\n from: TStepId;\n eventType: string;\n transitionId: string | null;\n error: unknown;\n timestamp: number;\n }\n | {\n type: \"step.exit\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"step.enter\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.complete\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"journey.close\";\n stepId: TStepId;\n timestamp: number;\n }\n | {\n type: \"navigation.previous\";\n from: TStepId;\n to: TStepId;\n requestedSteps: number;\n appliedSteps: number;\n timestamp: number;\n }\n | {\n type: \"navigation.lastVisited\";\n from: TStepId;\n to: TStepId;\n timestamp: number;\n }\n | {\n type: \"metadata.updated\";\n stepId: TStepId;\n previous: TStepMeta;\n next: TStepMeta;\n timestamp: number;\n };\n\n/** Runtime machine API for reading snapshots, sending events, and controlling flow. */\nexport type JourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n> = {\n getSnapshot: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n send: (\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToNextStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n terminateJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"terminateJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n completeJourney: (\n payload?: JourneyPayloadForDefaultEvent<TEventType, TPayloadMap, \"completeJourney\">\n ) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToPreviousStep: (steps?: number) => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n goToLastVisitedStep: () => Promise<JourneySendResult<TContext, TStepId, TStepMeta>>;\n updateContext: (\n updater: (context: TContext) => TContext\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n updateStepMetadata: (\n stepId: TStepId,\n updater: (metadata: TStepMeta) => TStepMeta\n ) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n clearStepError: (stepId?: TStepId) => JourneySnapshot<TContext, TStepId, TStepMeta>;\n resetMachine: () => JourneySnapshot<TContext, TStepId, TStepMeta>;\n subscribe: (listener: () => void) => () => void;\n subscribeEvent: (\n listener: (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n ) => () => void;\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_WILDCARD } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyGoToEvent,\n JourneyGoToStepByIdEventType,\n JourneyMachineEventType,\n JourneyMachinePayloadMap,\n JourneyPayloadFor,\n JourneySendEvent,\n JourneySendResult,\n JourneySnapshot,\n JourneyStatus,\n JourneyStepAsyncState,\n JourneyTerminal,\n JourneyTransition\n} from \"./types\";\n\nexport const assertStepExists = <TStepId extends string>(\n steps: Record<TStepId, unknown>,\n stepId: TStepId,\n message: string\n) => {\n if (!(stepId in steps)) {\n throw new Error(message);\n }\n};\n\nexport const normalizeStepCount = (steps?: number): number => {\n if (typeof steps !== \"number\" || !Number.isFinite(steps)) {\n return 1;\n }\n return Math.max(1, Math.trunc(steps));\n};\n\nexport const now = (): number => Date.now();\n\nconst unique = <T>(items: readonly T[]): T[] => [...new Set(items)];\n\nconst normalizeVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n stepIds: readonly TStepId[]\n): Record<TStepId, boolean> =>\n Object.fromEntries(stepIds.map((stepId) => [stepId, visited[stepId] === true])) as Record<\n TStepId,\n boolean\n >;\n\nexport const buildVisitedFromTimeline = <TStepId extends string>(\n timeline: readonly TStepId[],\n stepIds?: readonly TStepId[]\n): Record<TStepId, boolean> => {\n const resolvedStepIds = stepIds ?? unique(timeline);\n const visited = Object.fromEntries(resolvedStepIds.map((stepId) => [stepId, false])) as Record<\n TStepId,\n boolean\n >;\n\n for (const stepId of timeline) {\n visited[stepId] = true;\n }\n\n return visited;\n};\n\nexport const appendVisited = <TStepId extends string>(\n visited: Record<TStepId, boolean>,\n current: TStepId\n): Record<TStepId, boolean> => ({\n ...visited,\n [current]: true\n});\n\nexport const isPromiseLike = <T>(value: T | PromiseLike<T>): value is PromiseLike<T> =>\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof (value as { then: unknown }).then === \"function\";\n\nexport const buildIdleStepAsyncState = (): JourneyStepAsyncState => ({\n phase: JOURNEY_ASYNC_PHASE.IDLE,\n eventType: null,\n transitionId: null,\n error: null\n});\n\nexport const buildInitialAsyncState = <TStepId extends string>(\n steps: Record<TStepId, unknown>\n): JourneyAsyncState<TStepId> => {\n const byStep = Object.fromEntries(\n Object.keys(steps).map((stepId) => [stepId, buildIdleStepAsyncState()])\n ) as Record<TStepId, JourneyStepAsyncState>;\n\n return {\n isLoading: false,\n byStep\n };\n};\n\nexport const isGoToStepByIdEvent = <\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n event: JourneySendEvent<TStepId, TEventType, TPayloadMap>\n): event is JourneyGoToEvent<\n TStepId,\n JourneyPayloadFor<\n JourneyMachineEventType<TEventType>,\n JourneyMachinePayloadMap<TEventType, TPayloadMap>,\n JourneyGoToStepByIdEventType\n >\n> => event.type === JOURNEY_EVENT.GO_TO_STEP_BY_ID && \"stepId\" in event;\n\nexport const isTerminalTarget = <TStepId extends string>(\n target: TStepId | JourneyTerminal\n): target is JourneyTerminal => target === \"COMPLETE\" || target === \"TERMINATED\";\n\nexport const validateJourneyTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n steps: Record<TStepId, unknown>\n) => {\n const stepRegistry = steps as Record<string, unknown>;\n\n for (const [index, transition] of transitions.entries()) {\n if (!transition || typeof transition !== \"object\") {\n throw new Error(`Journey transition at index ${index} must be an object.`);\n }\n\n if (typeof transition.from !== \"string\" || typeof transition.event !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define string \"from\" and \"event\".`\n );\n }\n\n if (transition.from !== JOURNEY_WILDCARD && !(transition.from in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} references unknown from step \"${transition.from}\".`\n );\n }\n\n if (transition.event === \"completeJourney\" || transition.event === \"terminateJourney\") {\n if (\"to\" in transition && transition.to !== undefined) {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" cannot define \"to\".`\n );\n }\n continue;\n }\n\n if (typeof transition.to !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} with event \"${transition.event}\" must define string \"to\".`\n );\n }\n\n if (!isTerminalTarget(transition.to) && !(transition.to in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} points to unknown step \"${transition.to}\".`\n );\n }\n }\n};\n\nexport const buildSendResult = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n transitioned: boolean,\n transitionId?: string\n): JourneySendResult<TContext, TStepId, TStepMeta> =>\n transitionId ? { transitioned, transitionId, snapshot } : { transitioned, snapshot };\n\nexport const buildSnapshot = <TContext, TStepId extends string, TStepMeta>(\n timeline: readonly TStepId[],\n index: number,\n context: TContext,\n status: JourneyStatus,\n asyncState: JourneyAsyncState<TStepId>,\n stepMeta: Record<TStepId, TStepMeta>,\n visited?: Record<TStepId, boolean>\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n if (timeline.length === 0) {\n throw new Error(\"Journey timeline cannot be empty.\");\n }\n const safeIndex = Math.max(0, Math.min(Math.trunc(index), timeline.length - 1));\n const currentStepId = timeline[safeIndex] as TStepId;\n const stepIds = Object.keys(stepMeta) as TStepId[];\n return {\n status,\n currentStepId,\n history: {\n timeline: [...timeline],\n index: safeIndex\n },\n context,\n visited: visited\n ? normalizeVisited(visited, stepIds)\n : buildVisitedFromTimeline(timeline, stepIds),\n stepMeta: { ...stepMeta },\n async: asyncState\n };\n};\n\nexport const selectTransition = async <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>,\n TStepMeta\n>(\n transitions: readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[],\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n event: JourneyEvent<TStepId, TEventType, TPayloadMap>,\n hooks?: {\n onAsyncGuardStart?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardSuccess?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n ) => void;\n onAsyncGuardError?: (\n transition: JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n error: unknown\n ) => void;\n }\n): Promise<JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> | null> => {\n for (const transition of transitions) {\n const fromMatches =\n transition.from === JOURNEY_WILDCARD || transition.from === snapshot.currentStepId;\n const eventMatches = transition.event === event.type;\n\n if (!fromMatches || !eventMatches) {\n continue;\n }\n\n if (!transition.when) {\n return transition;\n }\n\n const guardResult = transition.when({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event\n });\n const asyncGuard = isPromiseLike(guardResult);\n if (asyncGuard) {\n hooks?.onAsyncGuardStart?.(transition);\n }\n\n let allowed: boolean;\n try {\n allowed = await guardResult;\n } catch (error) {\n if (asyncGuard) {\n hooks?.onAsyncGuardError?.(transition, error);\n }\n throw error;\n }\n\n if (asyncGuard) {\n hooks?.onAsyncGuardSuccess?.(transition);\n }\n\n if (allowed) {\n return transition;\n }\n }\n\n return null;\n};\n\nexport const transitionSnapshot = <TContext, TStepId extends string, TStepMeta>(\n snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>,\n nextCurrent: TStepId,\n nextContext: TContext\n): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const baseTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n let nextTimeline = baseTimeline;\n if (nextCurrent !== snapshot.currentStepId) {\n nextTimeline = [...baseTimeline, nextCurrent];\n }\n\n const nextIndex = nextTimeline.length - 1;\n const visited = appendVisited(snapshot.visited, nextCurrent);\n\n return buildSnapshot(\n nextTimeline,\n nextIndex,\n nextContext,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n visited\n );\n};\n", "import { JOURNEY_STATUS } from \"./types/journey.types\";\nimport type {\n JourneyPersistedSnapshot,\n JourneyPersistedState,\n JourneyStorage,\n ResolvedPersistence\n} from \"./types/persistence.types\";\nimport type { JourneyMachineOptions, JourneySnapshot, JourneyStatus } from \"./types/journey.types\";\nimport { buildInitialAsyncState, buildSnapshot, buildVisitedFromTimeline } from \"./machine-helpers\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst isStatusValue = (value: unknown): value is JourneyStatus =>\n value === JOURNEY_STATUS.RUNNING ||\n value === JOURNEY_STATUS.COMPLETE ||\n value === JOURNEY_STATUS.TERMINATED;\n\nconst resolveDefaultStorage = (): JourneyStorage | null => {\n const localStorageCandidate = (globalThis as { localStorage?: Partial<JourneyStorage> })\n .localStorage;\n\n if (\n !localStorageCandidate ||\n typeof localStorageCandidate.getItem !== \"function\" ||\n typeof localStorageCandidate.setItem !== \"function\" ||\n typeof localStorageCandidate.removeItem !== \"function\"\n ) {\n return null;\n }\n\n return localStorageCandidate as JourneyStorage;\n};\n\nconst resolvePersistence = <TContext, TStepId extends string, TStepMeta>(\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>[\"persistence\"]\n): ResolvedPersistence<TContext, TStepId, TStepMeta> | null => {\n if (!options) {\n return null;\n }\n\n const storage = options.storage ?? resolveDefaultStorage();\n if (!storage) {\n return null;\n }\n\n return {\n key: options.key,\n storage,\n version: options.version ?? 1,\n clearOnReset: options.clearOnReset ?? true,\n serialize: options.serialize ?? JSON.stringify,\n deserialize: options.deserialize ?? JSON.parse,\n ...(options.migrate ? { migrate: options.migrate } : {}),\n ...(options.onError ? { onError: options.onError } : {})\n };\n};\n\nconst coercePersistedSnapshot = <TContext, TStepId extends string, TStepMeta>(\n value: unknown,\n steps: Record<TStepId, unknown>,\n fallbackContext: TContext,\n fallbackStepMeta: Record<TStepId, TStepMeta>\n): {\n snapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta>;\n needsRewrite: boolean;\n} | null => {\n if (!isRecord(value)) {\n return null;\n }\n\n let needsRewrite = false;\n\n const rawHistory = isRecord(value.history) ? value.history : null;\n if (!rawHistory) {\n needsRewrite = true;\n }\n\n const rawTimeline = rawHistory?.timeline ?? value.timeline;\n const timeline = Array.isArray(rawTimeline)\n ? (rawTimeline.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[])\n : [];\n\n const currentStepIdValue =\n typeof value.currentStepId === \"string\" && value.currentStepId in steps\n ? (value.currentStepId as TStepId)\n : typeof value.current === \"string\" && value.current in steps\n ? (value.current as TStepId)\n : null;\n\n if (timeline.length === 0) {\n if (!currentStepIdValue) {\n return null;\n }\n timeline.push(currentStepIdValue);\n needsRewrite = true;\n }\n\n let index = timeline.length - 1;\n const rawIndex = rawHistory?.index ?? value.index;\n if (typeof rawIndex === \"number\" && Number.isFinite(rawIndex)) {\n index = Math.max(0, Math.min(Math.trunc(rawIndex), timeline.length - 1));\n if (index !== rawIndex) {\n needsRewrite = true;\n }\n } else if (currentStepIdValue) {\n const inferredIndex = timeline.lastIndexOf(currentStepIdValue);\n if (inferredIndex >= 0) {\n index = inferredIndex;\n needsRewrite = true;\n }\n }\n\n const status = isStatusValue(value.status) ? value.status : JOURNEY_STATUS.RUNNING;\n if (!isStatusValue(value.status)) {\n needsRewrite = true;\n }\n\n const stepIds = Object.keys(steps) as TStepId[];\n const visitedSource = value.visited;\n const visitedFromRecord = isRecord(visitedSource)\n ? (Object.fromEntries(\n stepIds.map((stepId) => [stepId, visitedSource[stepId] === true])\n ) as Record<TStepId, boolean>)\n : null;\n const visitedFromArray = Array.isArray(visitedSource)\n ? buildVisitedFromTimeline(\n visitedSource.filter(\n (step): step is TStepId => typeof step === \"string\" && step in steps\n ) as TStepId[],\n stepIds\n )\n : null;\n\n let visited = buildVisitedFromTimeline(timeline, stepIds);\n if (visitedFromRecord) {\n const visitedRecord = visitedSource as Record<string, unknown>;\n visited = visitedFromRecord;\n const hasMissingOrInvalidStep = stepIds.some(\n (stepId) => typeof visitedRecord[stepId] !== \"boolean\"\n );\n if (hasMissingOrInvalidStep) {\n needsRewrite = true;\n }\n } else if (visitedFromArray) {\n visited = visitedFromArray;\n needsRewrite = true;\n } else {\n needsRewrite = true;\n }\n\n const rawStepMeta = isRecord(value.stepMeta) ? value.stepMeta : null;\n if (!rawStepMeta) {\n needsRewrite = true;\n }\n\n const stepMeta = Object.fromEntries(\n Object.keys(steps).map((stepId) => {\n const typedStepId = stepId as TStepId;\n const rawValue = rawStepMeta ? rawStepMeta[stepId] : undefined;\n if (rawValue === undefined) {\n return [typedStepId, fallbackStepMeta[typedStepId]];\n }\n return [typedStepId, rawValue as TStepMeta];\n })\n ) as Record<TStepId, TStepMeta>;\n\n return {\n snapshot: {\n currentStepId: timeline[index] as TStepId,\n history: {\n timeline,\n index\n },\n context: (\"context\" in value ? value.context : fallbackContext) as TContext,\n status,\n visited,\n stepMeta\n },\n needsRewrite\n };\n};\n\n/**\n * Creates a persistence controller for snapshots, including hydration,\n * serialization, and storage error handling.\n */\nexport const createPersistenceController = <TContext, TStepId extends string, TStepMeta>(args: {\n initial: TStepId;\n context: TContext;\n stepMeta: Record<TStepId, TStepMeta>;\n steps: Record<TStepId, unknown>;\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>;\n}) => {\n const { initial, context, stepMeta, steps, options } = args;\n const persistence = resolvePersistence(options?.persistence);\n\n const reportPersistenceError = (error: unknown) => {\n persistence?.onError?.(error);\n };\n\n const persistSnapshot = (snapshot: JourneySnapshot<TContext, TStepId, TStepMeta>) => {\n if (!persistence) {\n return;\n }\n\n try {\n const persistedState: JourneyPersistedState<TContext, TStepId, TStepMeta> = {\n version: persistence.version,\n snapshot: {\n currentStepId: snapshot.currentStepId,\n history: {\n timeline: [...snapshot.history.timeline],\n index: snapshot.history.index\n },\n context: snapshot.context,\n status: snapshot.status,\n visited: { ...snapshot.visited },\n stepMeta: { ...snapshot.stepMeta }\n }\n };\n persistence.storage.setItem(persistence.key, persistence.serialize(persistedState));\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const removePersistedSnapshot = () => {\n if (!persistence) {\n return;\n }\n\n try {\n persistence.storage.removeItem(persistence.key);\n } catch (error) {\n reportPersistenceError(error);\n }\n };\n\n const hydrateSnapshot = (): JourneySnapshot<TContext, TStepId, TStepMeta> => {\n const initialSnapshot = buildSnapshot(\n [initial],\n 0,\n context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(steps),\n stepMeta\n );\n if (!persistence) {\n return initialSnapshot;\n }\n\n try {\n const rawPersisted = persistence.storage.getItem(persistence.key);\n if (!rawPersisted) {\n return initialSnapshot;\n }\n\n const parsed = persistence.deserialize(rawPersisted);\n if (!isRecord(parsed)) {\n return initialSnapshot;\n }\n\n const persistedVersion = parsed.version;\n if (typeof persistedVersion !== \"number\") {\n return initialSnapshot;\n }\n\n let persistedSnapshot: JourneyPersistedSnapshot<TContext, TStepId, TStepMeta> | null = null;\n let shouldRewritePersisted = false;\n\n if (persistedVersion === persistence.version) {\n const coerced = coercePersistedSnapshot(parsed.snapshot, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = Boolean(coerced?.needsRewrite);\n } else if (persistence.migrate) {\n const migrated = persistence.migrate(parsed.snapshot, persistedVersion);\n const coerced = coercePersistedSnapshot(migrated, steps, context, stepMeta);\n persistedSnapshot = coerced?.snapshot ?? null;\n shouldRewritePersisted = persistedSnapshot !== null;\n }\n\n if (!persistedSnapshot) {\n return initialSnapshot;\n }\n\n const hydratedSnapshot = buildSnapshot(\n persistedSnapshot.history.timeline,\n persistedSnapshot.history.index,\n persistedSnapshot.context,\n persistedSnapshot.status,\n buildInitialAsyncState(steps),\n persistedSnapshot.stepMeta,\n persistedSnapshot.visited\n );\n\n if (shouldRewritePersisted) {\n persistSnapshot(hydratedSnapshot);\n }\n\n return hydratedSnapshot;\n } catch (error) {\n reportPersistenceError(error);\n return initialSnapshot;\n }\n };\n\n return {\n clearOnReset: persistence?.clearOnReset ?? true,\n hydrateSnapshot,\n persistSnapshot,\n removePersistedSnapshot\n };\n};\n", "import { JOURNEY_ASYNC_PHASE, JOURNEY_EVENT, JOURNEY_STATUS } from \"./types\";\nimport type {\n JourneyAsyncState,\n JourneyAsyncPhase,\n JourneyDefaultEventType,\n JourneyDefinition,\n JourneyEvent,\n JourneyEventPayloadMap,\n JourneyMachine,\n JourneyMachineOptions,\n JourneyObservationEvent,\n JourneySendResult,\n JourneyStepDefinition,\n JourneyTransition,\n JourneyTerminal\n} from \"./types\";\nimport {\n assertStepExists,\n buildIdleStepAsyncState,\n buildInitialAsyncState,\n buildSendResult,\n buildSnapshot,\n isGoToStepByIdEvent,\n isPromiseLike,\n isTerminalTarget,\n normalizeStepCount,\n now,\n selectTransition,\n transitionSnapshot,\n validateJourneyTransitions\n} from \"./machine-helpers\";\nimport { createPersistenceController } from \"./persistence\";\n\n/**\n * Creates a journey machine from a journey definition.\n * Validates steps/transitions, hydrates persisted state (if configured),\n * and returns an API for sending events and reading snapshots.\n */\nexport function createJourneyMachine<\n TContext,\n TStepMeta = unknown,\n TSteps extends Record<string, JourneyStepDefinition<TStepMeta>> = Record<\n string,\n JourneyStepDefinition<TStepMeta>\n >,\n TPayloadMap extends JourneyEventPayloadMap<JourneyDefaultEventType> = Record<never, never>\n>(\n journey: {\n initial: Extract<keyof TSteps, string>;\n context: TContext;\n steps: TSteps;\n transitions: readonly JourneyTransition<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap\n >[];\n },\n options?: JourneyMachineOptions<TContext, Extract<keyof TSteps, string>, TStepMeta>\n): JourneyMachine<\n TContext,\n Extract<keyof TSteps, string>,\n JourneyDefaultEventType,\n TPayloadMap,\n TStepMeta\n>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>;\n// eslint-disable-next-line no-redeclare\nexport function createJourneyMachine<\n TContext,\n TStepId extends string,\n TEventType extends string = JourneyDefaultEventType,\n TPayloadMap extends JourneyEventPayloadMap<TEventType> = Record<never, never>,\n TStepMeta = unknown\n>(\n journey: JourneyDefinition<TContext, TStepId, TEventType, TPayloadMap, TStepMeta>,\n options?: JourneyMachineOptions<TContext, TStepId, TStepMeta>\n): JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> {\n if (!journey.steps || typeof journey.steps !== \"object\") {\n throw new Error(\"Journey steps must be a record object.\");\n }\n\n if (!Array.isArray(journey.transitions)) {\n throw new Error(\"Journey transitions must be an array.\");\n }\n\n assertStepExists(\n journey.steps,\n journey.initial,\n `Journey initial step \"${journey.initial}\" does not exist in steps registry.`\n );\n\n validateJourneyTransitions(journey.transitions, journey.steps);\n\n const buildStepMeta = (): Record<TStepId, TStepMeta> => {\n const stepMeta = {} as Record<TStepId, TStepMeta>;\n for (const stepId of Object.keys(journey.steps) as TStepId[]) {\n stepMeta[stepId] = journey.steps[stepId].meta as TStepMeta;\n }\n return stepMeta;\n };\n\n const { clearOnReset, hydrateSnapshot, persistSnapshot, removePersistedSnapshot } =\n createPersistenceController({\n initial: journey.initial,\n context: journey.context,\n stepMeta: buildStepMeta(),\n steps: journey.steps,\n ...(options ? { options } : {})\n });\n\n let snapshot = hydrateSnapshot();\n snapshot = {\n ...snapshot,\n async: buildInitialAsyncState(journey.steps)\n };\n\n const listeners = new Set<() => void>();\n const eventListeners = new Set<\n (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => void\n >();\n let actionQueue: Promise<void> = Promise.resolve();\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const emit = (event: JourneyObservationEvent<TStepId, TEventType, TPayloadMap, TStepMeta>) => {\n for (const listener of eventListeners) {\n listener(event);\n }\n };\n\n const queue = <T>(runner: () => Promise<T>): Promise<T> => {\n const resultPromise = actionQueue.then(runner, runner);\n actionQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n return resultPromise;\n };\n\n const isAsyncLoadingPhase = (phase: JourneyAsyncPhase): boolean =>\n phase === JOURNEY_ASYNC_PHASE.EVALUATING_WHEN || phase === JOURNEY_ASYNC_PHASE.RUNNING_EFFECT;\n\n const updateStepAsync = (\n stepId: TStepId,\n updater: (\n current: JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => JourneyAsyncState<TStepId>[\"byStep\"][TStepId]\n ) => {\n const current = snapshot.async.byStep[stepId] ?? buildIdleStepAsyncState();\n const next = updater(current);\n if (\n current.phase === next.phase &&\n current.eventType === next.eventType &&\n current.transitionId === next.transitionId &&\n current.error === next.error\n ) {\n return;\n }\n\n const nextByStep = {\n ...snapshot.async.byStep,\n [stepId]: next\n };\n const isLoading = Object.values(nextByStep).some((state) => isAsyncLoadingPhase(state.phase));\n snapshot = {\n ...snapshot,\n async: {\n isLoading,\n byStep: nextByStep\n }\n };\n notify();\n };\n\n const setStepLoading = (\n stepId: TStepId,\n phase: JourneyAsyncPhase,\n eventType: string,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase,\n eventType,\n transitionId: transitionId ?? null,\n error: null\n }));\n };\n\n const setStepIdle = (stepId: TStepId) => {\n updateStepAsync(stepId, () => buildIdleStepAsyncState());\n };\n\n const setStepError = (\n stepId: TStepId,\n eventType: string,\n error: unknown,\n transitionId?: string\n ) => {\n updateStepAsync(stepId, () => ({\n phase: JOURNEY_ASYNC_PHASE.ERROR,\n eventType,\n transitionId: transitionId ?? null,\n error\n }));\n };\n\n const applyPreviousNavigation = (\n requestedSteps?: number,\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const steps = normalizeStepCount(requestedSteps);\n if (snapshot.history.index === 0) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n const nextIndex = Math.max(0, snapshot.history.index - steps);\n const appliedSteps = snapshot.history.index - nextIndex;\n if (appliedSteps <= 0) {\n return buildSendResult(snapshot, false);\n }\n\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n nextIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"navigation.previous\",\n from,\n to: snapshot.currentStepId,\n requestedSteps: steps,\n appliedSteps,\n timestamp: now()\n });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const applyLastVisitedNavigation = (\n transitionId?: string\n ): JourneySendResult<TContext, TStepId, TStepMeta> => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const targetIndex = snapshot.history.timeline.length - 1;\n if (snapshot.history.index >= targetIndex) {\n return buildSendResult(snapshot, false);\n }\n\n const from = snapshot.currentStepId;\n emit({ type: \"step.exit\", stepId: from, timestamp: now() });\n snapshot = buildSnapshot(\n snapshot.history.timeline,\n targetIndex,\n snapshot.context,\n snapshot.status,\n snapshot.async,\n snapshot.stepMeta,\n snapshot.visited\n );\n persistSnapshot(snapshot);\n notify();\n\n emit({ type: \"navigation.lastVisited\", from, to: snapshot.currentStepId, timestamp: now() });\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n return buildSendResult(snapshot, true, transitionId);\n };\n\n const machine: JourneyMachine<TContext, TStepId, TEventType, TPayloadMap, TStepMeta> = {\n getSnapshot: () => snapshot,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n subscribeEvent: (listener) => {\n eventListeners.add(listener);\n return () => {\n eventListeners.delete(listener);\n };\n },\n resetMachine: () => {\n snapshot = buildSnapshot(\n [journey.initial],\n 0,\n journey.context,\n JOURNEY_STATUS.RUNNING,\n buildInitialAsyncState(journey.steps),\n buildStepMeta()\n );\n if (clearOnReset) {\n removePersistedSnapshot();\n } else {\n persistSnapshot(snapshot);\n }\n notify();\n return snapshot;\n },\n updateContext: (updater) => {\n snapshot = {\n ...snapshot,\n context: updater(snapshot.context)\n };\n persistSnapshot(snapshot);\n notify();\n return snapshot;\n },\n updateStepMetadata: (stepId, updater) => {\n if (!(stepId in journey.steps)) {\n return snapshot;\n }\n\n const previousMeta = snapshot.stepMeta[stepId];\n const nextMeta = updater(previousMeta);\n if (Object.is(previousMeta, nextMeta)) {\n return snapshot;\n }\n\n snapshot = {\n ...snapshot,\n stepMeta: {\n ...snapshot.stepMeta,\n [stepId]: nextMeta\n }\n };\n persistSnapshot(snapshot);\n notify();\n emit({\n type: \"metadata.updated\",\n stepId,\n previous: previousMeta,\n next: nextMeta,\n timestamp: now()\n });\n return snapshot;\n },\n clearStepError: (stepId) => {\n const resolvedStep = stepId ?? snapshot.currentStepId;\n if (!(resolvedStep in journey.steps)) {\n return snapshot;\n }\n\n setStepIdle(resolvedStep);\n return snapshot;\n },\n goToPreviousStep: (steps) =>\n queue(async () => {\n const result = applyPreviousNavigation(steps, \"goToPreviousStep\");\n return result;\n }),\n goToLastVisitedStep: () =>\n queue(async () => {\n const result = applyLastVisitedNavigation(\"goToLastVisitedStep\");\n return result;\n }),\n goToNextStep: () => machine.send({ type: \"goToNextStep\" }),\n terminateJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"terminateJourney\" })\n : machine.send({ type: \"terminateJourney\", payload }),\n completeJourney: (payload) =>\n payload === undefined\n ? machine.send({ type: \"completeJourney\" })\n : machine.send({ type: \"completeJourney\", payload }),\n send: (event) =>\n queue(async () => {\n if (snapshot.status !== JOURNEY_STATUS.RUNNING) {\n return buildSendResult(snapshot, false);\n }\n\n const fromStep = snapshot.currentStepId;\n\n if (isGoToStepByIdEvent(event)) {\n assertStepExists(\n journey.steps,\n event.stepId,\n `Cannot goToStepById unknown step \"${event.stepId}\".`\n );\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n setStepIdle(fromStep);\n\n const beforeCurrent = snapshot.currentStepId;\n const nextSnapshot = transitionSnapshot(snapshot, event.stepId, snapshot.context);\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n\n snapshot = nextSnapshot;\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n transitionId: JOURNEY_EVENT.GO_TO_STEP_BY_ID,\n timestamp: now()\n });\n\n if (nextSnapshot.currentStepId !== beforeCurrent) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, JOURNEY_EVENT.GO_TO_STEP_BY_ID);\n }\n\n const transitionEvent = event as JourneyEvent<TStepId, TEventType, TPayloadMap>;\n emit({ type: \"transition.start\", from: fromStep, event, timestamp: now() });\n\n let transition;\n try {\n transition = await selectTransition(journey.transitions, snapshot, transitionEvent, {\n onAsyncGuardStart: (currentTransition) => {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.EVALUATING_WHEN,\n transitionEvent.type,\n currentTransition.id\n );\n },\n onAsyncGuardSuccess: () => {\n setStepIdle(fromStep);\n },\n onAsyncGuardError: (currentTransition, error) => {\n setStepError(fromStep, transitionEvent.type, error, currentTransition.id);\n }\n });\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (!transition) {\n if (event.type === \"goToPreviousStep\" || event.type === \"back\") {\n const fallbackResult = applyPreviousNavigation(1, event.type);\n if (fallbackResult.transitioned) {\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: fallbackResult.snapshot.currentStepId,\n eventType: event.type,\n transitionId: null,\n timestamp: now()\n });\n }\n return fallbackResult;\n }\n\n return buildSendResult(snapshot, false);\n }\n\n let nextContext = snapshot.context;\n if (transition.effect) {\n const effectResultPromise = transition.effect({\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event: transitionEvent\n });\n if (isPromiseLike(effectResultPromise)) {\n setStepLoading(\n fromStep,\n JOURNEY_ASYNC_PHASE.RUNNING_EFFECT,\n transitionEvent.type,\n transition.id\n );\n }\n\n let effectResult: TContext | void;\n try {\n effectResult = await effectResultPromise;\n } catch (error) {\n setStepError(fromStep, transitionEvent.type, error, transition.id);\n emit({\n type: \"transition.error\",\n from: fromStep,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n error,\n timestamp: now()\n });\n throw error;\n }\n\n if (effectResult !== undefined) {\n nextContext = effectResult;\n }\n }\n\n setStepIdle(fromStep);\n\n const target: TStepId | JourneyTerminal =\n transition.event === \"completeJourney\"\n ? \"COMPLETE\"\n : transition.event === \"terminateJourney\"\n ? \"TERMINATED\"\n : (transition.to as TStepId | JourneyTerminal);\n\n if (isTerminalTarget(target)) {\n const normalizedTimeline = snapshot.history.timeline.slice(0, snapshot.history.index + 1);\n snapshot = {\n ...snapshot,\n history: {\n timeline: normalizedTimeline,\n index: normalizedTimeline.length - 1\n },\n context: nextContext,\n status: target === \"COMPLETE\" ? JOURNEY_STATUS.COMPLETE : JOURNEY_STATUS.TERMINATED\n };\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: target,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n emit({\n type: target === \"COMPLETE\" ? \"journey.complete\" : \"journey.close\",\n stepId: snapshot.currentStepId,\n timestamp: now()\n });\n\n return buildSendResult(snapshot, true, transition.id);\n }\n\n const resolvedTarget = target;\n\n assertStepExists(\n journey.steps,\n resolvedTarget,\n `Transition points to unknown step \"${resolvedTarget}\".`\n );\n\n const beforeCurrent = snapshot.currentStepId;\n if (beforeCurrent !== resolvedTarget) {\n emit({ type: \"step.exit\", stepId: beforeCurrent, timestamp: now() });\n }\n snapshot = transitionSnapshot(snapshot, resolvedTarget, nextContext);\n persistSnapshot(snapshot);\n notify();\n\n emit({\n type: \"transition.success\",\n from: fromStep,\n to: snapshot.currentStepId,\n eventType: transitionEvent.type,\n transitionId: transition.id ?? null,\n timestamp: now()\n });\n if (beforeCurrent !== snapshot.currentStepId) {\n emit({ type: \"step.enter\", stepId: snapshot.currentStepId, timestamp: now() });\n }\n\n return buildSendResult(snapshot, true, transition.id);\n })\n };\n\n return machine;\n}\n", "import { JOURNEY_WILDCARD } from \"./types/journey.types\";\nimport type { JourneyEventPayloadMap } from \"./types/journey.types\";\nimport type {\n EventBuilder,\n JourneyEventTransition,\n JourneyTransition,\n JourneyTransitionArgs,\n JourneyTransitionTarget,\n TransitionBranch,\n TransitionConfig\n} from \"./types/transitions.types\";\n\nconst createEventBuilder = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType\n): EventBuilder<TContext, TStepId, TEventType, TPayloadMap> => {\n if (event === \"completeJourney\") {\n return {\n complete: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"completeJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n if (event === \"terminateJourney\") {\n return {\n terminate: (\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Extract<TEventType, \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n }\n\n return {\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> =>\n ({\n ...config,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">,\n to\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>,\n choose: (\n ...branches: Array<TransitionBranch<TContext, TStepId, TEventType, TPayloadMap>>\n ): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n branches.map(\n (branch) =>\n ({\n ...branch,\n from,\n event: event as Exclude<TEventType, \"completeJourney\" | \"terminateJourney\">\n }) as JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n )\n } as EventBuilder<TContext, TStepId, TEventType, TPayloadMap>;\n};\n\nconst buildTerminalTransition = <\n TContext,\n TStepId extends string,\n TEventType extends \"completeJourney\" | \"terminateJourney\"\n>(\n from: TStepId | typeof JOURNEY_WILDCARD,\n event: TEventType,\n config: TransitionConfig<TContext, TStepId, TEventType, Record<never, never>> = {}\n): JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>> =>\n ({\n ...config,\n from,\n event\n }) as JourneyEventTransition<TContext, TStepId, TEventType, Record<never, never>>;\n\n/**\n * Fluent helpers for building journey transitions with type-safe branches.\n */\nexport const tx = {\n from: <TStepId extends string, TContext = unknown>(from: TStepId) => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(from, event),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(from, \"terminateJourney\", config)\n }),\n any: <TContext = unknown, TStepId extends string = string>() => ({\n on: <TEventType extends string>(event: TEventType) =>\n createEventBuilder<TContext, TStepId, TEventType, Record<never, never>>(\n JOURNEY_WILDCARD,\n event\n ),\n toComplete: (\n config: TransitionConfig<TContext, TStepId, \"completeJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"completeJourney\", config),\n toTerminate: (\n config: TransitionConfig<TContext, TStepId, \"terminateJourney\", Record<never, never>> = {}\n ) => buildTerminalTransition(JOURNEY_WILDCARD, \"terminateJourney\", config)\n }),\n when: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >(\n predicate: (\n args: JourneyTransitionArgs<TContext, TStepId, TEventType, TPayloadMap>\n ) => boolean | Promise<boolean>\n ) => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to,\n when: predicate\n })\n }),\n otherwise: <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n >() => ({\n to: (\n to: JourneyTransitionTarget<TStepId>,\n config: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap> = {}\n ): TransitionBranch<TContext, TStepId, TEventType, TPayloadMap> => ({\n ...config,\n to\n })\n })\n};\n\n/**\n * Flattens transition items and transition arrays into a single transition list.\n */\nexport const createTransitions = <\n TContext,\n TStepId extends string,\n TEventType extends string,\n TPayloadMap extends JourneyEventPayloadMap<TEventType>\n>(\n ...items: Array<\n | JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>\n | readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[]\n >\n): JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[] =>\n items.flatMap((item) => (Array.isArray(item) ? [...item] : [item]));\n"],
5
+ "mappings": "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",
6
6
  "names": ["JOURNEY_STATUS", "JOURNEY_WILDCARD", "JOURNEY_EVENT", "JOURNEY_ASYNC_PHASE", "assertStepExists", "steps", "stepId", "message", "normalizeStepCount", "now", "unique", "items", "normalizeVisited", "visited", "stepIds", "buildVisitedFromTimeline", "timeline", "resolvedStepIds", "appendVisited", "current", "isPromiseLike", "value", "buildIdleStepAsyncState", "JOURNEY_ASYNC_PHASE", "buildInitialAsyncState", "isGoToStepByIdEvent", "event", "JOURNEY_EVENT", "isTerminalTarget", "target", "validateJourneyTransitions", "transitions", "stepRegistry", "index", "transition", "JOURNEY_WILDCARD", "buildSendResult", "snapshot", "transitioned", "transitionId", "buildSnapshot", "context", "status", "asyncState", "stepMeta", "safeIndex", "currentStepId", "selectTransition", "hooks", "fromMatches", "eventMatches", "guardResult", "asyncGuard", "allowed", "error", "transitionSnapshot", "nextCurrent", "nextContext", "baseTimeline", "nextTimeline", "nextIndex", "isRecord", "value", "isStatusValue", "JOURNEY_STATUS", "resolveDefaultStorage", "localStorageCandidate", "resolvePersistence", "options", "storage", "coercePersistedSnapshot", "steps", "fallbackContext", "fallbackStepMeta", "needsRewrite", "rawHistory", "rawTimeline", "timeline", "step", "currentStepIdValue", "index", "rawIndex", "inferredIndex", "status", "stepIds", "visitedSource", "visitedFromRecord", "stepId", "visitedFromArray", "buildVisitedFromTimeline", "visited", "visitedRecord", "rawStepMeta", "stepMeta", "typedStepId", "rawValue", "createPersistenceController", "args", "initial", "context", "persistence", "reportPersistenceError", "error", "persistSnapshot", "snapshot", "persistedState", "removePersistedSnapshot", "hydrateSnapshot", "initialSnapshot", "buildSnapshot", "buildInitialAsyncState", "rawPersisted", "parsed", "persistedVersion", "persistedSnapshot", "shouldRewritePersisted", "coerced", "migrated", "hydratedSnapshot", "createJourneyMachine", "journey", "options", "assertStepExists", "validateJourneyTransitions", "buildStepMeta", "stepMeta", "stepId", "clearOnReset", "hydrateSnapshot", "persistSnapshot", "removePersistedSnapshot", "createPersistenceController", "snapshot", "buildInitialAsyncState", "listeners", "eventListeners", "actionQueue", "notify", "listener", "emit", "event", "queue", "runner", "resultPromise", "isAsyncLoadingPhase", "phase", "JOURNEY_ASYNC_PHASE", "updateStepAsync", "updater", "current", "buildIdleStepAsyncState", "next", "nextByStep", "isLoading", "state", "setStepLoading", "eventType", "transitionId", "setStepIdle", "setStepError", "error", "applyPreviousNavigation", "requestedSteps", "JOURNEY_STATUS", "buildSendResult", "steps", "normalizeStepCount", "from", "nextIndex", "appliedSteps", "now", "buildSnapshot", "applyLastVisitedNavigation", "targetIndex", "machine", "previousMeta", "nextMeta", "resolvedStep", "payload", "fromStep", "isGoToStepByIdEvent", "beforeCurrent", "nextSnapshot", "transitionSnapshot", "JOURNEY_EVENT", "transitionEvent", "transition", "selectTransition", "currentTransition", "fallbackResult", "nextContext", "effectResultPromise", "isPromiseLike", "effectResult", "target", "isTerminalTarget", "normalizedTimeline", "resolvedTarget", "createEventBuilder", "from", "event", "config", "to", "branches", "branch", "buildTerminalTransition", "tx", "JOURNEY_WILDCARD", "predicate", "createTransitions", "items", "item"]
7
7
  }
@@ -1,5 +1,8 @@
1
1
  import type { JourneyEventPayloadMap } from "./types/journey.types";
2
2
  import type { EventBuilder, JourneyEventTransition, JourneyTransition, JourneyTransitionArgs, JourneyTransitionTarget, TransitionBranch, TransitionConfig } from "./types/transitions.types";
3
+ /**
4
+ * Fluent helpers for building journey transitions with type-safe branches.
5
+ */
3
6
  export declare const tx: {
4
7
  from: <TStepId extends string, TContext = unknown>(from: TStepId) => {
5
8
  on: <TEventType extends string>(event: TEventType) => EventBuilder<TContext, TStepId, TEventType, Record<never, never>>;
@@ -18,4 +21,7 @@ export declare const tx: {
18
21
  to: (to: JourneyTransitionTarget<TStepId>, config?: TransitionConfig<TContext, TStepId, TEventType, TPayloadMap>) => TransitionBranch<TContext, TStepId, TEventType, TPayloadMap>;
19
22
  };
20
23
  };
24
+ /**
25
+ * Flattens transition items and transition arrays into a single transition list.
26
+ */
21
27
  export declare const createTransitions: <TContext, TStepId extends string, TEventType extends string, TPayloadMap extends JourneyEventPayloadMap<TEventType>>(...items: Array<JourneyTransition<TContext, TStepId, TEventType, TPayloadMap> | readonly JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[]>) => JourneyTransition<TContext, TStepId, TEventType, TPayloadMap>[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxova/journey-core",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Journey core state machine.",
5
5
  "keywords": [
6
6
  "journey",