viconic-react-icons 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2003,20 +2003,39 @@ var import_react = __toESM(require("react"));
2003
2003
  }
2004
2004
  })();
2005
2005
  var _initializedKits = /* @__PURE__ */ new Set();
2006
+ var _kitRegistry = {};
2007
+ var _pendingMisses = {};
2008
+ if (typeof document !== "undefined") {
2009
+ document.addEventListener("viconic:ready", (e) => {
2010
+ const prefix = e && e.detail && e.detail.prefix;
2011
+ if (prefix) _flushPendingMisses(prefix);
2012
+ });
2013
+ }
2006
2014
  var _kitMissQueues = {};
2007
2015
  var _kitMissTimers = {};
2008
- function _queueKitMiss(prefix, iconBaseName) {
2009
- if (typeof window === "undefined") return;
2016
+ function _resolveRegistry(prefix) {
2017
+ if (_kitRegistry[prefix]) return _kitRegistry[prefix];
2010
2018
  const kits = window.CopyIconsKit || {};
2011
- let kitId = null;
2012
2019
  for (const kId in kits) {
2013
2020
  const kit = kits[kId];
2014
2021
  if (kit.config && kit.config.prefix === prefix) {
2015
- kitId = kId;
2016
- break;
2022
+ const entry = { kitId: kId, api: kit.config.api || "https://api.viconic.dev" };
2023
+ _kitRegistry[prefix] = entry;
2024
+ return entry;
2017
2025
  }
2018
2026
  }
2019
- if (!kitId) return;
2027
+ return null;
2028
+ }
2029
+ function _flushPendingMisses(prefix) {
2030
+ const pending = _pendingMisses[prefix];
2031
+ if (!pending || !pending.size) return;
2032
+ const entry = _resolveRegistry(prefix);
2033
+ if (!entry) return;
2034
+ delete _pendingMisses[prefix];
2035
+ pending.forEach((name) => _dispatchBatchFetch(prefix, name, entry));
2036
+ }
2037
+ function _dispatchBatchFetch(prefix, iconBaseName, entry) {
2038
+ const { kitId, api } = entry;
2020
2039
  if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
2021
2040
  _kitMissQueues[kitId].add(iconBaseName);
2022
2041
  if (_kitMissTimers[kitId]) return;
@@ -2025,34 +2044,40 @@ function _queueKitMiss(prefix, iconBaseName) {
2025
2044
  const names = [..._kitMissQueues[kitId] || []];
2026
2045
  delete _kitMissQueues[kitId];
2027
2046
  if (!names.length) return;
2028
- const kit = (window.CopyIconsKit || {})[kitId];
2029
- if (!kit || !kit.config) return;
2030
- const api = kit.config.api || "https://api.viconic.dev";
2031
2047
  fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
2032
2048
  if (!bj || !bj.icons) return;
2033
2049
  const W = window.__viconic = window.__viconic || {};
2034
2050
  W.icons = W.icons || {};
2035
- const pfx = kit.config.prefix;
2036
2051
  for (const n in bj.icons) {
2037
2052
  if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
2038
2053
  const d = bj.icons[n];
2039
2054
  const svg = d.svg || "";
2040
2055
  if (!svg || !svg.includes("<")) continue;
2041
- W.icons[`@${pfx}/${n}`] = svg;
2042
- W.icons[`${pfx}:${n}`] = svg;
2043
- W.icons[`${pfx}/${n}`] = svg;
2056
+ W.icons[`@${prefix}/${n}`] = svg;
2057
+ W.icons[`${prefix}:${n}`] = svg;
2058
+ W.icons[`${prefix}/${n}`] = svg;
2044
2059
  W.icons[n] = W.icons[n] || svg;
2045
2060
  }
2046
2061
  try {
2047
- document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix: pfx, kitId } }));
2062
+ document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix, kitId } }));
2048
2063
  } catch (e) {
2049
2064
  }
2050
2065
  }).catch(() => {
2051
2066
  });
2052
2067
  }, 0);
2053
2068
  }
2069
+ function _queueKitMiss(prefix, iconBaseName) {
2070
+ if (typeof window === "undefined") return;
2071
+ const entry = _resolveRegistry(prefix);
2072
+ if (entry) {
2073
+ _dispatchBatchFetch(prefix, iconBaseName, entry);
2074
+ } else {
2075
+ if (!_pendingMisses[prefix]) _pendingMisses[prefix] = /* @__PURE__ */ new Set();
2076
+ _pendingMisses[prefix].add(iconBaseName);
2077
+ }
2078
+ }
2054
2079
  function initViconic(options = {}) {
2055
- const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
2080
+ const { kitId, cdnBase = "cdn.viconic.dev", version, prefix: explicitPrefix, api = "https://api.viconic.dev" } = options;
2056
2081
  if (typeof window === "undefined") return;
2057
2082
  if (!kitId) {
2058
2083
  console.warn("[Viconic] initViconic requires a kitId");
@@ -2060,6 +2085,13 @@ function initViconic(options = {}) {
2060
2085
  }
2061
2086
  if (_initializedKits.has(kitId)) return;
2062
2087
  _initializedKits.add(kitId);
2088
+ if (explicitPrefix) {
2089
+ _kitRegistry[explicitPrefix] = { kitId, api };
2090
+ }
2091
+ if (typeof window !== "undefined") {
2092
+ window.__viconicKitIds = window.__viconicKitIds || {};
2093
+ window.__viconicKitIds[kitId] = { api };
2094
+ }
2063
2095
  const scriptId = `viconic-kit-${kitId}`;
2064
2096
  if (document.getElementById(scriptId)) return;
2065
2097
  const script = document.createElement("script");
@@ -2069,6 +2101,15 @@ function initViconic(options = {}) {
2069
2101
  const vQuery = version === "dev" ? Date.now() : version;
2070
2102
  url += `?v=${vQuery}`;
2071
2103
  }
2104
+ script.onload = () => {
2105
+ const kits = window.CopyIconsKit || {};
2106
+ const kit = kits[kitId];
2107
+ if (kit && kit.config && kit.config.prefix) {
2108
+ const pfx = kit.config.prefix;
2109
+ _kitRegistry[pfx] = { kitId, api: kit.config.api || api };
2110
+ _flushPendingMisses(pfx);
2111
+ }
2112
+ };
2072
2113
  script.src = url;
2073
2114
  script.async = true;
2074
2115
  document.head.appendChild(script);
package/dist/index.mjs CHANGED
@@ -1968,20 +1968,39 @@ import React, { useEffect, useRef } from "react";
1968
1968
  }
1969
1969
  })();
1970
1970
  var _initializedKits = /* @__PURE__ */ new Set();
1971
+ var _kitRegistry = {};
1972
+ var _pendingMisses = {};
1973
+ if (typeof document !== "undefined") {
1974
+ document.addEventListener("viconic:ready", (e) => {
1975
+ const prefix = e && e.detail && e.detail.prefix;
1976
+ if (prefix) _flushPendingMisses(prefix);
1977
+ });
1978
+ }
1971
1979
  var _kitMissQueues = {};
1972
1980
  var _kitMissTimers = {};
1973
- function _queueKitMiss(prefix, iconBaseName) {
1974
- if (typeof window === "undefined") return;
1981
+ function _resolveRegistry(prefix) {
1982
+ if (_kitRegistry[prefix]) return _kitRegistry[prefix];
1975
1983
  const kits = window.CopyIconsKit || {};
1976
- let kitId = null;
1977
1984
  for (const kId in kits) {
1978
1985
  const kit = kits[kId];
1979
1986
  if (kit.config && kit.config.prefix === prefix) {
1980
- kitId = kId;
1981
- break;
1987
+ const entry = { kitId: kId, api: kit.config.api || "https://api.viconic.dev" };
1988
+ _kitRegistry[prefix] = entry;
1989
+ return entry;
1982
1990
  }
1983
1991
  }
1984
- if (!kitId) return;
1992
+ return null;
1993
+ }
1994
+ function _flushPendingMisses(prefix) {
1995
+ const pending = _pendingMisses[prefix];
1996
+ if (!pending || !pending.size) return;
1997
+ const entry = _resolveRegistry(prefix);
1998
+ if (!entry) return;
1999
+ delete _pendingMisses[prefix];
2000
+ pending.forEach((name) => _dispatchBatchFetch(prefix, name, entry));
2001
+ }
2002
+ function _dispatchBatchFetch(prefix, iconBaseName, entry) {
2003
+ const { kitId, api } = entry;
1985
2004
  if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
1986
2005
  _kitMissQueues[kitId].add(iconBaseName);
1987
2006
  if (_kitMissTimers[kitId]) return;
@@ -1990,34 +2009,40 @@ function _queueKitMiss(prefix, iconBaseName) {
1990
2009
  const names = [..._kitMissQueues[kitId] || []];
1991
2010
  delete _kitMissQueues[kitId];
1992
2011
  if (!names.length) return;
1993
- const kit = (window.CopyIconsKit || {})[kitId];
1994
- if (!kit || !kit.config) return;
1995
- const api = kit.config.api || "https://api.viconic.dev";
1996
2012
  fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
1997
2013
  if (!bj || !bj.icons) return;
1998
2014
  const W = window.__viconic = window.__viconic || {};
1999
2015
  W.icons = W.icons || {};
2000
- const pfx = kit.config.prefix;
2001
2016
  for (const n in bj.icons) {
2002
2017
  if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
2003
2018
  const d = bj.icons[n];
2004
2019
  const svg = d.svg || "";
2005
2020
  if (!svg || !svg.includes("<")) continue;
2006
- W.icons[`@${pfx}/${n}`] = svg;
2007
- W.icons[`${pfx}:${n}`] = svg;
2008
- W.icons[`${pfx}/${n}`] = svg;
2021
+ W.icons[`@${prefix}/${n}`] = svg;
2022
+ W.icons[`${prefix}:${n}`] = svg;
2023
+ W.icons[`${prefix}/${n}`] = svg;
2009
2024
  W.icons[n] = W.icons[n] || svg;
2010
2025
  }
2011
2026
  try {
2012
- document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix: pfx, kitId } }));
2027
+ document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix, kitId } }));
2013
2028
  } catch (e) {
2014
2029
  }
2015
2030
  }).catch(() => {
2016
2031
  });
2017
2032
  }, 0);
2018
2033
  }
2034
+ function _queueKitMiss(prefix, iconBaseName) {
2035
+ if (typeof window === "undefined") return;
2036
+ const entry = _resolveRegistry(prefix);
2037
+ if (entry) {
2038
+ _dispatchBatchFetch(prefix, iconBaseName, entry);
2039
+ } else {
2040
+ if (!_pendingMisses[prefix]) _pendingMisses[prefix] = /* @__PURE__ */ new Set();
2041
+ _pendingMisses[prefix].add(iconBaseName);
2042
+ }
2043
+ }
2019
2044
  function initViconic(options = {}) {
2020
- const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
2045
+ const { kitId, cdnBase = "cdn.viconic.dev", version, prefix: explicitPrefix, api = "https://api.viconic.dev" } = options;
2021
2046
  if (typeof window === "undefined") return;
2022
2047
  if (!kitId) {
2023
2048
  console.warn("[Viconic] initViconic requires a kitId");
@@ -2025,6 +2050,13 @@ function initViconic(options = {}) {
2025
2050
  }
2026
2051
  if (_initializedKits.has(kitId)) return;
2027
2052
  _initializedKits.add(kitId);
2053
+ if (explicitPrefix) {
2054
+ _kitRegistry[explicitPrefix] = { kitId, api };
2055
+ }
2056
+ if (typeof window !== "undefined") {
2057
+ window.__viconicKitIds = window.__viconicKitIds || {};
2058
+ window.__viconicKitIds[kitId] = { api };
2059
+ }
2028
2060
  const scriptId = `viconic-kit-${kitId}`;
2029
2061
  if (document.getElementById(scriptId)) return;
2030
2062
  const script = document.createElement("script");
@@ -2034,6 +2066,15 @@ function initViconic(options = {}) {
2034
2066
  const vQuery = version === "dev" ? Date.now() : version;
2035
2067
  url += `?v=${vQuery}`;
2036
2068
  }
2069
+ script.onload = () => {
2070
+ const kits = window.CopyIconsKit || {};
2071
+ const kit = kits[kitId];
2072
+ if (kit && kit.config && kit.config.prefix) {
2073
+ const pfx = kit.config.prefix;
2074
+ _kitRegistry[pfx] = { kitId, api: kit.config.api || api };
2075
+ _flushPendingMisses(pfx);
2076
+ }
2077
+ };
2037
2078
  script.src = url;
2038
2079
  script.async = true;
2039
2080
  document.head.appendChild(script);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viconic-react-icons",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Viconic Smart Icons loader for React — supports Kit and 200k+ system icons",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/index.jsx CHANGED
@@ -36,58 +36,99 @@ import './copyicons-smart-loader.js';
36
36
  // ============================================
37
37
  const _initializedKits = new Set();
38
38
 
39
+ // ============================================
40
+ // Kit registry: prefix -> { kitId, api }
41
+ // Populated by initViconic() via script.onload
42
+ // and by viconic:ready event handler.
43
+ // ============================================
44
+ const _kitRegistry = {}; // prefix -> { kitId, api }
45
+
46
+ // Pending misses buffered before registry is ready
47
+ // prefix -> Set of icon names
48
+ const _pendingMisses = {};
49
+
50
+ // Global viconic:ready listener — fires when kit loader calls register()
51
+ // This is the main trigger for flushing pending misses when loader.js
52
+ // completes its first batch fetch (which happens after script.onload).
53
+ if (typeof document !== 'undefined') {
54
+ document.addEventListener('viconic:ready', (e) => {
55
+ const prefix = e && e.detail && e.detail.prefix;
56
+ if (prefix) _flushPendingMisses(prefix);
57
+ });
58
+ }
59
+
39
60
  // ============================================
40
61
  // DEBOUNCED BATCH FETCH for missing kit icons
41
- // All ViconicIcon mounts queue their miss here;
42
- // a single setTimeout(0) fires ONE batch request
43
- // per kit instead of N individual kit.reload() calls.
44
62
  // ============================================
45
63
  const _kitMissQueues = {}; // kitId -> Set of icon names
46
64
  const _kitMissTimers = {}; // kitId -> timer handle
47
65
 
48
- function _queueKitMiss(prefix, iconBaseName) {
49
- if (typeof window === 'undefined') return;
50
- // Find kit by prefix
66
+ function _resolveRegistry(prefix) {
67
+ if (_kitRegistry[prefix]) return _kitRegistry[prefix];
68
+ // Fallback: check CopyIconsKit
51
69
  const kits = window.CopyIconsKit || {};
52
- let kitId = null;
53
70
  for (const kId in kits) {
54
71
  const kit = kits[kId];
55
- if (kit.config && kit.config.prefix === prefix) { kitId = kId; break; }
72
+ if (kit.config && kit.config.prefix === prefix) {
73
+ const entry = { kitId: kId, api: kit.config.api || 'https://api.viconic.dev' };
74
+ _kitRegistry[prefix] = entry;
75
+ return entry;
76
+ }
56
77
  }
57
- if (!kitId) return;
78
+ return null;
79
+ }
80
+
81
+ function _flushPendingMisses(prefix) {
82
+ const pending = _pendingMisses[prefix];
83
+ if (!pending || !pending.size) return;
84
+ const entry = _resolveRegistry(prefix);
85
+ if (!entry) return;
86
+ delete _pendingMisses[prefix];
87
+ pending.forEach(name => _dispatchBatchFetch(prefix, name, entry));
88
+ }
89
+
90
+ function _dispatchBatchFetch(prefix, iconBaseName, entry) {
91
+ const { kitId, api } = entry;
58
92
  if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = new Set();
59
93
  _kitMissQueues[kitId].add(iconBaseName);
60
- if (_kitMissTimers[kitId]) return; // already scheduled
94
+ if (_kitMissTimers[kitId]) return;
61
95
  _kitMissTimers[kitId] = setTimeout(() => {
62
96
  delete _kitMissTimers[kitId];
63
97
  const names = [...(_kitMissQueues[kitId] || [])];
64
98
  delete _kitMissQueues[kitId];
65
99
  if (!names.length) return;
66
- const kit = (window.CopyIconsKit || {})[kitId];
67
- if (!kit || !kit.config) return;
68
- const api = kit.config.api || 'https://api.viconic.dev';
69
100
  fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(',')}`)
70
101
  .then(r => r.ok ? r.json() : null)
71
102
  .then(bj => {
72
103
  if (!bj || !bj.icons) return;
73
104
  const W = (window.__viconic = window.__viconic || {});
74
105
  W.icons = W.icons || {};
75
- const pfx = kit.config.prefix;
76
106
  for (const n in bj.icons) {
77
107
  if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
78
108
  const d = bj.icons[n];
79
109
  const svg = d.svg || '';
80
110
  if (!svg || !svg.includes('<')) continue;
81
- W.icons[`@${pfx}/${n}`] = svg;
82
- W.icons[`${pfx}:${n}`] = svg;
83
- W.icons[`${pfx}/${n}`] = svg;
111
+ W.icons[`@${prefix}/${n}`] = svg;
112
+ W.icons[`${prefix}:${n}`] = svg;
113
+ W.icons[`${prefix}/${n}`] = svg;
84
114
  W.icons[n] = W.icons[n] || svg;
85
115
  }
86
- // Fire viconic:ready so all waiting ViconicIcon components inject
87
- try { document.dispatchEvent(new CustomEvent('viconic:ready', { detail: { prefix: pfx, kitId } })); } catch(e) {}
116
+ try { document.dispatchEvent(new CustomEvent('viconic:ready', { detail: { prefix, kitId } })); } catch(e) {}
88
117
  })
89
118
  .catch(() => {});
90
- }, 0); // setTimeout(0): collect ALL icon misses from current render cycle
119
+ }, 0);
120
+ }
121
+
122
+ function _queueKitMiss(prefix, iconBaseName) {
123
+ if (typeof window === 'undefined') return;
124
+ const entry = _resolveRegistry(prefix);
125
+ if (entry) {
126
+ _dispatchBatchFetch(prefix, iconBaseName, entry);
127
+ } else {
128
+ // Registry not ready yet — buffer until loader fires
129
+ if (!_pendingMisses[prefix]) _pendingMisses[prefix] = new Set();
130
+ _pendingMisses[prefix].add(iconBaseName);
131
+ }
91
132
  }
92
133
 
93
134
  /**
@@ -107,7 +148,7 @@ function _queueKitMiss(prefix, iconBaseName) {
107
148
  * initViconic({ kitId: 'another-kit-uuid', version: '1.0' });
108
149
  */
109
150
  export function initViconic(options = {}) {
110
- const { kitId, cdnBase = 'cdn.viconic.dev', version } = options;
151
+ const { kitId, cdnBase = 'cdn.viconic.dev', version, prefix: explicitPrefix, api = 'https://api.viconic.dev' } = options;
111
152
  if (typeof window === 'undefined') return; // SSR guard
112
153
  if (!kitId) {
113
154
  console.warn('[Viconic] initViconic requires a kitId');
@@ -116,6 +157,18 @@ export function initViconic(options = {}) {
116
157
  if (_initializedKits.has(kitId)) return; // Already initialized
117
158
  _initializedKits.add(kitId);
118
159
 
160
+ // Register synchronously so _queueKitMiss can find kitId immediately,
161
+ // even before the async loader.js script has loaded and populated CopyIconsKit.
162
+ // If prefix is not known yet, we'll also register once CopyIconsKit fires.
163
+ if (explicitPrefix) {
164
+ _kitRegistry[explicitPrefix] = { kitId, api };
165
+ }
166
+ // Also register by kitId so we can backfill prefix once loader fires
167
+ if (typeof window !== 'undefined') {
168
+ window.__viconicKitIds = window.__viconicKitIds || {};
169
+ window.__viconicKitIds[kitId] = { api };
170
+ }
171
+
119
172
  const scriptId = `viconic-kit-${kitId}`;
120
173
  if (document.getElementById(scriptId)) return; // Script already in DOM
121
174
 
@@ -129,6 +182,18 @@ export function initViconic(options = {}) {
129
182
  url += `?v=${vQuery}`;
130
183
  }
131
184
 
185
+ // Once loader.js runs and registers CopyIconsKit, backfill _kitRegistry and flush pending misses
186
+ script.onload = () => {
187
+ const kits = window.CopyIconsKit || {};
188
+ const kit = kits[kitId];
189
+ if (kit && kit.config && kit.config.prefix) {
190
+ const pfx = kit.config.prefix;
191
+ _kitRegistry[pfx] = { kitId, api: kit.config.api || api };
192
+ // Flush any misses buffered before the loader was ready
193
+ _flushPendingMisses(pfx);
194
+ }
195
+ };
196
+
132
197
  script.src = url;
133
198
  script.async = true;
134
199
  document.head.appendChild(script);