@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
- #gameLogic;
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.#gameLogic = new PuzzleGameLogic();
102
+ this.#logic = new PuzzleGameLogic();
103
103
  }
104
104
 
105
- get gameLogic() {
106
- return this.#gameLogic;
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.#gameLogic = new PuzzleGameLogic();
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.gameLogic} />
212
+ <Level1View gameLogic={puzzleState.logic} />
213
213
  {:else if puzzleState.isOnLevel2}
214
- <Level2View gameLogic={puzzleState.gameLogic} />
214
+ <Level2View gameLogic={puzzleState.logic} />
215
215
  {:else if puzzleState.isComplete}
216
216
  <CompleteView
217
- score={puzzleState.gameLogic.score}
217
+ score={puzzleState.logic.score}
218
218
  highestLevel={puzzleState.highestLevel} />
219
219
  {/if}
220
220
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.5.87",
3
+ "version": "0.5.88",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"