@hkdigital/lib-sveltekit 0.0.80 → 0.0.82

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 (44) hide show
  1. package/dist/classes/svelte/audio/AudioLoader.svelte.d.ts +30 -0
  2. package/dist/classes/svelte/audio/AudioLoader.svelte.js +58 -0
  3. package/dist/classes/svelte/audio/AudioScene.svelte.d.ts +52 -0
  4. package/dist/classes/svelte/audio/AudioScene.svelte.js +282 -0
  5. package/dist/classes/svelte/audio/mocks.d.ts +7 -0
  6. package/dist/classes/svelte/audio/mocks.js +35 -0
  7. package/dist/classes/svelte/final-state-machine/FiniteStateMachine.svelte.d.ts +50 -0
  8. package/dist/classes/svelte/final-state-machine/FiniteStateMachine.svelte.js +133 -0
  9. package/dist/classes/svelte/final-state-machine/index.d.ts +1 -0
  10. package/dist/classes/svelte/final-state-machine/index.js +1 -0
  11. package/dist/classes/svelte/image/ImageLoader.svelte.d.ts +8 -0
  12. package/dist/classes/svelte/image/ImageLoader.svelte.js +12 -0
  13. package/dist/classes/svelte/image/ImageVariantsLoader.svelte.d.ts +39 -0
  14. package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +151 -0
  15. package/dist/classes/svelte/image/index.d.ts +2 -0
  16. package/dist/classes/svelte/image/index.js +4 -0
  17. package/dist/classes/svelte/image/mocks.d.ts +7 -0
  18. package/dist/classes/svelte/image/mocks.js +38 -0
  19. package/dist/classes/svelte/image/typedef.d.ts +16 -0
  20. package/dist/classes/svelte/image/typedef.js +10 -0
  21. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.d.ts +12 -0
  22. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +107 -0
  23. package/dist/classes/svelte/loading-state-machine/constants.d.ts +12 -0
  24. package/dist/classes/svelte/loading-state-machine/constants.js +16 -0
  25. package/dist/classes/svelte/loading-state-machine/index.d.ts +2 -0
  26. package/dist/classes/svelte/loading-state-machine/index.js +3 -0
  27. package/dist/classes/svelte/network-loader/NetworkLoader.svelte.d.ts +85 -0
  28. package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +295 -0
  29. package/dist/classes/svelte/network-loader/constants.d.ts +2 -0
  30. package/dist/classes/svelte/network-loader/constants.js +3 -0
  31. package/dist/classes/svelte/network-loader/index.d.ts +2 -0
  32. package/dist/classes/svelte/network-loader/index.js +3 -0
  33. package/dist/components/image/ResponsiveImage.svelte +103 -0
  34. package/dist/components/image/ResponsiveImage.svelte.d.ts +15 -0
  35. package/dist/components/image/index.d.ts +4 -1
  36. package/dist/components/image/index.js +5 -1
  37. package/dist/types/imagetools.d.ts +84 -0
  38. package/dist/types/imagetools.js +8 -0
  39. package/dist/util/expect/arrays.d.ts +4 -0
  40. package/dist/util/expect/arrays.js +6 -1
  41. package/dist/util/http/response.js +1 -0
  42. package/dist/util/svelte/wait/index.d.ts +15 -0
  43. package/dist/util/svelte/wait/index.js +38 -0
  44. package/package.json +3 -1
@@ -0,0 +1,30 @@
1
+ /**
2
+ * AudioLoader instance
3
+ * - Loads audio data from network into an ArrayBuffer
4
+ * - Loaded data can be transferred to an AudioBufferSourceNode
5
+ */
6
+ export default class AudioLoader extends NetworkLoader {
7
+ /**
8
+ * Get an AudioBufferSourceNode instance
9
+ *
10
+ * @note AudioBufferSourceNodes can play only once, a new source node
11
+ * must be created otherwise
12
+ *
13
+ * @param {AudioContext} audioContext
14
+ *
15
+ * @returns {Promise<AudioBufferSourceNode>}
16
+ */
17
+ getAudioBufferSourceNode(audioContext: AudioContext): Promise<AudioBufferSourceNode>;
18
+ /**
19
+ * Gets data as AudioBuffer
20
+ * - Stores created AudioBuffer instance internally
21
+ * - Transfers data from internal ArrayBuffer, which will be detached
22
+ *
23
+ * @param {AudioContext} audioContext
24
+ *
25
+ * @returns {Promise<AudioBuffer>}
26
+ */
27
+ getAudioBuffer(audioContext: AudioContext): Promise<AudioBuffer>;
28
+ #private;
29
+ }
30
+ import { NetworkLoader } from '../network-loader/index.js';
@@ -0,0 +1,58 @@
1
+ import {
2
+ NetworkLoader,
3
+ ERROR_NOT_LOADED,
4
+ ERROR_TRANSFERRED
5
+ } from '../network-loader/index.js';
6
+
7
+ /**
8
+ * AudioLoader instance
9
+ * - Loads audio data from network into an ArrayBuffer
10
+ * - Loaded data can be transferred to an AudioBufferSourceNode
11
+ */
12
+ export default class AudioLoader extends NetworkLoader {
13
+ /** @type {AudioBuffer|null} */
14
+ #audioBuffer = null;
15
+
16
+ /**
17
+ * Get an AudioBufferSourceNode instance
18
+ *
19
+ * @note AudioBufferSourceNodes can play only once, a new source node
20
+ * must be created otherwise
21
+ *
22
+ * @param {AudioContext} audioContext
23
+ *
24
+ * @returns {Promise<AudioBufferSourceNode>}
25
+ */
26
+ async getAudioBufferSourceNode(audioContext) {
27
+ if (!this.#audioBuffer) {
28
+ this.#audioBuffer = await this.getAudioBuffer(audioContext);
29
+ }
30
+
31
+ return new AudioBufferSourceNode(audioContext, {
32
+ buffer: this.#audioBuffer
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Gets data as AudioBuffer
38
+ * - Stores created AudioBuffer instance internally
39
+ * - Transfers data from internal ArrayBuffer, which will be detached
40
+ *
41
+ * @param {AudioContext} audioContext
42
+ *
43
+ * @returns {Promise<AudioBuffer>}
44
+ */
45
+ async getAudioBuffer(audioContext) {
46
+ if (!this._buffer) {
47
+ throw new Error(ERROR_NOT_LOADED);
48
+ }
49
+
50
+ if (this._buffer.detached) {
51
+ throw new Error(ERROR_TRANSFERRED);
52
+ }
53
+
54
+ this.#audioBuffer = await audioContext.decodeAudioData(this._buffer);
55
+
56
+ return this.#audioBuffer;
57
+ }
58
+ } // end class
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @typedef {object} SourceConfig
3
+ * // property ...
4
+ */
5
+ /**
6
+ * @typedef {object} MemorySource
7
+ * @property {string} label
8
+ * @property {AudioLoader} audioLoader
9
+ * @property {SourceConfig} [config]
10
+ */
11
+ export default class AudioScene {
12
+ state: string;
13
+ loaded: boolean;
14
+ destroy(): void;
15
+ /**
16
+ * Add in-memory audio source
17
+ * - Uses an AudioLoader instance to load audio data from network
18
+ *
19
+ * @param {object} _
20
+ * @param {string} _.label
21
+ * @param {string} _.url
22
+ * @param {SourceConfig} [_.config]
23
+ */
24
+ defineMemorySource({ label, url, config }: {
25
+ label: string;
26
+ url: string;
27
+ config?: SourceConfig;
28
+ }): void;
29
+ /**
30
+ * Start loading all audio sources
31
+ *
32
+ * @param {AudioContext} audioContext
33
+ */
34
+ load(audioContext: AudioContext): void;
35
+ /**
36
+ * Get a source that can be used to plat the audio once
37
+ *
38
+ * @param {string} label
39
+ */
40
+ getSourceNode(label: string): Promise<AudioBufferSourceNode>;
41
+ #private;
42
+ }
43
+ /**
44
+ * // property ...
45
+ */
46
+ export type SourceConfig = object;
47
+ export type MemorySource = {
48
+ label: string;
49
+ audioLoader: AudioLoader;
50
+ config?: SourceConfig;
51
+ };
52
+ import AudioLoader from './AudioLoader.svelte.js';
@@ -0,0 +1,282 @@
1
+ import * as expect from '@hkdigital/lib-sveltekit/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 plat 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
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Create a response value that can be used by a mocked
3
+ * fetch function
4
+ *
5
+ * @returns {Response}
6
+ */
7
+ export function createWavResponse(): Response;
@@ -0,0 +1,35 @@
1
+ import { CONTENT_TYPE, CONTENT_LENGTH } from '@hkdigital/lib-sveltekit/constants/http/index.js';
2
+
3
+ import { AUDIO_WAV } from '@hkdigital/lib-sveltekit/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
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Initial code borrowed from:
3
+ *
4
+ * @see {@link https://runed.dev/docs/utilities/finite-state-machine}
5
+ */
6
+ /**
7
+ * Check if the value is valid meta data
8
+ *
9
+ * @param {any} meta
10
+ */
11
+ export function isLifecycleFnMeta(meta: any): boolean;
12
+ /**
13
+ * Defines a Finite State Machine
14
+ */
15
+ export default class FiniteStateMachine {
16
+ /**
17
+ * Constructor
18
+ *
19
+ * @param {string} initial
20
+ * @param {{ [key: string]: { [key: string]: (string|((...args: any[])=>void)) } }} states
21
+ */
22
+ constructor(initial: string, states: {
23
+ [key: string]: {
24
+ [key: string]: (string | ((...args: any[]) => void));
25
+ };
26
+ });
27
+ states: {
28
+ [key: string]: {
29
+ [key: string]: string | ((...args: any[]) => void);
30
+ };
31
+ };
32
+ /**
33
+ * Triggers a new event and returns the new state.
34
+ *
35
+ * @param {string} event
36
+ * @param {any[]} args
37
+ */
38
+ send(event: string, ...args: any[]): any;
39
+ /**
40
+ * Debounces the triggering of an event.
41
+ *
42
+ * @param {number} wait
43
+ * @param {string} event
44
+ * @param {any[]} args
45
+ */
46
+ debounce(wait: number, event: string, ...args: any[]): Promise<any>;
47
+ /** The current state. */
48
+ get current(): any;
49
+ #private;
50
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Initial code borrowed from:
3
+ *
4
+ * @see {@link https://runed.dev/docs/utilities/finite-state-machine}
5
+ */
6
+
7
+ /**
8
+ * Check if the value is valid meta data
9
+ *
10
+ * @param {any} meta
11
+ */
12
+ export function isLifecycleFnMeta(meta) {
13
+ return (
14
+ !!meta &&
15
+ typeof meta === 'object' &&
16
+ 'to' in meta &&
17
+ 'from' in meta &&
18
+ 'event' in meta &&
19
+ 'args' in meta
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Defines a Finite State Machine
25
+ */
26
+ export default class FiniteStateMachine {
27
+ #current = $state();
28
+ states;
29
+ #timeout = {};
30
+
31
+ /**
32
+ * Constructor
33
+ *
34
+ * @param {string} initial
35
+ * @param {{ [key: string]: { [key: string]: (string|((...args: any[])=>void)) } }} states
36
+ */
37
+ constructor(initial, states) {
38
+ this.#current = initial;
39
+ this.states = states;
40
+
41
+ // synthetically trigger _enter for the initial state.
42
+ this.#dispatch('_enter', {
43
+ from: null,
44
+ to: initial,
45
+ event: null,
46
+ args: []
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Transition to new state
52
+ *
53
+ * @param {string} newState
54
+ * @param {string} event
55
+ * @param {any[]} [args]
56
+ */
57
+ #transition(newState, event, args) {
58
+ const metadata = { from: this.#current, to: newState, event, args };
59
+ this.#dispatch('_exit', metadata);
60
+ this.#current = newState;
61
+ this.#dispatch('_enter', metadata);
62
+ }
63
+
64
+ /**
65
+ * Dispatch an event
66
+ *
67
+ * @param {string} event
68
+ * @param {any[]} args
69
+ */
70
+ #dispatch(event, ...args) {
71
+ const action =
72
+ this.states[this.#current]?.[event] ?? this.states['*']?.[event];
73
+ if (action instanceof Function) {
74
+ if (event === '_enter' || event === '_exit') {
75
+ if (isLifecycleFnMeta(args[0])) {
76
+ action(args[0]);
77
+ } else {
78
+ console.warn(
79
+ 'Invalid metadata passed to lifecycle function of the FSM.'
80
+ );
81
+ }
82
+ } else {
83
+ return action(...args);
84
+ }
85
+ } else if (typeof action === 'string') {
86
+ return action;
87
+ } else if (event !== '_enter' && event !== '_exit') {
88
+ console.warn(
89
+ 'No action defined for event',
90
+ event,
91
+ 'in state',
92
+ this.#current
93
+ );
94
+ }
95
+ }
96
+ /**
97
+ * Triggers a new event and returns the new state.
98
+ *
99
+ * @param {string} event
100
+ * @param {any[]} args
101
+ */
102
+ send(event, ...args) {
103
+ const newState = this.#dispatch(event, ...args);
104
+ if (newState && newState !== this.#current) {
105
+ this.#transition(newState, event, args);
106
+ }
107
+
108
+ return this.#current;
109
+ }
110
+ /**
111
+ * Debounces the triggering of an event.
112
+ *
113
+ * @param {number} wait
114
+ * @param {string} event
115
+ * @param {any[]} args
116
+ */
117
+ async debounce(wait = 500, event, ...args) {
118
+ if (this.#timeout[event]) {
119
+ clearTimeout(this.#timeout[event]);
120
+ }
121
+ return new Promise((resolve) => {
122
+ this.#timeout[event] = setTimeout(() => {
123
+ delete this.#timeout[event];
124
+ resolve(this.send(event, ...args));
125
+ }, wait);
126
+ });
127
+ }
128
+
129
+ /** The current state. */
130
+ get current() {
131
+ return this.#current;
132
+ }
133
+ }
@@ -0,0 +1 @@
1
+ export { default as FiniteStateMachine } from "./FiniteStateMachine.svelte";
@@ -0,0 +1 @@
1
+ export { default as FiniteStateMachine } from './FiniteStateMachine.svelte';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ImageLoader instance
3
+ * - Loads image data from network
4
+ * - The loading process can be monitored
5
+ */
6
+ export default class ImageLoader extends NetworkLoader {
7
+ }
8
+ import { NetworkLoader } from '../network-loader/index.js';
@@ -0,0 +1,12 @@
1
+ import {
2
+ NetworkLoader,
3
+ ERROR_NOT_LOADED,
4
+ ERROR_TRANSFERRED
5
+ } from '../network-loader/index.js';
6
+
7
+ /**
8
+ * ImageLoader instance
9
+ * - Loads image data from network
10
+ * - The loading process can be monitored
11
+ */
12
+ export default class ImageLoader extends NetworkLoader {} // end class