balises 0.6.0 → 0.7.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.
- package/README.md +53 -29
- package/dist/balises.esm.js +40 -1
- package/dist/balises.esm.js.map +1 -1
- package/dist/balises.iife.js +40 -1
- package/dist/balises.iife.js.map +1 -1
- package/dist/balises.iife.min.js +1 -1
- package/dist/balises.iife.min.js.map +1 -1
- package/dist/esm/async.js.map +1 -1
- package/dist/esm/each.d.ts +19 -8
- package/dist/esm/each.d.ts.map +1 -1
- package/dist/esm/each.js +173 -36
- package/dist/esm/each.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/parser.js.map +1 -1
- package/dist/esm/signals/computed.js.map +1 -1
- package/dist/esm/signals/context.js.map +1 -1
- package/dist/esm/signals/effect.js.map +1 -1
- package/dist/esm/signals/index.d.ts +1 -1
- package/dist/esm/signals/index.d.ts.map +1 -1
- package/dist/esm/signals/index.js +5 -3
- package/dist/esm/signals/index.js.map +1 -1
- package/dist/esm/signals/signal.d.ts +29 -0
- package/dist/esm/signals/signal.d.ts.map +1 -1
- package/dist/esm/signals/signal.js +39 -0
- package/dist/esm/signals/signal.js.map +1 -1
- package/dist/esm/signals/store.js.map +1 -1
- package/dist/esm/template.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -268,45 +268,59 @@ When rendering lists that change frequently, use `each()` for keyed reconciliati
|
|
|
268
268
|
|
|
269
269
|
**Note:** The `each()` function is opt-in via the `balises/each` import to keep the base bundle small. Use `html.with(eachPlugin)` to enable keyed list support.
|
|
270
270
|
|
|
271
|
+
**Two forms:**
|
|
272
|
+
|
|
273
|
+
1. **Two-arg form** (object reference as key): Render receives raw item. DOM reused only when same object reference appears.
|
|
274
|
+
2. **Three-arg form** (explicit key function): Render receives `ReadonlySignal<T>`. DOM reused when keys match, even with new object references.
|
|
275
|
+
|
|
271
276
|
```ts
|
|
272
277
|
import { html as baseHtml, signal } from "balises";
|
|
273
278
|
import eachPlugin, { each } from "balises/each";
|
|
274
279
|
|
|
275
280
|
const html = baseHtml.with(eachPlugin);
|
|
276
281
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
282
|
+
// Three-arg form: explicit key, receives ReadonlySignal
|
|
283
|
+
// DOM is preserved when keys match (ideal for API data)
|
|
284
|
+
const users = signal([
|
|
285
|
+
{ id: 1, name: "Alice" },
|
|
286
|
+
{ id: 2, name: "Bob" },
|
|
280
287
|
]);
|
|
281
288
|
|
|
282
289
|
html`
|
|
283
290
|
<ul>
|
|
284
291
|
${each(
|
|
285
|
-
|
|
286
|
-
(
|
|
287
|
-
(
|
|
292
|
+
users,
|
|
293
|
+
(user) => user.id,
|
|
294
|
+
(userSignal) => html`<li>${() => userSignal.value.name}</li>`,
|
|
288
295
|
)}
|
|
289
296
|
</ul>
|
|
290
297
|
`.render();
|
|
291
298
|
|
|
292
|
-
//
|
|
293
|
-
|
|
299
|
+
// Refetch from API - DOM preserved, content updated via signal
|
|
300
|
+
users.value = [
|
|
301
|
+
{ id: 1, name: "Alicia" }, // Same key, new object - DOM preserved!
|
|
302
|
+
{ id: 2, name: "Bobby" },
|
|
303
|
+
{ id: 3, name: "Carol" }, // New key - new DOM created
|
|
304
|
+
];
|
|
294
305
|
|
|
295
|
-
//
|
|
296
|
-
items
|
|
306
|
+
// Two-arg form: object reference as key, receives raw item
|
|
307
|
+
const items = signal([{ name: "Item 1" }, { name: "Item 2" }]);
|
|
297
308
|
|
|
298
|
-
|
|
299
|
-
|
|
309
|
+
html`
|
|
310
|
+
<ul>
|
|
311
|
+
${each(items, (item) => html`<li>${item.name}</li>`)}
|
|
312
|
+
</ul>
|
|
313
|
+
`.render();
|
|
300
314
|
```
|
|
301
315
|
|
|
302
316
|
Signatures:
|
|
303
317
|
|
|
304
318
|
```ts
|
|
305
|
-
each(list, keyFn, renderFn); //
|
|
306
|
-
each(list, renderFn); //
|
|
319
|
+
each(list, keyFn, renderFn); // Three-arg: keyFn extracts key, renderFn receives ReadonlySignal<T>
|
|
320
|
+
each(list, renderFn); // Two-arg: object reference as key, renderFn receives raw T
|
|
307
321
|
```
|
|
308
322
|
|
|
309
|
-
|
|
323
|
+
**Important:** When using the three-arg form, access item properties through `itemSignal.value` and wrap in `() => ...` for reactive updates.
|
|
310
324
|
|
|
311
325
|
## Reactivity API
|
|
312
326
|
|
|
@@ -334,6 +348,16 @@ count.value = count.value + 1;
|
|
|
334
348
|
count.value = count.value * 2;
|
|
335
349
|
```
|
|
336
350
|
|
|
351
|
+
**Reading without tracking dependencies:**
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
const count = signal(0);
|
|
355
|
+
|
|
356
|
+
// peek() reads without creating a dependency
|
|
357
|
+
// Useful in event handlers where you don't want reactivity
|
|
358
|
+
button.onclick = () => console.log(count.peek());
|
|
359
|
+
```
|
|
360
|
+
|
|
337
361
|
### `computed<T>(fn)`
|
|
338
362
|
|
|
339
363
|
Derives a value from other signals. Automatically tracks dependencies.
|
|
@@ -665,23 +689,23 @@ Performance comparison of Balises against other popular reactive libraries. Benc
|
|
|
665
689
|
┌───────┬───────────────────┬───────┬───────────────┬──────────────────┐
|
|
666
690
|
│ Rank │ Library │ Score │ Avg Time (μs) │ vs Fastest │
|
|
667
691
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
668
|
-
│ #1 🏆 │ preact@1.12.1 │ 0.000 │
|
|
692
|
+
│ #1 🏆 │ preact@1.12.1 │ 0.000 │ 64.17 │ 1.00x (baseline) │
|
|
669
693
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
670
|
-
│ #2 │ balises@0.
|
|
694
|
+
│ #2 │ balises@0.7.0 │ 0.033 │ 85.48 │ 1.33x │
|
|
671
695
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
672
|
-
│ #3 │ vue@3.5.26 │ 0.
|
|
696
|
+
│ #3 │ vue@3.5.26 │ 0.095 │ 94.27 │ 1.47x │
|
|
673
697
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
674
|
-
│ #4 │ maverick@6.0.0 │ 0.
|
|
698
|
+
│ #4 │ maverick@6.0.0 │ 0.146 │ 124.89 │ 1.95x │
|
|
675
699
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
676
|
-
│ #5 │ usignal@0.10.0 │ 0.
|
|
700
|
+
│ #5 │ usignal@0.10.0 │ 0.175 │ 133.48 │ 2.08x │
|
|
677
701
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
678
|
-
│ #6 │ angular@19.2.17 │ 0.
|
|
702
|
+
│ #6 │ angular@19.2.17 │ 0.214 │ 169.86 │ 2.65x │
|
|
679
703
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
680
|
-
│ #7 │ solid@1.9.10 │ 0.
|
|
704
|
+
│ #7 │ solid@1.9.10 │ 0.343 │ 260.01 │ 4.05x │
|
|
681
705
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
682
|
-
│ #8 │ mobx@6.15.0 │ 0.
|
|
706
|
+
│ #8 │ mobx@6.15.0 │ 0.854 │ 910.41 │ 14.19x │
|
|
683
707
|
├───────┼───────────────────┼───────┼───────────────┼──────────────────┤
|
|
684
|
-
│ #9 │ hyperactiv@0.11.3 │ 1.000 │
|
|
708
|
+
│ #9 │ hyperactiv@0.11.3 │ 1.000 │ 1051.12 │ 16.38x │
|
|
685
709
|
└───────┴───────────────────┴───────┴───────────────┴──────────────────┘
|
|
686
710
|
```
|
|
687
711
|
|
|
@@ -693,13 +717,13 @@ Performance comparison of Balises against other popular reactive libraries. Benc
|
|
|
693
717
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
694
718
|
│ preact@1.12.1 │ #1 🏆 │ #1 🏆 │ #2 │ #1 🏆 │ #1 🏆 │ #2 │ 1.3 │
|
|
695
719
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
696
|
-
│ balises@0.
|
|
720
|
+
│ balises@0.7.0 │ #3 │ #2 │ #1 🏆 │ #2 │ #2 │ #1 🏆 │ 1.8 │
|
|
697
721
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
698
|
-
│ vue@3.5.26 │ #
|
|
722
|
+
│ vue@3.5.26 │ #2 │ #3 │ #5 │ #3 │ #3 │ #5 │ 3.5 │
|
|
699
723
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
700
|
-
│ maverick@6.0.0 │ #5 │ #
|
|
724
|
+
│ maverick@6.0.0 │ #5 │ #5 │ #4 │ #4 │ #4 │ #4 │ 4.3 │
|
|
701
725
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
702
|
-
│ usignal@0.10.0 │ #4 │ #
|
|
726
|
+
│ usignal@0.10.0 │ #4 │ #4 │ #3 │ #5 │ #8 │ #6 │ 5.0 │
|
|
703
727
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
704
728
|
│ angular@19.2.17 │ #6 │ #6 │ #6 │ #6 │ #5 │ #3 │ 5.3 │
|
|
705
729
|
├───────────────────┼───────────────┼─────────────┼────────────────┼────────────────────┼─────────────┼──────────────┼──────────┤
|
|
@@ -726,7 +750,7 @@ Performance comparison of Balises against other popular reactive libraries. Benc
|
|
|
726
750
|
- These are synthetic benchmarks measuring pure reactivity - real apps should consider the whole picture (ecosystem, docs, community, etc.)
|
|
727
751
|
- Lower rank = better performance
|
|
728
752
|
|
|
729
|
-
_Last updated: 2026-01-
|
|
753
|
+
_Last updated: 2026-01-05_
|
|
730
754
|
|
|
731
755
|
<!-- BENCHMARK_RESULTS_END -->
|
|
732
756
|
|
package/dist/balises.esm.js
CHANGED
|
@@ -141,6 +141,19 @@ var Signal = class {
|
|
|
141
141
|
update(fn) {
|
|
142
142
|
this.value = fn(this.#value);
|
|
143
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Read the signal value without tracking dependencies.
|
|
146
|
+
* Useful in event handlers where you want the current value
|
|
147
|
+
* but don't want to create a reactive dependency.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* const count = signal(0);
|
|
151
|
+
* // In an event handler - no dependency tracking
|
|
152
|
+
* button.onclick = () => console.log(count.peek());
|
|
153
|
+
*/
|
|
154
|
+
peek() {
|
|
155
|
+
return this.#value;
|
|
156
|
+
}
|
|
144
157
|
/** @internal */
|
|
145
158
|
get targets() {
|
|
146
159
|
return this.#targets;
|
|
@@ -152,6 +165,32 @@ var Signal = class {
|
|
|
152
165
|
};
|
|
153
166
|
/** Create a new signal with the given initial value. */
|
|
154
167
|
const signal = (value) => new Signal(value);
|
|
168
|
+
/**
|
|
169
|
+
* A read-only view of a Signal.
|
|
170
|
+
* Provides reactive access without allowing external mutation.
|
|
171
|
+
* Used by `each()` to pass item signals to render functions.
|
|
172
|
+
*/
|
|
173
|
+
var ReadonlySignal = class {
|
|
174
|
+
#signal;
|
|
175
|
+
/** @internal */
|
|
176
|
+
constructor(signal$1) {
|
|
177
|
+
this.#signal = signal$1;
|
|
178
|
+
}
|
|
179
|
+
get value() {
|
|
180
|
+
return this.#signal.value;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Read the signal value without tracking dependencies.
|
|
184
|
+
* Useful in event handlers where you want the current value
|
|
185
|
+
* but don't want to create a reactive dependency.
|
|
186
|
+
*/
|
|
187
|
+
peek() {
|
|
188
|
+
return this.#signal.peek();
|
|
189
|
+
}
|
|
190
|
+
subscribe(fn) {
|
|
191
|
+
return this.#signal.subscribe(fn);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
155
194
|
|
|
156
195
|
//#endregion
|
|
157
196
|
//#region src/signals/computed.ts
|
|
@@ -407,7 +446,7 @@ function store(obj) {
|
|
|
407
446
|
//#endregion
|
|
408
447
|
//#region src/signals/index.ts
|
|
409
448
|
/** Check if a value is a reactive signal or computed. @internal */
|
|
410
|
-
const isSignal = (value) => value instanceof Signal || value instanceof Computed;
|
|
449
|
+
const isSignal = (value) => value instanceof Signal || value instanceof Computed || value instanceof ReadonlySignal;
|
|
411
450
|
|
|
412
451
|
//#endregion
|
|
413
452
|
//#region src/parser.ts
|
package/dist/balises.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"balises.esm.js","names":["context: Computed<unknown> | null","batchQueue: Set<Subscriber> | null","disposalStack: Array<Array<() => void>> | null","disposers: Array<() => void>","onTrack: {\n current: ((source: Signal<unknown> | Computed<unknown>) => void) | null;\n}","#value","#targets","#subs","#fn","#recompute","#dirty","#value","#subs","#sources","#sourceIndex","queue: Computed<unknown>[]","toNotify: Array<{ c: Computed<unknown>; old: unknown }>","#targets","#computing","cleanup: (() => void) | undefined","disposeScope: (() => void) | undefined","dispose: (() => void) | undefined","strings: TemplateStringsArray","values: unknown[]","plugins: InterpolationPlugin[]","disposers: (() => void)[]","stack: (Element | DocumentFragment)[]","reactives: Reactive<unknown>[]","pluginDisposers: (() => void)[]","nodes: Node[]","childDisposers: (() => void)[]","html: HtmlTag"],"sources":["../src/signals/context.ts","../src/signals/signal.ts","../src/signals/computed.ts","../src/signals/effect.ts","../src/signals/store.ts","../src/signals/index.ts","../src/parser.ts","../src/template.ts"],"sourcesContent":["/**\n * Global state and batching for the reactive system.\n */\n\nimport type { Computed } from \"./computed.js\";\nimport type { Signal } from \"./signal.js\";\n\n/** Callback function for subscribers */\nexport type Subscriber = () => void;\n\n/** The currently executing computed (for dependency tracking) */\nexport let context: Computed<unknown> | null = null;\n\n/** Set the current execution context */\nexport function setContext(c: Computed<unknown> | null): void {\n context = c;\n}\n\n/** Batching: defer subscriber notifications until batch completes */\nlet batchDepth = 0;\nlet batchQueue: Set<Subscriber> | null = null;\n\n/**\n * Batch multiple signal updates into a single notification pass.\n * Subscribers are only notified after the batch function completes.\n */\nexport function batch<T>(fn: () => T): T {\n batchDepth++;\n if (batchDepth === 1) batchQueue = new Set();\n try {\n return fn();\n } finally {\n if (--batchDepth === 0) {\n const q = batchQueue!;\n batchQueue = null;\n for (const sub of q) sub();\n }\n }\n}\n\n/** Check if currently batching */\nexport function isBatching(): boolean {\n return batchDepth > 0;\n}\n\n/** Add a subscriber to the batch queue */\nexport function enqueueBatchOne(sub: Subscriber): void {\n batchQueue!.add(sub);\n}\n\n/** Add multiple subscribers to the batch queue */\nexport function enqueueBatchAll(subs: Subscriber[]): void {\n for (let i = 0; i < subs.length; i++) batchQueue!.add(subs[i]!);\n}\n\n/** Scope disposal: collect all disposers in a scope */\nlet disposalStack: Array<Array<() => void>> | null = null;\n\n/**\n * Create a disposal scope that collects all subscriptions and computeds created within.\n * Returns the result of the function and a dispose function that cleans up all resources.\n *\n * @example\n * ```ts\n * const [result, dispose] = scope(() => {\n * const count = signal(0);\n * const doubled = computed(() => count.value * 2);\n * effect(() => console.log(doubled.value));\n * return { count, doubled };\n * });\n *\n * // Later: clean up all subscriptions and computeds\n * dispose();\n * ```\n */\nexport function scope<T>(fn: () => T): [result: T, dispose: () => void] {\n const disposers: Array<() => void> = [];\n\n // Push new disposal context\n if (!disposalStack) disposalStack = [];\n disposalStack.push(disposers);\n\n try {\n const result = fn();\n return [\n result,\n () => {\n for (let i = disposers.length - 1; i >= 0; i--) {\n disposers[i]!();\n }\n disposers.length = 0;\n },\n ];\n } finally {\n // Pop disposal context\n disposalStack.pop();\n if (!disposalStack.length) disposalStack = null;\n }\n}\n\n/**\n * Register a disposer in the current scope (if any).\n * This is called internally by computed/effect when they create cleanup functions.\n */\nexport function registerDisposer(dispose: () => void): void {\n disposalStack?.at(-1)?.push(dispose);\n}\n\n/**\n * Hook for tracking signal/computed accesses.\n * Set by async.ts when track() is active to capture dependencies.\n * Using an object wrapper so async.ts can mutate the current value.\n */\nexport const onTrack: {\n current: ((source: Signal<unknown> | Computed<unknown>) => void) | null;\n} = { current: null };\n","/**\n * Signal - A reactive value container.\n */\n\nimport type { Computed } from \"./computed.js\";\nimport {\n context,\n isBatching,\n enqueueBatchAll,\n onTrack,\n type Subscriber,\n} from \"./context.js\";\n\n/**\n * Remove an item from an array using swap-and-pop (O(1) removal).\n */\nexport function removeFromArray<T>(array: T[], item: T): void {\n const i = array.indexOf(item);\n if (i >= 0) {\n array[i] = array[array.length - 1]!;\n array.pop();\n }\n}\n\n/**\n * A reactive value container. When the value changes, all dependent\n * computeds are marked dirty and subscribers are notified.\n *\n * Uses Object.is() for equality checks to correctly handle NaN values.\n */\nexport class Signal<T> {\n #value: T;\n #subs: Subscriber[] = [];\n #targets: Computed<unknown>[] = [];\n\n constructor(value: T) {\n this.#value = value;\n }\n\n get value(): T {\n if (context) context.trackSource(this);\n if (onTrack.current) onTrack.current(this);\n return this.#value;\n }\n\n set value(v: T) {\n if (Object.is(this.#value, v)) return;\n this.#value = v;\n\n // Mark all dependent computeds as dirty\n const targets = this.#targets;\n for (let i = 0; i < targets.length; i++) {\n targets[i]!.markDirty();\n }\n\n // Notify subscribers\n if (this.#subs.length) {\n if (isBatching()) {\n enqueueBatchAll(this.#subs);\n } else {\n // Copy array to avoid issues if subscribers modify the array during iteration\n const subs = [...this.#subs];\n for (let i = 0; i < subs.length; i++) subs[i]!();\n }\n }\n }\n\n subscribe(fn: Subscriber): () => void {\n this.#subs.push(fn);\n return () => removeFromArray(this.#subs, fn);\n }\n\n /**\n * Update the signal value using an updater function.\n *\n * @param fn - Function that receives current value and returns new value\n *\n * @example\n * const count = signal(0);\n * count.update(n => n + 1); // increment\n */\n update(fn: (current: T) => T): void {\n this.value = fn(this.#value);\n }\n\n /** @internal */\n get targets(): Computed<unknown>[] {\n return this.#targets;\n }\n\n /** @internal */\n deleteTarget(target: Computed<unknown>): void {\n removeFromArray(this.#targets, target);\n }\n}\n\n/** Create a new signal with the given initial value. */\nexport const signal = <T>(value: T) => new Signal(value);\n","/**\n * Computed - A derived reactive value.\n */\n\nimport { Signal, removeFromArray } from \"./signal.js\";\nimport {\n context,\n setContext,\n isBatching,\n enqueueBatchOne,\n registerDisposer,\n onTrack,\n type Subscriber,\n} from \"./context.js\";\n\n/**\n * A derived reactive value. Automatically tracks dependencies and\n * recomputes when any dependency changes.\n *\n * Uses Object.is() for equality checks to correctly handle NaN values.\n */\nexport class Computed<T> {\n #fn: (() => T) | undefined;\n #value: T | undefined;\n #dirty = true;\n #computing = false;\n #subs: Subscriber[] = [];\n #targets: Computed<unknown>[] = [];\n #sources: (Signal<unknown> | Computed<unknown>)[] = [];\n #sourceIndex = 0;\n\n constructor(fn: () => T) {\n this.#fn = fn;\n this.#recompute();\n\n // Auto-register disposal in current root scope\n registerDisposer(() => this.dispose());\n }\n\n get value(): T {\n if (this.#dirty) this.#recompute();\n if (context && context !== this) context.trackSource(this);\n if (onTrack.current) onTrack.current(this);\n return this.#value as T;\n }\n\n subscribe(fn: Subscriber): () => void {\n this.#subs.push(fn);\n return () => removeFromArray(this.#subs, fn);\n }\n\n dispose(): void {\n this.#fn = undefined;\n const sources = this.#sources;\n for (let i = 0; i < sources.length; i++) {\n const source = sources[i];\n if (source) source.deleteTarget(this);\n }\n this.#sources = [];\n this.#subs.length = 0;\n }\n\n /**\n * Called by sources when accessed during recompute.\n * @internal\n */\n trackSource(source: Signal<unknown> | Computed<unknown>): void {\n // Skip tracking if disposed (can happen if dispose() is called during #fn execution)\n if (!this.#fn) return;\n\n const sources = this.#sources;\n const idx = this.#sourceIndex++;\n\n if (idx < sources.length) {\n if (sources[idx] === source) {\n // Same source at same position - nothing to do\n return;\n }\n // Different source - unlink old ones from this position\n for (let i = idx; i < sources.length; i++) {\n const s = sources[i];\n if (s) s.deleteTarget(this);\n }\n sources.length = idx;\n }\n // Add new source\n sources.push(source);\n source.targets.push(this);\n }\n\n /**\n * Mark this computed and all its dependents as dirty.\n * Uses a two-phase approach to avoid cascading issues:\n * 1. Mark all dependents as dirty (no subscriber calls)\n * 2. Notify subscribers after all dirty flags are set\n * @internal\n */\n markDirty(): void {\n if (this.#dirty) return;\n\n // Phase 1: Mark all dependents as dirty, collect subscribers\n const queue: Computed<unknown>[] = [this];\n const toNotify: Array<{ c: Computed<unknown>; old: unknown }> = [];\n\n for (let i = 0; i < queue.length; i++) {\n const c = queue[i]!;\n if (c.#dirty) continue;\n c.#dirty = true;\n\n // Propagate to all targets\n const targets = c.#targets;\n for (let j = 0; j < targets.length; j++) {\n const t = targets[j]!;\n if (!t.#dirty) queue.push(t);\n }\n\n // Collect computeds with subscribers for later notification\n if (c.#subs.length && c.#fn) {\n toNotify.push({ c, old: c.#value });\n }\n }\n\n // Phase 2: Notify subscribers (after all dirty flags are set)\n for (let i = 0; i < toNotify.length; i++) {\n const { c, old } = toNotify[i]!;\n const notify = () => {\n if (c.#fn) {\n c.#recompute();\n if (!Object.is(c.#value, old)) {\n const subs = c.#subs;\n for (let j = 0; j < subs.length; j++) subs[j]!();\n }\n }\n };\n void (isBatching() ? enqueueBatchOne(notify) : notify());\n }\n }\n\n /** @internal */\n get targets(): Computed<unknown>[] {\n return this.#targets;\n }\n\n /** @internal */\n deleteTarget(target: Computed<unknown>): void {\n removeFromArray(this.#targets, target);\n }\n\n #recompute(): void {\n if (this.#computing || !this.#fn) return;\n this.#computing = true;\n\n this.#sourceIndex = 0;\n const prevLen = this.#sources.length;\n\n const prev = context;\n setContext(this);\n try {\n this.#value = this.#fn();\n } finally {\n setContext(prev);\n\n // Unlink removed sources\n const newLen = this.#sourceIndex;\n if (newLen < prevLen) {\n const sources = this.#sources;\n for (let i = newLen; i < prevLen; i++) {\n const source = sources[i];\n if (source) {\n source.deleteTarget(this);\n }\n }\n sources.length = newLen;\n }\n\n this.#dirty = false;\n this.#computing = false;\n }\n }\n}\n\n/** Create a new computed from the given function. */\nexport const computed = <T>(fn: () => T) => new Computed(fn);\n","/**\n * Effect - Run side effects reactively.\n */\n\nimport { computed } from \"./computed.js\";\nimport { context, setContext, registerDisposer } from \"./context.js\";\n\n/**\n * Create a reactive effect that automatically tracks dependencies\n * and re-runs when they change.\n *\n * The effect function can optionally return a cleanup function that will be\n * called before the effect re-runs and when the effect is disposed.\n *\n * @param fn - The effect function to run. May return a cleanup function.\n * @returns A dispose function to stop the effect\n *\n * @example\n * const count = signal(0);\n * const dispose = effect(() => {\n * console.log(\"Count is:\", count.value);\n * });\n *\n * count.value = 1; // logs: \"Count is: 1\"\n * dispose(); // stop the effect\n *\n * @example\n * // With cleanup function\n * const userId = signal(1);\n * const dispose = effect(() => {\n * const subscription = api.subscribe(userId.value);\n * return () => subscription.unsubscribe(); // cleanup\n * });\n *\n * userId.value = 2; // cleanup runs, then effect re-runs with new subscription\n * dispose(); // final cleanup runs\n */\nexport function effect(fn: () => void | (() => void)): () => void {\n let cleanup: (() => void) | undefined;\n let disposed = false;\n\n const c = computed(() => {\n // Run cleanup outside of tracking context to avoid\n // reactive reads in cleanup creating new dependencies\n if (cleanup) {\n const prev = context;\n setContext(null);\n try {\n cleanup();\n } finally {\n setContext(prev);\n }\n }\n cleanup = fn() ?? undefined;\n return undefined;\n });\n // Subscribe to make it reactive (rerun on dependency changes)\n const unsub = c.subscribe(() => {});\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n unsub();\n c.dispose();\n cleanup?.();\n };\n\n // Register full effect dispose (with cleanup) in current scope\n // This overrides the computed's auto-registration with a more complete cleanup\n registerDisposer(dispose);\n\n return dispose;\n}\n","/**\n * Store - Reactive wrapper for plain objects.\n */\n\nimport { Signal } from \"./signal.js\";\n\nconst STORE = Symbol();\n\n/**\n * Create a reactive store from a plain object.\n * Each property becomes a signal, and nested objects are recursively wrapped.\n */\nexport function store<T extends object>(obj: T): T {\n const signals = new Map<string | symbol, Signal<unknown>>();\n\n /** Recursively wrap nested objects and arrays */\n const wrap = (value: unknown): unknown => {\n if (typeof value !== \"object\" || value === null) return value;\n if (STORE in value) return value; // Already a store\n if ((value as object).constructor === Object) {\n return store(value as Record<string, unknown>);\n }\n if (Array.isArray(value)) {\n return value.map(wrap);\n }\n return value;\n };\n\n /** Get or create a signal for a property */\n const getSignal = (key: string | symbol, initialValue: unknown) => {\n let sig = signals.get(key);\n if (!sig) {\n sig = new Signal(wrap(initialValue));\n signals.set(key, sig);\n }\n return sig;\n };\n\n return new Proxy(obj, {\n get(target, key) {\n // Allow symbol access (for STORE check and other internal symbols)\n if (typeof key === \"symbol\") {\n return target[key as keyof T];\n }\n return getSignal(key, target[key as keyof T]).value;\n },\n\n set(target, key, value) {\n if (typeof key === \"symbol\") {\n target[key as keyof T] = value;\n return true;\n }\n const wrapped = wrap(value);\n getSignal(key, target[key as keyof T]).value = wrapped;\n target[key as keyof T] = wrapped as T[keyof T];\n return true;\n },\n\n has(target, key) {\n return key === STORE || key in target;\n },\n });\n}\n","/**\n * Reactive signals with automatic dependency tracking.\n *\n * Uses index-based tracking: computed functions are assumed to access\n * their dependencies in the same order on each run. This enables O(1)\n * dependency checks without complex linked-list structures.\n */\n\nexport { Signal, signal } from \"./signal.js\";\nexport { Computed, computed } from \"./computed.js\";\nexport { effect } from \"./effect.js\";\nexport { store } from \"./store.js\";\nexport { batch, scope, type Subscriber } from \"./context.js\";\n\nimport { Signal } from \"./signal.js\";\nimport { Computed } from \"./computed.js\";\n\n/** Common interface for reactive values (Signal or Computed). */\nexport interface Reactive<T> {\n readonly value: T;\n subscribe(fn: () => void): () => void;\n}\n\n/** Check if a value is a reactive signal or computed. @internal */\nexport const isSignal = (value: unknown): value is Reactive<unknown> =>\n value instanceof Signal || value instanceof Computed;\n","/**\n * Streaming HTML parser for template literals.\n * State machine: Text=0, TagOpen=1, TagName=2, InTag=3, AttrName=4, AttrEq=5, AttrVal=6, CloseTag=7, Comment=8\n */\n\n/** Pre-compiled attribute: static strings interleaved with slot indexes */\nexport type Attr = [name: string, statics: string[], indexes: number[]];\n\nexport interface ParseCallbacks {\n onText: (text: string) => void;\n onOpenTag: (tag: string, attrs: Attr[], selfClosing: boolean) => void;\n onClose: () => void;\n onSlot: (index: number) => void;\n}\n\nexport class HTMLParser {\n private s = 0; // state\n private tag = \"\";\n private attr = \"\";\n private statics: string[] = [];\n private indexes: number[] = [];\n private attrs: Attr[] = [];\n private text = \"\";\n private q = \"\";\n\n parseTemplate(strings: TemplateStringsArray, cb: ParseCallbacks) {\n for (let i = 0; i < strings.length; i++) {\n this.parse(strings[i]!, cb);\n if (i < strings.length - 1) this.slot(i, cb);\n }\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n }\n\n private parse(str: string, cb: ParseCallbacks) {\n for (let i = 0; i < str.length; i++) {\n const ch = str[i]!,\n nx = str[i + 1],\n n2 = str[i + 2];\n\n if (this.s === 0) {\n // Text\n if (ch === \"<\") {\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n this.s = 1;\n } else this.text += ch;\n } else if (this.s === 1) {\n // TagOpen\n if (ch === \"/\") this.s = 7;\n else if (ch === \"!\" && nx === \"-\" && n2 === \"-\") {\n i += 2;\n this.s = 8;\n } else if (ch === \"!\" || ch === \"?\") {\n while (i < str.length && str[i] !== \">\") i++;\n this.s = 0;\n } else if (this.isA(ch)) {\n this.tag = ch;\n this.s = 2;\n } else {\n this.text += \"<\" + ch;\n this.s = 0;\n }\n } else if (this.s === 2) {\n // TagName\n if (this.isT(ch)) this.tag += ch;\n else if (this.isW(ch)) {\n this.s = 3;\n } else if (ch === \">\") {\n this.emit(cb, false);\n } else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n }\n } else if (this.s === 3) {\n // InTag\n if (this.isW(ch)) continue;\n if (ch === \">\") this.emit(cb, false);\n else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n } else {\n this.attr = ch;\n this.statics = [\"\"];\n this.indexes = [];\n this.s = 4;\n }\n } else if (this.s === 4) {\n // AttrName\n if (this.isT(ch) || ch === \"_\") this.attr += ch;\n else if (ch === \"=\") this.s = 5;\n else if (this.isW(ch)) {\n this.emitAttr();\n this.s = 3;\n } else if (ch === \">\") {\n this.emitAttr();\n this.emit(cb, false);\n } else if (ch === \"/\" && nx === \">\") {\n this.emitAttr();\n i++;\n this.emit(cb, true);\n }\n } else if (this.s === 5) {\n // AttrEq\n if (ch === '\"' || ch === \"'\") {\n this.q = ch;\n this.s = 6;\n } else if (!this.isW(ch)) {\n this.q = \"\";\n this.statics[0] += ch;\n this.s = 6;\n }\n } else if (this.s === 6) {\n // AttrVal\n const end = this.q\n ? ch === this.q\n : this.isW(ch) || ch === \">\" || ch === \"/\";\n if (end) {\n this.emitAttr();\n this.q = \"\";\n this.s = 3;\n if (ch === \">\") this.emit(cb, false);\n else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n }\n } else {\n this.statics[this.statics.length - 1] += ch;\n }\n } else if (this.s === 7) {\n // CloseTag\n if (ch === \">\") {\n cb.onClose();\n this.s = 0;\n }\n } else if (this.s === 8) {\n // Comment\n if (ch === \"-\" && nx === \"-\" && n2 === \">\") {\n i += 2;\n this.s = 0;\n }\n }\n }\n }\n\n private slot(index: number, cb: ParseCallbacks) {\n if (this.s === 5 || this.s === 6) {\n this.indexes.push(index);\n this.statics.push(\"\");\n if (this.s === 5) this.s = 6;\n } else {\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n cb.onSlot(index);\n }\n }\n\n private emit(cb: ParseCallbacks, self: boolean) {\n cb.onOpenTag(this.tag, this.attrs, self);\n this.tag = \"\";\n this.attrs = [];\n this.s = 0;\n }\n\n private emitAttr() {\n if (this.attr) this.attrs.push([this.attr, this.statics, this.indexes]);\n this.attr = \"\";\n this.statics = [];\n this.indexes = [];\n }\n\n private isA(c: string) {\n return (c >= \"a\" && c <= \"z\") || (c >= \"A\" && c <= \"Z\");\n }\n private isT(c: string) {\n return (\n (c >= \"a\" && c <= \"z\") ||\n (c >= \"A\" && c <= \"Z\") ||\n (c >= \"0\" && c <= \"9\") ||\n c === \"-\" ||\n c === \":\"\n );\n }\n private isW(c: string) {\n return c <= \" \" && c !== \"\";\n }\n}\n","/**\n * HTML template rendering with reactive bindings.\n *\n * Uses tagged template literals to create reactive DOM:\n * - Text interpolation: ${value} or ${signal}\n * - Attribute binding: class=\"${signal}\" (reactive)\n * - Event binding: @click=${handler}\n * - Property binding: .value=${signal} (sets DOM property, not attribute)\n * - Nested templates: ${html`<span>...</span>`}\n * - Arrays: ${items.map(i => html`<li>${i}</li>`)}\n *\n * Extend with plugins via html.with(...plugins) for additional interpolation types.\n */\n\nimport { computed, isSignal, scope, type Reactive } from \"./signals/index.js\";\nimport { HTMLParser, type Attr } from \"./parser.js\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/**\n * Plugin that handles custom interpolation types.\n * Return a bind function if this plugin handles the value, null otherwise.\n * First plugin to return non-null wins.\n */\nexport interface InterpolationPlugin {\n (\n value: unknown,\n ): ((marker: Comment, disposers: (() => void)[]) => void) | null;\n}\n\n/**\n * Html template tag function with plugin composition.\n */\nexport interface HtmlTag {\n (strings: TemplateStringsArray, ...values: unknown[]): Template;\n /** Create a new html tag with additional plugins */\n with(...plugins: InterpolationPlugin[]): HtmlTag;\n}\n\n/**\n * Create a computed that wraps function execution in a scope.\n * Nested computeds/effects are automatically disposed on re-run.\n * Returns [computed, dispose] - dispose cleans up both the computed\n * and any nested reactives from the last run.\n */\nfunction scopedComputed<T>(fn: () => T) {\n let disposeScope: (() => void) | undefined;\n\n const c = computed(() => {\n disposeScope?.();\n const [result, dispose] = scope(fn);\n disposeScope = dispose;\n return result;\n });\n\n return [c, () => (c.dispose(), disposeScope?.())] as const;\n}\n\n/**\n * Bind a value to an update function.\n * If reactive, subscribes and returns unsubscribe. Otherwise returns null.\n * Functions are wrapped in computed() for automatic reactivity.\n * Nested computeds/effects created inside functions are automatically\n * disposed when the function re-runs or the binding is disposed.\n */\nfunction bind(\n value: unknown,\n update: (v: unknown) => void,\n): (() => void) | null | undefined {\n let dispose: (() => void) | undefined;\n if (typeof value === \"function\") {\n [value, dispose] = scopedComputed(value as () => unknown);\n }\n if (isSignal(value)) {\n update(value.value);\n const unsub = value.subscribe(() =>\n update((value as Reactive<unknown>).value),\n );\n return dispose ? () => (unsub(), dispose()) : unsub;\n }\n update(value);\n}\n\n/** Result of rendering a template */\nexport interface RenderResult {\n fragment: DocumentFragment;\n dispose: () => void;\n}\n\n/** A parsed HTML template. Call render() to create live DOM. */\nexport class Template {\n constructor(\n private strings: TemplateStringsArray,\n private values: unknown[],\n private plugins: InterpolationPlugin[] = [],\n ) {}\n\n /**\n * Parse template and create live DOM.\n * Returns the fragment and a dispose function to clean up subscriptions.\n */\n render(): RenderResult {\n const fragment = document.createDocumentFragment();\n const disposers: (() => void)[] = [];\n const stack: (Element | DocumentFragment)[] = [fragment];\n const parser = new HTMLParser();\n const values = this.values;\n const plugins = this.plugins;\n\n const handleAttribute = (el: Element, [name, statics, indexes]: Attr) => {\n const idx0 = indexes[0];\n\n // Event binding: @click=${handler}\n if (name[0] === \"@\") {\n if (idx0 != null) {\n const handler = values[idx0] as EventListener;\n el.addEventListener(name.slice(1), handler);\n disposers.push(() => el.removeEventListener(name.slice(1), handler));\n }\n return;\n }\n\n // Property binding: .value=${data} - sets DOM property directly\n if (name[0] === \".\") {\n if (idx0 != null) {\n const unsub = bind(values[idx0], (v) => {\n (el as unknown as Record<string, unknown>)[name.slice(1)] = v;\n });\n if (unsub) disposers.push(unsub);\n }\n return;\n }\n\n // Static attribute (no dynamic parts)\n if (!indexes.length) {\n const value = statics[0] ?? \"\";\n el.setAttribute(name, value);\n return;\n }\n\n // Wrap functions in scoped computed, collect all reactive sources\n const reactives: Reactive<unknown>[] = [];\n for (const idx of indexes) {\n const v = values[idx];\n if (typeof v === \"function\") {\n const [c, dispose] = scopedComputed(v as () => unknown);\n values[idx] = c;\n reactives.push(c);\n disposers.push(dispose);\n } else if (isSignal(v)) {\n reactives.push(v);\n }\n }\n\n const update = () => {\n let result = statics[0]!;\n for (let i = 0; i < indexes.length; i++) {\n const v = values[indexes[i]!];\n const val = isSignal(v) ? (v as Reactive<unknown>).value : v;\n // Single dynamic attr: handle boolean/null specially\n if (indexes.length === 1 && (val == null || val === false)) {\n el.removeAttribute(name);\n return;\n }\n result += (val === true ? \"\" : (val ?? \"\")) + statics[i + 1]!;\n }\n el.setAttribute(name, result);\n };\n\n update();\n for (const s of reactives) disposers.push(s.subscribe(update));\n };\n\n /**\n * Bind dynamic content at a marker position.\n * Tries plugins first (first match wins), then falls back to default handling.\n */\n const bindContent = (marker: Comment, value: unknown): (() => void) => {\n // Try plugins first (first match wins)\n for (const plugin of plugins) {\n const binder = plugin(value);\n if (binder) {\n const pluginDisposers: (() => void)[] = [];\n binder(marker, pluginDisposers);\n return () => pluginDisposers.forEach((d) => d());\n }\n }\n\n // Default handling\n let nodes: Node[] = [];\n let childDisposers: (() => void)[] = [];\n\n const clear = () => {\n childDisposers.forEach((d) => d());\n childDisposers = [];\n nodes.forEach((n) => (n as ChildNode).remove());\n nodes = [];\n };\n\n const update = (v: unknown) => {\n clear();\n renderContent(marker, v, nodes, childDisposers);\n };\n\n const unsub = bind(value, update);\n return () => {\n unsub?.();\n clear();\n };\n };\n\n parser.parseTemplate(this.strings, {\n onText: (text) => {\n stack.at(-1)!.append(text);\n },\n\n onOpenTag: (tag, attrs, selfClosing) => {\n const parent = stack.at(-1)!;\n const isSvg =\n tag === \"svg\" ||\n tag === \"SVG\" ||\n (parent instanceof Element && parent.namespaceURI === SVG_NS);\n const el = isSvg\n ? document.createElementNS(SVG_NS, tag)\n : document.createElement(tag);\n for (const attr of attrs) handleAttribute(el, attr);\n parent.appendChild(el);\n if (!selfClosing) stack.push(el);\n },\n\n onClose: () => {\n if (stack.length > 1) stack.pop();\n },\n\n onSlot: (index) => {\n // Marker comment anchors dynamic content\n const marker = document.createComment(\"\");\n stack.at(-1)!.appendChild(marker);\n disposers.push(bindContent(marker, values[index]));\n },\n });\n\n return { fragment, dispose: () => disposers.forEach((d) => d()) };\n }\n}\n\n/**\n * Render content and insert nodes before marker.\n * Handles Templates, primitives, arrays.\n */\nfunction renderContent(\n marker: Comment,\n v: unknown,\n nodes: Node[],\n childDisposers: (() => void)[],\n): void {\n const parent = marker.parentNode!;\n\n for (const item of Array.isArray(v) ? v : [v]) {\n // Handle templates\n if (item instanceof Template) {\n const { fragment, dispose } = item.render();\n childDisposers.push(dispose);\n nodes.push(...fragment.childNodes);\n parent.insertBefore(fragment, marker);\n }\n // Handle primitives (ignore null/undefined/boolean)\n else if (item != null && typeof item !== \"boolean\") {\n const node = document.createTextNode(String(item));\n nodes.push(node);\n parent.insertBefore(node, marker);\n }\n }\n}\n\n/**\n * Create an html tag function with the given plugins.\n */\nfunction createHtmlWithPlugins(plugins: InterpolationPlugin[]): HtmlTag {\n const tag = ((strings: TemplateStringsArray, ...values: unknown[]) =>\n new Template(strings, values, plugins)) as HtmlTag;\n\n tag.with = (...morePlugins: InterpolationPlugin[]) =>\n createHtmlWithPlugins([...plugins, ...morePlugins]);\n\n return tag;\n}\n\n/**\n * Tagged template literal for creating reactive HTML templates.\n * Use .with(...plugins) to add interpolation handlers like each() or async generators.\n *\n * @example\n * ```ts\n * import { html } from \"balises\";\n * import eachPlugin, { each } from \"balises/each\";\n * import asyncPlugin from \"balises/async\";\n *\n * const html = baseHtml.with(eachPlugin, asyncPlugin);\n *\n * html`<div>${async function* () { ... }}</div>`.render();\n * ```\n */\nexport const html: HtmlTag = createHtmlWithPlugins([]);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"balises.esm.js","names":["context: Computed<unknown> | null","batchQueue: Set<Subscriber> | null","disposalStack: Array<Array<() => void>> | null","disposers: Array<() => void>","onTrack: {\n current: ((source: Signal<unknown> | Computed<unknown>) => void) | null;\n}","#value","#targets","#subs","#signal","signal","#fn","#recompute","#dirty","#value","#subs","#sources","#sourceIndex","queue: Computed<unknown>[]","toNotify: Array<{ c: Computed<unknown>; old: unknown }>","#targets","#computing","cleanup: (() => void) | undefined","disposeScope: (() => void) | undefined","dispose: (() => void) | undefined","strings: TemplateStringsArray","values: unknown[]","plugins: InterpolationPlugin[]","disposers: (() => void)[]","stack: (Element | DocumentFragment)[]","reactives: Reactive<unknown>[]","pluginDisposers: (() => void)[]","nodes: Node[]","childDisposers: (() => void)[]","html: HtmlTag"],"sources":["../src/signals/context.ts","../src/signals/signal.ts","../src/signals/computed.ts","../src/signals/effect.ts","../src/signals/store.ts","../src/signals/index.ts","../src/parser.ts","../src/template.ts"],"sourcesContent":["/**\n * Global state and batching for the reactive system.\n */\n\nimport type { Computed } from \"./computed.js\";\nimport type { Signal } from \"./signal.js\";\n\n/** Callback function for subscribers */\nexport type Subscriber = () => void;\n\n/** The currently executing computed (for dependency tracking) */\nexport let context: Computed<unknown> | null = null;\n\n/** Set the current execution context */\nexport function setContext(c: Computed<unknown> | null): void {\n context = c;\n}\n\n/** Batching: defer subscriber notifications until batch completes */\nlet batchDepth = 0;\nlet batchQueue: Set<Subscriber> | null = null;\n\n/**\n * Batch multiple signal updates into a single notification pass.\n * Subscribers are only notified after the batch function completes.\n */\nexport function batch<T>(fn: () => T): T {\n batchDepth++;\n if (batchDepth === 1) batchQueue = new Set();\n try {\n return fn();\n } finally {\n if (--batchDepth === 0) {\n const q = batchQueue!;\n batchQueue = null;\n for (const sub of q) sub();\n }\n }\n}\n\n/** Check if currently batching */\nexport function isBatching(): boolean {\n return batchDepth > 0;\n}\n\n/** Add a subscriber to the batch queue */\nexport function enqueueBatchOne(sub: Subscriber): void {\n batchQueue!.add(sub);\n}\n\n/** Add multiple subscribers to the batch queue */\nexport function enqueueBatchAll(subs: Subscriber[]): void {\n for (let i = 0; i < subs.length; i++) batchQueue!.add(subs[i]!);\n}\n\n/** Scope disposal: collect all disposers in a scope */\nlet disposalStack: Array<Array<() => void>> | null = null;\n\n/**\n * Create a disposal scope that collects all subscriptions and computeds created within.\n * Returns the result of the function and a dispose function that cleans up all resources.\n *\n * @example\n * ```ts\n * const [result, dispose] = scope(() => {\n * const count = signal(0);\n * const doubled = computed(() => count.value * 2);\n * effect(() => console.log(doubled.value));\n * return { count, doubled };\n * });\n *\n * // Later: clean up all subscriptions and computeds\n * dispose();\n * ```\n */\nexport function scope<T>(fn: () => T): [result: T, dispose: () => void] {\n const disposers: Array<() => void> = [];\n\n // Push new disposal context\n if (!disposalStack) disposalStack = [];\n disposalStack.push(disposers);\n\n try {\n const result = fn();\n return [\n result,\n () => {\n for (let i = disposers.length - 1; i >= 0; i--) {\n disposers[i]!();\n }\n disposers.length = 0;\n },\n ];\n } finally {\n // Pop disposal context\n disposalStack.pop();\n if (!disposalStack.length) disposalStack = null;\n }\n}\n\n/**\n * Register a disposer in the current scope (if any).\n * This is called internally by computed/effect when they create cleanup functions.\n */\nexport function registerDisposer(dispose: () => void): void {\n disposalStack?.at(-1)?.push(dispose);\n}\n\n/**\n * Hook for tracking signal/computed accesses.\n * Set by async.ts when track() is active to capture dependencies.\n * Using an object wrapper so async.ts can mutate the current value.\n */\nexport const onTrack: {\n current: ((source: Signal<unknown> | Computed<unknown>) => void) | null;\n} = { current: null };\n","/**\n * Signal - A reactive value container.\n */\n\nimport type { Computed } from \"./computed.js\";\nimport {\n context,\n isBatching,\n enqueueBatchAll,\n onTrack,\n type Subscriber,\n} from \"./context.js\";\n\n/**\n * Remove an item from an array using swap-and-pop (O(1) removal).\n */\nexport function removeFromArray<T>(array: T[], item: T): void {\n const i = array.indexOf(item);\n if (i >= 0) {\n array[i] = array[array.length - 1]!;\n array.pop();\n }\n}\n\n/**\n * A reactive value container. When the value changes, all dependent\n * computeds are marked dirty and subscribers are notified.\n *\n * Uses Object.is() for equality checks to correctly handle NaN values.\n */\nexport class Signal<T> {\n #value: T;\n #subs: Subscriber[] = [];\n #targets: Computed<unknown>[] = [];\n\n constructor(value: T) {\n this.#value = value;\n }\n\n get value(): T {\n if (context) context.trackSource(this);\n if (onTrack.current) onTrack.current(this);\n return this.#value;\n }\n\n set value(v: T) {\n if (Object.is(this.#value, v)) return;\n this.#value = v;\n\n // Mark all dependent computeds as dirty\n const targets = this.#targets;\n for (let i = 0; i < targets.length; i++) {\n targets[i]!.markDirty();\n }\n\n // Notify subscribers\n if (this.#subs.length) {\n if (isBatching()) {\n enqueueBatchAll(this.#subs);\n } else {\n // Copy array to avoid issues if subscribers modify the array during iteration\n const subs = [...this.#subs];\n for (let i = 0; i < subs.length; i++) subs[i]!();\n }\n }\n }\n\n subscribe(fn: Subscriber): () => void {\n this.#subs.push(fn);\n return () => removeFromArray(this.#subs, fn);\n }\n\n /**\n * Update the signal value using an updater function.\n *\n * @param fn - Function that receives current value and returns new value\n *\n * @example\n * const count = signal(0);\n * count.update(n => n + 1); // increment\n */\n update(fn: (current: T) => T): void {\n this.value = fn(this.#value);\n }\n\n /**\n * Read the signal value without tracking dependencies.\n * Useful in event handlers where you want the current value\n * but don't want to create a reactive dependency.\n *\n * @example\n * const count = signal(0);\n * // In an event handler - no dependency tracking\n * button.onclick = () => console.log(count.peek());\n */\n peek(): T {\n return this.#value;\n }\n\n /** @internal */\n get targets(): Computed<unknown>[] {\n return this.#targets;\n }\n\n /** @internal */\n deleteTarget(target: Computed<unknown>): void {\n removeFromArray(this.#targets, target);\n }\n}\n\n/** Create a new signal with the given initial value. */\nexport const signal = <T>(value: T) => new Signal(value);\n\n/**\n * A read-only view of a Signal.\n * Provides reactive access without allowing external mutation.\n * Used by `each()` to pass item signals to render functions.\n */\nexport class ReadonlySignal<T> {\n #signal: Signal<T>;\n\n /** @internal */\n constructor(signal: Signal<T>) {\n this.#signal = signal;\n }\n\n get value(): T {\n return this.#signal.value;\n }\n\n /**\n * Read the signal value without tracking dependencies.\n * Useful in event handlers where you want the current value\n * but don't want to create a reactive dependency.\n */\n peek(): T {\n return this.#signal.peek();\n }\n\n subscribe(fn: Subscriber): () => void {\n return this.#signal.subscribe(fn);\n }\n}\n","/**\n * Computed - A derived reactive value.\n */\n\nimport { Signal, removeFromArray } from \"./signal.js\";\nimport {\n context,\n setContext,\n isBatching,\n enqueueBatchOne,\n registerDisposer,\n onTrack,\n type Subscriber,\n} from \"./context.js\";\n\n/**\n * A derived reactive value. Automatically tracks dependencies and\n * recomputes when any dependency changes.\n *\n * Uses Object.is() for equality checks to correctly handle NaN values.\n */\nexport class Computed<T> {\n #fn: (() => T) | undefined;\n #value: T | undefined;\n #dirty = true;\n #computing = false;\n #subs: Subscriber[] = [];\n #targets: Computed<unknown>[] = [];\n #sources: (Signal<unknown> | Computed<unknown>)[] = [];\n #sourceIndex = 0;\n\n constructor(fn: () => T) {\n this.#fn = fn;\n this.#recompute();\n\n // Auto-register disposal in current root scope\n registerDisposer(() => this.dispose());\n }\n\n get value(): T {\n if (this.#dirty) this.#recompute();\n if (context && context !== this) context.trackSource(this);\n if (onTrack.current) onTrack.current(this);\n return this.#value as T;\n }\n\n subscribe(fn: Subscriber): () => void {\n this.#subs.push(fn);\n return () => removeFromArray(this.#subs, fn);\n }\n\n dispose(): void {\n this.#fn = undefined;\n const sources = this.#sources;\n for (let i = 0; i < sources.length; i++) {\n const source = sources[i];\n if (source) source.deleteTarget(this);\n }\n this.#sources = [];\n this.#subs.length = 0;\n }\n\n /**\n * Called by sources when accessed during recompute.\n * @internal\n */\n trackSource(source: Signal<unknown> | Computed<unknown>): void {\n // Skip tracking if disposed (can happen if dispose() is called during #fn execution)\n if (!this.#fn) return;\n\n const sources = this.#sources;\n const idx = this.#sourceIndex++;\n\n if (idx < sources.length) {\n if (sources[idx] === source) {\n // Same source at same position - nothing to do\n return;\n }\n // Different source - unlink old ones from this position\n for (let i = idx; i < sources.length; i++) {\n const s = sources[i];\n if (s) s.deleteTarget(this);\n }\n sources.length = idx;\n }\n // Add new source\n sources.push(source);\n source.targets.push(this);\n }\n\n /**\n * Mark this computed and all its dependents as dirty.\n * Uses a two-phase approach to avoid cascading issues:\n * 1. Mark all dependents as dirty (no subscriber calls)\n * 2. Notify subscribers after all dirty flags are set\n * @internal\n */\n markDirty(): void {\n if (this.#dirty) return;\n\n // Phase 1: Mark all dependents as dirty, collect subscribers\n const queue: Computed<unknown>[] = [this];\n const toNotify: Array<{ c: Computed<unknown>; old: unknown }> = [];\n\n for (let i = 0; i < queue.length; i++) {\n const c = queue[i]!;\n if (c.#dirty) continue;\n c.#dirty = true;\n\n // Propagate to all targets\n const targets = c.#targets;\n for (let j = 0; j < targets.length; j++) {\n const t = targets[j]!;\n if (!t.#dirty) queue.push(t);\n }\n\n // Collect computeds with subscribers for later notification\n if (c.#subs.length && c.#fn) {\n toNotify.push({ c, old: c.#value });\n }\n }\n\n // Phase 2: Notify subscribers (after all dirty flags are set)\n for (let i = 0; i < toNotify.length; i++) {\n const { c, old } = toNotify[i]!;\n const notify = () => {\n if (c.#fn) {\n c.#recompute();\n if (!Object.is(c.#value, old)) {\n const subs = c.#subs;\n for (let j = 0; j < subs.length; j++) subs[j]!();\n }\n }\n };\n void (isBatching() ? enqueueBatchOne(notify) : notify());\n }\n }\n\n /** @internal */\n get targets(): Computed<unknown>[] {\n return this.#targets;\n }\n\n /** @internal */\n deleteTarget(target: Computed<unknown>): void {\n removeFromArray(this.#targets, target);\n }\n\n #recompute(): void {\n if (this.#computing || !this.#fn) return;\n this.#computing = true;\n\n this.#sourceIndex = 0;\n const prevLen = this.#sources.length;\n\n const prev = context;\n setContext(this);\n try {\n this.#value = this.#fn();\n } finally {\n setContext(prev);\n\n // Unlink removed sources\n const newLen = this.#sourceIndex;\n if (newLen < prevLen) {\n const sources = this.#sources;\n for (let i = newLen; i < prevLen; i++) {\n const source = sources[i];\n if (source) {\n source.deleteTarget(this);\n }\n }\n sources.length = newLen;\n }\n\n this.#dirty = false;\n this.#computing = false;\n }\n }\n}\n\n/** Create a new computed from the given function. */\nexport const computed = <T>(fn: () => T) => new Computed(fn);\n","/**\n * Effect - Run side effects reactively.\n */\n\nimport { computed } from \"./computed.js\";\nimport { context, setContext, registerDisposer } from \"./context.js\";\n\n/**\n * Create a reactive effect that automatically tracks dependencies\n * and re-runs when they change.\n *\n * The effect function can optionally return a cleanup function that will be\n * called before the effect re-runs and when the effect is disposed.\n *\n * @param fn - The effect function to run. May return a cleanup function.\n * @returns A dispose function to stop the effect\n *\n * @example\n * const count = signal(0);\n * const dispose = effect(() => {\n * console.log(\"Count is:\", count.value);\n * });\n *\n * count.value = 1; // logs: \"Count is: 1\"\n * dispose(); // stop the effect\n *\n * @example\n * // With cleanup function\n * const userId = signal(1);\n * const dispose = effect(() => {\n * const subscription = api.subscribe(userId.value);\n * return () => subscription.unsubscribe(); // cleanup\n * });\n *\n * userId.value = 2; // cleanup runs, then effect re-runs with new subscription\n * dispose(); // final cleanup runs\n */\nexport function effect(fn: () => void | (() => void)): () => void {\n let cleanup: (() => void) | undefined;\n let disposed = false;\n\n const c = computed(() => {\n // Run cleanup outside of tracking context to avoid\n // reactive reads in cleanup creating new dependencies\n if (cleanup) {\n const prev = context;\n setContext(null);\n try {\n cleanup();\n } finally {\n setContext(prev);\n }\n }\n cleanup = fn() ?? undefined;\n return undefined;\n });\n // Subscribe to make it reactive (rerun on dependency changes)\n const unsub = c.subscribe(() => {});\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n unsub();\n c.dispose();\n cleanup?.();\n };\n\n // Register full effect dispose (with cleanup) in current scope\n // This overrides the computed's auto-registration with a more complete cleanup\n registerDisposer(dispose);\n\n return dispose;\n}\n","/**\n * Store - Reactive wrapper for plain objects.\n */\n\nimport { Signal } from \"./signal.js\";\n\nconst STORE = Symbol();\n\n/**\n * Create a reactive store from a plain object.\n * Each property becomes a signal, and nested objects are recursively wrapped.\n */\nexport function store<T extends object>(obj: T): T {\n const signals = new Map<string | symbol, Signal<unknown>>();\n\n /** Recursively wrap nested objects and arrays */\n const wrap = (value: unknown): unknown => {\n if (typeof value !== \"object\" || value === null) return value;\n if (STORE in value) return value; // Already a store\n if ((value as object).constructor === Object) {\n return store(value as Record<string, unknown>);\n }\n if (Array.isArray(value)) {\n return value.map(wrap);\n }\n return value;\n };\n\n /** Get or create a signal for a property */\n const getSignal = (key: string | symbol, initialValue: unknown) => {\n let sig = signals.get(key);\n if (!sig) {\n sig = new Signal(wrap(initialValue));\n signals.set(key, sig);\n }\n return sig;\n };\n\n return new Proxy(obj, {\n get(target, key) {\n // Allow symbol access (for STORE check and other internal symbols)\n if (typeof key === \"symbol\") {\n return target[key as keyof T];\n }\n return getSignal(key, target[key as keyof T]).value;\n },\n\n set(target, key, value) {\n if (typeof key === \"symbol\") {\n target[key as keyof T] = value;\n return true;\n }\n const wrapped = wrap(value);\n getSignal(key, target[key as keyof T]).value = wrapped;\n target[key as keyof T] = wrapped as T[keyof T];\n return true;\n },\n\n has(target, key) {\n return key === STORE || key in target;\n },\n });\n}\n","/**\n * Reactive signals with automatic dependency tracking.\n *\n * Uses index-based tracking: computed functions are assumed to access\n * their dependencies in the same order on each run. This enables O(1)\n * dependency checks without complex linked-list structures.\n */\n\nexport { Signal, signal, ReadonlySignal } from \"./signal.js\";\nexport { Computed, computed } from \"./computed.js\";\nexport { effect } from \"./effect.js\";\nexport { store } from \"./store.js\";\nexport { batch, scope, type Subscriber } from \"./context.js\";\n\nimport { Signal, ReadonlySignal } from \"./signal.js\";\nimport { Computed } from \"./computed.js\";\n\n/** Common interface for reactive values (Signal or Computed). */\nexport interface Reactive<T> {\n readonly value: T;\n subscribe(fn: () => void): () => void;\n}\n\n/** Check if a value is a reactive signal or computed. @internal */\nexport const isSignal = (value: unknown): value is Reactive<unknown> =>\n value instanceof Signal ||\n value instanceof Computed ||\n value instanceof ReadonlySignal;\n","/**\n * Streaming HTML parser for template literals.\n * State machine: Text=0, TagOpen=1, TagName=2, InTag=3, AttrName=4, AttrEq=5, AttrVal=6, CloseTag=7, Comment=8\n */\n\n/** Pre-compiled attribute: static strings interleaved with slot indexes */\nexport type Attr = [name: string, statics: string[], indexes: number[]];\n\nexport interface ParseCallbacks {\n onText: (text: string) => void;\n onOpenTag: (tag: string, attrs: Attr[], selfClosing: boolean) => void;\n onClose: () => void;\n onSlot: (index: number) => void;\n}\n\nexport class HTMLParser {\n private s = 0; // state\n private tag = \"\";\n private attr = \"\";\n private statics: string[] = [];\n private indexes: number[] = [];\n private attrs: Attr[] = [];\n private text = \"\";\n private q = \"\";\n\n parseTemplate(strings: TemplateStringsArray, cb: ParseCallbacks) {\n for (let i = 0; i < strings.length; i++) {\n this.parse(strings[i]!, cb);\n if (i < strings.length - 1) this.slot(i, cb);\n }\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n }\n\n private parse(str: string, cb: ParseCallbacks) {\n for (let i = 0; i < str.length; i++) {\n const ch = str[i]!,\n nx = str[i + 1],\n n2 = str[i + 2];\n\n if (this.s === 0) {\n // Text\n if (ch === \"<\") {\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n this.s = 1;\n } else this.text += ch;\n } else if (this.s === 1) {\n // TagOpen\n if (ch === \"/\") this.s = 7;\n else if (ch === \"!\" && nx === \"-\" && n2 === \"-\") {\n i += 2;\n this.s = 8;\n } else if (ch === \"!\" || ch === \"?\") {\n while (i < str.length && str[i] !== \">\") i++;\n this.s = 0;\n } else if (this.isA(ch)) {\n this.tag = ch;\n this.s = 2;\n } else {\n this.text += \"<\" + ch;\n this.s = 0;\n }\n } else if (this.s === 2) {\n // TagName\n if (this.isT(ch)) this.tag += ch;\n else if (this.isW(ch)) {\n this.s = 3;\n } else if (ch === \">\") {\n this.emit(cb, false);\n } else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n }\n } else if (this.s === 3) {\n // InTag\n if (this.isW(ch)) continue;\n if (ch === \">\") this.emit(cb, false);\n else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n } else {\n this.attr = ch;\n this.statics = [\"\"];\n this.indexes = [];\n this.s = 4;\n }\n } else if (this.s === 4) {\n // AttrName\n if (this.isT(ch) || ch === \"_\") this.attr += ch;\n else if (ch === \"=\") this.s = 5;\n else if (this.isW(ch)) {\n this.emitAttr();\n this.s = 3;\n } else if (ch === \">\") {\n this.emitAttr();\n this.emit(cb, false);\n } else if (ch === \"/\" && nx === \">\") {\n this.emitAttr();\n i++;\n this.emit(cb, true);\n }\n } else if (this.s === 5) {\n // AttrEq\n if (ch === '\"' || ch === \"'\") {\n this.q = ch;\n this.s = 6;\n } else if (!this.isW(ch)) {\n this.q = \"\";\n this.statics[0] += ch;\n this.s = 6;\n }\n } else if (this.s === 6) {\n // AttrVal\n const end = this.q\n ? ch === this.q\n : this.isW(ch) || ch === \">\" || ch === \"/\";\n if (end) {\n this.emitAttr();\n this.q = \"\";\n this.s = 3;\n if (ch === \">\") this.emit(cb, false);\n else if (ch === \"/\" && nx === \">\") {\n i++;\n this.emit(cb, true);\n }\n } else {\n this.statics[this.statics.length - 1] += ch;\n }\n } else if (this.s === 7) {\n // CloseTag\n if (ch === \">\") {\n cb.onClose();\n this.s = 0;\n }\n } else if (this.s === 8) {\n // Comment\n if (ch === \"-\" && nx === \"-\" && n2 === \">\") {\n i += 2;\n this.s = 0;\n }\n }\n }\n }\n\n private slot(index: number, cb: ParseCallbacks) {\n if (this.s === 5 || this.s === 6) {\n this.indexes.push(index);\n this.statics.push(\"\");\n if (this.s === 5) this.s = 6;\n } else {\n if (this.text) {\n cb.onText(this.text);\n this.text = \"\";\n }\n cb.onSlot(index);\n }\n }\n\n private emit(cb: ParseCallbacks, self: boolean) {\n cb.onOpenTag(this.tag, this.attrs, self);\n this.tag = \"\";\n this.attrs = [];\n this.s = 0;\n }\n\n private emitAttr() {\n if (this.attr) this.attrs.push([this.attr, this.statics, this.indexes]);\n this.attr = \"\";\n this.statics = [];\n this.indexes = [];\n }\n\n private isA(c: string) {\n return (c >= \"a\" && c <= \"z\") || (c >= \"A\" && c <= \"Z\");\n }\n private isT(c: string) {\n return (\n (c >= \"a\" && c <= \"z\") ||\n (c >= \"A\" && c <= \"Z\") ||\n (c >= \"0\" && c <= \"9\") ||\n c === \"-\" ||\n c === \":\"\n );\n }\n private isW(c: string) {\n return c <= \" \" && c !== \"\";\n }\n}\n","/**\n * HTML template rendering with reactive bindings.\n *\n * Uses tagged template literals to create reactive DOM:\n * - Text interpolation: ${value} or ${signal}\n * - Attribute binding: class=\"${signal}\" (reactive)\n * - Event binding: @click=${handler}\n * - Property binding: .value=${signal} (sets DOM property, not attribute)\n * - Nested templates: ${html`<span>...</span>`}\n * - Arrays: ${items.map(i => html`<li>${i}</li>`)}\n *\n * Extend with plugins via html.with(...plugins) for additional interpolation types.\n */\n\nimport { computed, isSignal, scope, type Reactive } from \"./signals/index.js\";\nimport { HTMLParser, type Attr } from \"./parser.js\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/**\n * Plugin that handles custom interpolation types.\n * Return a bind function if this plugin handles the value, null otherwise.\n * First plugin to return non-null wins.\n */\nexport interface InterpolationPlugin {\n (\n value: unknown,\n ): ((marker: Comment, disposers: (() => void)[]) => void) | null;\n}\n\n/**\n * Html template tag function with plugin composition.\n */\nexport interface HtmlTag {\n (strings: TemplateStringsArray, ...values: unknown[]): Template;\n /** Create a new html tag with additional plugins */\n with(...plugins: InterpolationPlugin[]): HtmlTag;\n}\n\n/**\n * Create a computed that wraps function execution in a scope.\n * Nested computeds/effects are automatically disposed on re-run.\n * Returns [computed, dispose] - dispose cleans up both the computed\n * and any nested reactives from the last run.\n */\nfunction scopedComputed<T>(fn: () => T) {\n let disposeScope: (() => void) | undefined;\n\n const c = computed(() => {\n disposeScope?.();\n const [result, dispose] = scope(fn);\n disposeScope = dispose;\n return result;\n });\n\n return [c, () => (c.dispose(), disposeScope?.())] as const;\n}\n\n/**\n * Bind a value to an update function.\n * If reactive, subscribes and returns unsubscribe. Otherwise returns null.\n * Functions are wrapped in computed() for automatic reactivity.\n * Nested computeds/effects created inside functions are automatically\n * disposed when the function re-runs or the binding is disposed.\n */\nfunction bind(\n value: unknown,\n update: (v: unknown) => void,\n): (() => void) | null | undefined {\n let dispose: (() => void) | undefined;\n if (typeof value === \"function\") {\n [value, dispose] = scopedComputed(value as () => unknown);\n }\n if (isSignal(value)) {\n update(value.value);\n const unsub = value.subscribe(() =>\n update((value as Reactive<unknown>).value),\n );\n return dispose ? () => (unsub(), dispose()) : unsub;\n }\n update(value);\n}\n\n/** Result of rendering a template */\nexport interface RenderResult {\n fragment: DocumentFragment;\n dispose: () => void;\n}\n\n/** A parsed HTML template. Call render() to create live DOM. */\nexport class Template {\n constructor(\n private strings: TemplateStringsArray,\n private values: unknown[],\n private plugins: InterpolationPlugin[] = [],\n ) {}\n\n /**\n * Parse template and create live DOM.\n * Returns the fragment and a dispose function to clean up subscriptions.\n */\n render(): RenderResult {\n const fragment = document.createDocumentFragment();\n const disposers: (() => void)[] = [];\n const stack: (Element | DocumentFragment)[] = [fragment];\n const parser = new HTMLParser();\n const values = this.values;\n const plugins = this.plugins;\n\n const handleAttribute = (el: Element, [name, statics, indexes]: Attr) => {\n const idx0 = indexes[0];\n\n // Event binding: @click=${handler}\n if (name[0] === \"@\") {\n if (idx0 != null) {\n const handler = values[idx0] as EventListener;\n el.addEventListener(name.slice(1), handler);\n disposers.push(() => el.removeEventListener(name.slice(1), handler));\n }\n return;\n }\n\n // Property binding: .value=${data} - sets DOM property directly\n if (name[0] === \".\") {\n if (idx0 != null) {\n const unsub = bind(values[idx0], (v) => {\n (el as unknown as Record<string, unknown>)[name.slice(1)] = v;\n });\n if (unsub) disposers.push(unsub);\n }\n return;\n }\n\n // Static attribute (no dynamic parts)\n if (!indexes.length) {\n const value = statics[0] ?? \"\";\n el.setAttribute(name, value);\n return;\n }\n\n // Wrap functions in scoped computed, collect all reactive sources\n const reactives: Reactive<unknown>[] = [];\n for (const idx of indexes) {\n const v = values[idx];\n if (typeof v === \"function\") {\n const [c, dispose] = scopedComputed(v as () => unknown);\n values[idx] = c;\n reactives.push(c);\n disposers.push(dispose);\n } else if (isSignal(v)) {\n reactives.push(v);\n }\n }\n\n const update = () => {\n let result = statics[0]!;\n for (let i = 0; i < indexes.length; i++) {\n const v = values[indexes[i]!];\n const val = isSignal(v) ? (v as Reactive<unknown>).value : v;\n // Single dynamic attr: handle boolean/null specially\n if (indexes.length === 1 && (val == null || val === false)) {\n el.removeAttribute(name);\n return;\n }\n result += (val === true ? \"\" : (val ?? \"\")) + statics[i + 1]!;\n }\n el.setAttribute(name, result);\n };\n\n update();\n for (const s of reactives) disposers.push(s.subscribe(update));\n };\n\n /**\n * Bind dynamic content at a marker position.\n * Tries plugins first (first match wins), then falls back to default handling.\n */\n const bindContent = (marker: Comment, value: unknown): (() => void) => {\n // Try plugins first (first match wins)\n for (const plugin of plugins) {\n const binder = plugin(value);\n if (binder) {\n const pluginDisposers: (() => void)[] = [];\n binder(marker, pluginDisposers);\n return () => pluginDisposers.forEach((d) => d());\n }\n }\n\n // Default handling\n let nodes: Node[] = [];\n let childDisposers: (() => void)[] = [];\n\n const clear = () => {\n childDisposers.forEach((d) => d());\n childDisposers = [];\n nodes.forEach((n) => (n as ChildNode).remove());\n nodes = [];\n };\n\n const update = (v: unknown) => {\n clear();\n renderContent(marker, v, nodes, childDisposers);\n };\n\n const unsub = bind(value, update);\n return () => {\n unsub?.();\n clear();\n };\n };\n\n parser.parseTemplate(this.strings, {\n onText: (text) => {\n stack.at(-1)!.append(text);\n },\n\n onOpenTag: (tag, attrs, selfClosing) => {\n const parent = stack.at(-1)!;\n const isSvg =\n tag === \"svg\" ||\n tag === \"SVG\" ||\n (parent instanceof Element && parent.namespaceURI === SVG_NS);\n const el = isSvg\n ? document.createElementNS(SVG_NS, tag)\n : document.createElement(tag);\n for (const attr of attrs) handleAttribute(el, attr);\n parent.appendChild(el);\n if (!selfClosing) stack.push(el);\n },\n\n onClose: () => {\n if (stack.length > 1) stack.pop();\n },\n\n onSlot: (index) => {\n // Marker comment anchors dynamic content\n const marker = document.createComment(\"\");\n stack.at(-1)!.appendChild(marker);\n disposers.push(bindContent(marker, values[index]));\n },\n });\n\n return { fragment, dispose: () => disposers.forEach((d) => d()) };\n }\n}\n\n/**\n * Render content and insert nodes before marker.\n * Handles Templates, primitives, arrays.\n */\nfunction renderContent(\n marker: Comment,\n v: unknown,\n nodes: Node[],\n childDisposers: (() => void)[],\n): void {\n const parent = marker.parentNode!;\n\n for (const item of Array.isArray(v) ? v : [v]) {\n // Handle templates\n if (item instanceof Template) {\n const { fragment, dispose } = item.render();\n childDisposers.push(dispose);\n nodes.push(...fragment.childNodes);\n parent.insertBefore(fragment, marker);\n }\n // Handle primitives (ignore null/undefined/boolean)\n else if (item != null && typeof item !== \"boolean\") {\n const node = document.createTextNode(String(item));\n nodes.push(node);\n parent.insertBefore(node, marker);\n }\n }\n}\n\n/**\n * Create an html tag function with the given plugins.\n */\nfunction createHtmlWithPlugins(plugins: InterpolationPlugin[]): HtmlTag {\n const tag = ((strings: TemplateStringsArray, ...values: unknown[]) =>\n new Template(strings, values, plugins)) as HtmlTag;\n\n tag.with = (...morePlugins: InterpolationPlugin[]) =>\n createHtmlWithPlugins([...plugins, ...morePlugins]);\n\n return tag;\n}\n\n/**\n * Tagged template literal for creating reactive HTML templates.\n * Use .with(...plugins) to add interpolation handlers like each() or async generators.\n *\n * @example\n * ```ts\n * import { html } from \"balises\";\n * import eachPlugin, { each } from \"balises/each\";\n * import asyncPlugin from \"balises/async\";\n *\n * const html = baseHtml.with(eachPlugin, asyncPlugin);\n *\n * html`<div>${async function* () { ... }}</div>`.render();\n * ```\n */\nexport const html: HtmlTag = createHtmlWithPlugins([]);\n"],"mappings":";;AAWA,IAAWA,UAAoC;;AAG/C,SAAgB,WAAW,GAAmC;AAC5D,WAAU;;;AAIZ,IAAI,aAAa;AACjB,IAAIC,aAAqC;;;;;AAMzC,SAAgB,MAAS,IAAgB;AACvC;AACA,KAAI,eAAe,EAAG,8BAAa,IAAI,KAAK;AAC5C,KAAI;AACF,SAAO,IAAI;WACH;AACR,MAAI,EAAE,eAAe,GAAG;GACtB,MAAM,IAAI;AACV,gBAAa;AACb,QAAK,MAAM,OAAO,EAAG,MAAK;;;;;AAMhC,SAAgB,aAAsB;AACpC,QAAO,aAAa;;;AAItB,SAAgB,gBAAgB,KAAuB;AACrD,YAAY,IAAI,IAAI;;;AAItB,SAAgB,gBAAgB,MAA0B;AACxD,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,YAAY,IAAI,KAAK,GAAI;;;AAIjE,IAAIC,gBAAiD;;;;;;;;;;;;;;;;;;AAmBrD,SAAgB,MAAS,IAA+C;CACtE,MAAMC,YAA+B,EAAE;AAGvC,KAAI,CAAC,cAAe,iBAAgB,EAAE;AACtC,eAAc,KAAK,UAAU;AAE7B,KAAI;AAEF,SAAO,CADQ,IAAI,QAGX;AACJ,QAAK,IAAI,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,IACzC,WAAU,IAAK;AAEjB,aAAU,SAAS;IAEtB;WACO;AAER,gBAAc,KAAK;AACnB,MAAI,CAAC,cAAc,OAAQ,iBAAgB;;;;;;;AAQ/C,SAAgB,iBAAiB,SAA2B;AAC1D,gBAAe,GAAG,GAAG,EAAE,KAAK,QAAQ;;;;;;;AAQtC,MAAaC,UAET,EAAE,SAAS,MAAM;;;;;;;ACnGrB,SAAgB,gBAAmB,OAAY,MAAe;CAC5D,MAAM,IAAI,MAAM,QAAQ,KAAK;AAC7B,KAAI,KAAK,GAAG;AACV,QAAM,KAAK,MAAM,MAAM,SAAS;AAChC,QAAM,KAAK;;;;;;;;;AAUf,IAAa,SAAb,MAAuB;CACrB;CACA,QAAsB,EAAE;CACxB,WAAgC,EAAE;CAElC,YAAY,OAAU;AACpB,QAAKC,QAAS;;CAGhB,IAAI,QAAW;AACb,MAAI,QAAS,SAAQ,YAAY,KAAK;AACtC,MAAI,QAAQ,QAAS,SAAQ,QAAQ,KAAK;AAC1C,SAAO,MAAKA;;CAGd,IAAI,MAAM,GAAM;AACd,MAAI,OAAO,GAAG,MAAKA,OAAQ,EAAE,CAAE;AAC/B,QAAKA,QAAS;EAGd,MAAM,UAAU,MAAKC;AACrB,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,SAAQ,GAAI,WAAW;AAIzB,MAAI,MAAKC,KAAM,OACb,KAAI,YAAY,CACd,iBAAgB,MAAKA,KAAM;OACtB;GAEL,MAAM,OAAO,CAAC,GAAG,MAAKA,KAAM;AAC5B,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,MAAK,IAAK;;;CAKtD,UAAU,IAA4B;AACpC,QAAKA,KAAM,KAAK,GAAG;AACnB,eAAa,gBAAgB,MAAKA,MAAO,GAAG;;;;;;;;;;;CAY9C,OAAO,IAA6B;AAClC,OAAK,QAAQ,GAAG,MAAKF,MAAO;;;;;;;;;;;;CAa9B,OAAU;AACR,SAAO,MAAKA;;;CAId,IAAI,UAA+B;AACjC,SAAO,MAAKC;;;CAId,aAAa,QAAiC;AAC5C,kBAAgB,MAAKA,SAAU,OAAO;;;;AAK1C,MAAa,UAAa,UAAa,IAAI,OAAO,MAAM;;;;;;AAOxD,IAAa,iBAAb,MAA+B;CAC7B;;CAGA,YAAY,UAAmB;AAC7B,QAAKE,SAAUC;;CAGjB,IAAI,QAAW;AACb,SAAO,MAAKD,OAAQ;;;;;;;CAQtB,OAAU;AACR,SAAO,MAAKA,OAAQ,MAAM;;CAG5B,UAAU,IAA4B;AACpC,SAAO,MAAKA,OAAQ,UAAU,GAAG;;;;;;;;;;;;;;;ACvHrC,IAAa,WAAb,MAAyB;CACvB;CACA;CACA,SAAS;CACT,aAAa;CACb,QAAsB,EAAE;CACxB,WAAgC,EAAE;CAClC,WAAoD,EAAE;CACtD,eAAe;CAEf,YAAY,IAAa;AACvB,QAAKE,KAAM;AACX,QAAKC,WAAY;AAGjB,yBAAuB,KAAK,SAAS,CAAC;;CAGxC,IAAI,QAAW;AACb,MAAI,MAAKC,MAAQ,OAAKD,WAAY;AAClC,MAAI,WAAW,YAAY,KAAM,SAAQ,YAAY,KAAK;AAC1D,MAAI,QAAQ,QAAS,SAAQ,QAAQ,KAAK;AAC1C,SAAO,MAAKE;;CAGd,UAAU,IAA4B;AACpC,QAAKC,KAAM,KAAK,GAAG;AACnB,eAAa,gBAAgB,MAAKA,MAAO,GAAG;;CAG9C,UAAgB;AACd,QAAKJ,KAAM;EACX,MAAM,UAAU,MAAKK;AACrB,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;AACvB,OAAI,OAAQ,QAAO,aAAa,KAAK;;AAEvC,QAAKA,UAAW,EAAE;AAClB,QAAKD,KAAM,SAAS;;;;;;CAOtB,YAAY,QAAmD;AAE7D,MAAI,CAAC,MAAKJ,GAAK;EAEf,MAAM,UAAU,MAAKK;EACrB,MAAM,MAAM,MAAKC;AAEjB,MAAI,MAAM,QAAQ,QAAQ;AACxB,OAAI,QAAQ,SAAS,OAEnB;AAGF,QAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,QAAQ,KAAK;IACzC,MAAM,IAAI,QAAQ;AAClB,QAAI,EAAG,GAAE,aAAa,KAAK;;AAE7B,WAAQ,SAAS;;AAGnB,UAAQ,KAAK,OAAO;AACpB,SAAO,QAAQ,KAAK,KAAK;;;;;;;;;CAU3B,YAAkB;AAChB,MAAI,MAAKJ,MAAQ;EAGjB,MAAMK,QAA6B,CAAC,KAAK;EACzC,MAAMC,WAA0D,EAAE;AAElE,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,IAAI,MAAM;AAChB,OAAI,GAAEN,MAAQ;AACd,MAAEA,QAAS;GAGX,MAAM,UAAU,GAAEO;AAClB,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,IAAI,QAAQ;AAClB,QAAI,CAAC,GAAEP,MAAQ,OAAM,KAAK,EAAE;;AAI9B,OAAI,GAAEE,KAAM,UAAU,GAAEJ,GACtB,UAAS,KAAK;IAAE;IAAG,KAAK,GAAEG;IAAQ,CAAC;;AAKvC,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,MAAM,EAAE,GAAG,QAAQ,SAAS;GAC5B,MAAM,eAAe;AACnB,QAAI,GAAEH,IAAK;AACT,QAAEC,WAAY;AACd,SAAI,CAAC,OAAO,GAAG,GAAEE,OAAQ,IAAI,EAAE;MAC7B,MAAM,OAAO,GAAEC;AACf,WAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,MAAK,IAAK;;;;AAItD,GAAM,YAAY,GAAG,gBAAgB,OAAO,GAAG,QAAQ;;;;CAK3D,IAAI,UAA+B;AACjC,SAAO,MAAKK;;;CAId,aAAa,QAAiC;AAC5C,kBAAgB,MAAKA,SAAU,OAAO;;CAGxC,aAAmB;AACjB,MAAI,MAAKC,aAAc,CAAC,MAAKV,GAAK;AAClC,QAAKU,YAAa;AAElB,QAAKJ,cAAe;EACpB,MAAM,UAAU,MAAKD,QAAS;EAE9B,MAAM,OAAO;AACb,aAAW,KAAK;AAChB,MAAI;AACF,SAAKF,QAAS,MAAKH,IAAK;YAChB;AACR,cAAW,KAAK;GAGhB,MAAM,SAAS,MAAKM;AACpB,OAAI,SAAS,SAAS;IACpB,MAAM,UAAU,MAAKD;AACrB,SAAK,IAAI,IAAI,QAAQ,IAAI,SAAS,KAAK;KACrC,MAAM,SAAS,QAAQ;AACvB,SAAI,OACF,QAAO,aAAa,KAAK;;AAG7B,YAAQ,SAAS;;AAGnB,SAAKH,QAAS;AACd,SAAKQ,YAAa;;;;;AAMxB,MAAa,YAAe,OAAgB,IAAI,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjJ5D,SAAgB,OAAO,IAA2C;CAChE,IAAIC;CACJ,IAAI,WAAW;CAEf,MAAM,IAAI,eAAe;AAGvB,MAAI,SAAS;GACX,MAAM,OAAO;AACb,cAAW,KAAK;AAChB,OAAI;AACF,aAAS;aACD;AACR,eAAW,KAAK;;;AAGpB,YAAU,IAAI,IAAI;GAElB;CAEF,MAAM,QAAQ,EAAE,gBAAgB,GAAG;CAEnC,MAAM,gBAAgB;AACpB,MAAI,SAAU;AACd,aAAW;AACX,SAAO;AACP,IAAE,SAAS;AACX,aAAW;;AAKb,kBAAiB,QAAQ;AAEzB,QAAO;;;;;;;;ACjET,MAAM,QAAQ,QAAQ;;;;;AAMtB,SAAgB,MAAwB,KAAW;CACjD,MAAM,0BAAU,IAAI,KAAuC;;CAG3D,MAAM,QAAQ,UAA4B;AACxC,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,SAAS,MAAO,QAAO;AAC3B,MAAK,MAAiB,gBAAgB,OACpC,QAAO,MAAM,MAAiC;AAEhD,MAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,IAAI,KAAK;AAExB,SAAO;;;CAIT,MAAM,aAAa,KAAsB,iBAA0B;EACjE,IAAI,MAAM,QAAQ,IAAI,IAAI;AAC1B,MAAI,CAAC,KAAK;AACR,SAAM,IAAI,OAAO,KAAK,aAAa,CAAC;AACpC,WAAQ,IAAI,KAAK,IAAI;;AAEvB,SAAO;;AAGT,QAAO,IAAI,MAAM,KAAK;EACpB,IAAI,QAAQ,KAAK;AAEf,OAAI,OAAO,QAAQ,SACjB,QAAO,OAAO;AAEhB,UAAO,UAAU,KAAK,OAAO,KAAgB,CAAC;;EAGhD,IAAI,QAAQ,KAAK,OAAO;AACtB,OAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO,OAAkB;AACzB,WAAO;;GAET,MAAM,UAAU,KAAK,MAAM;AAC3B,aAAU,KAAK,OAAO,KAAgB,CAAC,QAAQ;AAC/C,UAAO,OAAkB;AACzB,UAAO;;EAGT,IAAI,QAAQ,KAAK;AACf,UAAO,QAAQ,SAAS,OAAO;;EAElC,CAAC;;;;;;ACrCJ,MAAa,YAAY,UACvB,iBAAiB,UACjB,iBAAiB,YACjB,iBAAiB;;;;ACZnB,IAAa,aAAb,MAAwB;CACtB,AAAQ,IAAI;CACZ,AAAQ,MAAM;CACd,AAAQ,OAAO;CACf,AAAQ,UAAoB,EAAE;CAC9B,AAAQ,UAAoB,EAAE;CAC9B,AAAQ,QAAgB,EAAE;CAC1B,AAAQ,OAAO;CACf,AAAQ,IAAI;CAEZ,cAAc,SAA+B,IAAoB;AAC/D,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,QAAK,MAAM,QAAQ,IAAK,GAAG;AAC3B,OAAI,IAAI,QAAQ,SAAS,EAAG,MAAK,KAAK,GAAG,GAAG;;AAE9C,MAAI,KAAK,MAAM;AACb,MAAG,OAAO,KAAK,KAAK;AACpB,QAAK,OAAO;;;CAIhB,AAAQ,MAAM,KAAa,IAAoB;AAC7C,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;GACnC,MAAM,KAAK,IAAI,IACb,KAAK,IAAI,IAAI,IACb,KAAK,IAAI,IAAI;AAEf,OAAI,KAAK,MAAM,EAEb,KAAI,OAAO,KAAK;AACd,QAAI,KAAK,MAAM;AACb,QAAG,OAAO,KAAK,KAAK;AACpB,UAAK,OAAO;;AAEd,SAAK,IAAI;SACJ,MAAK,QAAQ;YACX,KAAK,MAAM,EAEpB,KAAI,OAAO,IAAK,MAAK,IAAI;YAChB,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC/C,SAAK;AACL,SAAK,IAAI;cACA,OAAO,OAAO,OAAO,KAAK;AACnC,WAAO,IAAI,IAAI,UAAU,IAAI,OAAO,IAAK;AACzC,SAAK,IAAI;cACA,KAAK,IAAI,GAAG,EAAE;AACvB,SAAK,MAAM;AACX,SAAK,IAAI;UACJ;AACL,SAAK,QAAQ,MAAM;AACnB,SAAK,IAAI;;YAEF,KAAK,MAAM,GAEpB;QAAI,KAAK,IAAI,GAAG,CAAE,MAAK,OAAO;aACrB,KAAK,IAAI,GAAG,CACnB,MAAK,IAAI;aACA,OAAO,IAChB,MAAK,KAAK,IAAI,MAAM;aACX,OAAO,OAAO,OAAO,KAAK;AACnC;AACA,UAAK,KAAK,IAAI,KAAK;;cAEZ,KAAK,MAAM,GAAG;AAEvB,QAAI,KAAK,IAAI,GAAG,CAAE;AAClB,QAAI,OAAO,IAAK,MAAK,KAAK,IAAI,MAAM;aAC3B,OAAO,OAAO,OAAO,KAAK;AACjC;AACA,UAAK,KAAK,IAAI,KAAK;WACd;AACL,UAAK,OAAO;AACZ,UAAK,UAAU,CAAC,GAAG;AACnB,UAAK,UAAU,EAAE;AACjB,UAAK,IAAI;;cAEF,KAAK,MAAM,GAEpB;QAAI,KAAK,IAAI,GAAG,IAAI,OAAO,IAAK,MAAK,QAAQ;aACpC,OAAO,IAAK,MAAK,IAAI;aACrB,KAAK,IAAI,GAAG,EAAE;AACrB,UAAK,UAAU;AACf,UAAK,IAAI;eACA,OAAO,KAAK;AACrB,UAAK,UAAU;AACf,UAAK,KAAK,IAAI,MAAM;eACX,OAAO,OAAO,OAAO,KAAK;AACnC,UAAK,UAAU;AACf;AACA,UAAK,KAAK,IAAI,KAAK;;cAEZ,KAAK,MAAM,GAEpB;QAAI,OAAO,QAAO,OAAO,KAAK;AAC5B,UAAK,IAAI;AACT,UAAK,IAAI;eACA,CAAC,KAAK,IAAI,GAAG,EAAE;AACxB,UAAK,IAAI;AACT,UAAK,QAAQ,MAAM;AACnB,UAAK,IAAI;;cAEF,KAAK,MAAM,EAKpB,KAHY,KAAK,IACb,OAAO,KAAK,IACZ,KAAK,IAAI,GAAG,IAAI,OAAO,OAAO,OAAO,KAChC;AACP,SAAK,UAAU;AACf,SAAK,IAAI;AACT,SAAK,IAAI;AACT,QAAI,OAAO,IAAK,MAAK,KAAK,IAAI,MAAM;aAC3B,OAAO,OAAO,OAAO,KAAK;AACjC;AACA,UAAK,KAAK,IAAI,KAAK;;SAGrB,MAAK,QAAQ,KAAK,QAAQ,SAAS,MAAM;YAElC,KAAK,MAAM,GAEpB;QAAI,OAAO,KAAK;AACd,QAAG,SAAS;AACZ,UAAK,IAAI;;cAEF,KAAK,MAAM,GAEpB;QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC1C,UAAK;AACL,UAAK,IAAI;;;;;CAMjB,AAAQ,KAAK,OAAe,IAAoB;AAC9C,MAAI,KAAK,MAAM,KAAK,KAAK,MAAM,GAAG;AAChC,QAAK,QAAQ,KAAK,MAAM;AACxB,QAAK,QAAQ,KAAK,GAAG;AACrB,OAAI,KAAK,MAAM,EAAG,MAAK,IAAI;SACtB;AACL,OAAI,KAAK,MAAM;AACb,OAAG,OAAO,KAAK,KAAK;AACpB,SAAK,OAAO;;AAEd,MAAG,OAAO,MAAM;;;CAIpB,AAAQ,KAAK,IAAoB,MAAe;AAC9C,KAAG,UAAU,KAAK,KAAK,KAAK,OAAO,KAAK;AACxC,OAAK,MAAM;AACX,OAAK,QAAQ,EAAE;AACf,OAAK,IAAI;;CAGX,AAAQ,WAAW;AACjB,MAAI,KAAK,KAAM,MAAK,MAAM,KAAK;GAAC,KAAK;GAAM,KAAK;GAAS,KAAK;GAAQ,CAAC;AACvE,OAAK,OAAO;AACZ,OAAK,UAAU,EAAE;AACjB,OAAK,UAAU,EAAE;;CAGnB,AAAQ,IAAI,GAAW;AACrB,SAAQ,KAAK,OAAO,KAAK,OAAS,KAAK,OAAO,KAAK;;CAErD,AAAQ,IAAI,GAAW;AACrB,SACG,KAAK,OAAO,KAAK,OACjB,KAAK,OAAO,KAAK,OACjB,KAAK,OAAO,KAAK,OAClB,MAAM,OACN,MAAM;;CAGV,AAAQ,IAAI,GAAW;AACrB,SAAO,KAAK,OAAO,MAAM;;;;;;;;;;;;;;;;;;;AC7K7B,MAAM,SAAS;;;;;;;AA4Bf,SAAS,eAAkB,IAAa;CACtC,IAAIC;CAEJ,MAAM,IAAI,eAAe;AACvB,kBAAgB;EAChB,MAAM,CAAC,QAAQ,WAAW,MAAM,GAAG;AACnC,iBAAe;AACf,SAAO;GACP;AAEF,QAAO,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE;;;;;;;;;AAUnD,SAAS,KACP,OACA,QACiC;CACjC,IAAIC;AACJ,KAAI,OAAO,UAAU,WACnB,EAAC,OAAO,WAAW,eAAe,MAAuB;AAE3D,KAAI,SAAS,MAAM,EAAE;AACnB,SAAO,MAAM,MAAM;EACnB,MAAM,QAAQ,MAAM,gBAClB,OAAQ,MAA4B,MAAM,CAC3C;AACD,SAAO,iBAAiB,OAAO,EAAE,SAAS,IAAI;;AAEhD,QAAO,MAAM;;;AAUf,IAAa,WAAb,MAAsB;CACpB,YACE,AAAQC,SACR,AAAQC,QACR,AAAQC,UAAiC,EAAE,EAC3C;EAHQ;EACA;EACA;;;;;;CAOV,SAAuB;EACrB,MAAM,WAAW,SAAS,wBAAwB;EAClD,MAAMC,YAA4B,EAAE;EACpC,MAAMC,QAAwC,CAAC,SAAS;EACxD,MAAM,SAAS,IAAI,YAAY;EAC/B,MAAM,SAAS,KAAK;EACpB,MAAM,UAAU,KAAK;EAErB,MAAM,mBAAmB,IAAa,CAAC,MAAM,SAAS,aAAmB;GACvE,MAAM,OAAO,QAAQ;AAGrB,OAAI,KAAK,OAAO,KAAK;AACnB,QAAI,QAAQ,MAAM;KAChB,MAAM,UAAU,OAAO;AACvB,QAAG,iBAAiB,KAAK,MAAM,EAAE,EAAE,QAAQ;AAC3C,eAAU,WAAW,GAAG,oBAAoB,KAAK,MAAM,EAAE,EAAE,QAAQ,CAAC;;AAEtE;;AAIF,OAAI,KAAK,OAAO,KAAK;AACnB,QAAI,QAAQ,MAAM;KAChB,MAAM,QAAQ,KAAK,OAAO,QAAQ,MAAM;AACtC,MAAC,GAA0C,KAAK,MAAM,EAAE,IAAI;OAC5D;AACF,SAAI,MAAO,WAAU,KAAK,MAAM;;AAElC;;AAIF,OAAI,CAAC,QAAQ,QAAQ;IACnB,MAAM,QAAQ,QAAQ,MAAM;AAC5B,OAAG,aAAa,MAAM,MAAM;AAC5B;;GAIF,MAAMC,YAAiC,EAAE;AACzC,QAAK,MAAM,OAAO,SAAS;IACzB,MAAM,IAAI,OAAO;AACjB,QAAI,OAAO,MAAM,YAAY;KAC3B,MAAM,CAAC,GAAG,WAAW,eAAe,EAAmB;AACvD,YAAO,OAAO;AACd,eAAU,KAAK,EAAE;AACjB,eAAU,KAAK,QAAQ;eACd,SAAS,EAAE,CACpB,WAAU,KAAK,EAAE;;GAIrB,MAAM,eAAe;IACnB,IAAI,SAAS,QAAQ;AACrB,SAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;KACvC,MAAM,IAAI,OAAO,QAAQ;KACzB,MAAM,MAAM,SAAS,EAAE,GAAI,EAAwB,QAAQ;AAE3D,SAAI,QAAQ,WAAW,MAAM,OAAO,QAAQ,QAAQ,QAAQ;AAC1D,SAAG,gBAAgB,KAAK;AACxB;;AAEF,gBAAW,QAAQ,OAAO,KAAM,OAAO,MAAO,QAAQ,IAAI;;AAE5D,OAAG,aAAa,MAAM,OAAO;;AAG/B,WAAQ;AACR,QAAK,MAAM,KAAK,UAAW,WAAU,KAAK,EAAE,UAAU,OAAO,CAAC;;;;;;EAOhE,MAAM,eAAe,QAAiB,UAAiC;AAErE,QAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,SAAS,OAAO,MAAM;AAC5B,QAAI,QAAQ;KACV,MAAMC,kBAAkC,EAAE;AAC1C,YAAO,QAAQ,gBAAgB;AAC/B,kBAAa,gBAAgB,SAAS,MAAM,GAAG,CAAC;;;GAKpD,IAAIC,QAAgB,EAAE;GACtB,IAAIC,iBAAiC,EAAE;GAEvC,MAAM,cAAc;AAClB,mBAAe,SAAS,MAAM,GAAG,CAAC;AAClC,qBAAiB,EAAE;AACnB,UAAM,SAAS,MAAO,EAAgB,QAAQ,CAAC;AAC/C,YAAQ,EAAE;;GAGZ,MAAM,UAAU,MAAe;AAC7B,WAAO;AACP,kBAAc,QAAQ,GAAG,OAAO,eAAe;;GAGjD,MAAM,QAAQ,KAAK,OAAO,OAAO;AACjC,gBAAa;AACX,aAAS;AACT,WAAO;;;AAIX,SAAO,cAAc,KAAK,SAAS;GACjC,SAAS,SAAS;AAChB,UAAM,GAAG,GAAG,CAAE,OAAO,KAAK;;GAG5B,YAAY,KAAK,OAAO,gBAAgB;IACtC,MAAM,SAAS,MAAM,GAAG,GAAG;IAK3B,MAAM,KAHJ,QAAQ,SACR,QAAQ,SACP,kBAAkB,WAAW,OAAO,iBAAiB,SAEpD,SAAS,gBAAgB,QAAQ,IAAI,GACrC,SAAS,cAAc,IAAI;AAC/B,SAAK,MAAM,QAAQ,MAAO,iBAAgB,IAAI,KAAK;AACnD,WAAO,YAAY,GAAG;AACtB,QAAI,CAAC,YAAa,OAAM,KAAK,GAAG;;GAGlC,eAAe;AACb,QAAI,MAAM,SAAS,EAAG,OAAM,KAAK;;GAGnC,SAAS,UAAU;IAEjB,MAAM,SAAS,SAAS,cAAc,GAAG;AACzC,UAAM,GAAG,GAAG,CAAE,YAAY,OAAO;AACjC,cAAU,KAAK,YAAY,QAAQ,OAAO,OAAO,CAAC;;GAErD,CAAC;AAEF,SAAO;GAAE;GAAU,eAAe,UAAU,SAAS,MAAM,GAAG,CAAC;GAAE;;;;;;;AAQrE,SAAS,cACP,QACA,GACA,OACA,gBACM;CACN,MAAM,SAAS,OAAO;AAEtB,MAAK,MAAM,QAAQ,MAAM,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE,CAE3C,KAAI,gBAAgB,UAAU;EAC5B,MAAM,EAAE,UAAU,YAAY,KAAK,QAAQ;AAC3C,iBAAe,KAAK,QAAQ;AAC5B,QAAM,KAAK,GAAG,SAAS,WAAW;AAClC,SAAO,aAAa,UAAU,OAAO;YAG9B,QAAQ,QAAQ,OAAO,SAAS,WAAW;EAClD,MAAM,OAAO,SAAS,eAAe,OAAO,KAAK,CAAC;AAClD,QAAM,KAAK,KAAK;AAChB,SAAO,aAAa,MAAM,OAAO;;;;;;AAQvC,SAAS,sBAAsB,SAAyC;CACtE,MAAM,QAAQ,SAA+B,GAAG,WAC9C,IAAI,SAAS,SAAS,QAAQ,QAAQ;AAExC,KAAI,QAAQ,GAAG,gBACb,sBAAsB,CAAC,GAAG,SAAS,GAAG,YAAY,CAAC;AAErD,QAAO;;;;;;;;;;;;;;;;;AAkBT,MAAaC,OAAgB,sBAAsB,EAAE,CAAC"}
|
package/dist/balises.iife.js
CHANGED
|
@@ -144,6 +144,19 @@ var Balises = (function(exports) {
|
|
|
144
144
|
update(fn) {
|
|
145
145
|
this.value = fn(this.#value);
|
|
146
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Read the signal value without tracking dependencies.
|
|
149
|
+
* Useful in event handlers where you want the current value
|
|
150
|
+
* but don't want to create a reactive dependency.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* const count = signal(0);
|
|
154
|
+
* // In an event handler - no dependency tracking
|
|
155
|
+
* button.onclick = () => console.log(count.peek());
|
|
156
|
+
*/
|
|
157
|
+
peek() {
|
|
158
|
+
return this.#value;
|
|
159
|
+
}
|
|
147
160
|
/** @internal */
|
|
148
161
|
get targets() {
|
|
149
162
|
return this.#targets;
|
|
@@ -155,6 +168,32 @@ var Balises = (function(exports) {
|
|
|
155
168
|
};
|
|
156
169
|
/** Create a new signal with the given initial value. */
|
|
157
170
|
const signal = (value) => new Signal(value);
|
|
171
|
+
/**
|
|
172
|
+
* A read-only view of a Signal.
|
|
173
|
+
* Provides reactive access without allowing external mutation.
|
|
174
|
+
* Used by `each()` to pass item signals to render functions.
|
|
175
|
+
*/
|
|
176
|
+
var ReadonlySignal = class {
|
|
177
|
+
#signal;
|
|
178
|
+
/** @internal */
|
|
179
|
+
constructor(signal$1) {
|
|
180
|
+
this.#signal = signal$1;
|
|
181
|
+
}
|
|
182
|
+
get value() {
|
|
183
|
+
return this.#signal.value;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Read the signal value without tracking dependencies.
|
|
187
|
+
* Useful in event handlers where you want the current value
|
|
188
|
+
* but don't want to create a reactive dependency.
|
|
189
|
+
*/
|
|
190
|
+
peek() {
|
|
191
|
+
return this.#signal.peek();
|
|
192
|
+
}
|
|
193
|
+
subscribe(fn) {
|
|
194
|
+
return this.#signal.subscribe(fn);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
158
197
|
|
|
159
198
|
//#endregion
|
|
160
199
|
//#region src/signals/computed.ts
|
|
@@ -410,7 +449,7 @@ var Balises = (function(exports) {
|
|
|
410
449
|
//#endregion
|
|
411
450
|
//#region src/signals/index.ts
|
|
412
451
|
/** Check if a value is a reactive signal or computed. @internal */
|
|
413
|
-
const isSignal = (value) => value instanceof Signal || value instanceof Computed;
|
|
452
|
+
const isSignal = (value) => value instanceof Signal || value instanceof Computed || value instanceof ReadonlySignal;
|
|
414
453
|
|
|
415
454
|
//#endregion
|
|
416
455
|
//#region src/parser.ts
|