iconly 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # iconly
2
2
 
3
- A lightweight utility to load and cache SVG icons in the browser, using IndexedDB to store the data.
3
+ A lightweight utility for SVG icon sprites in the browser. Load and cache an external sprite file (`iconly`), or build one from your own icon objects with tree-shaking (`iconly/sprite`).
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/iconly.svg?colorB=brightgreen)](https://www.npmjs.com/package/iconly)
6
6
  [![NPM Downloads](https://img.shields.io/npm/dm/iconly.svg?style=flat)](https://www.npmjs.com/package/iconly)
@@ -11,10 +11,10 @@ A lightweight utility to load and cache SVG icons in the browser, using IndexedD
11
11
 
12
12
  ## Features
13
13
 
14
- - Factory-based API with `createIconly()`.
14
+ - Factory-based API with `createIconly()` — fetch and cache an external sprite file.
15
15
  - IndexedDB, memory, or session storage strategies.
16
- - `init()` returns a `Result` and never throws.
17
- - ~2kB gzipped.
16
+ - `iconly/sprite` build a sprite from icon objects; no fetch, no storage, zero extra runtime deps.
17
+ - `init()` and `render()` return a `Result` and never throw.
18
18
 
19
19
  ---
20
20
 
@@ -26,7 +26,7 @@ npm install iconly
26
26
 
27
27
  ---
28
28
 
29
- ## Quick Start
29
+ ## Quick Start: external sprite file
30
30
 
31
31
  ```ts
32
32
  import { createIconly } from 'iconly';
@@ -65,16 +65,66 @@ Sprite file format:
65
65
 
66
66
  ---
67
67
 
68
+ ## Quick Start: icon objects
69
+
70
+ Import icons as ESM modules — your bundler tree-shakes unused ones. iconly only assembles the sprite string and injects it into the DOM.
71
+
72
+ ```ts
73
+ import { createSprite } from 'iconly/sprite';
74
+ import { search, user, trash } from './icons';
75
+
76
+ const sprite = createSprite({
77
+ icons: [search, user, trash],
78
+ container: '#app', // string | HTMLElement, defaults to document.body
79
+ });
80
+
81
+ const result = sprite.render();
82
+
83
+ if (!result.ok) {
84
+ console.error(result.error);
85
+ }
86
+ ```
87
+
88
+ Icon object format (bring your own):
89
+
90
+ ```ts
91
+ export const search = {
92
+ name: 'search', // id for <use href="#search">
93
+ viewBox: '0 0 24 24',
94
+ body: '<path d="..."/>',
95
+ };
96
+ ```
97
+
98
+ For SSR or tests — build the string without touching the DOM:
99
+
100
+ ```ts
101
+ import { buildSpriteString } from 'iconly/sprite';
102
+
103
+ const svg = buildSpriteString([search, user, trash]);
104
+ ```
105
+
106
+ ---
107
+
68
108
  ## API
69
109
 
110
+ ### `iconly`
111
+
70
112
  - `createIconly(config?)` — creates an icon loader instance.
71
113
  - `iconLoader.init()` — fetches (or loads from cache) the sprite and injects it into the DOM; returns `Result<void>`.
72
114
  - `iconLoader.abort()` — cancels an in-flight fetch.
73
115
 
116
+ ### `iconly/sprite`
117
+
118
+ - `createSprite(config)` — creates a sprite builder instance.
119
+ - `sprite.render()` — builds the sprite from `icons` and injects it into the DOM; returns `Result<void>` synchronously.
120
+ - `buildSpriteString(icons)` — returns the SVG sprite string without DOM access.
121
+
74
122
  ---
75
123
 
76
124
  ## Options
77
125
 
126
+ ### `createIconly`
127
+
78
128
  | Option | Type | Default | Description |
79
129
  | --- | --- | --- | --- |
80
130
  | `file` | `string` | `'./icons.svg'` | URL of the SVG file containing the icons. |
@@ -89,11 +139,18 @@ Sprite file format:
89
139
  | `onError` | `(error) => void` | `undefined` | Callback invoked on errors. |
90
140
  | `onDebug` | `(...args) => void` | `undefined` | Callback invoked for debug messages. |
91
141
 
142
+ ### `createSprite`
143
+
144
+ | Option | Type | Default | Description |
145
+ | --- | --- | --- | --- |
146
+ | `icons` | `IconlyIcon[]` | — | Icon objects to include in the sprite. |
147
+ | `container` | `string \| HTMLElement` | `document.body` | Container where the sprite is injected. |
148
+
92
149
  ---
93
150
 
94
151
  ## Error handling
95
152
 
96
- - `init()` never throws; it returns a `Result` with `ok: false` and `error` details.
153
+ - `init()` and `render()` never throw; they return a `Result` with `ok: false` and `error` details.
97
154
  - When `debug` is `false`, debug messages are suppressed.
98
155
  - Errors still trigger `onError` and `logger.error` (if provided), even when `debug` is `false`.
99
156
  - Call `iconLoader.abort()` to cancel a fetch (`fetch_aborted` error code).
@@ -0,0 +1,86 @@
1
+
2
+ //#region src/errors.ts
3
+ const createIconlyError = (code, message, cause) => ({
4
+ code,
5
+ message,
6
+ cause
7
+ });
8
+
9
+ //#endregion
10
+ //#region src/result.ts
11
+ const ok = (value) => ({
12
+ ok: true,
13
+ value
14
+ });
15
+ const err = (error) => ({
16
+ ok: false,
17
+ error
18
+ });
19
+
20
+ //#endregion
21
+ //#region src/dom.ts
22
+ const resolveContainer = (container) => {
23
+ if (typeof document === "undefined") return err(createIconlyError("container_invalid", "Document is not available in this environment."));
24
+ if (typeof container === "string") {
25
+ const found = document.querySelector(container);
26
+ if (!found || !(found instanceof HTMLElement)) return err(createIconlyError("container_invalid", `Invalid container selector: "${container}".`));
27
+ return ok(found);
28
+ }
29
+ if (container instanceof HTMLElement) return ok(container);
30
+ const fallback = document.body ?? document.documentElement;
31
+ if (!fallback) return err(createIconlyError("container_invalid", "No valid container element found."));
32
+ return ok(fallback);
33
+ };
34
+ const insertSvg = (container, data) => {
35
+ const found = container.querySelector("[data-iconly=\"iconset\"]");
36
+ let iconSetDiv = found instanceof HTMLElement ? found : null;
37
+ if (!iconSetDiv) {
38
+ iconSetDiv = document.createElement("div");
39
+ iconSetDiv.setAttribute("data-iconly", "iconset");
40
+ iconSetDiv.setAttribute("aria-hidden", "true");
41
+ iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
42
+ container.appendChild(iconSetDiv);
43
+ }
44
+ const svgDoc = new DOMParser().parseFromString(data, "image/svg+xml");
45
+ const parserError = svgDoc.querySelector("parsererror");
46
+ if (parserError) return err(createIconlyError("parse_error", `SVG parsing error: ${parserError.textContent ?? "Unknown error"}`));
47
+ iconSetDiv.innerHTML = "";
48
+ const svgEl = svgDoc.documentElement;
49
+ if (!svgEl) return err(createIconlyError("parse_error", "No valid SVG content found."));
50
+ const imported = document.importNode(svgEl, true);
51
+ iconSetDiv.appendChild(imported);
52
+ return ok(void 0);
53
+ };
54
+
55
+ //#endregion
56
+ Object.defineProperty(exports, 'createIconlyError', {
57
+ enumerable: true,
58
+ get: function () {
59
+ return createIconlyError;
60
+ }
61
+ });
62
+ Object.defineProperty(exports, 'err', {
63
+ enumerable: true,
64
+ get: function () {
65
+ return err;
66
+ }
67
+ });
68
+ Object.defineProperty(exports, 'insertSvg', {
69
+ enumerable: true,
70
+ get: function () {
71
+ return insertSvg;
72
+ }
73
+ });
74
+ Object.defineProperty(exports, 'ok', {
75
+ enumerable: true,
76
+ get: function () {
77
+ return ok;
78
+ }
79
+ });
80
+ Object.defineProperty(exports, 'resolveContainer', {
81
+ enumerable: true,
82
+ get: function () {
83
+ return resolveContainer;
84
+ }
85
+ });
86
+ //# sourceMappingURL=dom-Bqsr32nW.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-Bqsr32nW.cjs","names":[],"sources":["../src/errors.ts","../src/result.ts","../src/dom.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 resolveContainer = (container?: string | HTMLElement): 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 container === 'string') {\n const found = document.querySelector(container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError('container_invalid', `Invalid container selector: \"${container}\".`),\n );\n }\n\n return ok(found);\n }\n\n if (container instanceof HTMLElement) {\n return ok(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\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"],"mappings":";;AAEA,MAAa,qBACX,MACA,SACA,WACiB;CACjB;CACA;CACA;AACF;;;;ACRA,MAAa,MAAS,WAAyB;CAAE,IAAI;CAAM;AAAM;AAEjE,MAAa,OAAkB,WAAmC;CAAE,IAAI;CAAO;AAAM;;;;ACArF,MAAa,oBAAoB,cAA0D;CACzF,IAAI,OAAO,aAAa,aACtB,OAAO,IACL,kBAAkB,qBAAqB,gDAAgD,CACzF;CAGF,IAAI,OAAO,cAAc,UAAU;EACjC,MAAM,QAAQ,SAAS,cAAc,SAAS;EAE9C,IAAI,CAAC,SAAS,EAAE,iBAAiB,cAC/B,OAAO,IACL,kBAAkB,qBAAqB,gCAAgC,UAAU,GAAG,CACtF;EAGF,OAAO,GAAG,KAAK;CACjB;CAEA,IAAI,qBAAqB,aACvB,OAAO,GAAG,SAAS;CAGrB,MAAM,WAAW,SAAS,QAAQ,SAAS;CAE3C,IAAI,CAAC,UACH,OAAO,IAAI,kBAAkB,qBAAqB,mCAAmC,CAAC;CAGxF,OAAO,GAAG,QAAQ;AACpB;AAEA,MAAa,aAAa,WAAwB,SAA+B;CAC/E,MAAM,QAAQ,UAAU,cAAc,2BAAyB;CAC/D,IAAI,aAAiC,iBAAiB,cAAc,QAAQ;CAE5E,IAAI,CAAC,YAAY;EACf,aAAa,SAAS,cAAc,KAAK;EACzC,WAAW,aAAa,eAAe,SAAS;EAChD,WAAW,aAAa,eAAe,MAAM;EAC7C,WAAW,MAAM,UAAU;EAC3B,UAAU,YAAY,UAAU;CAClC;CAGA,MAAM,SAAS,IADI,UACC,CAAC,CAAC,gBAAgB,MAAM,eAAe;CAC3D,MAAM,cAAc,OAAO,cAAc,aAAa;CAEtD,IAAI,aACF,OAAO,IACL,kBACE,eACA,sBAAsB,YAAY,eAAe,iBACnD,CACF;CAGF,WAAW,YAAY;CAEvB,MAAM,QAAQ,OAAO;CAErB,IAAI,CAAC,OACH,OAAO,IAAI,kBAAkB,eAAe,6BAA6B,CAAC;CAG5E,MAAM,WAAW,SAAS,WAAW,OAAO,IAAI;CAEhD,WAAW,YAAY,QAAQ;CAE/B,OAAO,GAAG,MAAS;AACrB"}
@@ -0,0 +1,56 @@
1
+ //#region src/errors.ts
2
+ const createIconlyError = (code, message, cause) => ({
3
+ code,
4
+ message,
5
+ cause
6
+ });
7
+
8
+ //#endregion
9
+ //#region src/result.ts
10
+ const ok = (value) => ({
11
+ ok: true,
12
+ value
13
+ });
14
+ const err = (error) => ({
15
+ ok: false,
16
+ error
17
+ });
18
+
19
+ //#endregion
20
+ //#region src/dom.ts
21
+ const resolveContainer = (container) => {
22
+ if (typeof document === "undefined") return err(createIconlyError("container_invalid", "Document is not available in this environment."));
23
+ if (typeof container === "string") {
24
+ const found = document.querySelector(container);
25
+ if (!found || !(found instanceof HTMLElement)) return err(createIconlyError("container_invalid", `Invalid container selector: "${container}".`));
26
+ return ok(found);
27
+ }
28
+ if (container instanceof HTMLElement) return ok(container);
29
+ const fallback = document.body ?? document.documentElement;
30
+ if (!fallback) return err(createIconlyError("container_invalid", "No valid container element found."));
31
+ return ok(fallback);
32
+ };
33
+ const insertSvg = (container, data) => {
34
+ const found = container.querySelector("[data-iconly=\"iconset\"]");
35
+ let iconSetDiv = found instanceof HTMLElement ? found : null;
36
+ if (!iconSetDiv) {
37
+ iconSetDiv = document.createElement("div");
38
+ iconSetDiv.setAttribute("data-iconly", "iconset");
39
+ iconSetDiv.setAttribute("aria-hidden", "true");
40
+ iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
41
+ container.appendChild(iconSetDiv);
42
+ }
43
+ const svgDoc = new DOMParser().parseFromString(data, "image/svg+xml");
44
+ const parserError = svgDoc.querySelector("parsererror");
45
+ if (parserError) return err(createIconlyError("parse_error", `SVG parsing error: ${parserError.textContent ?? "Unknown error"}`));
46
+ iconSetDiv.innerHTML = "";
47
+ const svgEl = svgDoc.documentElement;
48
+ if (!svgEl) return err(createIconlyError("parse_error", "No valid SVG content found."));
49
+ const imported = document.importNode(svgEl, true);
50
+ iconSetDiv.appendChild(imported);
51
+ return ok(void 0);
52
+ };
53
+
54
+ //#endregion
55
+ export { createIconlyError as a, ok as i, resolveContainer as n, err as r, insertSvg as t };
56
+ //# sourceMappingURL=dom-senQJ1VA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-senQJ1VA.js","names":[],"sources":["../src/errors.ts","../src/result.ts","../src/dom.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 resolveContainer = (container?: string | HTMLElement): 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 container === 'string') {\n const found = document.querySelector(container);\n\n if (!found || !(found instanceof HTMLElement)) {\n return err(\n createIconlyError('container_invalid', `Invalid container selector: \"${container}\".`),\n );\n }\n\n return ok(found);\n }\n\n if (container instanceof HTMLElement) {\n return ok(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\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"],"mappings":";AAEA,MAAa,qBACX,MACA,SACA,WACiB;CACjB;CACA;CACA;AACF;;;;ACRA,MAAa,MAAS,WAAyB;CAAE,IAAI;CAAM;AAAM;AAEjE,MAAa,OAAkB,WAAmC;CAAE,IAAI;CAAO;AAAM;;;;ACArF,MAAa,oBAAoB,cAA0D;CACzF,IAAI,OAAO,aAAa,aACtB,OAAO,IACL,kBAAkB,qBAAqB,gDAAgD,CACzF;CAGF,IAAI,OAAO,cAAc,UAAU;EACjC,MAAM,QAAQ,SAAS,cAAc,SAAS;EAE9C,IAAI,CAAC,SAAS,EAAE,iBAAiB,cAC/B,OAAO,IACL,kBAAkB,qBAAqB,gCAAgC,UAAU,GAAG,CACtF;EAGF,OAAO,GAAG,KAAK;CACjB;CAEA,IAAI,qBAAqB,aACvB,OAAO,GAAG,SAAS;CAGrB,MAAM,WAAW,SAAS,QAAQ,SAAS;CAE3C,IAAI,CAAC,UACH,OAAO,IAAI,kBAAkB,qBAAqB,mCAAmC,CAAC;CAGxF,OAAO,GAAG,QAAQ;AACpB;AAEA,MAAa,aAAa,WAAwB,SAA+B;CAC/E,MAAM,QAAQ,UAAU,cAAc,2BAAyB;CAC/D,IAAI,aAAiC,iBAAiB,cAAc,QAAQ;CAE5E,IAAI,CAAC,YAAY;EACf,aAAa,SAAS,cAAc,KAAK;EACzC,WAAW,aAAa,eAAe,SAAS;EAChD,WAAW,aAAa,eAAe,MAAM;EAC7C,WAAW,MAAM,UAAU;EAC3B,UAAU,YAAY,UAAU;CAClC;CAGA,MAAM,SAAS,IADI,UACC,CAAC,CAAC,gBAAgB,MAAM,eAAe;CAC3D,MAAM,cAAc,OAAO,cAAc,aAAa;CAEtD,IAAI,aACF,OAAO,IACL,kBACE,eACA,sBAAsB,YAAY,eAAe,iBACnD,CACF;CAGF,WAAW,YAAY;CAEvB,MAAM,QAAQ,OAAO;CAErB,IAAI,CAAC,OACH,OAAO,IAAI,kBAAkB,eAAe,6BAA6B,CAAC;CAG5E,MAAM,WAAW,SAAS,WAAW,OAAO,IAAI;CAEhD,WAAW,YAAY,QAAQ;CAE/B,OAAO,GAAG,MAAS;AACrB"}
package/dist/index.cjs CHANGED
@@ -1,56 +1,15 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_dom = require('./dom-Bqsr32nW.cjs');
2
3
 
3
- //#region src/errors.ts
4
- const createIconlyError = (code, message, cause) => ({
5
- code,
6
- message,
7
- cause
8
- });
9
-
10
- //#endregion
11
- //#region src/result.ts
12
- const ok = (value) => ({
13
- ok: true,
14
- value
15
- });
16
- const err = (error) => ({
17
- ok: false,
18
- error
19
- });
20
-
21
- //#endregion
22
- //#region src/dom.ts
23
- const insertSvg = (container, data) => {
24
- const found = container.querySelector("[data-iconly=\"iconset\"]");
25
- let iconSetDiv = found instanceof HTMLElement ? found : null;
26
- if (!iconSetDiv) {
27
- iconSetDiv = document.createElement("div");
28
- iconSetDiv.setAttribute("data-iconly", "iconset");
29
- iconSetDiv.setAttribute("aria-hidden", "true");
30
- iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
31
- container.appendChild(iconSetDiv);
32
- }
33
- const svgDoc = new DOMParser().parseFromString(data, "image/svg+xml");
34
- const parserError = svgDoc.querySelector("parsererror");
35
- if (parserError) return err(createIconlyError("parse_error", `SVG parsing error: ${parserError.textContent ?? "Unknown error"}`));
36
- iconSetDiv.innerHTML = "";
37
- const svgEl = svgDoc.documentElement;
38
- if (!svgEl) return err(createIconlyError("parse_error", "No valid SVG content found."));
39
- const imported = document.importNode(svgEl, true);
40
- iconSetDiv.appendChild(imported);
41
- return ok(void 0);
42
- };
43
-
44
- //#endregion
45
4
  //#region src/fetcher.ts
46
5
  const fetchSvg = async (file, signal) => {
47
6
  try {
48
7
  const response = await fetch(file, { signal });
49
- if (!response.ok) return err(createIconlyError("fetch_failed", `Failed to fetch icons from "${file}".`));
50
- return ok(await response.text());
8
+ if (!response.ok) return require_dom.err(require_dom.createIconlyError("fetch_failed", `Failed to fetch icons from "${file}".`));
9
+ return require_dom.ok(await response.text());
51
10
  } catch (error) {
52
- if (error instanceof DOMException && error.name === "AbortError") return err(createIconlyError("fetch_aborted", "Fetch request was aborted.", error));
53
- return err(createIconlyError("fetch_failed", "Failed to fetch icons.", error));
11
+ if (error instanceof DOMException && error.name === "AbortError") return require_dom.err(require_dom.createIconlyError("fetch_aborted", "Fetch request was aborted.", error));
12
+ return require_dom.err(require_dom.createIconlyError("fetch_failed", "Failed to fetch icons.", error));
54
13
  }
55
14
  };
56
15
 
@@ -62,11 +21,11 @@ const createIndexedDbStorage = (options = {}) => {
62
21
  let dbPromise = null;
63
22
  const openDb = async () => {
64
23
  if (dbPromise) return dbPromise;
65
- if (typeof indexedDB === "undefined") throw createIconlyError("indexeddb_not_supported", "IndexedDB is not supported.");
24
+ if (typeof indexedDB === "undefined") throw require_dom.createIconlyError("indexeddb_not_supported", "IndexedDB is not supported.");
66
25
  dbPromise = new Promise((resolve, reject) => {
67
26
  const request = indexedDB.open(dbName, 1);
68
27
  request.onerror = () => {
69
- reject(createIconlyError("indexeddb_open_failed", "Failed to open IndexedDB connection.", request.error));
28
+ reject(require_dom.createIconlyError("indexeddb_open_failed", "Failed to open IndexedDB connection.", request.error));
70
29
  };
71
30
  request.onupgradeneeded = (event) => {
72
31
  const db = event.target.result;
@@ -79,18 +38,18 @@ const createIndexedDbStorage = (options = {}) => {
79
38
  const getStore = (db, mode) => db.transaction(storeName, mode).objectStore(storeName);
80
39
  const toIconlyError = (error, fallbackCode, message) => {
81
40
  if (error && typeof error === "object" && "code" in error && "message" in error) return error;
82
- return createIconlyError(fallbackCode, message, error);
41
+ return require_dom.createIconlyError(fallbackCode, message, error);
83
42
  };
84
43
  const get = async (version) => {
85
44
  try {
86
45
  const store = getStore(await openDb(), "readonly");
87
46
  return await new Promise((resolve) => {
88
47
  const request = store.get(version);
89
- request.onsuccess = () => resolve(ok(request.result));
90
- request.onerror = () => resolve(err(createIconlyError("indexeddb_request_failed", "Failed to read from IndexedDB.", request.error)));
48
+ request.onsuccess = () => resolve(require_dom.ok(request.result));
49
+ request.onerror = () => resolve(require_dom.err(require_dom.createIconlyError("indexeddb_request_failed", "Failed to read from IndexedDB.", request.error)));
91
50
  });
92
51
  } catch (error) {
93
- return err(toIconlyError(error, "indexeddb_open_failed", "Failed to open IndexedDB."));
52
+ return require_dom.err(toIconlyError(error, "indexeddb_open_failed", "Failed to open IndexedDB."));
94
53
  }
95
54
  };
96
55
  const set = async (record) => {
@@ -98,11 +57,11 @@ const createIndexedDbStorage = (options = {}) => {
98
57
  const store = getStore(await openDb(), "readwrite");
99
58
  return await new Promise((resolve) => {
100
59
  const request = store.put(record);
101
- request.onsuccess = () => resolve(ok(void 0));
102
- request.onerror = () => resolve(err(createIconlyError("indexeddb_request_failed", "Failed to write to IndexedDB.", request.error)));
60
+ request.onsuccess = () => resolve(require_dom.ok(void 0));
61
+ request.onerror = () => resolve(require_dom.err(require_dom.createIconlyError("indexeddb_request_failed", "Failed to write to IndexedDB.", request.error)));
103
62
  });
104
63
  } catch (error) {
105
- return err(createIconlyError("indexeddb_open_failed", "Failed to open IndexedDB.", error));
64
+ return require_dom.err(require_dom.createIconlyError("indexeddb_open_failed", "Failed to open IndexedDB.", error));
106
65
  }
107
66
  };
108
67
  return {
@@ -116,15 +75,15 @@ const createIndexedDbStorage = (options = {}) => {
116
75
  const createMemoryStorage = () => {
117
76
  const store = /* @__PURE__ */ new Map();
118
77
  const get = async (version) => {
119
- if (!store.has(version)) return ok(void 0);
120
- return ok({
78
+ if (!store.has(version)) return require_dom.ok(void 0);
79
+ return require_dom.ok({
121
80
  version,
122
81
  data: store.get(version) ?? ""
123
82
  });
124
83
  };
125
84
  const set = async (record) => {
126
85
  store.set(record.version, record.data);
127
- return ok(void 0);
86
+ return require_dom.ok(void 0);
128
87
  };
129
88
  return {
130
89
  get,
@@ -137,18 +96,18 @@ const createMemoryStorage = () => {
137
96
  const createSessionStorage = (options = {}) => {
138
97
  const keyPrefix = options.keyPrefix ?? "iconly";
139
98
  const resolveStorage = () => {
140
- if (typeof window === "undefined" || !window.sessionStorage) return err(createIconlyError("storage_unavailable", "SessionStorage is not available."));
141
- return ok(window.sessionStorage);
99
+ if (typeof window === "undefined" || !window.sessionStorage) return require_dom.err(require_dom.createIconlyError("storage_unavailable", "SessionStorage is not available."));
100
+ return require_dom.ok(window.sessionStorage);
142
101
  };
143
102
  const get = async (version) => {
144
103
  const storageResult = resolveStorage();
145
104
  if (!storageResult.ok) return storageResult;
146
105
  try {
147
106
  const raw = storageResult.value.getItem(`${keyPrefix}:${version}`);
148
- if (!raw) return ok(void 0);
149
- return ok(JSON.parse(raw));
107
+ if (!raw) return require_dom.ok(void 0);
108
+ return require_dom.ok(JSON.parse(raw));
150
109
  } catch (error) {
151
- return err(createIconlyError("storage_read_failed", "Failed to read from SessionStorage.", error));
110
+ return require_dom.err(require_dom.createIconlyError("storage_read_failed", "Failed to read from SessionStorage.", error));
152
111
  }
153
112
  };
154
113
  const set = async (record) => {
@@ -156,9 +115,9 @@ const createSessionStorage = (options = {}) => {
156
115
  if (!storageResult.ok) return storageResult;
157
116
  try {
158
117
  storageResult.value.setItem(`${keyPrefix}:${record.version}`, JSON.stringify(record));
159
- return ok(void 0);
118
+ return require_dom.ok(void 0);
160
119
  } catch (error) {
161
- return err(createIconlyError("storage_write_failed", "Failed to write to SessionStorage.", error));
120
+ return require_dom.err(require_dom.createIconlyError("storage_write_failed", "Failed to write to SessionStorage.", error));
162
121
  }
163
122
  };
164
123
  return {
@@ -200,18 +159,6 @@ const createIconly = (config = {}) => {
200
159
  const abort = () => {
201
160
  controller?.abort();
202
161
  };
203
- const resolveContainer = () => {
204
- if (typeof document === "undefined") return err(createIconlyError("container_invalid", "Document is not available in this environment."));
205
- if (typeof resolved.container === "string") {
206
- const found = document.querySelector(resolved.container);
207
- if (!found || !(found instanceof HTMLElement)) return err(createIconlyError("container_invalid", `Invalid container selector: "${resolved.container}".`));
208
- return ok(found);
209
- }
210
- if (resolved.container instanceof HTMLElement) return ok(resolved.container);
211
- const fallback = document.body ?? document.documentElement;
212
- if (!fallback) return err(createIconlyError("container_invalid", "No valid container element found."));
213
- return ok(fallback);
214
- };
215
162
  const logDebug = (...messages) => {
216
163
  if (!resolved.debug) return;
217
164
  resolved.onDebug?.(...messages);
@@ -223,10 +170,10 @@ const createIconly = (config = {}) => {
223
170
  };
224
171
  const fail = (error) => {
225
172
  logError(error);
226
- return err(error);
173
+ return require_dom.err(error);
227
174
  };
228
175
  const init = async () => {
229
- const containerResult = resolveContainer();
176
+ const containerResult = require_dom.resolveContainer(resolved.container);
230
177
  if (!containerResult.ok) return fail(containerResult.error);
231
178
  const cacheResult = await storage.get(resolved.version);
232
179
  if (!cacheResult.ok) return fail(cacheResult.error);
@@ -242,10 +189,10 @@ const createIconly = (config = {}) => {
242
189
  });
243
190
  if (!storeResult.ok) return fail(storeResult.error);
244
191
  } else logDebug("Using cached icon set", resolved.version);
245
- const insertResult = insertSvg(containerResult.value, data);
192
+ const insertResult = require_dom.insertSvg(containerResult.value, data);
246
193
  if (!insertResult.ok) return fail(insertResult.error);
247
194
  logDebug("Iconly has successfully initialized.");
248
- return ok(void 0);
195
+ return require_dom.ok(void 0);
249
196
  };
250
197
  return {
251
198
  init,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"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"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["err","createIconlyError","ok","createIconlyError","ok","err","ok","err","createIconlyError","ok","err","resolveContainer","insertSvg","ok"],"sources":["../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["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, resolveContainer } from './dom';\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 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(resolved.container);\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"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,48 +1,5 @@
1
- //#region src/types.d.ts
2
- type Result<T> = {
3
- ok: true;
4
- value: T;
5
- } | {
6
- ok: false;
7
- error: IconlyError;
8
- };
9
- type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
10
- interface IconlyError {
11
- code: IconlyErrorCode;
12
- message: string;
13
- cause?: unknown;
14
- }
15
- interface Logger {
16
- debug?: (...messages: unknown[]) => void;
17
- error?: (...messages: unknown[]) => void;
18
- }
19
- interface IconRecord {
20
- version: string;
21
- data: string;
22
- }
23
- interface IconStorage {
24
- get(version: string): Promise<Result<IconRecord | undefined>>;
25
- set(record: IconRecord): Promise<Result<void>>;
26
- }
27
- interface IconlyInstance {
28
- init: () => Promise<Result<void>>;
29
- abort: () => void;
30
- }
31
- type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
32
- interface IconlyConfig {
33
- file?: string;
34
- version?: string;
35
- debug?: boolean;
36
- container?: string | HTMLElement;
37
- storage?: StorageStrategy;
38
- dbName?: string;
39
- storeName?: string;
40
- sessionKeyPrefix?: string;
41
- logger?: Logger;
42
- onError?: (error: IconlyError) => void;
43
- onDebug?: (...messages: unknown[]) => void;
44
- }
45
- //#endregion
1
+ import { a as IconlyErrorCode, c as Logger, f as StorageStrategy, i as IconlyError, l as Result, n as IconStorage, r as IconlyConfig, s as IconlyInstance, t as IconRecord } from "./types-Byzu8V49.cjs";
2
+
46
3
  //#region src/core.d.ts
47
4
  declare const createIconly: (config?: IconlyConfig) => IconlyInstance;
48
5
  //#endregion
package/dist/index.d.ts CHANGED
@@ -1,48 +1,5 @@
1
- //#region src/types.d.ts
2
- type Result<T> = {
3
- ok: true;
4
- value: T;
5
- } | {
6
- ok: false;
7
- error: IconlyError;
8
- };
9
- type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
10
- interface IconlyError {
11
- code: IconlyErrorCode;
12
- message: string;
13
- cause?: unknown;
14
- }
15
- interface Logger {
16
- debug?: (...messages: unknown[]) => void;
17
- error?: (...messages: unknown[]) => void;
18
- }
19
- interface IconRecord {
20
- version: string;
21
- data: string;
22
- }
23
- interface IconStorage {
24
- get(version: string): Promise<Result<IconRecord | undefined>>;
25
- set(record: IconRecord): Promise<Result<void>>;
26
- }
27
- interface IconlyInstance {
28
- init: () => Promise<Result<void>>;
29
- abort: () => void;
30
- }
31
- type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
32
- interface IconlyConfig {
33
- file?: string;
34
- version?: string;
35
- debug?: boolean;
36
- container?: string | HTMLElement;
37
- storage?: StorageStrategy;
38
- dbName?: string;
39
- storeName?: string;
40
- sessionKeyPrefix?: string;
41
- logger?: Logger;
42
- onError?: (error: IconlyError) => void;
43
- onDebug?: (...messages: unknown[]) => void;
44
- }
45
- //#endregion
1
+ import { a as IconlyErrorCode, c as Logger, f as StorageStrategy, i as IconlyError, l as Result, n as IconStorage, r as IconlyConfig, s as IconlyInstance, t as IconRecord } from "./types-Byzu8V49.js";
2
+
46
3
  //#region src/core.d.ts
47
4
  declare const createIconly: (config?: IconlyConfig) => IconlyInstance;
48
5
  //#endregion
package/dist/index.js CHANGED
@@ -1,45 +1,5 @@
1
- //#region src/errors.ts
2
- const createIconlyError = (code, message, cause) => ({
3
- code,
4
- message,
5
- cause
6
- });
1
+ import { a as createIconlyError, i as ok, n as resolveContainer, r as err, t as insertSvg } from "./dom-senQJ1VA.js";
7
2
 
8
- //#endregion
9
- //#region src/result.ts
10
- const ok = (value) => ({
11
- ok: true,
12
- value
13
- });
14
- const err = (error) => ({
15
- ok: false,
16
- error
17
- });
18
-
19
- //#endregion
20
- //#region src/dom.ts
21
- const insertSvg = (container, data) => {
22
- const found = container.querySelector("[data-iconly=\"iconset\"]");
23
- let iconSetDiv = found instanceof HTMLElement ? found : null;
24
- if (!iconSetDiv) {
25
- iconSetDiv = document.createElement("div");
26
- iconSetDiv.setAttribute("data-iconly", "iconset");
27
- iconSetDiv.setAttribute("aria-hidden", "true");
28
- iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
29
- container.appendChild(iconSetDiv);
30
- }
31
- const svgDoc = new DOMParser().parseFromString(data, "image/svg+xml");
32
- const parserError = svgDoc.querySelector("parsererror");
33
- if (parserError) return err(createIconlyError("parse_error", `SVG parsing error: ${parserError.textContent ?? "Unknown error"}`));
34
- iconSetDiv.innerHTML = "";
35
- const svgEl = svgDoc.documentElement;
36
- if (!svgEl) return err(createIconlyError("parse_error", "No valid SVG content found."));
37
- const imported = document.importNode(svgEl, true);
38
- iconSetDiv.appendChild(imported);
39
- return ok(void 0);
40
- };
41
-
42
- //#endregion
43
3
  //#region src/fetcher.ts
44
4
  const fetchSvg = async (file, signal) => {
45
5
  try {
@@ -198,18 +158,6 @@ const createIconly = (config = {}) => {
198
158
  const abort = () => {
199
159
  controller?.abort();
200
160
  };
201
- const resolveContainer = () => {
202
- if (typeof document === "undefined") return err(createIconlyError("container_invalid", "Document is not available in this environment."));
203
- if (typeof resolved.container === "string") {
204
- const found = document.querySelector(resolved.container);
205
- if (!found || !(found instanceof HTMLElement)) return err(createIconlyError("container_invalid", `Invalid container selector: "${resolved.container}".`));
206
- return ok(found);
207
- }
208
- if (resolved.container instanceof HTMLElement) return ok(resolved.container);
209
- const fallback = document.body ?? document.documentElement;
210
- if (!fallback) return err(createIconlyError("container_invalid", "No valid container element found."));
211
- return ok(fallback);
212
- };
213
161
  const logDebug = (...messages) => {
214
162
  if (!resolved.debug) return;
215
163
  resolved.onDebug?.(...messages);
@@ -224,7 +172,7 @@ const createIconly = (config = {}) => {
224
172
  return err(error);
225
173
  };
226
174
  const init = async () => {
227
- const containerResult = resolveContainer();
175
+ const containerResult = resolveContainer(resolved.container);
228
176
  if (!containerResult.ok) return fail(containerResult.error);
229
177
  const cacheResult = await storage.get(resolved.version);
230
178
  if (!cacheResult.ok) return fail(cacheResult.error);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"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"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/fetcher.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/index.ts","../src/core.ts"],"sourcesContent":["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, resolveContainer } from './dom';\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 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(resolved.container);\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"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_dom = require('./dom-Bqsr32nW.cjs');
3
+
4
+ //#region src/sprite.ts
5
+ const escapeAttr = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
6
+ const buildSpriteString = (icons) => {
7
+ return `<svg xmlns="http://www.w3.org/2000/svg">${icons.map((icon) => `<symbol id="${escapeAttr(icon.name)}" viewBox="${escapeAttr(icon.viewBox)}">${icon.body}</symbol>`).join("")}</svg>`;
8
+ };
9
+ const createSprite = (config) => {
10
+ const { icons, container } = config;
11
+ return { render: () => {
12
+ const containerResult = require_dom.resolveContainer(container);
13
+ if (!containerResult.ok) return containerResult;
14
+ return require_dom.insertSvg(containerResult.value, buildSpriteString(icons));
15
+ } };
16
+ };
17
+
18
+ //#endregion
19
+ exports.buildSpriteString = buildSpriteString;
20
+ exports.createSprite = createSprite;
21
+ //# sourceMappingURL=sprite.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprite.cjs","names":["resolveContainer","insertSvg"],"sources":["../src/sprite.ts"],"sourcesContent":["import { insertSvg, resolveContainer } from './dom';\nimport type { IconlyIcon, Result, SpriteConfig, SpriteInstance } from './types';\n\nconst escapeAttr = (value: string): string =>\n value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\"/g, '&quot;');\n\nexport const buildSpriteString = (icons: IconlyIcon[]): string => {\n const symbols = icons\n .map(\n (icon) =>\n `<symbol id=\"${escapeAttr(icon.name)}\" viewBox=\"${escapeAttr(icon.viewBox)}\">${icon.body}</symbol>`,\n )\n .join('');\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\">${symbols}</svg>`;\n};\n\nexport const createSprite = (config: SpriteConfig): SpriteInstance => {\n const { icons, container } = config;\n\n return {\n render: (): Result<void> => {\n const containerResult = resolveContainer(container);\n\n if (!containerResult.ok) {\n return containerResult;\n }\n\n return insertSvg(containerResult.value, buildSpriteString(icons));\n },\n };\n};\n\nexport type { IconlyIcon, SpriteConfig, SpriteInstance } from './types';\n"],"mappings":";;;;AAGA,MAAM,cAAc,UAClB,MAAM,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,QAAQ;AAE3E,MAAa,qBAAqB,UAAgC;CAQhE,OAAO,2CAPS,MACb,KACE,SACC,eAAe,WAAW,KAAK,IAAI,EAAE,aAAa,WAAW,KAAK,OAAO,EAAE,IAAI,KAAK,KAAK,UAC7F,CAAC,CACA,KAAK,EAEgD,EAAE;AAC5D;AAEA,MAAa,gBAAgB,WAAyC;CACpE,MAAM,EAAE,OAAO,cAAc;CAE7B,OAAO,EACL,cAA4B;EAC1B,MAAM,kBAAkBA,6BAAiB,SAAS;EAElD,IAAI,CAAC,gBAAgB,IACnB,OAAO;EAGT,OAAOC,sBAAU,gBAAgB,OAAO,kBAAkB,KAAK,CAAC;CAClE,EACF;AACF"}
@@ -0,0 +1,8 @@
1
+ import { d as SpriteInstance, o as IconlyIcon, u as SpriteConfig } from "./types-Byzu8V49.cjs";
2
+
3
+ //#region src/sprite.d.ts
4
+ declare const buildSpriteString: (icons: IconlyIcon[]) => string;
5
+ declare const createSprite: (config: SpriteConfig) => SpriteInstance;
6
+ //#endregion
7
+ export { type IconlyIcon, type SpriteConfig, type SpriteInstance, buildSpriteString, createSprite };
8
+ //# sourceMappingURL=sprite.d.cts.map
@@ -0,0 +1,8 @@
1
+ import { d as SpriteInstance, o as IconlyIcon, u as SpriteConfig } from "./types-Byzu8V49.js";
2
+
3
+ //#region src/sprite.d.ts
4
+ declare const buildSpriteString: (icons: IconlyIcon[]) => string;
5
+ declare const createSprite: (config: SpriteConfig) => SpriteInstance;
6
+ //#endregion
7
+ export { type IconlyIcon, type SpriteConfig, type SpriteInstance, buildSpriteString, createSprite };
8
+ //# sourceMappingURL=sprite.d.ts.map
package/dist/sprite.js ADDED
@@ -0,0 +1,19 @@
1
+ import { n as resolveContainer, t as insertSvg } from "./dom-senQJ1VA.js";
2
+
3
+ //#region src/sprite.ts
4
+ const escapeAttr = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
5
+ const buildSpriteString = (icons) => {
6
+ return `<svg xmlns="http://www.w3.org/2000/svg">${icons.map((icon) => `<symbol id="${escapeAttr(icon.name)}" viewBox="${escapeAttr(icon.viewBox)}">${icon.body}</symbol>`).join("")}</svg>`;
7
+ };
8
+ const createSprite = (config) => {
9
+ const { icons, container } = config;
10
+ return { render: () => {
11
+ const containerResult = resolveContainer(container);
12
+ if (!containerResult.ok) return containerResult;
13
+ return insertSvg(containerResult.value, buildSpriteString(icons));
14
+ } };
15
+ };
16
+
17
+ //#endregion
18
+ export { buildSpriteString, createSprite };
19
+ //# sourceMappingURL=sprite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprite.js","names":[],"sources":["../src/sprite.ts"],"sourcesContent":["import { insertSvg, resolveContainer } from './dom';\nimport type { IconlyIcon, Result, SpriteConfig, SpriteInstance } from './types';\n\nconst escapeAttr = (value: string): string =>\n value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\"/g, '&quot;');\n\nexport const buildSpriteString = (icons: IconlyIcon[]): string => {\n const symbols = icons\n .map(\n (icon) =>\n `<symbol id=\"${escapeAttr(icon.name)}\" viewBox=\"${escapeAttr(icon.viewBox)}\">${icon.body}</symbol>`,\n )\n .join('');\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\">${symbols}</svg>`;\n};\n\nexport const createSprite = (config: SpriteConfig): SpriteInstance => {\n const { icons, container } = config;\n\n return {\n render: (): Result<void> => {\n const containerResult = resolveContainer(container);\n\n if (!containerResult.ok) {\n return containerResult;\n }\n\n return insertSvg(containerResult.value, buildSpriteString(icons));\n },\n };\n};\n\nexport type { IconlyIcon, SpriteConfig, SpriteInstance } from './types';\n"],"mappings":";;;AAGA,MAAM,cAAc,UAClB,MAAM,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,QAAQ;AAE3E,MAAa,qBAAqB,UAAgC;CAQhE,OAAO,2CAPS,MACb,KACE,SACC,eAAe,WAAW,KAAK,IAAI,EAAE,aAAa,WAAW,KAAK,OAAO,EAAE,IAAI,KAAK,KAAK,UAC7F,CAAC,CACA,KAAK,EAEgD,EAAE;AAC5D;AAEA,MAAa,gBAAgB,WAAyC;CACpE,MAAM,EAAE,OAAO,cAAc;CAE7B,OAAO,EACL,cAA4B;EAC1B,MAAM,kBAAkB,iBAAiB,SAAS;EAElD,IAAI,CAAC,gBAAgB,IACnB,OAAO;EAGT,OAAO,UAAU,gBAAgB,OAAO,kBAAkB,KAAK,CAAC;CAClE,EACF;AACF"}
@@ -0,0 +1,59 @@
1
+ //#region src/types.d.ts
2
+ type Result<T> = {
3
+ ok: true;
4
+ value: T;
5
+ } | {
6
+ ok: false;
7
+ error: IconlyError;
8
+ };
9
+ type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
10
+ interface IconlyError {
11
+ code: IconlyErrorCode;
12
+ message: string;
13
+ cause?: unknown;
14
+ }
15
+ interface Logger {
16
+ debug?: (...messages: unknown[]) => void;
17
+ error?: (...messages: unknown[]) => void;
18
+ }
19
+ interface IconRecord {
20
+ version: string;
21
+ data: string;
22
+ }
23
+ interface IconStorage {
24
+ get(version: string): Promise<Result<IconRecord | undefined>>;
25
+ set(record: IconRecord): Promise<Result<void>>;
26
+ }
27
+ interface IconlyInstance {
28
+ init: () => Promise<Result<void>>;
29
+ abort: () => void;
30
+ }
31
+ type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
32
+ interface IconlyIcon {
33
+ name: string;
34
+ viewBox: string;
35
+ body: string;
36
+ }
37
+ interface SpriteConfig {
38
+ icons: IconlyIcon[];
39
+ container?: string | HTMLElement;
40
+ }
41
+ interface SpriteInstance {
42
+ render: () => Result<void>;
43
+ }
44
+ interface IconlyConfig {
45
+ file?: string;
46
+ version?: string;
47
+ debug?: boolean;
48
+ container?: string | HTMLElement;
49
+ storage?: StorageStrategy;
50
+ dbName?: string;
51
+ storeName?: string;
52
+ sessionKeyPrefix?: string;
53
+ logger?: Logger;
54
+ onError?: (error: IconlyError) => void;
55
+ onDebug?: (...messages: unknown[]) => void;
56
+ }
57
+ //#endregion
58
+ export { IconlyErrorCode as a, Logger as c, SpriteInstance as d, StorageStrategy as f, IconlyError as i, Result as l, IconStorage as n, IconlyIcon as o, IconlyConfig as r, IconlyInstance as s, IconRecord as t, SpriteConfig as u };
59
+ //# sourceMappingURL=types-Byzu8V49.d.cts.map
@@ -0,0 +1,59 @@
1
+ //#region src/types.d.ts
2
+ type Result<T> = {
3
+ ok: true;
4
+ value: T;
5
+ } | {
6
+ ok: false;
7
+ error: IconlyError;
8
+ };
9
+ type IconlyErrorCode = 'container_invalid' | 'fetch_aborted' | 'fetch_failed' | 'indexeddb_not_supported' | 'indexeddb_open_failed' | 'indexeddb_request_failed' | 'parse_error' | 'storage_read_failed' | 'storage_unavailable' | 'storage_write_failed';
10
+ interface IconlyError {
11
+ code: IconlyErrorCode;
12
+ message: string;
13
+ cause?: unknown;
14
+ }
15
+ interface Logger {
16
+ debug?: (...messages: unknown[]) => void;
17
+ error?: (...messages: unknown[]) => void;
18
+ }
19
+ interface IconRecord {
20
+ version: string;
21
+ data: string;
22
+ }
23
+ interface IconStorage {
24
+ get(version: string): Promise<Result<IconRecord | undefined>>;
25
+ set(record: IconRecord): Promise<Result<void>>;
26
+ }
27
+ interface IconlyInstance {
28
+ init: () => Promise<Result<void>>;
29
+ abort: () => void;
30
+ }
31
+ type StorageStrategy = 'indexeddb' | 'memory' | 'session' | IconStorage;
32
+ interface IconlyIcon {
33
+ name: string;
34
+ viewBox: string;
35
+ body: string;
36
+ }
37
+ interface SpriteConfig {
38
+ icons: IconlyIcon[];
39
+ container?: string | HTMLElement;
40
+ }
41
+ interface SpriteInstance {
42
+ render: () => Result<void>;
43
+ }
44
+ interface IconlyConfig {
45
+ file?: string;
46
+ version?: string;
47
+ debug?: boolean;
48
+ container?: string | HTMLElement;
49
+ storage?: StorageStrategy;
50
+ dbName?: string;
51
+ storeName?: string;
52
+ sessionKeyPrefix?: string;
53
+ logger?: Logger;
54
+ onError?: (error: IconlyError) => void;
55
+ onDebug?: (...messages: unknown[]) => void;
56
+ }
57
+ //#endregion
58
+ export { IconlyErrorCode as a, Logger as c, SpriteInstance as d, StorageStrategy as f, IconlyError as i, Result as l, IconStorage as n, IconlyIcon as o, IconlyConfig as r, IconlyInstance as s, IconRecord as t, SpriteConfig as u };
59
+ //# sourceMappingURL=types-Byzu8V49.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iconly",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
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",
@@ -32,7 +32,6 @@
32
32
  "pack:check": "npm pack --dry-run && publint && attw --pack . --profile node16",
33
33
  "prepublishOnly": "npm run clean && npm run verify"
34
34
  },
35
- "source": "src/index.ts",
36
35
  "main": "./dist/index.cjs",
37
36
  "module": "./dist/index.js",
38
37
  "types": "./dist/index.d.ts",
@@ -46,6 +45,16 @@
46
45
  "types": "./dist/index.d.cts",
47
46
  "default": "./dist/index.cjs"
48
47
  }
48
+ },
49
+ "./sprite": {
50
+ "import": {
51
+ "types": "./dist/sprite.d.ts",
52
+ "default": "./dist/sprite.js"
53
+ },
54
+ "require": {
55
+ "types": "./dist/sprite.d.cts",
56
+ "default": "./dist/sprite.cjs"
57
+ }
49
58
  }
50
59
  },
51
60
  "files": [