@hkdigital/lib-core 0.4.22 → 0.4.24

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/auth/jwt/util.js +35 -41
  2. package/dist/network/loaders/audio/AudioScene.svelte.js +2 -2
  3. package/dist/network/loaders/image/ImageScene.svelte.js +18 -28
  4. package/dist/network/states/NetworkLoader.svelte.d.ts +1 -1
  5. package/dist/network/states/NetworkLoader.svelte.js +2 -2
  6. package/dist/services/README.md +23 -0
  7. package/dist/state/classes.d.ts +0 -2
  8. package/dist/state/classes.js +0 -2
  9. package/dist/state/{classes → machines}/finite-state-machine/FiniteStateMachine.svelte.d.ts +10 -0
  10. package/dist/state/{classes → machines}/finite-state-machine/FiniteStateMachine.svelte.js +19 -1
  11. package/dist/state/machines/finite-state-machine/README.md +545 -0
  12. package/dist/state/{classes → machines}/finite-state-machine/index.d.ts +1 -1
  13. package/dist/state/{classes → machines}/finite-state-machine/index.js +1 -1
  14. package/dist/state/machines/finite-state-machine/typedef.d.ts +29 -0
  15. package/dist/state/machines/finite-state-machine/typedef.js +28 -0
  16. package/dist/state/{classes → machines}/loading-state-machine/LoadingStateMachine.svelte.d.ts +0 -2
  17. package/dist/state/{classes → machines}/loading-state-machine/LoadingStateMachine.svelte.js +7 -27
  18. package/dist/state/machines/loading-state-machine/README.md +544 -0
  19. package/dist/state/machines/typedef.d.ts +1 -0
  20. package/dist/state/machines/typedef.js +1 -0
  21. package/dist/state/machines.d.ts +2 -0
  22. package/dist/state/machines.js +2 -0
  23. package/dist/state/typedef.d.ts +1 -0
  24. package/dist/state/typedef.js +1 -0
  25. package/dist/ui/components/game-box/README.md +245 -0
  26. package/package.json +1 -1
  27. /package/dist/state/{classes → machines}/loading-state-machine/constants.d.ts +0 -0
  28. /package/dist/state/{classes → machines}/loading-state-machine/constants.js +0 -0
  29. /package/dist/state/{classes → machines}/loading-state-machine/index.d.ts +0 -0
  30. /package/dist/state/{classes → machines}/loading-state-machine/index.js +0 -0
@@ -2,24 +2,32 @@
2
2
  * JWT utility functions
3
3
  *
4
4
  * @description
5
- * This module provides utility functions for JWT operations including
5
+ * This module provides utility functions for JWT operations including
6
6
  * sign, verify and error casting.
7
7
  */
8
8
 
9
+ // import jwt from 'jsonwebtoken';
10
+
11
+ // import {
12
+ // TokenExpiredError as JwtTokenExpiredError,
13
+ // JsonWebTokenError as JwtJsonWebTokenError,
14
+ // NotBeforeError as JwtNotBeforeError
15
+ // } from 'jsonwebtoken';
16
+
9
17
  import jwt from 'jsonwebtoken';
10
18
 
11
- import {
12
- TokenExpiredError as JwtTokenExpiredError,
13
- JsonWebTokenError as JwtJsonWebTokenError,
14
- NotBeforeError as JwtNotBeforeError
15
- } from 'jsonwebtoken';
19
+ const {
20
+ TokenExpiredError: JwtTokenExpiredError,
21
+ JsonWebTokenError: JwtJsonWebTokenError,
22
+ NotBeforeError: JwtNotBeforeError
23
+ } = jwt;
16
24
 
17
25
  import * as expect from '../../util/expect.js';
18
26
 
19
27
  import {
20
28
  JWT_DEFAULT_EXPIRES_IN,
21
29
  DEFAULT_ALGORITHM,
22
- VERIFY_OPTIONS
30
+ VERIFY_OPTIONS
23
31
  } from './constants.js';
24
32
 
25
33
  import {
@@ -54,38 +62,28 @@ import {
54
62
  *
55
63
  * @returns {string} JsonWebToken
56
64
  */
57
- export function sign(
58
- claims,
59
- secretOrPrivateKey,
60
- options={} )
61
- {
62
- expect.object( claims );
63
- expect.defined( secretOrPrivateKey );
64
-
65
- if( options )
66
- {
67
- expect.object( options );
68
- }
69
- else {
65
+ export function sign(claims, secretOrPrivateKey, options = {}) {
66
+ expect.object(claims);
67
+ expect.defined(secretOrPrivateKey);
68
+
69
+ if (options) {
70
+ expect.object(options);
71
+ } else {
70
72
  options = {};
71
73
  }
72
74
 
73
- if( !('algorithm' in options) )
74
- {
75
+ if (!('algorithm' in options)) {
75
76
  options.algorithm = DEFAULT_ALGORITHM;
76
77
  }
77
78
 
78
- if( !('expiresIn' in options) )
79
- {
79
+ if (!('expiresIn' in options)) {
80
80
  options.expiresIn = JWT_DEFAULT_EXPIRES_IN;
81
- }
82
- else if( !options.expiresIn )
83
- {
81
+ } else if (!options.expiresIn) {
84
82
  delete options.expiresIn;
85
83
  }
86
84
 
87
85
  // @ts-ignore
88
- return jwt.sign( claims, secretOrPrivateKey, options );
86
+ return jwt.sign(claims, secretOrPrivateKey, options);
89
87
  }
90
88
 
91
89
  /**
@@ -99,24 +97,20 @@ export function sign(
99
97
  *
100
98
  * @returns {import('./typedef.js').JwtPayload} claims - The decoded JWT payload
101
99
  */
102
- export function verify( token, secretOrPrivateKey, options=VERIFY_OPTIONS )
103
- {
104
- expect.notEmptyString( token );
105
- expect.defined( secretOrPrivateKey );
100
+ export function verify(token, secretOrPrivateKey, options = VERIFY_OPTIONS) {
101
+ expect.notEmptyString(token);
102
+ expect.defined(secretOrPrivateKey);
106
103
 
107
- if( !('algorithms' in options) )
108
- {
104
+ if (!('algorithms' in options)) {
109
105
  options.algorithms = VERIFY_OPTIONS.algorithms;
110
106
  }
111
107
 
112
108
  try {
113
109
  // @ts-ignore
114
- const decoded = jwt.verify( token, secretOrPrivateKey, options );
110
+ const decoded = jwt.verify(token, secretOrPrivateKey, options);
115
111
 
116
112
  return decoded;
117
- }
118
- catch( e )
119
- {
113
+ } catch (e) {
120
114
  //
121
115
  // Cast internal jsonwebtoken errors to Error types defined in this lib
122
116
  //
@@ -135,18 +129,18 @@ export function castJwtError(error) {
135
129
  if (error instanceof JwtTokenExpiredError) {
136
130
  return new TokenExpiredError(error.message, error.expiredAt, error);
137
131
  }
138
-
132
+
139
133
  if (error instanceof JwtNotBeforeError) {
140
134
  return new NotBeforeError(error.message, error.date, error);
141
135
  }
142
-
136
+
143
137
  if (error instanceof JwtJsonWebTokenError) {
144
138
  if (error.message === 'invalid signature') {
145
139
  return new InvalidSignatureError(error.message, error, error);
146
140
  }
147
141
  return new JsonWebTokenError(error.message, error, error);
148
142
  }
149
-
143
+
150
144
  // Return original error if not a known JWT error
151
145
  return error;
152
146
  }
@@ -1,6 +1,6 @@
1
1
  import * as expect from '../../../util/expect.js';
2
2
 
3
- import { LoadingStateMachine } from '../../../state/classes.js';
3
+ import { LoadingStateMachine } from '../../../state/machines.js';
4
4
 
5
5
  import {
6
6
  STATE_INITIAL,
@@ -11,7 +11,7 @@ import {
11
11
  STATE_ERROR,
12
12
  LOAD,
13
13
  LOADED
14
- } from '../../../state/classes/loading-state-machine/constants.js';
14
+ } from '../../../state/machines.js';
15
15
 
16
16
  import AudioLoader from './AudioLoader.svelte.js';
17
17
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import * as expect from '../../../util/expect.js';
4
4
 
5
- import { LoadingStateMachine } from '../../../state/classes.js';
5
+ import { LoadingStateMachine } from '../../../state/machines.js';
6
6
 
7
7
  import {
8
8
  STATE_INITIAL,
@@ -13,7 +13,7 @@ import {
13
13
  STATE_ERROR,
14
14
  LOAD,
15
15
  LOADED
16
- } from '../../../state/classes/loading-state-machine/constants.js';
16
+ } from '../../../state/machines.js';
17
17
 
18
18
  import ImageLoader from './ImageLoader.svelte.js';
19
19
 
@@ -74,30 +74,28 @@ export default class ImageScene {
74
74
  };
75
75
  });
76
76
 
77
+ #sourcesLoaded = $derived( this.#progress.sourcesLoaded );
78
+ #numberOfSources = $derived( this.#progress.numberOfSources );
79
+
77
80
  /**
78
81
  * Construct ImageScene
79
82
  */
80
83
  constructor() {
81
84
  const state = this.#state;
82
85
 
83
- $effect(() => {
86
+ $effect( () => {
84
87
  if (state.current === STATE_LOADING) {
85
- // console.log(
86
- // 'progress',
87
- // JSON.stringify($state.snapshot(this.#progress))
88
- // );
89
-
90
- const { sourcesLoaded, numberOfSources } = this.#progress;
91
-
92
- if (sourcesLoaded === numberOfSources) {
93
- // console.log(`All [${numberOfSources}] sources loaded`);
88
+ if (this.#sourcesLoaded === this.#numberOfSources) {
89
+ // console.log(`All [${this.#numberOfSources}] sources loaded`);
94
90
  this.#state.send(LOADED);
95
91
  }
96
92
  }
97
- });
93
+ } );
98
94
 
99
- $effect(() => {
100
- switch (state.current) {
95
+ state.onenter = ( state ) => {
96
+ // console.log('onenter', state );
97
+
98
+ switch (state) {
101
99
  case STATE_LOADING:
102
100
  {
103
101
  // console.log('ImageScene:loading');
@@ -129,13 +127,13 @@ export default class ImageScene {
129
127
 
130
128
  case STATE_ERROR:
131
129
  {
132
- console.log('ImageScene:error', state.error);
130
+ console.log('ImageScene:error', state);
133
131
  }
134
132
  break;
135
133
  } // end switch
136
134
 
137
- this.state = state.current;
138
- });
135
+ this.state = state;
136
+ };
139
137
  }
140
138
 
141
139
  destroy() {
@@ -166,22 +164,14 @@ export default class ImageScene {
166
164
  */
167
165
  load() {
168
166
  this.#state.send(LOAD);
167
+ }
169
168
 
170
- // FIXME: in unit test when moved to startloading it hangs!
171
-
169
+ async #startLoading() {
172
170
  for (const { imageLoader } of this.#imageSources) {
173
171
  imageLoader.load();
174
172
  }
175
173
  }
176
174
 
177
- async #startLoading() {
178
- // console.log('#startLoading');
179
- // FIXME: in unit test when moved to startloading it hangs!
180
- // for (const { audioLoader } of this.#memorySources) {
181
- // audioLoader.load();
182
- // }
183
- }
184
-
185
175
  /**
186
176
  * Get Image source
187
177
  *
@@ -88,4 +88,4 @@ export default class NetworkLoader {
88
88
  getObjectURL(): string;
89
89
  #private;
90
90
  }
91
- import { LoadingStateMachine } from '../../state/classes.js';
91
+ import { LoadingStateMachine } from '../../state/machines.js';
@@ -1,6 +1,6 @@
1
1
  import { CONTENT_TYPE } from '../../constants/http.js';
2
2
 
3
- import { LoadingStateMachine } from '../../state/classes.js';
3
+ import { LoadingStateMachine } from '../../state/machines.js';
4
4
 
5
5
  import {
6
6
  STATE_INITIAL,
@@ -14,7 +14,7 @@ import {
14
14
  LOADED,
15
15
  UNLOAD,
16
16
  INITIAL
17
- } from '../../state/classes/loading-state-machine/constants.js';
17
+ } from '../../state/machines.js';
18
18
 
19
19
  import * as expect from '../../util/expect.js';
20
20
 
@@ -259,6 +259,29 @@ manager.on(SERVICE_ERROR, async ({ service, error }) => {
259
259
  await manager.recoverService('database');
260
260
  ```
261
261
 
262
+ ### Log Event Forwarding
263
+
264
+ Forward all service log events to a centralised logger:
265
+
266
+ ```javascript
267
+ import { ServiceManager, SERVICE_LOG } from '$lib/services/index.js';
268
+ import { createServerLogger } from '$lib/logging/index.js';
269
+
270
+ const manager = new ServiceManager();
271
+ const logger = createServerLogger('SystemLogger');
272
+
273
+ // Listen to all log events and forward them to the logger
274
+ manager.on(SERVICE_LOG, (logEvent) => {
275
+ logger.logFromEvent('manager:service:log', logEvent);
276
+ });
277
+
278
+ // Register services
279
+ manager.register('database', DatabaseService, { ... });
280
+ manager.register('auth', AuthService, { ... });
281
+
282
+ await manager.startAll();
283
+ ```
284
+
262
285
  ## Plugins
263
286
 
264
287
  ServiceManager supports plugins e.g. to resolve service configurations dynamically.
@@ -1,3 +1 @@
1
- export { default as FiniteStateMachine } from "./classes/finite-state-machine/FiniteStateMachine.svelte.js";
2
- export { default as LoadingStateMachine } from "./classes/loading-state-machine/LoadingStateMachine.svelte.js";
3
1
  export { default as SubscribersCount } from "./classes/subscribers-count/SubscribersCount.js";
@@ -1,3 +1 @@
1
- export { default as FiniteStateMachine } from './classes/finite-state-machine/FiniteStateMachine.svelte.js';
2
- export { default as LoadingStateMachine } from './classes/loading-state-machine/LoadingStateMachine.svelte.js';
3
1
  export { default as SubscribersCount } from './classes/subscribers-count/SubscribersCount.js';
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * @see {@link https://runed.dev/docs/utilities/finite-state-machine}
5
5
  */
6
+ /** @typedef {import('./typedef.js').StateTransitionMetadata} StateTransitionMetadata */
7
+ /** @typedef {import('./typedef.js').OnEnterCallback} OnEnterCallback */
8
+ /** @typedef {import('./typedef.js').OnExitCallback} OnExitCallback */
6
9
  /**
7
10
  * Check if the value is valid meta data
8
11
  *
@@ -29,6 +32,10 @@ export default class FiniteStateMachine {
29
32
  [key: string]: string | ((...args: any[]) => void);
30
33
  };
31
34
  };
35
+ /** @type {OnEnterCallback | null} */
36
+ onenter: OnEnterCallback | null;
37
+ /** @type {OnExitCallback | null} */
38
+ onexit: OnExitCallback | null;
32
39
  /**
33
40
  * Triggers a new event and returns the new state.
34
41
  *
@@ -48,3 +55,6 @@ export default class FiniteStateMachine {
48
55
  get current(): any;
49
56
  #private;
50
57
  }
58
+ export type StateTransitionMetadata = import("./typedef.js").StateTransitionMetadata;
59
+ export type OnEnterCallback = import("./typedef.js").OnEnterCallback;
60
+ export type OnExitCallback = import("./typedef.js").OnExitCallback;
@@ -4,6 +4,10 @@
4
4
  * @see {@link https://runed.dev/docs/utilities/finite-state-machine}
5
5
  */
6
6
 
7
+ /** @typedef {import('./typedef.js').StateTransitionMetadata} StateTransitionMetadata */
8
+ /** @typedef {import('./typedef.js').OnEnterCallback} OnEnterCallback */
9
+ /** @typedef {import('./typedef.js').OnExitCallback} OnExitCallback */
10
+
7
11
  /**
8
12
  * Check if the value is valid meta data
9
13
  *
@@ -28,6 +32,12 @@ export default class FiniteStateMachine {
28
32
  states;
29
33
  #timeout = {};
30
34
 
35
+ /** @type {OnEnterCallback | null} */
36
+ onenter = null;
37
+
38
+ /** @type {OnExitCallback | null} */
39
+ onexit = null;
40
+
31
41
  /**
32
42
  * Constructor
33
43
  *
@@ -55,17 +65,25 @@ export default class FiniteStateMachine {
55
65
  * @param {any[]} [args]
56
66
  */
57
67
  #transition(newState, event, args) {
68
+ /** @type {StateTransitionMetadata} */
58
69
  const metadata = { from: this.#current, to: newState, event, args };
70
+
71
+ // Call onexit callback before leaving current state
72
+ this.onexit?.(this.#current, metadata);
73
+
59
74
  this.#dispatch('_exit', metadata);
60
75
  this.#current = newState;
61
76
  this.#dispatch('_enter', metadata);
77
+
78
+ // Call onenter callback after state change
79
+ this.onenter?.(newState, metadata);
62
80
  }
63
81
 
64
82
  /**
65
83
  * Dispatch an event
66
84
  *
67
85
  * @param {string} event
68
- * @param {any[]} args
86
+ * @param {any} args
69
87
  */
70
88
  #dispatch(event, ...args) {
71
89
  const action =