@jasonshimmy/custom-elements-runtime 3.3.0 → 3.5.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.
Files changed (106) hide show
  1. package/README.md +28 -7
  2. package/dist/css-utils-Bn-dO44e.js +203 -0
  3. package/dist/{css-utils-CC43BbEy.js.map → css-utils-Bn-dO44e.js.map} +1 -1
  4. package/dist/{css-utils-CC43BbEy.js → css-utils-CFeP8SK1.cjs} +5 -71
  5. package/dist/{css-utils-mgjmH8qX.cjs.map → css-utils-CFeP8SK1.cjs.map} +1 -1
  6. package/dist/custom-elements-runtime.cjs.js +3 -4
  7. package/dist/custom-elements-runtime.cjs.js.map +1 -1
  8. package/dist/custom-elements-runtime.colors.cjs.js +1 -2
  9. package/dist/custom-elements-runtime.colors.cjs.js.map +1 -1
  10. package/dist/custom-elements-runtime.colors.es.js +277 -277
  11. package/dist/custom-elements-runtime.colors.es.js.map +1 -1
  12. package/dist/custom-elements-runtime.directive-enhancements.cjs.js +1 -2
  13. package/dist/custom-elements-runtime.directive-enhancements.cjs.js.map +1 -1
  14. package/dist/custom-elements-runtime.directive-enhancements.es.js +106 -122
  15. package/dist/custom-elements-runtime.directive-enhancements.es.js.map +1 -1
  16. package/dist/custom-elements-runtime.directives.cjs.js +1 -2
  17. package/dist/custom-elements-runtime.directives.cjs.js.map +1 -1
  18. package/dist/custom-elements-runtime.directives.es.js +60 -65
  19. package/dist/custom-elements-runtime.directives.es.js.map +1 -1
  20. package/dist/custom-elements-runtime.dom-jit-css.cjs.js +1 -7
  21. package/dist/custom-elements-runtime.dom-jit-css.cjs.js.map +1 -1
  22. package/dist/custom-elements-runtime.dom-jit-css.es.js +103 -115
  23. package/dist/custom-elements-runtime.dom-jit-css.es.js.map +1 -1
  24. package/dist/custom-elements-runtime.es.js +206 -253
  25. package/dist/custom-elements-runtime.es.js.map +1 -1
  26. package/dist/custom-elements-runtime.event-bus.cjs.js +1 -2
  27. package/dist/custom-elements-runtime.event-bus.cjs.js.map +1 -1
  28. package/dist/custom-elements-runtime.event-bus.es.js +102 -108
  29. package/dist/custom-elements-runtime.event-bus.es.js.map +1 -1
  30. package/dist/custom-elements-runtime.jit-css.cjs.js +1 -2
  31. package/dist/custom-elements-runtime.jit-css.cjs.js.map +1 -1
  32. package/dist/custom-elements-runtime.jit-css.es.js +14 -32
  33. package/dist/custom-elements-runtime.jit-css.es.js.map +1 -1
  34. package/dist/custom-elements-runtime.router.cjs.js +20 -21
  35. package/dist/custom-elements-runtime.router.cjs.js.map +1 -1
  36. package/dist/custom-elements-runtime.router.es.js +866 -926
  37. package/dist/custom-elements-runtime.router.es.js.map +1 -1
  38. package/dist/custom-elements-runtime.ssr-middleware.cjs.js +3 -4
  39. package/dist/custom-elements-runtime.ssr-middleware.cjs.js.map +1 -1
  40. package/dist/custom-elements-runtime.ssr-middleware.es.js +67 -73
  41. package/dist/custom-elements-runtime.ssr-middleware.es.js.map +1 -1
  42. package/dist/custom-elements-runtime.ssr.cjs.js +1 -1
  43. package/dist/custom-elements-runtime.ssr.es.js +3 -13
  44. package/dist/custom-elements-runtime.store.cjs.js +1 -2
  45. package/dist/custom-elements-runtime.store.cjs.js.map +1 -1
  46. package/dist/custom-elements-runtime.store.es.js +32 -33
  47. package/dist/custom-elements-runtime.store.es.js.map +1 -1
  48. package/dist/custom-elements-runtime.transitions.cjs.js +1 -2
  49. package/dist/custom-elements-runtime.transitions.cjs.js.map +1 -1
  50. package/dist/custom-elements-runtime.transitions.es.js +200 -210
  51. package/dist/custom-elements-runtime.transitions.es.js.map +1 -1
  52. package/dist/custom-elements-runtime.vite-plugin.cjs.js +4 -2
  53. package/dist/custom-elements-runtime.vite-plugin.cjs.js.map +1 -1
  54. package/dist/custom-elements-runtime.vite-plugin.es.js +155 -78
  55. package/dist/custom-elements-runtime.vite-plugin.es.js.map +1 -1
  56. package/dist/helpers-DcEpRwq5.cjs +5 -0
  57. package/dist/helpers-DcEpRwq5.cjs.map +1 -0
  58. package/dist/helpers-tJgb4Qve.js +693 -0
  59. package/dist/helpers-tJgb4Qve.js.map +1 -0
  60. package/dist/hooks-CEUnvtsA.js +407 -0
  61. package/dist/hooks-CEUnvtsA.js.map +1 -0
  62. package/dist/hooks-CNfugc95.cjs +2 -0
  63. package/dist/hooks-CNfugc95.cjs.map +1 -0
  64. package/dist/logger-DIJ0UH3R.js +36 -0
  65. package/dist/{logger-L25axmB-.js.map → logger-DIJ0UH3R.js.map} +1 -1
  66. package/dist/logger-Dkht1dCX.cjs +2 -0
  67. package/dist/{logger-BYIN7ysT.cjs.map → logger-Dkht1dCX.cjs.map} +1 -1
  68. package/dist/namespace-helpers-CIUkG8Mn.js +56 -0
  69. package/dist/{namespace-helpers-BucDdgz_.js.map → namespace-helpers-CIUkG8Mn.js.map} +1 -1
  70. package/dist/namespace-helpers-yYIb7INq.cjs +2 -0
  71. package/dist/{namespace-helpers-Bf7rm9JV.cjs.map → namespace-helpers-yYIb7INq.cjs.map} +1 -1
  72. package/dist/runtime/tag-utils.d.ts +11 -0
  73. package/dist/ssr-BpYy9XlW.js +170 -0
  74. package/dist/{ssr-B3lxl1vr.js.map → ssr-BpYy9XlW.js.map} +1 -1
  75. package/dist/ssr-CFabTOyi.cjs +4 -0
  76. package/dist/{ssr-DtD9e5iA.cjs.map → ssr-CFabTOyi.cjs.map} +1 -1
  77. package/dist/ssr.d.ts +33 -0
  78. package/dist/style-A8l3aQ52.cjs +55 -0
  79. package/dist/{style-Bjn8zDiZ.cjs.map → style-A8l3aQ52.cjs.map} +1 -1
  80. package/dist/style-DSSoCbC9.js +1877 -0
  81. package/dist/{style-DuDoj_xK.js.map → style-DSSoCbC9.js.map} +1 -1
  82. package/dist/tag-utils-CoSXTr1F.js +10 -0
  83. package/dist/tag-utils-CoSXTr1F.js.map +1 -0
  84. package/dist/tag-utils-XJ3dkcPQ.cjs +2 -0
  85. package/dist/tag-utils-XJ3dkcPQ.cjs.map +1 -0
  86. package/dist/template-compiler-B4B_jAPN.cjs +19 -0
  87. package/dist/{template-compiler-BB4JJdqk.cjs.map → template-compiler-B4B_jAPN.cjs.map} +1 -1
  88. package/dist/template-compiler-C3h8_vbE.js +3044 -0
  89. package/dist/{template-compiler-Cs5axmn4.js.map → template-compiler-C3h8_vbE.js.map} +1 -1
  90. package/dist/vite-plugin.d.ts +96 -2
  91. package/package.json +8 -8
  92. package/dist/css-utils-mgjmH8qX.cjs +0 -577
  93. package/dist/hooks-_3xP4G2N.js +0 -1189
  94. package/dist/hooks-_3xP4G2N.js.map +0 -1
  95. package/dist/hooks-fYQgZk2g.cjs +0 -7
  96. package/dist/hooks-fYQgZk2g.cjs.map +0 -1
  97. package/dist/logger-BYIN7ysT.cjs +0 -3
  98. package/dist/logger-L25axmB-.js +0 -41
  99. package/dist/namespace-helpers-Bf7rm9JV.cjs +0 -3
  100. package/dist/namespace-helpers-BucDdgz_.js +0 -61
  101. package/dist/ssr-B3lxl1vr.js +0 -165
  102. package/dist/ssr-DtD9e5iA.cjs +0 -5
  103. package/dist/style-Bjn8zDiZ.cjs +0 -56
  104. package/dist/style-DuDoj_xK.js +0 -1972
  105. package/dist/template-compiler-BB4JJdqk.cjs +0 -23
  106. package/dist/template-compiler-Cs5axmn4.js +0 -3236
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.vite-plugin.cjs.js","names":[],"sources":["../src/lib/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugins for build-time JIT CSS generation and SSR configuration.\n *\n * Two plugins are exported:\n *\n * - **`cerJITCSS`** — Scans source files for utility class names and emits\n * pre-generated CSS, eliminating all runtime parsing cost for projects with\n * static class lists.\n *\n * - **`cerPlugin`** — All-in-one plugin combining `cerJITCSS` with SSR\n * configuration. Exposes a `virtual:cer-ssr-config` module containing the\n * resolved SSR render options so server entry files can import and use them\n * without duplication.\n *\n * @example cerJITCSS only\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerJITCSS } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerJITCSS({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * output: 'src/generated-jit.css',\n * extendedColors: true,\n * }),\n * ],\n * });\n * ```\n *\n * @example cerPlugin with SSR\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerPlugin } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * ssr: {\n * dsd: true,\n * jit: { extendedColors: true },\n * },\n * }),\n * ],\n * });\n * ```\n *\n * Then in your server entry:\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n\nimport type { Plugin } from 'vite';\nimport { readFileSync, writeFileSync, mkdirSync, globSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport {\n jitCSS,\n enableJITCSS,\n extractClassesFromHTML,\n type JITCSSOptions,\n} from './runtime/style';\n\n// --- Re-export extractClassesFromHTML for plugin consumers ---\n\n/**\n * Options for the `cerJITCSS` Vite plugin.\n */\nexport interface CerJITCSSPluginOptions extends JITCSSOptions {\n /**\n * Glob patterns (relative to `process.cwd()`) that identify which source\n * files the plugin should scan for utility class names.\n *\n * @example `['./src/**\\/*.{ts,html}', './index.html']`\n */\n content: string[];\n /**\n * File path (relative to `process.cwd()`) where the generated CSS will\n * be written. When omitted the plugin only emits a virtual module.\n */\n output?: string;\n /**\n * Whether to emit a virtual module `virtual:cer-jit-css` that resolves to\n * the generated CSS text. Defaults to `true`.\n */\n virtualModule?: boolean;\n}\n\nconst VIRTUAL_ID = 'virtual:cer-jit-css';\nconst RESOLVED_VIRTUAL_ID = '\\0virtual:cer-jit-css';\n\nfunction generateFromFiles(\n contentPatterns: string[],\n jitOptions: JITCSSOptions,\n): string {\n if (jitOptions && Object.keys(jitOptions).length > 0) {\n enableJITCSS(jitOptions);\n }\n\n const cwd = process.cwd();\n const files: string[] = [];\n\n for (const pattern of contentPatterns) {\n const matches = globSync(pattern, { cwd }).map((f) => resolve(cwd, f));\n files.push(...matches);\n }\n\n // Deduplicate files\n const uniqueFiles = [...new Set(files)];\n\n // Aggregate all class names across all files\n const allClasses = new Set<string>();\n\n for (const file of uniqueFiles) {\n try {\n const content = readFileSync(file, 'utf-8');\n const classes = extractClassesFromHTML(content);\n for (const cls of classes) allClasses.add(cls);\n } catch {\n // Skip unreadable files\n }\n }\n\n if (allClasses.size === 0) return '';\n\n // Build a fake HTML string containing all discovered classes so jitCSS()\n // can process the full set in one pass.\n const fakeHTML = `<div class=\"${[...allClasses].join(' ')}\"></div>`;\n return jitCSS(fakeHTML);\n}\n\n// ---------------------------------------------------------------------------\n// cerPlugin — combined JIT CSS + SSR configuration plugin\n// ---------------------------------------------------------------------------\n\n/**\n * SSR render options exposed via `virtual:cer-ssr-config`.\n */\nexport interface CerSSROptions {\n /**\n * Emit Declarative Shadow DOM output for registered custom elements.\n * @default true\n */\n dsd?: boolean;\n /**\n * Append the DSD polyfill `<script>` for browsers without native support.\n * @default true\n */\n dsdPolyfill?: boolean;\n /**\n * JIT CSS options forwarded to the SSR render pass.\n */\n jit?: JITCSSOptions;\n}\n\n/**\n * Options for the combined {@link cerPlugin}.\n */\nexport interface CerPluginOptions extends Partial<CerJITCSSPluginOptions> {\n /**\n * SSR configuration. When provided, a `virtual:cer-ssr-config` module is\n * registered so server entry files can import the resolved render options:\n *\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n ssr?: CerSSROptions;\n}\n\nconst VIRTUAL_SSR_ID = 'virtual:cer-ssr-config';\nconst RESOLVED_VIRTUAL_SSR_ID = '\\0virtual:cer-ssr-config';\n\n/**\n * All-in-one Vite plugin combining build-time JIT CSS generation with SSR\n * configuration. Returns an array of plugins so it can be spread directly\n * into the `plugins` array without nesting.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,html}'],\n * ssr: { dsd: true, jit: { extendedColors: true } },\n * }),\n * ],\n * });\n * ```\n */\nexport function cerPlugin(options: CerPluginOptions): Plugin[] {\n const plugins: Plugin[] = [];\n\n // JIT CSS plugin — only added when a `content` glob is provided\n if (options.content && options.content.length > 0) {\n plugins.push(\n cerJITCSS({\n content: options.content,\n output: options.output,\n virtualModule: options.virtualModule,\n extendedColors: options.extendedColors,\n customColors: options.customColors,\n disableVariants: options.disableVariants,\n }),\n );\n }\n\n // SSR config virtual module — registered whenever `ssr` is provided\n if (options.ssr) {\n const ssrConfig = options.ssr;\n const resolvedConfig = {\n dsd: ssrConfig.dsd ?? true,\n dsdPolyfill: ssrConfig.dsdPolyfill ?? true,\n ...(ssrConfig.jit ? { jit: ssrConfig.jit } : {}),\n };\n\n plugins.push({\n name: 'cer-ssr-config',\n resolveId(id: string) {\n if (id === VIRTUAL_SSR_ID) return RESOLVED_VIRTUAL_SSR_ID;\n return undefined;\n },\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_SSR_ID) {\n return `export default ${JSON.stringify(resolvedConfig)};`;\n }\n return undefined;\n },\n });\n }\n\n return plugins;\n}\n\n// ---------------------------------------------------------------------------\n// cerJITCSS — build-time JIT CSS plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Vite plugin that performs a build-time scan of source files and emits\n * pre-generated JIT CSS as a file and/or `virtual:cer-jit-css` module.\n */\nexport function cerJITCSS(options: CerJITCSSPluginOptions): Plugin {\n const {\n content,\n output,\n virtualModule = true,\n extendedColors,\n customColors,\n disableVariants,\n } = options;\n\n const jitOptions: JITCSSOptions = {\n extendedColors,\n customColors,\n disableVariants,\n };\n\n let generatedCSS = '';\n // Resolved file set built in buildStart and reused in handleHotUpdate to\n // avoid re-running globSync for every HMR file-change event.\n let watchedFiles: Set<string> | null = null;\n\n return {\n name: 'cer-jit-css',\n\n buildStart() {\n const cwd = process.cwd();\n const resolved = new Set<string>();\n for (const pattern of content) {\n globSync(pattern, { cwd }).forEach((f) => resolved.add(resolve(cwd, f)));\n }\n watchedFiles = resolved;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n },\n\n resolveId(id: string) {\n if (virtualModule && id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n return undefined;\n },\n\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return `export default ${JSON.stringify(generatedCSS)};`;\n }\n return undefined;\n },\n\n handleHotUpdate({ file, server }: { file: string; server: unknown }) {\n // Re-generate when a watched source file changes.\n // Use the cached file set from buildStart to avoid re-globbing.\n const isWatched = watchedFiles?.has(file) ?? false;\n\n if (!isWatched) return;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n\n if (virtualModule) {\n // Invalidate the virtual module so HMR triggers a reload\n const viteServer = server as {\n moduleGraph: { getModuleById: (id: string) => unknown };\n reloadModule: (mod: unknown) => void;\n };\n const mod = viteServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) viteServer.reloadModule(mod);\n }\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"custom-elements-runtime.vite-plugin.cjs.js","names":[],"sources":["../src/lib/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugins for build-time JIT CSS generation, SSR configuration, and\n * per-page component code splitting.\n *\n * Three plugins are exported:\n *\n * - **`cerJITCSS`** — Scans source files for utility class names and emits\n * pre-generated CSS, eliminating all runtime parsing cost for projects with\n * static class lists.\n *\n * - **`cerPlugin`** — All-in-one plugin combining `cerJITCSS` with SSR\n * configuration. Exposes a `virtual:cer-ssr-config` module containing the\n * resolved SSR render options so server entry files can import and use them\n * without duplication.\n *\n * - **`cerComponentImports`** — Transform plugin that scans each app file for\n * custom element tags used in `html\\`` template literals and injects static\n * `import` statements pointing to the corresponding component source files.\n * This gives Rollup the module graph edges it needs to automatically\n * code-split components per page chunk.\n *\n * Three build-time utilities are also exported:\n *\n * - **`resolveTagName`** — Normalize a component name to its registered tag name.\n * - **`extractTemplateTagNames`** — Extract hyphenated tag names from `html\\`` sources.\n * - **`extractComponentRegistrations`** — Extract registered tag names from `component()` calls.\n *\n * @example cerJITCSS only\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerJITCSS } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerJITCSS({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * output: 'src/generated-jit.css',\n * extendedColors: true,\n * }),\n * ],\n * });\n * ```\n *\n * @example cerPlugin with SSR\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerPlugin } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * ssr: {\n * dsd: true,\n * jit: { extendedColors: true },\n * },\n * }),\n * ],\n * });\n * ```\n *\n * Then in your server entry:\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n *\n * @example cerComponentImports for per-page code splitting\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerComponentImports } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerComponentImports({\n * componentsDir: '/absolute/path/to/app/components',\n * appRoot: '/absolute/path/to/app',\n * }),\n * ],\n * });\n * ```\n */\n\nimport type { Plugin, ViteDevServer } from 'vite';\nimport { readFileSync, writeFileSync, mkdirSync, globSync, existsSync } from 'node:fs';\nimport { resolve, relative, dirname } from 'node:path';\nimport {\n jitCSS,\n enableJITCSS,\n extractClassesFromHTML,\n type JITCSSOptions,\n} from './runtime/style';\nimport { resolveTagName as _resolveTagName } from './runtime/tag-utils';\n\n// --- Re-export extractClassesFromHTML for plugin consumers ---\n\n/**\n * Options for the `cerJITCSS` Vite plugin.\n */\nexport interface CerJITCSSPluginOptions extends JITCSSOptions {\n /**\n * Glob patterns (relative to `process.cwd()`) that identify which source\n * files the plugin should scan for utility class names.\n *\n * @example `['./src/**\\/*.{ts,html}', './index.html']`\n */\n content: string[];\n /**\n * File path (relative to `process.cwd()`) where the generated CSS will\n * be written. When omitted the plugin only emits a virtual module.\n */\n output?: string;\n /**\n * Whether to emit a virtual module `virtual:cer-jit-css` that resolves to\n * the generated CSS text. Defaults to `true`.\n */\n virtualModule?: boolean;\n}\n\nconst VIRTUAL_ID = 'virtual:cer-jit-css';\nconst RESOLVED_VIRTUAL_ID = '\\0virtual:cer-jit-css';\n\nfunction generateFromFiles(\n contentPatterns: string[],\n jitOptions: JITCSSOptions,\n): string {\n if (jitOptions && Object.keys(jitOptions).length > 0) {\n enableJITCSS(jitOptions);\n }\n\n const cwd = process.cwd();\n const files: string[] = [];\n\n for (const pattern of contentPatterns) {\n const matches = globSync(pattern, { cwd }).map((f) => resolve(cwd, f));\n files.push(...matches);\n }\n\n // Deduplicate files\n const uniqueFiles = [...new Set(files)];\n\n // Aggregate all class names across all files\n const allClasses = new Set<string>();\n\n for (const file of uniqueFiles) {\n try {\n const content = readFileSync(file, 'utf-8');\n const classes = extractClassesFromHTML(content);\n for (const cls of classes) allClasses.add(cls);\n } catch {\n // Skip unreadable files\n }\n }\n\n if (allClasses.size === 0) return '';\n\n // Build a fake HTML string containing all discovered classes so jitCSS()\n // can process the full set in one pass.\n const fakeHTML = `<div class=\"${[...allClasses].join(' ')}\"></div>`;\n return jitCSS(fakeHTML);\n}\n\n// ---------------------------------------------------------------------------\n// cerPlugin — combined JIT CSS + SSR configuration plugin\n// ---------------------------------------------------------------------------\n\n/**\n * SSR render options exposed via `virtual:cer-ssr-config`.\n */\nexport interface CerSSROptions {\n /**\n * Emit Declarative Shadow DOM output for registered custom elements.\n * @default true\n */\n dsd?: boolean;\n /**\n * Append the DSD polyfill `<script>` for browsers without native support.\n * @default true\n */\n dsdPolyfill?: boolean;\n /**\n * JIT CSS options forwarded to the SSR render pass.\n */\n jit?: JITCSSOptions;\n}\n\n/**\n * Options for the combined {@link cerPlugin}.\n */\nexport interface CerPluginOptions extends Partial<CerJITCSSPluginOptions> {\n /**\n * SSR configuration. When provided, a `virtual:cer-ssr-config` module is\n * registered so server entry files can import the resolved render options:\n *\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n ssr?: CerSSROptions;\n}\n\nconst VIRTUAL_SSR_ID = 'virtual:cer-ssr-config';\nconst RESOLVED_VIRTUAL_SSR_ID = '\\0virtual:cer-ssr-config';\n\n/**\n * All-in-one Vite plugin combining build-time JIT CSS generation with SSR\n * configuration. Returns an array of plugins so it can be spread directly\n * into the `plugins` array without nesting.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,html}'],\n * ssr: { dsd: true, jit: { extendedColors: true } },\n * }),\n * ],\n * });\n * ```\n */\nexport function cerPlugin(options: CerPluginOptions): Plugin[] {\n const plugins: Plugin[] = [];\n\n // JIT CSS plugin — only added when a `content` glob is provided\n if (options.content && options.content.length > 0) {\n plugins.push(\n cerJITCSS({\n content: options.content,\n output: options.output,\n virtualModule: options.virtualModule,\n extendedColors: options.extendedColors,\n customColors: options.customColors,\n disableVariants: options.disableVariants,\n }),\n );\n }\n\n // SSR config virtual module — registered whenever `ssr` is provided\n if (options.ssr) {\n const ssrConfig = options.ssr;\n const resolvedConfig = {\n dsd: ssrConfig.dsd ?? true,\n dsdPolyfill: ssrConfig.dsdPolyfill ?? true,\n ...(ssrConfig.jit ? { jit: ssrConfig.jit } : {}),\n };\n\n plugins.push({\n name: 'cer-ssr-config',\n resolveId(id: string) {\n if (id === VIRTUAL_SSR_ID) return RESOLVED_VIRTUAL_SSR_ID;\n return undefined;\n },\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_SSR_ID) {\n return `export default ${JSON.stringify(resolvedConfig)};`;\n }\n return undefined;\n },\n });\n }\n\n return plugins;\n}\n\n// ---------------------------------------------------------------------------\n// cerJITCSS — build-time JIT CSS plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Vite plugin that performs a build-time scan of source files and emits\n * pre-generated JIT CSS as a file and/or `virtual:cer-jit-css` module.\n */\nexport function cerJITCSS(options: CerJITCSSPluginOptions): Plugin {\n const {\n content,\n output,\n virtualModule = true,\n extendedColors,\n customColors,\n disableVariants,\n } = options;\n\n const jitOptions: JITCSSOptions = {\n extendedColors,\n customColors,\n disableVariants,\n };\n\n let generatedCSS = '';\n // Resolved file set built in buildStart and reused in handleHotUpdate to\n // avoid re-running globSync for every HMR file-change event.\n let watchedFiles: Set<string> | null = null;\n\n return {\n name: 'cer-jit-css',\n\n buildStart() {\n const cwd = process.cwd();\n const resolved = new Set<string>();\n for (const pattern of content) {\n globSync(pattern, { cwd }).forEach((f) => resolved.add(resolve(cwd, f)));\n }\n watchedFiles = resolved;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n },\n\n resolveId(id: string) {\n if (virtualModule && id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n return undefined;\n },\n\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return `export default ${JSON.stringify(generatedCSS)};`;\n }\n return undefined;\n },\n\n handleHotUpdate({ file, server }: { file: string; server: unknown }) {\n // Re-generate when a watched source file changes.\n // Use the cached file set from buildStart to avoid re-globbing.\n const isWatched = watchedFiles?.has(file) ?? false;\n\n if (!isWatched) return;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n\n if (virtualModule) {\n // Invalidate the virtual module so HMR triggers a reload\n const viteServer = server as {\n moduleGraph: { getModuleById: (id: string) => unknown };\n reloadModule: (mod: unknown) => void;\n };\n const mod = viteServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) viteServer.reloadModule(mod);\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tag resolution utilities (build-time)\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves a component() tag argument to the actual registered tag name.\n * Re-exported from runtime/tag-utils so consumers have a single import surface.\n *\n * Rules:\n * camelCase → kebab-case (myButton → my-button)\n * no hyphen → cer- prefix (app → cer-app)\n * has hyphen → unchanged (ks-badge → ks-badge)\n */\nexport const resolveTagName = _resolveTagName;\n\n/**\n * Scan TypeScript source text for all custom element tag names referenced\n * in html`` template literals.\n *\n * Strips line (//) and block (/* *\\/) comments first to avoid false\n * positives from commented-out code.\n *\n * Returns a Set of already-hyphenated tag names as they appear in the source\n * (e.g. \"ks-badge\", \"cer-app\"). Single-word names that would receive a\n * \"cer-\" prefix at runtime never appear as bare tags in templates — they\n * always appear as \"cer-something\" — so no normalization is needed here.\n *\n * Closing tags (</ks-badge>) do NOT match because the regex requires the\n * first character after < to be [a-z], not /.\n */\nexport function extractTemplateTagNames(source: string): Set<string> {\n const stripped = source\n .replace(/\\/\\/[^\\n]*/g, '') // line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, ''); // block comments\n\n const tags = new Set<string>();\n // Requires at least one hyphen-segment: matches custom elements only,\n // never native HTML elements like <div> or <span>.\n for (const m of stripped.matchAll(/<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)/g)) {\n tags.add(m[1]);\n }\n return tags;\n}\n\n/**\n * Extract all component tag names registered in a component source file.\n * Handles files that call component() more than once (returns all of them).\n *\n * Uses \\bcomponent\\( so it matches the standalone function name but not\n * names like importComponent( or registerComponent(.\n *\n * Returns resolved (normalized) tag names, ready to match against the output\n * of extractTemplateTagNames().\n */\nexport function extractComponentRegistrations(source: string): string[] {\n const stripped = source\n .replace(/\\/\\/[^\\n]*/g, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n const tags: string[] = [];\n for (const m of stripped.matchAll(/\\bcomponent\\(\\s*['\"`]([^'\"`]+)['\"`]/g)) {\n tags.push(resolveTagName(m[1]));\n }\n return tags;\n}\n\n// ---------------------------------------------------------------------------\n// cerComponentImports — per-page component code splitting plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Options for the {@link cerComponentImports} Vite plugin.\n */\nexport interface CerComponentImportsOptions {\n /**\n * Absolute path to the directory containing component files.\n * Every .ts file found here is scanned for component() registrations.\n */\n componentsDir: string;\n /**\n * Absolute path to the app source root. The transform is restricted to\n * files under this directory so node_modules and generated files are skipped.\n */\n appRoot: string;\n}\n\n/**\n * Vite plugin that injects static `import` statements for custom element\n * components used in each page/layout/component file.\n *\n * Replaces the eager `virtual:cer-components` side-effect import with\n * per-file static imports, giving Rollup graph edges it needs to\n * automatically code-split components per page chunk.\n *\n * Must be used with `enforce: 'pre'` (already set internally) to ensure\n * the transform sees the original TypeScript source before esbuild runs.\n */\nexport function cerComponentImports(options: CerComponentImportsOptions): Plugin {\n // Normalize both roots to forward slashes + trailing slash for reliable\n // startsWith checks that don't accidentally match sibling directories.\n const componentsDir = options.componentsDir.replace(/\\\\/g, '/').replace(/\\/?$/, '/');\n const appRoot = options.appRoot.replace(/\\\\/g, '/').replace(/\\/?$/, '/');\n\n // tag name → absolute file path (forward-slash normalized)\n const manifest = new Map<string, string>();\n\n function addFileToManifest(absPath: string): void {\n const normalized = absPath.replace(/\\\\/g, '/');\n try {\n const src = readFileSync(normalized, 'utf-8');\n for (const tag of extractComponentRegistrations(src)) {\n manifest.set(tag, normalized);\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n function removeFileFromManifest(absPath: string): void {\n const normalized = absPath.replace(/\\\\/g, '/');\n for (const [tag, path] of manifest.entries()) {\n if (path === normalized) manifest.delete(tag);\n }\n }\n\n function buildManifest(): void {\n manifest.clear();\n if (!existsSync(options.componentsDir)) return;\n for (const rel of globSync('**/*.ts', { cwd: options.componentsDir })) {\n addFileToManifest(resolve(options.componentsDir, rel));\n }\n }\n\n return {\n name: 'cer-component-imports',\n // Must run before esbuild/TypeScript compilation so we always see the\n // original html`` template literal strings, not compiled output.\n enforce: 'pre',\n\n buildStart() {\n buildManifest();\n },\n\n // watchChange fires for file create/delete/update events in both dev and build.\n watchChange(id: string, { event }: { event: 'create' | 'update' | 'delete' }) {\n const normalized = id.replace(/\\\\/g, '/');\n if (!normalized.startsWith(componentsDir) || !normalized.endsWith('.ts')) return;\n\n if (event === 'delete') {\n removeFileFromManifest(normalized);\n } else {\n // 'create' or 'update': remove stale entries then re-add\n removeFileFromManifest(normalized);\n addFileToManifest(normalized);\n }\n },\n\n transform(code: string, id: string) {\n // Strip Vite query strings (?v=abc, ?t=123, ?import, etc.) before checks.\n const cleanId = id.split('?')[0].replace(/\\\\/g, '/');\n\n // Only transform .ts files inside the app source root.\n if (!cleanId.endsWith('.ts') || !cleanId.startsWith(appRoot)) return null;\n\n // Quick bail-out: if the file has no html`` calls it cannot reference\n // components via templates. Avoids running the regex on utility files.\n if (!code.includes('html`')) return null;\n\n const usedTags = extractTemplateTagNames(code);\n if (usedTags.size === 0) return null;\n\n const injections: string[] = [];\n for (const tag of usedTags) {\n const componentFile = manifest.get(tag);\n if (componentFile) {\n // Use a path relative to the transformed file rather than an\n // absolute path to avoid exposing machine-local paths in build output.\n const rel = relative(dirname(cleanId), componentFile).replace(/\\\\/g, '/');\n const importPath = rel.startsWith('.') ? rel : `./${rel}`;\n injections.push(`import ${JSON.stringify(importPath)};`);\n }\n }\n if (injections.length === 0) return null;\n\n const prefix = injections.join('\\n') + '\\n';\n const newCode = prefix + code;\n\n // Zero-dependency source map for the \"prepend N lines\" case.\n //\n // Because enforce:'pre' guarantees no prior source map exists, the\n // mapping has an exact known structure:\n // • N injected lines → N semicolons (empty segments, no source pos)\n // • original line 1 → \"AAAA\" (all deltas = 0)\n // • original line k → \"AACA\" (col 0, src 0, +1 line, col 0)\n const injectedLineCount = injections.length;\n const originalLineCount = code.split('\\n').length;\n const mappings =\n ';'.repeat(injectedLineCount) +\n 'AAAA' +\n ';AACA'.repeat(originalLineCount - 1);\n\n return {\n code: newCode,\n map: {\n version: 3 as const,\n sources: [cleanId],\n sourcesContent: [code],\n names: [],\n mappings,\n },\n };\n },\n\n handleHotUpdate({ file, server }: { file: string; server: ViteDevServer }) {\n const normalized = file.replace(/\\\\/g, '/');\n if (!normalized.startsWith(componentsDir) || !normalized.endsWith('.ts')) return;\n\n // Snapshot the manifest tags for this file before and after the update.\n const before = new Set(\n [...manifest.entries()].filter(([, p]) => p === normalized).map(([t]) => t),\n );\n\n removeFileFromManifest(normalized);\n addFileToManifest(normalized);\n\n const after = new Set(\n [...manifest.entries()].filter(([, p]) => p === normalized).map(([t]) => t),\n );\n\n // If tag names didn't change, Vite's standard HMR propagation handles it.\n const manifestChanged =\n before.size !== after.size ||\n [...before].some((t) => !after.has(t));\n\n if (!manifestChanged) return;\n\n // Tag names changed — injected imports in consumer files are stale.\n // Invalidate all app .ts modules so the transform re-runs on next request.\n for (const [filePath, mods] of server.moduleGraph.fileToModulesMap) {\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(appRoot) && normalizedPath.endsWith('.ts')) {\n for (const mod of mods) {\n server.moduleGraph.invalidateModule(mod);\n }\n }\n }\n server.ws.send({ type: 'full-reload' });\n },\n };\n}\n"],"mappings":"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"}
@@ -1,84 +1,161 @@
1
- import { a as I, i as w, l as y } from "./style-DuDoj_xK.js";
2
- import { globSync as p, mkdirSync as V, readFileSync as j, writeFileSync as g } from "node:fs";
3
- import { dirname as R, resolve as S } from "node:path";
4
- var _ = "virtual:cer-jit-css", v = "\0virtual:cer-jit-css";
5
- function C(e, r) {
6
- r && Object.keys(r).length > 0 && w(r);
7
- const t = process.cwd(), n = [];
8
- for (const u of e) {
9
- const i = p(u, { cwd: t }).map((s) => S(t, s));
10
- n.push(...i);
11
- }
12
- const c = [...new Set(n)], a = /* @__PURE__ */ new Set();
13
- for (const u of c) try {
14
- const i = I(j(u, "utf-8"));
15
- for (const s of i) a.add(s);
16
- } catch {
17
- }
18
- return a.size === 0 ? "" : y(`<div class="${[...a].join(" ")}"></div>`);
1
+ import { t as e } from "./tag-utils-CoSXTr1F.js";
2
+ import { a as t, i as n, l as r } from "./style-DSSoCbC9.js";
3
+ import { existsSync as i, globSync as a, mkdirSync as o, readFileSync as s, writeFileSync as c } from "node:fs";
4
+ import { dirname as l, relative as u, resolve as d } from "node:path";
5
+ //#region src/lib/vite-plugin.ts
6
+ var f = "virtual:cer-jit-css", p = "\0virtual:cer-jit-css";
7
+ function m(e, i) {
8
+ i && Object.keys(i).length > 0 && n(i);
9
+ let o = process.cwd(), c = [];
10
+ for (let t of e) {
11
+ let e = a(t, { cwd: o }).map((e) => d(o, e));
12
+ c.push(...e);
13
+ }
14
+ let l = [...new Set(c)], u = /* @__PURE__ */ new Set();
15
+ for (let e of l) try {
16
+ let n = t(s(e, "utf-8"));
17
+ for (let e of n) u.add(e);
18
+ } catch {}
19
+ return u.size === 0 ? "" : r(`<div class="${[...u].join(" ")}"></div>`);
19
20
  }
20
- var b = "virtual:cer-ssr-config", h = "\0virtual:cer-ssr-config";
21
- function D(e) {
22
- const r = [];
23
- if (e.content && e.content.length > 0 && r.push(x({
24
- content: e.content,
25
- output: e.output,
26
- virtualModule: e.virtualModule,
27
- extendedColors: e.extendedColors,
28
- customColors: e.customColors,
29
- disableVariants: e.disableVariants
30
- })), e.ssr) {
31
- const t = e.ssr, n = {
32
- dsd: t.dsd ?? !0,
33
- dsdPolyfill: t.dsdPolyfill ?? !0,
34
- ...t.jit ? { jit: t.jit } : {}
35
- };
36
- r.push({
37
- name: "cer-ssr-config",
38
- resolveId(c) {
39
- if (c === b) return h;
40
- },
41
- load(c) {
42
- if (c === h) return `export default ${JSON.stringify(n)};`;
43
- }
44
- });
45
- }
46
- return r;
21
+ var h = "virtual:cer-ssr-config", g = "\0virtual:cer-ssr-config";
22
+ function _(e) {
23
+ let t = [];
24
+ if (e.content && e.content.length > 0 && t.push(v({
25
+ content: e.content,
26
+ output: e.output,
27
+ virtualModule: e.virtualModule,
28
+ extendedColors: e.extendedColors,
29
+ customColors: e.customColors,
30
+ disableVariants: e.disableVariants
31
+ })), e.ssr) {
32
+ let n = e.ssr, r = {
33
+ dsd: n.dsd ?? !0,
34
+ dsdPolyfill: n.dsdPolyfill ?? !0,
35
+ ...n.jit ? { jit: n.jit } : {}
36
+ };
37
+ t.push({
38
+ name: "cer-ssr-config",
39
+ resolveId(e) {
40
+ if (e === h) return g;
41
+ },
42
+ load(e) {
43
+ if (e === g) return `export default ${JSON.stringify(r)};`;
44
+ }
45
+ });
46
+ }
47
+ return t;
48
+ }
49
+ function v(e) {
50
+ let { content: t, output: n, virtualModule: r = !0, extendedColors: i, customColors: s, disableVariants: u } = e, h = {
51
+ extendedColors: i,
52
+ customColors: s,
53
+ disableVariants: u
54
+ }, g = "", _ = null;
55
+ return {
56
+ name: "cer-jit-css",
57
+ buildStart() {
58
+ let e = process.cwd(), r = /* @__PURE__ */ new Set();
59
+ for (let n of t) a(n, { cwd: e }).forEach((t) => r.add(d(e, t)));
60
+ if (_ = r, g = m(t, h), n) {
61
+ let e = d(process.cwd(), n);
62
+ o(l(e), { recursive: !0 }), c(e, g, "utf-8");
63
+ }
64
+ },
65
+ resolveId(e) {
66
+ if (r && e === f) return p;
67
+ },
68
+ load(e) {
69
+ if (e === p) return `export default ${JSON.stringify(g)};`;
70
+ },
71
+ handleHotUpdate({ file: e, server: i }) {
72
+ if ((_?.has(e) ?? !1) && (g = m(t, h), n && c(d(process.cwd(), n), g, "utf-8"), r)) {
73
+ let e = i, t = e.moduleGraph.getModuleById(p);
74
+ t && e.reloadModule(t);
75
+ }
76
+ }
77
+ };
78
+ }
79
+ var y = e;
80
+ function b(e) {
81
+ let t = e.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, ""), n = /* @__PURE__ */ new Set();
82
+ for (let e of t.matchAll(/<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)/g)) n.add(e[1]);
83
+ return n;
47
84
  }
48
85
  function x(e) {
49
- const { content: r, output: t, virtualModule: n = !0, extendedColors: c, customColors: a, disableVariants: u } = e, i = {
50
- extendedColors: c,
51
- customColors: a,
52
- disableVariants: u
53
- };
54
- let s = "", m = null;
55
- return {
56
- name: "cer-jit-css",
57
- buildStart() {
58
- const o = process.cwd(), d = /* @__PURE__ */ new Set();
59
- for (const l of r) p(l, { cwd: o }).forEach((f) => d.add(S(o, f)));
60
- if (m = d, s = C(r, i), t) {
61
- const l = S(process.cwd(), t);
62
- V(R(l), { recursive: !0 }), g(l, s, "utf-8");
63
- }
64
- },
65
- resolveId(o) {
66
- if (n && o === _) return v;
67
- },
68
- load(o) {
69
- if (o === v) return `export default ${JSON.stringify(s)};`;
70
- },
71
- handleHotUpdate({ file: o, server: d }) {
72
- if ((m?.has(o) ?? !1) && (s = C(r, i), t && g(S(process.cwd(), t), s, "utf-8"), n)) {
73
- const l = d, f = l.moduleGraph.getModuleById(v);
74
- f && l.reloadModule(f);
75
- }
76
- }
77
- };
86
+ let t = e.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, ""), n = [];
87
+ for (let e of t.matchAll(/\bcomponent\(\s*['"`]([^'"`]+)['"`]/g)) n.push(y(e[1]));
88
+ return n;
89
+ }
90
+ function S(e) {
91
+ let t = e.componentsDir.replace(/\\/g, "/").replace(/\/?$/, "/"), n = e.appRoot.replace(/\\/g, "/").replace(/\/?$/, "/"), r = /* @__PURE__ */ new Map();
92
+ function o(e) {
93
+ let t = e.replace(/\\/g, "/");
94
+ try {
95
+ let e = s(t, "utf-8");
96
+ for (let n of x(e)) r.set(n, t);
97
+ } catch {}
98
+ }
99
+ function c(e) {
100
+ let t = e.replace(/\\/g, "/");
101
+ for (let [e, n] of r.entries()) n === t && r.delete(e);
102
+ }
103
+ function f() {
104
+ if (r.clear(), i(e.componentsDir)) for (let t of a("**/*.ts", { cwd: e.componentsDir })) o(d(e.componentsDir, t));
105
+ }
106
+ return {
107
+ name: "cer-component-imports",
108
+ enforce: "pre",
109
+ buildStart() {
110
+ f();
111
+ },
112
+ watchChange(e, { event: n }) {
113
+ let r = e.replace(/\\/g, "/");
114
+ !r.startsWith(t) || !r.endsWith(".ts") || (n === "delete" ? c(r) : (c(r), o(r)));
115
+ },
116
+ transform(e, t) {
117
+ let i = t.split("?")[0].replace(/\\/g, "/");
118
+ if (!i.endsWith(".ts") || !i.startsWith(n) || !e.includes("html`")) return null;
119
+ let a = b(e);
120
+ if (a.size === 0) return null;
121
+ let o = [];
122
+ for (let e of a) {
123
+ let t = r.get(e);
124
+ if (t) {
125
+ let e = u(l(i), t).replace(/\\/g, "/"), n = e.startsWith(".") ? e : `./${e}`;
126
+ o.push(`import ${JSON.stringify(n)};`);
127
+ }
128
+ }
129
+ if (o.length === 0) return null;
130
+ let s = o.join("\n") + "\n" + e, c = o.length, d = e.split("\n").length, f = ";".repeat(c) + "AAAA" + ";AACA".repeat(d - 1);
131
+ return {
132
+ code: s,
133
+ map: {
134
+ version: 3,
135
+ sources: [i],
136
+ sourcesContent: [e],
137
+ names: [],
138
+ mappings: f
139
+ }
140
+ };
141
+ },
142
+ handleHotUpdate({ file: e, server: i }) {
143
+ let a = e.replace(/\\/g, "/");
144
+ if (!a.startsWith(t) || !a.endsWith(".ts")) return;
145
+ let s = new Set([...r.entries()].filter(([, e]) => e === a).map(([e]) => e));
146
+ c(a), o(a);
147
+ let l = new Set([...r.entries()].filter(([, e]) => e === a).map(([e]) => e));
148
+ if (s.size !== l.size || [...s].some((e) => !l.has(e))) {
149
+ for (let [e, t] of i.moduleGraph.fileToModulesMap) {
150
+ let r = e.replace(/\\/g, "/");
151
+ if (r.startsWith(n) && r.endsWith(".ts")) for (let e of t) i.moduleGraph.invalidateModule(e);
152
+ }
153
+ i.ws.send({ type: "full-reload" });
154
+ }
155
+ }
156
+ };
78
157
  }
79
- export {
80
- x as cerJITCSS,
81
- D as cerPlugin
82
- };
158
+ //#endregion
159
+ export { S as cerComponentImports, v as cerJITCSS, _ as cerPlugin, x as extractComponentRegistrations, b as extractTemplateTagNames, y as resolveTagName };
83
160
 
84
161
  //# sourceMappingURL=custom-elements-runtime.vite-plugin.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.vite-plugin.es.js","names":[],"sources":["../src/lib/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugins for build-time JIT CSS generation and SSR configuration.\n *\n * Two plugins are exported:\n *\n * - **`cerJITCSS`** — Scans source files for utility class names and emits\n * pre-generated CSS, eliminating all runtime parsing cost for projects with\n * static class lists.\n *\n * - **`cerPlugin`** — All-in-one plugin combining `cerJITCSS` with SSR\n * configuration. Exposes a `virtual:cer-ssr-config` module containing the\n * resolved SSR render options so server entry files can import and use them\n * without duplication.\n *\n * @example cerJITCSS only\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerJITCSS } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerJITCSS({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * output: 'src/generated-jit.css',\n * extendedColors: true,\n * }),\n * ],\n * });\n * ```\n *\n * @example cerPlugin with SSR\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerPlugin } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * ssr: {\n * dsd: true,\n * jit: { extendedColors: true },\n * },\n * }),\n * ],\n * });\n * ```\n *\n * Then in your server entry:\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n\nimport type { Plugin } from 'vite';\nimport { readFileSync, writeFileSync, mkdirSync, globSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport {\n jitCSS,\n enableJITCSS,\n extractClassesFromHTML,\n type JITCSSOptions,\n} from './runtime/style';\n\n// --- Re-export extractClassesFromHTML for plugin consumers ---\n\n/**\n * Options for the `cerJITCSS` Vite plugin.\n */\nexport interface CerJITCSSPluginOptions extends JITCSSOptions {\n /**\n * Glob patterns (relative to `process.cwd()`) that identify which source\n * files the plugin should scan for utility class names.\n *\n * @example `['./src/**\\/*.{ts,html}', './index.html']`\n */\n content: string[];\n /**\n * File path (relative to `process.cwd()`) where the generated CSS will\n * be written. When omitted the plugin only emits a virtual module.\n */\n output?: string;\n /**\n * Whether to emit a virtual module `virtual:cer-jit-css` that resolves to\n * the generated CSS text. Defaults to `true`.\n */\n virtualModule?: boolean;\n}\n\nconst VIRTUAL_ID = 'virtual:cer-jit-css';\nconst RESOLVED_VIRTUAL_ID = '\\0virtual:cer-jit-css';\n\nfunction generateFromFiles(\n contentPatterns: string[],\n jitOptions: JITCSSOptions,\n): string {\n if (jitOptions && Object.keys(jitOptions).length > 0) {\n enableJITCSS(jitOptions);\n }\n\n const cwd = process.cwd();\n const files: string[] = [];\n\n for (const pattern of contentPatterns) {\n const matches = globSync(pattern, { cwd }).map((f) => resolve(cwd, f));\n files.push(...matches);\n }\n\n // Deduplicate files\n const uniqueFiles = [...new Set(files)];\n\n // Aggregate all class names across all files\n const allClasses = new Set<string>();\n\n for (const file of uniqueFiles) {\n try {\n const content = readFileSync(file, 'utf-8');\n const classes = extractClassesFromHTML(content);\n for (const cls of classes) allClasses.add(cls);\n } catch {\n // Skip unreadable files\n }\n }\n\n if (allClasses.size === 0) return '';\n\n // Build a fake HTML string containing all discovered classes so jitCSS()\n // can process the full set in one pass.\n const fakeHTML = `<div class=\"${[...allClasses].join(' ')}\"></div>`;\n return jitCSS(fakeHTML);\n}\n\n// ---------------------------------------------------------------------------\n// cerPlugin — combined JIT CSS + SSR configuration plugin\n// ---------------------------------------------------------------------------\n\n/**\n * SSR render options exposed via `virtual:cer-ssr-config`.\n */\nexport interface CerSSROptions {\n /**\n * Emit Declarative Shadow DOM output for registered custom elements.\n * @default true\n */\n dsd?: boolean;\n /**\n * Append the DSD polyfill `<script>` for browsers without native support.\n * @default true\n */\n dsdPolyfill?: boolean;\n /**\n * JIT CSS options forwarded to the SSR render pass.\n */\n jit?: JITCSSOptions;\n}\n\n/**\n * Options for the combined {@link cerPlugin}.\n */\nexport interface CerPluginOptions extends Partial<CerJITCSSPluginOptions> {\n /**\n * SSR configuration. When provided, a `virtual:cer-ssr-config` module is\n * registered so server entry files can import the resolved render options:\n *\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n ssr?: CerSSROptions;\n}\n\nconst VIRTUAL_SSR_ID = 'virtual:cer-ssr-config';\nconst RESOLVED_VIRTUAL_SSR_ID = '\\0virtual:cer-ssr-config';\n\n/**\n * All-in-one Vite plugin combining build-time JIT CSS generation with SSR\n * configuration. Returns an array of plugins so it can be spread directly\n * into the `plugins` array without nesting.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,html}'],\n * ssr: { dsd: true, jit: { extendedColors: true } },\n * }),\n * ],\n * });\n * ```\n */\nexport function cerPlugin(options: CerPluginOptions): Plugin[] {\n const plugins: Plugin[] = [];\n\n // JIT CSS plugin — only added when a `content` glob is provided\n if (options.content && options.content.length > 0) {\n plugins.push(\n cerJITCSS({\n content: options.content,\n output: options.output,\n virtualModule: options.virtualModule,\n extendedColors: options.extendedColors,\n customColors: options.customColors,\n disableVariants: options.disableVariants,\n }),\n );\n }\n\n // SSR config virtual module — registered whenever `ssr` is provided\n if (options.ssr) {\n const ssrConfig = options.ssr;\n const resolvedConfig = {\n dsd: ssrConfig.dsd ?? true,\n dsdPolyfill: ssrConfig.dsdPolyfill ?? true,\n ...(ssrConfig.jit ? { jit: ssrConfig.jit } : {}),\n };\n\n plugins.push({\n name: 'cer-ssr-config',\n resolveId(id: string) {\n if (id === VIRTUAL_SSR_ID) return RESOLVED_VIRTUAL_SSR_ID;\n return undefined;\n },\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_SSR_ID) {\n return `export default ${JSON.stringify(resolvedConfig)};`;\n }\n return undefined;\n },\n });\n }\n\n return plugins;\n}\n\n// ---------------------------------------------------------------------------\n// cerJITCSS — build-time JIT CSS plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Vite plugin that performs a build-time scan of source files and emits\n * pre-generated JIT CSS as a file and/or `virtual:cer-jit-css` module.\n */\nexport function cerJITCSS(options: CerJITCSSPluginOptions): Plugin {\n const {\n content,\n output,\n virtualModule = true,\n extendedColors,\n customColors,\n disableVariants,\n } = options;\n\n const jitOptions: JITCSSOptions = {\n extendedColors,\n customColors,\n disableVariants,\n };\n\n let generatedCSS = '';\n // Resolved file set built in buildStart and reused in handleHotUpdate to\n // avoid re-running globSync for every HMR file-change event.\n let watchedFiles: Set<string> | null = null;\n\n return {\n name: 'cer-jit-css',\n\n buildStart() {\n const cwd = process.cwd();\n const resolved = new Set<string>();\n for (const pattern of content) {\n globSync(pattern, { cwd }).forEach((f) => resolved.add(resolve(cwd, f)));\n }\n watchedFiles = resolved;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n },\n\n resolveId(id: string) {\n if (virtualModule && id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n return undefined;\n },\n\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return `export default ${JSON.stringify(generatedCSS)};`;\n }\n return undefined;\n },\n\n handleHotUpdate({ file, server }: { file: string; server: unknown }) {\n // Re-generate when a watched source file changes.\n // Use the cached file set from buildStart to avoid re-globbing.\n const isWatched = watchedFiles?.has(file) ?? false;\n\n if (!isWatched) return;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n\n if (virtualModule) {\n // Invalidate the virtual module so HMR triggers a reload\n const viteServer = server as {\n moduleGraph: { getModuleById: (id: string) => unknown };\n reloadModule: (mod: unknown) => void;\n };\n const mod = viteServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) viteServer.reloadModule(mod);\n }\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"custom-elements-runtime.vite-plugin.es.js","names":[],"sources":["../src/lib/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugins for build-time JIT CSS generation, SSR configuration, and\n * per-page component code splitting.\n *\n * Three plugins are exported:\n *\n * - **`cerJITCSS`** — Scans source files for utility class names and emits\n * pre-generated CSS, eliminating all runtime parsing cost for projects with\n * static class lists.\n *\n * - **`cerPlugin`** — All-in-one plugin combining `cerJITCSS` with SSR\n * configuration. Exposes a `virtual:cer-ssr-config` module containing the\n * resolved SSR render options so server entry files can import and use them\n * without duplication.\n *\n * - **`cerComponentImports`** — Transform plugin that scans each app file for\n * custom element tags used in `html\\`` template literals and injects static\n * `import` statements pointing to the corresponding component source files.\n * This gives Rollup the module graph edges it needs to automatically\n * code-split components per page chunk.\n *\n * Three build-time utilities are also exported:\n *\n * - **`resolveTagName`** — Normalize a component name to its registered tag name.\n * - **`extractTemplateTagNames`** — Extract hyphenated tag names from `html\\`` sources.\n * - **`extractComponentRegistrations`** — Extract registered tag names from `component()` calls.\n *\n * @example cerJITCSS only\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerJITCSS } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerJITCSS({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * output: 'src/generated-jit.css',\n * extendedColors: true,\n * }),\n * ],\n * });\n * ```\n *\n * @example cerPlugin with SSR\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerPlugin } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,tsx,html}'],\n * ssr: {\n * dsd: true,\n * jit: { extendedColors: true },\n * },\n * }),\n * ],\n * });\n * ```\n *\n * Then in your server entry:\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n *\n * @example cerComponentImports for per-page code splitting\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { cerComponentImports } from '@jasonshimmy/custom-elements-runtime/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * cerComponentImports({\n * componentsDir: '/absolute/path/to/app/components',\n * appRoot: '/absolute/path/to/app',\n * }),\n * ],\n * });\n * ```\n */\n\nimport type { Plugin, ViteDevServer } from 'vite';\nimport { readFileSync, writeFileSync, mkdirSync, globSync, existsSync } from 'node:fs';\nimport { resolve, relative, dirname } from 'node:path';\nimport {\n jitCSS,\n enableJITCSS,\n extractClassesFromHTML,\n type JITCSSOptions,\n} from './runtime/style';\nimport { resolveTagName as _resolveTagName } from './runtime/tag-utils';\n\n// --- Re-export extractClassesFromHTML for plugin consumers ---\n\n/**\n * Options for the `cerJITCSS` Vite plugin.\n */\nexport interface CerJITCSSPluginOptions extends JITCSSOptions {\n /**\n * Glob patterns (relative to `process.cwd()`) that identify which source\n * files the plugin should scan for utility class names.\n *\n * @example `['./src/**\\/*.{ts,html}', './index.html']`\n */\n content: string[];\n /**\n * File path (relative to `process.cwd()`) where the generated CSS will\n * be written. When omitted the plugin only emits a virtual module.\n */\n output?: string;\n /**\n * Whether to emit a virtual module `virtual:cer-jit-css` that resolves to\n * the generated CSS text. Defaults to `true`.\n */\n virtualModule?: boolean;\n}\n\nconst VIRTUAL_ID = 'virtual:cer-jit-css';\nconst RESOLVED_VIRTUAL_ID = '\\0virtual:cer-jit-css';\n\nfunction generateFromFiles(\n contentPatterns: string[],\n jitOptions: JITCSSOptions,\n): string {\n if (jitOptions && Object.keys(jitOptions).length > 0) {\n enableJITCSS(jitOptions);\n }\n\n const cwd = process.cwd();\n const files: string[] = [];\n\n for (const pattern of contentPatterns) {\n const matches = globSync(pattern, { cwd }).map((f) => resolve(cwd, f));\n files.push(...matches);\n }\n\n // Deduplicate files\n const uniqueFiles = [...new Set(files)];\n\n // Aggregate all class names across all files\n const allClasses = new Set<string>();\n\n for (const file of uniqueFiles) {\n try {\n const content = readFileSync(file, 'utf-8');\n const classes = extractClassesFromHTML(content);\n for (const cls of classes) allClasses.add(cls);\n } catch {\n // Skip unreadable files\n }\n }\n\n if (allClasses.size === 0) return '';\n\n // Build a fake HTML string containing all discovered classes so jitCSS()\n // can process the full set in one pass.\n const fakeHTML = `<div class=\"${[...allClasses].join(' ')}\"></div>`;\n return jitCSS(fakeHTML);\n}\n\n// ---------------------------------------------------------------------------\n// cerPlugin — combined JIT CSS + SSR configuration plugin\n// ---------------------------------------------------------------------------\n\n/**\n * SSR render options exposed via `virtual:cer-ssr-config`.\n */\nexport interface CerSSROptions {\n /**\n * Emit Declarative Shadow DOM output for registered custom elements.\n * @default true\n */\n dsd?: boolean;\n /**\n * Append the DSD polyfill `<script>` for browsers without native support.\n * @default true\n */\n dsdPolyfill?: boolean;\n /**\n * JIT CSS options forwarded to the SSR render pass.\n */\n jit?: JITCSSOptions;\n}\n\n/**\n * Options for the combined {@link cerPlugin}.\n */\nexport interface CerPluginOptions extends Partial<CerJITCSSPluginOptions> {\n /**\n * SSR configuration. When provided, a `virtual:cer-ssr-config` module is\n * registered so server entry files can import the resolved render options:\n *\n * ```ts\n * import ssrConfig from 'virtual:cer-ssr-config';\n * import { renderToStringWithJITCSS } from '@jasonshimmy/custom-elements-runtime/ssr';\n *\n * const { htmlWithStyles } = renderToStringWithJITCSS(appVNode, ssrConfig);\n * ```\n */\n ssr?: CerSSROptions;\n}\n\nconst VIRTUAL_SSR_ID = 'virtual:cer-ssr-config';\nconst RESOLVED_VIRTUAL_SSR_ID = '\\0virtual:cer-ssr-config';\n\n/**\n * All-in-one Vite plugin combining build-time JIT CSS generation with SSR\n * configuration. Returns an array of plugins so it can be spread directly\n * into the `plugins` array without nesting.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * export default defineConfig({\n * plugins: [\n * cerPlugin({\n * content: ['./src/**\\/*.{ts,html}'],\n * ssr: { dsd: true, jit: { extendedColors: true } },\n * }),\n * ],\n * });\n * ```\n */\nexport function cerPlugin(options: CerPluginOptions): Plugin[] {\n const plugins: Plugin[] = [];\n\n // JIT CSS plugin — only added when a `content` glob is provided\n if (options.content && options.content.length > 0) {\n plugins.push(\n cerJITCSS({\n content: options.content,\n output: options.output,\n virtualModule: options.virtualModule,\n extendedColors: options.extendedColors,\n customColors: options.customColors,\n disableVariants: options.disableVariants,\n }),\n );\n }\n\n // SSR config virtual module — registered whenever `ssr` is provided\n if (options.ssr) {\n const ssrConfig = options.ssr;\n const resolvedConfig = {\n dsd: ssrConfig.dsd ?? true,\n dsdPolyfill: ssrConfig.dsdPolyfill ?? true,\n ...(ssrConfig.jit ? { jit: ssrConfig.jit } : {}),\n };\n\n plugins.push({\n name: 'cer-ssr-config',\n resolveId(id: string) {\n if (id === VIRTUAL_SSR_ID) return RESOLVED_VIRTUAL_SSR_ID;\n return undefined;\n },\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_SSR_ID) {\n return `export default ${JSON.stringify(resolvedConfig)};`;\n }\n return undefined;\n },\n });\n }\n\n return plugins;\n}\n\n// ---------------------------------------------------------------------------\n// cerJITCSS — build-time JIT CSS plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Vite plugin that performs a build-time scan of source files and emits\n * pre-generated JIT CSS as a file and/or `virtual:cer-jit-css` module.\n */\nexport function cerJITCSS(options: CerJITCSSPluginOptions): Plugin {\n const {\n content,\n output,\n virtualModule = true,\n extendedColors,\n customColors,\n disableVariants,\n } = options;\n\n const jitOptions: JITCSSOptions = {\n extendedColors,\n customColors,\n disableVariants,\n };\n\n let generatedCSS = '';\n // Resolved file set built in buildStart and reused in handleHotUpdate to\n // avoid re-running globSync for every HMR file-change event.\n let watchedFiles: Set<string> | null = null;\n\n return {\n name: 'cer-jit-css',\n\n buildStart() {\n const cwd = process.cwd();\n const resolved = new Set<string>();\n for (const pattern of content) {\n globSync(pattern, { cwd }).forEach((f) => resolved.add(resolve(cwd, f)));\n }\n watchedFiles = resolved;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n },\n\n resolveId(id: string) {\n if (virtualModule && id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n return undefined;\n },\n\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return `export default ${JSON.stringify(generatedCSS)};`;\n }\n return undefined;\n },\n\n handleHotUpdate({ file, server }: { file: string; server: unknown }) {\n // Re-generate when a watched source file changes.\n // Use the cached file set from buildStart to avoid re-globbing.\n const isWatched = watchedFiles?.has(file) ?? false;\n\n if (!isWatched) return;\n\n generatedCSS = generateFromFiles(content, jitOptions);\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n writeFileSync(outputPath, generatedCSS, 'utf-8');\n }\n\n if (virtualModule) {\n // Invalidate the virtual module so HMR triggers a reload\n const viteServer = server as {\n moduleGraph: { getModuleById: (id: string) => unknown };\n reloadModule: (mod: unknown) => void;\n };\n const mod = viteServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) viteServer.reloadModule(mod);\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tag resolution utilities (build-time)\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves a component() tag argument to the actual registered tag name.\n * Re-exported from runtime/tag-utils so consumers have a single import surface.\n *\n * Rules:\n * camelCase → kebab-case (myButton → my-button)\n * no hyphen → cer- prefix (app → cer-app)\n * has hyphen → unchanged (ks-badge → ks-badge)\n */\nexport const resolveTagName = _resolveTagName;\n\n/**\n * Scan TypeScript source text for all custom element tag names referenced\n * in html`` template literals.\n *\n * Strips line (//) and block (/* *\\/) comments first to avoid false\n * positives from commented-out code.\n *\n * Returns a Set of already-hyphenated tag names as they appear in the source\n * (e.g. \"ks-badge\", \"cer-app\"). Single-word names that would receive a\n * \"cer-\" prefix at runtime never appear as bare tags in templates — they\n * always appear as \"cer-something\" — so no normalization is needed here.\n *\n * Closing tags (</ks-badge>) do NOT match because the regex requires the\n * first character after < to be [a-z], not /.\n */\nexport function extractTemplateTagNames(source: string): Set<string> {\n const stripped = source\n .replace(/\\/\\/[^\\n]*/g, '') // line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, ''); // block comments\n\n const tags = new Set<string>();\n // Requires at least one hyphen-segment: matches custom elements only,\n // never native HTML elements like <div> or <span>.\n for (const m of stripped.matchAll(/<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)/g)) {\n tags.add(m[1]);\n }\n return tags;\n}\n\n/**\n * Extract all component tag names registered in a component source file.\n * Handles files that call component() more than once (returns all of them).\n *\n * Uses \\bcomponent\\( so it matches the standalone function name but not\n * names like importComponent( or registerComponent(.\n *\n * Returns resolved (normalized) tag names, ready to match against the output\n * of extractTemplateTagNames().\n */\nexport function extractComponentRegistrations(source: string): string[] {\n const stripped = source\n .replace(/\\/\\/[^\\n]*/g, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n const tags: string[] = [];\n for (const m of stripped.matchAll(/\\bcomponent\\(\\s*['\"`]([^'\"`]+)['\"`]/g)) {\n tags.push(resolveTagName(m[1]));\n }\n return tags;\n}\n\n// ---------------------------------------------------------------------------\n// cerComponentImports — per-page component code splitting plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Options for the {@link cerComponentImports} Vite plugin.\n */\nexport interface CerComponentImportsOptions {\n /**\n * Absolute path to the directory containing component files.\n * Every .ts file found here is scanned for component() registrations.\n */\n componentsDir: string;\n /**\n * Absolute path to the app source root. The transform is restricted to\n * files under this directory so node_modules and generated files are skipped.\n */\n appRoot: string;\n}\n\n/**\n * Vite plugin that injects static `import` statements for custom element\n * components used in each page/layout/component file.\n *\n * Replaces the eager `virtual:cer-components` side-effect import with\n * per-file static imports, giving Rollup graph edges it needs to\n * automatically code-split components per page chunk.\n *\n * Must be used with `enforce: 'pre'` (already set internally) to ensure\n * the transform sees the original TypeScript source before esbuild runs.\n */\nexport function cerComponentImports(options: CerComponentImportsOptions): Plugin {\n // Normalize both roots to forward slashes + trailing slash for reliable\n // startsWith checks that don't accidentally match sibling directories.\n const componentsDir = options.componentsDir.replace(/\\\\/g, '/').replace(/\\/?$/, '/');\n const appRoot = options.appRoot.replace(/\\\\/g, '/').replace(/\\/?$/, '/');\n\n // tag name → absolute file path (forward-slash normalized)\n const manifest = new Map<string, string>();\n\n function addFileToManifest(absPath: string): void {\n const normalized = absPath.replace(/\\\\/g, '/');\n try {\n const src = readFileSync(normalized, 'utf-8');\n for (const tag of extractComponentRegistrations(src)) {\n manifest.set(tag, normalized);\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n function removeFileFromManifest(absPath: string): void {\n const normalized = absPath.replace(/\\\\/g, '/');\n for (const [tag, path] of manifest.entries()) {\n if (path === normalized) manifest.delete(tag);\n }\n }\n\n function buildManifest(): void {\n manifest.clear();\n if (!existsSync(options.componentsDir)) return;\n for (const rel of globSync('**/*.ts', { cwd: options.componentsDir })) {\n addFileToManifest(resolve(options.componentsDir, rel));\n }\n }\n\n return {\n name: 'cer-component-imports',\n // Must run before esbuild/TypeScript compilation so we always see the\n // original html`` template literal strings, not compiled output.\n enforce: 'pre',\n\n buildStart() {\n buildManifest();\n },\n\n // watchChange fires for file create/delete/update events in both dev and build.\n watchChange(id: string, { event }: { event: 'create' | 'update' | 'delete' }) {\n const normalized = id.replace(/\\\\/g, '/');\n if (!normalized.startsWith(componentsDir) || !normalized.endsWith('.ts')) return;\n\n if (event === 'delete') {\n removeFileFromManifest(normalized);\n } else {\n // 'create' or 'update': remove stale entries then re-add\n removeFileFromManifest(normalized);\n addFileToManifest(normalized);\n }\n },\n\n transform(code: string, id: string) {\n // Strip Vite query strings (?v=abc, ?t=123, ?import, etc.) before checks.\n const cleanId = id.split('?')[0].replace(/\\\\/g, '/');\n\n // Only transform .ts files inside the app source root.\n if (!cleanId.endsWith('.ts') || !cleanId.startsWith(appRoot)) return null;\n\n // Quick bail-out: if the file has no html`` calls it cannot reference\n // components via templates. Avoids running the regex on utility files.\n if (!code.includes('html`')) return null;\n\n const usedTags = extractTemplateTagNames(code);\n if (usedTags.size === 0) return null;\n\n const injections: string[] = [];\n for (const tag of usedTags) {\n const componentFile = manifest.get(tag);\n if (componentFile) {\n // Use a path relative to the transformed file rather than an\n // absolute path to avoid exposing machine-local paths in build output.\n const rel = relative(dirname(cleanId), componentFile).replace(/\\\\/g, '/');\n const importPath = rel.startsWith('.') ? rel : `./${rel}`;\n injections.push(`import ${JSON.stringify(importPath)};`);\n }\n }\n if (injections.length === 0) return null;\n\n const prefix = injections.join('\\n') + '\\n';\n const newCode = prefix + code;\n\n // Zero-dependency source map for the \"prepend N lines\" case.\n //\n // Because enforce:'pre' guarantees no prior source map exists, the\n // mapping has an exact known structure:\n // • N injected lines → N semicolons (empty segments, no source pos)\n // • original line 1 → \"AAAA\" (all deltas = 0)\n // • original line k → \"AACA\" (col 0, src 0, +1 line, col 0)\n const injectedLineCount = injections.length;\n const originalLineCount = code.split('\\n').length;\n const mappings =\n ';'.repeat(injectedLineCount) +\n 'AAAA' +\n ';AACA'.repeat(originalLineCount - 1);\n\n return {\n code: newCode,\n map: {\n version: 3 as const,\n sources: [cleanId],\n sourcesContent: [code],\n names: [],\n mappings,\n },\n };\n },\n\n handleHotUpdate({ file, server }: { file: string; server: ViteDevServer }) {\n const normalized = file.replace(/\\\\/g, '/');\n if (!normalized.startsWith(componentsDir) || !normalized.endsWith('.ts')) return;\n\n // Snapshot the manifest tags for this file before and after the update.\n const before = new Set(\n [...manifest.entries()].filter(([, p]) => p === normalized).map(([t]) => t),\n );\n\n removeFileFromManifest(normalized);\n addFileToManifest(normalized);\n\n const after = new Set(\n [...manifest.entries()].filter(([, p]) => p === normalized).map(([t]) => t),\n );\n\n // If tag names didn't change, Vite's standard HMR propagation handles it.\n const manifestChanged =\n before.size !== after.size ||\n [...before].some((t) => !after.has(t));\n\n if (!manifestChanged) return;\n\n // Tag names changed — injected imports in consumer files are stale.\n // Invalidate all app .ts modules so the transform re-runs on next request.\n for (const [filePath, mods] of server.moduleGraph.fileToModulesMap) {\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(appRoot) && normalizedPath.endsWith('.ts')) {\n for (const mod of mods) {\n server.moduleGraph.invalidateModule(mod);\n }\n }\n }\n server.ws.send({ type: 'full-reload' });\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ const e=require(`./logger-Dkht1dCX.cjs`);function t(){let e=(()=>{try{return globalThis.process?.env?.NODE_ENV}catch{return}})(),t=(()=>{try{if(typeof window>`u`)return{vitest:!1,cypress:!1};let e=window;return{vitest:!!e.__vitest__,cypress:!!e.Cypress}}catch{return{vitest:!1,cypress:!1}}})();return{isTest:e===`test`||t.vitest||t.cypress,isVitest:t.vitest,isCypress:t.cypress}}var n=new class{pendingUpdates=new Map;isFlushScheduled=!1;isFlushing=!1;testEnv;lastCleanup=0;CLEANUP_INTERVAL=300*1e3;MAX_PENDING_SIZE=1e4;pendingIdleUpdates=new Map;idleCallbackHandle=null;constructor(){this.testEnv=t(),this.schedulePeriodicCleanup()}schedule(e,t){let n=t||e;this.pendingUpdates.size>=this.MAX_PENDING_SIZE&&this.performEmergencyCleanup(),this.pendingUpdates.set(n,e),this.isFlushScheduled||this.scheduleFlush()}scheduleFlush(){this.isFlushScheduled=!0,this.testEnv.isTest&&!this.isFlushing?this.flush():queueMicrotask(()=>this.flush())}flush(){if(this.isFlushing)return;this.isFlushing=!0;let t=this.pendingUpdates;this.pendingUpdates=new Map,this.isFlushScheduled=!1;try{for(let n of t.values())try{n()}catch(t){e.t(`Error in batched update:`,t)}}finally{this.isFlushing=!1}}flushImmediately(){this.pendingUpdates.size!==0&&(this.isFlushScheduled=!1,this.flush())}get pendingCount(){return this.pendingUpdates.size}get hasPendingUpdates(){return this.pendingUpdates.size>0}get isFlushingUpdates(){return this.isFlushing}schedulePeriodicCleanup(){if(this.testEnv.isTest)return;let e=()=>{this.performPeriodicCleanup(),this.testEnv.isTest||setTimeout(e,this.CLEANUP_INTERVAL)};setTimeout(e,this.CLEANUP_INTERVAL)}performPeriodicCleanup(){let t=Date.now();t-this.lastCleanup<this.CLEANUP_INTERVAL||(this.pendingUpdates.size>100&&e.r(`Scheduler has ${this.pendingUpdates.size} pending updates. Consider investigating.`),this.lastCleanup=t)}performEmergencyCleanup(t=this.pendingUpdates){e.r(`Scheduler emergency cleanup: too many pending updates, clearing oldest entries`);let n=Array.from(t.entries()),r=Math.floor(n.length/2);for(let e=0;e<r;e++)t.delete(n[e][0])}scheduleWithPriority(t,n=`normal`,r){if(n===`immediate`){try{t()}catch(t){e.t(`Error in immediate update:`,t)}return}if(n===`idle`){let e=r??t;this.pendingIdleUpdates.size>=this.MAX_PENDING_SIZE&&this.performEmergencyCleanup(this.pendingIdleUpdates),this.pendingIdleUpdates.set(e,t),this.scheduleIdleFlush();return}let i=r??t;this.pendingUpdates.size>=this.MAX_PENDING_SIZE&&this.performEmergencyCleanup(),this.pendingUpdates.set(i,t),this.isFlushScheduled||(this.isFlushScheduled=!0,queueMicrotask(()=>this.flush()))}scheduleIdleFlush(){if(this.idleCallbackHandle===null){if(this.testEnv.isTest){this.idleCallbackHandle=setTimeout(()=>{this.idleCallbackHandle=null,this.flushIdleUpdates(null)},0);return}typeof requestIdleCallback<`u`?this.idleCallbackHandle=requestIdleCallback(e=>{this.idleCallbackHandle=null,this.flushIdleUpdates(e)},{timeout:2e3}):this.idleCallbackHandle=setTimeout(()=>{this.idleCallbackHandle=null;let e=Date.now();this.flushIdleUpdates({timeRemaining:()=>Math.max(0,50-(Date.now()-e)),didTimeout:!1})},5)}}flushIdleUpdates(t){let n=Array.from(this.pendingIdleUpdates.entries());this.pendingIdleUpdates=new Map;for(let r=0;r<n.length;r++){if(t&&!t.didTimeout&&t.timeRemaining()<=0){for(let e=r;e<n.length;e++)this.pendingIdleUpdates.set(n[e][0],n[e][1]);this.scheduleIdleFlush();return}try{n[r][1]()}catch(t){e.t(`Error in idle update:`,t)}}}};function r(e,t){n.schedule(e,t)}function i(e,t=`normal`,r){n.scheduleWithPriority(e,t,r)}function a(){n.flushImmediately()}function o(){return new Promise(t=>{let r=0;for(;n.hasPendingUpdates&&r<100;)n.flushImmediately(),r++;r>=100&&e.r(`[nextTick] Maximum flush iterations reached — possible circular update loop. Check for watchers or computed values that unconditionally mutate reactive state.`),queueMicrotask(t)})}var s=new WeakSet,c=class{static cache=new WeakMap;static arrayHandlerCache=new WeakMap;static objectHandlerCache=new WeakMap;static getOrCreateProxy(e,t,n=!1){let r=this.cache.get(e);if(r)return r;let i=n?this.getOrCreateArrayHandler(t):this.getOrCreateObjectHandler(t),a=new Proxy(e,i);try{l.markAsProxy(a)}catch{}return this.cache.set(e,a),a}static getOrCreateArrayHandler(e){return this.arrayHandlerCache.has(e)||this.arrayHandlerCache.set(e,{get:(t,n,r)=>{let i=Reflect.get(t,n,r);return typeof i==`function`&&typeof n==`string`&&[`push`,`pop`,`shift`,`unshift`,`splice`,`sort`,`reverse`,`fill`,`copyWithin`].includes(n)?function(...n){let r=i.apply(t,n);return e.triggerUpdate(),r}:typeof i==`object`&&i&&typeof n==`string`?e.makeReactiveValue(i):i},set:(t,n,r)=>(t[n]=e.makeReactiveValue(r),e.triggerUpdate(),!0),deleteProperty:(t,n)=>(delete t[n],e.triggerUpdate(),!0)}),this.arrayHandlerCache.get(e)}static getOrCreateObjectHandler(e){return this.objectHandlerCache.has(e)||this.objectHandlerCache.set(e,{get:(t,n,r)=>{let i=Reflect.get(t,n,r);return typeof i==`object`&&i&&typeof n==`string`?e.makeReactiveValue(i):i},set:(t,n,r)=>(t[n]=e.makeReactiveValue(r),e.triggerUpdate(),!0),deleteProperty:(t,n)=>(delete t[n],e.triggerUpdate(),!0)}),this.objectHandlerCache.get(e)}static hasProxy(e){return this.cache.has(e)}static clear(){this.cache=new WeakMap,this.arrayHandlerCache=new WeakMap,this.objectHandlerCache=new WeakMap}static getStats(){return{hasCachedProxies:this.cache instanceof WeakMap}}},l=class{static contextCache=new WeakMap;static createReactiveProxy(e,t,n){try{if(s.has(e))return e}catch{}let r=Array.isArray(e),i=this.contextCache.get(t);i||(i=new WeakMap,this.contextCache.set(t,i));let a=i.get(n);return a||(a={triggerUpdate:t,makeReactiveValue:n},i.set(n,a)),c.getOrCreateProxy(e,a,r)}static markAsProxy(e){if(e)try{s.add(e)}catch{}}},u=!1;function d(){return u}function f(){u&&e.r(`[CER] beginDiscoveryRender() called while a discovery render is already active. This usually means a component was registered inside another component's render function. Ensure component() calls are at module top-level.`),u=!0}function p(){u=!1}var m=0;function h(e){return`${e}-${++m}`}var g=new class{currentComponentStack=[];componentData=new Map;stateStorage=new Map;trackingDisabled=!1;setCurrentComponent(e,t){if(this.currentComponentStack.push(e),!this.componentData.has(e))this.componentData.set(e,{dependencies:new Set,renderFn:t,stateIndex:0,lastWarnTime:0,watchers:new Map});else{let n=this.componentData.get(e);if(n.watchers&&n.watchers.size){for(let e of n.watchers.values())try{this.cleanup(e)}catch{}n.watchers.clear()}n.renderFn=t,n.stateIndex=0}}clearCurrentComponent(){this.currentComponentStack.pop()}getCurrentComponentId(){return this.currentComponentStack.length?this.currentComponentStack[this.currentComponentStack.length-1]:null}registerWatcher(e,t){let n=this.componentData.get(e);n&&n.watchers.set(t,t)}disableTracking(){this.trackingDisabled=!0}enableTracking(){this.trackingDisabled=!1}isRenderingComponent(){return this.currentComponentStack.length>0}shouldEmitRenderWarning(){let e=this.currentComponentStack.length?this.currentComponentStack[this.currentComponentStack.length-1]:null;if(!e)return!0;let t=this.componentData.get(e);if(!t)return!0;let n=Date.now();return n-t.lastWarnTime<1e3?!1:(t.lastWarnTime=n,!0)}withoutTracking(e){let t=this.trackingDisabled;this.trackingDisabled=!0;try{return e()}finally{this.trackingDisabled=t}}getOrCreateState(e){let t=this.currentComponentStack.length?this.currentComponentStack[this.currentComponentStack.length-1]:null;if(!t)return new _(e);let n=this.componentData.get(t);if(!n)return new _(e);let r=`${t}:${n.stateIndex++}`,i=this.stateStorage.get(r);return i||(i=new _(e),this.stateStorage.set(r,i)),i}trackDependency(e){if(this.trackingDisabled)return;let t=this.currentComponentStack.length?this.currentComponentStack[this.currentComponentStack.length-1]:null;if(!t)return;let n=this.componentData.get(t);n&&(n.dependencies.add(e),e.addDependent(t))}propagateDependencies(e){if(this.trackingDisabled)return;let t=this.currentComponentStack.length?this.currentComponentStack[this.currentComponentStack.length-1]:null;if(!t||t===e)return;let n=this.componentData.get(e);if(!n)return;let r=this.componentData.get(t);if(r)for(let e of n.dependencies)r.dependencies.add(e),e.addDependent(t)}triggerUpdate(e){let t=e.getDependents();for(let e of t){let t=this.componentData.get(e);t&&r(t.renderFn,e)}}cleanup(e){let t=this.componentData.get(e);if(t){for(let n of t.dependencies)n.removeDependent(e);this.componentData.delete(e)}let n=e+`:`;for(let e of this.stateStorage.keys())e.startsWith(n)&&this.stateStorage.delete(e)}},_=class{_value;_rawValue;dependents=new Set;constructor(e){this._rawValue=e,this._value=this.makeReactive(e);try{Object.defineProperty(this,Symbol.for(`@cer/ReactiveState`),{value:!0,enumerable:!1,configurable:!1})}catch{}}get value(){return g.trackDependency(this),this._value}set value(t){Object.is(t,this._rawValue)||(g.isRenderingComponent()&&g.shouldEmitRenderWarning()&&e.r(`🚨 State modification detected during render! This can cause infinite loops.
2
+ • Move state updates to event handlers
3
+ • Use watchEffect/watch for side effects
4
+ • Ensure computed properties don't modify state`),this._rawValue=t,this._value=this.makeReactive(t),g.triggerUpdate(this))}peek(){return this._value}initSilent(e){this._rawValue=e,this._value=e}addDependent(e){this.dependents.add(e)}removeDependent(e){this.dependents.delete(e)}getDependents(){return this.dependents}makeReactive(e){return typeof e!=`object`||!e||typeof Node<`u`&&e instanceof Node||typeof Element<`u`&&e instanceof Element||typeof HTMLElement<`u`&&e instanceof HTMLElement?e:l.createReactiveProxy(e,()=>g.triggerUpdate(this),e=>this.makeReactive(e))}};function v(e){return g.getOrCreateState(e===void 0?null:e)}function y(e){if(!e||typeof e!=`object`)return!1;try{let t=Symbol.for(`@cer/ReactiveState`);return Object.prototype.hasOwnProperty.call(e,t)}catch{return!1}}function b(e){let t,n=!0,r=h(`computed`),i=()=>{n=!0};try{let e=g.getCurrentComponentId();e&&g.registerWatcher(e,r)}catch{}return g.setCurrentComponent(r,i),t=e(),g.clearCurrentComponent(),n=!1,{get value(){return n&&=(g.setCurrentComponent(r,i),t=e(),g.clearCurrentComponent(),!1),g.propagateDependencies(r),t}}}function x(e){if(d())return()=>{};let t=h(`effect`);try{let e=g.getCurrentComponentId();e&&g.registerWatcher(e,t)}catch{}let n=()=>{g.setCurrentComponent(t,n);try{e()}finally{g.clearCurrentComponent()}};return n(),()=>{g.cleanup(t)}}var S=50;function C(t,n=new WeakMap,r=0){if(typeof t!=`object`||!t)return t;let i=t;if(n.has(i))return n.get(i);if(r>S)return e.r(`[watch] Deep clone exceeded ${S} nesting levels. Returning a reference at this depth instead of cloning further. Consider restructuring your state or switching to a shallow watch.`),t;if(typeof Node<`u`&&i instanceof Node)return t;if(i instanceof Date)return new Date(i.getTime());if(Array.isArray(i)){let e=[];n.set(i,e);for(let t=0;t<i.length;t++)e.push(C(i[t],n,r+1));return e}let a={};n.set(i,a);for(let e of Object.keys(i))try{a[e]=C(i[e],n,r+1)}catch{}return a}function w(e,t,n){if(d())return()=>{};let r,i=y(e)?()=>e.value:e,a=h(`watch`);try{let e=g.getCurrentComponentId();e&&g.registerWatcher(e,a)}catch{}let o=()=>{g.setCurrentComponent(a,o);let e=i();if(g.clearCurrentComponent(),n?.deep){let n=g.withoutTracking(()=>C(e));t(n,r),r=n}else e!==r&&(t(e,r),r=e)};return g.setCurrentComponent(a,o),r=i(),g.clearCurrentComponent(),n?.deep&&(r=g.withoutTracking(()=>C(r))),n&&n.immediate&&t(r,void 0),()=>{g.cleanup(a)}}var T=e=>{try{e()}catch{}},E=new Map,D=new Map,O=new Map,k=500,A,j,M=!1,N=!1,P,F=!!globalThis.process?.versions?.node;function I(e){if(E.has(e))return E.get(e);let t=e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase();return E.size<k&&E.set(e,t),t}function L(e){if(D.has(e))return D.get(e);let t=e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return D.size<k&&D.set(e,t),t}function R(e){if(typeof e==`string`){if(O.has(e))return O.get(e);let t=e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e]);return t!==e&&O.size<k&&O.set(e,t),t}return e}function z(t){if(!t)return``;let n=String(t);if(typeof document<`u`&&typeof document.createElement==`function`){let e=n.replace(/</g,``).replace(/>/g,``),t=P||=document.createElement(`div`);try{z._el=t}catch{}return t.innerHTML=e,(t.textContent||``).replace(RegExp(``,`g`),`<`).replace(RegExp(``,`g`),`>`)}let r={lt:`<`,gt:`>`,amp:`&`,quot:`"`,apos:`'`,nbsp:`\xA0`},i=A??z._namedMap,a=i;if(!a&&F)try{let e=globalThis.require;if(typeof e==`function`)for(let t of[`@jasonshimmy/custom-elements-runtime/entities.json`,`../../entities.json`,`../../../entities.json`,`../entities.json`,`./entities.json`])try{let n=e(t);if(n&&typeof n==`object`){a=n;break}}catch{}}catch{}if(!a){a=r,M=!0;try{z._usedFallback=!0}catch{}let e=z._namedMapLoader??j;e&&e().then(e=>{A=e;try{z._namedMap=e}catch{}}).catch(()=>{})}if((M||z._usedFallback)&&!(N||z._warnedFallback)){N=!0;try{z._warnedFallback=!0}catch{}try{e.r(`decodeEntities: using small SSR fallback entity map. Register the full entities.json via registerEntityMap(entities) on the server to enable full HTML5 named-entity decoding.`)}catch{}}return n.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g,(e,t)=>{if(t.charCodeAt(0)===35){let e=(t.charAt(1)||``).toLowerCase()===`x`?parseInt(t.slice(2),16):parseInt(t.slice(1),10);return Number.isNaN(e)?`&${t};`:String.fromCodePoint(e)}let n=a[t]??(i&&i[t]);return n===void 0?`&${t};`:n})}async function B(){let e=[`@jasonshimmy`,`custom-elements-runtime`,`entities.json`].join(`/`);try{let t=await import(e);return t&&(t.default||t)}catch{try{let t=[e,`./entities.json`,`../../entities.json`,`../../../entities.json`];for(let e of t)try{let t=await import(e);if(t)return t&&(t.default||t)}catch{}return{lt:`<`,gt:`>`,amp:`&`,quot:`"`,apos:`'`,nbsp:`\xA0`}}catch{return{lt:`<`,gt:`>`,amp:`&`,quot:`"`,apos:`'`,nbsp:`\xA0`}}}}j=B,z._namedMapLoader=B;function V(e,t){!e||typeof e!=`object`||A&&!t?.overwrite||(A=e)}function H(){A=void 0}function U(e){let t=String(e);return{__unsafeHTML:t,__rawHTML:t}}function W(e){return!!e&&(typeof e.__unsafeHTML==`string`||typeof e.__rawHTML==`string`)}function G(e,t){if(typeof t==`string`){if(t===``)return;let n=t.split(`.`),r=e;for(let e of n){if(typeof r!=`object`||!r){r=void 0;break}r=r[e]}return y(r)?r.value:r}return t}function K(e,t,n){let r=String(t).split(`.`),i=r.pop();if(!i)return;let a=r.reduce((e,t)=>(e[t]??(e[t]={}),e[t]),e);y(a[i])?a[i].value=n:a[i]=n}function q(e){try{if(e&&typeof e==`object`){if(y(e))return e.value;if(`value`in e){let t=e.value;return t==null||typeof t==`string`||typeof t==`number`||typeof t==`boolean`?t:e}}}catch{}return e}function J(e){let t=q(e);if(t==null)return null;let n=typeof t;return n===`string`||n===`number`||n===`boolean`?String(t):null}function Y(e){if(!e||typeof e!=`string`)return!1;if(e===`class`||e.endsWith(`Class`))return!0;if(e.includes(`-`))try{if(e.split(`-`).some(e=>e===`class`))return!0}catch{}return!1}Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return v}});
5
+ //# sourceMappingURL=helpers-DcEpRwq5.cjs.map