@hkdigital/lib-core 0.5.87 → 0.5.88
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.
|
@@ -189,6 +189,138 @@ export default class PageMachine {
|
|
|
189
189
|
* @returns {number} Number of data entries
|
|
190
190
|
*/
|
|
191
191
|
get dataSize(): number;
|
|
192
|
+
/**
|
|
193
|
+
* Set a dev data property value
|
|
194
|
+
*
|
|
195
|
+
* Automatically reactive - effects watching this key will re-run.
|
|
196
|
+
* Only available in dev mode - no-op in production.
|
|
197
|
+
*
|
|
198
|
+
* @param {string} key - Property key (use KEY_DEV_ constant)
|
|
199
|
+
* @param {any} value - Property value
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```javascript
|
|
203
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
204
|
+
* const KEY_DEV_SKIP_ANIMATIONS = 'dev-skip-animations';
|
|
205
|
+
*
|
|
206
|
+
* machine.setDevData(KEY_DEV_AUTO_NAVIGATION, true);
|
|
207
|
+
* machine.setDevData(KEY_DEV_SKIP_ANIMATIONS, false);
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
setDevData(key: string, value: any): void;
|
|
211
|
+
/**
|
|
212
|
+
* Get a dev data property value
|
|
213
|
+
*
|
|
214
|
+
* Automatically reactive - creates a dependency on this specific key.
|
|
215
|
+
* Only available in dev mode - returns undefined in production.
|
|
216
|
+
*
|
|
217
|
+
* @param {string} key - Property key (use KEY_DEV_ constant)
|
|
218
|
+
*
|
|
219
|
+
* @returns {any} Property value or undefined
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```javascript
|
|
223
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
224
|
+
*
|
|
225
|
+
* // Reactive - re-runs only when KEY_DEV_AUTO_NAVIGATION changes
|
|
226
|
+
* $effect(() => {
|
|
227
|
+
* const autoNav = machine.getDevData(KEY_DEV_AUTO_NAVIGATION);
|
|
228
|
+
* console.log('Auto-navigation:', autoNav);
|
|
229
|
+
* });
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
getDevData(key: string): any;
|
|
233
|
+
/**
|
|
234
|
+
* Get all dev data properties as plain object
|
|
235
|
+
*
|
|
236
|
+
* Note: Returns a snapshot (plain object), not reactive.
|
|
237
|
+
* Only available in dev mode - returns empty object in production.
|
|
238
|
+
*
|
|
239
|
+
* @returns {Record<string, any>} Plain object with all dev data
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```javascript
|
|
243
|
+
* const allDevData = machine.getAllDevData();
|
|
244
|
+
* console.log('Dev settings:', allDevData);
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
getAllDevData(): Record<string, any>;
|
|
248
|
+
/**
|
|
249
|
+
* Update multiple dev data properties at once
|
|
250
|
+
*
|
|
251
|
+
* Each property update triggers fine-grained reactivity.
|
|
252
|
+
* Only available in dev mode - no-op in production.
|
|
253
|
+
*
|
|
254
|
+
* @param {Record<string, any>} dataUpdates
|
|
255
|
+
* Object with key-value pairs (use KEY_DEV_ constants for keys)
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```javascript
|
|
259
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
260
|
+
* const KEY_DEV_SKIP_ANIMATIONS = 'dev-skip-animations';
|
|
261
|
+
*
|
|
262
|
+
* machine.updateDevData({
|
|
263
|
+
* [KEY_DEV_AUTO_NAVIGATION]: true,
|
|
264
|
+
* [KEY_DEV_SKIP_ANIMATIONS]: false
|
|
265
|
+
* });
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
updateDevData(dataUpdates: Record<string, any>): void;
|
|
269
|
+
/**
|
|
270
|
+
* Delete a dev data property
|
|
271
|
+
*
|
|
272
|
+
* Only available in dev mode - no-op in production.
|
|
273
|
+
*
|
|
274
|
+
* @param {string} key - Property key to delete (use KEY_DEV_ constant)
|
|
275
|
+
*
|
|
276
|
+
* @returns {boolean} True if the key existed and was deleted
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```javascript
|
|
280
|
+
* const KEY_DEV_TEMP_FLAG = 'dev-temp-flag';
|
|
281
|
+
*
|
|
282
|
+
* machine.deleteDevData(KEY_DEV_TEMP_FLAG);
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
deleteDevData(key: string): boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Check if dev data property exists
|
|
288
|
+
*
|
|
289
|
+
* Only available in dev mode - returns false in production.
|
|
290
|
+
*
|
|
291
|
+
* @param {string} key - Property key to check (use KEY_DEV_ constant)
|
|
292
|
+
*
|
|
293
|
+
* @returns {boolean} True if the key exists
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```javascript
|
|
297
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
298
|
+
*
|
|
299
|
+
* if (machine.hasDevData(KEY_DEV_AUTO_NAVIGATION)) {
|
|
300
|
+
* // Dev setting exists
|
|
301
|
+
* }
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
hasDevData(key: string): boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Clear all dev data properties
|
|
307
|
+
*
|
|
308
|
+
* Only available in dev mode - no-op in production.
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```javascript
|
|
312
|
+
* machine.clearDevData(); // Reset all dev settings
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
clearDevData(): void;
|
|
316
|
+
/**
|
|
317
|
+
* Get number of dev data properties
|
|
318
|
+
*
|
|
319
|
+
* Only available in dev mode - returns 0 in production.
|
|
320
|
+
*
|
|
321
|
+
* @returns {number} Number of dev data entries
|
|
322
|
+
*/
|
|
323
|
+
get devDataSize(): number;
|
|
192
324
|
/**
|
|
193
325
|
* Check if a route has been visited
|
|
194
326
|
*
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
* - Current route tracking and synchronization
|
|
9
9
|
* - Start path management
|
|
10
10
|
* - Data properties for business/domain state (using SvelteMap)
|
|
11
|
+
* - Dev data properties for dev-mode helpers (using SvelteMap)
|
|
11
12
|
* - Visited routes tracking (using SvelteSet)
|
|
12
13
|
* - Fine-grained reactivity without manual revision tracking
|
|
13
14
|
*
|
|
14
15
|
* Best practices:
|
|
15
16
|
* - Use constants for routes: `const ROUTE_INTRO = '/intro/start'`
|
|
16
17
|
* - Use KEY_ constants for data: `const KEY_SCORE = 'score'`
|
|
18
|
+
* - Use KEY_DEV_ constants for dev data: `const KEY_DEV_AUTO_NAV = 'dev-auto-navigation'`
|
|
17
19
|
*
|
|
18
20
|
* Basic usage:
|
|
19
21
|
* ```javascript
|
|
@@ -21,6 +23,7 @@
|
|
|
21
23
|
* const ROUTE_INTRO = '/intro/start';
|
|
22
24
|
* const KEY_SCORE = 'score';
|
|
23
25
|
* const KEY_TUTORIAL_SEEN = 'tutorial-seen';
|
|
26
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
24
27
|
*
|
|
25
28
|
* const machine = new PageMachine({
|
|
26
29
|
* startPath: ROUTE_INTRO,
|
|
@@ -48,6 +51,10 @@
|
|
|
48
51
|
* const score = machine.getData(KEY_SCORE);
|
|
49
52
|
* console.log('Score changed:', score);
|
|
50
53
|
* });
|
|
54
|
+
*
|
|
55
|
+
* // Dev-mode helpers (only available in dev)
|
|
56
|
+
* machine.setDevData(KEY_DEV_AUTO_NAVIGATION, true);
|
|
57
|
+
* const autoNavEnabled = machine.getDevData(KEY_DEV_AUTO_NAVIGATION);
|
|
51
58
|
* ```
|
|
52
59
|
*
|
|
53
60
|
* Animations and page-specific logic should use $effect in pages:
|
|
@@ -63,6 +70,7 @@
|
|
|
63
70
|
* ```
|
|
64
71
|
*/
|
|
65
72
|
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
|
73
|
+
import { dev } from '$app/environment';
|
|
66
74
|
|
|
67
75
|
export default class PageMachine {
|
|
68
76
|
/**
|
|
@@ -97,6 +105,14 @@ export default class PageMachine {
|
|
|
97
105
|
*/
|
|
98
106
|
#data;
|
|
99
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Reactive map for dev-mode helper data
|
|
110
|
+
* Uses SvelteMap for fine-grained reactivity
|
|
111
|
+
* Only available in dev mode
|
|
112
|
+
* @type {SvelteMap<string, any>|null}
|
|
113
|
+
*/
|
|
114
|
+
#devData;
|
|
115
|
+
|
|
100
116
|
/**
|
|
101
117
|
* Reactive set for visited routes
|
|
102
118
|
* Uses SvelteSet for automatic reactivity
|
|
@@ -147,6 +163,11 @@ export default class PageMachine {
|
|
|
147
163
|
this.#data = new SvelteMap();
|
|
148
164
|
this.#visitedRoutes = new SvelteSet();
|
|
149
165
|
|
|
166
|
+
// Initialize dev data (only in dev mode)
|
|
167
|
+
if (dev) {
|
|
168
|
+
this.#devData = new SvelteMap();
|
|
169
|
+
}
|
|
170
|
+
|
|
150
171
|
// Populate initial data
|
|
151
172
|
for (const [key, value] of Object.entries(initialData)) {
|
|
152
173
|
this.#data.set(key, value);
|
|
@@ -387,6 +408,174 @@ export default class PageMachine {
|
|
|
387
408
|
return this.#data.size;
|
|
388
409
|
}
|
|
389
410
|
|
|
411
|
+
/* ===== Dev Data Properties (Dev-Mode Helpers) ===== */
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Set a dev data property value
|
|
415
|
+
*
|
|
416
|
+
* Automatically reactive - effects watching this key will re-run.
|
|
417
|
+
* Only available in dev mode - no-op in production.
|
|
418
|
+
*
|
|
419
|
+
* @param {string} key - Property key (use KEY_DEV_ constant)
|
|
420
|
+
* @param {any} value - Property value
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```javascript
|
|
424
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
425
|
+
* const KEY_DEV_SKIP_ANIMATIONS = 'dev-skip-animations';
|
|
426
|
+
*
|
|
427
|
+
* machine.setDevData(KEY_DEV_AUTO_NAVIGATION, true);
|
|
428
|
+
* machine.setDevData(KEY_DEV_SKIP_ANIMATIONS, false);
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
setDevData(key, value) {
|
|
432
|
+
if (!dev) return;
|
|
433
|
+
this.#devData.set(key, value);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Get a dev data property value
|
|
438
|
+
*
|
|
439
|
+
* Automatically reactive - creates a dependency on this specific key.
|
|
440
|
+
* Only available in dev mode - returns undefined in production.
|
|
441
|
+
*
|
|
442
|
+
* @param {string} key - Property key (use KEY_DEV_ constant)
|
|
443
|
+
*
|
|
444
|
+
* @returns {any} Property value or undefined
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```javascript
|
|
448
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
449
|
+
*
|
|
450
|
+
* // Reactive - re-runs only when KEY_DEV_AUTO_NAVIGATION changes
|
|
451
|
+
* $effect(() => {
|
|
452
|
+
* const autoNav = machine.getDevData(KEY_DEV_AUTO_NAVIGATION);
|
|
453
|
+
* console.log('Auto-navigation:', autoNav);
|
|
454
|
+
* });
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
457
|
+
getDevData(key) {
|
|
458
|
+
if (!dev) return undefined;
|
|
459
|
+
return this.#devData.get(key);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Get all dev data properties as plain object
|
|
464
|
+
*
|
|
465
|
+
* Note: Returns a snapshot (plain object), not reactive.
|
|
466
|
+
* Only available in dev mode - returns empty object in production.
|
|
467
|
+
*
|
|
468
|
+
* @returns {Record<string, any>} Plain object with all dev data
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```javascript
|
|
472
|
+
* const allDevData = machine.getAllDevData();
|
|
473
|
+
* console.log('Dev settings:', allDevData);
|
|
474
|
+
* ```
|
|
475
|
+
*/
|
|
476
|
+
getAllDevData() {
|
|
477
|
+
if (!dev) return {};
|
|
478
|
+
return Object.fromEntries(this.#devData);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Update multiple dev data properties at once
|
|
483
|
+
*
|
|
484
|
+
* Each property update triggers fine-grained reactivity.
|
|
485
|
+
* Only available in dev mode - no-op in production.
|
|
486
|
+
*
|
|
487
|
+
* @param {Record<string, any>} dataUpdates
|
|
488
|
+
* Object with key-value pairs (use KEY_DEV_ constants for keys)
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```javascript
|
|
492
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
493
|
+
* const KEY_DEV_SKIP_ANIMATIONS = 'dev-skip-animations';
|
|
494
|
+
*
|
|
495
|
+
* machine.updateDevData({
|
|
496
|
+
* [KEY_DEV_AUTO_NAVIGATION]: true,
|
|
497
|
+
* [KEY_DEV_SKIP_ANIMATIONS]: false
|
|
498
|
+
* });
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
updateDevData(dataUpdates) {
|
|
502
|
+
if (!dev) return;
|
|
503
|
+
for (const [key, value] of Object.entries(dataUpdates)) {
|
|
504
|
+
this.#devData.set(key, value);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Delete a dev data property
|
|
510
|
+
*
|
|
511
|
+
* Only available in dev mode - no-op in production.
|
|
512
|
+
*
|
|
513
|
+
* @param {string} key - Property key to delete (use KEY_DEV_ constant)
|
|
514
|
+
*
|
|
515
|
+
* @returns {boolean} True if the key existed and was deleted
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* ```javascript
|
|
519
|
+
* const KEY_DEV_TEMP_FLAG = 'dev-temp-flag';
|
|
520
|
+
*
|
|
521
|
+
* machine.deleteDevData(KEY_DEV_TEMP_FLAG);
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
deleteDevData(key) {
|
|
525
|
+
if (!dev) return false;
|
|
526
|
+
return this.#devData.delete(key);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Check if dev data property exists
|
|
531
|
+
*
|
|
532
|
+
* Only available in dev mode - returns false in production.
|
|
533
|
+
*
|
|
534
|
+
* @param {string} key - Property key to check (use KEY_DEV_ constant)
|
|
535
|
+
*
|
|
536
|
+
* @returns {boolean} True if the key exists
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```javascript
|
|
540
|
+
* const KEY_DEV_AUTO_NAVIGATION = 'dev-auto-navigation';
|
|
541
|
+
*
|
|
542
|
+
* if (machine.hasDevData(KEY_DEV_AUTO_NAVIGATION)) {
|
|
543
|
+
* // Dev setting exists
|
|
544
|
+
* }
|
|
545
|
+
* ```
|
|
546
|
+
*/
|
|
547
|
+
hasDevData(key) {
|
|
548
|
+
if (!dev) return false;
|
|
549
|
+
return this.#devData.has(key);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Clear all dev data properties
|
|
554
|
+
*
|
|
555
|
+
* Only available in dev mode - no-op in production.
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```javascript
|
|
559
|
+
* machine.clearDevData(); // Reset all dev settings
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
clearDevData() {
|
|
563
|
+
if (!dev) return;
|
|
564
|
+
this.#devData.clear();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Get number of dev data properties
|
|
569
|
+
*
|
|
570
|
+
* Only available in dev mode - returns 0 in production.
|
|
571
|
+
*
|
|
572
|
+
* @returns {number} Number of dev data entries
|
|
573
|
+
*/
|
|
574
|
+
get devDataSize() {
|
|
575
|
+
if (!dev) return 0;
|
|
576
|
+
return this.#devData.size;
|
|
577
|
+
}
|
|
578
|
+
|
|
390
579
|
/* ===== Visited Routes Tracking ===== */
|
|
391
580
|
|
|
392
581
|
/**
|
|
@@ -79,7 +79,7 @@ const KEY_HIGHEST_LEVEL = 'highest-level';
|
|
|
79
79
|
const KEY_DIFFICULTY = 'difficulty';
|
|
80
80
|
|
|
81
81
|
export class PuzzleState extends PageMachine {
|
|
82
|
-
#
|
|
82
|
+
#logic;
|
|
83
83
|
|
|
84
84
|
constructor() {
|
|
85
85
|
// Call PageMachine constructor with route config
|
|
@@ -99,11 +99,11 @@ export class PuzzleState extends PageMachine {
|
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
this.#
|
|
102
|
+
this.#logic = new PuzzleGameLogic();
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
get
|
|
106
|
-
return this.#
|
|
105
|
+
get logic() {
|
|
106
|
+
return this.#logic;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// Computed properties for convenience
|
|
@@ -161,7 +161,7 @@ export class PuzzleState extends PageMachine {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
reset() {
|
|
164
|
-
this.#
|
|
164
|
+
this.#logic = new PuzzleGameLogic();
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -209,12 +209,12 @@ export const [createOrGetPuzzleState, createPuzzleState, getPuzzleState] =
|
|
|
209
209
|
{:else if puzzleState.isOnTutorial}
|
|
210
210
|
<TutorialView />
|
|
211
211
|
{:else if puzzleState.isOnLevel1}
|
|
212
|
-
<Level1View gameLogic={puzzleState.
|
|
212
|
+
<Level1View gameLogic={puzzleState.logic} />
|
|
213
213
|
{:else if puzzleState.isOnLevel2}
|
|
214
|
-
<Level2View gameLogic={puzzleState.
|
|
214
|
+
<Level2View gameLogic={puzzleState.logic} />
|
|
215
215
|
{:else if puzzleState.isComplete}
|
|
216
216
|
<CompleteView
|
|
217
|
-
score={puzzleState.
|
|
217
|
+
score={puzzleState.logic.score}
|
|
218
218
|
highestLevel={puzzleState.highestLevel} />
|
|
219
219
|
{/if}
|
|
220
220
|
```
|