@hkdigital/lib-core 0.4.24 → 0.4.26

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.
Files changed (30) hide show
  1. package/dist/logging/internal/adapters/pino.d.ts +7 -3
  2. package/dist/logging/internal/adapters/pino.js +200 -67
  3. package/dist/logging/internal/transports/pretty-transport.d.ts +17 -0
  4. package/dist/logging/internal/transports/pretty-transport.js +104 -0
  5. package/dist/logging/internal/transports/test-transport.d.ts +19 -0
  6. package/dist/logging/internal/transports/test-transport.js +79 -0
  7. package/dist/network/loaders/audio/AudioScene.svelte.d.ts +19 -10
  8. package/dist/network/loaders/audio/AudioScene.svelte.js +50 -75
  9. package/dist/network/loaders/image/ImageScene.svelte.d.ts +13 -13
  10. package/dist/network/loaders/image/ImageScene.svelte.js +56 -83
  11. package/dist/network/states/NetworkLoader.svelte.d.ts +6 -0
  12. package/dist/network/states/NetworkLoader.svelte.js +15 -6
  13. package/dist/services/service-base/ServiceBase.d.ts +12 -8
  14. package/dist/services/service-base/ServiceBase.js +8 -6
  15. package/dist/state/machines/finite-state-machine/FiniteStateMachine.svelte.d.ts +5 -9
  16. package/dist/state/machines/finite-state-machine/FiniteStateMachine.svelte.js +62 -32
  17. package/dist/state/machines/finite-state-machine/README.md +48 -46
  18. package/dist/state/machines/finite-state-machine/constants.d.ts +13 -0
  19. package/dist/state/machines/finite-state-machine/constants.js +15 -0
  20. package/dist/state/machines/finite-state-machine/index.d.ts +1 -0
  21. package/dist/state/machines/finite-state-machine/index.js +1 -0
  22. package/dist/state/machines/finite-state-machine/typedef.d.ts +3 -3
  23. package/dist/state/machines/finite-state-machine/typedef.js +21 -15
  24. package/dist/state/machines/loading-state-machine/LoadingStateMachine.svelte.d.ts +12 -0
  25. package/dist/state/machines/loading-state-machine/LoadingStateMachine.svelte.js +27 -2
  26. package/dist/state/machines/loading-state-machine/README.md +89 -41
  27. package/dist/state/machines/loading-state-machine/constants.d.ts +2 -0
  28. package/dist/state/machines/loading-state-machine/constants.js +2 -0
  29. package/package.json +1 -1
  30. package/dist/logging/internal/adapters/pino.js__ +0 -260
@@ -13,6 +13,19 @@ export default class AudioScene {
13
13
  loaded: boolean;
14
14
  muted: boolean;
15
15
  targetGain: number;
16
+ /**
17
+ * Get audio scene loading progress
18
+ */
19
+ get progress(): {
20
+ totalBytesLoaded: number;
21
+ totalSize: number;
22
+ sourcesLoaded: number;
23
+ numberOfSources: number;
24
+ };
25
+ /**
26
+ * Start loading all audio sources
27
+ */
28
+ load(): void;
16
29
  destroy(): void;
17
30
  /**
18
31
  * Add in-memory audio source
@@ -28,16 +41,6 @@ export default class AudioScene {
28
41
  url: string;
29
42
  config?: SourceConfig;
30
43
  }): void;
31
- /**
32
- * Start loading all audio sources
33
- */
34
- load(): void;
35
- /**
36
- * Set an audio context to use
37
- *
38
- * @param {AudioContext} [audioContext]
39
- */
40
- setAudioContext(audioContext?: AudioContext): void;
41
44
  /**
42
45
  * Get a source that can be used to play the audio once
43
46
  *
@@ -46,6 +49,12 @@ export default class AudioScene {
46
49
  * @returns {Promise<AudioBufferSourceNode>}
47
50
  */
48
51
  getSourceNode(label: string): Promise<AudioBufferSourceNode>;
52
+ /**
53
+ * Set an audio context to use
54
+ *
55
+ * @param {AudioContext} [audioContext]
56
+ */
57
+ setAudioContext(audioContext?: AudioContext): void;
49
58
  /**
50
59
  * Set target gain
51
60
  *
@@ -5,10 +5,7 @@ import { LoadingStateMachine } from '../../../state/machines.js';
5
5
  import {
6
6
  STATE_INITIAL,
7
7
  STATE_LOADING,
8
- STATE_UNLOADING,
9
8
  STATE_LOADED,
10
- STATE_CANCELLED,
11
- STATE_ERROR,
12
9
  LOAD,
13
10
  LOADED
14
11
  } from '../../../state/machines.js';
@@ -30,10 +27,9 @@ import AudioLoader from './AudioLoader.svelte.js';
30
27
  export default class AudioScene {
31
28
  #state = new LoadingStateMachine();
32
29
 
33
- // @note this exported state is set by $effect's
30
+ // @note this exported state is set by onenter
34
31
  state = $state(STATE_INITIAL);
35
32
 
36
- // @note this exported state is set by $effect's
37
33
  loaded = $derived.by(() => {
38
34
  return this.state === STATE_LOADED;
39
35
  });
@@ -109,47 +105,33 @@ export default class AudioScene {
109
105
  }
110
106
  });
111
107
 
112
- $effect(() => {
113
- switch (state.current) {
114
- case STATE_LOADING:
115
- {
116
- // console.log('AudioScene:loading');
117
- this.#startLoading();
118
- }
119
- break;
120
-
121
- case STATE_UNLOADING:
122
- {
123
- // console.log('AudioScene:unloading');
124
- // this.#startUnLoading();
125
- }
126
- break;
127
-
128
- case STATE_LOADED:
129
- {
130
- // console.log('AudioScene:loaded');
131
-
132
- // tODO
133
- // this.#abortLoading = null;
134
- }
135
- break;
136
-
137
- case STATE_CANCELLED:
138
- {
139
- // console.log('AudioScene:cancelled');
140
- // TODO
141
- }
142
- break;
143
-
144
- case STATE_ERROR:
145
- {
146
- console.error('AudioScene:error', state.error);
147
- }
148
- break;
149
- } // end switch
108
+ state.onenter = ( currentState ) => {
109
+ // console.log('onenter', currentState );
110
+
111
+ if(currentState === STATE_LOADING )
112
+ {
113
+ // console.log('AudioScene:loading');
114
+ this.#startLoading();
115
+ }
150
116
 
151
117
  this.state = state.current;
152
- });
118
+ };
119
+ }
120
+
121
+ /* ==== Common loader interface */
122
+
123
+ /**
124
+ * Get audio scene loading progress
125
+ */
126
+ get progress() {
127
+ return this.#progress;
128
+ }
129
+
130
+ /**
131
+ * Start loading all audio sources
132
+ */
133
+ load() {
134
+ this.#state.send(LOAD);
153
135
  }
154
136
 
155
137
  destroy() {
@@ -157,6 +139,8 @@ export default class AudioScene {
157
139
  // TODO: Unload AUdioLoaders?
158
140
  }
159
141
 
142
+ /* ==== Source definitions */
143
+
160
144
  /**
161
145
  * Add in-memory audio source
162
146
  * - Uses an AudioLoader instance to load audio data from network
@@ -175,36 +159,7 @@ export default class AudioScene {
175
159
  this.#memorySources.push({ label, audioLoader, config });
176
160
  }
177
161
 
178
- /**
179
- * Start loading all audio sources
180
- */
181
- load() {
182
- this.#state.send(LOAD);
183
-
184
- // FIXME: in unit test when moved to startloading it hangs!
185
-
186
- for (const { audioLoader } of this.#memorySources) {
187
- audioLoader.load();
188
- }
189
- }
190
-
191
- /**
192
- * Set an audio context to use
193
- *
194
- * @param {AudioContext} [audioContext]
195
- */
196
- setAudioContext( audioContext ) {
197
- this.#audioContext = audioContext;
198
- }
199
-
200
- async #startLoading() {
201
- // console.log('#startLoading');
202
-
203
- // FIXME: in unit test when moved to startloading it hangs!
204
- // for (const { audioLoader } of this.#memorySources) {
205
- // audioLoader.load();
206
- // }
207
- }
162
+ /* ==== Resource access */
208
163
 
209
164
  /**
210
165
  * Get a source that can be used to play the audio once
@@ -240,6 +195,25 @@ export default class AudioScene {
240
195
  return sourceNode;
241
196
  }
242
197
 
198
+ /**
199
+ * Set an audio context to use
200
+ *
201
+ * @param {AudioContext} [audioContext]
202
+ */
203
+ setAudioContext( audioContext ) {
204
+ this.#audioContext = audioContext;
205
+ }
206
+
207
+ async #startLoading() {
208
+ // console.log('#startLoading');
209
+
210
+ for (const { audioLoader } of this.#memorySources) {
211
+ audioLoader.load();
212
+ }
213
+ }
214
+
215
+ /* ==== Audio specific */
216
+
243
217
  /**
244
218
  * Set target gain
245
219
  *
@@ -281,6 +255,7 @@ export default class AudioScene {
281
255
  this.setTargetGain(this.#unmutedTargetGain);
282
256
  }
283
257
 
258
+ /* ==== Internals */
284
259
 
285
260
  #getGainNode()
286
261
  {
@@ -322,4 +297,4 @@ export default class AudioScene {
322
297
 
323
298
  throw new Error(`Source [${label}] has not been defined`);
324
299
  }
325
- }
300
+ } // end class
@@ -10,6 +10,19 @@
10
10
  export default class ImageScene {
11
11
  state: string;
12
12
  loaded: boolean;
13
+ /**
14
+ * Get image scene loading progress
15
+ */
16
+ get progress(): {
17
+ totalBytesLoaded: number;
18
+ totalSize: number;
19
+ sourcesLoaded: number;
20
+ numberOfSources: number;
21
+ };
22
+ /**
23
+ * Start loading all image sources
24
+ */
25
+ load(): void;
13
26
  destroy(): void;
14
27
  /**
15
28
  * Add image source
@@ -23,19 +36,6 @@ export default class ImageScene {
23
36
  label: string;
24
37
  imageSource: import("../../../config/typedef.js").ImageSource;
25
38
  }): void;
26
- /**
27
- * Start loading all image sources
28
- */
29
- load(): void;
30
- /**
31
- * Get image scene loading progress
32
- */
33
- get progress(): {
34
- totalBytesLoaded: number;
35
- totalSize: number;
36
- sourcesLoaded: number;
37
- numberOfSources: number;
38
- };
39
39
  /**
40
40
  * Get an image loader
41
41
  *
@@ -7,10 +7,7 @@ import { LoadingStateMachine } from '../../../state/machines.js';
7
7
  import {
8
8
  STATE_INITIAL,
9
9
  STATE_LOADING,
10
- STATE_UNLOADING,
11
10
  STATE_LOADED,
12
- STATE_CANCELLED,
13
- STATE_ERROR,
14
11
  LOAD,
15
12
  LOADED
16
13
  } from '../../../state/machines.js';
@@ -31,10 +28,9 @@ import ImageLoader from './ImageLoader.svelte.js';
31
28
  export default class ImageScene {
32
29
  #state = new LoadingStateMachine();
33
30
 
34
- // @note this exported state is set by $effect's
31
+ // @note this exported state is set by onenter
35
32
  state = $state(STATE_INITIAL);
36
33
 
37
- // @note this exported state is set by $effect's
38
34
  loaded = $derived.by(() => {
39
35
  return this.state === STATE_LOADED;
40
36
  });
@@ -92,55 +88,42 @@ export default class ImageScene {
92
88
  }
93
89
  } );
94
90
 
95
- state.onenter = ( state ) => {
96
- // console.log('onenter', state );
97
-
98
- switch (state) {
99
- case STATE_LOADING:
100
- {
101
- // console.log('ImageScene:loading');
102
- this.#startLoading();
103
- }
104
- break;
105
-
106
- case STATE_UNLOADING:
107
- {
108
- // console.log('ImageScene:unloading');
109
- // this.#startUnLoading();
110
- }
111
- break;
112
-
113
- case STATE_LOADED:
114
- {
115
- // console.log('ImageScene:loaded');
116
- // TODO
117
- // this.#abortLoading = null;
118
- }
119
- break;
120
-
121
- case STATE_CANCELLED:
122
- {
123
- // console.log('ImageScene:cancelled');
124
- // TODO
125
- }
126
- break;
127
-
128
- case STATE_ERROR:
129
- {
130
- console.log('ImageScene:error', state);
131
- }
132
- break;
133
- } // end switch
134
-
135
- this.state = state;
91
+ state.onenter = ( currentState ) => {
92
+ // console.log('onenter', currentState );
93
+
94
+ if(currentState === STATE_LOADING )
95
+ {
96
+ // console.log('ImageScene:loading');
97
+ this.#startLoading();
98
+ }
99
+
100
+ this.state = currentState;
136
101
  };
137
102
  }
138
103
 
104
+ /* ==== Common loader interface */
105
+
106
+ /**
107
+ * Get image scene loading progress
108
+ */
109
+ get progress() {
110
+ return this.#progress;
111
+ }
112
+
113
+ /**
114
+ * Start loading all image sources
115
+ */
116
+ load() {
117
+ this.#state.send(LOAD);
118
+ }
119
+
139
120
  destroy() {
140
121
  // TODO: disconnect all image sources?
141
122
  // TODO: Unload ImageLoaders?
142
123
  }
143
124
 
125
+ /* ==== Source definitions */
126
+
144
127
  /**
145
128
  * Add image source
146
129
  * - Uses an ImageLoader instance to load image data from network
@@ -159,42 +142,7 @@ export default class ImageScene {
159
142
  this.#imageSources.push({ label, imageLoader });
160
143
  }
161
144
 
162
- /**
163
- * Start loading all image sources
164
- */
165
- load() {
166
- this.#state.send(LOAD);
167
- }
168
-
169
- async #startLoading() {
170
- for (const { imageLoader } of this.#imageSources) {
171
- imageLoader.load();
172
- }
173
- }
174
-
175
- /**
176
- * Get Image source
177
- *
178
- * @param {string} label
179
- *
180
- * @returns {ImageSceneSource}
181
- */
182
- #getImageSceneSource(label) {
183
- for (const source of this.#imageSources) {
184
- if (label === source.label) {
185
- return source;
186
- }
187
- }
188
-
189
- throw new Error(`Source [${label}] has not been defined`);
190
- }
191
-
192
- /**
193
- * Get image scene loading progress
194
- */
195
- get progress() {
196
- return this.#progress;
197
- }
145
+ /* ==== Resource access */
198
146
 
199
147
  /**
200
148
  * Get an image loader
@@ -236,4 +184,29 @@ export default class ImageScene {
236
184
 
237
185
  return source.imageLoader.getObjectURL();
238
186
  }
239
- }
187
+
188
+ async #startLoading() {
189
+ for (const { imageLoader } of this.#imageSources) {
190
+ imageLoader.load();
191
+ }
192
+ }
193
+
194
+ /* ==== Internals */
195
+
196
+ /**
197
+ * Get Image source
198
+ *
199
+ * @param {string} label
200
+ *
201
+ * @returns {ImageSceneSource}
202
+ */
203
+ #getImageSceneSource(label) {
204
+ for (const source of this.#imageSources) {
205
+ if (label === source.label) {
206
+ return source;
207
+ }
208
+ }
209
+
210
+ throw new Error(`Source [${label}] has not been defined`);
211
+ }
212
+ } // end class
@@ -42,6 +42,12 @@ export default class NetworkLoader {
42
42
  * Unoad all network data
43
43
  */
44
44
  unload(): void;
45
+ /**
46
+ * Abort the current loading operation
47
+ * - Only works when in STATE_LOADING
48
+ * - Aborts network requests and transitions to STATE_CANCELLED
49
+ */
50
+ doAbort(): void;
45
51
  /**
46
52
  * Get network data size in bytes
47
53
  * - Info comes from the content length response header
@@ -13,7 +13,8 @@ import {
13
13
  ERROR,
14
14
  LOADED,
15
15
  UNLOAD,
16
- INITIAL
16
+ INITIAL,
17
+ CANCEL
17
18
  } from '../../state/machines.js';
18
19
 
19
20
  import * as expect from '../../util/expect.js';
@@ -89,10 +90,6 @@ export default class NetworkLoader {
89
90
  const state = this._state;
90
91
  // const progress = this.progress;
91
92
 
92
- //
93
- // ISSUE: $effect is not triggered by this._state changes,
94
- // using onenter instead
95
- //
96
93
  this._state.onenter = () => {
97
94
  switch (state.current) {
98
95
  case STATE_LOADING:
@@ -129,7 +126,10 @@ export default class NetworkLoader {
129
126
  case STATE_CANCELLED:
130
127
  {
131
128
  // console.log('NetworkLoader:cancelled');
132
- // TODO
129
+ if (this._abortLoading) {
130
+ this._abortLoading();
131
+ this._abortLoading = null;
132
+ }
133
133
  }
134
134
  break;
135
135
 
@@ -157,6 +157,15 @@ export default class NetworkLoader {
157
157
  this._state.send(UNLOAD);
158
158
  }
159
159
 
160
+ /**
161
+ * Abort the current loading operation
162
+ * - Only works when in STATE_LOADING
163
+ * - Aborts network requests and transitions to STATE_CANCELLED
164
+ */
165
+ doAbort() {
166
+ this._state.send(CANCEL);
167
+ }
168
+
160
169
  /**
161
170
  * Get network data size in bytes
162
171
  * - Info comes from the content length response header
@@ -156,36 +156,40 @@ export class ServiceBase extends EventEmitter {
156
156
  /**
157
157
  * Set the service state and emit event
158
158
  *
159
- * @private
159
+ * @protected
160
+ *
160
161
  * @param {ServiceState} newState - New state value
161
162
  * @emits {StateChangeEvent} EVENT_STATE_CHANGED
162
163
  */
163
- private _setState;
164
+ protected _setState(newState: ServiceState): void;
164
165
  /**
165
166
  * Set the service target state and emit event
166
167
  *
167
- * @private
168
+ * @protected
169
+ *
168
170
  * @param {ServiceState} newTargetState - New target state value
169
171
  * @emits {TargetStateChangeEvent} EVENT_TARGET_STATE_CHANGED
170
172
  */
171
- private _setTargetState;
173
+ protected _setTargetState(newTargetState: ServiceState): void;
172
174
  /**
173
175
  * Set the health status and emit event if changed
174
176
  *
175
- * @private
177
+ * @protected
178
+ *
176
179
  * @param {boolean} healthy - New health status
177
180
  * @emits {HealthChangeEvent} EVENT_HEALTH_CHANGED
178
181
  */
179
- private _setHealthy;
182
+ protected _setHealthy(healthy: boolean): void;
180
183
  /**
181
184
  * Set error state and emit error event
182
185
  *
183
- * @private
186
+ * @protected
187
+ *
184
188
  * @param {string} operation - Operation that failed
185
189
  * @param {Error} error - Error that occurred
186
190
  * @emits {ServiceErrorEvent} EVENT_ERROR
187
191
  */
188
- private _setError;
192
+ protected _setError(operation: string, error: Error): void;
189
193
  #private;
190
194
  }
191
195
  export default ServiceBase;
@@ -447,12 +447,11 @@ export class ServiceBase extends EventEmitter {
447
447
  return {};
448
448
  }
449
449
 
450
- // Private methods
451
-
452
450
  /**
453
451
  * Set the service state and emit event
454
452
  *
455
- * @private
453
+ * @protected
454
+ *
456
455
  * @param {ServiceState} newState - New state value
457
456
  * @emits {StateChangeEvent} EVENT_STATE_CHANGED
458
457
  */
@@ -473,7 +472,8 @@ export class ServiceBase extends EventEmitter {
473
472
  /**
474
473
  * Set the service target state and emit event
475
474
  *
476
- * @private
475
+ * @protected
476
+ *
477
477
  * @param {ServiceState} newTargetState - New target state value
478
478
  * @emits {TargetStateChangeEvent} EVENT_TARGET_STATE_CHANGED
479
479
  */
@@ -493,7 +493,8 @@ export class ServiceBase extends EventEmitter {
493
493
  /**
494
494
  * Set the health status and emit event if changed
495
495
  *
496
- * @private
496
+ * @protected
497
+ *
497
498
  * @param {boolean} healthy - New health status
498
499
  * @emits {HealthChangeEvent} EVENT_HEALTH_CHANGED
499
500
  */
@@ -515,7 +516,8 @@ export class ServiceBase extends EventEmitter {
515
516
  /**
516
517
  * Set error state and emit error event
517
518
  *
518
- * @private
519
+ * @protected
520
+ *
519
521
  * @param {string} operation - Operation that failed
520
522
  * @param {Error} error - Error that occurred
521
523
  * @emits {ServiceErrorEvent} EVENT_ERROR
@@ -1,9 +1,4 @@
1
- /**
2
- * Initial code borrowed from:
3
- *
4
- * @see {@link https://runed.dev/docs/utilities/finite-state-machine}
5
- */
6
- /** @typedef {import('./typedef.js').StateTransitionMetadata} StateTransitionMetadata */
1
+ /** @typedef {import('./typedef.js').TransitionData} TransitionData */
7
2
  /** @typedef {import('./typedef.js').OnEnterCallback} OnEnterCallback */
8
3
  /** @typedef {import('./typedef.js').OnExitCallback} OnExitCallback */
9
4
  /**
@@ -13,9 +8,9 @@
13
8
  */
14
9
  export function isLifecycleFnMeta(meta: any): boolean;
15
10
  /**
16
- * Defines a Finite State Machine
11
+ * Defines a Finite State Machine that extends EventEmitter
17
12
  */
18
- export default class FiniteStateMachine {
13
+ export default class FiniteStateMachine extends EventEmitter {
19
14
  /**
20
15
  * Constructor
21
16
  *
@@ -55,6 +50,7 @@ export default class FiniteStateMachine {
55
50
  get current(): any;
56
51
  #private;
57
52
  }
58
- export type StateTransitionMetadata = import("./typedef.js").StateTransitionMetadata;
53
+ export type TransitionData = import("./typedef.js").TransitionData;
59
54
  export type OnEnterCallback = import("./typedef.js").OnEnterCallback;
60
55
  export type OnExitCallback = import("./typedef.js").OnExitCallback;
56
+ import EventEmitter from '../../../generic/events/classes/EventEmitter.js';