@vielzeug/ore 2.2.0 → 3.0.1

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 (89) hide show
  1. package/README.md +2 -53
  2. package/dist/context.cjs +1 -1
  3. package/dist/context.cjs.map +1 -1
  4. package/dist/context.d.ts +4 -13
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +1 -1
  7. package/dist/context.js.map +1 -1
  8. package/dist/define.cjs.map +1 -1
  9. package/dist/define.d.ts +1 -1
  10. package/dist/define.d.ts.map +1 -1
  11. package/dist/define.js.map +1 -1
  12. package/dist/directives/each.cjs +1 -1
  13. package/dist/directives/each.cjs.map +1 -1
  14. package/dist/directives/each.d.ts +2 -2
  15. package/dist/directives/each.d.ts.map +1 -1
  16. package/dist/directives/each.js +1 -1
  17. package/dist/directives/each.js.map +1 -1
  18. package/dist/directives/when.cjs +1 -1
  19. package/dist/directives/when.cjs.map +1 -1
  20. package/dist/directives/when.js +1 -1
  21. package/dist/directives/when.js.map +1 -1
  22. package/dist/forms/field.cjs +1 -1
  23. package/dist/forms/field.cjs.map +1 -1
  24. package/dist/forms/field.d.ts +0 -7
  25. package/dist/forms/field.d.ts.map +1 -1
  26. package/dist/forms/field.js +1 -1
  27. package/dist/forms/field.js.map +1 -1
  28. package/dist/host-bind.cjs +1 -1
  29. package/dist/host-bind.cjs.map +1 -1
  30. package/dist/host-bind.d.ts +3 -10
  31. package/dist/host-bind.d.ts.map +1 -1
  32. package/dist/host-bind.js +1 -1
  33. package/dist/host-bind.js.map +1 -1
  34. package/dist/index.cjs +1 -1
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/ore.cjs +1 -1
  39. package/dist/ore.cjs.map +1 -1
  40. package/dist/ore.iife.js +1 -1
  41. package/dist/ore.iife.js.map +1 -1
  42. package/dist/ore.js +1 -1
  43. package/dist/ore.js.map +1 -1
  44. package/dist/runtime.cjs.map +1 -1
  45. package/dist/runtime.d.ts +1 -1
  46. package/dist/runtime.d.ts.map +1 -1
  47. package/dist/runtime.js.map +1 -1
  48. package/dist/template/bindings.cjs +1 -1
  49. package/dist/template/bindings.cjs.map +1 -1
  50. package/dist/template/bindings.js +1 -1
  51. package/dist/template/bindings.js.map +1 -1
  52. package/dist/testing/flush.cjs +1 -1
  53. package/dist/testing/flush.cjs.map +1 -1
  54. package/dist/testing/flush.d.ts +0 -18
  55. package/dist/testing/flush.d.ts.map +1 -1
  56. package/dist/testing/flush.js +1 -1
  57. package/dist/testing/flush.js.map +1 -1
  58. package/dist/testing/form-internals-polyfill.cjs +1 -1
  59. package/dist/testing/form-internals-polyfill.cjs.map +1 -1
  60. package/dist/testing/form-internals-polyfill.js +1 -1
  61. package/dist/testing/form-internals-polyfill.js.map +1 -1
  62. package/dist/testing/index.d.ts +3 -6
  63. package/dist/testing/index.d.ts.map +1 -1
  64. package/dist/testing/mount.cjs +1 -1
  65. package/dist/testing/mount.cjs.map +1 -1
  66. package/dist/testing/mount.d.ts +0 -20
  67. package/dist/testing/mount.d.ts.map +1 -1
  68. package/dist/testing/mount.js +1 -1
  69. package/dist/testing/mount.js.map +1 -1
  70. package/dist/testing/reset.cjs.map +1 -1
  71. package/dist/testing/reset.d.ts +1 -1
  72. package/dist/testing/reset.js.map +1 -1
  73. package/dist/testing.cjs +1 -1
  74. package/dist/testing.cjs.map +1 -1
  75. package/dist/testing.js +1 -1
  76. package/dist/testing.js.map +1 -1
  77. package/dist/utils/aria.cjs +1 -1
  78. package/dist/utils/aria.cjs.map +1 -1
  79. package/dist/utils/aria.d.ts +1 -13
  80. package/dist/utils/aria.d.ts.map +1 -1
  81. package/dist/utils/aria.js +1 -1
  82. package/dist/utils/aria.js.map +1 -1
  83. package/dist/utils/id.cjs +1 -1
  84. package/dist/utils/id.cjs.map +1 -1
  85. package/dist/utils/id.d.ts +2 -25
  86. package/dist/utils/id.d.ts.map +1 -1
  87. package/dist/utils/id.js +1 -1
  88. package/dist/utils/id.js.map +1 -1
  89. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"mount.cjs","names":[],"sources":["../../src/testing/mount.ts"],"sourcesContent":["/**\n * Component mounting utilities for test environments.\n */\n\nimport { type QueryScope, within } from '@vielzeug/assay';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from '../component-types';\nimport { define } from '../define';\nimport type { HTMLResult } from '../template/result';\nimport { setAttr } from '../utils/dom';\nimport { type FlushOptions, flush } from './flush';\nimport { _disposeRenderHooks } from './render-hook';\nimport { resetOreForTests } from './reset';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n// Fixture inherits Assay's complete QueryScope. Keeping that relationship structural means new\n// scoped query capabilities are immediately available to fixtures without a duplicate contract.\n/**\n * A mounted component ready for assertions. All inherited `QueryScope` methods are scoped to\n * `element.shadowRoot`, falling back to `element` for light-DOM components (`shadow: false`).\n */\nexport interface Fixture<T extends HTMLElement = HTMLElement> extends QueryScope {\n /** Run a callback then flush — the standard way to trigger and assert a reactive update */\n act(fn: () => unknown): Promise<void>;\n /** Set an attribute (boolean `false` removes it) then flush */\n attr(name: string, value: string | number | boolean): Promise<void>;\n /** Set multiple attributes then flush */\n attrs(record: Record<string, string | number | boolean>): Promise<void>;\n /** Remove the component from the DOM. Idempotent. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** The component element */\n element: T;\n /** Wait for all reactive updates and animation frames */\n flush(options?: FlushOptions): Promise<void>;\n /** The component's shadow root (null for light-DOM components) */\n readonly shadow: ShadowRoot | null;\n /** Delegates to `dispose()`. Enables `using` declarations. */\n [Symbol.dispose](): void;\n}\n\nexport interface MountOptions {\n /** HTML attributes to set on the element */\n attrs?: Record<string, string | number | boolean>;\n /** Extra component options when passing an inline setup function */\n componentOptions?: Omit<ComponentDefinition<Record<string, unknown>>, 'setup'>;\n /** Parent container (default: document.body) */\n container?: HTMLElement | ShadowRoot;\n /** Inner HTML for slot content */\n html?: string;\n /** Properties assigned directly onto the element */\n props?: Record<string, unknown>;\n}\n\ntype MountProps = { readonly [x: string]: Readable<unknown> };\n\n// Bivariant callback type keeps inline test callbacks ergonomic across varying prop specializations.\nexport type MountSetup = {\n bivarianceHack: (props: MountProps) => HTMLResult | null;\n}['bivarianceHack'];\n\n// ─── Test environment state ───────────────────────────────────────────────────\n\nexport const _mountedElements: HTMLElement[] = [];\n\n// Monotonic across the whole test run — never reset: custom element registrations\n// are permanent, so a re-used tag name would throw on re-define. Deterministic\n// within a run (trial-1, trial-2, ...) without a random suffix.\nlet _componentTagCounter = 0;\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction applyAttr(element: Element, name: string, value: string | number | boolean): void {\n // Same write path as the runtime's attribute bindings, so tests never set up\n // states the runtime itself can't produce (e.g. boolean true → \"true\").\n setAttr(element, name, value);\n}\n\nconst toError = (value: unknown): Error => {\n return value instanceof Error ? value : new Error(String(value));\n};\n\nconst withWindowErrorCapture = async <T>(action: () => Promise<T>): Promise<T> => {\n if (typeof window === 'undefined') return action();\n\n let captured: Error | null = null;\n const onError = (event: ErrorEvent) => {\n captured = toError(event.error ?? event.message);\n event.preventDefault();\n };\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n captured = toError(event.reason);\n event.preventDefault();\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n try {\n const result = await action();\n\n if (captured) throw captured;\n\n return result;\n } finally {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n};\n\n// ─── API ─────────────────────────────────────────────────────────────────────\n\n/**\n * Mount a component into the DOM and return a test fixture.\n *\n * Accepts a registered tag name, an inline setup function, or a component\n * options object. Setup functions are auto-registered with generated tag names.\n *\n * @example — inline setup function\n * const { query } = await mount(() => {\n * const count = signal(0);\n * return html`<button @click=${() => count.value++}>${count}</button>`;\n * });\n *\n * @example — registered tag name\n * const { query } = await mount('my-counter');\n */\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: MountSetup,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string | MountSetup,\n options: MountOptions = {},\n): Promise<Fixture<T>> {\n const { attrs = {}, componentOptions, container = document.body, html, props = {} } = options;\n\n let tagName: string;\n let inlineDefinition: ComponentDefinition<Record<string, unknown>> | undefined;\n\n if (typeof tagOrSetup === 'string') {\n tagName = tagOrSetup;\n } else {\n tagName = `trial-${++_componentTagCounter}`;\n inlineDefinition = {\n ...(componentOptions ?? {}),\n setup: tagOrSetup,\n };\n }\n\n if (inlineDefinition) {\n define(tagName, inlineDefinition);\n }\n\n const element = document.createElement(tagName) as T;\n\n if (html) element.innerHTML = html;\n\n if (Object.keys(props).length) Object.assign(element, props);\n\n for (const [name, value] of Object.entries(attrs)) applyAttr(element, name, value);\n\n try {\n await withWindowErrorCapture(async () => {\n container.appendChild(element);\n _mountedElements.push(element);\n await flush();\n });\n } catch (err) {\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n\n throw err;\n }\n\n let isDisposed = false;\n\n function dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n }\n\n const scope = within((element.shadowRoot ?? element) as Element);\n\n return {\n ...scope,\n\n async act(fn) {\n await fn();\n await flush();\n },\n\n async attr(name, value) {\n applyAttr(element, name, value);\n await flush();\n },\n\n async attrs(record) {\n for (const [name, value] of Object.entries(record)) applyAttr(element, name, value);\n await flush();\n },\n\n dispose,\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n element,\n\n flush,\n\n get shadow(): ShadowRoot | null {\n return element.shadowRoot;\n },\n\n [Symbol.dispose]() {\n dispose();\n },\n };\n}\n\n/**\n * Register and mount a component definition in a single call.\n *\n * Combines `define(tag, definition)` + `mount(tag, options)` — the standard\n * pattern for testing full custom-element lifecycle (props, reconnect, etc.).\n *\n * @example\n * const { query } = await mountComponent('my-counter', {\n * props: { count: prop.number(0) },\n * setup: (props) => html`<div>${props.count}</div>`,\n * });\n */\nexport async function mountComponent<Props extends Record<string, unknown>, T extends HTMLElement = HTMLElement>(\n tag: string,\n definition: ComponentDefinition<Props>,\n options?: MountOptions,\n): Promise<Fixture<T>> {\n define(tag, definition);\n\n return mount<T>(tag, options);\n}\n\n/**\n * Register a stub custom element (no-op if already defined).\n *\n * @example\n * mock('child-button', '<slot></slot>');\n */\nexport function mock(tagName: string, template = ''): void {\n if (!customElements.get(tagName)) {\n customElements.define(\n tagName,\n class extends HTMLElement {\n connectedCallback() {\n this.innerHTML = template;\n }\n },\n );\n }\n}\n\n/**\n * Remove all elements mounted via `mount()`.\n * Call in `afterEach` to keep tests isolated.\n *\n * @example\n * afterEach(() => cleanup());\n */\nexport function cleanup(): void {\n for (const el of _mountedElements) el.remove();\n _mountedElements.length = 0;\n _disposeRenderHooks();\n resetOreForTests();\n}\n\n/** @internal re-export for within() */\nexport type { QueryScope };\n"],"mappings":"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"}
1
+ {"version":3,"file":"mount.cjs","names":[],"sources":["../../src/testing/mount.ts"],"sourcesContent":["/**\n * Component mounting utilities for test environments.\n */\n\nimport { type QueryScope, within } from '@vielzeug/assay';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from '../component-types';\nimport { define } from '../define';\nimport type { HTMLResult } from '../template/result';\nimport { setAttr } from '../utils/dom';\nimport { type FlushOptions, flush } from './flush';\nimport { _disposeRenderHooks } from './render-hook';\nimport { resetOreForTests } from './reset';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n// Fixture inherits Assay's complete QueryScope. Keeping that relationship structural means new\n// scoped query capabilities are immediately available to fixtures without a duplicate contract.\n/**\n * A mounted component ready for assertions. All inherited `QueryScope` methods are scoped to\n * `element.shadowRoot`, falling back to `element` for light-DOM components (`shadow: false`).\n */\nexport interface Fixture<T extends HTMLElement = HTMLElement> extends QueryScope {\n /** Run a callback then flush — the standard way to trigger and assert a reactive update */\n act(fn: () => unknown): Promise<void>;\n /** Set an attribute (boolean `false` removes it) then flush */\n attr(name: string, value: string | number | boolean): Promise<void>;\n /** Set multiple attributes then flush */\n attrs(record: Record<string, string | number | boolean>): Promise<void>;\n /** Remove the component from the DOM. Idempotent. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** The component element */\n element: T;\n /** Wait for all reactive updates and animation frames */\n flush(options?: FlushOptions): Promise<void>;\n /** The component's shadow root (null for light-DOM components) */\n readonly shadow: ShadowRoot | null;\n /** Delegates to `dispose()`. Enables `using` declarations. */\n [Symbol.dispose](): void;\n}\n\nexport interface MountOptions {\n /** HTML attributes to set on the element */\n attrs?: Record<string, string | number | boolean>;\n /** Extra component options when passing an inline setup function */\n componentOptions?: Omit<ComponentDefinition<Record<string, unknown>>, 'setup'>;\n /** Parent container (default: document.body) */\n container?: HTMLElement | ShadowRoot;\n /** Inner HTML for slot content */\n html?: string;\n /** Properties assigned directly onto the element */\n props?: Record<string, unknown>;\n}\n\ntype MountProps = { readonly [x: string]: Readable<unknown> };\n\n// Bivariant callback type keeps inline test callbacks ergonomic across varying prop specializations.\nexport type MountSetup = {\n bivarianceHack: (props: MountProps) => HTMLResult | null;\n}['bivarianceHack'];\n\n// ─── Test environment state ───────────────────────────────────────────────────\n\nexport const _mountedElements: HTMLElement[] = [];\n\n// Monotonic across the whole test run — never reset: custom element registrations\n// are permanent, so a re-used tag name would throw on re-define. Deterministic\n// within a run (trial-1, trial-2, ...) without a random suffix.\nlet _componentTagCounter = 0;\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction applyAttr(element: Element, name: string, value: string | number | boolean): void {\n // Same write path as the runtime's attribute bindings, so tests never set up\n // states the runtime itself can't produce (e.g. boolean true → \"true\").\n setAttr(element, name, value);\n}\n\nconst toError = (value: unknown): Error => {\n return value instanceof Error ? value : new Error(String(value));\n};\n\nconst withWindowErrorCapture = async <T>(action: () => Promise<T>): Promise<T> => {\n if (typeof window === 'undefined') return action();\n\n let captured: Error | null = null;\n const onError = (event: ErrorEvent) => {\n captured = toError(event.error ?? event.message);\n event.preventDefault();\n };\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n captured = toError(event.reason);\n event.preventDefault();\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n try {\n const result = await action();\n\n if (captured) throw captured;\n\n return result;\n } finally {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n};\n\n// ─── API ─────────────────────────────────────────────────────────────────────\n\n/**\n * Mount a component into the DOM and return a test fixture.\n *\n * Accepts a registered tag name, an inline setup function, or a component\n * options object. Setup functions are auto-registered with generated tag names.\n *\n * @example — inline setup function\n * const { query } = await mount(() => {\n * const count = signal(0);\n * return html`<button @click=${() => count.value++}>${count}</button>`;\n * });\n *\n * @example — registered tag name\n * const { query } = await mount('my-counter');\n */\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: MountSetup,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string | MountSetup,\n options: MountOptions = {},\n): Promise<Fixture<T>> {\n const { attrs = {}, componentOptions, container = document.body, html, props = {} } = options;\n\n let tagName: string;\n let inlineDefinition: ComponentDefinition<Record<string, unknown>> | undefined;\n\n if (typeof tagOrSetup === 'string') {\n tagName = tagOrSetup;\n } else {\n tagName = `trial-${++_componentTagCounter}`;\n inlineDefinition = {\n ...(componentOptions ?? {}),\n setup: tagOrSetup,\n };\n }\n\n if (inlineDefinition) {\n define(tagName, inlineDefinition);\n }\n\n const element = document.createElement(tagName) as T;\n\n if (html) element.innerHTML = html;\n\n if (Object.keys(props).length) Object.assign(element, props);\n\n for (const [name, value] of Object.entries(attrs)) applyAttr(element, name, value);\n\n try {\n await withWindowErrorCapture(async () => {\n container.appendChild(element);\n _mountedElements.push(element);\n await flush();\n });\n } catch (err) {\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n\n throw err;\n }\n\n let isDisposed = false;\n\n function dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n }\n\n const scope = within((element.shadowRoot ?? element) as Element);\n\n return {\n ...scope,\n\n async act(fn) {\n await fn();\n await flush();\n },\n\n async attr(name, value) {\n applyAttr(element, name, value);\n await flush();\n },\n\n async attrs(record) {\n for (const [name, value] of Object.entries(record)) applyAttr(element, name, value);\n await flush();\n },\n\n dispose,\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n element,\n\n flush,\n\n get shadow(): ShadowRoot | null {\n return element.shadowRoot;\n },\n\n [Symbol.dispose]() {\n dispose();\n },\n };\n}\n\n/**\n * Remove all elements mounted via `mount()`.\n * Call in `afterEach` to keep tests isolated.\n *\n * @example\n * afterEach(() => cleanup());\n */\nexport function cleanup(): void {\n for (const el of _mountedElements) el.remove();\n _mountedElements.length = 0;\n _disposeRenderHooks();\n resetOreForTests();\n}\n\n/** @internal re-export for within() */\nexport type { QueryScope };\n"],"mappings":"iLAkEA,IAAa,EAAkC,CAAC,EAK5C,EAAuB,EAI3B,SAAS,EAAU,EAAkB,EAAc,EAAwC,CAGzF,EAAA,QAAQ,EAAS,EAAM,CAAK,CAC9B,CAEA,IAAM,EAAW,GACR,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,EAG3D,EAAyB,KAAU,IAAyC,CAChF,GAAI,OAAO,OAAW,IAAa,OAAO,EAAO,EAEjD,IAAI,EAAyB,KACvB,EAAW,GAAsB,CACrC,EAAW,EAAQ,EAAM,OAAS,EAAM,OAAO,EAC/C,EAAM,eAAe,CACvB,EACM,EAAwB,GAAiC,CAC7D,EAAW,EAAQ,EAAM,MAAM,EAC/B,EAAM,eAAe,CACvB,EAEA,OAAO,iBAAiB,QAAS,CAAO,EACxC,OAAO,iBAAiB,qBAAsB,CAAoB,EAElE,GAAI,CACF,IAAM,EAAS,MAAM,EAAO,EAE5B,GAAI,EAAU,MAAM,EAEpB,OAAO,CACT,QAAU,CACR,OAAO,oBAAoB,QAAS,CAAO,EAC3C,OAAO,oBAAoB,qBAAsB,CAAoB,CACvE,CACF,EA2BA,eAAsB,EACpB,EACA,EAAwB,CAAC,EACJ,CACrB,GAAM,CAAE,QAAQ,CAAC,EAAG,mBAAkB,YAAY,SAAS,KAAM,OAAM,QAAQ,CAAC,GAAM,EAElF,EACA,EAEA,OAAO,GAAe,SACxB,EAAU,GAEV,EAAU,SAAS,EAAE,IACrB,EAAmB,CACjB,GAAI,GAAoB,CAAC,EACzB,MAAO,CACT,GAGE,GACF,EAAA,OAAO,EAAS,CAAgB,EAGlC,IAAM,EAAU,SAAS,cAAc,CAAO,EAE1C,IAAM,EAAQ,UAAY,GAE1B,OAAO,KAAK,CAAK,CAAC,CAAC,QAAQ,OAAO,OAAO,EAAS,CAAK,EAE3D,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,CAAK,EAAG,EAAU,EAAS,EAAM,CAAK,EAEjF,GAAI,CACF,MAAM,EAAuB,SAAY,CACvC,EAAU,YAAY,CAAO,EAC7B,EAAiB,KAAK,CAAO,EAC7B,MAAM,EAAA,MAAM,CACd,CAAC,CACH,OAAS,EAAK,CACZ,EAAQ,OAAO,EAEf,IAAM,EAAI,EAAiB,QAAQ,CAAO,EAI1C,MAFI,IAAM,IAAI,EAAiB,OAAO,EAAG,CAAC,EAEpC,CACR,CAEA,IAAI,EAAa,GAEjB,SAAS,GAAU,CACjB,GAAI,EAAY,OAEhB,EAAa,GACb,EAAQ,OAAO,EAEf,IAAM,EAAI,EAAiB,QAAQ,CAAO,EAEtC,IAAM,IAAI,EAAiB,OAAO,EAAG,CAAC,CAC5C,CAIA,MAAO,CACL,IAAA,EAHY,EAAA,OAAA,CAAQ,EAAQ,YAAc,CAGvC,EAEH,MAAM,IAAI,EAAI,CACZ,MAAM,EAAG,EACT,MAAM,EAAA,MAAM,CACd,EAEA,MAAM,KAAK,EAAM,EAAO,CACtB,EAAU,EAAS,EAAM,CAAK,EAC9B,MAAM,EAAA,MAAM,CACd,EAEA,MAAM,MAAM,EAAQ,CAClB,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,CAAM,EAAG,EAAU,EAAS,EAAM,CAAK,EAClF,MAAM,EAAA,MAAM,CACd,EAEA,UAEA,IAAI,UAAoB,CACtB,OAAO,CACT,EAEA,UAEA,MAAA,EAAA,MAEA,IAAI,QAA4B,CAC9B,OAAO,EAAQ,UACjB,EAEA,CAAC,OAAO,UAAW,CACjB,EAAQ,CACV,CACF,CACF,CASA,SAAgB,GAAgB,CAC9B,IAAK,IAAM,KAAM,EAAkB,EAAG,OAAO,EAC7C,EAAiB,OAAS,EAC1B,EAAA,oBAAoB,EACpB,EAAA,iBAAiB,CACnB"}
@@ -66,26 +66,6 @@ export declare const _mountedElements: HTMLElement[];
66
66
  */
67
67
  export declare function mount<T extends HTMLElement = HTMLElement>(tagOrSetup: string, options?: MountOptions): Promise<Fixture<T>>;
68
68
  export declare function mount<T extends HTMLElement = HTMLElement>(tagOrSetup: MountSetup, options?: MountOptions): Promise<Fixture<T>>;
69
- /**
70
- * Register and mount a component definition in a single call.
71
- *
72
- * Combines `define(tag, definition)` + `mount(tag, options)` — the standard
73
- * pattern for testing full custom-element lifecycle (props, reconnect, etc.).
74
- *
75
- * @example
76
- * const { query } = await mountComponent('my-counter', {
77
- * props: { count: prop.number(0) },
78
- * setup: (props) => html`<div>${props.count}</div>`,
79
- * });
80
- */
81
- export declare function mountComponent<Props extends Record<string, unknown>, T extends HTMLElement = HTMLElement>(tag: string, definition: ComponentDefinition<Props>, options?: MountOptions): Promise<Fixture<T>>;
82
- /**
83
- * Register a stub custom element (no-op if already defined).
84
- *
85
- * @example
86
- * mock('child-button', '<slot></slot>');
87
- */
88
- export declare function mock(tagName: string, template?: string): void;
89
69
  /**
90
70
  * Remove all elements mounted via `mount()`.
91
71
  * Call in `afterEach` to keep tests isolated.
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/testing/mount.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/testing/mount.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAU,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,SAAS,CAAC;AAQnD;;;GAGG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,CAAE,SAAQ,UAAU;IAC9E,2FAA2F;IAC3F,GAAG,CAAC,EAAE,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+DAA+D;IAC/D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,yCAAyC;IACzC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,qDAAqD;IACrD,OAAO,IAAI,IAAI,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,4BAA4B;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,yDAAyD;IACzD,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,8DAA8D;IAC9D,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAClD,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/E,gDAAgD;IAChD,SAAS,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;IACrC,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,KAAK,UAAU,GAAG;IAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC;AAG9D,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,GAAG,IAAI,CAAC;CAC1D,CAAC,gBAAgB,CAAC,CAAC;AAIpB,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAO,CAAC;AAiDlD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,KAAK,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC7D,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,wBAAsB,KAAK,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC7D,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAqGvB;;;;;;GAMG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
@@ -1,2 +1,2 @@
1
- import{setAttr as e}from"../utils/dom.js";import{define as t}from"../define.js";import{flush as n}from"./flush.js";import{_disposeRenderHooks as r}from"./render-hook.js";import{resetOreForTests as i}from"./reset.js";import{within as a}from"@vielzeug/assay";var o=[],s=0;function c(t,n,r){e(t,n,r)}var l=e=>e instanceof Error?e:Error(String(e)),u=async e=>{if(typeof window>`u`)return e();let t=null,n=e=>{t=l(e.error??e.message),e.preventDefault()},r=e=>{t=l(e.reason),e.preventDefault()};window.addEventListener(`error`,n),window.addEventListener(`unhandledrejection`,r);try{let n=await e();if(t)throw t;return n}finally{window.removeEventListener(`error`,n),window.removeEventListener(`unhandledrejection`,r)}};async function d(e,r={}){let{attrs:i={},componentOptions:l,container:d=document.body,html:f,props:p={}}=r,m,h;typeof e==`string`?m=e:(m=`trial-${++s}`,h={...l??{},setup:e}),h&&t(m,h);let g=document.createElement(m);f&&(g.innerHTML=f),Object.keys(p).length&&Object.assign(g,p);for(let[e,t]of Object.entries(i))c(g,e,t);try{await u(async()=>{d.appendChild(g),o.push(g),await n()})}catch(e){g.remove();let t=o.indexOf(g);throw t!==-1&&o.splice(t,1),e}let _=!1;function v(){if(_)return;_=!0,g.remove();let e=o.indexOf(g);e!==-1&&o.splice(e,1)}return{...a(g.shadowRoot??g),async act(e){await e(),await n()},async attr(e,t){c(g,e,t),await n()},async attrs(e){for(let[t,n]of Object.entries(e))c(g,t,n);await n()},dispose:v,get disposed(){return _},element:g,flush:n,get shadow(){return g.shadowRoot},[Symbol.dispose](){v()}}}async function f(e,n,r){return t(e,n),d(e,r)}function p(e,t=``){customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=t}})}function m(){for(let e of o)e.remove();o.length=0,r(),i()}export{o as _mountedElements,m as cleanup,p as mock,d as mount,f as mountComponent};
1
+ import{setAttr as e}from"../utils/dom.js";import{define as t}from"../define.js";import{flush as n}from"./flush.js";import{_disposeRenderHooks as r}from"./render-hook.js";import{resetOreForTests as i}from"./reset.js";import{within as a}from"@vielzeug/assay";var o=[],s=0;function c(t,n,r){e(t,n,r)}var l=e=>e instanceof Error?e:Error(String(e)),u=async e=>{if(typeof window>`u`)return e();let t=null,n=e=>{t=l(e.error??e.message),e.preventDefault()},r=e=>{t=l(e.reason),e.preventDefault()};window.addEventListener(`error`,n),window.addEventListener(`unhandledrejection`,r);try{let n=await e();if(t)throw t;return n}finally{window.removeEventListener(`error`,n),window.removeEventListener(`unhandledrejection`,r)}};async function d(e,r={}){let{attrs:i={},componentOptions:l,container:d=document.body,html:f,props:p={}}=r,m,h;typeof e==`string`?m=e:(m=`trial-${++s}`,h={...l??{},setup:e}),h&&t(m,h);let g=document.createElement(m);f&&(g.innerHTML=f),Object.keys(p).length&&Object.assign(g,p);for(let[e,t]of Object.entries(i))c(g,e,t);try{await u(async()=>{d.appendChild(g),o.push(g),await n()})}catch(e){g.remove();let t=o.indexOf(g);throw t!==-1&&o.splice(t,1),e}let _=!1;function v(){if(_)return;_=!0,g.remove();let e=o.indexOf(g);e!==-1&&o.splice(e,1)}return{...a(g.shadowRoot??g),async act(e){await e(),await n()},async attr(e,t){c(g,e,t),await n()},async attrs(e){for(let[t,n]of Object.entries(e))c(g,t,n);await n()},dispose:v,get disposed(){return _},element:g,flush:n,get shadow(){return g.shadowRoot},[Symbol.dispose](){v()}}}function f(){for(let e of o)e.remove();o.length=0,r(),i()}export{o as _mountedElements,f as cleanup,d as mount};
2
2
  //# sourceMappingURL=mount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mount.js","names":[],"sources":["../../src/testing/mount.ts"],"sourcesContent":["/**\n * Component mounting utilities for test environments.\n */\n\nimport { type QueryScope, within } from '@vielzeug/assay';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from '../component-types';\nimport { define } from '../define';\nimport type { HTMLResult } from '../template/result';\nimport { setAttr } from '../utils/dom';\nimport { type FlushOptions, flush } from './flush';\nimport { _disposeRenderHooks } from './render-hook';\nimport { resetOreForTests } from './reset';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n// Fixture inherits Assay's complete QueryScope. Keeping that relationship structural means new\n// scoped query capabilities are immediately available to fixtures without a duplicate contract.\n/**\n * A mounted component ready for assertions. All inherited `QueryScope` methods are scoped to\n * `element.shadowRoot`, falling back to `element` for light-DOM components (`shadow: false`).\n */\nexport interface Fixture<T extends HTMLElement = HTMLElement> extends QueryScope {\n /** Run a callback then flush — the standard way to trigger and assert a reactive update */\n act(fn: () => unknown): Promise<void>;\n /** Set an attribute (boolean `false` removes it) then flush */\n attr(name: string, value: string | number | boolean): Promise<void>;\n /** Set multiple attributes then flush */\n attrs(record: Record<string, string | number | boolean>): Promise<void>;\n /** Remove the component from the DOM. Idempotent. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** The component element */\n element: T;\n /** Wait for all reactive updates and animation frames */\n flush(options?: FlushOptions): Promise<void>;\n /** The component's shadow root (null for light-DOM components) */\n readonly shadow: ShadowRoot | null;\n /** Delegates to `dispose()`. Enables `using` declarations. */\n [Symbol.dispose](): void;\n}\n\nexport interface MountOptions {\n /** HTML attributes to set on the element */\n attrs?: Record<string, string | number | boolean>;\n /** Extra component options when passing an inline setup function */\n componentOptions?: Omit<ComponentDefinition<Record<string, unknown>>, 'setup'>;\n /** Parent container (default: document.body) */\n container?: HTMLElement | ShadowRoot;\n /** Inner HTML for slot content */\n html?: string;\n /** Properties assigned directly onto the element */\n props?: Record<string, unknown>;\n}\n\ntype MountProps = { readonly [x: string]: Readable<unknown> };\n\n// Bivariant callback type keeps inline test callbacks ergonomic across varying prop specializations.\nexport type MountSetup = {\n bivarianceHack: (props: MountProps) => HTMLResult | null;\n}['bivarianceHack'];\n\n// ─── Test environment state ───────────────────────────────────────────────────\n\nexport const _mountedElements: HTMLElement[] = [];\n\n// Monotonic across the whole test run — never reset: custom element registrations\n// are permanent, so a re-used tag name would throw on re-define. Deterministic\n// within a run (trial-1, trial-2, ...) without a random suffix.\nlet _componentTagCounter = 0;\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction applyAttr(element: Element, name: string, value: string | number | boolean): void {\n // Same write path as the runtime's attribute bindings, so tests never set up\n // states the runtime itself can't produce (e.g. boolean true → \"true\").\n setAttr(element, name, value);\n}\n\nconst toError = (value: unknown): Error => {\n return value instanceof Error ? value : new Error(String(value));\n};\n\nconst withWindowErrorCapture = async <T>(action: () => Promise<T>): Promise<T> => {\n if (typeof window === 'undefined') return action();\n\n let captured: Error | null = null;\n const onError = (event: ErrorEvent) => {\n captured = toError(event.error ?? event.message);\n event.preventDefault();\n };\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n captured = toError(event.reason);\n event.preventDefault();\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n try {\n const result = await action();\n\n if (captured) throw captured;\n\n return result;\n } finally {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n};\n\n// ─── API ─────────────────────────────────────────────────────────────────────\n\n/**\n * Mount a component into the DOM and return a test fixture.\n *\n * Accepts a registered tag name, an inline setup function, or a component\n * options object. Setup functions are auto-registered with generated tag names.\n *\n * @example — inline setup function\n * const { query } = await mount(() => {\n * const count = signal(0);\n * return html`<button @click=${() => count.value++}>${count}</button>`;\n * });\n *\n * @example — registered tag name\n * const { query } = await mount('my-counter');\n */\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: MountSetup,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string | MountSetup,\n options: MountOptions = {},\n): Promise<Fixture<T>> {\n const { attrs = {}, componentOptions, container = document.body, html, props = {} } = options;\n\n let tagName: string;\n let inlineDefinition: ComponentDefinition<Record<string, unknown>> | undefined;\n\n if (typeof tagOrSetup === 'string') {\n tagName = tagOrSetup;\n } else {\n tagName = `trial-${++_componentTagCounter}`;\n inlineDefinition = {\n ...(componentOptions ?? {}),\n setup: tagOrSetup,\n };\n }\n\n if (inlineDefinition) {\n define(tagName, inlineDefinition);\n }\n\n const element = document.createElement(tagName) as T;\n\n if (html) element.innerHTML = html;\n\n if (Object.keys(props).length) Object.assign(element, props);\n\n for (const [name, value] of Object.entries(attrs)) applyAttr(element, name, value);\n\n try {\n await withWindowErrorCapture(async () => {\n container.appendChild(element);\n _mountedElements.push(element);\n await flush();\n });\n } catch (err) {\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n\n throw err;\n }\n\n let isDisposed = false;\n\n function dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n }\n\n const scope = within((element.shadowRoot ?? element) as Element);\n\n return {\n ...scope,\n\n async act(fn) {\n await fn();\n await flush();\n },\n\n async attr(name, value) {\n applyAttr(element, name, value);\n await flush();\n },\n\n async attrs(record) {\n for (const [name, value] of Object.entries(record)) applyAttr(element, name, value);\n await flush();\n },\n\n dispose,\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n element,\n\n flush,\n\n get shadow(): ShadowRoot | null {\n return element.shadowRoot;\n },\n\n [Symbol.dispose]() {\n dispose();\n },\n };\n}\n\n/**\n * Register and mount a component definition in a single call.\n *\n * Combines `define(tag, definition)` + `mount(tag, options)` — the standard\n * pattern for testing full custom-element lifecycle (props, reconnect, etc.).\n *\n * @example\n * const { query } = await mountComponent('my-counter', {\n * props: { count: prop.number(0) },\n * setup: (props) => html`<div>${props.count}</div>`,\n * });\n */\nexport async function mountComponent<Props extends Record<string, unknown>, T extends HTMLElement = HTMLElement>(\n tag: string,\n definition: ComponentDefinition<Props>,\n options?: MountOptions,\n): Promise<Fixture<T>> {\n define(tag, definition);\n\n return mount<T>(tag, options);\n}\n\n/**\n * Register a stub custom element (no-op if already defined).\n *\n * @example\n * mock('child-button', '<slot></slot>');\n */\nexport function mock(tagName: string, template = ''): void {\n if (!customElements.get(tagName)) {\n customElements.define(\n tagName,\n class extends HTMLElement {\n connectedCallback() {\n this.innerHTML = template;\n }\n },\n );\n }\n}\n\n/**\n * Remove all elements mounted via `mount()`.\n * Call in `afterEach` to keep tests isolated.\n *\n * @example\n * afterEach(() => cleanup());\n */\nexport function cleanup(): void {\n for (const el of _mountedElements) el.remove();\n _mountedElements.length = 0;\n _disposeRenderHooks();\n resetOreForTests();\n}\n\n/** @internal re-export for within() */\nexport type { QueryScope };\n"],"mappings":"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"}
1
+ {"version":3,"file":"mount.js","names":[],"sources":["../../src/testing/mount.ts"],"sourcesContent":["/**\n * Component mounting utilities for test environments.\n */\n\nimport { type QueryScope, within } from '@vielzeug/assay';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from '../component-types';\nimport { define } from '../define';\nimport type { HTMLResult } from '../template/result';\nimport { setAttr } from '../utils/dom';\nimport { type FlushOptions, flush } from './flush';\nimport { _disposeRenderHooks } from './render-hook';\nimport { resetOreForTests } from './reset';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n// Fixture inherits Assay's complete QueryScope. Keeping that relationship structural means new\n// scoped query capabilities are immediately available to fixtures without a duplicate contract.\n/**\n * A mounted component ready for assertions. All inherited `QueryScope` methods are scoped to\n * `element.shadowRoot`, falling back to `element` for light-DOM components (`shadow: false`).\n */\nexport interface Fixture<T extends HTMLElement = HTMLElement> extends QueryScope {\n /** Run a callback then flush — the standard way to trigger and assert a reactive update */\n act(fn: () => unknown): Promise<void>;\n /** Set an attribute (boolean `false` removes it) then flush */\n attr(name: string, value: string | number | boolean): Promise<void>;\n /** Set multiple attributes then flush */\n attrs(record: Record<string, string | number | boolean>): Promise<void>;\n /** Remove the component from the DOM. Idempotent. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** The component element */\n element: T;\n /** Wait for all reactive updates and animation frames */\n flush(options?: FlushOptions): Promise<void>;\n /** The component's shadow root (null for light-DOM components) */\n readonly shadow: ShadowRoot | null;\n /** Delegates to `dispose()`. Enables `using` declarations. */\n [Symbol.dispose](): void;\n}\n\nexport interface MountOptions {\n /** HTML attributes to set on the element */\n attrs?: Record<string, string | number | boolean>;\n /** Extra component options when passing an inline setup function */\n componentOptions?: Omit<ComponentDefinition<Record<string, unknown>>, 'setup'>;\n /** Parent container (default: document.body) */\n container?: HTMLElement | ShadowRoot;\n /** Inner HTML for slot content */\n html?: string;\n /** Properties assigned directly onto the element */\n props?: Record<string, unknown>;\n}\n\ntype MountProps = { readonly [x: string]: Readable<unknown> };\n\n// Bivariant callback type keeps inline test callbacks ergonomic across varying prop specializations.\nexport type MountSetup = {\n bivarianceHack: (props: MountProps) => HTMLResult | null;\n}['bivarianceHack'];\n\n// ─── Test environment state ───────────────────────────────────────────────────\n\nexport const _mountedElements: HTMLElement[] = [];\n\n// Monotonic across the whole test run — never reset: custom element registrations\n// are permanent, so a re-used tag name would throw on re-define. Deterministic\n// within a run (trial-1, trial-2, ...) without a random suffix.\nlet _componentTagCounter = 0;\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction applyAttr(element: Element, name: string, value: string | number | boolean): void {\n // Same write path as the runtime's attribute bindings, so tests never set up\n // states the runtime itself can't produce (e.g. boolean true → \"true\").\n setAttr(element, name, value);\n}\n\nconst toError = (value: unknown): Error => {\n return value instanceof Error ? value : new Error(String(value));\n};\n\nconst withWindowErrorCapture = async <T>(action: () => Promise<T>): Promise<T> => {\n if (typeof window === 'undefined') return action();\n\n let captured: Error | null = null;\n const onError = (event: ErrorEvent) => {\n captured = toError(event.error ?? event.message);\n event.preventDefault();\n };\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n captured = toError(event.reason);\n event.preventDefault();\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n try {\n const result = await action();\n\n if (captured) throw captured;\n\n return result;\n } finally {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n};\n\n// ─── API ─────────────────────────────────────────────────────────────────────\n\n/**\n * Mount a component into the DOM and return a test fixture.\n *\n * Accepts a registered tag name, an inline setup function, or a component\n * options object. Setup functions are auto-registered with generated tag names.\n *\n * @example — inline setup function\n * const { query } = await mount(() => {\n * const count = signal(0);\n * return html`<button @click=${() => count.value++}>${count}</button>`;\n * });\n *\n * @example — registered tag name\n * const { query } = await mount('my-counter');\n */\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: MountSetup,\n options?: MountOptions,\n): Promise<Fixture<T>>;\nexport async function mount<T extends HTMLElement = HTMLElement>(\n tagOrSetup: string | MountSetup,\n options: MountOptions = {},\n): Promise<Fixture<T>> {\n const { attrs = {}, componentOptions, container = document.body, html, props = {} } = options;\n\n let tagName: string;\n let inlineDefinition: ComponentDefinition<Record<string, unknown>> | undefined;\n\n if (typeof tagOrSetup === 'string') {\n tagName = tagOrSetup;\n } else {\n tagName = `trial-${++_componentTagCounter}`;\n inlineDefinition = {\n ...(componentOptions ?? {}),\n setup: tagOrSetup,\n };\n }\n\n if (inlineDefinition) {\n define(tagName, inlineDefinition);\n }\n\n const element = document.createElement(tagName) as T;\n\n if (html) element.innerHTML = html;\n\n if (Object.keys(props).length) Object.assign(element, props);\n\n for (const [name, value] of Object.entries(attrs)) applyAttr(element, name, value);\n\n try {\n await withWindowErrorCapture(async () => {\n container.appendChild(element);\n _mountedElements.push(element);\n await flush();\n });\n } catch (err) {\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n\n throw err;\n }\n\n let isDisposed = false;\n\n function dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n element.remove();\n\n const i = _mountedElements.indexOf(element);\n\n if (i !== -1) _mountedElements.splice(i, 1);\n }\n\n const scope = within((element.shadowRoot ?? element) as Element);\n\n return {\n ...scope,\n\n async act(fn) {\n await fn();\n await flush();\n },\n\n async attr(name, value) {\n applyAttr(element, name, value);\n await flush();\n },\n\n async attrs(record) {\n for (const [name, value] of Object.entries(record)) applyAttr(element, name, value);\n await flush();\n },\n\n dispose,\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n element,\n\n flush,\n\n get shadow(): ShadowRoot | null {\n return element.shadowRoot;\n },\n\n [Symbol.dispose]() {\n dispose();\n },\n };\n}\n\n/**\n * Remove all elements mounted via `mount()`.\n * Call in `afterEach` to keep tests isolated.\n *\n * @example\n * afterEach(() => cleanup());\n */\nexport function cleanup(): void {\n for (const el of _mountedElements) el.remove();\n _mountedElements.length = 0;\n _disposeRenderHooks();\n resetOreForTests();\n}\n\n/** @internal re-export for within() */\nexport type { QueryScope };\n"],"mappings":"iQAkEA,IAAa,EAAkC,CAAC,EAK5C,EAAuB,EAI3B,SAAS,EAAU,EAAkB,EAAc,EAAwC,CAGzF,EAAQ,EAAS,EAAM,CAAK,CAC9B,CAEA,IAAM,EAAW,GACR,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,EAG3D,EAAyB,KAAU,IAAyC,CAChF,GAAI,OAAO,OAAW,IAAa,OAAO,EAAO,EAEjD,IAAI,EAAyB,KACvB,EAAW,GAAsB,CACrC,EAAW,EAAQ,EAAM,OAAS,EAAM,OAAO,EAC/C,EAAM,eAAe,CACvB,EACM,EAAwB,GAAiC,CAC7D,EAAW,EAAQ,EAAM,MAAM,EAC/B,EAAM,eAAe,CACvB,EAEA,OAAO,iBAAiB,QAAS,CAAO,EACxC,OAAO,iBAAiB,qBAAsB,CAAoB,EAElE,GAAI,CACF,IAAM,EAAS,MAAM,EAAO,EAE5B,GAAI,EAAU,MAAM,EAEpB,OAAO,CACT,QAAU,CACR,OAAO,oBAAoB,QAAS,CAAO,EAC3C,OAAO,oBAAoB,qBAAsB,CAAoB,CACvE,CACF,EA2BA,eAAsB,EACpB,EACA,EAAwB,CAAC,EACJ,CACrB,GAAM,CAAE,QAAQ,CAAC,EAAG,mBAAkB,YAAY,SAAS,KAAM,OAAM,QAAQ,CAAC,GAAM,EAElF,EACA,EAEA,OAAO,GAAe,SACxB,EAAU,GAEV,EAAU,SAAS,EAAE,IACrB,EAAmB,CACjB,GAAI,GAAoB,CAAC,EACzB,MAAO,CACT,GAGE,GACF,EAAO,EAAS,CAAgB,EAGlC,IAAM,EAAU,SAAS,cAAc,CAAO,EAE1C,IAAM,EAAQ,UAAY,GAE1B,OAAO,KAAK,CAAK,CAAC,CAAC,QAAQ,OAAO,OAAO,EAAS,CAAK,EAE3D,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,CAAK,EAAG,EAAU,EAAS,EAAM,CAAK,EAEjF,GAAI,CACF,MAAM,EAAuB,SAAY,CACvC,EAAU,YAAY,CAAO,EAC7B,EAAiB,KAAK,CAAO,EAC7B,MAAM,EAAM,CACd,CAAC,CACH,OAAS,EAAK,CACZ,EAAQ,OAAO,EAEf,IAAM,EAAI,EAAiB,QAAQ,CAAO,EAI1C,MAFI,IAAM,IAAI,EAAiB,OAAO,EAAG,CAAC,EAEpC,CACR,CAEA,IAAI,EAAa,GAEjB,SAAS,GAAU,CACjB,GAAI,EAAY,OAEhB,EAAa,GACb,EAAQ,OAAO,EAEf,IAAM,EAAI,EAAiB,QAAQ,CAAO,EAEtC,IAAM,IAAI,EAAiB,OAAO,EAAG,CAAC,CAC5C,CAIA,MAAO,CACL,GAHY,EAAQ,EAAQ,YAAc,CAGvC,EAEH,MAAM,IAAI,EAAI,CACZ,MAAM,EAAG,EACT,MAAM,EAAM,CACd,EAEA,MAAM,KAAK,EAAM,EAAO,CACtB,EAAU,EAAS,EAAM,CAAK,EAC9B,MAAM,EAAM,CACd,EAEA,MAAM,MAAM,EAAQ,CAClB,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,CAAM,EAAG,EAAU,EAAS,EAAM,CAAK,EAClF,MAAM,EAAM,CACd,EAEA,UAEA,IAAI,UAAoB,CACtB,OAAO,CACT,EAEA,UAEA,QAEA,IAAI,QAA4B,CAC9B,OAAO,EAAQ,UACjB,EAEA,CAAC,OAAO,UAAW,CACjB,EAAQ,CACV,CACF,CACF,CASA,SAAgB,GAAgB,CAC9B,IAAK,IAAM,KAAM,EAAkB,EAAG,OAAO,EAC7C,EAAiB,OAAS,EAC1B,EAAoB,EACpB,EAAiB,CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"reset.cjs","names":[],"sources":["../../src/testing/reset.ts"],"sourcesContent":["/**\n * One honest entry point for cross-test isolation. Replaces the collection of\n * `_`-private reset functions the test harness used to import from individual\n * modules — those stay private to their modules; this is the supported seam.\n */\n\nimport { _clearStylesheetCache } from '../utils/css';\nimport { _resetIdCounter } from '../utils/id';\n\n/**\n * Reset every piece of global ore state a test can touch: the stylesheet cache\n * and both ID counters. Called by `cleanup()` — call it directly only if you\n * manage mounted elements yourself.\n */\nexport const resetOreForTests = (): void => {\n _clearStylesheetCache();\n _resetIdCounter();\n};\n"],"mappings":"iEAcA,IAAa,MAA+B,CAC1C,EAAA,sBAAsB,EACtB,EAAA,gBAAgB,CAClB"}
1
+ {"version":3,"file":"reset.cjs","names":[],"sources":["../../src/testing/reset.ts"],"sourcesContent":["/**\n * One honest entry point for cross-test isolation. Replaces the collection of\n * `_`-private reset functions the test harness used to import from individual\n * modules — those stay private to their modules; this is the supported seam.\n */\n\nimport { _clearStylesheetCache } from '../utils/css';\nimport { _resetIdCounter } from '../utils/id';\n\n/**\n * Reset every piece of global ore state a test can touch: the stylesheet cache\n * and the ID counter. Called by `cleanup()` — call it directly only if you\n * manage mounted elements yourself.\n */\nexport const resetOreForTests = (): void => {\n _clearStylesheetCache();\n _resetIdCounter();\n};\n"],"mappings":"iEAcA,IAAa,MAA+B,CAC1C,EAAA,sBAAsB,EACtB,EAAA,gBAAgB,CAClB"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /**
7
7
  * Reset every piece of global ore state a test can touch: the stylesheet cache
8
- * and both ID counters. Called by `cleanup()` — call it directly only if you
8
+ * and the ID counter. Called by `cleanup()` — call it directly only if you
9
9
  * manage mounted elements yourself.
10
10
  */
11
11
  export declare const resetOreForTests: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"reset.js","names":[],"sources":["../../src/testing/reset.ts"],"sourcesContent":["/**\n * One honest entry point for cross-test isolation. Replaces the collection of\n * `_`-private reset functions the test harness used to import from individual\n * modules — those stay private to their modules; this is the supported seam.\n */\n\nimport { _clearStylesheetCache } from '../utils/css';\nimport { _resetIdCounter } from '../utils/id';\n\n/**\n * Reset every piece of global ore state a test can touch: the stylesheet cache\n * and both ID counters. Called by `cleanup()` — call it directly only if you\n * manage mounted elements yourself.\n */\nexport const resetOreForTests = (): void => {\n _clearStylesheetCache();\n _resetIdCounter();\n};\n"],"mappings":"yGAcA,IAAa,MAA+B,CAC1C,EAAsB,EACtB,EAAgB,CAClB"}
1
+ {"version":3,"file":"reset.js","names":[],"sources":["../../src/testing/reset.ts"],"sourcesContent":["/**\n * One honest entry point for cross-test isolation. Replaces the collection of\n * `_`-private reset functions the test harness used to import from individual\n * modules — those stay private to their modules; this is the supported seam.\n */\n\nimport { _clearStylesheetCache } from '../utils/css';\nimport { _resetIdCounter } from '../utils/id';\n\n/**\n * Reset every piece of global ore state a test can touch: the stylesheet cache\n * and the ID counter. Called by `cleanup()` — call it directly only if you\n * manage mounted elements yourself.\n */\nexport const resetOreForTests = (): void => {\n _clearStylesheetCache();\n _resetIdCounter();\n};\n"],"mappings":"yGAcA,IAAa,MAA+B,CAC1C,EAAsB,EACtB,EAAgB,CAClB"}
package/dist/testing.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./testing/dom.cjs"),t=require("./testing/form-internals-polyfill.cjs"),n=require("./testing/flush.cjs"),r=require("./testing/render-hook.cjs"),i=require("./testing/reset.cjs"),a=require("./testing/mount.cjs");function o(e,n={}){e(a.cleanup),n.formInternals&&t.installFormInternalsPolyfill()}exports.OreTimeoutError=n.OreTimeoutError,exports.cleanup=a.cleanup,exports.debugFlush=n.debugFlush,exports.flush=n.flush,exports.install=o,exports.installFormInternalsPolyfill=t.installFormInternalsPolyfill,exports.mock=a.mock,exports.mount=a.mount,exports.mountComponent=a.mountComponent,exports.renderHook=r.renderHook,exports.resetOreForTests=i.resetOreForTests,exports.walkFlatTree=e.walkFlatTree;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./testing/form-internals-polyfill.cjs"),t=require("./testing/flush.cjs"),n=require("./testing/render-hook.cjs"),r=require("./testing/mount.cjs");function i(t,n={}){t(r.cleanup),n.formInternals&&e.installFormInternalsPolyfill()}exports.OreTimeoutError=t.OreTimeoutError,exports.cleanup=r.cleanup,exports.flush=t.flush,exports.install=i,exports.installFormInternalsPolyfill=e.installFormInternalsPolyfill,exports.mount=r.mount,exports.renderHook=n.renderHook;
2
2
  //# sourceMappingURL=testing.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.cjs","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for Ore components\n *\n * ⚠️ Requires DOM environment (browser / jsdom / happy-dom)\n *\n * This barrel re-exports the full testing API for convenience.\n * For tree-shaking, import directly from the focused sub-modules.\n */\n\nimport { installFormInternalsPolyfill } from './form-internals-polyfill';\nimport { cleanup } from './mount';\n\n// Testing-only error: flush() is its only thrower in this package (a pending-work timeout —\n// see flush.ts). Exported here (not from the main `.` entry) so components with no interest\n// in the testing sub-path don't carry a testing-only error class in their public type surface.\n// Generic DOM interaction helpers belong to @vielzeug/assay, not this Ore-specific test API.\nexport { walkFlatTree } from './dom';\nexport { debugFlush, type FlushOptions, flush, OreTimeoutError } from './flush';\nexport { installFormInternalsPolyfill } from './form-internals-polyfill';\nexport { cleanup, type Fixture, type MountOptions, type MountSetup, mock, mount, mountComponent } from './mount';\nexport { type HookFixture, renderHook } from './render-hook';\nexport { resetOreForTests } from './reset';\n\nexport type InstallOptions = {\n /**\n * Polyfill the jsdom/happy-dom gaps in `ElementInternals`/`FormData`/`<form>.reset()`\n * that `useField()` needs (see `installFormInternalsPolyfill`). Global monkey-patches,\n * so opt in only when the suite tests form-associated components.\n * @default false\n */\n formInternals?: boolean;\n};\n\n/**\n * Register auto-cleanup after each test. Call once in your test setup file.\n * Pass `{ formInternals: true }` when testing form-associated (`useField`) components.\n *\n * @example\n * // vitest.setup.ts\n * import { afterEach } from 'vitest';\n * import { install } from '@vielzeug/ore/testing';\n * install(afterEach, { formInternals: true });\n */\nexport function install(afterEachHook: (fn: () => void) => void, options: InstallOptions = {}): void {\n afterEachHook(cleanup);\n\n if (options.formInternals) installFormInternalsPolyfill();\n}\n"],"mappings":"qSA2CA,SAAgB,EAAQ,EAAyC,EAA0B,CAAC,EAAS,CACnG,EAAc,EAAA,OAAO,EAEjB,EAAQ,eAAe,EAAA,6BAA6B,CAC1D"}
1
+ {"version":3,"file":"testing.cjs","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for Ore components\n *\n * ⚠️ Requires DOM environment (browser / jsdom / happy-dom)\n *\n * This is the package's only public testing entry point.\n */\n\nimport { installFormInternalsPolyfill } from './form-internals-polyfill';\nimport { cleanup } from './mount';\n\n// Testing-only error: flush() is its only thrower in this package (a pending-work timeout —\n// see flush.ts). Exported here (not from the main `.` entry) so components with no interest\n// in the testing sub-path don't carry a testing-only error class in their public type surface.\n// Generic DOM interaction helpers belong to @vielzeug/assay, not this Ore-specific test API.\nexport { type FlushOptions, flush, OreTimeoutError } from './flush';\nexport { installFormInternalsPolyfill } from './form-internals-polyfill';\nexport { cleanup, type Fixture, type MountOptions, type MountSetup, mount } from './mount';\nexport { type HookFixture, renderHook } from './render-hook';\n\nexport type InstallOptions = {\n /**\n * Polyfill the jsdom/happy-dom gaps in `ElementInternals`/`FormData`/`<form>.reset()`\n * that `useField()` needs (see `installFormInternalsPolyfill`). Global monkey-patches,\n * so opt in only when the suite tests form-associated components.\n * @default false\n */\n formInternals?: boolean;\n};\n\n/**\n * Register auto-cleanup after each test. Call once in your test setup file.\n * Pass `{ formInternals: true }` when testing form-associated (`useField`) components.\n *\n * @example\n * // vitest.setup.ts\n * import { afterEach } from 'vitest';\n * import { install } from '@vielzeug/ore/testing';\n * install(afterEach, { formInternals: true });\n */\nexport function install(afterEachHook: (fn: () => void) => void, options: InstallOptions = {}): void {\n afterEachHook(cleanup);\n\n if (options.formInternals) installFormInternalsPolyfill();\n}\n"],"mappings":"qOAwCA,SAAgB,EAAQ,EAAyC,EAA0B,CAAC,EAAS,CACnG,EAAc,EAAA,OAAO,EAEjB,EAAQ,eAAe,EAAA,6BAA6B,CAC1D"}
package/dist/testing.js CHANGED
@@ -1,2 +1,2 @@
1
- import{walkFlatTree as e}from"./testing/dom.js";import{installFormInternalsPolyfill as t}from"./testing/form-internals-polyfill.js";import{OreTimeoutError as n,debugFlush as r,flush as i}from"./testing/flush.js";import{renderHook as a}from"./testing/render-hook.js";import{resetOreForTests as o}from"./testing/reset.js";import{cleanup as s,mock as c,mount as l,mountComponent as u}from"./testing/mount.js";function d(e,n={}){e(s),n.formInternals&&t()}export{n as OreTimeoutError,s as cleanup,r as debugFlush,i as flush,d as install,t as installFormInternalsPolyfill,c as mock,l as mount,u as mountComponent,a as renderHook,o as resetOreForTests,e as walkFlatTree};
1
+ import{installFormInternalsPolyfill as e}from"./testing/form-internals-polyfill.js";import{OreTimeoutError as t,flush as n}from"./testing/flush.js";import{renderHook as r}from"./testing/render-hook.js";import{cleanup as i,mount as a}from"./testing/mount.js";function o(t,n={}){t(i),n.formInternals&&e()}export{t as OreTimeoutError,i as cleanup,n as flush,o as install,e as installFormInternalsPolyfill,a as mount,r as renderHook};
2
2
  //# sourceMappingURL=testing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for Ore components\n *\n * ⚠️ Requires DOM environment (browser / jsdom / happy-dom)\n *\n * This barrel re-exports the full testing API for convenience.\n * For tree-shaking, import directly from the focused sub-modules.\n */\n\nimport { installFormInternalsPolyfill } from './form-internals-polyfill';\nimport { cleanup } from './mount';\n\n// Testing-only error: flush() is its only thrower in this package (a pending-work timeout —\n// see flush.ts). Exported here (not from the main `.` entry) so components with no interest\n// in the testing sub-path don't carry a testing-only error class in their public type surface.\n// Generic DOM interaction helpers belong to @vielzeug/assay, not this Ore-specific test API.\nexport { walkFlatTree } from './dom';\nexport { debugFlush, type FlushOptions, flush, OreTimeoutError } from './flush';\nexport { installFormInternalsPolyfill } from './form-internals-polyfill';\nexport { cleanup, type Fixture, type MountOptions, type MountSetup, mock, mount, mountComponent } from './mount';\nexport { type HookFixture, renderHook } from './render-hook';\nexport { resetOreForTests } from './reset';\n\nexport type InstallOptions = {\n /**\n * Polyfill the jsdom/happy-dom gaps in `ElementInternals`/`FormData`/`<form>.reset()`\n * that `useField()` needs (see `installFormInternalsPolyfill`). Global monkey-patches,\n * so opt in only when the suite tests form-associated components.\n * @default false\n */\n formInternals?: boolean;\n};\n\n/**\n * Register auto-cleanup after each test. Call once in your test setup file.\n * Pass `{ formInternals: true }` when testing form-associated (`useField`) components.\n *\n * @example\n * // vitest.setup.ts\n * import { afterEach } from 'vitest';\n * import { install } from '@vielzeug/ore/testing';\n * install(afterEach, { formInternals: true });\n */\nexport function install(afterEachHook: (fn: () => void) => void, options: InstallOptions = {}): void {\n afterEachHook(cleanup);\n\n if (options.formInternals) installFormInternalsPolyfill();\n}\n"],"mappings":"sZA2CA,SAAgB,EAAQ,EAAyC,EAA0B,CAAC,EAAS,CACnG,EAAc,CAAO,EAEjB,EAAQ,eAAe,EAA6B,CAC1D"}
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for Ore components\n *\n * ⚠️ Requires DOM environment (browser / jsdom / happy-dom)\n *\n * This is the package's only public testing entry point.\n */\n\nimport { installFormInternalsPolyfill } from './form-internals-polyfill';\nimport { cleanup } from './mount';\n\n// Testing-only error: flush() is its only thrower in this package (a pending-work timeout —\n// see flush.ts). Exported here (not from the main `.` entry) so components with no interest\n// in the testing sub-path don't carry a testing-only error class in their public type surface.\n// Generic DOM interaction helpers belong to @vielzeug/assay, not this Ore-specific test API.\nexport { type FlushOptions, flush, OreTimeoutError } from './flush';\nexport { installFormInternalsPolyfill } from './form-internals-polyfill';\nexport { cleanup, type Fixture, type MountOptions, type MountSetup, mount } from './mount';\nexport { type HookFixture, renderHook } from './render-hook';\n\nexport type InstallOptions = {\n /**\n * Polyfill the jsdom/happy-dom gaps in `ElementInternals`/`FormData`/`<form>.reset()`\n * that `useField()` needs (see `installFormInternalsPolyfill`). Global monkey-patches,\n * so opt in only when the suite tests form-associated components.\n * @default false\n */\n formInternals?: boolean;\n};\n\n/**\n * Register auto-cleanup after each test. Call once in your test setup file.\n * Pass `{ formInternals: true }` when testing form-associated (`useField`) components.\n *\n * @example\n * // vitest.setup.ts\n * import { afterEach } from 'vitest';\n * import { install } from '@vielzeug/ore/testing';\n * install(afterEach, { formInternals: true });\n */\nexport function install(afterEachHook: (fn: () => void) => void, options: InstallOptions = {}): void {\n afterEachHook(cleanup);\n\n if (options.formInternals) installFormInternalsPolyfill();\n}\n"],"mappings":"kQAwCA,SAAgB,EAAQ,EAAyC,EAA0B,CAAC,EAAS,CACnG,EAAc,CAAO,EAEjB,EAAQ,eAAe,EAA6B,CAC1D"}
@@ -1,2 +1,2 @@
1
- var e=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:`aria-${e}`,t=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:e;exports.normalizeAriaKey=e,exports.normalizeHostAttrKey=t;
1
+ var e=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:e;exports.normalizeHostAttrKey=e;
2
2
  //# sourceMappingURL=aria.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"aria.cjs","names":[],"sources":["../../src/utils/aria.ts"],"sourcesContent":["/**\n * Shared ARIA attribute key normalisation helpers.\n *\n * Two flavours are needed across the codebase:\n *\n * - `normalizeAriaKey` — always adds the `aria-` prefix for non-role keys.\n * Used by `aria()` and `bind({ aria: ... })`, where every config key is an ARIA attribute.\n *\n * - `normalizeHostAttrKey` — passes non-ARIA keys through unchanged.\n * Used by `host.bind({ attr: ... })` where keys may be arbitrary HTML attributes.\n */\n\n/** Normalise an aria config key to a full `aria-*` attribute name. */\nexport const normalizeAriaKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', 'expanded' → 'aria-expanded'\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : `aria-${key}`;\n};\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n"],"mappings":"AAaA,IAAa,EAAoB,GAC3B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM,QAAQ,IAIpE,EAAwB,GAC/B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM"}
1
+ {"version":3,"file":"aria.cjs","names":[],"sources":["../../src/utils/aria.ts"],"sourcesContent":["/** Host attribute key normalization. */\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n"],"mappings":"AAGA,IAAa,EAAwB,GAC/B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM"}
@@ -1,16 +1,4 @@
1
- /**
2
- * Shared ARIA attribute key normalisation helpers.
3
- *
4
- * Two flavours are needed across the codebase:
5
- *
6
- * - `normalizeAriaKey` — always adds the `aria-` prefix for non-role keys.
7
- * Used by `aria()` and `bind({ aria: ... })`, where every config key is an ARIA attribute.
8
- *
9
- * - `normalizeHostAttrKey` — passes non-ARIA keys through unchanged.
10
- * Used by `host.bind({ attr: ... })` where keys may be arbitrary HTML attributes.
11
- */
12
- /** Normalise an aria config key to a full `aria-*` attribute name. */
13
- export declare const normalizeAriaKey: (key: string) => string;
1
+ /** Host attribute key normalization. */
14
2
  /** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */
15
3
  export declare const normalizeHostAttrKey: (key: string) => string;
16
4
  //# sourceMappingURL=aria.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aria.d.ts","sourceRoot":"","sources":["../../src/utils/aria.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,MAK9C,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,KAAG,MAKlD,CAAC"}
1
+ {"version":3,"file":"aria.d.ts","sourceRoot":"","sources":["../../src/utils/aria.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,iGAAiG;AACjG,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,KAAG,MAKlD,CAAC"}
@@ -1,2 +1,2 @@
1
- var e=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:`aria-${e}`,t=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:e;export{e as normalizeAriaKey,t as normalizeHostAttrKey};
1
+ var e=e=>e===`role`||e.startsWith(`aria-`)?e:e.startsWith(`aria`)?`aria-${e.slice(4).toLowerCase()}`:e;export{e as normalizeHostAttrKey};
2
2
  //# sourceMappingURL=aria.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"aria.js","names":[],"sources":["../../src/utils/aria.ts"],"sourcesContent":["/**\n * Shared ARIA attribute key normalisation helpers.\n *\n * Two flavours are needed across the codebase:\n *\n * - `normalizeAriaKey` — always adds the `aria-` prefix for non-role keys.\n * Used by `aria()` and `bind({ aria: ... })`, where every config key is an ARIA attribute.\n *\n * - `normalizeHostAttrKey` — passes non-ARIA keys through unchanged.\n * Used by `host.bind({ attr: ... })` where keys may be arbitrary HTML attributes.\n */\n\n/** Normalise an aria config key to a full `aria-*` attribute name. */\nexport const normalizeAriaKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', 'expanded' → 'aria-expanded'\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : `aria-${key}`;\n};\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n"],"mappings":"AAaA,IAAa,EAAoB,GAC3B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM,QAAQ,IAIpE,EAAwB,GAC/B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM"}
1
+ {"version":3,"file":"aria.js","names":[],"sources":["../../src/utils/aria.ts"],"sourcesContent":["/** Host attribute key normalization. */\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n"],"mappings":"AAGA,IAAa,EAAwB,GAC/B,IAAQ,QAAU,EAAI,WAAW,OAAO,EAAU,EAG/C,EAAI,WAAW,MAAM,EAAI,QAAQ,EAAI,MAAM,CAAC,CAAC,CAAC,YAAY,IAAM"}
package/dist/utils/id.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=0,t=0,n=Math.random().toString(36).slice(2,6),r=()=>{e=0,t=0},i=(t=`id`)=>`${t}-${++e}`,a=(e=`id`)=>`${e}-${n}${++t}`,o=()=>{t=0};exports._resetIdCounter=r,exports.createId=i,exports.createStableId=a,exports.resetStableIdCounter=o;
1
+ var e=0,t=Math.random().toString(36).slice(2,6),n=()=>{e=0},r=(n=`id`)=>`${n}-${t}${++e}`;exports._resetIdCounter=n,exports.createId=r;
2
2
  //# sourceMappingURL=id.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"id.cjs","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["/**\n * Unique ID generation for runtime use (component IDs, label associations, etc.).\n * Template binding no longer uses this for marker IDs — binding targets are resolved\n * via path navigation on cloned template nodes.\n */\n\nlet _idCounter = 0;\nlet _stableCounter = 0;\nconst _tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Resets both ID counters. Called by testing cleanup(). */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n _stableCounter = 0;\n};\n\n/**\n * Generates a monotonically-increasing, unique-within-this-process ID with an optional prefix.\n * No public reset — this is for uniqueness, not cross-test determinism; use `createStableId()`\n * (and `resetStableIdCounter()`) when a test needs IDs to restart from the same value each run.\n */\nexport const createId = (prefix = 'id'): string => `${prefix}-${++_idCounter}`;\n\n/**\n * Generates a stable, unique ID with an optional semantic prefix.\n * Includes a short random tag to prevent collisions across multiple app instances.\n * Format: `${prefix}-${tag}${counter}` — e.g. `field-a3k21`.\n */\nexport const createStableId = (prefix = 'id'): string => `${prefix}-${_tag}${++_stableCounter}`;\n\n/**\n * Resets the `createStableId()` counter to 0. Use in test `beforeEach` hooks when you need\n * deterministic IDs across test runs.\n *\n * Named to match `createStableId()` precisely — `createId()` has no public reset (it's meant\n * for non-deterministic, monotonically-unique IDs; nothing in the package relies on it\n * restarting from a fixed value across tests).\n */\nexport const resetStableIdCounter = (): void => {\n _stableCounter = 0;\n};\n"],"mappings":"AAMA,IAAI,EAAa,EACb,EAAiB,EACf,EAAO,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAG,CAAC,EAGrC,MAA8B,CACzC,EAAa,EACb,EAAiB,CACnB,EAOa,GAAY,EAAS,OAAiB,GAAG,EAAO,GAAG,EAAE,IAOrD,GAAkB,EAAS,OAAiB,GAAG,EAAO,GAAG,IAAO,EAAE,IAUlE,MAAmC,CAC9C,EAAiB,CACnB"}
1
+ {"version":3,"file":"id.cjs","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["/** Unique ID generation for component and ARIA relationships. */\n\nlet counter = 0;\nconst tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Reset by the testing cleanup path. */\nexport const _resetIdCounter = (): void => {\n counter = 0;\n};\n\n/** Generate a collision-resistant ID with an optional semantic prefix. */\nexport const createId = (prefix = 'id'): string => `${prefix}-${tag}${++counter}`;\n"],"mappings":"AAEA,IAAI,EAAU,EACR,EAAM,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAG,CAAC,EAGpC,MAA8B,CACzC,EAAU,CACZ,EAGa,GAAY,EAAS,OAAiB,GAAG,EAAO,GAAG,IAAM,EAAE"}
@@ -1,27 +1,4 @@
1
- /**
2
- * Unique ID generation for runtime use (component IDs, label associations, etc.).
3
- * Template binding no longer uses this for marker IDs — binding targets are resolved
4
- * via path navigation on cloned template nodes.
5
- */
6
- /**
7
- * Generates a monotonically-increasing, unique-within-this-process ID with an optional prefix.
8
- * No public reset — this is for uniqueness, not cross-test determinism; use `createStableId()`
9
- * (and `resetStableIdCounter()`) when a test needs IDs to restart from the same value each run.
10
- */
1
+ /** Unique ID generation for component and ARIA relationships. */
2
+ /** Generate a collision-resistant ID with an optional semantic prefix. */
11
3
  export declare const createId: (prefix?: string) => string;
12
- /**
13
- * Generates a stable, unique ID with an optional semantic prefix.
14
- * Includes a short random tag to prevent collisions across multiple app instances.
15
- * Format: `${prefix}-${tag}${counter}` — e.g. `field-a3k21`.
16
- */
17
- export declare const createStableId: (prefix?: string) => string;
18
- /**
19
- * Resets the `createStableId()` counter to 0. Use in test `beforeEach` hooks when you need
20
- * deterministic IDs across test runs.
21
- *
22
- * Named to match `createStableId()` precisely — `createId()` has no public reset (it's meant
23
- * for non-deterministic, monotonically-unique IDs; nothing in the package relies on it
24
- * restarting from a fixed value across tests).
25
- */
26
- export declare const resetStableIdCounter: () => void;
27
4
  //# sourceMappingURL=id.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,eAAa,KAAG,MAAqC,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,eAAa,KAAG,MAAgD,CAAC;AAEhG;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,QAAO,IAEvC,CAAC"}
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAUjE,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,GAAI,eAAa,KAAG,MAAwC,CAAC"}
package/dist/utils/id.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=0,t=0,n=Math.random().toString(36).slice(2,6),r=()=>{e=0,t=0},i=(t=`id`)=>`${t}-${++e}`,a=(e=`id`)=>`${e}-${n}${++t}`,o=()=>{t=0};export{r as _resetIdCounter,i as createId,a as createStableId,o as resetStableIdCounter};
1
+ var e=0,t=Math.random().toString(36).slice(2,6),n=()=>{e=0},r=(n=`id`)=>`${n}-${t}${++e}`;export{n as _resetIdCounter,r as createId};
2
2
  //# sourceMappingURL=id.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"id.js","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["/**\n * Unique ID generation for runtime use (component IDs, label associations, etc.).\n * Template binding no longer uses this for marker IDs — binding targets are resolved\n * via path navigation on cloned template nodes.\n */\n\nlet _idCounter = 0;\nlet _stableCounter = 0;\nconst _tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Resets both ID counters. Called by testing cleanup(). */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n _stableCounter = 0;\n};\n\n/**\n * Generates a monotonically-increasing, unique-within-this-process ID with an optional prefix.\n * No public reset — this is for uniqueness, not cross-test determinism; use `createStableId()`\n * (and `resetStableIdCounter()`) when a test needs IDs to restart from the same value each run.\n */\nexport const createId = (prefix = 'id'): string => `${prefix}-${++_idCounter}`;\n\n/**\n * Generates a stable, unique ID with an optional semantic prefix.\n * Includes a short random tag to prevent collisions across multiple app instances.\n * Format: `${prefix}-${tag}${counter}` — e.g. `field-a3k21`.\n */\nexport const createStableId = (prefix = 'id'): string => `${prefix}-${_tag}${++_stableCounter}`;\n\n/**\n * Resets the `createStableId()` counter to 0. Use in test `beforeEach` hooks when you need\n * deterministic IDs across test runs.\n *\n * Named to match `createStableId()` precisely — `createId()` has no public reset (it's meant\n * for non-deterministic, monotonically-unique IDs; nothing in the package relies on it\n * restarting from a fixed value across tests).\n */\nexport const resetStableIdCounter = (): void => {\n _stableCounter = 0;\n};\n"],"mappings":"AAMA,IAAI,EAAa,EACb,EAAiB,EACf,EAAO,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAG,CAAC,EAGrC,MAA8B,CACzC,EAAa,EACb,EAAiB,CACnB,EAOa,GAAY,EAAS,OAAiB,GAAG,EAAO,GAAG,EAAE,IAOrD,GAAkB,EAAS,OAAiB,GAAG,EAAO,GAAG,IAAO,EAAE,IAUlE,MAAmC,CAC9C,EAAiB,CACnB"}
1
+ {"version":3,"file":"id.js","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["/** Unique ID generation for component and ARIA relationships. */\n\nlet counter = 0;\nconst tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Reset by the testing cleanup path. */\nexport const _resetIdCounter = (): void => {\n counter = 0;\n};\n\n/** Generate a collision-resistant ID with an optional semantic prefix. */\nexport const createId = (prefix = 'id'): string => `${prefix}-${tag}${++counter}`;\n"],"mappings":"AAEA,IAAI,EAAU,EACR,EAAM,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAG,CAAC,EAGpC,MAA8B,CACzC,EAAU,CACZ,EAGa,GAAY,EAAS,OAAiB,GAAG,EAAO,GAAG,IAAM,EAAE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vielzeug/ore",
3
- "version": "2.2.0",
4
- "description": "Custom element authoring primitives — reactive templates, signals, slots, and automatic lifecycle management",
3
+ "version": "3.0.1",
4
+ "description": "Functional web-component authoring on top of ripple",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/helmuthdu/vielzeug",
@@ -42,19 +42,19 @@
42
42
  "registry": "https://registry.npmjs.org/"
43
43
  },
44
44
  "scripts": {
45
- "build": "vite build && pnpm run build:bundle && pnpm run build:types",
45
+ "build": "vite build && pnpm --silent run build:bundle && pnpm --silent run build:types",
46
46
  "build:bundle": "vite build --config vite.bundle.config.ts",
47
47
  "build:types": "tsc -p tsconfig.declarations.json",
48
48
  "fix": "biome check --write src vitest.setup.ts",
49
49
  "lint": "biome ci src vitest.setup.ts",
50
- "prepublishOnly": "pnpm run build",
50
+ "prepublishOnly": "pnpm --silent run build",
51
51
  "preview": "vite preview",
52
52
  "test": "vitest",
53
53
  "test:types": "tsc -p tsconfig.json --noEmit"
54
54
  },
55
55
  "peerDependencies": {
56
- "@vielzeug/assay": "^2.2.0",
57
- "@vielzeug/ripple": "^2.3.0"
56
+ "@vielzeug/assay": "^3.0.0",
57
+ "@vielzeug/ripple": "^3.0.0"
58
58
  },
59
59
  "peerDependenciesMeta": {
60
60
  "@vielzeug/assay": {
@@ -62,13 +62,13 @@
62
62
  }
63
63
  },
64
64
  "devDependencies": {
65
- "@types/node": "^26.2.0",
66
- "@vielzeug/assay": "2.2.0",
67
- "@vielzeug/ripple": "2.3.0",
65
+ "@types/node": "^26.4.1",
66
+ "@vielzeug/assay": "3.0.0",
67
+ "@vielzeug/ripple": "3.0.0",
68
68
  "axe-core": "^4.13.0",
69
69
  "jsdom": "^30.0.1",
70
70
  "typescript": "^6.0.3",
71
- "vite": "^8.2.1",
72
- "vitest": "^4.1.10"
71
+ "vite": "^8.2.2",
72
+ "vitest": "^5.0.0"
73
73
  }
74
74
  }