tiny-essentials 1.29.0 → 1.29.2
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/changelog/1/29/1.md +11 -0
- package/changelog/1/29/2.md +82 -0
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyFetchLoader.min.js +1 -0
- package/dist/v1/TinyImageLoader.min.js +1 -0
- package/dist/v1/TinyMediaCache.min.js +1 -0
- package/dist/v1/TinyMediaLoader.min.js +1 -0
- package/dist/v1/basics/index.cjs +5 -0
- package/dist/v1/basics/index.d.mts +2 -1
- package/dist/v1/basics/index.d.mts.map +1 -1
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/basics/media/youtube.cjs +275 -0
- package/dist/v1/basics/media/youtube.d.mts +107 -0
- package/dist/v1/basics/media/youtube.d.mts.map +1 -0
- package/dist/v1/basics/media/youtube.mjs +214 -0
- package/dist/v1/index.cjs +13 -0
- package/dist/v1/index.d.mts +6 -1
- package/dist/v1/index.d.mts.map +1 -1
- package/dist/v1/index.mjs +7 -2
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.cjs +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts.map +1 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.mjs +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/index.cjs +0 -8
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts +0 -8
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts.map +1 -1
- package/dist/v1/libs/fs/plugins/OPFS/index.mjs +0 -8
- package/dist/v1/libs/html/TinyHtml.cjs +1 -1
- package/dist/v1/libs/html/TinyHtml.d.mts +2 -2
- package/dist/v1/libs/html/TinyHtml.d.mts.map +1 -1
- package/dist/v1/libs/html/TinyHtml.mjs +1 -1
- package/dist/v1/libs/html/loader/TinyMediaLoader.cjs +1999 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.d.mts +999 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.mjs +1852 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.cjs +77 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.d.mts +103 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.mjs +67 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.cjs +630 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.d.mts +138 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.mjs +576 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.cjs +70 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.d.mts +100 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.mjs +60 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.cjs +946 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.d.mts +67 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.mjs +896 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.cjs +225 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.d.mts +149 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.mjs +197 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.cjs +1454 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.d.mts +200 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.mjs +1317 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.cjs +668 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.d.mts +83 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.mjs +626 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.cjs +277 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.d.mts +118 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.mjs +247 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.cjs +128 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.d.mts +49 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.mjs +116 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.cjs +796 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.d.mts +354 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.mjs +734 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.cjs +302 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.d.mts +256 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.mjs +280 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.cjs +194 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.d.mts +138 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.mjs +175 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.cjs +359 -55
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts +64 -6
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyPkgExportValidator.mjs +320 -57
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.cjs +0 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts +0 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts.map +1 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.mjs +0 -1
- package/dist/v1/webTemplates/bootstrap/5.3/scss/background/_background-grid.scss +15 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/buttons/_buttons-contrast.scss +208 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/buttons/_buttons-ghost.scss +89 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/icon/_cube-icon.scss +65 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/icon/_sphere-pulse.scss +39 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_badges.scss +90 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_bootstrap-overrides.scss +495 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_buttons.scss +390 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_colors.scss +213 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_effects.scss +153 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_forms-tones.scss +69 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_forms.scss +323 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_global.scss +31 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_links.scss +47 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_tables.scss +25 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_theme.scss +21 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_tokens.scss +161 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_utilities.scss +81 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_variables.scss +63 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_form-tone-mixins.scss +236 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_sizing.scss +68 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_tone-mixins.scss +392 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_typography.scss +112 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/background/_tiny_gradient_1.scss +131 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/colors/_pink.scss +47 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.cjs +2 -2
- package/docs/v1/Exports.md +33 -2
- package/docs/v1/README.md +9 -0
- package/docs/v1/basics/youtube.md +204 -0
- package/docs/v1/libs/html/loader/TinyFetchLoader.md +114 -0
- package/docs/v1/libs/html/loader/TinyImageLoader.md +141 -0
- package/docs/v1/libs/html/loader/TinyMediaCache.md +166 -0
- package/docs/v1/libs/html/loader/TinyMediaLoader.md +300 -0
- package/docs/v1/libs/tools/TinyPkgExportValidator.md +55 -0
- package/docs/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters.md +0 -4
- package/docs/v1/webTemplates/bootstrap/5.3/DeepStrap.md +177 -0
- package/package.json +281 -17
- /package/dist/v1/webTemplates/bootstrap/5.3/scss/input/{Placeholder-Colors-Fix.scss → _placeholder-colors-fix.scss} +0 -0
- /package/dist/v1/webTemplates/bootstrap/5.3/scss/spacing/{Spacing-Plus.scss → _spacing-plus.scss} +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var TinyMediaLoader = require('../TinyMediaLoader.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview Generic file loader for external resources.
|
|
7
|
+
* Uses the native `fetch` API by default, but accepts any implementation
|
|
8
|
+
* that follows the same contract: `(input, init) => Promise<Response>`.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The response body types supported by the loader.
|
|
13
|
+
* @typedef {'blob'|'arraybuffer'|'text'|'json'} FetchResponseType
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Describes the configuration accepted by the {@link TinyFetchLoader} constructor.
|
|
18
|
+
* @typedef {Object} FetchLoaderOptions
|
|
19
|
+
* @property {string} [src] - The file URL.
|
|
20
|
+
* @property {RequestInit} [init] - The fetch options (method, headers, body, credentials, mode, cache, redirect, referrer, referrerPolicy, integrity, keepalive).
|
|
21
|
+
* @property {typeof fetch} [fetch] - A custom fetch implementation.
|
|
22
|
+
* @property {FetchResponseType} [responseType] - The response body type (default `'blob'`).
|
|
23
|
+
* @property {number} [timeout] - Maximum time in milliseconds before the load is aborted.
|
|
24
|
+
* @property {boolean} [useHeadRequest] - Whether to perform a HEAD request before downloading.
|
|
25
|
+
* @property {BodyInit} [body] - The request body forwarded to the transport (ignored by `GET`/`HEAD`).
|
|
26
|
+
* @property {boolean} [progressive] - Whether to emit progress events (default `true`).
|
|
27
|
+
* @property {boolean} [mirror] - Whether concurrent loads of the same source share a single download (default `true`).
|
|
28
|
+
* @property {import('../utils/TinyMediaCache.mjs').default|null} [cache] - An optional shared memory cache.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The signature of the function returned by {@link TinyFetchLoader#exportFetch}.
|
|
33
|
+
* @typedef {(input: string|URL|Request, init?: RequestInit) => Promise<Response>} TinyFetch
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Loads an arbitrary file through the native `fetch` API.
|
|
38
|
+
*
|
|
39
|
+
* The class does not create a DOM element. It reuses the state machine,
|
|
40
|
+
* progress tracker, cache and mirror registry of {@link TinyMediaLoader},
|
|
41
|
+
* and exposes the downloaded payload through {@link TinyFetchLoader#blob}
|
|
42
|
+
* and {@link TinyFetchLoader#data}.
|
|
43
|
+
* @extends {TinyMediaLoader<any>}
|
|
44
|
+
*/
|
|
45
|
+
class TinyFetchLoader extends TinyMediaLoader {
|
|
46
|
+
/** @type {RequestInit} */
|
|
47
|
+
#init;
|
|
48
|
+
/** @type {FetchResponseType} */
|
|
49
|
+
#responseType;
|
|
50
|
+
/** @type {Blob|null} */
|
|
51
|
+
#blob = null;
|
|
52
|
+
/** @type {Blob|ArrayBuffer|string|unknown|null} */
|
|
53
|
+
#data = null;
|
|
54
|
+
/** @type {FetchLoaderOptions} */
|
|
55
|
+
#options;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {FetchLoaderOptions} [options] - The loader configuration.
|
|
59
|
+
* @throws {TypeError} If `fetch` is not a function.
|
|
60
|
+
* @throws {TypeError} If `init` is not a plain object.
|
|
61
|
+
* @throws {RangeError} If `responseType` is not supported.
|
|
62
|
+
*/
|
|
63
|
+
constructor(options = {}) {
|
|
64
|
+
if (options === null || typeof options !== 'object' || Array.isArray(options)) {
|
|
65
|
+
throw new TypeError('The "options" argument must be a plain object.');
|
|
66
|
+
}
|
|
67
|
+
super(options);
|
|
68
|
+
|
|
69
|
+
const {
|
|
70
|
+
fetch: fetcher = globalThis.fetch.bind(globalThis),
|
|
71
|
+
init = {},
|
|
72
|
+
responseType = 'blob',
|
|
73
|
+
} = options;
|
|
74
|
+
|
|
75
|
+
if (typeof fetcher !== 'function') {
|
|
76
|
+
throw new TypeError('The "fetch" option must be a function.');
|
|
77
|
+
}
|
|
78
|
+
if (init === null || typeof init !== 'object' || Array.isArray(init)) {
|
|
79
|
+
throw new TypeError('The "init" option must be a plain object.');
|
|
80
|
+
}
|
|
81
|
+
if (!['blob', 'arraybuffer', 'text', 'json'].includes(responseType)) {
|
|
82
|
+
throw new RangeError(
|
|
83
|
+
'The "responseType" option must be one of: blob, arraybuffer, text, json.',
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this._fetch = fetcher;
|
|
88
|
+
this._requestInit = init;
|
|
89
|
+
this.#init = init;
|
|
90
|
+
this.#responseType = responseType;
|
|
91
|
+
this.#options = { ...options, fetch: fetcher, init: { ...init }, responseType };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The downloaded file, or null before the load finishes.
|
|
96
|
+
* @returns {Blob|null} The raw payload.
|
|
97
|
+
*/
|
|
98
|
+
get blob() {
|
|
99
|
+
return this.#blob;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The parsed payload, in the format requested by `responseType`.
|
|
104
|
+
* @returns {Blob|ArrayBuffer|string|unknown|null} The parsed payload.
|
|
105
|
+
*/
|
|
106
|
+
get data() {
|
|
107
|
+
return this.#data;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The response body type requested at construction time.
|
|
112
|
+
* @returns {FetchResponseType} The response body type.
|
|
113
|
+
*/
|
|
114
|
+
get responseType() {
|
|
115
|
+
return this.#responseType;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The fetch options forwarded to the transport.
|
|
120
|
+
* @returns {RequestInit} A defensive copy of the fetch options.
|
|
121
|
+
*/
|
|
122
|
+
get init() {
|
|
123
|
+
return { ...this.#init };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Creates a new loader with the same configuration.
|
|
128
|
+
*
|
|
129
|
+
* The clone is fully independent: it has its own state machine, its own
|
|
130
|
+
* abort controller and its own `blob`/`data` slots. The shared `cache` and
|
|
131
|
+
* the custom `fetch` implementation are reused by reference, which is what
|
|
132
|
+
* makes {@link TinyFetchLoader#exportFetch} cheap.
|
|
133
|
+
* @param {FetchLoaderOptions} [overrides] - Values that override the cloned configuration.
|
|
134
|
+
* @returns {TinyFetchLoader} A new, independent loader.
|
|
135
|
+
* @throws {TypeError} If `overrides` is not a plain object.
|
|
136
|
+
*/
|
|
137
|
+
clone(overrides = {}) {
|
|
138
|
+
if (overrides === null || typeof overrides !== 'object' || Array.isArray(overrides)) {
|
|
139
|
+
throw new TypeError('The "overrides" argument must be a plain object.');
|
|
140
|
+
}
|
|
141
|
+
const init = { ...this.#options.init, ...(overrides.init ?? {}) };
|
|
142
|
+
return new TinyFetchLoader({ ...this.#options, ...overrides, init });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Returns a `fetch`-compatible function backed by this loader.
|
|
147
|
+
* @returns {TinyFetch} A function with the same signature as `fetch`.
|
|
148
|
+
*/
|
|
149
|
+
exportFetch() {
|
|
150
|
+
const self = this;
|
|
151
|
+
return async function tinyFetch(input, init) {
|
|
152
|
+
return self._fetch(input, init);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Downloads the file, consulting the shared cache first.
|
|
158
|
+
* @protected
|
|
159
|
+
* @returns {Promise<void>} Resolves once the payload is ready.
|
|
160
|
+
*/
|
|
161
|
+
async _startLoad() {
|
|
162
|
+
const cached = this._acquireFromCache();
|
|
163
|
+
if (cached) {
|
|
164
|
+
this.emit('cachehit', cached);
|
|
165
|
+
this.#blob = cached.blob;
|
|
166
|
+
await this.#parse(cached.blob);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const blob = await this._downloadStream(this.src);
|
|
171
|
+
this.#blob = blob;
|
|
172
|
+
this._setResourceSize(blob.size);
|
|
173
|
+
|
|
174
|
+
if (this.cache) {
|
|
175
|
+
this._cacheBlob(blob);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
await this.#parse(blob);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Converts the raw blob into the format requested by `responseType`.
|
|
183
|
+
* @param {Blob} blob - The downloaded or cached payload.
|
|
184
|
+
* @returns {Promise<void>} Resolves once `data` is populated.
|
|
185
|
+
* @throws {SyntaxError} If `responseType` is `'json'` and the body is not valid JSON.
|
|
186
|
+
*/
|
|
187
|
+
async #parse(blob) {
|
|
188
|
+
if (this.#responseType === 'arraybuffer') {
|
|
189
|
+
this.#data = await blob.arrayBuffer();
|
|
190
|
+
} else if (this.#responseType === 'text') {
|
|
191
|
+
this.#data = await blob.text();
|
|
192
|
+
} else if (this.#responseType === 'json') {
|
|
193
|
+
this.#data = JSON.parse(await blob.text());
|
|
194
|
+
} else {
|
|
195
|
+
this.#data = blob;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Builds the metadata descriptor for the loaded file.
|
|
201
|
+
* @protected
|
|
202
|
+
* @returns {import('../TinyMediaLoader.mjs').MediaMetadataDetails} The file metadata.
|
|
203
|
+
*/
|
|
204
|
+
_getMetadataDetails() {
|
|
205
|
+
return {
|
|
206
|
+
type: this.#blob?.type || 'application/octet-stream',
|
|
207
|
+
width: 0,
|
|
208
|
+
height: 0,
|
|
209
|
+
duration: 0,
|
|
210
|
+
size: this.#blob?.size ?? 0,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* `TinyFetchLoader` does not render anything, so this method always throws.
|
|
216
|
+
* @protected
|
|
217
|
+
* @returns {never} This method never returns.
|
|
218
|
+
* @throws {Error} Always.
|
|
219
|
+
*/
|
|
220
|
+
_createElement() {
|
|
221
|
+
throw new Error('TinyFetchLoader does not create a DOM element.');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = TinyFetchLoader;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generic file loader for external resources.
|
|
3
|
+
* Uses the native `fetch` API by default, but accepts any implementation
|
|
4
|
+
* that follows the same contract: `(input, init) => Promise<Response>`.
|
|
5
|
+
*/
|
|
6
|
+
import TinyMediaLoader from '../TinyMediaLoader.mjs';
|
|
7
|
+
export type FetchResponseType = 'blob' | 'arraybuffer' | 'text' | 'json';
|
|
8
|
+
export type FetchLoaderOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* - The file URL.
|
|
11
|
+
*/
|
|
12
|
+
src?: string;
|
|
13
|
+
/**
|
|
14
|
+
* - The fetch options (method, headers, body, credentials, mode, cache, redirect, referrer, referrerPolicy, integrity, keepalive).
|
|
15
|
+
*/
|
|
16
|
+
init?: RequestInit;
|
|
17
|
+
/**
|
|
18
|
+
* - A custom fetch implementation.
|
|
19
|
+
*/
|
|
20
|
+
fetch?: typeof fetch;
|
|
21
|
+
/**
|
|
22
|
+
* - The response body type (default `'blob'`).
|
|
23
|
+
*/
|
|
24
|
+
responseType?: FetchResponseType;
|
|
25
|
+
/**
|
|
26
|
+
* - Maximum time in milliseconds before the load is aborted.
|
|
27
|
+
*/
|
|
28
|
+
timeout?: number;
|
|
29
|
+
/**
|
|
30
|
+
* - Whether to perform a HEAD request before downloading.
|
|
31
|
+
*/
|
|
32
|
+
useHeadRequest?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* - The request body forwarded to the transport (ignored by `GET`/`HEAD`).
|
|
35
|
+
*/
|
|
36
|
+
body?: BodyInit;
|
|
37
|
+
/**
|
|
38
|
+
* - Whether to emit progress events (default `true`).
|
|
39
|
+
*/
|
|
40
|
+
progressive?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* - Whether concurrent loads of the same source share a single download (default `true`).
|
|
43
|
+
*/
|
|
44
|
+
mirror?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* - An optional shared memory cache.
|
|
47
|
+
*/
|
|
48
|
+
cache?: import('../utils/TinyMediaCache.mjs').default | null;
|
|
49
|
+
};
|
|
50
|
+
export type TinyFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
51
|
+
/**
|
|
52
|
+
* The response body types supported by the loader.
|
|
53
|
+
* @typedef {'blob'|'arraybuffer'|'text'|'json'} FetchResponseType
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Describes the configuration accepted by the {@link TinyFetchLoader} constructor.
|
|
57
|
+
* @typedef {Object} FetchLoaderOptions
|
|
58
|
+
* @property {string} [src] - The file URL.
|
|
59
|
+
* @property {RequestInit} [init] - The fetch options (method, headers, body, credentials, mode, cache, redirect, referrer, referrerPolicy, integrity, keepalive).
|
|
60
|
+
* @property {typeof fetch} [fetch] - A custom fetch implementation.
|
|
61
|
+
* @property {FetchResponseType} [responseType] - The response body type (default `'blob'`).
|
|
62
|
+
* @property {number} [timeout] - Maximum time in milliseconds before the load is aborted.
|
|
63
|
+
* @property {boolean} [useHeadRequest] - Whether to perform a HEAD request before downloading.
|
|
64
|
+
* @property {BodyInit} [body] - The request body forwarded to the transport (ignored by `GET`/`HEAD`).
|
|
65
|
+
* @property {boolean} [progressive] - Whether to emit progress events (default `true`).
|
|
66
|
+
* @property {boolean} [mirror] - Whether concurrent loads of the same source share a single download (default `true`).
|
|
67
|
+
* @property {import('../utils/TinyMediaCache.mjs').default|null} [cache] - An optional shared memory cache.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* The signature of the function returned by {@link TinyFetchLoader#exportFetch}.
|
|
71
|
+
* @typedef {(input: string|URL|Request, init?: RequestInit) => Promise<Response>} TinyFetch
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* Loads an arbitrary file through the native `fetch` API.
|
|
75
|
+
*
|
|
76
|
+
* The class does not create a DOM element. It reuses the state machine,
|
|
77
|
+
* progress tracker, cache and mirror registry of {@link TinyMediaLoader},
|
|
78
|
+
* and exposes the downloaded payload through {@link TinyFetchLoader#blob}
|
|
79
|
+
* and {@link TinyFetchLoader#data}.
|
|
80
|
+
* @extends {TinyMediaLoader<any>}
|
|
81
|
+
*/
|
|
82
|
+
declare class TinyFetchLoader extends TinyMediaLoader<any> {
|
|
83
|
+
#private;
|
|
84
|
+
/**
|
|
85
|
+
* @param {FetchLoaderOptions} [options] - The loader configuration.
|
|
86
|
+
* @throws {TypeError} If `fetch` is not a function.
|
|
87
|
+
* @throws {TypeError} If `init` is not a plain object.
|
|
88
|
+
* @throws {RangeError} If `responseType` is not supported.
|
|
89
|
+
*/
|
|
90
|
+
constructor(options?: FetchLoaderOptions);
|
|
91
|
+
/**
|
|
92
|
+
* The downloaded file, or null before the load finishes.
|
|
93
|
+
* @returns {Blob|null} The raw payload.
|
|
94
|
+
*/
|
|
95
|
+
get blob(): Blob | null;
|
|
96
|
+
/**
|
|
97
|
+
* The parsed payload, in the format requested by `responseType`.
|
|
98
|
+
* @returns {Blob|ArrayBuffer|string|unknown|null} The parsed payload.
|
|
99
|
+
*/
|
|
100
|
+
get data(): Blob | ArrayBuffer | string | unknown | null;
|
|
101
|
+
/**
|
|
102
|
+
* The response body type requested at construction time.
|
|
103
|
+
* @returns {FetchResponseType} The response body type.
|
|
104
|
+
*/
|
|
105
|
+
get responseType(): FetchResponseType;
|
|
106
|
+
/**
|
|
107
|
+
* The fetch options forwarded to the transport.
|
|
108
|
+
* @returns {RequestInit} A defensive copy of the fetch options.
|
|
109
|
+
*/
|
|
110
|
+
get init(): RequestInit;
|
|
111
|
+
/**
|
|
112
|
+
* Creates a new loader with the same configuration.
|
|
113
|
+
*
|
|
114
|
+
* The clone is fully independent: it has its own state machine, its own
|
|
115
|
+
* abort controller and its own `blob`/`data` slots. The shared `cache` and
|
|
116
|
+
* the custom `fetch` implementation are reused by reference, which is what
|
|
117
|
+
* makes {@link TinyFetchLoader#exportFetch} cheap.
|
|
118
|
+
* @param {FetchLoaderOptions} [overrides] - Values that override the cloned configuration.
|
|
119
|
+
* @returns {TinyFetchLoader} A new, independent loader.
|
|
120
|
+
* @throws {TypeError} If `overrides` is not a plain object.
|
|
121
|
+
*/
|
|
122
|
+
clone(overrides?: FetchLoaderOptions): TinyFetchLoader;
|
|
123
|
+
/**
|
|
124
|
+
* Returns a `fetch`-compatible function backed by this loader.
|
|
125
|
+
* @returns {TinyFetch} A function with the same signature as `fetch`.
|
|
126
|
+
*/
|
|
127
|
+
exportFetch(): TinyFetch;
|
|
128
|
+
/**
|
|
129
|
+
* Downloads the file, consulting the shared cache first.
|
|
130
|
+
* @protected
|
|
131
|
+
* @returns {Promise<void>} Resolves once the payload is ready.
|
|
132
|
+
*/
|
|
133
|
+
protected _startLoad(): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Builds the metadata descriptor for the loaded file.
|
|
136
|
+
* @protected
|
|
137
|
+
* @returns {import('../TinyMediaLoader.mjs').MediaMetadataDetails} The file metadata.
|
|
138
|
+
*/
|
|
139
|
+
protected _getMetadataDetails(): import('../TinyMediaLoader.mjs').MediaMetadataDetails;
|
|
140
|
+
/**
|
|
141
|
+
* `TinyFetchLoader` does not render anything, so this method always throws.
|
|
142
|
+
* @protected
|
|
143
|
+
* @returns {never} This method never returns.
|
|
144
|
+
* @throws {Error} Always.
|
|
145
|
+
*/
|
|
146
|
+
protected _createElement(): never;
|
|
147
|
+
}
|
|
148
|
+
export default TinyFetchLoader;
|
|
149
|
+
//# sourceMappingURL=TinyFetchLoader.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TinyFetchLoader.d.mts","sourceRoot":"","sources":["../../../../../../src/v1/libs/html/loader/formats/TinyFetchLoader.mjs"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,eAAe,MAAM,wBAAwB,CAAC;AAIlD,YAA8C,iBAAiB,GAArD,MAAM,GAAC,aAAa,GAAC,MAAM,GAAC,MAAM,CAAmB;AAK/D,YAAkB,kBAAkB,GACpC;;;;IAAoB,GAAG,AAAvB,CACA,EADW,MAAM,CACjB;;;;IAAyB,IAAI,AAA7B,CACA,EADW,WAAW,CACtB;;;;IAA0B,KAAK,AAA/B,CACA,EADW,OAAO,KAAK,CACvB;;;;IAA+B,YAAY,AAA3C,CACA,EADW,iBAAiB,CAC5B;;;;IAAoB,OAAO,AAA3B,CACA,EADW,MAAM,CACjB;;;;IAAqB,cAAc,AAAnC,CACA,EADW,OAAO,CAClB;;;;IAAsB,IAAI,AAA1B,CACA,EADW,QAAQ,CACnB;;;;IAAqB,WAAW,AAAhC,CACA,EADW,OAAO,CAClB;;;;IAAqB,MAAM,AAA3B,CACA,EADW,OAAO,CAClB;;;;IAAgE,KAAK,AAArE,CACF,EADa,OAAO,6BAA6B,EAAE,OAAO,GAAC,IAAI,CAC/D;CAAA,CAAA;AAIE,YAAgF,SAAS,GAA/E,CAAC,KAAK,EAAE,MAAM,GAAC,GAAG,GAAC,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAW;AAtB5F;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AAEH;;;;;;;;GAQG;AACH,cAAM,eAAgB,SAAQ,eAAe,CAFhB,GAAG,CAEa;;IAY3C;;;;;OAKG;IACH,YAAY,OAAO,AALhB,CACA,EADQ,kBAKa,EA6BvB;IAED;;;OAGG;IACH,IAAI,IAAI,IAFK,IAAI,GAAC,IAAI,CAIrB;IAED;;;OAGG;IACH,IAAI,IAAI,IAFK,IAAI,GAAC,WAAW,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,CAIhD;IAED;;;OAGG;IACH,IAAI,YAAY,IAFH,iBAAiB,CAI7B;IAED;;;OAGG;IACH,IAAI,IAAI,IAFK,WAAW,CAIvB;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,SAAS,AAJZ,CACA,EADQ,kBAIS,GAHP,eAAe,CAS3B;IAED;;;OAGG;IACH,WAAW,IAFE,SAAS,CAOrB;IAED;;;;OAIG;IACH,UAAM,UAAU,IAFH,OAAO,CAAC,IAAI,CAAC,CAoBzB;IAoBD;;;;OAIG;IACH,UAAA,mBAAmB,IAFN,OAAO,wBAAwB,EAAE,oBAAoB,CAUjE;IAED;;;;;OAKG;IACH,UAAA,cAAc,IAHD,KAAK,CAKjB;CACF;eAEc,eAAe"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generic file loader for external resources.
|
|
3
|
+
* Uses the native `fetch` API by default, but accepts any implementation
|
|
4
|
+
* that follows the same contract: `(input, init) => Promise<Response>`.
|
|
5
|
+
*/
|
|
6
|
+
import TinyMediaLoader from '../TinyMediaLoader.mjs';
|
|
7
|
+
/**
|
|
8
|
+
* The response body types supported by the loader.
|
|
9
|
+
* @typedef {'blob'|'arraybuffer'|'text'|'json'} FetchResponseType
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Describes the configuration accepted by the {@link TinyFetchLoader} constructor.
|
|
13
|
+
* @typedef {Object} FetchLoaderOptions
|
|
14
|
+
* @property {string} [src] - The file URL.
|
|
15
|
+
* @property {RequestInit} [init] - The fetch options (method, headers, body, credentials, mode, cache, redirect, referrer, referrerPolicy, integrity, keepalive).
|
|
16
|
+
* @property {typeof fetch} [fetch] - A custom fetch implementation.
|
|
17
|
+
* @property {FetchResponseType} [responseType] - The response body type (default `'blob'`).
|
|
18
|
+
* @property {number} [timeout] - Maximum time in milliseconds before the load is aborted.
|
|
19
|
+
* @property {boolean} [useHeadRequest] - Whether to perform a HEAD request before downloading.
|
|
20
|
+
* @property {BodyInit} [body] - The request body forwarded to the transport (ignored by `GET`/`HEAD`).
|
|
21
|
+
* @property {boolean} [progressive] - Whether to emit progress events (default `true`).
|
|
22
|
+
* @property {boolean} [mirror] - Whether concurrent loads of the same source share a single download (default `true`).
|
|
23
|
+
* @property {import('../utils/TinyMediaCache.mjs').default|null} [cache] - An optional shared memory cache.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The signature of the function returned by {@link TinyFetchLoader#exportFetch}.
|
|
27
|
+
* @typedef {(input: string|URL|Request, init?: RequestInit) => Promise<Response>} TinyFetch
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Loads an arbitrary file through the native `fetch` API.
|
|
31
|
+
*
|
|
32
|
+
* The class does not create a DOM element. It reuses the state machine,
|
|
33
|
+
* progress tracker, cache and mirror registry of {@link TinyMediaLoader},
|
|
34
|
+
* and exposes the downloaded payload through {@link TinyFetchLoader#blob}
|
|
35
|
+
* and {@link TinyFetchLoader#data}.
|
|
36
|
+
* @extends {TinyMediaLoader<any>}
|
|
37
|
+
*/
|
|
38
|
+
class TinyFetchLoader extends TinyMediaLoader {
|
|
39
|
+
/** @type {RequestInit} */
|
|
40
|
+
#init;
|
|
41
|
+
/** @type {FetchResponseType} */
|
|
42
|
+
#responseType;
|
|
43
|
+
/** @type {Blob|null} */
|
|
44
|
+
#blob = null;
|
|
45
|
+
/** @type {Blob|ArrayBuffer|string|unknown|null} */
|
|
46
|
+
#data = null;
|
|
47
|
+
/** @type {FetchLoaderOptions} */
|
|
48
|
+
#options;
|
|
49
|
+
/**
|
|
50
|
+
* @param {FetchLoaderOptions} [options] - The loader configuration.
|
|
51
|
+
* @throws {TypeError} If `fetch` is not a function.
|
|
52
|
+
* @throws {TypeError} If `init` is not a plain object.
|
|
53
|
+
* @throws {RangeError} If `responseType` is not supported.
|
|
54
|
+
*/
|
|
55
|
+
constructor(options = {}) {
|
|
56
|
+
if (options === null || typeof options !== 'object' || Array.isArray(options)) {
|
|
57
|
+
throw new TypeError('The "options" argument must be a plain object.');
|
|
58
|
+
}
|
|
59
|
+
super(options);
|
|
60
|
+
const { fetch: fetcher = globalThis.fetch.bind(globalThis), init = {}, responseType = 'blob', } = options;
|
|
61
|
+
if (typeof fetcher !== 'function') {
|
|
62
|
+
throw new TypeError('The "fetch" option must be a function.');
|
|
63
|
+
}
|
|
64
|
+
if (init === null || typeof init !== 'object' || Array.isArray(init)) {
|
|
65
|
+
throw new TypeError('The "init" option must be a plain object.');
|
|
66
|
+
}
|
|
67
|
+
if (!['blob', 'arraybuffer', 'text', 'json'].includes(responseType)) {
|
|
68
|
+
throw new RangeError('The "responseType" option must be one of: blob, arraybuffer, text, json.');
|
|
69
|
+
}
|
|
70
|
+
this._fetch = fetcher;
|
|
71
|
+
this._requestInit = init;
|
|
72
|
+
this.#init = init;
|
|
73
|
+
this.#responseType = responseType;
|
|
74
|
+
this.#options = { ...options, fetch: fetcher, init: { ...init }, responseType };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The downloaded file, or null before the load finishes.
|
|
78
|
+
* @returns {Blob|null} The raw payload.
|
|
79
|
+
*/
|
|
80
|
+
get blob() {
|
|
81
|
+
return this.#blob;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The parsed payload, in the format requested by `responseType`.
|
|
85
|
+
* @returns {Blob|ArrayBuffer|string|unknown|null} The parsed payload.
|
|
86
|
+
*/
|
|
87
|
+
get data() {
|
|
88
|
+
return this.#data;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The response body type requested at construction time.
|
|
92
|
+
* @returns {FetchResponseType} The response body type.
|
|
93
|
+
*/
|
|
94
|
+
get responseType() {
|
|
95
|
+
return this.#responseType;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The fetch options forwarded to the transport.
|
|
99
|
+
* @returns {RequestInit} A defensive copy of the fetch options.
|
|
100
|
+
*/
|
|
101
|
+
get init() {
|
|
102
|
+
return { ...this.#init };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates a new loader with the same configuration.
|
|
106
|
+
*
|
|
107
|
+
* The clone is fully independent: it has its own state machine, its own
|
|
108
|
+
* abort controller and its own `blob`/`data` slots. The shared `cache` and
|
|
109
|
+
* the custom `fetch` implementation are reused by reference, which is what
|
|
110
|
+
* makes {@link TinyFetchLoader#exportFetch} cheap.
|
|
111
|
+
* @param {FetchLoaderOptions} [overrides] - Values that override the cloned configuration.
|
|
112
|
+
* @returns {TinyFetchLoader} A new, independent loader.
|
|
113
|
+
* @throws {TypeError} If `overrides` is not a plain object.
|
|
114
|
+
*/
|
|
115
|
+
clone(overrides = {}) {
|
|
116
|
+
if (overrides === null || typeof overrides !== 'object' || Array.isArray(overrides)) {
|
|
117
|
+
throw new TypeError('The "overrides" argument must be a plain object.');
|
|
118
|
+
}
|
|
119
|
+
const init = { ...this.#options.init, ...(overrides.init ?? {}) };
|
|
120
|
+
return new TinyFetchLoader({ ...this.#options, ...overrides, init });
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns a `fetch`-compatible function backed by this loader.
|
|
124
|
+
* @returns {TinyFetch} A function with the same signature as `fetch`.
|
|
125
|
+
*/
|
|
126
|
+
exportFetch() {
|
|
127
|
+
const self = this;
|
|
128
|
+
return async function tinyFetch(input, init) {
|
|
129
|
+
return self._fetch(input, init);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Downloads the file, consulting the shared cache first.
|
|
134
|
+
* @protected
|
|
135
|
+
* @returns {Promise<void>} Resolves once the payload is ready.
|
|
136
|
+
*/
|
|
137
|
+
async _startLoad() {
|
|
138
|
+
const cached = this._acquireFromCache();
|
|
139
|
+
if (cached) {
|
|
140
|
+
this.emit('cachehit', cached);
|
|
141
|
+
this.#blob = cached.blob;
|
|
142
|
+
await this.#parse(cached.blob);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const blob = await this._downloadStream(this.src);
|
|
146
|
+
this.#blob = blob;
|
|
147
|
+
this._setResourceSize(blob.size);
|
|
148
|
+
if (this.cache) {
|
|
149
|
+
this._cacheBlob(blob);
|
|
150
|
+
}
|
|
151
|
+
await this.#parse(blob);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Converts the raw blob into the format requested by `responseType`.
|
|
155
|
+
* @param {Blob} blob - The downloaded or cached payload.
|
|
156
|
+
* @returns {Promise<void>} Resolves once `data` is populated.
|
|
157
|
+
* @throws {SyntaxError} If `responseType` is `'json'` and the body is not valid JSON.
|
|
158
|
+
*/
|
|
159
|
+
async #parse(blob) {
|
|
160
|
+
if (this.#responseType === 'arraybuffer') {
|
|
161
|
+
this.#data = await blob.arrayBuffer();
|
|
162
|
+
}
|
|
163
|
+
else if (this.#responseType === 'text') {
|
|
164
|
+
this.#data = await blob.text();
|
|
165
|
+
}
|
|
166
|
+
else if (this.#responseType === 'json') {
|
|
167
|
+
this.#data = JSON.parse(await blob.text());
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.#data = blob;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Builds the metadata descriptor for the loaded file.
|
|
175
|
+
* @protected
|
|
176
|
+
* @returns {import('../TinyMediaLoader.mjs').MediaMetadataDetails} The file metadata.
|
|
177
|
+
*/
|
|
178
|
+
_getMetadataDetails() {
|
|
179
|
+
return {
|
|
180
|
+
type: this.#blob?.type || 'application/octet-stream',
|
|
181
|
+
width: 0,
|
|
182
|
+
height: 0,
|
|
183
|
+
duration: 0,
|
|
184
|
+
size: this.#blob?.size ?? 0,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* `TinyFetchLoader` does not render anything, so this method always throws.
|
|
189
|
+
* @protected
|
|
190
|
+
* @returns {never} This method never returns.
|
|
191
|
+
* @throws {Error} Always.
|
|
192
|
+
*/
|
|
193
|
+
_createElement() {
|
|
194
|
+
throw new Error('TinyFetchLoader does not create a DOM element.');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export default TinyFetchLoader;
|