UNPKG

react-inlinesvg

Version:
229 lines (223 loc) 7.62 kB
"use client"; "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/provider.tsx var provider_exports = {}; __export(provider_exports, { default: () => CacheProvider, useCacheStore: () => useCacheStore }); module.exports = __toCommonJS(provider_exports); var import_react = __toESM(require("react")); // src/config.ts var CACHE_NAME = "react-inlinesvg"; var CACHE_MAX_RETRIES = 10; var STATUS = { IDLE: "idle", LOADING: "loading", LOADED: "loaded", FAILED: "failed", READY: "ready", UNSUPPORTED: "unsupported" }; // src/modules/helpers.ts function canUseDOM() { return !!(typeof window !== "undefined" && window.document?.createElement); } async function request(url, options) { const response = await fetch(url, options); const contentType = response.headers.get("content-type"); const [fileType] = (contentType ?? "").split(/ ?; ?/); if (response.status > 299) { throw new Error("Not found"); } if (!["image/svg+xml", "text/plain"].some((d) => fileType.includes(d))) { throw new Error(`Content type isn't valid: ${fileType}`); } return response.text(); } // src/modules/cache.ts var CacheStore = class { constructor(options = {}) { __publicField(this, "cacheApi"); __publicField(this, "cacheStore"); __publicField(this, "subscribers", []); __publicField(this, "isReady", false); const { name = CACHE_NAME, persistent = false } = options; this.cacheStore = /* @__PURE__ */ new Map(); const usePersistentCache = persistent && canUseDOM() && "caches" in window; if (usePersistentCache) { caches.open(name).then((cache) => { this.cacheApi = cache; }).catch((error) => { console.error(`Failed to open cache: ${error.message}`); this.cacheApi = void 0; }).finally(() => { this.isReady = true; const callbacks = [...this.subscribers]; this.subscribers.length = 0; callbacks.forEach((callback) => { try { callback(); } catch (error) { console.error(`Error in CacheStore subscriber callback: ${error.message}`); } }); }); } else { this.isReady = true; } } onReady(callback) { if (this.isReady) { callback(); return () => { }; } this.subscribers.push(callback); return () => { const index = this.subscribers.indexOf(callback); if (index >= 0) { this.subscribers.splice(index, 1); } }; } waitForReady() { if (this.isReady) { return Promise.resolve(); } return new Promise((resolve) => { this.onReady(resolve); }); } async get(url, fetchOptions) { await this.fetchAndCache(url, fetchOptions); return this.cacheStore.get(url)?.content ?? ""; } getContent(url) { return this.cacheStore.get(url)?.content ?? ""; } set(url, data) { this.cacheStore.set(url, data); } isCached(url) { return this.cacheStore.get(url)?.status === STATUS.LOADED; } async fetchAndCache(url, fetchOptions) { if (!this.isReady) { await this.waitForReady(); } const cache = this.cacheStore.get(url); if (cache?.status === STATUS.LOADED) { return; } if (cache?.status === STATUS.LOADING) { await this.handleLoading(url, fetchOptions?.signal || void 0, async () => { this.cacheStore.set(url, { content: "", status: STATUS.IDLE }); await this.fetchAndCache(url, fetchOptions); }); return; } this.cacheStore.set(url, { content: "", status: STATUS.LOADING }); try { const content = this.cacheApi ? await this.fetchFromPersistentCache(url, fetchOptions) : await request(url, fetchOptions); this.cacheStore.set(url, { content, status: STATUS.LOADED }); } catch (error) { this.cacheStore.set(url, { content: "", status: STATUS.FAILED }); throw error; } } async fetchFromPersistentCache(url, fetchOptions) { const data = await this.cacheApi?.match(url); if (data) { return data.text(); } await this.cacheApi?.add(new Request(url, fetchOptions)); const response = await this.cacheApi?.match(url); return await response?.text() ?? ""; } async handleLoading(url, signal, callback) { for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) { if (signal?.aborted) { throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError"); } if (this.cacheStore.get(url)?.status !== STATUS.LOADING) { return; } await sleep(0.1); } await callback(); } keys() { return [...this.cacheStore.keys()]; } data() { return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value })); } async delete(url) { if (this.cacheApi) { await this.cacheApi.delete(url); } this.cacheStore.delete(url); } async clear() { if (this.cacheApi) { const keys = await this.cacheApi.keys(); await Promise.allSettled(keys.map((key) => this.cacheApi.delete(key))); } this.cacheStore.clear(); } }; function sleep(seconds = 1) { return new Promise((resolve) => { setTimeout(resolve, seconds * 1e3); }); } // src/provider.tsx var CacheContext = (0, import_react.createContext)(null); function CacheProvider({ children, name }) { const [store] = (0, import_react.useState)(() => new CacheStore({ name, persistent: true })); return /* @__PURE__ */ import_react.default.createElement(CacheContext.Provider, { value: store }, children); } function useCacheStore() { return (0, import_react.useContext)(CacheContext); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useCacheStore }); //# sourceMappingURL=provider.js.map // fix-cjs-exports if (module.exports.default) { Object.assign(module.exports.default, module.exports); module.exports = module.exports.default; delete module.exports.default; }