@hkdigital/lib-sveltekit 0.0.83 → 0.0.85
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.
- package/dist/classes/svelte/audio/AudioScene.svelte.d.ts +1 -1
- package/dist/classes/svelte/audio/AudioScene.svelte.js +261 -261
- package/dist/config/imagetools-config.d.ts +3 -4
- package/dist/config/imagetools-config.js +21 -12
- package/dist/types/imagetools.d.ts +0 -3
- package/package.json +8 -8
- package/dist/types/imagetools.js +0 -8
@@ -1,19 +1,19 @@
|
|
1
1
|
import * as expect from '@hkdigital/lib-sveltekit/util/expect/index.js';
|
2
2
|
|
3
3
|
import {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
17
|
} from '../loading-state-machine/index.js';
|
18
18
|
|
19
19
|
import AudioLoader from './AudioLoader.svelte.js';
|
@@ -31,252 +31,252 @@ import AudioLoader from './AudioLoader.svelte.js';
|
|
31
31
|
*/
|
32
32
|
|
33
33
|
export default class AudioScene {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
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
282
|
}
|
@@ -4,15 +4,14 @@
|
|
4
4
|
*
|
5
5
|
* @param {object} [options]
|
6
6
|
* @param {number[]} [options.widths=DEFAULT_WIDTHS]
|
7
|
+
*
|
7
8
|
* @returns {(
|
8
9
|
* entries: [string, string[]][]
|
9
|
-
* ) =>
|
10
|
+
* ) => (Record<string, string | string[]>[])}
|
10
11
|
*/
|
11
12
|
export function generateResponseConfigs(options?: {
|
12
13
|
widths?: number[];
|
13
|
-
}): (entries: [string, string[]][]) =>
|
14
|
-
[key: string]: string | string[];
|
15
|
-
}[];
|
14
|
+
}): (entries: [string, string[]][]) => (Record<string, string | string[]>[]);
|
16
15
|
/**
|
17
16
|
* Configures and returns a function that can be used as
|
18
17
|
* 'defaultDirectives' parameter in imagetools config
|
@@ -34,24 +34,20 @@ const DEFAULT_PRESETS = {
|
|
34
34
|
*
|
35
35
|
* @param {object} [options]
|
36
36
|
* @param {number[]} [options.widths=DEFAULT_WIDTHS]
|
37
|
+
*
|
37
38
|
* @returns {(
|
38
39
|
* entries: [string, string[]][]
|
39
|
-
* ) =>
|
40
|
+
* ) => (Record<string, string | string[]>[])}
|
40
41
|
*/
|
41
42
|
export function generateResponseConfigs(options) {
|
43
|
+
//
|
44
|
+
// @see https://github.com/JonasKruckenberg/imagetools
|
45
|
+
// /blob/main/docs/core/src/functions/resolveConfigs.md
|
46
|
+
//
|
42
47
|
return function resolveConfigs(entries /*, outputFormats*/) {
|
43
48
|
// console.log('resolveConfigs:entries', entries);
|
44
49
|
|
45
|
-
|
46
|
-
const responsiveConfig = entries.find(([key]) => key === 'responsive');
|
47
|
-
|
48
|
-
if (!responsiveConfig) {
|
49
|
-
// Directive 'responsive' was not set => do nothing
|
50
|
-
return [];
|
51
|
-
}
|
52
|
-
|
53
|
-
const widths = options?.widths ?? DEFAULT_WIDTHS;
|
54
|
-
|
50
|
+
/** @type {Record<string, string | string[]>} */
|
55
51
|
const configPairs = {};
|
56
52
|
|
57
53
|
for (const current of entries) {
|
@@ -62,7 +58,20 @@ export function generateResponseConfigs(options) {
|
|
62
58
|
configPairs[key] = value;
|
63
59
|
}
|
64
60
|
|
65
|
-
|
61
|
+
// @ts-ignore
|
62
|
+
const responsiveConfig = entries.find(([key]) => key === 'responsive');
|
63
|
+
|
64
|
+
if (!responsiveConfig) {
|
65
|
+
// Directive 'responsive' was not set => return original config
|
66
|
+
|
67
|
+
return [configPairs];
|
68
|
+
|
69
|
+
// Alternative: by returning undefined, the default resolveConfig is used
|
70
|
+
// return undefined;
|
71
|
+
}
|
72
|
+
|
73
|
+
const widths = options?.widths ?? DEFAULT_WIDTHS;
|
74
|
+
|
66
75
|
return widths.map((w) => {
|
67
76
|
return { ...configPairs, w: String(w) };
|
68
77
|
});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hkdigital/lib-sveltekit",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.85",
|
4
4
|
"author": "Jens Kleinhout, HKdigital (https://hkdigital.nl)",
|
5
5
|
"license": "ISC",
|
6
6
|
"repository": {
|
@@ -65,18 +65,18 @@
|
|
65
65
|
"prettier": "^3.4.2",
|
66
66
|
"prettier-plugin-svelte": "^3.3.2",
|
67
67
|
"prettier-plugin-tailwindcss": "^0.6.9",
|
68
|
-
"publint": "^0.
|
68
|
+
"publint": "^0.3.0",
|
69
69
|
"standardized-audio-context-mock": "^9.7.15",
|
70
|
-
"svelte": "^5.
|
71
|
-
"svelte-check": "^4.1.
|
70
|
+
"svelte": "^5.17.3",
|
71
|
+
"svelte-check": "^4.1.3",
|
72
72
|
"tailwindcss": "^3.4.17",
|
73
|
-
"typescript": "^5.7.
|
74
|
-
"vite": "^6.0.
|
73
|
+
"typescript": "^5.7.3",
|
74
|
+
"vite": "^6.0.7",
|
75
75
|
"vitest": "^2.1.8"
|
76
76
|
},
|
77
77
|
"dependencies": {
|
78
|
-
"@sveltejs/kit": "^2.15.
|
79
|
-
"runed": "^0.
|
78
|
+
"@sveltejs/kit": "^2.15.2",
|
79
|
+
"runed": "^0.23.0",
|
80
80
|
"valibot": "^0.42.1",
|
81
81
|
"zod": "^3.24.1"
|
82
82
|
}
|