@daltonr/pathwrite-core 0.4.0 → 0.6.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.
- package/README.md +58 -7
- package/dist/index.d.ts +141 -17
- package/dist/index.js +123 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +258 -64
package/README.md
CHANGED
|
@@ -63,16 +63,22 @@ const path: PathDefinition<CourseData> = {
|
|
|
63
63
|
| `PathStep<TData>` | A single step: guards, lifecycle hooks. |
|
|
64
64
|
| `PathStepContext<TData>` | Passed to every hook and guard. `data` is a **readonly snapshot copy** — return a patch to update state. |
|
|
65
65
|
| `PathSnapshot<TData>` | Point-in-time read of the engine: step ID, index, count, flags, and a copy of data. |
|
|
66
|
-
| `PathEvent` | Union of `stateChanged
|
|
66
|
+
| `PathEvent` | Union of `stateChanged` (includes `cause`), `completed`, `cancelled`, and `resumed`. |
|
|
67
|
+
| `StateChangeCause` | Identifies the method that triggered a `stateChanged` event: `"start"` \| `"next"` \| `"previous"` \| `"goToStep"` \| `"goToStepChecked"` \| `"setData"` \| `"cancel"` \| `"restart"`. |
|
|
68
|
+
| `PathObserver` | `(event: PathEvent, engine: PathEngine) => void` — a function registered at construction time that receives every event for the engine's lifetime. |
|
|
69
|
+
| `PathEngineOptions` | `{ observers?: PathObserver[] }` — options accepted by the `PathEngine` constructor and `PathEngine.fromState()`. |
|
|
70
|
+
| `ObserverStrategy` | Union type for the five built-in trigger strategies: `"onEveryChange" \| "onNext" \| "onSubPathComplete" \| "onComplete" \| "manual"`. Import and use in your own observer factories. |
|
|
71
|
+
| `matchesStrategy` | `(strategy: ObserverStrategy, event: PathEvent) => boolean` — returns `true` when an event should trigger an observer under the given strategy. Shared by every observer so none re-implement the same "when do I fire?" logic. |
|
|
67
72
|
|
|
68
73
|
## PathEngine API
|
|
69
74
|
|
|
70
75
|
```typescript
|
|
71
|
-
|
|
76
|
+
// Observers are wired before the first event fires
|
|
77
|
+
const engine = new PathEngine({ observers: [myObserver, anotherObserver] });
|
|
72
78
|
|
|
73
79
|
engine.start(definition, initialData?); // start or re-start a path
|
|
74
80
|
engine.restart(definition, initialData?); // tear down stack and start fresh (no hooks, no cancelled event)
|
|
75
|
-
engine.startSubPath(definition, data?);
|
|
81
|
+
engine.startSubPath(definition, data?, meta?); // push sub-path onto the stack (requires active path)
|
|
76
82
|
engine.next();
|
|
77
83
|
engine.previous();
|
|
78
84
|
engine.cancel();
|
|
@@ -83,13 +89,56 @@ engine.snapshot(); // returns PathSnapshot | null
|
|
|
83
89
|
|
|
84
90
|
// Serialization API (for persistence)
|
|
85
91
|
const state = engine.exportState(); // returns SerializedPathState | null
|
|
86
|
-
const restoredEngine = PathEngine.fromState(state, pathDefinitions);
|
|
92
|
+
const restoredEngine = PathEngine.fromState(state, pathDefinitions, { observers: [...] });
|
|
87
93
|
|
|
94
|
+
// Removable one-off listener (use subscribe when you need to unsubscribe)
|
|
88
95
|
const unsubscribe = engine.subscribe((event) => { ... });
|
|
89
|
-
unsubscribe();
|
|
96
|
+
unsubscribe();
|
|
90
97
|
```
|
|
91
98
|
|
|
92
|
-
##
|
|
99
|
+
## Observers
|
|
100
|
+
|
|
101
|
+
Observers are functions registered at construction time. They receive every event for the engine's lifetime and cannot be removed — for removable listeners use `subscribe()`.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// A logger observer
|
|
105
|
+
const logger: PathObserver = (event) =>
|
|
106
|
+
console.log(`[${event.type}]`, 'cause' in event ? event.cause : '');
|
|
107
|
+
|
|
108
|
+
// A persistence observer using matchesStrategy from core
|
|
109
|
+
import { matchesStrategy } from "@daltonr/pathwrite-core";
|
|
110
|
+
|
|
111
|
+
const persist: PathObserver = (event, engine) => {
|
|
112
|
+
if (matchesStrategy("onNext", event)) {
|
|
113
|
+
myStore.save(engine.exportState());
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const engine = new PathEngine({ observers: [logger, persist] });
|
|
118
|
+
|
|
119
|
+
// Observers are also passed through fromState — so restored engines are fully observed
|
|
120
|
+
const restoredEngine = PathEngine.fromState(saved, pathDefs, { observers: [logger, persist] });
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The second argument to each observer is the engine itself, which lets observers call `engine.exportState()`, `engine.snapshot()`, etc. without needing a separate reference.
|
|
124
|
+
|
|
125
|
+
### Building your own observer factory
|
|
126
|
+
|
|
127
|
+
`ObserverStrategy` and `matchesStrategy` are exported from core so any observer — not just HTTP persistence — can share the same strategy logic without reimplementing it:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { type ObserverStrategy, matchesStrategy, type PathObserver } from "@daltonr/pathwrite-core";
|
|
131
|
+
|
|
132
|
+
function myObserver(strategy: ObserverStrategy): PathObserver {
|
|
133
|
+
return (event, engine) => {
|
|
134
|
+
if (matchesStrategy(strategy, event)) {
|
|
135
|
+
// react — save to MongoDB, write to a log, fire analytics, etc.
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
|
|
93
142
|
|
|
94
143
|
All hooks are optional. Hooks that want to update data **return a partial patch** — the engine applies it automatically. Direct mutation of `ctx.data` is a no-op; the context receives a copy.
|
|
95
144
|
|
|
@@ -416,7 +465,7 @@ Sub-paths can themselves start sub-paths (unlimited nesting). Use `snapshot.nest
|
|
|
416
465
|
```typescript
|
|
417
466
|
engine.subscribe((event) => {
|
|
418
467
|
switch (event.type) {
|
|
419
|
-
case "stateChanged": // event.snapshot
|
|
468
|
+
case "stateChanged": // event.cause ("start" | "next" | "previous" | ...), event.snapshot
|
|
420
469
|
case "completed": // event.pathId, event.data
|
|
421
470
|
case "cancelled": // event.pathId, event.data
|
|
422
471
|
case "resumed": // event.resumedPathId, event.fromSubPathId, event.snapshot
|
|
@@ -424,6 +473,8 @@ engine.subscribe((event) => {
|
|
|
424
473
|
});
|
|
425
474
|
```
|
|
426
475
|
|
|
476
|
+
Every `stateChanged` event includes a `cause` field (`StateChangeCause`) identifying which public method triggered it. Use this to react to specific operations — for example, the `store-http` package uses `event.cause === "next"` to implement the `onNext` persistence strategy.
|
|
477
|
+
|
|
427
478
|
## State Persistence
|
|
428
479
|
|
|
429
480
|
The engine supports exporting and restoring state for persistence scenarios (e.g., saving wizard progress to a server or localStorage).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
export type PathData = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* The return type of a `fieldMessages` hook. Each key is a field ID; the value
|
|
4
|
+
* is an error string, or `undefined` / omitted to indicate no error for that field.
|
|
5
|
+
*
|
|
6
|
+
* Use `"_"` as a key for form-level errors that don't belong to a specific field:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* { _: "You must accept the terms and conditions." }
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export type FieldErrors = Record<string, string | undefined>;
|
|
2
12
|
export interface SerializedPathState {
|
|
3
13
|
version: 1;
|
|
4
14
|
pathId: string;
|
|
@@ -15,6 +25,19 @@ export interface SerializedPathState {
|
|
|
15
25
|
}>;
|
|
16
26
|
_isNavigating: boolean;
|
|
17
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* The interface every path state store must implement.
|
|
30
|
+
*
|
|
31
|
+
* `HttpStore` from `@daltonr/pathwrite-store-http` is the reference
|
|
32
|
+
* implementation. Any backend — MongoDB, Redis, localStorage, etc. —
|
|
33
|
+
* implements this interface and works with `httpPersistence` and
|
|
34
|
+
* `restoreOrStart` without any other changes.
|
|
35
|
+
*/
|
|
36
|
+
export interface PathStore {
|
|
37
|
+
save(key: string, state: SerializedPathState): Promise<void>;
|
|
38
|
+
load(key: string): Promise<SerializedPathState | null>;
|
|
39
|
+
delete(key: string): Promise<void>;
|
|
40
|
+
}
|
|
18
41
|
export interface PathStepContext<TData extends PathData = PathData> {
|
|
19
42
|
readonly pathId: string;
|
|
20
43
|
readonly stepId: string;
|
|
@@ -36,12 +59,26 @@ export interface PathStep<TData extends PathData = PathData> {
|
|
|
36
59
|
canMoveNext?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
37
60
|
canMovePrevious?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
38
61
|
/**
|
|
39
|
-
* Returns a
|
|
40
|
-
* yet valid. The shell displays these messages below the step content
|
|
41
|
-
* consumers do not need to duplicate
|
|
42
|
-
*
|
|
62
|
+
* Returns a map of field ID → error message explaining why the step is not
|
|
63
|
+
* yet valid. The shell displays these messages below the step content (labeled
|
|
64
|
+
* by field name) so consumers do not need to duplicate validation logic in
|
|
65
|
+
* the template. Return `undefined` for a field to indicate no error.
|
|
66
|
+
*
|
|
67
|
+
* When `fieldMessages` is provided and `canMoveNext` is **not**, the engine
|
|
68
|
+
* automatically derives `canMoveNext` as `true` when all values are `undefined`
|
|
69
|
+
* (i.e. no messages), eliminating the need to express the same logic twice.
|
|
70
|
+
*
|
|
71
|
+
* Evaluated synchronously on every snapshot; async functions default to `{}`.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* fieldMessages: ({ data }) => ({
|
|
76
|
+
* name: !data.name?.trim() ? "Required." : undefined,
|
|
77
|
+
* email: !isValidEmail(data.email) ? "Invalid email address." : undefined,
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
43
80
|
*/
|
|
44
|
-
|
|
81
|
+
fieldMessages?: (ctx: PathStepContext<TData>) => FieldErrors;
|
|
45
82
|
onEnter?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
46
83
|
onLeave?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
47
84
|
/**
|
|
@@ -87,16 +124,44 @@ export interface PathSnapshot<TData extends PathData = PathData> {
|
|
|
87
124
|
nestingLevel: number;
|
|
88
125
|
/** True while an async guard or hook is executing. Use to disable navigation controls. */
|
|
89
126
|
isNavigating: boolean;
|
|
90
|
-
/** Whether the current step's `canMoveNext` guard allows advancing. Async guards default to `true`. */
|
|
127
|
+
/** Whether the current step's `canMoveNext` guard allows advancing. Async guards default to `true`. Auto-derived as `true` when `fieldMessages` is defined and returns no messages, and `canMoveNext` is not explicitly defined. */
|
|
91
128
|
canMoveNext: boolean;
|
|
92
129
|
/** Whether the current step's `canMovePrevious` guard allows going back. Async guards default to `true`. */
|
|
93
130
|
canMovePrevious: boolean;
|
|
94
|
-
/**
|
|
95
|
-
|
|
131
|
+
/**
|
|
132
|
+
* True after the user has clicked Next / Submit on this step at least once,
|
|
133
|
+
* regardless of whether navigation succeeded. Resets to `false` when entering
|
|
134
|
+
* a new step.
|
|
135
|
+
*
|
|
136
|
+
* Use this to gate inline field-error display so errors are hidden on first
|
|
137
|
+
* render and only appear after the user has attempted to proceed:
|
|
138
|
+
*
|
|
139
|
+
* ```svelte
|
|
140
|
+
* {#if snapshot.hasAttemptedNext && snapshot.fieldMessages.email}
|
|
141
|
+
* <span class="error">{snapshot.fieldMessages.email}</span>
|
|
142
|
+
* {/if}
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* The shell itself uses this flag to gate its own automatic `fieldMessages`
|
|
146
|
+
* summary rendering — errors are never shown before the first Next attempt.
|
|
147
|
+
*/
|
|
148
|
+
hasAttemptedNext: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Field-keyed validation messages for the current step. Empty object when there are none.
|
|
151
|
+
* Use in step templates to render inline per-field errors: `snapshot.fieldMessages['email']`.
|
|
152
|
+
* The shell also renders these automatically in a labeled summary box.
|
|
153
|
+
* Use `"_"` as a key for form-level (non-field-specific) errors.
|
|
154
|
+
*/
|
|
155
|
+
fieldMessages: Record<string, string>;
|
|
96
156
|
data: TData;
|
|
97
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Identifies the public method that triggered a `stateChanged` event.
|
|
160
|
+
*/
|
|
161
|
+
export type StateChangeCause = "start" | "next" | "previous" | "goToStep" | "goToStepChecked" | "setData" | "cancel" | "restart";
|
|
98
162
|
export type PathEvent = {
|
|
99
163
|
type: "stateChanged";
|
|
164
|
+
cause: StateChangeCause;
|
|
100
165
|
snapshot: PathSnapshot;
|
|
101
166
|
} | {
|
|
102
167
|
type: "completed";
|
|
@@ -112,11 +177,65 @@ export type PathEvent = {
|
|
|
112
177
|
fromSubPathId: string;
|
|
113
178
|
snapshot: PathSnapshot;
|
|
114
179
|
};
|
|
180
|
+
/**
|
|
181
|
+
* A function called on every engine event. Observers are registered at
|
|
182
|
+
* construction time and receive every event for the lifetime of the engine.
|
|
183
|
+
*
|
|
184
|
+
* The second argument is the engine itself — useful when the observer needs to
|
|
185
|
+
* read current state (e.g. calling `engine.exportState()` for persistence).
|
|
186
|
+
*
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const logger: PathObserver = (event) => console.log(event.type);
|
|
189
|
+
* const persist: PathObserver = (event, engine) => { ... };
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export type PathObserver = (event: PathEvent, engine: PathEngine) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Determines which engine events an observer should react to.
|
|
195
|
+
*
|
|
196
|
+
* | Strategy | Triggers when |
|
|
197
|
+
* |---------------------|------------------------------------------------------------|
|
|
198
|
+
* | `"onEveryChange"` | Any settled `stateChanged` or `resumed` |
|
|
199
|
+
* | `"onNext"` | `next()` completes navigation *(default)* |
|
|
200
|
+
* | `"onSubPathComplete"` | Sub-path finishes and the parent resumes |
|
|
201
|
+
* | `"onComplete"` | The entire path completes |
|
|
202
|
+
* | `"manual"` | Never — caller decides when to act |
|
|
203
|
+
*/
|
|
204
|
+
export type ObserverStrategy = "onEveryChange" | "onNext" | "onSubPathComplete" | "onComplete" | "manual";
|
|
205
|
+
/**
|
|
206
|
+
* Returns `true` when `event` matches the trigger condition for `strategy`.
|
|
207
|
+
*
|
|
208
|
+
* Use this in any `PathObserver` factory to centralise the
|
|
209
|
+
* "which events should I react to?" decision so every observer
|
|
210
|
+
* (HTTP, MongoDB, logger, analytics…) shares the same semantics.
|
|
211
|
+
*
|
|
212
|
+
* ```typescript
|
|
213
|
+
* const observer: PathObserver = (event, engine) => {
|
|
214
|
+
* if (matchesStrategy(strategy, event)) doWork(engine);
|
|
215
|
+
* };
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
export declare function matchesStrategy(strategy: ObserverStrategy, event: PathEvent): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Options accepted by the `PathEngine` constructor and `PathEngine.fromState()`.
|
|
221
|
+
*/
|
|
222
|
+
export interface PathEngineOptions {
|
|
223
|
+
/**
|
|
224
|
+
* Zero or more observers to register before the first event fires.
|
|
225
|
+
* Each observer is called synchronously on every engine event for the
|
|
226
|
+
* lifetime of the engine. Observers cannot be removed; for removable
|
|
227
|
+
* listeners use `engine.subscribe()`.
|
|
228
|
+
*/
|
|
229
|
+
observers?: PathObserver[];
|
|
230
|
+
}
|
|
115
231
|
export declare class PathEngine {
|
|
116
232
|
private activePath;
|
|
117
233
|
private readonly pathStack;
|
|
118
234
|
private readonly listeners;
|
|
119
235
|
private _isNavigating;
|
|
236
|
+
/** True after the user has called next() on the current step at least once. Resets on step entry. */
|
|
237
|
+
private _hasAttemptedNext;
|
|
238
|
+
constructor(options?: PathEngineOptions);
|
|
120
239
|
/**
|
|
121
240
|
* Restores a PathEngine from previously exported state.
|
|
122
241
|
*
|
|
@@ -131,7 +250,7 @@ export declare class PathEngine {
|
|
|
131
250
|
* @throws If `state` references a path ID not present in `pathDefinitions`,
|
|
132
251
|
* or if the state format is invalid.
|
|
133
252
|
*/
|
|
134
|
-
static fromState(state: SerializedPathState, pathDefinitions: Record<string, PathDefinition
|
|
253
|
+
static fromState(state: SerializedPathState, pathDefinitions: Record<string, PathDefinition>, options?: PathEngineOptions): PathEngine;
|
|
135
254
|
subscribe(listener: (event: PathEvent) => void): () => void;
|
|
136
255
|
start(path: PathDefinition<any>, initialData?: PathData): Promise<void>;
|
|
137
256
|
/**
|
|
@@ -227,15 +346,20 @@ export declare class PathEngine {
|
|
|
227
346
|
*/
|
|
228
347
|
private evaluateGuardSync;
|
|
229
348
|
/**
|
|
230
|
-
* Evaluates
|
|
231
|
-
*
|
|
232
|
-
*
|
|
349
|
+
* Evaluates `canMoveNext` synchronously for inclusion in the snapshot.
|
|
350
|
+
* When `canMoveNext` is defined, delegates to `evaluateGuardSync`.
|
|
351
|
+
* When absent but `fieldMessages` is defined, auto-derives: `true` iff no messages.
|
|
352
|
+
* When neither is defined, returns `true`.
|
|
353
|
+
*/
|
|
354
|
+
private evaluateCanMoveNextSync;
|
|
355
|
+
/**
|
|
356
|
+
* Evaluates a fieldMessages function synchronously for inclusion in the snapshot.
|
|
357
|
+
* If the hook is absent, returns `{}`.
|
|
358
|
+
* If the hook returns a `Promise`, returns `{}` (async hooks are not supported in snapshots).
|
|
359
|
+
* `undefined` values are stripped from the result — only fields with a defined message are included.
|
|
233
360
|
*
|
|
234
|
-
* **Note:** Like guards, `
|
|
361
|
+
* **Note:** Like guards, `fieldMessages` is evaluated before `onEnter` runs on first
|
|
235
362
|
* entry. Write it defensively so it does not throw when fields are absent.
|
|
236
|
-
*
|
|
237
|
-
* If the function throws, the error is caught, a `console.warn` is emitted, and `[]`
|
|
238
|
-
* is returned so validation messages do not block the UI unexpectedly.
|
|
239
363
|
*/
|
|
240
|
-
private
|
|
364
|
+
private evaluateFieldMessagesSync;
|
|
241
365
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns `true` when `event` matches the trigger condition for `strategy`.
|
|
3
|
+
*
|
|
4
|
+
* Use this in any `PathObserver` factory to centralise the
|
|
5
|
+
* "which events should I react to?" decision so every observer
|
|
6
|
+
* (HTTP, MongoDB, logger, analytics…) shares the same semantics.
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const observer: PathObserver = (event, engine) => {
|
|
10
|
+
* if (matchesStrategy(strategy, event)) doWork(engine);
|
|
11
|
+
* };
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function matchesStrategy(strategy, event) {
|
|
15
|
+
switch (strategy) {
|
|
16
|
+
case "onEveryChange":
|
|
17
|
+
// Only react once navigation has settled — stateChanged fires twice per
|
|
18
|
+
// navigation (isNavigating:true then false).
|
|
19
|
+
return (event.type === "stateChanged" && !event.snapshot.isNavigating)
|
|
20
|
+
|| event.type === "resumed";
|
|
21
|
+
case "onNext":
|
|
22
|
+
return event.type === "stateChanged"
|
|
23
|
+
&& event.cause === "next"
|
|
24
|
+
&& !event.snapshot.isNavigating;
|
|
25
|
+
case "onSubPathComplete":
|
|
26
|
+
return event.type === "resumed";
|
|
27
|
+
case "onComplete":
|
|
28
|
+
return event.type === "completed";
|
|
29
|
+
case "manual":
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
1
33
|
export class PathEngine {
|
|
2
34
|
activePath = null;
|
|
3
35
|
pathStack = [];
|
|
4
36
|
listeners = new Set();
|
|
5
37
|
_isNavigating = false;
|
|
38
|
+
/** True after the user has called next() on the current step at least once. Resets on step entry. */
|
|
39
|
+
_hasAttemptedNext = false;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
if (options?.observers) {
|
|
42
|
+
for (const observer of options.observers) {
|
|
43
|
+
// Wrap so observer receives the engine instance as the second argument
|
|
44
|
+
this.listeners.add((event) => observer(event, this));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
6
48
|
/**
|
|
7
49
|
* Restores a PathEngine from previously exported state.
|
|
8
50
|
*
|
|
@@ -17,11 +59,11 @@ export class PathEngine {
|
|
|
17
59
|
* @throws If `state` references a path ID not present in `pathDefinitions`,
|
|
18
60
|
* or if the state format is invalid.
|
|
19
61
|
*/
|
|
20
|
-
static fromState(state, pathDefinitions) {
|
|
62
|
+
static fromState(state, pathDefinitions, options) {
|
|
21
63
|
if (state.version !== 1) {
|
|
22
64
|
throw new Error(`Unsupported SerializedPathState version: ${state.version}`);
|
|
23
65
|
}
|
|
24
|
-
const engine = new PathEngine();
|
|
66
|
+
const engine = new PathEngine(options);
|
|
25
67
|
// Restore the path stack (sub-paths)
|
|
26
68
|
for (const stackItem of state.pathStack) {
|
|
27
69
|
const definition = pathDefinitions[stackItem.pathId];
|
|
@@ -130,7 +172,7 @@ export class PathEngine {
|
|
|
130
172
|
setData(key, value) {
|
|
131
173
|
const active = this.requireActivePath();
|
|
132
174
|
active.data[key] = value;
|
|
133
|
-
this.emitStateChanged();
|
|
175
|
+
this.emitStateChanged("setData");
|
|
134
176
|
return Promise.resolve();
|
|
135
177
|
}
|
|
136
178
|
/** Jumps directly to the step with the given ID. Does not check guards or shouldSkip. */
|
|
@@ -191,9 +233,10 @@ export class PathEngine {
|
|
|
191
233
|
this.pathStack.length === 0,
|
|
192
234
|
nestingLevel: this.pathStack.length,
|
|
193
235
|
isNavigating: this._isNavigating,
|
|
194
|
-
|
|
236
|
+
hasAttemptedNext: this._hasAttemptedNext,
|
|
237
|
+
canMoveNext: this.evaluateCanMoveNextSync(step, active),
|
|
195
238
|
canMovePrevious: this.evaluateGuardSync(step.canMovePrevious, active),
|
|
196
|
-
|
|
239
|
+
fieldMessages: this.evaluateFieldMessagesSync(step.fieldMessages, active),
|
|
197
240
|
data: { ...active.data }
|
|
198
241
|
};
|
|
199
242
|
}
|
|
@@ -257,23 +300,26 @@ export class PathEngine {
|
|
|
257
300
|
await this.finishActivePath();
|
|
258
301
|
return;
|
|
259
302
|
}
|
|
260
|
-
this.emitStateChanged();
|
|
303
|
+
this.emitStateChanged("start");
|
|
261
304
|
try {
|
|
262
305
|
this.applyPatch(await this.enterCurrentStep());
|
|
263
306
|
this._isNavigating = false;
|
|
264
|
-
this.emitStateChanged();
|
|
307
|
+
this.emitStateChanged("start");
|
|
265
308
|
}
|
|
266
309
|
catch (err) {
|
|
267
310
|
this._isNavigating = false;
|
|
268
|
-
this.emitStateChanged();
|
|
311
|
+
this.emitStateChanged("start");
|
|
269
312
|
throw err;
|
|
270
313
|
}
|
|
271
314
|
}
|
|
272
315
|
async _nextAsync(active) {
|
|
273
316
|
if (this._isNavigating)
|
|
274
317
|
return;
|
|
318
|
+
// Record that the user has attempted to advance — used by shells and step
|
|
319
|
+
// templates to gate error display ("punish late, reward early").
|
|
320
|
+
this._hasAttemptedNext = true;
|
|
275
321
|
this._isNavigating = true;
|
|
276
|
-
this.emitStateChanged();
|
|
322
|
+
this.emitStateChanged("next");
|
|
277
323
|
try {
|
|
278
324
|
const step = this.getCurrentStep(active);
|
|
279
325
|
if (await this.canMoveNext(active, step)) {
|
|
@@ -288,11 +334,11 @@ export class PathEngine {
|
|
|
288
334
|
this.applyPatch(await this.enterCurrentStep());
|
|
289
335
|
}
|
|
290
336
|
this._isNavigating = false;
|
|
291
|
-
this.emitStateChanged();
|
|
337
|
+
this.emitStateChanged("next");
|
|
292
338
|
}
|
|
293
339
|
catch (err) {
|
|
294
340
|
this._isNavigating = false;
|
|
295
|
-
this.emitStateChanged();
|
|
341
|
+
this.emitStateChanged("next");
|
|
296
342
|
throw err;
|
|
297
343
|
}
|
|
298
344
|
}
|
|
@@ -305,7 +351,7 @@ export class PathEngine {
|
|
|
305
351
|
if (active.currentStepIndex === 0 && this.pathStack.length === 0)
|
|
306
352
|
return;
|
|
307
353
|
this._isNavigating = true;
|
|
308
|
-
this.emitStateChanged();
|
|
354
|
+
this.emitStateChanged("previous");
|
|
309
355
|
try {
|
|
310
356
|
const step = this.getCurrentStep(active);
|
|
311
357
|
if (await this.canMovePrevious(active, step)) {
|
|
@@ -320,11 +366,11 @@ export class PathEngine {
|
|
|
320
366
|
this.applyPatch(await this.enterCurrentStep());
|
|
321
367
|
}
|
|
322
368
|
this._isNavigating = false;
|
|
323
|
-
this.emitStateChanged();
|
|
369
|
+
this.emitStateChanged("previous");
|
|
324
370
|
}
|
|
325
371
|
catch (err) {
|
|
326
372
|
this._isNavigating = false;
|
|
327
|
-
this.emitStateChanged();
|
|
373
|
+
this.emitStateChanged("previous");
|
|
328
374
|
throw err;
|
|
329
375
|
}
|
|
330
376
|
}
|
|
@@ -332,18 +378,18 @@ export class PathEngine {
|
|
|
332
378
|
if (this._isNavigating)
|
|
333
379
|
return;
|
|
334
380
|
this._isNavigating = true;
|
|
335
|
-
this.emitStateChanged();
|
|
381
|
+
this.emitStateChanged("goToStep");
|
|
336
382
|
try {
|
|
337
383
|
const currentStep = this.getCurrentStep(active);
|
|
338
384
|
this.applyPatch(await this.leaveCurrentStep(active, currentStep));
|
|
339
385
|
active.currentStepIndex = targetIndex;
|
|
340
386
|
this.applyPatch(await this.enterCurrentStep());
|
|
341
387
|
this._isNavigating = false;
|
|
342
|
-
this.emitStateChanged();
|
|
388
|
+
this.emitStateChanged("goToStep");
|
|
343
389
|
}
|
|
344
390
|
catch (err) {
|
|
345
391
|
this._isNavigating = false;
|
|
346
|
-
this.emitStateChanged();
|
|
392
|
+
this.emitStateChanged("goToStep");
|
|
347
393
|
throw err;
|
|
348
394
|
}
|
|
349
395
|
}
|
|
@@ -351,7 +397,7 @@ export class PathEngine {
|
|
|
351
397
|
if (this._isNavigating)
|
|
352
398
|
return;
|
|
353
399
|
this._isNavigating = true;
|
|
354
|
-
this.emitStateChanged();
|
|
400
|
+
this.emitStateChanged("goToStepChecked");
|
|
355
401
|
try {
|
|
356
402
|
const currentStep = this.getCurrentStep(active);
|
|
357
403
|
const goingForward = targetIndex > active.currentStepIndex;
|
|
@@ -364,11 +410,11 @@ export class PathEngine {
|
|
|
364
410
|
this.applyPatch(await this.enterCurrentStep());
|
|
365
411
|
}
|
|
366
412
|
this._isNavigating = false;
|
|
367
|
-
this.emitStateChanged();
|
|
413
|
+
this.emitStateChanged("goToStepChecked");
|
|
368
414
|
}
|
|
369
415
|
catch (err) {
|
|
370
416
|
this._isNavigating = false;
|
|
371
|
-
this.emitStateChanged();
|
|
417
|
+
this.emitStateChanged("goToStepChecked");
|
|
372
418
|
throw err;
|
|
373
419
|
}
|
|
374
420
|
}
|
|
@@ -378,7 +424,7 @@ export class PathEngine {
|
|
|
378
424
|
// sub-path (which may have currentStepIndex = -1).
|
|
379
425
|
this.activePath = this.pathStack.pop() ?? null;
|
|
380
426
|
this._isNavigating = true;
|
|
381
|
-
this.emitStateChanged();
|
|
427
|
+
this.emitStateChanged("cancel");
|
|
382
428
|
try {
|
|
383
429
|
const parent = this.activePath;
|
|
384
430
|
if (parent) {
|
|
@@ -394,11 +440,11 @@ export class PathEngine {
|
|
|
394
440
|
}
|
|
395
441
|
}
|
|
396
442
|
this._isNavigating = false;
|
|
397
|
-
this.emitStateChanged();
|
|
443
|
+
this.emitStateChanged("cancel");
|
|
398
444
|
}
|
|
399
445
|
catch (err) {
|
|
400
446
|
this._isNavigating = false;
|
|
401
|
-
this.emitStateChanged();
|
|
447
|
+
this.emitStateChanged("cancel");
|
|
402
448
|
throw err;
|
|
403
449
|
}
|
|
404
450
|
}
|
|
@@ -452,8 +498,8 @@ export class PathEngine {
|
|
|
452
498
|
listener(event);
|
|
453
499
|
}
|
|
454
500
|
}
|
|
455
|
-
emitStateChanged() {
|
|
456
|
-
this.emit({ type: "stateChanged", snapshot: this.snapshot() });
|
|
501
|
+
emitStateChanged(cause) {
|
|
502
|
+
this.emit({ type: "stateChanged", cause, snapshot: this.snapshot() });
|
|
457
503
|
}
|
|
458
504
|
getCurrentStep(active) {
|
|
459
505
|
return active.definition.steps[active.currentStepIndex];
|
|
@@ -488,6 +534,8 @@ export class PathEngine {
|
|
|
488
534
|
}
|
|
489
535
|
}
|
|
490
536
|
async enterCurrentStep() {
|
|
537
|
+
// Each step starts fresh — errors are not shown until the user attempts to proceed.
|
|
538
|
+
this._hasAttemptedNext = false;
|
|
491
539
|
const active = this.activePath;
|
|
492
540
|
if (!active)
|
|
493
541
|
return;
|
|
@@ -518,15 +566,19 @@ export class PathEngine {
|
|
|
518
566
|
return step.onLeave(ctx);
|
|
519
567
|
}
|
|
520
568
|
async canMoveNext(active, step) {
|
|
521
|
-
if (
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
569
|
+
if (step.canMoveNext) {
|
|
570
|
+
const ctx = {
|
|
571
|
+
pathId: active.definition.id,
|
|
572
|
+
stepId: step.id,
|
|
573
|
+
data: { ...active.data },
|
|
574
|
+
isFirstEntry: !active.visitedStepIds.has(step.id)
|
|
575
|
+
};
|
|
576
|
+
return step.canMoveNext(ctx);
|
|
577
|
+
}
|
|
578
|
+
if (step.fieldMessages) {
|
|
579
|
+
return Object.keys(this.evaluateFieldMessagesSync(step.fieldMessages, active)).length === 0;
|
|
580
|
+
}
|
|
581
|
+
return true;
|
|
530
582
|
}
|
|
531
583
|
async canMovePrevious(active, step) {
|
|
532
584
|
if (!step.canMovePrevious)
|
|
@@ -585,19 +637,31 @@ export class PathEngine {
|
|
|
585
637
|
}
|
|
586
638
|
}
|
|
587
639
|
/**
|
|
588
|
-
* Evaluates
|
|
589
|
-
*
|
|
590
|
-
*
|
|
640
|
+
* Evaluates `canMoveNext` synchronously for inclusion in the snapshot.
|
|
641
|
+
* When `canMoveNext` is defined, delegates to `evaluateGuardSync`.
|
|
642
|
+
* When absent but `fieldMessages` is defined, auto-derives: `true` iff no messages.
|
|
643
|
+
* When neither is defined, returns `true`.
|
|
644
|
+
*/
|
|
645
|
+
evaluateCanMoveNextSync(step, active) {
|
|
646
|
+
if (step.canMoveNext)
|
|
647
|
+
return this.evaluateGuardSync(step.canMoveNext, active);
|
|
648
|
+
if (step.fieldMessages) {
|
|
649
|
+
return Object.keys(this.evaluateFieldMessagesSync(step.fieldMessages, active)).length === 0;
|
|
650
|
+
}
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Evaluates a fieldMessages function synchronously for inclusion in the snapshot.
|
|
655
|
+
* If the hook is absent, returns `{}`.
|
|
656
|
+
* If the hook returns a `Promise`, returns `{}` (async hooks are not supported in snapshots).
|
|
657
|
+
* `undefined` values are stripped from the result — only fields with a defined message are included.
|
|
591
658
|
*
|
|
592
|
-
* **Note:** Like guards, `
|
|
659
|
+
* **Note:** Like guards, `fieldMessages` is evaluated before `onEnter` runs on first
|
|
593
660
|
* entry. Write it defensively so it does not throw when fields are absent.
|
|
594
|
-
*
|
|
595
|
-
* If the function throws, the error is caught, a `console.warn` is emitted, and `[]`
|
|
596
|
-
* is returned so validation messages do not block the UI unexpectedly.
|
|
597
661
|
*/
|
|
598
|
-
|
|
662
|
+
evaluateFieldMessagesSync(fn, active) {
|
|
599
663
|
if (!fn)
|
|
600
|
-
return
|
|
664
|
+
return {};
|
|
601
665
|
const step = this.getCurrentStep(active);
|
|
602
666
|
const ctx = {
|
|
603
667
|
pathId: active.definition.id,
|
|
@@ -607,23 +671,28 @@ export class PathEngine {
|
|
|
607
671
|
};
|
|
608
672
|
try {
|
|
609
673
|
const result = fn(ctx);
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
|
|
674
|
+
if (result && typeof result === "object" && typeof result.then !== "function") {
|
|
675
|
+
const filtered = {};
|
|
676
|
+
for (const [key, val] of Object.entries(result)) {
|
|
677
|
+
if (val !== undefined && val !== null && val !== "") {
|
|
678
|
+
filtered[key] = val;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return filtered;
|
|
682
|
+
}
|
|
613
683
|
if (result && typeof result.then === "function") {
|
|
614
|
-
console.warn(`[pathwrite] Async
|
|
615
|
-
`
|
|
616
|
-
`Returning [] as default. ` +
|
|
684
|
+
console.warn(`[pathwrite] Async fieldMessages detected on step "${step.id}". ` +
|
|
685
|
+
`fieldMessages must be synchronous. Returning {} as default. ` +
|
|
617
686
|
`Use synchronous validation or move async checks to canMoveNext.`);
|
|
618
687
|
}
|
|
619
|
-
return
|
|
688
|
+
return {};
|
|
620
689
|
}
|
|
621
690
|
catch (err) {
|
|
622
|
-
console.warn(`[pathwrite]
|
|
623
|
-
`Returning
|
|
624
|
-
`Note:
|
|
691
|
+
console.warn(`[pathwrite] fieldMessages on step "${step.id}" threw an error during snapshot evaluation. ` +
|
|
692
|
+
`Returning {} as a safe default. ` +
|
|
693
|
+
`Note: fieldMessages is evaluated before onEnter runs on first entry — ` +
|
|
625
694
|
`ensure it handles missing/undefined data gracefully.`, err);
|
|
626
|
-
return
|
|
695
|
+
return {};
|
|
627
696
|
}
|
|
628
697
|
}
|
|
629
698
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export type PathData = Record<string, unknown>;
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The return type of a `fieldMessages` hook. Each key is a field ID; the value
|
|
5
|
+
* is an error string, or `undefined` / omitted to indicate no error for that field.
|
|
6
|
+
*
|
|
7
|
+
* Use `"_"` as a key for form-level errors that don't belong to a specific field:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* { _: "You must accept the terms and conditions." }
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export type FieldErrors = Record<string, string | undefined>;
|
|
13
|
+
|
|
3
14
|
export interface SerializedPathState {
|
|
4
15
|
version: 1;
|
|
5
16
|
pathId: string;
|
|
@@ -17,6 +28,20 @@ export interface SerializedPathState {
|
|
|
17
28
|
_isNavigating: boolean;
|
|
18
29
|
}
|
|
19
30
|
|
|
31
|
+
/**
|
|
32
|
+
* The interface every path state store must implement.
|
|
33
|
+
*
|
|
34
|
+
* `HttpStore` from `@daltonr/pathwrite-store-http` is the reference
|
|
35
|
+
* implementation. Any backend — MongoDB, Redis, localStorage, etc. —
|
|
36
|
+
* implements this interface and works with `httpPersistence` and
|
|
37
|
+
* `restoreOrStart` without any other changes.
|
|
38
|
+
*/
|
|
39
|
+
export interface PathStore {
|
|
40
|
+
save(key: string, state: SerializedPathState): Promise<void>;
|
|
41
|
+
load(key: string): Promise<SerializedPathState | null>;
|
|
42
|
+
delete(key: string): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
|
|
20
45
|
export interface PathStepContext<TData extends PathData = PathData> {
|
|
21
46
|
readonly pathId: string;
|
|
22
47
|
readonly stepId: string;
|
|
@@ -39,12 +64,26 @@ export interface PathStep<TData extends PathData = PathData> {
|
|
|
39
64
|
canMoveNext?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
40
65
|
canMovePrevious?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
41
66
|
/**
|
|
42
|
-
* Returns a
|
|
43
|
-
* yet valid. The shell displays these messages below the step content
|
|
44
|
-
* consumers do not need to duplicate
|
|
45
|
-
*
|
|
67
|
+
* Returns a map of field ID → error message explaining why the step is not
|
|
68
|
+
* yet valid. The shell displays these messages below the step content (labeled
|
|
69
|
+
* by field name) so consumers do not need to duplicate validation logic in
|
|
70
|
+
* the template. Return `undefined` for a field to indicate no error.
|
|
71
|
+
*
|
|
72
|
+
* When `fieldMessages` is provided and `canMoveNext` is **not**, the engine
|
|
73
|
+
* automatically derives `canMoveNext` as `true` when all values are `undefined`
|
|
74
|
+
* (i.e. no messages), eliminating the need to express the same logic twice.
|
|
75
|
+
*
|
|
76
|
+
* Evaluated synchronously on every snapshot; async functions default to `{}`.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* fieldMessages: ({ data }) => ({
|
|
81
|
+
* name: !data.name?.trim() ? "Required." : undefined,
|
|
82
|
+
* email: !isValidEmail(data.email) ? "Invalid email address." : undefined,
|
|
83
|
+
* })
|
|
84
|
+
* ```
|
|
46
85
|
*/
|
|
47
|
-
|
|
86
|
+
fieldMessages?: (ctx: PathStepContext<TData>) => FieldErrors;
|
|
48
87
|
onEnter?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
49
88
|
onLeave?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
50
89
|
/**
|
|
@@ -104,17 +143,53 @@ export interface PathSnapshot<TData extends PathData = PathData> {
|
|
|
104
143
|
nestingLevel: number;
|
|
105
144
|
/** True while an async guard or hook is executing. Use to disable navigation controls. */
|
|
106
145
|
isNavigating: boolean;
|
|
107
|
-
/** Whether the current step's `canMoveNext` guard allows advancing. Async guards default to `true`. */
|
|
146
|
+
/** Whether the current step's `canMoveNext` guard allows advancing. Async guards default to `true`. Auto-derived as `true` when `fieldMessages` is defined and returns no messages, and `canMoveNext` is not explicitly defined. */
|
|
108
147
|
canMoveNext: boolean;
|
|
109
148
|
/** Whether the current step's `canMovePrevious` guard allows going back. Async guards default to `true`. */
|
|
110
149
|
canMovePrevious: boolean;
|
|
111
|
-
/**
|
|
112
|
-
|
|
150
|
+
/**
|
|
151
|
+
* True after the user has clicked Next / Submit on this step at least once,
|
|
152
|
+
* regardless of whether navigation succeeded. Resets to `false` when entering
|
|
153
|
+
* a new step.
|
|
154
|
+
*
|
|
155
|
+
* Use this to gate inline field-error display so errors are hidden on first
|
|
156
|
+
* render and only appear after the user has attempted to proceed:
|
|
157
|
+
*
|
|
158
|
+
* ```svelte
|
|
159
|
+
* {#if snapshot.hasAttemptedNext && snapshot.fieldMessages.email}
|
|
160
|
+
* <span class="error">{snapshot.fieldMessages.email}</span>
|
|
161
|
+
* {/if}
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* The shell itself uses this flag to gate its own automatic `fieldMessages`
|
|
165
|
+
* summary rendering — errors are never shown before the first Next attempt.
|
|
166
|
+
*/
|
|
167
|
+
hasAttemptedNext: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Field-keyed validation messages for the current step. Empty object when there are none.
|
|
170
|
+
* Use in step templates to render inline per-field errors: `snapshot.fieldMessages['email']`.
|
|
171
|
+
* The shell also renders these automatically in a labeled summary box.
|
|
172
|
+
* Use `"_"` as a key for form-level (non-field-specific) errors.
|
|
173
|
+
*/
|
|
174
|
+
fieldMessages: Record<string, string>;
|
|
113
175
|
data: TData;
|
|
114
176
|
}
|
|
115
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Identifies the public method that triggered a `stateChanged` event.
|
|
180
|
+
*/
|
|
181
|
+
export type StateChangeCause =
|
|
182
|
+
| "start"
|
|
183
|
+
| "next"
|
|
184
|
+
| "previous"
|
|
185
|
+
| "goToStep"
|
|
186
|
+
| "goToStepChecked"
|
|
187
|
+
| "setData"
|
|
188
|
+
| "cancel"
|
|
189
|
+
| "restart";
|
|
190
|
+
|
|
116
191
|
export type PathEvent =
|
|
117
|
-
| { type: "stateChanged"; snapshot: PathSnapshot }
|
|
192
|
+
| { type: "stateChanged"; cause: StateChangeCause; snapshot: PathSnapshot }
|
|
118
193
|
| { type: "completed"; pathId: string; data: PathData }
|
|
119
194
|
| { type: "cancelled"; pathId: string; data: PathData }
|
|
120
195
|
| {
|
|
@@ -124,6 +199,84 @@ export type PathEvent =
|
|
|
124
199
|
snapshot: PathSnapshot;
|
|
125
200
|
};
|
|
126
201
|
|
|
202
|
+
/**
|
|
203
|
+
* A function called on every engine event. Observers are registered at
|
|
204
|
+
* construction time and receive every event for the lifetime of the engine.
|
|
205
|
+
*
|
|
206
|
+
* The second argument is the engine itself — useful when the observer needs to
|
|
207
|
+
* read current state (e.g. calling `engine.exportState()` for persistence).
|
|
208
|
+
*
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const logger: PathObserver = (event) => console.log(event.type);
|
|
211
|
+
* const persist: PathObserver = (event, engine) => { ... };
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export type PathObserver = (event: PathEvent, engine: PathEngine) => void;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Determines which engine events an observer should react to.
|
|
218
|
+
*
|
|
219
|
+
* | Strategy | Triggers when |
|
|
220
|
+
* |---------------------|------------------------------------------------------------|
|
|
221
|
+
* | `"onEveryChange"` | Any settled `stateChanged` or `resumed` |
|
|
222
|
+
* | `"onNext"` | `next()` completes navigation *(default)* |
|
|
223
|
+
* | `"onSubPathComplete"` | Sub-path finishes and the parent resumes |
|
|
224
|
+
* | `"onComplete"` | The entire path completes |
|
|
225
|
+
* | `"manual"` | Never — caller decides when to act |
|
|
226
|
+
*/
|
|
227
|
+
export type ObserverStrategy =
|
|
228
|
+
| "onEveryChange"
|
|
229
|
+
| "onNext"
|
|
230
|
+
| "onSubPathComplete"
|
|
231
|
+
| "onComplete"
|
|
232
|
+
| "manual";
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Returns `true` when `event` matches the trigger condition for `strategy`.
|
|
236
|
+
*
|
|
237
|
+
* Use this in any `PathObserver` factory to centralise the
|
|
238
|
+
* "which events should I react to?" decision so every observer
|
|
239
|
+
* (HTTP, MongoDB, logger, analytics…) shares the same semantics.
|
|
240
|
+
*
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const observer: PathObserver = (event, engine) => {
|
|
243
|
+
* if (matchesStrategy(strategy, event)) doWork(engine);
|
|
244
|
+
* };
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export function matchesStrategy(strategy: ObserverStrategy, event: PathEvent): boolean {
|
|
248
|
+
switch (strategy) {
|
|
249
|
+
case "onEveryChange":
|
|
250
|
+
// Only react once navigation has settled — stateChanged fires twice per
|
|
251
|
+
// navigation (isNavigating:true then false).
|
|
252
|
+
return (event.type === "stateChanged" && !event.snapshot.isNavigating)
|
|
253
|
+
|| event.type === "resumed";
|
|
254
|
+
case "onNext":
|
|
255
|
+
return event.type === "stateChanged"
|
|
256
|
+
&& event.cause === "next"
|
|
257
|
+
&& !event.snapshot.isNavigating;
|
|
258
|
+
case "onSubPathComplete":
|
|
259
|
+
return event.type === "resumed";
|
|
260
|
+
case "onComplete":
|
|
261
|
+
return event.type === "completed";
|
|
262
|
+
case "manual":
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Options accepted by the `PathEngine` constructor and `PathEngine.fromState()`.
|
|
269
|
+
*/
|
|
270
|
+
export interface PathEngineOptions {
|
|
271
|
+
/**
|
|
272
|
+
* Zero or more observers to register before the first event fires.
|
|
273
|
+
* Each observer is called synchronously on every engine event for the
|
|
274
|
+
* lifetime of the engine. Observers cannot be removed; for removable
|
|
275
|
+
* listeners use `engine.subscribe()`.
|
|
276
|
+
*/
|
|
277
|
+
observers?: PathObserver[];
|
|
278
|
+
}
|
|
279
|
+
|
|
127
280
|
interface ActivePath {
|
|
128
281
|
definition: PathDefinition;
|
|
129
282
|
currentStepIndex: number;
|
|
@@ -137,6 +290,17 @@ export class PathEngine {
|
|
|
137
290
|
private readonly pathStack: ActivePath[] = [];
|
|
138
291
|
private readonly listeners = new Set<(event: PathEvent) => void>();
|
|
139
292
|
private _isNavigating = false;
|
|
293
|
+
/** True after the user has called next() on the current step at least once. Resets on step entry. */
|
|
294
|
+
private _hasAttemptedNext = false;
|
|
295
|
+
|
|
296
|
+
constructor(options?: PathEngineOptions) {
|
|
297
|
+
if (options?.observers) {
|
|
298
|
+
for (const observer of options.observers) {
|
|
299
|
+
// Wrap so observer receives the engine instance as the second argument
|
|
300
|
+
this.listeners.add((event) => observer(event, this));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
140
304
|
|
|
141
305
|
/**
|
|
142
306
|
* Restores a PathEngine from previously exported state.
|
|
@@ -154,13 +318,14 @@ export class PathEngine {
|
|
|
154
318
|
*/
|
|
155
319
|
public static fromState(
|
|
156
320
|
state: SerializedPathState,
|
|
157
|
-
pathDefinitions: Record<string, PathDefinition
|
|
321
|
+
pathDefinitions: Record<string, PathDefinition>,
|
|
322
|
+
options?: PathEngineOptions
|
|
158
323
|
): PathEngine {
|
|
159
324
|
if (state.version !== 1) {
|
|
160
325
|
throw new Error(`Unsupported SerializedPathState version: ${state.version}`);
|
|
161
326
|
}
|
|
162
327
|
|
|
163
|
-
const engine = new PathEngine();
|
|
328
|
+
const engine = new PathEngine(options);
|
|
164
329
|
|
|
165
330
|
// Restore the path stack (sub-paths)
|
|
166
331
|
for (const stackItem of state.pathStack) {
|
|
@@ -289,7 +454,7 @@ export class PathEngine {
|
|
|
289
454
|
public setData(key: string, value: unknown): Promise<void> {
|
|
290
455
|
const active = this.requireActivePath();
|
|
291
456
|
active.data[key] = value;
|
|
292
|
-
this.emitStateChanged();
|
|
457
|
+
this.emitStateChanged("setData");
|
|
293
458
|
return Promise.resolve();
|
|
294
459
|
}
|
|
295
460
|
|
|
@@ -355,9 +520,10 @@ export class PathEngine {
|
|
|
355
520
|
this.pathStack.length === 0,
|
|
356
521
|
nestingLevel: this.pathStack.length,
|
|
357
522
|
isNavigating: this._isNavigating,
|
|
358
|
-
|
|
523
|
+
hasAttemptedNext: this._hasAttemptedNext,
|
|
524
|
+
canMoveNext: this.evaluateCanMoveNextSync(step, active),
|
|
359
525
|
canMovePrevious: this.evaluateGuardSync(step.canMovePrevious, active),
|
|
360
|
-
|
|
526
|
+
fieldMessages: this.evaluateFieldMessagesSync(step.fieldMessages, active),
|
|
361
527
|
data: { ...active.data }
|
|
362
528
|
};
|
|
363
529
|
}
|
|
@@ -431,15 +597,15 @@ export class PathEngine {
|
|
|
431
597
|
return;
|
|
432
598
|
}
|
|
433
599
|
|
|
434
|
-
this.emitStateChanged();
|
|
600
|
+
this.emitStateChanged("start");
|
|
435
601
|
|
|
436
602
|
try {
|
|
437
603
|
this.applyPatch(await this.enterCurrentStep());
|
|
438
604
|
this._isNavigating = false;
|
|
439
|
-
this.emitStateChanged();
|
|
605
|
+
this.emitStateChanged("start");
|
|
440
606
|
} catch (err) {
|
|
441
607
|
this._isNavigating = false;
|
|
442
|
-
this.emitStateChanged();
|
|
608
|
+
this.emitStateChanged("start");
|
|
443
609
|
throw err;
|
|
444
610
|
}
|
|
445
611
|
}
|
|
@@ -447,8 +613,11 @@ export class PathEngine {
|
|
|
447
613
|
private async _nextAsync(active: ActivePath): Promise<void> {
|
|
448
614
|
if (this._isNavigating) return;
|
|
449
615
|
|
|
616
|
+
// Record that the user has attempted to advance — used by shells and step
|
|
617
|
+
// templates to gate error display ("punish late, reward early").
|
|
618
|
+
this._hasAttemptedNext = true;
|
|
450
619
|
this._isNavigating = true;
|
|
451
|
-
this.emitStateChanged();
|
|
620
|
+
this.emitStateChanged("next");
|
|
452
621
|
|
|
453
622
|
try {
|
|
454
623
|
const step = this.getCurrentStep(active);
|
|
@@ -468,10 +637,10 @@ export class PathEngine {
|
|
|
468
637
|
}
|
|
469
638
|
|
|
470
639
|
this._isNavigating = false;
|
|
471
|
-
this.emitStateChanged();
|
|
640
|
+
this.emitStateChanged("next");
|
|
472
641
|
} catch (err) {
|
|
473
642
|
this._isNavigating = false;
|
|
474
|
-
this.emitStateChanged();
|
|
643
|
+
this.emitStateChanged("next");
|
|
475
644
|
throw err;
|
|
476
645
|
}
|
|
477
646
|
}
|
|
@@ -485,7 +654,7 @@ export class PathEngine {
|
|
|
485
654
|
if (active.currentStepIndex === 0 && this.pathStack.length === 0) return;
|
|
486
655
|
|
|
487
656
|
this._isNavigating = true;
|
|
488
|
-
this.emitStateChanged();
|
|
657
|
+
this.emitStateChanged("previous");
|
|
489
658
|
|
|
490
659
|
try {
|
|
491
660
|
const step = this.getCurrentStep(active);
|
|
@@ -505,10 +674,10 @@ export class PathEngine {
|
|
|
505
674
|
}
|
|
506
675
|
|
|
507
676
|
this._isNavigating = false;
|
|
508
|
-
this.emitStateChanged();
|
|
677
|
+
this.emitStateChanged("previous");
|
|
509
678
|
} catch (err) {
|
|
510
679
|
this._isNavigating = false;
|
|
511
|
-
this.emitStateChanged();
|
|
680
|
+
this.emitStateChanged("previous");
|
|
512
681
|
throw err;
|
|
513
682
|
}
|
|
514
683
|
}
|
|
@@ -517,7 +686,7 @@ export class PathEngine {
|
|
|
517
686
|
if (this._isNavigating) return;
|
|
518
687
|
|
|
519
688
|
this._isNavigating = true;
|
|
520
|
-
this.emitStateChanged();
|
|
689
|
+
this.emitStateChanged("goToStep");
|
|
521
690
|
|
|
522
691
|
try {
|
|
523
692
|
const currentStep = this.getCurrentStep(active);
|
|
@@ -527,10 +696,10 @@ export class PathEngine {
|
|
|
527
696
|
|
|
528
697
|
this.applyPatch(await this.enterCurrentStep());
|
|
529
698
|
this._isNavigating = false;
|
|
530
|
-
this.emitStateChanged();
|
|
699
|
+
this.emitStateChanged("goToStep");
|
|
531
700
|
} catch (err) {
|
|
532
701
|
this._isNavigating = false;
|
|
533
|
-
this.emitStateChanged();
|
|
702
|
+
this.emitStateChanged("goToStep");
|
|
534
703
|
throw err;
|
|
535
704
|
}
|
|
536
705
|
}
|
|
@@ -539,7 +708,7 @@ export class PathEngine {
|
|
|
539
708
|
if (this._isNavigating) return;
|
|
540
709
|
|
|
541
710
|
this._isNavigating = true;
|
|
542
|
-
this.emitStateChanged();
|
|
711
|
+
this.emitStateChanged("goToStepChecked");
|
|
543
712
|
|
|
544
713
|
try {
|
|
545
714
|
const currentStep = this.getCurrentStep(active);
|
|
@@ -555,10 +724,10 @@ export class PathEngine {
|
|
|
555
724
|
}
|
|
556
725
|
|
|
557
726
|
this._isNavigating = false;
|
|
558
|
-
this.emitStateChanged();
|
|
727
|
+
this.emitStateChanged("goToStepChecked");
|
|
559
728
|
} catch (err) {
|
|
560
729
|
this._isNavigating = false;
|
|
561
|
-
this.emitStateChanged();
|
|
730
|
+
this.emitStateChanged("goToStepChecked");
|
|
562
731
|
throw err;
|
|
563
732
|
}
|
|
564
733
|
}
|
|
@@ -574,7 +743,7 @@ export class PathEngine {
|
|
|
574
743
|
this.activePath = this.pathStack.pop() ?? null;
|
|
575
744
|
|
|
576
745
|
this._isNavigating = true;
|
|
577
|
-
this.emitStateChanged();
|
|
746
|
+
this.emitStateChanged("cancel");
|
|
578
747
|
|
|
579
748
|
try {
|
|
580
749
|
const parent = this.activePath;
|
|
@@ -595,10 +764,10 @@ export class PathEngine {
|
|
|
595
764
|
}
|
|
596
765
|
|
|
597
766
|
this._isNavigating = false;
|
|
598
|
-
this.emitStateChanged();
|
|
767
|
+
this.emitStateChanged("cancel");
|
|
599
768
|
} catch (err) {
|
|
600
769
|
this._isNavigating = false;
|
|
601
|
-
this.emitStateChanged();
|
|
770
|
+
this.emitStateChanged("cancel");
|
|
602
771
|
throw err;
|
|
603
772
|
}
|
|
604
773
|
}
|
|
@@ -662,8 +831,8 @@ export class PathEngine {
|
|
|
662
831
|
}
|
|
663
832
|
}
|
|
664
833
|
|
|
665
|
-
private emitStateChanged(): void {
|
|
666
|
-
this.emit({ type: "stateChanged", snapshot: this.snapshot()! });
|
|
834
|
+
private emitStateChanged(cause: StateChangeCause): void {
|
|
835
|
+
this.emit({ type: "stateChanged", cause, snapshot: this.snapshot()! });
|
|
667
836
|
}
|
|
668
837
|
|
|
669
838
|
private getCurrentStep(active: ActivePath): PathStep {
|
|
@@ -702,6 +871,8 @@ export class PathEngine {
|
|
|
702
871
|
}
|
|
703
872
|
|
|
704
873
|
private async enterCurrentStep(): Promise<Partial<PathData> | void> {
|
|
874
|
+
// Each step starts fresh — errors are not shown until the user attempts to proceed.
|
|
875
|
+
this._hasAttemptedNext = false;
|
|
705
876
|
const active = this.activePath;
|
|
706
877
|
if (!active) return;
|
|
707
878
|
const step = this.getCurrentStep(active);
|
|
@@ -737,14 +908,19 @@ export class PathEngine {
|
|
|
737
908
|
active: ActivePath,
|
|
738
909
|
step: PathStep
|
|
739
910
|
): Promise<boolean> {
|
|
740
|
-
if (
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
911
|
+
if (step.canMoveNext) {
|
|
912
|
+
const ctx: PathStepContext = {
|
|
913
|
+
pathId: active.definition.id,
|
|
914
|
+
stepId: step.id,
|
|
915
|
+
data: { ...active.data },
|
|
916
|
+
isFirstEntry: !active.visitedStepIds.has(step.id)
|
|
917
|
+
};
|
|
918
|
+
return step.canMoveNext(ctx);
|
|
919
|
+
}
|
|
920
|
+
if (step.fieldMessages) {
|
|
921
|
+
return Object.keys(this.evaluateFieldMessagesSync(step.fieldMessages, active)).length === 0;
|
|
922
|
+
}
|
|
923
|
+
return true;
|
|
748
924
|
}
|
|
749
925
|
|
|
750
926
|
private async canMovePrevious(
|
|
@@ -813,21 +989,33 @@ export class PathEngine {
|
|
|
813
989
|
}
|
|
814
990
|
|
|
815
991
|
/**
|
|
816
|
-
* Evaluates
|
|
817
|
-
*
|
|
818
|
-
*
|
|
992
|
+
* Evaluates `canMoveNext` synchronously for inclusion in the snapshot.
|
|
993
|
+
* When `canMoveNext` is defined, delegates to `evaluateGuardSync`.
|
|
994
|
+
* When absent but `fieldMessages` is defined, auto-derives: `true` iff no messages.
|
|
995
|
+
* When neither is defined, returns `true`.
|
|
996
|
+
*/
|
|
997
|
+
private evaluateCanMoveNextSync(step: PathStep, active: ActivePath): boolean {
|
|
998
|
+
if (step.canMoveNext) return this.evaluateGuardSync(step.canMoveNext, active);
|
|
999
|
+
if (step.fieldMessages) {
|
|
1000
|
+
return Object.keys(this.evaluateFieldMessagesSync(step.fieldMessages, active)).length === 0;
|
|
1001
|
+
}
|
|
1002
|
+
return true;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Evaluates a fieldMessages function synchronously for inclusion in the snapshot.
|
|
1007
|
+
* If the hook is absent, returns `{}`.
|
|
1008
|
+
* If the hook returns a `Promise`, returns `{}` (async hooks are not supported in snapshots).
|
|
1009
|
+
* `undefined` values are stripped from the result — only fields with a defined message are included.
|
|
819
1010
|
*
|
|
820
|
-
* **Note:** Like guards, `
|
|
1011
|
+
* **Note:** Like guards, `fieldMessages` is evaluated before `onEnter` runs on first
|
|
821
1012
|
* entry. Write it defensively so it does not throw when fields are absent.
|
|
822
|
-
*
|
|
823
|
-
* If the function throws, the error is caught, a `console.warn` is emitted, and `[]`
|
|
824
|
-
* is returned so validation messages do not block the UI unexpectedly.
|
|
825
1013
|
*/
|
|
826
|
-
private
|
|
827
|
-
fn: ((ctx: PathStepContext) =>
|
|
1014
|
+
private evaluateFieldMessagesSync(
|
|
1015
|
+
fn: ((ctx: PathStepContext) => FieldErrors) | undefined,
|
|
828
1016
|
active: ActivePath
|
|
829
|
-
): string
|
|
830
|
-
if (!fn) return
|
|
1017
|
+
): Record<string, string> {
|
|
1018
|
+
if (!fn) return {};
|
|
831
1019
|
const step = this.getCurrentStep(active);
|
|
832
1020
|
const ctx: PathStepContext = {
|
|
833
1021
|
pathId: active.definition.id,
|
|
@@ -837,26 +1025,32 @@ export class PathEngine {
|
|
|
837
1025
|
};
|
|
838
1026
|
try {
|
|
839
1027
|
const result = fn(ctx);
|
|
840
|
-
if (
|
|
841
|
-
|
|
842
|
-
|
|
1028
|
+
if (result && typeof result === "object" && typeof (result as unknown as { then?: unknown }).then !== "function") {
|
|
1029
|
+
const filtered: Record<string, string> = {};
|
|
1030
|
+
for (const [key, val] of Object.entries(result)) {
|
|
1031
|
+
if (val !== undefined && val !== null && val !== "") {
|
|
1032
|
+
filtered[key] = val;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return filtered;
|
|
1036
|
+
}
|
|
1037
|
+
if (result && typeof (result as unknown as { then?: unknown }).then === "function") {
|
|
843
1038
|
console.warn(
|
|
844
|
-
`[pathwrite] Async
|
|
845
|
-
`
|
|
846
|
-
`Returning [] as default. ` +
|
|
1039
|
+
`[pathwrite] Async fieldMessages detected on step "${step.id}". ` +
|
|
1040
|
+
`fieldMessages must be synchronous. Returning {} as default. ` +
|
|
847
1041
|
`Use synchronous validation or move async checks to canMoveNext.`
|
|
848
1042
|
);
|
|
849
1043
|
}
|
|
850
|
-
return
|
|
1044
|
+
return {};
|
|
851
1045
|
} catch (err) {
|
|
852
1046
|
console.warn(
|
|
853
|
-
`[pathwrite]
|
|
854
|
-
`Returning
|
|
855
|
-
`Note:
|
|
1047
|
+
`[pathwrite] fieldMessages on step "${step.id}" threw an error during snapshot evaluation. ` +
|
|
1048
|
+
`Returning {} as a safe default. ` +
|
|
1049
|
+
`Note: fieldMessages is evaluated before onEnter runs on first entry — ` +
|
|
856
1050
|
`ensure it handles missing/undefined data gracefully.`,
|
|
857
1051
|
err
|
|
858
1052
|
);
|
|
859
|
-
return
|
|
1053
|
+
return {};
|
|
860
1054
|
}
|
|
861
1055
|
}
|
|
862
1056
|
}
|