@rxova/journey-core 1.0.0-rc.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +182 -186
  2. package/dist/connectors/immer/immer.cjs +2 -0
  3. package/dist/connectors/immer/immer.cjs.map +7 -0
  4. package/dist/connectors/immer/immer.d.cts +11 -0
  5. package/dist/connectors/immer/immer.d.ts +11 -0
  6. package/dist/connectors/immer/immer.js +2 -0
  7. package/dist/connectors/immer/immer.js.map +7 -0
  8. package/dist/connectors/immer/immer.types.d.cts +9 -0
  9. package/dist/connectors/immer/immer.types.d.ts +9 -0
  10. package/dist/core/errors.d.cts +57 -0
  11. package/dist/core/errors.d.ts +57 -0
  12. package/dist/core/helpers.d.cts +46 -0
  13. package/dist/core/helpers.d.ts +46 -0
  14. package/dist/core/machine.d.cts +9 -0
  15. package/dist/core/machine.d.ts +9 -0
  16. package/dist/core/runtime.d.cts +115 -0
  17. package/dist/core/runtime.d.ts +115 -0
  18. package/dist/core/runtime.types.d.cts +112 -0
  19. package/dist/core/runtime.types.d.ts +112 -0
  20. package/dist/core/store.d.cts +31 -0
  21. package/dist/core/store.d.ts +31 -0
  22. package/dist/core/types.d.cts +481 -0
  23. package/dist/core/types.d.ts +481 -0
  24. package/dist/diagnostics/diagnostics.helpers.d.cts +17 -0
  25. package/dist/diagnostics/diagnostics.helpers.d.ts +17 -0
  26. package/dist/diagnostics/diagnostics.types.d.cts +22 -0
  27. package/dist/diagnostics/diagnostics.types.d.ts +22 -0
  28. package/dist/graph/bag.types.d.cts +91 -0
  29. package/dist/graph/bag.types.d.ts +91 -0
  30. package/dist/graph/graph.d.cts +63 -0
  31. package/dist/graph/graph.d.ts +63 -0
  32. package/dist/graph/graph.types.d.cts +212 -0
  33. package/dist/graph/graph.types.d.ts +212 -0
  34. package/dist/graph/work.d.cts +81 -0
  35. package/dist/graph/work.d.ts +81 -0
  36. package/dist/index.cjs +1 -1
  37. package/dist/index.cjs.map +4 -4
  38. package/dist/index.d.cts +13 -5
  39. package/dist/index.d.ts +13 -5
  40. package/dist/index.js +1 -1
  41. package/dist/index.js.map +4 -4
  42. package/dist/linear/linear.d.cts +33 -0
  43. package/dist/linear/linear.d.ts +33 -0
  44. package/dist/linear/linear.types.d.cts +28 -0
  45. package/dist/linear/linear.types.d.ts +28 -0
  46. package/dist/plugins/analytics/analytics.d.cts +8 -0
  47. package/dist/plugins/analytics/analytics.d.ts +8 -0
  48. package/dist/plugins/analytics/analytics.helpers.d.cts +2 -0
  49. package/dist/plugins/analytics/analytics.helpers.d.ts +2 -0
  50. package/dist/plugins/analytics/analytics.types.d.cts +27 -0
  51. package/dist/plugins/analytics/analytics.types.d.ts +27 -0
  52. package/dist/plugins/execution-paths/execution-paths.d.cts +7 -4
  53. package/dist/plugins/execution-paths/execution-paths.d.ts +7 -4
  54. package/dist/plugins/execution-paths/execution-paths.types.d.cts +21 -0
  55. package/dist/plugins/execution-paths/execution-paths.types.d.ts +21 -0
  56. package/dist/plugins/index.cjs +2 -0
  57. package/dist/plugins/index.cjs.map +7 -0
  58. package/dist/plugins/index.d.cts +19 -0
  59. package/dist/plugins/index.d.ts +19 -0
  60. package/dist/plugins/index.js +2 -0
  61. package/dist/plugins/index.js.map +7 -0
  62. package/dist/plugins/persistence/persistence.d.cts +16 -0
  63. package/dist/plugins/persistence/persistence.d.ts +16 -0
  64. package/dist/plugins/persistence/persistence.helpers.d.cts +34 -0
  65. package/dist/plugins/persistence/persistence.helpers.d.ts +34 -0
  66. package/dist/plugins/persistence/persistence.types.d.cts +63 -0
  67. package/dist/plugins/persistence/persistence.types.d.ts +63 -0
  68. package/dist/plugins/replay/replay.d.cts +7 -0
  69. package/dist/plugins/replay/replay.d.ts +7 -0
  70. package/dist/plugins/replay/replay.helpers.d.cts +22 -0
  71. package/dist/plugins/replay/replay.helpers.d.ts +22 -0
  72. package/dist/plugins/replay/replay.types.d.cts +28 -0
  73. package/dist/plugins/replay/replay.types.d.ts +28 -0
  74. package/package.json +78 -79
  75. package/dist/journey-builder/index.d.cts +0 -5
  76. package/dist/journey-builder/index.d.ts +0 -5
  77. package/dist/journey-builder/types.d.cts +0 -126
  78. package/dist/journey-builder/types.d.ts +0 -126
  79. package/dist/journey-machine/async-state.d.cts +0 -12
  80. package/dist/journey-machine/async-state.d.ts +0 -12
  81. package/dist/journey-machine/computed.d.cts +0 -2
  82. package/dist/journey-machine/computed.d.ts +0 -2
  83. package/dist/journey-machine/controls.d.cts +0 -17
  84. package/dist/journey-machine/controls.d.ts +0 -17
  85. package/dist/journey-machine/helpers.d.cts +0 -52
  86. package/dist/journey-machine/helpers.d.ts +0 -52
  87. package/dist/journey-machine/index.d.cts +0 -3
  88. package/dist/journey-machine/index.d.ts +0 -3
  89. package/dist/journey-machine/navigation.d.cts +0 -32
  90. package/dist/journey-machine/navigation.d.ts +0 -32
  91. package/dist/journey-machine/plugin-controller.d.cts +0 -15
  92. package/dist/journey-machine/plugin-controller.d.ts +0 -15
  93. package/dist/journey-machine/resolve-journey-definition.d.cts +0 -2
  94. package/dist/journey-machine/resolve-journey-definition.d.ts +0 -2
  95. package/dist/journey-machine/runtime.d.cts +0 -33
  96. package/dist/journey-machine/runtime.d.ts +0 -33
  97. package/dist/journey-machine/send.d.cts +0 -9
  98. package/dist/journey-machine/send.d.ts +0 -9
  99. package/dist/plugins/analytics/index.cjs +0 -2
  100. package/dist/plugins/analytics/index.cjs.map +0 -7
  101. package/dist/plugins/analytics/index.d.cts +0 -25
  102. package/dist/plugins/analytics/index.d.ts +0 -25
  103. package/dist/plugins/analytics/index.js +0 -2
  104. package/dist/plugins/analytics/index.js.map +0 -7
  105. package/dist/plugins/autosave/index.cjs +0 -2
  106. package/dist/plugins/autosave/index.cjs.map +0 -7
  107. package/dist/plugins/autosave/index.d.cts +0 -17
  108. package/dist/plugins/autosave/index.d.ts +0 -17
  109. package/dist/plugins/autosave/index.js +0 -2
  110. package/dist/plugins/autosave/index.js.map +0 -7
  111. package/dist/plugins/diagnostics/diagnostics.d.cts +0 -3
  112. package/dist/plugins/diagnostics/diagnostics.d.ts +0 -3
  113. package/dist/plugins/diagnostics/index.cjs +0 -2
  114. package/dist/plugins/diagnostics/index.cjs.map +0 -7
  115. package/dist/plugins/diagnostics/index.d.cts +0 -15
  116. package/dist/plugins/diagnostics/index.d.ts +0 -15
  117. package/dist/plugins/diagnostics/index.js +0 -2
  118. package/dist/plugins/diagnostics/index.js.map +0 -7
  119. package/dist/plugins/execution-paths/index.cjs +0 -2
  120. package/dist/plugins/execution-paths/index.cjs.map +0 -7
  121. package/dist/plugins/execution-paths/index.d.cts +0 -18
  122. package/dist/plugins/execution-paths/index.d.ts +0 -18
  123. package/dist/plugins/execution-paths/index.js +0 -2
  124. package/dist/plugins/execution-paths/index.js.map +0 -7
  125. package/dist/plugins/persistence/controller.d.cts +0 -17
  126. package/dist/plugins/persistence/controller.d.ts +0 -17
  127. package/dist/plugins/persistence/index.cjs +0 -2
  128. package/dist/plugins/persistence/index.cjs.map +0 -7
  129. package/dist/plugins/persistence/index.d.cts +0 -12
  130. package/dist/plugins/persistence/index.d.ts +0 -12
  131. package/dist/plugins/persistence/index.js +0 -2
  132. package/dist/plugins/persistence/index.js.map +0 -7
  133. package/dist/plugins/replay/index.cjs +0 -2
  134. package/dist/plugins/replay/index.cjs.map +0 -7
  135. package/dist/plugins/replay/index.d.cts +0 -27
  136. package/dist/plugins/replay/index.d.ts +0 -27
  137. package/dist/plugins/replay/index.js +0 -2
  138. package/dist/plugins/replay/index.js.map +0 -7
  139. package/dist/types/analytics.types.d.cts +0 -33
  140. package/dist/types/analytics.types.d.ts +0 -33
  141. package/dist/types/autosave.types.d.cts +0 -23
  142. package/dist/types/autosave.types.d.ts +0 -23
  143. package/dist/types/diagnostics.types.d.cts +0 -38
  144. package/dist/types/diagnostics.types.d.ts +0 -38
  145. package/dist/types/index.d.cts +0 -9
  146. package/dist/types/index.d.ts +0 -9
  147. package/dist/types/journey.types.d.cts +0 -191
  148. package/dist/types/journey.types.d.ts +0 -191
  149. package/dist/types/machine.types.d.cts +0 -104
  150. package/dist/types/machine.types.d.ts +0 -104
  151. package/dist/types/observation.types.d.cts +0 -83
  152. package/dist/types/observation.types.d.ts +0 -83
  153. package/dist/types/persistence.types.d.cts +0 -34
  154. package/dist/types/persistence.types.d.ts +0 -34
  155. package/dist/types/replay.types.d.cts +0 -35
  156. package/dist/types/replay.types.d.ts +0 -35
  157. package/dist/types/transitions.types.d.cts +0 -122
  158. package/dist/types/transitions.types.d.ts +0 -122
@@ -1,52 +0,0 @@
1
- import type { JourneyAsyncState, JourneyEvent, JourneyGoToEvent, JourneyJsonObject, JourneyPayloadFor, JourneyResolvedTransition, JourneySendEvent, JourneySendResult, JourneySnapshot, JourneyStatus, JourneyStepAsyncState, JourneyTerminal, JourneyTransition, JourneyTransitionArgs } from "../types";
2
- export declare const assertStepExists: <TStepId extends string>(steps: Record<TStepId, unknown>, stepId: TStepId, message: string) => void;
3
- export declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
4
- export declare function assertSerializableContext<TContext extends JourneyJsonObject>(context: TContext, label?: string): TContext;
5
- export declare const cloneContext: <TContext extends JourneyJsonObject>(context: TContext) => TContext;
6
- export declare const cloneMetaValue: <T>(value: T) => T;
7
- export declare const normalizeStepCount: (steps?: number) => number;
8
- export declare const now: () => number;
9
- export declare const buildVisitedFromTimeline: <TStepId extends string>(timeline: readonly TStepId[], stepIds?: readonly TStepId[]) => Record<TStepId, boolean>;
10
- export declare const appendVisited: <TStepId extends string>(visited: Record<TStepId, boolean>, current: TStepId) => Record<TStepId, boolean>;
11
- export declare const isPromiseLike: <T>(value: T | PromiseLike<T>) => value is PromiseLike<T>;
12
- export declare const validateFiniteTimeout: (timeoutMs: unknown, label: string) => void;
13
- export declare class JourneyTimeoutError extends Error {
14
- name: string;
15
- constructor(message: string);
16
- }
17
- export declare class JourneyDisposedError extends Error {
18
- name: string;
19
- readonly operation: string;
20
- constructor(operation: string);
21
- }
22
- export declare const isDevelopmentEnvironment: () => boolean;
23
- export declare const warnInDevelopment: (message: string, detail?: unknown) => void;
24
- export declare const errorInDevelopment: (message: string, detail?: unknown) => void;
25
- export declare const withTimeout: <T>(promise: PromiseLike<T>, timeoutMs: number | undefined, buildError: () => Error) => Promise<T>;
26
- export declare const withAbortSignal: <T>(promise: PromiseLike<T>, signal: AbortSignal) => Promise<T>;
27
- export declare const buildIdleStepAsyncState: () => JourneyStepAsyncState;
28
- export declare const buildInitialAsyncState: <TStepId extends string>(steps: Record<TStepId, unknown>) => JourneyAsyncState<TStepId>;
29
- export declare const isGoToStepByIdEvent: <TStepId extends string, TEventMap extends Record<string, unknown>>(event: JourneySendEvent<TStepId, TEventMap>) => event is JourneyGoToEvent<TStepId, JourneyPayloadFor<TEventMap, "goToStepById">>;
30
- export declare const isTerminalTarget: <TStepId extends string>(target: TStepId | JourneyTerminal) => target is JourneyTerminal;
31
- export declare const resolveTransitionTarget: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(transition: JourneyTransition<TContext, TStepId, TEventMap, THandlers>) => TStepId | JourneyTerminal;
32
- export declare const validateJourneyTransitions: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[], steps: Record<TStepId, unknown>) => void;
33
- export declare const buildSendResult: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>, transitioned: boolean, options?: {
34
- transitionId?: string;
35
- label?: string;
36
- error?: unknown;
37
- }) => JourneySendResult<TContext, TStepId>;
38
- export declare const buildSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(timeline: readonly TStepId[], index: number, context: TContext, status: JourneyStatus, asyncState: JourneyAsyncState<TStepId>, visited?: Record<TStepId, boolean>) => JourneySnapshot<TContext, TStepId>;
39
- export declare const stabilizeSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>) => JourneySnapshot<TContext, TStepId>;
40
- export declare const selectTransition: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>, TTransition extends {
41
- from: TStepId | "*";
42
- event: string;
43
- when?: (args: JourneyTransitionArgs<TContext, TStepId, TEventMap, THandlers>) => boolean | Promise<boolean>;
44
- timeoutMs?: number;
45
- id?: string;
46
- label?: string;
47
- }>(transitions: readonly TTransition[], snapshot: JourneySnapshot<TContext, TStepId>, event: JourneyEvent<TStepId, TEventMap>, signal: AbortSignal, handlers: THandlers, hooks?: {
48
- onAsyncGuardStart?: (transition: TTransition) => void;
49
- onAsyncGuardSuccess?: (transition: TTransition) => void;
50
- onAsyncGuardError?: (transition: TTransition, error: unknown) => void;
51
- }, defaultTimeoutMs?: number) => Promise<TTransition | null>;
52
- export declare const transitionSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>, nextCurrent: TStepId, nextContext: TContext) => JourneySnapshot<TContext, TStepId>;
@@ -1,52 +0,0 @@
1
- import type { JourneyAsyncState, JourneyEvent, JourneyGoToEvent, JourneyJsonObject, JourneyPayloadFor, JourneyResolvedTransition, JourneySendEvent, JourneySendResult, JourneySnapshot, JourneyStatus, JourneyStepAsyncState, JourneyTerminal, JourneyTransition, JourneyTransitionArgs } from "../types";
2
- export declare const assertStepExists: <TStepId extends string>(steps: Record<TStepId, unknown>, stepId: TStepId, message: string) => void;
3
- export declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
4
- export declare function assertSerializableContext<TContext extends JourneyJsonObject>(context: TContext, label?: string): TContext;
5
- export declare const cloneContext: <TContext extends JourneyJsonObject>(context: TContext) => TContext;
6
- export declare const cloneMetaValue: <T>(value: T) => T;
7
- export declare const normalizeStepCount: (steps?: number) => number;
8
- export declare const now: () => number;
9
- export declare const buildVisitedFromTimeline: <TStepId extends string>(timeline: readonly TStepId[], stepIds?: readonly TStepId[]) => Record<TStepId, boolean>;
10
- export declare const appendVisited: <TStepId extends string>(visited: Record<TStepId, boolean>, current: TStepId) => Record<TStepId, boolean>;
11
- export declare const isPromiseLike: <T>(value: T | PromiseLike<T>) => value is PromiseLike<T>;
12
- export declare const validateFiniteTimeout: (timeoutMs: unknown, label: string) => void;
13
- export declare class JourneyTimeoutError extends Error {
14
- name: string;
15
- constructor(message: string);
16
- }
17
- export declare class JourneyDisposedError extends Error {
18
- name: string;
19
- readonly operation: string;
20
- constructor(operation: string);
21
- }
22
- export declare const isDevelopmentEnvironment: () => boolean;
23
- export declare const warnInDevelopment: (message: string, detail?: unknown) => void;
24
- export declare const errorInDevelopment: (message: string, detail?: unknown) => void;
25
- export declare const withTimeout: <T>(promise: PromiseLike<T>, timeoutMs: number | undefined, buildError: () => Error) => Promise<T>;
26
- export declare const withAbortSignal: <T>(promise: PromiseLike<T>, signal: AbortSignal) => Promise<T>;
27
- export declare const buildIdleStepAsyncState: () => JourneyStepAsyncState;
28
- export declare const buildInitialAsyncState: <TStepId extends string>(steps: Record<TStepId, unknown>) => JourneyAsyncState<TStepId>;
29
- export declare const isGoToStepByIdEvent: <TStepId extends string, TEventMap extends Record<string, unknown>>(event: JourneySendEvent<TStepId, TEventMap>) => event is JourneyGoToEvent<TStepId, JourneyPayloadFor<TEventMap, "goToStepById">>;
30
- export declare const isTerminalTarget: <TStepId extends string>(target: TStepId | JourneyTerminal) => target is JourneyTerminal;
31
- export declare const resolveTransitionTarget: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(transition: JourneyTransition<TContext, TStepId, TEventMap, THandlers>) => TStepId | JourneyTerminal;
32
- export declare const validateJourneyTransitions: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[], steps: Record<TStepId, unknown>) => void;
33
- export declare const buildSendResult: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>, transitioned: boolean, options?: {
34
- transitionId?: string;
35
- label?: string;
36
- error?: unknown;
37
- }) => JourneySendResult<TContext, TStepId>;
38
- export declare const buildSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(timeline: readonly TStepId[], index: number, context: TContext, status: JourneyStatus, asyncState: JourneyAsyncState<TStepId>, visited?: Record<TStepId, boolean>) => JourneySnapshot<TContext, TStepId>;
39
- export declare const stabilizeSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>) => JourneySnapshot<TContext, TStepId>;
40
- export declare const selectTransition: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>, TTransition extends {
41
- from: TStepId | "*";
42
- event: string;
43
- when?: (args: JourneyTransitionArgs<TContext, TStepId, TEventMap, THandlers>) => boolean | Promise<boolean>;
44
- timeoutMs?: number;
45
- id?: string;
46
- label?: string;
47
- }>(transitions: readonly TTransition[], snapshot: JourneySnapshot<TContext, TStepId>, event: JourneyEvent<TStepId, TEventMap>, signal: AbortSignal, handlers: THandlers, hooks?: {
48
- onAsyncGuardStart?: (transition: TTransition) => void;
49
- onAsyncGuardSuccess?: (transition: TTransition) => void;
50
- onAsyncGuardError?: (transition: TTransition, error: unknown) => void;
51
- }, defaultTimeoutMs?: number) => Promise<TTransition | null>;
52
- export declare const transitionSnapshot: <TContext extends JourneyJsonObject, TStepId extends string>(snapshot: JourneySnapshot<TContext, TStepId>, nextCurrent: TStepId, nextContext: TContext) => JourneySnapshot<TContext, TStepId>;
@@ -1,3 +0,0 @@
1
- import type { JourneyDefinition, JourneyJsonObject, JourneyMachinePlugin, JourneyMachineOptions, JourneyMachineWithPlugins } from "../types";
2
- /** Creates a journey machine from a definition and optional runtime/plugin options. */
3
- export declare function createJourneyMachine<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>, TPlugins extends readonly JourneyMachinePlugin[] = []>(journey: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyMachineOptions<TPlugins>): JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>;
@@ -1,3 +0,0 @@
1
- import type { JourneyDefinition, JourneyJsonObject, JourneyMachinePlugin, JourneyMachineOptions, JourneyMachineWithPlugins } from "../types";
2
- /** Creates a journey machine from a definition and optional runtime/plugin options. */
3
- export declare function createJourneyMachine<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>, TPlugins extends readonly JourneyMachinePlugin[] = []>(journey: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyMachineOptions<TPlugins>): JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>;
@@ -1,32 +0,0 @@
1
- import type { JourneyEvent, JourneyJsonObject, JourneyResolvedTransition, JourneySendResult, JourneySnapshot, JourneyTerminal } from "../types";
2
- import type { JourneyMachineRuntime } from "./runtime";
3
- export type JourneyLifecycleScheduler<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>> = (args: {
4
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
5
- snapshot: JourneySnapshot<TContext, TStepId>;
6
- from: TStepId;
7
- to: TStepId | JourneyTerminal;
8
- event: JourneyEvent<TStepId, TEventMap> | {
9
- type: "goToLastVisitedStep";
10
- } | {
11
- type: "goToPreviousStep";
12
- };
13
- transitionId: string | null;
14
- label?: string;
15
- runVersion: number;
16
- transition?: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>;
17
- }) => void;
18
- export type JourneyMachineNavigationController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>> = {
19
- applyPreviousNavigation: (requestedSteps?: number, transitionId?: string, runVersion?: number) => JourneySendResult<TContext, TStepId>;
20
- applyLastVisitedNavigation: (transitionId?: string, runVersion?: number) => JourneySendResult<TContext, TStepId>;
21
- hasDeclaredTransitionForEvent: (fromStep: TStepId, eventType: string) => boolean;
22
- commitTerminalTransition: (fromStep: TStepId, target: JourneyTerminal, transitionEvent: {
23
- type: string;
24
- }, transitionId: string | null, transition: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers> | undefined, nextContext: TContext, runVersion?: number) => JourneySendResult<TContext, TStepId>;
25
- commitStepTransition: (fromStep: TStepId, target: TStepId, transitionEvent: JourneyEvent<TStepId, TEventMap>, transition: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>, nextContext: TContext, runVersion?: number) => JourneySendResult<TContext, TStepId>;
26
- };
27
- export declare const createJourneyMachineNavigationController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>({ runtime, steps, transitions, scheduleLifecycle }: {
28
- runtime: JourneyMachineRuntime<TContext, TStepId, TEventMap>;
29
- steps: Record<TStepId, unknown>;
30
- transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[];
31
- scheduleLifecycle: JourneyLifecycleScheduler<TContext, TStepId, TEventMap, THandlers>;
32
- }) => JourneyMachineNavigationController<TContext, TStepId, TEventMap, THandlers>;
@@ -1,32 +0,0 @@
1
- import type { JourneyEvent, JourneyJsonObject, JourneyResolvedTransition, JourneySendResult, JourneySnapshot, JourneyTerminal } from "../types";
2
- import type { JourneyMachineRuntime } from "./runtime";
3
- export type JourneyLifecycleScheduler<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>> = (args: {
4
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
5
- snapshot: JourneySnapshot<TContext, TStepId>;
6
- from: TStepId;
7
- to: TStepId | JourneyTerminal;
8
- event: JourneyEvent<TStepId, TEventMap> | {
9
- type: "goToLastVisitedStep";
10
- } | {
11
- type: "goToPreviousStep";
12
- };
13
- transitionId: string | null;
14
- label?: string;
15
- runVersion: number;
16
- transition?: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>;
17
- }) => void;
18
- export type JourneyMachineNavigationController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>> = {
19
- applyPreviousNavigation: (requestedSteps?: number, transitionId?: string, runVersion?: number) => JourneySendResult<TContext, TStepId>;
20
- applyLastVisitedNavigation: (transitionId?: string, runVersion?: number) => JourneySendResult<TContext, TStepId>;
21
- hasDeclaredTransitionForEvent: (fromStep: TStepId, eventType: string) => boolean;
22
- commitTerminalTransition: (fromStep: TStepId, target: JourneyTerminal, transitionEvent: {
23
- type: string;
24
- }, transitionId: string | null, transition: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers> | undefined, nextContext: TContext, runVersion?: number) => JourneySendResult<TContext, TStepId>;
25
- commitStepTransition: (fromStep: TStepId, target: TStepId, transitionEvent: JourneyEvent<TStepId, TEventMap>, transition: JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>, nextContext: TContext, runVersion?: number) => JourneySendResult<TContext, TStepId>;
26
- };
27
- export declare const createJourneyMachineNavigationController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>({ runtime, steps, transitions, scheduleLifecycle }: {
28
- runtime: JourneyMachineRuntime<TContext, TStepId, TEventMap>;
29
- steps: Record<TStepId, unknown>;
30
- transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[];
31
- scheduleLifecycle: JourneyLifecycleScheduler<TContext, TStepId, TEventMap, THandlers>;
32
- }) => JourneyMachineNavigationController<TContext, TStepId, TEventMap, THandlers>;
@@ -1,15 +0,0 @@
1
- import type { JourneyJsonObject, JourneyMachine, JourneyMachinePlugin, JourneyMachinePluginSetupContext, JourneyMachineSnapshotReason, JourneySnapshot } from "../types";
2
- export type JourneyMachinePluginController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta, THandlers extends Record<string, unknown>> = {
3
- hydrateSnapshot: (snapshot: JourneySnapshot<TContext, TStepId>) => JourneySnapshot<TContext, TStepId>;
4
- onSnapshotChange: (args: {
5
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
6
- snapshot: JourneySnapshot<TContext, TStepId>;
7
- reason: JourneyMachineSnapshotReason;
8
- }) => void;
9
- extendMachine: (machine: JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers>) => JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
10
- dispose: () => void;
11
- };
12
- export declare const createJourneyMachinePluginController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta, THandlers extends Record<string, unknown> = Record<never, never>>({ plugins, setupContext }: {
13
- plugins: readonly JourneyMachinePlugin[];
14
- setupContext: JourneyMachinePluginSetupContext<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
15
- }) => JourneyMachinePluginController<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
@@ -1,15 +0,0 @@
1
- import type { JourneyJsonObject, JourneyMachine, JourneyMachinePlugin, JourneyMachinePluginSetupContext, JourneyMachineSnapshotReason, JourneySnapshot } from "../types";
2
- export type JourneyMachinePluginController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta, THandlers extends Record<string, unknown>> = {
3
- hydrateSnapshot: (snapshot: JourneySnapshot<TContext, TStepId>) => JourneySnapshot<TContext, TStepId>;
4
- onSnapshotChange: (args: {
5
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
6
- snapshot: JourneySnapshot<TContext, TStepId>;
7
- reason: JourneyMachineSnapshotReason;
8
- }) => void;
9
- extendMachine: (machine: JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers>) => JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
10
- dispose: () => void;
11
- };
12
- export declare const createJourneyMachinePluginController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta, THandlers extends Record<string, unknown> = Record<never, never>>({ plugins, setupContext }: {
13
- plugins: readonly JourneyMachinePlugin[];
14
- setupContext: JourneyMachinePluginSetupContext<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
15
- }) => JourneyMachinePluginController<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
@@ -1,2 +0,0 @@
1
- import type { JourneyDefinition, JourneyJsonObject, JourneyResolvedDefinition } from "../types";
2
- export declare const resolveJourneyDefinition: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>>(journey: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>) => JourneyResolvedDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
@@ -1,2 +0,0 @@
1
- import type { JourneyDefinition, JourneyJsonObject, JourneyResolvedDefinition } from "../types";
2
- export declare const resolveJourneyDefinition: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>>(journey: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>) => JourneyResolvedDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>;
@@ -1,33 +0,0 @@
1
- import type { JourneyEqualityFn, JourneyJsonObject, JourneyMachineSnapshotReason, JourneyObservationEvent, JourneySelector, JourneySnapshot } from "../types";
2
- type SnapshotOptions = {
3
- notify?: boolean;
4
- reason?: JourneyMachineSnapshotReason;
5
- };
6
- export type JourneyMachineRuntime<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>> = {
7
- getSnapshot: () => JourneySnapshot<TContext, TStepId>;
8
- peekSnapshot: () => JourneySnapshot<TContext, TStepId>;
9
- setSnapshot: (nextSnapshot: JourneySnapshot<TContext, TStepId>, options?: SnapshotOptions) => JourneySnapshot<TContext, TStepId>;
10
- isDisposed: () => boolean;
11
- isRunActive: (runVersion: number) => boolean;
12
- cancelInFlight: () => void;
13
- openLifecycle: (runVersion: number) => AbortController | null;
14
- closeLifecycle: (controller: AbortController) => void;
15
- queue: <T>(runner: (runVersion: number, signal: AbortSignal) => Promise<T>, onCanceled: () => T) => Promise<T>;
16
- notify: () => void;
17
- emit: (event: JourneyObservationEvent<TStepId, TEventMap>) => void;
18
- subscribe: (listener: () => void) => () => void;
19
- subscribeSelector: <TSelected>(selector: JourneySelector<TContext, TStepId, TSelected>, listener: (next: TSelected, previous: TSelected) => void, equalityFn?: JourneyEqualityFn<TSelected>) => () => void;
20
- subscribeEvent: (listener: (event: JourneyObservationEvent<TStepId, TEventMap>) => void) => () => void;
21
- dispose: () => void;
22
- };
23
- export declare const createJourneyMachineRuntime: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>>({ snapshot: initialSnapshot, onSnapshotChange, onDispose, onListenerError }: {
24
- snapshot: JourneySnapshot<TContext, TStepId>;
25
- onSnapshotChange?: (args: {
26
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
27
- snapshot: JourneySnapshot<TContext, TStepId>;
28
- reason: JourneyMachineSnapshotReason;
29
- }) => void;
30
- onDispose?: () => void;
31
- onListenerError?: (error: unknown, context: "snapshot" | "event") => void;
32
- }) => JourneyMachineRuntime<TContext, TStepId, TEventMap>;
33
- export {};
@@ -1,33 +0,0 @@
1
- import type { JourneyEqualityFn, JourneyJsonObject, JourneyMachineSnapshotReason, JourneyObservationEvent, JourneySelector, JourneySnapshot } from "../types";
2
- type SnapshotOptions = {
3
- notify?: boolean;
4
- reason?: JourneyMachineSnapshotReason;
5
- };
6
- export type JourneyMachineRuntime<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>> = {
7
- getSnapshot: () => JourneySnapshot<TContext, TStepId>;
8
- peekSnapshot: () => JourneySnapshot<TContext, TStepId>;
9
- setSnapshot: (nextSnapshot: JourneySnapshot<TContext, TStepId>, options?: SnapshotOptions) => JourneySnapshot<TContext, TStepId>;
10
- isDisposed: () => boolean;
11
- isRunActive: (runVersion: number) => boolean;
12
- cancelInFlight: () => void;
13
- openLifecycle: (runVersion: number) => AbortController | null;
14
- closeLifecycle: (controller: AbortController) => void;
15
- queue: <T>(runner: (runVersion: number, signal: AbortSignal) => Promise<T>, onCanceled: () => T) => Promise<T>;
16
- notify: () => void;
17
- emit: (event: JourneyObservationEvent<TStepId, TEventMap>) => void;
18
- subscribe: (listener: () => void) => () => void;
19
- subscribeSelector: <TSelected>(selector: JourneySelector<TContext, TStepId, TSelected>, listener: (next: TSelected, previous: TSelected) => void, equalityFn?: JourneyEqualityFn<TSelected>) => () => void;
20
- subscribeEvent: (listener: (event: JourneyObservationEvent<TStepId, TEventMap>) => void) => () => void;
21
- dispose: () => void;
22
- };
23
- export declare const createJourneyMachineRuntime: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>>({ snapshot: initialSnapshot, onSnapshotChange, onDispose, onListenerError }: {
24
- snapshot: JourneySnapshot<TContext, TStepId>;
25
- onSnapshotChange?: (args: {
26
- previousSnapshot: JourneySnapshot<TContext, TStepId>;
27
- snapshot: JourneySnapshot<TContext, TStepId>;
28
- reason: JourneyMachineSnapshotReason;
29
- }) => void;
30
- onDispose?: () => void;
31
- onListenerError?: (error: unknown, context: "snapshot" | "event") => void;
32
- }) => JourneyMachineRuntime<TContext, TStepId, TEventMap>;
33
- export {};
@@ -1,9 +0,0 @@
1
- import type { JourneyJsonObject, JourneyResolvedTransition, JourneySendEvent, JourneySendResult } from "../types";
2
- import type { JourneyMachineAsyncStateController } from "./async-state";
3
- import type { JourneyMachineNavigationController } from "./navigation";
4
- import type { JourneyMachineRuntime } from "./runtime";
5
- export type JourneyMachineSendController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>> = {
6
- executeSend: (event: JourneySendEvent<TStepId, TEventMap>, runVersion: number, signal: AbortSignal) => Promise<JourneySendResult<TContext, TStepId>>;
7
- buildCanceledSendResult: (operation?: string) => JourneySendResult<TContext, TStepId>;
8
- };
9
- export declare const createJourneyMachineSendController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(runtime: JourneyMachineRuntime<TContext, TStepId, TEventMap>, asyncState: JourneyMachineAsyncStateController<TStepId>, navigation: JourneyMachineNavigationController<TContext, TStepId, TEventMap, THandlers>, headless: boolean, steps: Record<TStepId, unknown>, transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[], handlers: THandlers, requireExplicitCompletion: boolean, defaultTimeoutMs: number | undefined) => JourneyMachineSendController<TContext, TStepId, TEventMap>;
@@ -1,9 +0,0 @@
1
- import type { JourneyJsonObject, JourneyResolvedTransition, JourneySendEvent, JourneySendResult } from "../types";
2
- import type { JourneyMachineAsyncStateController } from "./async-state";
3
- import type { JourneyMachineNavigationController } from "./navigation";
4
- import type { JourneyMachineRuntime } from "./runtime";
5
- export type JourneyMachineSendController<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>> = {
6
- executeSend: (event: JourneySendEvent<TStepId, TEventMap>, runVersion: number, signal: AbortSignal) => Promise<JourneySendResult<TContext, TStepId>>;
7
- buildCanceledSendResult: (operation?: string) => JourneySendResult<TContext, TStepId>;
8
- };
9
- export declare const createJourneyMachineSendController: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown>, THandlers extends Record<string, unknown>>(runtime: JourneyMachineRuntime<TContext, TStepId, TEventMap>, asyncState: JourneyMachineAsyncStateController<TStepId>, navigation: JourneyMachineNavigationController<TContext, TStepId, TEventMap, THandlers>, headless: boolean, steps: Record<TStepId, unknown>, transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[], handlers: THandlers, requireExplicitCompletion: boolean, defaultTimeoutMs: number | undefined) => JourneyMachineSendController<TContext, TStepId, TEventMap>;
@@ -1,2 +0,0 @@
1
- "use strict";var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var b=(n,t)=>{for(var i in t)m(n,i,{get:t[i],enumerable:!0})},I=(n,t,i,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of S(t))!x.call(n,a)&&a!==i&&m(n,a,{get:()=>t[a],enumerable:!(c=f(t,a))||c.enumerable});return n};var J=n=>I(m({},"__esModule",{value:!0}),n);var g={};b(g,{createAnalyticsPlugin:()=>E});module.exports=J(g);var w=()=>{let n=globalThis;if(typeof n.__DEV__=="boolean")return n.__DEV__;let t=n.process?.env?.NODE_ENV;return t===void 0||t==="development"},l=(n,t)=>{if(!(!w()||typeof console>"u")){if(t===void 0){console.warn(n);return}console.warn(n,t)}};var h=({context:n})=>({context:n}),E=n=>{let t,i=null,c=null,a=(y,u)=>{try{n.track(u)}catch(r){if(n.onError){n.onError(r,y);return}l("Journey analytics track() threw without an onError handler.",r)}};return{name:"analytics",setup:()=>({augmentMachine:({machine:y})=>{let u=y,r=(s,e)=>{a(s,e)},p=s=>{if(!n.includeStepMeta)return{};let e=u.getStepMeta(s);return e===void 0?{}:{stepMeta:e}},T=({from:s,to:e})=>{if(!n.includeStepMeta)return{};let d=u.getStepMeta(s),o=e==="COMPLETE"||e==="TERMINATED"?void 0:u.getStepMeta(e);return{...d===void 0?{}:{fromStepMeta:d},...o===void 0?{}:{toStepMeta:o}}};return t=u.subscribeEvent(s=>{let e=s,d=u.getSnapshot(),o=h({context:d.context});switch(e.type){case"journey.start":i=e.timestamp,c=e.timestamp,r(e,{name:"journey_started",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...p(e.stepId),...o}});return;case"step.enter":c=e.timestamp,r(e,{name:"step_viewed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...p(e.stepId),...o}});return;case"step.exit":r(e,{name:"step_exited",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...c===null?{}:{dwellMs:Math.max(0,e.timestamp-c)},...p(e.stepId),...o}});return;case"transition.start":r(e,{name:"transition_started",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,eventType:e.event.type,...o}});return;case"transition.success":r(e,{name:"transition_succeeded",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,eventType:e.eventType,transitionId:e.transitionId,...e.label!==void 0?{label:e.label}:{},...T({from:e.from,to:e.to}),...o}});return;case"transition.error":r(e,{name:"transition_failed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,eventType:e.eventType,transitionId:e.transitionId,...e.label!==void 0?{label:e.label}:{},error:e.error,...o}});return;case"journey.completed":r(e,{name:"journey_completed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...i===null?{}:{durationMs:Math.max(0,e.timestamp-i)},...p(e.stepId),...o}});return;case"journey.terminated":r(e,{name:"journey_terminated",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...i===null?{}:{durationMs:Math.max(0,e.timestamp-i)},...p(e.stepId),...o}});return;case"navigation.previous":r(e,{name:"navigation_previous",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,requestedSteps:e.requestedSteps,appliedSteps:e.appliedSteps,...T({from:e.from,to:e.to}),...o}});return;case"navigation.lastVisited":r(e,{name:"navigation_last_visited",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,...T({from:e.from,to:e.to}),...o}});return}}),{trackAnalyticsEvent:(s,e={})=>{let d={name:s,timestamp:Date.now(),...n.machineId?{machineId:n.machineId}:{},payload:e};return a(d,d),d}}},dispose:()=>{t?.()}})}};0&&(module.exports={createAnalyticsPlugin});
2
- //# sourceMappingURL=index.cjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugins/analytics/index.ts", "../../../src/journey-machine/helpers.ts"],
4
- "sourcesContent": ["import { warnInDevelopment } from \"../../journey-machine/helpers\";\n\nimport type {\n JourneyAnalyticsPluginOptions,\n JourneyAnalyticsTrackedEvent,\n JourneyJsonObject,\n JourneyMachine,\n JourneyMachinePlugin,\n JourneyObservationEvent,\n JourneyTerminal\n} from \"../../types\";\n\nconst buildBasePayload = <TContext extends JourneyJsonObject>({\n context\n}: {\n context: TContext;\n}) => ({ context });\n\nexport type JourneyAnalyticsMachineExtension<\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TStepMeta\n> = {\n trackAnalyticsEvent: (\n name: string,\n payload?: Record<string, unknown>\n ) => JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>;\n};\n\nexport type JourneyAnalyticsMachine<\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TEventMap extends Record<string, unknown> = Record<never, never>,\n TStepMeta = unknown,\n THandlers extends Record<string, unknown> = Record<never, never>\n> = JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers> &\n JourneyAnalyticsMachineExtension<TContext, TStepId, TStepMeta>;\n\n/** Creates a plugin that converts journey observation events into analytics envelopes. */\nexport const createAnalyticsPlugin = <\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TEventMap extends Record<string, unknown> = Record<never, never>,\n TStepMeta = unknown\n>(\n options: JourneyAnalyticsPluginOptions<TContext, TStepId, TEventMap, TStepMeta>\n) => {\n let unsubscribe: (() => void) | undefined;\n let startedAt: number | null = null;\n let activeStepEnteredAt: number | null = null;\n\n const trackSafely = (\n event:\n | JourneyObservationEvent<TStepId, TEventMap>\n | JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>,\n tracked: JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>\n ) => {\n try {\n options.track(tracked);\n } catch (error) {\n if (options.onError) {\n options.onError(error, event);\n return;\n }\n\n warnInDevelopment(\"Journey analytics track() threw without an onError handler.\", error);\n }\n };\n\n return {\n name: \"analytics\",\n setup: () => ({\n augmentMachine: ({ machine }) => {\n const typedMachine = machine as JourneyMachine<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n Record<string, unknown>\n >;\n\n const emitTracked = (\n sourceEvent: JourneyObservationEvent<TStepId, TEventMap>,\n tracked: JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>\n ) => {\n trackSafely(sourceEvent, tracked);\n };\n\n const buildStepMetaPayload = (stepId: TStepId) => {\n if (!options.includeStepMeta) {\n return {};\n }\n\n const stepMeta = typedMachine.getStepMeta(stepId) as TStepMeta | undefined;\n return stepMeta === undefined ? {} : { stepMeta };\n };\n\n const buildTransitionMetaPayload = ({\n from,\n to\n }: {\n from: TStepId;\n to: TStepId | JourneyTerminal;\n }) => {\n if (!options.includeStepMeta) {\n return {};\n }\n\n const fromStepMeta = typedMachine.getStepMeta(from) as TStepMeta | undefined;\n const toStepMeta =\n to === \"COMPLETE\" || to === \"TERMINATED\"\n ? undefined\n : (typedMachine.getStepMeta(to) as TStepMeta | undefined);\n\n return {\n ...(fromStepMeta === undefined ? {} : { fromStepMeta }),\n ...(toStepMeta === undefined ? {} : { toStepMeta })\n };\n };\n\n unsubscribe = typedMachine.subscribeEvent((event) => {\n const typedEvent = event as JourneyObservationEvent<TStepId, TEventMap>;\n const snapshot = typedMachine.getSnapshot();\n const basePayload = buildBasePayload({\n context: snapshot.context as TContext\n });\n\n switch (typedEvent.type) {\n case \"journey.start\":\n startedAt = typedEvent.timestamp;\n activeStepEnteredAt = typedEvent.timestamp;\n emitTracked(typedEvent, {\n name: \"journey_started\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n stepId: typedEvent.stepId,\n ...buildStepMetaPayload(typedEvent.stepId),\n ...basePayload\n }\n });\n return;\n case \"step.enter\":\n activeStepEnteredAt = typedEvent.timestamp;\n emitTracked(typedEvent, {\n name: \"step_viewed\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n stepId: typedEvent.stepId,\n ...buildStepMetaPayload(typedEvent.stepId),\n ...basePayload\n }\n });\n return;\n case \"step.exit\":\n emitTracked(typedEvent, {\n name: \"step_exited\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n stepId: typedEvent.stepId,\n ...(activeStepEnteredAt === null\n ? {}\n : { dwellMs: Math.max(0, typedEvent.timestamp - activeStepEnteredAt) }),\n ...buildStepMetaPayload(typedEvent.stepId),\n ...basePayload\n }\n });\n return;\n case \"transition.start\":\n emitTracked(typedEvent, {\n name: \"transition_started\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n from: typedEvent.from,\n eventType: typedEvent.event.type,\n ...basePayload\n }\n });\n return;\n case \"transition.success\":\n emitTracked(typedEvent, {\n name: \"transition_succeeded\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n from: typedEvent.from,\n to: typedEvent.to,\n eventType: typedEvent.eventType,\n transitionId: typedEvent.transitionId,\n ...(typedEvent.label !== undefined ? { label: typedEvent.label } : {}),\n ...buildTransitionMetaPayload({\n from: typedEvent.from,\n to: typedEvent.to as TStepId | JourneyTerminal\n }),\n ...basePayload\n }\n });\n return;\n case \"transition.error\":\n emitTracked(typedEvent, {\n name: \"transition_failed\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n from: typedEvent.from,\n eventType: typedEvent.eventType,\n transitionId: typedEvent.transitionId,\n ...(typedEvent.label !== undefined ? { label: typedEvent.label } : {}),\n error: typedEvent.error,\n ...basePayload\n }\n });\n return;\n case \"journey.completed\":\n emitTracked(typedEvent, {\n name: \"journey_completed\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n stepId: typedEvent.stepId,\n ...(startedAt === null\n ? {}\n : { durationMs: Math.max(0, typedEvent.timestamp - startedAt) }),\n ...buildStepMetaPayload(typedEvent.stepId),\n ...basePayload\n }\n });\n return;\n case \"journey.terminated\":\n emitTracked(typedEvent, {\n name: \"journey_terminated\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n stepId: typedEvent.stepId,\n ...(startedAt === null\n ? {}\n : { durationMs: Math.max(0, typedEvent.timestamp - startedAt) }),\n ...buildStepMetaPayload(typedEvent.stepId),\n ...basePayload\n }\n });\n return;\n case \"navigation.previous\":\n emitTracked(typedEvent, {\n name: \"navigation_previous\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n from: typedEvent.from,\n to: typedEvent.to,\n requestedSteps: typedEvent.requestedSteps,\n appliedSteps: typedEvent.appliedSteps,\n ...buildTransitionMetaPayload({\n from: typedEvent.from,\n to: typedEvent.to\n }),\n ...basePayload\n }\n });\n return;\n case \"navigation.lastVisited\":\n emitTracked(typedEvent, {\n name: \"navigation_last_visited\",\n timestamp: typedEvent.timestamp,\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload: {\n from: typedEvent.from,\n to: typedEvent.to,\n ...buildTransitionMetaPayload({\n from: typedEvent.from,\n to: typedEvent.to\n }),\n ...basePayload\n }\n });\n return;\n }\n });\n\n return {\n trackAnalyticsEvent: (name: string, payload: Record<string, unknown> = {}) => {\n const tracked = {\n name,\n timestamp: Date.now(),\n ...(options.machineId ? { machineId: options.machineId } : {}),\n payload\n } satisfies JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>;\n trackSafely(tracked, tracked);\n return tracked;\n }\n };\n },\n dispose: () => {\n unsubscribe?.();\n }\n })\n } satisfies JourneyMachinePlugin;\n};\n\nexport type { JourneyAnalyticsPluginOptions, JourneyAnalyticsTrackedEvent } from \"../../types\";\n", "import type {\n JourneyAsyncState,\n JourneyEvent,\n JourneyGoToEvent,\n JourneyJsonObject,\n JourneyJsonValue,\n JourneyPayloadFor,\n JourneyResolvedTransition,\n JourneySendEvent,\n JourneySendResult,\n JourneySnapshot,\n JourneyStatus,\n JourneyStepAsyncState,\n JourneyTerminal,\n JourneyTransition,\n JourneyTransitionArgs\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 isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);\n\nconst cloneSerializableValue = <T extends JourneyJsonValue>(value: T): T => {\n if (Array.isArray(value)) {\n return value.map((entry) => cloneSerializableValue(entry)) as T;\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n key,\n cloneSerializableValue(entryValue as JourneyJsonValue)\n ])\n ) as T;\n }\n\n return value;\n};\n\ntype SerializableCheckState = {\n readonly seen: WeakSet<object>;\n};\n\nconst describeValue = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n\n if (Array.isArray(value)) {\n return \"array\";\n }\n\n if (typeof value === \"object\") {\n const constructorName = (value as { constructor?: { name?: string } }).constructor?.name;\n return constructorName && constructorName !== \"Object\" ? constructorName : \"object\";\n }\n\n return typeof value;\n};\n\nfunction assertSerializableValue(\n value: unknown,\n label: string,\n state: SerializableCheckState,\n path: readonly string[] = []\n): asserts value is JourneyJsonValue {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return;\n }\n\n const pathLabel = path.length === 0 ? label : `${label}.${path.join(\".\")}`;\n\n if (value === undefined) {\n throw new Error(`${pathLabel} must be JSON-serializable. Received undefined.`);\n }\n\n if (typeof value === \"bigint\" || typeof value === \"symbol\" || typeof value === \"function\") {\n throw new Error(`${pathLabel} must be JSON-serializable. Received ${typeof value}.`);\n }\n\n if (typeof value !== \"object\") {\n throw new Error(`${pathLabel} must be JSON-serializable. Received ${describeValue(value)}.`);\n }\n\n if (state.seen.has(value)) {\n throw new Error(\n `${pathLabel} must be JSON-serializable. Circular references are not supported.`\n );\n }\n\n state.seen.add(value);\n\n if (Array.isArray(value)) {\n for (const [index, entryValue] of value.entries()) {\n assertSerializableValue(entryValue, label, state, [...path, String(index)]);\n }\n return;\n }\n\n if (!isPlainObject(value)) {\n throw new Error(\n `${pathLabel} must be JSON-serializable. Received non-plain ${describeValue(value)}.`\n );\n }\n\n for (const [key, entryValue] of Object.entries(value)) {\n assertSerializableValue(entryValue, label, state, [...path, key]);\n }\n}\n\nexport function assertSerializableContext<TContext extends JourneyJsonObject>(\n context: TContext,\n label = \"Journey context\"\n): TContext {\n assertSerializableValue(context, label, { seen: new WeakSet() });\n return context;\n}\n\nexport const cloneContext = <TContext extends JourneyJsonObject>(context: TContext): TContext =>\n cloneSerializableValue(assertSerializableContext(context));\n\nconst cloneDefinitionValueFallback = (value: unknown): unknown => {\n if (Array.isArray(value)) {\n return value.map((entry) => cloneDefinitionValueFallback(entry));\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime());\n }\n\n if (value instanceof Map) {\n return new Map(\n [...value.entries()].map(([key, entryValue]) => [\n cloneDefinitionValueFallback(key),\n cloneDefinitionValueFallback(entryValue)\n ])\n );\n }\n\n if (value instanceof Set) {\n return new Set([...value].map((entry) => cloneDefinitionValueFallback(entry)));\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n key,\n cloneDefinitionValueFallback(entryValue)\n ])\n );\n }\n\n return value;\n};\n\nexport const cloneMetaValue = <T>(value: T): T => {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return value;\n }\n\n if (typeof structuredClone === \"function\") {\n try {\n return structuredClone(value);\n } catch {\n return cloneDefinitionValueFallback(value) as T;\n }\n } else {\n return cloneDefinitionValueFallback(value) as T;\n }\n};\n\nconst freezeSnapshotValue = (value: unknown) => {\n if (typeof value !== \"object\" || value === null || Object.isFrozen(value)) {\n return;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n freezeSnapshotValue(item);\n }\n Object.freeze(value);\n return;\n }\n\n if (!isPlainObject(value)) {\n return;\n }\n\n for (const entryValue of Object.values(value)) {\n freezeSnapshotValue(entryValue);\n }\n Object.freeze(value);\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\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nexport const validateFiniteTimeout = (timeoutMs: unknown, label: string) => {\n if (timeoutMs !== undefined && !isFiniteNumber(timeoutMs)) {\n throw new Error(`${label} must define a finite numeric \"timeoutMs\" when provided.`);\n }\n};\n\nexport class JourneyTimeoutError extends Error {\n override name = \"JourneyTimeoutError\";\n\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class JourneyDisposedError extends Error {\n override name = \"JourneyDisposedError\";\n readonly operation: string;\n\n constructor(operation: string) {\n super(`Journey machine has been disposed; \"${operation}\" can no longer be used.`);\n this.operation = operation;\n }\n}\n\ntype DiagnosticGlobal = typeof globalThis & {\n __DEV__?: unknown;\n process?: {\n env?: {\n NODE_ENV?: string;\n };\n };\n};\n\nexport const isDevelopmentEnvironment = (): boolean => {\n const diagnosticGlobal = globalThis as DiagnosticGlobal;\n if (typeof diagnosticGlobal.__DEV__ === \"boolean\") {\n return diagnosticGlobal.__DEV__;\n }\n\n const nodeEnv = diagnosticGlobal.process?.env?.NODE_ENV;\n return nodeEnv === undefined || nodeEnv === \"development\";\n};\n\nexport const warnInDevelopment = (message: string, detail?: unknown) => {\n if (!isDevelopmentEnvironment() || typeof console === \"undefined\") {\n return;\n }\n\n if (detail === undefined) {\n console.warn(message);\n return;\n }\n\n console.warn(message, detail);\n};\n\nexport const errorInDevelopment = (message: string, detail?: unknown) => {\n if (!isDevelopmentEnvironment() || typeof console === \"undefined\") {\n return;\n }\n\n if (detail === undefined) {\n console.error(message);\n return;\n }\n\n console.error(message, detail);\n};\n\nexport const withTimeout = async <T>(\n promise: PromiseLike<T>,\n timeoutMs: number | undefined,\n buildError: () => Error\n): Promise<T> => {\n if (!isFiniteNumber(timeoutMs) || timeoutMs <= 0) {\n return await promise;\n }\n\n return await new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(buildError());\n }, timeoutMs);\n\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n }\n );\n });\n};\n\nexport const withAbortSignal = async <T>(\n promise: PromiseLike<T>,\n signal: AbortSignal\n): Promise<T> => {\n if (signal.aborted) {\n throw signal.reason;\n }\n\n return await new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(signal.reason);\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n }\n );\n });\n};\n\nexport const buildIdleStepAsyncState = (): JourneyStepAsyncState => ({\n 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 TEventMap extends Record<string, unknown>\n>(\n event: JourneySendEvent<TStepId, TEventMap>\n): event is JourneyGoToEvent<TStepId, JourneyPayloadFor<TEventMap, \"goToStepById\">> =>\n event.type === \"goToStepById\" && \"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 resolveTransitionTarget = <\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TEventMap extends Record<string, unknown>,\n THandlers extends Record<string, unknown>\n>(\n transition: JourneyTransition<TContext, TStepId, TEventMap, THandlers>\n): TStepId | JourneyTerminal =>\n transition.event === \"completeJourney\"\n ? \"COMPLETE\"\n : transition.event === \"terminateJourney\"\n ? \"TERMINATED\"\n : (transition.to as TStepId | JourneyTerminal);\n\nexport const validateJourneyTransitions = <\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TEventMap extends Record<string, unknown>,\n THandlers extends Record<string, unknown>\n>(\n transitions: readonly JourneyResolvedTransition<TContext, TStepId, TEventMap, THandlers>[],\n steps: Record<TStepId, unknown>\n) => {\n const stepRegistry = steps as Record<string, unknown>;\n const allowedKeys = new Set([\n \"from\",\n \"event\",\n \"to\",\n \"when\",\n \"updateContext\",\n \"onEnter\",\n \"onLeave\",\n \"id\",\n \"label\",\n \"timeoutMs\"\n ]);\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 for (const key of Object.keys(transition)) {\n if (!allowedKeys.has(key)) {\n throw new Error(\n `Journey transition at index ${index} contains unsupported field \"${key}\".`\n );\n }\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 !== \"*\" && !(transition.from in stepRegistry)) {\n throw new Error(\n `Journey transition at index ${index} references unknown from step \"${transition.from}\".`\n );\n }\n\n validateFiniteTimeout(transition.timeoutMs, `Journey transition at index ${index}`);\n\n if (transition.when !== undefined && typeof transition.when !== \"function\") {\n throw new Error(\n `Journey transition at index ${index} must define \"when\" as a function when provided.`\n );\n }\n\n if (transition.updateContext !== undefined && typeof transition.updateContext !== \"function\") {\n throw new Error(\n `Journey transition at index ${index} must define \"updateContext\" as a function when provided.`\n );\n }\n\n if (transition.onEnter !== undefined && typeof transition.onEnter !== \"function\") {\n throw new Error(\n `Journey transition at index ${index} must define \"onEnter\" as a function when provided.`\n );\n }\n\n if (transition.onLeave !== undefined && typeof transition.onLeave !== \"function\") {\n throw new Error(\n `Journey transition at index ${index} must define \"onLeave\" as a function when provided.`\n );\n }\n\n if (transition.id !== undefined && typeof transition.id !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define \"id\" as a string when provided.`\n );\n }\n\n if (transition.label !== undefined && typeof transition.label !== \"string\") {\n throw new Error(\n `Journey transition at index ${index} must define \"label\" as a string when provided.`\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 extends JourneyJsonObject, TStepId extends string>(\n snapshot: JourneySnapshot<TContext, TStepId>,\n transitioned: boolean,\n options: {\n transitionId?: string;\n label?: string;\n error?: unknown;\n } = {}\n): JourneySendResult<TContext, TStepId> => ({\n transitioned,\n ...(options.transitionId !== undefined ? { transitionId: options.transitionId } : {}),\n ...(options.label !== undefined ? { label: options.label } : {}),\n ...(\"error\" in options ? { error: options.error } : {}),\n snapshot\n});\n\nexport const buildSnapshot = <TContext extends JourneyJsonObject, TStepId extends string>(\n timeline: readonly TStepId[],\n index: number,\n context: TContext,\n status: JourneyStatus,\n asyncState: JourneyAsyncState<TStepId>,\n visited?: Record<TStepId, boolean>\n): JourneySnapshot<TContext, TStepId> => {\n if (timeline.length === 0) {\n throw new Error(\"Journey timeline cannot be empty.\");\n }\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 = unique(\n visited ? ([...(Object.keys(visited) as TStepId[]), ...timeline] as const) : timeline\n );\n\n return {\n status,\n currentStepId,\n history: {\n timeline: [...timeline],\n index: safeIndex\n },\n context: cloneContext(context),\n visited: visited\n ? normalizeVisited(visited, stepIds)\n : buildVisitedFromTimeline(timeline, stepIds),\n async: cloneSerializableValue(\n asyncState as unknown as JourneyJsonValue\n ) as JourneyAsyncState<TStepId>\n };\n};\n\nexport const stabilizeSnapshot = <TContext extends JourneyJsonObject, TStepId extends string>(\n snapshot: JourneySnapshot<TContext, TStepId>\n): JourneySnapshot<TContext, TStepId> => {\n const stableSnapshot: JourneySnapshot<TContext, TStepId> = {\n ...snapshot,\n history: {\n timeline: [...snapshot.history.timeline],\n index: snapshot.history.index\n },\n context: cloneContext(snapshot.context),\n visited: { ...snapshot.visited },\n async: cloneSerializableValue(\n snapshot.async as unknown as JourneyJsonValue\n ) as JourneyAsyncState<TStepId>\n };\n\n freezeSnapshotValue(stableSnapshot);\n return stableSnapshot;\n};\n\nexport const selectTransition = async <\n TContext extends JourneyJsonObject,\n TStepId extends string,\n TEventMap extends Record<string, unknown>,\n THandlers extends Record<string, unknown>,\n TTransition extends {\n from: TStepId | \"*\";\n event: string;\n when?: (\n args: JourneyTransitionArgs<TContext, TStepId, TEventMap, THandlers>\n ) => boolean | Promise<boolean>;\n timeoutMs?: number;\n id?: string;\n label?: string;\n }\n>(\n transitions: readonly TTransition[],\n snapshot: JourneySnapshot<TContext, TStepId>,\n event: JourneyEvent<TStepId, TEventMap>,\n signal: AbortSignal,\n handlers: THandlers,\n hooks?: {\n onAsyncGuardStart?: (transition: TTransition) => void;\n onAsyncGuardSuccess?: (transition: TTransition) => void;\n onAsyncGuardError?: (transition: TTransition, error: unknown) => void;\n },\n defaultTimeoutMs?: number\n): Promise<TTransition | null> => {\n for (const transition of transitions) {\n const fromMatches = transition.from === \"*\" || 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 let guardResult: boolean | Promise<boolean>;\n if (signal.aborted) {\n throw signal.reason;\n }\n\n guardResult = (\n transition.when as (\n args: JourneyTransitionArgs<TContext, TStepId, TEventMap, THandlers>\n ) => boolean | Promise<boolean>\n )({\n snapshot,\n context: snapshot.context,\n from: snapshot.currentStepId,\n timeline: snapshot.history.timeline,\n index: snapshot.history.index,\n event,\n signal,\n handlers\n });\n\n const asyncGuard = isPromiseLike(guardResult);\n const asyncGuardPromise = asyncGuard ? (guardResult as PromiseLike<boolean>) : null;\n\n let allowed: boolean;\n try {\n if (asyncGuard) {\n hooks?.onAsyncGuardStart?.(transition);\n allowed = await withTimeout(\n withAbortSignal(asyncGuardPromise as PromiseLike<boolean>, signal),\n transition.timeoutMs ?? defaultTimeoutMs,\n () =>\n new JourneyTimeoutError(\n `Transition guard timed out after ${transition.timeoutMs ?? defaultTimeoutMs}ms (event: ${event.type}, transition: ${transition.id ?? \"<anonymous>\"}).`\n )\n );\n } else {\n allowed = guardResult as boolean;\n }\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 extends JourneyJsonObject, TStepId extends string>(\n snapshot: JourneySnapshot<TContext, TStepId>,\n nextCurrent: TStepId,\n nextContext: TContext\n): JourneySnapshot<TContext, TStepId> => {\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 visited\n );\n};\n"],
5
- "mappings": "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",
6
- "names": ["analytics_exports", "__export", "createAnalyticsPlugin", "__toCommonJS", "isDevelopmentEnvironment", "diagnosticGlobal", "nodeEnv", "warnInDevelopment", "message", "detail", "buildBasePayload", "context", "createAnalyticsPlugin", "options", "unsubscribe", "startedAt", "activeStepEnteredAt", "trackSafely", "event", "tracked", "error", "warnInDevelopment", "machine", "typedMachine", "emitTracked", "sourceEvent", "buildStepMetaPayload", "stepId", "stepMeta", "buildTransitionMetaPayload", "from", "to", "fromStepMeta", "toStepMeta", "typedEvent", "snapshot", "basePayload", "name", "payload"]
7
- }
@@ -1,25 +0,0 @@
1
- import type { JourneyAnalyticsPluginOptions, JourneyAnalyticsTrackedEvent, JourneyJsonObject, JourneyMachine } from "../../types";
2
- export type JourneyAnalyticsMachineExtension<TContext extends JourneyJsonObject, TStepId extends string, TStepMeta> = {
3
- trackAnalyticsEvent: (name: string, payload?: Record<string, unknown>) => JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>;
4
- };
5
- export type JourneyAnalyticsMachine<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>> = JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers> & JourneyAnalyticsMachineExtension<TContext, TStepId, TStepMeta>;
6
- /** Creates a plugin that converts journey observation events into analytics envelopes. */
7
- export declare const createAnalyticsPlugin: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown>(options: JourneyAnalyticsPluginOptions<TContext, TStepId, TEventMap, TStepMeta>) => {
8
- name: string;
9
- setup: <TContext_1 extends JourneyJsonObject, TStepId_1 extends string, TEventMap_1 extends Record<string, unknown> = Record<never, never>, TStepMeta_1 = unknown, THandlers extends Record<string, unknown> = Record<never, never>>() => {
10
- augmentMachine: ({ machine }: {
11
- machine: JourneyMachine<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
12
- journey: import("../..").JourneyDefinition<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
13
- resolvedJourney: import("../../types").JourneyResolvedDefinition<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
14
- }) => {
15
- trackAnalyticsEvent: (name: string, payload?: Record<string, unknown>) => {
16
- payload: Record<string, unknown>;
17
- machineId?: string;
18
- name: string;
19
- timestamp: number;
20
- };
21
- };
22
- dispose: () => void;
23
- };
24
- };
25
- export type { JourneyAnalyticsPluginOptions, JourneyAnalyticsTrackedEvent } from "../../types";
@@ -1,25 +0,0 @@
1
- import type { JourneyAnalyticsPluginOptions, JourneyAnalyticsTrackedEvent, JourneyJsonObject, JourneyMachine } from "../../types";
2
- export type JourneyAnalyticsMachineExtension<TContext extends JourneyJsonObject, TStepId extends string, TStepMeta> = {
3
- trackAnalyticsEvent: (name: string, payload?: Record<string, unknown>) => JourneyAnalyticsTrackedEvent<TContext, TStepId, TStepMeta>;
4
- };
5
- export type JourneyAnalyticsMachine<TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown, THandlers extends Record<string, unknown> = Record<never, never>> = JourneyMachine<TContext, TStepId, TEventMap, TStepMeta, THandlers> & JourneyAnalyticsMachineExtension<TContext, TStepId, TStepMeta>;
6
- /** Creates a plugin that converts journey observation events into analytics envelopes. */
7
- export declare const createAnalyticsPlugin: <TContext extends JourneyJsonObject, TStepId extends string, TEventMap extends Record<string, unknown> = Record<never, never>, TStepMeta = unknown>(options: JourneyAnalyticsPluginOptions<TContext, TStepId, TEventMap, TStepMeta>) => {
8
- name: string;
9
- setup: <TContext_1 extends JourneyJsonObject, TStepId_1 extends string, TEventMap_1 extends Record<string, unknown> = Record<never, never>, TStepMeta_1 = unknown, THandlers extends Record<string, unknown> = Record<never, never>>() => {
10
- augmentMachine: ({ machine }: {
11
- machine: JourneyMachine<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
12
- journey: import("../..").JourneyDefinition<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
13
- resolvedJourney: import("../../types").JourneyResolvedDefinition<TContext_1, TStepId_1, TEventMap_1, TStepMeta_1, THandlers>;
14
- }) => {
15
- trackAnalyticsEvent: (name: string, payload?: Record<string, unknown>) => {
16
- payload: Record<string, unknown>;
17
- machineId?: string;
18
- name: string;
19
- timestamp: number;
20
- };
21
- };
22
- dispose: () => void;
23
- };
24
- };
25
- export type { JourneyAnalyticsPluginOptions, JourneyAnalyticsTrackedEvent } from "../../types";
@@ -1,2 +0,0 @@
1
- var l=()=>{let n=globalThis;if(typeof n.__DEV__=="boolean")return n.__DEV__;let i=n.process?.env?.NODE_ENV;return i===void 0||i==="development"},m=(n,i)=>{if(!(!l()||typeof console>"u")){if(i===void 0){console.warn(n);return}console.warn(n,i)}};var f=({context:n})=>({context:n}),b=n=>{let i,d=null,u=null,T=(p,a)=>{try{n.track(a)}catch(t){if(n.onError){n.onError(t,p);return}m("Journey analytics track() threw without an onError handler.",t)}};return{name:"analytics",setup:()=>({augmentMachine:({machine:p})=>{let a=p,t=(o,e)=>{T(o,e)},c=o=>{if(!n.includeStepMeta)return{};let e=a.getStepMeta(o);return e===void 0?{}:{stepMeta:e}},y=({from:o,to:e})=>{if(!n.includeStepMeta)return{};let s=a.getStepMeta(o),r=e==="COMPLETE"||e==="TERMINATED"?void 0:a.getStepMeta(e);return{...s===void 0?{}:{fromStepMeta:s},...r===void 0?{}:{toStepMeta:r}}};return i=a.subscribeEvent(o=>{let e=o,s=a.getSnapshot(),r=f({context:s.context});switch(e.type){case"journey.start":d=e.timestamp,u=e.timestamp,t(e,{name:"journey_started",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...c(e.stepId),...r}});return;case"step.enter":u=e.timestamp,t(e,{name:"step_viewed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...c(e.stepId),...r}});return;case"step.exit":t(e,{name:"step_exited",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...u===null?{}:{dwellMs:Math.max(0,e.timestamp-u)},...c(e.stepId),...r}});return;case"transition.start":t(e,{name:"transition_started",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,eventType:e.event.type,...r}});return;case"transition.success":t(e,{name:"transition_succeeded",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,eventType:e.eventType,transitionId:e.transitionId,...e.label!==void 0?{label:e.label}:{},...y({from:e.from,to:e.to}),...r}});return;case"transition.error":t(e,{name:"transition_failed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,eventType:e.eventType,transitionId:e.transitionId,...e.label!==void 0?{label:e.label}:{},error:e.error,...r}});return;case"journey.completed":t(e,{name:"journey_completed",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...d===null?{}:{durationMs:Math.max(0,e.timestamp-d)},...c(e.stepId),...r}});return;case"journey.terminated":t(e,{name:"journey_terminated",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{stepId:e.stepId,...d===null?{}:{durationMs:Math.max(0,e.timestamp-d)},...c(e.stepId),...r}});return;case"navigation.previous":t(e,{name:"navigation_previous",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,requestedSteps:e.requestedSteps,appliedSteps:e.appliedSteps,...y({from:e.from,to:e.to}),...r}});return;case"navigation.lastVisited":t(e,{name:"navigation_last_visited",timestamp:e.timestamp,...n.machineId?{machineId:n.machineId}:{},payload:{from:e.from,to:e.to,...y({from:e.from,to:e.to}),...r}});return}}),{trackAnalyticsEvent:(o,e={})=>{let s={name:o,timestamp:Date.now(),...n.machineId?{machineId:n.machineId}:{},payload:e};return T(s,s),s}}},dispose:()=>{i?.()}})}};export{b as createAnalyticsPlugin};
2
- //# sourceMappingURL=index.js.map