sigula 1.0.3 → 1.0.4

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 CHANGED
@@ -11,7 +11,7 @@ A minimal, signal-based web framework with fine-grained reactivity. No virtual D
11
11
  - No virtual DOM — no diffing, no VNodes. Direct real DOM operations with minimal runtime overhead
12
12
  - Minimal HTML templates — based on native string templates. No custom compiler, no DSL — just JavaScript strings
13
13
  - Batched, coalesced updates — writes are queued in a microtask, so a signal touched many times before the flush runs its bindings once, with the final value
14
- - Ultra small — ~4.1KB minified + gzipped
14
+ - Ultra small — ~4.0KB minified + gzipped
15
15
  - TypeScript friendly — full type inference for signals and template bindings
16
16
  - Simple but performant — tiny API surface, low mental overhead, no compromise on performance
17
17
 
@@ -231,7 +231,7 @@ const App: View = html`
231
231
 
232
232
  ### Ultra small
233
233
 
234
- minified + gzipped: ~4.1KB
234
+ minified + gzipped: ~4.0KB
235
235
 
236
236
  ## 📖 Reference
237
237
 
@@ -243,6 +243,7 @@ All exports are named exports from `sigula`.
243
243
  - [Control flow](#control-flow)
244
244
  - [Rendering](#rendering)
245
245
  - [Low-level API](#low-level-api)
246
+ - [Errors](#errors)
246
247
  - [Reactivity model](#reactivity-model)
247
248
 
248
249
  ### Reactivity
@@ -273,7 +274,7 @@ The core reactive value.
273
274
  | `trans` | `(fn: (v: T) => T): void` | Applies `fn` to the current value via `update`, so an equal result is skipped. |
274
275
  | `equals` | `(other: unknown): boolean` | `Equatable` implementation; two `Sig`s are equal when their values are deeply equal. |
275
276
  | `addBind` | `<C>(bind: Bind<T, C>): void` | Registers a binding. Prefer `createBind` / the `patch`/`text`/`view` APIs. |
276
- | `removeBind` | `(bind: Bind<T, CmdContext>): void` | Unregisters a binding; runs `cleanup()` when the last one goes away. |
277
+ | `removeBind` | `<C>(bind: Bind<T, C>): void` | Unregisters a binding; runs `cleanup()` when the last one goes away. |
277
278
  | `getBinds` | `(): Bind<T, CmdContext>[]` | Returns the current bindings. |
278
279
  | `cleanup` | `(): void` | Overridable hook called when a signal loses all bindings. No-op on `Sig`. |
279
280
 
@@ -356,7 +357,7 @@ const createBind: <T, C extends CmdContext>(
356
357
  cmd: Cmd<T, C>,
357
358
  ) => Bind<T, C>;
358
359
 
359
- const removeBind: (bind: Bind<unknown, CmdContext>) => void;
360
+ const removeBind: <T, C extends CmdContext>(bind: Bind<T, C>) => void;
360
361
  ```
361
362
 
362
363
  Low-level bind management. `createBind` wires `cmd(sig.get(), context)` to run whenever `sig` changes; `removeBind` detaches it. `Bind` is the resulting record:
@@ -394,7 +395,7 @@ html`<p>${text(label)}</p>`;
394
395
  html`<button ${patch(on('click', handler))}>Go</button>`;
395
396
  ```
396
397
 
397
- Templates are cached per call site, so repeated renders skip parsing. Using `patch(...)` in a content position throws `html: unmatched interpolation; patch() must be in attribute position`. An interpolation count that does not match the number of slots throws `html: expected N interpolation(s), got M`; a mismatch means the cached template for that call site was built from a different mix of interpolations.
398
+ Templates are cached per call site, so repeated renders skip parsing. Using `patch(...)` in a content position throws `E12`. An interpolation count that does not match the number of slots throws `E11:<expected>:<got>`; a mismatch means the cached template for that call site was built from a different mix of interpolations. See [Errors](#errors).
398
399
 
399
400
  #### `text`
400
401
 
@@ -415,23 +416,23 @@ interface View<T = unknown, C extends CmdContext = any> {
415
416
  type: 'view';
416
417
  node: Node;
417
418
  bind?: Bind<T, C> | undefined;
418
- childCommits?: Commit<unknown, CmdContext>[];
419
- live?: () => Boundary | undefined;
419
+ cleanBinds: () => void;
420
+ boundary: () => Boundary;
421
+ children?: (AnyView | Patch)[];
420
422
  }
421
423
 
422
424
  type AnyView = View<any, any>;
423
425
  ```
424
426
 
425
- `View` is the unit returned by `html`, `text`, `view`, and `repeat`. Its `node` is a DOM node or `DocumentFragment`. `live` returns the boundary the view currently occupies; `render` calls it at disposal time so a view that swaps its own contents (`view`, `repeat`) is torn down from its current nodes.
427
+ `View` is the unit returned by `html`, `text`, `view`, and `repeat`. Its `node` is a DOM node or `DocumentFragment`. `boundary` returns the nodes the view currently occupies; `render` calls it at disposal time so a view that swaps its own contents (`view`, `repeat`) is torn down from its current nodes. `cleanBinds` detaches the view's bindings and, recursively, those of its `children`.
426
428
 
427
- #### `extractBoundary` / `replaceWithView`
429
+ #### `replaceWithView`
428
430
 
429
431
  ```ts
430
- const extractBoundary: (view: View) => Boundary;
431
432
  const replaceWithView: (old: Boundary, view: View) => Boundary;
432
433
  ```
433
434
 
434
- Helpers used by `view` and `repeat` to mount a view and later swap it. `extractBoundary` wraps `view.node` in a `Boundary`; `replaceWithView` replaces an existing boundary with the view's node and returns the new boundary.
435
+ Helper used by `view` and `repeat` to swap a mounted view: replaces an existing boundary with the view's node and returns the new boundary.
435
436
 
436
437
  ### DOM bindings
437
438
 
@@ -571,10 +572,11 @@ type ToAnyPatchItem = (el: Element) => AnyPatchItem;
571
572
  interface Patch {
572
573
  type: 'patch';
573
574
  toPatchItems: ToAnyPatchItem[];
575
+ cleanBinds: () => void;
574
576
  }
575
577
  ```
576
578
 
577
- `ToPatchItem` defers reading the target element until mount. `patch` collects these factories into a single `Patch`.
579
+ `ToPatchItem` defers reading the target element until mount. `patch` collects these factories into a single `Patch`; `cleanBinds` detaches the bindings created when the patch was committed to an element.
578
580
 
579
581
  ### Control flow
580
582
 
@@ -635,7 +637,7 @@ render(() => html`<p>lazy</p>`, document.body);
635
637
  dispose();
636
638
  ```
637
639
 
638
- A view that swaps its own contents — one built with `view()` or `repeat()` at the root — disposes the nodes currently in `node`, not the ones originally appended. An empty template such as html`` renders nothing and its disposer is a no-op.
640
+ A view that swaps its own contents — one built with `view()` or `repeat()` at the root — disposes the nodes currently in `node`, not the ones originally appended. An empty tagged template throws `E10`.
639
641
 
640
642
  ### Low-level API
641
643
 
@@ -658,7 +660,15 @@ An inclusive range of sibling nodes (`start` through `end`).
658
660
  const toBoundary: (node: Node) => Boundary;
659
661
  ```
660
662
 
661
- Wraps a node in a `Boundary`. For a `DocumentFragment`, the boundary spans its first and last child; otherwise it covers the node itself. Throws `toBoundary: empty fragment` on an empty fragment.
663
+ Wraps a node in a `Boundary`. For a `DocumentFragment`, the boundary spans its first and last child; otherwise it covers the node itself. Throws `E2` on an empty fragment.
664
+
665
+ #### `walkBoundary`
666
+
667
+ ```ts
668
+ const walkBoundary: (b: Boundary, fn: (node: Node) => void) => void;
669
+ ```
670
+
671
+ Visits every node from `b.start` through `b.end`. Callers capture the next sibling before mutating; `removeBoundary` and `repeat`'s reordering are built on it.
662
672
 
663
673
  #### `removeBoundary`
664
674
 
@@ -674,7 +684,7 @@ Removes every node in the boundary. A no-op if the boundary has no parent.
674
684
  const replaceWithNode: (old: Boundary, node: Node) => Boundary;
675
685
  ```
676
686
 
677
- Replaces an entire boundary with `node` and returns the new boundary. Throws if `old` has no parent. This is the primitive behind dynamic `view` and `repeat` swaps.
687
+ Replaces an entire boundary with `node` and returns the new boundary. Throws `E3` if `old` has no parent. This is the primitive behind dynamic `view` and `repeat` swaps.
678
688
 
679
689
  #### `Cmd` / `AnyCmd` / `CmdContext`
680
690
 
@@ -689,18 +699,26 @@ type AnyCmd = Cmd<any, any>;
689
699
 
690
700
  A `Cmd` is the unit of work a binding runs: it receives the current signal value and its context.
691
701
 
692
- #### `Commit` / `cleanCommit`
702
+ ### Errors
693
703
 
694
- ```ts
695
- interface Commit<T, C extends CmdContext> {
696
- binds: Bind<T, C> | Bind<T, C>[] | undefined;
697
- children?: Commit<unknown, CmdContext>[] | undefined;
698
- }
704
+ Runtime errors carry a short code in `message` instead of a sentence, so the
705
+ string tables stay out of the bundle. Codes with arguments are colon-separated.
706
+ Look yours up here:
699
707
 
700
- const cleanCommit: (commit: Commit<unknown, CmdContext>) => void;
701
- ```
702
-
703
- A `Commit` groups the bindings created by mounting a view; `cleanCommit` recursively removes them all. `View.childCommits` carries these so a parent can tear a whole subtree down at once.
708
+ | Code | Thrown by | Meaning |
709
+ | --- | --- | --- |
710
+ | `E1:<index>` | `at` | Array index out of range. |
711
+ | `E2` | `toBoundary` | Cannot build a boundary from an empty fragment. |
712
+ | `E3` | `replaceWithNode` | The old boundary has no `parentNode`. |
713
+ | `E4` | `patch` | A keyed command (`attr`, `style`, `styleProperty`, `toggleClass`) was given no key. |
714
+ | `E5` | `patch` | `act` was given no function. |
715
+ | `E6` | `patch` | `on` was given no event type. |
716
+ | `E7` | `repeat` | The rendered items have no parent node. |
717
+ | `E8` | `repeat` | The temporary start/end fences were removed mid-update. |
718
+ | `E9` | `repeat` | There is no node after the fence to move before. |
719
+ | `E10` | `html` | The template is empty (an empty tagged template). |
720
+ | `E11:<expected>:<got>` | `html` | Interpolation count does not match the template's slots. |
721
+ | `E12` | `html` | Unmatched interpolation; `patch()` must be in attribute position. |
704
722
 
705
723
  ### Reactivity model
706
724
 
package/dist/sigula.d.ts CHANGED
@@ -3,6 +3,7 @@ export interface Boundary {
3
3
  start: Node;
4
4
  end: Node;
5
5
  }
6
+ export declare const walkBoundary: (b: Boundary, fn: (node: Node) => void) => void;
6
7
  export declare const removeBoundary: (b: Boundary) => void;
7
8
  export declare const toBoundary: (node: Node) => Boundary;
8
9
  export declare const replaceWithNode: (old: Boundary, node: Node) => Boundary;
@@ -40,7 +41,7 @@ export declare class Sig<T> implements Equatable {
40
41
  update(v: T): void;
41
42
  trans(fn: (v: T) => T): void;
42
43
  addBind<C extends CmdContext>(bind: Bind<T, C>): void;
43
- removeBind(bind: Bind<T, CmdContext>): void;
44
+ removeBind<C extends CmdContext>(bind: Bind<T, C>): void;
44
45
  getBinds(): Bind<T, CmdContext>[];
45
46
  cleanup(): void;
46
47
  }
@@ -52,16 +53,9 @@ export declare class DerivedSig<T> extends Sig<T> {
52
53
  cleanup(): void;
53
54
  }
54
55
  export declare const sig: <T>(v: T) => Sig<T>;
55
- export declare const removeBind: (bind: Bind<unknown, CmdContext>) => void;
56
+ export declare const removeBind: <T, C extends CmdContext>(bind: Bind<T, C>) => void;
56
57
  export declare const createBind: <T, C extends CmdContext>(sig: Sig<T>, context: C, cmd: Cmd<T, C>) => Bind<T, C>;
57
58
  //#endregion
58
- //#region src/commit.d.ts
59
- export interface Commit<T, C extends CmdContext = any> {
60
- binds: Bind<T, C> | Bind<T, C>[] | undefined;
61
- children?: Commit<unknown, any>[] | undefined;
62
- }
63
- export declare const cleanCommit: (commit: Commit<unknown, CmdContext>) => void;
64
- //#endregion
65
59
  //#region src/compute.d.ts
66
60
  export interface SigRecord {
67
61
  [key: string]: Sig<any>;
@@ -86,6 +80,7 @@ export type ToAnyPatchItem = (el: Element) => AnyPatchItem;
86
80
  export interface Patch {
87
81
  type: 'patch';
88
82
  toPatchItems: ToAnyPatchItem[];
83
+ cleanBinds: () => void;
89
84
  }
90
85
  export declare const patch: (...toPatchItems: ToAnyPatchItem[]) => Patch;
91
86
  export declare const id: <T>(source: T | Sig<T>) => ToPatchItem<T>;
@@ -102,22 +97,21 @@ type _Listener<K extends keyof HTMLElementEventMap> = (this: HTMLElement, ev: HT
102
97
  export declare const on: <K extends keyof HTMLElementEventMap>(type: K, listener: _Listener<K>, options?: boolean | AddEventListenerOptions) => ToPatchItem<_Listener<K>>;
103
98
  //#endregion
104
99
  //#region src/view.d.ts
100
+ export type ChildView = AnyView | Patch;
105
101
  export interface View<T = unknown, C extends CmdContext = any> {
106
102
  type: 'view';
107
103
  node: Node;
108
104
  bind?: Bind<T, C> | undefined;
109
- childCommits?: Commit<unknown, CmdContext>[];
110
- live?: () => Boundary | undefined;
105
+ cleanBinds: () => void;
106
+ boundary: () => Boundary;
107
+ children?: ChildView[] | undefined;
111
108
  }
112
109
  export type AnyView = View<any, any>;
113
110
  export interface ViewContext<T> extends CmdContext {
114
- boundary: Boundary;
115
- bind?: AnyBind | undefined;
116
- childCommits?: Commit<unknown, CmdContext>[] | undefined;
117
- viewFn: (val: T) => View;
111
+ inner: AnyView;
112
+ viewFn: (val: T) => AnyView;
118
113
  }
119
114
  export declare const view: <T>(sig: Sig<T>, viewFn: (val: T) => AnyView) => View<T, ViewContext<T>>;
120
- export declare const extractBoundary: (view: View) => Boundary;
121
115
  export declare const replaceWithView: (old: Boundary, view: View) => Boundary;
122
116
  //#endregion
123
117
  //#region src/html.d.ts
@@ -133,11 +127,9 @@ export type RepeatProp<T> = {
133
127
  compare?: (a: T, b: T) => boolean;
134
128
  };
135
129
  interface Track<T> {
136
- boundary: Boundary;
137
- bind?: AnyBind | undefined;
138
- item: T;
139
130
  key: string;
140
- childCommits?: Commit<unknown, CmdContext>[] | undefined;
131
+ item: T;
132
+ view: AnyView;
141
133
  checked?: boolean;
142
134
  cleaned?: boolean;
143
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sigula.d.ts","names":[],"sources":["../src/boundary.ts","../src/cmd.ts","../src/eq.ts","../src/sig.bind.ts","../src/commit.ts","../src/compute.ts","../src/patch.ts","../src/view.ts","../src/html.ts","../src/render.ts","../src/repeat.ts","../src/text.ts"],"mappings":"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"}
1
+ {"version":3,"file":"sigula.d.ts","names":[],"sources":["../src/boundary.ts","../src/cmd.ts","../src/eq.ts","../src/sig.bind.ts","../src/compute.ts","../src/patch.ts","../src/view.ts","../src/html.ts","../src/render.ts","../src/repeat.ts","../src/text.ts"],"mappings":"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"}
package/dist/sigula.js CHANGED
@@ -1,2 +1,2 @@
1
- const e=e=>{let t=e.start.parentNode;if(t){if(e.start===e.end)t.removeChild(e.start);else{let n=e.start;for(;n;){let r=n.nextSibling;if(t.removeChild(n),n===e.end)break;n=r}}}},t=e=>{let t=e.nodeType===Node.DOCUMENT_FRAGMENT_NODE?{start:e.firstChild,end:e.lastChild}:{start:e,end:e};if(!t.start||!t.end)throw Error(`toBoundary: empty fragment`);return t},n=(e,n)=>{let r=t(n),i=e.start.parentNode;if(!i)throw Error(`replaceWithNode: old boundary has no parentNode`);if(e.start===e.end)i.replaceChild(n,e.start);else{let t=e.start.nextSibling;for(i.replaceChild(n,e.start);t;){let n=t.nextSibling;if(i.removeChild(t),t===e.end)break;t=n}}return r},r=e=>typeof e==`object`&&!!e&&`equals`in e&&typeof e.equals==`function`,i=(e,t)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`)return!1;if(r(e))return e.equals(t);if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!i(e[n],t[n]))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.toString()===t.toString();if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!t.has(n)||!i(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;let n=Array.from(e),r=Array.from(t);return i(n,r)}if(Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;let n=e,a=t,o=Object.keys(n),s=Object.keys(a);if(o.length!==s.length)return!1;for(let e=0;e<o.length;e++){let t=o[e];if(!Object.hasOwn(a,t)||!i(n[t],a[t]))return!1}return!0},a=new class{_binds=[];head=0;running=!1;scheduled=!1;addAll(e){for(let t of e)t.queued||(t.queued=!0,this._binds.push(t));return this._binds.length>this.head&&this.kick(),this}kick(){this.running||this.scheduled||(this.scheduled=!0,queueMicrotask(()=>{this.running=!0,this.scheduled=!1,this.flush()}))}flush(){this.running=!0;try{for(;this.head<this._binds.length;){let e=this._binds[this.head++];try{let{removed:t,sig:n,context:r,cmd:i}=e;t||i(n.get(),r)}catch(t){console.error(`[Queue] task failed:`,t,e)}finally{e.queued=!1}}}finally{this.running=!1,this.head<this._binds.length?(this._binds=this._binds.slice(this.head),this.head=0,this.kick()):(this._binds.length=0,this.head=0)}}};var o=class e{_val;_binds=[];constructor(e){this._val=e}equals(t){return t instanceof e&&i(this.get(),t.get())}get(){return this._val}forceUpdate(e){this._val=e,a.addAll(this._binds)}update(e){i(e,this._val)||this.forceUpdate(e)}trans(e){this.update(e(this._val))}addBind(e){this._binds.push(e)}removeBind(e){let t=this._binds.indexOf(e);t>=0&&this._binds.splice(t,1),this._binds.length===0&&this.cleanup()}getBinds(){return this._binds}cleanup(){}},s=class extends o{_fromBinds=[];_linked=!0;addFromBind(e){this._fromBinds.push(e)}addBind(e){if(super.addBind(e),this._linked)return;this._linked=!0;for(let e=0;e<this._fromBinds.length;e++){let t=this._fromBinds[e];this._fromBinds[e]=u(t.sig,t.context,t.cmd)}let t=this._fromBinds[0];t&&t.cmd(t.sig.get(),t.context)}cleanup(){if(this._linked){this._linked=!1;for(let e of this._fromBinds)l(e)}}};const c=e=>new o(e),l=e=>{e.removed=!0,e.sig.removeBind(e)},u=(e,t,n)=>{let r={sig:e,context:t,cmd:n,removed:!1,queued:!1};return e.addBind(r),r},d=e=>{e.binds&&(Array.isArray(e.binds)?e.binds.forEach(e=>{l(e)}):l(e.binds)),e.children?.forEach(e=>{d(e)})},f=(e,t)=>{t.target.update(t.fn(e))},p=(e,t)=>{let n={};for(let[e,r]of t.entries)n[e]=r.get();t.target.update(t.fn(n))},m=(e,t)=>{let n=new s(t(e.get())),r={target:n,fn:t};return n.addFromBind(u(e,r,f)),n},h=(e,t)=>{let n=[],r={};for(let[t,i]of Object.entries(e))t&&i&&(n.push([t,i]),r[t]=i.get());let i=new s(t(r)),a={target:i,fn:t,entries:n};for(let e of n)i.addFromBind(u(e[1],a,p));return i};function g(e,t){return e instanceof o?m(e,t):h(e,t)}const _=(e,t)=>{let n=e[t];if(n===void 0)throw RangeError(`index ${t} out of range`);return n},v=`@sig_${Math.random().toFixed(9).slice(2)}`,y=/* @__PURE__ */ new WeakMap;let b;const x=()=>(b??=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT),b),ee=e=>e.type===`patch`?v:`<!--${v}-->`,te=e=>{if(e.length>31){let t=``;for(let n of e)t+=n.type===`patch`?`p`:`v`;return t}let t=0;for(let n=0;n<e.length;n++)e[n]?.type===`patch`&&(t|=1<<n);return t},ne=e=>e.hasAttribute(v),re=e=>e.removeAttribute(v),ie=e=>e.data.trim()===v,ae=(e,t)=>(t.replaceWith(e.node),{binds:e.bind,children:e.childCommits}),oe=(e,t)=>{let n=[];return e.toPatchItems.forEach(e=>{let r=e(t);r.source instanceof o?(r.cmd(r.source.get(),r.context),n.push(u(r.source,r.context,r.cmd))):r.cmd(r.source,r.context)}),{binds:n}},S=(e,t,n,r,i)=>{let a=x();a.currentNode=e;let o=a.nextNode(),s=0,c=0;for(;o!==null&&c<t.length;)r(o,s,c)&&(n.push({item:_(t,c),node:o}),i&&i.push(s),c++,o.nodeType===Node.ELEMENT_NODE&&re(o)),o=a.nextNode(),s++;a.currentNode=document},se=(e,...n)=>{let r=e.length-1;if(n.length!==r)throw Error(`html: expected ${r} interpolation${r===1?``:`s`}, got ${n.length}`);let i,a=[],o=te(n),s=y.get(e);if(s?.shape===o)i=document.importNode(s.el.content,!0),n&&n.length>0&&S(i,n,a,(e,t,n)=>t===s.indexes[n]);else{let t=document.createElement(`template`);t.innerHTML=C(e,...n);let r={el:t,indexes:[],shape:o};i=document.importNode(t.content,!0),n&&n.length>0&&S(i,n,a,e=>e.nodeType===Node.ELEMENT_NODE?ne(e):e.nodeType===Node.COMMENT_NODE&&ie(e),r.indexes),y.set(e,r)}if(a.length!==n.length)throw Error(`html: unmatched interpolation; patch() must be in attribute position`);let c=[];a.forEach(({item:e,node:t})=>{e.type===`patch`?c.push(oe(e,t)):e.type===`view`&&c.push(ae(e,t))});let l=i.firstChild?t(i):void 0;return{type:`view`,node:i,childCommits:c,live:()=>l}},C=(e,...t)=>{let n=e[0]??``;for(let r=0;r<t.length;r++)n+=ee(_(t,r))+(e[r+1]??``);return n},w=(...e)=>({type:`patch`,toPatchItems:e}),T=(e,t,n)=>r=>({source:e,context:t?{node:r,extra:t}:{node:r},cmd:n}),E=e=>{let t=e.extra?.[0];if(!t)throw Error(`patch: empty key`);return t},ce=(e,t)=>{t.node.id=String(e)},le=e=>T(e,void 0,ce),D=(e,t)=>{t.node.value=String(e)},O=e=>T(e,void 0,D),k=(e,t)=>{t.node.setAttribute(E(t),String(e))},A=(e,t)=>T(e,[t],k),j=(e,t)=>{t.node.style[E(t)]=String(e)},M=(e,t)=>T(e,[t],j),N=(e,t)=>{t.node.style.setProperty(E(t),String(e))},P=(e,t)=>T(e,[t],N),F=(e,t)=>{t.node.classList.toggle(E(t),!!e)},I=(e,t)=>T(e,[t],F),L=(e,t)=>{t.extra?.forEach(n=>{t.node.classList.toggle(n,!!e)})},R=(e,...t)=>T(e,t,L),z=(e,t)=>{let n=t.extra?.[0];if(!n)throw Error(`patch: no function`);n(t.node,e)},B=(e,t)=>T(e,[t],z),V=(e,t)=>{let n=t.extra?.[0],r=t.extra?.[1];if(!n)throw Error(`patch: no event type`);t.node.addEventListener(n,e,r)},ue=(e,t,n)=>T(t,[e,n],V),H=(t,n)=>{let r=typeof t==`function`?t():t;n.appendChild(r.node);let i={binds:r.bind,children:r.childCommits};return()=>{d(i);let t=r.live?.();t&&e(t)}},U=(e,t)=>{let n=t.viewFn(e),r=G(t.boundary,n);t.bind&&l(t.bind),t.childCommits?.forEach(e=>{d(e)}),t.boundary=r,t.bind=n.bind,t.childCommits=n.childCommits},de=(e,t)=>{let n=t(e.get()),r={boundary:W(n),bind:n.bind,viewFn:t,childCommits:n.childCommits},i=u(e,r,U);return{...n,bind:i,live:()=>r.boundary}},W=e=>t(e.node),G=(e,t)=>n(e,t.node),K=t=>{e(t.boundary),t.bind&&l(t.bind),t.childCommits?.forEach(e=>{d(e)}),t.cleaned=!0},fe=(e,t)=>{if(!Array.isArray(e)||e.length===0){let e=document.createDocumentFragment();e.appendChild(document.createComment(`empty-list`)),t.boundary=n(t.boundary,e),t.tracks.forEach(K),t.tracks=[];return}let r=[];if(!Array.isArray(t.tracks)||t.tracks.length===0){let i=$(e,t.prop,r);t.boundary=n(t.boundary,i),t.tracks=r;return}let a=t.boundary.start,o=t.boundary.end,s=a.parentNode;if(!s)throw Error(`no parent node`);let c=t.prop.compare??i,l=e.map(e=>t.prop.key(e)),u=t.tracks;if(u.length===e.length&&u.every((t,n)=>{let r=e[n];return t.key===l[n]&&c(t.item,r)}))return;let d=document.createComment(`repeat-start-fence`),f=document.createComment(`repeat-end-fence`);s.insertBefore(d,a),s.insertBefore(f,o.nextSibling);let p={parent:s,startFence:d,endFence:f},m=u.map(e=>e.key),h,g,v=0,y=t.tracks.length-1,b=0,x=e.length-1;for(;v<=y&&b<=x;)if(t.tracks[v]?.checked)v++;else if(t.tracks[y]?.checked)y--;else if(t.tracks[v]?.key===l[b])r[b]=Q(_(t.tracks,v),_(e,b),t.prop,c),v++,b++;else if(t.tracks[y]?.key===l[x])r[x]=Q(_(t.tracks,y),_(e,x),t.prop,c),y--,x--;else if(t.tracks[v]?.key===l[x])r[x]=Q(_(t.tracks,v),_(e,x),t.prop,c),X(p,_(r,x),pe(p,r[x+1])),v++,x--;else if(t.tracks[y]?.key===l[b])r[b]=Q(_(t.tracks,y),_(e,b),t.prop,c),X(p,_(r,b),J(p,r[b-1])),y--,b++;else if((h===void 0||g===void 0)&&(h=q(l,b,x),g=q(m,v,y)),!h.has(m[v]))K(_(t.tracks,v)),v++;else if(!h.has(m[y]))K(_(t.tracks,y)),y--;else{let n=g.get(l[b]),i=n===void 0?null:t.tracks[n];i?(r[b]=Q(i,_(e,b),t.prop,c),X(p,_(r,b),J(p,r[b-1])),i.checked=!0):r[b]=Z(p,_(e,b),t.prop,J(p,r[b-1])),b++}for(;b<=x;)r[b]=Z(p,_(e,b),t.prop,J(p,r[b-1])),b++;for(;v<=y;)!t.tracks[v]?.cleaned&&!t.tracks[v]?.checked&&K(_(t.tracks,v)),v++;if(!p.startFence.nextSibling||!p.endFence.previousSibling)throw Error(`error container fences`);t.boundary={start:p.startFence.nextSibling,end:p.endFence.previousSibling},p.parent.removeChild(p.startFence),p.parent.removeChild(p.endFence),t.tracks=r},q=(e,t,n)=>{let r=/* @__PURE__ */ new Map;for(let i=t;i<=n;i++)r.set(e[i],i);return r},pe=(e,t)=>t?t.boundary.start:e.endFence,J=(e,t)=>{let n=t?t.boundary.end:e.startFence;if(!n.nextSibling)throw Error(`no after fence`);return n.nextSibling},Y=(e,t,n)=>{e.moveBefore?e.moveBefore(t,n):e.insertBefore(t,n)},X=(e,t,n)=>{let r=e.parent;if(t.boundary.start===t.boundary.end)Y(r,t.boundary.start,n);else{let e=t.boundary.start;for(;e;){let i=e.nextSibling;if(Y(r,e,n),e===t.boundary.end)break;e=i}}},Z=(e,t,n,r)=>{let i=n.view(t),a=W(i);return e.parent.insertBefore(i.node,r),{key:n.key(t),boundary:a,bind:i.bind,childCommits:i.childCommits,item:t}},Q=(e,t,n,r)=>{if(r(e.item,t))return{...e,checked:!1,cleaned:!1};let i=n.view(t),a=G(e.boundary,i);return K(e),{key:n.key(t),boundary:a,bind:i.bind,childCommits:i.childCommits,item:t}},$=(e,t,n)=>{let r=document.createDocumentFragment();return e.forEach(e=>{let i=t.view(e),a=t.key(e),o=W(i);n.push({key:a,boundary:o,bind:i.bind,item:e,childCommits:i.childCommits}),r.appendChild(i.node)}),r.childNodes.length===0&&r.appendChild(document.createComment(`empty-list`)),r},me=(e,n)=>{let r=[],i=$(e.get(),n,r),a={prop:n,tracks:r,boundary:t(i)};return{type:`view`,node:i,bind:u(e,a,fe),live:()=>a.boundary}},he=(e,t)=>{t.node.textContent=String(e)},ge=e=>{let t=document.createTextNode(e instanceof o?String(e.get()):String(e)),n={node:t};return{type:`view`,node:t,bind:e instanceof o?u(e,n,he):void 0}};export{s as DerivedSig,o as Sig,B as act,A as attr,d as cleanCommit,g as compute,u as createBind,W as extractBoundary,se as html,le as id,i as isEqual,ue as on,w as patch,l as removeBind,e as removeBoundary,H as render,me as repeat,n as replaceWithNode,G as replaceWithView,c as sig,M as style,P as styleProperty,ge as text,t as toBoundary,I as toggleClass,R as toggleClasses,O as val,de as view};
1
+ function e(e){throw Error(e)}const t=(e,t)=>{let n=e.start;for(;n;){let r=n.nextSibling;if(t(n),n===e.end)break;n=r}},n=e=>{let n=e.start.parentNode;n&&t(e,e=>n.removeChild(e))},r=t=>{let n=t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?{start:t.firstChild,end:t.lastChild}:{start:t,end:t};return(!n.start||!n.end)&&e(`E2`),n},i=(t,n)=>{let i=r(n),a=t.start.parentNode;if(a||e(`E3`),t.start===t.end)a.replaceChild(n,t.start);else{let e=t.start.nextSibling;for(a.replaceChild(n,t.start);e;){let n=e.nextSibling;if(a.removeChild(e),e===t.end)break;e=n}}return i},a=e=>typeof e==`object`&&!!e&&`equals`in e&&typeof e.equals==`function`,o=(e,t)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`)return!1;if(a(e))return e.equals(t);if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!o(e[n],t[n]))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.toString()===t.toString();if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!t.has(n)||!o(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;let n=Array.from(e),r=Array.from(t);return o(n,r)}if(Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;let n=e,r=t,i=Object.keys(n),s=Object.keys(r);if(i.length!==s.length)return!1;for(let e=0;e<i.length;e++){let t=i[e];if(!Object.hasOwn(r,t)||!o(n[t],r[t]))return!1}return!0},s=new class{_binds=[];head=0;running=!1;scheduled=!1;addAll(e){for(let t of e)t.queued||(t.queued=!0,this._binds.push(t));return this._binds.length>this.head&&this.kick(),this}kick(){this.running||this.scheduled||(this.scheduled=!0,queueMicrotask(()=>{this.running=!0,this.scheduled=!1,this.flush()}))}flush(){this.running=!0;try{for(;this.head<this._binds.length;){let e=this._binds[this.head++];try{let{removed:t,sig:n,context:r,cmd:i}=e;t||i(n.get(),r)}catch(t){console.error(`[Queue] task failed:`,t,e)}finally{e.queued=!1}}}finally{this.running=!1,this.head<this._binds.length?(this._binds=this._binds.slice(this.head),this.head=0,this.kick()):(this._binds.length=0,this.head=0)}}};var c=class e{_val;_binds=[];constructor(e){this._val=e}equals(t){return t instanceof e&&o(this.get(),t.get())}get(){return this._val}forceUpdate(e){this._val=e,s.addAll(this._binds)}update(e){o(e,this._val)||this.forceUpdate(e)}trans(e){this.update(e(this._val))}addBind(e){this._binds.push(e)}removeBind(e){let t=this._binds.indexOf(e);t>=0&&this._binds.splice(t,1),this._binds.length===0&&this.cleanup()}getBinds(){return this._binds}cleanup(){}},l=class extends c{_fromBinds=[];_linked=!0;addFromBind(e){this._fromBinds.push(e)}addBind(e){if(super.addBind(e),this._linked)return;this._linked=!0;for(let e=0;e<this._fromBinds.length;e++){let t=this._fromBinds[e];this._fromBinds[e]=f(t.sig,t.context,t.cmd)}let t=this._fromBinds[0];t&&t.cmd(t.sig.get(),t.context)}cleanup(){if(this._linked){this._linked=!1;for(let e of this._fromBinds)d(e)}}};const u=e=>new c(e),d=e=>{e.removed=!0,e.sig.removeBind(e)},f=(e,t,n)=>{let r={sig:e,context:t,cmd:n,removed:!1,queued:!1};return e.addBind(r),r},p=(e,t)=>{t.target.update(t.fn(e))},m=(e,t)=>{let n={};for(let[e,r]of t.entries)n[e]=r.get();t.target.update(t.fn(n))},h=(e,t)=>{let n=new l(t(e.get())),r={target:n,fn:t};return n.addFromBind(f(e,r,p)),n},g=(e,t)=>{let n=[],r={};for(let[t,i]of Object.entries(e))t&&i&&(n.push([t,i]),r[t]=i.get());let i=new l(t(r)),a={target:i,fn:t,entries:n};for(let e of n)i.addFromBind(f(e[1],a,m));return i};function _(e,t){return e instanceof c?h(e,t):g(e,t)}const v=(e,t)=>{let n=e[t];if(n===void 0)throw RangeError(`E1:${t}`);return n},y=`@sig_${Math.random().toFixed(9).slice(2)}`,b=/* @__PURE__ */ new WeakMap;let x;const S=()=>(x??=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT),x),ee=e=>e.type===`patch`?y:`<!--${y}-->`,C=e=>{if(e.length>31){let t=``;for(let n of e)t+=n.type===`patch`?`p`:`v`;return t}let t=0;for(let n=0;n<e.length;n++)e[n]?.type===`patch`&&(t|=1<<n);return t},w=e=>e.hasAttribute(y),te=e=>e.removeAttribute(y),ne=e=>e.data.trim()===y,T=(e,t)=>{t.replaceWith(e.node)},re=(e,t)=>{let n=[];e.toPatchItems.forEach(e=>{let r=e(t);r.source instanceof c?(r.cmd(r.source.get(),r.context),n.push(f(r.source,r.context,r.cmd))):r.cmd(r.source,r.context)}),e.cleanBinds=()=>{n.forEach(d)}},E=(e,t,n,r,i)=>{let a=S();a.currentNode=e;let o=a.nextNode(),s=0,c=0;for(;o!==null&&c<t.length;)r(o,s,c)&&(n.push({item:v(t,c),node:o}),i&&i.push(s),c++,o.nodeType===Node.ELEMENT_NODE&&te(o)),o=a.nextNode(),s++;a.currentNode=document},ie=(t,...n)=>{t.length<=1&&!t?.[0]&&e(`E10`);let i=t.length-1;n.length!==i&&e(`E11:${i}:${n.length}`);let a,o=[],s=C(n),c=b.get(t);if(c?.shape===s)a=document.importNode(c.el.content,!0),n&&n.length>0&&E(a,n,o,(e,t,n)=>t===c.indexes[n]);else{let e=document.createElement(`template`);e.innerHTML=ae(t,...n);let r={el:e,indexes:[],shape:s};a=document.importNode(e.content,!0),n&&n.length>0&&E(a,n,o,e=>e.nodeType===Node.ELEMENT_NODE?w(e):e.nodeType===Node.COMMENT_NODE&&ne(e),r.indexes),b.set(t,r)}o.length!==n.length&&e(`E12`),o.forEach(({item:e,node:t})=>{e.type===`patch`?re(e,t):T(e,t)});let l=o.map(e=>e.item),u=r(a);return{type:`view`,node:a,children:l,boundary:()=>{let e=t.length-1;if(!t[0]){let e=l[0];e?.type===`view`&&(u.start=e.boundary().start)}if(!t[e]){let t=l[e-1];t?.type===`view`&&(u.end=t.boundary().end)}return u},cleanBinds:()=>{l.forEach(e=>{e.cleanBinds()})}}},ae=(e,...t)=>{let n=e[0]??``;for(let r=0;r<t.length;r++)n+=ee(v(t,r))+(e[r+1]??``);return n},oe=()=>{},se=(...e)=>({type:`patch`,toPatchItems:e,cleanBinds:oe}),D=(e,t,n)=>r=>({source:e,context:t?{node:r,extra:t}:{node:r},cmd:n}),O=t=>{let n=t.extra?.[0];return n||e(`E4`),n},k=(e,t)=>{t.node.id=String(e)},A=e=>D(e,void 0,k),j=(e,t)=>{t.node.value=String(e)},M=e=>D(e,void 0,j),N=(e,t)=>{t.node.setAttribute(O(t),String(e))},P=(e,t)=>D(e,[t],N),F=(e,t)=>{t.node.style[O(t)]=String(e)},I=(e,t)=>D(e,[t],F),L=(e,t)=>{t.node.style.setProperty(O(t),String(e))},R=(e,t)=>D(e,[t],L),z=(e,t)=>{t.node.classList.toggle(O(t),!!e)},B=(e,t)=>D(e,[t],z),V=(e,t)=>{t.extra?.forEach(n=>{t.node.classList.toggle(n,!!e)})},H=(e,...t)=>D(e,t,V),ce=(t,n)=>{let r=n.extra?.[0];r||e(`E5`),r(n.node,t)},U=(e,t)=>D(e,[t],ce),W=(t,n)=>{let r=n.extra?.[0],i=n.extra?.[1];r||e(`E6`),n.node.addEventListener(r,t,i)},G=(e,t,n)=>D(t,[e,n],W),le=(e,t)=>{let r=typeof e==`function`?e():e;return t.appendChild(r.node),()=>{n(r.boundary()),r.cleanBinds()}},ue=(e,t)=>{let n=t.inner.boundary(),r=t.viewFn(e);K(n,r),t.inner.cleanBinds(),t.inner=r},de=(e,t)=>{let n=t(e.get()),r={inner:n,viewFn:t},i=f(e,r,ue);return{type:`view`,node:n.node,bind:i,boundary:()=>r.inner.boundary(),cleanBinds:()=>{d(i),r.inner.cleanBinds()}}},K=(e,t)=>i(e,t.node),q=e=>{n(e.view.boundary()),e.view.cleanBinds(),e.cleaned=!0},fe=(t,n)=>{if(!Array.isArray(t)||t.length===0){let e=document.createDocumentFragment();e.appendChild(document.createComment(`empty-list`)),n.boundary=i(n.boundary,e),n.tracks.forEach(q),n.tracks=[];return}let r=[];if(!Array.isArray(n.tracks)||n.tracks.length===0){let e=$(t,n.prop,r);n.boundary=i(n.boundary,e),n.tracks=r;return}let a=n.boundary.start,s=n.boundary.end,c=a.parentNode;c||e(`E7`);let l=n.prop.compare??o,u=t.map(e=>n.prop.key(e)),d=n.tracks;if(d.length===t.length&&d.every((e,n)=>{let r=t[n];return e.key===u[n]&&l(e.item,r)}))return;let f=document.createComment(`repeat-start-fence`),p=document.createComment(`repeat-end-fence`);c.insertBefore(f,a),c.insertBefore(p,s.nextSibling);let m={parent:c,startFence:f,endFence:p},h=d.map(e=>e.key),g,_,y=0,b=n.tracks.length-1,x=0,S=t.length-1;for(;y<=b&&x<=S;)if(n.tracks[y]?.checked)y++;else if(n.tracks[b]?.checked)b--;else if(n.tracks[y]?.key===u[x])r[x]=Q(v(n.tracks,y),v(t,x),n.prop,l),y++,x++;else if(n.tracks[b]?.key===u[S])r[S]=Q(v(n.tracks,b),v(t,S),n.prop,l),b--,S--;else if(n.tracks[y]?.key===u[S])r[S]=Q(v(n.tracks,y),v(t,S),n.prop,l),X(m,v(r,S),pe(m,r[S+1])),y++,S--;else if(n.tracks[b]?.key===u[x])r[x]=Q(v(n.tracks,b),v(t,x),n.prop,l),X(m,v(r,x),Y(m,r[x-1])),b--,x++;else if((g===void 0||_===void 0)&&(g=J(u,x,S),_=J(h,y,b)),!g.has(h[y]))q(v(n.tracks,y)),y++;else if(!g.has(h[b]))q(v(n.tracks,b)),b--;else{let e=_.get(u[x]),i=e===void 0?null:n.tracks[e];i?(r[x]=Q(i,v(t,x),n.prop,l),X(m,v(r,x),Y(m,r[x-1])),i.checked=!0):r[x]=Z(m,v(t,x),n.prop,Y(m,r[x-1])),x++}for(;x<=S;)r[x]=Z(m,v(t,x),n.prop,Y(m,r[x-1])),x++;for(;y<=b;)!n.tracks[y]?.cleaned&&!n.tracks[y]?.checked&&q(v(n.tracks,y)),y++;(!m.startFence.nextSibling||!m.endFence.previousSibling)&&e(`E8`),n.boundary={start:m.startFence.nextSibling,end:m.endFence.previousSibling},m.parent.removeChild(m.startFence),m.parent.removeChild(m.endFence),n.tracks=r},J=(e,t,n)=>{let r=/* @__PURE__ */ new Map;for(let i=t;i<=n;i++)r.set(e[i],i);return r},pe=(e,t)=>t?t.view.boundary().start:e.endFence,Y=(t,n)=>{let r=n?n.view.boundary().end:t.startFence;return r.nextSibling||e(`E9`),r.nextSibling},me=(e,t,n)=>{e.moveBefore?e.moveBefore(t,n):e.insertBefore(t,n)},X=(e,n,r)=>{let i=e.parent;t(n.view.boundary(),e=>me(i,e,r))},Z=(e,t,n,r)=>{let i=n.view(t);return e.parent.insertBefore(i.node,r),{key:n.key(t),item:t,view:i}},Q=(e,t,n,r)=>{if(r(e.item,t))return{...e,checked:!1,cleaned:!1};let i=e.view.boundary(),a=n.view(t);return K(i,a),q(e),{key:n.key(t),item:t,view:a}},$=(e,t,n)=>{let r=document.createDocumentFragment();return e.forEach(e=>{let i=t.view(e),a=t.key(e);n.push({key:a,item:e,view:i}),r.appendChild(i.node)}),r.childNodes.length===0&&r.appendChild(document.createComment(`empty-list`)),r},he=(e,t)=>{let n=[],i=$(e.get(),t,n),a={prop:t,tracks:n,boundary:r(i)},o=f(e,a,fe);return{type:`view`,node:i,bind:o,boundary:()=>a.boundary,cleanBinds:()=>{d(o),a.tracks.forEach(e=>{e.view.cleanBinds()})}}},ge=(e,t)=>{t.node.textContent=String(e)},_e=e=>{let t=document.createTextNode(e instanceof c?String(e.get()):String(e)),n={node:t},i=e instanceof c?f(e,n,ge):void 0,a=r(t);return{type:`view`,node:t,bind:i,boundary:()=>a,cleanBinds:()=>{i&&d(i)}}};export{l as DerivedSig,c as Sig,U as act,P as attr,_ as compute,f as createBind,ie as html,A as id,o as isEqual,G as on,se as patch,d as removeBind,n as removeBoundary,le as render,he as repeat,i as replaceWithNode,K as replaceWithView,u as sig,I as style,R as styleProperty,_e as text,r as toBoundary,B as toggleClass,H as toggleClasses,M as val,de as view,t as walkBoundary};
2
2
  //# sourceMappingURL=sigula.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sigula.js","names":["removeBoundary","parent","b","next","toBoundary","node","replaceWithNode","newBoundary","old","n","isEquatable","value","isEqual","a","i","key","val","arrA","arrB","ao","bo","aKeys","bKeys","QUEUE","bind","binds","removed","cmd","sig","context","err","Sig","v","fn","index","DerivedSig","f","createBind","first","removeBind","cleanCommit","commit","child","computeCmd","ctx","s","computeRecordCmd","vals","k","_compute","target","source","_computeRecord","entries","entry","compute","at","arr","MARK","tplCache","walker","_walker","_toMark","item","_shape","items","shape","bits","_hasMark","el","_rmMark","_isView","commitView","view","commitPatch","patch","toPatchItem","_scan","w","frag","nodeIndex","itemIndex","hit","wraps","indexes","html","slots","strs","exist","template","_text","tpl","commits","boundary","parts","text","toPatchItems","_toPatchItem","extra","elem","_key","idCmd","id","valCmd","attrCmd","attr","styleCmd","style","stylePropertyCmd","styleProperty","toggleClassCmd","toggleClass","token","toggleClassesCmd","toggleClasses","tokens","actCmd","act","onCmd","type","options","listener","on","render","viewArg","viewCmd","replaceWithView","viewFn","extractBoundary","_cleanTrack","track","repeatCmd","newFrag","newTracks","_init","start","end","compare","newKeys","tracks","startFence","endFence","container","oldKeys","newKeyToIndexMap","oldKeyToIndexMap","oldHead","oldTail","newHead","newTail","_setTrack","_moveTrack","_beforeFence","_afterFence","_generateMap","oldIndex","oldTrack","_insertNewTrack","map","list","_mvNodeBefore","fence","prop","repeat","textCmd"],"sources":["../src/boundary.ts","../src/eq.ts","../src/sig.bind.ts","../src/commit.ts","../src/compute.ts","../src/utils.ts","../src/html.ts","../src/patch.ts","../src/render.ts","../src/view.ts","../src/repeat.ts","../src/text.ts"],"sourcesContent":["export interface Boundary {\n start: Node;\n end: Node;\n}\n\nexport const removeBoundary = (b: Boundary) => {\n const parent = b.start.parentNode;\n if (!parent) {\n return;\n }\n\n if (b.start === b.end) parent.removeChild(b.start);\n else {\n // walking siblings is faster than a Range\n let n: Node | null = b.start;\n while (n) {\n const next: Node | null = n.nextSibling;\n parent.removeChild(n);\n if (n === b.end) break;\n n = next;\n }\n }\n};\n\nexport const toBoundary = (node: Node): Boundary => {\n const b =\n node.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ? {start: node.firstChild, end: node.lastChild}\n : {start: node, end: node};\n if (!b.start || !b.end) throw new Error('toBoundary: empty fragment');\n return b as Boundary;\n};\n\nexport const replaceWithNode = (old: Boundary, node: Node) => {\n const newBoundary = toBoundary(node);\n const parent = old.start.parentNode;\n if (!parent)\n throw new Error('replaceWithNode: old boundary has no parentNode');\n\n if (old.start === old.end) {\n parent.replaceChild(node, old.start);\n } else {\n let n = old.start.nextSibling;\n parent.replaceChild(node, old.start);\n while (n) {\n const next = n.nextSibling;\n parent.removeChild(n);\n if (n === old.end) break;\n n = next;\n }\n }\n\n return newBoundary;\n};\n","export interface Equatable {\n equals(other: unknown): boolean;\n}\n\nconst isEquatable = (value: unknown): value is Equatable =>\n typeof value === 'object' &&\n value !== null &&\n 'equals' in value &&\n typeof value.equals === 'function';\n\nexport type UnknownRecord = Record<string, unknown>;\n\nexport const isEqual = <T>(a: T, b: T): boolean => {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n\n if (a === null || b === null || typeof a !== 'object') return false;\n\n if (isEquatable(a)) return a.equals(b);\n\n // may let Array always return false\n // if (Array.isArray(a) || Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Date\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n\n // RegExp\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n // Map\n if (a instanceof Map && b instanceof Map) {\n if (a.size !== b.size) return false;\n for (const [key, val] of a) {\n if (!b.has(key) || !isEqual(val, b.get(key))) return false;\n }\n return true;\n }\n\n // Set\n if (a instanceof Set && b instanceof Set) {\n if (a.size !== b.size) return false;\n const arrA = Array.from(a);\n const arrB = Array.from(b);\n return isEqual(arrA, arrB);\n }\n\n // Object & Record\n // Reject different prototypes before falling back to a key comparison.\n // Object.keys is [] for Date, Map, Set, RegExp, Error and [], so without\n // this guard isEqual([], {}) and isEqual(new Date(0), {}) both report\n // equal and Sig.update silently swallows a shape-changing write.\n // Must stay BELOW the isEquatable check above: hoisting it stops a user\n // Equatable from ever being consulted.\n if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n\n // both are objects sharing one prototype from here on, and the length check\n // plus Object.hasOwn below prove the two key sets are identical, so ao[key]\n // is always an own property\n const ao = a as UnknownRecord;\n const bo = b as UnknownRecord;\n\n const aKeys = Object.keys(ao);\n const bKeys = Object.keys(bo);\n if (aKeys.length !== bKeys.length) return false;\n\n for (let i = 0; i < aKeys.length; i++) {\n const key = aKeys[i] as string;\n if (!Object.hasOwn(bo, key)) return false;\n if (!isEqual(ao[key], bo[key])) return false;\n }\n\n return true;\n};\n","import type {Cmd, CmdContext} from './cmd';\nimport {type Equatable, isEqual} from './eq';\n\nexport interface Bind<T, C extends CmdContext> {\n sig: Sig<T>;\n context: C;\n cmd: Cmd<T, C>;\n removed: boolean;\n queued?: boolean;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: any bind\nexport type AnyBind = Bind<any, any>;\n\nclass Queue {\n private _binds: AnyBind[] = [];\n private head = 0;\n private running = false;\n private scheduled = false;\n\n addAll(binds: readonly AnyBind[]): this {\n for (const bind of binds) {\n if (bind.queued) continue;\n bind.queued = true;\n this._binds.push(bind);\n }\n if (this._binds.length > this.head) this.kick();\n return this;\n }\n\n private kick(): void {\n if (this.running || this.scheduled) return;\n this.scheduled = true;\n queueMicrotask(() => {\n this.running = true;\n this.scheduled = false;\n this.flush();\n });\n }\n\n private flush(): void {\n this.running = true;\n try {\n while (this.head < this._binds.length) {\n const bind = this._binds[this.head++]!;\n try {\n const {removed, sig, context, cmd} = bind;\n if (!removed) cmd(sig.get(), context);\n } catch (err) {\n console.error('[Queue] task failed:', err, bind);\n } finally {\n // re-arm after running: cmd reads sig.get() at call time, so a bind\n // that runs after a write already sees the newest value and must\n // not re-run, while one that ran before it has to be queued again\n bind.queued = false;\n }\n }\n } finally {\n this.running = false;\n if (this.head < this._binds.length) {\n // almost impossible in js/ts\n this._binds = this._binds.slice(this.head);\n this.head = 0;\n this.kick();\n } else {\n this._binds.length = 0;\n this.head = 0;\n }\n }\n }\n}\n\nconst QUEUE = new Queue();\n\nexport class Sig<T> implements Equatable {\n private _val: T;\n private _binds: AnyBind[] = [];\n\n constructor(val: T) {\n this._val = val;\n }\n\n equals(b: unknown) {\n if (b instanceof Sig) return isEqual(this.get(), b.get());\n return false;\n }\n\n get(): T {\n return this._val;\n }\n\n forceUpdate(v: T) {\n this._val = v;\n QUEUE.addAll(this._binds);\n }\n\n update(v: T) {\n if (isEqual(v, this._val)) return;\n this.forceUpdate(v);\n }\n\n trans(fn: (v: T) => T) {\n this.update(fn(this._val));\n }\n\n addBind<C extends CmdContext>(bind: Bind<T, C>) {\n this._binds.push(bind);\n }\n\n removeBind(bind: Bind<T, CmdContext>) {\n const index = this._binds.indexOf(bind);\n if (index >= 0) this._binds.splice(index, 1);\n if (this._binds.length === 0) {\n this.cleanup();\n }\n }\n\n getBinds(): Bind<T, CmdContext>[] {\n return this._binds;\n }\n\n // empty: DerivedSig overrides this to detach from its sources when its last\n // observer goes away\n cleanup() {}\n}\n\nexport class DerivedSig<T> extends Sig<T> {\n private _fromBinds: AnyBind[] = [];\n private _linked = true;\n\n addFromBind<S, C extends CmdContext>(bind: Bind<S, C>) {\n this._fromBinds.push(bind);\n }\n\n // A derived signal's upstream links are torn down when its last observer\n // goes away, which happens any time a view() subtree is hidden. The links\n // cannot be revived in place because removeBind marks them removed, so we\n // rebuild fresh binds from each recipe and recompute once: sources usually\n // moved while we were detached.\n //\n // super.addBind must stay first: the recompute below updates this signal\n // straight away, so the returning observer has to be registered before it\n // or it misses the value and only catches up on some later update.\n override addBind<C extends CmdContext>(bind: Bind<T, C>) {\n super.addBind(bind);\n if (this._linked) return;\n this._linked = true;\n for (let i = 0; i < this._fromBinds.length; i++) {\n const f = this._fromBinds[i]!;\n this._fromBinds[i] = createBind(f.sig, f.context, f.cmd);\n }\n // every from-bind shares one context whose cmd reads all sources, so one\n // invocation recomputes the whole derived value\n const first = this._fromBinds[0];\n if (first) first.cmd(first.sig.get(), first.context);\n }\n\n override cleanup() {\n if (!this._linked) return;\n this._linked = false;\n for (const b of this._fromBinds) removeBind(b);\n }\n}\n\nexport const sig = <T>(v: T) => new Sig(v);\n\nexport const removeBind = (bind: Bind<unknown, CmdContext>) => {\n bind.removed = true;\n bind.sig.removeBind(bind);\n};\n\nexport const createBind = <T, C extends CmdContext>(\n sig: Sig<T>,\n context: C,\n cmd: Cmd<T, C>,\n): Bind<T, C> => {\n const bind: Bind<T, C> = {sig, context, cmd, removed: false, queued: false};\n sig.addBind(bind);\n return bind;\n};\n","import type {CmdContext} from './cmd';\nimport {type Bind, removeBind} from './sig.bind';\n\n// biome-ignore lint/suspicious/noExplicitAny: Commit with any context\nexport interface Commit<T, C extends CmdContext = any> {\n binds: Bind<T, C> | Bind<T, C>[] | undefined;\n // biome-ignore lint/suspicious/noExplicitAny: Commit.children with any context\n children?: Commit<unknown, any>[] | undefined;\n}\n\nexport const cleanCommit = (commit: Commit<unknown, CmdContext>) => {\n if (commit.binds) {\n if (Array.isArray(commit.binds)) {\n commit.binds.forEach((bind) => {\n removeBind(bind);\n });\n } else {\n removeBind(commit.binds);\n }\n }\n commit.children?.forEach((child) => {\n cleanCommit(child);\n });\n};\n","import type {CmdContext} from './cmd';\nimport {createBind, DerivedSig, Sig} from './sig.bind';\n\nexport interface SigRecord {\n // biome-ignore lint/suspicious/noExplicitAny: any sig val\n [key: string]: Sig<any>;\n}\n\nexport type ValRecord<K extends SigRecord> = {\n [P in keyof K]: K[P] extends Sig<infer U> ? U : never;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: heterogeneous source sigs\ntype ComputeEntry = [string, Sig<any>];\n\ninterface ComputeContext<S, T> extends CmdContext {\n target: Sig<T>;\n fn: (s: S) => T;\n}\n\ninterface ComputeRecordContext<S extends SigRecord, T> extends CmdContext {\n target: Sig<T>;\n fn: (v: ValRecord<S>) => T;\n entries: ComputeEntry[];\n}\n\nconst computeCmd = <S, T>(s: S, ctx: ComputeContext<S, T>) => {\n ctx.target.update(ctx.fn(s));\n};\n\nconst computeRecordCmd = <S extends SigRecord, T>(\n _s: unknown,\n ctx: ComputeRecordContext<S, T>,\n) => {\n const vals: Record<string, unknown> = {};\n for (const [k, s] of ctx.entries) vals[k] = s.get();\n ctx.target.update(ctx.fn(vals as ValRecord<S>));\n};\n\nconst _compute = <S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T> => {\n const target = new DerivedSig(fn(source.get()));\n const ctx: ComputeContext<S, T> = {target, fn};\n target.addFromBind(createBind(source, ctx, computeCmd));\n return target;\n};\n\nconst _computeRecord = <S extends SigRecord, T>(\n source: S,\n fn: (v: ValRecord<S>) => T,\n): DerivedSig<T> => {\n const entries: ComputeEntry[] = [];\n const vals: Record<string, unknown> = {};\n for (const [k, s] of Object.entries(source)) {\n if (!k || !s) continue;\n entries.push([k, s]);\n vals[k] = s.get();\n }\n\n const target = new DerivedSig(fn(vals as ValRecord<S>));\n const ctx: ComputeRecordContext<S, T> = {target, fn, entries};\n\n for (const entry of entries) {\n target.addFromBind(createBind(entry[1], ctx, computeRecordCmd));\n }\n\n return target;\n};\n\nexport function compute<S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T>;\nexport function compute<S extends SigRecord, T>(\n source: S,\n fn: (v: ValRecord<S>) => T,\n): DerivedSig<T>;\n// biome-ignore lint/suspicious/noExplicitAny: any source\nexport function compute(source: any, fn: (v: any) => any): DerivedSig<any> {\n return source instanceof Sig\n ? _compute(source, fn)\n : _computeRecord(source, fn);\n}\n","export const at = <T>(arr: T[], index: number): T => {\n const v = arr[index];\n if (v === undefined) throw new RangeError(`index ${index} out of range`);\n return v;\n};\n","import {toBoundary} from './boundary';\nimport type {CmdContext} from './cmd';\nimport type {Commit} from './commit';\nimport type {Patch, PatchContext} from './patch';\nimport {type Bind, createBind, Sig} from './sig.bind';\nimport {at} from './utils';\nimport type {AnyView, View} from './view';\n\nconst MARK = `@sig_${Math.random().toFixed(9).slice(2)}`;\n\ninterface Tpl {\n el: HTMLTemplateElement;\n indexes: number[];\n // a bitmask for up to 31 slots, the string form beyond that\n shape: number | string;\n}\n\ninterface Wrap<T, C extends CmdContext> {\n item: Patch | View<T, C>;\n node: Node;\n}\n\nconst tplCache = new WeakMap<TemplateStringsArray, Tpl>();\n\nlet walker: TreeWalker | undefined;\n\n// Created on first use rather than at module scope so that importing sigula\n// stays side-effect free and works where there is no document (SSR, tests).\nconst _walker = (): TreeWalker => {\n walker ??= document.createTreeWalker(\n document,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n );\n return walker;\n};\n\nconst _toMark = (item: Patch | View): string =>\n item.type === 'patch' ? MARK : `<!--${MARK}-->`;\n\n// The markup of a call site depends on the kind of every interpolation: a patch\n// gets an attribute marker, a view gets a comment marker. Reusing a cached\n// template across a different mix would hand the wrong node type to\n// commitPatch/commitView, so the mix is part of the cache identity.\n// A bitmask is far cheaper to build and compare than a string, and 31 slots\n// keeps it a non-negative int32 — 1 << 31 flips the sign. Beyond that fall\n// back to the string form so wide templates keep working unchanged.\nconst MAX_MASKED_SLOTS = 31;\n\nconst _shape = (items: readonly (Patch | AnyView)[]): number | string => {\n if (items.length > MAX_MASKED_SLOTS) {\n let shape = '';\n for (const item of items) shape += item.type === 'patch' ? 'p' : 'v';\n return shape;\n }\n let bits = 0;\n for (let i = 0; i < items.length; i++) {\n if (items[i]?.type === 'patch') bits |= 1 << i;\n }\n return bits;\n};\n\nconst _hasMark = (el: Element) => el.hasAttribute(MARK);\nconst _rmMark = (el: Element) => el.removeAttribute(MARK);\nconst _isView = (item: Comment) => item.data.trim() === MARK;\n\nconst commitView = <T, C extends CmdContext>(\n view: View<T, C>,\n node: Node,\n): Commit<T, C> => {\n (node as Comment).replaceWith(view.node);\n return {\n binds: view.bind,\n children: view.childCommits,\n };\n};\n\nconst commitPatch = (\n patch: Patch,\n node: Node,\n): Commit<unknown, PatchContext> => {\n const binds: Bind<unknown, PatchContext>[] = [];\n patch.toPatchItems.forEach((toPatchItem) => {\n const item = toPatchItem(node as Element);\n if (item.source instanceof Sig) {\n item.cmd(item.source.get(), item.context);\n binds.push(createBind(item.source, item.context, item.cmd));\n // binds.push(item.source, item.context, item.cmd);\n } else {\n item.cmd(item.source, item.context);\n }\n });\n\n return {binds};\n};\n\n// Both template passes walk the same tree hunting for the next interpolation\n// slot and then do exactly the same thing with it; only the way a slot is\n// recognised differs, so that part is the only argument.\nconst _scan = (\n frag: DocumentFragment,\n items: (Patch | AnyView)[],\n wraps: Wrap<unknown, CmdContext>[],\n hit: (node: Node, nodeIndex: number, itemIndex: number) => boolean,\n indexes?: number[],\n) => {\n const w = _walker();\n w.currentNode = frag;\n let node = w.nextNode();\n let nodeIndex = 0;\n let itemIndex = 0;\n while (node !== null && itemIndex < items.length) {\n if (hit(node, nodeIndex, itemIndex)) {\n wraps.push({item: at(items, itemIndex), node});\n if (indexes) indexes.push(nodeIndex);\n itemIndex++;\n if (node.nodeType === Node.ELEMENT_NODE) _rmMark(node as Element);\n }\n node = w.nextNode();\n nodeIndex++;\n }\n // https://github.com/lit/lit/blob/c42ee1e96b8fd61f7256f61d715daef572e76e52/packages/lit-html/src/lit-html.ts#L1260\n // We need to set the currentNode away from the cloned tree so that we\n // don't hold onto the tree even if it is detached and should be freed.\n w.currentNode = document;\n};\n\nexport const html = (\n strs: TemplateStringsArray,\n ...items: (Patch | AnyView)[]\n): View => {\n // const frag = document.createDocumentFragment();\n const slots = strs.length - 1;\n if (items.length !== slots) {\n throw new Error(\n `html: expected ${slots} interpolation${slots === 1 ? '' : 's'}, got ${items.length}`,\n );\n }\n\n let frag: DocumentFragment;\n const wraps: Wrap<unknown, CmdContext>[] = [];\n\n const shape = _shape(items);\n const exist = tplCache.get(strs);\n if (exist?.shape === shape) {\n frag = document.importNode(exist.el.content, true);\n if (items && items.length > 0) {\n _scan(\n frag,\n items,\n wraps,\n (_node, nodeIndex, itemIndex) => nodeIndex === exist.indexes[itemIndex],\n );\n }\n } else {\n const template = document.createElement('template');\n template.innerHTML = _text(strs, ...items);\n const tpl: Tpl = {el: template, indexes: [], shape};\n frag = document.importNode(template.content, true);\n\n if (items && items.length > 0) {\n _scan(\n frag,\n items,\n wraps,\n (node) =>\n node.nodeType === Node.ELEMENT_NODE\n ? _hasMark(node as Element)\n : node.nodeType === Node.COMMENT_NODE && _isView(node as Comment),\n tpl.indexes,\n );\n }\n\n tplCache.set(strs, tpl);\n }\n\n if (wraps.length !== items.length)\n throw new Error(\n 'html: unmatched interpolation; patch() must be in attribute position',\n );\n\n const commits: Commit<unknown>[] = [];\n wraps.forEach(({item, node}) => {\n if (item.type === 'patch') {\n commits.push(commitPatch(item, node));\n } else if (item.type === 'view') {\n commits.push(commitView(item, node));\n }\n });\n\n const boundary = frag.firstChild ? toBoundary(frag) : undefined;\n\n return {\n type: 'view',\n node: frag,\n childCommits: commits,\n live: () => boundary,\n };\n};\n\nconst _text = (strs: TemplateStringsArray, ...parts: (Patch | AnyView)[]) => {\n let text = strs[0] ?? '';\n for (let i = 0; i < parts.length; i++) {\n text += _toMark(at(parts, i)) + (strs[i + 1] ?? '');\n }\n return text;\n};\n","import type {Cmd, CmdContext} from './cmd';\nimport type {Sig} from './sig.bind';\n\nexport interface PatchContext extends CmdContext {\n // kind: 'elem';\n node: Node;\n extra?: unknown[];\n}\n\nexport interface PatchItem<T> {\n source: T | Sig<T>;\n context: PatchContext;\n cmd: Cmd<T, PatchContext>;\n}\nexport type ToPatchItem<T> = (el: Element) => PatchItem<T>;\n\n// biome-ignore lint/suspicious/noExplicitAny: any patch item\nexport type AnyPatchItem = PatchItem<any>;\nexport type ToAnyPatchItem = (el: Element) => AnyPatchItem;\n\nexport interface Patch {\n type: 'patch';\n toPatchItems: ToAnyPatchItem[];\n}\n\nexport const patch = (...toPatchItems: ToAnyPatchItem[]): Patch => ({\n type: 'patch',\n toPatchItems,\n});\n\n// Every patch item is the same shape -- bind `source` to `elem` plus whatever\n// arguments the command needs -- so the whole body lives here once.\nconst _toPatchItem =\n <T>(\n source: T | Sig<T>,\n extra: unknown[] | undefined,\n cmd: Cmd<T, PatchContext>,\n ): ToPatchItem<T> =>\n (elem) => ({\n source,\n context: extra ? {node: elem, extra} : {node: elem},\n cmd,\n });\n\n// most commands take their attribute/style/class name as the first extra\nconst _key = (ctx: PatchContext): string => {\n const key = ctx.extra?.[0];\n if (!key) throw new Error('patch: empty key');\n return key as string;\n};\n\nconst idCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).id = String(val);\n};\n\nexport const id = <T>(source: T | Sig<T>): ToPatchItem<T> =>\n _toPatchItem(source, undefined, idCmd);\n\nconst valCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as unknown as {value: string}).value = String(val);\n};\n\nexport const val = <T>(source: T | Sig<T>): ToPatchItem<T> =>\n _toPatchItem(source, undefined, valCmd);\n\nconst attrCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).setAttribute(_key(ctx), String(val));\n};\n\nexport const attr = <T>(source: T | Sig<T>, key: string): ToPatchItem<T> =>\n _toPatchItem(source, [key], attrCmd);\n\nexport type WritableStyleKey = {\n [K in keyof CSSStyleDeclaration]: CSSStyleDeclaration[K] extends string\n ? K\n : never;\n}[keyof CSSStyleDeclaration];\n\nconst styleCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as HTMLElement).style[_key(ctx) as WritableStyleKey] = String(val);\n};\n\nexport const style = <T>(\n source: T | Sig<T>,\n key: WritableStyleKey,\n): ToPatchItem<T> => _toPatchItem(source, [key], styleCmd);\n\nconst stylePropertyCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as HTMLElement).style.setProperty(_key(ctx), String(val));\n};\n\nexport const styleProperty = <T>(\n source: T | Sig<T>,\n key: string,\n): ToPatchItem<T> => _toPatchItem(source, [key], stylePropertyCmd);\n\nconst toggleClassCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).classList.toggle(_key(ctx), Boolean(val));\n};\n\nexport const toggleClass = <T>(\n source: T | Sig<T>,\n token: string,\n): ToPatchItem<T> => _toPatchItem(source, [token], toggleClassCmd);\n\nconst toggleClassesCmd = <T>(val: T, ctx: PatchContext) => {\n ctx.extra?.forEach((token) => {\n (ctx.node as Element).classList.toggle(token as string, Boolean(val));\n });\n};\n\nexport const toggleClasses = <T>(\n source: T | Sig<T>,\n ...tokens: string[]\n): ToPatchItem<T> => _toPatchItem(source, tokens, toggleClassesCmd);\n\nexport type ActFn<T> = (node: Node, val?: T) => void;\n\nconst actCmd = <T>(val: T, ctx: PatchContext) => {\n const fn = ctx.extra?.[0] as ActFn<T> | undefined;\n if (!fn) throw new Error('patch: no function');\n fn(ctx.node, val);\n};\n\nexport const act = <T>(source: T | Sig<T>, fn: ActFn<T>): ToPatchItem<T> =>\n _toPatchItem(source, [fn], actCmd);\n\ntype _Listener<K extends keyof HTMLElementEventMap> = (\n this: HTMLElement,\n ev: HTMLElementEventMap[K],\n) => unknown;\n\nconst onCmd = (listener: unknown, ctx: PatchContext) => {\n const type = ctx.extra?.[0] as string | undefined;\n const options = ctx.extra?.[1] as\n | boolean\n | AddEventListenerOptions\n | undefined;\n if (!type) throw new Error('patch: no event type');\n ctx.node.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject,\n options,\n );\n};\n\nexport const on = <K extends keyof HTMLElementEventMap>(\n type: K,\n listener: _Listener<K>,\n options?: boolean | AddEventListenerOptions,\n): ToPatchItem<_Listener<K>> => _toPatchItem(listener, [type, options], onCmd);\n","import {removeBoundary} from './boundary';\nimport type {CmdContext} from './cmd';\nimport type {Commit} from './commit';\nimport {cleanCommit} from './commit';\nimport type {AnyView} from './view';\n\nexport const render = (\n viewArg: AnyView | (() => AnyView),\n node: Node,\n): (() => void) => {\n const view = typeof viewArg === 'function' ? viewArg() : viewArg;\n node.appendChild(view.node);\n const commit: Commit<unknown, CmdContext> = {\n binds: view.bind,\n children: view.childCommits,\n };\n return () => {\n cleanCommit(commit);\n // Read the boundary at dispose time, never at mount. view() and repeat()\n // swap ctx.boundary on every update, so the nodes still in the host are\n // the current ones, not the ones render originally appended.\n const boundary = view.live?.();\n if (boundary) removeBoundary(boundary);\n };\n};\n","import {type Boundary, replaceWithNode, toBoundary} from './boundary';\nimport type {CmdContext} from './cmd';\nimport {type Commit, cleanCommit} from './commit';\nimport {\n type AnyBind,\n type Bind,\n createBind,\n removeBind,\n type Sig,\n} from './sig.bind';\n\n// biome-ignore lint/suspicious/noExplicitAny: View with any context\nexport interface View<T = unknown, C extends CmdContext = any> {\n type: 'view';\n node: Node;\n bind?: Bind<T, C> | undefined;\n childCommits?: Commit<unknown, CmdContext>[];\n live?: () => Boundary | undefined;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: any view\nexport type AnyView = View<any, any>;\n\nexport interface ViewContext<T> extends CmdContext {\n boundary: Boundary;\n bind?: AnyBind | undefined;\n childCommits?: Commit<unknown, CmdContext>[] | undefined;\n viewFn: (val: T) => View;\n}\n\nconst viewCmd = <T>(val: T, ctx: ViewContext<T>) => {\n const view = ctx.viewFn(val);\n const newBoundary = replaceWithView(ctx.boundary, view);\n if (ctx.bind) removeBind(ctx.bind);\n ctx.childCommits?.forEach((commit) => {\n cleanCommit(commit);\n });\n ctx.boundary = newBoundary;\n ctx.bind = view.bind;\n ctx.childCommits = view.childCommits;\n};\n\nexport const view = <T>(\n sig: Sig<T>,\n viewFn: (val: T) => AnyView,\n): View<T, ViewContext<T>> => {\n const view = viewFn(sig.get());\n\n const boundary = extractBoundary(view);\n\n const ctx: ViewContext<T> = {\n boundary,\n bind: view.bind,\n viewFn,\n childCommits: view.childCommits,\n };\n\n const bind = createBind(sig, ctx, viewCmd);\n\n return {\n ...view,\n bind,\n live: () => ctx.boundary,\n };\n};\n\nexport const extractBoundary = (view: View): Boundary => toBoundary(view.node);\n\nexport const replaceWithView = (old: Boundary, view: View): Boundary => {\n return replaceWithNode(old, view.node);\n};\n","import {\n type Boundary,\n removeBoundary,\n replaceWithNode,\n toBoundary,\n} from './boundary';\nimport type {CmdContext} from './cmd';\nimport {type Commit, cleanCommit} from './commit';\nimport {isEqual} from './eq';\nimport {type AnyBind, createBind, removeBind, type Sig} from './sig.bind';\nimport {at} from './utils';\nimport {\n type AnyView,\n extractBoundary,\n replaceWithView,\n type View,\n} from './view';\n\nexport type RepeatProp<T> = {\n key: (item: T) => string;\n view: (item: T) => AnyView;\n compare?: (a: T, b: T) => boolean;\n};\n\ninterface Container {\n parent: ParentNode;\n startFence: Node;\n endFence: Node;\n}\n\ninterface Track<T> {\n boundary: Boundary;\n bind?: AnyBind | undefined;\n item: T;\n key: string;\n childCommits?: Commit<unknown, CmdContext>[] | undefined;\n checked?: boolean;\n cleaned?: boolean;\n}\n\nexport interface RepeatContext<T> extends CmdContext {\n prop: RepeatProp<T>;\n boundary: Boundary;\n tracks: Track<T>[];\n}\n\nconst _cleanTrack = <T>(track: Track<T>) => {\n removeBoundary(track.boundary);\n if (track.bind) removeBind(track.bind);\n track.childCommits?.forEach((commit) => {\n cleanCommit(commit);\n });\n track.cleaned = true;\n};\n\nconst repeatCmd = <T>(items: T[], ctx: RepeatContext<T>) => {\n if (!Array.isArray(items) || items.length === 0) {\n const newFrag = document.createDocumentFragment();\n newFrag.appendChild(document.createComment('empty-list'));\n const newBoundary = replaceWithNode(ctx.boundary, newFrag);\n ctx.boundary = newBoundary;\n ctx.tracks.forEach(_cleanTrack);\n ctx.tracks = [];\n return;\n }\n const newTracks: Track<T>[] = [];\n if (!Array.isArray(ctx.tracks) || ctx.tracks.length === 0) {\n const newFrag = _init(items, ctx.prop, newTracks);\n const newBoundary = replaceWithNode(ctx.boundary, newFrag);\n ctx.boundary = newBoundary;\n // ctx.tracks.forEach(_cleanTrack);\n ctx.tracks = newTracks;\n return;\n }\n\n const start = ctx.boundary.start;\n const end = ctx.boundary.end;\n const parent = start.parentNode;\n if (!parent) throw new Error('no parent node');\n\n const compare = ctx.prop.compare ?? isEqual;\n const newKeys = items.map((item) => ctx.prop.key(item));\n const tracks = ctx.tracks;\n\n // Nothing changed: same keys, same order, equal items. Bail out before\n // touching the DOM so a redundant re-render costs zero DOM mutations\n // instead of a fence insert/remove pair.\n if (tracks.length === items.length) {\n const unchanged = tracks.every((track, i) => {\n const item = items[i] as T;\n return track.key === newKeys[i] && compare(track.item, item);\n });\n if (unchanged) return;\n }\n\n const startFence = document.createComment('repeat-start-fence');\n const endFence = document.createComment('repeat-end-fence');\n\n parent.insertBefore(startFence, start);\n parent.insertBefore(endFence, end.nextSibling);\n\n const container: Container = {\n parent,\n startFence,\n endFence,\n };\n\n const oldKeys = tracks.map((track) => track.key);\n\n let newKeyToIndexMap: Map<unknown, number> | undefined;\n let oldKeyToIndexMap: Map<unknown, number> | undefined;\n\n let oldHead = 0;\n let oldTail = ctx.tracks.length - 1;\n let newHead = 0;\n let newTail = items.length - 1;\n\n while (oldHead <= oldTail && newHead <= newTail) {\n if (ctx.tracks[oldHead]?.checked) {\n // console.log('skip old head', ctx.tracks[oldHead].key);\n\n oldHead++;\n } else if (ctx.tracks[oldTail]?.checked) {\n // console.log('skip old tail', ctx.tracks[oldTail].key);\n\n oldTail--;\n } else if (ctx.tracks[oldHead]?.key === newKeys[newHead]) {\n // old head matches new head; update in place\n // console.log('matches head', newKeys[newHead]);\n\n newTracks[newHead] = _setTrack(\n at(ctx.tracks, oldHead),\n at(items, newHead),\n ctx.prop,\n compare,\n );\n oldHead++;\n newHead++;\n } else if (ctx.tracks[oldTail]?.key === newKeys[newTail]) {\n // old tail matches nwe tail; update in place\n // console.log('matches tail', newKeys[newTail]);\n\n newTracks[newTail] = _setTrack(\n at(ctx.tracks, oldTail),\n at(items, newTail),\n ctx.prop,\n compare,\n );\n oldTail--;\n newTail--;\n } else if (ctx.tracks[oldHead]?.key === newKeys[newTail]) {\n // Old head matches new tail; update and move to new tail\n // console.log(\n // 'Old head matches new tail',\n // ctx.tracks[oldHead].key,\n // newKeys[newTail],\n // );\n newTracks[newTail] = _setTrack(\n at(ctx.tracks, oldHead),\n at(items, newTail),\n ctx.prop,\n compare,\n );\n //\n // const before = ref ? boundaryStart(ref.boundary) : fence;\n // _moveTrackBefore(after, newTracks[newTail], newTracks[newTail + 1]);\n _moveTrack(\n container,\n at(newTracks, newTail),\n _beforeFence(container, newTracks[newTail + 1]),\n );\n oldHead++;\n newTail--;\n } else if (ctx.tracks[oldTail]?.key === newKeys[newHead]) {\n // old tail matches new head; update and move to new head\n // console.log(\n // 'old tail matches new head',\n // ctx.tracks[oldTail].key,\n // newKeys[newHead],\n // );\n\n newTracks[newHead] = _setTrack(\n at(ctx.tracks, oldTail),\n at(items, newHead),\n ctx.prop,\n compare,\n );\n // if (!before.nextSibling) throw new Error('no before.nextSibling');\n // _moveTrackAfter(before, newTracks[newHead], newTracks[newHead - 1]);\n _moveTrack(\n container,\n at(newTracks, newHead),\n _afterFence(container, newTracks[newHead - 1]),\n );\n oldTail--;\n newHead++;\n } else {\n if (newKeyToIndexMap === undefined || oldKeyToIndexMap === undefined) {\n newKeyToIndexMap = _generateMap(newKeys, newHead, newTail);\n oldKeyToIndexMap = _generateMap(oldKeys, oldHead, oldTail);\n }\n if (!newKeyToIndexMap.has(oldKeys[oldHead])) {\n // remove old head\n // console.log('remove old head', ctx.tracks[oldHead].key);\n _cleanTrack(at(ctx.tracks, oldHead));\n oldHead++;\n } else if (!newKeyToIndexMap.has(oldKeys[oldTail])) {\n // remove old tail\n // console.log('remove old tail', ctx.tracks[oldTail].key);\n _cleanTrack(at(ctx.tracks, oldTail));\n oldTail--;\n } else {\n const oldIndex = oldKeyToIndexMap.get(newKeys[newHead]);\n const oldTrack = oldIndex !== undefined ? ctx.tracks[oldIndex] : null;\n if (oldTrack) {\n // console.log(\n // 'move old item to new head:',\n // oldTrack.key,\n // newKeys[newHead],\n // );\n newTracks[newHead] = _setTrack(\n oldTrack,\n at(items, newHead),\n ctx.prop,\n compare,\n );\n // _moveTrackAfter(before, newTracks[newHead], newTracks[newHead - 1]);\n _moveTrack(\n container,\n at(newTracks, newHead),\n _afterFence(container, newTracks[newHead - 1]),\n );\n oldTrack.checked = true;\n // ctx.tracks[oldIndex as number].checked = true;\n } else {\n // create a new one and insert it\n // console.log('create new item:', newKeys[newHead]);\n newTracks[newHead] = _insertNewTrack(\n container,\n at(items, newHead),\n ctx.prop,\n _afterFence(container, newTracks[newHead - 1]),\n );\n }\n newHead++;\n }\n }\n }\n\n while (newHead <= newTail) {\n // console.log('create new head:', newKeys[newHead]);\n newTracks[newHead] = _insertNewTrack(\n container,\n at(items, newHead),\n ctx.prop,\n _afterFence(container, newTracks[newHead - 1]),\n );\n newHead++;\n }\n\n while (oldHead <= oldTail) {\n // console.log('remove old head:', ctx.tracks[oldHead].key);\n if (!ctx.tracks[oldHead]?.cleaned && !ctx.tracks[oldHead]?.checked)\n _cleanTrack(at(ctx.tracks, oldHead));\n oldHead++;\n }\n\n if (!container.startFence.nextSibling || !container.endFence.previousSibling)\n throw new Error('error container fences');\n\n ctx.boundary = {\n start: container.startFence.nextSibling,\n end: container.endFence.previousSibling,\n };\n container.parent.removeChild(container.startFence);\n container.parent.removeChild(container.endFence);\n ctx.tracks = newTracks;\n};\n\nconst _generateMap = (list: unknown[], start: number, end: number) => {\n const map = new Map<unknown, number>();\n for (let i = start; i <= end; i++) {\n map.set(list[i], i);\n }\n return map;\n};\n\nconst _beforeFence = <T>(container: Container, track?: Track<T>): Node =>\n track ? track.boundary.start : container.endFence;\nconst _afterFence = <T>(container: Container, track?: Track<T>): Node => {\n const node = track ? track.boundary.end : container.startFence;\n if (!node.nextSibling) throw new Error('no after fence');\n return node.nextSibling;\n};\n\nconst _mvNodeBefore = (parent: ParentNode, node: Node, child: Node | null) => {\n if (parent.moveBefore) parent.moveBefore(node, child);\n else parent.insertBefore(node, child);\n};\n\nconst _moveTrack = <T>(container: Container, track: Track<T>, fence: Node) => {\n const parent = container.parent;\n\n if (track.boundary.start === track.boundary.end)\n _mvNodeBefore(parent, track.boundary.start, fence);\n else {\n let n: Node | null = track.boundary.start;\n while (n) {\n const next: Node | null = n.nextSibling;\n _mvNodeBefore(parent, n, fence);\n if (n === track.boundary.end) break;\n n = next;\n }\n }\n};\n\nconst _insertNewTrack = <T>(\n container: Container,\n item: T,\n prop: RepeatProp<T>,\n fence: Node,\n): Track<T> => {\n const view = prop.view(item);\n const boundary = extractBoundary(view);\n container.parent.insertBefore(view.node, fence);\n return {\n key: prop.key(item),\n boundary,\n bind: view.bind,\n childCommits: view.childCommits,\n item,\n };\n};\n\nconst _setTrack = <T>(\n old: Track<T>,\n item: T,\n prop: RepeatProp<T>,\n compare: (a: T, b: T) => boolean,\n): Track<T> => {\n if (compare(old.item, item)) {\n return {\n ...old,\n checked: false,\n cleaned: false,\n };\n }\n\n const view = prop.view(item);\n const newBoundary = replaceWithView(old.boundary, view);\n _cleanTrack(old);\n\n const newTrack: Track<T> = {\n key: prop.key(item),\n boundary: newBoundary,\n bind: view.bind,\n childCommits: view.childCommits,\n item,\n };\n\n return newTrack;\n};\n\nconst _init = <T>(\n items: T[],\n prop: RepeatProp<T>,\n tracks: Track<T>[],\n): DocumentFragment => {\n const frag = document.createDocumentFragment();\n items.forEach((item) => {\n const view = prop.view(item);\n const key = prop.key(item);\n\n const boundary = extractBoundary(view);\n tracks.push({\n key,\n boundary,\n bind: view.bind,\n item,\n childCommits: view.childCommits,\n });\n frag.appendChild(view.node);\n });\n\n if (frag.childNodes.length === 0) {\n frag.appendChild(document.createComment('empty-list'));\n }\n return frag;\n};\n\nexport const repeat = <T>(\n sig: Sig<T[]>,\n prop: RepeatProp<T>,\n): View<T[], RepeatContext<T>> => {\n const tracks: Track<T>[] = [];\n const frag = _init(sig.get(), prop, tracks);\n\n const ctx: RepeatContext<T> = {prop, tracks, boundary: toBoundary(frag)};\n const bind = createBind(sig, ctx, repeatCmd);\n\n return {\n type: 'view',\n node: frag,\n bind,\n live: () => ctx.boundary,\n };\n};\n","import type {PatchContext} from './patch';\nimport {createBind, Sig} from './sig.bind';\nimport type {View} from './view';\n\nconst textCmd = <T>(val: T, ctx: PatchContext) => {\n ctx.node.textContent = String(val);\n};\n\nexport const text = <T>(source: T | Sig<T>): View<T, PatchContext> => {\n const text = document.createTextNode(\n source instanceof Sig ? String(source.get()) : String(source),\n );\n const ctx: PatchContext = {node: text};\n const bind =\n source instanceof Sig ? createBind(source, ctx, textCmd) : undefined;\n return {\n type: 'view',\n node: text,\n bind,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"sigula.js","names":["err","code","walkBoundary","b","next","fn","removeBoundary","parent","node","toBoundary","replaceWithNode","newBoundary","old","n","isEquatable","value","isEqual","a","i","key","val","arrA","arrB","ao","bo","aKeys","bKeys","QUEUE","bind","binds","removed","cmd","sig","context","Sig","v","index","DerivedSig","f","createBind","first","removeBind","computeCmd","ctx","s","computeRecordCmd","vals","k","_compute","target","source","_computeRecord","entries","entry","compute","at","arr","MARK","tplCache","walker","_walker","_toMark","item","_shape","items","shape","bits","_hasMark","el","_rmMark","_isView","commitView","view","commitPatch","patch","toPatchItem","_scan","w","frag","nodeIndex","itemIndex","hit","wraps","indexes","html","strs","slots","exist","template","_text","tpl","children","boundary","last","endChild","child","parts","text","_noop","toPatchItems","_toPatchItem","extra","elem","_key","idCmd","id","valCmd","attrCmd","attr","styleCmd","style","stylePropertyCmd","styleProperty","toggleClassCmd","toggleClass","token","toggleClassesCmd","toggleClasses","tokens","actCmd","act","onCmd","type","options","listener","on","render","viewArg","viewCmd","oldBoundary","newInner","replaceWithView","inner","viewFn","_cleanTrack","track","repeatCmd","newFrag","newTracks","_init","start","end","compare","newKeys","tracks","startFence","endFence","container","oldKeys","newKeyToIndexMap","oldKeyToIndexMap","oldHead","oldTail","newHead","newTail","_setTrack","_moveTrack","_beforeFence","_afterFence","_generateMap","oldIndex","oldTrack","_insertNewTrack","map","list","_mvNodeBefore","fence","prop","repeat","t","textCmd"],"sources":["../src/err.ts","../src/boundary.ts","../src/eq.ts","../src/sig.bind.ts","../src/compute.ts","../src/utils.ts","../src/html.ts","../src/patch.ts","../src/render.ts","../src/view.ts","../src/repeat.ts","../src/text.ts"],"sourcesContent":["// Thrown errors carry a short code instead of a message. The full text for\n// every code lives in the README so the runtime bundle stays small; use the\n// table there to translate `E1`, `E7`, ... back into a sentence.\nexport function err(code: string): never {\n throw new Error(code);\n}\n","import {err} from './err';\n\nexport interface Boundary {\n start: Node;\n end: Node;\n}\n\n// Visits every node from start through end. Callers capture nextSibling before\n// mutating, so the walk survives removals and moves.\nexport const walkBoundary = (b: Boundary, fn: (node: Node) => void) => {\n let n: Node | null = b.start;\n while (n) {\n const next: Node | null = n.nextSibling;\n fn(n);\n if (n === b.end) break;\n n = next;\n }\n};\n\nexport const removeBoundary = (b: Boundary) => {\n const parent = b.start.parentNode;\n if (!parent) return;\n walkBoundary(b, (node) => parent.removeChild(node));\n};\n\nexport const toBoundary = (node: Node): Boundary => {\n const b =\n node.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ? {start: node.firstChild, end: node.lastChild}\n : {start: node, end: node};\n if (!b.start || !b.end) err('E2');\n return b as Boundary;\n};\n\nexport const replaceWithNode = (old: Boundary, node: Node): Boundary => {\n const newBoundary = toBoundary(node);\n const parent = old.start.parentNode;\n if (!parent) err('E3');\n\n if (old.start === old.end) {\n parent.replaceChild(node, old.start);\n } else {\n let n = old.start.nextSibling;\n parent.replaceChild(node, old.start);\n while (n) {\n const next = n.nextSibling;\n parent.removeChild(n);\n if (n === old.end) break;\n n = next;\n }\n }\n\n return newBoundary;\n};\n","export interface Equatable {\n equals(other: unknown): boolean;\n}\n\nconst isEquatable = (value: unknown): value is Equatable =>\n typeof value === 'object' &&\n value !== null &&\n 'equals' in value &&\n typeof value.equals === 'function';\n\nexport type UnknownRecord = Record<string, unknown>;\n\nexport const isEqual = <T>(a: T, b: T): boolean => {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n\n if (a === null || b === null || typeof a !== 'object') return false;\n\n if (isEquatable(a)) return a.equals(b);\n\n // may let Array always return false\n // if (Array.isArray(a) || Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Date\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n\n // RegExp\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n // Map\n if (a instanceof Map && b instanceof Map) {\n if (a.size !== b.size) return false;\n for (const [key, val] of a) {\n if (!b.has(key) || !isEqual(val, b.get(key))) return false;\n }\n return true;\n }\n\n // Set\n if (a instanceof Set && b instanceof Set) {\n if (a.size !== b.size) return false;\n const arrA = Array.from(a);\n const arrB = Array.from(b);\n return isEqual(arrA, arrB);\n }\n\n // Object & Record\n // Reject different prototypes before falling back to a key comparison.\n // Object.keys is [] for Date, Map, Set, RegExp, Error and [], so without\n // this guard isEqual([], {}) and isEqual(new Date(0), {}) both report\n // equal and Sig.update silently swallows a shape-changing write.\n // Must stay BELOW the isEquatable check above: hoisting it stops a user\n // Equatable from ever being consulted.\n if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n\n // both are objects sharing one prototype from here on, and the length check\n // plus Object.hasOwn below prove the two key sets are identical, so ao[key]\n // is always an own property\n const ao = a as UnknownRecord;\n const bo = b as UnknownRecord;\n\n const aKeys = Object.keys(ao);\n const bKeys = Object.keys(bo);\n if (aKeys.length !== bKeys.length) return false;\n\n for (let i = 0; i < aKeys.length; i++) {\n const key = aKeys[i] as string;\n if (!Object.hasOwn(bo, key)) return false;\n if (!isEqual(ao[key], bo[key])) return false;\n }\n\n return true;\n};\n","import type {Cmd, CmdContext} from './cmd';\nimport {type Equatable, isEqual} from './eq';\n\nexport interface Bind<T, C extends CmdContext> {\n sig: Sig<T>;\n context: C;\n cmd: Cmd<T, C>;\n removed: boolean;\n queued?: boolean;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: any bind\nexport type AnyBind = Bind<any, any>;\n\nclass Queue {\n private _binds: AnyBind[] = [];\n private head = 0;\n private running = false;\n private scheduled = false;\n\n addAll(binds: readonly AnyBind[]): this {\n for (const bind of binds) {\n if (bind.queued) continue;\n bind.queued = true;\n this._binds.push(bind);\n }\n if (this._binds.length > this.head) this.kick();\n return this;\n }\n\n private kick(): void {\n if (this.running || this.scheduled) return;\n this.scheduled = true;\n queueMicrotask(() => {\n this.running = true;\n this.scheduled = false;\n this.flush();\n });\n }\n\n private flush(): void {\n this.running = true;\n try {\n while (this.head < this._binds.length) {\n const bind = this._binds[this.head++] as AnyBind;\n try {\n const {removed, sig, context, cmd} = bind;\n if (!removed) cmd(sig.get(), context);\n } catch (err) {\n console.error('[Queue] task failed:', err, bind);\n } finally {\n // re-arm after running: cmd reads sig.get() at call time, so a bind\n // that runs after a write already sees the newest value and must\n // not re-run, while one that ran before it has to be queued again\n bind.queued = false;\n }\n }\n } finally {\n this.running = false;\n if (this.head < this._binds.length) {\n // almost impossible in js/ts\n this._binds = this._binds.slice(this.head);\n this.head = 0;\n this.kick();\n } else {\n this._binds.length = 0;\n this.head = 0;\n }\n }\n }\n}\n\nconst QUEUE = new Queue();\n\nexport class Sig<T> implements Equatable {\n private _val: T;\n private _binds: AnyBind[] = [];\n\n constructor(val: T) {\n this._val = val;\n }\n\n equals(b: unknown) {\n if (b instanceof Sig) return isEqual(this.get(), b.get());\n return false;\n }\n\n get(): T {\n return this._val;\n }\n\n forceUpdate(v: T) {\n this._val = v;\n QUEUE.addAll(this._binds);\n }\n\n update(v: T) {\n if (isEqual(v, this._val)) return;\n this.forceUpdate(v);\n }\n\n trans(fn: (v: T) => T) {\n this.update(fn(this._val));\n }\n\n addBind<C extends CmdContext>(bind: Bind<T, C>) {\n this._binds.push(bind);\n }\n\n removeBind<C extends CmdContext>(bind: Bind<T, C>) {\n const index = this._binds.indexOf(bind);\n if (index >= 0) this._binds.splice(index, 1);\n if (this._binds.length === 0) {\n this.cleanup();\n }\n }\n\n getBinds(): Bind<T, CmdContext>[] {\n return this._binds;\n }\n\n // empty: DerivedSig overrides this to detach from its sources when its last\n // observer goes away\n cleanup() {}\n}\n\nexport class DerivedSig<T> extends Sig<T> {\n private _fromBinds: AnyBind[] = [];\n private _linked = true;\n\n addFromBind<S, C extends CmdContext>(bind: Bind<S, C>) {\n this._fromBinds.push(bind);\n }\n\n // A derived signal's upstream links are torn down when its last observer\n // goes away, which happens any time a view() subtree is hidden. The links\n // cannot be revived in place because removeBind marks them removed, so we\n // rebuild fresh binds from each recipe and recompute once: sources usually\n // moved while we were detached.\n //\n // super.addBind must stay first: the recompute below updates this signal\n // straight away, so the returning observer has to be registered before it\n // or it misses the value and only catches up on some later update.\n override addBind<C extends CmdContext>(bind: Bind<T, C>) {\n super.addBind(bind);\n if (this._linked) return;\n this._linked = true;\n for (let i = 0; i < this._fromBinds.length; i++) {\n const f = this._fromBinds[i] as AnyBind;\n this._fromBinds[i] = createBind(f.sig, f.context, f.cmd);\n }\n // every from-bind shares one context whose cmd reads all sources, so one\n // invocation recomputes the whole derived value\n const first = this._fromBinds[0];\n if (first) first.cmd(first.sig.get(), first.context);\n }\n\n override cleanup() {\n if (!this._linked) return;\n this._linked = false;\n for (const b of this._fromBinds) removeBind(b);\n }\n}\n\nexport const sig = <T>(v: T) => new Sig(v);\n\nexport const removeBind = <T, C extends CmdContext>(bind: Bind<T, C>) => {\n bind.removed = true;\n bind.sig.removeBind(bind);\n};\n\nexport const createBind = <T, C extends CmdContext>(\n sig: Sig<T>,\n context: C,\n cmd: Cmd<T, C>,\n): Bind<T, C> => {\n const bind: Bind<T, C> = {sig, context, cmd, removed: false, queued: false};\n sig.addBind(bind);\n return bind;\n};\n","import type {CmdContext} from './cmd';\nimport {createBind, DerivedSig, Sig} from './sig.bind';\n\nexport interface SigRecord {\n // biome-ignore lint/suspicious/noExplicitAny: any sig val\n [key: string]: Sig<any>;\n}\n\nexport type ValRecord<K extends SigRecord> = {\n [P in keyof K]: K[P] extends Sig<infer U> ? U : never;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: heterogeneous source sigs\ntype ComputeEntry = [string, Sig<any>];\n\ninterface ComputeContext<S, T> extends CmdContext {\n target: Sig<T>;\n fn: (s: S) => T;\n}\n\ninterface ComputeRecordContext<S extends SigRecord, T> extends CmdContext {\n target: Sig<T>;\n fn: (v: ValRecord<S>) => T;\n entries: ComputeEntry[];\n}\n\nconst computeCmd = <S, T>(s: S, ctx: ComputeContext<S, T>) => {\n ctx.target.update(ctx.fn(s));\n};\n\nconst computeRecordCmd = <S extends SigRecord, T>(\n _s: unknown,\n ctx: ComputeRecordContext<S, T>,\n) => {\n const vals: Record<string, unknown> = {};\n for (const [k, s] of ctx.entries) vals[k] = s.get();\n ctx.target.update(ctx.fn(vals as ValRecord<S>));\n};\n\nconst _compute = <S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T> => {\n const target = new DerivedSig(fn(source.get()));\n const ctx: ComputeContext<S, T> = {target, fn};\n target.addFromBind(createBind(source, ctx, computeCmd));\n return target;\n};\n\nconst _computeRecord = <S extends SigRecord, T>(\n source: S,\n fn: (v: ValRecord<S>) => T,\n): DerivedSig<T> => {\n const entries: ComputeEntry[] = [];\n const vals: Record<string, unknown> = {};\n for (const [k, s] of Object.entries(source)) {\n if (!k || !s) continue;\n entries.push([k, s]);\n vals[k] = s.get();\n }\n\n const target = new DerivedSig(fn(vals as ValRecord<S>));\n const ctx: ComputeRecordContext<S, T> = {target, fn, entries};\n\n for (const entry of entries) {\n target.addFromBind(createBind(entry[1], ctx, computeRecordCmd));\n }\n\n return target;\n};\n\nexport function compute<S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T>;\nexport function compute<S extends SigRecord, T>(\n source: S,\n fn: (v: ValRecord<S>) => T,\n): DerivedSig<T>;\n// biome-ignore lint/suspicious/noExplicitAny: any source\nexport function compute(source: any, fn: (v: any) => any): DerivedSig<any> {\n return source instanceof Sig\n ? _compute(source, fn)\n : _computeRecord(source, fn);\n}\n","export const at = <T>(arr: T[], index: number): T => {\n const v = arr[index];\n if (v === undefined) throw new RangeError(`E1:${index}`);\n return v;\n};\n","import {toBoundary} from './boundary';\nimport type {CmdContext} from './cmd';\nimport {err} from './err';\nimport type {Patch, PatchContext} from './patch';\nimport {type Bind, createBind, removeBind, Sig} from './sig.bind';\nimport {at} from './utils';\nimport type {AnyView, View} from './view';\n\nconst MARK = `@sig_${Math.random().toFixed(9).slice(2)}`;\n\ninterface Tpl {\n el: HTMLTemplateElement;\n indexes: number[];\n // a bitmask for up to 31 slots, the string form beyond that\n shape: number | string;\n}\n\ninterface Wrap<T, C extends CmdContext> {\n item: Patch | View<T, C>;\n node: Node;\n}\n\nconst tplCache = new WeakMap<TemplateStringsArray, Tpl>();\n\nlet walker: TreeWalker | undefined;\n\n// Created on first use rather than at module scope so that importing sigula\n// stays side-effect free and works where there is no document (SSR, tests).\nconst _walker = (): TreeWalker => {\n walker ??= document.createTreeWalker(\n document,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n );\n return walker;\n};\n\nconst _toMark = (item: Patch | View): string =>\n item.type === 'patch' ? MARK : `<!--${MARK}-->`;\n\n// The markup of a call site depends on the kind of every interpolation: a patch\n// gets an attribute marker, a view gets a comment marker. Reusing a cached\n// template across a different mix would hand the wrong node type to\n// commitPatch/commitView, so the mix is part of the cache identity.\n// A bitmask is far cheaper to build and compare than a string, and 31 slots\n// keeps it a non-negative int32 — 1 << 31 flips the sign. Beyond that fall\n// back to the string form so wide templates keep working unchanged.\nconst MAX_MASKED_SLOTS = 31;\n\nconst _shape = (items: readonly (Patch | AnyView)[]): number | string => {\n if (items.length > MAX_MASKED_SLOTS) {\n let shape = '';\n for (const item of items) shape += item.type === 'patch' ? 'p' : 'v';\n return shape;\n }\n let bits = 0;\n for (let i = 0; i < items.length; i++) {\n if (items[i]?.type === 'patch') bits |= 1 << i;\n }\n return bits;\n};\n\nconst _hasMark = (el: Element) => el.hasAttribute(MARK);\nconst _rmMark = (el: Element) => el.removeAttribute(MARK);\nconst _isView = (item: Comment) => item.data.trim() === MARK;\n\nconst commitView = <T, C extends CmdContext>(view: View<T, C>, node: Node) => {\n (node as Comment).replaceWith(view.node);\n};\n\nconst commitPatch = (patch: Patch, node: Node) => {\n const binds: Bind<unknown, PatchContext>[] = [];\n patch.toPatchItems.forEach((toPatchItem) => {\n const item = toPatchItem(node as Element);\n if (item.source instanceof Sig) {\n item.cmd(item.source.get(), item.context);\n binds.push(createBind(item.source, item.context, item.cmd));\n } else {\n item.cmd(item.source, item.context);\n }\n });\n\n patch.cleanBinds = () => {\n binds.forEach(removeBind);\n };\n};\n\n// Both template passes walk the same tree hunting for the next interpolation\n// slot and then do exactly the same thing with it; only the way a slot is\n// recognised differs, so that part is the only argument.\nconst _scan = (\n frag: DocumentFragment,\n items: (Patch | AnyView)[],\n wraps: Wrap<unknown, CmdContext>[],\n hit: (node: Node, nodeIndex: number, itemIndex: number) => boolean,\n indexes?: number[],\n) => {\n const w = _walker();\n w.currentNode = frag;\n let node = w.nextNode();\n let nodeIndex = 0;\n let itemIndex = 0;\n while (node !== null && itemIndex < items.length) {\n if (hit(node, nodeIndex, itemIndex)) {\n wraps.push({item: at(items, itemIndex), node});\n if (indexes) indexes.push(nodeIndex);\n itemIndex++;\n if (node.nodeType === Node.ELEMENT_NODE) _rmMark(node as Element);\n }\n node = w.nextNode();\n nodeIndex++;\n }\n // https://github.com/lit/lit/blob/c42ee1e96b8fd61f7256f61d715daef572e76e52/packages/lit-html/src/lit-html.ts#L1260\n // We need to set the currentNode away from the cloned tree so that we\n // don't hold onto the tree even if it is detached and should be freed.\n w.currentNode = document;\n};\n\nexport const html = (\n strs: TemplateStringsArray,\n ...items: (Patch | AnyView)[]\n): View => {\n if (strs.length <= 1 && !strs?.[0]) err('E10');\n const slots = strs.length - 1;\n if (items.length !== slots) err(`E11:${slots}:${items.length}`);\n\n let frag: DocumentFragment;\n const wraps: Wrap<unknown, CmdContext>[] = [];\n\n const shape = _shape(items);\n const exist = tplCache.get(strs);\n if (exist?.shape === shape) {\n frag = document.importNode(exist.el.content, true);\n if (items && items.length > 0) {\n _scan(\n frag,\n items,\n wraps,\n (_node, nodeIndex, itemIndex) => nodeIndex === exist.indexes[itemIndex],\n );\n }\n } else {\n const template = document.createElement('template');\n template.innerHTML = _text(strs, ...items);\n const tpl: Tpl = {el: template, indexes: [], shape};\n frag = document.importNode(template.content, true);\n\n if (items && items.length > 0) {\n _scan(\n frag,\n items,\n wraps,\n (node) =>\n node.nodeType === Node.ELEMENT_NODE\n ? _hasMark(node as Element)\n : node.nodeType === Node.COMMENT_NODE && _isView(node as Comment),\n tpl.indexes,\n );\n }\n\n tplCache.set(strs, tpl);\n }\n\n if (wraps.length !== items.length) err('E12');\n\n wraps.forEach(({item, node}) => {\n if (item.type === 'patch') commitPatch(item, node);\n else commitView(item, node);\n });\n const children = wraps.map((w) => w.item);\n const boundary = toBoundary(frag);\n\n return {\n type: 'view',\n node: frag,\n children,\n boundary: () => {\n // A view swapping its own contents changes the node at the edge, so when\n // the template begins or ends with an interpolation track that edge.\n const last = strs.length - 1;\n if (!strs[0]) {\n const first = children[0];\n if (first?.type === 'view') boundary.start = first.boundary().start;\n }\n if (!strs[last]) {\n const endChild = children[last - 1];\n if (endChild?.type === 'view') boundary.end = endChild.boundary().end;\n }\n return boundary;\n },\n cleanBinds: () => {\n children.forEach((child) => {\n child.cleanBinds();\n });\n },\n };\n};\n\nconst _text = (strs: TemplateStringsArray, ...parts: (Patch | AnyView)[]) => {\n let text = strs[0] ?? '';\n for (let i = 0; i < parts.length; i++) {\n text += _toMark(at(parts, i)) + (strs[i + 1] ?? '');\n }\n return text;\n};\n","import type {Cmd, CmdContext} from './cmd';\nimport {err} from './err';\nimport type {Sig} from './sig.bind';\n\nexport interface PatchContext extends CmdContext {\n // kind: 'elem';\n node: Node;\n extra?: unknown[];\n}\n\nexport interface PatchItem<T> {\n source: T | Sig<T>;\n context: PatchContext;\n cmd: Cmd<T, PatchContext>;\n}\nexport type ToPatchItem<T> = (el: Element) => PatchItem<T>;\n\n// biome-ignore lint/suspicious/noExplicitAny: any patch item\nexport type AnyPatchItem = PatchItem<any>;\nexport type ToAnyPatchItem = (el: Element) => AnyPatchItem;\n\nconst _noop = (): void => {};\nexport interface Patch {\n type: 'patch';\n toPatchItems: ToAnyPatchItem[];\n cleanBinds: () => void;\n}\n\nexport const patch = (...toPatchItems: ToAnyPatchItem[]): Patch => ({\n type: 'patch',\n toPatchItems,\n cleanBinds: _noop,\n});\n\n// Every patch item is the same shape -- bind `source` to `elem` plus whatever\n// arguments the command needs -- so the whole body lives here once.\nconst _toPatchItem =\n <T>(\n source: T | Sig<T>,\n extra: unknown[] | undefined,\n cmd: Cmd<T, PatchContext>,\n ): ToPatchItem<T> =>\n (elem) => ({\n source,\n context: extra ? {node: elem, extra} : {node: elem},\n cmd,\n });\n\n// most commands take their attribute/style/class name as the first extra\nconst _key = (ctx: PatchContext): string => {\n const key = ctx.extra?.[0];\n if (!key) err('E4');\n return key as string;\n};\n\nconst idCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).id = String(val);\n};\n\nexport const id = <T>(source: T | Sig<T>): ToPatchItem<T> =>\n _toPatchItem(source, undefined, idCmd);\n\nconst valCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as unknown as {value: string}).value = String(val);\n};\n\nexport const val = <T>(source: T | Sig<T>): ToPatchItem<T> =>\n _toPatchItem(source, undefined, valCmd);\n\nconst attrCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).setAttribute(_key(ctx), String(val));\n};\n\nexport const attr = <T>(source: T | Sig<T>, key: string): ToPatchItem<T> =>\n _toPatchItem(source, [key], attrCmd);\n\nexport type WritableStyleKey = {\n [K in keyof CSSStyleDeclaration]: CSSStyleDeclaration[K] extends string\n ? K\n : never;\n}[keyof CSSStyleDeclaration];\n\nconst styleCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as HTMLElement).style[_key(ctx) as WritableStyleKey] = String(val);\n};\n\nexport const style = <T>(\n source: T | Sig<T>,\n key: WritableStyleKey,\n): ToPatchItem<T> => _toPatchItem(source, [key], styleCmd);\n\nconst stylePropertyCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as HTMLElement).style.setProperty(_key(ctx), String(val));\n};\n\nexport const styleProperty = <T>(\n source: T | Sig<T>,\n key: string,\n): ToPatchItem<T> => _toPatchItem(source, [key], stylePropertyCmd);\n\nconst toggleClassCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).classList.toggle(_key(ctx), Boolean(val));\n};\n\nexport const toggleClass = <T>(\n source: T | Sig<T>,\n token: string,\n): ToPatchItem<T> => _toPatchItem(source, [token], toggleClassCmd);\n\nconst toggleClassesCmd = <T>(val: T, ctx: PatchContext) => {\n ctx.extra?.forEach((token) => {\n (ctx.node as Element).classList.toggle(token as string, Boolean(val));\n });\n};\n\nexport const toggleClasses = <T>(\n source: T | Sig<T>,\n ...tokens: string[]\n): ToPatchItem<T> => _toPatchItem(source, tokens, toggleClassesCmd);\n\nexport type ActFn<T> = (node: Node, val?: T) => void;\n\nconst actCmd = <T>(val: T, ctx: PatchContext) => {\n const fn = ctx.extra?.[0] as ActFn<T> | undefined;\n if (!fn) err('E5');\n fn(ctx.node, val);\n};\n\nexport const act = <T>(source: T | Sig<T>, fn: ActFn<T>): ToPatchItem<T> =>\n _toPatchItem(source, [fn], actCmd);\n\ntype _Listener<K extends keyof HTMLElementEventMap> = (\n this: HTMLElement,\n ev: HTMLElementEventMap[K],\n) => unknown;\n\nconst onCmd = (listener: unknown, ctx: PatchContext) => {\n const type = ctx.extra?.[0] as string | undefined;\n const options = ctx.extra?.[1] as\n | boolean\n | AddEventListenerOptions\n | undefined;\n if (!type) err('E6');\n ctx.node.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject,\n options,\n );\n};\n\nexport const on = <K extends keyof HTMLElementEventMap>(\n type: K,\n listener: _Listener<K>,\n options?: boolean | AddEventListenerOptions,\n): ToPatchItem<_Listener<K>> => _toPatchItem(listener, [type, options], onCmd);\n","import {removeBoundary} from './boundary';\nimport type {AnyView} from './view';\n\nexport const render = (\n viewArg: AnyView | (() => AnyView),\n node: Node,\n): (() => void) => {\n const view = typeof viewArg === 'function' ? viewArg() : viewArg;\n node.appendChild(view.node);\n\n return () => {\n removeBoundary(view.boundary());\n view.cleanBinds();\n };\n};\n","import {type Boundary, replaceWithNode} from './boundary';\nimport type {CmdContext} from './cmd';\nimport type {Patch} from './patch';\nimport {type Bind, createBind, removeBind, type Sig} from './sig.bind';\n\nexport type ChildView = AnyView | Patch;\n\n// biome-ignore lint/suspicious/noExplicitAny: View with any context\nexport interface View<T = unknown, C extends CmdContext = any> {\n type: 'view';\n node: Node;\n bind?: Bind<T, C> | undefined;\n cleanBinds: () => void;\n boundary: () => Boundary;\n\n children?: ChildView[] | undefined;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: any view\nexport type AnyView = View<any, any>;\n\nexport interface ViewContext<T> extends CmdContext {\n inner: AnyView;\n viewFn: (val: T) => AnyView;\n}\n\nconst viewCmd = <T>(val: T, ctx: ViewContext<T>) => {\n const oldBoundary = ctx.inner.boundary();\n const newInner = ctx.viewFn(val);\n replaceWithView(oldBoundary, newInner);\n ctx.inner.cleanBinds();\n ctx.inner = newInner;\n};\n\nexport const view = <T>(\n sig: Sig<T>,\n viewFn: (val: T) => AnyView,\n): View<T, ViewContext<T>> => {\n const inner = viewFn(sig.get());\n\n const ctx: ViewContext<T> = {\n inner,\n viewFn,\n };\n\n const bind = createBind(sig, ctx, viewCmd);\n\n return {\n type: 'view',\n node: inner.node,\n bind,\n boundary: () => ctx.inner.boundary(),\n cleanBinds: () => {\n removeBind(bind);\n ctx.inner.cleanBinds();\n },\n };\n};\n\nexport const replaceWithView = (old: Boundary, view: View): Boundary =>\n replaceWithNode(old, view.node);\n","import {\n type Boundary,\n removeBoundary,\n replaceWithNode,\n toBoundary,\n walkBoundary,\n} from './boundary';\nimport type {CmdContext} from './cmd';\nimport {isEqual} from './eq';\nimport {err} from './err';\nimport {createBind, removeBind, type Sig} from './sig.bind';\nimport {at} from './utils';\nimport {type AnyView, replaceWithView, type View} from './view';\n\nexport type RepeatProp<T> = {\n key: (item: T) => string;\n view: (item: T) => AnyView;\n compare?: (a: T, b: T) => boolean;\n};\n\ninterface Container {\n parent: ParentNode;\n startFence: Node;\n endFence: Node;\n}\n\ninterface Track<T> {\n key: string;\n item: T;\n view: AnyView;\n checked?: boolean;\n cleaned?: boolean;\n}\n\nexport interface RepeatContext<T> extends CmdContext {\n prop: RepeatProp<T>;\n boundary: Boundary;\n tracks: Track<T>[];\n}\n\nconst _cleanTrack = <T>(track: Track<T>) => {\n removeBoundary(track.view.boundary());\n track.view.cleanBinds();\n track.cleaned = true;\n};\n\nconst repeatCmd = <T>(items: T[], ctx: RepeatContext<T>) => {\n if (!Array.isArray(items) || items.length === 0) {\n const newFrag = document.createDocumentFragment();\n newFrag.appendChild(document.createComment('empty-list'));\n const newBoundary = replaceWithNode(ctx.boundary, newFrag);\n ctx.boundary = newBoundary;\n ctx.tracks.forEach(_cleanTrack);\n ctx.tracks = [];\n return;\n }\n const newTracks: Track<T>[] = [];\n if (!Array.isArray(ctx.tracks) || ctx.tracks.length === 0) {\n const newFrag = _init(items, ctx.prop, newTracks);\n const newBoundary = replaceWithNode(ctx.boundary, newFrag);\n ctx.boundary = newBoundary;\n ctx.tracks = newTracks;\n return;\n }\n\n const start = ctx.boundary.start;\n const end = ctx.boundary.end;\n const parent = start.parentNode;\n if (!parent) err('E7');\n\n const compare = ctx.prop.compare ?? isEqual;\n const newKeys = items.map((item) => ctx.prop.key(item));\n const tracks = ctx.tracks;\n\n // Nothing changed: same keys, same order, equal items. Bail out before\n // touching the DOM so a redundant re-render costs zero DOM mutations\n // instead of a fence insert/remove pair.\n if (tracks.length === items.length) {\n const unchanged = tracks.every((track, i) => {\n const item = items[i] as T;\n return track.key === newKeys[i] && compare(track.item, item);\n });\n if (unchanged) return;\n }\n\n const startFence = document.createComment('repeat-start-fence');\n const endFence = document.createComment('repeat-end-fence');\n\n parent.insertBefore(startFence, start);\n parent.insertBefore(endFence, end.nextSibling);\n\n const container: Container = {\n parent,\n startFence,\n endFence,\n };\n\n const oldKeys = tracks.map((track) => track.key);\n\n let newKeyToIndexMap: Map<unknown, number> | undefined;\n let oldKeyToIndexMap: Map<unknown, number> | undefined;\n\n let oldHead = 0;\n let oldTail = ctx.tracks.length - 1;\n let newHead = 0;\n let newTail = items.length - 1;\n\n while (oldHead <= oldTail && newHead <= newTail) {\n if (ctx.tracks[oldHead]?.checked) {\n oldHead++;\n } else if (ctx.tracks[oldTail]?.checked) {\n oldTail--;\n } else if (ctx.tracks[oldHead]?.key === newKeys[newHead]) {\n // old head matches new head; update in place\n newTracks[newHead] = _setTrack(\n at(ctx.tracks, oldHead),\n at(items, newHead),\n ctx.prop,\n compare,\n );\n oldHead++;\n newHead++;\n } else if (ctx.tracks[oldTail]?.key === newKeys[newTail]) {\n // old tail matches new tail; update in place\n newTracks[newTail] = _setTrack(\n at(ctx.tracks, oldTail),\n at(items, newTail),\n ctx.prop,\n compare,\n );\n oldTail--;\n newTail--;\n } else if (ctx.tracks[oldHead]?.key === newKeys[newTail]) {\n // old head matches new tail; update and move to new tail\n newTracks[newTail] = _setTrack(\n at(ctx.tracks, oldHead),\n at(items, newTail),\n ctx.prop,\n compare,\n );\n _moveTrack(\n container,\n at(newTracks, newTail),\n _beforeFence(container, newTracks[newTail + 1]),\n );\n oldHead++;\n newTail--;\n } else if (ctx.tracks[oldTail]?.key === newKeys[newHead]) {\n // old tail matches new head; update and move to new head\n newTracks[newHead] = _setTrack(\n at(ctx.tracks, oldTail),\n at(items, newHead),\n ctx.prop,\n compare,\n );\n _moveTrack(\n container,\n at(newTracks, newHead),\n _afterFence(container, newTracks[newHead - 1]),\n );\n oldTail--;\n newHead++;\n } else {\n if (newKeyToIndexMap === undefined || oldKeyToIndexMap === undefined) {\n newKeyToIndexMap = _generateMap(newKeys, newHead, newTail);\n oldKeyToIndexMap = _generateMap(oldKeys, oldHead, oldTail);\n }\n if (!newKeyToIndexMap.has(oldKeys[oldHead])) {\n _cleanTrack(at(ctx.tracks, oldHead));\n oldHead++;\n } else if (!newKeyToIndexMap.has(oldKeys[oldTail])) {\n _cleanTrack(at(ctx.tracks, oldTail));\n oldTail--;\n } else {\n const oldIndex = oldKeyToIndexMap.get(newKeys[newHead]);\n const oldTrack = oldIndex !== undefined ? ctx.tracks[oldIndex] : null;\n if (oldTrack) {\n newTracks[newHead] = _setTrack(\n oldTrack,\n at(items, newHead),\n ctx.prop,\n compare,\n );\n _moveTrack(\n container,\n at(newTracks, newHead),\n _afterFence(container, newTracks[newHead - 1]),\n );\n oldTrack.checked = true;\n } else {\n newTracks[newHead] = _insertNewTrack(\n container,\n at(items, newHead),\n ctx.prop,\n _afterFence(container, newTracks[newHead - 1]),\n );\n }\n newHead++;\n }\n }\n }\n\n while (newHead <= newTail) {\n newTracks[newHead] = _insertNewTrack(\n container,\n at(items, newHead),\n ctx.prop,\n _afterFence(container, newTracks[newHead - 1]),\n );\n newHead++;\n }\n\n while (oldHead <= oldTail) {\n if (!ctx.tracks[oldHead]?.cleaned && !ctx.tracks[oldHead]?.checked)\n _cleanTrack(at(ctx.tracks, oldHead));\n oldHead++;\n }\n\n if (!container.startFence.nextSibling || !container.endFence.previousSibling)\n err('E8');\n\n ctx.boundary = {\n start: container.startFence.nextSibling,\n end: container.endFence.previousSibling,\n };\n container.parent.removeChild(container.startFence);\n container.parent.removeChild(container.endFence);\n ctx.tracks = newTracks;\n};\n\nconst _generateMap = (list: unknown[], start: number, end: number) => {\n const map = new Map<unknown, number>();\n for (let i = start; i <= end; i++) {\n map.set(list[i], i);\n }\n return map;\n};\n\nconst _beforeFence = <T>(container: Container, track?: Track<T>): Node =>\n track ? track.view.boundary().start : container.endFence;\nconst _afterFence = <T>(container: Container, track?: Track<T>): Node => {\n const node = track ? track.view.boundary().end : container.startFence;\n if (!node.nextSibling) err('E9');\n return node.nextSibling;\n};\n\nconst _mvNodeBefore = (parent: ParentNode, node: Node, child: Node | null) => {\n if (parent.moveBefore) parent.moveBefore(node, child);\n else parent.insertBefore(node, child);\n};\n\nconst _moveTrack = <T>(container: Container, track: Track<T>, fence: Node) => {\n const parent = container.parent;\n walkBoundary(track.view.boundary(), (node) =>\n _mvNodeBefore(parent, node, fence),\n );\n};\n\nconst _insertNewTrack = <T>(\n container: Container,\n item: T,\n prop: RepeatProp<T>,\n fence: Node,\n): Track<T> => {\n const view = prop.view(item);\n container.parent.insertBefore(view.node, fence);\n return {\n key: prop.key(item),\n item,\n view,\n };\n};\n\nconst _setTrack = <T>(\n old: Track<T>,\n item: T,\n prop: RepeatProp<T>,\n compare: (a: T, b: T) => boolean,\n): Track<T> => {\n if (compare(old.item, item)) {\n return {\n ...old,\n checked: false,\n cleaned: false,\n };\n }\n\n const oldBoundary = old.view.boundary();\n const view = prop.view(item);\n replaceWithView(oldBoundary, view);\n _cleanTrack(old);\n\n const newTrack: Track<T> = {\n key: prop.key(item),\n item,\n view,\n };\n\n return newTrack;\n};\n\nconst _init = <T>(\n items: T[],\n prop: RepeatProp<T>,\n tracks: Track<T>[],\n): DocumentFragment => {\n const frag = document.createDocumentFragment();\n items.forEach((item) => {\n const view = prop.view(item);\n const key = prop.key(item);\n\n tracks.push({\n key,\n item,\n view,\n });\n frag.appendChild(view.node);\n });\n\n if (frag.childNodes.length === 0) {\n frag.appendChild(document.createComment('empty-list'));\n }\n return frag;\n};\n\nexport const repeat = <T>(\n sig: Sig<T[]>,\n prop: RepeatProp<T>,\n): View<T[], RepeatContext<T>> => {\n const tracks: Track<T>[] = [];\n const frag = _init(sig.get(), prop, tracks);\n\n const ctx: RepeatContext<T> = {prop, tracks, boundary: toBoundary(frag)};\n const bind = createBind(sig, ctx, repeatCmd);\n\n return {\n type: 'view',\n node: frag,\n bind,\n boundary: () => ctx.boundary,\n cleanBinds: () => {\n removeBind(bind);\n ctx.tracks.forEach((t) => {\n t.view.cleanBinds();\n });\n },\n };\n};\n","import {toBoundary} from './boundary';\nimport type {PatchContext} from './patch';\nimport {createBind, removeBind, Sig} from './sig.bind';\nimport type {View} from './view';\n\nconst textCmd = <T>(val: T, ctx: PatchContext) => {\n ctx.node.textContent = String(val);\n};\n\nexport const text = <T>(source: T | Sig<T>): View<T, PatchContext> => {\n const text = document.createTextNode(\n source instanceof Sig ? String(source.get()) : String(source),\n );\n const ctx: PatchContext = {node: text};\n const bind =\n source instanceof Sig ? createBind(source, ctx, textCmd) : undefined;\n const boundary = toBoundary(text);\n return {\n type: 'view',\n node: text,\n bind,\n boundary: () => boundary,\n cleanBinds: () => {\n if (bind) removeBind(bind);\n },\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigula",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "author": "zjh <zhanjh@126.com>",
5
5
  "description": "Tiny web framework with fine-grained signal reactivity.",
6
6
  "license": "MIT",