@vielzeug/craftit 2.0.0 → 2.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.
@@ -1,2 +1,2 @@
1
- require(`@vielzeug/stateit`);function e(){return{value:null}}function t(){return[]}function n(e,t=[]){return{__bindings:t,__html:e,toString(){return e}}}function r(e){return typeof e==`string`?{bindings:[],html:e}:{bindings:e.__bindings,html:e.__html}}var i=Symbol(`craftit.eachSignal`);exports.EACH_SIGNAL=i,exports.extractResult=r,exports.htmlResult=n,exports.ref=e,exports.refs=t;
1
+ require(`@vielzeug/stateit`);var e=Symbol(`craftit.htmlResultBrand`);function t(){return{value:null}}function n(){return[]}function r(t,n=[]){let r={__bindings:n,__html:t,toString(){return t}};return Object.defineProperty(r,e,{configurable:!1,enumerable:!1,value:!0,writable:!1}),r}var i=t=>typeof t==`object`&&!!t&&t[e]===!0;function a(e){return typeof e==`string`?{bindings:[],html:e}:{bindings:e.__bindings,html:e.__html}}var o=Symbol(`craftit.eachSignal`);exports.EACH_SIGNAL=o,exports.extractResult=a,exports.htmlResult=r,exports.isHtmlResult=i,exports.ref=t,exports.refs=n;
2
2
  //# sourceMappingURL=internal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.cjs","names":[],"sources":["../../src/core/internal.ts"],"sourcesContent":["/**\n * @internal — Binding type system and engine internals.\n *\n * These types define the contract between the template compiler and binding engine.\n * They are NOT part of the public API and importing directly is an unstable contract.\n *\n * Public-facing types (HTMLResult, Directive, Ref, RefCallback, Refs) are\n * re-exported from the main entry point.\n */\n\nimport { type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// REF TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Ref<T extends Element> {\n value: T | null;\n}\n\nexport function ref<T extends Element>(): Ref<T> {\n return { value: null };\n}\n\nexport type Refs<T extends Element> = T[];\n\nexport function refs<T extends Element>(): Refs<T> {\n return [];\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// HTML RESULT\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type HTMLResult = {\n __bindings: Binding[];\n __html: string;\n toString(): string;\n};\n\n/** @internal — construct an HTMLResult from a pre-built html string and bindings. */\nexport function htmlResult(html: string, bindings: Binding[] = []): HTMLResult {\n return {\n __bindings: bindings,\n __html: html,\n toString() {\n return html;\n },\n };\n}\n\n/** @internal — extract html and bindings from a string or HTMLResult. */\nexport function extractResult(v: string | HTMLResult): { bindings: Binding[]; html: string } {\n return typeof v === 'string' ? { bindings: [], html: v } : { bindings: v.__bindings, html: v.__html };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DIRECTIVES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DirectiveContext {\n /** The cleanup registration function for the component. */\n registerCleanup: (fn: () => void) => void;\n}\n\nexport interface Directive {\n /** Invoked when the element is mounted in the DOM. */\n mount?(el: HTMLElement, context: DirectiveContext): void;\n /** Invoked by the template engine to render content (interpolation directives). */\n render?(): HTMLResult | string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// BINDING TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type TextBinding = {\n signal: ReadonlySignal<unknown>;\n type: 'text';\n uid: string;\n};\n\nexport type AttrBinding = {\n mode: 'bool' | 'attr';\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'attr';\n uid: string;\n value?: unknown;\n};\n\nexport type PropBinding = {\n /** Optional writable source used for native two-way bridge (.value/.checked). */\n model?: Signal<unknown>;\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'prop';\n uid: string;\n value?: unknown;\n};\n\nexport type EventBinding = {\n handler: (e: Event) => void;\n modifiers?: {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n prevent?: boolean;\n self?: boolean;\n stop?: boolean;\n };\n name: string;\n type: 'event';\n uid: string;\n};\n\nexport type RefBinding = {\n ref: Ref<Element> | Refs<Element> | RefCallback<Element>;\n type: 'ref';\n uid: string;\n};\n\nexport type CallbackBinding = {\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => void;\n type: 'callback';\n uid: string;\n};\n\nexport type HtmlBinding = {\n keyed?: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n type: 'html';\n uid: string;\n};\n\nexport type Binding =\n | TextBinding\n | AttrBinding\n | PropBinding\n | EventBinding\n | RefBinding\n | CallbackBinding\n | HtmlBinding;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// INTERNAL MARKERS & CONSTANTS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** @internal — opaque marker for each() reactive results. */\nexport const EACH_SIGNAL: unique symbol = Symbol('craftit.eachSignal');\n\n/** @internal — binding element identifier attribute. */\nexport const CF_ID_ATTR = 'u';\n"],"mappings":"6BAoBA,SAAgB,GAAiC,CAC/C,MAAO,CAAE,MAAO,KAAM,CAKxB,SAAgB,GAAmC,CACjD,MAAO,EAAE,CAgBX,SAAgB,EAAW,EAAc,EAAsB,EAAE,CAAc,CAC7E,MAAO,CACL,WAAY,EACZ,OAAQ,EACR,UAAW,CACT,OAAO,GAEV,CAIH,SAAgB,EAAc,EAA+D,CAC3F,OAAO,OAAO,GAAM,SAAW,CAAE,SAAU,EAAE,CAAE,KAAM,EAAG,CAAG,CAAE,SAAU,EAAE,WAAY,KAAM,EAAE,OAAQ,CAqGvG,IAAa,EAA6B,OAAO,qBAAqB"}
1
+ {"version":3,"file":"internal.cjs","names":[],"sources":["../../src/core/internal.ts"],"sourcesContent":["/**\n * @internal — Binding type system and engine internals.\n *\n * These types define the contract between the template compiler and binding engine.\n * They are NOT part of the public API and importing directly is an unstable contract.\n *\n * Public-facing types (HTMLResult, Directive, Ref, RefCallback, Refs) are\n * re-exported from the main entry point.\n */\n\nimport { type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nconst HTML_RESULT_BRAND: unique symbol = Symbol('craftit.htmlResultBrand');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// REF TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Ref<T extends Element> {\n value: T | null;\n}\n\nexport function ref<T extends Element>(): Ref<T> {\n return { value: null };\n}\n\nexport type Refs<T extends Element> = T[];\n\nexport function refs<T extends Element>(): Refs<T> {\n return [];\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// HTML RESULT\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface HTMLResult {\n __bindings: Binding[];\n __html: string;\n toString(): string;\n}\n\n/** @internal — construct an HTMLResult from a pre-built html string and bindings. */\nexport function htmlResult(html: string, bindings: Binding[] = []): HTMLResult {\n const result = {\n __bindings: bindings,\n __html: html,\n toString() {\n return html;\n },\n };\n\n Object.defineProperty(result, HTML_RESULT_BRAND, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n\n return result as HTMLResult;\n}\n\n/** @internal — strict HTMLResult runtime type guard. */\nexport const isHtmlResult = (value: unknown): value is HTMLResult =>\n typeof value === 'object' && !!value && (value as Record<symbol, unknown>)[HTML_RESULT_BRAND] === true;\n\n/** @internal — extract html and bindings from a string or HTMLResult. */\nexport function extractResult(v: string | HTMLResult): { bindings: Binding[]; html: string } {\n return typeof v === 'string' ? { bindings: [], html: v } : { bindings: v.__bindings, html: v.__html };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DIRECTIVES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DirectiveContext {\n /** The cleanup registration function for the component. */\n registerCleanup: (fn: () => void) => void;\n}\n\nexport interface Directive {\n /** Invoked when the element is mounted in the DOM. */\n mount?(el: HTMLElement, context: DirectiveContext): void;\n /** Invoked by the template engine to render content (interpolation directives). */\n render?(): HTMLResult | string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// BINDING TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type TextBinding = {\n signal: ReadonlySignal<unknown>;\n type: 'text';\n uid: string;\n};\n\nexport type AttrBinding = {\n mode: 'bool' | 'attr';\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'attr';\n uid: string;\n value?: unknown;\n};\n\nexport type PropBinding = {\n /** Optional writable source used for native two-way bridge (.value/.checked). */\n model?: Signal<unknown>;\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'prop';\n uid: string;\n value?: unknown;\n};\n\nexport type EventBinding = {\n handler: (e: Event) => void;\n modifiers?: {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n prevent?: boolean;\n self?: boolean;\n stop?: boolean;\n };\n name: string;\n type: 'event';\n uid: string;\n};\n\nexport type RefBinding = {\n ref: Ref<Element> | Refs<Element> | RefCallback<Element>;\n type: 'ref';\n uid: string;\n};\n\nexport type CallbackBinding = {\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => void;\n type: 'callback';\n uid: string;\n};\n\nexport type HtmlBinding = {\n keyed?: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n type: 'html';\n uid: string;\n};\n\nexport type Binding =\n | TextBinding\n | AttrBinding\n | PropBinding\n | EventBinding\n | RefBinding\n | CallbackBinding\n | HtmlBinding;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// INTERNAL MARKERS & CONSTANTS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** @internal — opaque marker for each() reactive results. */\nexport const EACH_SIGNAL: unique symbol = Symbol('craftit.eachSignal');\n\n/** @internal — binding element identifier attribute. */\nexport const CF_ID_ATTR = 'u';\n"],"mappings":"6BAYA,IAAM,EAAmC,OAAO,0BAA0B,CAU1E,SAAgB,GAAiC,CAC/C,MAAO,CAAE,MAAO,KAAM,CAKxB,SAAgB,GAAmC,CACjD,MAAO,EAAE,CAgBX,SAAgB,EAAW,EAAc,EAAsB,EAAE,CAAc,CAC7E,IAAM,EAAS,CACb,WAAY,EACZ,OAAQ,EACR,UAAW,CACT,OAAO,GAEV,CASD,OAPA,OAAO,eAAe,EAAQ,EAAmB,CAC/C,aAAc,GACd,WAAY,GACZ,MAAO,GACP,SAAU,GACX,CAAC,CAEK,EAIT,IAAa,EAAgB,GAC3B,OAAO,GAAU,UAAY,CAAC,CAAC,GAAU,EAAkC,KAAuB,GAGpG,SAAgB,EAAc,EAA+D,CAC3F,OAAO,OAAO,GAAM,SAAW,CAAE,SAAU,EAAE,CAAE,KAAM,EAAG,CAAG,CAAE,SAAU,EAAE,WAAY,KAAM,EAAE,OAAQ,CAqGvG,IAAa,EAA6B,OAAO,qBAAqB"}
@@ -15,13 +15,15 @@ export declare function ref<T extends Element>(): Ref<T>;
15
15
  export type Refs<T extends Element> = T[];
16
16
  export declare function refs<T extends Element>(): Refs<T>;
17
17
  export type RefCallback<T extends Element> = (el: T | null) => void;
18
- export type HTMLResult = {
18
+ export interface HTMLResult {
19
19
  __bindings: Binding[];
20
20
  __html: string;
21
21
  toString(): string;
22
- };
22
+ }
23
23
  /** @internal — construct an HTMLResult from a pre-built html string and bindings. */
24
24
  export declare function htmlResult(html: string, bindings?: Binding[]): HTMLResult;
25
+ /** @internal — strict HTMLResult runtime type guard. */
26
+ export declare const isHtmlResult: (value: unknown) => value is HTMLResult;
25
27
  /** @internal — extract html and bindings from a string or HTMLResult. */
26
28
  export declare function extractResult(v: string | HTMLResult): {
27
29
  bindings: Binding[];
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/core/internal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/core/internal.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"@vielzeug/stateit";function e(){return{value:null}}function t(){return[]}function n(e,t=[]){return{__bindings:t,__html:e,toString(){return e}}}function r(e){return typeof e==`string`?{bindings:[],html:e}:{bindings:e.__bindings,html:e.__html}}var i=Symbol(`craftit.eachSignal`);export{i as EACH_SIGNAL,r as extractResult,n as htmlResult,e as ref,t as refs};
1
+ import"@vielzeug/stateit";var e=Symbol(`craftit.htmlResultBrand`);function t(){return{value:null}}function n(){return[]}function r(t,n=[]){let r={__bindings:n,__html:t,toString(){return t}};return Object.defineProperty(r,e,{configurable:!1,enumerable:!1,value:!0,writable:!1}),r}var i=t=>typeof t==`object`&&!!t&&t[e]===!0;function a(e){return typeof e==`string`?{bindings:[],html:e}:{bindings:e.__bindings,html:e.__html}}var o=Symbol(`craftit.eachSignal`);export{o as EACH_SIGNAL,a as extractResult,r as htmlResult,i as isHtmlResult,t as ref,n as refs};
2
2
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","names":[],"sources":["../../src/core/internal.ts"],"sourcesContent":["/**\n * @internal — Binding type system and engine internals.\n *\n * These types define the contract between the template compiler and binding engine.\n * They are NOT part of the public API and importing directly is an unstable contract.\n *\n * Public-facing types (HTMLResult, Directive, Ref, RefCallback, Refs) are\n * re-exported from the main entry point.\n */\n\nimport { type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// REF TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Ref<T extends Element> {\n value: T | null;\n}\n\nexport function ref<T extends Element>(): Ref<T> {\n return { value: null };\n}\n\nexport type Refs<T extends Element> = T[];\n\nexport function refs<T extends Element>(): Refs<T> {\n return [];\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// HTML RESULT\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type HTMLResult = {\n __bindings: Binding[];\n __html: string;\n toString(): string;\n};\n\n/** @internal — construct an HTMLResult from a pre-built html string and bindings. */\nexport function htmlResult(html: string, bindings: Binding[] = []): HTMLResult {\n return {\n __bindings: bindings,\n __html: html,\n toString() {\n return html;\n },\n };\n}\n\n/** @internal — extract html and bindings from a string or HTMLResult. */\nexport function extractResult(v: string | HTMLResult): { bindings: Binding[]; html: string } {\n return typeof v === 'string' ? { bindings: [], html: v } : { bindings: v.__bindings, html: v.__html };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DIRECTIVES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DirectiveContext {\n /** The cleanup registration function for the component. */\n registerCleanup: (fn: () => void) => void;\n}\n\nexport interface Directive {\n /** Invoked when the element is mounted in the DOM. */\n mount?(el: HTMLElement, context: DirectiveContext): void;\n /** Invoked by the template engine to render content (interpolation directives). */\n render?(): HTMLResult | string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// BINDING TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type TextBinding = {\n signal: ReadonlySignal<unknown>;\n type: 'text';\n uid: string;\n};\n\nexport type AttrBinding = {\n mode: 'bool' | 'attr';\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'attr';\n uid: string;\n value?: unknown;\n};\n\nexport type PropBinding = {\n /** Optional writable source used for native two-way bridge (.value/.checked). */\n model?: Signal<unknown>;\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'prop';\n uid: string;\n value?: unknown;\n};\n\nexport type EventBinding = {\n handler: (e: Event) => void;\n modifiers?: {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n prevent?: boolean;\n self?: boolean;\n stop?: boolean;\n };\n name: string;\n type: 'event';\n uid: string;\n};\n\nexport type RefBinding = {\n ref: Ref<Element> | Refs<Element> | RefCallback<Element>;\n type: 'ref';\n uid: string;\n};\n\nexport type CallbackBinding = {\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => void;\n type: 'callback';\n uid: string;\n};\n\nexport type HtmlBinding = {\n keyed?: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n type: 'html';\n uid: string;\n};\n\nexport type Binding =\n | TextBinding\n | AttrBinding\n | PropBinding\n | EventBinding\n | RefBinding\n | CallbackBinding\n | HtmlBinding;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// INTERNAL MARKERS & CONSTANTS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** @internal — opaque marker for each() reactive results. */\nexport const EACH_SIGNAL: unique symbol = Symbol('craftit.eachSignal');\n\n/** @internal — binding element identifier attribute. */\nexport const CF_ID_ATTR = 'u';\n"],"mappings":"0BAoBA,SAAgB,GAAiC,CAC/C,MAAO,CAAE,MAAO,KAAM,CAKxB,SAAgB,GAAmC,CACjD,MAAO,EAAE,CAgBX,SAAgB,EAAW,EAAc,EAAsB,EAAE,CAAc,CAC7E,MAAO,CACL,WAAY,EACZ,OAAQ,EACR,UAAW,CACT,OAAO,GAEV,CAIH,SAAgB,EAAc,EAA+D,CAC3F,OAAO,OAAO,GAAM,SAAW,CAAE,SAAU,EAAE,CAAE,KAAM,EAAG,CAAG,CAAE,SAAU,EAAE,WAAY,KAAM,EAAE,OAAQ,CAqGvG,IAAa,EAA6B,OAAO,qBAAqB"}
1
+ {"version":3,"file":"internal.js","names":[],"sources":["../../src/core/internal.ts"],"sourcesContent":["/**\n * @internal — Binding type system and engine internals.\n *\n * These types define the contract between the template compiler and binding engine.\n * They are NOT part of the public API and importing directly is an unstable contract.\n *\n * Public-facing types (HTMLResult, Directive, Ref, RefCallback, Refs) are\n * re-exported from the main entry point.\n */\n\nimport { type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nconst HTML_RESULT_BRAND: unique symbol = Symbol('craftit.htmlResultBrand');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// REF TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Ref<T extends Element> {\n value: T | null;\n}\n\nexport function ref<T extends Element>(): Ref<T> {\n return { value: null };\n}\n\nexport type Refs<T extends Element> = T[];\n\nexport function refs<T extends Element>(): Refs<T> {\n return [];\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// HTML RESULT\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface HTMLResult {\n __bindings: Binding[];\n __html: string;\n toString(): string;\n}\n\n/** @internal — construct an HTMLResult from a pre-built html string and bindings. */\nexport function htmlResult(html: string, bindings: Binding[] = []): HTMLResult {\n const result = {\n __bindings: bindings,\n __html: html,\n toString() {\n return html;\n },\n };\n\n Object.defineProperty(result, HTML_RESULT_BRAND, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n\n return result as HTMLResult;\n}\n\n/** @internal — strict HTMLResult runtime type guard. */\nexport const isHtmlResult = (value: unknown): value is HTMLResult =>\n typeof value === 'object' && !!value && (value as Record<symbol, unknown>)[HTML_RESULT_BRAND] === true;\n\n/** @internal — extract html and bindings from a string or HTMLResult. */\nexport function extractResult(v: string | HTMLResult): { bindings: Binding[]; html: string } {\n return typeof v === 'string' ? { bindings: [], html: v } : { bindings: v.__bindings, html: v.__html };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DIRECTIVES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DirectiveContext {\n /** The cleanup registration function for the component. */\n registerCleanup: (fn: () => void) => void;\n}\n\nexport interface Directive {\n /** Invoked when the element is mounted in the DOM. */\n mount?(el: HTMLElement, context: DirectiveContext): void;\n /** Invoked by the template engine to render content (interpolation directives). */\n render?(): HTMLResult | string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// BINDING TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type TextBinding = {\n signal: ReadonlySignal<unknown>;\n type: 'text';\n uid: string;\n};\n\nexport type AttrBinding = {\n mode: 'bool' | 'attr';\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'attr';\n uid: string;\n value?: unknown;\n};\n\nexport type PropBinding = {\n /** Optional writable source used for native two-way bridge (.value/.checked). */\n model?: Signal<unknown>;\n name: string;\n signal?: ReadonlySignal<unknown>;\n type: 'prop';\n uid: string;\n value?: unknown;\n};\n\nexport type EventBinding = {\n handler: (e: Event) => void;\n modifiers?: {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n prevent?: boolean;\n self?: boolean;\n stop?: boolean;\n };\n name: string;\n type: 'event';\n uid: string;\n};\n\nexport type RefBinding = {\n ref: Ref<Element> | Refs<Element> | RefCallback<Element>;\n type: 'ref';\n uid: string;\n};\n\nexport type CallbackBinding = {\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => void;\n type: 'callback';\n uid: string;\n};\n\nexport type HtmlBinding = {\n keyed?: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n type: 'html';\n uid: string;\n};\n\nexport type Binding =\n | TextBinding\n | AttrBinding\n | PropBinding\n | EventBinding\n | RefBinding\n | CallbackBinding\n | HtmlBinding;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// INTERNAL MARKERS & CONSTANTS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** @internal — opaque marker for each() reactive results. */\nexport const EACH_SIGNAL: unique symbol = Symbol('craftit.eachSignal');\n\n/** @internal — binding element identifier attribute. */\nexport const CF_ID_ATTR = 'u';\n"],"mappings":"0BAYA,IAAM,EAAmC,OAAO,0BAA0B,CAU1E,SAAgB,GAAiC,CAC/C,MAAO,CAAE,MAAO,KAAM,CAKxB,SAAgB,GAAmC,CACjD,MAAO,EAAE,CAgBX,SAAgB,EAAW,EAAc,EAAsB,EAAE,CAAc,CAC7E,IAAM,EAAS,CACb,WAAY,EACZ,OAAQ,EACR,UAAW,CACT,OAAO,GAEV,CASD,OAPA,OAAO,eAAe,EAAQ,EAAmB,CAC/C,aAAc,GACd,WAAY,GACZ,MAAO,GACP,SAAU,GACX,CAAC,CAEK,EAIT,IAAa,EAAgB,GAC3B,OAAO,GAAU,UAAY,CAAC,CAAC,GAAU,EAAkC,KAAuB,GAGpG,SAAgB,EAAc,EAA+D,CAC3F,OAAO,OAAO,GAAM,SAAW,CAAE,SAAU,EAAE,CAAE,KAAM,EAAG,CAAG,CAAE,SAAU,EAAE,WAAY,KAAM,EAAE,OAAQ,CAqGvG,IAAa,EAA6B,OAAO,qBAAqB"}
@@ -1,2 +1,2 @@
1
- const e=require(`./internal.cjs`),t=require(`./utilities.cjs`),n=require(`./template-bindings.cjs`);let r=require(`@vielzeug/stateit`);var i=RegExp(`u="([^"]+)"`,`g`),a=e=>typeof e==`object`&&!!e&&`__html`in e,o=e=>e.replace(/>\s+</g,`><`).trim(),s=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],c=new WeakMap,l=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},u=e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of s){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=l(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}},d=e=>{let t=c.get(e);return t||(t=u(e),c.set(e,t)),t},f=()=>{let e=0;return()=>String(e++)},p=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(i,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`<!--${r(t)}-->`)}},m=t=>typeof t!=`object`||!t||!(e.EACH_SIGNAL in t)?null:t[e.EACH_SIGNAL],h=e=>typeof e==`string`?t.escapeHtml(e):e==null?``:a(e)?e.__html:t.escapeHtml(String(e)),g=(e,t)=>{let n={bindings:[],html:``},i=(0,r.signal)(n);return t(()=>{let t=e(),r=Array.isArray(t)?t:[t],o=f(),s=``,c=[];for(let e of r)if(a(e)){let t=p(e,o);s+=t.html,c.push(...t.bindings)}else s+=h(e);let l=c.length!==n.bindings.length||c.some((e,t)=>e!==n.bindings[t]);(s!==n.html||l)&&(n={bindings:c,html:s},i.value=n)}),{bindings:[],signal:i}},_=(e,t)=>{let n=m(e);if(n)return{keyed:!0,signal:n};if(typeof e==`function`&&!(0,r.isSignal)(e)){let{signal:n}=g(e,t);return{keyed:!1,signal:n}}return(0,r.isSignal)(e)&&a(e.value)?{keyed:!1,signal:(0,r.computed)(()=>{let t=e.value;if(!a(t))return{bindings:[],html:String(t)};let n=p(t,f());return{bindings:n.bindings,html:n.html}})}:null},v=()=>{},y=(t,i,s)=>{let c=d(t),l=``,u=[],m=null,g=f(),v=e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`),y=e=>((!m||v(e))&&(m=g()),m),b=()=>{m=null};for(let e=0;e<c.slots.length;e++){let t=c.slots[e],o=i[e];if(t.kind===`event`){if(typeof o==`function`){let e=y(t.prefix);l+=`${t.prefix} u="${e}"`,u.push({handler:o,modifiers:t.modifiers,name:t.name,type:`event`,uid:e})}else l+=t.raw;continue}if(t.kind===`ref`){if(o){let e=y(t.prefix);l+=`${t.prefix} u="${e}"`,u.push({ref:o,type:`ref`,uid:e})}else l+=t.raw;continue}if(t.kind===`specialAttr`){let e=y(t.prefix);l+=`${t.prefix} u="${e}"`,u.push(n.createAttrBinding(t.mode,t.name,e,o));continue}if(t.kind===`prop`){let e=y(t.prefix);l+=`${t.prefix} u="${e}"`,u.push(n.createPropBinding(t.name,e,o));continue}if(t.kind===`plainAttr`){let e=y(t.prefix);l+=`${t.prefix} u="${e}"`,u.push(n.createAttrBinding(`attr`,t.name,e,o));continue}if(typeof o==`object`&&o&&(`mount`in o||`render`in o)){let e=`render`in o,n=e?g():y(t.raw);e?l+=`${t.raw}<!--${n}-->`:l+=`${t.raw} u="${n}"`;let i=o.mount?.bind(o);if(i&&u.push({apply:(e,t)=>{i(e,{registerCleanup:t})},type:`callback`,uid:n}),e){let e=o.render.bind(o),t={bindings:[],html:``},i=(0,r.signal)(t);s(()=>{let n=e(),r=Array.isArray(n)?n:[n],o=f(),s=``,c=[];for(let e of r)if(a(e)){let t=p(e,o);s+=t.html,c.push(...t.bindings)}else s+=h(e);let l=c.length!==t.bindings.length||c.some((e,n)=>e!==t.bindings[n]);(s!==t.html||l)&&(t={bindings:c,html:s},i.value=t)}),u.push({keyed:!1,signal:i,type:`html`,uid:n})}continue}b();let d=_(o,s);if(d){let e=g();l+=`${t.raw}<!--${e}-->`,u.push({keyed:d.keyed,signal:d.signal,type:`html`,uid:e});continue}if(Array.isArray(o)){let e=``;for(let t of o)if(a(t)){let n=p(t,g);e+=n.html,u.push(...n.bindings)}else e+=h(t);l+=t.raw+e;continue}if((0,r.isSignal)(o)){let e=g();l+=`${t.raw}<!--${e}-->`,u.push({signal:o,type:`text`,uid:e})}else if(a(o)){let e=p(o,g);l+=t.raw+e.html,u.push(...e.bindings)}else l+=t.raw+h(o)}return l+=c.tail,e.htmlResult(o(l),u)};exports.compileTemplate=y,exports.resetTemplateCompilerState=v;
1
+ const e=require(`./internal.cjs`),t=require(`./utilities.cjs`),n=require(`./template-bindings.cjs`);let r=require(`@vielzeug/stateit`);var i=RegExp(`u="([^"]+)"`,`g`),a=e=>e.replace(/>\s+</g,`><`).trim(),o=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],s=new WeakMap,c=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},l=e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of o){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=c(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}},u=e=>{let t=s.get(e);return t||(t=l(e),s.set(e,t)),t},d=()=>{let e=0;return()=>String(e++)},f=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(i,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`<!--${r(t)}-->`)}},p=t=>typeof t!=`object`||!t||!(e.EACH_SIGNAL in t)?null:t[e.EACH_SIGNAL],m=n=>typeof n==`string`?t.escapeHtml(n):n==null?``:e.isHtmlResult(n)?n.__html:t.escapeHtml(String(n)),h=(t,n)=>{let i={bindings:[],html:``},a=(0,r.signal)(i);return n(()=>{let n=t(),r=Array.isArray(n)?n:[n],o=d(),s=``,c=[];for(let t of r)if(e.isHtmlResult(t)){let e=f(t,o);s+=e.html,c.push(...e.bindings)}else s+=m(t);let l=c.length!==i.bindings.length||c.some((e,t)=>e!==i.bindings[t]);(s!==i.html||l)&&(i={bindings:c,html:s},a.value=i)}),{bindings:[],signal:a}},g=(t,n)=>{let i=p(t);if(i)return{keyed:!0,signal:i};if(typeof t==`function`&&!(0,r.isSignal)(t)){let{signal:e}=h(t,n);return{keyed:!1,signal:e}}return(0,r.isSignal)(t)&&e.isHtmlResult(t.value)?{keyed:!1,signal:(0,r.computed)(()=>{let n=t.value;if(!e.isHtmlResult(n))return{bindings:[],html:m(n)};let r=f(n,d());return{bindings:r.bindings,html:r.html}})}:null},_=()=>{},v=(t,i,o)=>{let s=u(t),c=``,l=[],p=null,h=d(),_=e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`),v=e=>((!p||_(e))&&(p=h()),p),y=()=>{p=null};for(let t=0;t<s.slots.length;t++){let a=s.slots[t],u=i[t];if(a.kind===`event`){if(typeof u==`function`){let e=v(a.prefix);c+=`${a.prefix} u="${e}"`,l.push({handler:u,modifiers:a.modifiers,name:a.name,type:`event`,uid:e})}else c+=a.raw;continue}if(a.kind===`ref`){if(u){let e=v(a.prefix);c+=`${a.prefix} u="${e}"`,l.push({ref:u,type:`ref`,uid:e})}else c+=a.raw;continue}if(a.kind===`specialAttr`){let e=v(a.prefix);c+=`${a.prefix} u="${e}"`,l.push(n.createAttrBinding(a.mode,a.name,e,u));continue}if(a.kind===`prop`){let e=v(a.prefix);c+=`${a.prefix} u="${e}"`,l.push(n.createPropBinding(a.name,e,u));continue}if(a.kind===`plainAttr`){let e=v(a.prefix);c+=`${a.prefix} u="${e}"`,l.push(n.createAttrBinding(`attr`,a.name,e,u));continue}if(typeof u==`object`&&u&&(`mount`in u||`render`in u)){let t=`render`in u,n=t?h():v(a.raw);t?c+=`${a.raw}<!--${n}-->`:c+=`${a.raw} u="${n}"`;let i=u.mount?.bind(u);if(i&&l.push({apply:(e,t)=>{i(e,{registerCleanup:t})},type:`callback`,uid:n}),t){let t=u.render.bind(u),i={bindings:[],html:``},a=(0,r.signal)(i);o(()=>{let n=t(),r=Array.isArray(n)?n:[n],o=d(),s=``,c=[];for(let t of r)if(e.isHtmlResult(t)){let e=f(t,o);s+=e.html,c.push(...e.bindings)}else s+=m(t);let l=c.length!==i.bindings.length||c.some((e,t)=>e!==i.bindings[t]);(s!==i.html||l)&&(i={bindings:c,html:s},a.value=i)}),l.push({keyed:!1,signal:a,type:`html`,uid:n})}continue}y();let p=g(u,o);if(p){let e=h();c+=`${a.raw}<!--${e}-->`,l.push({keyed:p.keyed,signal:p.signal,type:`html`,uid:e});continue}if(Array.isArray(u)){let t=``;for(let n of u)if(e.isHtmlResult(n)){let e=f(n,h);t+=e.html,l.push(...e.bindings)}else t+=m(n);c+=a.raw+t;continue}if((0,r.isSignal)(u)){let e=h();c+=`${a.raw}<!--${e}-->`,l.push({signal:u,type:`text`,uid:e})}else if(e.isHtmlResult(u)){let e=f(u,h);c+=a.raw+e.html,l.push(...e.bindings)}else c+=a.raw+m(u)}return c+=s.tail,e.htmlResult(a(c),l)};exports.compileTemplate=v,exports.resetTemplateCompilerState=_;
2
2
  //# sourceMappingURL=template-compiler.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"template-compiler.cjs","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst isHtmlResult = (value: unknown): value is HTMLResult => typeof value === 'object' && !!value && '__html' in value;\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: String(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"template-compiler.cjs","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n isHtmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: resolveDirectiveValue(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"template-compiler.d.ts","sourceRoot":"","sources":["../../src/core/template-compiler.ts"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAuPpB,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,oBAAoB,EAC7B,QAAQ,OAAO,EAAE,EACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,KAC/B,UA2LF,CAAC"}
1
+ {"version":3,"file":"template-compiler.d.ts","sourceRoot":"","sources":["../../src/core/template-compiler.ts"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAsPpB,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,oBAAoB,EAC7B,QAAQ,OAAO,EAAE,EACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,KAC/B,UA2LF,CAAC"}
@@ -1,2 +1,2 @@
1
- import{EACH_SIGNAL as e,htmlResult as t}from"./internal.js";import{escapeHtml as n}from"./utilities.js";import{createAttrBinding as r,createPropBinding as i}from"./template-bindings.js";import{computed as a,isSignal as o,signal as s}from"@vielzeug/stateit";var c=RegExp(`u="([^"]+)"`,`g`),l=e=>typeof e==`object`&&!!e&&`__html`in e,u=e=>e.replace(/>\s+</g,`><`).trim(),d=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],f=new WeakMap,p=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},m=e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of d){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=p(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}},h=e=>{let t=f.get(e);return t||(t=m(e),f.set(e,t)),t},g=()=>{let e=0;return()=>String(e++)},_=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(c,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`<!--${r(t)}-->`)}},v=t=>typeof t!=`object`||!t||!(e in t)?null:t[e],y=e=>typeof e==`string`?n(e):e==null?``:l(e)?e.__html:n(String(e)),b=(e,t)=>{let n={bindings:[],html:``},r=s(n);return t(()=>{let t=e(),i=Array.isArray(t)?t:[t],a=g(),o=``,s=[];for(let e of i)if(l(e)){let t=_(e,a);o+=t.html,s.push(...t.bindings)}else o+=y(e);let c=s.length!==n.bindings.length||s.some((e,t)=>e!==n.bindings[t]);(o!==n.html||c)&&(n={bindings:s,html:o},r.value=n)}),{bindings:[],signal:r}},x=(e,t)=>{let n=v(e);if(n)return{keyed:!0,signal:n};if(typeof e==`function`&&!o(e)){let{signal:n}=b(e,t);return{keyed:!1,signal:n}}return o(e)&&l(e.value)?{keyed:!1,signal:a(()=>{let t=e.value;if(!l(t))return{bindings:[],html:String(t)};let n=_(t,g());return{bindings:n.bindings,html:n.html}})}:null},S=()=>{},C=(e,n,a)=>{let c=h(e),d=``,f=[],p=null,m=g(),v=e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`),b=e=>((!p||v(e))&&(p=m()),p),S=()=>{p=null};for(let e=0;e<c.slots.length;e++){let t=c.slots[e],u=n[e];if(t.kind===`event`){if(typeof u==`function`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({handler:u,modifiers:t.modifiers,name:t.name,type:`event`,uid:e})}else d+=t.raw;continue}if(t.kind===`ref`){if(u){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({ref:u,type:`ref`,uid:e})}else d+=t.raw;continue}if(t.kind===`specialAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(r(t.mode,t.name,e,u));continue}if(t.kind===`prop`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(i(t.name,e,u));continue}if(t.kind===`plainAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(r(`attr`,t.name,e,u));continue}if(typeof u==`object`&&u&&(`mount`in u||`render`in u)){let e=`render`in u,n=e?m():b(t.raw);e?d+=`${t.raw}<!--${n}-->`:d+=`${t.raw} u="${n}"`;let r=u.mount?.bind(u);if(r&&f.push({apply:(e,t)=>{r(e,{registerCleanup:t})},type:`callback`,uid:n}),e){let e=u.render.bind(u),t={bindings:[],html:``},r=s(t);a(()=>{let n=e(),i=Array.isArray(n)?n:[n],a=g(),o=``,s=[];for(let e of i)if(l(e)){let t=_(e,a);o+=t.html,s.push(...t.bindings)}else o+=y(e);let c=s.length!==t.bindings.length||s.some((e,n)=>e!==t.bindings[n]);(o!==t.html||c)&&(t={bindings:s,html:o},r.value=t)}),f.push({keyed:!1,signal:r,type:`html`,uid:n})}continue}S();let p=x(u,a);if(p){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({keyed:p.keyed,signal:p.signal,type:`html`,uid:e});continue}if(Array.isArray(u)){let e=``;for(let t of u)if(l(t)){let n=_(t,m);e+=n.html,f.push(...n.bindings)}else e+=y(t);d+=t.raw+e;continue}if(o(u)){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({signal:u,type:`text`,uid:e})}else if(l(u)){let e=_(u,m);d+=t.raw+e.html,f.push(...e.bindings)}else d+=t.raw+y(u)}return d+=c.tail,t(u(d),f)};export{C as compileTemplate,S as resetTemplateCompilerState};
1
+ import{EACH_SIGNAL as e,htmlResult as t,isHtmlResult as n}from"./internal.js";import{escapeHtml as r}from"./utilities.js";import{createAttrBinding as i,createPropBinding as a}from"./template-bindings.js";import{computed as o,isSignal as s,signal as c}from"@vielzeug/stateit";var l=RegExp(`u="([^"]+)"`,`g`),u=e=>e.replace(/>\s+</g,`><`).trim(),d=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],f=new WeakMap,p=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},m=e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of d){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=p(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}},h=e=>{let t=f.get(e);return t||(t=m(e),f.set(e,t)),t},g=()=>{let e=0;return()=>String(e++)},_=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(l,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`<!--${r(t)}-->`)}},v=t=>typeof t!=`object`||!t||!(e in t)?null:t[e],y=e=>typeof e==`string`?r(e):e==null?``:n(e)?e.__html:r(String(e)),b=(e,t)=>{let r={bindings:[],html:``},i=c(r);return t(()=>{let t=e(),a=Array.isArray(t)?t:[t],o=g(),s=``,c=[];for(let e of a)if(n(e)){let t=_(e,o);s+=t.html,c.push(...t.bindings)}else s+=y(e);let l=c.length!==r.bindings.length||c.some((e,t)=>e!==r.bindings[t]);(s!==r.html||l)&&(r={bindings:c,html:s},i.value=r)}),{bindings:[],signal:i}},x=(e,t)=>{let r=v(e);if(r)return{keyed:!0,signal:r};if(typeof e==`function`&&!s(e)){let{signal:n}=b(e,t);return{keyed:!1,signal:n}}return s(e)&&n(e.value)?{keyed:!1,signal:o(()=>{let t=e.value;if(!n(t))return{bindings:[],html:y(t)};let r=_(t,g());return{bindings:r.bindings,html:r.html}})}:null},S=()=>{},C=(e,r,o)=>{let l=h(e),d=``,f=[],p=null,m=g(),v=e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`),b=e=>((!p||v(e))&&(p=m()),p),S=()=>{p=null};for(let e=0;e<l.slots.length;e++){let t=l.slots[e],u=r[e];if(t.kind===`event`){if(typeof u==`function`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({handler:u,modifiers:t.modifiers,name:t.name,type:`event`,uid:e})}else d+=t.raw;continue}if(t.kind===`ref`){if(u){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({ref:u,type:`ref`,uid:e})}else d+=t.raw;continue}if(t.kind===`specialAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(i(t.mode,t.name,e,u));continue}if(t.kind===`prop`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(a(t.name,e,u));continue}if(t.kind===`plainAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(i(`attr`,t.name,e,u));continue}if(typeof u==`object`&&u&&(`mount`in u||`render`in u)){let e=`render`in u,r=e?m():b(t.raw);e?d+=`${t.raw}<!--${r}-->`:d+=`${t.raw} u="${r}"`;let i=u.mount?.bind(u);if(i&&f.push({apply:(e,t)=>{i(e,{registerCleanup:t})},type:`callback`,uid:r}),e){let e=u.render.bind(u),t={bindings:[],html:``},i=c(t);o(()=>{let r=e(),a=Array.isArray(r)?r:[r],o=g(),s=``,c=[];for(let e of a)if(n(e)){let t=_(e,o);s+=t.html,c.push(...t.bindings)}else s+=y(e);let l=c.length!==t.bindings.length||c.some((e,n)=>e!==t.bindings[n]);(s!==t.html||l)&&(t={bindings:c,html:s},i.value=t)}),f.push({keyed:!1,signal:i,type:`html`,uid:r})}continue}S();let p=x(u,o);if(p){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({keyed:p.keyed,signal:p.signal,type:`html`,uid:e});continue}if(Array.isArray(u)){let e=``;for(let t of u)if(n(t)){let n=_(t,m);e+=n.html,f.push(...n.bindings)}else e+=y(t);d+=t.raw+e;continue}if(s(u)){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({signal:u,type:`text`,uid:e})}else if(n(u)){let e=_(u,m);d+=t.raw+e.html,f.push(...e.bindings)}else d+=t.raw+y(u)}return d+=l.tail,t(u(d),f)};export{C as compileTemplate,S as resetTemplateCompilerState};
2
2
  //# sourceMappingURL=template-compiler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"template-compiler.js","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst isHtmlResult = (value: unknown): value is HTMLResult => typeof value === 'object' && !!value && '__html' in value;\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: String(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"template-compiler.js","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n isHtmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: resolveDirectiveValue(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`./runtime-lifecycle.cjs`);var t=0,n=()=>{t=0},r=e=>{for(let t of e)t()},i=(e,t,n)=>{n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},a=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},o=e=>`${e?`${e}-`:`cft-`}${++t}`,s=(e,t)=>{let n=`${e}-${t&&t.trim()?t:o(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},c=(e,t)=>n=>{e()&&t(n)},l=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),u={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},d=e=>String(e).replace(/[&<>"']/g,e=>u[e]),f=()=>{let t=e.currentRuntime().el;return((n,...r)=>{e.fire.custom(t,String(n),r.length>0?{detail:r[0]}:void 0)})},p=function(){return this.content},m=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:p}},h=new Map,g=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=h.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),h.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};exports._resetIdCounter=n,exports.createEmitFn=f,exports.createFormIds=s,exports.createId=o,exports.css=m,exports.escapeHtml=d,exports.guard=c,exports.listen=a,exports.loadStylesheet=g,exports.runAll=r,exports.setAttr=i,exports.toKebab=l;
1
+ const e=require(`./runtime-lifecycle.cjs`);var t=0,n=()=>{t=0},r=e=>{for(let t of e)t()},i=(e,t,n)=>{if(/^on/i.test(t)){e.removeAttribute(t);return}n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},a=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},o=e=>`${e?`${e}-`:`cft-`}${++t}`,s=(e,t)=>{let n=`${e}-${t&&t.trim()?t:o(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},c=(e,t)=>n=>{e()&&t(n)},l=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),u={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},d=e=>String(e).replace(/[&<>"']/g,e=>u[e]),f=()=>{let t=e.currentRuntime().el;return((n,...r)=>{e.fire.custom(t,String(n),r.length>0?{detail:r[0]}:void 0)})},p=function(){return this.content},m=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:p}},h=new Map,g=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=h.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),h.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};exports._resetIdCounter=n,exports.createEmitFn=f,exports.createFormIds=s,exports.createId=o,exports.css=m,exports.escapeHtml=d,exports.guard=c,exports.listen=a,exports.loadStylesheet=g,exports.runAll=r,exports.setAttr=i,exports.toKebab=l;
2
2
  //# sourceMappingURL=utilities.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.cjs","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\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\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"2CAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CACpE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,EAAA,gBAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAA,KAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}
1
+ {"version":3,"file":"utilities.cjs","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n // Avoid inline event-handler attributes (onclick, onerror, ...) to reduce injection risk.\n if (/^on/i.test(name)) {\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\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\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"2CAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CAExE,GAAI,OAAO,KAAK,EAAK,CAAE,CACrB,EAAG,gBAAgB,EAAK,CAExB,OAGE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,EAAA,gBAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAA,KAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/core/utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,iFAAiF;AACjF,eAAO,MAAM,eAAe,QAAO,IAElC,CAAC;AAGF,yDAAyD;AACzD,eAAO,MAAM,MAAM,GAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAG,IAElD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,IAAI,OAAO,EAAE,MAAM,MAAM,EAAE,KAAK,OAAO,KAAG,IAQjE,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,IAAI,WAAW,EACf,MAAM,MAAM,EACZ,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,EACzB,UAAU,uBAAuB,KAChC,CAAC,MAAM,IAAI,CAMb,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,MAA4D,CAAC;AAExG;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,OAAO,MAAM,GAAG,IAAI;;;;;CAUjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GACf,CAAC,SAAS,KAAK,GAAG,KAAK,EAAE,WAAW,MAAM,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAG5F,CAAC;AAEJ,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAA6D,CAAC;AAIpG;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,MAA2D,CAAC;AAMxG,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,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,IAAI,CAAC;IACjD,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,IAAI,CAAC;CAClF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAK,MAAM,CAAC,CAAC,CAM1E,CAAC;AAMF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC;AAMF,eAAO,MAAM,GAAG,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,SAczE,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,aAAa,GAAG,SAAS,KAAG,aAkB1E,CAAC"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/core/utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,iFAAiF;AACjF,eAAO,MAAM,eAAe,QAAO,IAElC,CAAC;AAGF,yDAAyD;AACzD,eAAO,MAAM,MAAM,GAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAG,IAElD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,IAAI,OAAO,EAAE,MAAM,MAAM,EAAE,KAAK,OAAO,KAAG,IAejE,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,IAAI,WAAW,EACf,MAAM,MAAM,EACZ,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,EACzB,UAAU,uBAAuB,KAChC,CAAC,MAAM,IAAI,CAMb,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,MAA4D,CAAC;AAExG;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,OAAO,MAAM,GAAG,IAAI;;;;;CAUjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GACf,CAAC,SAAS,KAAK,GAAG,KAAK,EAAE,WAAW,MAAM,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAG5F,CAAC;AAEJ,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAA6D,CAAC;AAIpG;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,MAA2D,CAAC;AAMxG,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,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,IAAI,CAAC;IACjD,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,IAAI,CAAC;CAClF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAK,MAAM,CAAC,CAAC,CAM1E,CAAC;AAMF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC;AAMF,eAAO,MAAM,GAAG,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,SAczE,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,aAAa,GAAG,SAAS,KAAG,aAkB1E,CAAC"}
@@ -1,2 +1,2 @@
1
- import{currentRuntime as e,fire as t}from"./runtime-lifecycle.js";var n=0,r=()=>{n=0},i=e=>{for(let t of e)t()},a=(e,t,n)=>{n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},o=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},s=e=>`${e?`${e}-`:`cft-`}${++n}`,c=(e,t)=>{let n=`${e}-${t&&t.trim()?t:s(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},l=(e,t)=>n=>{e()&&t(n)},u=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),d={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},f=e=>String(e).replace(/[&<>"']/g,e=>d[e]),p=()=>{let n=e().el;return((e,...r)=>{t.custom(n,String(e),r.length>0?{detail:r[0]}:void 0)})},m=function(){return this.content},h=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:m}},g=new Map,_=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=g.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),g.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};export{r as _resetIdCounter,p as createEmitFn,c as createFormIds,s as createId,h as css,f as escapeHtml,l as guard,o as listen,_ as loadStylesheet,i as runAll,a as setAttr,u as toKebab};
1
+ import{currentRuntime as e,fire as t}from"./runtime-lifecycle.js";var n=0,r=()=>{n=0},i=e=>{for(let t of e)t()},a=(e,t,n)=>{if(/^on/i.test(t)){e.removeAttribute(t);return}n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},o=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},s=e=>`${e?`${e}-`:`cft-`}${++n}`,c=(e,t)=>{let n=`${e}-${t&&t.trim()?t:s(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},l=(e,t)=>n=>{e()&&t(n)},u=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),d={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},f=e=>String(e).replace(/[&<>"']/g,e=>d[e]),p=()=>{let n=e().el;return((e,...r)=>{t.custom(n,String(e),r.length>0?{detail:r[0]}:void 0)})},m=function(){return this.content},h=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:m}},g=new Map,_=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=g.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),g.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};export{r as _resetIdCounter,p as createEmitFn,c as createFormIds,s as createId,h as css,f as escapeHtml,l as guard,o as listen,_ as loadStylesheet,i as runAll,a as setAttr,u as toKebab};
2
2
  //# sourceMappingURL=utilities.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.js","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\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\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"kEAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CACpE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,GAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}
1
+ {"version":3,"file":"utilities.js","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n // Avoid inline event-handler attributes (onclick, onerror, ...) to reduce injection risk.\n if (/^on/i.test(name)) {\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\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\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"kEAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CAExE,GAAI,OAAO,KAAK,EAAK,CAAE,CACrB,EAAG,gBAAgB,EAAK,CAExB,OAGE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,GAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}