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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/config.ts","../src/modules/helpers.ts","../src/modules/cache.ts","../src/modules/hooks.tsx","../src/modules/utils.ts"],"sourcesContent":["import React, {\n cloneElement,\n isValidElement,\n ReactElement,\n useCallback,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react';\nimport convert from 'react-from-dom';\n\nimport { STATUS } from './config';\nimport CacheStore from './modules/cache';\nimport { canUseDOM, isSupportedEnvironment, omit, randomString, request } from './modules/helpers';\nimport { usePrevious } from './modules/hooks';\nimport { getNode } from './modules/utils';\nimport { FetchError, Props, State, Status } from './types';\n\n// eslint-disable-next-line import/no-mutable-exports\nexport let cacheStore: CacheStore;\n\nfunction ReactInlineSVG(props: Props) {\n const {\n cacheRequests = true,\n children = null,\n description,\n fetchOptions,\n innerRef,\n loader = null,\n onError,\n onLoad,\n src,\n title,\n uniqueHash,\n } = props;\n const [state, setState] = useReducer(\n (previousState: State, nextState: Partial<State>) => ({\n ...previousState,\n ...nextState,\n }),\n {\n content: '',\n element: null,\n\n isCached: cacheRequests && cacheStore.isCached(props.src),\n status: STATUS.IDLE,\n },\n );\n const { content, element, isCached, status } = state;\n const previousProps = usePrevious(props);\n const previousState = usePrevious(state);\n\n const hash = useRef(uniqueHash ?? randomString(8));\n const isActive = useRef(false);\n const isInitialized = useRef(false);\n\n const handleError = useCallback(\n (error: Error | FetchError) => {\n if (isActive.current) {\n setState({\n status:\n error.message === 'Browser does not support SVG' ? STATUS.UNSUPPORTED : STATUS.FAILED,\n });\n\n onError?.(error);\n }\n },\n [onError],\n );\n\n const handleLoad = useCallback((loadedContent: string, hasCache = false) => {\n if (isActive.current) {\n setState({\n content: loadedContent,\n isCached: hasCache,\n status: STATUS.LOADED,\n });\n }\n }, []);\n\n const fetchContent = useCallback(async () => {\n const responseContent: string = await request(src, fetchOptions);\n\n handleLoad(responseContent);\n }, [fetchOptions, handleLoad, src]);\n\n const getElement = useCallback(() => {\n try {\n const node = getNode({ ...props, handleError, hash: hash.current, content }) as Node;\n const convertedElement = convert(node);\n\n if (!convertedElement || !isValidElement(convertedElement)) {\n throw new Error('Could not convert the src to a React element');\n }\n\n setState({\n element: convertedElement,\n status: STATUS.READY,\n });\n } catch (error: any) {\n handleError(new Error(error.message));\n }\n }, [content, handleError, props]);\n\n const getContent = useCallback(async () => {\n const dataURI = /^data:image\\/svg[^,]*?(;base64)?,(.*)/u.exec(src);\n let inlineSrc;\n\n if (dataURI) {\n inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);\n } else if (src.includes('<svg')) {\n inlineSrc = src;\n }\n\n if (inlineSrc) {\n handleLoad(inlineSrc);\n\n return;\n }\n\n try {\n if (cacheRequests) {\n const cachedContent = await cacheStore.get(src, fetchOptions);\n\n handleLoad(cachedContent, true);\n } else {\n await fetchContent();\n }\n } catch (error: any) {\n handleError(error);\n }\n }, [cacheRequests, fetchContent, fetchOptions, handleError, handleLoad, src]);\n\n const load = useCallback(async () => {\n if (isActive.current) {\n setState({\n content: '',\n element: null,\n isCached: false,\n status: STATUS.LOADING,\n });\n }\n }, []);\n\n // Run on mount\n useEffect(\n () => {\n isActive.current = true;\n\n if (!canUseDOM() || isInitialized.current) {\n return () => undefined;\n }\n\n try {\n if (status === STATUS.IDLE) {\n if (!isSupportedEnvironment()) {\n throw new Error('Browser does not support SVG');\n }\n\n if (!src) {\n throw new Error('Missing src');\n }\n\n load();\n }\n } catch (error: any) {\n handleError(error);\n }\n\n isInitialized.current = true;\n\n return () => {\n isActive.current = false;\n };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Handle prop changes\n useEffect(() => {\n if (!canUseDOM()) {\n return;\n }\n\n if (!previousProps) {\n return;\n }\n\n if (previousProps.src !== src) {\n if (!src) {\n handleError(new Error('Missing src'));\n\n return;\n }\n\n load();\n } else if (previousProps.title !== title || previousProps.description !== description) {\n getElement();\n }\n }, [description, getElement, handleError, load, previousProps, src, title]);\n\n // handle state\n useEffect(() => {\n if (!previousState) {\n return;\n }\n\n if (previousState.status !== STATUS.LOADING && status === STATUS.LOADING) {\n getContent();\n }\n\n if (previousState.status !== STATUS.LOADED && status === STATUS.LOADED) {\n getElement();\n }\n\n if (previousState.status !== STATUS.READY && status === STATUS.READY) {\n onLoad?.(src, isCached);\n }\n }, [getContent, getElement, isCached, onLoad, previousState, src, status]);\n\n const elementProps = omit(\n props,\n 'baseURL',\n 'cacheRequests',\n 'children',\n 'description',\n 'fetchOptions',\n 'innerRef',\n 'loader',\n 'onError',\n 'onLoad',\n 'preProcessor',\n 'src',\n 'title',\n 'uniqueHash',\n 'uniquifyIDs',\n );\n\n if (!canUseDOM()) {\n return loader;\n }\n\n if (element) {\n return cloneElement(element as ReactElement<any>, {\n ref: innerRef,\n ...elementProps,\n });\n }\n\n if (([STATUS.UNSUPPORTED, STATUS.FAILED] as Status[]).includes(status)) {\n return children;\n }\n\n return loader;\n}\n\nexport default function InlineSVG(props: Props) {\n if (!cacheStore) {\n cacheStore = new CacheStore();\n }\n\n const { loader } = props;\n const hasCallback = useRef(false);\n const [isReady, setReady] = useState(cacheStore.isReady);\n\n useEffect(() => {\n if (!hasCallback.current) {\n cacheStore.onReady(() => {\n setReady(true);\n });\n\n hasCallback.current = true;\n }\n }, []);\n\n if (!isReady) {\n return loader;\n }\n\n return <ReactInlineSVG {...props} />;\n}\n\nexport * from './types';\n","export const CACHE_NAME = 'react-inlinesvg';\nexport const CACHE_MAX_RETRIES = 10;\n\nexport const STATUS = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n FAILED: 'failed',\n READY: 'ready',\n UNSUPPORTED: 'unsupported',\n} as const;\n","import type { PlainObject } from '../types';\n\nfunction randomCharacter(character: string) {\n return character[Math.floor(Math.random() * character.length)];\n}\n\nexport function canUseDOM(): boolean {\n return !!(typeof window !== 'undefined' && window.document?.createElement);\n}\n\nexport function isSupportedEnvironment(): boolean {\n return supportsInlineSVG() && typeof window !== 'undefined' && window !== null;\n}\n\n/**\n * Remove properties from an object\n */\nexport function omit<T extends PlainObject, K extends keyof T>(\n input: T,\n ...filter: K[]\n): Omit<T, K> {\n const output: any = {};\n\n for (const key in input) {\n if ({}.hasOwnProperty.call(input, key)) {\n if (!filter.includes(key as unknown as K)) {\n output[key] = input[key];\n }\n }\n }\n\n return output as Omit<T, K>;\n}\n\nexport function randomString(length: number): string {\n const letters = 'abcdefghijklmnopqrstuvwxyz';\n const numbers = '1234567890';\n const charset = `${letters}${letters.toUpperCase()}${numbers}`;\n\n let R = '';\n\n for (let index = 0; index < length; index++) {\n R += randomCharacter(charset);\n }\n\n return R;\n}\n\nexport async function request(url: string, options?: RequestInit) {\n const response = await fetch(url, options);\n const contentType = response.headers.get('content-type');\n const [fileType] = (contentType ?? '').split(/ ?; ?/);\n\n if (response.status > 299) {\n throw new Error('Not found');\n }\n\n if (!['image/svg+xml', 'text/plain'].some(d => fileType.includes(d))) {\n throw new Error(`Content type isn't valid: ${fileType}`);\n }\n\n return response.text();\n}\n\nexport function sleep(seconds = 1) {\n return new Promise(resolve => {\n setTimeout(resolve, seconds * 1000);\n });\n}\n\nexport function supportsInlineSVG(): boolean {\n /* c8 ignore next 3 */\n if (!document) {\n return false;\n }\n\n const div = document.createElement('div');\n\n div.innerHTML = '<svg />';\n const svg = div.firstChild as SVGSVGElement;\n\n return !!svg && svg.namespaceURI === 'http://www.w3.org/2000/svg';\n}\n","import { CACHE_MAX_RETRIES, CACHE_NAME, STATUS } from '../config';\nimport { StorageItem } from '../types';\n\nimport { canUseDOM, request, sleep } from './helpers';\n\nexport default class CacheStore {\n private cacheApi: Cache | undefined;\n private readonly cacheStore: Map<string, StorageItem>;\n private readonly subscribers: Array<() => void> = [];\n public isReady = false;\n\n constructor() {\n this.cacheStore = new Map<string, StorageItem>();\n\n let cacheName = CACHE_NAME;\n let usePersistentCache = false;\n\n if (canUseDOM()) {\n cacheName = window.REACT_INLINESVG_CACHE_NAME ?? CACHE_NAME;\n usePersistentCache = !!window.REACT_INLINESVG_PERSISTENT_CACHE && 'caches' in window;\n }\n\n if (usePersistentCache) {\n caches\n .open(cacheName)\n .then(cache => {\n this.cacheApi = cache;\n })\n .catch(error => {\n // eslint-disable-next-line no-console\n console.error(`Failed to open cache: ${error.message}`);\n })\n .finally(() => {\n this.isReady = true;\n this.subscribers.forEach(callback => callback());\n });\n } else {\n this.isReady = true;\n }\n }\n\n public onReady(callback: () => void) {\n if (this.isReady) {\n callback();\n } else {\n this.subscribers.push(callback);\n }\n }\n\n public async get(url: string, fetchOptions?: RequestInit) {\n await (this.cacheApi\n ? this.fetchAndAddToPersistentCache(url, fetchOptions)\n : this.fetchAndAddToInternalCache(url, fetchOptions));\n\n return this.cacheStore.get(url)?.content ?? '';\n }\n\n public set(url: string, data: StorageItem) {\n this.cacheStore.set(url, data);\n }\n\n public isCached(url: string) {\n return this.cacheStore.get(url)?.status === STATUS.LOADED;\n }\n\n private async fetchAndAddToInternalCache(url: string, fetchOptions?: RequestInit) {\n const cache = this.cacheStore.get(url);\n\n if (cache?.status === STATUS.LOADING) {\n await this.handleLoading(url, async () => {\n this.cacheStore.set(url, { content: '', status: STATUS.IDLE });\n await this.fetchAndAddToInternalCache(url, fetchOptions);\n });\n\n return;\n }\n\n if (!cache?.content) {\n this.cacheStore.set(url, { content: '', status: STATUS.LOADING });\n\n try {\n const content = await request(url, fetchOptions);\n\n this.cacheStore.set(url, { content, status: STATUS.LOADED });\n } catch (error: any) {\n this.cacheStore.set(url, { content: '', status: STATUS.FAILED });\n throw error;\n }\n }\n }\n\n private async fetchAndAddToPersistentCache(url: string, fetchOptions?: RequestInit) {\n const cache = this.cacheStore.get(url);\n\n if (cache?.status === STATUS.LOADED) {\n return;\n }\n\n if (cache?.status === STATUS.LOADING) {\n await this.handleLoading(url, async () => {\n this.cacheStore.set(url, { content: '', status: STATUS.IDLE });\n await this.fetchAndAddToPersistentCache(url, fetchOptions);\n });\n\n return;\n }\n\n this.cacheStore.set(url, { content: '', status: STATUS.LOADING });\n\n const data = await this.cacheApi?.match(url);\n\n if (data) {\n const content = await data.text();\n\n this.cacheStore.set(url, { content, status: STATUS.LOADED });\n\n return;\n }\n\n try {\n await this.cacheApi?.add(new Request(url, fetchOptions));\n\n const response = await this.cacheApi?.match(url);\n const content = (await response?.text()) ?? '';\n\n this.cacheStore.set(url, { content, status: STATUS.LOADED });\n } catch (error: any) {\n this.cacheStore.set(url, { content: '', status: STATUS.FAILED });\n throw error;\n }\n }\n\n private async handleLoading(url: string, callback: () => Promise<void>) {\n let retryCount = 0;\n\n while (this.cacheStore.get(url)?.status === STATUS.LOADING && retryCount < CACHE_MAX_RETRIES) {\n // eslint-disable-next-line no-await-in-loop\n await sleep(0.1);\n retryCount += 1;\n }\n\n if (retryCount >= CACHE_MAX_RETRIES) {\n await callback();\n }\n }\n\n public keys(): Array<string> {\n return [...this.cacheStore.keys()];\n }\n\n public data(): Array<Record<string, StorageItem>> {\n return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value }));\n }\n\n public async delete(url: string) {\n if (this.cacheApi) {\n await this.cacheApi.delete(url);\n }\n\n this.cacheStore.delete(url);\n }\n\n public async clear() {\n if (this.cacheApi) {\n const keys = await this.cacheApi.keys();\n\n for (const key of keys) {\n // eslint-disable-next-line no-await-in-loop\n await this.cacheApi.delete(key);\n }\n }\n\n this.cacheStore.clear();\n }\n}\n","import { useEffect, useRef } from 'react';\n\nexport function usePrevious<T>(state: T): T | undefined {\n const ref = useRef<T>(undefined);\n\n useEffect(() => {\n ref.current = state;\n });\n\n return ref.current;\n}\n","import convert from 'react-from-dom';\n\nimport { Props, State } from '../types';\n\ninterface GetNodeOptions extends Props, Pick<State, 'content'> {\n handleError: (error: Error) => void;\n hash: string;\n}\n\ninterface UpdateSVGAttributesOptions extends Pick<Props, 'baseURL' | 'uniquifyIDs'> {\n hash: string;\n}\n\nexport function getNode(options: GetNodeOptions) {\n const {\n baseURL,\n content,\n description,\n handleError,\n hash,\n preProcessor,\n title,\n uniquifyIDs = false,\n } = options;\n\n try {\n const svgText = processSVG(content, preProcessor);\n const node = convert(svgText, { nodeOnly: true });\n\n if (!node || !(node instanceof SVGSVGElement)) {\n throw new Error('Could not convert the src to a DOM Node');\n }\n\n const svg = updateSVGAttributes(node, { baseURL, hash, uniquifyIDs });\n\n if (description) {\n const originalDesc = svg.querySelector('desc');\n\n if (originalDesc?.parentNode) {\n originalDesc.parentNode.removeChild(originalDesc);\n }\n\n const descElement = document.createElementNS('http://www.w3.org/2000/svg', 'desc');\n\n descElement.innerHTML = description;\n svg.prepend(descElement);\n }\n\n if (typeof title !== 'undefined') {\n const originalTitle = svg.querySelector('title');\n\n if (originalTitle?.parentNode) {\n originalTitle.parentNode.removeChild(originalTitle);\n }\n\n if (title) {\n const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n\n titleElement.innerHTML = title;\n svg.prepend(titleElement);\n }\n }\n\n return svg;\n } catch (error: any) {\n return handleError(error);\n }\n}\n\nexport function processSVG(content: string, preProcessor?: Props['preProcessor']) {\n if (preProcessor) {\n return preProcessor(content);\n }\n\n return content;\n}\n\nexport function updateSVGAttributes(\n node: SVGSVGElement,\n options: UpdateSVGAttributesOptions,\n): SVGSVGElement {\n const { baseURL = '', hash, uniquifyIDs } = options;\n const replaceableAttributes = ['id', 'href', 'xlink:href', 'xlink:role', 'xlink:arcrole'];\n const linkAttributes = ['href', 'xlink:href'];\n const isDataValue = (name: string, value: string) =>\n linkAttributes.includes(name) && (value ? !value.includes('#') : false);\n\n if (!uniquifyIDs) {\n return node;\n }\n\n [...node.children].forEach(d => {\n if (d.attributes?.length) {\n const attributes = Object.values(d.attributes).map(a => {\n const attribute = a;\n const match = /url\\((.*?)\\)/.exec(a.value);\n\n if (match?.[1]) {\n attribute.value = a.value.replace(match[0], `url(${baseURL}${match[1]}__${hash})`);\n }\n\n return attribute;\n });\n\n replaceableAttributes.forEach(r => {\n const attribute = attributes.find(a => a.name === r);\n\n if (attribute && !isDataValue(r, attribute.value)) {\n attribute.value = `${attribute.value}__${hash}`;\n }\n });\n }\n\n if (d.children.length) {\n return updateSVGAttributes(d as SVGSVGElement, options);\n }\n\n return d;\n });\n\n return node;\n}\n"],"mappings":"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","names":["useEffect","useRef","convert","previousState","useRef","convert","useEffect"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/config.ts","../src/modules/helpers.ts","../src/modules/cache.ts","../src/modules/useInlineSVG.ts","../src/modules/hooks.tsx","../src/modules/utils.ts","../src/provider.tsx"],"sourcesContent":["import { cloneElement, ReactElement, SVGProps } from 'react';\n\nimport { STATUS } from './config';\nimport CacheStore from './modules/cache';\nimport { canUseDOM, omit } from './modules/helpers';\nimport useInlineSVG from './modules/useInlineSVG';\nimport { useCacheStore } from './provider';\nimport { Props, Status } from './types';\n\nexport const cacheStore = new CacheStore();\n\nexport default function InlineSVG(props: Props) {\n const { children = null, innerRef, loader = null } = props;\n const contextStore = useCacheStore();\n const store = contextStore ?? cacheStore;\n\n const { element, status } = useInlineSVG(props, store);\n\n if (!canUseDOM()) {\n return loader;\n }\n\n if (element) {\n return cloneElement(element as ReactElement<SVGProps<SVGElement>>, {\n ref: innerRef,\n ...omit(\n props,\n 'baseURL',\n 'cacheRequests',\n 'children',\n 'description',\n 'fetchOptions',\n 'innerRef',\n 'loader',\n 'onError',\n 'onLoad',\n 'preProcessor',\n 'src',\n 'title',\n 'uniqueHash',\n 'uniquifyIDs',\n ),\n });\n }\n\n if (([STATUS.UNSUPPORTED, STATUS.FAILED] as Status[]).includes(status)) {\n return children;\n }\n\n return loader;\n}\n\nexport * from './types';\n","export const CACHE_NAME = 'react-inlinesvg';\nexport const CACHE_MAX_RETRIES = 10;\n\nexport const STATUS = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n FAILED: 'failed',\n READY: 'ready',\n UNSUPPORTED: 'unsupported',\n} as const;\n","function randomCharacter(character: string) {\n return character[Math.floor(Math.random() * character.length)];\n}\n\nexport function canUseDOM(): boolean {\n return !!(typeof window !== 'undefined' && window.document?.createElement);\n}\n\nexport function isSupportedEnvironment(): boolean {\n return supportsInlineSVG() && typeof window !== 'undefined' && window !== null;\n}\n\n/**\n * Remove properties from an object\n */\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(\n input: T,\n ...filter: K[]\n): Omit<T, K> {\n const output: any = {};\n\n for (const key in input) {\n if ({}.hasOwnProperty.call(input, key)) {\n if (!filter.includes(key as unknown as K)) {\n output[key] = input[key];\n }\n }\n }\n\n return output as Omit<T, K>;\n}\n\nexport function randomString(length: number): string {\n const letters = 'abcdefghijklmnopqrstuvwxyz';\n const numbers = '1234567890';\n const charset = `${letters}${letters.toUpperCase()}${numbers}`;\n\n let R = '';\n\n for (let index = 0; index < length; index++) {\n R += randomCharacter(charset);\n }\n\n return R;\n}\n\nexport async function request(url: string, options?: RequestInit) {\n const response = await fetch(url, options);\n const contentType = response.headers.get('content-type');\n const [fileType] = (contentType ?? '').split(/ ?; ?/);\n\n if (response.status > 299) {\n throw new Error('Not found');\n }\n\n if (!['image/svg+xml', 'text/plain'].some(d => fileType.includes(d))) {\n throw new Error(`Content type isn't valid: ${fileType}`);\n }\n\n return response.text();\n}\n\nexport function supportsInlineSVG(): boolean {\n /* c8 ignore next 3 */\n if (!document) {\n return false;\n }\n\n const div = document.createElement('div');\n\n div.innerHTML = '<svg />';\n const svg = div.firstChild as SVGSVGElement;\n\n return !!svg && svg.namespaceURI === 'http://www.w3.org/2000/svg';\n}\n","import { CACHE_MAX_RETRIES, CACHE_NAME, STATUS } from '../config';\nimport { StorageItem } from '../types';\n\nimport { canUseDOM, request } from './helpers';\n\nexport interface CacheStoreOptions {\n name?: string;\n persistent?: boolean;\n}\n\nexport default class CacheStore {\n private cacheApi: Cache | undefined;\n private readonly cacheStore: Map<string, StorageItem>;\n private readonly subscribers: Array<() => void> = [];\n public isReady = false;\n\n constructor(options: CacheStoreOptions = {}) {\n const { name = CACHE_NAME, persistent = false } = options;\n\n this.cacheStore = new Map<string, StorageItem>();\n\n const usePersistentCache = persistent && canUseDOM() && 'caches' in window;\n\n if (usePersistentCache) {\n // eslint-disable-next-line promise/catch-or-return\n caches\n .open(name)\n .then(cache => {\n this.cacheApi = cache;\n })\n .catch(error => {\n // eslint-disable-next-line no-console\n console.error(`Failed to open cache: ${error.message}`);\n this.cacheApi = undefined;\n })\n .finally(() => {\n this.isReady = true;\n // Copy to avoid mutation issues\n const callbacks = [...this.subscribers];\n\n // Clear array efficiently\n this.subscribers.length = 0;\n\n callbacks.forEach(callback => {\n try {\n callback();\n } catch (error: any) {\n // eslint-disable-next-line no-console\n console.error(`Error in CacheStore subscriber callback: ${error.message}`);\n }\n });\n });\n } else {\n this.isReady = true;\n }\n }\n\n public onReady(callback: () => void): () => void {\n if (this.isReady) {\n callback();\n\n return () => {};\n }\n\n this.subscribers.push(callback);\n\n return () => {\n const index = this.subscribers.indexOf(callback);\n\n if (index >= 0) {\n this.subscribers.splice(index, 1);\n }\n };\n }\n\n private waitForReady(): Promise<void> {\n if (this.isReady) {\n return Promise.resolve();\n }\n\n return new Promise(resolve => {\n this.onReady(resolve);\n });\n }\n\n public async get(url: string, fetchOptions?: RequestInit) {\n await this.fetchAndCache(url, fetchOptions);\n\n return this.cacheStore.get(url)?.content ?? '';\n }\n\n public getContent(url: string): string {\n return this.cacheStore.get(url)?.content ?? '';\n }\n\n public set(url: string, data: StorageItem) {\n this.cacheStore.set(url, data);\n }\n\n public isCached(url: string) {\n return this.cacheStore.get(url)?.status === STATUS.LOADED;\n }\n\n private async fetchAndCache(url: string, fetchOptions?: RequestInit) {\n if (!this.isReady) {\n await this.waitForReady();\n }\n\n const cache = this.cacheStore.get(url);\n\n if (cache?.status === STATUS.LOADED) {\n return;\n }\n\n if (cache?.status === STATUS.LOADING) {\n await this.handleLoading(url, fetchOptions?.signal || undefined, async () => {\n this.cacheStore.set(url, { content: '', status: STATUS.IDLE });\n await this.fetchAndCache(url, fetchOptions);\n });\n\n return;\n }\n\n this.cacheStore.set(url, { content: '', status: STATUS.LOADING });\n\n try {\n const content = this.cacheApi\n ? await this.fetchFromPersistentCache(url, fetchOptions)\n : await request(url, fetchOptions);\n\n this.cacheStore.set(url, { content, status: STATUS.LOADED });\n } catch (error: any) {\n this.cacheStore.set(url, { content: '', status: STATUS.FAILED });\n throw error;\n }\n }\n\n private async fetchFromPersistentCache(url: string, fetchOptions?: RequestInit): Promise<string> {\n const data = await this.cacheApi?.match(url);\n\n if (data) {\n return data.text();\n }\n\n await this.cacheApi?.add(new Request(url, fetchOptions));\n\n const response = await this.cacheApi?.match(url);\n\n return (await response?.text()) ?? '';\n }\n\n private async handleLoading(\n url: string,\n signal: AbortSignal | undefined,\n callback: () => Promise<void>,\n ) {\n for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) {\n if (signal?.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new DOMException('The operation was aborted.', 'AbortError');\n }\n\n if (this.cacheStore.get(url)?.status !== STATUS.LOADING) {\n return;\n }\n\n await sleep(0.1);\n }\n\n await callback();\n }\n\n public keys(): Array<string> {\n return [...this.cacheStore.keys()];\n }\n\n public data(): Array<Record<string, StorageItem>> {\n return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value }));\n }\n\n public async delete(url: string) {\n if (this.cacheApi) {\n await this.cacheApi.delete(url);\n }\n\n this.cacheStore.delete(url);\n }\n\n public async clear() {\n if (this.cacheApi) {\n const keys = await this.cacheApi.keys();\n\n await Promise.allSettled(keys.map(key => this.cacheApi!.delete(key)));\n }\n\n this.cacheStore.clear();\n }\n}\n\nfunction sleep(seconds = 1) {\n return new Promise(resolve => {\n setTimeout(resolve, seconds * 1000);\n });\n}\n","import { isValidElement, useCallback, useEffect, useReducer, useRef } from 'react';\nimport convert from 'react-from-dom';\n\nimport { STATUS } from '../config';\nimport type { FetchError, Props, State } from '../types';\n\nimport type CacheStore from './cache';\nimport { canUseDOM, isSupportedEnvironment, randomString, request } from './helpers';\nimport { useMount, usePrevious } from './hooks';\nimport { getNode } from './utils';\n\nexport default function useInlineSVG(props: Props, cacheStore: CacheStore) {\n const {\n baseURL,\n cacheRequests = true,\n description,\n fetchOptions,\n onError,\n onLoad,\n preProcessor,\n src,\n title,\n uniqueHash,\n uniquifyIDs,\n } = props;\n\n const hash = useRef(uniqueHash ?? randomString(8));\n const fetchOptionsRef = useRef(fetchOptions);\n const onErrorRef = useRef(onError);\n const onLoadRef = useRef(onLoad);\n const preProcessorRef = useRef(preProcessor);\n\n fetchOptionsRef.current = fetchOptions;\n onErrorRef.current = onError;\n onLoadRef.current = onLoad;\n preProcessorRef.current = preProcessor;\n\n const [state, setState] = useReducer(\n (previousState: State, nextState: Partial<State>) => ({\n ...previousState,\n ...nextState,\n }),\n {\n content: '',\n element: null,\n isCached: false,\n status: STATUS.IDLE,\n },\n (initial): State => {\n const cached = cacheRequests && cacheStore.isCached(src);\n\n if (!cached) {\n return initial;\n }\n\n const cachedContent = cacheStore.getContent(src);\n\n try {\n const node = getNode({\n ...props,\n handleError: () => {},\n hash: hash.current,\n content: cachedContent,\n });\n\n if (!node) {\n return { ...initial, content: cachedContent, isCached: true, status: STATUS.LOADED };\n }\n\n const convertedElement = convert(node as Node);\n\n if (convertedElement && isValidElement(convertedElement)) {\n return {\n content: cachedContent,\n element: convertedElement,\n isCached: true,\n status: STATUS.READY,\n };\n }\n } catch {\n // Fall through to effect-driven flow\n }\n\n return {\n ...initial,\n content: cachedContent,\n isCached: true,\n status: STATUS.LOADED,\n };\n },\n );\n const { content, element, isCached, status } = state;\n const previousProps = usePrevious(props);\n const previousState = usePrevious(state);\n const isActive = useRef(false);\n const isInitialized = useRef(false);\n\n const handleError = useCallback((error: Error | FetchError) => {\n if (isActive.current) {\n setState({\n status:\n error.message === 'Browser does not support SVG' ? STATUS.UNSUPPORTED : STATUS.FAILED,\n });\n\n onErrorRef.current?.(error);\n }\n }, []);\n\n const getElement = useCallback(() => {\n try {\n const node = getNode({\n baseURL,\n content,\n description,\n handleError,\n hash: hash.current,\n preProcessor: preProcessorRef.current,\n src,\n title,\n uniquifyIDs,\n }) as Node;\n const convertedElement = convert(node);\n\n if (!convertedElement || !isValidElement(convertedElement)) {\n throw new Error('Could not convert the src to a React element');\n }\n\n setState({\n element: convertedElement,\n status: STATUS.READY,\n });\n } catch (error: any) {\n handleError(error);\n }\n }, [baseURL, content, description, handleError, src, title, uniquifyIDs]);\n\n // Mount\n useMount(() => {\n isActive.current = true;\n\n if (!canUseDOM() || isInitialized.current) {\n return undefined;\n }\n\n try {\n if (status === STATUS.READY) {\n onLoadRef.current?.(src, isCached);\n } else if (status === STATUS.IDLE) {\n if (!isSupportedEnvironment()) {\n throw new Error('Browser does not support SVG');\n }\n\n if (!src) {\n throw new Error('Missing src');\n }\n\n setState({ content: '', element: null, isCached: false, status: STATUS.LOADING });\n }\n } catch (error: any) {\n handleError(error);\n }\n\n isInitialized.current = true;\n\n return () => {\n isActive.current = false;\n };\n });\n\n // Src changes\n useEffect(() => {\n if (!canUseDOM() || !previousProps) {\n return;\n }\n\n if (previousProps.src !== src) {\n if (!src) {\n handleError(new Error('Missing src'));\n\n return;\n }\n\n setState({ content: '', element: null, isCached: false, status: STATUS.LOADING });\n }\n }, [handleError, previousProps, src]);\n\n // Fetch content when status is LOADING\n useEffect(() => {\n if (status !== STATUS.LOADING) {\n return undefined;\n }\n\n const controller = new AbortController();\n let active = true;\n\n (async () => {\n try {\n const dataURI = /^data:image\\/svg[^,]*?(;base64)?,(.*)/.exec(src);\n let inlineSrc;\n\n if (dataURI) {\n inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);\n } else if (src.includes('<svg')) {\n inlineSrc = src;\n }\n\n if (inlineSrc) {\n if (active) {\n setState({ content: inlineSrc, isCached: false, status: STATUS.LOADED });\n }\n\n return;\n }\n\n const fetchParameters = { ...fetchOptionsRef.current, signal: controller.signal };\n let loadedContent: string;\n let hasCache = false;\n\n if (cacheRequests) {\n hasCache = cacheStore.isCached(src);\n loadedContent = await cacheStore.get(src, fetchParameters);\n } else {\n loadedContent = await request(src, fetchParameters);\n }\n\n if (active) {\n setState({ content: loadedContent, isCached: hasCache, status: STATUS.LOADED });\n }\n } catch (error: any) {\n if (active && error.name !== 'AbortError') {\n handleError(error);\n }\n }\n })();\n\n return () => {\n active = false;\n controller.abort();\n };\n }, [cacheRequests, cacheStore, handleError, src, status]);\n\n // LOADED -> READY\n useEffect(() => {\n if (status === STATUS.LOADED && content) {\n getElement();\n }\n }, [content, getElement, status]);\n\n // Title and description changes\n useEffect(() => {\n if (!canUseDOM() || !previousProps || previousProps.src !== src) {\n return;\n }\n\n if (previousProps.title !== title || previousProps.description !== description) {\n getElement();\n }\n }, [description, getElement, previousProps, src, title]);\n\n // READY -> onLoad\n useEffect(() => {\n if (!previousState) {\n return;\n }\n\n if (status === STATUS.READY && previousState.status !== STATUS.READY) {\n onLoadRef.current?.(src, isCached);\n }\n }, [isCached, previousState, src, status]);\n\n return { element, status };\n}\n","import { EffectCallback, useEffect, useRef } from 'react';\n\nexport function useMount(effect: EffectCallback) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(effect, []);\n}\n\nexport function usePrevious<T>(state: T): T | undefined {\n const ref = useRef<T>(undefined);\n\n useEffect(() => {\n ref.current = state;\n });\n\n return ref.current;\n}\n","import convert from 'react-from-dom';\n\nimport { Props, State } from '../types';\n\ninterface GetNodeOptions extends Props, Pick<State, 'content'> {\n handleError: (error: Error) => void;\n hash: string;\n}\n\ninterface UpdateSVGAttributesOptions extends Pick<Props, 'baseURL' | 'uniquifyIDs'> {\n hash: string;\n}\n\nfunction uniquifyStyleIds(svgText: string, hash: string, baseURL: string): string {\n const idMatches = svgText.matchAll(/\\bid=([\"'])([^\"']+)\\1/g);\n const ids = [...new Set([...idMatches].map(m => m[2]))];\n\n if (!ids.length) {\n return svgText;\n }\n\n ids.sort((a, b) => b.length - a.length);\n\n return svgText.replace(/<style[^>]*>([\\S\\s]*?)<\\/style>/gi, (fullMatch, cssContent) => {\n let modified = cssContent as string;\n\n for (const id of ids) {\n const escaped = id.replace(/[$()*+.?[\\\\\\]^{|}]/g, '\\\\$&');\n\n modified = modified.replace(\n new RegExp(`url\\\\((['\"]?)#${escaped}\\\\1\\\\)`, 'g'),\n `url($1${baseURL}#${id}__${hash}$1)`,\n );\n modified = modified.replace(\n new RegExp(`#${escaped}(?![a-zA-Z0-9_-])`, 'g'),\n `#${id}__${hash}`,\n );\n }\n\n return fullMatch.replace(cssContent, modified);\n });\n}\n\nexport function getNode(options: GetNodeOptions) {\n const {\n baseURL,\n content,\n description,\n handleError,\n hash,\n preProcessor,\n title,\n uniquifyIDs = false,\n } = options;\n\n try {\n let svgText = processSVG(content, preProcessor);\n\n if (uniquifyIDs) {\n svgText = uniquifyStyleIds(svgText, hash, baseURL ?? '');\n }\n\n const node = convert(svgText, { nodeOnly: true });\n\n if (!node || !(node instanceof SVGSVGElement)) {\n throw new Error('Could not convert the src to a DOM Node');\n }\n\n const svg = updateSVGAttributes(node, { baseURL, hash, uniquifyIDs });\n\n if (description) {\n const originalDesc = svg.querySelector('desc');\n\n if (originalDesc?.parentNode) {\n originalDesc.parentNode.removeChild(originalDesc);\n }\n\n const descElement = document.createElementNS('http://www.w3.org/2000/svg', 'desc');\n\n descElement.innerHTML = description;\n svg.prepend(descElement);\n }\n\n if (typeof title !== 'undefined') {\n const originalTitle = svg.querySelector('title');\n\n if (originalTitle?.parentNode) {\n originalTitle.parentNode.removeChild(originalTitle);\n }\n\n if (title) {\n const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n\n titleElement.innerHTML = title;\n svg.prepend(titleElement);\n }\n }\n\n return svg;\n } catch (error: any) {\n return handleError(error);\n }\n}\n\nexport function processSVG(content: string, preProcessor?: Props['preProcessor']) {\n if (preProcessor) {\n return preProcessor(content);\n }\n\n return content;\n}\n\nexport function updateSVGAttributes(\n node: SVGSVGElement,\n options: UpdateSVGAttributesOptions,\n): SVGSVGElement {\n const { baseURL = '', hash, uniquifyIDs } = options;\n const replaceableAttributes = ['id', 'href', 'xlink:href', 'xlink:role', 'xlink:arcrole'];\n const linkAttributes = ['href', 'xlink:href'];\n const isDataValue = (name: string, value: string) =>\n linkAttributes.includes(name) && (value ? !value.includes('#') : false);\n\n if (!uniquifyIDs) {\n return node;\n }\n\n [...node.children].forEach(d => {\n if (d.attributes?.length) {\n const attributes = Object.values(d.attributes).map(a => {\n const attribute = a;\n const match = /url\\((.*?)\\)/.exec(a.value);\n\n if (match?.[1]) {\n attribute.value = a.value.replace(match[0], `url(${baseURL}${match[1]}__${hash})`);\n }\n\n return attribute;\n });\n\n replaceableAttributes.forEach(r => {\n const attribute = attributes.find(a => a.name === r);\n\n if (attribute && !isDataValue(r, attribute.value)) {\n attribute.value = `${attribute.value}__${hash}`;\n }\n });\n }\n\n if (d.children.length) {\n return updateSVGAttributes(d as SVGSVGElement, options);\n }\n\n return d;\n });\n\n return node;\n}\n","import React, { createContext, ReactNode, useContext, useState } from 'react';\n\nimport CacheStore from './modules/cache';\n\nconst CacheContext = createContext<CacheStore | null>(null);\n\ninterface Props {\n children: ReactNode;\n name?: string;\n}\n\nexport default function CacheProvider({ children, name }: Props) {\n const [store] = useState(() => new CacheStore({ name, persistent: true }));\n\n return <CacheContext.Provider value={store}>{children}</CacheContext.Provider>;\n}\n\nexport function useCacheStore(): CacheStore | null {\n return useContext(CacheContext);\n}\n"],"mappings":"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","names":["useEffect","useRef","convert","cacheStore","useRef","previousState","convert","useEffect"]}
@@ -1,9 +1,11 @@
1
- import { ReactNode } from 'react';
1
+ import react__default, { ReactNode } from 'react';
2
+ import { C as CacheStore } from './cache-NLB60kAd.mjs';
2
3
 
3
4
  interface Props {
4
5
  children: ReactNode;
5
6
  name?: string;
6
7
  }
7
- declare function CacheProvider({ children, name }: Props): ReactNode;
8
+ declare function CacheProvider({ children, name }: Props): react__default.JSX.Element;
9
+ declare function useCacheStore(): CacheStore | null;
8
10
 
9
- export { CacheProvider as default };
11
+ export { CacheProvider as default, useCacheStore };
@@ -1,10 +1,12 @@
1
- import { ReactNode } from 'react';
1
+ import react__default, { ReactNode } from 'react';
2
+ import { C as CacheStore } from './cache-NLB60kAd.js';
2
3
 
3
4
  interface Props {
4
5
  children: ReactNode;
5
6
  name?: string;
6
7
  }
7
- declare function CacheProvider({ children, name }: Props): ReactNode;
8
+ declare function CacheProvider({ children, name }: Props): react__default.JSX.Element;
9
+ declare function useCacheStore(): CacheStore | null;
8
10
 
9
- export { CacheProvider as default };
11
+ export { CacheProvider as default, useCacheStore };
10
12
  export = CacheProvider
package/dist/provider.js CHANGED
@@ -1,9 +1,12 @@
1
1
  "use client";
2
2
  "use strict";
3
+ var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
6
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
10
  var __export = (target, all) => {
8
11
  for (var name in all)
9
12
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,28 +19,206 @@ var __copyProps = (to, from, except, desc) => {
16
19
  }
17
20
  return to;
18
21
  };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
19
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
20
32
 
21
33
  // src/provider.tsx
22
34
  var provider_exports = {};
23
35
  __export(provider_exports, {
24
- default: () => CacheProvider
36
+ default: () => CacheProvider,
37
+ useCacheStore: () => useCacheStore
25
38
  });
26
39
  module.exports = __toCommonJS(provider_exports);
40
+ var import_react = __toESM(require("react"));
41
+
42
+ // src/config.ts
43
+ var CACHE_NAME = "react-inlinesvg";
44
+ var CACHE_MAX_RETRIES = 10;
45
+ var STATUS = {
46
+ IDLE: "idle",
47
+ LOADING: "loading",
48
+ LOADED: "loaded",
49
+ FAILED: "failed",
50
+ READY: "ready",
51
+ UNSUPPORTED: "unsupported"
52
+ };
27
53
 
28
54
  // src/modules/helpers.ts
29
55
  function canUseDOM() {
30
56
  return !!(typeof window !== "undefined" && window.document?.createElement);
31
57
  }
58
+ async function request(url, options) {
59
+ const response = await fetch(url, options);
60
+ const contentType = response.headers.get("content-type");
61
+ const [fileType] = (contentType ?? "").split(/ ?; ?/);
62
+ if (response.status > 299) {
63
+ throw new Error("Not found");
64
+ }
65
+ if (!["image/svg+xml", "text/plain"].some((d) => fileType.includes(d))) {
66
+ throw new Error(`Content type isn't valid: ${fileType}`);
67
+ }
68
+ return response.text();
69
+ }
70
+
71
+ // src/modules/cache.ts
72
+ var CacheStore = class {
73
+ constructor(options = {}) {
74
+ __publicField(this, "cacheApi");
75
+ __publicField(this, "cacheStore");
76
+ __publicField(this, "subscribers", []);
77
+ __publicField(this, "isReady", false);
78
+ const { name = CACHE_NAME, persistent = false } = options;
79
+ this.cacheStore = /* @__PURE__ */ new Map();
80
+ const usePersistentCache = persistent && canUseDOM() && "caches" in window;
81
+ if (usePersistentCache) {
82
+ caches.open(name).then((cache) => {
83
+ this.cacheApi = cache;
84
+ }).catch((error) => {
85
+ console.error(`Failed to open cache: ${error.message}`);
86
+ this.cacheApi = void 0;
87
+ }).finally(() => {
88
+ this.isReady = true;
89
+ const callbacks = [...this.subscribers];
90
+ this.subscribers.length = 0;
91
+ callbacks.forEach((callback) => {
92
+ try {
93
+ callback();
94
+ } catch (error) {
95
+ console.error(`Error in CacheStore subscriber callback: ${error.message}`);
96
+ }
97
+ });
98
+ });
99
+ } else {
100
+ this.isReady = true;
101
+ }
102
+ }
103
+ onReady(callback) {
104
+ if (this.isReady) {
105
+ callback();
106
+ return () => {
107
+ };
108
+ }
109
+ this.subscribers.push(callback);
110
+ return () => {
111
+ const index = this.subscribers.indexOf(callback);
112
+ if (index >= 0) {
113
+ this.subscribers.splice(index, 1);
114
+ }
115
+ };
116
+ }
117
+ waitForReady() {
118
+ if (this.isReady) {
119
+ return Promise.resolve();
120
+ }
121
+ return new Promise((resolve) => {
122
+ this.onReady(resolve);
123
+ });
124
+ }
125
+ async get(url, fetchOptions) {
126
+ await this.fetchAndCache(url, fetchOptions);
127
+ return this.cacheStore.get(url)?.content ?? "";
128
+ }
129
+ getContent(url) {
130
+ return this.cacheStore.get(url)?.content ?? "";
131
+ }
132
+ set(url, data) {
133
+ this.cacheStore.set(url, data);
134
+ }
135
+ isCached(url) {
136
+ return this.cacheStore.get(url)?.status === STATUS.LOADED;
137
+ }
138
+ async fetchAndCache(url, fetchOptions) {
139
+ if (!this.isReady) {
140
+ await this.waitForReady();
141
+ }
142
+ const cache = this.cacheStore.get(url);
143
+ if (cache?.status === STATUS.LOADED) {
144
+ return;
145
+ }
146
+ if (cache?.status === STATUS.LOADING) {
147
+ await this.handleLoading(url, fetchOptions?.signal || void 0, async () => {
148
+ this.cacheStore.set(url, { content: "", status: STATUS.IDLE });
149
+ await this.fetchAndCache(url, fetchOptions);
150
+ });
151
+ return;
152
+ }
153
+ this.cacheStore.set(url, { content: "", status: STATUS.LOADING });
154
+ try {
155
+ const content = this.cacheApi ? await this.fetchFromPersistentCache(url, fetchOptions) : await request(url, fetchOptions);
156
+ this.cacheStore.set(url, { content, status: STATUS.LOADED });
157
+ } catch (error) {
158
+ this.cacheStore.set(url, { content: "", status: STATUS.FAILED });
159
+ throw error;
160
+ }
161
+ }
162
+ async fetchFromPersistentCache(url, fetchOptions) {
163
+ const data = await this.cacheApi?.match(url);
164
+ if (data) {
165
+ return data.text();
166
+ }
167
+ await this.cacheApi?.add(new Request(url, fetchOptions));
168
+ const response = await this.cacheApi?.match(url);
169
+ return await response?.text() ?? "";
170
+ }
171
+ async handleLoading(url, signal, callback) {
172
+ for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) {
173
+ if (signal?.aborted) {
174
+ throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
175
+ }
176
+ if (this.cacheStore.get(url)?.status !== STATUS.LOADING) {
177
+ return;
178
+ }
179
+ await sleep(0.1);
180
+ }
181
+ await callback();
182
+ }
183
+ keys() {
184
+ return [...this.cacheStore.keys()];
185
+ }
186
+ data() {
187
+ return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value }));
188
+ }
189
+ async delete(url) {
190
+ if (this.cacheApi) {
191
+ await this.cacheApi.delete(url);
192
+ }
193
+ this.cacheStore.delete(url);
194
+ }
195
+ async clear() {
196
+ if (this.cacheApi) {
197
+ const keys = await this.cacheApi.keys();
198
+ await Promise.allSettled(keys.map((key) => this.cacheApi.delete(key)));
199
+ }
200
+ this.cacheStore.clear();
201
+ }
202
+ };
203
+ function sleep(seconds = 1) {
204
+ return new Promise((resolve) => {
205
+ setTimeout(resolve, seconds * 1e3);
206
+ });
207
+ }
32
208
 
33
209
  // src/provider.tsx
210
+ var CacheContext = (0, import_react.createContext)(null);
34
211
  function CacheProvider({ children, name }) {
35
- if (canUseDOM()) {
36
- window.REACT_INLINESVG_CACHE_NAME = name;
37
- window.REACT_INLINESVG_PERSISTENT_CACHE = true;
38
- }
39
- return children;
212
+ const [store] = (0, import_react.useState)(() => new CacheStore({ name, persistent: true }));
213
+ return /* @__PURE__ */ import_react.default.createElement(CacheContext.Provider, { value: store }, children);
214
+ }
215
+ function useCacheStore() {
216
+ return (0, import_react.useContext)(CacheContext);
40
217
  }
218
+ // Annotate the CommonJS export names for ESM import in node:
219
+ 0 && (module.exports = {
220
+ useCacheStore
221
+ });
41
222
  //# sourceMappingURL=provider.js.map
42
223
  // fix-cjs-exports
43
224
  if (module.exports.default) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.tsx","../src/modules/helpers.ts"],"sourcesContent":["import { ReactNode } from 'react';\n\nimport { canUseDOM } from './modules/helpers';\n\ninterface Props {\n children: ReactNode;\n name?: string;\n}\n\nexport default function CacheProvider({ children, name }: Props) {\n if (canUseDOM()) {\n window.REACT_INLINESVG_CACHE_NAME = name;\n window.REACT_INLINESVG_PERSISTENT_CACHE = true;\n }\n\n return children;\n}\n","import type { PlainObject } from '../types';\n\nfunction randomCharacter(character: string) {\n return character[Math.floor(Math.random() * character.length)];\n}\n\nexport function canUseDOM(): boolean {\n return !!(typeof window !== 'undefined' && window.document?.createElement);\n}\n\nexport function isSupportedEnvironment(): boolean {\n return supportsInlineSVG() && typeof window !== 'undefined' && window !== null;\n}\n\n/**\n * Remove properties from an object\n */\nexport function omit<T extends PlainObject, K extends keyof T>(\n input: T,\n ...filter: K[]\n): Omit<T, K> {\n const output: any = {};\n\n for (const key in input) {\n if ({}.hasOwnProperty.call(input, key)) {\n if (!filter.includes(key as unknown as K)) {\n output[key] = input[key];\n }\n }\n }\n\n return output as Omit<T, K>;\n}\n\nexport function randomString(length: number): string {\n const letters = 'abcdefghijklmnopqrstuvwxyz';\n const numbers = '1234567890';\n const charset = `${letters}${letters.toUpperCase()}${numbers}`;\n\n let R = '';\n\n for (let index = 0; index < length; index++) {\n R += randomCharacter(charset);\n }\n\n return R;\n}\n\nexport async function request(url: string, options?: RequestInit) {\n const response = await fetch(url, options);\n const contentType = response.headers.get('content-type');\n const [fileType] = (contentType ?? '').split(/ ?; ?/);\n\n if (response.status > 299) {\n throw new Error('Not found');\n }\n\n if (!['image/svg+xml', 'text/plain'].some(d => fileType.includes(d))) {\n throw new Error(`Content type isn't valid: ${fileType}`);\n }\n\n return response.text();\n}\n\nexport function sleep(seconds = 1) {\n return new Promise(resolve => {\n setTimeout(resolve, seconds * 1000);\n });\n}\n\nexport function supportsInlineSVG(): boolean {\n /* c8 ignore next 3 */\n if (!document) {\n return false;\n }\n\n const div = document.createElement('div');\n\n div.innerHTML = '<svg />';\n const svg = div.firstChild as SVGSVGElement;\n\n return !!svg && svg.namespaceURI === 'http://www.w3.org/2000/svg';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMO,SAAS,YAAqB;AACnC,SAAO,CAAC,EAAE,OAAO,WAAW,eAAe,OAAO,UAAU;AAC9D;;;ADCe,SAAR,cAA+B,EAAE,UAAU,KAAK,GAAU;AAC/D,MAAI,UAAU,GAAG;AACf,WAAO,6BAA6B;AACpC,WAAO,mCAAmC;AAAA,EAC5C;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/provider.tsx","../src/config.ts","../src/modules/helpers.ts","../src/modules/cache.ts"],"sourcesContent":["import React, { createContext, ReactNode, useContext, useState } from 'react';\n\nimport CacheStore from './modules/cache';\n\nconst CacheContext = createContext<CacheStore | null>(null);\n\ninterface Props {\n children: ReactNode;\n name?: string;\n}\n\nexport default function CacheProvider({ children, name }: Props) {\n const [store] = useState(() => new CacheStore({ name, persistent: true }));\n\n return <CacheContext.Provider value={store}>{children}</CacheContext.Provider>;\n}\n\nexport function useCacheStore(): CacheStore | null {\n return useContext(CacheContext);\n}\n","export const CACHE_NAME = 'react-inlinesvg';\nexport const CACHE_MAX_RETRIES = 10;\n\nexport const STATUS = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n FAILED: 'failed',\n READY: 'ready',\n UNSUPPORTED: 'unsupported',\n} as const;\n","function randomCharacter(character: string) {\n return character[Math.floor(Math.random() * character.length)];\n}\n\nexport function canUseDOM(): boolean {\n return !!(typeof window !== 'undefined' && window.document?.createElement);\n}\n\nexport function isSupportedEnvironment(): boolean {\n return supportsInlineSVG() && typeof window !== 'undefined' && window !== null;\n}\n\n/**\n * Remove properties from an object\n */\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(\n input: T,\n ...filter: K[]\n): Omit<T, K> {\n const output: any = {};\n\n for (const key in input) {\n if ({}.hasOwnProperty.call(input, key)) {\n if (!filter.includes(key as unknown as K)) {\n output[key] = input[key];\n }\n }\n }\n\n return output as Omit<T, K>;\n}\n\nexport function randomString(length: number): string {\n const letters = 'abcdefghijklmnopqrstuvwxyz';\n const numbers = '1234567890';\n const charset = `${letters}${letters.toUpperCase()}${numbers}`;\n\n let R = '';\n\n for (let index = 0; index < length; index++) {\n R += randomCharacter(charset);\n }\n\n return R;\n}\n\nexport async function request(url: string, options?: RequestInit) {\n const response = await fetch(url, options);\n const contentType = response.headers.get('content-type');\n const [fileType] = (contentType ?? '').split(/ ?; ?/);\n\n if (response.status > 299) {\n throw new Error('Not found');\n }\n\n if (!['image/svg+xml', 'text/plain'].some(d => fileType.includes(d))) {\n throw new Error(`Content type isn't valid: ${fileType}`);\n }\n\n return response.text();\n}\n\nexport function supportsInlineSVG(): boolean {\n /* c8 ignore next 3 */\n if (!document) {\n return false;\n }\n\n const div = document.createElement('div');\n\n div.innerHTML = '<svg />';\n const svg = div.firstChild as SVGSVGElement;\n\n return !!svg && svg.namespaceURI === 'http://www.w3.org/2000/svg';\n}\n","import { CACHE_MAX_RETRIES, CACHE_NAME, STATUS } from '../config';\nimport { StorageItem } from '../types';\n\nimport { canUseDOM, request } from './helpers';\n\nexport interface CacheStoreOptions {\n name?: string;\n persistent?: boolean;\n}\n\nexport default class CacheStore {\n private cacheApi: Cache | undefined;\n private readonly cacheStore: Map<string, StorageItem>;\n private readonly subscribers: Array<() => void> = [];\n public isReady = false;\n\n constructor(options: CacheStoreOptions = {}) {\n const { name = CACHE_NAME, persistent = false } = options;\n\n this.cacheStore = new Map<string, StorageItem>();\n\n const usePersistentCache = persistent && canUseDOM() && 'caches' in window;\n\n if (usePersistentCache) {\n // eslint-disable-next-line promise/catch-or-return\n caches\n .open(name)\n .then(cache => {\n this.cacheApi = cache;\n })\n .catch(error => {\n // eslint-disable-next-line no-console\n console.error(`Failed to open cache: ${error.message}`);\n this.cacheApi = undefined;\n })\n .finally(() => {\n this.isReady = true;\n // Copy to avoid mutation issues\n const callbacks = [...this.subscribers];\n\n // Clear array efficiently\n this.subscribers.length = 0;\n\n callbacks.forEach(callback => {\n try {\n callback();\n } catch (error: any) {\n // eslint-disable-next-line no-console\n console.error(`Error in CacheStore subscriber callback: ${error.message}`);\n }\n });\n });\n } else {\n this.isReady = true;\n }\n }\n\n public onReady(callback: () => void): () => void {\n if (this.isReady) {\n callback();\n\n return () => {};\n }\n\n this.subscribers.push(callback);\n\n return () => {\n const index = this.subscribers.indexOf(callback);\n\n if (index >= 0) {\n this.subscribers.splice(index, 1);\n }\n };\n }\n\n private waitForReady(): Promise<void> {\n if (this.isReady) {\n return Promise.resolve();\n }\n\n return new Promise(resolve => {\n this.onReady(resolve);\n });\n }\n\n public async get(url: string, fetchOptions?: RequestInit) {\n await this.fetchAndCache(url, fetchOptions);\n\n return this.cacheStore.get(url)?.content ?? '';\n }\n\n public getContent(url: string): string {\n return this.cacheStore.get(url)?.content ?? '';\n }\n\n public set(url: string, data: StorageItem) {\n this.cacheStore.set(url, data);\n }\n\n public isCached(url: string) {\n return this.cacheStore.get(url)?.status === STATUS.LOADED;\n }\n\n private async fetchAndCache(url: string, fetchOptions?: RequestInit) {\n if (!this.isReady) {\n await this.waitForReady();\n }\n\n const cache = this.cacheStore.get(url);\n\n if (cache?.status === STATUS.LOADED) {\n return;\n }\n\n if (cache?.status === STATUS.LOADING) {\n await this.handleLoading(url, fetchOptions?.signal || undefined, async () => {\n this.cacheStore.set(url, { content: '', status: STATUS.IDLE });\n await this.fetchAndCache(url, fetchOptions);\n });\n\n return;\n }\n\n this.cacheStore.set(url, { content: '', status: STATUS.LOADING });\n\n try {\n const content = this.cacheApi\n ? await this.fetchFromPersistentCache(url, fetchOptions)\n : await request(url, fetchOptions);\n\n this.cacheStore.set(url, { content, status: STATUS.LOADED });\n } catch (error: any) {\n this.cacheStore.set(url, { content: '', status: STATUS.FAILED });\n throw error;\n }\n }\n\n private async fetchFromPersistentCache(url: string, fetchOptions?: RequestInit): Promise<string> {\n const data = await this.cacheApi?.match(url);\n\n if (data) {\n return data.text();\n }\n\n await this.cacheApi?.add(new Request(url, fetchOptions));\n\n const response = await this.cacheApi?.match(url);\n\n return (await response?.text()) ?? '';\n }\n\n private async handleLoading(\n url: string,\n signal: AbortSignal | undefined,\n callback: () => Promise<void>,\n ) {\n for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) {\n if (signal?.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new DOMException('The operation was aborted.', 'AbortError');\n }\n\n if (this.cacheStore.get(url)?.status !== STATUS.LOADING) {\n return;\n }\n\n await sleep(0.1);\n }\n\n await callback();\n }\n\n public keys(): Array<string> {\n return [...this.cacheStore.keys()];\n }\n\n public data(): Array<Record<string, StorageItem>> {\n return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value }));\n }\n\n public async delete(url: string) {\n if (this.cacheApi) {\n await this.cacheApi.delete(url);\n }\n\n this.cacheStore.delete(url);\n }\n\n public async clear() {\n if (this.cacheApi) {\n const keys = await this.cacheApi.keys();\n\n await Promise.allSettled(keys.map(key => this.cacheApi!.delete(key)));\n }\n\n this.cacheStore.clear();\n }\n}\n\nfunction sleep(seconds = 1) {\n return new Promise(resolve => {\n setTimeout(resolve, seconds * 1000);\n });\n}\n"],"mappings":"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","names":["React"]}
package/dist/provider.mjs CHANGED
@@ -1,19 +1,189 @@
1
1
  "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+
6
+ // src/provider.tsx
7
+ import React, { createContext, useContext, useState } from "react";
8
+
9
+ // src/config.ts
10
+ var CACHE_NAME = "react-inlinesvg";
11
+ var CACHE_MAX_RETRIES = 10;
12
+ var STATUS = {
13
+ IDLE: "idle",
14
+ LOADING: "loading",
15
+ LOADED: "loaded",
16
+ FAILED: "failed",
17
+ READY: "ready",
18
+ UNSUPPORTED: "unsupported"
19
+ };
2
20
 
3
21
  // src/modules/helpers.ts
4
22
  function canUseDOM() {
5
23
  return !!(typeof window !== "undefined" && window.document?.createElement);
6
24
  }
25
+ async function request(url, options) {
26
+ const response = await fetch(url, options);
27
+ const contentType = response.headers.get("content-type");
28
+ const [fileType] = (contentType ?? "").split(/ ?; ?/);
29
+ if (response.status > 299) {
30
+ throw new Error("Not found");
31
+ }
32
+ if (!["image/svg+xml", "text/plain"].some((d) => fileType.includes(d))) {
33
+ throw new Error(`Content type isn't valid: ${fileType}`);
34
+ }
35
+ return response.text();
36
+ }
37
+
38
+ // src/modules/cache.ts
39
+ var CacheStore = class {
40
+ constructor(options = {}) {
41
+ __publicField(this, "cacheApi");
42
+ __publicField(this, "cacheStore");
43
+ __publicField(this, "subscribers", []);
44
+ __publicField(this, "isReady", false);
45
+ const { name = CACHE_NAME, persistent = false } = options;
46
+ this.cacheStore = /* @__PURE__ */ new Map();
47
+ const usePersistentCache = persistent && canUseDOM() && "caches" in window;
48
+ if (usePersistentCache) {
49
+ caches.open(name).then((cache) => {
50
+ this.cacheApi = cache;
51
+ }).catch((error) => {
52
+ console.error(`Failed to open cache: ${error.message}`);
53
+ this.cacheApi = void 0;
54
+ }).finally(() => {
55
+ this.isReady = true;
56
+ const callbacks = [...this.subscribers];
57
+ this.subscribers.length = 0;
58
+ callbacks.forEach((callback) => {
59
+ try {
60
+ callback();
61
+ } catch (error) {
62
+ console.error(`Error in CacheStore subscriber callback: ${error.message}`);
63
+ }
64
+ });
65
+ });
66
+ } else {
67
+ this.isReady = true;
68
+ }
69
+ }
70
+ onReady(callback) {
71
+ if (this.isReady) {
72
+ callback();
73
+ return () => {
74
+ };
75
+ }
76
+ this.subscribers.push(callback);
77
+ return () => {
78
+ const index = this.subscribers.indexOf(callback);
79
+ if (index >= 0) {
80
+ this.subscribers.splice(index, 1);
81
+ }
82
+ };
83
+ }
84
+ waitForReady() {
85
+ if (this.isReady) {
86
+ return Promise.resolve();
87
+ }
88
+ return new Promise((resolve) => {
89
+ this.onReady(resolve);
90
+ });
91
+ }
92
+ async get(url, fetchOptions) {
93
+ await this.fetchAndCache(url, fetchOptions);
94
+ return this.cacheStore.get(url)?.content ?? "";
95
+ }
96
+ getContent(url) {
97
+ return this.cacheStore.get(url)?.content ?? "";
98
+ }
99
+ set(url, data) {
100
+ this.cacheStore.set(url, data);
101
+ }
102
+ isCached(url) {
103
+ return this.cacheStore.get(url)?.status === STATUS.LOADED;
104
+ }
105
+ async fetchAndCache(url, fetchOptions) {
106
+ if (!this.isReady) {
107
+ await this.waitForReady();
108
+ }
109
+ const cache = this.cacheStore.get(url);
110
+ if (cache?.status === STATUS.LOADED) {
111
+ return;
112
+ }
113
+ if (cache?.status === STATUS.LOADING) {
114
+ await this.handleLoading(url, fetchOptions?.signal || void 0, async () => {
115
+ this.cacheStore.set(url, { content: "", status: STATUS.IDLE });
116
+ await this.fetchAndCache(url, fetchOptions);
117
+ });
118
+ return;
119
+ }
120
+ this.cacheStore.set(url, { content: "", status: STATUS.LOADING });
121
+ try {
122
+ const content = this.cacheApi ? await this.fetchFromPersistentCache(url, fetchOptions) : await request(url, fetchOptions);
123
+ this.cacheStore.set(url, { content, status: STATUS.LOADED });
124
+ } catch (error) {
125
+ this.cacheStore.set(url, { content: "", status: STATUS.FAILED });
126
+ throw error;
127
+ }
128
+ }
129
+ async fetchFromPersistentCache(url, fetchOptions) {
130
+ const data = await this.cacheApi?.match(url);
131
+ if (data) {
132
+ return data.text();
133
+ }
134
+ await this.cacheApi?.add(new Request(url, fetchOptions));
135
+ const response = await this.cacheApi?.match(url);
136
+ return await response?.text() ?? "";
137
+ }
138
+ async handleLoading(url, signal, callback) {
139
+ for (let retryCount = 0; retryCount < CACHE_MAX_RETRIES; retryCount++) {
140
+ if (signal?.aborted) {
141
+ throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
142
+ }
143
+ if (this.cacheStore.get(url)?.status !== STATUS.LOADING) {
144
+ return;
145
+ }
146
+ await sleep(0.1);
147
+ }
148
+ await callback();
149
+ }
150
+ keys() {
151
+ return [...this.cacheStore.keys()];
152
+ }
153
+ data() {
154
+ return [...this.cacheStore.entries()].map(([key, value]) => ({ [key]: value }));
155
+ }
156
+ async delete(url) {
157
+ if (this.cacheApi) {
158
+ await this.cacheApi.delete(url);
159
+ }
160
+ this.cacheStore.delete(url);
161
+ }
162
+ async clear() {
163
+ if (this.cacheApi) {
164
+ const keys = await this.cacheApi.keys();
165
+ await Promise.allSettled(keys.map((key) => this.cacheApi.delete(key)));
166
+ }
167
+ this.cacheStore.clear();
168
+ }
169
+ };
170
+ function sleep(seconds = 1) {
171
+ return new Promise((resolve) => {
172
+ setTimeout(resolve, seconds * 1e3);
173
+ });
174
+ }
7
175
 
8
176
  // src/provider.tsx
177
+ var CacheContext = createContext(null);
9
178
  function CacheProvider({ children, name }) {
10
- if (canUseDOM()) {
11
- window.REACT_INLINESVG_CACHE_NAME = name;
12
- window.REACT_INLINESVG_PERSISTENT_CACHE = true;
13
- }
14
- return children;
179
+ const [store] = useState(() => new CacheStore({ name, persistent: true }));
180
+ return /* @__PURE__ */ React.createElement(CacheContext.Provider, { value: store }, children);
181
+ }
182
+ function useCacheStore() {
183
+ return useContext(CacheContext);
15
184
  }
16
185
  export {
17
- CacheProvider as default
186
+ CacheProvider as default,
187
+ useCacheStore
18
188
  };
19
189
  //# sourceMappingURL=provider.mjs.map