@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.
- package/README.md +11 -8
- package/dist/_component-class.cjs +2 -0
- package/dist/_component-class.cjs.map +1 -0
- package/dist/_component-class.d.ts +2 -0
- package/dist/_component-class.d.ts.map +1 -0
- package/dist/_component-class.js +2 -0
- package/dist/_component-class.js.map +1 -0
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +1 -1
- package/dist/_dev.js.map +1 -1
- package/dist/base-element.cjs +1 -1
- package/dist/base-element.cjs.map +1 -1
- package/dist/base-element.d.ts +9 -15
- package/dist/base-element.d.ts.map +1 -1
- package/dist/base-element.js +1 -1
- package/dist/base-element.js.map +1 -1
- package/dist/component-types.d.ts +3 -14
- package/dist/component-types.d.ts.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.ts +13 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/define.cjs +1 -1
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.ts +6 -5
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +1 -1
- package/dist/define.js.map +1 -1
- package/dist/directives/classMap.cjs +1 -1
- package/dist/directives/classMap.cjs.map +1 -1
- package/dist/directives/classMap.d.ts.map +1 -1
- package/dist/directives/classMap.js +1 -1
- package/dist/directives/classMap.js.map +1 -1
- package/dist/directives/each.cjs +1 -1
- package/dist/directives/each.cjs.map +1 -1
- package/dist/directives/each.d.ts +9 -2
- package/dist/directives/each.d.ts.map +1 -1
- package/dist/directives/each.js +1 -1
- package/dist/directives/each.js.map +1 -1
- package/dist/directives/live.cjs +1 -1
- package/dist/directives/live.cjs.map +1 -1
- package/dist/directives/live.d.ts +10 -12
- package/dist/directives/live.d.ts.map +1 -1
- package/dist/directives/live.js +1 -1
- package/dist/directives/live.js.map +1 -1
- package/dist/directives/styleMap.cjs +1 -1
- package/dist/directives/styleMap.cjs.map +1 -1
- package/dist/directives/styleMap.d.ts +1 -1
- package/dist/directives/styleMap.d.ts.map +1 -1
- package/dist/directives/styleMap.js +1 -1
- package/dist/directives/styleMap.js.map +1 -1
- package/dist/directives/unsafe-html.cjs +2 -0
- package/dist/directives/unsafe-html.cjs.map +1 -0
- package/dist/directives/unsafe-html.d.ts +14 -0
- package/dist/directives/unsafe-html.d.ts.map +1 -0
- package/dist/directives/unsafe-html.js +2 -0
- package/dist/directives/unsafe-html.js.map +1 -0
- package/dist/directives/when.cjs +1 -1
- package/dist/directives/when.cjs.map +1 -1
- package/dist/directives/when.d.ts +1 -1
- package/dist/directives/when.d.ts.map +1 -1
- package/dist/directives/when.js +1 -1
- package/dist/directives/when.js.map +1 -1
- package/dist/errors.cjs +2 -2
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +21 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/forms/field.cjs +1 -1
- package/dist/forms/field.cjs.map +1 -1
- package/dist/forms/field.d.ts +5 -1
- package/dist/forms/field.d.ts.map +1 -1
- package/dist/forms/field.js +1 -1
- package/dist/forms/field.js.map +1 -1
- package/dist/host-bind.cjs +1 -1
- package/dist/host-bind.cjs.map +1 -1
- package/dist/host-bind.d.ts +6 -0
- package/dist/host-bind.d.ts.map +1 -1
- package/dist/host-bind.js +1 -1
- package/dist/host-bind.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +15 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/observers/intersection-observe.cjs +1 -1
- package/dist/observers/intersection-observe.cjs.map +1 -1
- package/dist/observers/intersection-observe.d.ts.map +1 -1
- package/dist/observers/intersection-observe.js +1 -1
- package/dist/observers/intersection-observe.js.map +1 -1
- package/dist/observers/media-observe.cjs +1 -1
- package/dist/observers/media-observe.cjs.map +1 -1
- package/dist/observers/media-observe.d.ts.map +1 -1
- package/dist/observers/media-observe.js +1 -1
- package/dist/observers/media-observe.js.map +1 -1
- package/dist/observers/mutation-observe.cjs +1 -1
- package/dist/observers/mutation-observe.cjs.map +1 -1
- package/dist/observers/mutation-observe.d.ts.map +1 -1
- package/dist/observers/mutation-observe.js +1 -1
- package/dist/observers/mutation-observe.js.map +1 -1
- package/dist/observers/resize-observe.cjs +1 -1
- package/dist/observers/resize-observe.cjs.map +1 -1
- package/dist/observers/resize-observe.d.ts.map +1 -1
- package/dist/observers/resize-observe.js +1 -1
- package/dist/observers/resize-observe.js.map +1 -1
- package/dist/ore.cjs +2 -2
- package/dist/ore.cjs.map +1 -1
- package/dist/ore.iife.js +2 -2
- package/dist/ore.iife.js.map +1 -1
- package/dist/ore.js +2 -2
- package/dist/ore.js.map +1 -1
- package/dist/props.cjs +1 -1
- package/dist/props.cjs.map +1 -1
- package/dist/props.d.ts +1 -6
- package/dist/props.d.ts.map +1 -1
- package/dist/props.js +1 -1
- package/dist/props.js.map +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.ts +7 -10
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/slots.cjs +1 -1
- package/dist/slots.cjs.map +1 -1
- package/dist/slots.d.ts.map +1 -1
- package/dist/slots.js +1 -1
- package/dist/slots.js.map +1 -1
- package/dist/template/binding-types.cjs +1 -0
- package/dist/template/binding-types.d.ts +59 -0
- package/dist/template/binding-types.d.ts.map +1 -0
- package/dist/template/binding-types.js +1 -0
- package/dist/template/bindings.cjs +1 -1
- package/dist/template/bindings.cjs.map +1 -1
- package/dist/template/bindings.d.ts +18 -3
- package/dist/template/bindings.d.ts.map +1 -1
- package/dist/template/bindings.js +1 -1
- package/dist/template/bindings.js.map +1 -1
- package/dist/template/compiler.cjs +1 -1
- package/dist/template/compiler.cjs.map +1 -1
- package/dist/template/compiler.d.ts +0 -4
- package/dist/template/compiler.d.ts.map +1 -1
- package/dist/template/compiler.js +1 -1
- package/dist/template/compiler.js.map +1 -1
- package/dist/template/instantiator.cjs +1 -1
- package/dist/template/instantiator.cjs.map +1 -1
- package/dist/template/instantiator.d.ts +6 -1
- package/dist/template/instantiator.d.ts.map +1 -1
- package/dist/template/instantiator.js +1 -1
- package/dist/template/instantiator.js.map +1 -1
- package/dist/template/result.cjs +2 -0
- package/dist/template/result.cjs.map +1 -0
- package/dist/template/result.d.ts +42 -0
- package/dist/template/result.d.ts.map +1 -0
- package/dist/template/result.js +2 -0
- package/dist/template/result.js.map +1 -0
- package/dist/testing/flush.cjs +1 -1
- package/dist/testing/flush.cjs.map +1 -1
- package/dist/testing/flush.d.ts +30 -26
- package/dist/testing/flush.d.ts.map +1 -1
- package/dist/testing/flush.js +1 -1
- package/dist/testing/flush.js.map +1 -1
- package/dist/testing/form-internals-polyfill.cjs +1 -1
- package/dist/testing/form-internals-polyfill.cjs.map +1 -1
- package/dist/testing/form-internals-polyfill.d.ts +9 -7
- package/dist/testing/form-internals-polyfill.d.ts.map +1 -1
- package/dist/testing/form-internals-polyfill.js +1 -1
- package/dist/testing/form-internals-polyfill.js.map +1 -1
- package/dist/testing/index.d.ts +35 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/mount.cjs +1 -1
- package/dist/testing/mount.cjs.map +1 -1
- package/dist/testing/mount.d.ts +10 -19
- package/dist/testing/mount.d.ts.map +1 -1
- package/dist/testing/mount.js +1 -1
- package/dist/testing/mount.js.map +1 -1
- package/dist/testing/render-hook.cjs +1 -1
- package/dist/testing/render-hook.cjs.map +1 -1
- package/dist/testing/render-hook.js +1 -1
- package/dist/testing/render-hook.js.map +1 -1
- package/dist/testing/reset.cjs +2 -0
- package/dist/testing/reset.cjs.map +1 -0
- package/dist/testing/reset.d.ts +12 -0
- package/dist/testing/reset.d.ts.map +1 -0
- package/dist/testing/reset.js +2 -0
- package/dist/testing/reset.js.map +1 -0
- package/dist/testing.cjs +2 -1
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.js +2 -1
- package/dist/testing.js.map +1 -0
- package/dist/utils/aria.cjs.map +1 -1
- package/dist/utils/aria.d.ts +1 -1
- package/dist/utils/aria.js.map +1 -1
- package/dist/utils/brand.cjs +2 -0
- package/dist/utils/brand.cjs.map +1 -0
- package/dist/utils/brand.d.ts +16 -0
- package/dist/utils/brand.d.ts.map +1 -0
- package/dist/utils/brand.js +2 -0
- package/dist/utils/brand.js.map +1 -0
- package/dist/utils/css.cjs +1 -1
- package/dist/utils/css.cjs.map +1 -1
- package/dist/utils/css.d.ts.map +1 -1
- package/dist/utils/css.js +1 -1
- package/dist/utils/css.js.map +1 -1
- package/dist/utils/dom.cjs +1 -1
- package/dist/utils/dom.cjs.map +1 -1
- package/dist/utils/dom.d.ts +34 -0
- package/dist/utils/dom.d.ts.map +1 -1
- package/dist/utils/dom.js +1 -1
- package/dist/utils/dom.js.map +1 -1
- package/dist/utils/emit.cjs.map +1 -1
- package/dist/utils/emit.d.ts +10 -3
- package/dist/utils/emit.d.ts.map +1 -1
- package/dist/utils/emit.js.map +1 -1
- package/dist/utils/id.cjs +1 -1
- package/dist/utils/id.cjs.map +1 -1
- package/dist/utils/id.d.ts +11 -2
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +1 -1
- package/dist/utils/id.js.map +1 -1
- package/package.json +15 -30
- package/dist/aria.cjs +0 -2
- package/dist/aria.cjs.map +0 -1
- package/dist/aria.d.ts +0 -20
- package/dist/aria.d.ts.map +0 -1
- package/dist/aria.js +0 -2
- package/dist/aria.js.map +0 -1
- package/dist/devtools.cjs +0 -2
- package/dist/devtools.cjs.map +0 -1
- package/dist/devtools.d.ts +0 -32
- package/dist/devtools.d.ts.map +0 -1
- package/dist/devtools.js +0 -2
- package/dist/devtools.js.map +0 -1
- package/dist/directives/index.d.ts +0 -8
- package/dist/directives/index.d.ts.map +0 -1
- package/dist/directives/model.cjs +0 -2
- package/dist/directives/model.cjs.map +0 -1
- package/dist/directives/model.d.ts +0 -28
- package/dist/directives/model.d.ts.map +0 -1
- package/dist/directives/model.js +0 -2
- package/dist/directives/model.js.map +0 -1
- package/dist/directives/raw.cjs +0 -2
- package/dist/directives/raw.cjs.map +0 -1
- package/dist/directives/raw.d.ts +0 -16
- package/dist/directives/raw.d.ts.map +0 -1
- package/dist/directives/raw.js +0 -2
- package/dist/directives/raw.js.map +0 -1
- package/dist/directives.cjs +0 -1
- package/dist/directives.js +0 -1
- package/dist/forms/context.cjs +0 -2
- package/dist/forms/context.cjs.map +0 -1
- package/dist/forms/context.d.ts +0 -56
- package/dist/forms/context.d.ts.map +0 -1
- package/dist/forms/context.js +0 -2
- package/dist/forms/context.js.map +0 -1
- package/dist/forms/index.d.ts +0 -11
- package/dist/forms/index.d.ts.map +0 -1
- package/dist/forms.cjs +0 -1
- package/dist/forms.js +0 -1
- package/dist/observers/index.d.ts +0 -5
- package/dist/observers/index.d.ts.map +0 -1
- package/dist/observers.cjs +0 -1
- package/dist/observers.js +0 -1
- package/dist/template.cjs +0 -1
- package/dist/template.d.ts +0 -4
- package/dist/template.d.ts.map +0 -1
- package/dist/template.js +0 -1
- package/dist/testing/events.cjs +0 -2
- package/dist/testing/events.cjs.map +0 -1
- package/dist/testing/events.d.ts +0 -37
- package/dist/testing/events.d.ts.map +0 -1
- package/dist/testing/events.js +0 -2
- package/dist/testing/events.js.map +0 -1
- package/dist/testing/interactions.cjs +0 -2
- package/dist/testing/interactions.cjs.map +0 -1
- package/dist/testing/interactions.d.ts +0 -27
- package/dist/testing/interactions.d.ts.map +0 -1
- package/dist/testing/interactions.js +0 -2
- package/dist/testing/interactions.js.map +0 -1
- package/dist/testing/query.cjs +0 -2
- package/dist/testing/query.cjs.map +0 -1
- package/dist/testing/query.d.ts +0 -24
- package/dist/testing/query.d.ts.map +0 -1
- package/dist/testing/query.js +0 -2
- package/dist/testing/query.js.map +0 -1
- package/dist/testing/testing.cjs +0 -2
- package/dist/testing/testing.cjs.map +0 -1
- package/dist/testing/testing.d.ts +0 -32
- package/dist/testing/testing.d.ts.map +0 -1
- package/dist/testing/testing.js +0 -2
- package/dist/testing/testing.js.map +0 -1
- package/dist/testing/wait.cjs +0 -2
- package/dist/testing/wait.cjs.map +0 -1
- package/dist/testing/wait.d.ts +0 -35
- package/dist/testing/wait.d.ts.map +0 -1
- package/dist/testing/wait.js +0 -2
- package/dist/testing/wait.js.map +0 -1
- package/dist/types/bindings.cjs +0 -2
- package/dist/types/bindings.cjs.map +0 -1
- package/dist/types/bindings.d.ts +0 -125
- package/dist/types/bindings.d.ts.map +0 -1
- package/dist/types/bindings.js +0 -2
- package/dist/types/bindings.js.map +0 -1
- package/dist/types.cjs +0 -2
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.ts +0 -19
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/event-modifiers.cjs +0 -2
- package/dist/utils/event-modifiers.cjs.map +0 -1
- package/dist/utils/event-modifiers.d.ts +0 -11
- package/dist/utils/event-modifiers.d.ts.map +0 -1
- package/dist/utils/event-modifiers.js +0 -2
- package/dist/utils/event-modifiers.js.map +0 -1
package/dist/utils/dom.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.cjs","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { warn } from '../_dev';\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding.
|
|
1
|
+
{"version":3,"file":"dom.cjs","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { ORE_ERRORS } from '../errors';\n\n/**\n * Resolves a value that may be a plain value, a getter function, or a reactive\n * signal — the one shared three-way branch used by `classMap`/`styleMap`/`bind()`.\n */\nexport const resolveMaybeReactive = <T>(value: T | Readable<T> | (() => T)): T =>\n typeof value === 'function' ? (value as () => T)() : isReactive(value) ? value.value : value;\n\n/**\n * Characters that can break out of a CSS declaration in an inline style value or property name.\n * Semicolons end the current declaration; braces are meaningful in stylesheet rules but not\n * inline style values, and signal an injection attempt there.\n */\nexport const UNSAFE_CSS_CHARS = /[;{}]/g;\n\nexport const sanitizeCssToken = (value: string): string => value.replace(UNSAFE_CSS_CHARS, '');\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * Tracks \"whatever is currently rendered in one spot\" — a list of live DOM nodes plus the\n * cleanup functions that were registered while mounting them. `clear()` tears both down and\n * resets to empty, ready for the next render.\n *\n * Every directive/binding that swaps its rendered content when a reactive source changes\n * (`when()`, `unsafeHtml()`, `each()`'s empty-list fallback, `applyHtmlBinding()`) needs exactly this\n * bookkeeping — this is the one shared implementation instead of four independently-maintained\n * `currentNodes`/`currentCleanups` variable pairs.\n */\nexport type ReplaceableSlot = {\n /** Tears down every registered cleanup and removes every tracked node, then resets to empty. */\n clear(): void;\n /** Currently tracked nodes — read after mounting to know what's live. */\n readonly nodes: Node[];\n /** Pass as the `registerCleanup` callback to whatever mounts the next render. */\n registerCleanup(fn: () => void): void;\n /** Replace the tracked node list (call once mounting the next render is complete). */\n setNodes(nodes: Node[]): void;\n};\n\nexport const createReplaceableSlot = (): ReplaceableSlot => {\n let nodes: Node[] = [];\n let cleanups: (() => void)[] = [];\n\n return {\n clear() {\n runAll(cleanups);\n removeNodes(nodes);\n cleanups = [];\n nodes = [];\n },\n get nodes() {\n return nodes;\n },\n registerCleanup(fn) {\n cleanups.push(fn);\n },\n setNodes(next) {\n nodes = next;\n },\n };\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Sanitize untrusted content, then use unsafeHtml() if HTML injection is required.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) {\n warn(ORE_ERRORS.listenNullTarget(name));\n\n return () => {};\n }\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n"],"mappings":"0FAaA,IAAa,EAA2B,GACtC,OAAO,GAAU,WAAc,EAAkB,GAAA,EAAI,EAAA,WAAA,CAAW,CAAK,EAAI,EAAM,MAAQ,EAO5E,EAAmB,SAEnB,EAAoB,GAA0B,EAAM,QAAQ,EAAkB,EAAE,EAEhF,EAAU,GAA8B,CACnD,IAAK,IAAI,EAAI,EAAI,OAAS,EAAG,GAAK,EAAG,IAAK,EAAI,EAAE,CAAE,CACpD,EAEa,EAAe,GAAwB,CAClD,IAAK,IAAM,KAAQ,EACjB,EAAoB,OAAO,CAE/B,EAuBa,MAA+C,CAC1D,IAAI,EAAgB,CAAC,EACjB,EAA2B,CAAC,EAEhC,MAAO,CACL,OAAQ,CACN,EAAO,CAAQ,EACf,EAAY,CAAK,EACjB,EAAW,CAAC,EACZ,EAAQ,CAAC,CACX,EACA,IAAI,OAAQ,CACV,OAAO,CACT,EACA,gBAAgB,EAAI,CAClB,EAAS,KAAK,CAAE,CAClB,EACA,SAAS,EAAM,CACb,EAAQ,CACV,CACF,CACF,EASM,EAAY,IAAI,IAAI,CACxB,SACA,OACA,WACA,OACA,aACA,OACA,WACA,OACA,SACA,MACA,YACF,CAAC,EASK,EACJ,sGAEW,GAAW,EAAa,EAAc,IAAuB,CACxE,IAAM,EAAY,EAAK,YAAY,EAEnC,GAAI,YAAY,KAAK,CAAI,EAAG,CAExB,GAAyB,EAAzB,EAAkG,EAAK,MAAM,CAAC,EAA9G,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,IAAc,SAAU,CAI1B,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,GAAO,MAAQ,IAAQ,GAAO,CAChC,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,IAAM,EAAS,IAAQ,GAAO,OAAS,OAAO,CAAG,EAEjD,GAAI,EAAU,IAAI,CAAS,GAAK,EAAoB,KAAK,CAAM,EAAG,CAE9D,GAA8C,EAA9C,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,EAAG,aAAa,EAAM,CAAM,CAC9B,EAEa,GACX,EACA,EACA,EACA,IACiB,CACjB,GAAI,CAAC,EAGH,OAFK,EAAA,WAAW,iBAAiB,CAAI,MAExB,CAAC,EAGhB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,CAAO,MAE9B,EAAG,oBAAoB,EAAM,EAAU,CAAO,CAC7D,EAEa,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,YAAY,GAAG,EAErF,EAAqB,GAChC,MAAM,QAAQ,CAAK,GAAM,OAAO,GAAU,YAAY"}
|
package/dist/utils/dom.d.ts
CHANGED
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Low-level DOM utilities used throughout the runtime and binding layers.
|
|
3
3
|
*/
|
|
4
|
+
import { type Readable } from '@vielzeug/ripple';
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a value that may be a plain value, a getter function, or a reactive
|
|
7
|
+
* signal — the one shared three-way branch used by `classMap`/`styleMap`/`bind()`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const resolveMaybeReactive: <T>(value: T | Readable<T> | (() => T)) => T;
|
|
10
|
+
/**
|
|
11
|
+
* Characters that can break out of a CSS declaration in an inline style value or property name.
|
|
12
|
+
* Semicolons end the current declaration; braces are meaningful in stylesheet rules but not
|
|
13
|
+
* inline style values, and signal an injection attempt there.
|
|
14
|
+
*/
|
|
15
|
+
export declare const UNSAFE_CSS_CHARS: RegExp;
|
|
16
|
+
export declare const sanitizeCssToken: (value: string) => string;
|
|
4
17
|
export declare const runAll: (fns: (() => void)[]) => void;
|
|
5
18
|
export declare const removeNodes: (nodes: Node[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Tracks "whatever is currently rendered in one spot" — a list of live DOM nodes plus the
|
|
21
|
+
* cleanup functions that were registered while mounting them. `clear()` tears both down and
|
|
22
|
+
* resets to empty, ready for the next render.
|
|
23
|
+
*
|
|
24
|
+
* Every directive/binding that swaps its rendered content when a reactive source changes
|
|
25
|
+
* (`when()`, `unsafeHtml()`, `each()`'s empty-list fallback, `applyHtmlBinding()`) needs exactly this
|
|
26
|
+
* bookkeeping — this is the one shared implementation instead of four independently-maintained
|
|
27
|
+
* `currentNodes`/`currentCleanups` variable pairs.
|
|
28
|
+
*/
|
|
29
|
+
export type ReplaceableSlot = {
|
|
30
|
+
/** Tears down every registered cleanup and removes every tracked node, then resets to empty. */
|
|
31
|
+
clear(): void;
|
|
32
|
+
/** Currently tracked nodes — read after mounting to know what's live. */
|
|
33
|
+
readonly nodes: Node[];
|
|
34
|
+
/** Pass as the `registerCleanup` callback to whatever mounts the next render. */
|
|
35
|
+
registerCleanup(fn: () => void): void;
|
|
36
|
+
/** Replace the tracked node list (call once mounting the next render is complete). */
|
|
37
|
+
setNodes(nodes: Node[]): void;
|
|
38
|
+
};
|
|
39
|
+
export declare const createReplaceableSlot: () => ReplaceableSlot;
|
|
6
40
|
export declare const setAttr: (el: Element, name: string, val: unknown) => void;
|
|
7
41
|
export declare const listen: (el: EventTarget | null | undefined, name: string, handler: EventListener, options?: AddEventListenerOptions) => (() => void);
|
|
8
42
|
export declare const toKebab: (str: string) => string;
|
package/dist/utils/dom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/utils/dom.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/utils/dom.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK7D;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAG,CACiB,CAAC;AAE/F;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAW,CAAC;AAEzC,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,MAA6C,CAAC;AAE/F,eAAO,MAAM,MAAM,GAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,KAAG,IAE5C,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,IAAI,EAAE,KAAG,IAI3C,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,gGAAgG;IAChG,KAAK,IAAI,IAAI,CAAC;IACd,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IACvB,iFAAiF;IACjF,eAAe,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACtC,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAO,eAqBxC,CAAC;AAiCF,eAAO,MAAM,OAAO,GAAI,IAAI,OAAO,EAAE,MAAM,MAAM,EAAE,KAAK,OAAO,KAAG,IAuCjE,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,IAAI,WAAW,GAAG,IAAI,GAAG,SAAS,EAClC,MAAM,MAAM,EACZ,SAAS,aAAa,EACtB,UAAU,uBAAuB,KAChC,CAAC,MAAM,IAAI,CAYb,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAA6D,CAAC;AAEpG,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACW,CAAC"}
|
package/dist/utils/dom.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import"../_dev.js";import{ORE_ERRORS as e}from"../errors.js";import{isReactive as t}from"@vielzeug/ripple";var n=e=>typeof e==`function`?e():t(e)?e.value:e,r=/[;{}]/g,i=e=>e.replace(r,``),a=e=>{for(let t=e.length-1;t>=0;t--)e[t]()},o=e=>{for(let t of e)t.remove()},s=()=>{let e=[],t=[];return{clear(){a(t),o(e),t=[],e=[]},get nodes(){return e},registerCleanup(e){t.push(e)},setNodes(t){e=t}}},c=new Set([`action`,`cite`,`codebase`,`data`,`formaction`,`href`,`manifest`,`ping`,`poster`,`src`,`xlink:href`]),l=/^\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\/(?:html|svg\+xml)|application\/(?:xhtml|xml)))/i,u=(e,t,n)=>{let r=t.toLowerCase();if(/^on[a-z]/i.test(t)){`${t}${t.slice(2)}`,e.removeAttribute(t);return}if(r===`srcdoc`){e.removeAttribute(t);return}if(n==null||n===!1){e.removeAttribute(t);return}let i=n===!0?`true`:String(n);if(c.has(r)&&l.test(i)){`${t}`,e.removeAttribute(t);return}e.setAttribute(t,i)},d=(t,n,r,i)=>{if(!t)return e.listenNullTarget(n),()=>{};let a=r;return t.addEventListener(n,a,i),()=>t.removeEventListener(n,a,i)},f=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),p=e=>Array.isArray(e)||typeof e==`object`&&!!e;export{r as UNSAFE_CSS_CHARS,s as createReplaceableSlot,p as isStructuredValue,d as listen,o as removeNodes,n as resolveMaybeReactive,a as runAll,i as sanitizeCssToken,u as setAttr,f as toKebab};
|
|
2
2
|
//# sourceMappingURL=dom.js.map
|
package/dist/utils/dom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.js","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { warn } from '../_dev';\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding.
|
|
1
|
+
{"version":3,"file":"dom.js","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { ORE_ERRORS } from '../errors';\n\n/**\n * Resolves a value that may be a plain value, a getter function, or a reactive\n * signal — the one shared three-way branch used by `classMap`/`styleMap`/`bind()`.\n */\nexport const resolveMaybeReactive = <T>(value: T | Readable<T> | (() => T)): T =>\n typeof value === 'function' ? (value as () => T)() : isReactive(value) ? value.value : value;\n\n/**\n * Characters that can break out of a CSS declaration in an inline style value or property name.\n * Semicolons end the current declaration; braces are meaningful in stylesheet rules but not\n * inline style values, and signal an injection attempt there.\n */\nexport const UNSAFE_CSS_CHARS = /[;{}]/g;\n\nexport const sanitizeCssToken = (value: string): string => value.replace(UNSAFE_CSS_CHARS, '');\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * Tracks \"whatever is currently rendered in one spot\" — a list of live DOM nodes plus the\n * cleanup functions that were registered while mounting them. `clear()` tears both down and\n * resets to empty, ready for the next render.\n *\n * Every directive/binding that swaps its rendered content when a reactive source changes\n * (`when()`, `unsafeHtml()`, `each()`'s empty-list fallback, `applyHtmlBinding()`) needs exactly this\n * bookkeeping — this is the one shared implementation instead of four independently-maintained\n * `currentNodes`/`currentCleanups` variable pairs.\n */\nexport type ReplaceableSlot = {\n /** Tears down every registered cleanup and removes every tracked node, then resets to empty. */\n clear(): void;\n /** Currently tracked nodes — read after mounting to know what's live. */\n readonly nodes: Node[];\n /** Pass as the `registerCleanup` callback to whatever mounts the next render. */\n registerCleanup(fn: () => void): void;\n /** Replace the tracked node list (call once mounting the next render is complete). */\n setNodes(nodes: Node[]): void;\n};\n\nexport const createReplaceableSlot = (): ReplaceableSlot => {\n let nodes: Node[] = [];\n let cleanups: (() => void)[] = [];\n\n return {\n clear() {\n runAll(cleanups);\n removeNodes(nodes);\n cleanups = [];\n nodes = [];\n },\n get nodes() {\n return nodes;\n },\n registerCleanup(fn) {\n cleanups.push(fn);\n },\n setNodes(next) {\n nodes = next;\n },\n };\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Sanitize untrusted content, then use unsafeHtml() if HTML injection is required.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) {\n warn(ORE_ERRORS.listenNullTarget(name));\n\n return () => {};\n }\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n"],"mappings":"2GAaA,IAAa,EAA2B,GACtC,OAAO,GAAU,WAAc,EAAkB,EAAI,EAAW,CAAK,EAAI,EAAM,MAAQ,EAO5E,EAAmB,SAEnB,EAAoB,GAA0B,EAAM,QAAQ,EAAkB,EAAE,EAEhF,EAAU,GAA8B,CACnD,IAAK,IAAI,EAAI,EAAI,OAAS,EAAG,GAAK,EAAG,IAAK,EAAI,EAAE,CAAE,CACpD,EAEa,EAAe,GAAwB,CAClD,IAAK,IAAM,KAAQ,EACjB,EAAoB,OAAO,CAE/B,EAuBa,MAA+C,CAC1D,IAAI,EAAgB,CAAC,EACjB,EAA2B,CAAC,EAEhC,MAAO,CACL,OAAQ,CACN,EAAO,CAAQ,EACf,EAAY,CAAK,EACjB,EAAW,CAAC,EACZ,EAAQ,CAAC,CACX,EACA,IAAI,OAAQ,CACV,OAAO,CACT,EACA,gBAAgB,EAAI,CAClB,EAAS,KAAK,CAAE,CAClB,EACA,SAAS,EAAM,CACb,EAAQ,CACV,CACF,CACF,EASM,EAAY,IAAI,IAAI,CACxB,SACA,OACA,WACA,OACA,aACA,OACA,WACA,OACA,SACA,MACA,YACF,CAAC,EASK,EACJ,sGAEW,GAAW,EAAa,EAAc,IAAuB,CACxE,IAAM,EAAY,EAAK,YAAY,EAEnC,GAAI,YAAY,KAAK,CAAI,EAAG,CAExB,GAAyB,EAAzB,EAAkG,EAAK,MAAM,CAAC,EAA9G,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,IAAc,SAAU,CAI1B,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,GAAO,MAAQ,IAAQ,GAAO,CAChC,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,IAAM,EAAS,IAAQ,GAAO,OAAS,OAAO,CAAG,EAEjD,GAAI,EAAU,IAAI,CAAS,GAAK,EAAoB,KAAK,CAAM,EAAG,CAE9D,GAA8C,EAA9C,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,EAAG,aAAa,EAAM,CAAM,CAC9B,EAEa,GACX,EACA,EACA,EACA,IACiB,CACjB,GAAI,CAAC,EAGH,OAFK,EAAW,iBAAiB,CAAI,MAExB,CAAC,EAGhB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,CAAO,MAE9B,EAAG,oBAAoB,EAAM,EAAU,CAAO,CAC7D,EAEa,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,YAAY,GAAG,EAErF,EAAqB,GAChC,MAAM,QAAQ,CAAK,GAAM,OAAO,GAAU,YAAY"}
|
package/dist/utils/emit.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.cjs","names":[],"sources":["../../src/utils/emit.ts"],"sourcesContent":["/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\
|
|
1
|
+
{"version":3,"file":"emit.cjs","names":[],"sources":["../../src/utils/emit.ts"],"sourcesContent":["/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\n/**\n * Typed emit function: only declared event names type-check, and `detail` is\n * required exactly when its payload type is non-void. Dynamic event names must\n * be cast at the call site — an intentional speed bump, not a silent escape.\n */\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): boolean;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;\n};\n\nconst DEFAULT_FIRE_OPTIONS = { bubbles: true, cancelable: true, composed: false };\n\n/**\n * Returns a typed `emit()` function bound to the current component's host element.\n * Call once during `setup()` — the `Emits` type parameter maps event names to\n * their `detail` payload type.\n *\n * Every event is dispatched `cancelable: true`, and `emit()` returns `dispatchEvent`'s\n * own boolean result — `false` when a listener called `preventDefault()`. Components\n * that need to know whether a listener cancelled an event (e.g. to skip a default\n * action) read this return value directly instead of hand-rolling `dispatchEvent`.\n *\n * Events do **not** cross the shadow boundary by default (`composed: false`) — a\n * listener outside the component's shadow root will not observe them. Dispatch a\n * `CustomEvent` with `composed: true` by hand if an event must escape the shadow root.\n *\n * @example\n * ```ts\n * type Events = { close: undefined; change: { value: string } };\n *\n * setup(props) {\n * const emit = useEmit<Events>();\n * emit('close');\n *\n * const notCancelled = emit('change', { value: 'ok' });\n * if (notCancelled) props.value.value = 'ok';\n * }\n * ```\n */\nexport const useEmit = <T extends Record<string, unknown> = Record<string, never>>(): EmitFn<T> => {\n const host = getHost();\n\n return ((event: keyof T, ...rest: unknown[]) => {\n const customEventInit = rest.length > 0 ? { ...DEFAULT_FIRE_OPTIONS, detail: rest[0] } : DEFAULT_FIRE_OPTIONS;\n\n return host.dispatchEvent(new CustomEvent<unknown>(String(event), customEventInit));\n }) as EmitFn<T>;\n};\n"],"mappings":"kCAqBA,IAAM,EAAuB,CAAE,QAAS,GAAM,WAAY,GAAM,SAAU,EAAM,EA6BnE,MAAsF,CACjG,IAAM,EAAO,EAAA,QAAQ,EAErB,QAAS,EAAgB,GAAG,IAAoB,CAC9C,IAAM,EAAkB,EAAK,OAAS,EAAI,CAAE,GAAG,EAAsB,OAAQ,EAAK,EAAG,EAAI,EAEzF,OAAO,EAAK,cAAc,IAAI,YAAqB,OAAO,CAAK,EAAG,CAAe,CAAC,CACpF,EACF"}
|
package/dist/utils/emit.d.ts
CHANGED
|
@@ -5,12 +5,15 @@ type NoDetail = void | undefined | never;
|
|
|
5
5
|
type KeysWithoutDetail<T extends Record<string, unknown>> = {
|
|
6
6
|
[P in keyof T]: [T[P]] extends [NoDetail] ? P : never;
|
|
7
7
|
}[keyof T];
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Typed emit function: only declared event names type-check, and `detail` is
|
|
10
|
+
* required exactly when its payload type is non-void. Dynamic event names must
|
|
11
|
+
* be cast at the call site — an intentional speed bump, not a silent escape.
|
|
12
|
+
*/
|
|
13
|
+
export type EmitFn<T extends Record<string, unknown>> = {
|
|
9
14
|
<K extends KeysWithoutDetail<T>>(event: K): boolean;
|
|
10
15
|
<K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;
|
|
11
16
|
};
|
|
12
|
-
type LooseEmitFn = (event: string, detail?: unknown) => boolean;
|
|
13
|
-
export type EmitFn<T extends Record<string, unknown>> = StrictEmitFn<T> & LooseEmitFn;
|
|
14
17
|
/**
|
|
15
18
|
* Returns a typed `emit()` function bound to the current component's host element.
|
|
16
19
|
* Call once during `setup()` — the `Emits` type parameter maps event names to
|
|
@@ -21,6 +24,10 @@ export type EmitFn<T extends Record<string, unknown>> = StrictEmitFn<T> & LooseE
|
|
|
21
24
|
* that need to know whether a listener cancelled an event (e.g. to skip a default
|
|
22
25
|
* action) read this return value directly instead of hand-rolling `dispatchEvent`.
|
|
23
26
|
*
|
|
27
|
+
* Events do **not** cross the shadow boundary by default (`composed: false`) — a
|
|
28
|
+
* listener outside the component's shadow root will not observe them. Dispatch a
|
|
29
|
+
* `CustomEvent` with `composed: true` by hand if an event must escape the shadow root.
|
|
30
|
+
*
|
|
24
31
|
* @example
|
|
25
32
|
* ```ts
|
|
26
33
|
* type Events = { close: undefined; change: { value: string } };
|
package/dist/utils/emit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/utils/emit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,KAAK,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;AACzC,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK;CACtD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/utils/emit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,KAAK,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;AACzC,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK;CACtD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;GAIG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACtD,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IACpD,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACrF,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAK,MAAM,CAAC,CAAC,CAQ7F,CAAC"}
|
package/dist/utils/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","names":[],"sources":["../../src/utils/emit.ts"],"sourcesContent":["/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\
|
|
1
|
+
{"version":3,"file":"emit.js","names":[],"sources":["../../src/utils/emit.ts"],"sourcesContent":["/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\n/**\n * Typed emit function: only declared event names type-check, and `detail` is\n * required exactly when its payload type is non-void. Dynamic event names must\n * be cast at the call site — an intentional speed bump, not a silent escape.\n */\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): boolean;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;\n};\n\nconst DEFAULT_FIRE_OPTIONS = { bubbles: true, cancelable: true, composed: false };\n\n/**\n * Returns a typed `emit()` function bound to the current component's host element.\n * Call once during `setup()` — the `Emits` type parameter maps event names to\n * their `detail` payload type.\n *\n * Every event is dispatched `cancelable: true`, and `emit()` returns `dispatchEvent`'s\n * own boolean result — `false` when a listener called `preventDefault()`. Components\n * that need to know whether a listener cancelled an event (e.g. to skip a default\n * action) read this return value directly instead of hand-rolling `dispatchEvent`.\n *\n * Events do **not** cross the shadow boundary by default (`composed: false`) — a\n * listener outside the component's shadow root will not observe them. Dispatch a\n * `CustomEvent` with `composed: true` by hand if an event must escape the shadow root.\n *\n * @example\n * ```ts\n * type Events = { close: undefined; change: { value: string } };\n *\n * setup(props) {\n * const emit = useEmit<Events>();\n * emit('close');\n *\n * const notCancelled = emit('change', { value: 'ok' });\n * if (notCancelled) props.value.value = 'ok';\n * }\n * ```\n */\nexport const useEmit = <T extends Record<string, unknown> = Record<string, never>>(): EmitFn<T> => {\n const host = getHost();\n\n return ((event: keyof T, ...rest: unknown[]) => {\n const customEventInit = rest.length > 0 ? { ...DEFAULT_FIRE_OPTIONS, detail: rest[0] } : DEFAULT_FIRE_OPTIONS;\n\n return host.dispatchEvent(new CustomEvent<unknown>(String(event), customEventInit));\n }) as EmitFn<T>;\n};\n"],"mappings":"wCAqBA,IAAM,EAAuB,CAAE,QAAS,GAAM,WAAY,GAAM,SAAU,EAAM,EA6BnE,MAAsF,CACjG,IAAM,EAAO,EAAQ,EAErB,QAAS,EAAgB,GAAG,IAAoB,CAC9C,IAAM,EAAkB,EAAK,OAAS,EAAI,CAAE,GAAG,EAAsB,OAAQ,EAAK,EAAG,EAAI,EAEzF,OAAO,EAAK,cAAc,IAAI,YAAqB,OAAO,CAAK,EAAG,CAAe,CAAC,CACpF,EACF"}
|
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.
|
|
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;
|
|
2
2
|
//# sourceMappingURL=id.cjs.map
|
package/dist/utils/id.cjs.map
CHANGED
|
@@ -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\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
|
|
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"}
|
package/dist/utils/id.d.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* Template binding no longer uses this for marker IDs — binding targets are resolved
|
|
4
4
|
* via path navigation on cloned template nodes.
|
|
5
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
|
+
*/
|
|
6
11
|
export declare const createId: (prefix?: string) => string;
|
|
7
12
|
/**
|
|
8
13
|
* Generates a stable, unique ID with an optional semantic prefix.
|
|
@@ -11,8 +16,12 @@ export declare const createId: (prefix?: string) => string;
|
|
|
11
16
|
*/
|
|
12
17
|
export declare const createStableId: (prefix?: string) => string;
|
|
13
18
|
/**
|
|
14
|
-
* Resets the
|
|
19
|
+
* Resets the `createStableId()` counter to 0. Use in test `beforeEach` hooks when you need
|
|
15
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).
|
|
16
25
|
*/
|
|
17
|
-
export declare const
|
|
26
|
+
export declare const resetStableIdCounter: () => void;
|
|
18
27
|
//# sourceMappingURL=id.d.ts.map
|
package/dist/utils/id.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,eAAO,MAAM,QAAQ,GAAI,eAAa,KAAG,MAAqC,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,eAAa,KAAG,MAAgD,CAAC;AAEhG
|
|
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"}
|
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
|
|
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};
|
|
2
2
|
//# sourceMappingURL=id.js.map
|
package/dist/utils/id.js.map
CHANGED
|
@@ -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\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
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vielzeug/ore",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Custom element authoring primitives — reactive templates, signals, slots, and automatic lifecycle management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -16,30 +16,6 @@
|
|
|
16
16
|
"import": "./dist/index.js",
|
|
17
17
|
"require": "./dist/index.cjs"
|
|
18
18
|
},
|
|
19
|
-
"./devtools": {
|
|
20
|
-
"source": "./src/devtools.ts",
|
|
21
|
-
"types": "./dist/devtools.d.ts",
|
|
22
|
-
"import": "./dist/devtools.js",
|
|
23
|
-
"require": "./dist/devtools.cjs"
|
|
24
|
-
},
|
|
25
|
-
"./directives": {
|
|
26
|
-
"source": "./src/directives/index.ts",
|
|
27
|
-
"types": "./dist/directives/index.d.ts",
|
|
28
|
-
"import": "./dist/directives.js",
|
|
29
|
-
"require": "./dist/directives.cjs"
|
|
30
|
-
},
|
|
31
|
-
"./forms": {
|
|
32
|
-
"source": "./src/forms/index.ts",
|
|
33
|
-
"types": "./dist/forms/index.d.ts",
|
|
34
|
-
"import": "./dist/forms.js",
|
|
35
|
-
"require": "./dist/forms.cjs"
|
|
36
|
-
},
|
|
37
|
-
"./observers": {
|
|
38
|
-
"source": "./src/observers/index.ts",
|
|
39
|
-
"types": "./dist/observers/index.d.ts",
|
|
40
|
-
"import": "./dist/observers.js",
|
|
41
|
-
"require": "./dist/observers.cjs"
|
|
42
|
-
},
|
|
43
19
|
"./testing": {
|
|
44
20
|
"source": "./src/testing/index.ts",
|
|
45
21
|
"types": "./dist/testing/index.d.ts",
|
|
@@ -55,6 +31,7 @@
|
|
|
55
31
|
"prepublishOnly": "pnpm run build",
|
|
56
32
|
"preview": "vite preview",
|
|
57
33
|
"test": "vitest",
|
|
34
|
+
"test:types": "tsc -p tsconfig.json --noEmit",
|
|
58
35
|
"build:bundle": "vite build --config vite.bundle.config.ts"
|
|
59
36
|
},
|
|
60
37
|
"publishConfig": {
|
|
@@ -64,15 +41,23 @@
|
|
|
64
41
|
"engines": {
|
|
65
42
|
"node": ">=22"
|
|
66
43
|
},
|
|
67
|
-
"
|
|
68
|
-
"@vielzeug/
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@vielzeug/assay": "^2.0.0",
|
|
46
|
+
"@vielzeug/ripple": "^2.0.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"@vielzeug/assay": {
|
|
50
|
+
"optional": true
|
|
51
|
+
}
|
|
69
52
|
},
|
|
70
53
|
"devDependencies": {
|
|
71
|
-
"@types/node": "^26.1.
|
|
54
|
+
"@types/node": "^26.1.2",
|
|
55
|
+
"@vielzeug/assay": "2.0.0",
|
|
56
|
+
"@vielzeug/ripple": "2.0.0",
|
|
72
57
|
"axe-core": "^4.12.1",
|
|
73
|
-
"jsdom": "^
|
|
58
|
+
"jsdom": "^30.0.1",
|
|
74
59
|
"typescript": "^6.0.3",
|
|
75
|
-
"vite": "^8.
|
|
60
|
+
"vite": "^8.2.0",
|
|
76
61
|
"vitest": "^4.1.10"
|
|
77
62
|
}
|
|
78
63
|
}
|
package/dist/aria.cjs
DELETED
package/dist/aria.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aria.cjs","names":[],"sources":["../src/aria.ts"],"sourcesContent":["/**\n * Reactive ARIA attribute sync.\n *\n * `aria()` is a thin wrapper over `bind({ attr })` — the two used to carry\n * independent copies of the same \"static | getter | signal → attribute write\"\n * logic, which had already drifted (this file's writes bypassed the\n * `on*`/dangerous-URL-scheme hardening that `setAttr()` gives every other\n * attribute write in the package). `aria()` now exists purely to normalize\n * bare ARIA property names (`expanded` → `aria-expanded`) before delegating —\n * for attributes that are already fully-qualified, `bind({ attr }, { target })`\n * is equivalent.\n */\n\nimport { bind, type HostBindingValue } from './host-bind';\nimport { normalizeAriaKey } from './utils/aria';\n\nexport type AriaConfig = Record<string, HostBindingValue>;\n\n/**\n * Reactively sync ARIA attributes on any element, auto-cleanup on component\n * disconnect. Returns a cleanup function that removes all reactive bindings.\n */\nexport const aria = (target: Element, config: AriaConfig): (() => void) => {\n const attr: Record<string, HostBindingValue> = {};\n\n for (const [key, value] of Object.entries(config)) attr[normalizeAriaKey(key)] = value;\n\n return bind({ attr }, { target });\n};\n"],"mappings":"iEAsBA,IAAa,GAAQ,EAAiB,IAAqC,CACzE,IAAM,EAAyC,CAAC,EAEhD,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAM,EAAG,EAAK,EAAA,iBAAiB,CAAG,GAAK,EAEjF,OAAO,EAAA,KAAK,CAAE,MAAK,EAAG,CAAE,QAAO,CAAC,CAClC"}
|
package/dist/aria.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reactive ARIA attribute sync.
|
|
3
|
-
*
|
|
4
|
-
* `aria()` is a thin wrapper over `bind({ attr })` — the two used to carry
|
|
5
|
-
* independent copies of the same "static | getter | signal → attribute write"
|
|
6
|
-
* logic, which had already drifted (this file's writes bypassed the
|
|
7
|
-
* `on*`/dangerous-URL-scheme hardening that `setAttr()` gives every other
|
|
8
|
-
* attribute write in the package). `aria()` now exists purely to normalize
|
|
9
|
-
* bare ARIA property names (`expanded` → `aria-expanded`) before delegating —
|
|
10
|
-
* for attributes that are already fully-qualified, `bind({ attr }, { target })`
|
|
11
|
-
* is equivalent.
|
|
12
|
-
*/
|
|
13
|
-
import { type HostBindingValue } from './host-bind';
|
|
14
|
-
export type AriaConfig = Record<string, HostBindingValue>;
|
|
15
|
-
/**
|
|
16
|
-
* Reactively sync ARIA attributes on any element, auto-cleanup on component
|
|
17
|
-
* disconnect. Returns a cleanup function that removes all reactive bindings.
|
|
18
|
-
*/
|
|
19
|
-
export declare const aria: (target: Element, config: AriaConfig) => (() => void);
|
|
20
|
-
//# sourceMappingURL=aria.d.ts.map
|
package/dist/aria.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aria.d.ts","sourceRoot":"","sources":["../src/aria.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG1D,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ,OAAO,EAAE,QAAQ,UAAU,KAAG,CAAC,MAAM,IAAI,CAMrE,CAAC"}
|
package/dist/aria.js
DELETED
package/dist/aria.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aria.js","names":[],"sources":["../src/aria.ts"],"sourcesContent":["/**\n * Reactive ARIA attribute sync.\n *\n * `aria()` is a thin wrapper over `bind({ attr })` — the two used to carry\n * independent copies of the same \"static | getter | signal → attribute write\"\n * logic, which had already drifted (this file's writes bypassed the\n * `on*`/dangerous-URL-scheme hardening that `setAttr()` gives every other\n * attribute write in the package). `aria()` now exists purely to normalize\n * bare ARIA property names (`expanded` → `aria-expanded`) before delegating —\n * for attributes that are already fully-qualified, `bind({ attr }, { target })`\n * is equivalent.\n */\n\nimport { bind, type HostBindingValue } from './host-bind';\nimport { normalizeAriaKey } from './utils/aria';\n\nexport type AriaConfig = Record<string, HostBindingValue>;\n\n/**\n * Reactively sync ARIA attributes on any element, auto-cleanup on component\n * disconnect. Returns a cleanup function that removes all reactive bindings.\n */\nexport const aria = (target: Element, config: AriaConfig): (() => void) => {\n const attr: Record<string, HostBindingValue> = {};\n\n for (const [key, value] of Object.entries(config)) attr[normalizeAriaKey(key)] = value;\n\n return bind({ attr }, { target });\n};\n"],"mappings":"yFAsBA,IAAa,GAAQ,EAAiB,IAAqC,CACzE,IAAM,EAAyC,CAAC,EAEhD,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAM,EAAG,EAAK,EAAiB,CAAG,GAAK,EAEjF,OAAO,EAAK,CAAE,MAAK,EAAG,CAAE,QAAO,CAAC,CAClC"}
|
package/dist/devtools.cjs
DELETED
package/dist/devtools.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/ore — debug utilities for component update visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugFlush } from '@vielzeug/ore/devtools';\n * ```\n */\n\nimport type { FlushOptions } from './testing/flush';\n\nimport { flush } from './testing/flush';\n\n/**\n * Flushes pending reactive updates with debug logging pre-wired to `console.debug`.\n *\n * Equivalent to `flush({ ...options, logger: console.debug })` but imported from a\n * dedicated sub-path so the `console.debug` reference is tree-shaken from production\n * bundles when this sub-path is not imported.\n *\n * Logs each turn and timing phase to `console.debug` so you can diagnose\n * unexpected update order or timing issues.\n *\n * @example\n * ```ts\n * import { debugFlush } from '@vielzeug/ore/devtools';\n *\n * // in a test\n * await debugFlush();\n * // [flush] starting with maxTurns=5\n * // [flush] microtask turn 1/5\n * // ...\n * ```\n */\nexport async function debugFlush(options?: Omit<FlushOptions, 'logger'>): Promise<void> {\n return flush({ ...options, logger: console.debug });\n}\n"],"mappings":"0GAkCA,eAAsB,EAAW,EAAuD,CACtF,OAAO,EAAA,MAAM,CAAE,GAAG,EAAS,OAAQ,QAAQ,KAAM,CAAC,CACpD"}
|
package/dist/devtools.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @vielzeug/ore — debug utilities for component update visualisation.
|
|
3
|
-
*
|
|
4
|
-
* Import from the dedicated sub-path so it is tree-shaken from production bundles:
|
|
5
|
-
* ```ts
|
|
6
|
-
* import { debugFlush } from '@vielzeug/ore/devtools';
|
|
7
|
-
* ```
|
|
8
|
-
*/
|
|
9
|
-
import type { FlushOptions } from './testing/flush';
|
|
10
|
-
/**
|
|
11
|
-
* Flushes pending reactive updates with debug logging pre-wired to `console.debug`.
|
|
12
|
-
*
|
|
13
|
-
* Equivalent to `flush({ ...options, logger: console.debug })` but imported from a
|
|
14
|
-
* dedicated sub-path so the `console.debug` reference is tree-shaken from production
|
|
15
|
-
* bundles when this sub-path is not imported.
|
|
16
|
-
*
|
|
17
|
-
* Logs each turn and timing phase to `console.debug` so you can diagnose
|
|
18
|
-
* unexpected update order or timing issues.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* import { debugFlush } from '@vielzeug/ore/devtools';
|
|
23
|
-
*
|
|
24
|
-
* // in a test
|
|
25
|
-
* await debugFlush();
|
|
26
|
-
* // [flush] starting with maxTurns=5
|
|
27
|
-
* // [flush] microtask turn 1/5
|
|
28
|
-
* // ...
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export declare function debugFlush(options?: Omit<FlushOptions, 'logger'>): Promise<void>;
|
|
32
|
-
//# sourceMappingURL=devtools.d.ts.map
|
package/dist/devtools.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF"}
|
package/dist/devtools.js
DELETED
package/dist/devtools.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/ore — debug utilities for component update visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugFlush } from '@vielzeug/ore/devtools';\n * ```\n */\n\nimport type { FlushOptions } from './testing/flush';\n\nimport { flush } from './testing/flush';\n\n/**\n * Flushes pending reactive updates with debug logging pre-wired to `console.debug`.\n *\n * Equivalent to `flush({ ...options, logger: console.debug })` but imported from a\n * dedicated sub-path so the `console.debug` reference is tree-shaken from production\n * bundles when this sub-path is not imported.\n *\n * Logs each turn and timing phase to `console.debug` so you can diagnose\n * unexpected update order or timing issues.\n *\n * @example\n * ```ts\n * import { debugFlush } from '@vielzeug/ore/devtools';\n *\n * // in a test\n * await debugFlush();\n * // [flush] starting with maxTurns=5\n * // [flush] microtask turn 1/5\n * // ...\n * ```\n */\nexport async function debugFlush(options?: Omit<FlushOptions, 'logger'>): Promise<void> {\n return flush({ ...options, logger: console.debug });\n}\n"],"mappings":"2CAkCA,eAAsB,EAAW,EAAuD,CACtF,OAAO,EAAM,CAAE,GAAG,EAAS,OAAQ,QAAQ,KAAM,CAAC,CACpD"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { classMap } from './classMap';
|
|
2
|
-
export { each } from './each';
|
|
3
|
-
export { live, type LiveSignal } from './live';
|
|
4
|
-
export { model } from './model';
|
|
5
|
-
export { raw, setRawSanitizer } from './raw';
|
|
6
|
-
export { styleMap } from './styleMap';
|
|
7
|
-
export { when } from './when';
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/directives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../types/bindings.cjs"),t=require("../utils/dom.cjs");let n=require("@vielzeug/ripple");function r(r){return e.createSpreadObject((e,i)=>{let a=e,o=a.type===`checkbox`,s=a.type===`number`||a.type===`range`,c=e instanceof HTMLSelectElement,l=c&&e.multiple,u=(0,n.effect)(()=>{let t=r.value;if(l){let n=Array.isArray(t)?t:[],r=e;for(let e of r.options)e.selected=n.includes(e.value)}else o?a.checked=!!t:e.value=t==null?``:String(t)});i(()=>u.dispose()),i(t.listen(e,c?`change`:`input`,e=>{let t=e.target;if(l){let t=e.target;r.value=Array.from(t.selectedOptions).map(e=>e.value)}else o?r.value=t.checked:s?r.value=t.value===``?0:Number(t.value):r.value=t.value}))})}exports.model=r;
|
|
2
|
-
//# sourceMappingURL=model.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model.cjs","names":[],"sources":["../../src/directives/model.ts"],"sourcesContent":["import { effect as rawEffect, type Signal } from '@vielzeug/ripple';\n\nimport { createSpreadObject, type SpreadObject } from '../types/bindings';\nimport { listen } from '../utils/dom';\n\n/**\n * Two-way binding spread for form inputs.\n * Syncs the signal value to the element's DOM value and back.\n *\n * Supports `type=\"text\"` (default), `type=\"number\"`, `type=\"range\"`,\n * `type=\"checkbox\"`, `<select>` (single-select), and\n * `<select multiple>` (multi-select, `Signal<string[]>`).\n *\n * @example\n * ```ts\n * const name = signal('');\n * html`<input type=\"text\" ${model(name)} />`\n *\n * const count = signal(0);\n * html`<input type=\"number\" ${model(count)} />`\n *\n * const checked = signal(false);\n * html`<input type=\"checkbox\" ${model(checked)} />`\n *\n * const selected = signal<string[]>([]);\n * html`<select multiple ${model(selected)}><option value=\"a\">A</option></select>`\n * ```\n */\nexport function model<T extends string | number | boolean | null>(source: Signal<T>): SpreadObject;\nexport function model(source: Signal<string[]>): SpreadObject;\nexport function model<T extends string | number | boolean | null | string[]>(source: Signal<T>): SpreadObject {\n return createSpreadObject((el, registerCleanup) => {\n const input = el as HTMLInputElement;\n const isCheckbox = input.type === 'checkbox';\n const isNumeric = input.type === 'number' || input.type === 'range';\n const isSelect = el instanceof HTMLSelectElement;\n const isMultiSelect = isSelect && (el as HTMLSelectElement).multiple;\n\n // Signal → DOM\n const sub = rawEffect(() => {\n const v = source.value;\n\n if (isMultiSelect) {\n const selected = Array.isArray(v) ? (v as string[]) : [];\n const selectEl = el as HTMLSelectElement;\n\n for (const opt of selectEl.options) {\n opt.selected = selected.includes(opt.value);\n }\n } else if (isCheckbox) {\n input.checked = Boolean(v);\n } else {\n (el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value =\n v == null ? '' : String(v as string | number | boolean | null);\n }\n });\n\n registerCleanup(() => sub.dispose());\n\n // DOM → Signal\n // <select> fires 'change'; text/number/range/textarea/checkbox fire 'input'.\n const eventName = isSelect ? 'change' : 'input';\n\n registerCleanup(\n listen(el, eventName, (e: Event) => {\n const target = e.target as HTMLInputElement;\n\n if (isMultiSelect) {\n const selectEl = e.target as HTMLSelectElement;\n const values = Array.from(selectEl.selectedOptions).map((opt) => opt.value);\n\n (source as Signal<string[]>).value = values;\n } else if (isCheckbox) {\n source.value = target.checked as T;\n } else if (isNumeric) {\n source.value = (target.value === '' ? 0 : Number(target.value)) as T;\n } else {\n source.value = target.value as T;\n }\n }),\n );\n });\n}\n"],"mappings":"yGA8BA,SAAgB,EAA6D,EAAiC,CAC5G,OAAO,EAAA,oBAAoB,EAAI,IAAoB,CACjD,IAAM,EAAQ,EACR,EAAa,EAAM,OAAS,WAC5B,EAAY,EAAM,OAAS,UAAY,EAAM,OAAS,QACtD,EAAW,aAAc,kBACzB,EAAgB,GAAa,EAAyB,SAGtD,GAAA,EAAA,EAAA,OAAA,KAAsB,CAC1B,IAAM,EAAI,EAAO,MAEjB,GAAI,EAAe,CACjB,IAAM,EAAW,MAAM,QAAQ,CAAC,EAAK,EAAiB,CAAC,EACjD,EAAW,EAEjB,IAAK,IAAM,KAAO,EAAS,QACzB,EAAI,SAAW,EAAS,SAAS,EAAI,KAAK,CAE9C,MAAW,EACT,EAAM,QAAU,EAAQ,EAExB,EAAmE,MACjE,GAAK,KAAO,GAAK,OAAO,CAAqC,CAEnE,CAAC,EAED,MAAsB,EAAI,QAAQ,CAAC,EAMnC,EACE,EAAA,OAAO,EAHS,EAAW,SAAW,QAGf,GAAa,CAClC,IAAM,EAAS,EAAE,OAEjB,GAAI,EAAe,CACjB,IAAM,EAAW,EAAE,OAGnB,EAA6B,MAFd,MAAM,KAAK,EAAS,eAAe,CAAC,CAAC,IAAK,GAAQ,EAAI,KAEhC,CACvC,MAAW,EACT,EAAO,MAAQ,EAAO,QACb,EACT,EAAO,MAAS,EAAO,QAAU,GAAK,EAAI,OAAO,EAAO,KAAK,EAE7D,EAAO,MAAQ,EAAO,KAE1B,CAAC,CACH,CACF,CAAC,CACH"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { type Signal } from '@vielzeug/ripple';
|
|
2
|
-
import { type SpreadObject } from '../types/bindings';
|
|
3
|
-
/**
|
|
4
|
-
* Two-way binding spread for form inputs.
|
|
5
|
-
* Syncs the signal value to the element's DOM value and back.
|
|
6
|
-
*
|
|
7
|
-
* Supports `type="text"` (default), `type="number"`, `type="range"`,
|
|
8
|
-
* `type="checkbox"`, `<select>` (single-select), and
|
|
9
|
-
* `<select multiple>` (multi-select, `Signal<string[]>`).
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const name = signal('');
|
|
14
|
-
* html`<input type="text" ${model(name)} />`
|
|
15
|
-
*
|
|
16
|
-
* const count = signal(0);
|
|
17
|
-
* html`<input type="number" ${model(count)} />`
|
|
18
|
-
*
|
|
19
|
-
* const checked = signal(false);
|
|
20
|
-
* html`<input type="checkbox" ${model(checked)} />`
|
|
21
|
-
*
|
|
22
|
-
* const selected = signal<string[]>([]);
|
|
23
|
-
* html`<select multiple ${model(selected)}><option value="a">A</option></select>`
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export declare function model<T extends string | number | boolean | null>(source: Signal<T>): SpreadObject;
|
|
27
|
-
export declare function model(source: Signal<string[]>): SpreadObject;
|
|
28
|
-
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/directives/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;AACnG,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC"}
|
package/dist/directives/model.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createSpreadObject as e}from"../types/bindings.js";import{listen as t}from"../utils/dom.js";import{effect as n}from"@vielzeug/ripple";function r(r){return e((e,i)=>{let a=e,o=a.type===`checkbox`,s=a.type===`number`||a.type===`range`,c=e instanceof HTMLSelectElement,l=c&&e.multiple,u=n(()=>{let t=r.value;if(l){let n=Array.isArray(t)?t:[],r=e;for(let e of r.options)e.selected=n.includes(e.value)}else o?a.checked=!!t:e.value=t==null?``:String(t)});i(()=>u.dispose()),i(t(e,c?`change`:`input`,e=>{let t=e.target;if(l){let t=e.target;r.value=Array.from(t.selectedOptions).map(e=>e.value)}else o?r.value=t.checked:s?r.value=t.value===``?0:Number(t.value):r.value=t.value}))})}export{r as model};
|
|
2
|
-
//# sourceMappingURL=model.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","names":[],"sources":["../../src/directives/model.ts"],"sourcesContent":["import { effect as rawEffect, type Signal } from '@vielzeug/ripple';\n\nimport { createSpreadObject, type SpreadObject } from '../types/bindings';\nimport { listen } from '../utils/dom';\n\n/**\n * Two-way binding spread for form inputs.\n * Syncs the signal value to the element's DOM value and back.\n *\n * Supports `type=\"text\"` (default), `type=\"number\"`, `type=\"range\"`,\n * `type=\"checkbox\"`, `<select>` (single-select), and\n * `<select multiple>` (multi-select, `Signal<string[]>`).\n *\n * @example\n * ```ts\n * const name = signal('');\n * html`<input type=\"text\" ${model(name)} />`\n *\n * const count = signal(0);\n * html`<input type=\"number\" ${model(count)} />`\n *\n * const checked = signal(false);\n * html`<input type=\"checkbox\" ${model(checked)} />`\n *\n * const selected = signal<string[]>([]);\n * html`<select multiple ${model(selected)}><option value=\"a\">A</option></select>`\n * ```\n */\nexport function model<T extends string | number | boolean | null>(source: Signal<T>): SpreadObject;\nexport function model(source: Signal<string[]>): SpreadObject;\nexport function model<T extends string | number | boolean | null | string[]>(source: Signal<T>): SpreadObject {\n return createSpreadObject((el, registerCleanup) => {\n const input = el as HTMLInputElement;\n const isCheckbox = input.type === 'checkbox';\n const isNumeric = input.type === 'number' || input.type === 'range';\n const isSelect = el instanceof HTMLSelectElement;\n const isMultiSelect = isSelect && (el as HTMLSelectElement).multiple;\n\n // Signal → DOM\n const sub = rawEffect(() => {\n const v = source.value;\n\n if (isMultiSelect) {\n const selected = Array.isArray(v) ? (v as string[]) : [];\n const selectEl = el as HTMLSelectElement;\n\n for (const opt of selectEl.options) {\n opt.selected = selected.includes(opt.value);\n }\n } else if (isCheckbox) {\n input.checked = Boolean(v);\n } else {\n (el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value =\n v == null ? '' : String(v as string | number | boolean | null);\n }\n });\n\n registerCleanup(() => sub.dispose());\n\n // DOM → Signal\n // <select> fires 'change'; text/number/range/textarea/checkbox fire 'input'.\n const eventName = isSelect ? 'change' : 'input';\n\n registerCleanup(\n listen(el, eventName, (e: Event) => {\n const target = e.target as HTMLInputElement;\n\n if (isMultiSelect) {\n const selectEl = e.target as HTMLSelectElement;\n const values = Array.from(selectEl.selectedOptions).map((opt) => opt.value);\n\n (source as Signal<string[]>).value = values;\n } else if (isCheckbox) {\n source.value = target.checked as T;\n } else if (isNumeric) {\n source.value = (target.value === '' ? 0 : Number(target.value)) as T;\n } else {\n source.value = target.value as T;\n }\n }),\n );\n });\n}\n"],"mappings":"6IA8BA,SAAgB,EAA6D,EAAiC,CAC5G,OAAO,GAAoB,EAAI,IAAoB,CACjD,IAAM,EAAQ,EACR,EAAa,EAAM,OAAS,WAC5B,EAAY,EAAM,OAAS,UAAY,EAAM,OAAS,QACtD,EAAW,aAAc,kBACzB,EAAgB,GAAa,EAAyB,SAGtD,EAAM,MAAgB,CAC1B,IAAM,EAAI,EAAO,MAEjB,GAAI,EAAe,CACjB,IAAM,EAAW,MAAM,QAAQ,CAAC,EAAK,EAAiB,CAAC,EACjD,EAAW,EAEjB,IAAK,IAAM,KAAO,EAAS,QACzB,EAAI,SAAW,EAAS,SAAS,EAAI,KAAK,CAE9C,MAAW,EACT,EAAM,QAAU,EAAQ,EAExB,EAAmE,MACjE,GAAK,KAAO,GAAK,OAAO,CAAqC,CAEnE,CAAC,EAED,MAAsB,EAAI,QAAQ,CAAC,EAMnC,EACE,EAAO,EAHS,EAAW,SAAW,QAGf,GAAa,CAClC,IAAM,EAAS,EAAE,OAEjB,GAAI,EAAe,CACjB,IAAM,EAAW,EAAE,OAGnB,EAA6B,MAFd,MAAM,KAAK,EAAS,eAAe,CAAC,CAAC,IAAK,GAAQ,EAAI,KAEhC,CACvC,MAAW,EACT,EAAO,MAAQ,EAAO,QACb,EACT,EAAO,MAAS,EAAO,QAAU,GAAK,EAAI,OAAO,EAAO,KAAK,EAE7D,EAAO,MAAQ,EAAO,KAE1B,CAAC,CACH,CACF,CAAC,CACH"}
|
package/dist/directives/raw.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_dev.cjs"),t=require("../errors.cjs"),n=require("../types/bindings.cjs"),r=require("../utils/dom.cjs");let i=require("@vielzeug/ripple");var a=null,o=!1,s=e=>{a=e,e||(o=!1)},c=()=>{a=null,o=!1},l=t=>a?a(t):(t&&!o&&(o=!0,e.warn(`raw() was called without a sanitizer registered. Passing user-supplied HTML directly to raw() is an XSS risk. Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).`)),t),u=(e,t,n)=>{let r=document.createElement(`template`);r.innerHTML=e;let i=Array.from(r.content.cloneNode(!0).childNodes);for(let e of i)t.insertBefore(e,n);return i};function d(e){if(typeof e==`function`){let t=(0,i.computed)(e);return n.createDirectiveResult((e,n)=>{n(()=>t.dispose()),d(t).mount(e,n)})}return n.createDirectiveResult((n,a)=>{let o=n.parentNode;t.invariant(o,`raw() anchor comment has no parent node`);let s=document.createComment(`raw/end`);if(o.insertBefore(s,n.nextSibling),(0,i.isReactive)(e)){let t=[],n=e,c=(0,i.effect)(()=>{r.removeNodes(t),t=u(l(n.value),o,s)});a(()=>c.dispose()),a(()=>{r.removeNodes(t),s.remove()})}else u(l(e),o,s),a(()=>s.remove())})}exports._resetRawSanitizer=c,exports.raw=d,exports.setRawSanitizer=s;
|
|
2
|
-
//# sourceMappingURL=raw.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"raw.cjs","names":[],"sources":["../../src/directives/raw.ts"],"sourcesContent":["import { computed, effect as rawEffect, isReactive, type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult } from '../types/bindings';\nimport { removeNodes } from '../utils/dom';\n\ntype RawSanitizer = (html: string) => string;\n\nlet _sanitizer: RawSanitizer | null = null;\nlet _warned = false;\n\nexport const setRawSanitizer = (fn: RawSanitizer | null): void => {\n _sanitizer = fn;\n\n if (!fn) _warned = false;\n};\n\n/** @internal */\nexport const _resetRawSanitizer = (): void => {\n _sanitizer = null;\n _warned = false;\n};\n\nconst sanitize = (value: string): string => {\n if (_sanitizer) return _sanitizer(value);\n\n if (value && !_warned) {\n _warned = true;\n warn(\n 'raw() was called without a sanitizer registered. ' +\n 'Passing user-supplied HTML directly to raw() is an XSS risk. ' +\n 'Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).',\n );\n }\n\n return value;\n};\n\nconst parseRaw = (html: string, parent: ParentNode, insertBefore: Node): Node[] => {\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const nodes = Array.from(tpl.content.cloneNode(true).childNodes);\n\n for (const node of nodes) parent.insertBefore(node, insertBefore);\n\n return nodes;\n};\n\n/**\n * Renders a trusted HTML string without escaping as a DirectiveResult.\n * Only use with content you control — passing user-supplied strings\n * directly is an XSS risk. Register a sanitizer with setRawSanitizer()\n * to add a runtime safety net.\n *\n * Supports static strings, signals, and getter functions `() => string`.\n * When reactive, the DOM is updated in-place whenever the value changes.\n */\nexport function raw(value: (() => string) | string | Signal<string> | Readable<string>): DirectiveResult {\n if (typeof value === 'function') {\n const c = computed(value);\n\n return createDirectiveResult((anchor, registerCleanup) => {\n registerCleanup(() => c.dispose());\n raw(c).mount(anchor, registerCleanup);\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'raw() anchor comment has no parent node');\n\n const endMarker = document.createComment('raw/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n if (isReactive(value)) {\n let currentNodes: Node[] = [];\n const src = value as Readable<string>;\n\n const stop = rawEffect(() => {\n removeNodes(currentNodes);\n currentNodes = parseRaw(sanitize(src.value), parent, endMarker);\n });\n\n registerCleanup(() => stop.dispose());\n registerCleanup(() => {\n removeNodes(currentNodes);\n endMarker.remove();\n });\n } else {\n parseRaw(sanitize(value), parent, endMarker);\n\n registerCleanup(() => endMarker.remove());\n }\n });\n}\n"],"mappings":"6JASA,IAAI,EAAkC,KAClC,EAAU,GAED,EAAmB,GAAkC,CAChE,EAAa,EAER,IAAI,EAAU,GACrB,EAGa,MAAiC,CAC5C,EAAa,KACb,EAAU,EACZ,EAEM,EAAY,GACZ,EAAmB,EAAW,CAAK,GAEnC,GAAS,CAAC,IACZ,EAAU,GACV,EAAA,KACE,uMAGF,GAGK,GAGH,GAAY,EAAc,EAAoB,IAA+B,CACjF,IAAM,EAAM,SAAS,cAAc,UAAU,EAE7C,EAAI,UAAY,EAEhB,IAAM,EAAQ,MAAM,KAAK,EAAI,QAAQ,UAAU,EAAI,CAAC,CAAC,UAAU,EAE/D,IAAK,IAAM,KAAQ,EAAO,EAAO,aAAa,EAAM,CAAY,EAEhE,OAAO,CACT,EAWA,SAAgB,EAAI,EAAqF,CACvG,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,GAAA,EAAA,EAAA,SAAA,CAAa,CAAK,EAExB,OAAO,EAAA,uBAAuB,EAAQ,IAAoB,CACxD,MAAsB,EAAE,QAAQ,CAAC,EACjC,EAAI,CAAC,CAAC,CAAC,MAAM,EAAQ,CAAe,CACtC,CAAC,CACH,CAEA,OAAO,EAAA,uBAAuB,EAAQ,IAAoB,CACxD,IAAM,EAAS,EAAO,WAEtB,EAAA,UAAU,EAAQ,yCAAyC,EAE3D,IAAM,EAAY,SAAS,cAAc,SAAS,EAIlD,GAFA,EAAO,aAAa,EAAW,EAAO,WAAW,GAEjD,EAAA,EAAA,WAAA,CAAe,CAAK,EAAG,CACrB,IAAI,EAAuB,CAAC,EACtB,EAAM,EAEN,GAAA,EAAA,EAAA,OAAA,KAAuB,CAC3B,EAAA,YAAY,CAAY,EACxB,EAAe,EAAS,EAAS,EAAI,KAAK,EAAG,EAAQ,CAAS,CAChE,CAAC,EAED,MAAsB,EAAK,QAAQ,CAAC,EACpC,MAAsB,CACpB,EAAA,YAAY,CAAY,EACxB,EAAU,OAAO,CACnB,CAAC,CACH,MACE,EAAS,EAAS,CAAK,EAAG,EAAQ,CAAS,EAE3C,MAAsB,EAAU,OAAO,CAAC,CAE5C,CAAC,CACH"}
|
package/dist/directives/raw.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type Readable, type Signal } from '@vielzeug/ripple';
|
|
2
|
-
import { type DirectiveResult } from '../types/bindings';
|
|
3
|
-
type RawSanitizer = (html: string) => string;
|
|
4
|
-
export declare const setRawSanitizer: (fn: RawSanitizer | null) => void;
|
|
5
|
-
/**
|
|
6
|
-
* Renders a trusted HTML string without escaping as a DirectiveResult.
|
|
7
|
-
* Only use with content you control — passing user-supplied strings
|
|
8
|
-
* directly is an XSS risk. Register a sanitizer with setRawSanitizer()
|
|
9
|
-
* to add a runtime safety net.
|
|
10
|
-
*
|
|
11
|
-
* Supports static strings, signals, and getter functions `() => string`.
|
|
12
|
-
* When reactive, the DOM is updated in-place whenever the value changes.
|
|
13
|
-
*/
|
|
14
|
-
export declare function raw(value: (() => string) | string | Signal<string> | Readable<string>): DirectiveResult;
|
|
15
|
-
export {};
|
|
16
|
-
//# sourceMappingURL=raw.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/directives/raw.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAIzG,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGhF,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAK7C,eAAO,MAAM,eAAe,GAAI,IAAI,YAAY,GAAG,IAAI,KAAG,IAIzD,CAAC;AAmCF;;;;;;;;GAQG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,eAAe,CAuCvG"}
|
package/dist/directives/raw.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{warn as e}from"../_dev.js";import{invariant as t}from"../errors.js";import{createDirectiveResult as n}from"../types/bindings.js";import{removeNodes as r}from"../utils/dom.js";import{computed as i,effect as a,isReactive as o}from"@vielzeug/ripple";var s=null,c=!1,l=e=>{s=e,e||(c=!1)},u=()=>{s=null,c=!1},d=t=>s?s(t):(t&&!c&&(c=!0,e(`raw() was called without a sanitizer registered. Passing user-supplied HTML directly to raw() is an XSS risk. Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).`)),t),f=(e,t,n)=>{let r=document.createElement(`template`);r.innerHTML=e;let i=Array.from(r.content.cloneNode(!0).childNodes);for(let e of i)t.insertBefore(e,n);return i};function p(e){if(typeof e==`function`){let t=i(e);return n((e,n)=>{n(()=>t.dispose()),p(t).mount(e,n)})}return n((n,i)=>{let s=n.parentNode;t(s,`raw() anchor comment has no parent node`);let c=document.createComment(`raw/end`);if(s.insertBefore(c,n.nextSibling),o(e)){let t=[],n=e,o=a(()=>{r(t),t=f(d(n.value),s,c)});i(()=>o.dispose()),i(()=>{r(t),c.remove()})}else f(d(e),s,c),i(()=>c.remove())})}export{u as _resetRawSanitizer,p as raw,l as setRawSanitizer};
|
|
2
|
-
//# sourceMappingURL=raw.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"raw.js","names":[],"sources":["../../src/directives/raw.ts"],"sourcesContent":["import { computed, effect as rawEffect, isReactive, type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult } from '../types/bindings';\nimport { removeNodes } from '../utils/dom';\n\ntype RawSanitizer = (html: string) => string;\n\nlet _sanitizer: RawSanitizer | null = null;\nlet _warned = false;\n\nexport const setRawSanitizer = (fn: RawSanitizer | null): void => {\n _sanitizer = fn;\n\n if (!fn) _warned = false;\n};\n\n/** @internal */\nexport const _resetRawSanitizer = (): void => {\n _sanitizer = null;\n _warned = false;\n};\n\nconst sanitize = (value: string): string => {\n if (_sanitizer) return _sanitizer(value);\n\n if (value && !_warned) {\n _warned = true;\n warn(\n 'raw() was called without a sanitizer registered. ' +\n 'Passing user-supplied HTML directly to raw() is an XSS risk. ' +\n 'Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).',\n );\n }\n\n return value;\n};\n\nconst parseRaw = (html: string, parent: ParentNode, insertBefore: Node): Node[] => {\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const nodes = Array.from(tpl.content.cloneNode(true).childNodes);\n\n for (const node of nodes) parent.insertBefore(node, insertBefore);\n\n return nodes;\n};\n\n/**\n * Renders a trusted HTML string without escaping as a DirectiveResult.\n * Only use with content you control — passing user-supplied strings\n * directly is an XSS risk. Register a sanitizer with setRawSanitizer()\n * to add a runtime safety net.\n *\n * Supports static strings, signals, and getter functions `() => string`.\n * When reactive, the DOM is updated in-place whenever the value changes.\n */\nexport function raw(value: (() => string) | string | Signal<string> | Readable<string>): DirectiveResult {\n if (typeof value === 'function') {\n const c = computed(value);\n\n return createDirectiveResult((anchor, registerCleanup) => {\n registerCleanup(() => c.dispose());\n raw(c).mount(anchor, registerCleanup);\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'raw() anchor comment has no parent node');\n\n const endMarker = document.createComment('raw/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n if (isReactive(value)) {\n let currentNodes: Node[] = [];\n const src = value as Readable<string>;\n\n const stop = rawEffect(() => {\n removeNodes(currentNodes);\n currentNodes = parseRaw(sanitize(src.value), parent, endMarker);\n });\n\n registerCleanup(() => stop.dispose());\n registerCleanup(() => {\n removeNodes(currentNodes);\n endMarker.remove();\n });\n } else {\n parseRaw(sanitize(value), parent, endMarker);\n\n registerCleanup(() => endMarker.remove());\n }\n });\n}\n"],"mappings":"8PASA,IAAI,EAAkC,KAClC,EAAU,GAED,EAAmB,GAAkC,CAChE,EAAa,EAER,IAAI,EAAU,GACrB,EAGa,MAAiC,CAC5C,EAAa,KACb,EAAU,EACZ,EAEM,EAAY,GACZ,EAAmB,EAAW,CAAK,GAEnC,GAAS,CAAC,IACZ,EAAU,GACV,EACE,uMAGF,GAGK,GAGH,GAAY,EAAc,EAAoB,IAA+B,CACjF,IAAM,EAAM,SAAS,cAAc,UAAU,EAE7C,EAAI,UAAY,EAEhB,IAAM,EAAQ,MAAM,KAAK,EAAI,QAAQ,UAAU,EAAI,CAAC,CAAC,UAAU,EAE/D,IAAK,IAAM,KAAQ,EAAO,EAAO,aAAa,EAAM,CAAY,EAEhE,OAAO,CACT,EAWA,SAAgB,EAAI,EAAqF,CACvG,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,EAAI,EAAS,CAAK,EAExB,OAAO,GAAuB,EAAQ,IAAoB,CACxD,MAAsB,EAAE,QAAQ,CAAC,EACjC,EAAI,CAAC,CAAC,CAAC,MAAM,EAAQ,CAAe,CACtC,CAAC,CACH,CAEA,OAAO,GAAuB,EAAQ,IAAoB,CACxD,IAAM,EAAS,EAAO,WAEtB,EAAU,EAAQ,yCAAyC,EAE3D,IAAM,EAAY,SAAS,cAAc,SAAS,EAIlD,GAFA,EAAO,aAAa,EAAW,EAAO,WAAW,EAE7C,EAAW,CAAK,EAAG,CACrB,IAAI,EAAuB,CAAC,EACtB,EAAM,EAEN,EAAO,MAAgB,CAC3B,EAAY,CAAY,EACxB,EAAe,EAAS,EAAS,EAAI,KAAK,EAAG,EAAQ,CAAS,CAChE,CAAC,EAED,MAAsB,EAAK,QAAQ,CAAC,EACpC,MAAsB,CACpB,EAAY,CAAY,EACxB,EAAU,OAAO,CACnB,CAAC,CACH,MACE,EAAS,EAAS,CAAK,EAAG,EAAQ,CAAS,EAE3C,MAAsB,EAAU,OAAO,CAAC,CAE5C,CAAC,CACH"}
|