@servlyadmin/runtime-core 0.1.8 → 0.1.10

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
@@ -17,6 +17,7 @@ import {
17
17
  extractDependencies,
18
18
  extractDependenciesFromCode
19
19
  } from "./chunk-CIUQK4GA.js";
20
+ import "./chunk-MCKGQKYU.js";
20
21
 
21
22
  // src/analyticsTypes.ts
22
23
  var DEFAULT_ANALYTICS_CONFIG = {
@@ -2291,6 +2292,316 @@ function resetOverrideSystem() {
2291
2292
  }
2292
2293
  }
2293
2294
 
2295
+ // src/icons.ts
2296
+ var cdnEnabled = false;
2297
+ function setIconCdnEnabled(enabled) {
2298
+ cdnEnabled = enabled;
2299
+ }
2300
+ function isIconCdnEnabled() {
2301
+ return cdnEnabled;
2302
+ }
2303
+ var ICONIFY_COLLECTIONS = {
2304
+ Ai: "ant-design",
2305
+ Bi: "bi",
2306
+ Bs: "bi",
2307
+ Bx: "bx",
2308
+ Ci: "circum",
2309
+ Cg: "gg",
2310
+ Di: "devicon",
2311
+ Fi: "feather",
2312
+ Fc: "flat-color-icons",
2313
+ Fa: "fa-solid",
2314
+ Fa6: "fa6-solid",
2315
+ Gi: "game-icons",
2316
+ Go: "octicon",
2317
+ Gr: "grommet-icons",
2318
+ Hi: "heroicons-outline",
2319
+ Hi2: "heroicons",
2320
+ Im: "icomoon-free",
2321
+ Io: "ion",
2322
+ Io5: "ion",
2323
+ Lu: "lucide",
2324
+ Md: "ic",
2325
+ Pi: "ph",
2326
+ Ri: "ri",
2327
+ Rx: "radix-icons",
2328
+ Si: "simple-icons",
2329
+ Sl: "simple-line-icons",
2330
+ Tb: "tabler",
2331
+ Tfi: "themify",
2332
+ Vsc: "codicon",
2333
+ Wi: "wi"
2334
+ };
2335
+ var ICON_SET_STYLES = {
2336
+ Fi: { stroke: true },
2337
+ Lu: { stroke: true },
2338
+ Hi: { stroke: true },
2339
+ Hi2: { stroke: true },
2340
+ Tb: { stroke: true }
2341
+ };
2342
+ var iconCache = /* @__PURE__ */ new Map();
2343
+ var pendingFetches = /* @__PURE__ */ new Map();
2344
+ var registeredIcons = /* @__PURE__ */ new Map();
2345
+ function registerIcon(set, name, data) {
2346
+ const key = `${set}:${name}`;
2347
+ registeredIcons.set(key, data);
2348
+ iconCache.set(key, data);
2349
+ }
2350
+ function registerIcons(icons) {
2351
+ for (const [set, setIcons] of Object.entries(icons)) {
2352
+ for (const [name, data] of Object.entries(setIcons)) {
2353
+ registerIcon(set, name, data);
2354
+ }
2355
+ }
2356
+ }
2357
+ function isIconRegistered(icon) {
2358
+ const key = `${icon.set}:${icon.name}`;
2359
+ return registeredIcons.has(key);
2360
+ }
2361
+ function getRegisteredIconKeys() {
2362
+ return Array.from(registeredIcons.keys());
2363
+ }
2364
+ function toKebabCase(str) {
2365
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
2366
+ }
2367
+ function getIconifyName(name, set) {
2368
+ const prefixLength = set.length;
2369
+ let baseName = name;
2370
+ if (name.startsWith(set)) {
2371
+ baseName = name.slice(prefixLength);
2372
+ }
2373
+ let kebabName = toKebabCase(baseName);
2374
+ switch (set) {
2375
+ case "Md":
2376
+ if (baseName.startsWith("Outline")) {
2377
+ kebabName = toKebabCase(baseName.slice(7)) + "-outline";
2378
+ }
2379
+ kebabName = "baseline-" + kebabName;
2380
+ break;
2381
+ case "Hi2":
2382
+ if (baseName.startsWith("Outline")) {
2383
+ kebabName = toKebabCase(baseName.slice(7));
2384
+ } else if (baseName.startsWith("Solid")) {
2385
+ kebabName = toKebabCase(baseName.slice(5)) + "-solid";
2386
+ }
2387
+ break;
2388
+ case "Io":
2389
+ case "Io5":
2390
+ if (baseName.startsWith("Ios")) {
2391
+ kebabName = toKebabCase(baseName.slice(3));
2392
+ } else if (baseName.startsWith("Md")) {
2393
+ kebabName = toKebabCase(baseName.slice(2));
2394
+ }
2395
+ break;
2396
+ case "Pi":
2397
+ if (baseName.endsWith("Bold")) {
2398
+ kebabName = toKebabCase(baseName.slice(0, -4)) + "-bold";
2399
+ } else if (baseName.endsWith("Fill")) {
2400
+ kebabName = toKebabCase(baseName.slice(0, -4)) + "-fill";
2401
+ } else if (baseName.endsWith("Light")) {
2402
+ kebabName = toKebabCase(baseName.slice(0, -5)) + "-light";
2403
+ } else if (baseName.endsWith("Thin")) {
2404
+ kebabName = toKebabCase(baseName.slice(0, -4)) + "-thin";
2405
+ } else if (baseName.endsWith("Duotone")) {
2406
+ kebabName = toKebabCase(baseName.slice(0, -7)) + "-duotone";
2407
+ }
2408
+ break;
2409
+ }
2410
+ return kebabName;
2411
+ }
2412
+ async function fetchIconFromIconify(set, name) {
2413
+ if (!cdnEnabled) {
2414
+ return null;
2415
+ }
2416
+ const collection = ICONIFY_COLLECTIONS[set];
2417
+ if (!collection) {
2418
+ return null;
2419
+ }
2420
+ const iconName = getIconifyName(name, set);
2421
+ try {
2422
+ const url = `https://api.iconify.design/${collection}/${iconName}.svg`;
2423
+ const response = await fetch(url);
2424
+ if (!response.ok) {
2425
+ const altNames = [
2426
+ iconName.replace(/-outline$/, ""),
2427
+ iconName.replace(/-solid$/, ""),
2428
+ iconName.replace(/-fill$/, ""),
2429
+ iconName.replace(/^baseline-/, "")
2430
+ ].filter((alt) => alt !== iconName);
2431
+ for (const altName of altNames) {
2432
+ const altUrl = `https://api.iconify.design/${collection}/${altName}.svg`;
2433
+ const altResponse = await fetch(altUrl);
2434
+ if (altResponse.ok) {
2435
+ return parseSvgResponse(await altResponse.text());
2436
+ }
2437
+ }
2438
+ return null;
2439
+ }
2440
+ return parseSvgResponse(await response.text());
2441
+ } catch {
2442
+ return null;
2443
+ }
2444
+ }
2445
+ function parseSvgResponse(svgText) {
2446
+ try {
2447
+ const parser = new DOMParser();
2448
+ const doc = parser.parseFromString(svgText, "image/svg+xml");
2449
+ const svg = doc.querySelector("svg");
2450
+ if (!svg) {
2451
+ return null;
2452
+ }
2453
+ const viewBox = svg.getAttribute("viewBox");
2454
+ const width = parseInt(svg.getAttribute("width") || "24", 10);
2455
+ const height = parseInt(svg.getAttribute("height") || "24", 10);
2456
+ const body = svg.innerHTML;
2457
+ return {
2458
+ body,
2459
+ width,
2460
+ height,
2461
+ viewBox: viewBox || `0 0 ${width} ${height}`
2462
+ };
2463
+ } catch {
2464
+ return null;
2465
+ }
2466
+ }
2467
+ async function getIconData(icon) {
2468
+ const key = `${icon.set}:${icon.name}`;
2469
+ if (iconCache.has(key)) {
2470
+ return iconCache.get(key);
2471
+ }
2472
+ if (pendingFetches.has(key)) {
2473
+ return pendingFetches.get(key);
2474
+ }
2475
+ if (!cdnEnabled) {
2476
+ return null;
2477
+ }
2478
+ const fetchPromise = fetchIconFromIconify(icon.set, icon.name);
2479
+ pendingFetches.set(key, fetchPromise);
2480
+ const data = await fetchPromise;
2481
+ pendingFetches.delete(key);
2482
+ if (data) {
2483
+ iconCache.set(key, data);
2484
+ }
2485
+ return data;
2486
+ }
2487
+ function getIconDataSync(icon) {
2488
+ const key = `${icon.set}:${icon.name}`;
2489
+ return iconCache.get(key) || null;
2490
+ }
2491
+ function createIconSVG(icon, data, size = 24, color = "currentColor") {
2492
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2493
+ svg.setAttribute("width", String(size));
2494
+ svg.setAttribute("height", String(size));
2495
+ svg.setAttribute("viewBox", data.viewBox || "0 0 24 24");
2496
+ svg.setAttribute("data-icon-name", icon.name);
2497
+ svg.setAttribute("data-icon-set", icon.set);
2498
+ svg.setAttribute("class", `servly-icon servly-icon-${icon.set.toLowerCase()}`);
2499
+ const style = ICON_SET_STYLES[icon.set];
2500
+ if (style?.stroke) {
2501
+ svg.setAttribute("fill", "none");
2502
+ svg.setAttribute("stroke", color);
2503
+ svg.setAttribute("stroke-width", "2");
2504
+ svg.setAttribute("stroke-linecap", "round");
2505
+ svg.setAttribute("stroke-linejoin", "round");
2506
+ } else {
2507
+ svg.setAttribute("fill", color);
2508
+ }
2509
+ svg.innerHTML = data.body;
2510
+ const paths = svg.querySelectorAll("path, circle, rect, polygon, line, polyline");
2511
+ paths.forEach((el) => {
2512
+ if (!el.getAttribute("fill") || el.getAttribute("fill") === "currentColor") {
2513
+ if (style?.stroke) {
2514
+ el.setAttribute("stroke", color);
2515
+ } else {
2516
+ el.setAttribute("fill", color);
2517
+ }
2518
+ }
2519
+ });
2520
+ return svg;
2521
+ }
2522
+ function createPlaceholderIcon(icon, size = 24, color = "currentColor") {
2523
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2524
+ svg.setAttribute("width", String(size));
2525
+ svg.setAttribute("height", String(size));
2526
+ svg.setAttribute("viewBox", "0 0 24 24");
2527
+ svg.setAttribute("fill", "none");
2528
+ svg.setAttribute("stroke", color);
2529
+ svg.setAttribute("stroke-width", "2");
2530
+ svg.setAttribute("stroke-linecap", "round");
2531
+ svg.setAttribute("stroke-linejoin", "round");
2532
+ svg.setAttribute("data-icon-name", icon.name);
2533
+ svg.setAttribute("data-icon-set", icon.set);
2534
+ svg.setAttribute("data-icon-missing", "true");
2535
+ svg.setAttribute("class", "servly-icon servly-icon-placeholder");
2536
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
2537
+ circle.setAttribute("cx", "12");
2538
+ circle.setAttribute("cy", "12");
2539
+ circle.setAttribute("r", "10");
2540
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
2541
+ path.setAttribute("d", "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3");
2542
+ const dot = document.createElementNS("http://www.w3.org/2000/svg", "line");
2543
+ dot.setAttribute("x1", "12");
2544
+ dot.setAttribute("y1", "17");
2545
+ dot.setAttribute("x2", "12.01");
2546
+ dot.setAttribute("y2", "17");
2547
+ svg.appendChild(circle);
2548
+ svg.appendChild(path);
2549
+ svg.appendChild(dot);
2550
+ return svg;
2551
+ }
2552
+ function renderIcon(container, icon, size = 24, color = "currentColor") {
2553
+ const cachedData = getIconDataSync(icon);
2554
+ if (cachedData) {
2555
+ const svg = createIconSVG(icon, cachedData, size, color);
2556
+ container.innerHTML = "";
2557
+ container.appendChild(svg);
2558
+ return;
2559
+ }
2560
+ if (!cdnEnabled) {
2561
+ const placeholder2 = createPlaceholderIcon(icon, size, color);
2562
+ container.innerHTML = "";
2563
+ container.appendChild(placeholder2);
2564
+ console.warn(
2565
+ `[Icons] Icon not bundled: ${icon.set}:${icon.name}. Use registerIcon() to bundle it, or enable CDN with setIconCdnEnabled(true).`
2566
+ );
2567
+ return;
2568
+ }
2569
+ const placeholder = createPlaceholderIcon(icon, size, color);
2570
+ placeholder.setAttribute("data-icon-loading", "true");
2571
+ placeholder.removeAttribute("data-icon-missing");
2572
+ container.innerHTML = "";
2573
+ container.appendChild(placeholder);
2574
+ getIconData(icon).then((data) => {
2575
+ if (data) {
2576
+ const svg = createIconSVG(icon, data, size, color);
2577
+ container.innerHTML = "";
2578
+ container.appendChild(svg);
2579
+ } else {
2580
+ placeholder.setAttribute("data-icon-missing", "true");
2581
+ placeholder.removeAttribute("data-icon-loading");
2582
+ }
2583
+ });
2584
+ }
2585
+ async function preloadIcons(icons) {
2586
+ await Promise.all(icons.map((icon) => getIconData(icon)));
2587
+ }
2588
+ function clearIconCache() {
2589
+ iconCache.clear();
2590
+ pendingFetches.clear();
2591
+ registeredIcons.forEach((data, key) => {
2592
+ iconCache.set(key, data);
2593
+ });
2594
+ }
2595
+ function isIconSetSupported(set) {
2596
+ return set in ICONIFY_COLLECTIONS;
2597
+ }
2598
+ function getSupportedIconSets() {
2599
+ return Object.keys(ICONIFY_COLLECTIONS);
2600
+ }
2601
+ function getIconifyCollection(set) {
2602
+ return ICONIFY_COLLECTIONS[set];
2603
+ }
2604
+
2294
2605
  // src/renderer.ts
2295
2606
  var COMPONENT_TO_TAG = {
2296
2607
  container: "div",
@@ -2673,6 +2984,9 @@ function renderElement(element, tree, context, eventHandlers, elementStates, sta
2673
2984
  if (element.componentId === "slot") {
2674
2985
  return renderSlotElement(element, tree, context, eventHandlers, elementStates, state, isRootElement);
2675
2986
  }
2987
+ if (element.componentId === "icon") {
2988
+ return renderIconElement(element, context, eventHandlers, elementStates, state, isRootElement);
2989
+ }
2676
2990
  const elementState = createElement(element, context, eventHandlers, isRootElement, state);
2677
2991
  elementStates.set(element.i, elementState);
2678
2992
  const config = element.configuration;
@@ -2690,6 +3004,40 @@ function renderElement(element, tree, context, eventHandlers, elementStates, sta
2690
3004
  }
2691
3005
  return elementState.domElement;
2692
3006
  }
3007
+ function renderIconElement(element, context, eventHandlers, elementStates, state, isRootElement) {
3008
+ const config = element.configuration || {};
3009
+ const icon = config.icon;
3010
+ const iconColor = config.iconColor || "currentColor";
3011
+ const iconSize = config.iconSize || 24;
3012
+ const wrapper = document.createElement("div");
3013
+ wrapper.setAttribute("data-servly-id", element.i);
3014
+ wrapper.className = "pointer-events-none";
3015
+ const styles = buildElementStyles(element, context);
3016
+ applyStyles(wrapper, styles);
3017
+ const className = buildClassName(element, context);
3018
+ if (className) {
3019
+ wrapper.className = `pointer-events-none ${className}`;
3020
+ }
3021
+ if (state.iconRenderer && icon) {
3022
+ const iconElement = state.iconRenderer(icon, iconSize, iconColor, "");
3023
+ if (iconElement) {
3024
+ wrapper.appendChild(iconElement);
3025
+ }
3026
+ } else if (icon) {
3027
+ renderIcon(wrapper, icon, iconSize, iconColor);
3028
+ }
3029
+ const elementState = {
3030
+ element,
3031
+ domElement: wrapper,
3032
+ styles,
3033
+ className: wrapper.className,
3034
+ textContent: "",
3035
+ eventListeners: /* @__PURE__ */ new Map()
3036
+ };
3037
+ elementStates.set(element.i, elementState);
3038
+ attachEventHandlers(wrapper, element, eventHandlers, context, elementState, isRootElement, state);
3039
+ return wrapper;
3040
+ }
2693
3041
  function renderComponentViewElement(element, tree, context, eventHandlers, elementStates, state, isRootElement) {
2694
3042
  const componentViewId = `${element.componentId}-${element.i}`;
2695
3043
  if (globalRenderingStack.has(componentViewId)) {
@@ -2709,7 +3057,15 @@ function renderComponentViewElement(element, tree, context, eventHandlers, eleme
2709
3057
  viewLayout = component.layout;
2710
3058
  }
2711
3059
  }
3060
+ if (!viewLayout && state.views === void 0 && state.viewsArray) {
3061
+ const viewsArray = state.viewsArray;
3062
+ const found = viewsArray.find((v) => v.id === element.componentId);
3063
+ if (found) {
3064
+ viewLayout = found.layout;
3065
+ }
3066
+ }
2712
3067
  if (!viewLayout) {
3068
+ console.warn(`[Servly] Component not found: ${element.componentId}. Available in views: ${state.views ? Array.from(state.views.keys()).join(", ") : "none"}. Registry has: ${state.componentRegistry?.has(element.componentId) ? "yes" : "no"}`);
2713
3069
  const placeholder = document.createElement("div");
2714
3070
  placeholder.className = "border-2 border-yellow-500 border-dashed p-4 bg-yellow-50";
2715
3071
  placeholder.innerHTML = `<p class="text-yellow-600 text-sm">Component not found: ${element.componentId}</p>`;
@@ -2823,14 +3179,26 @@ function render(options) {
2823
3179
  eventHandlers,
2824
3180
  componentRegistry,
2825
3181
  onDependencyNeeded,
2826
- views,
3182
+ views: viewsInput,
2827
3183
  enableStateManager,
2828
3184
  initialState,
2829
3185
  onStateChange,
2830
3186
  pluginExecutors,
2831
3187
  onNavigate,
2832
- onApiCall
3188
+ onApiCall,
3189
+ iconRenderer
2833
3190
  } = options;
3191
+ let views;
3192
+ if (viewsInput instanceof Map) {
3193
+ views = viewsInput;
3194
+ } else if (Array.isArray(viewsInput)) {
3195
+ views = /* @__PURE__ */ new Map();
3196
+ for (const view of viewsInput) {
3197
+ if (view && view.id) {
3198
+ views.set(view.id, view);
3199
+ }
3200
+ }
3201
+ }
2834
3202
  const startTime = performance.now();
2835
3203
  const memorySampler = getMemorySampler();
2836
3204
  const longTaskObserver = getLongTaskObserver();
@@ -2878,7 +3246,8 @@ function render(options) {
2878
3246
  eventSystem,
2879
3247
  stateManager,
2880
3248
  overrideSystem,
2881
- enableOverrides: hasAnyOverrides
3249
+ enableOverrides: hasAnyOverrides,
3250
+ iconRenderer
2882
3251
  };
2883
3252
  container.innerHTML = "";
2884
3253
  if (rootElements.length === 0) {
@@ -3155,7 +3524,7 @@ async function createServlyRenderer(options) {
3155
3524
  container = containerOption;
3156
3525
  }
3157
3526
  if (shouldInjectTailwind) {
3158
- const { initServlyTailwind: initServlyTailwind2 } = await import("./tailwind-CGAHPC3O.js");
3527
+ const { initServlyTailwind: initServlyTailwind2 } = await import("./tailwind-3FTT56ZG.js");
3159
3528
  await initServlyTailwind2(tailwindConfig);
3160
3529
  }
3161
3530
  const activeRenders = [];
@@ -3525,17 +3894,33 @@ function calculateBackoffDelay(retryCount, config) {
3525
3894
  function sleep(ms) {
3526
3895
  return new Promise((resolve) => setTimeout(resolve, ms));
3527
3896
  }
3528
- function buildViewsMap(views) {
3529
- if (!views || views.length === 0) return void 0;
3897
+ function buildViewsMap(views, bundle) {
3530
3898
  const viewsMap = /* @__PURE__ */ new Map();
3531
- for (const view of views) {
3532
- viewsMap.set(view.id, {
3533
- id: view.id,
3534
- layout: view.layout,
3535
- props: view.props
3536
- });
3899
+ if (views && views.length > 0) {
3900
+ for (const view of views) {
3901
+ if (view && view.id) {
3902
+ viewsMap.set(view.id, {
3903
+ id: view.id,
3904
+ layout: view.layout,
3905
+ props: view.props
3906
+ });
3907
+ }
3908
+ }
3537
3909
  }
3538
- return viewsMap;
3910
+ if (bundle) {
3911
+ for (const [key, component] of Object.entries(bundle)) {
3912
+ const atIndex = key.lastIndexOf("@");
3913
+ const viewId = atIndex > 0 ? key.substring(0, atIndex) : key;
3914
+ if (!viewsMap.has(viewId) && component && component.layout) {
3915
+ viewsMap.set(viewId, {
3916
+ id: viewId,
3917
+ layout: component.layout,
3918
+ props: void 0
3919
+ });
3920
+ }
3921
+ }
3922
+ }
3923
+ return viewsMap.size > 0 ? viewsMap : void 0;
3539
3924
  }
3540
3925
  async function resolveVersionFromApi(id, specifier, apiKey) {
3541
3926
  if (/^\d+\.\d+\.\d+$/.test(specifier)) {
@@ -3637,7 +4022,7 @@ async function fetchComponent(id, options = {}) {
3637
4022
  if (cached.bundle) {
3638
4023
  registry = buildRegistryFromBundle(cached);
3639
4024
  }
3640
- const views = buildViewsMap(cached.views);
4025
+ const views = buildViewsMap(cached.views, cached.bundle);
3641
4026
  const duration = performance.now() - startTime;
3642
4027
  analytics.trackFetch(id, cached.version, duration, true, {
3643
4028
  cacheHit: true,
@@ -3660,7 +4045,7 @@ async function fetchComponent(id, options = {}) {
3660
4045
  if (cached.bundle) {
3661
4046
  registry = buildRegistryFromBundle(cached);
3662
4047
  }
3663
- const views = buildViewsMap(cached.views);
4048
+ const views = buildViewsMap(cached.views, cached.bundle);
3664
4049
  return {
3665
4050
  data: cached,
3666
4051
  fromCache: true,
@@ -3692,7 +4077,7 @@ async function fetchComponent(id, options = {}) {
3692
4077
  version: entry.resolved || entry.version
3693
4078
  }));
3694
4079
  }
3695
- const views = buildViewsMap(data.views);
4080
+ const views = buildViewsMap(data.views, data.bundle);
3696
4081
  const duration = performance.now() - startTime;
3697
4082
  analytics.trackFetch(id, resolvedVersion, duration, false, {
3698
4083
  cacheHit: false,
@@ -3727,7 +4112,7 @@ async function fetchComponent(id, options = {}) {
3727
4112
  async function fetchComponentWithDependencies(id, options = {}) {
3728
4113
  const result = await fetchComponent(id, { ...options, includeBundle: true });
3729
4114
  if (result.pendingDependencies && result.pendingDependencies.length > 0) {
3730
- const { createRegistry: createRegistry2 } = await import("./registry-GCCVK65D.js");
4115
+ const { createRegistry: createRegistry2 } = await import("./registry-7UL42655.js");
3731
4116
  const registry = result.registry || createRegistry2();
3732
4117
  await Promise.all(
3733
4118
  result.pendingDependencies.map(async (dep) => {
@@ -4199,6 +4584,142 @@ function getSampleValue(def) {
4199
4584
  return def.defaultValue;
4200
4585
  }
4201
4586
  }
4587
+
4588
+ // src/iconExtractor.ts
4589
+ var REACT_ICONS_PACKAGES = {
4590
+ Ai: "react-icons/ai",
4591
+ Bi: "react-icons/bi",
4592
+ Bs: "react-icons/bs",
4593
+ Cg: "react-icons/cg",
4594
+ Di: "react-icons/di",
4595
+ Fa: "react-icons/fa",
4596
+ Fa6: "react-icons/fa6",
4597
+ Fc: "react-icons/fc",
4598
+ Fi: "react-icons/fi",
4599
+ Gi: "react-icons/gi",
4600
+ Go: "react-icons/go",
4601
+ Gr: "react-icons/gr",
4602
+ Hi: "react-icons/hi",
4603
+ Hi2: "react-icons/hi2",
4604
+ Im: "react-icons/im",
4605
+ Io: "react-icons/io",
4606
+ Io5: "react-icons/io5",
4607
+ Lu: "react-icons/lu",
4608
+ Md: "react-icons/md",
4609
+ Pi: "react-icons/pi",
4610
+ Ri: "react-icons/ri",
4611
+ Rx: "react-icons/rx",
4612
+ Si: "react-icons/si",
4613
+ Sl: "react-icons/sl",
4614
+ Tb: "react-icons/tb",
4615
+ Tfi: "react-icons/tfi",
4616
+ Vsc: "react-icons/vsc",
4617
+ Wi: "react-icons/wi"
4618
+ };
4619
+ async function extractIconFromReactIcons(iconName, iconSet) {
4620
+ const packagePath = REACT_ICONS_PACKAGES[iconSet];
4621
+ if (!packagePath) {
4622
+ console.warn(`Unknown icon set: ${iconSet}`);
4623
+ return null;
4624
+ }
4625
+ try {
4626
+ const iconModule = await import(packagePath);
4627
+ const IconComponent = iconModule[iconName];
4628
+ if (!IconComponent) {
4629
+ console.warn(`Icon not found: ${iconName} in ${packagePath}`);
4630
+ return null;
4631
+ }
4632
+ const React = await import("./react-EKMBDYIU.js");
4633
+ const { renderToStaticMarkup } = await import("./server.node-CQL3CG75.js");
4634
+ const svgString = renderToStaticMarkup(React.createElement(IconComponent, { size: 24 }));
4635
+ return parseSvgString(svgString);
4636
+ } catch (error) {
4637
+ console.error(`Failed to extract icon ${iconSet}:${iconName}:`, error);
4638
+ return null;
4639
+ }
4640
+ }
4641
+ function parseSvgString(svgString) {
4642
+ const viewBoxMatch = svgString.match(/viewBox="([^"]+)"/);
4643
+ const viewBox = viewBoxMatch ? viewBoxMatch[1] : "0 0 24 24";
4644
+ const widthMatch = svgString.match(/width="(\d+)"/);
4645
+ const heightMatch = svgString.match(/height="(\d+)"/);
4646
+ const width = widthMatch ? parseInt(widthMatch[1], 10) : 24;
4647
+ const height = heightMatch ? parseInt(heightMatch[1], 10) : 24;
4648
+ const bodyMatch = svgString.match(/<svg[^>]*>([\s\S]*)<\/svg>/);
4649
+ const body = bodyMatch ? bodyMatch[1].trim() : "";
4650
+ if (!body) {
4651
+ return null;
4652
+ }
4653
+ return {
4654
+ body,
4655
+ viewBox,
4656
+ width,
4657
+ height
4658
+ };
4659
+ }
4660
+ function findIconsInLayout(elements) {
4661
+ const icons = [];
4662
+ const seen = /* @__PURE__ */ new Set();
4663
+ for (const element of elements) {
4664
+ if (element.componentId === "icon" && element.configuration?.icon) {
4665
+ const icon = element.configuration.icon;
4666
+ const key = `${icon.set}:${icon.name}`;
4667
+ if (!seen.has(key)) {
4668
+ seen.add(key);
4669
+ icons.push({
4670
+ name: icon.name,
4671
+ set: icon.set,
4672
+ setName: icon.setName
4673
+ });
4674
+ }
4675
+ }
4676
+ }
4677
+ return icons;
4678
+ }
4679
+ async function extractIconsForLayout(elements) {
4680
+ const icons = findIconsInLayout(elements);
4681
+ const result = {};
4682
+ for (const icon of icons) {
4683
+ const data = await extractIconFromReactIcons(icon.name, icon.set);
4684
+ if (data) {
4685
+ if (!result[icon.set]) {
4686
+ result[icon.set] = {};
4687
+ }
4688
+ result[icon.set][icon.name] = data;
4689
+ }
4690
+ }
4691
+ return result;
4692
+ }
4693
+ function generateIconBundle(icons) {
4694
+ const lines = [
4695
+ "// Auto-generated icon bundle",
4696
+ "// Do not edit manually",
4697
+ "",
4698
+ "import { registerIcons, type IconData } from '@servlyadmin/runtime-core';",
4699
+ "",
4700
+ "const BUNDLED_ICONS: Record<string, Record<string, IconData>> = {"
4701
+ ];
4702
+ for (const [set, setIcons] of Object.entries(icons)) {
4703
+ lines.push(` ${set}: {`);
4704
+ for (const [name, data] of Object.entries(setIcons)) {
4705
+ const escapedBody = data.body.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n");
4706
+ lines.push(` ${name}: {`);
4707
+ lines.push(` body: '${escapedBody}',`);
4708
+ lines.push(` viewBox: '${data.viewBox}',`);
4709
+ if (data.width) lines.push(` width: ${data.width},`);
4710
+ if (data.height) lines.push(` height: ${data.height},`);
4711
+ lines.push(` },`);
4712
+ }
4713
+ lines.push(` },`);
4714
+ }
4715
+ lines.push("};");
4716
+ lines.push("");
4717
+ lines.push("// Register all bundled icons");
4718
+ lines.push("registerIcons(BUNDLED_ICONS);");
4719
+ lines.push("");
4720
+ lines.push("export { BUNDLED_ICONS };");
4721
+ return lines.join("\n");
4722
+ }
4202
4723
  export {
4203
4724
  AnalyticsCollector,
4204
4725
  DEFAULT_CACHE_CONFIG,
@@ -4222,6 +4743,7 @@ export {
4222
4743
  bumpVersion,
4223
4744
  camelToKebab,
4224
4745
  clearAllCaches,
4746
+ clearIconCache,
4225
4747
  clearLocalStorageCache,
4226
4748
  clearMemoryCache,
4227
4749
  clearStyles,
@@ -4229,6 +4751,8 @@ export {
4229
4751
  collectAllViewDependencies,
4230
4752
  compareVersions,
4231
4753
  configureAnalytics,
4754
+ createIconSVG,
4755
+ createPlaceholderIcon,
4232
4756
  createRegistry,
4233
4757
  createServlyRenderer,
4234
4758
  createViewsMap,
@@ -4238,12 +4762,16 @@ export {
4238
4762
  extractBindingKeys,
4239
4763
  extractDependencies,
4240
4764
  extractDependenciesFromCode,
4765
+ extractIconFromReactIcons,
4766
+ extractIconsForLayout,
4241
4767
  extractOverrideDependencies,
4242
4768
  extractReferencedViewIds,
4243
4769
  fetchComponent,
4244
4770
  fetchComponentWithDependencies,
4771
+ findIconsInLayout,
4245
4772
  formatStyleValue,
4246
4773
  formatVersion,
4774
+ generateIconBundle,
4247
4775
  generateTestCases,
4248
4776
  getAnalytics,
4249
4777
  getCacheKey,
@@ -4251,15 +4779,20 @@ export {
4251
4779
  getDependencyTree,
4252
4780
  getEventSystem,
4253
4781
  getFromCache,
4782
+ getIconData,
4783
+ getIconDataSync,
4784
+ getIconifyCollection,
4254
4785
  getLocalStorage,
4255
4786
  getLongTaskObserver,
4256
4787
  getMemoryCacheSize,
4257
4788
  getMemorySampler,
4258
4789
  getMountOverrides,
4259
4790
  getOverrideSystem,
4791
+ getRegisteredIconKeys,
4260
4792
  getRegistryUrl,
4261
4793
  getSessionManager,
4262
4794
  getSessionStorage,
4795
+ getSupportedIconSets,
4263
4796
  getTailwind,
4264
4797
  getUrlInfo,
4265
4798
  getValueByPath,
@@ -4273,12 +4806,18 @@ export {
4273
4806
  injectTailwind,
4274
4807
  invalidateCache,
4275
4808
  isComponentAvailable,
4809
+ isIconCdnEnabled,
4810
+ isIconRegistered,
4811
+ isIconSetSupported,
4276
4812
  isTailwindLoaded,
4277
4813
  isValidSpecifier,
4278
4814
  navigateTo,
4279
4815
  parseVersion,
4280
4816
  prefetchComponents,
4817
+ preloadIcons,
4281
4818
  processStyles,
4819
+ registerIcon,
4820
+ registerIcons,
4282
4821
  removeClass,
4283
4822
  removeCustomStyles,
4284
4823
  removeLocalStorage,
@@ -4286,6 +4825,7 @@ export {
4286
4825
  removeTailwind,
4287
4826
  render,
4288
4827
  renderDynamicList,
4828
+ renderIcon,
4289
4829
  renderInShadow,
4290
4830
  renderNode,
4291
4831
  resetAnalytics,
@@ -4302,6 +4842,7 @@ export {
4302
4842
  runAllTests,
4303
4843
  runTestCase,
4304
4844
  satisfiesVersion,
4845
+ setIconCdnEnabled,
4305
4846
  setInCache,
4306
4847
  setLocalStorage,
4307
4848
  setRegistryUrl,