@stacksjs/stx 0.2.95 → 0.2.96

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 (612) hide show
  1. package/dist/a11y.js +598 -2
  2. package/dist/analytics.js +159 -2
  3. package/dist/analyzer.js +240 -2
  4. package/dist/animation.js +688 -2
  5. package/dist/app-shell.js +220 -2
  6. package/dist/app.js +79 -2
  7. package/dist/assets.js +155 -2
  8. package/dist/ast.js +630 -2
  9. package/dist/async-components.js +428 -2
  10. package/dist/auth.js +12 -2
  11. package/dist/broadcasting.js +102 -2
  12. package/dist/browser-composables.js +565 -2
  13. package/dist/build-assets.js +29 -2
  14. package/dist/build-mode-detector.js +50 -2
  15. package/dist/build-optimizer.js +433 -2
  16. package/dist/build-views.js +180 -2
  17. package/dist/build.js +33 -2
  18. package/dist/builtins/drawer.js +37 -2
  19. package/dist/builtins/escape.js +3 -2
  20. package/dist/builtins/icon.js +83 -2
  21. package/dist/builtins/index.js +34 -2
  22. package/dist/builtins/modal.js +38 -2
  23. package/dist/builtins/safe-image.js +51 -2
  24. package/dist/builtins/stx-image.js +200 -2
  25. package/dist/builtins/stx-link.js +41 -2
  26. package/dist/builtins/stx-loading-indicator.js +35 -2
  27. package/dist/builtins/suspense.js +24 -2
  28. package/dist/builtins/toast.js +42 -2
  29. package/dist/builtins/tooltip.js +106 -2
  30. package/dist/builtins/transition-group.js +22 -2
  31. package/dist/bundle-analyzer/collector.js +233 -2
  32. package/dist/bundle-analyzer/index.js +82 -2
  33. package/dist/bundle-analyzer/report.js +318 -2
  34. package/dist/bundle-analyzer/treemap.js +594 -2
  35. package/dist/caching.js +131 -2
  36. package/dist/cli.js +11317 -10982
  37. package/dist/client/directive.js +14 -2
  38. package/dist/client/index.js +2 -2
  39. package/dist/client-helpers.js +312 -2
  40. package/dist/client-script-bundler.js +216 -6
  41. package/dist/client-script.js +754 -2
  42. package/dist/client.js +73 -4
  43. package/dist/component-hmr.js +585 -2
  44. package/dist/component-library.d.ts +6 -0
  45. package/dist/component-library.js +683 -0
  46. package/dist/component-processing.js +613 -2
  47. package/dist/component-registry.js +90 -2
  48. package/dist/component-renderer.js +660 -2
  49. package/dist/components.js +213 -2
  50. package/dist/composables/index.js +220 -2
  51. package/dist/composables/use-battery.js +101 -2
  52. package/dist/composables/use-broadcast-channel.js +80 -2
  53. package/dist/composables/use-channel.js +124 -2
  54. package/dist/composables/use-clipboard.js +79 -2
  55. package/dist/composables/use-color-mode.js +131 -2
  56. package/dist/composables/use-cookie.js +86 -2
  57. package/dist/composables/use-device-orientation.js +181 -2
  58. package/dist/composables/use-event-listener.js +27 -2
  59. package/dist/composables/use-event-source.js +166 -2
  60. package/dist/composables/use-eye-dropper.js +142 -2
  61. package/dist/composables/use-fetch.js +223 -2
  62. package/dist/composables/use-fullscreen.js +110 -2
  63. package/dist/composables/use-geolocation.js +101 -2
  64. package/dist/composables/use-idle.js +182 -2
  65. package/dist/composables/use-intersection-observer.js +168 -2
  66. package/dist/composables/use-keyboard.js +224 -2
  67. package/dist/composables/use-media-query.js +62 -2
  68. package/dist/composables/use-meta.js +48 -2
  69. package/dist/composables/use-mouse.js +286 -2
  70. package/dist/composables/use-mutation-observer.js +129 -2
  71. package/dist/composables/use-network.js +85 -2
  72. package/dist/composables/use-notification.js +94 -2
  73. package/dist/composables/use-permissions.js +132 -2
  74. package/dist/composables/use-query.js +0 -1
  75. package/dist/composables/use-resize-observer.js +157 -2
  76. package/dist/composables/use-router.js +51 -2
  77. package/dist/composables/use-share.js +104 -2
  78. package/dist/composables/use-speech.js +294 -2
  79. package/dist/composables/use-storage.js +130 -2
  80. package/dist/composables/use-text-selection.js +205 -4
  81. package/dist/composables/use-timer.js +183 -2
  82. package/dist/composables/use-utilities.js +176 -2
  83. package/dist/composables/use-wake-lock.js +122 -2
  84. package/dist/composables/use-websocket.js +165 -2
  85. package/dist/composables/use-window.js +163 -2
  86. package/dist/composables.js +552 -2
  87. package/dist/composition-api.js +190 -2
  88. package/dist/computed.js +376 -8
  89. package/dist/conditionals.js +599 -2
  90. package/dist/config.js +751 -2
  91. package/dist/craft-bridge.js +432 -2
  92. package/dist/craft-compiler.js +810 -2
  93. package/dist/craft-components.js +945 -2
  94. package/dist/craft-entry.js +5 -2
  95. package/dist/craft-ssr.js +559 -2
  96. package/dist/csp.js +220 -2
  97. package/dist/csrf.js +38 -2
  98. package/dist/custom-directives.js +136 -2
  99. package/dist/defer.js +156 -2
  100. package/dist/deploy/config-generators.js +214 -2
  101. package/dist/deploy/index.js +203 -2
  102. package/dist/deploy/netlify.js +167 -2
  103. package/dist/dev-server/crosswind.js +379 -2
  104. package/dist/dev-server/index.js +7 -2
  105. package/dist/dev-server/keyboard-shortcuts.js +81 -2
  106. package/dist/dev-server/native-window.js +91 -2
  107. package/dist/dev-server/port-utils.js +40 -2
  108. package/dist/dev-server/serve-app.js +682 -2
  109. package/dist/dev-server/serve-file.js +439 -2
  110. package/dist/dev-server/serve-markdown.js +281 -2
  111. package/dist/dev-server/serve-multi.js +579 -2
  112. package/dist/dev-server/terminal-colors.js +45 -2
  113. package/dist/dev-server/theme-selector.js +111 -2
  114. package/dist/dev-server/types.js +43 -2
  115. package/dist/dev-server.js +4 -2
  116. package/dist/devtools.js +462 -18
  117. package/dist/directive-api.js +355 -2
  118. package/dist/docs.js +567 -2
  119. package/dist/doctor.js +123 -2
  120. package/dist/document-shell.js +105 -2
  121. package/dist/dynamic-components.js +78 -2
  122. package/dist/edge-runtime.js +539 -2
  123. package/dist/env.js +9 -2
  124. package/dist/error-boundaries.js +62 -12
  125. package/dist/error-handling.js +1 -2
  126. package/dist/errors/codes.js +97 -2
  127. package/dist/errors/formatter.js +196 -2
  128. package/dist/errors/index.js +44 -2
  129. package/dist/errors/logger.js +250 -2
  130. package/dist/errors/sanitizer.js +181 -2
  131. package/dist/errors/types.js +86 -2
  132. package/dist/events.js +382 -2
  133. package/dist/expressions.js +650 -2
  134. package/dist/formatter.js +265 -2
  135. package/dist/forms-validation.js +510 -4
  136. package/dist/forms.js +709 -2
  137. package/dist/head.js +224 -2
  138. package/dist/heatmap.js +566 -2
  139. package/dist/hot-reload.js +367 -2
  140. package/dist/html-masking.js +73 -2
  141. package/dist/hydration-runtime.js +195 -2
  142. package/dist/hydration.js +654 -2
  143. package/dist/i18n.js +633 -2
  144. package/dist/image-optimization/auto-sibling.js +88 -2
  145. package/dist/image-optimization/build-plugin.js +241 -2
  146. package/dist/image-optimization/component.js +244 -2
  147. package/dist/image-optimization/directive.js +203 -2
  148. package/dist/image-optimization/index.js +54 -2
  149. package/dist/image-optimization/processor.js +262 -2
  150. package/dist/image-optimization/serve.js +102 -2
  151. package/dist/includes.js +733 -2
  152. package/dist/index.d.ts +1 -0
  153. package/dist/index.js +134 -2
  154. package/dist/init.js +505 -2
  155. package/dist/inline-assets.js +82 -2
  156. package/dist/interactive.js +383 -2
  157. package/dist/internal-markdown.js +141 -2
  158. package/dist/island-chunking.js +52 -2
  159. package/dist/js-ts.js +57 -2
  160. package/dist/jsx-runtime.js +289 -2
  161. package/dist/keep-alive.js +421 -2
  162. package/dist/lazy-loader.js +245 -2
  163. package/dist/loading-indicator.js +322 -2
  164. package/dist/loops.js +643 -2
  165. package/dist/manifest.js +31 -2
  166. package/dist/markdown.js +68 -2
  167. package/dist/media/client/blur-up.js +217 -2
  168. package/dist/media/client/index.js +53 -2
  169. package/dist/media/client/lazy-load.js +283 -2
  170. package/dist/media/client/upload-handler.js +354 -2
  171. package/dist/media/image/component.js +574 -2
  172. package/dist/media/image/directive.js +160 -2
  173. package/dist/media/image/editing.js +193 -2
  174. package/dist/media/image/index.js +80 -2
  175. package/dist/media/image/placeholder.js +188 -2
  176. package/dist/media/image/processor/cache.js +51 -2
  177. package/dist/media/image/processor/index.js +3 -2
  178. package/dist/media/image/processor/optimizer.js +202 -2
  179. package/dist/media/image/processor/responsive.js +162 -2
  180. package/dist/media/image/srcset.js +194 -2
  181. package/dist/media/index.js +198 -2
  182. package/dist/media/manager/embed.js +253 -2
  183. package/dist/media/protected/component.js +235 -2
  184. package/dist/media/protected/index.js +20 -2
  185. package/dist/media/protected/signature.js +205 -2
  186. package/dist/media/shared/cache.js +132 -2
  187. package/dist/media/shared/hash.js +35 -2
  188. package/dist/media/shared/index.js +2 -2
  189. package/dist/media/types.js +0 -1
  190. package/dist/media/upload/component.js +320 -2
  191. package/dist/media/upload/index.js +1 -2
  192. package/dist/media/video/directive.js +142 -2
  193. package/dist/media/video/index.js +583 -2
  194. package/dist/media/video/processor/cache.js +52 -2
  195. package/dist/media/video/processor/index.js +4 -2
  196. package/dist/media/video/processor/streaming.js +197 -2
  197. package/dist/media/video/processor/thumbnail.js +134 -2
  198. package/dist/media/video/processor/transcoder.js +283 -2
  199. package/dist/method-spoofing.js +17 -2
  200. package/dist/middleware.js +40 -2
  201. package/dist/misc-directives.js +222 -2
  202. package/dist/native-build.js +511 -2
  203. package/dist/parser/directive-parser.js +239 -2
  204. package/dist/parser/expression-parser.js +358 -2
  205. package/dist/parser/index.js +23 -2
  206. package/dist/parser/tokenizer.js +534 -2
  207. package/dist/partial-hydration.js +427 -2
  208. package/dist/performance-utils.js +430 -2
  209. package/dist/placeholder.js +35 -2
  210. package/dist/plugin-system.js +214 -2
  211. package/dist/plugin.js +173 -2
  212. package/dist/precompiler.js +660 -81
  213. package/dist/process.js +711 -2
  214. package/dist/production-build.js +596 -2
  215. package/dist/production-builder.js +132 -2
  216. package/dist/production-server.js +188 -2
  217. package/dist/props.js +224 -2
  218. package/dist/public-env.js +19 -2
  219. package/dist/pwa/audit.js +255 -2
  220. package/dist/pwa/directives.js +332 -2
  221. package/dist/pwa/icons.js +109 -2
  222. package/dist/pwa/index.js +47 -2
  223. package/dist/pwa/inject.js +102 -2
  224. package/dist/pwa/manifest.js +186 -2
  225. package/dist/pwa/offline.js +259 -2
  226. package/dist/pwa/precache.js +116 -2
  227. package/dist/pwa/service-worker.js +860 -2
  228. package/dist/pwa/workbox-strategies.js +167 -2
  229. package/dist/pwa/workbox.js +382 -2
  230. package/dist/pwa.js +427 -427
  231. package/dist/reactive-bindings.js +266 -2
  232. package/dist/reactive.js +569 -2
  233. package/dist/reactivity.js +559 -2
  234. package/dist/release.js +1 -2
  235. package/dist/render.js +165 -2
  236. package/dist/route-middleware.js +17 -2
  237. package/dist/router.js +9 -2
  238. package/dist/routes.js +14 -2
  239. package/dist/runtime-injection.js +120 -2
  240. package/dist/runtime.js +94 -2
  241. package/dist/safe-evaluator.js +444 -2
  242. package/dist/scaffolding.js +897 -2
  243. package/dist/screenshot.js +87 -2
  244. package/dist/script-classifier.js +32 -2
  245. package/dist/script-validation.js +158 -2
  246. package/dist/seo.js +457 -2
  247. package/dist/serve.js +237 -2
  248. package/dist/server-bindings.js +108 -2
  249. package/dist/server-components.js +338 -11
  250. package/dist/signal-processing.js +946 -2
  251. package/dist/signals-api.js +154 -2
  252. package/dist/signals.js +5287 -2
  253. package/dist/site-builder/build.js +224 -2
  254. package/dist/site-builder/i18n.js +140 -2
  255. package/dist/site-builder/index.js +15 -2
  256. package/dist/site-builder/robots.js +26 -2
  257. package/dist/site-builder/router.js +27 -2
  258. package/dist/site-builder/seo.js +36 -2
  259. package/dist/site-builder/sitemap.js +26 -2
  260. package/dist/site-builder/theme.js +33 -2
  261. package/dist/site-builder/types.js +0 -1
  262. package/dist/slots.js +201 -2
  263. package/dist/source-maps.js +350 -2
  264. package/dist/spa-shell.js +34 -2
  265. package/dist/ssg.js +389 -389
  266. package/dist/ssr.js +355 -2
  267. package/dist/state-management.js +533 -2
  268. package/dist/store-imports.js +13 -2
  269. package/dist/store-loader.js +72 -5
  270. package/dist/stores-client.js +132 -2
  271. package/dist/story/addons.js +261 -2
  272. package/dist/story/analytics.js +235 -2
  273. package/dist/story/auto-stories.js +158 -2
  274. package/dist/story/bookmarks.js +277 -2
  275. package/dist/story/bun-test.js +102 -2
  276. package/dist/story/cli.js +155 -2
  277. package/dist/story/collect/analyzer.js +305 -2
  278. package/dist/story/collect/index.js +27 -2
  279. package/dist/story/collect/parser.js +129 -2
  280. package/dist/story/collect/scanner.js +101 -2
  281. package/dist/story/collect/tree.js +110 -2
  282. package/dist/story/commands/build.js +172 -2
  283. package/dist/story/commands/dev.js +78 -2
  284. package/dist/story/commands/index.js +3 -2
  285. package/dist/story/commands/preview.js +56 -2
  286. package/dist/story/compiled-output.js +151 -2
  287. package/dist/story/composition.js +261 -2
  288. package/dist/story/config-watcher.js +67 -2
  289. package/dist/story/config.js +64 -2
  290. package/dist/story/context.js +27 -2
  291. package/dist/story/controls/index.js +320 -2
  292. package/dist/story/crosswind.js +189 -2
  293. package/dist/story/desktop-preview.js +105 -2
  294. package/dist/story/docs-generator.js +186 -2
  295. package/dist/story/errors.js +239 -2
  296. package/dist/story/figma-export.js +224 -2
  297. package/dist/story/generator.js +165 -2
  298. package/dist/story/hmr.js +131 -2
  299. package/dist/story/hot-swap.js +207 -2
  300. package/dist/story/index.js +49 -2
  301. package/dist/story/interactions.js +225 -2
  302. package/dist/story/keyboard-shortcuts.js +345 -2
  303. package/dist/story/output.js +153 -2
  304. package/dist/story/performance.js +252 -2
  305. package/dist/story/presets.js +289 -2
  306. package/dist/story/props-validation.js +215 -2
  307. package/dist/story/renderer.js +209 -2
  308. package/dist/story/search-index.js +106 -2
  309. package/dist/story/search.js +140 -2
  310. package/dist/story/server.js +965 -2
  311. package/dist/story/setup.js +78 -2
  312. package/dist/story/snapshots.js +170 -2
  313. package/dist/story/testing.js +163 -2
  314. package/dist/story/theme.js +170 -2
  315. package/dist/story/types.js +0 -2
  316. package/dist/story/ui/code-panel.js +175 -2
  317. package/dist/story/ui/controls-panel.js +168 -2
  318. package/dist/story/ui/index.js +4 -2
  319. package/dist/story/ui/navigation.js +250 -2
  320. package/dist/story/ui/preview.js +251 -2
  321. package/dist/story/visual-testing.js +247 -2
  322. package/dist/streaming.js +537 -2
  323. package/dist/strict-lint.js +288 -2
  324. package/dist/style-scoping.js +50 -2
  325. package/dist/suspense.js +398 -2
  326. package/dist/teleport.js +109 -2
  327. package/dist/template-compiler.js +63 -2
  328. package/dist/template-hydrator.js +82 -2
  329. package/dist/template-tag-balance.js +93 -2
  330. package/dist/testing.js +581 -2
  331. package/dist/transitions.js +443 -2
  332. package/dist/type-checker.js +581 -2
  333. package/dist/types/component-types.d.ts +54 -0
  334. package/dist/types/component-types.js +0 -1
  335. package/dist/types/config-types.js +0 -1
  336. package/dist/types/context-types.js +0 -1
  337. package/dist/types/csp-types.js +0 -1
  338. package/dist/types/directive-types.js +3 -2
  339. package/dist/types/index.d.ts +5 -0
  340. package/dist/types/index.js +1 -2
  341. package/dist/types/pwa-types.js +0 -1
  342. package/dist/types.js +1 -2
  343. package/dist/typescript-templates.js +386 -4
  344. package/dist/utils.js +942 -2
  345. package/dist/validator.js +171 -2
  346. package/dist/variable-extractor.js +1094 -2
  347. package/dist/view-composers.js +29 -2
  348. package/dist/virtual-scrolling.js +454 -2
  349. package/dist/visual-editor.js +688 -28
  350. package/dist/vue-template.js +475 -2
  351. package/dist/web-components/css-scoping.js +177 -2
  352. package/dist/web-components/index.js +13 -2
  353. package/dist/web-components/reactive-generator.js +121 -56
  354. package/dist/web-components.js +1447 -2
  355. package/dist/x-element.js +17 -5
  356. package/package.json +5 -6
  357. package/dist/chunk-04n64bnt.js +0 -5
  358. package/dist/chunk-06w68hyg.js +0 -7
  359. package/dist/chunk-07y6m5xx.js +0 -3
  360. package/dist/chunk-095s3972.js +0 -99
  361. package/dist/chunk-09k66d8a.js +0 -3
  362. package/dist/chunk-0a61y94n.js +0 -24
  363. package/dist/chunk-0b9w2w1y.js +0 -1
  364. package/dist/chunk-0dx4q6yq.js +0 -3
  365. package/dist/chunk-0dz85jrp.js +0 -3
  366. package/dist/chunk-0jd0pndq.js +0 -3
  367. package/dist/chunk-0p0nyq50.js +0 -6
  368. package/dist/chunk-0p1h3p3w.js +0 -3
  369. package/dist/chunk-0qakwen3.js +0 -1
  370. package/dist/chunk-0qnz93q2.js +0 -3
  371. package/dist/chunk-10debkj5.js +0 -71
  372. package/dist/chunk-15nesxgt.js +0 -5224
  373. package/dist/chunk-1sr54zp8.js +0 -3
  374. package/dist/chunk-1v49fwr5.js +0 -3
  375. package/dist/chunk-1xz0w746.js +0 -1539
  376. package/dist/chunk-1z5nhbjt.js +0 -90
  377. package/dist/chunk-1zgsgk4b.js +0 -1
  378. package/dist/chunk-20swzkx3.js +0 -216
  379. package/dist/chunk-27zsyhrd.js +0 -4
  380. package/dist/chunk-29y0hk5z.js +0 -3
  381. package/dist/chunk-2cdvw21b.js +0 -274
  382. package/dist/chunk-2j21d3ka.js +0 -161
  383. package/dist/chunk-2jxbwnkz.js +0 -2
  384. package/dist/chunk-31dr4bys.js +0 -6
  385. package/dist/chunk-35faj94w.js +0 -15
  386. package/dist/chunk-39gm08bn.js +0 -39
  387. package/dist/chunk-3a4qsygv.js +0 -51
  388. package/dist/chunk-3te20hqw.js +0 -3
  389. package/dist/chunk-43t7faps.js +0 -24
  390. package/dist/chunk-44hd3kab.js +0 -1
  391. package/dist/chunk-47kpewks.js +0 -71
  392. package/dist/chunk-4aj7ftqb.js +0 -1
  393. package/dist/chunk-4d2y57k7.js +0 -3
  394. package/dist/chunk-4deg33rw.js +0 -57
  395. package/dist/chunk-4k7d8p8d.js +0 -188
  396. package/dist/chunk-4qcy5tx6.js +0 -53
  397. package/dist/chunk-4x7kae4j.js +0 -3
  398. package/dist/chunk-55nwdnsd.js +0 -3
  399. package/dist/chunk-55yp0q8t.js +0 -201
  400. package/dist/chunk-5f43yz6z.js +0 -12
  401. package/dist/chunk-5shey2e4.js +0 -3
  402. package/dist/chunk-6b5k6w2q.js +0 -7
  403. package/dist/chunk-6djzdes9.js +0 -14
  404. package/dist/chunk-6e4c6g46.js +0 -3
  405. package/dist/chunk-6eqbxcrd.js +0 -8
  406. package/dist/chunk-7074g241.js +0 -3
  407. package/dist/chunk-7b6s3g65.js +0 -179
  408. package/dist/chunk-7cgmq685.js +0 -33
  409. package/dist/chunk-7dkz6z2s.js +0 -3
  410. package/dist/chunk-7ed3tean.js +0 -3
  411. package/dist/chunk-7gd339hd.js +0 -109
  412. package/dist/chunk-7j5e8sdj.js +0 -3
  413. package/dist/chunk-7n8g0nfn.js +0 -38
  414. package/dist/chunk-7sqdeqsw.js +0 -1
  415. package/dist/chunk-80g54ncj.js +0 -3
  416. package/dist/chunk-8a5bxece.js +0 -4
  417. package/dist/chunk-8ahwt6a4.js +0 -721
  418. package/dist/chunk-8b3z0zd5.js +0 -8
  419. package/dist/chunk-8dhdpa5h.js +0 -4
  420. package/dist/chunk-8n9nnqr6.js +0 -3
  421. package/dist/chunk-8qc1bsym.js +0 -3
  422. package/dist/chunk-8va64c9n.js +0 -3
  423. package/dist/chunk-8vtm0m84.js +0 -3
  424. package/dist/chunk-8xj7c3mf.js +0 -8
  425. package/dist/chunk-988dw6q3.js +0 -9
  426. package/dist/chunk-9b6cec0v.js +0 -321
  427. package/dist/chunk-9cf97f9p.js +0 -3
  428. package/dist/chunk-9ecv8aqj.js +0 -14
  429. package/dist/chunk-9eq3ht5f.js +0 -8
  430. package/dist/chunk-9jtj77jx.js +0 -3
  431. package/dist/chunk-9t14se2t.js +0 -83
  432. package/dist/chunk-9wmq2272.js +0 -3
  433. package/dist/chunk-9zbk5zx5.js +0 -57
  434. package/dist/chunk-a2g2qb2y.js +0 -386
  435. package/dist/chunk-a3hyn4we.js +0 -79
  436. package/dist/chunk-a87qqft6.js +0 -194
  437. package/dist/chunk-ah88wzbg.js +0 -10
  438. package/dist/chunk-akf1r75r.js +0 -102
  439. package/dist/chunk-amaa1bev.js +0 -2
  440. package/dist/chunk-avx8aydt.js +0 -3
  441. package/dist/chunk-ay9qf4zj.js +0 -6
  442. package/dist/chunk-aywxfqev.js +0 -3
  443. package/dist/chunk-azkegjd8.js +0 -61
  444. package/dist/chunk-b77wjyn7.js +0 -84
  445. package/dist/chunk-baf1hfwh.js +0 -231
  446. package/dist/chunk-bdk6g1vj.js +0 -3
  447. package/dist/chunk-bhqgmyqw.js +0 -36
  448. package/dist/chunk-bk3j0n82.js +0 -341
  449. package/dist/chunk-bndmdahk.js +0 -3
  450. package/dist/chunk-bpgg59wa.js +0 -3
  451. package/dist/chunk-bs3gmfxz.js +0 -5
  452. package/dist/chunk-bxc7kjsk.js +0 -32
  453. package/dist/chunk-c7jg8w13.js +0 -3
  454. package/dist/chunk-ckxjqqn9.js +0 -3
  455. package/dist/chunk-cn8az1b4.js +0 -1
  456. package/dist/chunk-d0zjtdw4.js +0 -29
  457. package/dist/chunk-d1qh1x2g.js +0 -3
  458. package/dist/chunk-djddhmcc.js +0 -60
  459. package/dist/chunk-dqn9gyhb.js +0 -21
  460. package/dist/chunk-drjq2zwg.js +0 -3
  461. package/dist/chunk-dvfs1h3c.js +0 -117
  462. package/dist/chunk-e2q9c5vq.js +0 -8
  463. package/dist/chunk-e98v1bc6.js +0 -12
  464. package/dist/chunk-ejayeex8.js +0 -2
  465. package/dist/chunk-ejh8fyak.js +0 -3
  466. package/dist/chunk-ek2w6zvy.js +0 -4
  467. package/dist/chunk-ewa88139.js +0 -6
  468. package/dist/chunk-fjk3x41y.js +0 -3
  469. package/dist/chunk-frg705zq.js +0 -302
  470. package/dist/chunk-fzm3y0r3.js +0 -267
  471. package/dist/chunk-g1vt329s.js +0 -21
  472. package/dist/chunk-g4ps1dj8.js +0 -140
  473. package/dist/chunk-gkzq8zw4.js +0 -23
  474. package/dist/chunk-gz5fmp3q.js +0 -3
  475. package/dist/chunk-h0hjy0kn.js +0 -292
  476. package/dist/chunk-h5jxydqq.js +0 -147
  477. package/dist/chunk-h5wa62ek.js +0 -145
  478. package/dist/chunk-h7aq56qj.js +0 -28
  479. package/dist/chunk-h82kjdr4.js +0 -83
  480. package/dist/chunk-hbehnm18.js +0 -3
  481. package/dist/chunk-hbgxbgam.js +0 -58
  482. package/dist/chunk-hc2mf5h6.js +0 -4
  483. package/dist/chunk-hjm2xab3.js +0 -3
  484. package/dist/chunk-hjv76kcw.js +0 -1
  485. package/dist/chunk-hrnnh4tq.js +0 -142
  486. package/dist/chunk-ht43ds42.js +0 -236
  487. package/dist/chunk-hxx3za24.js +0 -62
  488. package/dist/chunk-hy8820vc.js +0 -6
  489. package/dist/chunk-j447q024.js +0 -28
  490. package/dist/chunk-j58vh0w6.js +0 -314
  491. package/dist/chunk-j8tn8enq.js +0 -3
  492. package/dist/chunk-jc0fc4ht.js +0 -11
  493. package/dist/chunk-jcs0ymw7.js +0 -3
  494. package/dist/chunk-jjamhxpm.js +0 -139
  495. package/dist/chunk-jjb05d21.js +0 -3
  496. package/dist/chunk-jjdq01dv.js +0 -128
  497. package/dist/chunk-jnmgm2xw.js +0 -5
  498. package/dist/chunk-jpndqst5.js +0 -3
  499. package/dist/chunk-jt0ezawy.js +0 -351
  500. package/dist/chunk-jz73j3qs.js +0 -169
  501. package/dist/chunk-k21df0pg.js +0 -10
  502. package/dist/chunk-k848dzsa.js +0 -429
  503. package/dist/chunk-kdfe4t91.js +0 -3
  504. package/dist/chunk-keawsbpn.js +0 -5
  505. package/dist/chunk-kgym7ch9.js +0 -8
  506. package/dist/chunk-khdn7jwe.js +0 -3
  507. package/dist/chunk-km25cwz6.js +0 -3
  508. package/dist/chunk-knm8a8yx.js +0 -398
  509. package/dist/chunk-krqn0ddk.js +0 -3
  510. package/dist/chunk-ktkmvaa8.js +0 -1
  511. package/dist/chunk-kx6eb6ma.js +0 -4
  512. package/dist/chunk-kypas8vy.js +0 -4
  513. package/dist/chunk-m167kjhv.js +0 -4
  514. package/dist/chunk-m491r0rj.js +0 -358
  515. package/dist/chunk-m8448qby.js +0 -11
  516. package/dist/chunk-mgj88zeq.js +0 -64
  517. package/dist/chunk-mhgk632d.js +0 -3
  518. package/dist/chunk-mv4fb50w.js +0 -1
  519. package/dist/chunk-n5kg7fpx.js +0 -7
  520. package/dist/chunk-n98x35xd.js +0 -8
  521. package/dist/chunk-n9dhs1dw.js +0 -106
  522. package/dist/chunk-nd9rmddh.js +0 -6
  523. package/dist/chunk-ngxfwzq3.js +0 -3
  524. package/dist/chunk-nhv099jv.js +0 -19
  525. package/dist/chunk-nm15ccsg.js +0 -5
  526. package/dist/chunk-npfmdb6y.js +0 -71
  527. package/dist/chunk-nvwb4x04.js +0 -3
  528. package/dist/chunk-nw34xajc.js +0 -8
  529. package/dist/chunk-p077sw22.js +0 -3
  530. package/dist/chunk-p1h8065h.js +0 -3
  531. package/dist/chunk-p3e0cqtt.js +0 -34
  532. package/dist/chunk-p3fpb79v.js +0 -477
  533. package/dist/chunk-p52yzjq6.js +0 -498
  534. package/dist/chunk-p73meypx.js +0 -134
  535. package/dist/chunk-pa9zb7ty.js +0 -4
  536. package/dist/chunk-payfb24w.js +0 -207
  537. package/dist/chunk-pcm1vd8w.js +0 -3
  538. package/dist/chunk-pcntd9h4.js +0 -3
  539. package/dist/chunk-pg1fvqb9.js +0 -167
  540. package/dist/chunk-psc3wfcf.js +0 -1115
  541. package/dist/chunk-pznnww6k.js +0 -6
  542. package/dist/chunk-q6zhd9yf.js +0 -3
  543. package/dist/chunk-qa59zejf.js +0 -246
  544. package/dist/chunk-qvrbjpdc.js +0 -3
  545. package/dist/chunk-qygvvygy.js +0 -12
  546. package/dist/chunk-r0jcmpv6.js +0 -68
  547. package/dist/chunk-r5m9xtm7.js +0 -3
  548. package/dist/chunk-rh80q1nd.js +0 -1
  549. package/dist/chunk-rkffm9sy.js +0 -128
  550. package/dist/chunk-rpx5fa65.js +0 -3
  551. package/dist/chunk-rqxf5hns.js +0 -3
  552. package/dist/chunk-rtr974rc.js +0 -30
  553. package/dist/chunk-rvptcndz.js +0 -3
  554. package/dist/chunk-rw26rpek.js +0 -171
  555. package/dist/chunk-rw7937v4.js +0 -19
  556. package/dist/chunk-rwrv9wbf.js +0 -3
  557. package/dist/chunk-rz2ec6g7.js +0 -347
  558. package/dist/chunk-s6ja2bdg.js +0 -66
  559. package/dist/chunk-scpkdrdb.js +0 -4
  560. package/dist/chunk-shv88d2d.js +0 -10
  561. package/dist/chunk-t0c9wvpr.js +0 -3
  562. package/dist/chunk-tffh3b1e.js +0 -35
  563. package/dist/chunk-tg2f1mzq.js +0 -11
  564. package/dist/chunk-trfswy66.js +0 -77
  565. package/dist/chunk-tzwtg722.js +0 -3
  566. package/dist/chunk-v7f8jj15.js +0 -4
  567. package/dist/chunk-v8j49spx.js +0 -3
  568. package/dist/chunk-v97390pe.js +0 -1
  569. package/dist/chunk-vcr5pzpx.js +0 -233
  570. package/dist/chunk-veeerpwa.js +0 -3
  571. package/dist/chunk-vg5kt6az.js +0 -4
  572. package/dist/chunk-vgv7jvyz.js +0 -219
  573. package/dist/chunk-vjbefncc.js +0 -3
  574. package/dist/chunk-vmxjghsm.js +0 -3
  575. package/dist/chunk-vw7vqd76.js +0 -3
  576. package/dist/chunk-vx22he47.js +0 -1
  577. package/dist/chunk-w3b6m427.js +0 -45
  578. package/dist/chunk-wazkqv7n.js +0 -3
  579. package/dist/chunk-wf7zrjsw.js +0 -138
  580. package/dist/chunk-wfg2gm11.js +0 -3
  581. package/dist/chunk-wg9k6h8w.js +0 -12
  582. package/dist/chunk-wkz2vwkr.js +0 -81
  583. package/dist/chunk-wvef3ngh.js +0 -127
  584. package/dist/chunk-wvf31nzs.js +0 -3
  585. package/dist/chunk-x05nxhyv.js +0 -262
  586. package/dist/chunk-x0770gt9.js +0 -4
  587. package/dist/chunk-x24s4heg.js +0 -1166
  588. package/dist/chunk-x3r64r0c.js +0 -6
  589. package/dist/chunk-x5g9w4hh.js +0 -5
  590. package/dist/chunk-xgkv66q5.js +0 -2230
  591. package/dist/chunk-xqq1vxb6.js +0 -1
  592. package/dist/chunk-xs03kc1h.js +0 -196
  593. package/dist/chunk-xv34zbp4.js +0 -3
  594. package/dist/chunk-xw36p73h.js +0 -90
  595. package/dist/chunk-xyg1r5w0.js +0 -4
  596. package/dist/chunk-xys2sxh6.js +0 -16
  597. package/dist/chunk-y0qg6rrv.js +0 -3
  598. package/dist/chunk-y1k17c8b.js +0 -21
  599. package/dist/chunk-y5xz0jc4.js +0 -141
  600. package/dist/chunk-y6xsqe9a.js +0 -10
  601. package/dist/chunk-yb1t2h8h.js +0 -11
  602. package/dist/chunk-ygvyc6wv.js +0 -90
  603. package/dist/chunk-yj4x5ehw.js +0 -21
  604. package/dist/chunk-yn38c15w.js +0 -4
  605. package/dist/chunk-ynhngsdh.js +0 -3
  606. package/dist/chunk-yrsb6j3z.js +0 -3
  607. package/dist/chunk-yywfvfph.js +0 -2
  608. package/dist/chunk-zcxzdrn7.js +0 -5
  609. package/dist/chunk-zen6ax1y.js +0 -27
  610. package/dist/chunk-zf2pek72.js +0 -3
  611. package/dist/chunk-zk3d0jjf.js +0 -7
  612. package/dist/chunk-zy3rp1ab.js +0 -93
@@ -1,2 +1,1447 @@
1
- // @bun
2
- import{Dr as a,Er as b,Fr as c,Gr as d,Hr as e,Ir as f,Jr as g,Kr as h,Lr as i,Mr as j,Nr as k,Or as l,Pr as m}from"./chunk-1xz0w746.js";import"./chunk-m8448qby.js";import"./chunk-kx6eb6ma.js";import"./chunk-g1vt329s.js";import"./chunk-7074g241.js";import"./chunk-9cf97f9p.js";import"./chunk-6djzdes9.js";import"./chunk-v7f8jj15.js";import"./chunk-keawsbpn.js";import"./chunk-8b3z0zd5.js";import"./chunk-hbgxbgam.js";import"./chunk-ejh8fyak.js";import"./chunk-krqn0ddk.js";import"./chunk-y1k17c8b.js";import"./chunk-2j21d3ka.js";import"./chunk-frg705zq.js";import"./chunk-hjm2xab3.js";import"./chunk-07y6m5xx.js";import"./chunk-wazkqv7n.js";import"./chunk-x05nxhyv.js";import"./chunk-31dr4bys.js";import"./chunk-mgj88zeq.js";import"./chunk-m167kjhv.js";import"./chunk-3a4qsygv.js";import"./chunk-dqn9gyhb.js";import"./chunk-988dw6q3.js";import"./chunk-8qc1bsym.js";import"./chunk-xyg1r5w0.js";import"./chunk-7gd339hd.js";import"./chunk-4deg33rw.js";import"./chunk-pa9zb7ty.js";import"./chunk-a2g2qb2y.js";import"./chunk-h5jxydqq.js";import"./chunk-nhv099jv.js";import"./chunk-shv88d2d.js";import"./chunk-0dx4q6yq.js";import"./chunk-ek2w6zvy.js";import"./chunk-9wmq2272.js";import"./chunk-7dkz6z2s.js";import"./chunk-9ecv8aqj.js";import"./chunk-bdk6g1vj.js";import"./chunk-xqq1vxb6.js";import"./chunk-amaa1bev.js";import"./chunk-r5m9xtm7.js";import"./chunk-bs3gmfxz.js";import"./chunk-1zgsgk4b.js";import"./chunk-2jxbwnkz.js";import"./chunk-zen6ax1y.js";import"./chunk-yb1t2h8h.js";import"./chunk-fjk3x41y.js";import"./chunk-5shey2e4.js";import"./chunk-27zsyhrd.js";import"./chunk-7ed3tean.js";import"./chunk-8vtm0m84.js";import"./chunk-tzwtg722.js";import"./chunk-ah88wzbg.js";import"./chunk-v8j49spx.js";import"./chunk-tg2f1mzq.js";import"./chunk-n9dhs1dw.js";import"./chunk-rwrv9wbf.js";import"./chunk-wg9k6h8w.js";import"./chunk-9jtj77jx.js";import"./chunk-qygvvygy.js";import"./chunk-gz5fmp3q.js";import"./chunk-vjbefncc.js";import"./chunk-8xj7c3mf.js";import"./chunk-qvrbjpdc.js";import"./chunk-w3b6m427.js";import"./chunk-rz2ec6g7.js";import"./chunk-35faj94w.js";import"./chunk-djddhmcc.js";import"./chunk-knm8a8yx.js";import"./chunk-xv34zbp4.js";export{m as webComponentDirectiveHandler,d as scopeHTML,c as scopeCSS,k as parseSFCComponent,e as getScopeAttribute,b as generateScopeId,l as generateSFCWebComponent,h as generateReactiveWebComponentTS,g as generateReactiveWebComponent,j as generateReactiveRuntime,i as generateReactiveMixin,f as extractAndScopeStyles,a as buildWebComponents};
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ErrorCodes, inlineError } from "./error-handling.js";
4
+ import { fileExists, resolveTemplatePath } from "./utils.js";
5
+ export async function buildWebComponents(options, dependencies) {
6
+ if (!options.webComponents?.enabled)
7
+ return [];
8
+ const webComponents = options.webComponents.components || [], builtComponents = [];
9
+ if (webComponents.length > 0) {
10
+ if (options.debug)
11
+ console.log(`Building ${webComponents.length} web components...`);
12
+ for (const component of webComponents)
13
+ try {
14
+ const outputPath = await buildWebComponent(component, options, dependencies);
15
+ if (outputPath)
16
+ builtComponents.push(outputPath);
17
+ } catch (error) {
18
+ console.error(`Error building web component ${component.name}:`, error);
19
+ if (options.debug)
20
+ throw error;
21
+ }
22
+ }
23
+ return builtComponents;
24
+ }
25
+ async function buildWebComponent(component, options, dependencies) {
26
+ const { name, file, tag, extends: baseElement } = component;
27
+ if (!name || !file || !tag) {
28
+ console.error("Invalid web component configuration, missing required fields:", component);
29
+ return null;
30
+ }
31
+ let filePath = null;
32
+ if (path.isAbsolute(file) && await fileExists(file))
33
+ filePath = file;
34
+ else if (options.componentsDir) {
35
+ const componentsPath = path.join(options.componentsDir, file);
36
+ if (await fileExists(componentsPath))
37
+ filePath = componentsPath;
38
+ }
39
+ if (!filePath)
40
+ filePath = await resolveTemplatePath(file, process.cwd(), options, dependencies);
41
+ if (!filePath) {
42
+ console.error(`Web component source file not found: ${file}`);
43
+ return null;
44
+ }
45
+ const source = await Bun.file(filePath).text();
46
+ dependencies.add(filePath);
47
+ const isTypeScript = (component.outputFormat || "js") === "ts", webComponentCode = isTypeScript ? generateWebComponentCodeTypeScript({
48
+ name,
49
+ tag,
50
+ baseElement,
51
+ source,
52
+ shadowDOM: component.shadowDOM ?? !0,
53
+ template: component.template ?? !0,
54
+ styleSource: component.styleSource,
55
+ attributes: component.attributes || [],
56
+ attributeTypes: component.attributeTypes || {}
57
+ }) : generateWebComponentCode({
58
+ name,
59
+ tag,
60
+ baseElement,
61
+ source,
62
+ shadowDOM: component.shadowDOM ?? !0,
63
+ template: component.template ?? !0,
64
+ styleSource: component.styleSource,
65
+ attributes: component.attributes || []
66
+ }), outputDir = options.webComponents?.outputDir || "dist/web-components";
67
+ await fs.promises.mkdir(outputDir, { recursive: !0 });
68
+ const extension = isTypeScript ? "ts" : "js", outputFile = path.join(outputDir, `${tag}.${extension}`);
69
+ await Bun.write(outputFile, webComponentCode);
70
+ if (options.debug)
71
+ console.log(`Built web component ${name} -> ${outputFile}`);
72
+ return outputFile;
73
+ }
74
+ function generateWebComponentCode(options) {
75
+ const {
76
+ name,
77
+ tag,
78
+ baseElement = "HTMLElement",
79
+ source,
80
+ shadowDOM,
81
+ template,
82
+ styleSource,
83
+ attributes = []
84
+ } = options;
85
+ let htmlContent = source.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").trim();
86
+ if (!shadowDOM) {
87
+ htmlContent = htmlContent.replace(/<slot\s+name=["']([^"']+)["']\s*>([\s\S]*?)<\/slot>/gi, '<div data-slot="$1">$2</div>');
88
+ htmlContent = htmlContent.replace(/<slot\s+name=["']([^"']+)["']\s*\/>/gi, '<div data-slot="$1"></div>');
89
+ htmlContent = htmlContent.replace(/<slot\s*>([\s\S]*?)<\/slot>/gi, "<div data-default-slot>$1</div>");
90
+ htmlContent = htmlContent.replace(/<slot\s*\/>/gi, "<div data-default-slot></div>");
91
+ }
92
+ let styles = "";
93
+ if (styleSource)
94
+ styles = `<link rel="stylesheet" href="${styleSource}">`;
95
+ return `/**
96
+ * ${name} Web Component
97
+ * Auto-generated from stx component
98
+ */
99
+ class ${name.replace(/\W/g, "")} extends ${baseElement} {
100
+ constructor() {
101
+ super()
102
+ ${shadowDOM ? 'this.attachShadow({ mode: "open" })' : ""}
103
+ ${template ? "this._createTemplate()" : "this._render()"}
104
+ }
105
+
106
+ ${template ? `
107
+ _createTemplate() {
108
+ const template = document.createElement('template')
109
+ template.innerHTML = \`${styles}${htmlContent}\`
110
+ ${shadowDOM ? "this.shadowRoot.appendChild(template.content.cloneNode(true))" : "this.appendChild(template.content.cloneNode(true))"}
111
+ this._processSlots()
112
+ }
113
+ ` : `
114
+ _render() {
115
+ ${shadowDOM ? "this.shadowRoot.innerHTML" : "this.innerHTML"} = \`${styles}${htmlContent}\`
116
+ this._processSlots()
117
+ }
118
+ `}
119
+
120
+ _processSlots() {
121
+ ${shadowDOM ? `// Shadow DOM handles slot assignment automatically
122
+ // Listen for slot changes if needed
123
+ const slots = this.shadowRoot.querySelectorAll('slot')
124
+ slots.forEach(slot => {
125
+ slot.addEventListener('slotchange', (e) => {
126
+ const assignedNodes = slot.assignedNodes()
127
+ this.dispatchEvent(new CustomEvent('slot-changed', {
128
+ detail: { slotName: slot.name || 'default', assignedNodes }
129
+ }))
130
+ })
131
+ })` : `// Manual slot processing for non-shadow DOM mode
132
+ const slots = this.querySelectorAll('[data-slot]')
133
+ const lightDOMChildren = Array.from(this.childNodes).filter(
134
+ node => node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute('data-slot')
135
+ )
136
+
137
+ // Process named slots
138
+ slots.forEach(slotEl => {
139
+ const slotName = slotEl.getAttribute('data-slot')
140
+ const slottedContent = this.querySelector(\`[slot="\${slotName}"]\`)
141
+ if (slottedContent) {
142
+ // Replace slot placeholder with actual content
143
+ slotEl.innerHTML = ''
144
+ slotEl.appendChild(slottedContent.cloneNode(true))
145
+ }
146
+ })
147
+
148
+ // Process default slot
149
+ const defaultSlot = this.querySelector('[data-slot=""]') || this.querySelector('[data-default-slot]')
150
+ if (defaultSlot) {
151
+ const unslottedContent = Array.from(this.children).filter(
152
+ child => !child.hasAttribute('slot') && child !== defaultSlot
153
+ )
154
+ if (unslottedContent.length > 0) {
155
+ defaultSlot.innerHTML = ''
156
+ unslottedContent.forEach(content => {
157
+ defaultSlot.appendChild(content.cloneNode(true))
158
+ })
159
+ }
160
+ }`}
161
+ }
162
+
163
+ ${attributes.length > 0 ? `
164
+ static get observedAttributes() {
165
+ return [${attributes.map((attr) => `'${attr}'`).join(", ")}]
166
+ }
167
+
168
+ attributeChangedCallback(name, oldValue, newValue) {
169
+ if (oldValue !== newValue) {
170
+ this[name] = newValue
171
+ ${template ? "" : "this._render()"}
172
+ }
173
+ }
174
+ ` : ""}
175
+
176
+ connectedCallback() {
177
+ // Component connected to the DOM
178
+ }
179
+
180
+ disconnectedCallback() {
181
+ // Component removed from the DOM
182
+ }
183
+ }
184
+
185
+ // Register the web component
186
+ customElements.define('${tag}', ${name.replace(/\W/g, "")})
187
+ `;
188
+ }
189
+ function generateWebComponentCodeTypeScript(options) {
190
+ const {
191
+ name,
192
+ tag,
193
+ baseElement = "HTMLElement",
194
+ source,
195
+ shadowDOM,
196
+ template,
197
+ styleSource,
198
+ attributes = [],
199
+ attributeTypes = {}
200
+ } = options, className = name.replace(/\W/g, "");
201
+ let htmlContent = source.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").trim();
202
+ if (!shadowDOM) {
203
+ htmlContent = htmlContent.replace(/<slot\s+name=["']([^"']+)["']\s*>([\s\S]*?)<\/slot>/gi, '<div data-slot="$1">$2</div>');
204
+ htmlContent = htmlContent.replace(/<slot\s+name=["']([^"']+)["']\s*\/>/gi, '<div data-slot="$1"></div>');
205
+ htmlContent = htmlContent.replace(/<slot\s*>([\s\S]*?)<\/slot>/gi, "<div data-default-slot>$1</div>");
206
+ htmlContent = htmlContent.replace(/<slot\s*\/>/gi, "<div data-default-slot></div>");
207
+ }
208
+ htmlContent = htmlContent.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
209
+ const styles = styleSource ? `<link rel="stylesheet" href="${styleSource}">` : "", getTypeScriptType = (attr) => {
210
+ switch (attributeTypes[attr]) {
211
+ case "number":
212
+ return "number";
213
+ case "boolean":
214
+ return "boolean";
215
+ case "object":
216
+ return "Record<string, unknown>";
217
+ default:
218
+ return "string";
219
+ }
220
+ }, toCamelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()), propertyDeclarations = attributes.map((attr) => ` private _${toCamelCase(attr)}: ${getTypeScriptType(attr)} | null = null;`).join(`
221
+ `), gettersSetters = attributes.map((attr) => {
222
+ const type = getTypeScriptType(attr), camelCase = toCamelCase(attr);
223
+ return `
224
+ get ${camelCase}(): ${type} | null {
225
+ return this._${camelCase};
226
+ }
227
+
228
+ set ${camelCase}(value: ${type} | null) {
229
+ this._${camelCase} = value;
230
+ if (value !== null) {
231
+ this.setAttribute('${attr}', String(value));
232
+ }
233
+ else {
234
+ this.removeAttribute('${attr}');
235
+ }
236
+ }`;
237
+ }).join(`
238
+ `), propsInterface = attributes.length > 0 ? `/**
239
+ * Props interface for ${name}
240
+ */
241
+ export interface ${className}Props {
242
+ ${attributes.map((attr) => {
243
+ const type = getTypeScriptType(attr);
244
+ return ` ${toCamelCase(attr)}?: ${type};`;
245
+ }).join(`
246
+ `)}
247
+ }
248
+ ` : "", observedAttributesCode = attributes.length > 0 ? `
249
+ static get observedAttributes(): string[] {
250
+ return [${attributes.map((attr) => `'${attr}'`).join(", ")}];
251
+ }
252
+
253
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
254
+ if (oldValue !== newValue) {
255
+ const camelCase = name.replace(/-([a-z])/g, (_: string, letter: string) => letter.toUpperCase());
256
+ (this as unknown as Record<string, unknown>)[\`_\${camelCase}\`] = this._parseAttributeValue(name, newValue);
257
+ ${template ? "" : "this._render();"}
258
+ }
259
+ }
260
+
261
+ private _parseAttributeValue(name: string, value: string | null): unknown {
262
+ if (value === null) return null;
263
+ const typeMap: Record<string, string> = ${JSON.stringify(attributeTypes)};
264
+ const type = typeMap[name] || 'string';
265
+ switch (type) {
266
+ case 'number': return Number(value);
267
+ case 'boolean': return value !== 'false' && value !== '0';
268
+ case 'object': try { return JSON.parse(value); }
269
+ catch { return value; }
270
+ default: return value;
271
+ }
272
+ }
273
+ ` : "", templateMethod = template ? `
274
+ private _createTemplate(): void {
275
+ const template = document.createElement('template');
276
+ template.innerHTML = \`${styles}${htmlContent}\`;
277
+ ${shadowDOM ? "this.shadowRoot!.appendChild(template.content.cloneNode(true));" : "this.appendChild(template.content.cloneNode(true));"}
278
+ this._processSlots();
279
+ }` : `
280
+ private _render(): void {
281
+ ${shadowDOM ? "this.shadowRoot!.innerHTML" : "this.innerHTML"} = \`${styles}${htmlContent}\`;
282
+ this._processSlots();
283
+ }`;
284
+ return `/**
285
+ * ${name} Web Component
286
+ * Auto-generated from stx component (TypeScript)
287
+ *
288
+ * @example
289
+ * \`\`\`html
290
+ * <${tag}></${tag}>
291
+ * \`\`\`
292
+ */
293
+
294
+ /**
295
+ * Detail type for slot-changed event
296
+ */
297
+ interface SlotChangeDetail {
298
+ slotName: string;
299
+ assignedNodes: Node[];
300
+ }
301
+
302
+ ${propsInterface}
303
+ /**
304
+ * ${name} custom element class
305
+ * @customElement ${tag}
306
+ */
307
+ export class ${className} extends ${baseElement} {
308
+ ${propertyDeclarations}
309
+
310
+ constructor() {
311
+ super();
312
+ ${shadowDOM ? 'this.attachShadow({ mode: "open" });' : ""}
313
+ ${template ? "this._createTemplate();" : "this._render();"}
314
+ }
315
+ ${templateMethod}
316
+ ${shadowDOM ? `
317
+ private _processSlots(): void {
318
+ const slots = this.shadowRoot!.querySelectorAll('slot');
319
+ slots.forEach((slot) => {
320
+ slot.addEventListener('slotchange', () => {
321
+ const assignedNodes = (slot as HTMLSlotElement).assignedNodes();
322
+ this.dispatchEvent(new CustomEvent<SlotChangeDetail>('slot-changed', {
323
+ detail: { slotName: slot.getAttribute('name') || 'default', assignedNodes }
324
+ }));
325
+ });
326
+ });
327
+ }` : `
328
+ private _processSlots(): void {
329
+ const slots = this.querySelectorAll('[data-slot]');
330
+ slots.forEach((slotEl) => {
331
+ const slotName = slotEl.getAttribute('data-slot');
332
+ if (slotName) {
333
+ const slottedContent = this.querySelector(\`[slot="\${slotName}"]\`);
334
+ if (slottedContent) {
335
+ slotEl.innerHTML = '';
336
+ slotEl.appendChild(slottedContent.cloneNode(true));
337
+ }
338
+ }
339
+ });
340
+ }`}
341
+ ${observedAttributesCode}
342
+ ${gettersSetters}
343
+
344
+ connectedCallback(): void {
345
+ // Component connected to the DOM
346
+ }
347
+
348
+ disconnectedCallback(): void {
349
+ // Component removed from the DOM
350
+ }
351
+
352
+ adoptedCallback(): void {
353
+ // Component moved to a new document
354
+ }
355
+ }
356
+
357
+ // Type augmentation for HTMLElementTagNameMap
358
+ declare global {
359
+ interface HTMLElementTagNameMap {
360
+ '${tag}': ${className};
361
+ }
362
+ }
363
+
364
+ // Register the web component
365
+ customElements.define('${tag}', ${className});
366
+ `;
367
+ }
368
+ const defaultCssScopingConfig = {
369
+ strategy: "attribute",
370
+ attributeName: "data-v",
371
+ preserveOriginal: !0
372
+ };
373
+ export function generateScopeId(componentName) {
374
+ const hash = componentName.split("").reduce((acc, char) => (acc << 5) - acc + char.charCodeAt(0) | 0, 0);
375
+ return Math.abs(hash).toString(36).slice(0, 8);
376
+ }
377
+ export function scopeCSS(css, componentTag, config = {}) {
378
+ const mergedConfig = { ...defaultCssScopingConfig, ...config }, scopeId = generateScopeId(componentTag);
379
+ switch (mergedConfig.strategy) {
380
+ case "shadow":
381
+ return css;
382
+ case "prefix":
383
+ return scopeCSSWithPrefix(css, mergedConfig.prefix || componentTag, mergedConfig.preserveOriginal);
384
+ case "attribute":
385
+ return scopeCSSWithAttribute(css, scopeId, mergedConfig.attributeName || "data-v", mergedConfig.preserveOriginal);
386
+ case "bem":
387
+ return scopeCSSWithBEM(css, componentTag, mergedConfig.preserveOriginal);
388
+ default:
389
+ return css;
390
+ }
391
+ }
392
+ function scopeCSSWithAttribute(css, scopeId, attributeName, preserveOriginal) {
393
+ const scopeAttr = `[${attributeName}-${scopeId}]`;
394
+ return css.replace(/([.#]?[\w-]+|\*)\s*(\{|,)/g, (match, selector, delimiter) => {
395
+ if (selector.startsWith("@"))
396
+ return match;
397
+ if (/^(?::root|:host|html|body)$/i.test(selector))
398
+ return match;
399
+ return `${preserveOriginal ? `${selector}${scopeAttr}` : `${selector}${scopeAttr}`}${delimiter}`;
400
+ });
401
+ }
402
+ function scopeCSSWithPrefix(css, prefix, preserveOriginal) {
403
+ return css.replace(/\.([a-z_][\w-]*)/gi, (match, className) => {
404
+ if (className.startsWith(prefix))
405
+ return match;
406
+ const scopedClass = `${prefix}__${className}`;
407
+ return preserveOriginal ? `.${scopedClass}` : `.${scopedClass}`;
408
+ });
409
+ }
410
+ function scopeCSSWithBEM(css, componentName, preserveOriginal) {
411
+ const block = componentName.replace(/[^a-z0-9]/gi, "-");
412
+ return css.replace(/\.([a-z_][\w-]*)/gi, (match, className) => {
413
+ if (className.includes("__") || className.includes("--")) {
414
+ if (!className.startsWith(block))
415
+ return `.${block}__${className}`;
416
+ return match;
417
+ }
418
+ const scopedClass = `${block}__${className}`;
419
+ return preserveOriginal ? `.${scopedClass}` : `.${scopedClass}`;
420
+ });
421
+ }
422
+ export function scopeHTML(html, componentTag, config = {}) {
423
+ const mergedConfig = { ...defaultCssScopingConfig, ...config };
424
+ if (mergedConfig.strategy === "shadow")
425
+ return html;
426
+ if (mergedConfig.strategy === "attribute") {
427
+ const scopeId = generateScopeId(componentTag), scopeAttr = `${mergedConfig.attributeName || "data-v"}-${scopeId}`;
428
+ return html.replace(/<([a-z][a-z0-9-]*)([^>]*)>/gi, (match, tag, attrs) => {
429
+ if (/^(?:script|style|!--)$/i.test(tag))
430
+ return match;
431
+ const isSelfClosing = attrs.trimEnd().endsWith("/"), cleanAttrs = isSelfClosing ? attrs.slice(0, -1) : attrs;
432
+ return `<${tag}${cleanAttrs} ${scopeAttr}${isSelfClosing ? "/" : ""}>`;
433
+ });
434
+ }
435
+ if (mergedConfig.strategy === "prefix" || mergedConfig.strategy === "bem") {
436
+ const prefix = mergedConfig.strategy === "bem" ? componentTag.replace(/[^a-z0-9]/gi, "-") : mergedConfig.prefix || componentTag;
437
+ return html.replace(/\bclass\s*=\s*["']([^"']+)["']/gi, (match, classes) => {
438
+ return `class="${classes.split(/\s+/).map((cls) => {
439
+ if (!cls)
440
+ return cls;
441
+ if (cls.startsWith(prefix))
442
+ return cls;
443
+ return `${prefix}__${cls}`;
444
+ }).join(" ")}"`;
445
+ });
446
+ }
447
+ return html;
448
+ }
449
+ export function getScopeAttribute(componentTag, config = {}) {
450
+ const mergedConfig = { ...defaultCssScopingConfig, ...config }, scopeId = generateScopeId(componentTag);
451
+ return `${mergedConfig.attributeName || "data-v"}-${scopeId}`;
452
+ }
453
+ export function extractAndScopeStyles(html, componentTag, config = {}) {
454
+ let extractedCSS = "";
455
+ const htmlWithoutStyles = html.replace(/<style([^>]*)>([\s\S]*?)<\/style>/gi, (_match, attrs, cssContent) => {
456
+ if (/\bscoped\b/i.test(attrs) || config.strategy !== "shadow")
457
+ extractedCSS += `${scopeCSS(cssContent, componentTag, config)}
458
+ `;
459
+ else
460
+ extractedCSS += `${cssContent}
461
+ `;
462
+ return "";
463
+ });
464
+ return {
465
+ html: scopeHTML(htmlWithoutStyles, componentTag, config),
466
+ css: extractedCSS.trim()
467
+ };
468
+ }
469
+ function camelToKebab(str) {
470
+ return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
471
+ }
472
+ function _kebabToCamel(str) {
473
+ return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
474
+ }
475
+ export function generateReactiveWebComponent(config) {
476
+ const {
477
+ name,
478
+ tag,
479
+ baseElement = "HTMLElement",
480
+ template,
481
+ styles = "",
482
+ shadowDOM = !0,
483
+ properties = {},
484
+ lifecycle = {},
485
+ events = {},
486
+ methods = {},
487
+ state = {}
488
+ } = config, className = name.replace(/\W/g, ""), propertyNames = Object.keys(properties), observedAttributes = propertyNames.filter((prop) => properties[prop].attribute !== !1).map((prop) => properties[prop].attribute || camelToKebab(prop)), propertyDeclarations = propertyNames.map((prop) => {
489
+ const def = properties[prop], defaultValue = def.default !== void 0 ? JSON.stringify(def.default) : def.type === "string" ? '""' : def.type === "number" ? "0" : def.type === "boolean" ? "false" : def.type === "array" ? "[]" : "{}";
490
+ return ` this._${prop} = ${defaultValue};`;
491
+ }).join(`
492
+ `), propertyAccessors = propertyNames.map((prop) => {
493
+ const def = properties[prop], attrName = def.attribute !== !1 ? def.attribute || camelToKebab(prop) : null, reflectCode = def.reflect && attrName ? `
494
+ if (value !== null && value !== undefined) {
495
+ ${def.type === "boolean" ? `if (value) { this.setAttribute('${attrName}', ''); }
496
+ else { this.removeAttribute('${attrName}'); }` : `this.setAttribute('${attrName}', ${def.type === "object" || def.type === "array" ? "JSON.stringify(value)" : "String(value)"});`}
497
+ }
498
+ else {
499
+ this.removeAttribute('${attrName}');
500
+ }` : "", observerCode = def.observer ? `this.${def.observer}(value, oldValue);` : "", renderCode = def.render !== !1 ? "this._scheduleRender();" : "";
501
+ return `
502
+ get ${prop}() {
503
+ return this._${prop};
504
+ }
505
+
506
+ set ${prop}(value) {
507
+ const oldValue = this._${prop};
508
+ if (oldValue === value) return;
509
+ this._${prop} = value;${reflectCode}
510
+ ${observerCode}
511
+ ${renderCode}
512
+ this.dispatchEvent(new CustomEvent('${prop}-changed', {
513
+ detail: { value, oldValue },
514
+ bubbles: true
515
+ }));
516
+ }`;
517
+ }).join(`
518
+ `), attributeChangedCode = observedAttributes.length > 0 ? `
519
+ static get observedAttributes() {
520
+ return [${observedAttributes.map((a) => `'${a}'`).join(", ")}];
521
+ }
522
+
523
+ attributeChangedCallback(name, oldValue, newValue) {
524
+ if (oldValue === newValue) return;
525
+ const propName = this._attrToProp[name];
526
+ if (propName) {
527
+ const propDef = this._propertyDefs[propName];
528
+ this[propName] = this._deserializeAttribute(newValue, propDef.type);
529
+ }
530
+ ${lifecycle.attributeChanged || ""}
531
+ }` : "", eventBindings = Object.entries(events).map(([event, handler]) => {
532
+ return `this._root.addEventListener('${event}', (e) => { ${handler} });`;
533
+ }).join(`
534
+ `), methodDefinitions = Object.entries(methods).map(([methodName, body]) => {
535
+ return `
536
+ ${methodName}() {
537
+ ${body}
538
+ }`;
539
+ }).join(`
540
+ `), propertyDefsMap = JSON.stringify(Object.fromEntries(propertyNames.map((prop) => [prop, properties[prop]]))), attrToPropMap = JSON.stringify(Object.fromEntries(propertyNames.filter((prop) => properties[prop].attribute !== !1).map((prop) => [properties[prop].attribute || camelToKebab(prop), prop]))), escapedTemplate = template.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${"), escapedStyles = styles.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
541
+ return `/**
542
+ * ${name} - Reactive Web Component
543
+ * Auto-generated with reactive properties and lifecycle management
544
+ *
545
+ * @customElement ${tag}
546
+ */
547
+ class ${className} extends ${baseElement} {
548
+ // Property definitions
549
+ _propertyDefs = ${propertyDefsMap};
550
+ _attrToProp = ${attrToPropMap};
551
+
552
+ // Internal state
553
+ _state = ${JSON.stringify(state)};
554
+ _renderPending = false;
555
+ _isConnected = false;
556
+
557
+ constructor() {
558
+ super();
559
+ ${shadowDOM ? 'this.attachShadow({ mode: "open" });' : ""}
560
+ this._root = ${shadowDOM ? "this.shadowRoot" : "this"};
561
+
562
+ // Initialize properties with defaults
563
+ ${propertyDeclarations}
564
+
565
+ // Initial render
566
+ this._render();
567
+ }
568
+
569
+ // =========================================================================
570
+ // Reactive Properties
571
+ // =========================================================================
572
+ ${propertyAccessors}
573
+
574
+ // =========================================================================
575
+ // State Management
576
+ // =========================================================================
577
+
578
+ /**
579
+ * Get current internal state
580
+ */
581
+ get state() {
582
+ return { ...this._state };
583
+ }
584
+
585
+ /**
586
+ * Update internal state and trigger re-render
587
+ * @param {Object} updates - State updates to merge
588
+ */
589
+ setState(updates) {
590
+ const oldState = { ...this._state };
591
+ this._state = { ...this._state, ...updates };
592
+ this._scheduleRender();
593
+ this.dispatchEvent(new CustomEvent('state-changed', {
594
+ detail: { state: this._state, oldState },
595
+ bubbles: true
596
+ }));
597
+ }
598
+
599
+ // =========================================================================
600
+ // Rendering
601
+ // =========================================================================
602
+
603
+ /**
604
+ * Schedule a render on the next animation frame (batched)
605
+ */
606
+ _scheduleRender() {
607
+ if (this._renderPending) return;
608
+ this._renderPending = true;
609
+ requestAnimationFrame(() => {
610
+ this._renderPending = false;
611
+ this._render();
612
+ });
613
+ }
614
+
615
+ /**
616
+ * Render the component template
617
+ */
618
+ _render() {
619
+ const template = \`${escapedStyles ? `<style>${escapedStyles}</style>` : ""}${escapedTemplate}\`;
620
+
621
+ // Interpolate template with property values
622
+ const rendered = template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, propName) => {
623
+ if (propName in this) {
624
+ const value = this[propName];
625
+ if (value === null || value === undefined) return '';
626
+ if (typeof value === 'object') return JSON.stringify(value);
627
+ return String(value);
628
+ }
629
+ if (propName in this._state) {
630
+ const value = this._state[propName];
631
+ if (value === null || value === undefined) return '';
632
+ if (typeof value === 'object') return JSON.stringify(value);
633
+ return String(value);
634
+ }
635
+ return match;
636
+ });
637
+
638
+ this._root.innerHTML = rendered;
639
+ this._bindEvents();
640
+ }
641
+
642
+ /**
643
+ * Bind event handlers after render
644
+ */
645
+ _bindEvents() {
646
+ ${eventBindings}
647
+ }
648
+
649
+ // =========================================================================
650
+ // Attribute Handling
651
+ // =========================================================================
652
+
653
+ /**
654
+ * Deserialize attribute value to property type
655
+ */
656
+ _deserializeAttribute(value, type) {
657
+ if (value === null) return null;
658
+ switch (type) {
659
+ case 'number': return Number(value);
660
+ case 'boolean': return value !== null && value !== 'false' && value !== '0';
661
+ case 'object':
662
+ case 'array':
663
+ try { return JSON.parse(value); }
664
+ catch { return type === 'array' ? [] : {}; }
665
+ default: return value;
666
+ }
667
+ }
668
+
669
+ ${attributeChangedCode}
670
+
671
+ // =========================================================================
672
+ // Lifecycle
673
+ // =========================================================================
674
+
675
+ connectedCallback() {
676
+ this._isConnected = true;
677
+ ${lifecycle.connected || "// Component connected to DOM"}
678
+ }
679
+
680
+ disconnectedCallback() {
681
+ this._isConnected = false;
682
+ ${lifecycle.disconnected || "// Component disconnected from DOM"}
683
+ }
684
+
685
+ adoptedCallback() {
686
+ ${lifecycle.adopted || "// Component moved to new document"}
687
+ }
688
+
689
+ // =========================================================================
690
+ // Custom Methods
691
+ // =========================================================================
692
+ ${methodDefinitions}
693
+ }
694
+
695
+ // Register the custom element
696
+ customElements.define('${tag}', ${className});
697
+
698
+ // Export for module usage
699
+ export { ${className} };
700
+ export default ${className};
701
+ `;
702
+ }
703
+ export function generateReactiveWebComponentTS(config) {
704
+ const {
705
+ name,
706
+ tag,
707
+ baseElement = "HTMLElement",
708
+ template,
709
+ styles = "",
710
+ shadowDOM = !0,
711
+ properties = {},
712
+ lifecycle = {},
713
+ events = {},
714
+ methods = {},
715
+ state = {}
716
+ } = config, className = name.replace(/\W/g, ""), propertyNames = Object.keys(properties), observedAttributes = propertyNames.filter((prop) => properties[prop].attribute !== !1).map((prop) => properties[prop].attribute || camelToKebab(prop)), getTypeScriptType = (type) => {
717
+ switch (type) {
718
+ case "string":
719
+ return "string";
720
+ case "number":
721
+ return "number";
722
+ case "boolean":
723
+ return "boolean";
724
+ case "object":
725
+ return "Record<string, unknown>";
726
+ case "array":
727
+ return "unknown[]";
728
+ default:
729
+ return "unknown";
730
+ }
731
+ }, propsInterface = propertyNames.length > 0 ? `
732
+ /**
733
+ * Props interface for ${name}
734
+ */
735
+ export interface ${className}Props {
736
+ ${propertyNames.map((prop) => ` ${prop}?: ${getTypeScriptType(properties[prop].type)};`).join(`
737
+ `)}
738
+ }
739
+ ` : "", stateInterface = Object.keys(state).length > 0 ? `
740
+ /**
741
+ * State interface for ${name}
742
+ */
743
+ export interface ${className}State {
744
+ ${Object.entries(state).map(([key, value]) => ` ${key}: ${typeof value};`).join(`
745
+ `)}
746
+ }
747
+ ` : `
748
+ export interface ${className}State {
749
+ [key: string]: unknown;
750
+ }
751
+ `, propertyDeclarations = propertyNames.map((prop) => {
752
+ const def = properties[prop], tsType = getTypeScriptType(def.type);
753
+ return ` private _${prop}: ${tsType};`;
754
+ }).join(`
755
+ `), propertyAccessors = propertyNames.map((prop) => {
756
+ const def = properties[prop], tsType = getTypeScriptType(def.type), attrName = def.attribute !== !1 ? def.attribute || camelToKebab(prop) : null, defaultValue = def.default !== void 0 ? JSON.stringify(def.default) : def.type === "string" ? '""' : def.type === "number" ? "0" : def.type === "boolean" ? "false" : def.type === "array" ? "[]" : "{}", reflectCode = def.reflect && attrName ? `
757
+ if (value !== null && value !== undefined) {
758
+ ${def.type === "boolean" ? `if (value) { this.setAttribute('${attrName}', ''); }
759
+ else { this.removeAttribute('${attrName}'); }` : `this.setAttribute('${attrName}', ${def.type === "object" || def.type === "array" ? "JSON.stringify(value)" : "String(value)"});`}
760
+ }
761
+ else {
762
+ this.removeAttribute('${attrName}');
763
+ }` : "", observerCode = def.observer ? `this.${def.observer}(value, oldValue);` : "", renderCode = def.render !== !1 ? "this._scheduleRender();" : "";
764
+ return `
765
+ get ${prop}(): ${tsType} {
766
+ return this._${prop};
767
+ }
768
+
769
+ set ${prop}(value: ${tsType}) {
770
+ const oldValue = this._${prop};
771
+ if (oldValue === value) return;
772
+ this._${prop} = value;${reflectCode}
773
+ ${observerCode}
774
+ ${renderCode}
775
+ this.dispatchEvent(new CustomEvent('${prop}-changed', {
776
+ detail: { value, oldValue },
777
+ bubbles: true
778
+ }));
779
+ }
780
+
781
+ // Property default: ${defaultValue}`;
782
+ }).join(`
783
+ `), attributeChangedCode = observedAttributes.length > 0 ? `
784
+ static get observedAttributes(): string[] {
785
+ return [${observedAttributes.map((a) => `'${a}'`).join(", ")}];
786
+ }
787
+
788
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
789
+ if (oldValue === newValue) return;
790
+ const propName = this._attrToProp[name];
791
+ if (propName) {
792
+ const propDef = this._propertyDefs[propName];
793
+ (this as unknown as Record<string, unknown>)[propName] = this._deserializeAttribute(newValue, propDef.type);
794
+ }
795
+ ${lifecycle.attributeChanged || ""}
796
+ }` : "", eventBindings = Object.entries(events).map(([event, handler]) => {
797
+ return `this._root.addEventListener('${event}', (e: Event) => { ${handler} });`;
798
+ }).join(`
799
+ `), methodDefinitions = Object.entries(methods).map(([methodName, body]) => {
800
+ return `
801
+ ${methodName}(): void {
802
+ ${body}
803
+ }`;
804
+ }).join(`
805
+ `), escapedTemplate = template.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${"), escapedStyles = styles.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
806
+ return `/**
807
+ * ${name} - Reactive Web Component (TypeScript)
808
+ * Auto-generated with reactive properties and lifecycle management
809
+ *
810
+ * @customElement ${tag}
811
+ */
812
+
813
+ ${propsInterface}
814
+ ${stateInterface}
815
+
816
+ /**
817
+ * Property definition type
818
+ */
819
+ interface PropertyDefinition {
820
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
821
+ default?: unknown;
822
+ reflect?: boolean;
823
+ attribute?: string | false;
824
+ observer?: string;
825
+ render?: boolean;
826
+ }
827
+
828
+ /**
829
+ * ${name} custom element
830
+ */
831
+ export class ${className} extends ${baseElement} {
832
+ // Property definitions
833
+ private _propertyDefs: Record<string, PropertyDefinition> = ${JSON.stringify(properties)};
834
+ private _attrToProp: Record<string, string> = ${JSON.stringify(Object.fromEntries(propertyNames.filter((prop) => properties[prop].attribute !== !1).map((prop) => [properties[prop].attribute || camelToKebab(prop), prop])))};
835
+
836
+ // Internal state
837
+ private _state: ${className}State = ${JSON.stringify(state)};
838
+ private _renderPending = false;
839
+ private _isConnected = false;
840
+ private _root: ShadowRoot | HTMLElement;
841
+
842
+ // Property backing fields
843
+ ${propertyDeclarations}
844
+
845
+ constructor() {
846
+ super();
847
+ ${shadowDOM ? 'this.attachShadow({ mode: "open" });' : ""}
848
+ this._root = ${shadowDOM ? "this.shadowRoot!" : "this"};
849
+
850
+ // Initialize properties with defaults
851
+ ${propertyNames.map((prop) => {
852
+ const def = properties[prop], defaultValue = def.default !== void 0 ? JSON.stringify(def.default) : def.type === "string" ? '""' : def.type === "number" ? "0" : def.type === "boolean" ? "false" : def.type === "array" ? "[]" : "{}";
853
+ return ` this._${prop} = ${defaultValue};`;
854
+ }).join(`
855
+ `)}
856
+
857
+ // Initial render
858
+ this._render();
859
+ }
860
+
861
+ // =========================================================================
862
+ // Reactive Properties
863
+ // =========================================================================
864
+ ${propertyAccessors}
865
+
866
+ // =========================================================================
867
+ // State Management
868
+ // =========================================================================
869
+
870
+ /**
871
+ * Get current internal state
872
+ */
873
+ get state(): ${className}State {
874
+ return { ...this._state };
875
+ }
876
+
877
+ /**
878
+ * Update internal state and trigger re-render
879
+ */
880
+ setState(updates: Partial<${className}State>): void {
881
+ const oldState = { ...this._state };
882
+ this._state = { ...this._state, ...updates };
883
+ this._scheduleRender();
884
+ this.dispatchEvent(new CustomEvent('state-changed', {
885
+ detail: { state: this._state, oldState },
886
+ bubbles: true
887
+ }));
888
+ }
889
+
890
+ // =========================================================================
891
+ // Rendering
892
+ // =========================================================================
893
+
894
+ /**
895
+ * Schedule a render on the next animation frame (batched)
896
+ */
897
+ private _scheduleRender(): void {
898
+ if (this._renderPending) return;
899
+ this._renderPending = true;
900
+ requestAnimationFrame(() => {
901
+ this._renderPending = false;
902
+ this._render();
903
+ });
904
+ }
905
+
906
+ /**
907
+ * Render the component template
908
+ */
909
+ private _render(): void {
910
+ const template = \`${escapedStyles ? `<style>${escapedStyles}</style>` : ""}${escapedTemplate}\`;
911
+
912
+ // Interpolate template with property values
913
+ const rendered = template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, propName) => {
914
+ if (propName in this) {
915
+ const value = (this as unknown as Record<string, unknown>)[propName];
916
+ if (value === null || value === undefined) return '';
917
+ if (typeof value === 'object') return JSON.stringify(value);
918
+ return String(value);
919
+ }
920
+ if (propName in this._state) {
921
+ const value = this._state[propName as keyof ${className}State];
922
+ if (value === null || value === undefined) return '';
923
+ if (typeof value === 'object') return JSON.stringify(value);
924
+ return String(value);
925
+ }
926
+ return match;
927
+ });
928
+
929
+ this._root.innerHTML = rendered;
930
+ this._bindEvents();
931
+ }
932
+
933
+ /**
934
+ * Bind event handlers after render
935
+ */
936
+ private _bindEvents(): void {
937
+ ${eventBindings}
938
+ }
939
+
940
+ // =========================================================================
941
+ // Attribute Handling
942
+ // =========================================================================
943
+
944
+ /**
945
+ * Deserialize attribute value to property type
946
+ */
947
+ private _deserializeAttribute(value: string | null, type: string): unknown {
948
+ if (value === null) return null;
949
+ switch (type) {
950
+ case 'number': return Number(value);
951
+ case 'boolean': return value !== null && value !== 'false' && value !== '0';
952
+ case 'object':
953
+ case 'array':
954
+ try { return JSON.parse(value); }
955
+ catch { return type === 'array' ? [] : {}; }
956
+ default: return value;
957
+ }
958
+ }
959
+
960
+ ${attributeChangedCode}
961
+
962
+ // =========================================================================
963
+ // Lifecycle
964
+ // =========================================================================
965
+
966
+ connectedCallback(): void {
967
+ this._isConnected = true;
968
+ ${lifecycle.connected || "// Component connected to DOM"}
969
+ }
970
+
971
+ disconnectedCallback(): void {
972
+ this._isConnected = false;
973
+ ${lifecycle.disconnected || "// Component disconnected from DOM"}
974
+ }
975
+
976
+ adoptedCallback(): void {
977
+ ${lifecycle.adopted || "// Component moved to new document"}
978
+ }
979
+
980
+ // =========================================================================
981
+ // Custom Methods
982
+ // =========================================================================
983
+ ${methodDefinitions}
984
+ }
985
+
986
+ // Type augmentation for HTMLElementTagNameMap
987
+ declare global {
988
+ interface HTMLElementTagNameMap {
989
+ '${tag}': ${className};
990
+ }
991
+ }
992
+
993
+ // Register the custom element
994
+ customElements.define('${tag}', ${className});
995
+
996
+ export default ${className};
997
+ `;
998
+ }
999
+ export function generateReactiveMixin() {
1000
+ return `/**
1001
+ * ReactiveElement Mixin
1002
+ * Adds reactive properties and lifecycle management to web components
1003
+ */
1004
+ const ReactiveElement = (Base) => class extends Base {
1005
+ static get observedAttributes() {
1006
+ const props = this.properties || {};
1007
+ return Object.keys(props)
1008
+ .filter(prop => props[prop].attribute !== false)
1009
+ .map(prop => props[prop].attribute || prop.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase());
1010
+ }
1011
+
1012
+ constructor() {
1013
+ super();
1014
+ this._state = {};
1015
+ this._renderPending = false;
1016
+ this._propertyValues = new Map();
1017
+ this._initializeProperties();
1018
+ }
1019
+
1020
+ _initializeProperties() {
1021
+ const props = this.constructor.properties || {};
1022
+ for (const [name, def] of Object.entries(props)) {
1023
+ // Set default value
1024
+ if (def.default !== undefined) {
1025
+ this._propertyValues.set(name, def.default);
1026
+ }
1027
+
1028
+ // Define getter/setter
1029
+ Object.defineProperty(this, name, {
1030
+ get: () => this._propertyValues.get(name),
1031
+ set: (value) => {
1032
+ const oldValue = this._propertyValues.get(name);
1033
+ if (oldValue === value) return;
1034
+ this._propertyValues.set(name, value);
1035
+
1036
+ // Reflect to attribute
1037
+ if (def.reflect) {
1038
+ const attrName = def.attribute || name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
1039
+ if (def.type === 'boolean') {
1040
+ value ? this.setAttribute(attrName, '') : this.removeAttribute(attrName);
1041
+ }
1042
+ else {
1043
+ this.setAttribute(attrName, def.type === 'object' ? JSON.stringify(value) : String(value));
1044
+ }
1045
+ }
1046
+
1047
+ // Call observer
1048
+ if (def.observer && typeof this[def.observer] === 'function') {
1049
+ this[def.observer](value, oldValue);
1050
+ }
1051
+
1052
+ // Schedule render
1053
+ if (def.render !== false) {
1054
+ this._scheduleRender();
1055
+ }
1056
+
1057
+ // Dispatch event
1058
+ this.dispatchEvent(new CustomEvent(\`\${name}-changed\`, {
1059
+ detail: { value, oldValue },
1060
+ bubbles: true
1061
+ }));
1062
+ },
1063
+ enumerable: true,
1064
+ configurable: true
1065
+ });
1066
+ }
1067
+ }
1068
+
1069
+ attributeChangedCallback(name, oldValue, newValue) {
1070
+ if (oldValue === newValue) return;
1071
+ const props = this.constructor.properties || {};
1072
+ const propName = Object.keys(props).find(p =>
1073
+ (props[p].attribute || p.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()) === name
1074
+ );
1075
+ if (propName) {
1076
+ const def = props[propName];
1077
+ this[propName] = this._deserialize(newValue, def.type);
1078
+ }
1079
+ }
1080
+
1081
+ _deserialize(value, type) {
1082
+ if (value === null) return null;
1083
+ switch (type) {
1084
+ case 'number': return Number(value);
1085
+ case 'boolean': return value !== null && value !== 'false';
1086
+ case 'object':
1087
+ case 'array':
1088
+ try { return JSON.parse(value); }
1089
+ catch { return type === 'array' ? [] : {}; }
1090
+ default: return value;
1091
+ }
1092
+ }
1093
+
1094
+ get state() {
1095
+ return { ...this._state };
1096
+ }
1097
+
1098
+ setState(updates) {
1099
+ const oldState = { ...this._state };
1100
+ this._state = { ...this._state, ...updates };
1101
+ this._scheduleRender();
1102
+ this.dispatchEvent(new CustomEvent('state-changed', {
1103
+ detail: { state: this._state, oldState },
1104
+ bubbles: true
1105
+ }));
1106
+ }
1107
+
1108
+ _scheduleRender() {
1109
+ if (this._renderPending) return;
1110
+ this._renderPending = true;
1111
+ requestAnimationFrame(() => {
1112
+ this._renderPending = false;
1113
+ if (typeof this.render === 'function') {
1114
+ this.render();
1115
+ }
1116
+ });
1117
+ }
1118
+ };
1119
+
1120
+ export { ReactiveElement };
1121
+ export default ReactiveElement;
1122
+ `;
1123
+ }
1124
+ export function generateReactiveRuntime() {
1125
+ return `/**
1126
+ * stx Reactive Web Components Runtime
1127
+ * Provides base classes and utilities for reactive web components
1128
+ */
1129
+ (function(global) {
1130
+ 'use strict';
1131
+
1132
+ /**
1133
+ * Base class for reactive web components
1134
+ */
1135
+ class StxElement extends HTMLElement {
1136
+ static get observedAttributes() {
1137
+ const props = this.properties || {};
1138
+ return Object.keys(props)
1139
+ .filter(prop => props[prop].attribute !== false)
1140
+ .map(prop => props[prop].attribute || toKebabCase(prop));
1141
+ }
1142
+
1143
+ constructor() {
1144
+ super();
1145
+ this._state = {};
1146
+ this._renderPending = false;
1147
+ this._props = new Map();
1148
+ this._setupShadowDOM();
1149
+ this._initProperties();
1150
+ }
1151
+
1152
+ _setupShadowDOM() {
1153
+ if (this.constructor.useShadowDOM !== false) {
1154
+ this.attachShadow({ mode: 'open' });
1155
+ this._root = this.shadowRoot;
1156
+ }
1157
+ else {
1158
+ this._root = this;
1159
+ }
1160
+ }
1161
+
1162
+ _initProperties() {
1163
+ const props = this.constructor.properties || {};
1164
+ for (const [name, def] of Object.entries(props)) {
1165
+ let value = def.default;
1166
+ this._props.set(name, value);
1167
+
1168
+ Object.defineProperty(this, name, {
1169
+ get: () => this._props.get(name),
1170
+ set: (newValue) => this._setProperty(name, newValue, def),
1171
+ enumerable: true
1172
+ });
1173
+ }
1174
+ }
1175
+
1176
+ _setProperty(name, value, def) {
1177
+ const oldValue = this._props.get(name);
1178
+ if (oldValue === value) return;
1179
+
1180
+ this._props.set(name, value);
1181
+
1182
+ if (def.reflect && def.attribute !== false) {
1183
+ this._reflectToAttribute(name, value, def);
1184
+ }
1185
+
1186
+ if (def.observer && this[def.observer]) {
1187
+ this[def.observer](value, oldValue);
1188
+ }
1189
+
1190
+ if (def.render !== false) {
1191
+ this.requestUpdate();
1192
+ }
1193
+
1194
+ this.dispatchEvent(new CustomEvent(name + '-changed', {
1195
+ detail: { value, oldValue },
1196
+ bubbles: true,
1197
+ composed: true
1198
+ }));
1199
+ }
1200
+
1201
+ _reflectToAttribute(name, value, def) {
1202
+ const attrName = def.attribute || toKebabCase(name);
1203
+ if (value == null || (def.type === 'boolean' && !value)) {
1204
+ this.removeAttribute(attrName);
1205
+ }
1206
+ else if (def.type === 'boolean') {
1207
+ this.setAttribute(attrName, '');
1208
+ }
1209
+ else if (def.type === 'object' || def.type === 'array') {
1210
+ this.setAttribute(attrName, JSON.stringify(value));
1211
+ }
1212
+ else {
1213
+ this.setAttribute(attrName, String(value));
1214
+ }
1215
+ }
1216
+
1217
+ attributeChangedCallback(name, oldValue, newValue) {
1218
+ if (oldValue === newValue) return;
1219
+ const props = this.constructor.properties || {};
1220
+ const propName = Object.keys(props).find(p => {
1221
+ const def = props[p];
1222
+ return (def.attribute || toKebabCase(p)) === name;
1223
+ });
1224
+
1225
+ if (propName) {
1226
+ const def = props[propName];
1227
+ this[propName] = deserialize(newValue, def.type);
1228
+ }
1229
+ }
1230
+
1231
+ get state() {
1232
+ return { ...this._state };
1233
+ }
1234
+
1235
+ setState(updates) {
1236
+ const oldState = { ...this._state };
1237
+ Object.assign(this._state, updates);
1238
+ this.requestUpdate();
1239
+ this.dispatchEvent(new CustomEvent('state-changed', {
1240
+ detail: { state: this._state, oldState },
1241
+ bubbles: true
1242
+ }));
1243
+ }
1244
+
1245
+ requestUpdate() {
1246
+ if (this._renderPending) return;
1247
+ this._renderPending = true;
1248
+ requestAnimationFrame(() => {
1249
+ this._renderPending = false;
1250
+ this.update();
1251
+ });
1252
+ }
1253
+
1254
+ update() {
1255
+ if (this.render) {
1256
+ const content = this.render();
1257
+ if (typeof content === 'string') {
1258
+ this._root.innerHTML = content;
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ connectedCallback() {
1264
+ this.update();
1265
+ if (this.connected) this.connected();
1266
+ }
1267
+
1268
+ disconnectedCallback() {
1269
+ if (this.disconnected) this.disconnected();
1270
+ }
1271
+
1272
+ adoptedCallback() {
1273
+ if (this.adopted) this.adopted();
1274
+ }
1275
+
1276
+ // Template helper
1277
+ html(strings, ...values) {
1278
+ return strings.reduce((result, str, i) => {
1279
+ let value = values[i] || '';
1280
+ if (Array.isArray(value)) value = value.join('');
1281
+ if (typeof value === 'object') value = JSON.stringify(value);
1282
+ return result + str + value;
1283
+ }, '');
1284
+ }
1285
+ }
1286
+
1287
+ // Utility functions
1288
+ function toKebabCase(str) {
1289
+ return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
1290
+ }
1291
+
1292
+ function deserialize(value, type) {
1293
+ if (value === null) return null;
1294
+ switch (type) {
1295
+ case 'number': return Number(value);
1296
+ case 'boolean': return value !== null && value !== 'false' && value !== '0';
1297
+ case 'object':
1298
+ case 'array':
1299
+ try { return JSON.parse(value); }
1300
+ catch { return type === 'array' ? [] : {}; }
1301
+ default: return value;
1302
+ }
1303
+ }
1304
+
1305
+ // Export to global
1306
+ global.StxElement = StxElement;
1307
+ global.stxComponents = global.stxComponents || {};
1308
+
1309
+ // Helper to define components
1310
+ global.defineStxComponent = function(tag, config) {
1311
+ const { properties, template, styles, methods, ...options } = config;
1312
+
1313
+ class Component extends StxElement {
1314
+ static get properties() { return properties || {}; }
1315
+ static get useShadowDOM() { return options.shadowDOM !== false; }
1316
+
1317
+ render() {
1318
+ let html = template || '';
1319
+ // Simple interpolation
1320
+ html = html.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, key) => {
1321
+ if (key in this) return this[key] ?? '';
1322
+ if (key in this._state) return this._state[key] ?? '';
1323
+ return match;
1324
+ });
1325
+ return (styles ? '<style>' + styles + '</style>' : '') + html;
1326
+ }
1327
+ }
1328
+
1329
+ // Add methods
1330
+ if (methods) {
1331
+ for (const [name, fn] of Object.entries(methods)) {
1332
+ Component.prototype[name] = fn;
1333
+ }
1334
+ }
1335
+
1336
+ customElements.define(tag, Component);
1337
+ global.stxComponents[tag] = Component;
1338
+ return Component;
1339
+ };
1340
+
1341
+ })(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);
1342
+ `;
1343
+ }
1344
+ export function parseSFCComponent(source, defaultTag) {
1345
+ const scriptMatch = source.match(/<script\b[^>]*>([\s\S]*?)<\/script>/i), scriptContent = scriptMatch ? scriptMatch[1].trim() : "";
1346
+ let tag = defaultTag, props = [], shadowDOM = !0;
1347
+ if (scriptContent) {
1348
+ const exportMatch = scriptContent.match(/export\s+default\s+({[\s\S]*})/);
1349
+ if (exportMatch)
1350
+ try {
1351
+ const configStr = exportMatch[1], tagMatch = configStr.match(/tag\s*:\s*['"`]([^'"`]+)['"`]/);
1352
+ if (tagMatch)
1353
+ tag = tagMatch[1];
1354
+ const propsMatch = configStr.match(/props\s*:\s*\[([\s\S]*?)\]/);
1355
+ if (propsMatch)
1356
+ props = propsMatch[1].split(",").map((p) => p.trim().replace(/['"`]/g, "")).filter((p) => p.length > 0);
1357
+ const shadowMatch = configStr.match(/shadowDOM\s*:\s*(true|false)/);
1358
+ if (shadowMatch)
1359
+ shadowDOM = shadowMatch[1] === "true";
1360
+ } catch {}
1361
+ }
1362
+ const templateMatch = source.match(/<template\b(?![^>]*\bid\s*=)[^>]*>([\s\S]*?)<\/template>/i), template = templateMatch ? templateMatch[1].trim() : "", styleMatch = source.match(/<style\b[^>]*>([\s\S]*?)<\/style>/i), styles = styleMatch ? styleMatch[1].trim() : "";
1363
+ return {
1364
+ tag,
1365
+ props,
1366
+ template,
1367
+ styles,
1368
+ script: scriptContent,
1369
+ shadowDOM
1370
+ };
1371
+ }
1372
+ export function generateSFCWebComponent(parsed) {
1373
+ const { tag, props, template, styles, shadowDOM } = parsed, className = tag.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(""), escapedTemplate = template.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${"), escapedStyles = styles.replace(/\\/g, "\\\\").replace(/`/g, "\\`"), observedAttrs = props.map((p) => `'${p}'`).join(", "), propertyAccessors = props.map((prop) => `
1374
+ get ${prop}() {
1375
+ return this.getAttribute('${prop}') || '';
1376
+ }
1377
+ set ${prop}(value) {
1378
+ if (value) {
1379
+ this.setAttribute('${prop}', value);
1380
+ }
1381
+ else {
1382
+ this.removeAttribute('${prop}');
1383
+ }
1384
+ }`).join(`
1385
+ `);
1386
+ return `/**
1387
+ * ${className} Web Component
1388
+ * Auto-generated from SFC
1389
+ */
1390
+ class ${className} extends HTMLElement {
1391
+ constructor() {
1392
+ super();
1393
+ ${shadowDOM ? "this.attachShadow({ mode: 'open' });" : ""}
1394
+ this._render();
1395
+ }
1396
+
1397
+ static get observedAttributes() {
1398
+ return [${observedAttrs}];
1399
+ }
1400
+
1401
+ attributeChangedCallback(name, oldValue, newValue) {
1402
+ if (oldValue !== newValue) {
1403
+ this._render();
1404
+ }
1405
+ }
1406
+ ${propertyAccessors}
1407
+
1408
+ _render() {
1409
+ const template = \`${escapedStyles ? `<style>${escapedStyles}</style>` : ""}${escapedTemplate}\`;
1410
+
1411
+ // Interpolate {{ prop }} with attribute values
1412
+ const rendered = template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, prop) => {
1413
+ return this.getAttribute(prop) || '';
1414
+ });
1415
+
1416
+ ${shadowDOM ? "this.shadowRoot.innerHTML = rendered;" : "this.innerHTML = rendered;"}
1417
+ }
1418
+
1419
+ connectedCallback() {
1420
+ this._render();
1421
+ }
1422
+ }
1423
+
1424
+ customElements.define('${tag}', ${className});
1425
+ `;
1426
+ }
1427
+ export async function webComponentDirectiveHandler(content, params, context, filePath) {
1428
+ if (params.length < 1)
1429
+ return inlineError("WebComponent", "@webcomponent directive requires at least the tag name parameter", ErrorCodes.INVALID_DIRECTIVE_SYNTAX);
1430
+ const tagName = params[0].replace(/['"]/g, ""), componentsDir = (context.__stx_options || {}).componentsDir || "components", possiblePaths = [
1431
+ path.join(path.dirname(filePath), componentsDir, `${tagName}.stx`),
1432
+ path.join(process.cwd(), componentsDir, `${tagName}.stx`),
1433
+ path.join(path.dirname(filePath), `${tagName}.stx`)
1434
+ ];
1435
+ let componentSource = null;
1436
+ for (const componentPath of possiblePaths)
1437
+ if (await fileExists(componentPath)) {
1438
+ componentSource = await Bun.file(componentPath).text();
1439
+ break;
1440
+ }
1441
+ if (!componentSource)
1442
+ return inlineError("WebComponent", `Component file not found: ${tagName}.stx`, ErrorCodes.FILE_NOT_FOUND);
1443
+ const parsed = parseSFCComponent(componentSource, tagName);
1444
+ return `<script type="module">
1445
+ ${generateSFCWebComponent(parsed)}
1446
+ </script>`;
1447
+ }