@hkdigital/lib-core 0.5.57 → 0.5.59
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/dist/logging/internal/logger/Logger.js +1 -1
- package/dist/state/machines/page-machine/PageMachine.svelte.d.ts +146 -138
- package/dist/state/machines/page-machine/PageMachine.svelte.js +263 -445
- package/dist/state/machines/page-machine/PageMachine.svelte.js__ +708 -0
- package/dist/state/machines/page-machine/README.md +121 -69
- package/package.json +1 -1
|
@@ -264,7 +264,7 @@ export default class Logger extends EventEmitter {
|
|
|
264
264
|
...this.#defaultContext
|
|
265
265
|
};
|
|
266
266
|
|
|
267
|
-
const childName = `${this.name}
|
|
267
|
+
const childName = `${this.name}:${name}`;
|
|
268
268
|
|
|
269
269
|
const child = new Logger(childName, level ?? this.level, context);
|
|
270
270
|
|
|
@@ -5,124 +5,113 @@ export default class PageMachine {
|
|
|
5
5
|
* @param {Object} config - Configuration object
|
|
6
6
|
* @param {string} config.startPath
|
|
7
7
|
* Start path for this route group (e.g., '/game/play')
|
|
8
|
-
* @param {
|
|
9
|
-
*
|
|
8
|
+
* @param {string[]} [config.routes=[]]
|
|
9
|
+
* Optional list of valid routes (for validation/dev tools)
|
|
10
10
|
* @param {Record<string, any>} [config.initialData={}]
|
|
11
|
-
* Initial data properties (
|
|
12
|
-
* @param {Record<string, Function>} [config.onEnterHooks={}]
|
|
13
|
-
* Map of states to onEnter hook functions
|
|
11
|
+
* Initial data properties (use KEY_ constants for keys)
|
|
14
12
|
* @param {import('../../../logging/client.js').Logger} [config.logger]
|
|
15
|
-
* Logger instance (optional
|
|
13
|
+
* Logger instance (optional)
|
|
16
14
|
*
|
|
17
15
|
* @example
|
|
18
16
|
* ```javascript
|
|
17
|
+
* const ROUTE_INTRO = '/intro/start';
|
|
18
|
+
* const KEY_INTRO_COMPLETED = 'intro-completed';
|
|
19
|
+
* const KEY_SCORE = 'score';
|
|
20
|
+
*
|
|
19
21
|
* const machine = new PageMachine({
|
|
20
|
-
* startPath:
|
|
21
|
-
*
|
|
22
|
-
* [STATE_START]: '/intro/start',
|
|
23
|
-
* [STATE_ANIMATE]: '/intro/animate'
|
|
24
|
-
* },
|
|
22
|
+
* startPath: ROUTE_INTRO,
|
|
23
|
+
* routes: [ROUTE_INTRO, '/intro/profile'],
|
|
25
24
|
* initialData: {
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* onEnterHooks: {
|
|
29
|
-
* [STATE_ANIMATE]: (done) => {
|
|
30
|
-
* setTimeout(() => done(STATE_START), 1000);
|
|
31
|
-
* return {
|
|
32
|
-
* abort: () => clearTimeout(...),
|
|
33
|
-
* complete: () => done(STATE_START)
|
|
34
|
-
* };
|
|
35
|
-
* }
|
|
25
|
+
* [KEY_INTRO_COMPLETED]: false,
|
|
26
|
+
* [KEY_SCORE]: 0
|
|
36
27
|
* }
|
|
37
28
|
* });
|
|
38
29
|
* ```
|
|
39
30
|
*/
|
|
40
|
-
constructor({ startPath,
|
|
31
|
+
constructor({ startPath, routes, initialData, logger }: {
|
|
41
32
|
startPath: string;
|
|
42
|
-
|
|
33
|
+
routes?: string[] | undefined;
|
|
43
34
|
initialData?: Record<string, any> | undefined;
|
|
44
|
-
onEnterHooks?: Record<string, Function> | undefined;
|
|
45
35
|
logger?: import("../../../logging/client.js").Logger | undefined;
|
|
46
36
|
});
|
|
47
37
|
/**
|
|
48
|
-
* Logger instance
|
|
38
|
+
* Logger instance
|
|
49
39
|
* @type {import('../../../logging/client.js').Logger}
|
|
50
40
|
*/
|
|
51
41
|
logger: import("../../../logging/client.js").Logger;
|
|
52
42
|
/**
|
|
53
|
-
* Synchronize machine
|
|
43
|
+
* Synchronize machine with URL path
|
|
54
44
|
*
|
|
55
|
-
* Call this in a $effect that watches $page.url.pathname
|
|
56
|
-
* Automatically tracks visited
|
|
45
|
+
* Call this in a $effect that watches $page.url.pathname.
|
|
46
|
+
* Automatically tracks visited routes.
|
|
57
47
|
*
|
|
58
48
|
* @param {string} currentPath - Current URL pathname
|
|
59
49
|
*
|
|
60
|
-
* @returns {boolean} True if
|
|
50
|
+
* @returns {boolean} True if route was changed
|
|
61
51
|
*/
|
|
62
52
|
syncFromPath(currentPath: string): boolean;
|
|
63
53
|
/**
|
|
64
|
-
* Get route
|
|
65
|
-
*
|
|
66
|
-
* @param {string} state - State name
|
|
67
|
-
*
|
|
68
|
-
* @returns {string} Route path or null if no mapping
|
|
69
|
-
*/
|
|
70
|
-
getPathForState(state: string): string;
|
|
71
|
-
/**
|
|
72
|
-
* Navigate to the route path for a given state
|
|
73
|
-
*
|
|
74
|
-
* @param {string} state - State name
|
|
75
|
-
*/
|
|
76
|
-
navigateToState(state: string): void;
|
|
77
|
-
/**
|
|
78
|
-
* Get route path for current state
|
|
79
|
-
*
|
|
80
|
-
* @returns {string|null} Route path or null if no mapping
|
|
81
|
-
*/
|
|
82
|
-
getCurrentPath(): string | null;
|
|
83
|
-
/**
|
|
84
|
-
* Get current state
|
|
54
|
+
* Get current route
|
|
85
55
|
*
|
|
86
|
-
* @returns {string} Current
|
|
56
|
+
* @returns {string} Current route path
|
|
87
57
|
*/
|
|
88
58
|
get current(): string;
|
|
89
59
|
/**
|
|
90
|
-
* Get the
|
|
60
|
+
* Get the routes list
|
|
91
61
|
*
|
|
92
|
-
* @returns {
|
|
62
|
+
* @returns {string[]} Copy of routes list
|
|
93
63
|
*/
|
|
94
|
-
get
|
|
64
|
+
get routes(): string[];
|
|
95
65
|
/**
|
|
96
66
|
* Set a data property value
|
|
97
67
|
*
|
|
98
|
-
*
|
|
68
|
+
* Automatically reactive - effects watching this key will re-run.
|
|
69
|
+
* Uses fine-grained reactivity, so only effects watching this specific
|
|
70
|
+
* key will be triggered.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} key - Property key (use KEY_ constant)
|
|
99
73
|
* @param {any} value - Property value
|
|
100
74
|
*
|
|
101
75
|
* @example
|
|
102
76
|
* ```javascript
|
|
103
|
-
*
|
|
104
|
-
*
|
|
77
|
+
* const KEY_HAS_STRONG_PROFILE = 'has-strong-profile';
|
|
78
|
+
* const KEY_PROFILE_SCORE = 'profile-score';
|
|
79
|
+
*
|
|
80
|
+
* machine.setData(KEY_HAS_STRONG_PROFILE, true);
|
|
81
|
+
* machine.setData(KEY_PROFILE_SCORE, 85);
|
|
105
82
|
* ```
|
|
106
83
|
*/
|
|
107
84
|
setData(key: string, value: any): void;
|
|
108
85
|
/**
|
|
109
86
|
* Get a data property value
|
|
110
87
|
*
|
|
111
|
-
*
|
|
88
|
+
* Automatically reactive - creates a dependency on this specific key.
|
|
89
|
+
* The effect will only re-run when THIS key changes, not when other
|
|
90
|
+
* keys change.
|
|
91
|
+
*
|
|
92
|
+
* @param {string} key - Property key (use KEY_ constant)
|
|
112
93
|
*
|
|
113
94
|
* @returns {any} Property value or undefined
|
|
114
95
|
*
|
|
115
96
|
* @example
|
|
116
97
|
* ```javascript
|
|
117
|
-
* const
|
|
118
|
-
*
|
|
98
|
+
* const KEY_SCORE = 'score';
|
|
99
|
+
*
|
|
100
|
+
* // Reactive - re-runs only when KEY_SCORE changes
|
|
101
|
+
* $effect(() => {
|
|
102
|
+
* const score = machine.getData(KEY_SCORE);
|
|
103
|
+
* console.log('Score:', score);
|
|
104
|
+
* });
|
|
119
105
|
* ```
|
|
120
106
|
*/
|
|
121
107
|
getData(key: string): any;
|
|
122
108
|
/**
|
|
123
|
-
* Get all data properties
|
|
109
|
+
* Get all data properties as plain object
|
|
110
|
+
*
|
|
111
|
+
* Note: This returns a snapshot (plain object), not a reactive map.
|
|
112
|
+
* Use this for serialization or server sync, not for reactive tracking.
|
|
124
113
|
*
|
|
125
|
-
* @returns {Record<string, any>}
|
|
114
|
+
* @returns {Record<string, any>} Plain object with all data
|
|
126
115
|
*
|
|
127
116
|
* @example
|
|
128
117
|
* ```javascript
|
|
@@ -134,154 +123,173 @@ export default class PageMachine {
|
|
|
134
123
|
/**
|
|
135
124
|
* Update multiple data properties at once
|
|
136
125
|
*
|
|
137
|
-
*
|
|
126
|
+
* Each property update triggers fine-grained reactivity.
|
|
127
|
+
*
|
|
128
|
+
* @param {Record<string, any>} dataUpdates
|
|
129
|
+
* Object with key-value pairs (use KEY_ constants for keys)
|
|
138
130
|
*
|
|
139
131
|
* @example
|
|
140
132
|
* ```javascript
|
|
133
|
+
* const KEY_HAS_STRONG_PROFILE = 'has-strong-profile';
|
|
134
|
+
* const KEY_PROFILE_SCORE = 'profile-score';
|
|
135
|
+
* const KEY_MATCHED_SECTOR = 'matched-sector';
|
|
136
|
+
*
|
|
141
137
|
* machine.updateData({
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
138
|
+
* [KEY_HAS_STRONG_PROFILE]: true,
|
|
139
|
+
* [KEY_PROFILE_SCORE]: 85,
|
|
140
|
+
* [KEY_MATCHED_SECTOR]: 'technology'
|
|
145
141
|
* });
|
|
146
142
|
* ```
|
|
147
143
|
*/
|
|
148
144
|
updateData(dataUpdates: Record<string, any>): void;
|
|
149
145
|
/**
|
|
150
|
-
*
|
|
146
|
+
* Delete a data property
|
|
151
147
|
*
|
|
152
|
-
* @param {string}
|
|
148
|
+
* @param {string} key - Property key to delete (use KEY_ constant)
|
|
153
149
|
*
|
|
154
|
-
* @returns {boolean} True if the
|
|
150
|
+
* @returns {boolean} True if the key existed and was deleted
|
|
155
151
|
*
|
|
156
152
|
* @example
|
|
157
153
|
* ```javascript
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
154
|
+
* const KEY_TEMPORARY_FLAG = 'temporary-flag';
|
|
155
|
+
*
|
|
156
|
+
* machine.deleteData(KEY_TEMPORARY_FLAG);
|
|
161
157
|
* ```
|
|
162
158
|
*/
|
|
163
|
-
|
|
159
|
+
deleteData(key: string): boolean;
|
|
164
160
|
/**
|
|
165
|
-
* Check if
|
|
161
|
+
* Check if data property exists
|
|
162
|
+
*
|
|
163
|
+
* @param {string} key - Property key to check (use KEY_ constant)
|
|
166
164
|
*
|
|
167
|
-
* @returns {boolean} True if the
|
|
165
|
+
* @returns {boolean} True if the key exists
|
|
168
166
|
*
|
|
169
167
|
* @example
|
|
170
168
|
* ```javascript
|
|
171
|
-
*
|
|
172
|
-
*
|
|
169
|
+
* const KEY_TUTORIAL_SEEN = 'tutorial-seen';
|
|
170
|
+
*
|
|
171
|
+
* if (machine.hasData(KEY_TUTORIAL_SEEN)) {
|
|
172
|
+
* // Skip tutorial
|
|
173
173
|
* }
|
|
174
174
|
* ```
|
|
175
175
|
*/
|
|
176
|
-
|
|
176
|
+
hasData(key: string): boolean;
|
|
177
177
|
/**
|
|
178
|
-
*
|
|
178
|
+
* Clear all data properties
|
|
179
179
|
*
|
|
180
|
-
* @
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
* Reset visited states tracking
|
|
185
|
-
* Useful for testing or resetting experience
|
|
180
|
+
* @example
|
|
181
|
+
* ```javascript
|
|
182
|
+
* machine.clearData(); // Reset all game data
|
|
183
|
+
* ```
|
|
186
184
|
*/
|
|
187
|
-
|
|
185
|
+
clearData(): void;
|
|
188
186
|
/**
|
|
189
|
-
* Get
|
|
187
|
+
* Get number of data properties
|
|
190
188
|
*
|
|
191
|
-
* @returns {
|
|
189
|
+
* @returns {number} Number of data entries
|
|
192
190
|
*/
|
|
193
|
-
get
|
|
191
|
+
get dataSize(): number;
|
|
194
192
|
/**
|
|
195
|
-
*
|
|
193
|
+
* Check if a route has been visited
|
|
196
194
|
*
|
|
197
|
-
*
|
|
198
|
-
*/
|
|
199
|
-
get startState(): string;
|
|
200
|
-
/**
|
|
201
|
-
* Check if the supplied path matches the start path
|
|
195
|
+
* Automatically reactive - creates a dependency on the visited routes set.
|
|
202
196
|
*
|
|
203
|
-
* @param {string}
|
|
197
|
+
* @param {string} route - Route path to check
|
|
204
198
|
*
|
|
205
|
-
* @returns {boolean} True if
|
|
199
|
+
* @returns {boolean} True if the route has been visited
|
|
206
200
|
*
|
|
207
201
|
* @example
|
|
208
202
|
* ```javascript
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
203
|
+
* // Reactive - re-runs when visited routes change
|
|
204
|
+
* $effect(() => {
|
|
205
|
+
* if (machine.hasVisited('/intro/profile')) {
|
|
206
|
+
* console.log('User has seen profile page');
|
|
207
|
+
* }
|
|
208
|
+
* });
|
|
212
209
|
* ```
|
|
213
210
|
*/
|
|
214
|
-
|
|
211
|
+
hasVisited(route: string): boolean;
|
|
215
212
|
/**
|
|
216
|
-
* Check if
|
|
213
|
+
* Check if the start route has been visited
|
|
217
214
|
*
|
|
218
|
-
* @returns {boolean} True if
|
|
215
|
+
* @returns {boolean} True if the start route has been visited
|
|
219
216
|
*
|
|
220
217
|
* @example
|
|
221
218
|
* ```javascript
|
|
222
|
-
* if (machine.
|
|
223
|
-
* //
|
|
219
|
+
* if (machine.hasVisitedStart) {
|
|
220
|
+
* // User has been to the start page
|
|
224
221
|
* }
|
|
225
222
|
* ```
|
|
226
223
|
*/
|
|
227
|
-
get
|
|
224
|
+
get hasVisitedStart(): boolean;
|
|
228
225
|
/**
|
|
229
|
-
*
|
|
226
|
+
* Get all visited routes as array
|
|
230
227
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* machine.redirectToStartPath();
|
|
235
|
-
* ```
|
|
228
|
+
* Note: Returns a snapshot (plain array), not reactive.
|
|
229
|
+
*
|
|
230
|
+
* @returns {string[]} Array of visited route paths
|
|
236
231
|
*/
|
|
237
|
-
|
|
232
|
+
getVisitedRoutes(): string[];
|
|
238
233
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
234
|
+
* Reset visited routes tracking
|
|
235
|
+
*
|
|
236
|
+
* Clears all visited routes and marks only the current route as visited.
|
|
241
237
|
*
|
|
242
238
|
* @example
|
|
243
239
|
* ```javascript
|
|
244
|
-
* //
|
|
245
|
-
* machine.abortTransitions();
|
|
240
|
+
* machine.resetVisitedRoutes(); // Reset progress tracking
|
|
246
241
|
* ```
|
|
247
242
|
*/
|
|
248
|
-
|
|
243
|
+
resetVisitedRoutes(): void;
|
|
244
|
+
/**
|
|
245
|
+
* Get number of visited routes
|
|
246
|
+
*
|
|
247
|
+
* @returns {number} Number of routes visited
|
|
248
|
+
*/
|
|
249
|
+
get visitedRoutesCount(): number;
|
|
250
|
+
/**
|
|
251
|
+
* Get the start path
|
|
252
|
+
*
|
|
253
|
+
* @returns {string} Start path
|
|
254
|
+
*/
|
|
255
|
+
get startPath(): string;
|
|
249
256
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
257
|
+
* Check if the supplied path matches the start path
|
|
258
|
+
*
|
|
259
|
+
* @param {string} path - Path to check
|
|
260
|
+
*
|
|
261
|
+
* @returns {boolean} True if path matches start path
|
|
252
262
|
*
|
|
253
263
|
* @example
|
|
254
264
|
* ```javascript
|
|
255
|
-
*
|
|
256
|
-
*
|
|
265
|
+
* if (machine.isStartPath('/game/play')) {
|
|
266
|
+
* // User is on the start page
|
|
267
|
+
* }
|
|
257
268
|
* ```
|
|
258
269
|
*/
|
|
259
|
-
|
|
270
|
+
isStartPath(path: string): boolean;
|
|
260
271
|
/**
|
|
261
|
-
* Check if
|
|
272
|
+
* Check if currently on the start path
|
|
262
273
|
*
|
|
263
|
-
* @returns {boolean} True if
|
|
274
|
+
* @returns {boolean} True if current route is the start path
|
|
264
275
|
*
|
|
265
276
|
* @example
|
|
266
|
-
* ```
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
277
|
+
* ```javascript
|
|
278
|
+
* if (machine.isOnStartPath) {
|
|
279
|
+
* // Show onboarding
|
|
280
|
+
* }
|
|
270
281
|
* ```
|
|
271
282
|
*/
|
|
272
|
-
get
|
|
283
|
+
get isOnStartPath(): boolean;
|
|
273
284
|
/**
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* @returns {boolean} True if abortTransitions() can be called
|
|
285
|
+
* Navigate to the start path
|
|
277
286
|
*
|
|
278
287
|
* @example
|
|
279
|
-
* ```
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* {/if}
|
|
288
|
+
* ```javascript
|
|
289
|
+
* // Redirect user to start
|
|
290
|
+
* machine.redirectToStartPath();
|
|
283
291
|
* ```
|
|
284
292
|
*/
|
|
285
|
-
|
|
293
|
+
redirectToStartPath(): void;
|
|
286
294
|
#private;
|
|
287
295
|
}
|