@rxova/journey-react 0.7.0 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -173
- package/dist/client.cjs +2 -0
- package/dist/client.cjs.map +7 -0
- package/dist/client.d.cts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +7 -0
- package/dist/createJourney.d.cts +15 -0
- package/dist/createJourney.d.ts +15 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/provider.d.cts +9 -0
- package/dist/provider.d.ts +9 -0
- package/dist/runtime-hooks.d.cts +17 -0
- package/dist/runtime-hooks.d.ts +17 -0
- package/dist/types.d.cts +58 -0
- package/dist/types.d.ts +49 -47
- package/package.json +17 -8
- package/dist/bindings/Provider.d.ts +0 -8
- package/dist/bindings/StepRenderer.d.ts +0 -13
- package/dist/bindings/index.d.ts +0 -6
- package/dist/bindings/useJourneyApi.d.ts +0 -16
- package/dist/bindings/useJourneyEvent.d.ts +0 -5
- package/dist/bindings/useJourneyMachine.d.ts +0 -4
- package/dist/bindings/useJourneySelector.d.ts +0 -5
- package/dist/bindings/useJourneySnapshot.d.ts +0 -5
package/README.md
CHANGED
|
@@ -1,226 +1,149 @@
|
|
|
1
1
|
# @rxova/journey-react
|
|
2
2
|
|
|
3
|
-
Typed React bindings for
|
|
3
|
+
Typed React bindings for multi-step UI flows.
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@rxova/journey-react">
|
|
7
|
+
<img src="https://img.shields.io/npm/v/@rxova/journey-react?color=0f8f6a" alt="npm" />
|
|
8
|
+
</a>
|
|
9
|
+
<img src="https://img.shields.io/badge/6.3%20kB-brotli-0f8f6a" alt="size" />
|
|
10
|
+
<img src="https://img.shields.io/badge/React%2018+-black" alt="React 18+" />
|
|
11
|
+
<img src="https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white" alt="TypeScript" />
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
`@rxova/journey-react` is approaching a `1.0.0-rc` contract freeze. The key runtime rule is unchanged:
|
|
15
|
+
one `createJourney(...)` call creates one machine instance immediately, and the returned hooks/components stay bound to that instance.
|
|
4
16
|
|
|
5
17
|
## Install
|
|
6
18
|
|
|
7
19
|
```bash
|
|
8
|
-
|
|
9
|
-
yarn add @rxova/journey-react
|
|
10
|
-
npm i @rxova/journey-react
|
|
11
|
-
bun add @rxova/journey-react
|
|
20
|
+
npm i @rxova/journey-react @rxova/journey-core
|
|
12
21
|
```
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## API Style
|
|
17
|
-
|
|
18
|
-
`@rxova/journey-react` is bindings-first:
|
|
19
|
-
|
|
20
|
-
- `createJourneyBindings(journey)` returns a typed bundle that contains:
|
|
21
|
-
- `Provider`
|
|
22
|
-
- `StepRenderer`
|
|
23
|
-
- `useJourneyApi`
|
|
24
|
-
- `useJourneyEvent`
|
|
25
|
-
- `useJourneySelector`
|
|
26
|
-
- `useJourneySnapshot`
|
|
27
|
-
- `useJourneyMachine`
|
|
28
|
-
|
|
29
|
-
No per-hook generic arguments are needed at callsites.
|
|
23
|
+
Use the root entry for server-safe imports. When a Next.js App Router client boundary should be explicit,
|
|
24
|
+
import from `@rxova/journey-react/client`.
|
|
30
25
|
|
|
31
26
|
## Quickstart
|
|
32
27
|
|
|
33
28
|
```tsx
|
|
34
|
-
import
|
|
35
|
-
import {
|
|
29
|
+
import { createJourney, type JourneyViews } from "@rxova/journey-react";
|
|
30
|
+
import type { JourneyDefinition } from "@rxova/journey-core";
|
|
36
31
|
|
|
37
32
|
type StepId = "start" | "review";
|
|
38
|
-
type
|
|
39
|
-
|
|
40
|
-
let bindings: ReturnType<typeof createJourneyBindings<Ctx, StepId>>;
|
|
41
|
-
|
|
42
|
-
const Start = () => {
|
|
43
|
-
const api = bindings.useJourneyApi();
|
|
44
|
-
return <button onClick={() => void api.goToNextStep()}>Next</button>;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const Review = () => {
|
|
48
|
-
const api = bindings.useJourneyApi();
|
|
49
|
-
return <button onClick={() => void api.completeJourney()}>Submit</button>;
|
|
50
|
-
};
|
|
33
|
+
type Context = { name: string };
|
|
51
34
|
|
|
52
|
-
const
|
|
35
|
+
const definition: JourneyDefinition<Context, StepId> = {
|
|
53
36
|
initial: "start",
|
|
54
37
|
context: { name: "" },
|
|
55
|
-
steps: {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{ from: "start", event: "goToNextStep", to: "review" },
|
|
61
|
-
{ from: "review", event: "completeJourney" }
|
|
62
|
-
]
|
|
38
|
+
steps: { start: {}, review: {} },
|
|
39
|
+
transitions: {
|
|
40
|
+
start: { goToNextStep: [{ to: "review" }] },
|
|
41
|
+
review: { completeJourney: true }
|
|
42
|
+
}
|
|
63
43
|
};
|
|
64
44
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
export const App = () => {
|
|
68
|
-
const Provider = bindings.Provider;
|
|
69
|
-
const StepRenderer = bindings.StepRenderer;
|
|
45
|
+
const signup = createJourney(definition);
|
|
70
46
|
|
|
47
|
+
const Start = () => {
|
|
48
|
+
const api = signup.useJourneyApi();
|
|
49
|
+
const snap = signup.useJourneySnapshot();
|
|
71
50
|
return (
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
51
|
+
<div>
|
|
52
|
+
<p>Hello, {snap.context.name || "stranger"}</p>
|
|
53
|
+
<button onClick={() => void api.goToNextStep()}>Next</button>
|
|
54
|
+
</div>
|
|
75
55
|
);
|
|
76
56
|
};
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Split Files Pattern (Hooks In Steps)
|
|
80
|
-
|
|
81
|
-
If step components live in separate files and call Journey hooks, export bindings as `let`:
|
|
82
57
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
import { Start, Review } from "./steps";
|
|
87
|
-
|
|
88
|
-
type StepId = "start" | "review";
|
|
89
|
-
type Ctx = { name: string };
|
|
90
|
-
|
|
91
|
-
export let bindings: ReturnType<typeof createJourneyBindings<Ctx, StepId>>;
|
|
92
|
-
|
|
93
|
-
const journey: JourneyReactDefinition<Ctx, StepId> = {
|
|
94
|
-
initial: "start",
|
|
95
|
-
context: { name: "" },
|
|
96
|
-
steps: {
|
|
97
|
-
start: { component: Start },
|
|
98
|
-
review: { component: Review }
|
|
99
|
-
},
|
|
100
|
-
transitions: [
|
|
101
|
-
{ from: "start", event: "goToNextStep", to: "review" },
|
|
102
|
-
{ from: "review", event: "completeJourney" }
|
|
103
|
-
]
|
|
58
|
+
const Review = () => {
|
|
59
|
+
const api = signup.useJourneyApi();
|
|
60
|
+
return <button onClick={() => void api.completeJourney()}>Submit</button>;
|
|
104
61
|
};
|
|
105
62
|
|
|
106
|
-
|
|
63
|
+
const views: JourneyViews<StepId> = { start: Start, review: Review };
|
|
64
|
+
|
|
65
|
+
export const App = () => (
|
|
66
|
+
<signup.JourneyProvider views={views}>
|
|
67
|
+
<signup.StepRenderer />
|
|
68
|
+
</signup.JourneyProvider>
|
|
69
|
+
);
|
|
107
70
|
```
|
|
108
71
|
|
|
109
72
|
## Hooks
|
|
110
73
|
|
|
111
|
-
|
|
112
|
-
- `useJourneyEvent(listener)` subscribes to typed lifecycle events.
|
|
113
|
-
- `useJourneySelector(selector, equalityFn?)` subscribes to a selected slice and rerenders only when that selected value changes.
|
|
114
|
-
- `useJourneyApi()` returns typed commands.
|
|
115
|
-
- `useJourneyMachine()` returns the underlying core machine instance.
|
|
116
|
-
|
|
117
|
-
## Journey API Helpers
|
|
118
|
-
|
|
119
|
-
From `bindings.useJourneyApi()`:
|
|
74
|
+
`createJourney()` returns a runtime with bound hooks:
|
|
120
75
|
|
|
121
|
-
- `
|
|
122
|
-
- `
|
|
123
|
-
- `
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
- `goToLastVisitedStep()`
|
|
127
|
-
- `updateContext`
|
|
128
|
-
- `updateStepMetadata`
|
|
129
|
-
- `clearStepError`, `resetJourney`
|
|
76
|
+
- **`useJourneySnapshot()`** — full snapshot: `currentStepId`, `context`, `history`, `status`, `async`
|
|
77
|
+
- **`useJourneyApi()`** — runtime commands: `start`, `goToNextStep`, `goToPreviousStep`, `completeJourney`, `send`, etc.
|
|
78
|
+
- **`useJourneyComputed()`** — derived state: `mode`, `activeStepId`, `isLoading`, `isFirstStep`, `isLastStep`
|
|
79
|
+
- **`useJourneySelector(selector, eq?)`** — subscribe to a slice of the snapshot
|
|
80
|
+
- **`useJourneyEvent(listener)`** — stream lifecycle events for analytics
|
|
130
81
|
|
|
131
|
-
|
|
82
|
+
## Navigation
|
|
132
83
|
|
|
133
84
|
```ts
|
|
134
|
-
|
|
85
|
+
const api = signup.useJourneyApi();
|
|
86
|
+
|
|
87
|
+
await api.start();
|
|
88
|
+
await api.goToNextStep();
|
|
89
|
+
await api.goToPreviousStep();
|
|
90
|
+
await api.goToLastVisitedStep();
|
|
91
|
+
await api.completeJourney();
|
|
92
|
+
await api.terminateJourney();
|
|
93
|
+
await api.goToStepById("review");
|
|
94
|
+
|
|
95
|
+
api.updateContext((ctx) => ({ ...ctx, name: "Ada" }));
|
|
96
|
+
api.resetJourney();
|
|
135
97
|
```
|
|
136
98
|
|
|
137
|
-
|
|
99
|
+
Transition failures resolve through `result.error` instead of rejecting, so `void api.goToNextStep()` is safe from unhandled promise rejections.
|
|
138
100
|
|
|
139
|
-
|
|
101
|
+
## Custom Step Renderer
|
|
140
102
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
- `<Provider />` creates an internal core machine from the bound journey.
|
|
144
|
-
- `<Provider journey={...} />` lets you pass a different journey definition at runtime.
|
|
145
|
-
- Internal machine is preserved across `journey` and `persistence` prop changes by default.
|
|
146
|
-
- Set `resetOnJourneyChange` to rebuild internal machine when `journey` identity changes.
|
|
147
|
-
- Set `resetOnPersistenceChange` to rebuild internal machine when `persistence` identity changes.
|
|
148
|
-
- `<Provider machine={externalMachine} />` uses your machine directly.
|
|
149
|
-
- `persistence` applies only when Provider owns the internal machine.
|
|
150
|
-
- Internal Provider-owned machines default to completing on `goToNextStep()` when the current step declares no next transition.
|
|
151
|
-
- Set `completeOnNoNextStep={false}` to opt out.
|
|
152
|
-
- `onStart(event)` wraps `machine.subscribeStart(...)`.
|
|
153
|
-
- `onComplete(event)` wraps `machine.subscribeComplete(...)`.
|
|
154
|
-
- `onTerminate(event)` wraps `machine.subscribeTerminate(...)`.
|
|
155
|
-
- All three callback props work with internal and external machines.
|
|
156
|
-
- `onStart` replays startup on mount, matching core `journey.start` behavior.
|
|
157
|
-
- `onComplete` and `onTerminate` fire only for emitted terminal lifecycle events.
|
|
103
|
+
`StepRenderer` is a convenience — it just looks up the current step's view from the `views` record and renders it. You can build your own if you need transitions, animations, or a different rendering strategy:
|
|
158
104
|
|
|
159
105
|
```tsx
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
</bindings.Provider>
|
|
106
|
+
const MyStepRenderer = () => {
|
|
107
|
+
const { currentStepId } = signup.useJourneySnapshot();
|
|
108
|
+
const View = views[currentStepId];
|
|
109
|
+
if (!View) return <p>Unknown step</p>;
|
|
110
|
+
return <View />;
|
|
111
|
+
};
|
|
167
112
|
```
|
|
168
113
|
|
|
169
|
-
##
|
|
170
|
-
|
|
171
|
-
Core async state is exposed via snapshot:
|
|
114
|
+
## Plugins
|
|
172
115
|
|
|
173
116
|
```tsx
|
|
174
|
-
|
|
175
|
-
const snapshot = bindings.useJourneySnapshot();
|
|
117
|
+
import { createPersistencePlugin } from "@rxova/journey-core/persistence";
|
|
176
118
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<div>
|
|
183
|
-
<p>Something failed.</p>
|
|
184
|
-
<button onClick={() => api.clearStepError()}>Dismiss</button>
|
|
185
|
-
</div>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
119
|
+
const signup = createJourney(definition, {
|
|
120
|
+
plugins: [createPersistencePlugin({ key: "signup", version: 1 })],
|
|
121
|
+
defaultTimeoutMs: 30_000
|
|
122
|
+
});
|
|
188
123
|
```
|
|
189
124
|
|
|
190
|
-
##
|
|
125
|
+
## Runtime Ownership
|
|
191
126
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```tsx
|
|
195
|
-
import React from "react";
|
|
196
|
-
import { attachJourneyDevtools } from "@rxova/journey-devtools-bridge";
|
|
127
|
+
Each `createJourney()` call creates one machine instance. The returned hooks are permanently bound to it.
|
|
197
128
|
|
|
198
|
-
|
|
199
|
-
|
|
129
|
+
- Rendering multiple providers from the same runtime shares one journey state
|
|
130
|
+
- `JourneyProvider` auto-starts an `idled` runtime, but does not dispose it by default
|
|
131
|
+
- Provider-free flows can start manually through `useJourneyApi().start()` or `machine.start()`
|
|
132
|
+
- Provider-owned startup failures are reported through `onError(error, { phase: "start" })`
|
|
133
|
+
- Set `disposeOnUnmount` when a provider fully owns a component-scoped runtime
|
|
134
|
+
- Independent instances require separate `createJourney()` calls
|
|
135
|
+
- `createJourneyFactory()` returns a typed helper for producing fresh runtimes from the same definition/options pair and is the preferred path when request-scoped or boundary-scoped isolation matters
|
|
136
|
+
- `dispose()` tears down subscriptions when the runtime is no longer needed
|
|
200
137
|
|
|
201
|
-
|
|
202
|
-
return attachJourneyDevtools(machine, { label: "Signup" });
|
|
203
|
-
}, [machine]);
|
|
204
|
-
|
|
205
|
-
return null;
|
|
206
|
-
};
|
|
207
|
-
```
|
|
138
|
+
## Documentation
|
|
208
139
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const transitions = createTransitions(
|
|
217
|
-
tx.from("start").on("goToNextStep").to("review"),
|
|
218
|
-
tx.from("review").toComplete()
|
|
219
|
-
);
|
|
220
|
-
```
|
|
140
|
+
- [Pre-1.0 Migration](https://rxova.org/docs/core/pre-1-0-migration)
|
|
141
|
+
- [Stability Contract](https://rxova.org/docs/core/stability)
|
|
142
|
+
- [React Quickstart](https://rxova.org/docs/react/quickstart)
|
|
143
|
+
- [Provider and Hooks](https://rxova.org/docs/react/provider-and-hooks)
|
|
144
|
+
- [Patterns](https://rxova.org/docs/react/patterns)
|
|
145
|
+
- [Core Docs](https://rxova.org/docs/core/getting-started)
|
|
221
146
|
|
|
222
|
-
##
|
|
147
|
+
## License
|
|
223
148
|
|
|
224
|
-
|
|
225
|
-
- In React Server Components environments, call bindings/hooks from client components.
|
|
226
|
-
- Server-side rendering is supported (Provider + StepRenderer render safely on the server).
|
|
149
|
+
MIT
|
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";"use client";var D=Object.create;var h=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var z=(t,r)=>{for(var u in r)h(t,u,{get:r[u],enumerable:!0})},w=(t,r,u,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of B(r))!U.call(t,a)&&a!==u&&h(t,a,{get:()=>r[a],enumerable:!(d=N(r,a))||d.enumerable});return t};var k=(t,r,u)=>(u=t!=null?D($(t)):{},w(r||!t||!t.__esModule?h(u,"default",{value:t,enumerable:!0}):u,t)),G=t=>w(h({},"__esModule",{value:!0}),t);var X={};z(X,{createJourney:()=>b,createJourneyFactory:()=>q});module.exports=G(X);var F=require("@rxova/journey-core");var c=k(require("react"),1),S=require("react/jsx-runtime"),M=typeof window>"u"?c.default.useEffect:c.default.useLayoutEffect,K=(t,r,u)=>{if(u){u(t,r);return}console.error(`JourneyProvider ${r.phase} failed.`,t)},j=(t,r)=>{let u=c.default.createContext(null),d=(e="hook")=>{let n=c.default.useContext(u);if(!n)throw new Error(`${e} must be used within JourneyProvider.`);return n},a=({runtimeMachine:e,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T})=>{let v=c.default.useRef(n),y=c.default.useRef(o),i=c.default.useRef(s),f=c.default.useRef(l),x=c.default.useRef(null),E=n!==void 0,m=o!==void 0,C=s!==void 0;v.current=n,y.current=o,i.current=s,f.current=l,M(()=>{x.current!==null&&(globalThis.clearTimeout(x.current),x.current=null)});let R=c.default.useCallback(J=>J.status,[e]),A=c.default.useCallback(J=>e.subscribeSelector(R,()=>{J()}),[e,R]),I=c.default.useCallback(()=>e.getSnapshot().status,[e]),O=c.default.useSyncExternalStore(A,I,I);return M(()=>{if(!E&&!m&&!C)return;let J=E?e.subscribeStart(g=>{v.current?.(g)}):void 0,V=m?e.subscribeComplete(g=>{y.current?.(g)}):void 0,W=C?e.subscribeTerminate(g=>{i.current?.(g)}):void 0;return()=>{J?.(),V?.(),W?.()}},[e,m,E,C]),M(()=>{O==="idled"&&e.start().catch(J=>{K(J,{phase:"start"},f.current)})},[e,O]),M(()=>{if(T)return()=>{x.current=globalThis.setTimeout(()=>{x.current=null,e.dispose()},0)}},[e,T]),null};return{JourneyProvider:({views:e,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T=!1,children:v})=>{let y=t;return(0,S.jsxs)(u.Provider,{value:e,children:[v,(0,S.jsx)(a,{runtimeMachine:y,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T})]})},StepRenderer:({fallback:e=null})=>{let n=r(T=>T.currentStepId),s=d("StepRenderer")[n];if(!s)return(0,S.jsx)(S.Fragment,{children:e});let l=s;return(0,S.jsx)(c.default.Fragment,{children:(0,S.jsx)(l,{})},n)}}};var p=k(require("react"),1),Q=typeof window>"u"?p.default.useEffect:p.default.useLayoutEffect,H=t=>{let r=()=>{let e=t,n=p.default.useCallback(()=>e.getSnapshot(),[e]),o=p.default.useCallback(s=>e.subscribe(s),[e]);return p.default.useSyncExternalStore(o,n,n)},u=()=>{let e=r(),n=t;return p.default.useMemo(()=>n.getComputed(),[n,e])},d=(e,n)=>{let o=t,s=n??Object.is,l=p.default.useRef(null),T=p.default.useCallback(()=>{let y=o.getSnapshot(),i=l.current;if(i&&Object.is(i.machine,o)&&Object.is(i.selector,e)&&Object.is(i.isEqual,s)&&Object.is(i.snapshot,y))return i.selected;let f=e(y);return i&&Object.is(i.machine,o)&&Object.is(i.selector,e)&&Object.is(i.isEqual,s)&&s(i.selected,f)?(l.current={machine:o,snapshot:y,selected:i.selected,selector:e,isEqual:s},i.selected):(l.current={machine:o,snapshot:y,selected:f,selector:e,isEqual:s},f)},[o,s,e]),v=p.default.useCallback(y=>o.subscribeSelector(e,()=>{y()},s),[o,s,e]);return p.default.useSyncExternalStore(v,T,T)},a=e=>{let n=t,o=p.default.useRef(e);o.current=e,Q(()=>n.subscribeEvent(s=>{o.current(s)}),[n])};return{useJourneySnapshot:r,useJourneyComputed:u,useJourneySelector:d,useJourneyApi:()=>{let e=t;return p.default.useMemo(()=>({start:e.start,send:e.send,goToNextStep:e.goToNextStep,goToStepById:e.goToStepById,terminateJourney:e.terminateJourney,completeJourney:e.completeJourney,goToPreviousStep:e.goToPreviousStep,goToLastVisitedStep:e.goToLastVisitedStep,clearStepError:e.clearStepError,updateContext:e.updateContext,getStepMeta:e.getStepMeta,resetJourney:()=>e.resetJourney()}),[e])},useJourneyEvent:a,useJourneyStepLifecycle:(e,n)=>{a(o=>{o.type==="step.enter"&&o.stepId===e?n.onEnter?.({context:t.getSnapshot().context}):o.type==="step.exit"&&o.stepId===e&&n.onLeave?.({context:t.getSnapshot().context})})}}};var b=(t,r)=>{let d=(0,F.createJourneyMachine)(t,r),a=H(d),P=j(d,a.useJourneySelector);return{machine:d,dispose:()=>d.dispose(),...a,...P}},q=(t,r)=>()=>b(t,r);0&&(module.exports={createJourney,createJourneyFactory});
|
|
2
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client.ts", "../src/createJourney.tsx", "../src/provider.tsx", "../src/runtime-hooks.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\";\n\nexport * from \"./index\";\n", "import { createJourneyMachine } from \"@rxova/journey-core\";\nimport type {\n JourneyDefinition,\n JourneyJsonObject,\n JourneyMachineOptions,\n JourneyMachinePlugin,\n JourneyMachineWithPlugins\n} from \"@rxova/journey-core\";\nimport { createJourneyProviderArtifacts } from \"./provider\";\nimport { createJourneyHooks } from \"./runtime-hooks\";\nimport type { JourneyRuntime, JourneyRuntimeFactory } from \"./types\";\n\ntype JourneyOptionsInput<TPlugins extends readonly JourneyMachinePlugin[]> = JourneyMachineOptions<\n TPlugins extends [] ? readonly JourneyMachinePlugin[] : TPlugins\n>;\n\n/**\n * Creates a journey machine and returns React hooks/components bound to that machine.\n * Hooks work without a provider; `JourneyProvider` is only required for `StepRenderer`.\n */\nexport const createJourney = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>,\n options?: JourneyOptionsInput<TPlugins>\n): JourneyRuntime<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers> => {\n const machineOptions = options as JourneyMachineOptions<TPlugins> | undefined;\n const machine = createJourneyMachine<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >(definition, machineOptions) as JourneyMachineWithPlugins<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >;\n const hooks = createJourneyHooks<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>(\n machine\n );\n const providerArtifacts = createJourneyProviderArtifacts<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >(machine, hooks.useJourneySelector);\n\n return {\n machine,\n dispose: () => machine.dispose(),\n ...hooks,\n ...providerArtifacts\n };\n};\n\n/**\n * Creates a typed factory for producing fresh React-bound journey runtimes.\n * Use this when a component or route boundary needs independent instances\n * from the same definition/options pair.\n */\nexport const createJourneyFactory = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>,\n options?: JourneyOptionsInput<TPlugins>\n): JourneyRuntimeFactory<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers> => {\n return () =>\n createJourney<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>(\n definition,\n options\n );\n};\n", "import React from \"react\";\n\nimport type {\n JourneyEqualityFn,\n JourneyJsonObject,\n JourneySelector,\n JourneyMachineWithPlugins,\n JourneyMachinePlugin\n} from \"@rxova/journey-core\";\nimport type { JourneyProviderErrorContext, JourneyProviderProps, JourneyViews } from \"./types\";\n\nconst useSafeLayoutEffect = typeof window === \"undefined\" ? React.useEffect : React.useLayoutEffect;\n\nconst reportProviderError = (\n error: unknown,\n context: JourneyProviderErrorContext,\n listener?: ((error: unknown, context: JourneyProviderErrorContext) => void) | undefined\n) => {\n if (listener) {\n listener(error, context);\n return;\n }\n\n console.error(`JourneyProvider ${context.phase} failed.`, error);\n};\n\nexport const createJourneyProviderArtifacts = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n machine: JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>,\n useJourneySelector: <TSelected>(\n selector: JourneySelector<TContext, TStepId, TSelected>,\n equalityFn?: JourneyEqualityFn<TSelected>\n ) => TSelected\n) => {\n const ViewsContext = React.createContext<JourneyViews<TStepId> | null>(null);\n\n const useJourneyViews = (hookName = \"hook\") => {\n const views = React.useContext(ViewsContext);\n if (!views) {\n throw new Error(`${hookName} must be used within JourneyProvider.`);\n }\n return views;\n };\n\n const ProviderController = ({\n runtimeMachine,\n onStart,\n onComplete,\n onTerminate,\n onError,\n disposeOnUnmount\n }: {\n runtimeMachine: typeof machine;\n onStart: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onStart\"] | undefined;\n onComplete: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onComplete\"] | undefined;\n onTerminate: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onTerminate\"] | undefined;\n onError: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onError\"] | undefined;\n disposeOnUnmount: boolean;\n }) => {\n const onStartRef = React.useRef(onStart);\n const onCompleteRef = React.useRef(onComplete);\n const onTerminateRef = React.useRef(onTerminate);\n const onErrorRef = React.useRef(onError);\n const scheduledDisposeRef = React.useRef<ReturnType<typeof globalThis.setTimeout> | null>(null);\n const hasOnStart = onStart !== undefined;\n const hasOnComplete = onComplete !== undefined;\n const hasOnTerminate = onTerminate !== undefined;\n\n onStartRef.current = onStart;\n onCompleteRef.current = onComplete;\n onTerminateRef.current = onTerminate;\n onErrorRef.current = onError;\n\n useSafeLayoutEffect(() => {\n if (scheduledDisposeRef.current === null) {\n return;\n }\n\n globalThis.clearTimeout(scheduledDisposeRef.current);\n scheduledDisposeRef.current = null;\n });\n\n const selectStatus = React.useCallback(\n (snapshot: ReturnType<typeof runtimeMachine.getSnapshot>) => snapshot.status,\n [runtimeMachine]\n );\n const subscribeToStatus = React.useCallback(\n (onStoreChange: () => void) =>\n runtimeMachine.subscribeSelector(selectStatus, () => {\n onStoreChange();\n }),\n [runtimeMachine, selectStatus]\n );\n const getStatus = React.useCallback(\n () => runtimeMachine.getSnapshot().status,\n [runtimeMachine]\n );\n const status = React.useSyncExternalStore(subscribeToStatus, getStatus, getStatus);\n\n useSafeLayoutEffect(() => {\n if (!hasOnStart && !hasOnComplete && !hasOnTerminate) {\n return;\n }\n\n const unsubStart = hasOnStart\n ? runtimeMachine.subscribeStart((event) => {\n onStartRef.current?.(event);\n })\n : undefined;\n\n const unsubComplete = hasOnComplete\n ? runtimeMachine.subscribeComplete((event) => {\n onCompleteRef.current?.(event);\n })\n : undefined;\n\n const unsubTerminate = hasOnTerminate\n ? runtimeMachine.subscribeTerminate((event) => {\n onTerminateRef.current?.(event);\n })\n : undefined;\n\n return () => {\n unsubStart?.();\n unsubComplete?.();\n unsubTerminate?.();\n };\n }, [runtimeMachine, hasOnComplete, hasOnStart, hasOnTerminate]);\n\n useSafeLayoutEffect(() => {\n if (status === \"idled\") {\n void runtimeMachine.start().catch((error) => {\n reportProviderError(error, { phase: \"start\" }, onErrorRef.current);\n });\n }\n }, [runtimeMachine, status]);\n\n useSafeLayoutEffect(() => {\n if (!disposeOnUnmount) {\n return;\n }\n\n return () => {\n scheduledDisposeRef.current = globalThis.setTimeout(() => {\n scheduledDisposeRef.current = null;\n runtimeMachine.dispose();\n }, 0);\n };\n }, [runtimeMachine, disposeOnUnmount]);\n\n return null;\n };\n\n const JourneyProvider = ({\n views,\n onStart,\n onComplete,\n onTerminate,\n onError,\n disposeOnUnmount = false,\n children\n }: JourneyProviderProps<TStepId, TEventMap, TStepMeta>) => {\n const runtimeMachine = machine;\n\n return (\n <ViewsContext.Provider value={views}>\n {children}\n <ProviderController\n runtimeMachine={runtimeMachine}\n onStart={onStart}\n onComplete={onComplete}\n onTerminate={onTerminate}\n onError={onError}\n disposeOnUnmount={disposeOnUnmount}\n />\n </ViewsContext.Provider>\n );\n };\n\n const StepRenderer = ({ fallback = null }: { fallback?: React.ReactNode }) => {\n const currentStepId = useJourneySelector((snapshot) => snapshot.currentStepId);\n const views = useJourneyViews(\"StepRenderer\");\n const StepComponent = views[currentStepId];\n\n if (!StepComponent) {\n return <>{fallback}</>;\n }\n\n const StepView = StepComponent as React.ComponentType;\n\n return (\n <React.Fragment key={currentStepId}>\n <StepView />\n </React.Fragment>\n );\n };\n\n return {\n JourneyProvider,\n StepRenderer\n };\n};\n", "import React from \"react\";\n\nimport type {\n JourneyComputed,\n JourneyEqualityFn,\n JourneyJsonObject,\n JourneyMachinePlugin,\n JourneyMachineWithPlugins,\n JourneyObservationEvent,\n JourneySelector,\n JourneySnapshot\n} from \"@rxova/journey-core\";\nimport type { JourneyApi } from \"./types\";\n\ntype SelectorCache<TContext extends JourneyJsonObject, TStepId extends string, TSelected> = {\n machine: unknown;\n snapshot: JourneySnapshot<TContext, TStepId>;\n selected: TSelected;\n selector: unknown;\n isEqual: JourneyEqualityFn<TSelected>;\n};\n\nconst useSafeLayoutEffect = typeof window === \"undefined\" ? React.useEffect : React.useLayoutEffect;\n\nexport const createJourneyHooks = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n machine: JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>\n) => {\n const useJourneySnapshot = (): JourneySnapshot<TContext, TStepId> => {\n const runtimeMachine = machine;\n const getSnapshot = React.useCallback(() => runtimeMachine.getSnapshot(), [runtimeMachine]);\n const subscribe = React.useCallback(\n (onStoreChange: () => void) => runtimeMachine.subscribe(onStoreChange),\n [runtimeMachine]\n );\n\n return React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useJourneyComputed = (): JourneyComputed<TStepId> => {\n const snapshot = useJourneySnapshot();\n const runtimeMachine = machine;\n return React.useMemo(() => {\n void snapshot;\n return runtimeMachine.getComputed();\n }, [runtimeMachine, snapshot]);\n };\n\n const useJourneySelector = <TSelected,>(\n selector: JourneySelector<TContext, TStepId, TSelected>,\n equalityFn?: JourneyEqualityFn<TSelected>\n ): TSelected => {\n const runtimeMachine = machine;\n const isEqual = equalityFn ?? Object.is;\n const cacheRef = React.useRef<SelectorCache<TContext, TStepId, TSelected> | null>(null);\n\n const getSelectedSnapshot = React.useCallback(() => {\n const nextSnapshot = runtimeMachine.getSnapshot();\n const cached = cacheRef.current;\n\n if (\n cached &&\n Object.is(cached.machine, runtimeMachine) &&\n Object.is(cached.selector, selector) &&\n Object.is(cached.isEqual, isEqual) &&\n Object.is(cached.snapshot, nextSnapshot)\n ) {\n return cached.selected;\n }\n\n const nextSelected = selector(nextSnapshot);\n\n if (\n cached &&\n Object.is(cached.machine, runtimeMachine) &&\n Object.is(cached.selector, selector) &&\n Object.is(cached.isEqual, isEqual) &&\n isEqual(cached.selected, nextSelected)\n ) {\n cacheRef.current = {\n machine: runtimeMachine,\n snapshot: nextSnapshot,\n selected: cached.selected,\n selector,\n isEqual\n };\n return cached.selected;\n }\n\n cacheRef.current = {\n machine: runtimeMachine,\n snapshot: nextSnapshot,\n selected: nextSelected,\n selector,\n isEqual\n };\n return nextSelected;\n }, [runtimeMachine, isEqual, selector]);\n\n const subscribeToSelectedSnapshot = React.useCallback(\n (onStoreChange: () => void) =>\n runtimeMachine.subscribeSelector(\n selector,\n () => {\n onStoreChange();\n },\n isEqual\n ),\n [runtimeMachine, isEqual, selector]\n );\n\n return React.useSyncExternalStore(\n subscribeToSelectedSnapshot,\n getSelectedSnapshot,\n getSelectedSnapshot\n );\n };\n\n const useJourneyEvent = (\n listener: (event: JourneyObservationEvent<TStepId, TEventMap>) => void\n ): void => {\n const runtimeMachine = machine;\n const listenerRef = React.useRef(listener);\n listenerRef.current = listener;\n\n useSafeLayoutEffect(() => {\n return runtimeMachine.subscribeEvent((event) => {\n listenerRef.current(event);\n });\n }, [runtimeMachine]);\n };\n\n const useJourneyStepLifecycle = (\n stepId: TStepId,\n callbacks: {\n onEnter?: (args: { context: TContext }) => void;\n onLeave?: (args: { context: TContext }) => void;\n }\n ): void => {\n useJourneyEvent((event) => {\n if (event.type === \"step.enter\" && event.stepId === stepId) {\n callbacks.onEnter?.({ context: machine.getSnapshot().context });\n } else if (event.type === \"step.exit\" && event.stepId === stepId) {\n callbacks.onLeave?.({ context: machine.getSnapshot().context });\n }\n });\n };\n\n const useJourneyApi = (): JourneyApi<TContext, TStepId, TEventMap, TStepMeta> => {\n const runtimeMachine = machine;\n return React.useMemo(\n () => ({\n start: runtimeMachine.start,\n send: runtimeMachine.send,\n goToNextStep: runtimeMachine.goToNextStep,\n goToStepById: runtimeMachine.goToStepById,\n terminateJourney: runtimeMachine.terminateJourney,\n completeJourney: runtimeMachine.completeJourney,\n goToPreviousStep: runtimeMachine.goToPreviousStep,\n goToLastVisitedStep: runtimeMachine.goToLastVisitedStep,\n clearStepError: runtimeMachine.clearStepError,\n updateContext: runtimeMachine.updateContext,\n getStepMeta: runtimeMachine.getStepMeta,\n resetJourney: () => runtimeMachine.resetJourney()\n }),\n [runtimeMachine]\n );\n };\n\n return {\n useJourneySnapshot,\n useJourneyComputed,\n useJourneySelector,\n useJourneyApi,\n useJourneyEvent,\n useJourneyStepLifecycle\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["client_exports", "__export", "createJourney", "createJourneyFactory", "__toCommonJS", "import_journey_core", "import_react", "import_jsx_runtime", "useSafeLayoutEffect", "React", "reportProviderError", "error", "context", "listener", "createJourneyProviderArtifacts", "machine", "useJourneySelector", "ViewsContext", "useJourneyViews", "hookName", "views", "ProviderController", "runtimeMachine", "onStart", "onComplete", "onTerminate", "onError", "disposeOnUnmount", "onStartRef", "onCompleteRef", "onTerminateRef", "onErrorRef", "scheduledDisposeRef", "hasOnStart", "hasOnComplete", "hasOnTerminate", "selectStatus", "snapshot", "subscribeToStatus", "onStoreChange", "getStatus", "status", "unsubStart", "event", "unsubComplete", "unsubTerminate", "children", "fallback", "currentStepId", "StepComponent", "StepView", "import_react", "useSafeLayoutEffect", "React", "createJourneyHooks", "machine", "useJourneySnapshot", "runtimeMachine", "getSnapshot", "subscribe", "onStoreChange", "useJourneyComputed", "snapshot", "useJourneySelector", "selector", "equalityFn", "isEqual", "cacheRef", "getSelectedSnapshot", "nextSnapshot", "cached", "nextSelected", "subscribeToSelectedSnapshot", "useJourneyEvent", "listener", "listenerRef", "event", "stepId", "callbacks", "createJourney", "definition", "options", "machine", "hooks", "createJourneyHooks", "providerArtifacts", "createJourneyProviderArtifacts", "createJourneyFactory"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./index";
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./index";
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{createJourneyMachine as W}from"@rxova/journey-core";import u from"react";import{Fragment as A,jsx as h,jsxs as L}from"react/jsx-runtime";var g=typeof window>"u"?u.useEffect:u.useLayoutEffect,q=(r,c,y)=>{if(y){y(r,c);return}console.error(`JourneyProvider ${c.phase} failed.`,r)},I=(r,c)=>{let y=u.createContext(null),l=(e="hook")=>{let t=u.useContext(y);if(!t)throw new Error(`${e} must be used within JourneyProvider.`);return t},T=({runtimeMachine:e,onStart:t,onComplete:n,onTerminate:o,onError:p,disposeOnUnmount:d})=>{let J=u.useRef(t),a=u.useRef(n),s=u.useRef(o),v=u.useRef(p),f=u.useRef(null),P=t!==void 0,E=n!==void 0,m=o!==void 0;J.current=t,a.current=n,s.current=o,v.current=p,g(()=>{f.current!==null&&(globalThis.clearTimeout(f.current),f.current=null)});let C=u.useCallback(S=>S.status,[e]),j=u.useCallback(S=>e.subscribeSelector(C,()=>{S()}),[e,C]),b=u.useCallback(()=>e.getSnapshot().status,[e]),R=u.useSyncExternalStore(j,b,b);return g(()=>{if(!P&&!E&&!m)return;let S=P?e.subscribeStart(x=>{J.current?.(x)}):void 0,H=E?e.subscribeComplete(x=>{a.current?.(x)}):void 0,F=m?e.subscribeTerminate(x=>{s.current?.(x)}):void 0;return()=>{S?.(),H?.(),F?.()}},[e,E,P,m]),g(()=>{R==="idled"&&e.start().catch(S=>{q(S,{phase:"start"},v.current)})},[e,R]),g(()=>{if(d)return()=>{f.current=globalThis.setTimeout(()=>{f.current=null,e.dispose()},0)}},[e,d]),null};return{JourneyProvider:({views:e,onStart:t,onComplete:n,onTerminate:o,onError:p,disposeOnUnmount:d=!1,children:J})=>{let a=r;return L(y.Provider,{value:e,children:[J,h(T,{runtimeMachine:a,onStart:t,onComplete:n,onTerminate:o,onError:p,disposeOnUnmount:d})]})},StepRenderer:({fallback:e=null})=>{let t=c(d=>d.currentStepId),o=l("StepRenderer")[t];if(!o)return h(A,{children:e});let p=o;return h(u.Fragment,{children:h(p,{})},t)}}};import i from"react";var V=typeof window>"u"?i.useEffect:i.useLayoutEffect,O=r=>{let c=()=>{let e=r,t=i.useCallback(()=>e.getSnapshot(),[e]),n=i.useCallback(o=>e.subscribe(o),[e]);return i.useSyncExternalStore(n,t,t)},y=()=>{let e=c(),t=r;return i.useMemo(()=>t.getComputed(),[t,e])},l=(e,t)=>{let n=r,o=t??Object.is,p=i.useRef(null),d=i.useCallback(()=>{let a=n.getSnapshot(),s=p.current;if(s&&Object.is(s.machine,n)&&Object.is(s.selector,e)&&Object.is(s.isEqual,o)&&Object.is(s.snapshot,a))return s.selected;let v=e(a);return s&&Object.is(s.machine,n)&&Object.is(s.selector,e)&&Object.is(s.isEqual,o)&&o(s.selected,v)?(p.current={machine:n,snapshot:a,selected:s.selected,selector:e,isEqual:o},s.selected):(p.current={machine:n,snapshot:a,selected:v,selector:e,isEqual:o},v)},[n,o,e]),J=i.useCallback(a=>n.subscribeSelector(e,()=>{a()},o),[n,o,e]);return i.useSyncExternalStore(J,d,d)},T=e=>{let t=r,n=i.useRef(e);n.current=e,V(()=>t.subscribeEvent(o=>{n.current(o)}),[t])};return{useJourneySnapshot:c,useJourneyComputed:y,useJourneySelector:l,useJourneyApi:()=>{let e=r;return i.useMemo(()=>({start:e.start,send:e.send,goToNextStep:e.goToNextStep,goToStepById:e.goToStepById,terminateJourney:e.terminateJourney,completeJourney:e.completeJourney,goToPreviousStep:e.goToPreviousStep,goToLastVisitedStep:e.goToLastVisitedStep,clearStepError:e.clearStepError,updateContext:e.updateContext,getStepMeta:e.getStepMeta,resetJourney:()=>e.resetJourney()}),[e])},useJourneyEvent:T,useJourneyStepLifecycle:(e,t)=>{T(n=>{n.type==="step.enter"&&n.stepId===e?t.onEnter?.({context:r.getSnapshot().context}):n.type==="step.exit"&&n.stepId===e&&t.onLeave?.({context:r.getSnapshot().context})})}}};var w=(r,c)=>{let l=W(r,c),T=O(l),M=I(l,T.useJourneySelector);return{machine:l,dispose:()=>l.dispose(),...T,...M}},D=(r,c)=>()=>w(r,c);export{w as createJourney,D as createJourneyFactory};
|
|
2
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/createJourney.tsx", "../src/provider.tsx", "../src/runtime-hooks.tsx"],
|
|
4
|
+
"sourcesContent": ["import { createJourneyMachine } from \"@rxova/journey-core\";\nimport type {\n JourneyDefinition,\n JourneyJsonObject,\n JourneyMachineOptions,\n JourneyMachinePlugin,\n JourneyMachineWithPlugins\n} from \"@rxova/journey-core\";\nimport { createJourneyProviderArtifacts } from \"./provider\";\nimport { createJourneyHooks } from \"./runtime-hooks\";\nimport type { JourneyRuntime, JourneyRuntimeFactory } from \"./types\";\n\ntype JourneyOptionsInput<TPlugins extends readonly JourneyMachinePlugin[]> = JourneyMachineOptions<\n TPlugins extends [] ? readonly JourneyMachinePlugin[] : TPlugins\n>;\n\n/**\n * Creates a journey machine and returns React hooks/components bound to that machine.\n * Hooks work without a provider; `JourneyProvider` is only required for `StepRenderer`.\n */\nexport const createJourney = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>,\n options?: JourneyOptionsInput<TPlugins>\n): JourneyRuntime<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers> => {\n const machineOptions = options as JourneyMachineOptions<TPlugins> | undefined;\n const machine = createJourneyMachine<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >(definition, machineOptions) as JourneyMachineWithPlugins<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >;\n const hooks = createJourneyHooks<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>(\n machine\n );\n const providerArtifacts = createJourneyProviderArtifacts<\n TContext,\n TStepId,\n TEventMap,\n TStepMeta,\n THandlers,\n TPlugins\n >(machine, hooks.useJourneySelector);\n\n return {\n machine,\n dispose: () => machine.dispose(),\n ...hooks,\n ...providerArtifacts\n };\n};\n\n/**\n * Creates a typed factory for producing fresh React-bound journey runtimes.\n * Use this when a component or route boundary needs independent instances\n * from the same definition/options pair.\n */\nexport const createJourneyFactory = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>,\n options?: JourneyOptionsInput<TPlugins>\n): JourneyRuntimeFactory<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers> => {\n return () =>\n createJourney<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>(\n definition,\n options\n );\n};\n", "import React from \"react\";\n\nimport type {\n JourneyEqualityFn,\n JourneyJsonObject,\n JourneySelector,\n JourneyMachineWithPlugins,\n JourneyMachinePlugin\n} from \"@rxova/journey-core\";\nimport type { JourneyProviderErrorContext, JourneyProviderProps, JourneyViews } from \"./types\";\n\nconst useSafeLayoutEffect = typeof window === \"undefined\" ? React.useEffect : React.useLayoutEffect;\n\nconst reportProviderError = (\n error: unknown,\n context: JourneyProviderErrorContext,\n listener?: ((error: unknown, context: JourneyProviderErrorContext) => void) | undefined\n) => {\n if (listener) {\n listener(error, context);\n return;\n }\n\n console.error(`JourneyProvider ${context.phase} failed.`, error);\n};\n\nexport const createJourneyProviderArtifacts = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n machine: JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>,\n useJourneySelector: <TSelected>(\n selector: JourneySelector<TContext, TStepId, TSelected>,\n equalityFn?: JourneyEqualityFn<TSelected>\n ) => TSelected\n) => {\n const ViewsContext = React.createContext<JourneyViews<TStepId> | null>(null);\n\n const useJourneyViews = (hookName = \"hook\") => {\n const views = React.useContext(ViewsContext);\n if (!views) {\n throw new Error(`${hookName} must be used within JourneyProvider.`);\n }\n return views;\n };\n\n const ProviderController = ({\n runtimeMachine,\n onStart,\n onComplete,\n onTerminate,\n onError,\n disposeOnUnmount\n }: {\n runtimeMachine: typeof machine;\n onStart: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onStart\"] | undefined;\n onComplete: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onComplete\"] | undefined;\n onTerminate: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onTerminate\"] | undefined;\n onError: JourneyProviderProps<TStepId, TEventMap, TStepMeta>[\"onError\"] | undefined;\n disposeOnUnmount: boolean;\n }) => {\n const onStartRef = React.useRef(onStart);\n const onCompleteRef = React.useRef(onComplete);\n const onTerminateRef = React.useRef(onTerminate);\n const onErrorRef = React.useRef(onError);\n const scheduledDisposeRef = React.useRef<ReturnType<typeof globalThis.setTimeout> | null>(null);\n const hasOnStart = onStart !== undefined;\n const hasOnComplete = onComplete !== undefined;\n const hasOnTerminate = onTerminate !== undefined;\n\n onStartRef.current = onStart;\n onCompleteRef.current = onComplete;\n onTerminateRef.current = onTerminate;\n onErrorRef.current = onError;\n\n useSafeLayoutEffect(() => {\n if (scheduledDisposeRef.current === null) {\n return;\n }\n\n globalThis.clearTimeout(scheduledDisposeRef.current);\n scheduledDisposeRef.current = null;\n });\n\n const selectStatus = React.useCallback(\n (snapshot: ReturnType<typeof runtimeMachine.getSnapshot>) => snapshot.status,\n [runtimeMachine]\n );\n const subscribeToStatus = React.useCallback(\n (onStoreChange: () => void) =>\n runtimeMachine.subscribeSelector(selectStatus, () => {\n onStoreChange();\n }),\n [runtimeMachine, selectStatus]\n );\n const getStatus = React.useCallback(\n () => runtimeMachine.getSnapshot().status,\n [runtimeMachine]\n );\n const status = React.useSyncExternalStore(subscribeToStatus, getStatus, getStatus);\n\n useSafeLayoutEffect(() => {\n if (!hasOnStart && !hasOnComplete && !hasOnTerminate) {\n return;\n }\n\n const unsubStart = hasOnStart\n ? runtimeMachine.subscribeStart((event) => {\n onStartRef.current?.(event);\n })\n : undefined;\n\n const unsubComplete = hasOnComplete\n ? runtimeMachine.subscribeComplete((event) => {\n onCompleteRef.current?.(event);\n })\n : undefined;\n\n const unsubTerminate = hasOnTerminate\n ? runtimeMachine.subscribeTerminate((event) => {\n onTerminateRef.current?.(event);\n })\n : undefined;\n\n return () => {\n unsubStart?.();\n unsubComplete?.();\n unsubTerminate?.();\n };\n }, [runtimeMachine, hasOnComplete, hasOnStart, hasOnTerminate]);\n\n useSafeLayoutEffect(() => {\n if (status === \"idled\") {\n void runtimeMachine.start().catch((error) => {\n reportProviderError(error, { phase: \"start\" }, onErrorRef.current);\n });\n }\n }, [runtimeMachine, status]);\n\n useSafeLayoutEffect(() => {\n if (!disposeOnUnmount) {\n return;\n }\n\n return () => {\n scheduledDisposeRef.current = globalThis.setTimeout(() => {\n scheduledDisposeRef.current = null;\n runtimeMachine.dispose();\n }, 0);\n };\n }, [runtimeMachine, disposeOnUnmount]);\n\n return null;\n };\n\n const JourneyProvider = ({\n views,\n onStart,\n onComplete,\n onTerminate,\n onError,\n disposeOnUnmount = false,\n children\n }: JourneyProviderProps<TStepId, TEventMap, TStepMeta>) => {\n const runtimeMachine = machine;\n\n return (\n <ViewsContext.Provider value={views}>\n {children}\n <ProviderController\n runtimeMachine={runtimeMachine}\n onStart={onStart}\n onComplete={onComplete}\n onTerminate={onTerminate}\n onError={onError}\n disposeOnUnmount={disposeOnUnmount}\n />\n </ViewsContext.Provider>\n );\n };\n\n const StepRenderer = ({ fallback = null }: { fallback?: React.ReactNode }) => {\n const currentStepId = useJourneySelector((snapshot) => snapshot.currentStepId);\n const views = useJourneyViews(\"StepRenderer\");\n const StepComponent = views[currentStepId];\n\n if (!StepComponent) {\n return <>{fallback}</>;\n }\n\n const StepView = StepComponent as React.ComponentType;\n\n return (\n <React.Fragment key={currentStepId}>\n <StepView />\n </React.Fragment>\n );\n };\n\n return {\n JourneyProvider,\n StepRenderer\n };\n};\n", "import React from \"react\";\n\nimport type {\n JourneyComputed,\n JourneyEqualityFn,\n JourneyJsonObject,\n JourneyMachinePlugin,\n JourneyMachineWithPlugins,\n JourneyObservationEvent,\n JourneySelector,\n JourneySnapshot\n} from \"@rxova/journey-core\";\nimport type { JourneyApi } from \"./types\";\n\ntype SelectorCache<TContext extends JourneyJsonObject, TStepId extends string, TSelected> = {\n machine: unknown;\n snapshot: JourneySnapshot<TContext, TStepId>;\n selected: TSelected;\n selector: unknown;\n isEqual: JourneyEqualityFn<TSelected>;\n};\n\nconst useSafeLayoutEffect = typeof window === \"undefined\" ? React.useEffect : React.useLayoutEffect;\n\nexport const createJourneyHooks = <\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 TPlugins extends readonly JourneyMachinePlugin[] = []\n>(\n machine: JourneyMachineWithPlugins<TContext, TStepId, TEventMap, TStepMeta, THandlers, TPlugins>\n) => {\n const useJourneySnapshot = (): JourneySnapshot<TContext, TStepId> => {\n const runtimeMachine = machine;\n const getSnapshot = React.useCallback(() => runtimeMachine.getSnapshot(), [runtimeMachine]);\n const subscribe = React.useCallback(\n (onStoreChange: () => void) => runtimeMachine.subscribe(onStoreChange),\n [runtimeMachine]\n );\n\n return React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useJourneyComputed = (): JourneyComputed<TStepId> => {\n const snapshot = useJourneySnapshot();\n const runtimeMachine = machine;\n return React.useMemo(() => {\n void snapshot;\n return runtimeMachine.getComputed();\n }, [runtimeMachine, snapshot]);\n };\n\n const useJourneySelector = <TSelected,>(\n selector: JourneySelector<TContext, TStepId, TSelected>,\n equalityFn?: JourneyEqualityFn<TSelected>\n ): TSelected => {\n const runtimeMachine = machine;\n const isEqual = equalityFn ?? Object.is;\n const cacheRef = React.useRef<SelectorCache<TContext, TStepId, TSelected> | null>(null);\n\n const getSelectedSnapshot = React.useCallback(() => {\n const nextSnapshot = runtimeMachine.getSnapshot();\n const cached = cacheRef.current;\n\n if (\n cached &&\n Object.is(cached.machine, runtimeMachine) &&\n Object.is(cached.selector, selector) &&\n Object.is(cached.isEqual, isEqual) &&\n Object.is(cached.snapshot, nextSnapshot)\n ) {\n return cached.selected;\n }\n\n const nextSelected = selector(nextSnapshot);\n\n if (\n cached &&\n Object.is(cached.machine, runtimeMachine) &&\n Object.is(cached.selector, selector) &&\n Object.is(cached.isEqual, isEqual) &&\n isEqual(cached.selected, nextSelected)\n ) {\n cacheRef.current = {\n machine: runtimeMachine,\n snapshot: nextSnapshot,\n selected: cached.selected,\n selector,\n isEqual\n };\n return cached.selected;\n }\n\n cacheRef.current = {\n machine: runtimeMachine,\n snapshot: nextSnapshot,\n selected: nextSelected,\n selector,\n isEqual\n };\n return nextSelected;\n }, [runtimeMachine, isEqual, selector]);\n\n const subscribeToSelectedSnapshot = React.useCallback(\n (onStoreChange: () => void) =>\n runtimeMachine.subscribeSelector(\n selector,\n () => {\n onStoreChange();\n },\n isEqual\n ),\n [runtimeMachine, isEqual, selector]\n );\n\n return React.useSyncExternalStore(\n subscribeToSelectedSnapshot,\n getSelectedSnapshot,\n getSelectedSnapshot\n );\n };\n\n const useJourneyEvent = (\n listener: (event: JourneyObservationEvent<TStepId, TEventMap>) => void\n ): void => {\n const runtimeMachine = machine;\n const listenerRef = React.useRef(listener);\n listenerRef.current = listener;\n\n useSafeLayoutEffect(() => {\n return runtimeMachine.subscribeEvent((event) => {\n listenerRef.current(event);\n });\n }, [runtimeMachine]);\n };\n\n const useJourneyStepLifecycle = (\n stepId: TStepId,\n callbacks: {\n onEnter?: (args: { context: TContext }) => void;\n onLeave?: (args: { context: TContext }) => void;\n }\n ): void => {\n useJourneyEvent((event) => {\n if (event.type === \"step.enter\" && event.stepId === stepId) {\n callbacks.onEnter?.({ context: machine.getSnapshot().context });\n } else if (event.type === \"step.exit\" && event.stepId === stepId) {\n callbacks.onLeave?.({ context: machine.getSnapshot().context });\n }\n });\n };\n\n const useJourneyApi = (): JourneyApi<TContext, TStepId, TEventMap, TStepMeta> => {\n const runtimeMachine = machine;\n return React.useMemo(\n () => ({\n start: runtimeMachine.start,\n send: runtimeMachine.send,\n goToNextStep: runtimeMachine.goToNextStep,\n goToStepById: runtimeMachine.goToStepById,\n terminateJourney: runtimeMachine.terminateJourney,\n completeJourney: runtimeMachine.completeJourney,\n goToPreviousStep: runtimeMachine.goToPreviousStep,\n goToLastVisitedStep: runtimeMachine.goToLastVisitedStep,\n clearStepError: runtimeMachine.clearStepError,\n updateContext: runtimeMachine.updateContext,\n getStepMeta: runtimeMachine.getStepMeta,\n resetJourney: () => runtimeMachine.resetJourney()\n }),\n [runtimeMachine]\n );\n };\n\n return {\n useJourneySnapshot,\n useJourneyComputed,\n useJourneySelector,\n useJourneyApi,\n useJourneyEvent,\n useJourneyStepLifecycle\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["createJourneyMachine", "React", "Fragment", "jsx", "jsxs", "useSafeLayoutEffect", "reportProviderError", "error", "context", "listener", "createJourneyProviderArtifacts", "machine", "useJourneySelector", "ViewsContext", "useJourneyViews", "hookName", "views", "ProviderController", "runtimeMachine", "onStart", "onComplete", "onTerminate", "onError", "disposeOnUnmount", "onStartRef", "onCompleteRef", "onTerminateRef", "onErrorRef", "scheduledDisposeRef", "hasOnStart", "hasOnComplete", "hasOnTerminate", "selectStatus", "snapshot", "subscribeToStatus", "onStoreChange", "getStatus", "status", "unsubStart", "event", "unsubComplete", "unsubTerminate", "children", "fallback", "currentStepId", "StepComponent", "StepView", "React", "useSafeLayoutEffect", "createJourneyHooks", "machine", "useJourneySnapshot", "runtimeMachine", "getSnapshot", "subscribe", "onStoreChange", "useJourneyComputed", "snapshot", "useJourneySelector", "selector", "equalityFn", "isEqual", "cacheRef", "getSelectedSnapshot", "nextSnapshot", "cached", "nextSelected", "subscribeToSelectedSnapshot", "useJourneyEvent", "listener", "listenerRef", "event", "stepId", "callbacks", "createJourney", "definition", "options", "machine", "createJourneyMachine", "hooks", "createJourneyHooks", "providerArtifacts", "createJourneyProviderArtifacts", "createJourneyFactory"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JourneyDefinition, JourneyJsonObject, JourneyMachineOptions, JourneyMachinePlugin } from "@rxova/journey-core";
|
|
2
|
+
import type { JourneyRuntime, JourneyRuntimeFactory } from "./types";
|
|
3
|
+
type JourneyOptionsInput<TPlugins extends readonly JourneyMachinePlugin[]> = JourneyMachineOptions<TPlugins extends [] ? readonly JourneyMachinePlugin[] : TPlugins>;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a journey machine and returns React hooks/components bound to that machine.
|
|
6
|
+
* Hooks work without a provider; `JourneyProvider` is only required for `StepRenderer`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const createJourney: <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[] = []>(definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyOptionsInput<TPlugins>) => JourneyRuntime<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers>;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a typed factory for producing fresh React-bound journey runtimes.
|
|
11
|
+
* Use this when a component or route boundary needs independent instances
|
|
12
|
+
* from the same definition/options pair.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createJourneyFactory: <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[] = []>(definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyOptionsInput<TPlugins>) => JourneyRuntimeFactory<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JourneyDefinition, JourneyJsonObject, JourneyMachineOptions, JourneyMachinePlugin } from "@rxova/journey-core";
|
|
2
|
+
import type { JourneyRuntime, JourneyRuntimeFactory } from "./types";
|
|
3
|
+
type JourneyOptionsInput<TPlugins extends readonly JourneyMachinePlugin[]> = JourneyMachineOptions<TPlugins extends [] ? readonly JourneyMachinePlugin[] : TPlugins>;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a journey machine and returns React hooks/components bound to that machine.
|
|
6
|
+
* Hooks work without a provider; `JourneyProvider` is only required for `StepRenderer`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const createJourney: <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[] = []>(definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyOptionsInput<TPlugins>) => JourneyRuntime<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers>;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a typed factory for producing fresh React-bound journey runtimes.
|
|
11
|
+
* Use this when a component or route boundary needs independent instances
|
|
12
|
+
* from the same definition/options pair.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createJourneyFactory: <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[] = []>(definition: JourneyDefinition<TContext, TStepId, TEventMap, TStepMeta, THandlers>, options?: JourneyOptionsInput<TPlugins>) => JourneyRuntimeFactory<TContext, TStepId, TEventMap, TStepMeta, TPlugins, THandlers>;
|
|
15
|
+
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";var D=Object.create;var h=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var z=(t,r)=>{for(var u in r)h(t,u,{get:r[u],enumerable:!0})},w=(t,r,u,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of B(r))!U.call(t,a)&&a!==u&&h(t,a,{get:()=>r[a],enumerable:!(d=N(r,a))||d.enumerable});return t};var k=(t,r,u)=>(u=t!=null?D($(t)):{},w(r||!t||!t.__esModule?h(u,"default",{value:t,enumerable:!0}):u,t)),G=t=>w(h({},"__esModule",{value:!0}),t);var X={};z(X,{createJourney:()=>b,createJourneyFactory:()=>q});module.exports=G(X);var F=require("@rxova/journey-core");var c=k(require("react"),1),S=require("react/jsx-runtime"),M=typeof window>"u"?c.default.useEffect:c.default.useLayoutEffect,K=(t,r,u)=>{if(u){u(t,r);return}console.error(`JourneyProvider ${r.phase} failed.`,t)},j=(t,r)=>{let u=c.default.createContext(null),d=(e="hook")=>{let n=c.default.useContext(u);if(!n)throw new Error(`${e} must be used within JourneyProvider.`);return n},a=({runtimeMachine:e,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T})=>{let v=c.default.useRef(n),y=c.default.useRef(o),i=c.default.useRef(s),f=c.default.useRef(l),x=c.default.useRef(null),E=n!==void 0,m=o!==void 0,C=s!==void 0;v.current=n,y.current=o,i.current=s,f.current=l,M(()=>{x.current!==null&&(globalThis.clearTimeout(x.current),x.current=null)});let R=c.default.useCallback(J=>J.status,[e]),A=c.default.useCallback(J=>e.subscribeSelector(R,()=>{J()}),[e,R]),I=c.default.useCallback(()=>e.getSnapshot().status,[e]),O=c.default.useSyncExternalStore(A,I,I);return M(()=>{if(!E&&!m&&!C)return;let J=E?e.subscribeStart(g=>{v.current?.(g)}):void 0,V=m?e.subscribeComplete(g=>{y.current?.(g)}):void 0,W=C?e.subscribeTerminate(g=>{i.current?.(g)}):void 0;return()=>{J?.(),V?.(),W?.()}},[e,m,E,C]),M(()=>{O==="idled"&&e.start().catch(J=>{K(J,{phase:"start"},f.current)})},[e,O]),M(()=>{if(T)return()=>{x.current=globalThis.setTimeout(()=>{x.current=null,e.dispose()},0)}},[e,T]),null};return{JourneyProvider:({views:e,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T=!1,children:v})=>{let y=t;return(0,S.jsxs)(u.Provider,{value:e,children:[v,(0,S.jsx)(a,{runtimeMachine:y,onStart:n,onComplete:o,onTerminate:s,onError:l,disposeOnUnmount:T})]})},StepRenderer:({fallback:e=null})=>{let n=r(T=>T.currentStepId),s=d("StepRenderer")[n];if(!s)return(0,S.jsx)(S.Fragment,{children:e});let l=s;return(0,S.jsx)(c.default.Fragment,{children:(0,S.jsx)(l,{})},n)}}};var p=k(require("react"),1),Q=typeof window>"u"?p.default.useEffect:p.default.useLayoutEffect,H=t=>{let r=()=>{let e=t,n=p.default.useCallback(()=>e.getSnapshot(),[e]),o=p.default.useCallback(s=>e.subscribe(s),[e]);return p.default.useSyncExternalStore(o,n,n)},u=()=>{let e=r(),n=t;return p.default.useMemo(()=>n.getComputed(),[n,e])},d=(e,n)=>{let o=t,s=n??Object.is,l=p.default.useRef(null),T=p.default.useCallback(()=>{let y=o.getSnapshot(),i=l.current;if(i&&Object.is(i.machine,o)&&Object.is(i.selector,e)&&Object.is(i.isEqual,s)&&Object.is(i.snapshot,y))return i.selected;let f=e(y);return i&&Object.is(i.machine,o)&&Object.is(i.selector,e)&&Object.is(i.isEqual,s)&&s(i.selected,f)?(l.current={machine:o,snapshot:y,selected:i.selected,selector:e,isEqual:s},i.selected):(l.current={machine:o,snapshot:y,selected:f,selector:e,isEqual:s},f)},[o,s,e]),v=p.default.useCallback(y=>o.subscribeSelector(e,()=>{y()},s),[o,s,e]);return p.default.useSyncExternalStore(v,T,T)},a=e=>{let n=t,o=p.default.useRef(e);o.current=e,Q(()=>n.subscribeEvent(s=>{o.current(s)}),[n])};return{useJourneySnapshot:r,useJourneyComputed:u,useJourneySelector:d,useJourneyApi:()=>{let e=t;return p.default.useMemo(()=>({start:e.start,send:e.send,goToNextStep:e.goToNextStep,goToStepById:e.goToStepById,terminateJourney:e.terminateJourney,completeJourney:e.completeJourney,goToPreviousStep:e.goToPreviousStep,goToLastVisitedStep:e.goToLastVisitedStep,clearStepError:e.clearStepError,updateContext:e.updateContext,getStepMeta:e.getStepMeta,resetJourney:()=>e.resetJourney()}),[e])},useJourneyEvent:a,useJourneyStepLifecycle:(e,n)=>{a(o=>{o.type==="step.enter"&&o.stepId===e?n.onEnter?.({context:t.getSnapshot().context}):o.type==="step.exit"&&o.stepId===e&&n.onLeave?.({context:t.getSnapshot().context})})}}};var b=(t,r)=>{let d=(0,F.createJourneyMachine)(t,r),a=H(d),P=j(d,a.useJourneySelector);return{machine:d,dispose:()=>d.dispose(),...a,...P}},q=(t,r)=>()=>b(t,r);0&&(module.exports={createJourney,createJourneyFactory});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|