@hkdigital/lib-sveltekit 0.0.90 → 0.0.92
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.js +1 -1
- package/dist/classes/svelte/audio/mocks.js +2 -2
- package/dist/classes/svelte/image/ImageLoader.svelte.d.ts +11 -0
- package/dist/classes/svelte/image/ImageLoader.svelte.js +28 -10
- package/dist/classes/svelte/image/ImageScene.svelte.d.ts +78 -0
- package/dist/classes/svelte/image/ImageScene.svelte.js +256 -0
- package/dist/classes/svelte/image/ImageVariantsLoader.svelte.d.ts +2 -6
- package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +3 -3
- package/dist/classes/svelte/image/mocks.js +2 -5
- package/dist/classes/svelte/image/typedef.js +0 -2
- package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +2 -0
- package/dist/classes/svelte/network-loader/NetworkLoader.svelte.d.ts +5 -8
- package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +24 -19
- package/dist/classes/svelte/network-loader/mocks.js +2 -2
- package/dist/classes/svelte/network-loader/typedef.d.ts +7 -0
- package/dist/classes/svelte/network-loader/typedef.js +8 -0
- package/dist/components/image/ImageBox.svelte +242 -0
- package/dist/components/image/ImageBox.svelte.d.ts +60 -0
- package/dist/components/image/ResponsiveImage.svelte +1 -1
- package/dist/components/image/typedef.d.ts +4 -0
- package/dist/components/image/typedef.js +32 -0
- package/dist/config/imagetools-config.js +6 -1
- package/dist/{types → config}/imagetools.d.ts +31 -21
- package/dist/config/typedef.d.ts +7 -0
- package/dist/config/typedef.js +8 -0
- package/dist/util/http/mocks.js +1 -1
- package/dist/util/image/index.d.ts +9 -0
- package/dist/util/image/index.js +24 -0
- package/package.json +19 -17
@@ -1,6 +1,6 @@
|
|
1
|
-
import { CONTENT_TYPE, CONTENT_LENGTH } from '
|
1
|
+
import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
|
2
2
|
|
3
|
-
import { AUDIO_WAV } from '
|
3
|
+
import { AUDIO_WAV } from '../../../constants/mime/audio.js';
|
4
4
|
|
5
5
|
// import MockWav from './tiny-silence.wav?raw';
|
6
6
|
|
@@ -4,5 +4,16 @@
|
|
4
4
|
* - The loading process can be monitored
|
5
5
|
*/
|
6
6
|
export default class ImageLoader extends NetworkLoader {
|
7
|
+
/**
|
8
|
+
* @param {object} _
|
9
|
+
* @param {ImageMeta|ImageMeta[]} _.imageMeta
|
10
|
+
*/
|
11
|
+
constructor({ imageMeta }: {
|
12
|
+
imageMeta: ImageMeta | ImageMeta[];
|
13
|
+
});
|
14
|
+
get imageMeta(): import("./typedef.js").ImageMeta;
|
15
|
+
get url(): string;
|
16
|
+
#private;
|
7
17
|
}
|
18
|
+
export type ImageMeta = import("./typedef.js").ImageMeta;
|
8
19
|
import { NetworkLoader } from '../network-loader/index.js';
|
@@ -1,3 +1,7 @@
|
|
1
|
+
/** @typedef {import('./typedef.js').ImageMeta} ImageMeta */
|
2
|
+
|
3
|
+
import { toSingleImageMeta } from '../../../util/image/index.js';
|
4
|
+
|
1
5
|
import {
|
2
6
|
NetworkLoader
|
3
7
|
// ERROR_NOT_LOADED,
|
@@ -10,20 +14,34 @@ import {
|
|
10
14
|
* - The loading process can be monitored
|
11
15
|
*/
|
12
16
|
export default class ImageLoader extends NetworkLoader {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
/** @type {ImageMeta} */
|
18
|
+
#imageMeta;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @param {object} _
|
22
|
+
* @param {ImageMeta|ImageMeta[]} _.imageMeta
|
23
|
+
*/
|
24
|
+
constructor({ imageMeta }) {
|
25
|
+
imageMeta = toSingleImageMeta(imageMeta);
|
26
|
+
|
27
|
+
super({ url: imageMeta.src });
|
28
|
+
|
29
|
+
this.#imageMeta = imageMeta;
|
30
|
+
}
|
31
|
+
|
32
|
+
get imageMeta() {
|
33
|
+
return this.#imageMeta;
|
34
|
+
}
|
35
|
+
|
36
|
+
get url() {
|
37
|
+
return this._url;
|
38
|
+
}
|
39
|
+
|
22
40
|
// /**
|
23
41
|
// * Get object URL that can be used as src parameter of an HTML image
|
24
42
|
// *
|
25
43
|
// * @note the objectURL should be revoked when no longer used
|
26
44
|
// */
|
27
|
-
//
|
45
|
+
// getObjectURL() {}
|
28
46
|
//
|
29
47
|
} // end class
|
@@ -0,0 +1,78 @@
|
|
1
|
+
/**
|
2
|
+
* @typedef {object} SourceConfig
|
3
|
+
* // property ...
|
4
|
+
*/
|
5
|
+
/**
|
6
|
+
* @typedef {object} ImageSource
|
7
|
+
* @property {string} label
|
8
|
+
* @property {ImageLoader} imageLoader
|
9
|
+
* @property {ImageMeta} [imageMeta]
|
10
|
+
*/
|
11
|
+
export default class ImageScene {
|
12
|
+
state: string;
|
13
|
+
loaded: boolean;
|
14
|
+
destroy(): void;
|
15
|
+
/**
|
16
|
+
* Add image source
|
17
|
+
* - Uses an ImageLoader instance to load image data from network
|
18
|
+
*
|
19
|
+
* @param {object} _
|
20
|
+
* @param {string} _.label
|
21
|
+
* @param {ImageMeta|ImageMeta[]} _.imageMeta
|
22
|
+
*/
|
23
|
+
defineImage({ label, imageMeta }: {
|
24
|
+
label: string;
|
25
|
+
imageMeta: ImageMeta | ImageMeta[];
|
26
|
+
}): void;
|
27
|
+
/**
|
28
|
+
* Start loading all image sources
|
29
|
+
*/
|
30
|
+
load(): void;
|
31
|
+
/**
|
32
|
+
* Get image scene loading progress
|
33
|
+
*/
|
34
|
+
get progress(): {
|
35
|
+
totalBytesLoaded: number;
|
36
|
+
totalSize: number;
|
37
|
+
sourcesLoaded: number;
|
38
|
+
numberOfSources: number;
|
39
|
+
};
|
40
|
+
/**
|
41
|
+
* Get an image loader
|
42
|
+
*
|
43
|
+
* @param {string} label
|
44
|
+
*
|
45
|
+
* @returns {ImageLoader}
|
46
|
+
*/
|
47
|
+
getImageLoader(label: string): ImageLoader;
|
48
|
+
/**
|
49
|
+
* Get object URL that can be used as src parameter of an HTML image
|
50
|
+
*
|
51
|
+
* @param {string} label
|
52
|
+
*
|
53
|
+
* @returns {ImageMeta}
|
54
|
+
*/
|
55
|
+
getImageMeta(label: string): ImageMeta;
|
56
|
+
/**
|
57
|
+
* Get object URL that can be used as src parameter of an HTML image
|
58
|
+
*
|
59
|
+
* @param {string} label
|
60
|
+
*
|
61
|
+
* @note the objectURL should be revoked when no longer used
|
62
|
+
*
|
63
|
+
* @returns {string}
|
64
|
+
*/
|
65
|
+
getObjectURL(label: string): string;
|
66
|
+
#private;
|
67
|
+
}
|
68
|
+
export type ImageMeta = import("./typedef.js").ImageMeta;
|
69
|
+
/**
|
70
|
+
* // property ...
|
71
|
+
*/
|
72
|
+
export type SourceConfig = object;
|
73
|
+
export type ImageSource = {
|
74
|
+
label: string;
|
75
|
+
imageLoader: ImageLoader;
|
76
|
+
imageMeta?: ImageMeta;
|
77
|
+
};
|
78
|
+
import ImageLoader from './ImageLoader.svelte.js';
|
@@ -0,0 +1,256 @@
|
|
1
|
+
/** @typedef {import('./typedef.js').ImageMeta} ImageMeta */
|
2
|
+
|
3
|
+
import * as expect from '../../../util/expect/index.js';
|
4
|
+
|
5
|
+
import {
|
6
|
+
LoadingStateMachine,
|
7
|
+
STATE_INITIAL,
|
8
|
+
STATE_LOADING,
|
9
|
+
STATE_UNLOADING,
|
10
|
+
STATE_LOADED,
|
11
|
+
STATE_CANCELLED,
|
12
|
+
STATE_ERROR,
|
13
|
+
LOAD,
|
14
|
+
// CANCEL,
|
15
|
+
ERROR,
|
16
|
+
LOADED,
|
17
|
+
UNLOAD,
|
18
|
+
INITIAL
|
19
|
+
} from '../loading-state-machine/index.js';
|
20
|
+
|
21
|
+
import ImageLoader from './ImageLoader.svelte.js';
|
22
|
+
|
23
|
+
/**
|
24
|
+
* @typedef {object} SourceConfig
|
25
|
+
* // property ...
|
26
|
+
*/
|
27
|
+
|
28
|
+
/**
|
29
|
+
* @typedef {object} ImageSource
|
30
|
+
* @property {string} label
|
31
|
+
* @property {ImageLoader} imageLoader
|
32
|
+
* @property {ImageMeta} [imageMeta]
|
33
|
+
*/
|
34
|
+
|
35
|
+
export default class ImageScene {
|
36
|
+
#state = new LoadingStateMachine();
|
37
|
+
|
38
|
+
// @note this exported state is set by $effect's
|
39
|
+
state = $state(STATE_INITIAL);
|
40
|
+
|
41
|
+
// @note this exported state is set by $effect's
|
42
|
+
loaded = $derived.by(() => {
|
43
|
+
return this.state === STATE_LOADED;
|
44
|
+
});
|
45
|
+
|
46
|
+
/** @type {ImageSource[]} */
|
47
|
+
#imageSources = $state([]);
|
48
|
+
|
49
|
+
#progress = $derived.by(() => {
|
50
|
+
// console.log('update progress');
|
51
|
+
|
52
|
+
let totalSize = 0;
|
53
|
+
let totalBytesLoaded = 0;
|
54
|
+
let sourcesLoaded = 0;
|
55
|
+
|
56
|
+
const sources = this.#imageSources;
|
57
|
+
const numberOfSources = sources.length;
|
58
|
+
|
59
|
+
for (let j = 0; j < numberOfSources; j++) {
|
60
|
+
const source = sources[j];
|
61
|
+
const { imageLoader } = source;
|
62
|
+
|
63
|
+
const { bytesLoaded, size, loaded } = imageLoader.progress;
|
64
|
+
|
65
|
+
totalSize += size;
|
66
|
+
totalBytesLoaded += bytesLoaded;
|
67
|
+
|
68
|
+
if (loaded) {
|
69
|
+
sourcesLoaded++;
|
70
|
+
}
|
71
|
+
} // end for
|
72
|
+
|
73
|
+
return {
|
74
|
+
totalBytesLoaded,
|
75
|
+
totalSize,
|
76
|
+
sourcesLoaded,
|
77
|
+
numberOfSources
|
78
|
+
};
|
79
|
+
});
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Construct AudioScene
|
83
|
+
*
|
84
|
+
* @param {object} _
|
85
|
+
* @param {AudioContext} _.audioContext
|
86
|
+
*/
|
87
|
+
constructor() {
|
88
|
+
const state = this.#state;
|
89
|
+
|
90
|
+
$effect(() => {
|
91
|
+
if (state.current === STATE_LOADING) {
|
92
|
+
// console.log(
|
93
|
+
// 'progress',
|
94
|
+
// JSON.stringify($state.snapshot(this.#progress))
|
95
|
+
// );
|
96
|
+
|
97
|
+
const { sourcesLoaded, numberOfSources } = this.#progress;
|
98
|
+
|
99
|
+
if (sourcesLoaded === numberOfSources) {
|
100
|
+
// console.log(`All [${numberOfSources}] sources loaded`);
|
101
|
+
this.#state.send(LOADED);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
});
|
105
|
+
|
106
|
+
$effect(() => {
|
107
|
+
switch (state.current) {
|
108
|
+
case STATE_LOADING:
|
109
|
+
{
|
110
|
+
// console.log('ImageScene:loading');
|
111
|
+
this.#startLoading();
|
112
|
+
}
|
113
|
+
break;
|
114
|
+
|
115
|
+
case STATE_UNLOADING:
|
116
|
+
{
|
117
|
+
// console.log('ImageScene:unloading');
|
118
|
+
// this.#startUnLoading();
|
119
|
+
}
|
120
|
+
break;
|
121
|
+
|
122
|
+
case STATE_LOADED:
|
123
|
+
{
|
124
|
+
// console.log('ImageScene:loaded');
|
125
|
+
// TODO
|
126
|
+
// this.#abortLoading = null;
|
127
|
+
}
|
128
|
+
break;
|
129
|
+
|
130
|
+
case STATE_CANCELLED:
|
131
|
+
{
|
132
|
+
// console.log('ImageScene:cancelled');
|
133
|
+
// TODO
|
134
|
+
}
|
135
|
+
break;
|
136
|
+
|
137
|
+
case STATE_ERROR:
|
138
|
+
{
|
139
|
+
console.log('ImageScene:error', state.error);
|
140
|
+
}
|
141
|
+
break;
|
142
|
+
} // end switch
|
143
|
+
|
144
|
+
this.state = state.current;
|
145
|
+
});
|
146
|
+
}
|
147
|
+
|
148
|
+
destroy() {
|
149
|
+
// TODO: disconnect all image sources?
|
150
|
+
// TODO: Unload ImageLoaders?
|
151
|
+
}
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Add image source
|
155
|
+
* - Uses an ImageLoader instance to load image data from network
|
156
|
+
*
|
157
|
+
* @param {object} _
|
158
|
+
* @param {string} _.label
|
159
|
+
* @param {ImageMeta|ImageMeta[]} _.imageMeta
|
160
|
+
*/
|
161
|
+
defineImage({ label, imageMeta }) {
|
162
|
+
expect.notEmptyString(label);
|
163
|
+
|
164
|
+
// expect.notEmptyString(url);
|
165
|
+
|
166
|
+
const imageLoader = new ImageLoader({ imageMeta });
|
167
|
+
|
168
|
+
this.#imageSources.push({ label, imageLoader, imageMeta });
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Start loading all image sources
|
173
|
+
*/
|
174
|
+
load() {
|
175
|
+
this.#state.send(LOAD);
|
176
|
+
|
177
|
+
// FIXME: in unit test when moved to startloading it hangs!
|
178
|
+
|
179
|
+
for (const { imageLoader } of this.#imageSources) {
|
180
|
+
imageLoader.load();
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
async #startLoading() {
|
185
|
+
// console.log('#startLoading');
|
186
|
+
// FIXME: in unit test when moved to startloading it hangs!
|
187
|
+
// for (const { audioLoader } of this.#memorySources) {
|
188
|
+
// audioLoader.load();
|
189
|
+
// }
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Get Image source
|
194
|
+
*
|
195
|
+
* @param {string} label
|
196
|
+
*
|
197
|
+
* @returns {ImageSource}
|
198
|
+
*/
|
199
|
+
#getImageSource(label) {
|
200
|
+
for (const source of this.#imageSources) {
|
201
|
+
if (label === source.label) {
|
202
|
+
return source;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
throw new Error(`Source [${label}] has not been defined`);
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Get image scene loading progress
|
211
|
+
*/
|
212
|
+
get progress() {
|
213
|
+
return this.#progress;
|
214
|
+
}
|
215
|
+
|
216
|
+
/**
|
217
|
+
* Get an image loader
|
218
|
+
*
|
219
|
+
* @param {string} label
|
220
|
+
*
|
221
|
+
* @returns {ImageLoader}
|
222
|
+
*/
|
223
|
+
getImageLoader(label) {
|
224
|
+
const source = this.#getImageSource(label);
|
225
|
+
|
226
|
+
return source.imageLoader;
|
227
|
+
}
|
228
|
+
|
229
|
+
/**
|
230
|
+
* Get object URL that can be used as src parameter of an HTML image
|
231
|
+
*
|
232
|
+
* @param {string} label
|
233
|
+
*
|
234
|
+
* @returns {ImageMeta}
|
235
|
+
*/
|
236
|
+
getImageMeta(label) {
|
237
|
+
const source = this.#getImageSource(label);
|
238
|
+
|
239
|
+
return source.imageMeta;
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
* Get object URL that can be used as src parameter of an HTML image
|
244
|
+
*
|
245
|
+
* @param {string} label
|
246
|
+
*
|
247
|
+
* @note the objectURL should be revoked when no longer used
|
248
|
+
*
|
249
|
+
* @returns {string}
|
250
|
+
*/
|
251
|
+
getObjectURL(label) {
|
252
|
+
const source = this.#getImageSource(label);
|
253
|
+
|
254
|
+
return source.imageLoader.getObjectURL();
|
255
|
+
}
|
256
|
+
}
|
@@ -20,12 +20,8 @@ export default class ImageVariantsLoader {
|
|
20
20
|
*
|
21
21
|
* @returns {string|null}
|
22
22
|
*/
|
23
|
-
|
24
|
-
get progress():
|
25
|
-
bytesLoaded: number;
|
26
|
-
size: number;
|
27
|
-
loaded: boolean;
|
28
|
-
};
|
23
|
+
getObjectURL(): string | null;
|
24
|
+
get progress(): import("../network-loader/typedef.js").LoadingProgress;
|
29
25
|
/**
|
30
26
|
* Get optimal image variant
|
31
27
|
*
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/** @typedef {import('./typedef.js').ImageMeta} ImageMeta */
|
2
2
|
|
3
|
-
// import * as expect from '
|
3
|
+
// import * as expect from '../../../util/expect/index.js';
|
4
4
|
|
5
5
|
import { untrack } from 'svelte';
|
6
6
|
|
@@ -90,13 +90,13 @@ export default class ImageVariantsLoader {
|
|
90
90
|
*
|
91
91
|
* @returns {string|null}
|
92
92
|
*/
|
93
|
-
|
93
|
+
getObjectURL() {
|
94
94
|
// Example usage:
|
95
95
|
//
|
96
96
|
// $effect(() => {
|
97
97
|
// if (variantsLoader.loaded) {
|
98
98
|
// // @ts-ignore
|
99
|
-
// imageUrl = variantsLoader.
|
99
|
+
// imageUrl = variantsLoader.getObjectURL();
|
100
100
|
// }
|
101
101
|
|
102
102
|
// return () => {
|
@@ -1,9 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
CONTENT_TYPE,
|
3
|
-
CONTENT_LENGTH
|
4
|
-
} from '@hkdigital/lib-sveltekit/constants/http/index.js';
|
1
|
+
import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
|
5
2
|
|
6
|
-
import { IMAGE_PNG } from '
|
3
|
+
import { IMAGE_PNG } from '../../../constants/mime/image.js';
|
7
4
|
|
8
5
|
/**
|
9
6
|
* A minimal 1x1 black PNG encoded as base64
|
@@ -47,6 +47,7 @@ export default class LoadingStateMachine extends FiniteStateMachine {
|
|
47
47
|
},
|
48
48
|
[STATE_LOADING]: {
|
49
49
|
_enter: () => {
|
50
|
+
// console.log('LoadingStateMachine: enter LOADING');
|
50
51
|
this.onenter?.(STATE_LOADING);
|
51
52
|
},
|
52
53
|
[CANCEL]: STATE_CANCELLED,
|
@@ -55,6 +56,7 @@ export default class LoadingStateMachine extends FiniteStateMachine {
|
|
55
56
|
},
|
56
57
|
[STATE_LOADED]: {
|
57
58
|
_enter: () => {
|
59
|
+
// console.log('LoadingStateMachine: enter LOADED');
|
58
60
|
this.onenter?.(STATE_LOADED);
|
59
61
|
},
|
60
62
|
[LOAD]: STATE_LOADING,
|
@@ -14,7 +14,7 @@ export default class NetworkLoader {
|
|
14
14
|
url: string;
|
15
15
|
});
|
16
16
|
_state: LoadingStateMachine;
|
17
|
-
state:
|
17
|
+
state: any;
|
18
18
|
initial: boolean;
|
19
19
|
loaded: boolean;
|
20
20
|
/** @type {string|null} */
|
@@ -30,11 +30,8 @@ export default class NetworkLoader {
|
|
30
30
|
_headers: Headers | null;
|
31
31
|
/** @type {ArrayBuffer|null} */
|
32
32
|
_buffer: ArrayBuffer | null;
|
33
|
-
|
34
|
-
|
35
|
-
size: number;
|
36
|
-
loaded: boolean;
|
37
|
-
};
|
33
|
+
/** @type {import('./typedef.js').LoadingProgress} */
|
34
|
+
progress: import("./typedef.js").LoadingProgress;
|
38
35
|
/** @type {null|(()=>void)} */
|
39
36
|
_abortLoading: null | (() => void);
|
40
37
|
/**
|
@@ -86,9 +83,9 @@ export default class NetworkLoader {
|
|
86
83
|
*
|
87
84
|
* @note the objectURL should be revoked when no longer used
|
88
85
|
*
|
89
|
-
* @returns {string
|
86
|
+
* @returns {string}
|
90
87
|
*/
|
91
|
-
|
88
|
+
getObjectURL(): string;
|
92
89
|
#private;
|
93
90
|
}
|
94
91
|
import { LoadingStateMachine } from '../loading-state-machine/index.js';
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { CONTENT_TYPE } from '
|
1
|
+
import { CONTENT_TYPE } from '../../../constants/http/index.js';
|
2
2
|
|
3
3
|
import {
|
4
4
|
LoadingStateMachine,
|
@@ -16,9 +16,9 @@ import {
|
|
16
16
|
INITIAL
|
17
17
|
} from '../loading-state-machine/index.js';
|
18
18
|
|
19
|
-
import * as expect from '
|
19
|
+
import * as expect from '../../../util/expect/index.js';
|
20
20
|
|
21
|
-
import { httpGet, loadResponseBuffer } from '
|
21
|
+
import { httpGet, loadResponseBuffer } from '../../../util/http/index.js';
|
22
22
|
|
23
23
|
import { ERROR_NOT_LOADED, ERROR_TRANSFERRED } from './constants.js';
|
24
24
|
|
@@ -28,17 +28,19 @@ import { ERROR_NOT_LOADED, ERROR_TRANSFERRED } from './constants.js';
|
|
28
28
|
* - Loaded data can be transferred to an AudioBufferSourceNode
|
29
29
|
*/
|
30
30
|
export default class NetworkLoader {
|
31
|
+
// _state = $state(new LoadingStateMachine());
|
31
32
|
_state = new LoadingStateMachine();
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
state = $derived.by(() => {
|
35
|
+
return this._state.current;
|
36
|
+
});
|
35
37
|
|
36
38
|
initial = $derived.by(() => {
|
37
|
-
return this.
|
39
|
+
return this._state.current === STATE_INITIAL;
|
38
40
|
});
|
39
41
|
|
40
42
|
loaded = $derived.by(() => {
|
41
|
-
return this.
|
43
|
+
return this._state.current === STATE_LOADED;
|
42
44
|
});
|
43
45
|
|
44
46
|
/** @type {string|null} */
|
@@ -60,6 +62,8 @@ export default class NetworkLoader {
|
|
60
62
|
_buffer = null;
|
61
63
|
|
62
64
|
// Export state property as readonly
|
65
|
+
|
66
|
+
/** @type {import('./typedef.js').LoadingProgress} */
|
63
67
|
progress = $derived.by(() => {
|
64
68
|
return {
|
65
69
|
bytesLoaded: this._bytesLoaded,
|
@@ -84,11 +88,15 @@ export default class NetworkLoader {
|
|
84
88
|
|
85
89
|
const state = this._state;
|
86
90
|
|
87
|
-
|
91
|
+
//
|
92
|
+
// ISSUE: $effect is not triggered by this._state changes,
|
93
|
+
// using onenter instead
|
94
|
+
//
|
95
|
+
this._state.onenter = () => {
|
88
96
|
switch (state.current) {
|
89
97
|
case STATE_LOADING:
|
90
98
|
{
|
91
|
-
// console.log('NetworkLoader:loading');
|
99
|
+
// console.log('**** NetworkLoader:loading');
|
92
100
|
this.#load();
|
93
101
|
}
|
94
102
|
break;
|
@@ -125,15 +133,14 @@ export default class NetworkLoader {
|
|
125
133
|
}
|
126
134
|
break;
|
127
135
|
} // end switch
|
128
|
-
|
129
|
-
this.state = state.current;
|
130
|
-
});
|
136
|
+
};
|
131
137
|
}
|
132
138
|
|
133
139
|
/**
|
134
140
|
* Start loading all network data
|
135
141
|
*/
|
136
142
|
load() {
|
143
|
+
// console.log('NetworkLoader: load() called');
|
137
144
|
this._state.send(LOAD);
|
138
145
|
}
|
139
146
|
|
@@ -220,16 +227,16 @@ export default class NetworkLoader {
|
|
220
227
|
*
|
221
228
|
* @note the objectURL should be revoked when no longer used
|
222
229
|
*
|
223
|
-
* @returns {string
|
230
|
+
* @returns {string}
|
224
231
|
*/
|
225
|
-
|
232
|
+
getObjectURL() {
|
226
233
|
//
|
227
234
|
// Example usage:
|
228
235
|
//
|
229
236
|
// $effect(() => {
|
230
237
|
// if (loader.loaded) {
|
231
238
|
// // @ts-ignore
|
232
|
-
// objectUrl = loader.
|
239
|
+
// objectUrl = loader.getObjectURL();
|
233
240
|
// }
|
234
241
|
//
|
235
242
|
// return () => {
|
@@ -240,9 +247,7 @@ export default class NetworkLoader {
|
|
240
247
|
// };
|
241
248
|
// });
|
242
249
|
|
243
|
-
|
244
|
-
|
245
|
-
return blob ? URL.createObjectURL(blob) : null;
|
250
|
+
return URL.createObjectURL(this.getBlob());
|
246
251
|
}
|
247
252
|
|
248
253
|
/**
|
@@ -251,7 +256,7 @@ export default class NetworkLoader {
|
|
251
256
|
*/
|
252
257
|
async #load() {
|
253
258
|
try {
|
254
|
-
// console.log('
|
259
|
+
// console.log('>>>> NetworkLoader:#load', this._url);
|
255
260
|
|
256
261
|
if (this._abortLoading) {
|
257
262
|
// console.log('Abort loading');
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { CONTENT_TYPE, CONTENT_LENGTH } from '
|
1
|
+
import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
|
2
2
|
|
3
|
-
import { OCTET_STREAM } from '
|
3
|
+
import { OCTET_STREAM } from '../../../constants/mime/application.js';
|
4
4
|
|
5
5
|
const BASE64_DATA =
|
6
6
|
'UklGRnwAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
|
@@ -0,0 +1,242 @@
|
|
1
|
+
<script>
|
2
|
+
import { onMount } from 'svelte';
|
3
|
+
|
4
|
+
import { ImageLoader } from '../../classes/svelte/image/index.js';
|
5
|
+
|
6
|
+
import { toSingleImageMeta } from '../../util/image/index.js';
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @example
|
10
|
+
* import { ImageBox } from '/path/to/ImageBox/index.js';
|
11
|
+
*
|
12
|
+
* // @note 'as=metadata' is set by the preset
|
13
|
+
* import NeonLightsOff from '../../img/NeonLightsOff.jpg?preset=gradient';
|
14
|
+
*
|
15
|
+
* <!-- Example that fits in an outer-box -->
|
16
|
+
*
|
17
|
+
* <div class="outer-box">
|
18
|
+
* <ImageBox image={ArmyGreen} fit="contain" position="center center" />
|
19
|
+
* </div>
|
20
|
+
*
|
21
|
+
* <!-- Examples that has have width, height or aspect set -->
|
22
|
+
*
|
23
|
+
* <ImageBox
|
24
|
+
* image={ArmyGreen}
|
25
|
+
* fit="contain"
|
26
|
+
* position="center center"
|
27
|
+
* width="w-[200px]"
|
28
|
+
* height="h-[200px]"
|
29
|
+
* classes="border-8 border-green-500"
|
30
|
+
* />
|
31
|
+
*
|
32
|
+
* <ImageBox
|
33
|
+
* image={ArmyGreen}
|
34
|
+
* fit="contain"
|
35
|
+
* position="center center"
|
36
|
+
* width="w-[200px]"
|
37
|
+
* aspect="aspect-square"
|
38
|
+
* classes="border-8 border-green-500"
|
39
|
+
* />
|
40
|
+
*
|
41
|
+
* <ImageBox
|
42
|
+
* image={ArmyGreen}
|
43
|
+
* fit="contain"
|
44
|
+
* position="center center"
|
45
|
+
* height="h-[200px]"
|
46
|
+
* aspect="aspect-square"
|
47
|
+
* classes="border-8 border-green-500"
|
48
|
+
* />
|
49
|
+
*
|
50
|
+
* <!-- Or hack it using !important -->
|
51
|
+
*
|
52
|
+
* <ImageBox
|
53
|
+
* image={ArmyGreen}
|
54
|
+
* fit="contain"
|
55
|
+
* position="center center"
|
56
|
+
* classes="!w-[200px] !h-[200px] border-8 border-green-500"
|
57
|
+
* />
|
58
|
+
*/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @typedef {import('./typedef.js').ObjectFit} ObjectFit
|
62
|
+
* @typedef {import('./typedef.js').ObjectPosition} ObjectPosition
|
63
|
+
*
|
64
|
+
* @typedef {import('../../classes/svelte/network-loader/typedef.js').LoadingProgress} LoadingProgress
|
65
|
+
*
|
66
|
+
* @typedef {import('../../config/typedef.js').ImageMeta} ImageMeta
|
67
|
+
*
|
68
|
+
* @typedef {Object} Props
|
69
|
+
* @property {string} [base] - Base styling class
|
70
|
+
* @property {string} [bg] - Background styling class
|
71
|
+
* @property {string} [classes] - Additional CSS classes
|
72
|
+
* @property {string} [width] - Width of the image container
|
73
|
+
* @property {string} [height] - Height of the image container
|
74
|
+
* @property {string} [aspect] - Aspect ratio of the image container
|
75
|
+
* @property {string} [overflow] - Overflow behavior
|
76
|
+
* @property {ObjectFit} [fit] - Object-fit property
|
77
|
+
* @property {ObjectPosition} [position] - Object-position property
|
78
|
+
*
|
79
|
+
* @property {ImageMeta|ImageMeta[]} [imageMeta]
|
80
|
+
* Image metadata, TODO: array of image metadata for responsive image
|
81
|
+
*
|
82
|
+
* @property {ImageLoader} [imageLoader]
|
83
|
+
* Image loader
|
84
|
+
*
|
85
|
+
* @property {string} [alt] - Alternative text for the image
|
86
|
+
* @property {() => LoadingProgress} [onProgress] - Progress callback function
|
87
|
+
* @property {*} [attr] - Additional arbitrary attributes
|
88
|
+
*/
|
89
|
+
|
90
|
+
/** @type {Props} */
|
91
|
+
let {
|
92
|
+
// Style
|
93
|
+
base,
|
94
|
+
bg,
|
95
|
+
classes,
|
96
|
+
width,
|
97
|
+
height,
|
98
|
+
aspect,
|
99
|
+
overflow = 'overflow-clip',
|
100
|
+
|
101
|
+
// Fitting and positioning of image in its container
|
102
|
+
fit = 'contain',
|
103
|
+
position = 'left top',
|
104
|
+
|
105
|
+
// Image meta data
|
106
|
+
imageMeta,
|
107
|
+
|
108
|
+
imageLoader,
|
109
|
+
|
110
|
+
alt = '',
|
111
|
+
|
112
|
+
// Attributes
|
113
|
+
...attrs
|
114
|
+
} = $props();
|
115
|
+
|
116
|
+
// let show = $state(false);
|
117
|
+
|
118
|
+
/** @type {HTMLDivElement|undefined} */
|
119
|
+
let imgBoxElem = $state();
|
120
|
+
|
121
|
+
/** @type {HTMLImageElement|undefined} */
|
122
|
+
let imgElem = $state();
|
123
|
+
|
124
|
+
let aspectStyle = $state('');
|
125
|
+
|
126
|
+
// > Loading
|
127
|
+
|
128
|
+
let metaWidth = $state(0);
|
129
|
+
let metaHeight = $state(0);
|
130
|
+
|
131
|
+
let imageMeta_ = $state();
|
132
|
+
|
133
|
+
$effect(() => {
|
134
|
+
if( imageMeta )
|
135
|
+
{
|
136
|
+
imageMeta_ = toSingleImageMeta( imageMeta );
|
137
|
+
}
|
138
|
+
});
|
139
|
+
|
140
|
+
$effect(() => {
|
141
|
+
//
|
142
|
+
// Set meta width and height
|
143
|
+
//
|
144
|
+
if (imageMeta_) {
|
145
|
+
if (imageMeta_.width) {
|
146
|
+
metaWidth = imageMeta_.width;
|
147
|
+
}
|
148
|
+
|
149
|
+
if (imageMeta_.height) {
|
150
|
+
metaHeight = imageMeta_.height;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
});
|
154
|
+
|
155
|
+
/** @type {ImageLoader|undefined} */
|
156
|
+
let imageLoader_ = $state();
|
157
|
+
|
158
|
+
$effect( () => {
|
159
|
+
//
|
160
|
+
// User supplied imageLoader instead of imageMeta
|
161
|
+
//
|
162
|
+
if( !imageMeta && imageLoader && !imageLoader_ )
|
163
|
+
{
|
164
|
+
imageLoader_ = imageLoader;
|
165
|
+
imageMeta_ = imageLoader.imageMeta;
|
166
|
+
}
|
167
|
+
} );
|
168
|
+
|
169
|
+
/** @type {string|null} */
|
170
|
+
let objectUrl = $state(null);
|
171
|
+
|
172
|
+
$effect(() => {
|
173
|
+
//
|
174
|
+
// Create image loader
|
175
|
+
//
|
176
|
+
if (imageMeta_ && !imageLoader_) {
|
177
|
+
imageLoader_ = new ImageLoader({ imageMeta: imageMeta_ });
|
178
|
+
}
|
179
|
+
});
|
180
|
+
|
181
|
+
$effect(() => {
|
182
|
+
//
|
183
|
+
// Start loading if imageLoader_ is in state 'initial'
|
184
|
+
//
|
185
|
+
// TODO: implement lazy flag
|
186
|
+
//
|
187
|
+
if (imageLoader_?.initial) {
|
188
|
+
imageLoader_.load();
|
189
|
+
}
|
190
|
+
});
|
191
|
+
|
192
|
+
$effect(() => {
|
193
|
+
//
|
194
|
+
// Get objectUrl when the image has finished loading
|
195
|
+
//
|
196
|
+
if (imageLoader_.loaded) {
|
197
|
+
// @ts-ignore
|
198
|
+
objectUrl = imageLoader_.getObjectURL();
|
199
|
+
}
|
200
|
+
|
201
|
+
return () => {
|
202
|
+
if (objectUrl) {
|
203
|
+
URL.revokeObjectURL(objectUrl);
|
204
|
+
objectUrl = null;
|
205
|
+
}
|
206
|
+
};
|
207
|
+
});
|
208
|
+
|
209
|
+
</script>
|
210
|
+
|
211
|
+
<div
|
212
|
+
data-image-box
|
213
|
+
bind:this={imgBoxElem}
|
214
|
+
class="{base} {bg} {aspect} {overflow} {width} {height} {classes}"
|
215
|
+
style:--fit={fit}
|
216
|
+
style:--pos={position}
|
217
|
+
style:aspect-ratio={aspectStyle}
|
218
|
+
style:width={width || (height && aspect) ? undefined : '100%'}
|
219
|
+
style:height={height || (width && aspect) ? undefined : '100%'}
|
220
|
+
{...attrs}
|
221
|
+
>
|
222
|
+
{#if metaWidth && metaHeight}
|
223
|
+
<img src={objectUrl} {alt} width={metaWidth} height={metaHeight} />
|
224
|
+
{/if}
|
225
|
+
</div>
|
226
|
+
|
227
|
+
<style>
|
228
|
+
[data-image-box] {
|
229
|
+
max-width: 100%;
|
230
|
+
max-height: 100%;
|
231
|
+
}
|
232
|
+
|
233
|
+
img {
|
234
|
+
display: block;
|
235
|
+
width: 100%;
|
236
|
+
height: 100%;
|
237
|
+
max-width: 100%;
|
238
|
+
max-height: 100%;
|
239
|
+
object-fit: var(--fit);
|
240
|
+
object-position: var(--pos);
|
241
|
+
}
|
242
|
+
</style>
|
@@ -0,0 +1,60 @@
|
|
1
|
+
export default ImageBox;
|
2
|
+
declare const ImageBox: import("svelte").Component<{
|
3
|
+
/**
|
4
|
+
* - Base styling class
|
5
|
+
*/
|
6
|
+
base?: string;
|
7
|
+
/**
|
8
|
+
* - Background styling class
|
9
|
+
*/
|
10
|
+
bg?: string;
|
11
|
+
/**
|
12
|
+
* - Additional CSS classes
|
13
|
+
*/
|
14
|
+
classes?: string;
|
15
|
+
/**
|
16
|
+
* - Width of the image container
|
17
|
+
*/
|
18
|
+
width?: string;
|
19
|
+
/**
|
20
|
+
* - Height of the image container
|
21
|
+
*/
|
22
|
+
height?: string;
|
23
|
+
/**
|
24
|
+
* - Aspect ratio of the image container
|
25
|
+
*/
|
26
|
+
aspect?: string;
|
27
|
+
/**
|
28
|
+
* - Overflow behavior
|
29
|
+
*/
|
30
|
+
overflow?: string;
|
31
|
+
/**
|
32
|
+
* - Object-fit property
|
33
|
+
*/
|
34
|
+
fit?: import("./typedef.js").ObjectFit;
|
35
|
+
/**
|
36
|
+
* - Object-position property
|
37
|
+
*/
|
38
|
+
position?: import("./typedef.js").ObjectPosition;
|
39
|
+
/**
|
40
|
+
* Image metadata, TODO: array of image metadata for responsive image
|
41
|
+
*/
|
42
|
+
imageMeta?: import("../../config/typedef.js").ImageMeta | import("../../config/typedef.js").ImageMeta[];
|
43
|
+
/**
|
44
|
+
* Image loader
|
45
|
+
*/
|
46
|
+
imageLoader?: ImageLoader;
|
47
|
+
/**
|
48
|
+
* - Alternative text for the image
|
49
|
+
*/
|
50
|
+
alt?: string;
|
51
|
+
/**
|
52
|
+
* - Progress callback function
|
53
|
+
*/
|
54
|
+
onProgress?: () => import("../../classes/svelte/network-loader/typedef.js").LoadingProgress;
|
55
|
+
/**
|
56
|
+
* - Additional arbitrary attributes
|
57
|
+
*/
|
58
|
+
attr?: any;
|
59
|
+
}, {}, "">;
|
60
|
+
import { ImageLoader } from '../../classes/svelte/image/index.js';
|
@@ -0,0 +1,4 @@
|
|
1
|
+
declare const _default: {};
|
2
|
+
export default _default;
|
3
|
+
export type ObjectFit = ("contain" | "cover" | "fill" | "none" | "scale-down");
|
4
|
+
export type ObjectPosition = ("left" | "center" | "right" | "top" | "bottom" | "left top" | "left center" | "left bottom" | "center top" | "center center" | "center bottom" | "right top" | "right center" | "right bottom" | `${number}% ${number}%` | `${number}px ${number}px`);
|
@@ -0,0 +1,32 @@
|
|
1
|
+
/**
|
2
|
+
* @typedef {(
|
3
|
+
* 'contain' |
|
4
|
+
* 'cover' |
|
5
|
+
* 'fill' |
|
6
|
+
* 'none' |
|
7
|
+
* 'scale-down'
|
8
|
+
* )} ObjectFit
|
9
|
+
*/
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @typedef {(
|
13
|
+
* 'left' |
|
14
|
+
* 'center' |
|
15
|
+
* 'right' |
|
16
|
+
* 'top' |
|
17
|
+
* 'bottom' |
|
18
|
+
* 'left top' |
|
19
|
+
* 'left center' |
|
20
|
+
* 'left bottom' |
|
21
|
+
* 'center top' |
|
22
|
+
* 'center center' |
|
23
|
+
* 'center bottom' |
|
24
|
+
* 'right top' |
|
25
|
+
* 'right center' |
|
26
|
+
* 'right bottom' |
|
27
|
+
* `${number}% ${number}%` |
|
28
|
+
* `${number}px ${number}px`
|
29
|
+
* )} ObjectPosition
|
30
|
+
*/
|
31
|
+
|
32
|
+
export default {};
|
@@ -5,7 +5,7 @@ const DEFAULT_PRESETS = {
|
|
5
5
|
format: 'avif',
|
6
6
|
quality: '90'
|
7
7
|
},
|
8
|
-
|
8
|
+
render: {
|
9
9
|
format: 'jpg',
|
10
10
|
quality: '95',
|
11
11
|
as: 'metadata'
|
@@ -15,6 +15,11 @@ const DEFAULT_PRESETS = {
|
|
15
15
|
quality: '95',
|
16
16
|
as: 'metadata'
|
17
17
|
},
|
18
|
+
gradient: {
|
19
|
+
format: 'jpg',
|
20
|
+
quality: '95',
|
21
|
+
as: 'metadata'
|
22
|
+
},
|
18
23
|
drawing: {
|
19
24
|
format: 'avif',
|
20
25
|
quality: '90',
|
@@ -1,10 +1,10 @@
|
|
1
|
+
// export interface ImageMeta {
|
2
|
+
// src: string;
|
3
|
+
// width: number;
|
4
|
+
// height: number;
|
5
|
+
// }
|
1
6
|
|
2
|
-
|
3
|
-
interface ImageMeta {
|
4
|
-
src: string;
|
5
|
-
width?: number;
|
6
|
-
height?: number;
|
7
|
-
}
|
7
|
+
type ImageMeta = import('./typedef.js').ImageMeta;
|
8
8
|
|
9
9
|
declare module '*?responsive' {
|
10
10
|
const out: ImageMeta[];
|
@@ -16,52 +16,62 @@ declare module '*&responsive' {
|
|
16
16
|
export default out;
|
17
17
|
}
|
18
18
|
|
19
|
-
declare module '*?preset=
|
20
|
-
const out: ImageMeta|ImageMeta[];
|
19
|
+
declare module '*?preset=photo' {
|
20
|
+
const out: ImageMeta | ImageMeta[];
|
21
21
|
export default out;
|
22
22
|
}
|
23
23
|
|
24
|
-
declare module '*&preset=
|
25
|
-
const out: ImageMeta|ImageMeta[];
|
24
|
+
declare module '*&preset=photo' {
|
25
|
+
const out: ImageMeta | ImageMeta[];
|
26
26
|
export default out;
|
27
27
|
}
|
28
28
|
|
29
|
-
declare module '*?preset=
|
30
|
-
const out: ImageMeta|ImageMeta[];
|
29
|
+
declare module '*?preset=render' {
|
30
|
+
const out: ImageMeta | ImageMeta[];
|
31
31
|
export default out;
|
32
32
|
}
|
33
33
|
|
34
|
-
declare module '*&preset=
|
35
|
-
const out: ImageMeta|ImageMeta[];
|
34
|
+
declare module '*&preset=render' {
|
35
|
+
const out: ImageMeta | ImageMeta[];
|
36
|
+
export default out;
|
37
|
+
}
|
38
|
+
|
39
|
+
declare module '*?preset=gradient' {
|
40
|
+
const out: ImageMeta | ImageMeta[];
|
41
|
+
export default out;
|
42
|
+
}
|
43
|
+
|
44
|
+
declare module '*&preset=gradient' {
|
45
|
+
const out: ImageMeta | ImageMeta[];
|
36
46
|
export default out;
|
37
47
|
}
|
38
48
|
|
39
49
|
declare module '*?preset=drawing' {
|
40
|
-
const out: ImageMeta|ImageMeta[];
|
50
|
+
const out: ImageMeta | ImageMeta[];
|
41
51
|
export default out;
|
42
52
|
}
|
43
53
|
|
44
54
|
declare module '*&preset=drawing' {
|
45
|
-
const out: ImageMeta|ImageMeta[];
|
55
|
+
const out: ImageMeta | ImageMeta[];
|
46
56
|
export default out;
|
47
57
|
}
|
48
58
|
|
49
59
|
declare module '*?preset=savedata' {
|
50
|
-
const out: ImageMeta|ImageMeta[];
|
60
|
+
const out: ImageMeta | ImageMeta[];
|
51
61
|
export default out;
|
52
62
|
}
|
53
63
|
|
54
64
|
declare module '*&preset=savedata' {
|
55
|
-
const out: ImageMeta|ImageMeta[];
|
65
|
+
const out: ImageMeta | ImageMeta[];
|
56
66
|
export default out;
|
57
67
|
}
|
58
68
|
|
59
69
|
declare module '*?preset=blur' {
|
60
|
-
const out: ImageMeta|ImageMeta[];
|
70
|
+
const out: ImageMeta | ImageMeta[];
|
61
71
|
export default out;
|
62
72
|
}
|
63
73
|
|
64
74
|
declare module '*&preset=blur' {
|
65
|
-
const out: ImageMeta|ImageMeta[];
|
75
|
+
const out: ImageMeta | ImageMeta[];
|
66
76
|
export default out;
|
67
|
-
}
|
77
|
+
}
|
package/dist/util/http/mocks.js
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* Returns the unchanged image meta object or the last item of
|
3
|
+
* an array of ImageMeta objects. This is assumed to be a list
|
4
|
+
* of sorted responsive image formats, so it should be the
|
5
|
+
* largest image.
|
6
|
+
*
|
7
|
+
* @param {ImageMeta|ImageMeta[]} imageMeta
|
8
|
+
*/
|
9
|
+
export function toSingleImageMeta(imageMeta: ImageMeta | ImageMeta[]): import("../../config/typedef").ImageMeta;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/**
|
2
|
+
* Returns the unchanged image meta object or the last item of
|
3
|
+
* an array of ImageMeta objects. This is assumed to be a list
|
4
|
+
* of sorted responsive image formats, so it should be the
|
5
|
+
* largest image.
|
6
|
+
*
|
7
|
+
* @param {ImageMeta|ImageMeta[]} imageMeta
|
8
|
+
*/
|
9
|
+
export function toSingleImageMeta(imageMeta) {
|
10
|
+
if (Array.isArray(imageMeta)) {
|
11
|
+
if (!imageMeta.length) {
|
12
|
+
throw new Error('List of ImageMeta objects is empty');
|
13
|
+
}
|
14
|
+
imageMeta = imageMeta[imageMeta.length - 1];
|
15
|
+
}
|
16
|
+
|
17
|
+
if (typeof imageMeta === 'object') {
|
18
|
+
return imageMeta;
|
19
|
+
} else if (!imageMeta) {
|
20
|
+
throw new Error('Missing [imageMeta]');
|
21
|
+
}
|
22
|
+
|
23
|
+
throw new Error('Invalid value for parameter [imageMeta]');
|
24
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hkdigital/lib-sveltekit",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.92",
|
4
4
|
"author": "Jens Kleinhout, HKdigital (https://hkdigital.nl)",
|
5
5
|
"license": "ISC",
|
6
6
|
"repository": {
|
@@ -17,19 +17,19 @@
|
|
17
17
|
],
|
18
18
|
"scripts": {
|
19
19
|
"dev": "vite dev",
|
20
|
-
"build": "vite build && npm run package",
|
20
|
+
"build": "cross-env vite build && npm run package",
|
21
21
|
"preview": "vite preview",
|
22
|
-
"package": "svelte-kit sync && svelte-package && publint",
|
23
|
-
"prepublishOnly": "npm run package",
|
24
|
-
"publish:npm": "npm version patch && npm publish --access public && git push",
|
25
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
26
|
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
22
|
+
"package": "cross-env svelte-kit sync && svelte-package && publint",
|
23
|
+
"prepublishOnly": "cross-env npm run package",
|
24
|
+
"publish:npm": "cross-env npm version patch && npm publish --access public && git push",
|
25
|
+
"check": "cross-env svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
26
|
+
"check:watch": "cross-env svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
27
27
|
"format": "prettier --write .",
|
28
|
-
"lint": "prettier --check . && eslint .",
|
28
|
+
"lint": "cross-env prettier --check . && eslint .",
|
29
29
|
"test:unit": "vitest",
|
30
|
-
"test": "npm run test:unit -- --run && npm run test:e2e",
|
30
|
+
"test": "cross-env npm run test:unit -- --run && npm run test:e2e",
|
31
31
|
"test:e2e": "playwright test",
|
32
|
-
"upgrade:all": "ncu -u && pnpm install"
|
32
|
+
"upgrade:all": "cross-env ncu -u && pnpm install"
|
33
33
|
},
|
34
34
|
"files": [
|
35
35
|
"dist",
|
@@ -48,6 +48,7 @@
|
|
48
48
|
"./*": "./dist/*"
|
49
49
|
},
|
50
50
|
"peerDependencies": {
|
51
|
+
"@sveltejs/kit": "^2.15.2",
|
51
52
|
"svelte": "^5.0.0"
|
52
53
|
},
|
53
54
|
"devDependencies": {
|
@@ -57,25 +58,26 @@
|
|
57
58
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
58
59
|
"@types/eslint": "^9.6.1",
|
59
60
|
"autoprefixer": "^10.4.20",
|
60
|
-
"
|
61
|
-
"eslint
|
61
|
+
"cross-env": "^7.0.3",
|
62
|
+
"eslint": "^9.18.0",
|
63
|
+
"eslint-config-prettier": "^10.0.1",
|
62
64
|
"eslint-plugin-svelte": "^2.46.1",
|
63
65
|
"globals": "^15.14.0",
|
64
66
|
"jsdom": "^26.0.0",
|
65
67
|
"prettier": "^3.4.2",
|
66
|
-
"prettier-plugin-svelte": "^3.3.
|
68
|
+
"prettier-plugin-svelte": "^3.3.3",
|
67
69
|
"prettier-plugin-tailwindcss": "^0.6.9",
|
68
|
-
"publint": "^0.3.
|
70
|
+
"publint": "^0.3.2",
|
69
71
|
"standardized-audio-context-mock": "^9.7.15",
|
70
|
-
"svelte": "^5.17.
|
71
|
-
"svelte-check": "^4.1.
|
72
|
+
"svelte": "^5.17.5",
|
73
|
+
"svelte-check": "^4.1.4",
|
72
74
|
"tailwindcss": "^3.4.17",
|
73
75
|
"typescript": "^5.7.3",
|
74
76
|
"vite": "^6.0.7",
|
77
|
+
"vite-imagetools": "^7.0.5",
|
75
78
|
"vitest": "^2.1.8"
|
76
79
|
},
|
77
80
|
"dependencies": {
|
78
|
-
"@sveltejs/kit": "^2.15.2",
|
79
81
|
"runed": "^0.23.0",
|
80
82
|
"valibot": "^0.42.1",
|
81
83
|
"zod": "^3.24.1"
|