iconly 3.0.0-dev.1 → 3.0.1-rc.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/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## 3.0.0
6
+
7
+ ### Breaking changes
8
+
9
+ - **API changed**: `new Iconly()` was replaced by `createIconly()`.
10
+ - **Init contract changed**: `init()` no longer throws and no longer returns `void`. It now returns a `Result<void>` that must be checked via `result.ok`.
11
+ - **DOM anchor changed**: the injected sprite wrapper is now a `<div data-iconly="iconset" aria-hidden="true">...</div>` inside the configured `container` (previously `id="iconset"`).
12
+ - **Storage is configurable**: caching can use `'indexeddb' | 'memory' | 'session'` or a custom storage implementation.
13
+
14
+ ### Migration guide
15
+
16
+ #### 1) Constructor → factory
17
+
18
+ Before:
19
+
20
+ ```js
21
+ import Iconly from 'iconly';
22
+ const iconly = new Iconly({ file: './sprite.svg' });
23
+ await iconly.init();
24
+ ```
25
+
26
+ After:
27
+
28
+ ```js
29
+ import { createIconly } from 'iconly';
30
+ const iconly = createIconly({ file: './sprite.svg' });
31
+ const result = await iconly.init();
32
+ if (!result.ok) console.error(result.error);
33
+ ```
34
+
35
+ #### 2) DOM anchor
36
+
37
+ Before:
38
+ ```html
39
+ #iconset
40
+ ```
41
+
42
+ After (created inside `container`):
43
+ ```html
44
+ [data-iconly="iconset"]
45
+ ```
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 ux-ui.pro
3
+ Copyright (c) 2026 ux-ui.pro
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -28,6 +28,14 @@ import { createIconly } from 'iconly';
28
28
  ```
29
29
  <br>
30
30
 
31
+ # Upgrading to v3
32
+ - The API is now factory-based: use `createIconly()` instead of `new Iconly()`.
33
+ - `init()` returns a `Result<void>` and never throws.
34
+ - The injected sprite wrapper is now `[data-iconly="iconset"]` inside `container` (instead of `#iconset`).
35
+
36
+ See `CHANGELOG.md` for details.
37
+ <br>
38
+
31
39
  # Usage
32
40
  ```javascript
33
41
  const iconLoader = createIconly({
@@ -44,6 +52,8 @@ if (!result.ok) {
44
52
  }
45
53
  ```
46
54
 
55
+ After `init()`, the SVG sprite is injected into the `container` inside `<div data-iconly="iconset" aria-hidden="true">...</div>`.
56
+
47
57
  ```HTML
48
58
  <svg>
49
59
  <use href="#icon-name"></use>
@@ -83,5 +93,4 @@ if (!result.ok) {
83
93
  - You can cancel a fetch by calling `iconLoader.abort()`, which results in a `fetch_aborted` error code.
84
94
 
85
95
  # License
86
-
87
96
  MIT
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=(e,t,o)=>({code:e,message:t,cause:o}),u=e=>({ok:!0,value:e}),a=e=>({ok:!1,error:e}),S=(e,t)=>{const o=e.querySelector('[data-iconly="iconset"]');let n=o instanceof HTMLElement?o:null;n||(n=document.createElement("div"),n.setAttribute("data-iconly","iconset"),n.setAttribute("aria-hidden","true"),n.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(n));const f=new DOMParser().parseFromString(t,"image/svg+xml"),c=f.querySelector("parsererror");if(c)return a(i("parse_error",`SVG parsing error: ${c.textContent??"Unknown error"}`));n.innerHTML="";const g=f.documentElement;if(!g)return a(i("parse_error","No valid SVG content found."));const b=document.importNode(g,!0);return n.appendChild(b),u(void 0)},w=async(e,t)=>{try{const o=await fetch(e,{signal:t});if(!o.ok)return a(i("fetch_failed",`Failed to fetch icons from "${e}".`));const n=await o.text();return u(n)}catch(o){return o instanceof DOMException&&o.name==="AbortError"?a(i("fetch_aborted","Fetch request was aborted.",o)):a(i("fetch_failed","Failed to fetch icons.",o))}},x=(e={})=>{const t=e.dbName??"iconlyDB",o=e.storeName??"icons";let n=null;const y=async()=>{if(n)return n;if(typeof indexedDB>"u")throw i("indexeddb_not_supported","IndexedDB is not supported.");return n=new Promise((d,r)=>{const s=indexedDB.open(t,1);s.onerror=()=>{r(i("indexeddb_open_failed","Failed to open IndexedDB connection.",s.error))},s.onupgradeneeded=m=>{const l=m.target.result;l.objectStoreNames.contains(o)||l.createObjectStore(o,{keyPath:"version"})},s.onsuccess=()=>d(s.result)}),n},f=(d,r)=>d.transaction(o,r).objectStore(o),c=(d,r,s)=>d&&typeof d=="object"&&"code"in d&&"message"in d?d:i(r,s,d);return{get:async d=>{try{const r=await y(),s=f(r,"readonly");return await new Promise(m=>{const l=s.get(d);l.onsuccess=()=>m(u(l.result)),l.onerror=()=>m(a(i("indexeddb_request_failed","Failed to read from IndexedDB.",l.error)))})}catch(r){return a(c(r,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async d=>{try{const r=await y(),s=f(r,"readwrite");return await new Promise(m=>{const l=s.put(d);l.onsuccess=()=>m(u(void 0)),l.onerror=()=>m(a(i("indexeddb_request_failed","Failed to write to IndexedDB.",l.error)))})}catch(r){return a(i("indexeddb_open_failed","Failed to open IndexedDB.",r))}}}},h=()=>{const e=new Map;return{get:async n=>e.has(n)?u({version:n,data:e.get(n)??""}):u(void 0),set:async n=>(e.set(n.version,n.data),u(void 0))}},_=(e={})=>{const t=e.keyPrefix??"iconly",o=()=>typeof window>"u"||!window.sessionStorage?a(i("storage_unavailable","SessionStorage is not available.")):u(window.sessionStorage);return{get:async f=>{const c=o();if(!c.ok)return c;try{const g=c.value.getItem(`${t}:${f}`);if(!g)return u(void 0);const b=JSON.parse(g);return u(b)}catch(g){return a(i("storage_read_failed","Failed to read from SessionStorage.",g))}},set:async f=>{const c=o();if(!c.ok)return c;try{return c.value.setItem(`${t}:${f.version}`,JSON.stringify(f)),u(void 0)}catch(g){return a(i("storage_write_failed","Failed to write to SessionStorage.",g))}}}},D=(e,t)=>!e||e==="indexeddb"?x({dbName:t.dbName,storeName:t.storeName}):e==="memory"?h():e==="session"?_({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},o=D(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let n=null;const y=()=>{n?.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 r=document.body??document.documentElement;return r?u(r):a(i("container_invalid","No valid container element found."))},c=(...r)=>{t.debug&&(t.onDebug?.(...r),t.logger?.debug?.("[Iconly debug]",...r))},g=r=>{t.onError?.(r),t.logger?.error?.("[Iconly error]",r)},b=r=>(g(r),a(r));return{init:async()=>{const r=f();if(!r.ok)return b(r.error);const s=await o.get(t.version);if(!s.ok)return b(s.error);let m=s.value?.data;if(m)c("Using cached icon set",t.version);else{n=new AbortController;const v=await w(t.file,n.signal);if(!v.ok)return b(v.error);m=v.value;const p=await o.set({version:t.version,data:m});if(!p.ok)return b(p.error)}const l=S(r.value,m);return l.ok?(c("Iconly has successfully initialized."),u(void 0)):b(l.error)},abort:y}};exports.createIconly=N;
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","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 const found = container.querySelector('[data-iconly=\"iconset\"]');\n let iconSetDiv: HTMLElement | null = found instanceof HTMLElement ? found : null;\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.setAttribute('data-iconly', '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","found","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","fallback","logDebug","messages","logError","fail","containerResult","cacheResult","fetchResult","storeResult","insertResult"],"mappings":"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"}
package/dist/index.es.js CHANGED
@@ -1,64 +1,65 @@
1
- const i = (e, t, r) => ({
1
+ const i = (e, t, o) => ({
2
2
  code: e,
3
3
  message: t,
4
- cause: r
4
+ cause: o
5
5
  }), u = (e) => ({ ok: !0, value: e }), a = (e) => ({ ok: !1, error: e }), w = (e, t) => {
6
- let r = document.getElementById("iconset");
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"), f = b.querySelector("parsererror");
9
- if (f)
6
+ const o = e.querySelector('[data-iconly="iconset"]');
7
+ let n = o instanceof HTMLElement ? o : null;
8
+ n || (n = document.createElement("div"), n.setAttribute("data-iconly", "iconset"), n.setAttribute("aria-hidden", "true"), n.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;", e.appendChild(n));
9
+ const f = new DOMParser().parseFromString(t, "image/svg+xml"), c = f.querySelector("parsererror");
10
+ if (c)
10
11
  return a(
11
12
  i(
12
13
  "parse_error",
13
- `SVG parsing error: ${f.textContent ?? "Unknown error"}`
14
+ `SVG parsing error: ${c.textContent ?? "Unknown error"}`
14
15
  )
15
16
  );
16
- r.innerHTML = "";
17
- const c = b.documentElement;
18
- if (!c)
17
+ n.innerHTML = "";
18
+ const g = f.documentElement;
19
+ if (!g)
19
20
  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);
21
+ const b = document.importNode(g, !0);
22
+ return n.appendChild(b), u(void 0);
22
23
  }, x = async (e, t) => {
23
24
  try {
24
- const r = await fetch(e, { signal: t });
25
- if (!r.ok)
25
+ const o = await fetch(e, { signal: t });
26
+ if (!o.ok)
26
27
  return a(i("fetch_failed", `Failed to fetch icons from "${e}".`));
27
- const o = await r.text();
28
- return u(o);
29
- } catch (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));
28
+ const n = await o.text();
29
+ return u(n);
30
+ } catch (o) {
31
+ return o instanceof DOMException && o.name === "AbortError" ? a(i("fetch_aborted", "Fetch request was aborted.", o)) : a(i("fetch_failed", "Failed to fetch icons.", o));
31
32
  }
32
33
  }, S = (e = {}) => {
33
- const t = e.dbName ?? "iconlyDB", r = e.storeName ?? "icons";
34
- let o = null;
35
- const b = async () => {
36
- if (o)
37
- return o;
34
+ const t = e.dbName ?? "iconlyDB", o = e.storeName ?? "icons";
35
+ let n = null;
36
+ const y = async () => {
37
+ if (n)
38
+ return n;
38
39
  if (typeof indexedDB > "u")
39
40
  throw i("indexeddb_not_supported", "IndexedDB is not supported.");
40
- return o = new Promise((d, n) => {
41
+ return n = new Promise((d, r) => {
41
42
  const s = indexedDB.open(t, 1);
42
43
  s.onerror = () => {
43
- n(
44
+ r(
44
45
  i(
45
46
  "indexeddb_open_failed",
46
47
  "Failed to open IndexedDB connection.",
47
48
  s.error
48
49
  )
49
50
  );
50
- }, s.onupgradeneeded = (g) => {
51
- const l = g.target.result;
52
- l.objectStoreNames.contains(r) || l.createObjectStore(r, { keyPath: "version" });
51
+ }, s.onupgradeneeded = (m) => {
52
+ const l = m.target.result;
53
+ l.objectStoreNames.contains(o) || l.createObjectStore(o, { keyPath: "version" });
53
54
  }, 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);
55
+ }), n;
56
+ }, f = (d, r) => d.transaction(o, r).objectStore(o), c = (d, r, s) => d && typeof d == "object" && "code" in d && "message" in d ? d : i(r, s, d);
56
57
  return { get: async (d) => {
57
58
  try {
58
- const n = await b(), s = f(n, "readonly");
59
- return await new Promise((g) => {
59
+ const r = await y(), s = f(r, "readonly");
60
+ return await new Promise((m) => {
60
61
  const l = s.get(d);
61
- l.onsuccess = () => g(u(l.result)), l.onerror = () => g(
62
+ l.onsuccess = () => m(u(l.result)), l.onerror = () => m(
62
63
  a(
63
64
  i(
64
65
  "indexeddb_request_failed",
@@ -68,15 +69,15 @@ const i = (e, t, r) => ({
68
69
  )
69
70
  );
70
71
  });
71
- } catch (n) {
72
- return a(c(n, "indexeddb_open_failed", "Failed to open IndexedDB."));
72
+ } catch (r) {
73
+ return a(c(r, "indexeddb_open_failed", "Failed to open IndexedDB."));
73
74
  }
74
75
  }, set: async (d) => {
75
76
  try {
76
- const n = await b(), s = f(n, "readwrite");
77
- return await new Promise((g) => {
77
+ const r = await y(), s = f(r, "readwrite");
78
+ return await new Promise((m) => {
78
79
  const l = s.put(d);
79
- l.onsuccess = () => g(u(void 0)), l.onerror = () => g(
80
+ l.onsuccess = () => m(u(void 0)), l.onerror = () => m(
80
81
  a(
81
82
  i(
82
83
  "indexeddb_request_failed",
@@ -86,39 +87,39 @@ const i = (e, t, r) => ({
86
87
  )
87
88
  );
88
89
  });
89
- } catch (n) {
90
- return a(i("indexeddb_open_failed", "Failed to open IndexedDB.", n));
90
+ } catch (r) {
91
+ return a(i("indexeddb_open_failed", "Failed to open IndexedDB.", r));
91
92
  }
92
93
  } };
93
94
  }, h = () => {
94
95
  const e = /* @__PURE__ */ new Map();
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
+ return { get: async (n) => e.has(n) ? u({ version: n, data: e.get(n) ?? "" }) : u(void 0), set: async (n) => (e.set(n.version, n.data), u(void 0)) };
96
97
  }, _ = (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
+ const t = e.keyPrefix ?? "iconly", o = () => typeof window > "u" || !window.sessionStorage ? a(i("storage_unavailable", "SessionStorage is not available.")) : u(window.sessionStorage);
98
99
  return { get: async (f) => {
99
- const c = r();
100
+ const c = o();
100
101
  if (!c.ok)
101
102
  return c;
102
103
  try {
103
- const m = c.value.getItem(`${t}:${f}`);
104
- if (!m)
104
+ const g = c.value.getItem(`${t}:${f}`);
105
+ if (!g)
105
106
  return u(void 0);
106
- const y = JSON.parse(m);
107
- return u(y);
108
- } catch (m) {
107
+ const b = JSON.parse(g);
108
+ return u(b);
109
+ } catch (g) {
109
110
  return a(
110
- i("storage_read_failed", "Failed to read from SessionStorage.", m)
111
+ i("storage_read_failed", "Failed to read from SessionStorage.", g)
111
112
  );
112
113
  }
113
114
  }, set: async (f) => {
114
- const c = r();
115
+ const c = o();
115
116
  if (!c.ok)
116
117
  return c;
117
118
  try {
118
119
  return c.value.setItem(`${t}:${f.version}`, JSON.stringify(f)), u(void 0);
119
- } catch (m) {
120
+ } catch (g) {
120
121
  return a(
121
- i("storage_write_failed", "Failed to write to SessionStorage.", m)
122
+ i("storage_write_failed", "Failed to write to SessionStorage.", g)
122
123
  );
123
124
  }
124
125
  } };
@@ -134,14 +135,14 @@ const i = (e, t, r) => ({
134
135
  logger: e.logger,
135
136
  onError: e.onError,
136
137
  onDebug: e.onDebug
137
- }, r = D(e.storage, {
138
+ }, o = D(e.storage, {
138
139
  dbName: e.dbName,
139
140
  storeName: e.storeName,
140
141
  sessionKeyPrefix: e.sessionKeyPrefix
141
142
  });
142
- let o = null;
143
- const b = () => {
144
- o?.abort();
143
+ let n = null;
144
+ const y = () => {
145
+ n?.abort();
145
146
  }, f = () => {
146
147
  if (typeof document > "u")
147
148
  return a(
@@ -158,39 +159,39 @@ const i = (e, t, r) => ({
158
159
  }
159
160
  if (t.container instanceof HTMLElement)
160
161
  return u(t.container);
161
- const n = document.body ?? document.documentElement;
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));
165
- }, m = (n) => {
166
- t.onError?.(n), t.logger?.error?.("[Iconly error]", n);
167
- }, y = (n) => (m(n), a(n));
162
+ const r = document.body ?? document.documentElement;
163
+ return r ? u(r) : a(i("container_invalid", "No valid container element found."));
164
+ }, c = (...r) => {
165
+ t.debug && (t.onDebug?.(...r), t.logger?.debug?.("[Iconly debug]", ...r));
166
+ }, g = (r) => {
167
+ t.onError?.(r), t.logger?.error?.("[Iconly error]", r);
168
+ }, b = (r) => (g(r), a(r));
168
169
  return { init: async () => {
169
- const n = f();
170
- if (!n.ok)
171
- return y(n.error);
172
- const s = await r.get(t.version);
170
+ const r = f();
171
+ if (!r.ok)
172
+ return b(r.error);
173
+ const s = await o.get(t.version);
173
174
  if (!s.ok)
174
- return y(s.error);
175
- let g = s.value?.data;
176
- if (g)
175
+ return b(s.error);
176
+ let m = s.value?.data;
177
+ if (m)
177
178
  c("Using cached icon set", t.version);
178
179
  else {
179
- o = new AbortController();
180
- const v = await x(t.file, o.signal);
180
+ n = new AbortController();
181
+ const v = await x(t.file, n.signal);
181
182
  if (!v.ok)
182
- return y(v.error);
183
- g = v.value;
184
- const p = await r.set({
183
+ return b(v.error);
184
+ m = v.value;
185
+ const p = await o.set({
185
186
  version: t.version,
186
- data: g
187
+ data: m
187
188
  });
188
189
  if (!p.ok)
189
- return y(p.error);
190
+ return b(p.error);
190
191
  }
191
- const l = w(n.value, g);
192
- return l.ok ? (c("Iconly has successfully initialized."), u(void 0)) : y(l.error);
193
- }, abort: b };
192
+ const l = w(r.value, m);
193
+ return l.ok ? (c("Iconly has successfully initialized."), u(void 0)) : b(l.error);
194
+ }, abort: y };
194
195
  };
195
196
  export {
196
197
  N as createIconly
@@ -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","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 const found = container.querySelector('[data-iconly=\"iconset\"]');\n let iconSetDiv: HTMLElement | null = found instanceof HTMLElement ? found : null;\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.setAttribute('data-iconly', '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","found","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","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,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"})}));
1
+ (function(y,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(y=typeof globalThis<"u"?globalThis:y||self,s(y.Iconly={}))})(this,(function(y){"use strict";const s=(e,t,o)=>({code:e,message:t,cause:o}),c=e=>({ok:!0,value:e}),a=e=>({ok:!1,error:e}),h=(e,t)=>{const o=e.querySelector('[data-iconly="iconset"]');let n=o instanceof HTMLElement?o:null;n||(n=document.createElement("div"),n.setAttribute("data-iconly","iconset"),n.setAttribute("aria-hidden","true"),n.style.cssText="width: 0; height: 0; position: absolute; left: -9999px;",e.appendChild(n));const f=new DOMParser().parseFromString(t,"image/svg+xml"),d=f.querySelector("parsererror");if(d)return a(s("parse_error",`SVG parsing error: ${d.textContent??"Unknown error"}`));n.innerHTML="";const g=f.documentElement;if(!g)return a(s("parse_error","No valid SVG content found."));const b=document.importNode(g,!0);return n.appendChild(b),c(void 0)},w=async(e,t)=>{try{const o=await fetch(e,{signal:t});if(!o.ok)return a(s("fetch_failed",`Failed to fetch icons from "${e}".`));const n=await o.text();return c(n)}catch(o){return o instanceof DOMException&&o.name==="AbortError"?a(s("fetch_aborted","Fetch request was aborted.",o)):a(s("fetch_failed","Failed to fetch icons.",o))}},x=(e={})=>{const t=e.dbName??"iconlyDB",o=e.storeName??"icons";let n=null;const p=async()=>{if(n)return n;if(typeof indexedDB>"u")throw s("indexeddb_not_supported","IndexedDB is not supported.");return n=new Promise((u,r)=>{const i=indexedDB.open(t,1);i.onerror=()=>{r(s("indexeddb_open_failed","Failed to open IndexedDB connection.",i.error))},i.onupgradeneeded=m=>{const l=m.target.result;l.objectStoreNames.contains(o)||l.createObjectStore(o,{keyPath:"version"})},i.onsuccess=()=>u(i.result)}),n},f=(u,r)=>u.transaction(o,r).objectStore(o),d=(u,r,i)=>u&&typeof u=="object"&&"code"in u&&"message"in u?u:s(r,i,u);return{get:async u=>{try{const r=await p(),i=f(r,"readonly");return await new Promise(m=>{const l=i.get(u);l.onsuccess=()=>m(c(l.result)),l.onerror=()=>m(a(s("indexeddb_request_failed","Failed to read from IndexedDB.",l.error)))})}catch(r){return a(d(r,"indexeddb_open_failed","Failed to open IndexedDB."))}},set:async u=>{try{const r=await p(),i=f(r,"readwrite");return await new Promise(m=>{const l=i.put(u);l.onsuccess=()=>m(c(void 0)),l.onerror=()=>m(a(s("indexeddb_request_failed","Failed to write to IndexedDB.",l.error)))})}catch(r){return a(s("indexeddb_open_failed","Failed to open IndexedDB.",r))}}}},_=()=>{const e=new Map;return{get:async n=>e.has(n)?c({version:n,data:e.get(n)??""}):c(void 0),set:async n=>(e.set(n.version,n.data),c(void 0))}},D=(e={})=>{const t=e.keyPrefix??"iconly",o=()=>typeof window>"u"||!window.sessionStorage?a(s("storage_unavailable","SessionStorage is not available.")):c(window.sessionStorage);return{get:async f=>{const d=o();if(!d.ok)return d;try{const g=d.value.getItem(`${t}:${f}`);if(!g)return c(void 0);const b=JSON.parse(g);return c(b)}catch(g){return a(s("storage_read_failed","Failed to read from SessionStorage.",g))}},set:async f=>{const d=o();if(!d.ok)return d;try{return d.value.setItem(`${t}:${f.version}`,JSON.stringify(f)),c(void 0)}catch(g){return a(s("storage_write_failed","Failed to write to SessionStorage.",g))}}}},I=(e,t)=>!e||e==="indexeddb"?x({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},o=I(e.storage,{dbName:e.dbName,storeName:e.storeName,sessionKeyPrefix:e.sessionKeyPrefix});let n=null;const p=()=>{n?.abort()},f=()=>{if(typeof document>"u")return a(s("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(s("container_invalid",`Invalid container selector: "${t.container}".`)):c(i)}if(t.container instanceof HTMLElement)return c(t.container);const r=document.body??document.documentElement;return r?c(r):a(s("container_invalid","No valid container element found."))},d=(...r)=>{t.debug&&(t.onDebug?.(...r),t.logger?.debug?.("[Iconly debug]",...r))},g=r=>{t.onError?.(r),t.logger?.error?.("[Iconly error]",r)},b=r=>(g(r),a(r));return{init:async()=>{const r=f();if(!r.ok)return b(r.error);const i=await o.get(t.version);if(!i.ok)return b(i.error);let m=i.value?.data;if(m)d("Using cached icon set",t.version);else{n=new AbortController;const v=await w(t.file,n.signal);if(!v.ok)return b(v.error);m=v.value;const S=await o.set({version:t.version,data:m});if(!S.ok)return b(S.error)}const l=h(r.value,m);return l.ok?(d("Iconly has successfully initialized."),c(void 0)):b(l.error)},abort:p}};y.createIconly=N,Object.defineProperty(y,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","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 const found = container.querySelector('[data-iconly=\"iconset\"]');\n let iconSetDiv: HTMLElement | null = found instanceof HTMLElement ? found : null;\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.setAttribute('data-iconly', '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","found","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","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.1",
3
+ "version": "3.0.1-rc.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",
@@ -26,7 +26,8 @@
26
26
  "format": "biome format --write src tests",
27
27
  "typecheck": "tsc -p tsconfig.json --noEmit",
28
28
  "test": "vitest run",
29
- "test:watch": "vitest"
29
+ "test:watch": "vitest",
30
+ "prepublishOnly": "yarn clean && yarn build && yarn verify"
30
31
  },
31
32
  "source": "src/index.ts",
32
33
  "main": "dist/index.cjs.js",
@@ -43,6 +44,7 @@
43
44
  },
44
45
  "files": [
45
46
  "dist",
47
+ "CHANGELOG.md",
46
48
  "README.md",
47
49
  "LICENSE"
48
50
  ],