react-inlinesvg 4.1.8 → 4.3.0
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/README.md +28 -34
- package/dist/cache-NLB60kAd.d.mts +142 -0
- package/dist/cache-NLB60kAd.d.ts +142 -0
- package/dist/index.d.mts +7 -73
- package/dist/index.d.ts +7 -73
- package/dist/index.js +284 -202
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +280 -206
- package/dist/index.mjs.map +1 -1
- package/dist/provider.d.mts +5 -3
- package/dist/provider.d.ts +5 -3
- package/dist/provider.js +187 -6
- package/dist/provider.js.map +1 -1
- package/dist/provider.mjs +176 -6
- package/dist/provider.mjs.map +1 -1
- package/package.json +25 -41
- package/src/index.tsx +29 -261
- package/src/modules/cache.ts +100 -70
- package/src/modules/helpers.ts +1 -9
- package/src/modules/hooks.tsx +6 -1
- package/src/modules/useInlineSVG.ts +272 -0
- package/src/modules/utils.ts +36 -1
- package/src/provider.tsx +10 -7
- package/src/types.ts +69 -3
- package/src/global.d.ts +0 -6
package/dist/index.js
CHANGED
|
@@ -31,14 +31,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
32
32
|
|
|
33
33
|
// src/index.tsx
|
|
34
|
-
var
|
|
35
|
-
__export(
|
|
34
|
+
var index_exports = {};
|
|
35
|
+
__export(index_exports, {
|
|
36
36
|
cacheStore: () => cacheStore,
|
|
37
37
|
default: () => InlineSVG
|
|
38
38
|
});
|
|
39
|
-
module.exports = __toCommonJS(
|
|
40
|
-
var
|
|
41
|
-
var import_react_from_dom2 = __toESM(require("react-from-dom"));
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
var import_react4 = require("react");
|
|
42
41
|
|
|
43
42
|
// src/config.ts
|
|
44
43
|
var CACHE_NAME = "react-inlinesvg";
|
|
@@ -95,11 +94,6 @@ async function request(url, options) {
|
|
|
95
94
|
}
|
|
96
95
|
return response.text();
|
|
97
96
|
}
|
|
98
|
-
function sleep(seconds = 1) {
|
|
99
|
-
return new Promise((resolve) => {
|
|
100
|
-
setTimeout(resolve, seconds * 1e3);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
97
|
function supportsInlineSVG() {
|
|
104
98
|
if (!document) {
|
|
105
99
|
return false;
|
|
@@ -112,26 +106,31 @@ function supportsInlineSVG() {
|
|
|
112
106
|
|
|
113
107
|
// src/modules/cache.ts
|
|
114
108
|
var CacheStore = class {
|
|
115
|
-
constructor() {
|
|
109
|
+
constructor(options = {}) {
|
|
116
110
|
__publicField(this, "cacheApi");
|
|
117
111
|
__publicField(this, "cacheStore");
|
|
118
112
|
__publicField(this, "subscribers", []);
|
|
119
113
|
__publicField(this, "isReady", false);
|
|
114
|
+
const { name = CACHE_NAME, persistent = false } = options;
|
|
120
115
|
this.cacheStore = /* @__PURE__ */ new Map();
|
|
121
|
-
|
|
122
|
-
let usePersistentCache = false;
|
|
123
|
-
if (canUseDOM()) {
|
|
124
|
-
cacheName = window.REACT_INLINESVG_CACHE_NAME ?? CACHE_NAME;
|
|
125
|
-
usePersistentCache = !!window.REACT_INLINESVG_PERSISTENT_CACHE && "caches" in window;
|
|
126
|
-
}
|
|
116
|
+
const usePersistentCache = persistent && canUseDOM() && "caches" in window;
|
|
127
117
|
if (usePersistentCache) {
|
|
128
|
-
caches.open(
|
|
118
|
+
caches.open(name).then((cache) => {
|
|
129
119
|
this.cacheApi = cache;
|
|
130
120
|
}).catch((error) => {
|
|
131
121
|
console.error(`Failed to open cache: ${error.message}`);
|
|
122
|
+
this.cacheApi = void 0;
|
|
132
123
|
}).finally(() => {
|
|
133
124
|
this.isReady = true;
|
|
134
|
-
this.subscribers
|
|
125
|
+
const callbacks = [...this.subscribers];
|
|
126
|
+
this.subscribers.length = 0;
|
|
127
|
+
callbacks.forEach((callback) => {
|
|
128
|
+
try {
|
|
129
|
+
callback();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(`Error in CacheStore subscriber callback: ${error.message}`);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
135
134
|
});
|
|
136
135
|
} else {
|
|
137
136
|
this.isReady = true;
|
|
@@ -140,12 +139,30 @@ var CacheStore = class {
|
|
|
140
139
|
onReady(callback) {
|
|
141
140
|
if (this.isReady) {
|
|
142
141
|
callback();
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
return () => {
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
this.subscribers.push(callback);
|
|
146
|
+
return () => {
|
|
147
|
+
const index = this.subscribers.indexOf(callback);
|
|
148
|
+
if (index >= 0) {
|
|
149
|
+
this.subscribers.splice(index, 1);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
waitForReady() {
|
|
154
|
+
if (this.isReady) {
|
|
155
|
+
return Promise.resolve();
|
|
145
156
|
}
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
this.onReady(resolve);
|
|
159
|
+
});
|
|
146
160
|
}
|
|
147
161
|
async get(url, fetchOptions) {
|
|
148
|
-
await
|
|
162
|
+
await this.fetchAndCache(url, fetchOptions);
|
|
163
|
+
return this.cacheStore.get(url)?.content ?? "";
|
|
164
|
+
}
|
|
165
|
+
getContent(url) {
|
|
149
166
|
return this.cacheStore.get(url)?.content ?? "";
|
|
150
167
|
}
|
|
151
168
|
set(url, data) {
|
|
@@ -154,64 +171,50 @@ var CacheStore = class {
|
|
|
154
171
|
isCached(url) {
|
|
155
172
|
return this.cacheStore.get(url)?.status === STATUS.LOADED;
|
|
156
173
|
}
|
|
157
|
-
async
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
await this.handleLoading(url, async () => {
|
|
161
|
-
this.cacheStore.set(url, { content: "", status: STATUS.IDLE });
|
|
162
|
-
await this.fetchAndAddToInternalCache(url, fetchOptions);
|
|
163
|
-
});
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
if (!cache?.content) {
|
|
167
|
-
this.cacheStore.set(url, { content: "", status: STATUS.LOADING });
|
|
168
|
-
try {
|
|
169
|
-
const content = await request(url, fetchOptions);
|
|
170
|
-
this.cacheStore.set(url, { content, status: STATUS.LOADED });
|
|
171
|
-
} catch (error) {
|
|
172
|
-
this.cacheStore.set(url, { content: "", status: STATUS.FAILED });
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
174
|
+
async fetchAndCache(url, fetchOptions) {
|
|
175
|
+
if (!this.isReady) {
|
|
176
|
+
await this.waitForReady();
|
|
175
177
|
}
|
|
176
|
-
}
|
|
177
|
-
async fetchAndAddToPersistentCache(url, fetchOptions) {
|
|
178
178
|
const cache = this.cacheStore.get(url);
|
|
179
179
|
if (cache?.status === STATUS.LOADED) {
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
182
|
if (cache?.status === STATUS.LOADING) {
|
|
183
|
-
await this.handleLoading(url, async () => {
|
|
183
|
+
await this.handleLoading(url, fetchOptions?.signal || void 0, async () => {
|
|
184
184
|
this.cacheStore.set(url, { content: "", status: STATUS.IDLE });
|
|
185
|
-
await this.
|
|
185
|
+
await this.fetchAndCache(url, fetchOptions);
|
|
186
186
|
});
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
189
|
this.cacheStore.set(url, { content: "", status: STATUS.LOADING });
|
|
190
|
-
const data = await this.cacheApi?.match(url);
|
|
191
|
-
if (data) {
|
|
192
|
-
const content = await data.text();
|
|
193
|
-
this.cacheStore.set(url, { content, status: STATUS.LOADED });
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
190
|
try {
|
|
197
|
-
await this.
|
|
198
|
-
const response = await this.cacheApi?.match(url);
|
|
199
|
-
const content = await response?.text() ?? "";
|
|
191
|
+
const content = this.cacheApi ? await this.fetchFromPersistentCache(url, fetchOptions) : await request(url, fetchOptions);
|
|
200
192
|
this.cacheStore.set(url, { content, status: STATUS.LOADED });
|
|
201
193
|
} catch (error) {
|
|
202
194
|
this.cacheStore.set(url, { content: "", status: STATUS.FAILED });
|
|
203
195
|
throw error;
|
|
204
196
|
}
|
|
205
197
|
}
|
|
206
|
-
async
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
retryCount += 1;
|
|
198
|
+
async fetchFromPersistentCache(url, fetchOptions) {
|
|
199
|
+
const data = await this.cacheApi?.match(url);
|
|
200
|
+
if (data) {
|
|
201
|
+
return data.text();
|
|
211
202
|
}
|
|
212
|
-
|
|
213
|
-
|
|
203
|
+
await this.cacheApi?.add(new Request(url, fetchOptions));
|
|
204
|
+
const response = await this.cacheApi?.match(url);
|
|
205
|
+
return await response?.text() ?? "";
|
|
206
|
+
}
|
|
207
|
+
async handleLoading(url, signal, callback) {
|
|
208
|
+
for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) {
|
|
209
|
+
if (signal?.aborted) {
|
|
210
|
+
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
|
|
211
|
+
}
|
|
212
|
+
if (this.cacheStore.get(url)?.status !== STATUS.LOADING) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
await sleep(0.1);
|
|
214
216
|
}
|
|
217
|
+
await callback();
|
|
215
218
|
}
|
|
216
219
|
keys() {
|
|
217
220
|
return [...this.cacheStore.keys()];
|
|
@@ -228,16 +231,26 @@ var CacheStore = class {
|
|
|
228
231
|
async clear() {
|
|
229
232
|
if (this.cacheApi) {
|
|
230
233
|
const keys = await this.cacheApi.keys();
|
|
231
|
-
|
|
232
|
-
await this.cacheApi.delete(key);
|
|
233
|
-
}
|
|
234
|
+
await Promise.allSettled(keys.map((key) => this.cacheApi.delete(key)));
|
|
234
235
|
}
|
|
235
236
|
this.cacheStore.clear();
|
|
236
237
|
}
|
|
237
238
|
};
|
|
239
|
+
function sleep(seconds = 1) {
|
|
240
|
+
return new Promise((resolve) => {
|
|
241
|
+
setTimeout(resolve, seconds * 1e3);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/modules/useInlineSVG.ts
|
|
246
|
+
var import_react2 = require("react");
|
|
247
|
+
var import_react_from_dom2 = __toESM(require("react-from-dom"));
|
|
238
248
|
|
|
239
249
|
// src/modules/hooks.tsx
|
|
240
250
|
var import_react = require("react");
|
|
251
|
+
function useMount(effect) {
|
|
252
|
+
(0, import_react.useEffect)(effect, []);
|
|
253
|
+
}
|
|
241
254
|
function usePrevious(state) {
|
|
242
255
|
const ref = (0, import_react.useRef)(void 0);
|
|
243
256
|
(0, import_react.useEffect)(() => {
|
|
@@ -248,6 +261,29 @@ function usePrevious(state) {
|
|
|
248
261
|
|
|
249
262
|
// src/modules/utils.ts
|
|
250
263
|
var import_react_from_dom = __toESM(require("react-from-dom"));
|
|
264
|
+
function uniquifyStyleIds(svgText, hash, baseURL) {
|
|
265
|
+
const idMatches = svgText.matchAll(/\bid=(["'])([^"']+)\1/g);
|
|
266
|
+
const ids = [...new Set([...idMatches].map((m) => m[2]))];
|
|
267
|
+
if (!ids.length) {
|
|
268
|
+
return svgText;
|
|
269
|
+
}
|
|
270
|
+
ids.sort((a, b) => b.length - a.length);
|
|
271
|
+
return svgText.replace(/<style[^>]*>([\S\s]*?)<\/style>/gi, (fullMatch, cssContent) => {
|
|
272
|
+
let modified = cssContent;
|
|
273
|
+
for (const id of ids) {
|
|
274
|
+
const escaped = id.replace(/[$()*+.?[\\\]^{|}]/g, "\\$&");
|
|
275
|
+
modified = modified.replace(
|
|
276
|
+
new RegExp(`url\\((['"]?)#${escaped}\\1\\)`, "g"),
|
|
277
|
+
`url($1${baseURL}#${id}__${hash}$1)`
|
|
278
|
+
);
|
|
279
|
+
modified = modified.replace(
|
|
280
|
+
new RegExp(`#${escaped}(?![a-zA-Z0-9_-])`, "g"),
|
|
281
|
+
`#${id}__${hash}`
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
return fullMatch.replace(cssContent, modified);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
251
287
|
function getNode(options) {
|
|
252
288
|
const {
|
|
253
289
|
baseURL,
|
|
@@ -260,7 +296,10 @@ function getNode(options) {
|
|
|
260
296
|
uniquifyIDs = false
|
|
261
297
|
} = options;
|
|
262
298
|
try {
|
|
263
|
-
|
|
299
|
+
let svgText = processSVG(content, preProcessor);
|
|
300
|
+
if (uniquifyIDs) {
|
|
301
|
+
svgText = uniquifyStyleIds(svgText, hash, baseURL ?? "");
|
|
302
|
+
}
|
|
264
303
|
const node = (0, import_react_from_dom.default)(svgText, { nodeOnly: true });
|
|
265
304
|
if (!node || !(node instanceof SVGSVGElement)) {
|
|
266
305
|
throw new Error("Could not convert the src to a DOM Node");
|
|
@@ -330,22 +369,30 @@ function updateSVGAttributes(node, options) {
|
|
|
330
369
|
return node;
|
|
331
370
|
}
|
|
332
371
|
|
|
333
|
-
// src/
|
|
334
|
-
|
|
335
|
-
function ReactInlineSVG(props) {
|
|
372
|
+
// src/modules/useInlineSVG.ts
|
|
373
|
+
function useInlineSVG(props, cacheStore2) {
|
|
336
374
|
const {
|
|
375
|
+
baseURL,
|
|
337
376
|
cacheRequests = true,
|
|
338
|
-
children = null,
|
|
339
377
|
description,
|
|
340
378
|
fetchOptions,
|
|
341
|
-
innerRef,
|
|
342
|
-
loader = null,
|
|
343
379
|
onError,
|
|
344
380
|
onLoad,
|
|
381
|
+
preProcessor,
|
|
345
382
|
src,
|
|
346
383
|
title,
|
|
347
|
-
uniqueHash
|
|
384
|
+
uniqueHash,
|
|
385
|
+
uniquifyIDs
|
|
348
386
|
} = props;
|
|
387
|
+
const hash = (0, import_react2.useRef)(uniqueHash ?? randomString(8));
|
|
388
|
+
const fetchOptionsRef = (0, import_react2.useRef)(fetchOptions);
|
|
389
|
+
const onErrorRef = (0, import_react2.useRef)(onError);
|
|
390
|
+
const onLoadRef = (0, import_react2.useRef)(onLoad);
|
|
391
|
+
const preProcessorRef = (0, import_react2.useRef)(preProcessor);
|
|
392
|
+
fetchOptionsRef.current = fetchOptions;
|
|
393
|
+
onErrorRef.current = onError;
|
|
394
|
+
onLoadRef.current = onLoad;
|
|
395
|
+
preProcessorRef.current = preProcessor;
|
|
349
396
|
const [state, setState] = (0, import_react2.useReducer)(
|
|
350
397
|
(previousState2, nextState) => ({
|
|
351
398
|
...previousState2,
|
|
@@ -354,43 +401,71 @@ function ReactInlineSVG(props) {
|
|
|
354
401
|
{
|
|
355
402
|
content: "",
|
|
356
403
|
element: null,
|
|
357
|
-
isCached:
|
|
404
|
+
isCached: false,
|
|
358
405
|
status: STATUS.IDLE
|
|
406
|
+
},
|
|
407
|
+
(initial) => {
|
|
408
|
+
const cached = cacheRequests && cacheStore2.isCached(src);
|
|
409
|
+
if (!cached) {
|
|
410
|
+
return initial;
|
|
411
|
+
}
|
|
412
|
+
const cachedContent = cacheStore2.getContent(src);
|
|
413
|
+
try {
|
|
414
|
+
const node = getNode({
|
|
415
|
+
...props,
|
|
416
|
+
handleError: () => {
|
|
417
|
+
},
|
|
418
|
+
hash: hash.current,
|
|
419
|
+
content: cachedContent
|
|
420
|
+
});
|
|
421
|
+
if (!node) {
|
|
422
|
+
return { ...initial, content: cachedContent, isCached: true, status: STATUS.LOADED };
|
|
423
|
+
}
|
|
424
|
+
const convertedElement = (0, import_react_from_dom2.default)(node);
|
|
425
|
+
if (convertedElement && (0, import_react2.isValidElement)(convertedElement)) {
|
|
426
|
+
return {
|
|
427
|
+
content: cachedContent,
|
|
428
|
+
element: convertedElement,
|
|
429
|
+
isCached: true,
|
|
430
|
+
status: STATUS.READY
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
} catch {
|
|
434
|
+
}
|
|
435
|
+
return {
|
|
436
|
+
...initial,
|
|
437
|
+
content: cachedContent,
|
|
438
|
+
isCached: true,
|
|
439
|
+
status: STATUS.LOADED
|
|
440
|
+
};
|
|
359
441
|
}
|
|
360
442
|
);
|
|
361
443
|
const { content, element, isCached, status } = state;
|
|
362
444
|
const previousProps = usePrevious(props);
|
|
363
445
|
const previousState = usePrevious(state);
|
|
364
|
-
const hash = (0, import_react2.useRef)(uniqueHash ?? randomString(8));
|
|
365
446
|
const isActive = (0, import_react2.useRef)(false);
|
|
366
447
|
const isInitialized = (0, import_react2.useRef)(false);
|
|
367
|
-
const handleError = (0, import_react2.useCallback)(
|
|
368
|
-
(error) => {
|
|
369
|
-
if (isActive.current) {
|
|
370
|
-
setState({
|
|
371
|
-
status: error.message === "Browser does not support SVG" ? STATUS.UNSUPPORTED : STATUS.FAILED
|
|
372
|
-
});
|
|
373
|
-
onError?.(error);
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
[onError]
|
|
377
|
-
);
|
|
378
|
-
const handleLoad = (0, import_react2.useCallback)((loadedContent, hasCache = false) => {
|
|
448
|
+
const handleError = (0, import_react2.useCallback)((error) => {
|
|
379
449
|
if (isActive.current) {
|
|
380
450
|
setState({
|
|
381
|
-
|
|
382
|
-
isCached: hasCache,
|
|
383
|
-
status: STATUS.LOADED
|
|
451
|
+
status: error.message === "Browser does not support SVG" ? STATUS.UNSUPPORTED : STATUS.FAILED
|
|
384
452
|
});
|
|
453
|
+
onErrorRef.current?.(error);
|
|
385
454
|
}
|
|
386
455
|
}, []);
|
|
387
|
-
const fetchContent = (0, import_react2.useCallback)(async () => {
|
|
388
|
-
const responseContent = await request(src, fetchOptions);
|
|
389
|
-
handleLoad(responseContent);
|
|
390
|
-
}, [fetchOptions, handleLoad, src]);
|
|
391
456
|
const getElement = (0, import_react2.useCallback)(() => {
|
|
392
457
|
try {
|
|
393
|
-
const node = getNode({
|
|
458
|
+
const node = getNode({
|
|
459
|
+
baseURL,
|
|
460
|
+
content,
|
|
461
|
+
description,
|
|
462
|
+
handleError,
|
|
463
|
+
hash: hash.current,
|
|
464
|
+
preProcessor: preProcessorRef.current,
|
|
465
|
+
src,
|
|
466
|
+
title,
|
|
467
|
+
uniquifyIDs
|
|
468
|
+
});
|
|
394
469
|
const convertedElement = (0, import_react_from_dom2.default)(node);
|
|
395
470
|
if (!convertedElement || !(0, import_react2.isValidElement)(convertedElement)) {
|
|
396
471
|
throw new Error("Could not convert the src to a React element");
|
|
@@ -400,124 +475,151 @@ function ReactInlineSVG(props) {
|
|
|
400
475
|
status: STATUS.READY
|
|
401
476
|
});
|
|
402
477
|
} catch (error) {
|
|
403
|
-
handleError(
|
|
404
|
-
}
|
|
405
|
-
}, [content, handleError,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);
|
|
411
|
-
} else if (src.includes("<svg")) {
|
|
412
|
-
inlineSrc = src;
|
|
413
|
-
}
|
|
414
|
-
if (inlineSrc) {
|
|
415
|
-
handleLoad(inlineSrc);
|
|
416
|
-
return;
|
|
478
|
+
handleError(error);
|
|
479
|
+
}
|
|
480
|
+
}, [baseURL, content, description, handleError, src, title, uniquifyIDs]);
|
|
481
|
+
useMount(() => {
|
|
482
|
+
isActive.current = true;
|
|
483
|
+
if (!canUseDOM() || isInitialized.current) {
|
|
484
|
+
return void 0;
|
|
417
485
|
}
|
|
418
486
|
try {
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
487
|
+
if (status === STATUS.READY) {
|
|
488
|
+
onLoadRef.current?.(src, isCached);
|
|
489
|
+
} else if (status === STATUS.IDLE) {
|
|
490
|
+
if (!isSupportedEnvironment()) {
|
|
491
|
+
throw new Error("Browser does not support SVG");
|
|
492
|
+
}
|
|
493
|
+
if (!src) {
|
|
494
|
+
throw new Error("Missing src");
|
|
495
|
+
}
|
|
496
|
+
setState({ content: "", element: null, isCached: false, status: STATUS.LOADING });
|
|
424
497
|
}
|
|
425
498
|
} catch (error) {
|
|
426
499
|
handleError(error);
|
|
427
500
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
});
|
|
501
|
+
isInitialized.current = true;
|
|
502
|
+
return () => {
|
|
503
|
+
isActive.current = false;
|
|
504
|
+
};
|
|
505
|
+
});
|
|
506
|
+
(0, import_react2.useEffect)(() => {
|
|
507
|
+
if (!canUseDOM() || !previousProps) {
|
|
508
|
+
return;
|
|
437
509
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
if (!canUseDOM() || isInitialized.current) {
|
|
443
|
-
return () => void 0;
|
|
510
|
+
if (previousProps.src !== src) {
|
|
511
|
+
if (!src) {
|
|
512
|
+
handleError(new Error("Missing src"));
|
|
513
|
+
return;
|
|
444
514
|
}
|
|
515
|
+
setState({ content: "", element: null, isCached: false, status: STATUS.LOADING });
|
|
516
|
+
}
|
|
517
|
+
}, [handleError, previousProps, src]);
|
|
518
|
+
(0, import_react2.useEffect)(() => {
|
|
519
|
+
if (status !== STATUS.LOADING) {
|
|
520
|
+
return void 0;
|
|
521
|
+
}
|
|
522
|
+
const controller = new AbortController();
|
|
523
|
+
let active = true;
|
|
524
|
+
(async () => {
|
|
445
525
|
try {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
526
|
+
const dataURI = /^data:image\/svg[^,]*?(;base64)?,(.*)/.exec(src);
|
|
527
|
+
let inlineSrc;
|
|
528
|
+
if (dataURI) {
|
|
529
|
+
inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);
|
|
530
|
+
} else if (src.includes("<svg")) {
|
|
531
|
+
inlineSrc = src;
|
|
532
|
+
}
|
|
533
|
+
if (inlineSrc) {
|
|
534
|
+
if (active) {
|
|
535
|
+
setState({ content: inlineSrc, isCached: false, status: STATUS.LOADED });
|
|
452
536
|
}
|
|
453
|
-
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const fetchParameters = { ...fetchOptionsRef.current, signal: controller.signal };
|
|
540
|
+
let loadedContent;
|
|
541
|
+
let hasCache = false;
|
|
542
|
+
if (cacheRequests) {
|
|
543
|
+
hasCache = cacheStore2.isCached(src);
|
|
544
|
+
loadedContent = await cacheStore2.get(src, fetchParameters);
|
|
545
|
+
} else {
|
|
546
|
+
loadedContent = await request(src, fetchParameters);
|
|
547
|
+
}
|
|
548
|
+
if (active) {
|
|
549
|
+
setState({ content: loadedContent, isCached: hasCache, status: STATUS.LOADED });
|
|
454
550
|
}
|
|
455
551
|
} catch (error) {
|
|
456
|
-
|
|
552
|
+
if (active && error.name !== "AbortError") {
|
|
553
|
+
handleError(error);
|
|
554
|
+
}
|
|
457
555
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
[]
|
|
465
|
-
);
|
|
556
|
+
})();
|
|
557
|
+
return () => {
|
|
558
|
+
active = false;
|
|
559
|
+
controller.abort();
|
|
560
|
+
};
|
|
561
|
+
}, [cacheRequests, cacheStore2, handleError, src, status]);
|
|
466
562
|
(0, import_react2.useEffect)(() => {
|
|
467
|
-
if (
|
|
468
|
-
|
|
563
|
+
if (status === STATUS.LOADED && content) {
|
|
564
|
+
getElement();
|
|
469
565
|
}
|
|
470
|
-
|
|
566
|
+
}, [content, getElement, status]);
|
|
567
|
+
(0, import_react2.useEffect)(() => {
|
|
568
|
+
if (!canUseDOM() || !previousProps || previousProps.src !== src) {
|
|
471
569
|
return;
|
|
472
570
|
}
|
|
473
|
-
if (previousProps.
|
|
474
|
-
if (!src) {
|
|
475
|
-
handleError(new Error("Missing src"));
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
load();
|
|
479
|
-
} else if (previousProps.title !== title || previousProps.description !== description) {
|
|
571
|
+
if (previousProps.title !== title || previousProps.description !== description) {
|
|
480
572
|
getElement();
|
|
481
573
|
}
|
|
482
|
-
}, [description, getElement,
|
|
574
|
+
}, [description, getElement, previousProps, src, title]);
|
|
483
575
|
(0, import_react2.useEffect)(() => {
|
|
484
576
|
if (!previousState) {
|
|
485
577
|
return;
|
|
486
578
|
}
|
|
487
|
-
if (
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
if (previousState.status !== STATUS.LOADED && status === STATUS.LOADED) {
|
|
491
|
-
getElement();
|
|
579
|
+
if (status === STATUS.READY && previousState.status !== STATUS.READY) {
|
|
580
|
+
onLoadRef.current?.(src, isCached);
|
|
492
581
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
"uniqueHash",
|
|
512
|
-
"uniquifyIDs"
|
|
513
|
-
);
|
|
582
|
+
}, [isCached, previousState, src, status]);
|
|
583
|
+
return { element, status };
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/provider.tsx
|
|
587
|
+
var import_react3 = __toESM(require("react"));
|
|
588
|
+
var CacheContext = (0, import_react3.createContext)(null);
|
|
589
|
+
function useCacheStore() {
|
|
590
|
+
return (0, import_react3.useContext)(CacheContext);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/index.tsx
|
|
594
|
+
var cacheStore = new CacheStore();
|
|
595
|
+
function InlineSVG(props) {
|
|
596
|
+
const { children = null, innerRef, loader = null } = props;
|
|
597
|
+
const contextStore = useCacheStore();
|
|
598
|
+
const store = contextStore ?? cacheStore;
|
|
599
|
+
const { element, status } = useInlineSVG(props, store);
|
|
514
600
|
if (!canUseDOM()) {
|
|
515
601
|
return loader;
|
|
516
602
|
}
|
|
517
603
|
if (element) {
|
|
518
|
-
return (0,
|
|
604
|
+
return (0, import_react4.cloneElement)(element, {
|
|
519
605
|
ref: innerRef,
|
|
520
|
-
...
|
|
606
|
+
...omit(
|
|
607
|
+
props,
|
|
608
|
+
"baseURL",
|
|
609
|
+
"cacheRequests",
|
|
610
|
+
"children",
|
|
611
|
+
"description",
|
|
612
|
+
"fetchOptions",
|
|
613
|
+
"innerRef",
|
|
614
|
+
"loader",
|
|
615
|
+
"onError",
|
|
616
|
+
"onLoad",
|
|
617
|
+
"preProcessor",
|
|
618
|
+
"src",
|
|
619
|
+
"title",
|
|
620
|
+
"uniqueHash",
|
|
621
|
+
"uniquifyIDs"
|
|
622
|
+
)
|
|
521
623
|
});
|
|
522
624
|
}
|
|
523
625
|
if ([STATUS.UNSUPPORTED, STATUS.FAILED].includes(status)) {
|
|
@@ -525,26 +627,6 @@ function ReactInlineSVG(props) {
|
|
|
525
627
|
}
|
|
526
628
|
return loader;
|
|
527
629
|
}
|
|
528
|
-
function InlineSVG(props) {
|
|
529
|
-
if (!cacheStore) {
|
|
530
|
-
cacheStore = new CacheStore();
|
|
531
|
-
}
|
|
532
|
-
const { loader } = props;
|
|
533
|
-
const hasCallback = (0, import_react2.useRef)(false);
|
|
534
|
-
const [isReady, setReady] = (0, import_react2.useState)(cacheStore.isReady);
|
|
535
|
-
(0, import_react2.useEffect)(() => {
|
|
536
|
-
if (!hasCallback.current) {
|
|
537
|
-
cacheStore.onReady(() => {
|
|
538
|
-
setReady(true);
|
|
539
|
-
});
|
|
540
|
-
hasCallback.current = true;
|
|
541
|
-
}
|
|
542
|
-
}, []);
|
|
543
|
-
if (!isReady) {
|
|
544
|
-
return loader;
|
|
545
|
-
}
|
|
546
|
-
return /* @__PURE__ */ import_react2.default.createElement(ReactInlineSVG, { ...props });
|
|
547
|
-
}
|
|
548
630
|
// Annotate the CommonJS export names for ESM import in node:
|
|
549
631
|
0 && (module.exports = {
|
|
550
632
|
cacheStore
|