@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
package/index.dev.js ADDED
@@ -0,0 +1,1688 @@
1
+ // node_modules/@zeix/cause-effect/src/errors.ts
2
+ class CircularDependencyError extends Error {
3
+ constructor(where) {
4
+ super(`Circular dependency detected in ${where}`);
5
+ this.name = "CircularDependencyError";
6
+ }
7
+ }
8
+
9
+ class InvalidCallbackError extends TypeError {
10
+ constructor(where, value) {
11
+ super(`Invalid ${where} callback ${value}`);
12
+ this.name = "InvalidCallbackError";
13
+ }
14
+ }
15
+
16
+ class InvalidSignalValueError extends TypeError {
17
+ constructor(where, value) {
18
+ super(`Invalid signal value ${value} in ${where}`);
19
+ this.name = "InvalidSignalValueError";
20
+ }
21
+ }
22
+
23
+ class NullishSignalValueError extends TypeError {
24
+ constructor(where) {
25
+ super(`Nullish signal values are not allowed in ${where}`);
26
+ this.name = "NullishSignalValueError";
27
+ }
28
+ }
29
+
30
+ class StoreKeyExistsError extends Error {
31
+ constructor(key, value) {
32
+ super(`Could not add store key "${key}" with value ${value} because it already exists`);
33
+ this.name = "StoreKeyExistsError";
34
+ }
35
+ }
36
+
37
+ class StoreKeyRangeError extends RangeError {
38
+ constructor(index) {
39
+ super(`Could not remove store index ${String(index)} because it is out of range`);
40
+ this.name = "StoreKeyRangeError";
41
+ }
42
+ }
43
+
44
+ class StoreKeyReadonlyError extends Error {
45
+ constructor(key, value) {
46
+ super(`Could not set store key "${key}" to ${value} because it is readonly`);
47
+ this.name = "StoreKeyReadonlyError";
48
+ }
49
+ }
50
+
51
+ // node_modules/@zeix/cause-effect/src/util.ts
52
+ var UNSET = Symbol();
53
+ var isString = (value) => typeof value === "string";
54
+ var isNumber = (value) => typeof value === "number";
55
+ var isSymbol = (value) => typeof value === "symbol";
56
+ var isFunction = (fn) => typeof fn === "function";
57
+ var isAsyncFunction = (fn) => isFunction(fn) && fn.constructor.name === "AsyncFunction";
58
+ var isObjectOfType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
59
+ var isRecord = (value) => isObjectOfType(value, "Object");
60
+ var isRecordOrArray = (value) => isRecord(value) || Array.isArray(value);
61
+ var validArrayIndexes = (keys) => {
62
+ if (!keys.length)
63
+ return null;
64
+ const indexes = keys.map((k) => isString(k) ? parseInt(k, 10) : isNumber(k) ? k : NaN);
65
+ return indexes.every((index) => Number.isFinite(index) && index >= 0) ? indexes.sort((a, b) => a - b) : null;
66
+ };
67
+ var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
68
+ var toError = (reason) => reason instanceof Error ? reason : Error(String(reason));
69
+ var recordToArray = (record) => {
70
+ const indexes = validArrayIndexes(Object.keys(record));
71
+ if (indexes === null)
72
+ return record;
73
+ const array = [];
74
+ for (const index of indexes)
75
+ array.push(record[String(index)]);
76
+ return array;
77
+ };
78
+ var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
79
+
80
+ // node_modules/@zeix/cause-effect/src/diff.ts
81
+ var isEqual = (a, b, visited) => {
82
+ if (Object.is(a, b))
83
+ return true;
84
+ if (typeof a !== typeof b)
85
+ return false;
86
+ if (typeof a !== "object" || a === null || b === null)
87
+ return false;
88
+ if (!visited)
89
+ visited = new WeakSet;
90
+ if (visited.has(a) || visited.has(b))
91
+ throw new CircularDependencyError("isEqual");
92
+ visited.add(a);
93
+ visited.add(b);
94
+ try {
95
+ if (Array.isArray(a) && Array.isArray(b)) {
96
+ if (a.length !== b.length)
97
+ return false;
98
+ for (let i = 0;i < a.length; i++) {
99
+ if (!isEqual(a[i], b[i], visited))
100
+ return false;
101
+ }
102
+ return true;
103
+ }
104
+ if (Array.isArray(a) !== Array.isArray(b))
105
+ return false;
106
+ if (isRecord(a) && isRecord(b)) {
107
+ const aKeys = Object.keys(a);
108
+ const bKeys = Object.keys(b);
109
+ if (aKeys.length !== bKeys.length)
110
+ return false;
111
+ for (const key of aKeys) {
112
+ if (!(key in b))
113
+ return false;
114
+ if (!isEqual(a[key], b[key], visited))
115
+ return false;
116
+ }
117
+ return true;
118
+ }
119
+ return false;
120
+ } finally {
121
+ visited.delete(a);
122
+ visited.delete(b);
123
+ }
124
+ };
125
+ var diff = (oldObj, newObj) => {
126
+ const oldValid = isRecordOrArray(oldObj);
127
+ const newValid = isRecordOrArray(newObj);
128
+ if (!oldValid || !newValid) {
129
+ const changed2 = !Object.is(oldObj, newObj);
130
+ return {
131
+ changed: changed2,
132
+ add: changed2 && newValid ? newObj : {},
133
+ change: {},
134
+ remove: changed2 && oldValid ? oldObj : {}
135
+ };
136
+ }
137
+ const visited = new WeakSet;
138
+ const add = {};
139
+ const change = {};
140
+ const remove = {};
141
+ const oldKeys = Object.keys(oldObj);
142
+ const newKeys = Object.keys(newObj);
143
+ const allKeys = new Set([...oldKeys, ...newKeys]);
144
+ for (const key of allKeys) {
145
+ const oldHas = key in oldObj;
146
+ const newHas = key in newObj;
147
+ if (!oldHas && newHas) {
148
+ add[key] = newObj[key];
149
+ continue;
150
+ } else if (oldHas && !newHas) {
151
+ remove[key] = UNSET;
152
+ continue;
153
+ }
154
+ const oldValue = oldObj[key];
155
+ const newValue = newObj[key];
156
+ if (!isEqual(oldValue, newValue, visited))
157
+ change[key] = newValue;
158
+ }
159
+ const changed = Object.keys(add).length > 0 || Object.keys(change).length > 0 || Object.keys(remove).length > 0;
160
+ return {
161
+ changed,
162
+ add,
163
+ change,
164
+ remove
165
+ };
166
+ };
167
+
168
+ // node_modules/@zeix/cause-effect/src/system.ts
169
+ var activeWatcher;
170
+ var pendingWatchers = new Set;
171
+ var batchDepth = 0;
172
+ var createWatcher = (watch) => {
173
+ const cleanups = new Set;
174
+ const w = watch;
175
+ w.unwatch = (cleanup) => {
176
+ cleanups.add(cleanup);
177
+ };
178
+ w.cleanup = () => {
179
+ for (const cleanup of cleanups)
180
+ cleanup();
181
+ cleanups.clear();
182
+ };
183
+ return w;
184
+ };
185
+ var subscribe = (watchers) => {
186
+ if (activeWatcher && !watchers.has(activeWatcher)) {
187
+ const watcher = activeWatcher;
188
+ watcher.unwatch(() => {
189
+ watchers.delete(watcher);
190
+ });
191
+ watchers.add(watcher);
192
+ }
193
+ };
194
+ var notify = (watchers) => {
195
+ for (const watcher of watchers) {
196
+ if (batchDepth)
197
+ pendingWatchers.add(watcher);
198
+ else
199
+ watcher();
200
+ }
201
+ };
202
+ var flush = () => {
203
+ while (pendingWatchers.size) {
204
+ const watchers = Array.from(pendingWatchers);
205
+ pendingWatchers.clear();
206
+ for (const watcher of watchers)
207
+ watcher();
208
+ }
209
+ };
210
+ var batch = (fn) => {
211
+ batchDepth++;
212
+ try {
213
+ fn();
214
+ } finally {
215
+ flush();
216
+ batchDepth--;
217
+ }
218
+ };
219
+ var observe = (run, watcher) => {
220
+ const prev = activeWatcher;
221
+ activeWatcher = watcher;
222
+ try {
223
+ run();
224
+ } finally {
225
+ activeWatcher = prev;
226
+ }
227
+ };
228
+
229
+ // node_modules/@zeix/cause-effect/src/computed.ts
230
+ var TYPE_COMPUTED = "Computed";
231
+ var createComputed = (callback, initialValue = UNSET) => {
232
+ if (!isComputedCallback(callback))
233
+ throw new InvalidCallbackError("computed", valueString(callback));
234
+ if (initialValue == null)
235
+ throw new NullishSignalValueError("computed");
236
+ const watchers = new Set;
237
+ let value = initialValue;
238
+ let error;
239
+ let controller;
240
+ let dirty = true;
241
+ let changed = false;
242
+ let computing = false;
243
+ const ok = (v) => {
244
+ if (!isEqual(v, value)) {
245
+ value = v;
246
+ changed = true;
247
+ }
248
+ error = undefined;
249
+ dirty = false;
250
+ };
251
+ const nil = () => {
252
+ changed = UNSET !== value;
253
+ value = UNSET;
254
+ error = undefined;
255
+ };
256
+ const err = (e) => {
257
+ const newError = toError(e);
258
+ changed = !error || newError.name !== error.name || newError.message !== error.message;
259
+ value = UNSET;
260
+ error = newError;
261
+ };
262
+ const settle = (fn) => (arg) => {
263
+ computing = false;
264
+ controller = undefined;
265
+ fn(arg);
266
+ if (changed)
267
+ notify(watchers);
268
+ };
269
+ const watcher = createWatcher(() => {
270
+ dirty = true;
271
+ controller?.abort();
272
+ if (watchers.size)
273
+ notify(watchers);
274
+ else
275
+ watcher.cleanup();
276
+ });
277
+ watcher.unwatch(() => {
278
+ controller?.abort();
279
+ });
280
+ const compute = () => observe(() => {
281
+ if (computing)
282
+ throw new CircularDependencyError("computed");
283
+ changed = false;
284
+ if (isAsyncFunction(callback)) {
285
+ if (controller)
286
+ return value;
287
+ controller = new AbortController;
288
+ controller.signal.addEventListener("abort", () => {
289
+ computing = false;
290
+ controller = undefined;
291
+ compute();
292
+ }, {
293
+ once: true
294
+ });
295
+ }
296
+ let result;
297
+ computing = true;
298
+ try {
299
+ result = controller ? callback(value, controller.signal) : callback(value);
300
+ } catch (e) {
301
+ if (isAbortError(e))
302
+ nil();
303
+ else
304
+ err(e);
305
+ computing = false;
306
+ return;
307
+ }
308
+ if (result instanceof Promise)
309
+ result.then(settle(ok), settle(err));
310
+ else if (result == null || UNSET === result)
311
+ nil();
312
+ else
313
+ ok(result);
314
+ computing = false;
315
+ }, watcher);
316
+ const computed = {};
317
+ Object.defineProperties(computed, {
318
+ [Symbol.toStringTag]: {
319
+ value: TYPE_COMPUTED
320
+ },
321
+ get: {
322
+ value: () => {
323
+ subscribe(watchers);
324
+ flush();
325
+ if (dirty)
326
+ compute();
327
+ if (error)
328
+ throw error;
329
+ return value;
330
+ }
331
+ }
332
+ });
333
+ return computed;
334
+ };
335
+ var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
336
+ var isComputedCallback = (value) => isFunction(value) && value.length < 3;
337
+ // node_modules/@zeix/cause-effect/src/effect.ts
338
+ var createEffect = (callback) => {
339
+ if (!isFunction(callback) || callback.length > 1)
340
+ throw new InvalidCallbackError("effect", valueString(callback));
341
+ const isAsync = isAsyncFunction(callback);
342
+ let running = false;
343
+ let controller;
344
+ const watcher = createWatcher(() => observe(() => {
345
+ if (running)
346
+ throw new CircularDependencyError("effect");
347
+ running = true;
348
+ controller?.abort();
349
+ controller = undefined;
350
+ let cleanup;
351
+ try {
352
+ if (isAsync) {
353
+ controller = new AbortController;
354
+ const currentController = controller;
355
+ callback(controller.signal).then((cleanup2) => {
356
+ if (isFunction(cleanup2) && controller === currentController)
357
+ watcher.unwatch(cleanup2);
358
+ }).catch((error) => {
359
+ if (!isAbortError(error))
360
+ console.error("Async effect error:", error);
361
+ });
362
+ } else {
363
+ cleanup = callback();
364
+ if (isFunction(cleanup))
365
+ watcher.unwatch(cleanup);
366
+ }
367
+ } catch (error) {
368
+ if (!isAbortError(error))
369
+ console.error("Effect callback error:", error);
370
+ }
371
+ running = false;
372
+ }, watcher));
373
+ watcher();
374
+ return () => {
375
+ controller?.abort();
376
+ watcher.cleanup();
377
+ };
378
+ };
379
+ // node_modules/@zeix/cause-effect/src/match.ts
380
+ function match(result, handlers) {
381
+ try {
382
+ if (result.pending)
383
+ handlers.nil?.();
384
+ else if (result.errors)
385
+ handlers.err?.(result.errors);
386
+ else if (result.ok)
387
+ handlers.ok(result.values);
388
+ } catch (error) {
389
+ if (handlers.err && (!result.errors || !result.errors.includes(toError(error))))
390
+ handlers.err(result.errors ? [...result.errors, toError(error)] : [toError(error)]);
391
+ else
392
+ throw error;
393
+ }
394
+ }
395
+ // node_modules/@zeix/cause-effect/src/resolve.ts
396
+ function resolve(signals) {
397
+ const errors = [];
398
+ let pending = false;
399
+ const values = {};
400
+ for (const [key, signal] of Object.entries(signals)) {
401
+ try {
402
+ const value = signal.get();
403
+ if (value === UNSET)
404
+ pending = true;
405
+ else
406
+ values[key] = value;
407
+ } catch (e) {
408
+ errors.push(toError(e));
409
+ }
410
+ }
411
+ if (pending)
412
+ return { ok: false, pending: true };
413
+ if (errors.length > 0)
414
+ return { ok: false, errors };
415
+ return { ok: true, values };
416
+ }
417
+ // node_modules/@zeix/cause-effect/src/state.ts
418
+ var TYPE_STATE = "State";
419
+ var createState = (initialValue) => {
420
+ if (initialValue == null)
421
+ throw new NullishSignalValueError("state");
422
+ const watchers = new Set;
423
+ let value = initialValue;
424
+ const setValue = (newValue) => {
425
+ if (newValue == null)
426
+ throw new NullishSignalValueError("state");
427
+ if (isEqual(value, newValue))
428
+ return;
429
+ value = newValue;
430
+ notify(watchers);
431
+ if (UNSET === value)
432
+ watchers.clear();
433
+ };
434
+ const state = {};
435
+ Object.defineProperties(state, {
436
+ [Symbol.toStringTag]: {
437
+ value: TYPE_STATE
438
+ },
439
+ get: {
440
+ value: () => {
441
+ subscribe(watchers);
442
+ return value;
443
+ }
444
+ },
445
+ set: {
446
+ value: (newValue) => {
447
+ setValue(newValue);
448
+ }
449
+ },
450
+ update: {
451
+ value: (updater) => {
452
+ if (!isFunction(updater))
453
+ throw new InvalidCallbackError("state update", valueString(updater));
454
+ setValue(updater(value));
455
+ }
456
+ }
457
+ });
458
+ return state;
459
+ };
460
+ var isState = (value) => isObjectOfType(value, TYPE_STATE);
461
+
462
+ // node_modules/@zeix/cause-effect/src/store.ts
463
+ var TYPE_STORE = "Store";
464
+ var createStore = (initialValue) => {
465
+ if (initialValue == null)
466
+ throw new NullishSignalValueError("store");
467
+ const watchers = new Set;
468
+ const listeners = {
469
+ add: new Set,
470
+ change: new Set,
471
+ remove: new Set,
472
+ sort: new Set
473
+ };
474
+ const signals = new Map;
475
+ const signalWatchers = new Map;
476
+ const isArrayLike = Array.isArray(initialValue);
477
+ const current = () => {
478
+ const record = {};
479
+ for (const [key, signal] of signals)
480
+ record[key] = signal.get();
481
+ return record;
482
+ };
483
+ const emit = (key, changes) => {
484
+ Object.freeze(changes);
485
+ for (const listener of listeners[key])
486
+ listener(changes);
487
+ };
488
+ const getSortedIndexes = () => Array.from(signals.keys()).map((k) => Number(k)).filter((n) => Number.isInteger(n)).sort((a, b) => a - b);
489
+ const isValidValue = (key, value) => {
490
+ if (value == null)
491
+ throw new NullishSignalValueError(`store for key "${key}"`);
492
+ if (value === UNSET)
493
+ return true;
494
+ if (isSymbol(value) || isFunction(value) || isComputed(value))
495
+ throw new InvalidSignalValueError(`store for key "${key}"`, valueString(value));
496
+ return true;
497
+ };
498
+ const addProperty = (key, value, single = false) => {
499
+ if (!isValidValue(key, value))
500
+ return false;
501
+ const signal = isState(value) || isStore(value) ? value : isRecord(value) || Array.isArray(value) ? createStore(value) : createState(value);
502
+ signals.set(key, signal);
503
+ const watcher = createWatcher(() => observe(() => {
504
+ emit("change", { [key]: signal.get() });
505
+ }, watcher));
506
+ watcher();
507
+ signalWatchers.set(key, watcher);
508
+ if (single) {
509
+ notify(watchers);
510
+ emit("add", { [key]: value });
511
+ }
512
+ return true;
513
+ };
514
+ const removeProperty = (key, single = false) => {
515
+ const ok = signals.delete(key);
516
+ if (ok) {
517
+ const watcher = signalWatchers.get(key);
518
+ if (watcher)
519
+ watcher.cleanup();
520
+ signalWatchers.delete(key);
521
+ }
522
+ if (single) {
523
+ notify(watchers);
524
+ emit("remove", { [key]: UNSET });
525
+ }
526
+ return ok;
527
+ };
528
+ const reconcile = (oldValue, newValue, initialRun) => {
529
+ const changes = diff(oldValue, newValue);
530
+ batch(() => {
531
+ if (Object.keys(changes.add).length) {
532
+ for (const key in changes.add)
533
+ addProperty(key, changes.add[key] ?? UNSET);
534
+ if (initialRun) {
535
+ setTimeout(() => {
536
+ emit("add", changes.add);
537
+ }, 0);
538
+ } else {
539
+ emit("add", changes.add);
540
+ }
541
+ }
542
+ if (Object.keys(changes.change).length) {
543
+ for (const key in changes.change) {
544
+ const value = changes.change[key];
545
+ if (!isValidValue(key, value))
546
+ continue;
547
+ const signal = signals.get(key);
548
+ if (isMutableSignal(signal))
549
+ signal.set(value);
550
+ else
551
+ throw new StoreKeyReadonlyError(key, valueString(value));
552
+ }
553
+ emit("change", changes.change);
554
+ }
555
+ if (Object.keys(changes.remove).length) {
556
+ for (const key in changes.remove)
557
+ removeProperty(key);
558
+ emit("remove", changes.remove);
559
+ }
560
+ });
561
+ return changes.changed;
562
+ };
563
+ reconcile({}, initialValue, true);
564
+ const store = {};
565
+ Object.defineProperties(store, {
566
+ [Symbol.toStringTag]: {
567
+ value: TYPE_STORE
568
+ },
569
+ [Symbol.isConcatSpreadable]: {
570
+ value: isArrayLike
571
+ },
572
+ [Symbol.iterator]: {
573
+ value: isArrayLike ? function* () {
574
+ const indexes = getSortedIndexes();
575
+ for (const index of indexes) {
576
+ const signal = signals.get(String(index));
577
+ if (signal)
578
+ yield signal;
579
+ }
580
+ } : function* () {
581
+ for (const [key, signal] of signals)
582
+ yield [key, signal];
583
+ }
584
+ },
585
+ add: {
586
+ value: isArrayLike ? (v) => {
587
+ addProperty(String(signals.size), v, true);
588
+ } : (k, v) => {
589
+ if (!signals.has(k))
590
+ addProperty(k, v, true);
591
+ else
592
+ throw new StoreKeyExistsError(k, valueString(v));
593
+ }
594
+ },
595
+ get: {
596
+ value: () => {
597
+ subscribe(watchers);
598
+ return recordToArray(current());
599
+ }
600
+ },
601
+ remove: {
602
+ value: isArrayLike ? (index) => {
603
+ const currentArray = recordToArray(current());
604
+ const currentLength = signals.size;
605
+ if (!Array.isArray(currentArray) || index <= -currentLength || index >= currentLength)
606
+ throw new StoreKeyRangeError(index);
607
+ const newArray = [...currentArray];
608
+ newArray.splice(index, 1);
609
+ if (reconcile(currentArray, newArray))
610
+ notify(watchers);
611
+ } : (k) => {
612
+ if (signals.has(k))
613
+ removeProperty(k, true);
614
+ }
615
+ },
616
+ set: {
617
+ value: (v) => {
618
+ if (reconcile(current(), v)) {
619
+ notify(watchers);
620
+ if (UNSET === v)
621
+ watchers.clear();
622
+ }
623
+ }
624
+ },
625
+ update: {
626
+ value: (fn) => {
627
+ const oldValue = current();
628
+ const newValue = fn(recordToArray(oldValue));
629
+ if (reconcile(oldValue, newValue)) {
630
+ notify(watchers);
631
+ if (UNSET === newValue)
632
+ watchers.clear();
633
+ }
634
+ }
635
+ },
636
+ sort: {
637
+ value: (compareFn) => {
638
+ const entries = Array.from(signals.entries()).map(([key, signal]) => [key, signal.get()]).sort(compareFn ? (a, b) => compareFn(a[1], b[1]) : (a, b) => String(a[1]).localeCompare(String(b[1])));
639
+ const newOrder = entries.map(([key]) => String(key));
640
+ const newSignals = new Map;
641
+ entries.forEach(([key], newIndex) => {
642
+ const oldKey = String(key);
643
+ const newKey = isArrayLike ? String(newIndex) : String(key);
644
+ const signal = signals.get(oldKey);
645
+ if (signal)
646
+ newSignals.set(newKey, signal);
647
+ });
648
+ signals.clear();
649
+ newSignals.forEach((signal, key) => signals.set(key, signal));
650
+ notify(watchers);
651
+ emit("sort", newOrder);
652
+ }
653
+ },
654
+ on: {
655
+ value: (type, listener) => {
656
+ listeners[type].add(listener);
657
+ return () => listeners[type].delete(listener);
658
+ }
659
+ },
660
+ length: {
661
+ get() {
662
+ subscribe(watchers);
663
+ return signals.size;
664
+ }
665
+ }
666
+ });
667
+ return new Proxy(store, {
668
+ get(target, prop) {
669
+ if (prop in target)
670
+ return Reflect.get(target, prop);
671
+ if (isSymbol(prop))
672
+ return;
673
+ return signals.get(prop);
674
+ },
675
+ has(target, prop) {
676
+ if (prop in target)
677
+ return true;
678
+ return signals.has(String(prop));
679
+ },
680
+ ownKeys(target) {
681
+ const staticKeys = Reflect.ownKeys(target);
682
+ const signalKeys = isArrayLike ? getSortedIndexes().map((key) => String(key)) : Array.from(signals.keys());
683
+ return [...new Set([...signalKeys, ...staticKeys])];
684
+ },
685
+ getOwnPropertyDescriptor(target, prop) {
686
+ if (prop in target)
687
+ return Reflect.getOwnPropertyDescriptor(target, prop);
688
+ const signal = signals.get(String(prop));
689
+ return signal ? {
690
+ enumerable: true,
691
+ configurable: true,
692
+ writable: true,
693
+ value: signal
694
+ } : undefined;
695
+ }
696
+ });
697
+ };
698
+ var isStore = (value) => isObjectOfType(value, TYPE_STORE);
699
+
700
+ // node_modules/@zeix/cause-effect/src/signal.ts
701
+ var isSignal = (value) => isState(value) || isComputed(value) || isStore(value);
702
+ var isMutableSignal = (value) => isState(value) || isStore(value);
703
+ function toSignal(value) {
704
+ if (isSignal(value))
705
+ return value;
706
+ if (isComputedCallback(value))
707
+ return createComputed(value);
708
+ if (Array.isArray(value) || isRecord(value))
709
+ return createStore(value);
710
+ return createState(value);
711
+ }
712
+ // src/util.ts
713
+ var DEV_MODE = true;
714
+ var LOG_DEBUG = "debug";
715
+ var LOG_WARN = "warn";
716
+ var LOG_ERROR = "error";
717
+ var RESERVED_WORDS = new Set([
718
+ "constructor",
719
+ "prototype"
720
+ ]);
721
+ var HTML_ELEMENT_PROPS = new Set([
722
+ "id",
723
+ "class",
724
+ "className",
725
+ "title",
726
+ "role",
727
+ "style",
728
+ "dataset",
729
+ "lang",
730
+ "dir",
731
+ "hidden",
732
+ "children",
733
+ "innerHTML",
734
+ "outerHTML",
735
+ "textContent",
736
+ "innerText"
737
+ ]);
738
+ var idString = (id) => id ? `#${id}` : "";
739
+ var classString = (classList) => classList?.length ? `.${Array.from(classList).join(".")}` : "";
740
+ var isElement = (node) => node.nodeType === Node.ELEMENT_NODE;
741
+ var isCustomElement = (element) => element.localName.includes("-");
742
+ var isNotYetDefinedComponent = (element) => isCustomElement(element) && element.matches(":not(:defined)");
743
+ var elementName = (el) => el ? `<${el.localName}${idString(el.id)}${classString(el.classList)}>` : "<unknown>";
744
+ var log = (value, msg, level = LOG_DEBUG) => {
745
+ if (DEV_MODE || [LOG_ERROR, LOG_WARN].includes(level))
746
+ console[level](msg, value);
747
+ return value;
748
+ };
749
+ var validatePropertyName = (prop) => {
750
+ if (RESERVED_WORDS.has(prop))
751
+ return `Property name "${prop}" is a reserved word`;
752
+ if (HTML_ELEMENT_PROPS.has(prop))
753
+ return `Property name "${prop}" conflicts with inherited HTMLElement property`;
754
+ return null;
755
+ };
756
+
757
+ // src/errors.ts
758
+ class CircularMutationError extends Error {
759
+ constructor(host, selector) {
760
+ super(`Circular dependency detected in selection signal for component ${elementName(host)} with selector "${selector}"`);
761
+ this.name = "CircularMutationError";
762
+ }
763
+ }
764
+
765
+ class InvalidComponentNameError extends TypeError {
766
+ constructor(component) {
767
+ super(`Invalid component name "${component}". Custom element names must contain a hyphen, start with a lowercase letter, and contain only lowercase letters, numbers, and hyphens.`);
768
+ this.name = "InvalidComponentNameError";
769
+ }
770
+ }
771
+
772
+ class InvalidPropertyNameError extends TypeError {
773
+ constructor(component, prop, reason) {
774
+ super(`Invalid property name "${prop}" for component <${component}>. ${reason}`);
775
+ this.name = "InvalidPropertyNameError";
776
+ }
777
+ }
778
+
779
+ class InvalidEffectsError extends TypeError {
780
+ constructor(host, cause) {
781
+ super(`Invalid effects in component ${elementName(host)}. Effects must be a record of effects for UI elements or the component, or a Promise that resolves to effects.`);
782
+ this.name = "InvalidEffectsError";
783
+ if (cause)
784
+ this.cause = cause;
785
+ }
786
+ }
787
+
788
+ class MissingElementError extends Error {
789
+ constructor(host, selector, required) {
790
+ super(`Missing required element <${selector}> in component ${elementName(host)}. ${required}`);
791
+ this.name = "MissingElementError";
792
+ }
793
+ }
794
+
795
+ class DependencyTimeoutError extends Error {
796
+ constructor(host, missing) {
797
+ super(`Timeout waiting for: [${missing.join(", ")}] in component ${elementName(host)}.`);
798
+ this.name = "DependencyTimeoutError";
799
+ }
800
+ }
801
+
802
+ class InvalidReactivesError extends TypeError {
803
+ constructor(host, target, reactives) {
804
+ super(`Expected reactives passed from ${elementName(host)} to ${elementName(target)} to be a record of signals, reactive property names or functions. Got ${valueString(reactives)}.`);
805
+ this.name = "InvalidReactivesError";
806
+ }
807
+ }
808
+
809
+ class InvalidCustomElementError extends TypeError {
810
+ constructor(target, where) {
811
+ super(`Target ${elementName(target)} is not a custom element in ${where}.`);
812
+ this.name = "InvalidCustomElementError";
813
+ }
814
+ }
815
+
816
+ // src/signals/collection.ts
817
+ var TYPE_COLLECTION = "Collection";
818
+ var extractAttributes = (selector) => {
819
+ const attributes = new Set;
820
+ if (selector.includes("."))
821
+ attributes.add("class");
822
+ if (selector.includes("#"))
823
+ attributes.add("id");
824
+ if (selector.includes("[")) {
825
+ const parts = selector.split("[");
826
+ for (let i = 1;i < parts.length; i++) {
827
+ const part = parts[i];
828
+ if (!part.includes("]"))
829
+ continue;
830
+ const attrName = part.split("=")[0].trim().replace(/[^a-zA-Z0-9_-]/g, "");
831
+ if (attrName)
832
+ attributes.add(attrName);
833
+ }
834
+ }
835
+ return [...attributes];
836
+ };
837
+ function createCollection(parent, selector) {
838
+ const watchers = new Set;
839
+ const listeners = {
840
+ add: new Set,
841
+ remove: new Set
842
+ };
843
+ let elements = [];
844
+ let observer;
845
+ const findMatches = (nodes) => {
846
+ const elements2 = Array.from(nodes).filter(isElement);
847
+ const found = [];
848
+ for (const element of elements2) {
849
+ if (element.matches(selector))
850
+ found.push(element);
851
+ found.push(...Array.from(element.querySelectorAll(selector)));
852
+ }
853
+ return found;
854
+ };
855
+ const notifyListeners = (listeners2, elements2) => {
856
+ Object.freeze(elements2);
857
+ for (const listener of listeners2)
858
+ listener(elements2);
859
+ };
860
+ const observe2 = () => {
861
+ elements = Array.from(parent.querySelectorAll(selector));
862
+ observer = new MutationObserver((mutations) => {
863
+ const added = [];
864
+ const removed = [];
865
+ for (const mutation of mutations) {
866
+ if (mutation.type === "childList") {
867
+ if (mutation.addedNodes.length)
868
+ added.push(...findMatches(mutation.addedNodes));
869
+ if (mutation.removedNodes.length)
870
+ removed.push(...findMatches(mutation.removedNodes));
871
+ } else if (mutation.type === "attributes") {
872
+ const target = mutation.target;
873
+ if (isElement(target)) {
874
+ const wasMatching = elements.includes(target);
875
+ const isMatching = target.matches(selector);
876
+ if (wasMatching && !isMatching)
877
+ removed.push(target);
878
+ else if (!wasMatching && isMatching)
879
+ added.push(target);
880
+ }
881
+ }
882
+ }
883
+ if (added.length || removed.length) {
884
+ elements = Array.from(parent.querySelectorAll(selector));
885
+ notify(watchers);
886
+ }
887
+ if (added.length)
888
+ notifyListeners(listeners.add, added);
889
+ if (removed.length)
890
+ notifyListeners(listeners.remove, removed);
891
+ });
892
+ const observerConfig = {
893
+ childList: true,
894
+ subtree: true
895
+ };
896
+ const observedAttributes = extractAttributes(selector);
897
+ if (observedAttributes.length) {
898
+ observerConfig.attributes = true;
899
+ observerConfig.attributeFilter = observedAttributes;
900
+ }
901
+ observer.observe(parent, observerConfig);
902
+ };
903
+ const collection = {};
904
+ Object.defineProperties(collection, {
905
+ [Symbol.toStringTag]: {
906
+ value: TYPE_COLLECTION
907
+ },
908
+ [Symbol.isConcatSpreadable]: {
909
+ value: true
910
+ },
911
+ [Symbol.iterator]: {
912
+ value: function* () {
913
+ for (const element of elements)
914
+ yield element;
915
+ }
916
+ },
917
+ get: {
918
+ value: () => {
919
+ subscribe(watchers);
920
+ if (!observer)
921
+ observe2();
922
+ return elements;
923
+ }
924
+ },
925
+ on: {
926
+ value: (type, listener) => {
927
+ const listenerSet = listeners[type];
928
+ if (!listenerSet)
929
+ throw new TypeError(`Invalid change notification type: ${type}`);
930
+ listenerSet.add(listener);
931
+ if (!observer)
932
+ observe2();
933
+ return () => listenerSet.delete(listener);
934
+ }
935
+ },
936
+ length: {
937
+ get: () => {
938
+ subscribe(watchers);
939
+ if (!observer)
940
+ observe2();
941
+ return elements.length;
942
+ }
943
+ }
944
+ });
945
+ return new Proxy(collection, {
946
+ get(target, prop) {
947
+ if (prop in target)
948
+ return Reflect.get(target, prop);
949
+ if (isSymbol(prop))
950
+ return;
951
+ const index = Number(prop);
952
+ if (Number.isInteger(index))
953
+ return elements[index];
954
+ return;
955
+ },
956
+ has(target, prop) {
957
+ if (prop in target)
958
+ return true;
959
+ if (Number.isInteger(Number(prop)))
960
+ return !!elements[Number(prop)];
961
+ return false;
962
+ },
963
+ ownKeys(target) {
964
+ const staticKeys = Reflect.ownKeys(target);
965
+ const indexes = Object.keys(elements).map((key) => String(key));
966
+ return [...new Set([...indexes, ...staticKeys])];
967
+ },
968
+ getOwnPropertyDescriptor(target, prop) {
969
+ if (prop in target)
970
+ return Reflect.getOwnPropertyDescriptor(target, prop);
971
+ const element = elements[Number(prop)];
972
+ return element ? {
973
+ enumerable: true,
974
+ configurable: true,
975
+ writable: true,
976
+ value: element
977
+ } : undefined;
978
+ }
979
+ });
980
+ }
981
+ var isCollection = (value) => Object.prototype.toString.call(value) === `[object Collection]`;
982
+
983
+ // src/effects.ts
984
+ var RESET = Symbol("RESET");
985
+ var getUpdateDescription = (op, name = "") => {
986
+ const ops = {
987
+ a: "attribute ",
988
+ c: "class ",
989
+ d: "dataset ",
990
+ h: "inner HTML",
991
+ m: "method call ",
992
+ p: "property ",
993
+ s: "style property ",
994
+ t: "text content"
995
+ };
996
+ return ops[op] + name;
997
+ };
998
+ var runElementEffects = (host, target, effects) => {
999
+ const cleanups = [];
1000
+ const run = (fn) => {
1001
+ const cleanup = fn(host, target);
1002
+ if (cleanup)
1003
+ cleanups.push(cleanup);
1004
+ };
1005
+ if (Array.isArray(effects))
1006
+ for (const fn of effects)
1007
+ run(fn);
1008
+ else
1009
+ run(effects);
1010
+ return () => {
1011
+ cleanups.forEach((cleanup) => cleanup());
1012
+ cleanups.length = 0;
1013
+ };
1014
+ };
1015
+ var runCollectionEffects = (host, collection, effects) => {
1016
+ const cleanups = new Map;
1017
+ const attach = (targets) => {
1018
+ for (const target of targets) {
1019
+ const cleanup = runElementEffects(host, target, effects);
1020
+ if (cleanup)
1021
+ cleanups.set(target, cleanup);
1022
+ }
1023
+ };
1024
+ const detach = (targets) => {
1025
+ for (const target of targets) {
1026
+ cleanups.get(target)?.();
1027
+ cleanups.delete(target);
1028
+ }
1029
+ };
1030
+ collection.on("add", attach);
1031
+ collection.on("remove", detach);
1032
+ attach(collection.get());
1033
+ return () => {
1034
+ for (const cleanup of cleanups.values())
1035
+ cleanup();
1036
+ cleanups.clear();
1037
+ };
1038
+ };
1039
+ var runEffects = (ui, effects) => {
1040
+ if (!isRecord(effects))
1041
+ throw new InvalidEffectsError(ui.host);
1042
+ const cleanups = [];
1043
+ const keys = Object.keys(effects);
1044
+ for (const key of keys) {
1045
+ const k = key;
1046
+ if (!effects[k])
1047
+ continue;
1048
+ const elementEffects = Array.isArray(effects[k]) ? effects[k] : [effects[k]];
1049
+ if (isCollection(ui[k])) {
1050
+ cleanups.push(runCollectionEffects(ui.host, ui[k], elementEffects));
1051
+ } else if (ui[k]) {
1052
+ const cleanup = runElementEffects(ui.host, ui[k], elementEffects);
1053
+ if (cleanup)
1054
+ cleanups.push(cleanup);
1055
+ }
1056
+ }
1057
+ return () => {
1058
+ for (const cleanup of cleanups)
1059
+ cleanup();
1060
+ cleanups.length = 0;
1061
+ };
1062
+ };
1063
+ var resolveReactive = (reactive, host, target, context) => {
1064
+ try {
1065
+ return isString(reactive) ? host[reactive] : isSignal(reactive) ? reactive.get() : isFunction(reactive) ? reactive(target) : RESET;
1066
+ } catch (error) {
1067
+ if (context) {
1068
+ log(error, `Failed to resolve value of ${valueString(reactive)}${context ? ` for ${context}` : ""} in ${elementName(target)}${host !== target ? ` in ${elementName(host)}` : ""}`, LOG_ERROR);
1069
+ }
1070
+ return RESET;
1071
+ }
1072
+ };
1073
+ var updateElement = (reactive, updater) => (host, target) => {
1074
+ const { op, name = "", read, update } = updater;
1075
+ const operationDesc = getUpdateDescription(op, name);
1076
+ const ok = (verb) => () => {
1077
+ if (DEV_MODE && host.debug) {
1078
+ log(target, `${verb} ${operationDesc} of ${elementName(target)} in ${elementName(host)}`);
1079
+ }
1080
+ updater.resolve?.(target);
1081
+ };
1082
+ const err = (verb) => (error) => {
1083
+ log(error, `Failed to ${verb} ${operationDesc} of ${elementName(target)} in ${elementName(host)}`, LOG_ERROR);
1084
+ updater.reject?.(error);
1085
+ };
1086
+ const fallback = read(target);
1087
+ return createEffect(() => {
1088
+ const value = resolveReactive(reactive, host, target, operationDesc);
1089
+ const resolvedValue = value === RESET ? fallback : value === UNSET ? updater.delete ? null : fallback : value;
1090
+ if (updater.delete && resolvedValue === null) {
1091
+ try {
1092
+ updater.delete(target);
1093
+ ok("delete")();
1094
+ } catch (error) {
1095
+ err("delete")(error);
1096
+ }
1097
+ } else if (resolvedValue != null) {
1098
+ const current = read(target);
1099
+ if (Object.is(resolvedValue, current))
1100
+ return;
1101
+ try {
1102
+ update(target, resolvedValue);
1103
+ ok("update")();
1104
+ } catch (error) {
1105
+ err("update")(error);
1106
+ }
1107
+ }
1108
+ });
1109
+ };
1110
+
1111
+ // src/parsers.ts
1112
+ var isParser = (value) => isFunction(value) && value.length >= 2;
1113
+ var isReader = (value) => isFunction(value);
1114
+ var getFallback = (ui, fallback) => isReader(fallback) ? fallback(ui) : fallback;
1115
+ var read = (reader, fallback) => (ui) => {
1116
+ const value = reader(ui);
1117
+ return isString(value) && isParser(fallback) ? fallback(ui, value) : value ?? getFallback(ui, fallback);
1118
+ };
1119
+
1120
+ // src/ui.ts
1121
+ var DEPENDENCY_TIMEOUT = 50;
1122
+ var getHelpers = (host) => {
1123
+ const root = host.shadowRoot ?? host;
1124
+ const dependencies = new Set;
1125
+ function first(selector, required) {
1126
+ const target = root.querySelector(selector);
1127
+ if (required != null && !target)
1128
+ throw new MissingElementError(host, selector, required);
1129
+ if (target && isNotYetDefinedComponent(target))
1130
+ dependencies.add(target.localName);
1131
+ return target ?? undefined;
1132
+ }
1133
+ function all(selector, required) {
1134
+ const collection = createCollection(root, selector);
1135
+ const targets = collection.get();
1136
+ if (required != null && !targets.length)
1137
+ throw new MissingElementError(host, selector, required);
1138
+ if (targets.length)
1139
+ targets.forEach((target) => {
1140
+ if (isNotYetDefinedComponent(target))
1141
+ dependencies.add(target.localName);
1142
+ });
1143
+ return collection;
1144
+ }
1145
+ const resolveDependencies = (callback) => {
1146
+ if (dependencies.size) {
1147
+ const deps = Array.from(dependencies);
1148
+ Promise.race([
1149
+ Promise.all(deps.map((dep) => customElements.whenDefined(dep))),
1150
+ new Promise((_, reject) => {
1151
+ setTimeout(() => {
1152
+ reject(new DependencyTimeoutError(host, deps.filter((dep) => !customElements.get(dep))));
1153
+ }, DEPENDENCY_TIMEOUT);
1154
+ })
1155
+ ]).then(callback).catch(() => {
1156
+ callback();
1157
+ });
1158
+ } else {
1159
+ callback();
1160
+ }
1161
+ };
1162
+ return [{ first, all }, resolveDependencies];
1163
+ };
1164
+
1165
+ // src/component.ts
1166
+ function defineComponent(name, props = {}, select = () => ({}), setup = () => ({})) {
1167
+ if (!name.includes("-") || !name.match(/^[a-z][a-z0-9-]*$/))
1168
+ throw new InvalidComponentNameError(name);
1169
+ for (const prop of Object.keys(props)) {
1170
+ const error = validatePropertyName(prop);
1171
+ if (error)
1172
+ throw new InvalidPropertyNameError(name, prop, error);
1173
+ }
1174
+
1175
+ class Truc extends HTMLElement {
1176
+ debug;
1177
+ #ui;
1178
+ #signals = {};
1179
+ #cleanup;
1180
+ static observedAttributes = Object.entries(props)?.filter(([, initializer]) => isParser(initializer)).map(([prop]) => prop) ?? [];
1181
+ connectedCallback() {
1182
+ const [elementQueries, resolveDependencies] = getHelpers(this);
1183
+ const ui = {
1184
+ ...select(elementQueries),
1185
+ host: this
1186
+ };
1187
+ this.#ui = ui;
1188
+ Object.freeze(this.#ui);
1189
+ const isReaderOrMethodProducer = (value) => {
1190
+ return isFunction(value);
1191
+ };
1192
+ const createSignal = (key, initializer) => {
1193
+ const result = isParser(initializer) ? initializer(ui, this.getAttribute(key)) : isReaderOrMethodProducer(initializer) ? initializer(ui) : initializer;
1194
+ if (result != null)
1195
+ this.#setAccessor(key, result);
1196
+ };
1197
+ for (const [prop, initializer] of Object.entries(props)) {
1198
+ if (initializer == null || prop in this)
1199
+ continue;
1200
+ createSignal(prop, initializer);
1201
+ }
1202
+ resolveDependencies(() => {
1203
+ this.#cleanup = runEffects(ui, setup(ui));
1204
+ });
1205
+ }
1206
+ disconnectedCallback() {
1207
+ if (isFunction(this.#cleanup))
1208
+ this.#cleanup();
1209
+ }
1210
+ attributeChangedCallback(name2, oldValue, newValue) {
1211
+ if (!this.#ui || newValue === oldValue || isComputed(this.#signals[name2]))
1212
+ return;
1213
+ const parser = props[name2];
1214
+ if (!isParser(parser))
1215
+ return;
1216
+ const parsed = parser(this.#ui, newValue, oldValue);
1217
+ if (name2 in this)
1218
+ this[name2] = parsed;
1219
+ else
1220
+ this.#setAccessor(name2, parsed);
1221
+ }
1222
+ #setAccessor(key, value) {
1223
+ const signal = isSignal(value) ? value : isComputedCallback(value) ? createComputed(value) : createState(value);
1224
+ const prev = this.#signals[key];
1225
+ const mutable = isMutableSignal(signal);
1226
+ this.#signals[key] = signal;
1227
+ Object.defineProperty(this, key, {
1228
+ get: signal.get,
1229
+ set: mutable ? signal.set : undefined,
1230
+ enumerable: true,
1231
+ configurable: mutable
1232
+ });
1233
+ if (prev && isState(prev) || isStore(prev))
1234
+ prev.set(UNSET);
1235
+ }
1236
+ }
1237
+ customElements.define(name, Truc);
1238
+ return customElements.get(name);
1239
+ }
1240
+ // src/context.ts
1241
+ var CONTEXT_REQUEST = "context-request";
1242
+
1243
+ class ContextRequestEvent extends Event {
1244
+ context;
1245
+ callback;
1246
+ subscribe;
1247
+ constructor(context, callback, subscribe2 = false) {
1248
+ super(CONTEXT_REQUEST, {
1249
+ bubbles: true,
1250
+ composed: true
1251
+ });
1252
+ this.context = context;
1253
+ this.callback = callback;
1254
+ this.subscribe = subscribe2;
1255
+ }
1256
+ }
1257
+ var provideContexts = (contexts) => (host) => {
1258
+ const listener = (e) => {
1259
+ const { context, callback } = e;
1260
+ if (isString(context) && contexts.includes(context) && isFunction(callback)) {
1261
+ e.stopImmediatePropagation();
1262
+ callback(() => host[context]);
1263
+ }
1264
+ };
1265
+ host.addEventListener(CONTEXT_REQUEST, listener);
1266
+ return () => host.removeEventListener(CONTEXT_REQUEST, listener);
1267
+ };
1268
+ var requestContext = (context, fallback) => (ui) => {
1269
+ let consumed = () => getFallback(ui, fallback);
1270
+ ui.host.dispatchEvent(new ContextRequestEvent(context, (getter) => {
1271
+ consumed = getter;
1272
+ }));
1273
+ return createComputed(consumed);
1274
+ };
1275
+ // src/effects/attribute.ts
1276
+ var isSafeURL = (value) => {
1277
+ if (/^(mailto|tel):/i.test(value))
1278
+ return true;
1279
+ if (value.includes("://")) {
1280
+ try {
1281
+ const url = new URL(value, window.location.origin);
1282
+ return ["http:", "https:", "ftp:"].includes(url.protocol);
1283
+ } catch {
1284
+ return false;
1285
+ }
1286
+ }
1287
+ return true;
1288
+ };
1289
+ var safeSetAttribute = (element, attr, value) => {
1290
+ if (/^on/i.test(attr))
1291
+ throw new Error(`Unsafe attribute: ${attr}`);
1292
+ value = String(value).trim();
1293
+ if (!isSafeURL(value))
1294
+ throw new Error(`Unsafe URL for ${attr}: ${value}`);
1295
+ element.setAttribute(attr, value);
1296
+ };
1297
+ var setAttribute = (name, reactive = name) => updateElement(reactive, {
1298
+ op: "a",
1299
+ name,
1300
+ read: (el) => el.getAttribute(name),
1301
+ update: (el, value) => {
1302
+ safeSetAttribute(el, name, value);
1303
+ },
1304
+ delete: (el) => {
1305
+ el.removeAttribute(name);
1306
+ }
1307
+ });
1308
+ var toggleAttribute = (name, reactive = name) => updateElement(reactive, {
1309
+ op: "a",
1310
+ name,
1311
+ read: (el) => el.hasAttribute(name),
1312
+ update: (el, value) => {
1313
+ el.toggleAttribute(name, value);
1314
+ }
1315
+ });
1316
+ // src/effects/class.ts
1317
+ var toggleClass = (token, reactive = token) => updateElement(reactive, {
1318
+ op: "c",
1319
+ name: token,
1320
+ read: (el) => el.classList.contains(token),
1321
+ update: (el, value) => {
1322
+ el.classList.toggle(token, value);
1323
+ }
1324
+ });
1325
+ // src/scheduler.ts
1326
+ var PASSIVE_EVENTS = new Set([
1327
+ "scroll",
1328
+ "resize",
1329
+ "mousewheel",
1330
+ "touchstart",
1331
+ "touchmove",
1332
+ "wheel"
1333
+ ]);
1334
+ var pendingElements = new Set;
1335
+ var tasks = new WeakMap;
1336
+ var requestId;
1337
+ var runTasks = () => {
1338
+ requestId = undefined;
1339
+ const elements = Array.from(pendingElements);
1340
+ pendingElements.clear();
1341
+ for (const element of elements)
1342
+ tasks.get(element)?.();
1343
+ };
1344
+ var requestTick = () => {
1345
+ if (requestId)
1346
+ cancelAnimationFrame(requestId);
1347
+ requestId = requestAnimationFrame(runTasks);
1348
+ };
1349
+ var schedule = (element, task) => {
1350
+ tasks.set(element, task);
1351
+ pendingElements.add(element);
1352
+ requestTick();
1353
+ };
1354
+
1355
+ // src/effects/event.ts
1356
+ var on = (type, handler, options = {}) => (host, target) => {
1357
+ if (!("passive" in options))
1358
+ options = { ...options, passive: PASSIVE_EVENTS.has(type) };
1359
+ const listener = (e) => {
1360
+ const task = () => {
1361
+ const result = handler(e);
1362
+ if (!isRecord(result))
1363
+ return;
1364
+ batch(() => {
1365
+ for (const [key, value] of Object.entries(result)) {
1366
+ try {
1367
+ host[key] = value;
1368
+ } catch (error) {
1369
+ log(error, `Reactive property "${key}" on ${elementName(host)} from event ${type} on ${elementName(target)} could not be set, because it is read-only.`, LOG_ERROR);
1370
+ }
1371
+ }
1372
+ });
1373
+ };
1374
+ if (options.passive)
1375
+ schedule(target, task);
1376
+ else
1377
+ task();
1378
+ };
1379
+ target.addEventListener(type, listener, options);
1380
+ return () => target.removeEventListener(type, listener);
1381
+ };
1382
+ // src/effects/html.ts
1383
+ var dangerouslySetInnerHTML = (reactive, options = {}) => updateElement(reactive, {
1384
+ op: "h",
1385
+ read: (el) => (el.shadowRoot || !options.shadowRootMode ? el : null)?.innerHTML ?? "",
1386
+ update: (el, html) => {
1387
+ const { shadowRootMode, allowScripts } = options;
1388
+ if (!html) {
1389
+ if (el.shadowRoot)
1390
+ el.shadowRoot.innerHTML = "<slot></slot>";
1391
+ return "";
1392
+ }
1393
+ if (shadowRootMode && !el.shadowRoot)
1394
+ el.attachShadow({ mode: shadowRootMode });
1395
+ const target = el.shadowRoot || el;
1396
+ schedule(el, () => {
1397
+ target.innerHTML = html;
1398
+ if (allowScripts) {
1399
+ target.querySelectorAll("script").forEach((script) => {
1400
+ const newScript = document.createElement("script");
1401
+ newScript.appendChild(document.createTextNode(script.textContent ?? ""));
1402
+ const typeAttr = script.getAttribute("type");
1403
+ if (typeAttr)
1404
+ newScript.setAttribute("type", typeAttr);
1405
+ target.appendChild(newScript);
1406
+ script.remove();
1407
+ });
1408
+ }
1409
+ });
1410
+ return allowScripts ? " with scripts" : "";
1411
+ }
1412
+ });
1413
+ // src/effects/pass.ts
1414
+ var pass = (props) => (host, target) => {
1415
+ if (!isCustomElement(target))
1416
+ throw new InvalidCustomElementError(target, `pass from ${elementName(host)}`);
1417
+ const reactives = isFunction(props) ? props(target) : props;
1418
+ if (!isRecord(reactives))
1419
+ throw new InvalidReactivesError(host, target, reactives);
1420
+ const resetProperties = {};
1421
+ const getGetter = (value) => {
1422
+ if (isSignal(value))
1423
+ return value.get;
1424
+ const fn = isString(value) && value in host ? () => host[value] : isComputedCallback(value) ? value : undefined;
1425
+ return fn ? createComputed(fn).get : undefined;
1426
+ };
1427
+ for (const [prop, reactive] of Object.entries(reactives)) {
1428
+ if (reactive == null)
1429
+ continue;
1430
+ const descriptor = Object.getOwnPropertyDescriptor(target, prop);
1431
+ if (!(prop in target) || !descriptor?.configurable)
1432
+ continue;
1433
+ const applied = isFunction(reactive) && reactive.length === 1 ? reactive(target) : reactive;
1434
+ const isArray = Array.isArray(applied) && applied.length === 2;
1435
+ const getter = getGetter(isArray ? applied[0] : applied);
1436
+ const setter = isArray && isFunction(applied[1]) ? applied[1] : undefined;
1437
+ if (!getter)
1438
+ continue;
1439
+ resetProperties[prop] = descriptor;
1440
+ Object.defineProperty(target, prop, {
1441
+ configurable: true,
1442
+ enumerable: true,
1443
+ get: getter,
1444
+ set: setter
1445
+ });
1446
+ descriptor.set?.call(target, UNSET);
1447
+ }
1448
+ return () => {
1449
+ Object.defineProperties(target, resetProperties);
1450
+ };
1451
+ };
1452
+ // src/effects/property.ts
1453
+ var setProperty = (key, reactive = key) => updateElement(reactive, {
1454
+ op: "p",
1455
+ name: key,
1456
+ read: (el) => (key in el) ? el[key] : UNSET,
1457
+ update: (el, value) => {
1458
+ el[key] = value;
1459
+ }
1460
+ });
1461
+ var show = (reactive) => updateElement(reactive, {
1462
+ op: "p",
1463
+ name: "hidden",
1464
+ read: (el) => !el.hidden,
1465
+ update: (el, value) => {
1466
+ el.hidden = !value;
1467
+ }
1468
+ });
1469
+ // src/effects/style.ts
1470
+ var setStyle = (prop, reactive = prop) => updateElement(reactive, {
1471
+ op: "s",
1472
+ name: prop,
1473
+ read: (el) => el.style.getPropertyValue(prop),
1474
+ update: (el, value) => {
1475
+ el.style.setProperty(prop, value);
1476
+ },
1477
+ delete: (el) => {
1478
+ el.style.removeProperty(prop);
1479
+ }
1480
+ });
1481
+ // src/effects/text.ts
1482
+ var setText = (reactive) => updateElement(reactive, {
1483
+ op: "t",
1484
+ read: (el) => el.textContent,
1485
+ update: (el, value) => {
1486
+ Array.from(el.childNodes).filter((node) => node.nodeType !== Node.COMMENT_NODE).forEach((node) => node.remove());
1487
+ el.append(document.createTextNode(value));
1488
+ }
1489
+ });
1490
+ // src/parsers/boolean.ts
1491
+ var asBoolean = () => (_, value) => value != null && value !== "false";
1492
+ // src/parsers/json.ts
1493
+ var asJSON = (fallback) => (ui, value) => {
1494
+ if ((value ?? fallback) == null)
1495
+ throw new TypeError("asJSON: Value and fallback are both null or undefined");
1496
+ if (value == null)
1497
+ return getFallback(ui, fallback);
1498
+ if (value === "")
1499
+ throw new TypeError("Empty string is not valid JSON");
1500
+ let result;
1501
+ try {
1502
+ result = JSON.parse(value);
1503
+ } catch (error) {
1504
+ throw new SyntaxError(`Failed to parse JSON: ${String(error)}`, {
1505
+ cause: error
1506
+ });
1507
+ }
1508
+ return result ?? getFallback(ui, fallback);
1509
+ };
1510
+ // src/parsers/number.ts
1511
+ var parseNumber = (parseFn, value) => {
1512
+ if (value == null)
1513
+ return;
1514
+ const parsed = parseFn(value);
1515
+ return Number.isFinite(parsed) ? parsed : undefined;
1516
+ };
1517
+ var asInteger = (fallback = 0) => (ui, value) => {
1518
+ if (value == null)
1519
+ return getFallback(ui, fallback);
1520
+ const trimmed = value.trim();
1521
+ if (trimmed.toLowerCase().startsWith("0x"))
1522
+ return parseNumber((v) => parseInt(v, 16), trimmed) ?? getFallback(ui, fallback);
1523
+ const parsed = parseNumber(parseFloat, value);
1524
+ return parsed != null ? Math.trunc(parsed) : getFallback(ui, fallback);
1525
+ };
1526
+ var asNumber = (fallback = 0) => (ui, value) => parseNumber(parseFloat, value) ?? getFallback(ui, fallback);
1527
+ // src/parsers/string.ts
1528
+ var asString = (fallback = "") => (ui, value) => value ?? getFallback(ui, fallback);
1529
+ var asEnum = (valid) => (_, value) => {
1530
+ if (value == null)
1531
+ return valid[0];
1532
+ const lowerValue = value.toLowerCase();
1533
+ const matchingValid = valid.find((v) => v.toLowerCase() === lowerValue);
1534
+ return matchingValid ? value : valid[0];
1535
+ };
1536
+ // src/signals/sensor.ts
1537
+ var createSensor = (init, key, events) => (ui) => {
1538
+ const { host } = ui;
1539
+ const watchers = new Set;
1540
+ let value = getFallback(ui, init);
1541
+ const targets = isCollection(ui[key]) ? ui[key].get() : [ui[key]];
1542
+ const eventMap = new Map;
1543
+ let cleanup;
1544
+ const getTarget = (eventTarget) => {
1545
+ for (const t of targets) {
1546
+ if (t.contains(eventTarget))
1547
+ return t;
1548
+ }
1549
+ };
1550
+ const listen = () => {
1551
+ for (const [type, handler] of Object.entries(events)) {
1552
+ const options = { passive: PASSIVE_EVENTS.has(type) };
1553
+ const listener = (e) => {
1554
+ const eventTarget = e.target;
1555
+ if (!eventTarget)
1556
+ return;
1557
+ const target = getTarget(eventTarget);
1558
+ if (!target)
1559
+ return;
1560
+ e.stopPropagation();
1561
+ const task = () => {
1562
+ try {
1563
+ const next = handler({
1564
+ event: e,
1565
+ ui,
1566
+ target,
1567
+ prev: value
1568
+ });
1569
+ if (next == null || next instanceof Promise)
1570
+ return;
1571
+ if (!Object.is(next, value)) {
1572
+ value = next;
1573
+ if (watchers.size)
1574
+ notify(watchers);
1575
+ else if (cleanup)
1576
+ cleanup();
1577
+ }
1578
+ } catch (error) {
1579
+ e.stopImmediatePropagation();
1580
+ throw error;
1581
+ }
1582
+ };
1583
+ if (options.passive)
1584
+ schedule(host, task);
1585
+ else
1586
+ task();
1587
+ };
1588
+ eventMap.set(type, listener);
1589
+ host.addEventListener(type, listener, options);
1590
+ }
1591
+ cleanup = () => {
1592
+ if (eventMap.size) {
1593
+ for (const [type, listener] of eventMap)
1594
+ host.removeEventListener(type, listener);
1595
+ eventMap.clear();
1596
+ }
1597
+ cleanup = undefined;
1598
+ };
1599
+ };
1600
+ const sensor = {};
1601
+ Object.defineProperties(sensor, {
1602
+ [Symbol.toStringTag]: {
1603
+ value: TYPE_COMPUTED
1604
+ },
1605
+ get: {
1606
+ value: () => {
1607
+ subscribe(watchers);
1608
+ if (watchers.size && !eventMap.size)
1609
+ listen();
1610
+ return value;
1611
+ }
1612
+ }
1613
+ });
1614
+ return sensor;
1615
+ };
1616
+ export {
1617
+ valueString,
1618
+ updateElement,
1619
+ toggleClass,
1620
+ toggleAttribute,
1621
+ toSignal,
1622
+ toError,
1623
+ show,
1624
+ setText,
1625
+ setStyle,
1626
+ setProperty,
1627
+ setAttribute,
1628
+ schedule,
1629
+ runElementEffects,
1630
+ runEffects,
1631
+ resolve,
1632
+ requestContext,
1633
+ read,
1634
+ provideContexts,
1635
+ pass,
1636
+ on,
1637
+ match,
1638
+ isSymbol,
1639
+ isString,
1640
+ isStore,
1641
+ isState,
1642
+ isSignal,
1643
+ isRecordOrArray,
1644
+ isRecord,
1645
+ isParser,
1646
+ isNumber,
1647
+ isMutableSignal,
1648
+ isFunction,
1649
+ isEqual,
1650
+ isComputed,
1651
+ isCollection,
1652
+ isAsyncFunction,
1653
+ isAbortError,
1654
+ diff,
1655
+ defineComponent,
1656
+ dangerouslySetInnerHTML,
1657
+ createStore,
1658
+ createState,
1659
+ createSensor,
1660
+ createEffect,
1661
+ createComputed,
1662
+ createCollection,
1663
+ batch,
1664
+ asString,
1665
+ asNumber,
1666
+ asJSON,
1667
+ asInteger,
1668
+ asEnum,
1669
+ asBoolean,
1670
+ UNSET,
1671
+ StoreKeyReadonlyError,
1672
+ StoreKeyRangeError,
1673
+ StoreKeyExistsError,
1674
+ NullishSignalValueError,
1675
+ MissingElementError,
1676
+ InvalidSignalValueError,
1677
+ InvalidReactivesError,
1678
+ InvalidPropertyNameError,
1679
+ InvalidEffectsError,
1680
+ InvalidCustomElementError,
1681
+ InvalidComponentNameError,
1682
+ InvalidCallbackError,
1683
+ DependencyTimeoutError,
1684
+ ContextRequestEvent,
1685
+ CircularMutationError,
1686
+ CircularDependencyError,
1687
+ CONTEXT_REQUEST
1688
+ };