@daltonr/pathwrite-core 0.1.4 → 0.2.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 +3 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +565 -0
package/README.md
CHANGED
|
@@ -43,6 +43,8 @@ engine.next();
|
|
|
43
43
|
engine.previous();
|
|
44
44
|
engine.cancel();
|
|
45
45
|
engine.setData(key, value); // update a single data value; emits stateChanged
|
|
46
|
+
engine.goToStep(stepId); // jump to step by ID; bypasses guards and shouldSkip
|
|
47
|
+
engine.goToStepChecked(stepId); // jump to step by ID; checks canMoveNext / canMovePrevious first
|
|
46
48
|
engine.snapshot(); // returns PathSnapshot | null
|
|
47
49
|
|
|
48
50
|
const unsubscribe = engine.subscribe((event) => { ... });
|
|
@@ -60,6 +62,7 @@ All hooks are optional. Hooks that want to update data **return a partial patch*
|
|
|
60
62
|
| `onSubPathComplete` | On the parent step when a sub-path finishes | ✅ |
|
|
61
63
|
| `canMoveNext` | Before advancing — return `false` to block | — |
|
|
62
64
|
| `canMovePrevious` | Before going back — return `false` to block | — |
|
|
65
|
+
| `validationMessages` | On every snapshot — return `string[]` explaining why the step is not yet valid | — |
|
|
63
66
|
|
|
64
67
|
### Snapshot guard booleans
|
|
65
68
|
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export interface PathStep<TData extends PathData = PathData> {
|
|
|
11
11
|
shouldSkip?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
12
12
|
canMoveNext?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
13
13
|
canMovePrevious?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Returns a list of human-readable messages explaining why the step is not
|
|
16
|
+
* yet valid. The shell displays these messages below the step content so
|
|
17
|
+
* consumers do not need to duplicate guard logic in the template.
|
|
18
|
+
* Evaluated synchronously on every snapshot; async functions default to `[]`.
|
|
19
|
+
*/
|
|
20
|
+
validationMessages?: (ctx: PathStepContext<TData>) => string[] | Promise<string[]>;
|
|
14
21
|
onEnter?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
15
22
|
onLeave?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
16
23
|
onSubPathComplete?: (subPathId: string, subPathData: PathData, ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
@@ -45,6 +52,8 @@ export interface PathSnapshot<TData extends PathData = PathData> {
|
|
|
45
52
|
canMoveNext: boolean;
|
|
46
53
|
/** Whether the current step's `canMovePrevious` guard allows going back. Async guards default to `true`. */
|
|
47
54
|
canMovePrevious: boolean;
|
|
55
|
+
/** Messages from the current step's `validationMessages` hook. Empty array when there are none. */
|
|
56
|
+
validationMessages: string[];
|
|
48
57
|
data: TData;
|
|
49
58
|
}
|
|
50
59
|
export type PathEvent = {
|
|
@@ -80,11 +89,23 @@ export declare class PathEngine {
|
|
|
80
89
|
setData(key: string, value: unknown): Promise<void>;
|
|
81
90
|
/** Jumps directly to the step with the given ID. Does not check guards or shouldSkip. */
|
|
82
91
|
goToStep(stepId: string): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Jumps directly to the step with the given ID, but first checks the
|
|
94
|
+
* direction-appropriate guard on the current step:
|
|
95
|
+
* - Going forward → checks `canMoveNext`
|
|
96
|
+
* - Going backward → checks `canMovePrevious`
|
|
97
|
+
*
|
|
98
|
+
* If the guard blocks, navigation does not occur and `stateChanged` is still
|
|
99
|
+
* emitted (so the UI can react). `shouldSkip` is not evaluated.
|
|
100
|
+
* Throws if the target step ID does not exist.
|
|
101
|
+
*/
|
|
102
|
+
goToStepChecked(stepId: string): Promise<void>;
|
|
83
103
|
snapshot(): PathSnapshot | null;
|
|
84
104
|
private _startAsync;
|
|
85
105
|
private _nextAsync;
|
|
86
106
|
private _previousAsync;
|
|
87
107
|
private _goToStepAsync;
|
|
108
|
+
private _goToStepCheckedAsync;
|
|
88
109
|
private finishActivePath;
|
|
89
110
|
private requireActivePath;
|
|
90
111
|
private assertPathHasSteps;
|
|
@@ -103,4 +124,10 @@ export declare class PathEngine {
|
|
|
103
124
|
* If the guard returns a `Promise`, returns `true` (optimistic default).
|
|
104
125
|
*/
|
|
105
126
|
private evaluateGuardSync;
|
|
127
|
+
/**
|
|
128
|
+
* Evaluates a validationMessages function synchronously for inclusion in the snapshot.
|
|
129
|
+
* If the hook is absent, returns `[]`.
|
|
130
|
+
* If the hook returns a `Promise`, returns `[]` (async hooks are not supported in snapshots).
|
|
131
|
+
*/
|
|
132
|
+
private evaluateValidationMessagesSync;
|
|
106
133
|
}
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,26 @@ export class PathEngine {
|
|
|
58
58
|
}
|
|
59
59
|
return this._goToStepAsync(active, targetIndex);
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Jumps directly to the step with the given ID, but first checks the
|
|
63
|
+
* direction-appropriate guard on the current step:
|
|
64
|
+
* - Going forward → checks `canMoveNext`
|
|
65
|
+
* - Going backward → checks `canMovePrevious`
|
|
66
|
+
*
|
|
67
|
+
* If the guard blocks, navigation does not occur and `stateChanged` is still
|
|
68
|
+
* emitted (so the UI can react). `shouldSkip` is not evaluated.
|
|
69
|
+
* Throws if the target step ID does not exist.
|
|
70
|
+
*/
|
|
71
|
+
goToStepChecked(stepId) {
|
|
72
|
+
const active = this.requireActivePath();
|
|
73
|
+
const targetIndex = active.definition.steps.findIndex((s) => s.id === stepId);
|
|
74
|
+
if (targetIndex === -1) {
|
|
75
|
+
return Promise.reject(new Error(`Step "${stepId}" not found in path "${active.definition.id}".`));
|
|
76
|
+
}
|
|
77
|
+
if (targetIndex === active.currentStepIndex)
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
return this._goToStepCheckedAsync(active, targetIndex);
|
|
80
|
+
}
|
|
61
81
|
snapshot() {
|
|
62
82
|
if (this.activePath === null) {
|
|
63
83
|
return null;
|
|
@@ -89,6 +109,7 @@ export class PathEngine {
|
|
|
89
109
|
isNavigating: this._isNavigating,
|
|
90
110
|
canMoveNext: this.evaluateGuardSync(step.canMoveNext, active),
|
|
91
111
|
canMovePrevious: this.evaluateGuardSync(step.canMovePrevious, active),
|
|
112
|
+
validationMessages: this.evaluateValidationMessagesSync(step.validationMessages, active),
|
|
92
113
|
data: { ...active.data }
|
|
93
114
|
};
|
|
94
115
|
}
|
|
@@ -155,6 +176,11 @@ export class PathEngine {
|
|
|
155
176
|
async _previousAsync(active) {
|
|
156
177
|
if (this._isNavigating)
|
|
157
178
|
return;
|
|
179
|
+
// No-op when already on the first step of a top-level path.
|
|
180
|
+
// Sub-paths still cancel/pop back to the parent when previous() is called
|
|
181
|
+
// on their first step (the currentStepIndex < 0 branch below handles that).
|
|
182
|
+
if (active.currentStepIndex === 0 && this.pathStack.length === 0)
|
|
183
|
+
return;
|
|
158
184
|
this._isNavigating = true;
|
|
159
185
|
this.emitStateChanged();
|
|
160
186
|
try {
|
|
@@ -198,6 +224,31 @@ export class PathEngine {
|
|
|
198
224
|
throw err;
|
|
199
225
|
}
|
|
200
226
|
}
|
|
227
|
+
async _goToStepCheckedAsync(active, targetIndex) {
|
|
228
|
+
if (this._isNavigating)
|
|
229
|
+
return;
|
|
230
|
+
this._isNavigating = true;
|
|
231
|
+
this.emitStateChanged();
|
|
232
|
+
try {
|
|
233
|
+
const currentStep = this.getCurrentStep(active);
|
|
234
|
+
const goingForward = targetIndex > active.currentStepIndex;
|
|
235
|
+
const allowed = goingForward
|
|
236
|
+
? await this.canMoveNext(active, currentStep)
|
|
237
|
+
: await this.canMovePrevious(active, currentStep);
|
|
238
|
+
if (allowed) {
|
|
239
|
+
this.applyPatch(await this.leaveCurrentStep(active, currentStep));
|
|
240
|
+
active.currentStepIndex = targetIndex;
|
|
241
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
242
|
+
}
|
|
243
|
+
this._isNavigating = false;
|
|
244
|
+
this.emitStateChanged();
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
this._isNavigating = false;
|
|
248
|
+
this.emitStateChanged();
|
|
249
|
+
throw err;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
201
252
|
async finishActivePath() {
|
|
202
253
|
const finished = this.requireActivePath();
|
|
203
254
|
const finishedPathId = finished.definition.id;
|
|
@@ -342,5 +393,24 @@ export class PathEngine {
|
|
|
342
393
|
// Async guard — default to true (optimistic); the engine will enforce the real result on navigation.
|
|
343
394
|
return true;
|
|
344
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Evaluates a validationMessages function synchronously for inclusion in the snapshot.
|
|
398
|
+
* If the hook is absent, returns `[]`.
|
|
399
|
+
* If the hook returns a `Promise`, returns `[]` (async hooks are not supported in snapshots).
|
|
400
|
+
*/
|
|
401
|
+
evaluateValidationMessagesSync(fn, active) {
|
|
402
|
+
if (!fn)
|
|
403
|
+
return [];
|
|
404
|
+
const ctx = {
|
|
405
|
+
pathId: active.definition.id,
|
|
406
|
+
stepId: this.getCurrentStep(active).id,
|
|
407
|
+
data: { ...active.data }
|
|
408
|
+
};
|
|
409
|
+
const result = fn(ctx);
|
|
410
|
+
if (Array.isArray(result))
|
|
411
|
+
return result;
|
|
412
|
+
// Async hook — default to empty; consumers should keep validationMessages synchronous.
|
|
413
|
+
return [];
|
|
414
|
+
}
|
|
345
415
|
}
|
|
346
416
|
//# sourceMappingURL=index.js.map
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daltonr/pathwrite-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Headless path engine — deterministic state machine with stack-based sub-path orchestration. Zero dependencies.",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"types": "dist/index.d.ts",
|
|
30
30
|
"files": [
|
|
31
31
|
"dist",
|
|
32
|
+
"src",
|
|
32
33
|
"README.md",
|
|
33
34
|
"LICENSE"
|
|
34
35
|
],
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
export type PathData = Record<string, unknown>;
|
|
2
|
+
|
|
3
|
+
export interface PathStepContext<TData extends PathData = PathData> {
|
|
4
|
+
readonly pathId: string;
|
|
5
|
+
readonly stepId: string;
|
|
6
|
+
readonly data: Readonly<TData>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface PathStep<TData extends PathData = PathData> {
|
|
10
|
+
id: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
meta?: Record<string, unknown>;
|
|
13
|
+
shouldSkip?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
14
|
+
canMoveNext?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
15
|
+
canMovePrevious?: (ctx: PathStepContext<TData>) => boolean | Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a list of human-readable messages explaining why the step is not
|
|
18
|
+
* yet valid. The shell displays these messages below the step content so
|
|
19
|
+
* consumers do not need to duplicate guard logic in the template.
|
|
20
|
+
* Evaluated synchronously on every snapshot; async functions default to `[]`.
|
|
21
|
+
*/
|
|
22
|
+
validationMessages?: (ctx: PathStepContext<TData>) => string[] | Promise<string[]>;
|
|
23
|
+
onEnter?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
24
|
+
onLeave?: (ctx: PathStepContext<TData>) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
25
|
+
onSubPathComplete?: (
|
|
26
|
+
subPathId: string,
|
|
27
|
+
subPathData: PathData,
|
|
28
|
+
ctx: PathStepContext<TData>
|
|
29
|
+
) => Partial<TData> | void | Promise<Partial<TData> | void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PathDefinition<TData extends PathData = PathData> {
|
|
33
|
+
id: string;
|
|
34
|
+
title?: string;
|
|
35
|
+
steps: PathStep<TData>[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type StepStatus = "completed" | "current" | "upcoming";
|
|
39
|
+
|
|
40
|
+
export interface StepSummary {
|
|
41
|
+
id: string;
|
|
42
|
+
title?: string;
|
|
43
|
+
meta?: Record<string, unknown>;
|
|
44
|
+
status: StepStatus;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface PathSnapshot<TData extends PathData = PathData> {
|
|
48
|
+
pathId: string;
|
|
49
|
+
stepId: string;
|
|
50
|
+
stepTitle?: string;
|
|
51
|
+
stepMeta?: Record<string, unknown>;
|
|
52
|
+
stepIndex: number;
|
|
53
|
+
stepCount: number;
|
|
54
|
+
progress: number;
|
|
55
|
+
steps: StepSummary[];
|
|
56
|
+
isFirstStep: boolean;
|
|
57
|
+
isLastStep: boolean;
|
|
58
|
+
nestingLevel: number;
|
|
59
|
+
/** True while an async guard or hook is executing. Use to disable navigation controls. */
|
|
60
|
+
isNavigating: boolean;
|
|
61
|
+
/** Whether the current step's `canMoveNext` guard allows advancing. Async guards default to `true`. */
|
|
62
|
+
canMoveNext: boolean;
|
|
63
|
+
/** Whether the current step's `canMovePrevious` guard allows going back. Async guards default to `true`. */
|
|
64
|
+
canMovePrevious: boolean;
|
|
65
|
+
/** Messages from the current step's `validationMessages` hook. Empty array when there are none. */
|
|
66
|
+
validationMessages: string[];
|
|
67
|
+
data: TData;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type PathEvent =
|
|
71
|
+
| { type: "stateChanged"; snapshot: PathSnapshot }
|
|
72
|
+
| { type: "completed"; pathId: string; data: PathData }
|
|
73
|
+
| { type: "cancelled"; pathId: string; data: PathData }
|
|
74
|
+
| {
|
|
75
|
+
type: "resumed";
|
|
76
|
+
resumedPathId: string;
|
|
77
|
+
fromSubPathId: string;
|
|
78
|
+
snapshot: PathSnapshot;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
interface ActivePath {
|
|
82
|
+
definition: PathDefinition;
|
|
83
|
+
currentStepIndex: number;
|
|
84
|
+
data: PathData;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export class PathEngine {
|
|
88
|
+
private activePath: ActivePath | null = null;
|
|
89
|
+
private readonly pathStack: ActivePath[] = [];
|
|
90
|
+
private readonly listeners = new Set<(event: PathEvent) => void>();
|
|
91
|
+
private _isNavigating = false;
|
|
92
|
+
|
|
93
|
+
public subscribe(listener: (event: PathEvent) => void): () => void {
|
|
94
|
+
this.listeners.add(listener);
|
|
95
|
+
return () => this.listeners.delete(listener);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Public API
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
public start(path: PathDefinition, initialData: PathData = {}): Promise<void> {
|
|
103
|
+
this.assertPathHasSteps(path);
|
|
104
|
+
return this._startAsync(path, initialData);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Starts a sub-path on top of the currently active path. Throws if no path is running. */
|
|
108
|
+
public startSubPath(path: PathDefinition, initialData: PathData = {}): Promise<void> {
|
|
109
|
+
this.requireActivePath();
|
|
110
|
+
return this.start(path, initialData);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public next(): Promise<void> {
|
|
114
|
+
const active = this.requireActivePath();
|
|
115
|
+
return this._nextAsync(active);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public previous(): Promise<void> {
|
|
119
|
+
const active = this.requireActivePath();
|
|
120
|
+
return this._previousAsync(active);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Cancel is synchronous (no hooks). Returns a resolved Promise for API consistency. */
|
|
124
|
+
public cancel(): Promise<void> {
|
|
125
|
+
const active = this.requireActivePath();
|
|
126
|
+
if (this._isNavigating) return Promise.resolve();
|
|
127
|
+
|
|
128
|
+
const cancelledPathId = active.definition.id;
|
|
129
|
+
const cancelledData = { ...active.data };
|
|
130
|
+
|
|
131
|
+
if (this.pathStack.length > 0) {
|
|
132
|
+
this.activePath = this.pathStack.pop() ?? null;
|
|
133
|
+
this.emitStateChanged();
|
|
134
|
+
return Promise.resolve();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.activePath = null;
|
|
138
|
+
this.emit({ type: "cancelled", pathId: cancelledPathId, data: cancelledData });
|
|
139
|
+
return Promise.resolve();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public setData(key: string, value: unknown): Promise<void> {
|
|
143
|
+
const active = this.requireActivePath();
|
|
144
|
+
active.data[key] = value;
|
|
145
|
+
this.emitStateChanged();
|
|
146
|
+
return Promise.resolve();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Jumps directly to the step with the given ID. Does not check guards or shouldSkip. */
|
|
150
|
+
public goToStep(stepId: string): Promise<void> {
|
|
151
|
+
const active = this.requireActivePath();
|
|
152
|
+
const targetIndex = active.definition.steps.findIndex((s) => s.id === stepId);
|
|
153
|
+
if (targetIndex === -1) {
|
|
154
|
+
throw new Error(`Step "${stepId}" not found in path "${active.definition.id}".`);
|
|
155
|
+
}
|
|
156
|
+
return this._goToStepAsync(active, targetIndex);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Jumps directly to the step with the given ID, but first checks the
|
|
161
|
+
* direction-appropriate guard on the current step:
|
|
162
|
+
* - Going forward → checks `canMoveNext`
|
|
163
|
+
* - Going backward → checks `canMovePrevious`
|
|
164
|
+
*
|
|
165
|
+
* If the guard blocks, navigation does not occur and `stateChanged` is still
|
|
166
|
+
* emitted (so the UI can react). `shouldSkip` is not evaluated.
|
|
167
|
+
* Throws if the target step ID does not exist.
|
|
168
|
+
*/
|
|
169
|
+
public goToStepChecked(stepId: string): Promise<void> {
|
|
170
|
+
const active = this.requireActivePath();
|
|
171
|
+
const targetIndex = active.definition.steps.findIndex((s) => s.id === stepId);
|
|
172
|
+
if (targetIndex === -1) {
|
|
173
|
+
return Promise.reject(new Error(`Step "${stepId}" not found in path "${active.definition.id}".`));
|
|
174
|
+
}
|
|
175
|
+
if (targetIndex === active.currentStepIndex) return Promise.resolve();
|
|
176
|
+
return this._goToStepCheckedAsync(active, targetIndex);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public snapshot(): PathSnapshot | null {
|
|
180
|
+
if (this.activePath === null) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const active = this.activePath;
|
|
185
|
+
const step = this.getCurrentStep(active);
|
|
186
|
+
const { steps } = active.definition;
|
|
187
|
+
const stepCount = steps.length;
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
pathId: active.definition.id,
|
|
191
|
+
stepId: step.id,
|
|
192
|
+
stepTitle: step.title,
|
|
193
|
+
stepMeta: step.meta,
|
|
194
|
+
stepIndex: active.currentStepIndex,
|
|
195
|
+
stepCount,
|
|
196
|
+
progress: stepCount <= 1 ? 1 : active.currentStepIndex / (stepCount - 1),
|
|
197
|
+
steps: steps.map((s, i) => ({
|
|
198
|
+
id: s.id,
|
|
199
|
+
title: s.title,
|
|
200
|
+
meta: s.meta,
|
|
201
|
+
status: i < active.currentStepIndex ? "completed" as const
|
|
202
|
+
: i === active.currentStepIndex ? "current" as const
|
|
203
|
+
: "upcoming" as const
|
|
204
|
+
})),
|
|
205
|
+
isFirstStep: active.currentStepIndex === 0,
|
|
206
|
+
isLastStep:
|
|
207
|
+
active.currentStepIndex === stepCount - 1 &&
|
|
208
|
+
this.pathStack.length === 0,
|
|
209
|
+
nestingLevel: this.pathStack.length,
|
|
210
|
+
isNavigating: this._isNavigating,
|
|
211
|
+
canMoveNext: this.evaluateGuardSync(step.canMoveNext, active),
|
|
212
|
+
canMovePrevious: this.evaluateGuardSync(step.canMovePrevious, active),
|
|
213
|
+
validationMessages: this.evaluateValidationMessagesSync(step.validationMessages, active),
|
|
214
|
+
data: { ...active.data }
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// Private async helpers
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
|
|
222
|
+
private async _startAsync(path: PathDefinition, initialData: PathData): Promise<void> {
|
|
223
|
+
if (this._isNavigating) return;
|
|
224
|
+
|
|
225
|
+
if (this.activePath !== null) {
|
|
226
|
+
this.pathStack.push(this.activePath);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
this.activePath = {
|
|
230
|
+
definition: path,
|
|
231
|
+
currentStepIndex: 0,
|
|
232
|
+
data: { ...initialData }
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
this._isNavigating = true;
|
|
236
|
+
|
|
237
|
+
await this.skipSteps(1);
|
|
238
|
+
|
|
239
|
+
if (this.activePath.currentStepIndex >= path.steps.length) {
|
|
240
|
+
this._isNavigating = false;
|
|
241
|
+
await this.finishActivePath();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.emitStateChanged();
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
249
|
+
this._isNavigating = false;
|
|
250
|
+
this.emitStateChanged();
|
|
251
|
+
} catch (err) {
|
|
252
|
+
this._isNavigating = false;
|
|
253
|
+
this.emitStateChanged();
|
|
254
|
+
throw err;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private async _nextAsync(active: ActivePath): Promise<void> {
|
|
259
|
+
if (this._isNavigating) return;
|
|
260
|
+
|
|
261
|
+
this._isNavigating = true;
|
|
262
|
+
this.emitStateChanged();
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
const step = this.getCurrentStep(active);
|
|
266
|
+
|
|
267
|
+
if (await this.canMoveNext(active, step)) {
|
|
268
|
+
this.applyPatch(await this.leaveCurrentStep(active, step));
|
|
269
|
+
active.currentStepIndex += 1;
|
|
270
|
+
await this.skipSteps(1);
|
|
271
|
+
|
|
272
|
+
if (active.currentStepIndex >= active.definition.steps.length) {
|
|
273
|
+
this._isNavigating = false;
|
|
274
|
+
await this.finishActivePath();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
this._isNavigating = false;
|
|
282
|
+
this.emitStateChanged();
|
|
283
|
+
} catch (err) {
|
|
284
|
+
this._isNavigating = false;
|
|
285
|
+
this.emitStateChanged();
|
|
286
|
+
throw err;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private async _previousAsync(active: ActivePath): Promise<void> {
|
|
291
|
+
if (this._isNavigating) return;
|
|
292
|
+
|
|
293
|
+
// No-op when already on the first step of a top-level path.
|
|
294
|
+
// Sub-paths still cancel/pop back to the parent when previous() is called
|
|
295
|
+
// on their first step (the currentStepIndex < 0 branch below handles that).
|
|
296
|
+
if (active.currentStepIndex === 0 && this.pathStack.length === 0) return;
|
|
297
|
+
|
|
298
|
+
this._isNavigating = true;
|
|
299
|
+
this.emitStateChanged();
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
const step = this.getCurrentStep(active);
|
|
303
|
+
|
|
304
|
+
if (await this.canMovePrevious(active, step)) {
|
|
305
|
+
this.applyPatch(await this.leaveCurrentStep(active, step));
|
|
306
|
+
active.currentStepIndex -= 1;
|
|
307
|
+
await this.skipSteps(-1);
|
|
308
|
+
|
|
309
|
+
if (active.currentStepIndex < 0) {
|
|
310
|
+
this._isNavigating = false;
|
|
311
|
+
await this.cancel();
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this._isNavigating = false;
|
|
319
|
+
this.emitStateChanged();
|
|
320
|
+
} catch (err) {
|
|
321
|
+
this._isNavigating = false;
|
|
322
|
+
this.emitStateChanged();
|
|
323
|
+
throw err;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private async _goToStepAsync(active: ActivePath, targetIndex: number): Promise<void> {
|
|
328
|
+
if (this._isNavigating) return;
|
|
329
|
+
|
|
330
|
+
this._isNavigating = true;
|
|
331
|
+
this.emitStateChanged();
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
const currentStep = this.getCurrentStep(active);
|
|
335
|
+
this.applyPatch(await this.leaveCurrentStep(active, currentStep));
|
|
336
|
+
|
|
337
|
+
active.currentStepIndex = targetIndex;
|
|
338
|
+
|
|
339
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
340
|
+
this._isNavigating = false;
|
|
341
|
+
this.emitStateChanged();
|
|
342
|
+
} catch (err) {
|
|
343
|
+
this._isNavigating = false;
|
|
344
|
+
this.emitStateChanged();
|
|
345
|
+
throw err;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private async _goToStepCheckedAsync(active: ActivePath, targetIndex: number): Promise<void> {
|
|
350
|
+
if (this._isNavigating) return;
|
|
351
|
+
|
|
352
|
+
this._isNavigating = true;
|
|
353
|
+
this.emitStateChanged();
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
const currentStep = this.getCurrentStep(active);
|
|
357
|
+
const goingForward = targetIndex > active.currentStepIndex;
|
|
358
|
+
const allowed = goingForward
|
|
359
|
+
? await this.canMoveNext(active, currentStep)
|
|
360
|
+
: await this.canMovePrevious(active, currentStep);
|
|
361
|
+
|
|
362
|
+
if (allowed) {
|
|
363
|
+
this.applyPatch(await this.leaveCurrentStep(active, currentStep));
|
|
364
|
+
active.currentStepIndex = targetIndex;
|
|
365
|
+
this.applyPatch(await this.enterCurrentStep());
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
this._isNavigating = false;
|
|
369
|
+
this.emitStateChanged();
|
|
370
|
+
} catch (err) {
|
|
371
|
+
this._isNavigating = false;
|
|
372
|
+
this.emitStateChanged();
|
|
373
|
+
throw err;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
private async finishActivePath(): Promise<void> {
|
|
378
|
+
const finished = this.requireActivePath();
|
|
379
|
+
const finishedPathId = finished.definition.id;
|
|
380
|
+
const finishedData = { ...finished.data };
|
|
381
|
+
|
|
382
|
+
if (this.pathStack.length > 0) {
|
|
383
|
+
this.activePath = this.pathStack.pop()!;
|
|
384
|
+
const parent = this.activePath;
|
|
385
|
+
const parentStep = this.getCurrentStep(parent);
|
|
386
|
+
|
|
387
|
+
if (parentStep.onSubPathComplete) {
|
|
388
|
+
const ctx: PathStepContext = {
|
|
389
|
+
pathId: parent.definition.id,
|
|
390
|
+
stepId: parentStep.id,
|
|
391
|
+
data: { ...parent.data }
|
|
392
|
+
};
|
|
393
|
+
this.applyPatch(
|
|
394
|
+
await parentStep.onSubPathComplete(finishedPathId, finishedData, ctx)
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
this.emit({
|
|
399
|
+
type: "resumed",
|
|
400
|
+
resumedPathId: parent.definition.id,
|
|
401
|
+
fromSubPathId: finishedPathId,
|
|
402
|
+
snapshot: this.snapshot()!
|
|
403
|
+
});
|
|
404
|
+
} else {
|
|
405
|
+
this.activePath = null;
|
|
406
|
+
this.emit({ type: "completed", pathId: finishedPathId, data: finishedData });
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ---------------------------------------------------------------------------
|
|
411
|
+
// Private helpers
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
413
|
+
|
|
414
|
+
private requireActivePath(): ActivePath {
|
|
415
|
+
if (this.activePath === null) {
|
|
416
|
+
throw new Error("No active path.");
|
|
417
|
+
}
|
|
418
|
+
return this.activePath;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private assertPathHasSteps(path: PathDefinition): void {
|
|
422
|
+
if (!path.steps || path.steps.length === 0) {
|
|
423
|
+
throw new Error(`Path "${path.id}" must have at least one step.`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private emit(event: PathEvent): void {
|
|
428
|
+
for (const listener of this.listeners) {
|
|
429
|
+
listener(event);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private emitStateChanged(): void {
|
|
434
|
+
this.emit({ type: "stateChanged", snapshot: this.snapshot()! });
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private getCurrentStep(active: ActivePath): PathStep {
|
|
438
|
+
return active.definition.steps[active.currentStepIndex];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private applyPatch(patch: Partial<PathData> | void | null | undefined): void {
|
|
442
|
+
if (patch && typeof patch === "object") {
|
|
443
|
+
const active = this.activePath;
|
|
444
|
+
if (active) {
|
|
445
|
+
Object.assign(active.data, patch);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private async skipSteps(direction: 1 | -1): Promise<void> {
|
|
451
|
+
const active = this.activePath;
|
|
452
|
+
if (!active) return;
|
|
453
|
+
|
|
454
|
+
while (
|
|
455
|
+
active.currentStepIndex >= 0 &&
|
|
456
|
+
active.currentStepIndex < active.definition.steps.length
|
|
457
|
+
) {
|
|
458
|
+
const step = active.definition.steps[active.currentStepIndex];
|
|
459
|
+
if (!step.shouldSkip) break;
|
|
460
|
+
const ctx: PathStepContext = {
|
|
461
|
+
pathId: active.definition.id,
|
|
462
|
+
stepId: step.id,
|
|
463
|
+
data: { ...active.data }
|
|
464
|
+
};
|
|
465
|
+
const skip = await step.shouldSkip(ctx);
|
|
466
|
+
if (!skip) break;
|
|
467
|
+
active.currentStepIndex += direction;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
private async enterCurrentStep(): Promise<Partial<PathData> | void> {
|
|
472
|
+
const active = this.activePath;
|
|
473
|
+
if (!active) return;
|
|
474
|
+
const step = this.getCurrentStep(active);
|
|
475
|
+
if (!step.onEnter) return;
|
|
476
|
+
const ctx: PathStepContext = {
|
|
477
|
+
pathId: active.definition.id,
|
|
478
|
+
stepId: step.id,
|
|
479
|
+
data: { ...active.data }
|
|
480
|
+
};
|
|
481
|
+
return step.onEnter(ctx);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
private async leaveCurrentStep(
|
|
485
|
+
active: ActivePath,
|
|
486
|
+
step: PathStep
|
|
487
|
+
): Promise<Partial<PathData> | void> {
|
|
488
|
+
if (!step.onLeave) return;
|
|
489
|
+
const ctx: PathStepContext = {
|
|
490
|
+
pathId: active.definition.id,
|
|
491
|
+
stepId: step.id,
|
|
492
|
+
data: { ...active.data }
|
|
493
|
+
};
|
|
494
|
+
return step.onLeave(ctx);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
private async canMoveNext(
|
|
498
|
+
active: ActivePath,
|
|
499
|
+
step: PathStep
|
|
500
|
+
): Promise<boolean> {
|
|
501
|
+
if (!step.canMoveNext) return true;
|
|
502
|
+
const ctx: PathStepContext = {
|
|
503
|
+
pathId: active.definition.id,
|
|
504
|
+
stepId: step.id,
|
|
505
|
+
data: { ...active.data }
|
|
506
|
+
};
|
|
507
|
+
return step.canMoveNext(ctx);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
private async canMovePrevious(
|
|
511
|
+
active: ActivePath,
|
|
512
|
+
step: PathStep
|
|
513
|
+
): Promise<boolean> {
|
|
514
|
+
if (!step.canMovePrevious) return true;
|
|
515
|
+
const ctx: PathStepContext = {
|
|
516
|
+
pathId: active.definition.id,
|
|
517
|
+
stepId: step.id,
|
|
518
|
+
data: { ...active.data }
|
|
519
|
+
};
|
|
520
|
+
return step.canMovePrevious(ctx);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Evaluates a guard function synchronously for inclusion in the snapshot.
|
|
525
|
+
* If the guard is absent, returns `true`.
|
|
526
|
+
* If the guard returns a `Promise`, returns `true` (optimistic default).
|
|
527
|
+
*/
|
|
528
|
+
private evaluateGuardSync(
|
|
529
|
+
guard: ((ctx: PathStepContext) => boolean | Promise<boolean>) | undefined,
|
|
530
|
+
active: ActivePath
|
|
531
|
+
): boolean {
|
|
532
|
+
if (!guard) return true;
|
|
533
|
+
const ctx: PathStepContext = {
|
|
534
|
+
pathId: active.definition.id,
|
|
535
|
+
stepId: this.getCurrentStep(active).id,
|
|
536
|
+
data: { ...active.data }
|
|
537
|
+
};
|
|
538
|
+
const result = guard(ctx);
|
|
539
|
+
if (typeof result === "boolean") return result;
|
|
540
|
+
// Async guard — default to true (optimistic); the engine will enforce the real result on navigation.
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Evaluates a validationMessages function synchronously for inclusion in the snapshot.
|
|
546
|
+
* If the hook is absent, returns `[]`.
|
|
547
|
+
* If the hook returns a `Promise`, returns `[]` (async hooks are not supported in snapshots).
|
|
548
|
+
*/
|
|
549
|
+
private evaluateValidationMessagesSync(
|
|
550
|
+
fn: ((ctx: PathStepContext) => string[] | Promise<string[]>) | undefined,
|
|
551
|
+
active: ActivePath
|
|
552
|
+
): string[] {
|
|
553
|
+
if (!fn) return [];
|
|
554
|
+
const ctx: PathStepContext = {
|
|
555
|
+
pathId: active.definition.id,
|
|
556
|
+
stepId: this.getCurrentStep(active).id,
|
|
557
|
+
data: { ...active.data }
|
|
558
|
+
};
|
|
559
|
+
const result = fn(ctx);
|
|
560
|
+
if (Array.isArray(result)) return result;
|
|
561
|
+
// Async hook — default to empty; consumers should keep validationMessages synchronous.
|
|
562
|
+
return [];
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|