iconly 3.0.0-dev.0 → 3.0.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=(e,t,r)=>({code:e,message:t,cause:r}),f=e=>({ok:!0,value:e}),d=e=>({ok:!1,error:e}),S=(e,t)=>{let r=document.getElementById("iconset");r||(r=document.createElement("div"),r.id="iconset",r.setAttribute("aria-hidden","true"),r.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(r));const b=new DOMParser().parseFromString(t,"image/svg+xml"),g=b.querySelector("parsererror");if(g)return d(c("parse_error",`SVG parsing error: ${g.textContent??"Unknown error"}`));r.innerHTML="";const u=b.documentElement;if(!u)return d(c("parse_error","No valid SVG content found."));const m=document.importNode(u,!0);return r.appendChild(m),f(void 0)},x=async(e,t)=>{try{const r=await fetch(e,{signal:t});if(!r.ok)return d(c("fetch_failed",`Failed to fetch icons from "${e}".`));const i=await r.text();return f(i)}catch(r){return r instanceof DOMException&&r.name==="AbortError"?d(c("fetch_aborted","Fetch request was aborted.",r)):d(c("fetch_failed","Failed to fetch icons.",r))}},h=(e={})=>{const t=e.dbName??"iconlyDB",r=e.storeName??"icons";let i=null;const b=async()=>{if(i)return i;if(typeof indexedDB>"u")throw c("indexeddb_not_supported","IndexedDB is not supported.");return i=new Promise((l,n)=>{const o=indexedDB.open(t,1);o.onerror=()=>{n(c("indexeddb_open_failed","Failed to open IndexedDB connection.",o.error))},o.onupgradeneeded=s=>{const a=s.target.result;a.objectStoreNames.contains(r)||a.createObjectStore(r,{keyPath:"version"})},o.onsuccess=()=>l(o.result)}),i},g=(l,n)=>l.transaction(r,n).objectStore(r),u=(l,n,o)=>l&&typeof l=="object"&&"code"in l&&"message"in l?l:c(n,o,l);return{get:async l=>{try{const n=await b(),o=g(n,"readonly");return await new Promise(s=>{const a=o.get(l);a.onsuccess=()=>s(f(a.result)),a.onerror=()=>s(d(c("indexeddb_request_failed","Failed to read from IndexedDB.",a.error)))})}catch(n){return d(u(n,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async l=>{try{const n=await b(),o=g(n,"readwrite");return await new Promise(s=>{const a=o.put(l);a.onsuccess=()=>s(f(void 0)),a.onerror=()=>s(d(c("indexeddb_request_failed","Failed to write to IndexedDB.",a.error)))})}catch(n){return d(c("indexeddb_open_failed","Failed to open IndexedDB.",n))}}}},_=()=>{const e=new Map;return{get:async i=>e.has(i)?f({version:i,data:e.get(i)??""}):f(void 0),set:async i=>(e.set(i.version,i.data),f(void 0))}},D=(e={})=>{const t=e.keyPrefix??"iconly",r=()=>typeof window>"u"||!window.sessionStorage?d(c("storage_unavailable","SessionStorage is not available.")):f(window.sessionStorage);return{get:async g=>{const u=r();if(!u.ok)return u;try{const m=u.value.getItem(`${t}:${g}`);if(!m)return f(void 0);const y=JSON.parse(m);return f(y)}catch(m){return d(c("storage_read_failed","Failed to read from SessionStorage.",m))}},set:async g=>{const u=r();if(!u.ok)return u;try{return u.value.setItem(`${t}:${g.version}`,JSON.stringify(g)),f(void 0)}catch(m){return d(c("storage_write_failed","Failed to write to SessionStorage.",m))}}}},I=(e,t)=>!e||e==="indexeddb"?h({dbName:t.dbName,storeName:t.storeName}):e==="memory"?_():e==="session"?D({keyPrefix:t.sessionKeyPrefix}):e,N=(e={})=>{const t={file:e.file??"./icons.svg",version:e.version??"1.0",debug:e.debug??!1,container:e.container,logger:e.logger,onError:e.onError,onDebug:e.onDebug},r=I(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let i=null;const b=()=>{i==null||i.abort()},g=()=>{if(typeof document>"u")return d(c("container_invalid","Document is not available in this environment."));if(typeof t.container=="string"){const o=document.querySelector(t.container);return!o||!(o instanceof HTMLElement)?d(c("container_invalid",`Invalid container selector: "${t.container}".`)):f(o)}if(t.container instanceof HTMLElement)return f(t.container);const n=document.body??document.documentElement;return n?f(n):d(c("container_invalid","No valid container element found."))},u=(...n)=>{var o,s,a;t.debug&&((o=t.onDebug)==null||o.call(t,...n),(a=(s=t.logger)==null?void 0:s.debug)==null||a.call(s,"[Iconly debug]",...n))},m=n=>{var o,s,a;(o=t.onError)==null||o.call(t,n),(a=(s=t.logger)==null?void 0:s.error)==null||a.call(s,"[Iconly error]",n)},y=n=>(m(n),d(n));return{init:async()=>{var v;const n=g();if(!n.ok)return y(n.error);const o=await r.get(t.version);if(!o.ok)return y(o.error);let s=(v=o.value)==null?void 0:v.data;if(s)u("Using cached icon set",t.version);else{i=new AbortController;const p=await x(t.file,i.signal);if(!p.ok)return y(p.error);s=p.value;const w=await r.set({version:t.version,data:s});if(!w.ok)return y(w.error)}const a=S(n.value,s);return a.ok?(u("Iconly has successfully initialized."),f(void 0)):y(a.error)},abort:b}};exports.createIconly=N;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=(e,t,r)=>({code:e,message:t,cause:r}),u=e=>({ok:!0,value:e}),a=e=>({ok:!1,error:e}),w=(e,t)=>{let r=document.getElementById("iconset");r||(r=document.createElement("div"),r.id="iconset",r.setAttribute("aria-hidden","true"),r.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(r));const b=new DOMParser().parseFromString(t,"image/svg+xml"),f=b.querySelector("parsererror");if(f)return a(i("parse_error",`SVG parsing error: ${f.textContent??"Unknown error"}`));r.innerHTML="";const c=b.documentElement;if(!c)return a(i("parse_error","No valid SVG content found."));const m=document.importNode(c,!0);return r.appendChild(m),u(void 0)},S=async(e,t)=>{try{const r=await fetch(e,{signal:t});if(!r.ok)return a(i("fetch_failed",`Failed to fetch icons from "${e}".`));const o=await r.text();return u(o)}catch(r){return r instanceof DOMException&&r.name==="AbortError"?a(i("fetch_aborted","Fetch request was aborted.",r)):a(i("fetch_failed","Failed to fetch icons.",r))}},x=(e={})=>{const t=e.dbName??"iconlyDB",r=e.storeName??"icons";let o=null;const b=async()=>{if(o)return o;if(typeof indexedDB>"u")throw i("indexeddb_not_supported","IndexedDB is not supported.");return o=new Promise((d,n)=>{const s=indexedDB.open(t,1);s.onerror=()=>{n(i("indexeddb_open_failed","Failed to open IndexedDB connection.",s.error))},s.onupgradeneeded=g=>{const l=g.target.result;l.objectStoreNames.contains(r)||l.createObjectStore(r,{keyPath:"version"})},s.onsuccess=()=>d(s.result)}),o},f=(d,n)=>d.transaction(r,n).objectStore(r),c=(d,n,s)=>d&&typeof d=="object"&&"code"in d&&"message"in d?d:i(n,s,d);return{get:async d=>{try{const n=await b(),s=f(n,"readonly");return await new Promise(g=>{const l=s.get(d);l.onsuccess=()=>g(u(l.result)),l.onerror=()=>g(a(i("indexeddb_request_failed","Failed to read from IndexedDB.",l.error)))})}catch(n){return a(c(n,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async d=>{try{const n=await b(),s=f(n,"readwrite");return await new Promise(g=>{const l=s.put(d);l.onsuccess=()=>g(u(void 0)),l.onerror=()=>g(a(i("indexeddb_request_failed","Failed to write to IndexedDB.",l.error)))})}catch(n){return a(i("indexeddb_open_failed","Failed to open IndexedDB.",n))}}}},h=()=>{const e=new Map;return{get:async o=>e.has(o)?u({version:o,data:e.get(o)??""}):u(void 0),set:async o=>(e.set(o.version,o.data),u(void 0))}},_=(e={})=>{const t=e.keyPrefix??"iconly",r=()=>typeof window>"u"||!window.sessionStorage?a(i("storage_unavailable","SessionStorage is not available.")):u(window.sessionStorage);return{get:async f=>{const c=r();if(!c.ok)return c;try{const m=c.value.getItem(`${t}:${f}`);if(!m)return u(void 0);const y=JSON.parse(m);return u(y)}catch(m){return a(i("storage_read_failed","Failed to read from SessionStorage.",m))}},set:async f=>{const c=r();if(!c.ok)return c;try{return c.value.setItem(`${t}:${f.version}`,JSON.stringify(f)),u(void 0)}catch(m){return a(i("storage_write_failed","Failed to write to SessionStorage.",m))}}}},D=(e,t)=>!e||e==="indexeddb"?x({dbName:t.dbName,storeName:t.storeName}):e==="memory"?h():e==="session"?_({keyPrefix:t.sessionKeyPrefix}):e,I=(e={})=>{const t={file:e.file??"./icons.svg",version:e.version??"1.0",debug:e.debug??!1,container:e.container,logger:e.logger,onError:e.onError,onDebug:e.onDebug},r=D(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let o=null;const b=()=>{o?.abort()},f=()=>{if(typeof document>"u")return a(i("container_invalid","Document is not available in this environment."));if(typeof t.container=="string"){const s=document.querySelector(t.container);return!s||!(s instanceof HTMLElement)?a(i("container_invalid",`Invalid container selector: "${t.container}".`)):u(s)}if(t.container instanceof HTMLElement)return u(t.container);const n=document.body??document.documentElement;return n?u(n):a(i("container_invalid","No valid container element found."))},c=(...n)=>{t.debug&&(t.onDebug?.(...n),t.logger?.debug?.("[Iconly debug]",...n))},m=n=>{t.onError?.(n),t.logger?.error?.("[Iconly error]",n)},y=n=>(m(n),a(n));return{init:async()=>{const n=f();if(!n.ok)return y(n.error);const s=await r.get(t.version);if(!s.ok)return y(s.error);let g=s.value?.data;if(g)c("Using cached icon set",t.version);else{o=new AbortController;const v=await S(t.file,o.signal);if(!v.ok)return y(v.error);g=v.value;const p=await r.set({version:t.version,data:g});if(!p.ok)return y(p.error)}const l=w(n.value,g);return l.ok?(c("Iconly has successfully initialized."),u(void 0)):y(l.error)},abort:b}};exports.createIconly=I;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","_a","_c","_b","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,55 @@
1
- export { createIconly } from './core';
2
- export type { IconlyConfig, IconlyError, IconlyErrorCode, IconlyInstance, IconRecord, IconStorage, Logger, Result, StorageStrategy, } from './types';
3
- //# sourceMappingURL=index.d.ts.map
1
+ export declare const createIconly: (config?: IconlyConfig) => IconlyInstance;
2
+
3
+ export declare interface IconlyConfig {
4
+ file?: string;
5
+ version?: string;
6
+ debug?: boolean;
7
+ container?: string | HTMLElement;
8
+ storage?: StorageStrategy;
9
+ dbName?: string;
10
+ storeName?: string;
11
+ sessionKeyPrefix?: string;
12
+ logger?: Logger;
13
+ onError?: (error: IconlyError) => void;
14
+ onDebug?: (...messages: unknown[]) => void;
15
+ }
16
+
17
+ export declare interface IconlyError {
18
+ code: IconlyErrorCode;
19
+ message: string;
20
+ cause?: unknown;
21
+ }
22
+
23
+ export declare type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
24
+
25
+ export declare interface IconlyInstance {
26
+ init: () => Promise<Result<void>>;
27
+ abort: () => void;
28
+ }
29
+
30
+ export declare interface IconRecord {
31
+ version: string;
32
+ data: string;
33
+ }
34
+
35
+ export declare interface IconStorage {
36
+ get(version: string): Promise<Result<IconRecord | undefined>>;
37
+ set(record: IconRecord): Promise<Result<void>>;
38
+ }
39
+
40
+ export declare interface Logger {
41
+ debug?: (...messages: unknown[]) => void;
42
+ error?: (...messages: unknown[]) => void;
43
+ }
44
+
45
+ export declare type Result<T> = {
46
+ ok: true;
47
+ value: T;
48
+ } | {
49
+ ok: false;
50
+ error: IconlyError;
51
+ };
52
+
53
+ export declare type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
54
+
55
+ export { }
package/dist/index.es.js CHANGED
@@ -1,131 +1,131 @@
1
- const c = (e, t, r) => ({
1
+ const i = (e, t, r) => ({
2
2
  code: e,
3
3
  message: t,
4
4
  cause: r
5
- }), f = (e) => ({ ok: !0, value: e }), d = (e) => ({ ok: !1, error: e }), x = (e, t) => {
5
+ }), u = (e) => ({ ok: !0, value: e }), a = (e) => ({ ok: !1, error: e }), w = (e, t) => {
6
6
  let r = document.getElementById("iconset");
7
7
  r || (r = document.createElement("div"), r.id = "iconset", r.setAttribute("aria-hidden", "true"), r.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;", e.appendChild(r));
8
- const b = new DOMParser().parseFromString(t, "image/svg+xml"), g = b.querySelector("parsererror");
9
- if (g)
10
- return d(
11
- c(
8
+ const b = new DOMParser().parseFromString(t, "image/svg+xml"), f = b.querySelector("parsererror");
9
+ if (f)
10
+ return a(
11
+ i(
12
12
  "parse_error",
13
- `SVG parsing error: ${g.textContent ?? "Unknown error"}`
13
+ `SVG parsing error: ${f.textContent ?? "Unknown error"}`
14
14
  )
15
15
  );
16
16
  r.innerHTML = "";
17
- const u = b.documentElement;
18
- if (!u)
19
- return d(c("parse_error", "No valid SVG content found."));
20
- const m = document.importNode(u, !0);
21
- return r.appendChild(m), f(void 0);
22
- }, S = async (e, t) => {
17
+ const c = b.documentElement;
18
+ if (!c)
19
+ return a(i("parse_error", "No valid SVG content found."));
20
+ const m = document.importNode(c, !0);
21
+ return r.appendChild(m), u(void 0);
22
+ }, x = async (e, t) => {
23
23
  try {
24
24
  const r = await fetch(e, { signal: t });
25
25
  if (!r.ok)
26
- return d(c("fetch_failed", `Failed to fetch icons from "${e}".`));
27
- const i = await r.text();
28
- return f(i);
26
+ return a(i("fetch_failed", `Failed to fetch icons from "${e}".`));
27
+ const o = await r.text();
28
+ return u(o);
29
29
  } catch (r) {
30
- return r instanceof DOMException && r.name === "AbortError" ? d(c("fetch_aborted", "Fetch request was aborted.", r)) : d(c("fetch_failed", "Failed to fetch icons.", r));
30
+ return r instanceof DOMException && r.name === "AbortError" ? a(i("fetch_aborted", "Fetch request was aborted.", r)) : a(i("fetch_failed", "Failed to fetch icons.", r));
31
31
  }
32
- }, h = (e = {}) => {
32
+ }, S = (e = {}) => {
33
33
  const t = e.dbName ?? "iconlyDB", r = e.storeName ?? "icons";
34
- let i = null;
34
+ let o = null;
35
35
  const b = async () => {
36
- if (i)
37
- return i;
36
+ if (o)
37
+ return o;
38
38
  if (typeof indexedDB > "u")
39
- throw c("indexeddb_not_supported", "IndexedDB is not supported.");
40
- return i = new Promise((l, n) => {
41
- const o = indexedDB.open(t, 1);
42
- o.onerror = () => {
39
+ throw i("indexeddb_not_supported", "IndexedDB is not supported.");
40
+ return o = new Promise((d, n) => {
41
+ const s = indexedDB.open(t, 1);
42
+ s.onerror = () => {
43
43
  n(
44
- c(
44
+ i(
45
45
  "indexeddb_open_failed",
46
46
  "Failed to open IndexedDB connection.",
47
- o.error
47
+ s.error
48
48
  )
49
49
  );
50
- }, o.onupgradeneeded = (s) => {
51
- const a = s.target.result;
52
- a.objectStoreNames.contains(r) || a.createObjectStore(r, { keyPath: "version" });
53
- }, o.onsuccess = () => l(o.result);
54
- }), i;
55
- }, g = (l, n) => l.transaction(r, n).objectStore(r), u = (l, n, o) => l && typeof l == "object" && "code" in l && "message" in l ? l : c(n, o, l);
56
- return { get: async (l) => {
50
+ }, s.onupgradeneeded = (g) => {
51
+ const l = g.target.result;
52
+ l.objectStoreNames.contains(r) || l.createObjectStore(r, { keyPath: "version" });
53
+ }, s.onsuccess = () => d(s.result);
54
+ }), o;
55
+ }, f = (d, n) => d.transaction(r, n).objectStore(r), c = (d, n, s) => d && typeof d == "object" && "code" in d && "message" in d ? d : i(n, s, d);
56
+ return { get: async (d) => {
57
57
  try {
58
- const n = await b(), o = g(n, "readonly");
59
- return await new Promise((s) => {
60
- const a = o.get(l);
61
- a.onsuccess = () => s(f(a.result)), a.onerror = () => s(
62
- d(
63
- c(
58
+ const n = await b(), s = f(n, "readonly");
59
+ return await new Promise((g) => {
60
+ const l = s.get(d);
61
+ l.onsuccess = () => g(u(l.result)), l.onerror = () => g(
62
+ a(
63
+ i(
64
64
  "indexeddb_request_failed",
65
65
  "Failed to read from IndexedDB.",
66
- a.error
66
+ l.error
67
67
  )
68
68
  )
69
69
  );
70
70
  });
71
71
  } catch (n) {
72
- return d(u(n, "indexeddb_open_failed", "Failed to open IndexedDB."));
72
+ return a(c(n, "indexeddb_open_failed", "Failed to open IndexedDB."));
73
73
  }
74
- }, set: async (l) => {
74
+ }, set: async (d) => {
75
75
  try {
76
- const n = await b(), o = g(n, "readwrite");
77
- return await new Promise((s) => {
78
- const a = o.put(l);
79
- a.onsuccess = () => s(f(void 0)), a.onerror = () => s(
80
- d(
81
- c(
76
+ const n = await b(), s = f(n, "readwrite");
77
+ return await new Promise((g) => {
78
+ const l = s.put(d);
79
+ l.onsuccess = () => g(u(void 0)), l.onerror = () => g(
80
+ a(
81
+ i(
82
82
  "indexeddb_request_failed",
83
83
  "Failed to write to IndexedDB.",
84
- a.error
84
+ l.error
85
85
  )
86
86
  )
87
87
  );
88
88
  });
89
89
  } catch (n) {
90
- return d(c("indexeddb_open_failed", "Failed to open IndexedDB.", n));
90
+ return a(i("indexeddb_open_failed", "Failed to open IndexedDB.", n));
91
91
  }
92
92
  } };
93
- }, _ = () => {
93
+ }, h = () => {
94
94
  const e = /* @__PURE__ */ new Map();
95
- return { get: async (i) => e.has(i) ? f({ version: i, data: e.get(i) ?? "" }) : f(void 0), set: async (i) => (e.set(i.version, i.data), f(void 0)) };
96
- }, D = (e = {}) => {
97
- const t = e.keyPrefix ?? "iconly", r = () => typeof window > "u" || !window.sessionStorage ? d(c("storage_unavailable", "SessionStorage is not available.")) : f(window.sessionStorage);
98
- return { get: async (g) => {
99
- const u = r();
100
- if (!u.ok)
101
- return u;
95
+ return { get: async (o) => e.has(o) ? u({ version: o, data: e.get(o) ?? "" }) : u(void 0), set: async (o) => (e.set(o.version, o.data), u(void 0)) };
96
+ }, _ = (e = {}) => {
97
+ const t = e.keyPrefix ?? "iconly", r = () => typeof window > "u" || !window.sessionStorage ? a(i("storage_unavailable", "SessionStorage is not available.")) : u(window.sessionStorage);
98
+ return { get: async (f) => {
99
+ const c = r();
100
+ if (!c.ok)
101
+ return c;
102
102
  try {
103
- const m = u.value.getItem(`${t}:${g}`);
103
+ const m = c.value.getItem(`${t}:${f}`);
104
104
  if (!m)
105
- return f(void 0);
105
+ return u(void 0);
106
106
  const y = JSON.parse(m);
107
- return f(y);
107
+ return u(y);
108
108
  } catch (m) {
109
- return d(
110
- c("storage_read_failed", "Failed to read from SessionStorage.", m)
109
+ return a(
110
+ i("storage_read_failed", "Failed to read from SessionStorage.", m)
111
111
  );
112
112
  }
113
- }, set: async (g) => {
114
- const u = r();
115
- if (!u.ok)
116
- return u;
113
+ }, set: async (f) => {
114
+ const c = r();
115
+ if (!c.ok)
116
+ return c;
117
117
  try {
118
- return u.value.setItem(`${t}:${g.version}`, JSON.stringify(g)), f(void 0);
118
+ return c.value.setItem(`${t}:${f.version}`, JSON.stringify(f)), u(void 0);
119
119
  } catch (m) {
120
- return d(
121
- c("storage_write_failed", "Failed to write to SessionStorage.", m)
120
+ return a(
121
+ i("storage_write_failed", "Failed to write to SessionStorage.", m)
122
122
  );
123
123
  }
124
124
  } };
125
- }, N = (e, t) => !e || e === "indexeddb" ? h({
125
+ }, D = (e, t) => !e || e === "indexeddb" ? S({
126
126
  dbName: t.dbName,
127
127
  storeName: t.storeName
128
- }) : e === "memory" ? _() : e === "session" ? D({ keyPrefix: t.sessionKeyPrefix }) : e, k = (e = {}) => {
128
+ }) : e === "memory" ? h() : e === "session" ? _({ keyPrefix: t.sessionKeyPrefix }) : e, N = (e = {}) => {
129
129
  const t = {
130
130
  file: e.file ?? "./icons.svg",
131
131
  version: e.version ?? "1.0",
@@ -134,68 +134,65 @@ const c = (e, t, r) => ({
134
134
  logger: e.logger,
135
135
  onError: e.onError,
136
136
  onDebug: e.onDebug
137
- }, r = N(e.storage, {
137
+ }, r = D(e.storage, {
138
138
  dbName: e.dbName,
139
139
  storeName: e.storeName,
140
140
  sessionKeyPrefix: e.sessionKeyPrefix
141
141
  });
142
- let i = null;
142
+ let o = null;
143
143
  const b = () => {
144
- i == null || i.abort();
145
- }, g = () => {
144
+ o?.abort();
145
+ }, f = () => {
146
146
  if (typeof document > "u")
147
- return d(
148
- c("container_invalid", "Document is not available in this environment.")
147
+ return a(
148
+ i("container_invalid", "Document is not available in this environment.")
149
149
  );
150
150
  if (typeof t.container == "string") {
151
- const o = document.querySelector(t.container);
152
- return !o || !(o instanceof HTMLElement) ? d(
153
- c(
151
+ const s = document.querySelector(t.container);
152
+ return !s || !(s instanceof HTMLElement) ? a(
153
+ i(
154
154
  "container_invalid",
155
155
  `Invalid container selector: "${t.container}".`
156
156
  )
157
- ) : f(o);
157
+ ) : u(s);
158
158
  }
159
159
  if (t.container instanceof HTMLElement)
160
- return f(t.container);
160
+ return u(t.container);
161
161
  const n = document.body ?? document.documentElement;
162
- return n ? f(n) : d(c("container_invalid", "No valid container element found."));
163
- }, u = (...n) => {
164
- var o, s, a;
165
- t.debug && ((o = t.onDebug) == null || o.call(t, ...n), (a = (s = t.logger) == null ? void 0 : s.debug) == null || a.call(s, "[Iconly debug]", ...n));
162
+ return n ? u(n) : a(i("container_invalid", "No valid container element found."));
163
+ }, c = (...n) => {
164
+ t.debug && (t.onDebug?.(...n), t.logger?.debug?.("[Iconly debug]", ...n));
166
165
  }, m = (n) => {
167
- var o, s, a;
168
- (o = t.onError) == null || o.call(t, n), (a = (s = t.logger) == null ? void 0 : s.error) == null || a.call(s, "[Iconly error]", n);
169
- }, y = (n) => (m(n), d(n));
166
+ t.onError?.(n), t.logger?.error?.("[Iconly error]", n);
167
+ }, y = (n) => (m(n), a(n));
170
168
  return { init: async () => {
171
- var v;
172
- const n = g();
169
+ const n = f();
173
170
  if (!n.ok)
174
171
  return y(n.error);
175
- const o = await r.get(t.version);
176
- if (!o.ok)
177
- return y(o.error);
178
- let s = (v = o.value) == null ? void 0 : v.data;
179
- if (s)
180
- u("Using cached icon set", t.version);
172
+ const s = await r.get(t.version);
173
+ if (!s.ok)
174
+ return y(s.error);
175
+ let g = s.value?.data;
176
+ if (g)
177
+ c("Using cached icon set", t.version);
181
178
  else {
182
- i = new AbortController();
183
- const p = await S(t.file, i.signal);
184
- if (!p.ok)
185
- return y(p.error);
186
- s = p.value;
187
- const w = await r.set({
179
+ o = new AbortController();
180
+ const v = await x(t.file, o.signal);
181
+ if (!v.ok)
182
+ return y(v.error);
183
+ g = v.value;
184
+ const p = await r.set({
188
185
  version: t.version,
189
- data: s
186
+ data: g
190
187
  });
191
- if (!w.ok)
192
- return y(w.error);
188
+ if (!p.ok)
189
+ return y(p.error);
193
190
  }
194
- const a = x(n.value, s);
195
- return a.ok ? (u("Iconly has successfully initialized."), f(void 0)) : y(a.error);
191
+ const l = w(n.value, g);
192
+ return l.ok ? (c("Iconly has successfully initialized."), u(void 0)) : y(l.error);
196
193
  }, abort: b };
197
194
  };
198
195
  export {
199
- k as createIconly
196
+ N as createIconly
200
197
  };
201
198
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","_a","_b","_c","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(p,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(p=typeof globalThis<"u"?globalThis:p||self,i(p.Iconly={}))})(this,(function(p){"use strict";const i=(e,t,r)=>({code:e,message:t,cause:r}),u=e=>({ok:!0,value:e}),d=e=>({ok:!1,error:e}),x=(e,t)=>{let r=document.getElementById("iconset");r||(r=document.createElement("div"),r.id="iconset",r.setAttribute("aria-hidden","true"),r.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(r));const b=new DOMParser().parseFromString(t,"image/svg+xml"),g=b.querySelector("parsererror");if(g)return d(i("parse_error",`SVG parsing error: ${g.textContent??"Unknown error"}`));r.innerHTML="";const l=b.documentElement;if(!l)return d(i("parse_error","No valid SVG content found."));const m=document.importNode(l,!0);return r.appendChild(m),u(void 0)},S=async(e,t)=>{try{const r=await fetch(e,{signal:t});if(!r.ok)return d(i("fetch_failed",`Failed to fetch icons from "${e}".`));const a=await r.text();return u(a)}catch(r){return r instanceof DOMException&&r.name==="AbortError"?d(i("fetch_aborted","Fetch request was aborted.",r)):d(i("fetch_failed","Failed to fetch icons.",r))}},_=(e={})=>{const t=e.dbName??"iconlyDB",r=e.storeName??"icons";let a=null;const b=async()=>{if(a)return a;if(typeof indexedDB>"u")throw i("indexeddb_not_supported","IndexedDB is not supported.");return a=new Promise((f,n)=>{const o=indexedDB.open(t,1);o.onerror=()=>{n(i("indexeddb_open_failed","Failed to open IndexedDB connection.",o.error))},o.onupgradeneeded=s=>{const c=s.target.result;c.objectStoreNames.contains(r)||c.createObjectStore(r,{keyPath:"version"})},o.onsuccess=()=>f(o.result)}),a},g=(f,n)=>f.transaction(r,n).objectStore(r),l=(f,n,o)=>f&&typeof f=="object"&&"code"in f&&"message"in f?f:i(n,o,f);return{get:async f=>{try{const n=await b(),o=g(n,"readonly");return await new Promise(s=>{const c=o.get(f);c.onsuccess=()=>s(u(c.result)),c.onerror=()=>s(d(i("indexeddb_request_failed","Failed to read from IndexedDB.",c.error)))})}catch(n){return d(l(n,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async f=>{try{const n=await b(),o=g(n,"readwrite");return await new Promise(s=>{const c=o.put(f);c.onsuccess=()=>s(u(void 0)),c.onerror=()=>s(d(i("indexeddb_request_failed","Failed to write to IndexedDB.",c.error)))})}catch(n){return d(i("indexeddb_open_failed","Failed to open IndexedDB.",n))}}}},D=()=>{const e=new Map;return{get:async a=>e.has(a)?u({version:a,data:e.get(a)??""}):u(void 0),set:async a=>(e.set(a.version,a.data),u(void 0))}},I=(e={})=>{const t=e.keyPrefix??"iconly",r=()=>typeof window>"u"||!window.sessionStorage?d(i("storage_unavailable","SessionStorage is not available.")):u(window.sessionStorage);return{get:async g=>{const l=r();if(!l.ok)return l;try{const m=l.value.getItem(`${t}:${g}`);if(!m)return u(void 0);const y=JSON.parse(m);return u(y)}catch(m){return d(i("storage_read_failed","Failed to read from SessionStorage.",m))}},set:async g=>{const l=r();if(!l.ok)return l;try{return l.value.setItem(`${t}:${g.version}`,JSON.stringify(g)),u(void 0)}catch(m){return d(i("storage_write_failed","Failed to write to SessionStorage.",m))}}}},N=(e,t)=>!e||e==="indexeddb"?_({dbName:t.dbName,storeName:t.storeName}):e==="memory"?D():e==="session"?I({keyPrefix:t.sessionKeyPrefix}):e,k=(e={})=>{const t={file:e.file??"./icons.svg",version:e.version??"1.0",debug:e.debug??!1,container:e.container,logger:e.logger,onError:e.onError,onDebug:e.onDebug},r=N(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let a=null;const b=()=>{a==null||a.abort()},g=()=>{if(typeof document>"u")return d(i("container_invalid","Document is not available in this environment."));if(typeof t.container=="string"){const o=document.querySelector(t.container);return!o||!(o instanceof HTMLElement)?d(i("container_invalid",`Invalid container selector: "${t.container}".`)):u(o)}if(t.container instanceof HTMLElement)return u(t.container);const n=document.body??document.documentElement;return n?u(n):d(i("container_invalid","No valid container element found."))},l=(...n)=>{var o,s,c;t.debug&&((o=t.onDebug)==null||o.call(t,...n),(c=(s=t.logger)==null?void 0:s.debug)==null||c.call(s,"[Iconly debug]",...n))},m=n=>{var o,s,c;(o=t.onError)==null||o.call(t,n),(c=(s=t.logger)==null?void 0:s.error)==null||c.call(s,"[Iconly error]",n)},y=n=>(m(n),d(n));return{init:async()=>{var h;const n=g();if(!n.ok)return y(n.error);const o=await r.get(t.version);if(!o.ok)return y(o.error);let s=(h=o.value)==null?void 0:h.data;if(s)l("Using cached icon set",t.version);else{a=new AbortController;const v=await S(t.file,a.signal);if(!v.ok)return y(v.error);s=v.value;const w=await r.set({version:t.version,data:s});if(!w.ok)return y(w.error)}const c=x(n.value,s);return c.ok?(l("Iconly has successfully initialized."),u(void 0)):y(c.error)},abort:b}};p.createIconly=k,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(p,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(p=typeof globalThis<"u"?globalThis:p||self,o(p.Iconly={}))})(this,(function(p){"use strict";const o=(e,t,r)=>({code:e,message:t,cause:r}),c=e=>({ok:!0,value:e}),a=e=>({ok:!1,error:e}),w=(e,t)=>{let r=document.getElementById("iconset");r||(r=document.createElement("div"),r.id="iconset",r.setAttribute("aria-hidden","true"),r.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(r));const b=new DOMParser().parseFromString(t,"image/svg+xml"),f=b.querySelector("parsererror");if(f)return a(o("parse_error",`SVG parsing error: ${f.textContent??"Unknown error"}`));r.innerHTML="";const d=b.documentElement;if(!d)return a(o("parse_error","No valid SVG content found."));const m=document.importNode(d,!0);return r.appendChild(m),c(void 0)},x=async(e,t)=>{try{const r=await fetch(e,{signal:t});if(!r.ok)return a(o("fetch_failed",`Failed to fetch icons from "${e}".`));const s=await r.text();return c(s)}catch(r){return r instanceof DOMException&&r.name==="AbortError"?a(o("fetch_aborted","Fetch request was aborted.",r)):a(o("fetch_failed","Failed to fetch icons.",r))}},S=(e={})=>{const t=e.dbName??"iconlyDB",r=e.storeName??"icons";let s=null;const b=async()=>{if(s)return s;if(typeof indexedDB>"u")throw o("indexeddb_not_supported","IndexedDB is not supported.");return s=new Promise((u,n)=>{const i=indexedDB.open(t,1);i.onerror=()=>{n(o("indexeddb_open_failed","Failed to open IndexedDB connection.",i.error))},i.onupgradeneeded=g=>{const l=g.target.result;l.objectStoreNames.contains(r)||l.createObjectStore(r,{keyPath:"version"})},i.onsuccess=()=>u(i.result)}),s},f=(u,n)=>u.transaction(r,n).objectStore(r),d=(u,n,i)=>u&&typeof u=="object"&&"code"in u&&"message"in u?u:o(n,i,u);return{get:async u=>{try{const n=await b(),i=f(n,"readonly");return await new Promise(g=>{const l=i.get(u);l.onsuccess=()=>g(c(l.result)),l.onerror=()=>g(a(o("indexeddb_request_failed","Failed to read from IndexedDB.",l.error)))})}catch(n){return a(d(n,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async u=>{try{const n=await b(),i=f(n,"readwrite");return await new Promise(g=>{const l=i.put(u);l.onsuccess=()=>g(c(void 0)),l.onerror=()=>g(a(o("indexeddb_request_failed","Failed to write to IndexedDB.",l.error)))})}catch(n){return a(o("indexeddb_open_failed","Failed to open IndexedDB.",n))}}}},_=()=>{const e=new Map;return{get:async s=>e.has(s)?c({version:s,data:e.get(s)??""}):c(void 0),set:async s=>(e.set(s.version,s.data),c(void 0))}},D=(e={})=>{const t=e.keyPrefix??"iconly",r=()=>typeof window>"u"||!window.sessionStorage?a(o("storage_unavailable","SessionStorage is not available.")):c(window.sessionStorage);return{get:async f=>{const d=r();if(!d.ok)return d;try{const m=d.value.getItem(`${t}:${f}`);if(!m)return c(void 0);const y=JSON.parse(m);return c(y)}catch(m){return a(o("storage_read_failed","Failed to read from SessionStorage.",m))}},set:async f=>{const d=r();if(!d.ok)return d;try{return d.value.setItem(`${t}:${f.version}`,JSON.stringify(f)),c(void 0)}catch(m){return a(o("storage_write_failed","Failed to write to SessionStorage.",m))}}}},I=(e,t)=>!e||e==="indexeddb"?S({dbName:t.dbName,storeName:t.storeName}):e==="memory"?_():e==="session"?D({keyPrefix:t.sessionKeyPrefix}):e,N=(e={})=>{const t={file:e.file??"./icons.svg",version:e.version??"1.0",debug:e.debug??!1,container:e.container,logger:e.logger,onError:e.onError,onDebug:e.onDebug},r=I(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let s=null;const b=()=>{s?.abort()},f=()=>{if(typeof document>"u")return a(o("container_invalid","Document is not available in this environment."));if(typeof t.container=="string"){const i=document.querySelector(t.container);return!i||!(i instanceof HTMLElement)?a(o("container_invalid",`Invalid container selector: "${t.container}".`)):c(i)}if(t.container instanceof HTMLElement)return c(t.container);const n=document.body??document.documentElement;return n?c(n):a(o("container_invalid","No valid container element found."))},d=(...n)=>{t.debug&&(t.onDebug?.(...n),t.logger?.debug?.("[Iconly debug]",...n))},m=n=>{t.onError?.(n),t.logger?.error?.("[Iconly error]",n)},y=n=>(m(n),a(n));return{init:async()=>{const n=f();if(!n.ok)return y(n.error);const i=await r.get(t.version);if(!i.ok)return y(i.error);let g=i.value?.data;if(g)d("Using cached icon set",t.version);else{s=new AbortController;const v=await x(t.file,s.signal);if(!v.ok)return y(v.error);g=v.value;const h=await r.set({version:t.version,data:g});if(!h.ok)return y(h.error)}const l=w(n.value,g);return l.ok?(d("Iconly has successfully initialized."),c(void 0)):y(l.error)},abort:b}};p.createIconly=N,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","_a","_c","_b","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/errors.ts","../src/result.ts","../src/dom.ts","../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["import type { IconlyError, IconlyErrorCode } from './types';\n\nexport const createIconlyError = (\n code: IconlyErrorCode,\n message: string,\n cause?: unknown,\n): IconlyError => ({\n code,\n message,\n cause,\n});\n","import type { IconlyError, Result } from './types';\n\nexport const ok = <T>(value: T): Result<T> => ({ ok: true, value });\n\nexport const err = <T = never>(error: IconlyError): Result<T> => ({ ok: false, error });\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const insertSvg = (container: HTMLElement, data: string): Result<void> => {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n container.appendChild(iconSetDiv);\n }\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(data, 'image/svg+xml');\n const parserError = svgDoc.querySelector('parsererror');\n\n if (parserError) {\n return err(\n createIconlyError(\n 'parse_error',\n `SVG parsing error: ${parserError.textContent ?? 'Unknown error'}`,\n ),\n );\n }\n\n iconSetDiv.innerHTML = '';\n\n const svgEl = svgDoc.documentElement;\n\n if (!svgEl) {\n return err(createIconlyError('parse_error', 'No valid SVG content found.'));\n }\n\n const imported = document.importNode(svgEl, true);\n\n iconSetDiv.appendChild(imported);\n\n return ok(undefined);\n};\n","import { createIconlyError } from './errors';\nimport { err, ok } from './result';\nimport type { Result } from './types';\n\nexport const fetchSvg = async (file: string, signal?: AbortSignal): Promise<Result<string>> => {\n try {\n const response = await fetch(file, { signal });\n\n if (!response.ok) {\n return err(createIconlyError('fetch_failed', `Failed to fetch icons from \"${file}\".`));\n }\n\n const data = await response.text();\n\n return ok(data);\n } catch (error: unknown) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return err(createIconlyError('fetch_aborted', 'Fetch request was aborted.', error));\n }\n\n return err(createIconlyError('fetch_failed', 'Failed to fetch icons.', error));\n }\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconlyError, IconRecord, IconStorage, Result } from '../types';\n\ninterface IndexedDbOptions {\n dbName?: string;\n storeName?: string;\n}\n\nexport const createIndexedDbStorage = (options: IndexedDbOptions = {}): IconStorage => {\n const dbName = options.dbName ?? 'iconlyDB';\n const storeName = options.storeName ?? 'icons';\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n\n const openDb = async (): Promise<IDBDatabase> => {\n if (dbPromise) {\n return dbPromise;\n }\n\n if (typeof indexedDB === 'undefined') {\n throw createIconlyError('indexeddb_not_supported', 'IndexedDB is not supported.');\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onerror = (): void => {\n reject(\n createIconlyError(\n 'indexeddb_open_failed',\n 'Failed to open IndexedDB connection.',\n request.error,\n ),\n );\n };\n\n request.onupgradeneeded = (event): void => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { keyPath: 'version' });\n }\n };\n\n request.onsuccess = (): void => resolve(request.result);\n });\n\n return dbPromise;\n };\n\n const getStore = (db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore =>\n db.transaction(storeName, mode).objectStore(storeName);\n\n const toIconlyError = (\n error: unknown,\n fallbackCode: IconlyError['code'],\n message: string,\n ): IconlyError => {\n if (error && typeof error === 'object' && 'code' in error && 'message' in error) {\n return error as IconlyError;\n }\n\n return createIconlyError(fallbackCode, message, error);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readonly');\n\n return await new Promise<Result<IconRecord | undefined>>((resolve) => {\n const request = store.get(version);\n\n request.onsuccess = (): void => resolve(ok(request.result as IconRecord | undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to read from IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(toIconlyError(error, 'indexeddb_open_failed', 'Failed to open IndexedDB.'));\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n try {\n const db = await openDb();\n const store = getStore(db, 'readwrite');\n\n return await new Promise<Result<void>>((resolve) => {\n const request = store.put(record);\n\n request.onsuccess = (): void => resolve(ok(undefined));\n request.onerror = (): void =>\n resolve(\n err(\n createIconlyError(\n 'indexeddb_request_failed',\n 'Failed to write to IndexedDB.',\n request.error,\n ),\n ),\n );\n });\n } catch (error: unknown) {\n return err(createIconlyError('indexeddb_open_failed', 'Failed to open IndexedDB.', error));\n }\n };\n\n return { get, set };\n};\n","import { ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\nexport const createMemoryStorage = (): IconStorage => {\n const store = new Map<string, string>();\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n if (!store.has(version)) {\n return ok(undefined);\n }\n\n return ok({ version, data: store.get(version) ?? '' });\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n store.set(record.version, record.data);\n\n return ok(undefined);\n };\n\n return { get, set };\n};\n","import { createIconlyError } from '../errors';\nimport { err, ok } from '../result';\nimport type { IconRecord, IconStorage, Result } from '../types';\n\ninterface SessionStorageOptions {\n keyPrefix?: string;\n}\n\nexport const createSessionStorage = (options: SessionStorageOptions = {}): IconStorage => {\n const keyPrefix = options.keyPrefix ?? 'iconly';\n\n const resolveStorage = (): Result<Storage> => {\n if (typeof window === 'undefined' || !window.sessionStorage) {\n return err(createIconlyError('storage_unavailable', 'SessionStorage is not available.'));\n }\n\n return ok(window.sessionStorage);\n };\n\n const get = async (version: string): Promise<Result<IconRecord | undefined>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);\n\n if (!raw) {\n return ok(undefined);\n }\n\n const parsed = JSON.parse(raw) as IconRecord;\n\n return ok(parsed);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_read_failed', 'Failed to read from SessionStorage.', error),\n );\n }\n };\n\n const set = async (record: IconRecord): Promise<Result<void>> => {\n const storageResult = resolveStorage();\n\n if (!storageResult.ok) {\n return storageResult;\n }\n\n try {\n storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));\n\n return ok(undefined);\n } catch (error: unknown) {\n return err(\n createIconlyError('storage_write_failed', 'Failed to write to SessionStorage.', error),\n );\n }\n };\n\n return { get, set };\n};\n","import type { IconStorage, StorageStrategy } from '../types';\nimport { createIndexedDbStorage } from './indexeddb';\nimport { createMemoryStorage } from './memory';\nimport { createSessionStorage } from './session';\n\nexport interface StorageFactoryOptions {\n dbName?: string;\n storeName?: string;\n sessionKeyPrefix?: string;\n}\n\nexport const resolveStorage = (\n strategy: StorageStrategy | undefined,\n options: StorageFactoryOptions,\n): IconStorage => {\n if (!strategy || strategy === 'indexeddb') {\n return createIndexedDbStorage({\n dbName: options.dbName,\n storeName: options.storeName,\n });\n }\n\n if (strategy === 'memory') {\n return createMemoryStorage();\n }\n\n if (strategy === 'session') {\n return createSessionStorage({ keyPrefix: options.sessionKeyPrefix });\n }\n\n return strategy;\n};\n","import { insertSvg } from './dom';\nimport { createIconlyError } from './errors';\nimport { fetchSvg } from './fetcher';\nimport { err, ok } from './result';\nimport { resolveStorage } from './storage';\nimport type { IconlyConfig, IconlyError, IconlyInstance, IconStorage, Result } from './types';\n\ninterface ResolvedIconlyConfig {\n file: string;\n version: string;\n debug: boolean;\n container?: string | HTMLElement;\n logger?: IconlyConfig['logger'];\n onError?: IconlyConfig['onError'];\n onDebug?: IconlyConfig['onDebug'];\n}\n\nexport const createIconly = (config: IconlyConfig = {}): IconlyInstance => {\n const resolved: ResolvedIconlyConfig = {\n file: config.file ?? './icons.svg',\n version: config.version ?? '1.0',\n debug: config.debug ?? false,\n container: config.container,\n logger: config.logger,\n onError: config.onError,\n onDebug: config.onDebug,\n };\n\n const storage: IconStorage = resolveStorage(config.storage, {\n dbName: config.dbName,\n storeName: config.storeName,\n sessionKeyPrefix: config.sessionKeyPrefix,\n });\n\n let controller: AbortController | null = null;\n\n const abort = (): void => {\n controller?.abort();\n };\n\n const resolveContainer = (): Result<HTMLElement> => {\n if (typeof document === 'undefined') {\n return err(\n createIconlyError('container_invalid', 'Document is not available in this environment.'),\n );\n }\n\n if (typeof resolved.container === 'string') {\n const found = document.querySelector(resolved.container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError(\n 'container_invalid',\n `Invalid container selector: \"${resolved.container}\".`,\n ),\n );\n }\n\n return ok(found);\n }\n\n if (resolved.container instanceof HTMLElement) {\n return ok(resolved.container);\n }\n\n const fallback = document.body ?? document.documentElement;\n\n if (!fallback) {\n return err(createIconlyError('container_invalid', 'No valid container element found.'));\n }\n\n return ok(fallback);\n };\n\n const logDebug = (...messages: unknown[]): void => {\n if (!resolved.debug) {\n return;\n }\n\n resolved.onDebug?.(...messages);\n resolved.logger?.debug?.('[Iconly debug]', ...messages);\n };\n\n const logError = (error: IconlyError): void => {\n resolved.onError?.(error);\n resolved.logger?.error?.('[Iconly error]', error);\n };\n\n const fail = (error: IconlyError): Result<void> => {\n logError(error);\n\n return err(error);\n };\n\n const init = async (): Promise<Result<void>> => {\n const containerResult = resolveContainer();\n\n if (!containerResult.ok) {\n return fail(containerResult.error);\n }\n\n const cacheResult = await storage.get(resolved.version);\n\n if (!cacheResult.ok) {\n return fail(cacheResult.error);\n }\n\n let data = cacheResult.value?.data;\n\n if (!data) {\n controller = new AbortController();\n\n const fetchResult = await fetchSvg(resolved.file, controller.signal);\n\n if (!fetchResult.ok) {\n return fail(fetchResult.error);\n }\n\n data = fetchResult.value;\n\n const storeResult = await storage.set({\n version: resolved.version,\n data,\n });\n\n if (!storeResult.ok) {\n return fail(storeResult.error);\n }\n } else {\n logDebug('Using cached icon set', resolved.version);\n }\n\n const insertResult = insertSvg(containerResult.value, data);\n\n if (!insertResult.ok) {\n return fail(insertResult.error);\n }\n\n logDebug('Iconly has successfully initialized.');\n\n return ok(undefined);\n };\n\n return { init, abort };\n};\n"],"names":["createIconlyError","code","message","cause","ok","value","err","error","insertSvg","container","data","iconSetDiv","svgDoc","parserError","svgEl","imported","fetchSvg","file","signal","response","createIndexedDbStorage","options","dbName","storeName","dbPromise","openDb","resolve","reject","request","event","db","getStore","mode","toIconlyError","fallbackCode","version","store","record","createMemoryStorage","createSessionStorage","keyPrefix","resolveStorage","storageResult","raw","parsed","strategy","createIconly","config","resolved","storage","controller","abort","resolveContainer","found","fallback","logDebug","messages","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iconly",
3
- "version": "3.0.0-dev.0",
3
+ "version": "3.0.0-dev.1",
4
4
  "description": "Iconly is designed to load and cache SVG icons in the browser, using IndexedDB to store the data. It retrieves the icons from a given SVG file, stores them in IndexedDB, and inserts them into the DOM for easy access and use.",
5
5
  "author": "ux-ui.pro",
6
6
  "license": "MIT",
@@ -20,14 +20,13 @@
20
20
  "scripts": {
21
21
  "clean": "rimraf dist",
22
22
  "build": "vite build",
23
+ "verify": "yarn lint && yarn typecheck && yarn test",
23
24
  "lint": "biome check src tests",
24
25
  "lint:fix": "biome check --write src tests",
25
26
  "format": "biome format --write src tests",
26
27
  "typecheck": "tsc -p tsconfig.json --noEmit",
27
28
  "test": "vitest run",
28
- "test:watch": "vitest",
29
- "verify": "npm run lint && npm run typecheck && npm run test",
30
- "prepublishOnly": "npm run verify"
29
+ "test:watch": "vitest"
31
30
  },
32
31
  "source": "src/index.ts",
33
32
  "main": "dist/index.cjs.js",
@@ -48,14 +47,14 @@
48
47
  "LICENSE"
49
48
  ],
50
49
  "devDependencies": {
51
- "@biomejs/biome": "2.3.10",
52
- "@types/node": "22.13.10",
50
+ "@biomejs/biome": "2.3.12",
51
+ "@types/node": "25.0.10",
53
52
  "fake-indexeddb": "6.2.5",
54
53
  "jsdom": "27.4.0",
55
- "rimraf": "6.0.1",
56
- "typescript": "5.8.2",
57
- "vite": "6.2.1",
58
- "vite-plugin-dts": "4.5.3",
54
+ "rimraf": "6.1.2",
55
+ "typescript": "5.9.3",
56
+ "vite": "7.3.1",
57
+ "vite-plugin-dts": "4.5.4",
59
58
  "vitest": "4.0.18"
60
59
  },
61
60
  "keywords": [
package/dist/core.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { IconlyConfig, IconlyInstance } from './types';
2
- export declare const createIconly: (config?: IconlyConfig) => IconlyInstance;
3
- //# sourceMappingURL=core.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAe,cAAc,EAAuB,MAAM,SAAS,CAAC;AAY9F,eAAO,MAAM,YAAY,GAAI,SAAQ,YAAiB,KAAG,cAgIxD,CAAC"}
package/dist/dom.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Result } from './types';
2
- export declare const insertSvg: (container: HTMLElement, data: string) => Result<void>;
3
- //# sourceMappingURL=dom.d.ts.map
package/dist/dom.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,eAAO,MAAM,SAAS,GAAI,WAAW,WAAW,EAAE,MAAM,MAAM,KAAG,MAAM,CAAC,IAAI,CAqC3E,CAAC"}
package/dist/errors.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { IconlyError, IconlyErrorCode } from './types';
2
- export declare const createIconlyError: (code: IconlyErrorCode, message: string, cause?: unknown) => IconlyError;
3
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE5D,eAAO,MAAM,iBAAiB,GAC5B,MAAM,eAAe,EACrB,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,WAID,CAAC"}
package/dist/fetcher.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Result } from './types';
2
- export declare const fetchSvg: (file: string, signal?: AbortSignal) => Promise<Result<string>>;
3
- //# sourceMappingURL=fetcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,eAAO,MAAM,QAAQ,GAAU,MAAM,MAAM,EAAE,SAAS,WAAW,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAkBzF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,cAAc,EACd,UAAU,EACV,WAAW,EACX,MAAM,EACN,MAAM,EACN,eAAe,GAChB,MAAM,SAAS,CAAC"}
package/dist/result.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import { IconlyError, Result } from './types';
2
- export declare const ok: <T>(value: T) => Result<T>;
3
- export declare const err: <T = never>(error: IconlyError) => Result<T>;
4
- //# sourceMappingURL=result.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnD,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAA0B,CAAC;AAEpE,eAAO,MAAM,GAAG,GAAI,CAAC,GAAG,KAAK,EAAE,OAAO,WAAW,KAAG,MAAM,CAAC,CAAC,CAA2B,CAAC"}
@@ -1,8 +0,0 @@
1
- import { IconStorage, StorageStrategy } from '../types';
2
- export interface StorageFactoryOptions {
3
- dbName?: string;
4
- storeName?: string;
5
- sessionKeyPrefix?: string;
6
- }
7
- export declare const resolveStorage: (strategy: StorageStrategy | undefined, options: StorageFactoryOptions) => IconStorage;
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAK7D,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,GACzB,UAAU,eAAe,GAAG,SAAS,EACrC,SAAS,qBAAqB,KAC7B,WAiBF,CAAC"}
@@ -1,8 +0,0 @@
1
- import { IconStorage } from '../types';
2
- interface IndexedDbOptions {
3
- dbName?: string;
4
- storeName?: string;
5
- }
6
- export declare const createIndexedDbStorage: (options?: IndexedDbOptions) => IconStorage;
7
- export {};
8
- //# sourceMappingURL=indexeddb.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/storage/indexeddb.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA2B,WAAW,EAAU,MAAM,UAAU,CAAC;AAE7E,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,GAAI,UAAS,gBAAqB,KAAG,WA4GvE,CAAC"}
@@ -1,3 +0,0 @@
1
- import { IconStorage } from '../types';
2
- export declare const createMemoryStorage: () => IconStorage;
3
- //# sourceMappingURL=memory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,WAAW,EAAU,MAAM,UAAU,CAAC;AAEhE,eAAO,MAAM,mBAAmB,QAAO,WAkBtC,CAAC"}
@@ -1,7 +0,0 @@
1
- import { IconStorage } from '../types';
2
- interface SessionStorageOptions {
3
- keyPrefix?: string;
4
- }
5
- export declare const createSessionStorage: (options?: SessionStorageOptions) => IconStorage;
6
- export {};
7
- //# sourceMappingURL=session.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/storage/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,WAAW,EAAU,MAAM,UAAU,CAAC;AAEhE,UAAU,qBAAqB;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,GAAI,UAAS,qBAA0B,KAAG,WAsD1E,CAAC"}
package/dist/types.d.ts DELETED
@@ -1,44 +0,0 @@
1
- export type Result<T> = {
2
- ok: true;
3
- value: T;
4
- } | {
5
- ok: false;
6
- error: IconlyError;
7
- };
8
- export type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
9
- export interface IconlyError {
10
- code: IconlyErrorCode;
11
- message: string;
12
- cause?: unknown;
13
- }
14
- export interface Logger {
15
- debug?: (...messages: unknown[]) => void;
16
- error?: (...messages: unknown[]) => void;
17
- }
18
- export interface IconRecord {
19
- version: string;
20
- data: string;
21
- }
22
- export interface IconStorage {
23
- get(version: string): Promise<Result<IconRecord | undefined>>;
24
- set(record: IconRecord): Promise<Result<void>>;
25
- }
26
- export interface IconlyInstance {
27
- init: () => Promise<Result<void>>;
28
- abort: () => void;
29
- }
30
- export type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
31
- export interface IconlyConfig {
32
- file?: string;
33
- version?: string;
34
- debug?: boolean;
35
- container?: string | HTMLElement;
36
- storage?: StorageStrategy;
37
- dbName?: string;
38
- storeName?: string;
39
- sessionKeyPrefix?: string;
40
- logger?: Logger;
41
- onError?: (error: IconlyError) => void;
42
- onDebug?: (...messages: unknown[]) => void;
43
- }
44
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,eAAe,GACf,cAAc,GACd,yBAAyB,GACzB,uBAAuB,GACvB,0BAA0B,GAC1B,aAAa,GACb,qBAAqB,GACrB,qBAAqB,GACrB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC;IAC9D,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CAC5C"}