@hkdigital/lib-sveltekit 0.1.6 → 0.1.7

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 (215) hide show
  1. package/README.md +127 -127
  2. package/dist/classes/data/IterableTree.js +243 -243
  3. package/dist/classes/data/Selector.js +190 -190
  4. package/dist/classes/data/index.js +2 -2
  5. package/dist/classes/index.js +3 -3
  6. package/dist/classes/promise/HkPromise.js +377 -377
  7. package/dist/classes/promise/index.js +1 -1
  8. package/dist/classes/stores/SubscribersCount.js +107 -107
  9. package/dist/classes/stores/index.js +1 -1
  10. package/dist/classes/streams/LogTransformStream.js +19 -19
  11. package/dist/classes/streams/ServerEventsStore.js +110 -110
  12. package/dist/classes/streams/TimeStampSource.js +26 -26
  13. package/dist/classes/streams/index.js +3 -3
  14. package/dist/classes/svelte/audio/AudioLoader.svelte.js +58 -58
  15. package/dist/classes/svelte/audio/AudioScene.svelte.js +282 -282
  16. package/dist/classes/svelte/audio/mocks.js +35 -35
  17. package/dist/classes/svelte/final-state-machine/FiniteStateMachine.svelte.js +133 -133
  18. package/dist/classes/svelte/final-state-machine/index.js +1 -1
  19. package/dist/classes/svelte/image/ImageLoader.svelte.js +47 -47
  20. package/dist/classes/svelte/image/ImageScene.svelte.js +253 -253
  21. package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +152 -152
  22. package/dist/classes/svelte/image/index.js +4 -4
  23. package/dist/classes/svelte/image/mocks.js +35 -35
  24. package/dist/classes/svelte/image/typedef.js +8 -8
  25. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
  26. package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
  27. package/dist/classes/svelte/loading-state-machine/index.js +3 -3
  28. package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +331 -331
  29. package/dist/classes/svelte/network-loader/constants.js +3 -3
  30. package/dist/classes/svelte/network-loader/index.js +3 -3
  31. package/dist/classes/svelte/network-loader/mocks.js +30 -30
  32. package/dist/classes/svelte/network-loader/typedef.js +8 -8
  33. package/dist/components/area/HkArea.svelte +49 -49
  34. package/dist/components/area/HkArea.svelte.d.ts +14 -0
  35. package/dist/components/area/HkGridArea.svelte +77 -77
  36. package/dist/components/area/HkGridArea.svelte.d.ts +22 -0
  37. package/dist/components/area/index.js +2 -2
  38. package/dist/components/boxes/game-box/GameBox.svelte +112 -112
  39. package/dist/components/boxes/game-box/GameBox.svelte.d.ts +15 -0
  40. package/dist/components/boxes/game-box/gamebox.util.js +83 -83
  41. package/dist/components/boxes/index.js +2 -2
  42. package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte +199 -199
  43. package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte.d.ts +22 -0
  44. package/dist/components/buttons/button/Button.svelte +76 -75
  45. package/dist/components/buttons/button/Button.svelte.d.ts +21 -0
  46. package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -0
  47. package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte.d.ts +16 -0
  48. package/dist/components/buttons/button-text/TextButton.svelte +21 -21
  49. package/dist/components/buttons/button-text/TextButton.svelte.d.ts +7 -0
  50. package/dist/components/buttons/index.d.ts +1 -0
  51. package/dist/components/buttons/index.js +3 -2
  52. package/dist/components/hkdev/blocks/TextBlock.svelte +46 -46
  53. package/dist/components/hkdev/blocks/TextBlock.svelte.d.ts +13 -0
  54. package/dist/components/hkdev/buttons/CheckButton.svelte +62 -62
  55. package/dist/components/hkdev/buttons/CheckButton.svelte.d.ts +18 -0
  56. package/dist/components/{icon → icons}/HkIcon.svelte +86 -86
  57. package/dist/components/icons/HkIcon.svelte.d.ts +22 -0
  58. package/dist/components/{icon → icons}/HkTabIcon.svelte +116 -116
  59. package/dist/components/icons/HkTabIcon.svelte.d.ts +40 -0
  60. package/dist/components/icons/SteezeIcon.svelte +96 -0
  61. package/dist/components/icons/SteezeIcon.svelte.d.ts +22 -0
  62. package/dist/components/{icon → icons}/index.d.ts +1 -0
  63. package/dist/components/{icon → icons}/index.js +6 -4
  64. package/dist/components/{icon → icons}/typedef.js +16 -16
  65. package/dist/components/image/ImageBox.svelte +208 -208
  66. package/dist/components/image/ImageBox.svelte.d.ts +19 -0
  67. package/dist/components/image/index.js +5 -5
  68. package/dist/components/image/typedef.js +32 -32
  69. package/dist/components/index.js +2 -2
  70. package/dist/components/inputs/index.js +1 -1
  71. package/dist/components/inputs/text-input/TestTextInput.svelte__ +102 -102
  72. package/dist/components/inputs/text-input/TextInput.svelte +226 -226
  73. package/dist/components/inputs/text-input/TextInput.svelte.d.ts +28 -0
  74. package/dist/components/inputs/text-input/TextInput.svelte___ +83 -83
  75. package/dist/components/inputs/text-input/assets/IconInvalid.svelte +14 -14
  76. package/dist/components/inputs/text-input/assets/IconValid.svelte +12 -12
  77. package/dist/components/layout/HkAppLayout.state.svelte.js +25 -25
  78. package/dist/components/layout/HkAppLayout.svelte +251 -251
  79. package/dist/components/layout/HkAppLayout.svelte.d.ts +11 -0
  80. package/dist/components/layout/HkGridLayers.svelte +82 -82
  81. package/dist/components/layout/HkGridLayers.svelte.d.ts +23 -0
  82. package/dist/components/layout/index.js +9 -9
  83. package/dist/components/panels/index.js +1 -1
  84. package/dist/components/panels/plain-panel/PlainPanel.svelte +33 -33
  85. package/dist/components/panels/plain-panel/PlainPanel.svelte.d.ts +12 -0
  86. package/dist/components/rows/index.js +3 -3
  87. package/dist/components/rows/panel-grid-row/PanelGridRow.svelte +104 -104
  88. package/dist/components/rows/panel-grid-row/PanelGridRow.svelte.d.ts +14 -0
  89. package/dist/components/rows/panel-row-2/PanelRow2.svelte +40 -40
  90. package/dist/components/rows/panel-row-2/PanelRow2.svelte.d.ts +14 -0
  91. package/dist/components/tab-bar/HkTabBar.state.svelte.js +149 -149
  92. package/dist/components/tab-bar/HkTabBar.svelte +74 -74
  93. package/dist/components/tab-bar/HkTabBar.svelte.d.ts +18 -0
  94. package/dist/components/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
  95. package/dist/components/tab-bar/HkTabBarSelector.svelte +49 -49
  96. package/dist/components/tab-bar/HkTabBarSelector.svelte.d.ts +19 -0
  97. package/dist/components/tab-bar/index.js +17 -17
  98. package/dist/components/tab-bar/typedef.d.ts +1 -1
  99. package/dist/components/tab-bar/typedef.js +8 -8
  100. package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte +179 -179
  101. package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte.d.ts +10 -0
  102. package/dist/components/widgets/compare-left-right/index.js +1 -1
  103. package/dist/components/widgets/scale-control/index.js +1 -1
  104. package/dist/config/imagetools-config.js +189 -189
  105. package/dist/config/imagetools.d.ts +71 -71
  106. package/dist/config/typedef.js +8 -8
  107. package/dist/constants/errors/api.js +9 -9
  108. package/dist/constants/errors/generic.js +5 -5
  109. package/dist/constants/errors/index.js +3 -3
  110. package/dist/constants/errors/jwt.js +5 -5
  111. package/dist/constants/http/headers.js +6 -6
  112. package/dist/constants/http/index.js +2 -2
  113. package/dist/constants/http/methods.js +2 -2
  114. package/dist/constants/index.js +3 -3
  115. package/dist/constants/mime/application.js +5 -5
  116. package/dist/constants/mime/audio.js +13 -13
  117. package/dist/constants/mime/image.js +3 -3
  118. package/dist/constants/mime/index.js +4 -4
  119. package/dist/constants/mime/text.js +2 -2
  120. package/dist/constants/regexp/index.js +31 -31
  121. package/dist/constants/regexp/inspiratie.js__ +95 -95
  122. package/dist/constants/regexp/text.js +49 -49
  123. package/dist/constants/regexp/user.js +32 -32
  124. package/dist/constants/regexp/web.js +3 -3
  125. package/dist/constants/state-labels/input-states.js +11 -11
  126. package/dist/constants/state-labels/submit-states.js +4 -4
  127. package/dist/constants/time.js +28 -28
  128. package/dist/css/tw-prose.postcss__ +259 -259
  129. package/dist/css/utilities.postcss +43 -43
  130. package/dist/design/design-config.js +73 -73
  131. package/dist/design/tailwind-theme-extend.d.ts +4 -4
  132. package/dist/design/tailwind-theme-extend.js +160 -151
  133. package/dist/schemas/index.js +1 -1
  134. package/dist/schemas/validate-url.js +180 -180
  135. package/dist/server/index.js +1 -1
  136. package/dist/server/logger.js +94 -94
  137. package/dist/states/index.js +1 -1
  138. package/dist/states/navigation.svelte.js +55 -55
  139. package/dist/stores/index.js +1 -1
  140. package/dist/stores/theme.js +80 -80
  141. package/dist/themes/hkdev/components/blocks/text-block.postcss +40 -40
  142. package/dist/themes/hkdev/components/boxes/game-box.postcss +13 -13
  143. package/dist/themes/hkdev/components/buttons/button-icon-steeze.postcss +22 -0
  144. package/dist/themes/hkdev/components/buttons/button-text.postcss +34 -34
  145. package/dist/themes/hkdev/components/buttons/button.postcss +138 -138
  146. package/dist/themes/hkdev/components/buttons/button.postcss__ +40 -0
  147. package/dist/themes/hkdev/components/buttons/button.postcss___ +91 -0
  148. package/dist/themes/hkdev/components/buttons/skip-button.postcss +8 -8
  149. package/dist/themes/hkdev/components/icons/icon-steeze.postcss +22 -0
  150. package/dist/themes/hkdev/components/inputs/text-input.postcss +108 -108
  151. package/dist/themes/hkdev/components/panels/plain-panel.postcss +46 -46
  152. package/dist/themes/hkdev/components/panels/speech-bubble.postcss +52 -52
  153. package/dist/themes/hkdev/components/rows/panel-grid-row.postcss +7 -7
  154. package/dist/themes/hkdev/components/rows/panel-row-2.postcss +9 -9
  155. package/dist/themes/hkdev/components.postcss +61 -55
  156. package/dist/themes/hkdev/debug.postcss +1 -1
  157. package/dist/themes/hkdev/global/layout.postcss +39 -39
  158. package/dist/themes/hkdev/global/on-colors.postcss +53 -53
  159. package/dist/themes/hkdev/global/text.postcss__ +34 -34
  160. package/dist/themes/hkdev/global/vars.postcss__ +7 -7
  161. package/dist/themes/hkdev/globals.postcss +11 -11
  162. package/dist/themes/hkdev/responsive.postcss +12 -12
  163. package/dist/themes/hkdev/theme-ext.js +15 -15
  164. package/dist/themes/hkdev/theme.js +227 -227
  165. package/dist/themes/index.js +1 -1
  166. package/dist/util/array/index.js +455 -455
  167. package/dist/util/compare/index.js +247 -247
  168. package/dist/util/css/css-vars.js +83 -83
  169. package/dist/util/css/index.js +1 -1
  170. package/dist/util/design-system/components/states.js +22 -22
  171. package/dist/util/design-system/css/clamp.js +66 -66
  172. package/dist/util/design-system/css/root-design-vars.js +100 -100
  173. package/dist/util/design-system/index.js +5 -5
  174. package/dist/util/design-system/layout/scaling.js +97 -97
  175. package/dist/util/design-system/tailwind.js +289 -289
  176. package/dist/util/expect/arrays.js +47 -47
  177. package/dist/util/expect/index.js +259 -259
  178. package/dist/util/expect/primitives.js +55 -55
  179. package/dist/util/expect/url.js +60 -60
  180. package/dist/util/function/index.js +218 -218
  181. package/dist/util/http/errors.js +97 -97
  182. package/dist/util/http/headers.js +45 -45
  183. package/dist/util/http/http-request.js +273 -273
  184. package/dist/util/http/index.js +22 -22
  185. package/dist/util/http/json-request.js +143 -143
  186. package/dist/util/http/mocks.js +65 -65
  187. package/dist/util/http/response.js +228 -228
  188. package/dist/util/http/url.js +52 -52
  189. package/dist/util/image/index.js +86 -86
  190. package/dist/util/index.js +2 -2
  191. package/dist/util/is/index.js +140 -140
  192. package/dist/util/iterate/index.js +234 -234
  193. package/dist/util/object/index.js +1361 -1361
  194. package/dist/util/singleton/index.js +97 -97
  195. package/dist/util/string/index.js +184 -184
  196. package/dist/util/svelte/index.js +2 -2
  197. package/dist/util/svelte/observe/index.js +49 -49
  198. package/dist/util/svelte/state-context/index.js +83 -83
  199. package/dist/util/svelte/wait/index.js +38 -38
  200. package/dist/util/sveltekit/index.js +1 -1
  201. package/dist/util/sveltekit/route-folders/index.js +82 -82
  202. package/dist/util/time/index.js +339 -339
  203. package/dist/valibot/date.js__ +10 -10
  204. package/dist/valibot/index.js +9 -9
  205. package/dist/valibot/url.js +95 -95
  206. package/dist/valibot/user.js +23 -23
  207. package/dist/zod/all.js +33 -33
  208. package/dist/zod/generic.js +11 -11
  209. package/dist/zod/javascript.js +32 -32
  210. package/dist/zod/user.js +16 -16
  211. package/dist/zod/web.js +52 -52
  212. package/package.json +99 -99
  213. package/dist/components/icon/HkIcon.svelte.d.ts +0 -10
  214. package/dist/components/icon/HkTabIcon.svelte.d.ts +0 -19
  215. /package/dist/components/{icon → icons}/typedef.d.ts +0 -0
@@ -1,282 +1,282 @@
1
- import * as expect from '../../../util/expect/index.js';
2
-
3
- import {
4
- LoadingStateMachine,
5
- STATE_INITIAL,
6
- STATE_LOADING,
7
- STATE_UNLOADING,
8
- STATE_LOADED,
9
- STATE_CANCELLED,
10
- STATE_ERROR,
11
- LOAD,
12
- // CANCEL,
13
- ERROR,
14
- LOADED,
15
- UNLOAD,
16
- INITIAL
17
- } from '../loading-state-machine/index.js';
18
-
19
- import AudioLoader from './AudioLoader.svelte.js';
20
-
21
- /**
22
- * @typedef {object} SourceConfig
23
- * // property ...
24
- */
25
-
26
- /**
27
- * @typedef {object} MemorySource
28
- * @property {string} label
29
- * @property {AudioLoader} audioLoader
30
- * @property {SourceConfig} [config]
31
- */
32
-
33
- export default class AudioScene {
34
- #state = new LoadingStateMachine();
35
-
36
- // @note this exported state is set by $effect's
37
- state = $state(STATE_INITIAL);
38
-
39
- // @note this exported state is set by $effect's
40
- loaded = $derived.by(() => {
41
- return this.state === STATE_LOADED;
42
- });
43
-
44
- /** @type {AudioContext|null} */
45
- #audioContext = null;
46
-
47
- /** @type {MemorySource[]} */
48
- #memorySources = $state([]);
49
-
50
- #progress = $derived.by(() => {
51
- // console.log('update progress');
52
-
53
- let totalSize = 0;
54
- let totalBytesLoaded = 0;
55
- let sourcesLoaded = 0;
56
-
57
- const sources = this.#memorySources;
58
- const numberOfSources = sources.length;
59
-
60
- for (let j = 0; j < numberOfSources; j++) {
61
- const source = sources[j];
62
- const { audioLoader } = source;
63
-
64
- const { bytesLoaded, size, loaded } = audioLoader.progress;
65
-
66
- totalSize += size;
67
- totalBytesLoaded += bytesLoaded;
68
-
69
- if (loaded) {
70
- sourcesLoaded++;
71
- }
72
- } // end for
73
-
74
- return {
75
- totalBytesLoaded,
76
- totalSize,
77
- sourcesLoaded,
78
- numberOfSources
79
- };
80
- });
81
-
82
- /**
83
- * Construct AudioScene
84
- *
85
- * @param {object} _
86
- * @param {AudioContext} _.audioContext
87
- */
88
- constructor() {
89
- const state = this.#state;
90
-
91
- $effect(() => {
92
- if (state.current === STATE_LOADING) {
93
- // console.log(
94
- // 'progress',
95
- // JSON.stringify($state.snapshot(this.#progress))
96
- // );
97
-
98
- const { sourcesLoaded, numberOfSources } = this.#progress;
99
-
100
- if (sourcesLoaded === numberOfSources) {
101
- console.log(`All [${numberOfSources}] sources loaded`);
102
- this.#state.send(LOADED);
103
- }
104
- }
105
- });
106
-
107
- $effect(() => {
108
- switch (state.current) {
109
- case STATE_LOADING:
110
- {
111
- console.log('AudioScene:loading');
112
- this.#startLoading();
113
- }
114
- break;
115
-
116
- case STATE_UNLOADING:
117
- {
118
- // console.log('AudioScene:unloading');
119
- // this.#startUnLoading();
120
- }
121
- break;
122
-
123
- case STATE_LOADED:
124
- {
125
- console.log('AudioScene:loaded');
126
-
127
- // tODO
128
- // this.#abortLoading = null;
129
- }
130
- break;
131
-
132
- case STATE_CANCELLED:
133
- {
134
- // console.log('AudioScene:cancelled');
135
- // TODO
136
- }
137
- break;
138
-
139
- case STATE_ERROR:
140
- {
141
- console.log('AudioScene:error', state.error);
142
- }
143
- break;
144
- } // end switch
145
-
146
- this.state = state.current;
147
- });
148
- }
149
-
150
- destroy() {
151
- // TODO: disconnect all audio sources?
152
- // TODO: Unload AUdioLoaders?
153
- }
154
-
155
- /**
156
- * Add in-memory audio source
157
- * - Uses an AudioLoader instance to load audio data from network
158
- *
159
- * @param {object} _
160
- * @param {string} _.label
161
- * @param {string} _.url
162
- * @param {SourceConfig} [_.config]
163
- */
164
- defineMemorySource({ label, url, config }) {
165
- expect.notEmptyString(label);
166
- expect.notEmptyString(url);
167
-
168
- const audioLoader = new AudioLoader({ url });
169
-
170
- this.#memorySources.push({ label, audioLoader, config });
171
- }
172
-
173
- /**
174
- * Start loading all audio sources
175
- *
176
- * @param {AudioContext} audioContext
177
- */
178
- load(audioContext) {
179
- this.#audioContext = audioContext;
180
- // console.log(123);
181
- this.#state.send(LOAD);
182
-
183
- // FIXME: in unit test when moved to startloading it hangs!
184
-
185
- for (const { audioLoader } of this.#memorySources) {
186
- audioLoader.load();
187
- }
188
- }
189
-
190
- async #startLoading() {
191
- console.log('#startLoading');
192
-
193
- // FIXME: in unit test when moved to startloading it hangs!
194
- // for (const { audioLoader } of this.#memorySources) {
195
- // audioLoader.load();
196
- // }
197
- }
198
-
199
- /**
200
- * Get a source that can be used to play the audio once
201
- *
202
- * @param {string} label
203
- */
204
- async getSourceNode(label) {
205
- // @note Gain setup
206
- // https://stackoverflow.com/questions/46203191/should-i-disconnect-nodes-that-cant-be-used-anymore
207
-
208
- const { audioLoader /*, config */ } = this.#getMemorySource(label);
209
-
210
- if (!audioLoader.loaded) {
211
- throw new Error(`Source [${label}] has not been loaded yet`);
212
- }
213
-
214
- const sourceNode = await audioLoader.getAudioBufferSourceNode(
215
- // @ts-ignore
216
- this.#audioContext
217
- );
218
-
219
- // @ts-ignore
220
- sourceNode.connect(this.#audioContext.destination);
221
-
222
- // Clean up
223
- sourceNode.onended = () => {
224
- // console.log(`Source [${label}] ended `);
225
- sourceNode.disconnect();
226
- };
227
-
228
- return sourceNode;
229
- }
230
-
231
- /**
232
- * Get memory source
233
- *
234
- * @param {string} label
235
- *
236
- * @returns {MemorySource}
237
- */
238
- #getMemorySource(label) {
239
- for (const source of this.#memorySources) {
240
- if (label === source.label) {
241
- return source;
242
- }
243
- }
244
-
245
- throw new Error(`Source [${label}] has not been defined`);
246
- }
247
-
248
- // connect
249
- // play
250
-
251
- // source.connect(audioContext.destination);
252
- // source.loop = true;
253
- // source.start();
254
-
255
- // /**
256
- // * Get the source identified by the specified label
257
- // *
258
- // * @param {string} label
259
- // */
260
- // async getBufferSourceNode(label) {
261
- // // expect.notEmptyString( label );
262
-
263
- // for (const source of this.#memorySources) {
264
- // if (label === source.label) {
265
- // if (!source.bufferSourceNode) {
266
- // source.bufferSourceNode =
267
- // await source.AudioLoader.transferToBufferSource(this.#audioContext);
268
- // }
269
-
270
- // return source.bufferSourceNode;
271
- // }
272
- // }
273
- // }
274
-
275
- // async connectSourceToDestination(label) {
276
- // const source = await this.getBufferSourceNode(label);
277
-
278
- // if (source) {
279
- // source.connect(this.#audioContext.destination);
280
- // }
281
- // }
282
- }
1
+ import * as expect from '../../../util/expect/index.js';
2
+
3
+ import {
4
+ LoadingStateMachine,
5
+ STATE_INITIAL,
6
+ STATE_LOADING,
7
+ STATE_UNLOADING,
8
+ STATE_LOADED,
9
+ STATE_CANCELLED,
10
+ STATE_ERROR,
11
+ LOAD,
12
+ // CANCEL,
13
+ ERROR,
14
+ LOADED,
15
+ UNLOAD,
16
+ INITIAL
17
+ } from '../loading-state-machine/index.js';
18
+
19
+ import AudioLoader from './AudioLoader.svelte.js';
20
+
21
+ /**
22
+ * @typedef {object} SourceConfig
23
+ * // property ...
24
+ */
25
+
26
+ /**
27
+ * @typedef {object} MemorySource
28
+ * @property {string} label
29
+ * @property {AudioLoader} audioLoader
30
+ * @property {SourceConfig} [config]
31
+ */
32
+
33
+ export default class AudioScene {
34
+ #state = new LoadingStateMachine();
35
+
36
+ // @note this exported state is set by $effect's
37
+ state = $state(STATE_INITIAL);
38
+
39
+ // @note this exported state is set by $effect's
40
+ loaded = $derived.by(() => {
41
+ return this.state === STATE_LOADED;
42
+ });
43
+
44
+ /** @type {AudioContext|null} */
45
+ #audioContext = null;
46
+
47
+ /** @type {MemorySource[]} */
48
+ #memorySources = $state([]);
49
+
50
+ #progress = $derived.by(() => {
51
+ // console.log('update progress');
52
+
53
+ let totalSize = 0;
54
+ let totalBytesLoaded = 0;
55
+ let sourcesLoaded = 0;
56
+
57
+ const sources = this.#memorySources;
58
+ const numberOfSources = sources.length;
59
+
60
+ for (let j = 0; j < numberOfSources; j++) {
61
+ const source = sources[j];
62
+ const { audioLoader } = source;
63
+
64
+ const { bytesLoaded, size, loaded } = audioLoader.progress;
65
+
66
+ totalSize += size;
67
+ totalBytesLoaded += bytesLoaded;
68
+
69
+ if (loaded) {
70
+ sourcesLoaded++;
71
+ }
72
+ } // end for
73
+
74
+ return {
75
+ totalBytesLoaded,
76
+ totalSize,
77
+ sourcesLoaded,
78
+ numberOfSources
79
+ };
80
+ });
81
+
82
+ /**
83
+ * Construct AudioScene
84
+ *
85
+ * @param {object} _
86
+ * @param {AudioContext} _.audioContext
87
+ */
88
+ constructor() {
89
+ const state = this.#state;
90
+
91
+ $effect(() => {
92
+ if (state.current === STATE_LOADING) {
93
+ // console.log(
94
+ // 'progress',
95
+ // JSON.stringify($state.snapshot(this.#progress))
96
+ // );
97
+
98
+ const { sourcesLoaded, numberOfSources } = this.#progress;
99
+
100
+ if (sourcesLoaded === numberOfSources) {
101
+ console.log(`All [${numberOfSources}] sources loaded`);
102
+ this.#state.send(LOADED);
103
+ }
104
+ }
105
+ });
106
+
107
+ $effect(() => {
108
+ switch (state.current) {
109
+ case STATE_LOADING:
110
+ {
111
+ console.log('AudioScene:loading');
112
+ this.#startLoading();
113
+ }
114
+ break;
115
+
116
+ case STATE_UNLOADING:
117
+ {
118
+ // console.log('AudioScene:unloading');
119
+ // this.#startUnLoading();
120
+ }
121
+ break;
122
+
123
+ case STATE_LOADED:
124
+ {
125
+ console.log('AudioScene:loaded');
126
+
127
+ // tODO
128
+ // this.#abortLoading = null;
129
+ }
130
+ break;
131
+
132
+ case STATE_CANCELLED:
133
+ {
134
+ // console.log('AudioScene:cancelled');
135
+ // TODO
136
+ }
137
+ break;
138
+
139
+ case STATE_ERROR:
140
+ {
141
+ console.log('AudioScene:error', state.error);
142
+ }
143
+ break;
144
+ } // end switch
145
+
146
+ this.state = state.current;
147
+ });
148
+ }
149
+
150
+ destroy() {
151
+ // TODO: disconnect all audio sources?
152
+ // TODO: Unload AUdioLoaders?
153
+ }
154
+
155
+ /**
156
+ * Add in-memory audio source
157
+ * - Uses an AudioLoader instance to load audio data from network
158
+ *
159
+ * @param {object} _
160
+ * @param {string} _.label
161
+ * @param {string} _.url
162
+ * @param {SourceConfig} [_.config]
163
+ */
164
+ defineMemorySource({ label, url, config }) {
165
+ expect.notEmptyString(label);
166
+ expect.notEmptyString(url);
167
+
168
+ const audioLoader = new AudioLoader({ url });
169
+
170
+ this.#memorySources.push({ label, audioLoader, config });
171
+ }
172
+
173
+ /**
174
+ * Start loading all audio sources
175
+ *
176
+ * @param {AudioContext} audioContext
177
+ */
178
+ load(audioContext) {
179
+ this.#audioContext = audioContext;
180
+ // console.log(123);
181
+ this.#state.send(LOAD);
182
+
183
+ // FIXME: in unit test when moved to startloading it hangs!
184
+
185
+ for (const { audioLoader } of this.#memorySources) {
186
+ audioLoader.load();
187
+ }
188
+ }
189
+
190
+ async #startLoading() {
191
+ console.log('#startLoading');
192
+
193
+ // FIXME: in unit test when moved to startloading it hangs!
194
+ // for (const { audioLoader } of this.#memorySources) {
195
+ // audioLoader.load();
196
+ // }
197
+ }
198
+
199
+ /**
200
+ * Get a source that can be used to play the audio once
201
+ *
202
+ * @param {string} label
203
+ */
204
+ async getSourceNode(label) {
205
+ // @note Gain setup
206
+ // https://stackoverflow.com/questions/46203191/should-i-disconnect-nodes-that-cant-be-used-anymore
207
+
208
+ const { audioLoader /*, config */ } = this.#getMemorySource(label);
209
+
210
+ if (!audioLoader.loaded) {
211
+ throw new Error(`Source [${label}] has not been loaded yet`);
212
+ }
213
+
214
+ const sourceNode = await audioLoader.getAudioBufferSourceNode(
215
+ // @ts-ignore
216
+ this.#audioContext
217
+ );
218
+
219
+ // @ts-ignore
220
+ sourceNode.connect(this.#audioContext.destination);
221
+
222
+ // Clean up
223
+ sourceNode.onended = () => {
224
+ // console.log(`Source [${label}] ended `);
225
+ sourceNode.disconnect();
226
+ };
227
+
228
+ return sourceNode;
229
+ }
230
+
231
+ /**
232
+ * Get memory source
233
+ *
234
+ * @param {string} label
235
+ *
236
+ * @returns {MemorySource}
237
+ */
238
+ #getMemorySource(label) {
239
+ for (const source of this.#memorySources) {
240
+ if (label === source.label) {
241
+ return source;
242
+ }
243
+ }
244
+
245
+ throw new Error(`Source [${label}] has not been defined`);
246
+ }
247
+
248
+ // connect
249
+ // play
250
+
251
+ // source.connect(audioContext.destination);
252
+ // source.loop = true;
253
+ // source.start();
254
+
255
+ // /**
256
+ // * Get the source identified by the specified label
257
+ // *
258
+ // * @param {string} label
259
+ // */
260
+ // async getBufferSourceNode(label) {
261
+ // // expect.notEmptyString( label );
262
+
263
+ // for (const source of this.#memorySources) {
264
+ // if (label === source.label) {
265
+ // if (!source.bufferSourceNode) {
266
+ // source.bufferSourceNode =
267
+ // await source.AudioLoader.transferToBufferSource(this.#audioContext);
268
+ // }
269
+
270
+ // return source.bufferSourceNode;
271
+ // }
272
+ // }
273
+ // }
274
+
275
+ // async connectSourceToDestination(label) {
276
+ // const source = await this.getBufferSourceNode(label);
277
+
278
+ // if (source) {
279
+ // source.connect(this.#audioContext.destination);
280
+ // }
281
+ // }
282
+ }
@@ -1,35 +1,35 @@
1
- import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
2
-
3
- import { AUDIO_WAV } from '../../../constants/mime/audio.js';
4
-
5
- // import MockWav from './tiny-silence.wav?raw';
6
-
7
- const BASE64_WAV =
8
- 'UklGRnwAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
9
-
10
- /**
11
- * Create a response value that can be used by a mocked
12
- * fetch function
13
- *
14
- * @returns {Response}
15
- */
16
- export function createWavResponse(/* data , options */) {
17
- // @note encode as Uint8Array to get the proper byte size of data
18
- // const bytes = new TextEncoder().encode(MockWav);
19
-
20
- const binaryString = atob(BASE64_WAV);
21
- const bytes = new Uint8Array(binaryString.length);
22
-
23
- for (let i = 0; i < binaryString.length; i++) {
24
- bytes[i] = binaryString.charCodeAt(i);
25
- }
26
-
27
- const response = new Response(bytes, {
28
- headers: new Headers({
29
- [CONTENT_TYPE]: AUDIO_WAV,
30
- [CONTENT_LENGTH]: String(bytes.length)
31
- })
32
- });
33
-
34
- return response;
35
- }
1
+ import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
2
+
3
+ import { AUDIO_WAV } from '../../../constants/mime/audio.js';
4
+
5
+ // import MockWav from './tiny-silence.wav?raw';
6
+
7
+ const BASE64_WAV =
8
+ 'UklGRnwAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
9
+
10
+ /**
11
+ * Create a response value that can be used by a mocked
12
+ * fetch function
13
+ *
14
+ * @returns {Response}
15
+ */
16
+ export function createWavResponse(/* data , options */) {
17
+ // @note encode as Uint8Array to get the proper byte size of data
18
+ // const bytes = new TextEncoder().encode(MockWav);
19
+
20
+ const binaryString = atob(BASE64_WAV);
21
+ const bytes = new Uint8Array(binaryString.length);
22
+
23
+ for (let i = 0; i < binaryString.length; i++) {
24
+ bytes[i] = binaryString.charCodeAt(i);
25
+ }
26
+
27
+ const response = new Response(bytes, {
28
+ headers: new Headers({
29
+ [CONTENT_TYPE]: AUDIO_WAV,
30
+ [CONTENT_LENGTH]: String(bytes.length)
31
+ })
32
+ });
33
+
34
+ return response;
35
+ }