@vielzeug/ore 1.2.3 → 2.0.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 (318) hide show
  1. package/README.md +11 -8
  2. package/dist/_component-class.cjs +2 -0
  3. package/dist/_component-class.cjs.map +1 -0
  4. package/dist/_component-class.d.ts +2 -0
  5. package/dist/_component-class.d.ts.map +1 -0
  6. package/dist/_component-class.js +2 -0
  7. package/dist/_component-class.js.map +1 -0
  8. package/dist/_dev.cjs +1 -1
  9. package/dist/_dev.cjs.map +1 -1
  10. package/dist/_dev.js +1 -1
  11. package/dist/_dev.js.map +1 -1
  12. package/dist/base-element.cjs +1 -1
  13. package/dist/base-element.cjs.map +1 -1
  14. package/dist/base-element.d.ts +9 -15
  15. package/dist/base-element.d.ts.map +1 -1
  16. package/dist/base-element.js +1 -1
  17. package/dist/base-element.js.map +1 -1
  18. package/dist/component-types.d.ts +3 -14
  19. package/dist/component-types.d.ts.map +1 -1
  20. package/dist/context.cjs +1 -1
  21. package/dist/context.cjs.map +1 -1
  22. package/dist/context.d.ts +13 -0
  23. package/dist/context.d.ts.map +1 -1
  24. package/dist/context.js +1 -1
  25. package/dist/context.js.map +1 -1
  26. package/dist/define.cjs +1 -1
  27. package/dist/define.cjs.map +1 -1
  28. package/dist/define.d.ts +6 -5
  29. package/dist/define.d.ts.map +1 -1
  30. package/dist/define.js +1 -1
  31. package/dist/define.js.map +1 -1
  32. package/dist/directives/classMap.cjs +1 -1
  33. package/dist/directives/classMap.cjs.map +1 -1
  34. package/dist/directives/classMap.d.ts.map +1 -1
  35. package/dist/directives/classMap.js +1 -1
  36. package/dist/directives/classMap.js.map +1 -1
  37. package/dist/directives/each.cjs +1 -1
  38. package/dist/directives/each.cjs.map +1 -1
  39. package/dist/directives/each.d.ts +9 -2
  40. package/dist/directives/each.d.ts.map +1 -1
  41. package/dist/directives/each.js +1 -1
  42. package/dist/directives/each.js.map +1 -1
  43. package/dist/directives/live.cjs +1 -1
  44. package/dist/directives/live.cjs.map +1 -1
  45. package/dist/directives/live.d.ts +10 -12
  46. package/dist/directives/live.d.ts.map +1 -1
  47. package/dist/directives/live.js +1 -1
  48. package/dist/directives/live.js.map +1 -1
  49. package/dist/directives/styleMap.cjs +1 -1
  50. package/dist/directives/styleMap.cjs.map +1 -1
  51. package/dist/directives/styleMap.d.ts +1 -1
  52. package/dist/directives/styleMap.d.ts.map +1 -1
  53. package/dist/directives/styleMap.js +1 -1
  54. package/dist/directives/styleMap.js.map +1 -1
  55. package/dist/directives/unsafe-html.cjs +2 -0
  56. package/dist/directives/unsafe-html.cjs.map +1 -0
  57. package/dist/directives/unsafe-html.d.ts +14 -0
  58. package/dist/directives/unsafe-html.d.ts.map +1 -0
  59. package/dist/directives/unsafe-html.js +2 -0
  60. package/dist/directives/unsafe-html.js.map +1 -0
  61. package/dist/directives/when.cjs +1 -1
  62. package/dist/directives/when.cjs.map +1 -1
  63. package/dist/directives/when.d.ts +1 -1
  64. package/dist/directives/when.d.ts.map +1 -1
  65. package/dist/directives/when.js +1 -1
  66. package/dist/directives/when.js.map +1 -1
  67. package/dist/errors.cjs +2 -2
  68. package/dist/errors.cjs.map +1 -1
  69. package/dist/errors.d.ts +21 -6
  70. package/dist/errors.d.ts.map +1 -1
  71. package/dist/errors.js +2 -2
  72. package/dist/errors.js.map +1 -1
  73. package/dist/forms/field.cjs +1 -1
  74. package/dist/forms/field.cjs.map +1 -1
  75. package/dist/forms/field.d.ts +5 -1
  76. package/dist/forms/field.d.ts.map +1 -1
  77. package/dist/forms/field.js +1 -1
  78. package/dist/forms/field.js.map +1 -1
  79. package/dist/host-bind.cjs +1 -1
  80. package/dist/host-bind.cjs.map +1 -1
  81. package/dist/host-bind.d.ts +6 -0
  82. package/dist/host-bind.d.ts.map +1 -1
  83. package/dist/host-bind.js +1 -1
  84. package/dist/host-bind.js.map +1 -1
  85. package/dist/index.cjs +1 -1
  86. package/dist/index.d.ts +15 -5
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +1 -1
  89. package/dist/observers/intersection-observe.cjs +1 -1
  90. package/dist/observers/intersection-observe.cjs.map +1 -1
  91. package/dist/observers/intersection-observe.d.ts.map +1 -1
  92. package/dist/observers/intersection-observe.js +1 -1
  93. package/dist/observers/intersection-observe.js.map +1 -1
  94. package/dist/observers/media-observe.cjs +1 -1
  95. package/dist/observers/media-observe.cjs.map +1 -1
  96. package/dist/observers/media-observe.d.ts.map +1 -1
  97. package/dist/observers/media-observe.js +1 -1
  98. package/dist/observers/media-observe.js.map +1 -1
  99. package/dist/observers/mutation-observe.cjs +1 -1
  100. package/dist/observers/mutation-observe.cjs.map +1 -1
  101. package/dist/observers/mutation-observe.d.ts.map +1 -1
  102. package/dist/observers/mutation-observe.js +1 -1
  103. package/dist/observers/mutation-observe.js.map +1 -1
  104. package/dist/observers/resize-observe.cjs +1 -1
  105. package/dist/observers/resize-observe.cjs.map +1 -1
  106. package/dist/observers/resize-observe.d.ts.map +1 -1
  107. package/dist/observers/resize-observe.js +1 -1
  108. package/dist/observers/resize-observe.js.map +1 -1
  109. package/dist/ore.cjs +2 -2
  110. package/dist/ore.cjs.map +1 -1
  111. package/dist/ore.iife.js +2 -2
  112. package/dist/ore.iife.js.map +1 -1
  113. package/dist/ore.js +2 -2
  114. package/dist/ore.js.map +1 -1
  115. package/dist/props.cjs +1 -1
  116. package/dist/props.cjs.map +1 -1
  117. package/dist/props.d.ts +1 -6
  118. package/dist/props.d.ts.map +1 -1
  119. package/dist/props.js +1 -1
  120. package/dist/props.js.map +1 -1
  121. package/dist/runtime.cjs +1 -1
  122. package/dist/runtime.cjs.map +1 -1
  123. package/dist/runtime.d.ts +7 -10
  124. package/dist/runtime.d.ts.map +1 -1
  125. package/dist/runtime.js +1 -1
  126. package/dist/runtime.js.map +1 -1
  127. package/dist/slots.cjs +1 -1
  128. package/dist/slots.cjs.map +1 -1
  129. package/dist/slots.d.ts.map +1 -1
  130. package/dist/slots.js +1 -1
  131. package/dist/slots.js.map +1 -1
  132. package/dist/template/binding-types.cjs +1 -0
  133. package/dist/template/binding-types.d.ts +59 -0
  134. package/dist/template/binding-types.d.ts.map +1 -0
  135. package/dist/template/binding-types.js +1 -0
  136. package/dist/template/bindings.cjs +1 -1
  137. package/dist/template/bindings.cjs.map +1 -1
  138. package/dist/template/bindings.d.ts +18 -3
  139. package/dist/template/bindings.d.ts.map +1 -1
  140. package/dist/template/bindings.js +1 -1
  141. package/dist/template/bindings.js.map +1 -1
  142. package/dist/template/compiler.cjs +1 -1
  143. package/dist/template/compiler.cjs.map +1 -1
  144. package/dist/template/compiler.d.ts +0 -4
  145. package/dist/template/compiler.d.ts.map +1 -1
  146. package/dist/template/compiler.js +1 -1
  147. package/dist/template/compiler.js.map +1 -1
  148. package/dist/template/instantiator.cjs +1 -1
  149. package/dist/template/instantiator.cjs.map +1 -1
  150. package/dist/template/instantiator.d.ts +6 -1
  151. package/dist/template/instantiator.d.ts.map +1 -1
  152. package/dist/template/instantiator.js +1 -1
  153. package/dist/template/instantiator.js.map +1 -1
  154. package/dist/template/result.cjs +2 -0
  155. package/dist/template/result.cjs.map +1 -0
  156. package/dist/template/result.d.ts +42 -0
  157. package/dist/template/result.d.ts.map +1 -0
  158. package/dist/template/result.js +2 -0
  159. package/dist/template/result.js.map +1 -0
  160. package/dist/testing/flush.cjs +1 -1
  161. package/dist/testing/flush.cjs.map +1 -1
  162. package/dist/testing/flush.d.ts +30 -26
  163. package/dist/testing/flush.d.ts.map +1 -1
  164. package/dist/testing/flush.js +1 -1
  165. package/dist/testing/flush.js.map +1 -1
  166. package/dist/testing/form-internals-polyfill.cjs +1 -1
  167. package/dist/testing/form-internals-polyfill.cjs.map +1 -1
  168. package/dist/testing/form-internals-polyfill.d.ts +9 -7
  169. package/dist/testing/form-internals-polyfill.d.ts.map +1 -1
  170. package/dist/testing/form-internals-polyfill.js +1 -1
  171. package/dist/testing/form-internals-polyfill.js.map +1 -1
  172. package/dist/testing/index.d.ts +35 -1
  173. package/dist/testing/index.d.ts.map +1 -1
  174. package/dist/testing/mount.cjs +1 -1
  175. package/dist/testing/mount.cjs.map +1 -1
  176. package/dist/testing/mount.d.ts +10 -19
  177. package/dist/testing/mount.d.ts.map +1 -1
  178. package/dist/testing/mount.js +1 -1
  179. package/dist/testing/mount.js.map +1 -1
  180. package/dist/testing/render-hook.cjs +1 -1
  181. package/dist/testing/render-hook.cjs.map +1 -1
  182. package/dist/testing/render-hook.js +1 -1
  183. package/dist/testing/render-hook.js.map +1 -1
  184. package/dist/testing/reset.cjs +2 -0
  185. package/dist/testing/reset.cjs.map +1 -0
  186. package/dist/testing/reset.d.ts +12 -0
  187. package/dist/testing/reset.d.ts.map +1 -0
  188. package/dist/testing/reset.js +2 -0
  189. package/dist/testing/reset.js.map +1 -0
  190. package/dist/testing.cjs +2 -1
  191. package/dist/testing.cjs.map +1 -0
  192. package/dist/testing.js +2 -1
  193. package/dist/testing.js.map +1 -0
  194. package/dist/utils/aria.cjs.map +1 -1
  195. package/dist/utils/aria.d.ts +1 -1
  196. package/dist/utils/aria.js.map +1 -1
  197. package/dist/utils/brand.cjs +2 -0
  198. package/dist/utils/brand.cjs.map +1 -0
  199. package/dist/utils/brand.d.ts +16 -0
  200. package/dist/utils/brand.d.ts.map +1 -0
  201. package/dist/utils/brand.js +2 -0
  202. package/dist/utils/brand.js.map +1 -0
  203. package/dist/utils/css.cjs +1 -1
  204. package/dist/utils/css.cjs.map +1 -1
  205. package/dist/utils/css.d.ts.map +1 -1
  206. package/dist/utils/css.js +1 -1
  207. package/dist/utils/css.js.map +1 -1
  208. package/dist/utils/dom.cjs +1 -1
  209. package/dist/utils/dom.cjs.map +1 -1
  210. package/dist/utils/dom.d.ts +34 -0
  211. package/dist/utils/dom.d.ts.map +1 -1
  212. package/dist/utils/dom.js +1 -1
  213. package/dist/utils/dom.js.map +1 -1
  214. package/dist/utils/emit.cjs.map +1 -1
  215. package/dist/utils/emit.d.ts +10 -3
  216. package/dist/utils/emit.d.ts.map +1 -1
  217. package/dist/utils/emit.js.map +1 -1
  218. package/dist/utils/id.cjs +1 -1
  219. package/dist/utils/id.cjs.map +1 -1
  220. package/dist/utils/id.d.ts +11 -2
  221. package/dist/utils/id.d.ts.map +1 -1
  222. package/dist/utils/id.js +1 -1
  223. package/dist/utils/id.js.map +1 -1
  224. package/package.json +15 -30
  225. package/dist/aria.cjs +0 -2
  226. package/dist/aria.cjs.map +0 -1
  227. package/dist/aria.d.ts +0 -20
  228. package/dist/aria.d.ts.map +0 -1
  229. package/dist/aria.js +0 -2
  230. package/dist/aria.js.map +0 -1
  231. package/dist/devtools.cjs +0 -2
  232. package/dist/devtools.cjs.map +0 -1
  233. package/dist/devtools.d.ts +0 -32
  234. package/dist/devtools.d.ts.map +0 -1
  235. package/dist/devtools.js +0 -2
  236. package/dist/devtools.js.map +0 -1
  237. package/dist/directives/index.d.ts +0 -8
  238. package/dist/directives/index.d.ts.map +0 -1
  239. package/dist/directives/model.cjs +0 -2
  240. package/dist/directives/model.cjs.map +0 -1
  241. package/dist/directives/model.d.ts +0 -28
  242. package/dist/directives/model.d.ts.map +0 -1
  243. package/dist/directives/model.js +0 -2
  244. package/dist/directives/model.js.map +0 -1
  245. package/dist/directives/raw.cjs +0 -2
  246. package/dist/directives/raw.cjs.map +0 -1
  247. package/dist/directives/raw.d.ts +0 -16
  248. package/dist/directives/raw.d.ts.map +0 -1
  249. package/dist/directives/raw.js +0 -2
  250. package/dist/directives/raw.js.map +0 -1
  251. package/dist/directives.cjs +0 -1
  252. package/dist/directives.js +0 -1
  253. package/dist/forms/context.cjs +0 -2
  254. package/dist/forms/context.cjs.map +0 -1
  255. package/dist/forms/context.d.ts +0 -56
  256. package/dist/forms/context.d.ts.map +0 -1
  257. package/dist/forms/context.js +0 -2
  258. package/dist/forms/context.js.map +0 -1
  259. package/dist/forms/index.d.ts +0 -11
  260. package/dist/forms/index.d.ts.map +0 -1
  261. package/dist/forms.cjs +0 -1
  262. package/dist/forms.js +0 -1
  263. package/dist/observers/index.d.ts +0 -5
  264. package/dist/observers/index.d.ts.map +0 -1
  265. package/dist/observers.cjs +0 -1
  266. package/dist/observers.js +0 -1
  267. package/dist/template.cjs +0 -1
  268. package/dist/template.d.ts +0 -4
  269. package/dist/template.d.ts.map +0 -1
  270. package/dist/template.js +0 -1
  271. package/dist/testing/events.cjs +0 -2
  272. package/dist/testing/events.cjs.map +0 -1
  273. package/dist/testing/events.d.ts +0 -37
  274. package/dist/testing/events.d.ts.map +0 -1
  275. package/dist/testing/events.js +0 -2
  276. package/dist/testing/events.js.map +0 -1
  277. package/dist/testing/interactions.cjs +0 -2
  278. package/dist/testing/interactions.cjs.map +0 -1
  279. package/dist/testing/interactions.d.ts +0 -27
  280. package/dist/testing/interactions.d.ts.map +0 -1
  281. package/dist/testing/interactions.js +0 -2
  282. package/dist/testing/interactions.js.map +0 -1
  283. package/dist/testing/query.cjs +0 -2
  284. package/dist/testing/query.cjs.map +0 -1
  285. package/dist/testing/query.d.ts +0 -24
  286. package/dist/testing/query.d.ts.map +0 -1
  287. package/dist/testing/query.js +0 -2
  288. package/dist/testing/query.js.map +0 -1
  289. package/dist/testing/testing.cjs +0 -2
  290. package/dist/testing/testing.cjs.map +0 -1
  291. package/dist/testing/testing.d.ts +0 -32
  292. package/dist/testing/testing.d.ts.map +0 -1
  293. package/dist/testing/testing.js +0 -2
  294. package/dist/testing/testing.js.map +0 -1
  295. package/dist/testing/wait.cjs +0 -2
  296. package/dist/testing/wait.cjs.map +0 -1
  297. package/dist/testing/wait.d.ts +0 -35
  298. package/dist/testing/wait.d.ts.map +0 -1
  299. package/dist/testing/wait.js +0 -2
  300. package/dist/testing/wait.js.map +0 -1
  301. package/dist/types/bindings.cjs +0 -2
  302. package/dist/types/bindings.cjs.map +0 -1
  303. package/dist/types/bindings.d.ts +0 -125
  304. package/dist/types/bindings.d.ts.map +0 -1
  305. package/dist/types/bindings.js +0 -2
  306. package/dist/types/bindings.js.map +0 -1
  307. package/dist/types.cjs +0 -2
  308. package/dist/types.cjs.map +0 -1
  309. package/dist/types.d.ts +0 -19
  310. package/dist/types.d.ts.map +0 -1
  311. package/dist/types.js +0 -2
  312. package/dist/types.js.map +0 -1
  313. package/dist/utils/event-modifiers.cjs +0 -2
  314. package/dist/utils/event-modifiers.cjs.map +0 -1
  315. package/dist/utils/event-modifiers.d.ts +0 -11
  316. package/dist/utils/event-modifiers.d.ts.map +0 -1
  317. package/dist/utils/event-modifiers.js +0 -2
  318. package/dist/utils/event-modifiers.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{invariant as e}from"../errors.js";import{createDirectiveResult as t,isHtmlResult as n}from"../types/bindings.js";import{removeNodes as r,runAll as i}from"../utils/dom.js";import{computed as a,effect as o,isReactive as s,untrack as c}from"@vielzeug/ripple";var l=`when() anchor comment has no parent node`,u=(e,t,n,r)=>e.mount(t,n,r);function d(d,f,p){return typeof d!=`function`&&!s(d)?t((t,i)=>{let a=d?f():p?p():null;if(!a||!n(a))return;let o=t.parentNode;e(o,l);let s=u(a,o,t,i);i(()=>r(s))}):t((t,s)=>{let m=typeof d==`function`?a(d):null,h=m??d;m&&s(()=>m.dispose());let g=t.parentNode;e(g,l);let _=document.createComment(`when/end`);g.insertBefore(_,t.nextSibling);let v=[],y=[],b=o(()=>{let e=h.value;i(y),r(v),y=[],v=[];let t=e?f():p?p():null;if(!t||!n(t))return;let a=[];v=c(()=>u(t,g,_,e=>a.push(e))),y=a});s(()=>b.dispose()),s(()=>{i(y),r(v),_.remove()})})}export{d as when};
1
+ import{invariant as e}from"../errors.js";import{createReplaceableSlot as t,removeNodes as n}from"../utils/dom.js";import{createDirectiveResult as r,isHtmlResult as i}from"../template/result.js";import{computed as a,effect as o,isReactive as s,untrack as c}from"@vielzeug/ripple";var l=`when() anchor comment has no parent node`;function u(u,d,f){return typeof u!=`function`&&!s(u)?r((t,r)=>{let a=u?d():f?f():null;if(!a||!i(a))return;let o=t.parentNode;e(o,l);let s=a.mount(o,t,r);r(()=>n(s))}):r((n,r)=>{let s=(typeof u==`function`?a(u):null)??u,p=n.parentNode;e(p,l);let m=document.createComment(`when/end`);p.insertBefore(m,n.nextSibling);let h=t(),g=o(()=>{let e=s.value;h.clear();let t=e?d():f?f():null;!t||!i(t)||h.setNodes(c(()=>t.mount(p,m,h.registerCleanup)))});r(()=>g.dispose()),r(()=>{h.clear(),m.remove()})})}export{u as when};
2
2
  //# sourceMappingURL=when.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"when.js","names":[],"sources":["../../src/directives/when.ts"],"sourcesContent":["import { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport type { RegisterCleanup } from '../template';\n\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult, isHtmlResult } from '../types/bindings';\nimport { removeNodes, runAll } from '../utils/dom';\n\ntype MaybeReactive<T> = T | (() => T) | Readable<T>;\n\ntype WhenRenderable = HTMLResult | null | undefined | false;\n\nconst NO_PARENT_MSG = 'when() anchor comment has no parent node';\n\nconst mountBranch = (\n result: HTMLResult,\n parent: ParentNode,\n insertBefore: Node,\n registerCleanup: RegisterCleanup,\n): Node[] => result.mount(parent, insertBefore, registerCleanup);\n\n/**\n * Conditionally renders one of two branches as a `DirectiveResult`.\n *\n * The condition may be a boolean, signal, or getter function.\n * When the condition changes, the current branch is cleaned up and\n * the new branch is mounted in its place.\n *\n * @example\n * ```ts\n * html`${when(isLoggedIn, () => html`<p>Welcome</p>`, () => html`<p>Log in</p>`)}`\n * ```\n */\nexport function when(\n condition: MaybeReactive<boolean>,\n truthy: () => WhenRenderable,\n falsy?: () => WhenRenderable,\n): DirectiveResult {\n if (typeof condition !== 'function' && !isReactive(condition)) {\n return createDirectiveResult((anchor, registerCleanup) => {\n const branch = condition ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const nodes = mountBranch(branch, parent, anchor, registerCleanup);\n\n registerCleanup(() => removeNodes(nodes));\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const ownedComputed = typeof condition === 'function' ? computed(condition as () => boolean) : null;\n const conditionSignal = ownedComputed ?? (condition as Readable<boolean>);\n\n if (ownedComputed) registerCleanup(() => ownedComputed.dispose());\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const endMarker = document.createComment('when/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n let currentNodes: Node[] = [];\n let currentCleanups: (() => void)[] = [];\n\n const sub = rawEffect(() => {\n const next = conditionSignal.value;\n\n runAll(currentCleanups);\n removeNodes(currentNodes);\n currentCleanups = [];\n currentNodes = [];\n\n const branch = next ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const branchCleanups: (() => void)[] = [];\n\n currentNodes = untrack(() => mountBranch(branch, parent, endMarker, (fn) => branchCleanups.push(fn)));\n currentCleanups = branchCleanups;\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n runAll(currentCleanups);\n removeNodes(currentNodes);\n endMarker.remove();\n });\n });\n}\n"],"mappings":"uQAYA,IAAM,EAAgB,2CAEhB,GACJ,EACA,EACA,EACA,IACW,EAAO,MAAM,EAAQ,EAAc,CAAe,EAc/D,SAAgB,EACd,EACA,EACA,EACiB,CAiBjB,OAhBI,OAAO,GAAc,YAAc,CAAC,EAAW,CAAS,EACnD,GAAuB,EAAQ,IAAoB,CACxD,IAAM,EAAS,EAAY,EAAO,EAAI,EAAQ,EAAM,EAAI,KAExD,GAAI,CAAC,GAAU,CAAC,EAAa,CAAM,EAAG,OAEtC,IAAM,EAAS,EAAO,WAEtB,EAAU,EAAQ,CAAa,EAE/B,IAAM,EAAQ,EAAY,EAAQ,EAAQ,EAAQ,CAAe,EAEjE,MAAsB,EAAY,CAAK,CAAC,CAC1C,CAAC,EAGI,GAAuB,EAAQ,IAAoB,CACxD,IAAM,EAAgB,OAAO,GAAc,WAAa,EAAS,CAA0B,EAAI,KACzF,EAAkB,GAAkB,EAEtC,GAAe,MAAsB,EAAc,QAAQ,CAAC,EAEhE,IAAM,EAAS,EAAO,WAEtB,EAAU,EAAQ,CAAa,EAE/B,IAAM,EAAY,SAAS,cAAc,UAAU,EAEnD,EAAO,aAAa,EAAW,EAAO,WAAW,EAEjD,IAAI,EAAuB,CAAC,EACxB,EAAkC,CAAC,EAEjC,EAAM,MAAgB,CAC1B,IAAM,EAAO,EAAgB,MAE7B,EAAO,CAAe,EACtB,EAAY,CAAY,EACxB,EAAkB,CAAC,EACnB,EAAe,CAAC,EAEhB,IAAM,EAAS,EAAO,EAAO,EAAI,EAAQ,EAAM,EAAI,KAEnD,GAAI,CAAC,GAAU,CAAC,EAAa,CAAM,EAAG,OAEtC,IAAM,EAAiC,CAAC,EAExC,EAAe,MAAc,EAAY,EAAQ,EAAQ,EAAY,GAAO,EAAe,KAAK,CAAE,CAAC,CAAC,EACpG,EAAkB,CACpB,CAAC,EAED,MAAsB,EAAI,QAAQ,CAAC,EACnC,MAAsB,CACpB,EAAO,CAAe,EACtB,EAAY,CAAY,EACxB,EAAU,OAAO,CACnB,CAAC,CACH,CAAC,CACH"}
1
+ {"version":3,"file":"when.js","names":[],"sources":["../../src/directives/when.ts"],"sourcesContent":["import { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult, isHtmlResult } from '../template/result';\nimport { createReplaceableSlot, removeNodes } from '../utils/dom';\n\ntype MaybeReactive<T> = T | (() => T) | Readable<T>;\n\ntype WhenRenderable = HTMLResult | null | undefined | false;\n\nconst NO_PARENT_MSG = 'when() anchor comment has no parent node';\n\n/**\n * Conditionally renders one of two branches as a `DirectiveResult`.\n *\n * The condition may be a boolean, signal, or getter function.\n * When the condition changes, the current branch is cleaned up and\n * the new branch is mounted in its place.\n *\n * @example\n * ```ts\n * html`${when(isLoggedIn, () => html`<p>Welcome</p>`, () => html`<p>Log in</p>`)}`\n * ```\n */\nexport function when(\n condition: MaybeReactive<boolean>,\n truthy: () => WhenRenderable,\n falsy?: () => WhenRenderable,\n): DirectiveResult {\n if (typeof condition !== 'function' && !isReactive(condition)) {\n return createDirectiveResult((anchor, registerCleanup) => {\n const branch = condition ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const nodes = branch.mount(parent, anchor, registerCleanup);\n\n registerCleanup(() => removeNodes(nodes));\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const ownedComputed = typeof condition === 'function' ? computed(condition as () => boolean) : null;\n const conditionSignal = ownedComputed ?? (condition as Readable<boolean>);\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const endMarker = document.createComment('when/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n const slot = createReplaceableSlot();\n\n const sub = rawEffect(() => {\n const next = conditionSignal.value;\n\n slot.clear();\n\n const branch = next ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n slot.setNodes(untrack(() => branch.mount(parent, endMarker, slot.registerCleanup)));\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n slot.clear();\n endMarker.remove();\n });\n });\n}\n"],"mappings":"uRAUA,IAAM,EAAgB,2CActB,SAAgB,EACd,EACA,EACA,EACiB,CAiBjB,OAhBI,OAAO,GAAc,YAAc,CAAC,EAAW,CAAS,EACnD,GAAuB,EAAQ,IAAoB,CACxD,IAAM,EAAS,EAAY,EAAO,EAAI,EAAQ,EAAM,EAAI,KAExD,GAAI,CAAC,GAAU,CAAC,EAAa,CAAM,EAAG,OAEtC,IAAM,EAAS,EAAO,WAEtB,EAAU,EAAQ,CAAa,EAE/B,IAAM,EAAQ,EAAO,MAAM,EAAQ,EAAQ,CAAe,EAE1D,MAAsB,EAAY,CAAK,CAAC,CAC1C,CAAC,EAGI,GAAuB,EAAQ,IAAoB,CAExD,IAAM,GADgB,OAAO,GAAc,WAAa,EAAS,CAA0B,EAAI,OACrD,EAEpC,EAAS,EAAO,WAEtB,EAAU,EAAQ,CAAa,EAE/B,IAAM,EAAY,SAAS,cAAc,UAAU,EAEnD,EAAO,aAAa,EAAW,EAAO,WAAW,EAEjD,IAAM,EAAO,EAAsB,EAE7B,EAAM,MAAgB,CAC1B,IAAM,EAAO,EAAgB,MAE7B,EAAK,MAAM,EAEX,IAAM,EAAS,EAAO,EAAO,EAAI,EAAQ,EAAM,EAAI,KAE/C,CAAC,GAAU,CAAC,EAAa,CAAM,GAEnC,EAAK,SAAS,MAAc,EAAO,MAAM,EAAQ,EAAW,EAAK,eAAe,CAAC,CAAC,CACpF,CAAC,EAED,MAAsB,EAAI,QAAQ,CAAC,EACnC,MAAsB,CACpB,EAAK,MAAM,EACX,EAAU,OAAO,CACnB,CAAC,CACH,CAAC,CACH"}
package/dist/errors.cjs CHANGED
@@ -1,3 +1,3 @@
1
- const e=require("./_dev.cjs");var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{constructor(e){super(e)}},r=class extends t{constructor(e){super(e)}},i=class extends t{component;phase;constructor(e,t){super(e,{cause:t.cause}),this.component=t.component,this.phase=t.phase}};function a(t,n){e.error(`<${t.component}> setup error (phase: ${t.phase}):`,t.cause),n.dispatchEvent(new CustomEvent(`ore:error`,{bubbles:!0,composed:!0,detail:t}))}var o=class extends t{},s={defineDuplicate:e=>`define('${e}') called twice — custom element already registered`,defineFieldRequiresFormAssociated:e=>`useField() requires define('${e}', { formAssociated: true })`,defineRequiresTag:`define() requires a tag name`,eachDuplicateKey:(e,t)=>`each() received duplicate key "${e}" at index ${t}`,injectStrictFailed:(e,t)=>`injectStrict() could not resolve key "${e}" in <${t}>`,invalidDynamicTagName:e=>`html\`...\`: dynamic tag name "${e}" is not a valid HTML element name`,invariantViolated:e=>`invariant violated: ${e}`,lifecycleOutsideSetup:`Lifecycle hooks must be called during component setup`,mismatchedDynamicCloseTag:"html`...`: dynamic closing tag has no matching dynamic opening tag",propInvalidReflect:`Structured props cannot use reflect:true — use prop.json() with reflect:false`,validationFailed:(e,t)=>`Validation failed for <${e}>:\n${t.join(`
2
- `)}`};function c(e,t){if(!e)throw new r(s.invariantViolated(t))}exports.ORE_ERRORS=s,exports.OreApiError=n,exports.OreError=t,exports.OreInternalError=r,exports.OreLifecycleError=i,exports.OreTimeoutError=o,exports.invariant=c,exports.reportRuntimeError=a;
1
+ require("./_dev.cjs");var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{constructor(e){super(e)}},n=class extends e{constructor(e){super(e)}},r=class extends e{component;phase;constructor(e,t){super(e,{cause:t.cause}),this.component=t.component,this.phase=t.phase}};function i(e,t){`${e.component}${e.phase}`,e.cause,t.dispatchEvent(new CustomEvent(`ore:error`,{bubbles:!0,composed:!0,detail:e}))}var a=class extends e{},o={asyncSetupUnsupported:`setup() must return an HTMLResult or null; use reactive state for asynchronous work`,defineDuplicate:e=>`define('${e}') called twice — custom element already registered`,defineFieldRequiresFormAssociated:e=>`useField() requires define('${e}', { formAssociated: true })`,defineRequiresTag:`define() requires a tag name`,eachDuplicateKey:(e,t)=>`each() received duplicate key "${e}" at index ${t}`,eventModifiersUnsupported:e=>`@${e}: event modifiers are unsupported; call native event methods in the handler instead`,injectStrictFailed:(e,t)=>`injectStrict() could not resolve key "${e}" in <${t}>`,invariantViolated:e=>`invariant violated: ${e}`,lifecycleOutsideSetup:`Lifecycle hooks must be called during component setup`,listenNullTarget:e=>`listen() called with a null/undefined target for event "${e}" — listener not attached`,propInvalidReflect:`Structured props cannot use reflect:true — use prop.json() with reflect:false`,templateInterpolationInTag:"html`...`: interpolations inside a tag must be named attributes, boolean attributes, events, or refs",useFieldAlreadyCalled:e=>`useField() was already called on <${e}>. Call it only once per component.`,validationFailed:(e,t)=>`Validation failed for <${e}>:\n${t.join(`
2
+ `)}`};function s(e,t){if(!e)throw new n(o.invariantViolated(t))}exports.ORE_ERRORS=o,exports.OreApiError=t,exports.OreError=e,exports.OreInternalError=n,exports.OreLifecycleError=r,exports.OreTimeoutError=a,exports.invariant=s,exports.reportRuntimeError=i;
3
3
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { error as logError } from './_dev';\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'async-setup'` — async setup() promise rejected\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n */\nexport type OreErrorPhase = 'async-setup' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n */\nexport function reportRuntimeError(error: OreLifecycleError, element: HTMLElement): void {\n logError(`<${error.component}> setup error (phase: ${error.phase}):`, error.cause);\n\n element.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `waitFor` and `waitForEvent` in the testing sub-path when a condition is not met within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invalidDynamicTagName: (tagName: string): string =>\n `html\\`...\\`: dynamic tag name \"${tagName}\" is not a valid HTML element name`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n mismatchedDynamicCloseTag: 'html`...`: dynamic closing tag has no matching dynamic opening tag',\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n"],"mappings":"8BAKA,IAAa,EAAb,MAAa,UAAiB,KAAM,CAClC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAA+B,CACvC,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAiC,CAAS,CACxC,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAOa,EAAb,cAAsC,CAAS,CAC7C,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAea,EAAb,cAAuC,CAAS,CAC9C,UACA,MAEA,YAAY,EAAiB,EAAoE,CAC/F,MAAM,EAAS,CAAE,MAAO,EAAQ,KAAM,CAAC,EACvC,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAKA,SAAgB,EAAmB,EAA0B,EAA4B,CACvF,EAAA,MAAS,IAAI,EAAM,UAAU,wBAAwB,EAAM,MAAM,IAAK,EAAM,KAAK,EAEjF,EAAQ,cACN,IAAI,YAAY,YAAa,CAC3B,QAAS,GACT,SAAU,GACV,OAAQ,CACV,CAAC,CACH,CACF,CAKA,IAAa,EAAb,cAAqC,CAAS,CAAC,EAElC,EAAa,CACxB,gBAAkB,GAAwB,WAAW,EAAI,qDACzD,kCAAoC,GAClC,+BAA+B,EAAI,8BACrC,kBAAmB,+BACnB,kBAAmB,EAAa,IAA0B,kCAAkC,EAAI,aAAa,IAC7G,oBAAqB,EAAa,IAAwB,yCAAyC,EAAI,QAAQ,EAAI,GACnH,sBAAwB,GACtB,kCAAkC,EAAQ,oCAC5C,kBAAoB,GAA4B,uBAAuB,IACvE,sBAAuB,wDACvB,0BAA2B,qEAC3B,mBAAoB,gFACpB,kBAAmB,EAAa,IAA6B,0BAA0B,EAAI,MAAM,EAAO,KAAK;CAAI,GACnH,EAYA,SAAgB,EAAU,EAAoB,EAAoC,CAChF,GAAI,CAAC,EAAW,MAAM,IAAI,EAAiB,EAAW,kBAAkB,CAAO,CAAC,CAClF"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { error as logError } from './_dev';\n\n// ─── Error policy ─────────────────────────────────────────────────────────────\n// One rule for the whole package — decide by whose code failed and whether it\n// can continue, never ad hoc per call site:\n//\n// API misuse (wrong arguments, hook outside setup, duplicate define)\n// → throw `OreApiError`, immediately, every build.\n// User-authored code failing inside ore's execution (setup, onMounted,\n// onFormReset, each() reconciliation)\n// → wrap in `OreLifecycleError` and report via `reportRuntimeError()`\n// (`ore:error` DOM event + dev console) so other callbacks keep running.\n// Recoverable oddity (overwrite warnings, blocked attribute writes)\n// → dev `warn()`/`error()` and continue. Never swallow silently.\n// Internal impossibility (compiled template metadata out of sync)\n// → `invariant()` throws `OreInternalError`, every build.\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n * - `'each-reconcile'` — `each()` failed to reconcile a list update (e.g. duplicate keys)\n */\nexport type OreErrorPhase = 'each-reconcile' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n *\n * `target` only needs to be an `EventTarget` (not specifically an `HTMLElement`) — component\n * lifecycle errors dispatch on the host element, but non-lifecycle failures (e.g. `each()`\n * reconciliation, which has no single \"component\" to attribute the error to) dispatch on\n * whatever live DOM node is available, such as the directive's own anchor `Comment`. Either way\n * the event still bubbles and crosses shadow boundaries (`composed: true`), so a listener on\n * `document`/`window` observes every report regardless of where it originated.\n *\n * The console log (via `_dev.ts`'s `error()`) is still dev-gated like the rest of the package's\n * console diagnostics, but the `ore:error` DOM event dispatch below is **not** — it fires in\n * every build, so consumers always have a way to observe runtime failures programmatically even\n * when console output is stripped in production.\n */\nexport function reportRuntimeError(error: OreLifecycleError, target: EventTarget): void {\n logError(`<${error.component}> lifecycle error (phase: ${error.phase}):`, error.cause);\n\n target.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `flush()` in the testing sub-path when pending component work doesn't settle within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n asyncSetupUnsupported: 'setup() must return an HTMLResult or null; use reactive state for asynchronous work',\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n eventModifiersUnsupported: (eventName: string): string =>\n `@${eventName}: event modifiers are unsupported; call native event methods in the handler instead`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n listenNullTarget: (eventName: string): string =>\n `listen() called with a null/undefined target for event \"${eventName}\" — listener not attached`,\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n templateInterpolationInTag:\n 'html`...`: interpolations inside a tag must be named attributes, boolean attributes, events, or refs',\n useFieldAlreadyCalled: (tag: string): string =>\n `useField() was already called on <${tag}>. Call it only once per component.`,\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n"],"mappings":"sBAoBA,IAAa,EAAb,MAAa,UAAiB,KAAM,CAClC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAA+B,CACvC,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAiC,CAAS,CACxC,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAOa,EAAb,cAAsC,CAAS,CAC7C,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAea,EAAb,cAAuC,CAAS,CAC9C,UACA,MAEA,YAAY,EAAiB,EAAoE,CAC/F,MAAM,EAAS,CAAE,MAAO,EAAQ,KAAM,CAAC,EACvC,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAiBA,SAAgB,EAAmB,EAA0B,EAA2B,CAC7E,GAAI,EAAM,UAAV,EAAgD,EAAM,MAAtD,EAAiE,EAAM,MAEhF,EAAO,cACL,IAAI,YAAY,YAAa,CAC3B,QAAS,GACT,SAAU,GACV,OAAQ,CACV,CAAC,CACH,CACF,CAKA,IAAa,EAAb,cAAqC,CAAS,CAAC,EAElC,EAAa,CACxB,sBAAuB,sFACvB,gBAAkB,GAAwB,WAAW,EAAI,qDACzD,kCAAoC,GAClC,+BAA+B,EAAI,8BACrC,kBAAmB,+BACnB,kBAAmB,EAAa,IAA0B,kCAAkC,EAAI,aAAa,IAC7G,0BAA4B,GAC1B,IAAI,EAAU,qFAChB,oBAAqB,EAAa,IAAwB,yCAAyC,EAAI,QAAQ,EAAI,GACnH,kBAAoB,GAA4B,uBAAuB,IACvE,sBAAuB,wDACvB,iBAAmB,GACjB,2DAA2D,EAAU,2BACvE,mBAAoB,gFACpB,2BACE,uGACF,sBAAwB,GACtB,qCAAqC,EAAI,qCAC3C,kBAAmB,EAAa,IAA6B,0BAA0B,EAAI,MAAM,EAAO,KAAK;CAAI,GACnH,EAYA,SAAgB,EAAU,EAAoB,EAAoC,CAChF,GAAI,CAAC,EAAW,MAAM,IAAI,EAAiB,EAAW,kBAAkB,CAAO,CAAC,CAClF"}
package/dist/errors.d.ts CHANGED
@@ -18,11 +18,11 @@ export declare class OreInternalError extends OreError {
18
18
  /**
19
19
  * The phase in which a component error occurred.
20
20
  * - `'setup'` — synchronous setup() threw
21
- * - `'async-setup'` — async setup() promise rejected
22
21
  * - `'mounted'` — an onMounted callback threw
23
22
  * - `'form-reset'` — an onFormReset callback threw
23
+ * - `'each-reconcile'` — `each()` failed to reconcile a list update (e.g. duplicate keys)
24
24
  */
25
- export type OreErrorPhase = 'async-setup' | 'form-reset' | 'mounted' | 'setup';
25
+ export type OreErrorPhase = 'each-reconcile' | 'form-reset' | 'mounted' | 'setup';
26
26
  /**
27
27
  * Structured error thrown by the Ore runtime when component setup fails.
28
28
  * Provides component name and original cause for debugging.
@@ -38,22 +38,37 @@ export declare class OreLifecycleError extends OreError {
38
38
  }
39
39
  /**
40
40
  * Report a runtime error via the ore:error event and console.
41
+ *
42
+ * `target` only needs to be an `EventTarget` (not specifically an `HTMLElement`) — component
43
+ * lifecycle errors dispatch on the host element, but non-lifecycle failures (e.g. `each()`
44
+ * reconciliation, which has no single "component" to attribute the error to) dispatch on
45
+ * whatever live DOM node is available, such as the directive's own anchor `Comment`. Either way
46
+ * the event still bubbles and crosses shadow boundaries (`composed: true`), so a listener on
47
+ * `document`/`window` observes every report regardless of where it originated.
48
+ *
49
+ * The console log (via `_dev.ts`'s `error()`) is still dev-gated like the rest of the package's
50
+ * console diagnostics, but the `ore:error` DOM event dispatch below is **not** — it fires in
51
+ * every build, so consumers always have a way to observe runtime failures programmatically even
52
+ * when console output is stripped in production.
41
53
  */
42
- export declare function reportRuntimeError(error: OreLifecycleError, element: HTMLElement): void;
43
- /** Thrown by `waitFor` and `waitForEvent` in the testing sub-path when a condition is not met within the timeout. */
54
+ export declare function reportRuntimeError(error: OreLifecycleError, target: EventTarget): void;
55
+ /** Thrown by `flush()` in the testing sub-path when pending component work doesn't settle within the timeout. */
44
56
  export declare class OreTimeoutError extends OreError {
45
57
  }
46
58
  export declare const ORE_ERRORS: {
59
+ readonly asyncSetupUnsupported: "setup() must return an HTMLResult or null; use reactive state for asynchronous work";
47
60
  readonly defineDuplicate: (tag: string) => string;
48
61
  readonly defineFieldRequiresFormAssociated: (tag: string) => string;
49
62
  readonly defineRequiresTag: "define() requires a tag name";
50
63
  readonly eachDuplicateKey: (key: string, index: number) => string;
64
+ readonly eventModifiersUnsupported: (eventName: string) => string;
51
65
  readonly injectStrictFailed: (key: string, tag: string) => string;
52
- readonly invalidDynamicTagName: (tagName: string) => string;
53
66
  readonly invariantViolated: (message: string) => string;
54
67
  readonly lifecycleOutsideSetup: "Lifecycle hooks must be called during component setup";
55
- readonly mismatchedDynamicCloseTag: "html`...`: dynamic closing tag has no matching dynamic opening tag";
68
+ readonly listenNullTarget: (eventName: string) => string;
56
69
  readonly propInvalidReflect: "Structured props cannot use reflect:true — use prop.json() with reflect:false";
70
+ readonly templateInterpolationInTag: "html`...`: interpolations inside a tag must be named attributes, boolean attributes, events, or refs";
71
+ readonly useFieldAlreadyCalled: (tag: string) => string;
57
72
  readonly validationFailed: (tag: string, errors: string[]) => string;
58
73
  };
59
74
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,kGAAkG;AAClG,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ;CAGzC;AAED,sGAAsG;AACtG,qBAAa,WAAY,SAAQ,QAAQ;gBAC3B,OAAO,EAAE,MAAM;CAG5B;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;gBAChC,OAAO,EAAE,MAAM;CAG5B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/E;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE;CAKhG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAUvF;AAID,qHAAqH;AACrH,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD,eAAO,MAAM,UAAU;oCACE,MAAM,KAAG,MAAM;sDACG,MAAM,KAAG,MAAM;;qCAGhC,MAAM,SAAS,MAAM,KAAG,MAAM;uCAC5B,MAAM,OAAO,MAAM,KAAG,MAAM;8CACrB,MAAM,KAAG,MAAM;0CAEnB,MAAM,KAAG,MAAM;;;;qCAIpB,MAAM,UAAU,MAAM,EAAE,KAAG,MAAM;CACjD,CAAC;AAEX;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAEhF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAmBA,kGAAkG;AAClG,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ;CAGzC;AAED,sGAAsG;AACtG,qBAAa,WAAY,SAAQ,QAAQ;gBAC3B,OAAO,EAAE,MAAM;CAG5B;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;gBAChC,OAAO,EAAE,MAAM;CAG5B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAElF;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE;CAKhG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAUtF;AAID,iHAAiH;AACjH,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD,eAAO,MAAM,UAAU;;oCAEE,MAAM,KAAG,MAAM;sDACG,MAAM,KAAG,MAAM;;qCAGhC,MAAM,SAAS,MAAM,KAAG,MAAM;oDACf,MAAM,KAAG,MAAM;uCAE5B,MAAM,OAAO,MAAM,KAAG,MAAM;0CACzB,MAAM,KAAG,MAAM;;2CAEd,MAAM,KAAG,MAAM;;;0CAKhB,MAAM,KAAG,MAAM;qCAEpB,MAAM,UAAU,MAAM,EAAE,KAAG,MAAM;CACjD,CAAC;AAEX;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAEhF"}
package/dist/errors.js CHANGED
@@ -1,3 +1,3 @@
1
- import{error as e}from"./_dev.js";var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{constructor(e){super(e)}},r=class extends t{constructor(e){super(e)}},i=class extends t{component;phase;constructor(e,t){super(e,{cause:t.cause}),this.component=t.component,this.phase=t.phase}};function a(t,n){e(`<${t.component}> setup error (phase: ${t.phase}):`,t.cause),n.dispatchEvent(new CustomEvent(`ore:error`,{bubbles:!0,composed:!0,detail:t}))}var o=class extends t{},s={defineDuplicate:e=>`define('${e}') called twice — custom element already registered`,defineFieldRequiresFormAssociated:e=>`useField() requires define('${e}', { formAssociated: true })`,defineRequiresTag:`define() requires a tag name`,eachDuplicateKey:(e,t)=>`each() received duplicate key "${e}" at index ${t}`,injectStrictFailed:(e,t)=>`injectStrict() could not resolve key "${e}" in <${t}>`,invalidDynamicTagName:e=>`html\`...\`: dynamic tag name "${e}" is not a valid HTML element name`,invariantViolated:e=>`invariant violated: ${e}`,lifecycleOutsideSetup:`Lifecycle hooks must be called during component setup`,mismatchedDynamicCloseTag:"html`...`: dynamic closing tag has no matching dynamic opening tag",propInvalidReflect:`Structured props cannot use reflect:true — use prop.json() with reflect:false`,validationFailed:(e,t)=>`Validation failed for <${e}>:\n${t.join(`
2
- `)}`};function c(e,t){if(!e)throw new r(s.invariantViolated(t))}export{s as ORE_ERRORS,n as OreApiError,t as OreError,r as OreInternalError,i as OreLifecycleError,o as OreTimeoutError,c as invariant,a as reportRuntimeError};
1
+ import"./_dev.js";var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{constructor(e){super(e)}},n=class extends e{constructor(e){super(e)}},r=class extends e{component;phase;constructor(e,t){super(e,{cause:t.cause}),this.component=t.component,this.phase=t.phase}};function i(e,t){`${e.component}${e.phase}`,e.cause,t.dispatchEvent(new CustomEvent(`ore:error`,{bubbles:!0,composed:!0,detail:e}))}var a=class extends e{},o={asyncSetupUnsupported:`setup() must return an HTMLResult or null; use reactive state for asynchronous work`,defineDuplicate:e=>`define('${e}') called twice — custom element already registered`,defineFieldRequiresFormAssociated:e=>`useField() requires define('${e}', { formAssociated: true })`,defineRequiresTag:`define() requires a tag name`,eachDuplicateKey:(e,t)=>`each() received duplicate key "${e}" at index ${t}`,eventModifiersUnsupported:e=>`@${e}: event modifiers are unsupported; call native event methods in the handler instead`,injectStrictFailed:(e,t)=>`injectStrict() could not resolve key "${e}" in <${t}>`,invariantViolated:e=>`invariant violated: ${e}`,lifecycleOutsideSetup:`Lifecycle hooks must be called during component setup`,listenNullTarget:e=>`listen() called with a null/undefined target for event "${e}" — listener not attached`,propInvalidReflect:`Structured props cannot use reflect:true — use prop.json() with reflect:false`,templateInterpolationInTag:"html`...`: interpolations inside a tag must be named attributes, boolean attributes, events, or refs",useFieldAlreadyCalled:e=>`useField() was already called on <${e}>. Call it only once per component.`,validationFailed:(e,t)=>`Validation failed for <${e}>:\n${t.join(`
2
+ `)}`};function s(e,t){if(!e)throw new n(o.invariantViolated(t))}export{o as ORE_ERRORS,t as OreApiError,e as OreError,n as OreInternalError,r as OreLifecycleError,a as OreTimeoutError,s as invariant,i as reportRuntimeError};
3
3
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { error as logError } from './_dev';\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'async-setup'` — async setup() promise rejected\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n */\nexport type OreErrorPhase = 'async-setup' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n */\nexport function reportRuntimeError(error: OreLifecycleError, element: HTMLElement): void {\n logError(`<${error.component}> setup error (phase: ${error.phase}):`, error.cause);\n\n element.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `waitFor` and `waitForEvent` in the testing sub-path when a condition is not met within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invalidDynamicTagName: (tagName: string): string =>\n `html\\`...\\`: dynamic tag name \"${tagName}\" is not a valid HTML element name`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n mismatchedDynamicCloseTag: 'html`...`: dynamic closing tag has no matching dynamic opening tag',\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n"],"mappings":"kCAKA,IAAa,EAAb,MAAa,UAAiB,KAAM,CAClC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAA+B,CACvC,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAiC,CAAS,CACxC,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAOa,EAAb,cAAsC,CAAS,CAC7C,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAea,EAAb,cAAuC,CAAS,CAC9C,UACA,MAEA,YAAY,EAAiB,EAAoE,CAC/F,MAAM,EAAS,CAAE,MAAO,EAAQ,KAAM,CAAC,EACvC,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAKA,SAAgB,EAAmB,EAA0B,EAA4B,CACvF,EAAS,IAAI,EAAM,UAAU,wBAAwB,EAAM,MAAM,IAAK,EAAM,KAAK,EAEjF,EAAQ,cACN,IAAI,YAAY,YAAa,CAC3B,QAAS,GACT,SAAU,GACV,OAAQ,CACV,CAAC,CACH,CACF,CAKA,IAAa,EAAb,cAAqC,CAAS,CAAC,EAElC,EAAa,CACxB,gBAAkB,GAAwB,WAAW,EAAI,qDACzD,kCAAoC,GAClC,+BAA+B,EAAI,8BACrC,kBAAmB,+BACnB,kBAAmB,EAAa,IAA0B,kCAAkC,EAAI,aAAa,IAC7G,oBAAqB,EAAa,IAAwB,yCAAyC,EAAI,QAAQ,EAAI,GACnH,sBAAwB,GACtB,kCAAkC,EAAQ,oCAC5C,kBAAoB,GAA4B,uBAAuB,IACvE,sBAAuB,wDACvB,0BAA2B,qEAC3B,mBAAoB,gFACpB,kBAAmB,EAAa,IAA6B,0BAA0B,EAAI,MAAM,EAAO,KAAK;CAAI,GACnH,EAYA,SAAgB,EAAU,EAAoB,EAAoC,CAChF,GAAI,CAAC,EAAW,MAAM,IAAI,EAAiB,EAAW,kBAAkB,CAAO,CAAC,CAClF"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { error as logError } from './_dev';\n\n// ─── Error policy ─────────────────────────────────────────────────────────────\n// One rule for the whole package — decide by whose code failed and whether it\n// can continue, never ad hoc per call site:\n//\n// API misuse (wrong arguments, hook outside setup, duplicate define)\n// → throw `OreApiError`, immediately, every build.\n// User-authored code failing inside ore's execution (setup, onMounted,\n// onFormReset, each() reconciliation)\n// → wrap in `OreLifecycleError` and report via `reportRuntimeError()`\n// (`ore:error` DOM event + dev console) so other callbacks keep running.\n// Recoverable oddity (overwrite warnings, blocked attribute writes)\n// → dev `warn()`/`error()` and continue. Never swallow silently.\n// Internal impossibility (compiled template metadata out of sync)\n// → `invariant()` throws `OreInternalError`, every build.\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n * - `'each-reconcile'` — `each()` failed to reconcile a list update (e.g. duplicate keys)\n */\nexport type OreErrorPhase = 'each-reconcile' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n *\n * `target` only needs to be an `EventTarget` (not specifically an `HTMLElement`) — component\n * lifecycle errors dispatch on the host element, but non-lifecycle failures (e.g. `each()`\n * reconciliation, which has no single \"component\" to attribute the error to) dispatch on\n * whatever live DOM node is available, such as the directive's own anchor `Comment`. Either way\n * the event still bubbles and crosses shadow boundaries (`composed: true`), so a listener on\n * `document`/`window` observes every report regardless of where it originated.\n *\n * The console log (via `_dev.ts`'s `error()`) is still dev-gated like the rest of the package's\n * console diagnostics, but the `ore:error` DOM event dispatch below is **not** — it fires in\n * every build, so consumers always have a way to observe runtime failures programmatically even\n * when console output is stripped in production.\n */\nexport function reportRuntimeError(error: OreLifecycleError, target: EventTarget): void {\n logError(`<${error.component}> lifecycle error (phase: ${error.phase}):`, error.cause);\n\n target.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `flush()` in the testing sub-path when pending component work doesn't settle within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n asyncSetupUnsupported: 'setup() must return an HTMLResult or null; use reactive state for asynchronous work',\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n eventModifiersUnsupported: (eventName: string): string =>\n `@${eventName}: event modifiers are unsupported; call native event methods in the handler instead`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n listenNullTarget: (eventName: string): string =>\n `listen() called with a null/undefined target for event \"${eventName}\" — listener not attached`,\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n templateInterpolationInTag:\n 'html`...`: interpolations inside a tag must be named attributes, boolean attributes, events, or refs',\n useFieldAlreadyCalled: (tag: string): string =>\n `useField() was already called on <${tag}>. Call it only once per component.`,\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n"],"mappings":"kBAoBA,IAAa,EAAb,MAAa,UAAiB,KAAM,CAClC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAA+B,CACvC,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAiC,CAAS,CACxC,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAOa,EAAb,cAAsC,CAAS,CAC7C,YAAY,EAAiB,CAC3B,MAAM,CAAO,CACf,CACF,EAea,EAAb,cAAuC,CAAS,CAC9C,UACA,MAEA,YAAY,EAAiB,EAAoE,CAC/F,MAAM,EAAS,CAAE,MAAO,EAAQ,KAAM,CAAC,EACvC,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAiBA,SAAgB,EAAmB,EAA0B,EAA2B,CAC7E,GAAI,EAAM,UAAV,EAAgD,EAAM,MAAtD,EAAiE,EAAM,MAEhF,EAAO,cACL,IAAI,YAAY,YAAa,CAC3B,QAAS,GACT,SAAU,GACV,OAAQ,CACV,CAAC,CACH,CACF,CAKA,IAAa,EAAb,cAAqC,CAAS,CAAC,EAElC,EAAa,CACxB,sBAAuB,sFACvB,gBAAkB,GAAwB,WAAW,EAAI,qDACzD,kCAAoC,GAClC,+BAA+B,EAAI,8BACrC,kBAAmB,+BACnB,kBAAmB,EAAa,IAA0B,kCAAkC,EAAI,aAAa,IAC7G,0BAA4B,GAC1B,IAAI,EAAU,qFAChB,oBAAqB,EAAa,IAAwB,yCAAyC,EAAI,QAAQ,EAAI,GACnH,kBAAoB,GAA4B,uBAAuB,IACvE,sBAAuB,wDACvB,iBAAmB,GACjB,2DAA2D,EAAU,2BACvE,mBAAoB,gFACpB,2BACE,uGACF,sBAAwB,GACtB,qCAAqC,EAAI,qCAC3C,kBAAmB,EAAa,IAA6B,0BAA0B,EAAI,MAAM,EAAO,KAAK;CAAI,GACnH,EAYA,SAAgB,EAAU,EAAoB,EAAoC,CAChF,GAAI,CAAC,EAAW,MAAM,IAAI,EAAiB,EAAW,kBAAkB,CAAO,CAAC,CAClF"}
@@ -1,2 +1,2 @@
1
- const e=require("../_dev.cjs"),t=require("../errors.cjs"),n=require("../runtime.cjs");require("@vielzeug/ripple");var r=new WeakMap,i=i=>{let a=i.el??n.getHost();if(!a.constructor.formAssociated)throw new t.OreApiError(t.ORE_ERRORS.defineFieldRequiresFormAssociated(a.localName));if(r.has(a))throw new t.OreApiError(`useField() was already called on <${a.localName}>. Call it only once per component.`);let o=a.attachInternals();r.set(a,o),n.onCleanup(()=>r.delete(a));let s=i.toFormValue??(e=>e==null?i.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));n.watchEffect(()=>{o.setFormValue(s(i.value.value))});let c=i.disabled;if(c)if(!(`states`in o))e.warn(`useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.`);else{let e=o.states;n.watchEffect(()=>{c.value?e.add(`disabled`):e.delete(`disabled`)})}return i.validity&&n.watchEffect(()=>{let t=i.validity?.value??{},n=Object.values(t).some(Boolean),r=i.validationMessage?.value??``;if(n&&!r){e.warn("useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() requires a non-empty message whenever any flag is true. Falling back to a generic message; pass `validationMessage` to customize it."),o.setValidity(t,`Invalid value.`);return}o.setValidity(t,r)}),i.onReset&&n.onFormReset(i.onReset),{checkValidity:()=>o.checkValidity(),internals:o,reportValidity:()=>o.reportValidity(),setCustomValidity:e=>e?o.setValidity({customError:!0},e):o.setValidity({}),setValidity:o.setValidity.bind(o)}};exports.useField=i;
1
+ require("../_dev.cjs");const e=require("../errors.cjs"),t=require("../runtime.cjs");require("@vielzeug/ripple");var n=new WeakMap,r=r=>{let i=r.el??t.getHost();if(!i.constructor.formAssociated)throw new e.OreApiError(e.ORE_ERRORS.defineFieldRequiresFormAssociated(i.localName));if(n.has(i))throw new e.OreApiError(e.ORE_ERRORS.useFieldAlreadyCalled(i.localName));let a=i.attachInternals();n.set(i,a),t.onCleanup(()=>n.delete(i));let o=r.toFormValue??(e=>e==null?r.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));t.watchEffect(()=>{a.setFormValue(o(r.value.value))});let s=r.disabled;if(s&&`states`in a){let e=a.states;t.watchEffect(()=>{s.value?e.add(`disabled`):e.delete(`disabled`)})}return r.validity&&t.watchEffect(()=>{let e=r.validity?.value??{},t=Object.values(e).some(Boolean),n=r.validationMessage?.value??``;if(t&&!n){a.setValidity(e,`Invalid value.`);return}a.setValidity(e,n)}),r.onReset&&t.onFormReset(r.onReset),{checkValidity:()=>a.checkValidity(),internals:a,reportValidity:()=>a.reportValidity(),setCustomValidity:e=>e?a.setValidity({customError:!0},e):a.setValidity({})}};exports.useField=r;
2
2
  //# sourceMappingURL=field.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.cjs","names":[],"sources":["../../src/forms/field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n"],"mappings":"kHAOA,IAAM,EAAoB,IAAI,QAiDjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAA,QAAQ,EAGnC,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAA,YAAY,EAAA,WAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAA,YAAY,qCAAqC,EAAK,UAAU,oCAAoC,EAGhH,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,EAAA,cAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,EAAA,gBAAkB,CAChB,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,EACF,GAAI,EAAE,WAAY,GAChB,EAAA,KACE,8HACF,MACK,CACL,IAAM,EAAS,EAAU,OAEzB,EAAA,gBAAkB,CACZ,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAmCF,OAhCI,EAAQ,UACV,EAAA,gBAAkB,CAChB,IAAM,EAAQ,EAAQ,UAAU,OAAS,CAAC,EAKpC,EAAU,OAAO,OAAO,CAAK,CAAC,CAAC,KAAK,OAAO,EAC3C,EAAU,EAAQ,mBAAmB,OAAS,GAEpD,GAAI,GAAW,CAAC,EAAS,CACvB,EAAA,KACE,0OAGF,EACA,EAAU,YAAY,EAAO,gBAAgB,EAE7C,MACF,CAEA,EAAU,YAAY,EAAO,CAAO,CACtC,CAAC,EAGC,EAAQ,SAAS,EAAA,YAAY,EAAQ,OAAO,EAOzC,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,EAO1F,YAAa,EAAU,YAAY,KAAK,CAAS,CACnD,CACF"}
1
+ {"version":3,"file":"field.cjs","names":[],"sources":["../../src/forms/field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n /**\n * Set (non-empty message) or clear (empty string) a custom validity error.\n * Guards the platform's throw-on-empty-message contract — prefer this over\n * calling `internals.setValidity` directly.\n */\n setCustomValidity: (message: string) => void;\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(ORE_ERRORS.useFieldAlreadyCalled(host.localName));\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n };\n};\n"],"mappings":"gHAOA,IAAM,EAAoB,IAAI,QAqDjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAA,QAAQ,EAGnC,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAA,YAAY,EAAA,WAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAA,YAAY,EAAA,WAAW,sBAAsB,EAAK,SAAS,CAAC,EAGxE,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,EAAA,cAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,EAAA,gBAAkB,CAChB,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,GACI,WAAY,EAIX,CACL,IAAM,EAAS,EAAU,OAEzB,EAAA,gBAAkB,CACZ,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAmCF,OAhCI,EAAQ,UACV,EAAA,gBAAkB,CAChB,IAAM,EAAQ,EAAQ,UAAU,OAAS,CAAC,EAKpC,EAAU,OAAO,OAAO,CAAK,CAAC,CAAC,KAAK,OAAO,EAC3C,EAAU,EAAQ,mBAAmB,OAAS,GAEpD,GAAI,GAAW,CAAC,EAAS,CAMvB,EAAU,YAAY,EAAO,gBAAgB,EAE7C,MACF,CAEA,EAAU,YAAY,EAAO,CAAO,CACtC,CAAC,EAGC,EAAQ,SAAS,EAAA,YAAY,EAAQ,OAAO,EAOzC,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,CAO5F,CACF"}
@@ -41,8 +41,12 @@ export type FormFieldHandle = {
41
41
  checkValidity: () => boolean;
42
42
  readonly internals: ElementInternals;
43
43
  reportValidity: () => boolean;
44
+ /**
45
+ * Set (non-empty message) or clear (empty string) a custom validity error.
46
+ * Guards the platform's throw-on-empty-message contract — prefer this over
47
+ * calling `internals.setValidity` directly.
48
+ */
44
49
  setCustomValidity: (message: string) => void;
45
- setValidity: ElementInternals['setValidity'];
46
50
  };
47
51
  export declare const useField: <T = unknown>(options: FormFieldOptions<T>) => FormFieldHandle;
48
52
  //# sourceMappingURL=field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/forms/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS9D,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC1C,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5D;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC;IAC9B,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;CAC9C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,KAAG,eAuFpE,CAAC"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/forms/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS9D,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC1C,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5D;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC;IAC9B;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,KAAG,eAsFpE,CAAC"}
@@ -1,2 +1,2 @@
1
- import{warn as e}from"../_dev.js";import{ORE_ERRORS as t,OreApiError as n}from"../errors.js";import{getHost as r,onCleanup as i,onFormReset as a,watchEffect as o}from"../runtime.js";import"@vielzeug/ripple";var s=new WeakMap,c=c=>{let l=c.el??r();if(!l.constructor.formAssociated)throw new n(t.defineFieldRequiresFormAssociated(l.localName));if(s.has(l))throw new n(`useField() was already called on <${l.localName}>. Call it only once per component.`);let u=l.attachInternals();s.set(l,u),i(()=>s.delete(l));let d=c.toFormValue??(e=>e==null?c.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));o(()=>{u.setFormValue(d(c.value.value))});let f=c.disabled;if(f)if(!(`states`in u))e(`useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.`);else{let e=u.states;o(()=>{f.value?e.add(`disabled`):e.delete(`disabled`)})}return c.validity&&o(()=>{let t=c.validity?.value??{},n=Object.values(t).some(Boolean),r=c.validationMessage?.value??``;if(n&&!r){e("useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() requires a non-empty message whenever any flag is true. Falling back to a generic message; pass `validationMessage` to customize it."),u.setValidity(t,`Invalid value.`);return}u.setValidity(t,r)}),c.onReset&&a(c.onReset),{checkValidity:()=>u.checkValidity(),internals:u,reportValidity:()=>u.reportValidity(),setCustomValidity:e=>e?u.setValidity({customError:!0},e):u.setValidity({}),setValidity:u.setValidity.bind(u)}};export{c as useField};
1
+ import"../_dev.js";import{ORE_ERRORS as e,OreApiError as t}from"../errors.js";import{getHost as n,onCleanup as r,onFormReset as i,watchEffect as a}from"../runtime.js";import"@vielzeug/ripple";var o=new WeakMap,s=s=>{let c=s.el??n();if(!c.constructor.formAssociated)throw new t(e.defineFieldRequiresFormAssociated(c.localName));if(o.has(c))throw new t(e.useFieldAlreadyCalled(c.localName));let l=c.attachInternals();o.set(c,l),r(()=>o.delete(c));let u=s.toFormValue??(e=>e==null?s.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));a(()=>{l.setFormValue(u(s.value.value))});let d=s.disabled;if(d&&`states`in l){let e=l.states;a(()=>{d.value?e.add(`disabled`):e.delete(`disabled`)})}return s.validity&&a(()=>{let e=s.validity?.value??{},t=Object.values(e).some(Boolean),n=s.validationMessage?.value??``;if(t&&!n){l.setValidity(e,`Invalid value.`);return}l.setValidity(e,n)}),s.onReset&&i(s.onReset),{checkValidity:()=>l.checkValidity(),internals:l,reportValidity:()=>l.reportValidity(),setCustomValidity:e=>e?l.setValidity({customError:!0},e):l.setValidity({})}};export{s as useField};
2
2
  //# sourceMappingURL=field.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","names":[],"sources":["../../src/forms/field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n"],"mappings":"+MAOA,IAAM,EAAoB,IAAI,QAiDjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAQ,EAGnC,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAY,EAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAY,qCAAqC,EAAK,UAAU,oCAAoC,EAGhH,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,MAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,MAAkB,CAChB,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,EACF,GAAI,EAAE,WAAY,GAChB,EACE,8HACF,MACK,CACL,IAAM,EAAS,EAAU,OAEzB,MAAkB,CACZ,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAmCF,OAhCI,EAAQ,UACV,MAAkB,CAChB,IAAM,EAAQ,EAAQ,UAAU,OAAS,CAAC,EAKpC,EAAU,OAAO,OAAO,CAAK,CAAC,CAAC,KAAK,OAAO,EAC3C,EAAU,EAAQ,mBAAmB,OAAS,GAEpD,GAAI,GAAW,CAAC,EAAS,CACvB,EACE,0OAGF,EACA,EAAU,YAAY,EAAO,gBAAgB,EAE7C,MACF,CAEA,EAAU,YAAY,EAAO,CAAO,CACtC,CAAC,EAGC,EAAQ,SAAS,EAAY,EAAQ,OAAO,EAOzC,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,EAO1F,YAAa,EAAU,YAAY,KAAK,CAAS,CACnD,CACF"}
1
+ {"version":3,"file":"field.js","names":[],"sources":["../../src/forms/field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n /**\n * Set (non-empty message) or clear (empty string) a custom validity error.\n * Guards the platform's throw-on-empty-message contract — prefer this over\n * calling `internals.setValidity` directly.\n */\n setCustomValidity: (message: string) => void;\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(ORE_ERRORS.useFieldAlreadyCalled(host.localName));\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n };\n};\n"],"mappings":"gMAOA,IAAM,EAAoB,IAAI,QAqDjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAQ,EAGnC,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAY,EAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAY,EAAW,sBAAsB,EAAK,SAAS,CAAC,EAGxE,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,MAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,MAAkB,CAChB,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,GACI,WAAY,EAIX,CACL,IAAM,EAAS,EAAU,OAEzB,MAAkB,CACZ,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAmCF,OAhCI,EAAQ,UACV,MAAkB,CAChB,IAAM,EAAQ,EAAQ,UAAU,OAAS,CAAC,EAKpC,EAAU,OAAO,OAAO,CAAK,CAAC,CAAC,KAAK,OAAO,EAC3C,EAAU,EAAQ,mBAAmB,OAAS,GAEpD,GAAI,GAAW,CAAC,EAAS,CAMvB,EAAU,YAAY,EAAO,gBAAgB,EAE7C,MACF,CAEA,EAAU,YAAY,EAAO,CAAO,CACtC,CAAC,EAGC,EAAQ,SAAS,EAAY,EAAQ,OAAO,EAOzC,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,CAO5F,CACF"}
@@ -1,2 +1,2 @@
1
- const e=require("./utils/dom.cjs"),t=require("./runtime.cjs"),n=require("./utils/aria.cjs");let r=require("@vielzeug/ripple");var i=(n,r)=>{let i=r?.target??t.getHost(),o=[];if(n.attr)for(let[e,t]of Object.entries(n.attr)){let n=s(i,a(e),t);n&&o.push(n)}if(n.class&&o.push(u(i,n.class)),n.style)for(let[e,t]of Object.entries(n.style)){let n=l(i,e,t);n&&o.push(n)}if(n.on){let{target:t,...a}=r??{};for(let t of Object.keys(n.on)){let r=n.on[t];r&&o.push(e.listen(i,t,r,a))}}let c=()=>{for(let e of o)e()};return t.tryRegisterCleanup(c),c},a=n.normalizeHostAttrKey,o=(e,n)=>{if(typeof e==`function`)return t.watchEffect(()=>n(e()));if((0,r.isReactive)(e))return t.watchEffect(()=>n(e.value));n(e)};function s(t,n,r){return o(r,r=>e.setAttr(t,n,r))}var c=/[;{}]/g;function l(t,n,r){let i=(n.startsWith(`--`)?n:e.toKebab(n)).replace(c,``);if(!i)return;let a=!1;return o(r,e=>{e!=null&&e!==``?(a=!0,t.style.setProperty(i,String(e).replace(c,``))):a&&t.style.removeProperty(i)})}function u(e,n){let i=typeof n==`function`?n:()=>{let e={};for(let[t,i]of Object.entries(n))e[t]=typeof i==`function`?i():(0,r.isReactive)(i)?i.value:!!i;return e},a=new Set;return t.watchEffect(()=>{let t=new Set;for(let[n,r]of Object.entries(i()))r&&(t.add(n),a.has(n)||e.classList.add(n));for(let n of a)t.has(n)||e.classList.remove(n);a=t})}exports.bind=i;
1
+ const e=require("./utils/dom.cjs"),t=require("./runtime.cjs"),n=require("./utils/aria.cjs");let r=require("@vielzeug/ripple");var i=(r,i)=>{let o=i?.target??t.getHost(),u=[];if(r.attr)for(let[e,t]of Object.entries(r.attr)){let n=s(o,a(e),t);n&&u.push(n)}if(r.aria)for(let[e,t]of Object.entries(r.aria)){let r=s(o,n.normalizeAriaKey(e),t);r&&u.push(r)}if(r.class&&u.push(l(o,r.class)),r.style)for(let[e,t]of Object.entries(r.style)){let n=c(o,e,t);n&&u.push(n)}if(r.on){let{target:t,...n}=i??{};for(let t of Object.keys(r.on)){let i=r.on[t];i&&u.push(e.listen(o,t,i,n))}}let d=()=>{for(let e of u)e()};return t.tryRegisterCleanup(d),d},a=n.normalizeHostAttrKey,o=(e,n)=>{if(typeof e==`function`)return t.watchEffect(()=>n(e()));if((0,r.isReactive)(e))return t.watchEffect(()=>n(e.value));n(e)};function s(t,n,r){return o(r,r=>e.setAttr(t,n,r))}function c(t,n,r){let i=e.sanitizeCssToken(n.startsWith(`--`)?n:e.toKebab(n));if(!i)return;let a=!1;return o(r,n=>{n!=null&&n!==``?(a=!0,t.style.setProperty(i,e.sanitizeCssToken(String(n)))):a&&t.style.removeProperty(i)})}function l(n,r){let i=typeof r==`function`?r:()=>{let t={};for(let[n,i]of Object.entries(r))t[n]=e.resolveMaybeReactive(i);return t},a=new Set;return t.watchEffect(()=>{let e=new Set;for(let[t,r]of Object.entries(i()))r&&(e.add(t),a.has(t)||n.classList.add(t));for(let t of a)e.has(t)||n.classList.remove(t);a=e})}exports.bind=i;
2
2
  //# sourceMappingURL=host-bind.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-bind.cjs","names":[],"sources":["../src/host-bind.ts"],"sourcesContent":["/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeHostAttrKey } from './utils/aria';\nimport { listen, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = (name.startsWith('--') ? name : toKebab(name)).replace(UNSAFE_CSS_CHARS, '');\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, String(v).replace(UNSAFE_CSS_CHARS, ''));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = typeof entry === 'function' ? entry() : isReactive(entry) ? entry.value : Boolean(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n"],"mappings":"8HA0DA,IAAa,GAAoB,EAAwB,IAAwC,CAC/F,IAAM,EAAM,GAAS,QAAsC,EAAA,QAAQ,EAC7D,EAA+B,CAAC,EAEtC,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAW,CACW,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAOF,GAJI,EAAO,OACT,EAAU,KAAK,EAAc,EAAI,EAAO,KAAK,CAAC,EAG5C,EAAO,MACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,KAAK,EAAG,CACvD,IAAM,EAAU,EAAW,EAAI,EAAK,CAAK,EAErC,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,GAAI,CACb,GAAM,CAAE,OAAQ,EAAI,GAAG,GAAoB,GAAW,CAAC,EAEvD,IAAK,IAAM,KAAS,OAAO,KAAK,EAAO,EAAE,EAAoC,CAC3E,IAAM,EAAW,EAAO,GAAG,GAEtB,GAEL,EAAU,KAAK,EAAA,OAAO,EAAI,EAAiB,EAA2B,CAAe,CAAC,CACxF,CACF,CAEA,IAAM,MAAsB,CAC1B,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,EAIA,OAFA,EAAA,mBAAmB,CAAO,EAEnB,CACT,EAEM,EAAa,EAAA,qBAEb,GACJ,EACA,IACwB,CACxB,GAAI,OAAO,GAAU,WACnB,OAAO,EAAA,gBAAkB,EAAQ,EAAM,CAAC,CAAC,EAG3C,IAAA,EAAA,EAAA,WAAA,CAAe,CAAK,EAClB,OAAO,EAAA,gBAAkB,EAAQ,EAAM,KAAK,CAAC,EAG/C,EAAQ,CAAK,CACf,EAEA,SAAS,EAAe,EAAmB,EAAc,EAA8C,CACrG,OAAO,EAAqB,EAAQ,GAAS,EAAA,QAAQ,EAAM,EAAM,CAAI,CAAC,CACxE,CAEA,IAAM,EAAmB,SAEzB,SAAS,EAAW,EAAmB,EAAc,EAA8C,CACjG,IAAM,GAAW,EAAK,WAAW,IAAI,EAAI,EAAO,EAAA,QAAQ,CAAI,EAAA,CAAG,QAAQ,EAAkB,EAAE,EAE3F,GAAI,CAAC,EAAS,OAEd,IAAI,EAAQ,GAQZ,OAAO,EAAqB,EAPV,GAA0D,CACtE,GAAK,MAAQ,IAAM,IACrB,EAAQ,GACR,EAAK,MAAM,YAAY,EAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAkB,EAAE,CAAC,GAC9D,GAAO,EAAK,MAAM,eAAe,CAAO,CACrD,CAE2C,CAC7C,CAEA,SAAS,EACP,EACA,EACY,CACZ,IAAM,EACJ,OAAO,GAAU,WACb,MAC+B,CAC7B,IAAM,EAAkC,CAAC,EAEzC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EAC7C,EAAO,GAAO,OAAO,GAAU,WAAa,EAAM,GAAA,EAAA,EAAA,WAAA,CAAe,CAAK,EAAI,EAAM,MAAQ,EAAQ,EAGlG,OAAO,CACT,EAEF,EAAO,IAAI,IAkBf,OAhBY,EAAA,gBAAkB,CAC5B,IAAM,EAAO,IAAI,IAEjB,IAAK,GAAM,CAAC,EAAK,KAAW,OAAO,QAAQ,EAAO,CAAC,EAC5C,IAEL,EAAK,IAAI,CAAG,EAEP,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,IAAI,CAAG,GAE5C,IAAK,IAAM,KAAO,EACX,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,OAAO,CAAG,EAE/C,EAAO,CACT,CAEO,CACT"}
1
+ {"version":3,"file":"host-bind.cjs","names":[],"sources":["../src/host-bind.ts"],"sourcesContent":["/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeAriaKey, normalizeHostAttrKey } from './utils/aria';\nimport { listen, resolveMaybeReactive, sanitizeCssToken, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n /**\n * ARIA attributes, keyed by bare property name (`expanded`) or fully-qualified\n * (`aria-expanded`) — both normalize to the same attribute. A separate key from `attr`\n * only so bare names can be normalized; the underlying write path is identical.\n */\n aria?: ReflectConfig;\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.aria) {\n for (const [key, value] of Object.entries(config.aria)) {\n const name = normalizeAriaKey(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = sanitizeCssToken(name.startsWith('--') ? name : toKebab(name));\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, sanitizeCssToken(String(v)));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = resolveMaybeReactive(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n"],"mappings":"8HAgEA,IAAa,GAAoB,EAAwB,IAAwC,CAC/F,IAAM,EAAM,GAAS,QAAsC,EAAA,QAAQ,EAC7D,EAA+B,CAAC,EAEtC,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAW,CACW,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAA,iBAAiB,CACK,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAOF,GAJI,EAAO,OACT,EAAU,KAAK,EAAc,EAAI,EAAO,KAAK,CAAC,EAG5C,EAAO,MACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,KAAK,EAAG,CACvD,IAAM,EAAU,EAAW,EAAI,EAAK,CAAK,EAErC,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,GAAI,CACb,GAAM,CAAE,OAAQ,EAAI,GAAG,GAAoB,GAAW,CAAC,EAEvD,IAAK,IAAM,KAAS,OAAO,KAAK,EAAO,EAAE,EAAoC,CAC3E,IAAM,EAAW,EAAO,GAAG,GAEtB,GAEL,EAAU,KAAK,EAAA,OAAO,EAAI,EAAiB,EAA2B,CAAe,CAAC,CACxF,CACF,CAEA,IAAM,MAAsB,CAC1B,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,EAIA,OAFA,EAAA,mBAAmB,CAAO,EAEnB,CACT,EAEM,EAAa,EAAA,qBAEb,GACJ,EACA,IACwB,CACxB,GAAI,OAAO,GAAU,WACnB,OAAO,EAAA,gBAAkB,EAAQ,EAAM,CAAC,CAAC,EAG3C,IAAA,EAAI,EAAA,WAAA,CAAW,CAAK,EAClB,OAAO,EAAA,gBAAkB,EAAQ,EAAM,KAAK,CAAC,EAG/C,EAAQ,CAAK,CACf,EAEA,SAAS,EAAe,EAAmB,EAAc,EAA8C,CACrG,OAAO,EAAqB,EAAQ,GAAS,EAAA,QAAQ,EAAM,EAAM,CAAI,CAAC,CACxE,CAEA,SAAS,EAAW,EAAmB,EAAc,EAA8C,CACjG,IAAM,EAAU,EAAA,iBAAiB,EAAK,WAAW,IAAI,EAAI,EAAO,EAAA,QAAQ,CAAI,CAAC,EAE7E,GAAI,CAAC,EAAS,OAEd,IAAI,EAAQ,GAQZ,OAAO,EAAqB,EAPV,GAA0D,CACtE,GAAK,MAAQ,IAAM,IACrB,EAAQ,GACR,EAAK,MAAM,YAAY,EAAS,EAAA,iBAAiB,OAAO,CAAC,CAAC,CAAC,GAClD,GAAO,EAAK,MAAM,eAAe,CAAO,CACrD,CAE2C,CAC7C,CAEA,SAAS,EACP,EACA,EACY,CACZ,IAAM,EACJ,OAAO,GAAU,WACb,MAC+B,CAC7B,IAAM,EAAkC,CAAC,EAEzC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EAC7C,EAAO,GAAO,EAAA,qBAAqB,CAAK,EAG1C,OAAO,CACT,EAEF,EAAO,IAAI,IAkBf,OAhBY,EAAA,gBAAkB,CAC5B,IAAM,EAAO,IAAI,IAEjB,IAAK,GAAM,CAAC,EAAK,KAAW,OAAO,QAAQ,EAAO,CAAC,EAC5C,IAEL,EAAK,IAAI,CAAG,EAEP,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,IAAI,CAAG,GAE5C,IAAK,IAAM,KAAO,EACX,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,OAAO,CAAG,EAE/C,EAAO,CACT,CAEO,CACT"}
@@ -16,6 +16,12 @@ type HostEventListener = {
16
16
  bivarianceHack(event: Event): void;
17
17
  }['bivarianceHack'];
18
18
  export type HostBindConfig = {
19
+ /**
20
+ * ARIA attributes, keyed by bare property name (`expanded`) or fully-qualified
21
+ * (`aria-expanded`) — both normalize to the same attribute. A separate key from `attr`
22
+ * only so bare names can be normalized; the underlying write path is identical.
23
+ */
24
+ aria?: ReflectConfig;
19
25
  attr?: ReflectConfig;
20
26
  class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;
21
27
  on?: Record<string, HostEventListener | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"host-bind.d.ts","sourceRoot":"","sources":["../src/host-bind.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM7D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GACpD,QAAQ,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GACtD,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE7D,KAAK,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC;AAE3E,KAAK,iBAAiB,GAAG;IAAE,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE,CAAC,gBAAgB,CAAC,CAAC;AAElF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAChF,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG;IAClD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,UA4ClB,CAAC"}
1
+ {"version":3,"file":"host-bind.d.ts","sourceRoot":"","sources":["../src/host-bind.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM7D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GACpD,QAAQ,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GACtD,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE7D,KAAK,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC;AAE3E,KAAK,iBAAiB,GAAG;IAAE,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE,CAAC,gBAAgB,CAAC,CAAC;AAElF,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAChF,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG;IAClD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,UAqDlB,CAAC"}
package/dist/host-bind.js CHANGED
@@ -1,2 +1,2 @@
1
- import{listen as e,setAttr as t,toKebab as n}from"./utils/dom.js";import{getHost as r,tryRegisterCleanup as i,watchEffect as a}from"./runtime.js";import{normalizeHostAttrKey as o}from"./utils/aria.js";import{isReactive as s}from"@vielzeug/ripple";var c=(t,n)=>{let a=n?.target??r(),o=[];if(t.attr)for(let[e,n]of Object.entries(t.attr)){let t=d(a,l(e),n);t&&o.push(t)}if(t.class&&o.push(m(a,t.class)),t.style)for(let[e,n]of Object.entries(t.style)){let t=p(a,e,n);t&&o.push(t)}if(t.on){let{target:r,...i}=n??{};for(let n of Object.keys(t.on)){let r=t.on[n];r&&o.push(e(a,n,r,i))}}let s=()=>{for(let e of o)e()};return i(s),s},l=o,u=(e,t)=>{if(typeof e==`function`)return a(()=>t(e()));if(s(e))return a(()=>t(e.value));t(e)};function d(e,n,r){return u(r,r=>t(e,n,r))}var f=/[;{}]/g;function p(e,t,r){let i=(t.startsWith(`--`)?t:n(t)).replace(f,``);if(!i)return;let a=!1;return u(r,t=>{t!=null&&t!==``?(a=!0,e.style.setProperty(i,String(t).replace(f,``))):a&&e.style.removeProperty(i)})}function m(e,t){let n=typeof t==`function`?t:()=>{let e={};for(let[n,r]of Object.entries(t))e[n]=typeof r==`function`?r():s(r)?r.value:!!r;return e},r=new Set;return a(()=>{let t=new Set;for(let[i,a]of Object.entries(n()))a&&(t.add(i),r.has(i)||e.classList.add(i));for(let n of r)t.has(n)||e.classList.remove(n);r=t})}export{c as bind};
1
+ import{listen as e,resolveMaybeReactive as t,sanitizeCssToken as n,setAttr as r,toKebab as i}from"./utils/dom.js";import{getHost as a,tryRegisterCleanup as o,watchEffect as s}from"./runtime.js";import{normalizeAriaKey as c,normalizeHostAttrKey as l}from"./utils/aria.js";import{isReactive as u}from"@vielzeug/ripple";var d=(t,n)=>{let r=n?.target??a(),i=[];if(t.attr)for(let[e,n]of Object.entries(t.attr)){let t=m(r,f(e),n);t&&i.push(t)}if(t.aria)for(let[e,n]of Object.entries(t.aria)){let t=m(r,c(e),n);t&&i.push(t)}if(t.class&&i.push(g(r,t.class)),t.style)for(let[e,n]of Object.entries(t.style)){let t=h(r,e,n);t&&i.push(t)}if(t.on){let{target:a,...o}=n??{};for(let n of Object.keys(t.on)){let a=t.on[n];a&&i.push(e(r,n,a,o))}}let s=()=>{for(let e of i)e()};return o(s),s},f=l,p=(e,t)=>{if(typeof e==`function`)return s(()=>t(e()));if(u(e))return s(()=>t(e.value));t(e)};function m(e,t,n){return p(n,n=>r(e,t,n))}function h(e,t,r){let a=n(t.startsWith(`--`)?t:i(t));if(!a)return;let o=!1;return p(r,t=>{t!=null&&t!==``?(o=!0,e.style.setProperty(a,n(String(t)))):o&&e.style.removeProperty(a)})}function g(e,n){let r=typeof n==`function`?n:()=>{let e={};for(let[r,i]of Object.entries(n))e[r]=t(i);return e},i=new Set;return s(()=>{let t=new Set;for(let[n,a]of Object.entries(r()))a&&(t.add(n),i.has(n)||e.classList.add(n));for(let n of i)t.has(n)||e.classList.remove(n);i=t})}export{d as bind};
2
2
  //# sourceMappingURL=host-bind.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-bind.js","names":[],"sources":["../src/host-bind.ts"],"sourcesContent":["/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeHostAttrKey } from './utils/aria';\nimport { listen, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = (name.startsWith('--') ? name : toKebab(name)).replace(UNSAFE_CSS_CHARS, '');\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, String(v).replace(UNSAFE_CSS_CHARS, ''));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = typeof entry === 'function' ? entry() : isReactive(entry) ? entry.value : Boolean(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n"],"mappings":"uPA0DA,IAAa,GAAoB,EAAwB,IAAwC,CAC/F,IAAM,EAAM,GAAS,QAAsC,EAAQ,EAC7D,EAA+B,CAAC,EAEtC,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAW,CACW,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAOF,GAJI,EAAO,OACT,EAAU,KAAK,EAAc,EAAI,EAAO,KAAK,CAAC,EAG5C,EAAO,MACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,KAAK,EAAG,CACvD,IAAM,EAAU,EAAW,EAAI,EAAK,CAAK,EAErC,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,GAAI,CACb,GAAM,CAAE,OAAQ,EAAI,GAAG,GAAoB,GAAW,CAAC,EAEvD,IAAK,IAAM,KAAS,OAAO,KAAK,EAAO,EAAE,EAAoC,CAC3E,IAAM,EAAW,EAAO,GAAG,GAEtB,GAEL,EAAU,KAAK,EAAO,EAAI,EAAiB,EAA2B,CAAe,CAAC,CACxF,CACF,CAEA,IAAM,MAAsB,CAC1B,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,EAIA,OAFA,EAAmB,CAAO,EAEnB,CACT,EAEM,EAAa,EAEb,GACJ,EACA,IACwB,CACxB,GAAI,OAAO,GAAU,WACnB,OAAO,MAAkB,EAAQ,EAAM,CAAC,CAAC,EAG3C,GAAI,EAAW,CAAK,EAClB,OAAO,MAAkB,EAAQ,EAAM,KAAK,CAAC,EAG/C,EAAQ,CAAK,CACf,EAEA,SAAS,EAAe,EAAmB,EAAc,EAA8C,CACrG,OAAO,EAAqB,EAAQ,GAAS,EAAQ,EAAM,EAAM,CAAI,CAAC,CACxE,CAEA,IAAM,EAAmB,SAEzB,SAAS,EAAW,EAAmB,EAAc,EAA8C,CACjG,IAAM,GAAW,EAAK,WAAW,IAAI,EAAI,EAAO,EAAQ,CAAI,EAAA,CAAG,QAAQ,EAAkB,EAAE,EAE3F,GAAI,CAAC,EAAS,OAEd,IAAI,EAAQ,GAQZ,OAAO,EAAqB,EAPV,GAA0D,CACtE,GAAK,MAAQ,IAAM,IACrB,EAAQ,GACR,EAAK,MAAM,YAAY,EAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAkB,EAAE,CAAC,GAC9D,GAAO,EAAK,MAAM,eAAe,CAAO,CACrD,CAE2C,CAC7C,CAEA,SAAS,EACP,EACA,EACY,CACZ,IAAM,EACJ,OAAO,GAAU,WACb,MAC+B,CAC7B,IAAM,EAAkC,CAAC,EAEzC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EAC7C,EAAO,GAAO,OAAO,GAAU,WAAa,EAAM,EAAI,EAAW,CAAK,EAAI,EAAM,MAAQ,EAAQ,EAGlG,OAAO,CACT,EAEF,EAAO,IAAI,IAkBf,OAhBY,MAAkB,CAC5B,IAAM,EAAO,IAAI,IAEjB,IAAK,GAAM,CAAC,EAAK,KAAW,OAAO,QAAQ,EAAO,CAAC,EAC5C,IAEL,EAAK,IAAI,CAAG,EAEP,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,IAAI,CAAG,GAE5C,IAAK,IAAM,KAAO,EACX,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,OAAO,CAAG,EAE/C,EAAO,CACT,CAEO,CACT"}
1
+ {"version":3,"file":"host-bind.js","names":[],"sources":["../src/host-bind.ts"],"sourcesContent":["/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeAriaKey, normalizeHostAttrKey } from './utils/aria';\nimport { listen, resolveMaybeReactive, sanitizeCssToken, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n /**\n * ARIA attributes, keyed by bare property name (`expanded`) or fully-qualified\n * (`aria-expanded`) — both normalize to the same attribute. A separate key from `attr`\n * only so bare names can be normalized; the underlying write path is identical.\n */\n aria?: ReflectConfig;\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.aria) {\n for (const [key, value] of Object.entries(config.aria)) {\n const name = normalizeAriaKey(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = sanitizeCssToken(name.startsWith('--') ? name : toKebab(name));\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, sanitizeCssToken(String(v)));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = resolveMaybeReactive(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n"],"mappings":"6TAgEA,IAAa,GAAoB,EAAwB,IAAwC,CAC/F,IAAM,EAAM,GAAS,QAAsC,EAAQ,EAC7D,EAA+B,CAAC,EAEtC,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAW,CACW,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,KACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,IAAI,EAAG,CAEtD,IAAM,EAAU,EAAe,EADlB,EAAiB,CACK,EAAM,CAAK,EAE1C,GAAS,EAAU,KAAK,CAAO,CACrC,CAOF,GAJI,EAAO,OACT,EAAU,KAAK,EAAc,EAAI,EAAO,KAAK,CAAC,EAG5C,EAAO,MACT,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,KAAK,EAAG,CACvD,IAAM,EAAU,EAAW,EAAI,EAAK,CAAK,EAErC,GAAS,EAAU,KAAK,CAAO,CACrC,CAGF,GAAI,EAAO,GAAI,CACb,GAAM,CAAE,OAAQ,EAAI,GAAG,GAAoB,GAAW,CAAC,EAEvD,IAAK,IAAM,KAAS,OAAO,KAAK,EAAO,EAAE,EAAoC,CAC3E,IAAM,EAAW,EAAO,GAAG,GAEtB,GAEL,EAAU,KAAK,EAAO,EAAI,EAAiB,EAA2B,CAAe,CAAC,CACxF,CACF,CAEA,IAAM,MAAsB,CAC1B,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,EAIA,OAFA,EAAmB,CAAO,EAEnB,CACT,EAEM,EAAa,EAEb,GACJ,EACA,IACwB,CACxB,GAAI,OAAO,GAAU,WACnB,OAAO,MAAkB,EAAQ,EAAM,CAAC,CAAC,EAG3C,GAAI,EAAW,CAAK,EAClB,OAAO,MAAkB,EAAQ,EAAM,KAAK,CAAC,EAG/C,EAAQ,CAAK,CACf,EAEA,SAAS,EAAe,EAAmB,EAAc,EAA8C,CACrG,OAAO,EAAqB,EAAQ,GAAS,EAAQ,EAAM,EAAM,CAAI,CAAC,CACxE,CAEA,SAAS,EAAW,EAAmB,EAAc,EAA8C,CACjG,IAAM,EAAU,EAAiB,EAAK,WAAW,IAAI,EAAI,EAAO,EAAQ,CAAI,CAAC,EAE7E,GAAI,CAAC,EAAS,OAEd,IAAI,EAAQ,GAQZ,OAAO,EAAqB,EAPV,GAA0D,CACtE,GAAK,MAAQ,IAAM,IACrB,EAAQ,GACR,EAAK,MAAM,YAAY,EAAS,EAAiB,OAAO,CAAC,CAAC,CAAC,GAClD,GAAO,EAAK,MAAM,eAAe,CAAO,CACrD,CAE2C,CAC7C,CAEA,SAAS,EACP,EACA,EACY,CACZ,IAAM,EACJ,OAAO,GAAU,WACb,MAC+B,CAC7B,IAAM,EAAkC,CAAC,EAEzC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EAC7C,EAAO,GAAO,EAAqB,CAAK,EAG1C,OAAO,CACT,EAEF,EAAO,IAAI,IAkBf,OAhBY,MAAkB,CAC5B,IAAM,EAAO,IAAI,IAEjB,IAAK,GAAM,CAAC,EAAK,KAAW,OAAO,QAAQ,EAAO,CAAC,EAC5C,IAEL,EAAK,IAAI,CAAG,EAEP,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,IAAI,CAAG,GAE5C,IAAK,IAAM,KAAO,EACX,EAAK,IAAI,CAAG,GAAG,EAAK,UAAU,OAAO,CAAG,EAE/C,EAAO,CACT,CAEO,CACT"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./types/bindings.cjs"),n=require("./runtime.cjs"),r=require("./context.cjs"),i=require("./props.cjs"),a=require("./utils/css.cjs"),o=require("./define.cjs"),s=require("./slots.cjs"),c=require("./host-bind.cjs"),l=require("./aria.cjs"),u=require("./utils/emit.cjs"),d=require("./template/instantiator.cjs");require("./template.cjs");const f=require("./utils/id.cjs");exports.OreApiError=e.OreApiError,exports.OreError=e.OreError,exports.OreInternalError=e.OreInternalError,exports.OreLifecycleError=e.OreLifecycleError,exports.OreTimeoutError=e.OreTimeoutError,exports.aria=l.aria,exports.bind=c.bind,exports.createContext=r.createContext,exports.createId=f.createId,exports.createStableId=f.createStableId,exports.css=a.css,exports.define=o.define,exports.getHost=n.getHost,exports.html=d.html,exports.inject=r.inject,exports.injectStrict=r.injectStrict,exports.onCleanup=n.onCleanup,exports.onElement=n.onElement,exports.onEvent=n.onEvent,exports.onFormReset=n.onFormReset,exports.onMounted=n.onMounted,exports.prop=i.prop,exports.provide=r.provide,exports.ref=t.ref,exports.resetIdCounter=f.resetIdCounter,exports.useEmit=u.useEmit,exports.useSlots=s.useSlots,exports.watchEffect=n.watchEffect;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./runtime.cjs"),n=require("./props.cjs"),r=require("./template/result.cjs"),i=require("./utils/css.cjs"),a=require("./define.cjs"),o=require("./context.cjs"),s=require("./slots.cjs"),c=require("./host-bind.cjs"),l=require("./utils/emit.cjs"),u=require("./directives/live.cjs"),d=require("./template/instantiator.cjs"),f=require("./directives/classMap.cjs"),p=require("./directives/each.cjs"),m=require("./directives/styleMap.cjs"),h=require("./directives/unsafe-html.cjs"),g=require("./directives/when.cjs"),_=require("./forms/field.cjs"),v=require("./observers/intersection-observe.cjs"),y=require("./observers/media-observe.cjs"),b=require("./observers/mutation-observe.cjs"),x=require("./observers/resize-observe.cjs"),S=require("./utils/id.cjs");exports.OreApiError=e.OreApiError,exports.OreError=e.OreError,exports.OreInternalError=e.OreInternalError,exports.OreLifecycleError=e.OreLifecycleError,exports.bind=c.bind,exports.classMap=f.classMap,exports.createContext=o.createContext,exports.createId=S.createId,exports.createStableId=S.createStableId,exports.css=i.css,exports.define=a.define,exports.each=p.each,exports.getHost=t.getHost,exports.html=d.html,exports.inject=o.inject,exports.injectStrict=o.injectStrict,exports.intersectionObserver=v.intersectionObserver,exports.live=u.live,exports.mediaObserver=y.mediaObserver,exports.mutationObserver=b.mutationObserver,exports.onCleanup=t.onCleanup,exports.onElement=t.onElement,exports.onEvent=t.onEvent,exports.onFormReset=t.onFormReset,exports.onMounted=t.onMounted,exports.prop=n.prop,exports.provide=o.provide,exports.ref=r.ref,exports.resetStableIdCounter=S.resetStableIdCounter,exports.resizeObserver=x.resizeObserver,exports.styleMap=m.styleMap,exports.unsafeHtml=h.unsafeHtml,exports.useEmit=l.useEmit,exports.useField=_.useField,exports.useSlots=s.useSlots,exports.watchEffect=t.watchEffect,exports.when=g.when;
package/dist/index.d.ts CHANGED
@@ -1,15 +1,25 @@
1
- export { OreApiError, OreError, type OreErrorPhase, OreInternalError, OreLifecycleError, OreTimeoutError, } from './errors';
1
+ export { OreApiError, OreError, type OreErrorPhase, OreInternalError, OreLifecycleError } from './errors';
2
2
  export { define, prop } from './define';
3
3
  export type { ComponentDefinition } from './component-types';
4
4
  export type { InferProps, PropDef, PropInputDefs, PropsDef } from './props';
5
5
  export { createContext, inject, injectStrict, provide, type InjectionKey } from './context';
6
6
  export { useSlots, type ComponentSlots } from './slots';
7
- export { aria, type AriaConfig } from './aria';
8
7
  export { bind, type BindOptions, type HostBindConfig, type HostBindFn, type HostBindingValue, type ReflectConfig, } from './host-bind';
9
8
  export { getHost, onCleanup, onElement, onEvent, onFormReset, type OnFormResetCallback, onMounted, type OnMountedCallback, watchEffect, } from './runtime';
10
9
  export { useEmit, type EmitFn } from './utils/emit';
11
- export { html } from './template';
10
+ export { html } from './template/instantiator';
11
+ export { type HTMLResult, ref, type Ref, type RefCallback } from './template/result';
12
+ export { classMap } from './directives/classMap';
13
+ export { each } from './directives/each';
14
+ export { live, type LiveBinding } from './directives/live';
15
+ export { styleMap } from './directives/styleMap';
16
+ export { unsafeHtml } from './directives/unsafe-html';
17
+ export { when } from './directives/when';
18
+ export { useField, type FormFieldHandle, type FormFieldOptions } from './forms/field';
19
+ export { intersectionObserver } from './observers/intersection-observe';
20
+ export { mediaObserver } from './observers/media-observe';
21
+ export { mutationObserver, type MutationObserverValue } from './observers/mutation-observe';
22
+ export { resizeObserver } from './observers/resize-observe';
12
23
  export { css, type CSSResult } from './utils/css';
13
- export { createId, createStableId, resetIdCounter } from './utils/id';
14
- export { ref, type DirectiveResult, type HTMLResult, type Ref, type RefCallback } from './types/bindings';
24
+ export { createId, createStableId, resetStableIdCounter } from './utils/id';
15
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,KAAK,aAAa,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5F,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EACL,IAAI,EACJ,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,KAAK,mBAAmB,EACxB,SAAS,EACT,KAAK,iBAAiB,EACtB,WAAW,GACZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,GAAG,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE1G,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5F,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,EACL,IAAI,EACJ,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,KAAK,mBAAmB,EACxB,SAAS,EACT,KAAK,iBAAiB,EACtB,WAAW,GACZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,KAAK,UAAU,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{OreApiError as e,OreError as t,OreInternalError as n,OreLifecycleError as r,OreTimeoutError as i}from"./errors.js";import{ref as a}from"./types/bindings.js";import{getHost as o,onCleanup as s,onElement as c,onEvent as l,onFormReset as u,onMounted as d,watchEffect as f}from"./runtime.js";import{createContext as p,inject as m,injectStrict as h,provide as g}from"./context.js";import{prop as _}from"./props.js";import{css as v}from"./utils/css.js";import{define as y}from"./define.js";import{useSlots as b}from"./slots.js";import{bind as x}from"./host-bind.js";import{aria as S}from"./aria.js";import{useEmit as C}from"./utils/emit.js";import{html as w}from"./template/instantiator.js";import"./template.js";import{createId as T,createStableId as E,resetIdCounter as D}from"./utils/id.js";export{e as OreApiError,t as OreError,n as OreInternalError,r as OreLifecycleError,i as OreTimeoutError,S as aria,x as bind,p as createContext,T as createId,E as createStableId,v as css,y as define,o as getHost,w as html,m as inject,h as injectStrict,s as onCleanup,c as onElement,l as onEvent,u as onFormReset,d as onMounted,_ as prop,g as provide,a as ref,D as resetIdCounter,C as useEmit,b as useSlots,f as watchEffect};
1
+ import{OreApiError as e,OreError as t,OreInternalError as n,OreLifecycleError as r}from"./errors.js";import{getHost as i,onCleanup as a,onElement as o,onEvent as s,onFormReset as c,onMounted as l,watchEffect as u}from"./runtime.js";import{prop as d}from"./props.js";import{ref as f}from"./template/result.js";import{css as p}from"./utils/css.js";import{define as m}from"./define.js";import{createContext as h,inject as g,injectStrict as _,provide as v}from"./context.js";import{useSlots as y}from"./slots.js";import{bind as b}from"./host-bind.js";import{useEmit as x}from"./utils/emit.js";import{live as S}from"./directives/live.js";import{html as C}from"./template/instantiator.js";import{classMap as w}from"./directives/classMap.js";import{each as T}from"./directives/each.js";import{styleMap as E}from"./directives/styleMap.js";import{unsafeHtml as D}from"./directives/unsafe-html.js";import{when as O}from"./directives/when.js";import{useField as k}from"./forms/field.js";import{intersectionObserver as A}from"./observers/intersection-observe.js";import{mediaObserver as j}from"./observers/media-observe.js";import{mutationObserver as M}from"./observers/mutation-observe.js";import{resizeObserver as N}from"./observers/resize-observe.js";import{createId as P,createStableId as F,resetStableIdCounter as I}from"./utils/id.js";export{e as OreApiError,t as OreError,n as OreInternalError,r as OreLifecycleError,b as bind,w as classMap,h as createContext,P as createId,F as createStableId,p as css,m as define,T as each,i as getHost,C as html,g as inject,_ as injectStrict,A as intersectionObserver,S as live,j as mediaObserver,M as mutationObserver,a as onCleanup,o as onElement,s as onEvent,c as onFormReset,l as onMounted,d as prop,v as provide,f as ref,I as resetStableIdCounter,N as resizeObserver,E as styleMap,D as unsafeHtml,x as useEmit,k as useField,y as useSlots,u as watchEffect,O as when};
@@ -1,2 +1,2 @@
1
- let e=require("@vielzeug/ripple");var t=(t,n)=>{let r=(0,e.signal)(null),i=new IntersectionObserver(([e])=>{e&&(r.value=e)},n);return i.observe(t),(0,e.onCleanup)(()=>i.disconnect()),r};exports.intersectionObserver=t;
1
+ const e=require("../runtime.cjs");let t=require("@vielzeug/ripple");var n=(n,r)=>{let i=(0,t.signal)(null),a=new IntersectionObserver(([e])=>{e&&(i.value=e)},r);return a.observe(n),e.onCleanup(()=>a.disconnect()),i};exports.intersectionObserver=n;
2
2
  //# sourceMappingURL=intersection-observe.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"intersection-observe.cjs","names":[],"sources":["../../src/observers/intersection-observe.ts"],"sourcesContent":["import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes an element's intersection with the viewport (or a given root) via\n * `IntersectionObserver`. Returns a `Reactive` that updates whenever the\n * intersection ratio changes.\n * Must be called inside a `mount()` callback.\n */\nexport const intersectionObserver = (\n el: Element,\n options?: IntersectionObserverInit,\n): Readable<IntersectionObserverEntry | null> => {\n const entry = signal<IntersectionObserverEntry | null>(null);\n const io = new IntersectionObserver(([nextEntry]) => {\n if (nextEntry) entry.value = nextEntry;\n }, options);\n\n io.observe(el);\n onCleanup(() => io.disconnect());\n\n return entry;\n};\n"],"mappings":"kCAQA,IAAa,GACX,EACA,IAC+C,CAC/C,IAAM,GAAA,EAAA,EAAA,OAAA,CAAiD,IAAI,EACrD,EAAK,IAAI,sBAAsB,CAAC,KAAe,CAC/C,IAAW,EAAM,MAAQ,EAC/B,EAAG,CAAO,EAKV,OAHA,EAAG,QAAQ,CAAE,GACb,EAAA,EAAA,UAAA,KAAgB,EAAG,WAAW,CAAC,EAExB,CACT"}
1
+ {"version":3,"file":"intersection-observe.cjs","names":[],"sources":["../../src/observers/intersection-observe.ts"],"sourcesContent":["import { type Readable, signal } from '@vielzeug/ripple';\n\nimport { onCleanup } from '../runtime';\n\n/**\n * Observes an element's intersection with the viewport (or a given root) via\n * `IntersectionObserver`. Returns a `Reactive` that updates whenever the\n * intersection ratio changes.\n * Must be called inside a `mount()` callback.\n */\nexport const intersectionObserver = (\n el: Element,\n options?: IntersectionObserverInit,\n): Readable<IntersectionObserverEntry | null> => {\n const entry = signal<IntersectionObserverEntry | null>(null);\n const io = new IntersectionObserver(([nextEntry]) => {\n if (nextEntry) entry.value = nextEntry;\n }, options);\n\n io.observe(el);\n onCleanup(() => io.disconnect());\n\n return entry;\n};\n"],"mappings":"oEAUA,IAAa,GACX,EACA,IAC+C,CAC/C,IAAM,GAAA,EAAQ,EAAA,OAAA,CAAyC,IAAI,EACrD,EAAK,IAAI,sBAAsB,CAAC,KAAe,CAC/C,IAAW,EAAM,MAAQ,EAC/B,EAAG,CAAO,EAKV,OAHA,EAAG,QAAQ,CAAE,EACb,EAAA,cAAgB,EAAG,WAAW,CAAC,EAExB,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"intersection-observe.d.ts","sourceRoot":"","sources":["../../src/observers/intersection-observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAqB,MAAM,kBAAkB,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,IAAI,OAAO,EACX,UAAU,wBAAwB,KACjC,QAAQ,CAAC,yBAAyB,GAAG,IAAI,CAU3C,CAAC"}
1
+ {"version":3,"file":"intersection-observe.d.ts","sourceRoot":"","sources":["../../src/observers/intersection-observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAIzD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,IAAI,OAAO,EACX,UAAU,wBAAwB,KACjC,QAAQ,CAAC,yBAAyB,GAAG,IAAI,CAU3C,CAAC"}