@zeix/le-truc 0.15.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 (406) hide show
  1. package/.ai-context.md +234 -0
  2. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
  3. package/.editorconfig +12 -0
  4. package/.github/copilot-instructions.md +62 -0
  5. package/.github/workflows/codeql.yml +108 -0
  6. package/.github/workflows/static.yml +43 -0
  7. package/.prettierrc +17 -0
  8. package/CLAUDE.md +215 -0
  9. package/CODE_OF_CONDUCT.md +128 -0
  10. package/CONTRIBUTING.md +160 -0
  11. package/LICENSE +21 -0
  12. package/README.md +474 -0
  13. package/biome.json +295 -0
  14. package/bun.lock +239 -0
  15. package/docs/about.html +105 -0
  16. package/docs/assets/main.css +1 -0
  17. package/docs/assets/main.js +10 -0
  18. package/docs/assets/main.js.map +66 -0
  19. package/docs/components.html +293 -0
  20. package/docs/data-flow.html +308 -0
  21. package/docs/examples/basic-button.html +367 -0
  22. package/docs/examples/basic-counter.html +188 -0
  23. package/docs/examples/basic-hello.html +138 -0
  24. package/docs/examples/basic-number.html +271 -0
  25. package/docs/examples/basic-pluralize.html +214 -0
  26. package/docs/examples/card-callout.html +152 -0
  27. package/docs/examples/card-mediaqueries.html +138 -0
  28. package/docs/examples/context-media.html +198 -0
  29. package/docs/examples/empty.html +37 -0
  30. package/docs/examples/form-checkbox.html +233 -0
  31. package/docs/examples/form-combobox.html +420 -0
  32. package/docs/examples/form-listbox.html +434 -0
  33. package/docs/examples/form-radiogroup.html +296 -0
  34. package/docs/examples/form-spinbutton.html +402 -0
  35. package/docs/examples/form-textbox.html +361 -0
  36. package/docs/examples/layout.html +67 -0
  37. package/docs/examples/module-carousel.html +552 -0
  38. package/docs/examples/module-catalog.html +241 -0
  39. package/docs/examples/module-codeblock.html +270 -0
  40. package/docs/examples/module-dialog.html +343 -0
  41. package/docs/examples/module-lazyload.html +289 -0
  42. package/docs/examples/module-list.html +197 -0
  43. package/docs/examples/module-pagination.html +283 -0
  44. package/docs/examples/module-scrollarea.html +447 -0
  45. package/docs/examples/module-tabgroup.html +526 -0
  46. package/docs/examples/module-todo.html +367 -0
  47. package/docs/examples/module-with-type.html +63 -0
  48. package/docs/examples/nested-components.html +88 -0
  49. package/docs/examples/recursive.html +56 -0
  50. package/docs/examples/simple-text.html +39 -0
  51. package/docs/examples/snippet.html +93 -0
  52. package/docs/examples/with-styles.html +75 -0
  53. package/docs/getting-started.html +143 -0
  54. package/docs/index.html +112 -0
  55. package/docs/sitemap.xml +28 -0
  56. package/docs/styling.html +160 -0
  57. package/docs/sw.js +112 -0
  58. package/docs-src/api/README.md +478 -0
  59. package/docs-src/api/_media/LICENSE +21 -0
  60. package/docs-src/api/classes/CircularDependencyError.md +299 -0
  61. package/docs-src/api/classes/CircularMutationError.md +301 -0
  62. package/docs-src/api/classes/ContextRequestEvent.md +590 -0
  63. package/docs-src/api/classes/DependencyTimeoutError.md +301 -0
  64. package/docs-src/api/classes/InvalidCallbackError.md +303 -0
  65. package/docs-src/api/classes/InvalidComponentNameError.md +295 -0
  66. package/docs-src/api/classes/InvalidCustomElementError.md +301 -0
  67. package/docs-src/api/classes/InvalidEffectsError.md +301 -0
  68. package/docs-src/api/classes/InvalidPropertyNameError.md +307 -0
  69. package/docs-src/api/classes/InvalidReactivesError.md +307 -0
  70. package/docs-src/api/classes/InvalidSignalValueError.md +303 -0
  71. package/docs-src/api/classes/MissingElementError.md +307 -0
  72. package/docs-src/api/classes/NullishSignalValueError.md +299 -0
  73. package/docs-src/api/classes/StoreKeyExistsError.md +303 -0
  74. package/docs-src/api/classes/StoreKeyRangeError.md +299 -0
  75. package/docs-src/api/classes/StoreKeyReadonlyError.md +303 -0
  76. package/docs-src/api/functions/asBoolean.md +21 -0
  77. package/docs-src/api/functions/asEnum.md +31 -0
  78. package/docs-src/api/functions/asInteger.md +39 -0
  79. package/docs-src/api/functions/asJSON.md +49 -0
  80. package/docs-src/api/functions/asNumber.md +37 -0
  81. package/docs-src/api/functions/asString.md +37 -0
  82. package/docs-src/api/functions/createCollection.md +83 -0
  83. package/docs-src/api/functions/createSensor.md +71 -0
  84. package/docs-src/api/functions/dangerouslySetInnerHTML.md +48 -0
  85. package/docs-src/api/functions/defineComponent.md +65 -0
  86. package/docs-src/api/functions/isCollection.md +37 -0
  87. package/docs-src/api/functions/isParser.md +41 -0
  88. package/docs-src/api/functions/match.md +47 -0
  89. package/docs-src/api/functions/on.md +58 -0
  90. package/docs-src/api/functions/pass.md +53 -0
  91. package/docs-src/api/functions/provideContexts.md +47 -0
  92. package/docs-src/api/functions/read.md +47 -0
  93. package/docs-src/api/functions/requestContext.md +51 -0
  94. package/docs-src/api/functions/resolve.md +40 -0
  95. package/docs-src/api/functions/runEffects.md +51 -0
  96. package/docs-src/api/functions/runElementEffects.md +57 -0
  97. package/docs-src/api/functions/schedule.md +33 -0
  98. package/docs-src/api/functions/setAttribute.md +48 -0
  99. package/docs-src/api/functions/setProperty.md +52 -0
  100. package/docs-src/api/functions/setStyle.md +48 -0
  101. package/docs-src/api/functions/setText.md +42 -0
  102. package/docs-src/api/functions/show.md +42 -0
  103. package/docs-src/api/functions/toSignal.md +37 -0
  104. package/docs-src/api/functions/toggleAttribute.md +48 -0
  105. package/docs-src/api/functions/toggleClass.md +48 -0
  106. package/docs-src/api/functions/updateElement.md +53 -0
  107. package/docs-src/api/globals.md +131 -0
  108. package/docs-src/api/type-aliases/Cleanup.md +27 -0
  109. package/docs-src/api/type-aliases/Collection.md +91 -0
  110. package/docs-src/api/type-aliases/CollectionListener.md +27 -0
  111. package/docs-src/api/type-aliases/Component.md +17 -0
  112. package/docs-src/api/type-aliases/ComponentProp.md +11 -0
  113. package/docs-src/api/type-aliases/ComponentProps.md +11 -0
  114. package/docs-src/api/type-aliases/ComponentSetup.md +31 -0
  115. package/docs-src/api/type-aliases/ComponentUI.md +27 -0
  116. package/docs-src/api/type-aliases/Computed.md +49 -0
  117. package/docs-src/api/type-aliases/ComputedCallback.md +29 -0
  118. package/docs-src/api/type-aliases/Context.md +33 -0
  119. package/docs-src/api/type-aliases/ContextType.md +19 -0
  120. package/docs-src/api/type-aliases/DangerouslySetInnerHTMLOptions.md +27 -0
  121. package/docs-src/api/type-aliases/DiffResult.md +61 -0
  122. package/docs-src/api/type-aliases/Effect.md +35 -0
  123. package/docs-src/api/type-aliases/EffectCallback.md +23 -0
  124. package/docs-src/api/type-aliases/Effects.md +21 -0
  125. package/docs-src/api/type-aliases/ElementEffects.md +21 -0
  126. package/docs-src/api/type-aliases/ElementFromKey.md +21 -0
  127. package/docs-src/api/type-aliases/ElementQueries.md +27 -0
  128. package/docs-src/api/type-aliases/ElementUpdater.md +131 -0
  129. package/docs-src/api/type-aliases/EventHandler.md +31 -0
  130. package/docs-src/api/type-aliases/EventType.md +17 -0
  131. package/docs-src/api/type-aliases/Fallback.md +21 -0
  132. package/docs-src/api/type-aliases/Initializers.md +21 -0
  133. package/docs-src/api/type-aliases/LooseReader.md +31 -0
  134. package/docs-src/api/type-aliases/MatchHandlers.md +77 -0
  135. package/docs-src/api/type-aliases/MaybeCleanup.md +23 -0
  136. package/docs-src/api/type-aliases/MaybeSignal.md +17 -0
  137. package/docs-src/api/type-aliases/Parser.md +39 -0
  138. package/docs-src/api/type-aliases/ParserOrFallback.md +21 -0
  139. package/docs-src/api/type-aliases/PassedProp.md +25 -0
  140. package/docs-src/api/type-aliases/PassedProps.md +21 -0
  141. package/docs-src/api/type-aliases/Reactive.md +25 -0
  142. package/docs-src/api/type-aliases/Reader.md +31 -0
  143. package/docs-src/api/type-aliases/ReservedWords.md +11 -0
  144. package/docs-src/api/type-aliases/ResolveResult.md +29 -0
  145. package/docs-src/api/type-aliases/SensorEvents.md +25 -0
  146. package/docs-src/api/type-aliases/Signal.md +41 -0
  147. package/docs-src/api/type-aliases/State.md +85 -0
  148. package/docs-src/api/type-aliases/Store.md +29 -0
  149. package/docs-src/api/type-aliases/UI.md +11 -0
  150. package/docs-src/api/type-aliases/UnknownContext.md +13 -0
  151. package/docs-src/api/variables/CONTEXT_REQUEST.md +11 -0
  152. package/docs-src/api/variables/UNSET.md +23 -0
  153. package/docs-src/api/variables/batch.md +25 -0
  154. package/docs-src/api/variables/createComputed.md +41 -0
  155. package/docs-src/api/variables/createEffect.md +35 -0
  156. package/docs-src/api/variables/createState.md +37 -0
  157. package/docs-src/api/variables/createStore.md +42 -0
  158. package/docs-src/api/variables/diff.md +43 -0
  159. package/docs-src/api/variables/isAbortError.md +33 -0
  160. package/docs-src/api/variables/isAsyncFunction.md +39 -0
  161. package/docs-src/api/variables/isComputed.md +37 -0
  162. package/docs-src/api/variables/isEqual.md +49 -0
  163. package/docs-src/api/variables/isFunction.md +39 -0
  164. package/docs-src/api/variables/isMutableSignal.md +37 -0
  165. package/docs-src/api/variables/isNumber.md +33 -0
  166. package/docs-src/api/variables/isRecord.md +39 -0
  167. package/docs-src/api/variables/isRecordOrArray.md +39 -0
  168. package/docs-src/api/variables/isSignal.md +37 -0
  169. package/docs-src/api/variables/isState.md +37 -0
  170. package/docs-src/api/variables/isStore.md +37 -0
  171. package/docs-src/api/variables/isString.md +33 -0
  172. package/docs-src/api/variables/isSymbol.md +33 -0
  173. package/docs-src/api/variables/toError.md +33 -0
  174. package/docs-src/api/variables/valueString.md +33 -0
  175. package/docs-src/includes/menu.html +44 -0
  176. package/docs-src/pages/about.md +89 -0
  177. package/docs-src/pages/components.md +437 -0
  178. package/docs-src/pages/data-flow.md +449 -0
  179. package/docs-src/pages/getting-started.md +170 -0
  180. package/docs-src/pages/index.md +98 -0
  181. package/docs-src/pages/styling.md +165 -0
  182. package/eslint.config.js +64 -0
  183. package/examples/_common/clear.ts +49 -0
  184. package/examples/_common/fetch.ts +160 -0
  185. package/examples/_common/focus.ts +45 -0
  186. package/examples/_common/highlight.ts +5 -0
  187. package/examples/_global.css +463 -0
  188. package/examples/basic-button/basic-button.css +176 -0
  189. package/examples/basic-button/basic-button.html +46 -0
  190. package/examples/basic-button/basic-button.spec.ts +160 -0
  191. package/examples/basic-button/basic-button.ts +45 -0
  192. package/examples/basic-button/copyToClipboard.ts +37 -0
  193. package/examples/basic-counter/basic-counter.css +21 -0
  194. package/examples/basic-counter/basic-counter.html +24 -0
  195. package/examples/basic-counter/basic-counter.spec.ts +85 -0
  196. package/examples/basic-counter/basic-counter.ts +43 -0
  197. package/examples/basic-hello/basic-hello.html +34 -0
  198. package/examples/basic-hello/basic-hello.spec.ts +110 -0
  199. package/examples/basic-hello/basic-hello.ts +36 -0
  200. package/examples/basic-number/basic-number.html +79 -0
  201. package/examples/basic-number/basic-number.spec.ts +175 -0
  202. package/examples/basic-number/basic-number.ts +124 -0
  203. package/examples/basic-pluralize/basic-pluralize.html +64 -0
  204. package/examples/basic-pluralize/basic-pluralize.spec.ts +258 -0
  205. package/examples/basic-pluralize/basic-pluralize.ts +82 -0
  206. package/examples/card-callout/card-callout.css +79 -0
  207. package/examples/card-callout/card-callout.html +5 -0
  208. package/examples/card-mediaqueries/card-mediaqueries.html +29 -0
  209. package/examples/card-mediaqueries/card-mediaqueries.spec.ts +300 -0
  210. package/examples/card-mediaqueries/card-mediaqueries.ts +41 -0
  211. package/examples/context-media/context-media.html +3 -0
  212. package/examples/context-media/context-media.ts +127 -0
  213. package/examples/form-checkbox/form-checkbox.css +70 -0
  214. package/examples/form-checkbox/form-checkbox.html +13 -0
  215. package/examples/form-checkbox/form-checkbox.spec.ts +357 -0
  216. package/examples/form-checkbox/form-checkbox.ts +50 -0
  217. package/examples/form-checkbox/vanilla-checkbox.ts +101 -0
  218. package/examples/form-combobox/form-combobox.css +118 -0
  219. package/examples/form-combobox/form-combobox.html +74 -0
  220. package/examples/form-combobox/form-combobox.spec.ts +977 -0
  221. package/examples/form-combobox/form-combobox.ts +128 -0
  222. package/examples/form-listbox/form-listbox.css +71 -0
  223. package/examples/form-listbox/form-listbox.html +67 -0
  224. package/examples/form-listbox/form-listbox.spec.ts +1050 -0
  225. package/examples/form-listbox/form-listbox.ts +196 -0
  226. package/examples/form-listbox/mocks/timezones.json +495 -0
  227. package/examples/form-radiogroup/form-radiogroup.css +87 -0
  228. package/examples/form-radiogroup/form-radiogroup.html +51 -0
  229. package/examples/form-radiogroup/form-radiogroup.spec.ts +515 -0
  230. package/examples/form-radiogroup/form-radiogroup.ts +58 -0
  231. package/examples/form-spinbutton/form-spinbutton.css +95 -0
  232. package/examples/form-spinbutton/form-spinbutton.html +96 -0
  233. package/examples/form-spinbutton/form-spinbutton.spec.ts +688 -0
  234. package/examples/form-spinbutton/form-spinbutton.ts +111 -0
  235. package/examples/form-textbox/form-textbox.css +104 -0
  236. package/examples/form-textbox/form-textbox.html +53 -0
  237. package/examples/form-textbox/form-textbox.spec.ts +542 -0
  238. package/examples/form-textbox/form-textbox.ts +104 -0
  239. package/examples/main.css +22 -0
  240. package/examples/main.ts +23 -0
  241. package/examples/module-carousel/module-carousel.css +113 -0
  242. package/examples/module-carousel/module-carousel.html +208 -0
  243. package/examples/module-carousel/module-carousel.spec.ts +523 -0
  244. package/examples/module-carousel/module-carousel.ts +131 -0
  245. package/examples/module-catalog/module-catalog.css +22 -0
  246. package/examples/module-catalog/module-catalog.html +82 -0
  247. package/examples/module-catalog/module-catalog.spec.ts +396 -0
  248. package/examples/module-catalog/module-catalog.ts +37 -0
  249. package/examples/module-codeblock/module-codeblock.css +95 -0
  250. package/examples/module-codeblock/module-codeblock.html +28 -0
  251. package/examples/module-codeblock/module-codeblock.ts +47 -0
  252. package/examples/module-demo/module-demo.css +13 -0
  253. package/examples/module-dialog/module-dialog.css +96 -0
  254. package/examples/module-dialog/module-dialog.html +66 -0
  255. package/examples/module-dialog/module-dialog.spec.ts +557 -0
  256. package/examples/module-dialog/module-dialog.ts +81 -0
  257. package/examples/module-lazyload/mocks/empty.html +1 -0
  258. package/examples/module-lazyload/mocks/module-with-type.html +27 -0
  259. package/examples/module-lazyload/mocks/nested-components.html +52 -0
  260. package/examples/module-lazyload/mocks/recursive.html +20 -0
  261. package/examples/module-lazyload/mocks/simple-text.html +3 -0
  262. package/examples/module-lazyload/mocks/snippet.html +57 -0
  263. package/examples/module-lazyload/mocks/with-styles.html +39 -0
  264. package/examples/module-lazyload/module-lazyload.html +132 -0
  265. package/examples/module-lazyload/module-lazyload.spec.ts +734 -0
  266. package/examples/module-lazyload/module-lazyload.ts +89 -0
  267. package/examples/module-list/module-list.html +30 -0
  268. package/examples/module-list/module-list.spec.ts +592 -0
  269. package/examples/module-list/module-list.ts +99 -0
  270. package/examples/module-pagination/module-pagination.css +79 -0
  271. package/examples/module-pagination/module-pagination.html +16 -0
  272. package/examples/module-pagination/module-pagination.spec.ts +701 -0
  273. package/examples/module-pagination/module-pagination.ts +88 -0
  274. package/examples/module-scrollarea/module-scrollarea.css +77 -0
  275. package/examples/module-scrollarea/module-scrollarea.html +189 -0
  276. package/examples/module-scrollarea/module-scrollarea.spec.ts +445 -0
  277. package/examples/module-scrollarea/module-scrollarea.ts +81 -0
  278. package/examples/module-tabgroup/module-tabgroup.css +55 -0
  279. package/examples/module-tabgroup/module-tabgroup.html +269 -0
  280. package/examples/module-tabgroup/module-tabgroup.spec.ts +631 -0
  281. package/examples/module-tabgroup/module-tabgroup.ts +102 -0
  282. package/examples/module-toc/module-toc.css +34 -0
  283. package/examples/module-todo/module-todo.css +84 -0
  284. package/examples/module-todo/module-todo.html +92 -0
  285. package/examples/module-todo/module-todo.spec.ts +528 -0
  286. package/examples/module-todo/module-todo.ts +91 -0
  287. package/examples/section-hero/section-hero.css +37 -0
  288. package/examples/section-menu/section-menu.css +81 -0
  289. package/examples/server.ts +95 -0
  290. package/examples/test-setup.md +314 -0
  291. package/index.dev.js +1688 -0
  292. package/index.dev.ts +127 -0
  293. package/index.js +3 -0
  294. package/index.js.map +42 -0
  295. package/index.ts +127 -0
  296. package/package.json +64 -0
  297. package/playwright.config.ts +31 -0
  298. package/server/BUILD_SYSTEM.md +428 -0
  299. package/server/SERVER.md +286 -0
  300. package/server/build.ts +91 -0
  301. package/server/config.ts +130 -0
  302. package/server/effects/api.ts +28 -0
  303. package/server/effects/css.ts +31 -0
  304. package/server/effects/examples.ts +109 -0
  305. package/server/effects/js.ts +32 -0
  306. package/server/effects/menu.ts +34 -0
  307. package/server/effects/pages.ts +178 -0
  308. package/server/effects/service-worker.ts +57 -0
  309. package/server/effects/sitemap.ts +27 -0
  310. package/server/file-signals.ts +361 -0
  311. package/server/file-watcher.ts +77 -0
  312. package/server/io.ts +174 -0
  313. package/server/layout-engine.ts +470 -0
  314. package/server/layout-utils.ts +615 -0
  315. package/server/layouts/api.html +76 -0
  316. package/server/layouts/base.html +37 -0
  317. package/server/layouts/blog.html +115 -0
  318. package/server/layouts/example.html +104 -0
  319. package/server/layouts/overview.html +165 -0
  320. package/server/layouts/page.html +36 -0
  321. package/server/layouts/test.html +24 -0
  322. package/server/markdoc-helpers.ts +217 -0
  323. package/server/markdoc.config.ts +29 -0
  324. package/server/schema/callout.markdoc.ts +17 -0
  325. package/server/schema/carousel.markdoc.ts +118 -0
  326. package/server/schema/demo.markdoc.ts +74 -0
  327. package/server/schema/fence.markdoc.ts +84 -0
  328. package/server/schema/heading.markdoc.ts +23 -0
  329. package/server/schema/hero.markdoc.ts +59 -0
  330. package/server/schema/section.markdoc.ts +10 -0
  331. package/server/schema/slide.markdoc.ts +17 -0
  332. package/server/schema/source.markdoc.ts +53 -0
  333. package/server/schema/tabgroup.markdoc.ts +102 -0
  334. package/server/serve.ts +635 -0
  335. package/server/templates/README.md +352 -0
  336. package/server/templates/constants.ts +236 -0
  337. package/server/templates/fragments.ts +159 -0
  338. package/server/templates/hmr.ts +269 -0
  339. package/server/templates/menu.ts +33 -0
  340. package/server/templates/performance-hints.ts +94 -0
  341. package/server/templates/service-worker.ts +403 -0
  342. package/server/templates/sitemap.ts +57 -0
  343. package/server/templates/toc.ts +41 -0
  344. package/server/templates/utils.ts +378 -0
  345. package/src/component.ts +215 -0
  346. package/src/context.ts +156 -0
  347. package/src/effects/attribute.ts +82 -0
  348. package/src/effects/class.ts +28 -0
  349. package/src/effects/event.ts +67 -0
  350. package/src/effects/html.ts +60 -0
  351. package/src/effects/method.ts +57 -0
  352. package/src/effects/pass.ts +103 -0
  353. package/src/effects/property.ts +57 -0
  354. package/src/effects/style.ts +34 -0
  355. package/src/effects/text.ts +28 -0
  356. package/src/effects.ts +412 -0
  357. package/src/errors.ts +160 -0
  358. package/src/parsers/boolean.ts +14 -0
  359. package/src/parsers/json.ts +33 -0
  360. package/src/parsers/number.ts +55 -0
  361. package/src/parsers/string.ts +32 -0
  362. package/src/parsers.ts +90 -0
  363. package/src/scheduler.ts +47 -0
  364. package/src/signals/collection.ts +253 -0
  365. package/src/signals/sensor.ts +131 -0
  366. package/src/ui.ts +236 -0
  367. package/src/util.ts +187 -0
  368. package/tsconfig.json +34 -0
  369. package/types/examples/basic-button/basic-button.d.ts +16 -0
  370. package/types/examples/basic-hello/basic-hello.d.ts +18 -0
  371. package/types/index.d.ts +27 -0
  372. package/types/index.dev.d.ts +27 -0
  373. package/types/src/collection.d.ts +27 -0
  374. package/types/src/component.d.ts +32 -0
  375. package/types/src/context.d.ts +85 -0
  376. package/types/src/effects/attribute.d.ts +23 -0
  377. package/types/src/effects/callMethod.d.ts +23 -0
  378. package/types/src/effects/class.d.ts +13 -0
  379. package/types/src/effects/dangerouslySetInnerHTML.d.ts +18 -0
  380. package/types/src/effects/event.d.ts +18 -0
  381. package/types/src/effects/html.d.ts +17 -0
  382. package/types/src/effects/method.d.ts +22 -0
  383. package/types/src/effects/pass.d.ts +18 -0
  384. package/types/src/effects/property.d.ts +22 -0
  385. package/types/src/effects/setAttribute.d.ts +24 -0
  386. package/types/src/effects/setProperty.d.ts +23 -0
  387. package/types/src/effects/setStyle.d.ts +14 -0
  388. package/types/src/effects/setText.d.ts +13 -0
  389. package/types/src/effects/style.d.ts +13 -0
  390. package/types/src/effects/text.d.ts +12 -0
  391. package/types/src/effects/toggleClass.d.ts +14 -0
  392. package/types/src/effects.d.ts +153 -0
  393. package/types/src/errors.d.ts +99 -0
  394. package/types/src/events.d.ts +27 -0
  395. package/types/src/extractors.d.ts +23 -0
  396. package/types/src/parsers/boolean.d.ts +10 -0
  397. package/types/src/parsers/json.d.ts +13 -0
  398. package/types/src/parsers/number.d.ts +21 -0
  399. package/types/src/parsers/string.d.ts +19 -0
  400. package/types/src/parsers.d.ts +41 -0
  401. package/types/src/scheduler.d.ts +11 -0
  402. package/types/src/sensor.d.ts +27 -0
  403. package/types/src/signals/collection.d.ts +32 -0
  404. package/types/src/signals/sensor.d.ts +27 -0
  405. package/types/src/ui.d.ts +37 -0
  406. package/types/src/util.d.ts +65 -0
@@ -0,0 +1,378 @@
1
+ /**
2
+ * Template Utilities
3
+ *
4
+ * Shared utilities for tagged template literals including escaping,
5
+ * validation, and error handling functions.
6
+ */
7
+
8
+ import {
9
+ DEFAULT_RESOURCE_TYPE,
10
+ DEVELOPMENT_CONFIG,
11
+ ERROR_MESSAGES,
12
+ MIN_HASH_LENGTHS,
13
+ RESOURCE_TYPE_MAP,
14
+ SELF_CLOSING_TAGS,
15
+ VALIDATION_PATTERNS,
16
+ } from './constants'
17
+
18
+ // HTML template tag with automatic escaping
19
+ export function html(
20
+ strings: TemplateStringsArray,
21
+ ...values: unknown[]
22
+ ): string {
23
+ return processTemplate(strings, values, 'html')
24
+ }
25
+
26
+ // XML template tag with automatic escaping
27
+ export function xml(
28
+ strings: TemplateStringsArray,
29
+ ...values: unknown[]
30
+ ): string {
31
+ return processTemplate(strings, values, 'xml')
32
+ }
33
+
34
+ // CSS template tag (no escaping needed for CSS)
35
+ export function css(
36
+ strings: TemplateStringsArray,
37
+ ...values: unknown[]
38
+ ): string {
39
+ return processTemplate(strings, values, 'css')
40
+ }
41
+
42
+ // JavaScript template tag for code generation
43
+ export function js(
44
+ strings: TemplateStringsArray,
45
+ ...values: unknown[]
46
+ ): string {
47
+ return processTemplate(strings, values, 'js')
48
+ }
49
+
50
+ // Core template processing function
51
+ function processTemplate(
52
+ strings: TemplateStringsArray,
53
+ values: unknown[],
54
+ type: 'html' | 'xml' | 'css' | 'js',
55
+ ): string {
56
+ let result = ''
57
+
58
+ for (let i = 0; i < strings.length; i++) {
59
+ result += strings[i]
60
+
61
+ if (i < values.length) {
62
+ const value = values[i]
63
+
64
+ if (value === null || value === undefined) {
65
+ continue
66
+ } else if (Array.isArray(value)) {
67
+ // Handle arrays based on template type
68
+ if (type === 'js') {
69
+ result += value
70
+ .map(item =>
71
+ typeof item === 'string' ? `'${item}'` : String(item),
72
+ )
73
+ .join(',\n\t')
74
+ } else {
75
+ result += value.join('')
76
+ }
77
+ } else if (typeof value === 'string') {
78
+ // Add strings directly (assume they're already safe)
79
+ result += value
80
+ } else {
81
+ // Convert other types to string and escape if needed
82
+ const stringValue = String(value)
83
+ if (type === 'html') {
84
+ result += escapeHtml(stringValue)
85
+ } else if (type === 'xml') {
86
+ result += escapeXml(stringValue)
87
+ } else {
88
+ result += stringValue
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ return result.trim()
95
+ }
96
+
97
+ // HTML escaping function
98
+ export function escapeHtml(text: string): string {
99
+ return text
100
+ .replace(/&/g, '&amp;')
101
+ .replace(/</g, '&lt;')
102
+ .replace(/>/g, '&gt;')
103
+ .replace(/"/g, '&quot;')
104
+ .replace(/'/g, '&#39;')
105
+ }
106
+
107
+ // XML escaping function
108
+ export function escapeXml(text: string): string {
109
+ return text
110
+ .replace(/&/g, '&amp;')
111
+ .replace(/</g, '&lt;')
112
+ .replace(/>/g, '&gt;')
113
+ .replace(/"/g, '&quot;')
114
+ .replace(/'/g, '&apos;')
115
+ }
116
+
117
+ // Generate URL-friendly slug from text
118
+ export function generateSlug(text: string): string {
119
+ return text
120
+ .toLowerCase()
121
+ .replace(/[^\w\s-]/g, '')
122
+ .replace(/\s+/g, '-')
123
+ .replace(/-+/g, '-')
124
+ .trim()
125
+ }
126
+
127
+ // Common sorting utilities
128
+ export interface SortableItem {
129
+ filename: string
130
+ }
131
+
132
+ export function createOrderedSort<T extends SortableItem>(
133
+ order: string[],
134
+ ): (a: T, b: T) => number {
135
+ return (a, b) => {
136
+ const aName = a.filename.replace('.html', '').replace('.md', '')
137
+ const bName = b.filename.replace('.html', '').replace('.md', '')
138
+
139
+ const aIndex = order.indexOf(aName)
140
+ const bIndex = order.indexOf(bName)
141
+
142
+ // If both items are in order, sort by their order
143
+ if (aIndex !== -1 && bIndex !== -1) {
144
+ return aIndex - bIndex
145
+ }
146
+
147
+ // If only one item is in order, prioritize it
148
+ if (aIndex !== -1) return -1
149
+ if (bIndex !== -1) return 1
150
+
151
+ // If neither item is in order, sort alphabetically
152
+ return aName.localeCompare(bName)
153
+ }
154
+ }
155
+
156
+ // Common validation patterns
157
+ export function validateHashString(
158
+ hash: string,
159
+ minLength: number = MIN_HASH_LENGTHS.ASSET_HASH,
160
+ ): boolean {
161
+ return VALIDATION_PATTERNS.HEX_HASH.test(hash) && hash.length >= minLength
162
+ }
163
+
164
+ export function validateRequiredString(
165
+ value: unknown,
166
+ fieldName: string,
167
+ ): string[] {
168
+ const errors: string[] = []
169
+ if (!value || typeof value !== 'string') {
170
+ errors.push(ERROR_MESSAGES.MISSING_REQUIRED_FIELD(fieldName))
171
+ }
172
+ return errors
173
+ }
174
+
175
+ export function validateArrayField<T>(
176
+ value: unknown,
177
+ fieldName: string,
178
+ validator?: (item: T) => boolean,
179
+ ): string[] {
180
+ const errors: string[] = []
181
+ if (value !== undefined && !Array.isArray(value)) {
182
+ errors.push(ERROR_MESSAGES.INVALID_TYPE(fieldName, 'array'))
183
+ } else if (value && validator) {
184
+ const invalidItems = (value as T[]).filter(item => !validator(item))
185
+ if (invalidItems.length > 0) {
186
+ errors.push(`${fieldName} contains invalid items`)
187
+ }
188
+ }
189
+ return errors
190
+ }
191
+
192
+ // Error boundary wrapper for template functions
193
+ export function safeRender<T extends (...args: any[]) => string>(
194
+ templateFn: T,
195
+ fallback: string = '',
196
+ onError?: (error: Error) => void,
197
+ ): T {
198
+ return ((...args: Parameters<T>) => {
199
+ try {
200
+ return templateFn(...args)
201
+ } catch (error) {
202
+ console.error('Template rendering error:', error)
203
+ onError?.(error as Error)
204
+ return fallback
205
+ }
206
+ }) as T
207
+ }
208
+
209
+ // Conditional rendering helper
210
+ export function when<T>(condition: boolean, template: () => T): T | '' {
211
+ return condition ? template() : ('' as T | '')
212
+ }
213
+
214
+ // Inverse conditional rendering helper
215
+ export function unless<T>(condition: boolean, template: () => T): T | '' {
216
+ return !condition ? template() : ('' as T | '')
217
+ }
218
+
219
+ // Safe array mapping with error handling
220
+ export function mapSafe<T, R>(
221
+ items: T[],
222
+ mapper: (item: T, index: number) => R,
223
+ separator: string = '',
224
+ ): string {
225
+ try {
226
+ return items.map(mapper).join(separator)
227
+ } catch (error) {
228
+ console.error('Template mapping error:', error)
229
+ return ''
230
+ }
231
+ }
232
+
233
+ // Template composition helper
234
+ export function fragment(...templates: string[]): string {
235
+ return templates.filter(Boolean).join('')
236
+ }
237
+
238
+ // Indent template content
239
+ export function indent(template: string, spaces: number = 2): string {
240
+ const indentation = ' '.repeat(spaces)
241
+ return template
242
+ .split('\n')
243
+ .map(line => (line.trim() ? indentation + line : line))
244
+ .join('\n')
245
+ }
246
+
247
+ // Minify HTML/XML by removing extra whitespace
248
+ export function minify(template: string): string {
249
+ return template.replace(/\s+/g, ' ').replace(/>\s+</g, '><').trim()
250
+ }
251
+
252
+ // Basic template validation
253
+ export interface ValidationResult {
254
+ valid: boolean
255
+ errors: string[]
256
+ }
257
+
258
+ export function validateHtml(template: string): ValidationResult {
259
+ const errors: string[] = []
260
+
261
+ // Basic validation checks
262
+ const openTags = template.match(/<[^/][^>]*>/g) || []
263
+ const closeTags = template.match(/<\/[^>]*>/g) || []
264
+
265
+ // Self-closing tags that don't need closing tags
266
+ const selfClosingTags = SELF_CLOSING_TAGS
267
+
268
+ // Check for unclosed tags (simplified check)
269
+ const openTagNames = openTags
270
+ .map(tag => tag.match(/<(\w+)/)?.[1])
271
+ .filter(Boolean)
272
+ .filter(tag => !selfClosingTags.includes(tag!))
273
+
274
+ const closeTagNames = closeTags
275
+ .map(tag => tag.match(/<\/(\w+)/)?.[1])
276
+ .filter(Boolean)
277
+
278
+ if (openTagNames.length !== closeTagNames.length) {
279
+ errors.push('Mismatched opening and closing tags')
280
+ }
281
+
282
+ // Check for common HTML issues
283
+ if (template.includes('< ')) {
284
+ errors.push('Space after opening bracket detected')
285
+ }
286
+
287
+ if (template.includes(' >')) {
288
+ errors.push('Space before closing bracket detected')
289
+ }
290
+
291
+ return { valid: errors.length === 0, errors }
292
+ }
293
+
294
+ export function validateXml(template: string): ValidationResult {
295
+ const errors: string[] = []
296
+
297
+ // Check for XML declaration
298
+ if (!template.includes('<?xml')) {
299
+ errors.push('Missing XML declaration')
300
+ }
301
+
302
+ // Check for proper encoding
303
+ if (template.includes('<?xml') && !template.includes('encoding=')) {
304
+ errors.push('Missing encoding declaration in XML')
305
+ }
306
+
307
+ // Basic tag matching (reuse HTML validation logic)
308
+ const htmlValidation = validateHtml(template)
309
+ errors.push(...htmlValidation.errors)
310
+
311
+ return { valid: errors.length === 0, errors }
312
+ }
313
+
314
+ // Development helpers
315
+ export function debugTemplate(name: string, template: string): string {
316
+ if (DEVELOPMENT_CONFIG.ENABLE_LOGGING) {
317
+ console.log(
318
+ `Template [${name}]:`,
319
+ template.substring(0, DEVELOPMENT_CONFIG.MAX_TEMPLATE_LENGTH_FOR_LOGGING)
320
+ + '...',
321
+ )
322
+ }
323
+ return template
324
+ }
325
+
326
+ // Performance measurement for template generation
327
+ export function measureTemplate<T extends (...args: any[]) => string>(
328
+ name: string,
329
+ templateFn: T,
330
+ ): T {
331
+ return ((...args: Parameters<T>) => {
332
+ if (!DEVELOPMENT_CONFIG.ENABLE_PERFORMANCE_MONITORING) {
333
+ return templateFn(...args)
334
+ }
335
+
336
+ const start = performance.now()
337
+ const result = templateFn(...args)
338
+ const end = performance.now()
339
+
340
+ const renderTime = end - start
341
+ if (DEVELOPMENT_CONFIG.ENABLE_LOGGING) {
342
+ console.log(`Template [${name}] rendered in ${renderTime.toFixed(2)}ms`)
343
+ }
344
+
345
+ return result
346
+ }) as T
347
+ }
348
+
349
+ // Template composition with validation
350
+ export function composeTemplates(
351
+ ...templates: Array<string | (() => string)>
352
+ ): string {
353
+ return templates
354
+ .map(template => (typeof template === 'function' ? template() : template))
355
+ .filter(Boolean)
356
+ .join('')
357
+ }
358
+
359
+ // Enhanced validation with multiple checks
360
+ export function createValidator<T>(
361
+ checks: Array<(value: T) => string[]>,
362
+ ): (value: T) => ValidationResult {
363
+ return (value: T) => {
364
+ const errors = checks.flatMap(check => check(value))
365
+ return { valid: errors.length === 0, errors }
366
+ }
367
+ }
368
+
369
+ // Resource type detection utility (moved from performance-hints)
370
+ export function getResourceType(url: string): string {
371
+ const extension = '.' + url.split('.').pop()?.toLowerCase()
372
+ return (RESOURCE_TYPE_MAP as any)[extension] || DEFAULT_RESOURCE_TYPE
373
+ }
374
+
375
+ // Check if resource requires crossorigin attribute
376
+ export function requiresCrossorigin(url: string): boolean {
377
+ return url.endsWith('.woff') || url.endsWith('.woff2')
378
+ }
@@ -0,0 +1,215 @@
1
+ import {
2
+ type ComputedCallback,
3
+ createComputed,
4
+ createState,
5
+ isComputed,
6
+ isComputedCallback,
7
+ isFunction,
8
+ isMutableSignal,
9
+ isSignal,
10
+ isState,
11
+ isStore,
12
+ type MaybeCleanup,
13
+ type Signal,
14
+ UNSET,
15
+ } from '@zeix/cause-effect'
16
+
17
+ import { type Effects, runEffects } from './effects'
18
+ import { InvalidComponentNameError, InvalidPropertyNameError } from './errors'
19
+ import { isParser, type Parser, type Reader } from './parsers'
20
+ import { type ElementQueries, getHelpers, type UI } from './ui'
21
+ import { validatePropertyName } from './util'
22
+
23
+ /* === Types === */
24
+
25
+ type ReservedWords =
26
+ | 'constructor'
27
+ | 'prototype'
28
+ | '__proto__'
29
+ | 'toString'
30
+ | 'valueOf'
31
+ | 'hasOwnProperty'
32
+ | 'isPrototypeOf'
33
+ | 'propertyIsEnumerable'
34
+ | 'toLocaleString'
35
+
36
+ type ComponentProp = Exclude<string, keyof HTMLElement | ReservedWords>
37
+ type ComponentProps = Record<ComponentProp, NonNullable<unknown>>
38
+
39
+ type Component<P extends ComponentProps> = HTMLElement & P
40
+ type ComponentUI<P extends ComponentProps, U extends UI> = U & {
41
+ host: Component<P>
42
+ }
43
+
44
+ type ComponentSetup<P extends ComponentProps, U extends UI> = (
45
+ ui: ComponentUI<P, U>,
46
+ ) => Effects<P, ComponentUI<P, U>>
47
+
48
+ type MethodProducer<P extends ComponentProps, U extends UI> = (
49
+ ui: U & { host: Component<P> },
50
+ ) => void
51
+
52
+ type Initializers<P extends ComponentProps, U extends UI> = {
53
+ [K in keyof P]?:
54
+ | P[K]
55
+ | Signal<P[K]>
56
+ | Parser<P[K], ComponentUI<P, U>>
57
+ | Reader<MaybeSignal<P[K]>, ComponentUI<P, U>>
58
+ | MethodProducer<P, ComponentUI<P, U>>
59
+ }
60
+
61
+ type MaybeSignal<T extends {}> = T | Signal<T> | ComputedCallback<T>
62
+
63
+ /* === Exported Functions === */
64
+
65
+ /**
66
+ * Define a component with dependency resolution and setup function (connectedCallback)
67
+ *
68
+ * @since 0.15.0
69
+ * @param {string} name - Custom element name
70
+ * @param {object} props - Component properties
71
+ * @param {function} select - Function to select UI elements
72
+ * @param {function} setup - Setup function
73
+ * @throws {InvalidComponentNameError} If component name is invalid
74
+ * @throws {InvalidPropertyNameError} If property name is invalid
75
+ */
76
+ function defineComponent<P extends ComponentProps, U extends UI = {}>(
77
+ name: string,
78
+ props: Initializers<P, U> = {} as Initializers<P, U>,
79
+ select: (elementQueries: ElementQueries) => U = () => ({}) as U,
80
+ setup: (ui: ComponentUI<P, U>) => Effects<P, ComponentUI<P, U>> = () => ({}),
81
+ ): Component<P> {
82
+ if (!name.includes('-') || !name.match(/^[a-z][a-z0-9-]*$/))
83
+ throw new InvalidComponentNameError(name)
84
+ for (const prop of Object.keys(props)) {
85
+ const error = validatePropertyName(prop)
86
+ if (error) throw new InvalidPropertyNameError(name, prop, error)
87
+ }
88
+
89
+ class Truc extends HTMLElement {
90
+ debug?: boolean
91
+ #ui: ComponentUI<P, U> | undefined
92
+ #signals = {} as { [K in keyof P]: Signal<P[K]> }
93
+ #cleanup: MaybeCleanup
94
+
95
+ static observedAttributes =
96
+ Object.entries(props)
97
+ ?.filter(([, initializer]) => isParser(initializer))
98
+ .map(([prop]) => prop) ?? []
99
+
100
+ /**
101
+ * Native callback when the custom element is first connected to the document
102
+ */
103
+ connectedCallback() {
104
+ // Initialize UI
105
+ const [elementQueries, resolveDependencies] = getHelpers(this)
106
+ const ui = {
107
+ ...select(elementQueries),
108
+ host: this as unknown as Component<P>,
109
+ }
110
+ this.#ui = ui
111
+ Object.freeze(this.#ui)
112
+
113
+ // Initialize signals
114
+ const isReaderOrMethodProducer = <K extends keyof P & string>(
115
+ value: unknown,
116
+ ): value is
117
+ | Reader<P[K], ComponentUI<P, U>>
118
+ | MethodProducer<P, ComponentUI<P, U>> => {
119
+ return isFunction(value)
120
+ }
121
+ const createSignal = <K extends keyof P & string>(
122
+ key: K,
123
+ initializer: Initializers<P, U>[K],
124
+ ) => {
125
+ const result = isParser<P[K], ComponentUI<P, U>>(initializer)
126
+ ? initializer(ui, this.getAttribute(key))
127
+ : isReaderOrMethodProducer<K>(initializer)
128
+ ? initializer(ui)
129
+ : (initializer as MaybeSignal<P[K]>)
130
+ if (result != null) this.#setAccessor(key, result)
131
+ }
132
+ for (const [prop, initializer] of Object.entries(props)) {
133
+ if (initializer == null || prop in this) continue
134
+ createSignal(prop, initializer)
135
+ }
136
+
137
+ // Resolve dependencies and run setup function
138
+ resolveDependencies(() => {
139
+ this.#cleanup = runEffects(ui, setup(ui))
140
+ })
141
+ }
142
+
143
+ /**
144
+ * Native callback when the custom element is disconnected from the document
145
+ */
146
+ disconnectedCallback() {
147
+ if (isFunction(this.#cleanup)) this.#cleanup()
148
+ }
149
+
150
+ /**
151
+ * Native callback when an observed attribute of the custom element changes
152
+ *
153
+ * @param {K} name - Name of the modified attribute
154
+ * @param {string | null} oldValue - Old value of the modified attribute
155
+ * @param {string | null} newValue - New value of the modified attribute
156
+ */
157
+ attributeChangedCallback<K extends keyof P>(
158
+ name: K,
159
+ oldValue: string | null,
160
+ newValue: string | null,
161
+ ) {
162
+ // Not connected yet, unchanged value or controlled by computed
163
+ if (!this.#ui || newValue === oldValue || isComputed(this.#signals[name]))
164
+ return
165
+
166
+ // Check whether we have a parser for the attribute
167
+ const parser = props[name]
168
+ if (!isParser<P[K], ComponentUI<P, U>>(parser)) return
169
+
170
+ const parsed = parser(this.#ui, newValue, oldValue)
171
+ if (name in this) (this as unknown as P)[name] = parsed
172
+ else this.#setAccessor(name, parsed)
173
+ }
174
+
175
+ /**
176
+ * Set the signal for a given key
177
+ *
178
+ * @since 0.15.0
179
+ * @param {K} key - Key to set accessor for
180
+ * @param {MaybeSignal<P[K]>} value - Initial value, signal or computed callback to create signal
181
+ */
182
+ #setAccessor<K extends keyof P>(key: K, value: MaybeSignal<P[K]>): void {
183
+ const signal = isSignal(value)
184
+ ? value
185
+ : isComputedCallback(value)
186
+ ? createComputed(value)
187
+ : createState(value)
188
+ const prev = this.#signals[key]
189
+ const mutable = isMutableSignal(signal)
190
+ this.#signals[key] = signal as Signal<P[K]>
191
+ Object.defineProperty(this, key, {
192
+ get: signal.get,
193
+ set: mutable ? signal.set : undefined,
194
+ enumerable: true,
195
+ configurable: mutable,
196
+ })
197
+ if ((prev && isState(prev)) || isStore(prev)) prev.set(UNSET)
198
+ }
199
+ }
200
+
201
+ customElements.define(name, Truc)
202
+ return customElements.get(name) as unknown as Component<P>
203
+ }
204
+
205
+ export {
206
+ type Component,
207
+ type ComponentProp,
208
+ type ComponentProps,
209
+ type ComponentUI,
210
+ type ComponentSetup,
211
+ type MaybeSignal,
212
+ type ReservedWords,
213
+ type Initializers,
214
+ defineComponent,
215
+ }