sigula 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -0
- package/dist/sigula.d.ts +162 -0
- package/dist/sigula.d.ts.map +1 -0
- package/dist/sigula.js +2 -0
- package/dist/sigula.js.map +1 -0
- package/package.json +51 -22
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Sigula
|
|
2
|
+
|
|
3
|
+
> Tiny web framework with fine-grained signal reactivity.
|
|
4
|
+
|
|
5
|
+
A minimal, signal-based web framework with fine-grained reactivity. No virtual DOM — just direct, minimal updates to the real DOM.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- Fine-grained signal reactivity — when state changes, only the DOM nodes that actually depend on it are updated, not the whole component tree
|
|
10
|
+
- Declarative signal sources + precise bindings — describe data sources declaratively with signals, then bind them precisely to the DOM or any effect
|
|
11
|
+
- No virtual DOM — no diffing, no VNodes. Direct real DOM operations with minimal runtime overhead
|
|
12
|
+
- Minimal HTML templates — based on native string templates. No custom compiler, no DSL — just JavaScript strings
|
|
13
|
+
- Ultra small — only ~3.89KB minified + gzipped
|
|
14
|
+
- TypeScript friendly — full type inference for signals and template bindings
|
|
15
|
+
- Simple but performant — tiny API surface, low mental overhead, no compromise on performance
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm install sigual
|
|
21
|
+
pnpm add sigual
|
|
22
|
+
yarn add sigual
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quck Start
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import {compute, html, on, patch, render, sig, text, type View} from 'sigula';
|
|
29
|
+
|
|
30
|
+
const Equation = (): View => {
|
|
31
|
+
const x = sig(0);
|
|
32
|
+
const y = sig(1);
|
|
33
|
+
|
|
34
|
+
const s = {x, y};
|
|
35
|
+
const sum = compute(s, (v) => v.x + v.y);
|
|
36
|
+
const product = compute(s, (v) => v.x * v.y);
|
|
37
|
+
const diff = compute(s, (v) => v.x - v.y);
|
|
38
|
+
const quotient = compute(s, (v) => v.x / v.y);
|
|
39
|
+
|
|
40
|
+
const xSquare = compute(x, (v) => v * v);
|
|
41
|
+
const ySquare = compute(y, (v) => v * v);
|
|
42
|
+
|
|
43
|
+
const sumDiffProduct = compute({sum, diff}, (v) => v.sum * v.diff);
|
|
44
|
+
const squareDiff = compute({xSquare, ySquare}, (v) => v.xSquare - v.ySquare);
|
|
45
|
+
|
|
46
|
+
return html`<div>
|
|
47
|
+
<h1>Equation</h1>
|
|
48
|
+
<div>
|
|
49
|
+
<p>x: ${text(x)} -
|
|
50
|
+
<button ${patch(on('click', () => x.trans((v) => v + 1)))}>+1</button>
|
|
51
|
+
<button ${patch(on('click', () => x.trans((v) => v - 1)))}>-1</button>
|
|
52
|
+
</p>
|
|
53
|
+
<p>y: ${text(y)} -
|
|
54
|
+
<button ${patch(on('click', () => y.trans((v) => v + 1)))}>+1</button>
|
|
55
|
+
<button ${patch(on('click', () => y.trans((v) => v - 1)))}>-1</button>
|
|
56
|
+
</p>
|
|
57
|
+
<p>sum: x + y = ${text(x)} + ${text(y)} = ${text(sum)}</p>
|
|
58
|
+
<p>difference: x - y = ${text(x)} - ${text(y)} = ${text(diff)}</p>
|
|
59
|
+
<p>product: x * y = ${text(x)} * ${text(y)} = ${text(product)}</p>
|
|
60
|
+
<p>quotient: x / y = ${text(x)} / ${text(y)} = ${text(quotient)}</p>
|
|
61
|
+
<p>
|
|
62
|
+
(x + y)(x - y)
|
|
63
|
+
= (${text(x)} + ${text(y)})(${text(x)} - ${text(y)})
|
|
64
|
+
= ${text(sum)}*${text(diff)} = ${text(sumDiffProduct)}
|
|
65
|
+
<br />
|
|
66
|
+
= x^2 - y^2 = ${text(xSquare)} - ${text(ySquare)} = ${text(squareDiff)}
|
|
67
|
+
</p>
|
|
68
|
+
</div>
|
|
69
|
+
</div>`;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const appNode = document.querySelector('#app');
|
|
73
|
+
if (!appNode) throw new Error('#app not found');
|
|
74
|
+
render(Equation(), appNode);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 🧠 Core Concepts
|
|
78
|
+
|
|
79
|
+
### Fine-grained updates to the real DOM
|
|
80
|
+
|
|
81
|
+
Traditional frameworks like React re-run component functions, generate a virtual DOM, diff it, and finally apply changes to the real DOM. Sigula works completely differently:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import {html text} from 'sigula';
|
|
85
|
+
|
|
86
|
+
const name = sig('Alice')
|
|
87
|
+
|
|
88
|
+
const App = html`<h1>Hello, ${text(name)}!</h1>`
|
|
89
|
+
|
|
90
|
+
// When name changes, only the text node inside <h1> is updated
|
|
91
|
+
name.update('Bob') // → the text changes from "Hello, Alice!" to "Hello, Bob!"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Only the exact text node that depends on name is updated. Everything else stays untouched.
|
|
95
|
+
|
|
96
|
+
### Declarative signal sources + precise bindings
|
|
97
|
+
|
|
98
|
+
Signals are the single source of truth. Every view and side effect is derived from them:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import {
|
|
102
|
+
compute,
|
|
103
|
+
html,
|
|
104
|
+
on,
|
|
105
|
+
patch,
|
|
106
|
+
render,
|
|
107
|
+
repeat,
|
|
108
|
+
type Sig,
|
|
109
|
+
sig,
|
|
110
|
+
style,
|
|
111
|
+
text,
|
|
112
|
+
type View,
|
|
113
|
+
val,
|
|
114
|
+
view,
|
|
115
|
+
} from 'sigula';
|
|
116
|
+
|
|
117
|
+
interface Todo {
|
|
118
|
+
id: number;
|
|
119
|
+
text: string;
|
|
120
|
+
done: Sig<boolean>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const Todos = (): View => {
|
|
124
|
+
const input = sig('');
|
|
125
|
+
const todos = sig<Todo[]>([]);
|
|
126
|
+
const filter = sig<'all' | 'active' | 'done'>('all');
|
|
127
|
+
|
|
128
|
+
// Derived Signals
|
|
129
|
+
const visibleTodos = compute({todos, filter}, (v) => {
|
|
130
|
+
switch (v.filter) {
|
|
131
|
+
case 'active':
|
|
132
|
+
return v.todos.filter((t) => !t.done.get());
|
|
133
|
+
case 'done':
|
|
134
|
+
return v.todos.filter((t) => t.done.get());
|
|
135
|
+
default:
|
|
136
|
+
return v.todos;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const isEmpty = compute(visibleTodos, (v) => v.length <= 0);
|
|
141
|
+
|
|
142
|
+
const addTodo = (e: Event) => {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
if (!input.get().trim()) return;
|
|
145
|
+
|
|
146
|
+
todos.trans((items) => [
|
|
147
|
+
...items,
|
|
148
|
+
{id: Date.now(), text: input.get().trim(), done: sig(false)},
|
|
149
|
+
]);
|
|
150
|
+
input.update('');
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const remove = (id: number) => {
|
|
154
|
+
todos.trans((items) => items.filter((item) => item.id !== id));
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const itemView = (item: Todo) => html`<li>
|
|
158
|
+
<span
|
|
159
|
+
${patch(
|
|
160
|
+
on('click', () => item.done.trans((v) => !v)),
|
|
161
|
+
style(
|
|
162
|
+
compute(item.done, (v): string => (v ? 'line-through' : 'none')),
|
|
163
|
+
'textDecoration',
|
|
164
|
+
),
|
|
165
|
+
)}
|
|
166
|
+
>${text(item.text)}</span>
|
|
167
|
+
<button ${patch(on('click', () => remove(item.id)))}>x</button>
|
|
168
|
+
</li>`;
|
|
169
|
+
|
|
170
|
+
// Bind precisely to the DOM
|
|
171
|
+
return html`<div style="margin: 2rem auto; max-width: 400px">
|
|
172
|
+
<h1>Todos</h1>
|
|
173
|
+
<form ${patch(on('submit', addTodo))}>
|
|
174
|
+
<input ${patch(
|
|
175
|
+
val(input),
|
|
176
|
+
on('change', (e) => {
|
|
177
|
+
if (e.target) input.update((e.target as HTMLInputElement).value);
|
|
178
|
+
}),
|
|
179
|
+
)} />
|
|
180
|
+
<button>Add</button>
|
|
181
|
+
</form>
|
|
182
|
+
<div>
|
|
183
|
+
filter:
|
|
184
|
+
<button ${patch(on('click', () => filter.update('all')))}>all</button>
|
|
185
|
+
<button ${patch(on('click', () => filter.update('active')))}>active</button>
|
|
186
|
+
<button ${patch(on('click', () => filter.update('done')))}>done</button>
|
|
187
|
+
</div>
|
|
188
|
+
${view(isEmpty, (v) =>
|
|
189
|
+
v
|
|
190
|
+
? text('empty')
|
|
191
|
+
: html`<ul>${repeat(visibleTodos, {
|
|
192
|
+
key: (item) => item.id.toString(),
|
|
193
|
+
view: (item) => itemView(item),
|
|
194
|
+
})}</ul>`,
|
|
195
|
+
)}
|
|
196
|
+
</div>`;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const appNode = document.querySelector('#app');
|
|
200
|
+
if (!appNode) throw new Error('#app not found');
|
|
201
|
+
render(Todos(), appNode);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Signals can bind to the DOM, to effects, or to other computed signals — one reactive model across the entire application.
|
|
205
|
+
|
|
206
|
+
### No virtual DOM
|
|
207
|
+
|
|
208
|
+
Sigula does not create VNodes and does not diff trees. During the initial mount, the template establishes direct subscriptions between signals and DOM nodes. Every subsequent signal change goes straight to the corresponding DOM node.
|
|
209
|
+
|
|
210
|
+
This means:
|
|
211
|
+
- No VNode creation or destruction overhead
|
|
212
|
+
- No diffing traversal cost
|
|
213
|
+
- Memory usage scales linearly with DOM nodes, not with component tree depth
|
|
214
|
+
|
|
215
|
+
### Minimal HTML templates
|
|
216
|
+
|
|
217
|
+
Templates are plain JavaScript native string templates. No custom compiler, no .vue files, no JSX transform:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
const App: View = html`
|
|
221
|
+
<div class="card">
|
|
222
|
+
<h2>${text(title)}</h2>
|
|
223
|
+
<p>${text(description)}</p>
|
|
224
|
+
<button ${patch(on('click', handleClick))}>Click me</button>
|
|
225
|
+
</div>
|
|
226
|
+
`
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
html is a tagged template function that returns a mountable template (`View`) object. You can use any editor's syntax highlighting, formatting, and ESLint rules — no extra tooling required.
|
|
230
|
+
|
|
231
|
+
### Ultra small
|
|
232
|
+
|
|
233
|
+
minified + gzipped: ~3.89KB
|
|
234
|
+
|
|
235
|
+
|
package/dist/sigula.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
//#region src/boundary.d.ts
|
|
2
|
+
export interface Boundary {
|
|
3
|
+
start: Node;
|
|
4
|
+
end: Node;
|
|
5
|
+
}
|
|
6
|
+
export declare const removeBoundary: (b: Boundary) => void;
|
|
7
|
+
export declare const toBoundary: (node: Node) => Boundary;
|
|
8
|
+
export declare const repleaceWithNode: (old: Boundary, node: Node) => Boundary;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/cmd.d.ts
|
|
11
|
+
export interface CmdContext {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export type Cmd<T, C extends CmdContext> = (val: T, context: C) => void;
|
|
15
|
+
export type AnyCmd = Cmd<any, any>;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/eq.d.ts
|
|
18
|
+
export interface Equatable {
|
|
19
|
+
equals(other: unknown): boolean;
|
|
20
|
+
}
|
|
21
|
+
export type UnknownRecord = Record<string, unknown>;
|
|
22
|
+
export declare const isEqual: <T>(a: T, b: T) => boolean;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/sig.bind.d.ts
|
|
25
|
+
export interface Bind<T, C extends CmdContext> {
|
|
26
|
+
sig: Sig<T>;
|
|
27
|
+
context: C;
|
|
28
|
+
cmd: Cmd<T, C>;
|
|
29
|
+
removed: boolean;
|
|
30
|
+
}
|
|
31
|
+
export type AnyBind = Bind<any, any>;
|
|
32
|
+
export declare class Sig<T> implements Equatable {
|
|
33
|
+
private _val;
|
|
34
|
+
private _binds;
|
|
35
|
+
constructor(val: T);
|
|
36
|
+
equals(b: unknown): boolean;
|
|
37
|
+
get(): T;
|
|
38
|
+
forceUpdate(v: T): void;
|
|
39
|
+
update(v: T): void;
|
|
40
|
+
trans(fn: (v: T) => T): void;
|
|
41
|
+
addBind<C extends CmdContext>(bind: Bind<T, C>): void;
|
|
42
|
+
removeBind(bind: Bind<T, CmdContext>): void;
|
|
43
|
+
getBinds(): Bind<T, CmdContext>[];
|
|
44
|
+
cleanup(): void;
|
|
45
|
+
}
|
|
46
|
+
export declare class DerivedSig<T> extends Sig<T> {
|
|
47
|
+
private _fromBinds;
|
|
48
|
+
addFromBind<S, C extends CmdContext>(bind: Bind<S, C>): void;
|
|
49
|
+
cleanup(): void;
|
|
50
|
+
}
|
|
51
|
+
export declare const sig: <T>(v: T) => Sig<T>;
|
|
52
|
+
export declare const removeBind: (bind: Bind<unknown, CmdContext>) => void;
|
|
53
|
+
export declare const createBind: <T, C extends CmdContext>(sig: Sig<T>, context: C, cmd: Cmd<T, C>) => Bind<T, C>;
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/commit.d.ts
|
|
56
|
+
export interface Commit<T, C extends CmdContext> {
|
|
57
|
+
binds: Bind<T, C> | Bind<T, C>[] | undefined;
|
|
58
|
+
children?: Commit<unknown, CmdContext>[] | undefined;
|
|
59
|
+
}
|
|
60
|
+
export declare const cleanCommit: (commit: Commit<unknown, CmdContext>) => void;
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/compute.d.ts
|
|
63
|
+
export interface SigRecord {
|
|
64
|
+
[key: string]: Sig<any>;
|
|
65
|
+
}
|
|
66
|
+
export type ValRecord<K extends SigRecord> = { [P in keyof K]: K[P] extends Sig<infer U> ? U : never; };
|
|
67
|
+
export declare const toValRecord: <S extends SigRecord>(source: S) => ValRecord<S>;
|
|
68
|
+
export interface ComputeContext<S, T> extends CmdContext {
|
|
69
|
+
target: Sig<T>;
|
|
70
|
+
fn: (s: S) => T;
|
|
71
|
+
}
|
|
72
|
+
export declare function compute<S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T>;
|
|
73
|
+
export declare function compute<S extends SigRecord, T>(source: S, fn: (v: ValRecord<S>) => T): DerivedSig<T>;
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/patch.d.ts
|
|
76
|
+
export interface PatchContext extends CmdContext {
|
|
77
|
+
node: Node;
|
|
78
|
+
extra?: unknown[];
|
|
79
|
+
}
|
|
80
|
+
export interface PatchItem<T> {
|
|
81
|
+
source: T | Sig<T>;
|
|
82
|
+
context: PatchContext;
|
|
83
|
+
cmd: Cmd<T, PatchContext>;
|
|
84
|
+
}
|
|
85
|
+
export type ToPatchItem<T> = (el: Element) => PatchItem<T>;
|
|
86
|
+
export type AnyPatchItem = PatchItem<any>;
|
|
87
|
+
export type ToAnyPatchItem = (el: Element) => AnyPatchItem;
|
|
88
|
+
export interface Patch {
|
|
89
|
+
type: 'patch';
|
|
90
|
+
toPatchItems: ToAnyPatchItem[];
|
|
91
|
+
}
|
|
92
|
+
export declare const patch: (...toPatchItems: ToAnyPatchItem[]) => Patch;
|
|
93
|
+
export declare const id: <T>(source: T | Sig<T>) => ToPatchItem<T>;
|
|
94
|
+
export declare const val: <T>(source: T | Sig<T>) => ToPatchItem<T>;
|
|
95
|
+
export declare const attr: <T>(source: T | Sig<T>, key: string) => ToPatchItem<T>;
|
|
96
|
+
export type WritableStyleKey = { [K in keyof CSSStyleDeclaration]: CSSStyleDeclaration[K] extends string ? K : never; }[keyof CSSStyleDeclaration];
|
|
97
|
+
export declare const style: <T>(source: T | Sig<T>, key: WritableStyleKey) => ToPatchItem<T>;
|
|
98
|
+
export declare const styleProperty: <T>(source: T | Sig<T>, key: string) => ToPatchItem<T>;
|
|
99
|
+
export declare const toggleClass: <T>(source: T | Sig<T>, token: string) => ToPatchItem<T>;
|
|
100
|
+
export declare const toggleClasses: <T>(source: T | Sig<T>, ...tokens: string[]) => ToPatchItem<T>;
|
|
101
|
+
export type ActFn<T> = (node: Node, val?: T) => void;
|
|
102
|
+
export declare const act: <T>(source: T | Sig<T>, fn: ActFn<T>) => ToPatchItem<T>;
|
|
103
|
+
type _Listener<K extends keyof HTMLElementEventMap> = (this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown;
|
|
104
|
+
export declare const on: <K extends keyof HTMLElementEventMap>(type: K, listener: _Listener<K>, options?: boolean | AddEventListenerOptions) => ToPatchItem<_Listener<K>>;
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/view.d.ts
|
|
107
|
+
export interface View<T = unknown, C extends CmdContext = CmdContext> {
|
|
108
|
+
type: 'view';
|
|
109
|
+
node: Node;
|
|
110
|
+
bind?: Bind<T, C> | undefined;
|
|
111
|
+
childCommits?: Commit<unknown, CmdContext>[];
|
|
112
|
+
}
|
|
113
|
+
export type AnyView = View<any, any>;
|
|
114
|
+
export interface ViewContext<T> extends CmdContext {
|
|
115
|
+
boundary: Boundary;
|
|
116
|
+
bind?: AnyBind | undefined;
|
|
117
|
+
childCommits?: Commit<unknown, CmdContext>[] | undefined;
|
|
118
|
+
viewFn: (val: T) => View;
|
|
119
|
+
}
|
|
120
|
+
export declare const view: <T>(sig: Sig<T>, viewFn: (val: T) => AnyView) => View<T, ViewContext<T>>;
|
|
121
|
+
export declare const extractBoundary: (view: View) => Boundary;
|
|
122
|
+
export declare const replaceWithView: (old: Boundary, view: View) => Boundary;
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/html.d.ts
|
|
125
|
+
export declare const MARK: string;
|
|
126
|
+
export declare const html: (strs: TemplateStringsArray, ...items: (Patch | AnyView)[]) => View;
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/render.d.ts
|
|
129
|
+
export declare const render: (viewArg: AnyView | (() => AnyView), node: Node) => void;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/repeat.d.ts
|
|
132
|
+
export type RepeatProp<T> = {
|
|
133
|
+
key: (item: T) => string;
|
|
134
|
+
view: (item: T) => AnyView;
|
|
135
|
+
compare?: (a: T, b: T) => boolean;
|
|
136
|
+
};
|
|
137
|
+
export interface Container {
|
|
138
|
+
parent: ParentNode;
|
|
139
|
+
startFence: Node;
|
|
140
|
+
endFence: Node;
|
|
141
|
+
}
|
|
142
|
+
export interface Track<T> {
|
|
143
|
+
boundary: Boundary;
|
|
144
|
+
bind?: AnyBind | undefined;
|
|
145
|
+
item: T;
|
|
146
|
+
key: string;
|
|
147
|
+
childCommits?: Commit<unknown, CmdContext>[] | undefined;
|
|
148
|
+
checked?: boolean;
|
|
149
|
+
cleaned?: boolean;
|
|
150
|
+
}
|
|
151
|
+
export interface RepeatContext<T> extends CmdContext {
|
|
152
|
+
prop: RepeatProp<T>;
|
|
153
|
+
boundary: Boundary;
|
|
154
|
+
tracks: Track<T>[];
|
|
155
|
+
}
|
|
156
|
+
export declare const _init: <T>(items: T[], prop: RepeatProp<T>, tracks: Track<T>[]) => DocumentFragment;
|
|
157
|
+
export declare const repeat: <T>(sig: Sig<T[]>, prop: RepeatProp<T>) => View<T[], RepeatContext<T>>;
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/text.d.ts
|
|
160
|
+
export declare const text: <T>(source: T | Sig<T>) => View<T, PatchContext>;
|
|
161
|
+
//#endregion
|
|
162
|
+
//# sourceMappingURL=sigula.d.ts.map
|
|
@@ -0,0 +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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"}
|
package/dist/sigula.js
ADDED
|
@@ -0,0 +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`);let a=e.start.nextSibling;for(i.replaceChild(n,e.start);a;){let t=a.nextSibling;if(i.removeChild(a),a===e.end)break;a=t}return r},r=e=>typeof e==`object`&&!!e&&`equals`in e&&typeof e.equals==`function`,i=e=>typeof e==`object`&&!!e,a=(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(!a(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)||!a(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 a(n,r)}if(Object.is(e,t))return!0;if(!i(e)||!i(t))return!1;let n=Object.keys(e),o=Object.keys(t);if(n.length!==o.length)return!1;for(let r of n)if(!Object.hasOwn(t,r)||!a(e[r],t[r]))return!1;return!0},o=new class{_binds=[];head=0;running=!1;scheduled=!1;scheduleFn;onError;constructor(e={}){let t=(e,t)=>{console.error(`[CallbackQueue] task failed:`,e,t)};this.scheduleFn=e.schedule??(e=>queueMicrotask(e)),this.onError=e.onError??t}get size(){return this._binds.length-this.head}get isRunning(){return this.running}get isScheduled(){return this.scheduled}add(...e){for(let t of e)this._binds.push(t);return e.length>0&&this.kick(),this}clear(){this._binds.length=0,this.head=0}kick(){this.running||this.scheduled||(this.scheduled=!0,this.scheduleFn(()=>{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++];if(e)try{let{removed:t,sig:n,context:r,cmd:i}=e;t||i(n.get(),r)}catch(t){this.onError(t,e)}}}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 s=class e{_val;_binds=[];constructor(e){this._val=e}equals(t){return t instanceof e&&a(this.get(),t.get())}get(){return this._val}forceUpdate(e){this._val=e,o.add(...this._binds)}update(e){a(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);this._binds.splice(t,1),this._binds.length===0&&this.cleanup()}getBinds(){return this._binds}cleanup(){}},c=class extends s{_fromBinds=[];addFromBind(e){this._fromBinds.push(e)}cleanup(){this._fromBinds.forEach(e=>{u(e)})}};const l=e=>new s(e),u=e=>{e.removed=!0,e.sig.removeBind(e)},d=(e,t,n)=>{let r={sig:e,context:t,cmd:n,removed:!1};return e.addBind(r),r},f=e=>{e.binds&&(Array.isArray(e.binds)?e.binds.forEach(e=>{u(e)}):u(e.binds)),e.children?.forEach(e=>{f(e)})},p=e=>{let t=Object.keys(e),n={};for(let r=0;r<t.length;r++){let i=t[r];i&&e[i]&&(n[i]=e[i].get())}return n},m=(e,t)=>{let n=t.fn(e);t.target.update(n)},h=(e,t)=>{let n=p(t.source),r=t.fn(n);t.target.update(r)},g=(e,t)=>{let n=new c(t(e.get())),r=d(e,{target:n,fn:t},m);return n.addFromBind(r),n},_=(e,t)=>{let n=new c(t(p(e))),r={source:e,target:n,fn:t},i=Object.keys(e);for(let t=0;t<i.length;t++){let a=i[t];if(a&&e[a]){let t=d(e[a],r,h);n.addFromBind(t)}}return n};function v(e,t){return e instanceof s?g(e,t):_(e,t)}const y=(e,t)=>{let n=e[t];if(n===void 0)throw RangeError(`index ${t} out of range`);return n},b=`@sig_${Math.random().toFixed(9).slice(2)}`,x=/* @__PURE__ */ new WeakMap,S=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT),ee=e=>e.type===`patch`?b:`<!--${b}-->`,te=e=>e.hasAttribute(b),C=e=>e.removeAttribute(b),ne=e=>e.data.trim()===b,re=(e,t)=>(t.replaceWith(e.node),{binds:e.bind,children:e.childCommits}),ie=(e,t)=>{let n=[];return e.toPatchItems.forEach(e=>{let r=e(t);r.source instanceof s?(r.cmd(r.source.get(),r.context),n.push(d(r.source,r.context,r.cmd))):r.cmd(r.source,r.context)}),{binds:n}},w=(e,...t)=>{let n,r=e.length-1,i=[],a=x.get(e);if(a){if(n=document.importNode(a.el.content,!0),t&&t.length>0){S.currentNode=n;let e=S.nextNode(),r=0,o=0,s=a.indexes[o];for(;s!==void 0;){if(r===s){if(e===null)throw Error(`empty node`);i.push({item:y(t,o),node:e}),o++,s=a.indexes[o],e.nodeType===Node.ELEMENT_NODE&&C(e)}e=S.nextNode(),r++}S.currentNode=document}}else{let a=document.createElement(`template`);a.innerHTML=T(e,...t);let o={el:a,indexes:[]};if(n=document.importNode(a.content,!0),t&&t.length>0){S.currentNode=n;let e=0,a=S.nextNode();for(;a!==null&&o.indexes.length<r;)a.nodeType===Node.ELEMENT_NODE?te(a)&&(o.indexes.push(e),i.push({item:y(t,i.length),node:a}),C(a)):a.nodeType===Node.COMMENT_NODE&&ne(a)&&(o.indexes.push(e),i.push({item:y(t,i.length),node:a})),a=S.nextNode(),e++;S.currentNode=document}x.set(e,o)}let o=[];return i.forEach(({item:e,node:t})=>{e.type===`patch`?o.push(ie(e,t)):e.type===`view`&&o.push(re(e,t))}),{type:`view`,node:n,childCommits:o}},T=(e,...t)=>{let n=e[0]??``;for(let r=0;r<t.length;r++)n+=ee(y(t,r))+(e[r+1]??``);return n},E=(...e)=>({type:`patch`,toPatchItems:e}),ae=(e,t)=>{t.node.id=String(e)},oe=e=>t=>({source:e,context:{node:t},cmd:ae}),se=(e,t)=>{t.node.value=String(e)},D=e=>t=>({source:e,context:{node:t},cmd:se}),O=(e,t)=>{let n=t.extra?t.extra[0]:null;if(!n)throw Error(`attrCmd: empty key`);t.node.setAttribute(n,String(e))},k=(e,t)=>n=>({source:e,context:{node:n,extra:[t]},cmd:O}),A=(e,t)=>{let n=t.extra?t.extra[0]:null;if(!n)throw Error(`attrCmd: empty key`);t.node.style[n]=String(e)},j=(e,t)=>n=>({source:e,context:{node:n,extra:[t]},cmd:A}),M=(e,t)=>{let n=t.extra?t.extra[0]:null;if(!n)throw Error(`attrCmd: empty key`);t.elem.style.setProperty(n,String(e))},N=(e,t)=>n=>({source:e,context:{node:n,extra:[t]},cmd:M}),P=(e,t)=>{let n=t.extra?t.extra[0]:null;if(!n)throw Error(`attrCmd: empty key`);t.node.classList.toggle(n,!!e)},F=(e,t)=>n=>({source:e,context:{node:n,extra:[t]},cmd:P}),I=(e,t)=>{t.extra?.forEach(n=>{t.node.classList.toggle(n,!!e)})},L=(e,...t)=>n=>({source:e,context:{node:n,extra:t},cmd:I}),R=(e,t)=>{let n=t.extra?t.extra[0]:null;if(!n)throw Error(`actCmd error: no function`);n(t.node,e)},z=(e,t)=>n=>({source:e,context:{node:n,extra:[t]},cmd:R}),B=(e,t)=>{let n=t.extra?.[0],r=t.extra?.[1];if(!n)throw Error(`onCmd no type`);t.node.addEventListener(n,e,r)},V=(e,t,n)=>r=>({source:t,context:{node:r,extra:[e,n]},cmd:B}),ce=(e,t)=>{let n=typeof e==`function`?e():e;t.appendChild(n.node)},H=(e,t)=>{let n=t.viewFn(e),r=G(t.boundary,n);t.bind&&u(t.bind),t.childCommits?.forEach(e=>{f(e)}),t.boundary=r,t.bind=n.bind,t.childCommits=n.childCommits},U=(e,t)=>{let n=t(e.get()),r={boundary:W(n),bind:n.bind,viewFn:t,childCommits:n.childCommits},i=d(e,r,H);return{...n,bind:i}},W=e=>t(e.node),G=(e,t)=>n(e,t.node),K=t=>{e(t.boundary),t.bind&&u(t.bind),t.childCommits?.forEach(e=>{f(e)}),t.cleaned=!0},le=(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 i=t.boundary.start,a=t.boundary.end,o=i.parentNode;if(!o)throw Error(`no parent node`);let s=document.createComment(`repeat-start-fence`),c=document.createComment(`repeat-end-fence`);o.insertBefore(s,i),o.insertBefore(c,a.nextSibling);let l={parent:o,startFence:s,endFence:c},u=e.map(e=>t.prop.key(e)),d=t.tracks.map(e=>e.key),f,p,m=0,h=t.tracks.length-1,g=0,_=e.length-1;for(;m<=h&&g<=_;)if(t.tracks[m]?.checked)m++;else if(t.tracks[h]?.checked)h--;else if(t.tracks[m]?.key===u[g])r[g]=Q(y(t.tracks,m),y(e,g),t.prop),m++,g++;else if(t.tracks[h]?.key===u[_])r[_]=Q(y(t.tracks,h),y(e,_),t.prop),h--,_--;else if(t.tracks[m]?.key===u[_])r[_]=Q(y(t.tracks,m),y(e,_),t.prop),X(l,y(r,_),ue(l,r[_+1])),m++,_--;else if(t.tracks[h]?.key===u[g])r[g]=Q(y(t.tracks,h),y(e,g),t.prop),X(l,y(r,g),J(l,r[g-1])),h--,g++;else if((f===void 0||p===void 0)&&(f=q(u,g,_),p=q(d,m,h)),!f.has(d[m]))K(y(t.tracks,m)),m++;else if(!f.has(d[h]))K(y(t.tracks,h)),h--;else{let n=p.get(u[g]),i=n?t.tracks[n]:null;i?(r[g]=Q(i,y(e,g),t.prop),X(l,y(r,g),J(l,r[g-1])),i.checked=!0):r[g]=Z(l,y(e,g),t.prop,J(l,r[g-1])),g++}for(;g<=_;)r[g]=Z(l,y(e,g),t.prop,J(l,r[g-1])),g++;for(;m<=h;)!t.tracks[m]?.cleaned&&!t.tracks[m]?.checked&&K(y(t.tracks,m)),m++;if(!l.startFence.nextSibling||!l.endFence.previousSibling)throw Error(`error container fences`);t.boundary={start:l.startFence.nextSibling,end:l.endFence.previousSibling},l.parent.removeChild(l.startFence),l.parent.removeChild(l.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},ue=(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)=>{if((n.compare??a)(e.item,t))return{...e,checked:!1,cleaned:!1};let r=n.view(t),i=G(e.boundary,r);return K(e),{key:n.key(t),boundary:i,bind:r.bind,childCommits:r.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},de=(e,n)=>{let r=[],i=$(e.get(),n,r),a={prop:n,tracks:r,boundary:t(i)};return{type:`view`,node:i,bind:d(e,a,le)}},fe=(e,t)=>{t.node.textContent=String(e)},pe=e=>{let t=document.createTextNode(e instanceof s?String(e.get()):String(e)),n={node:t};return{type:`view`,node:t,bind:e instanceof s?d(e,n,fe):void 0}};export{c as DerivedSig,b as MARK,s as Sig,$ as _init,z as act,k as attr,f as cleanCommit,v as compute,d as createBind,W as extractBoundary,w as html,oe as id,a as isEqual,V as on,E as patch,u as removeBind,e as removeBoundary,ce as render,de as repeat,G as replaceWithView,n as repleaceWithNode,l as sig,j as style,N as styleProperty,pe as text,t as toBoundary,p as toValRecord,F as toggleClass,L as toggleClasses,D as val,U as view};
|
|
2
|
+
//# sourceMappingURL=sigula.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigula.js","names":["removeBoundary","parent","b","next","toBoundary","node","repleaceWithNode","newBoundary","old","n","isEquatable","value","isRecord","v","isEqual","a","i","key","val","arrA","arrB","aKeys","bKeys","QUEUE","defaultOnError","err","bind","options","cb","binds","removed","cmd","sig","context","Sig","fn","index","DerivedSig","removeBind","createBind","cleanCommit","commit","child","toValRecord","keys","source","vals","k","computeCmd","res","ctx","s","computeRecordCmd","_compute","target","_computeRecord","compute","at","arr","MARK","tplCache","walker","_toMark","item","_hasMark","el","_rmMark","_isView","commitView","view","commitPatch","patch","toPatchItem","html","items","frag","itemCount","strs","wraps","exist","nodeIndex","itemIndex","existIndex","template","_text","tpl","commits","parts","text","toPatchItems","idCmd","id","elem","valCmd","attrCmd","attr","styleCmd","style","stylePropertyCmd","styleProperty","toggleClassCmd","token","toggleClass","toggleClassesCmd","toggleClasses","tokens","actCmd","act","onCmd","type","listener","on","render","viewArg","viewCmd","replaceWithView","viewFn","extractBoundary","_cleanTrack","track","repeatCmd","newFrag","newTracks","_init","start","end","startFence","endFence","container","newKeys","oldKeys","newKeyToIndexMap","oldKeyToIndexMap","oldHead","oldTail","newHead","newTail","_setTrack","_moveTrack","_beforeFence","_afterFence","_generateMap","oldIndex","oldTrack","_insertNewTrack","map","list","_mvNodeBefore","fence","prop","boundary","tracks","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 // console.warn('boundary has no parent');\n return;\n }\n\n // if (b.start === b.end) b.start.parentNode?.removeChild(b.start);\n if (b.start === b.end) parent.removeChild(b.start);\n else {\n // const range = document.createRange();\n // range.setStartBefore(b.start);\n // range.setEndAfter(b.end);\n // range.deleteContents();\n //\n // faster without 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 repleaceWithNode = (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 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 // if (old.start === old.end) {\n // parent.replaceChild(node, old.start);\n // } else {\n // console.log('-----------------------> replace with ndoe + range');\n // const doc = old.start.ownerDocument ?? document;\n // const range = doc.createRange();\n // range.setStartBefore(old.start);\n // range.setEndAfter(old.end);\n // range.deleteContents();\n // range.insertNode(node);\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\nconst isRecord = (v: unknown): v is UnknownRecord =>\n typeof v === 'object' && v !== null;\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 if (Object.is(a, b)) return true;\n if (!isRecord(a) || !isRecord(b)) return false;\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!Object.hasOwn(b, key)) return false;\n if (!isEqual(a[key], b[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}\n\n// biome-ignore lint/suspicious/noExplicitAny: any bind\nexport type AnyBind = Bind<any, any>;\n\ninterface QueueOptions {\n schedule?: (cb: () => void) => void;\n onError?: (err: unknown, bind: AnyBind) => void;\n}\n\nclass Queue {\n private _binds: AnyBind[] = [];\n private head = 0;\n private running = false;\n private scheduled = false;\n\n private readonly scheduleFn: (cb: () => void) => void;\n private readonly onError: (err: unknown, bind: AnyBind) => void;\n\n constructor(options: QueueOptions = {}) {\n const defaultOnError = (err: unknown, bind: AnyBind): void => {\n console.error('[CallbackQueue] task failed:', err, bind);\n };\n this.scheduleFn = options.schedule ?? ((cb) => queueMicrotask(cb));\n this.onError = options.onError ?? defaultOnError;\n }\n\n get size(): number {\n return this._binds.length - this.head;\n }\n\n get isRunning(): boolean {\n return this.running;\n }\n\n get isScheduled(): boolean {\n return this.scheduled;\n }\n\n add(...binds: AnyBind[]): this {\n for (const bind of binds) {\n this._binds.push(bind);\n }\n if (binds.length > 0) this.kick();\n return this;\n }\n\n clear(): void {\n this._binds.length = 0;\n this.head = 0;\n }\n\n private kick(): void {\n if (this.running || this.scheduled) return;\n this.scheduled = true;\n this.scheduleFn(() => {\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 if (bind) {\n try {\n const {removed, sig, context, cmd} = bind;\n if (!removed) cmd(sig.get(), context);\n } catch (err) {\n this.onError(err, bind);\n }\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: Bind<T, CmdContext>[] = [];\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.add(...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 as unknown as Bind<T, CmdContext>);\n }\n\n removeBind(bind: Bind<T, CmdContext>) {\n const index = this._binds.indexOf(bind);\n 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 cleanup() {\n // console.log('Sig.cleanup', this);\n }\n}\n\nexport class DerivedSig<T> extends Sig<T> {\n private _fromBinds: Bind<unknown, CmdContext>[] = [];\n\n addFromBind<S, C extends CmdContext>(bind: Bind<S, C>) {\n this._fromBinds.push(bind as unknown as Bind<unknown, CmdContext>);\n }\n\n override cleanup() {\n this._fromBinds.forEach((bind) => {\n removeBind(bind);\n });\n\n // console.log('DerivedSig.cleanup', this);\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};\n sig.addBind(bind);\n return bind;\n};\n","import type {CmdContext} from './cmd';\nimport {type Bind, removeBind} from './sig.bind';\n\nexport interface Commit<T, C extends CmdContext> {\n binds: Bind<T, C> | Bind<T, C>[] | undefined;\n children?: Commit<unknown, CmdContext>[] | 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\nexport const toValRecord = <S extends SigRecord>(source: S): ValRecord<S> => {\n const keys = Object.keys(source);\n const vals: Record<string, unknown> = {};\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i];\n if (k && source[k]) {\n vals[k] = source[k].get();\n }\n }\n return vals as ValRecord<S>;\n};\n\nexport interface ComputeContext<S, T> extends CmdContext {\n // source: Sig<S>;\n target: Sig<T>;\n fn: (s: S) => T;\n}\n\ninterface ComputeRecordContext<S extends SigRecord, T> extends CmdContext {\n source: S;\n target: Sig<T>;\n fn: (v: ValRecord<S>) => T;\n}\n\nconst computeCmd = <S, T>(s: S, ctx: ComputeContext<S, T>) => {\n const res = ctx.fn(s);\n ctx.target.update(res);\n};\n\nconst computeRecordCmd = <S extends SigRecord, T>(\n _s: unknown,\n ctx: ComputeRecordContext<S, T>,\n) => {\n const vals = toValRecord(ctx.source);\n const res = ctx.fn(vals);\n ctx.target.update(res);\n};\n\nconst _compute = <S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T> => {\n const output = fn(source.get());\n const target = new DerivedSig(output);\n const ctx: ComputeContext<S, T> = {target, fn};\n const bind = createBind(source, ctx, computeCmd);\n target.addFromBind(bind);\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 vals = toValRecord(source);\n const res = fn(vals);\n const target = new DerivedSig(res);\n\n const ctx: ComputeRecordContext<S, T> = {source, target, fn};\n\n const keys = Object.keys(source);\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i];\n if (k && source[k]) {\n const bind = createBind(source[k], ctx, computeRecordCmd);\n target.addFromBind(bind);\n }\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 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\nexport const MARK = `@sig_${Math.random().toFixed(9).slice(2)}`;\n\ninterface Tpl {\n el: HTMLTemplateElement;\n indexes: number[];\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>();\nconst walker = document.createTreeWalker(\n document,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n);\n\nconst _toMark = (item: Patch | View): string =>\n item.type === 'patch' ? MARK : `<!--${MARK}-->`;\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\nexport const html = (\n strs: TemplateStringsArray,\n ...items: (Patch | AnyView)[]\n): View => {\n // const frag = document.createDocumentFragment();\n let frag: DocumentFragment;\n const itemCount = strs.length - 1;\n const wraps: Wrap<unknown, CmdContext>[] = [];\n\n const exist = tplCache.get(strs);\n if (exist) {\n frag = document.importNode(exist.el.content, true);\n if (items && items.length > 0) {\n walker.currentNode = frag;\n\n let node = walker.nextNode();\n\n let nodeIndex = 0;\n let itemIndex = 0;\n let existIndex = exist.indexes[itemIndex];\n while (existIndex !== undefined) {\n if (nodeIndex === existIndex) {\n if (node === null) throw new Error('empty node');\n wraps.push({item: at(items, itemIndex), node});\n itemIndex++;\n existIndex = exist.indexes[itemIndex];\n if (node.nodeType === Node.ELEMENT_NODE) _rmMark(node as Element);\n }\n node = walker.nextNode();\n nodeIndex++;\n }\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 the tree is detached and should be\n // freed.\n walker.currentNode = document;\n }\n } else {\n const template = document.createElement('template');\n template.innerHTML = _text(strs, ...items);\n const tpl: Tpl = {el: template, indexes: []};\n frag = document.importNode(template.content, true);\n\n if (items && items.length > 0) {\n walker.currentNode = frag;\n let nodeIndex = 0;\n let node = walker.nextNode();\n\n while (node !== null && tpl.indexes.length < itemCount) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n if (_hasMark(node as Element)) {\n tpl.indexes.push(nodeIndex);\n wraps.push({item: at(items, wraps.length), node});\n _rmMark(node as Element);\n }\n } else if (node.nodeType === Node.COMMENT_NODE) {\n if (_isView(node as Comment)) {\n tpl.indexes.push(nodeIndex);\n wraps.push({item: at(items, wraps.length), node});\n }\n }\n //\n\n node = walker.nextNode();\n nodeIndex++;\n }\n walker.currentNode = document;\n }\n\n tplCache.set(strs, tpl);\n }\n\n const commits: Commit<unknown, CmdContext>[] = [];\n wraps.forEach(({item, node}) => {\n if (item.type === 'patch') {\n commits.push(\n commitPatch(item, node) as unknown as Commit<unknown, CmdContext>,\n );\n } else if (item.type === 'view') {\n commits.push(commitView(item, node));\n }\n });\n\n return {\n type: 'view',\n node: frag,\n childCommits: commits,\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\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\nconst idCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as Element).id = String(val);\n};\n\nexport const id =\n <T>(source: T | Sig<T>): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem},\n cmd: idCmd,\n });\n\nconst valCmd = <T>(val: T, ctx: PatchContext) => {\n (ctx.node as unknown as {value: string}).value = String(val);\n};\n\nexport const val =\n <T>(source: T | Sig<T>): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem},\n cmd: valCmd,\n });\n\nconst attrCmd = <T>(val: T, ctx: PatchContext) => {\n const key = ctx.extra ? ctx.extra[0] : null;\n if (!key) throw new Error('attrCmd: empty key');\n\n (ctx.node as Element).setAttribute(key as string, String(val));\n};\n\nexport const attr =\n <T>(source: T | Sig<T>, key: string): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem, extra: [key]},\n cmd: attrCmd,\n });\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 const key = ctx.extra ? ctx.extra[0] : null;\n if (!key) throw new Error('attrCmd: empty key');\n (ctx.node as HTMLElement).style[key as WritableStyleKey] = String(val);\n};\n\nexport const style =\n <T>(source: T | Sig<T>, key: WritableStyleKey): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem, extra: [key]},\n cmd: styleCmd,\n });\n\nconst stylePropertyCmd = <T>(val: T, ctx: PatchContext) => {\n const key = ctx.extra ? ctx.extra[0] : null;\n if (!key) throw new Error('attrCmd: empty key');\n (ctx.elem as HTMLElement).style.setProperty(key as string, String(val));\n};\n\nexport const styleProperty =\n <T>(source: T | Sig<T>, key: string): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem, extra: [key]},\n cmd: stylePropertyCmd,\n });\n\nconst toggleClassCmd = <T>(val: T, ctx: PatchContext) => {\n const token = ctx.extra ? ctx.extra[0] : null;\n if (!token) throw new Error('attrCmd: empty key');\n (ctx.node as Element).classList.toggle(token as string, Boolean(val));\n};\n\nexport const toggleClass =\n <T>(source: T | Sig<T>, token: string): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem, extra: [token]},\n cmd: toggleClassCmd,\n });\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 =\n <T>(source: T | Sig<T>, ...tokens: string[]): ToPatchItem<T> =>\n (elem: Element): PatchItem<T> => ({\n source,\n context: {node: elem, extra: tokens},\n cmd: toggleClassesCmd,\n });\n\nexport type ActFn<T> = (node: Node, val?: T) => void;\n\nconst actCmd = <T>(val: T, ctx: PatchContext) => {\n const fn = ctx.extra ? ctx.extra[0] : null;\n if (!fn) throw new Error('actCmd error: no function');\n (fn as ActFn<T>)(ctx.node, val);\n};\n\nexport const act =\n <T>(source: T | Sig<T>, fn: ActFn<T>): ToPatchItem<T> =>\n (node: Node): PatchItem<T> => ({\n source,\n context: {node, extra: [fn]},\n cmd: actCmd,\n });\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('onCmd no type');\n ctx.node.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject,\n options,\n );\n};\n\nexport const on =\n <K extends keyof HTMLElementEventMap>(\n type: K,\n listener: _Listener<K>,\n options?: boolean | AddEventListenerOptions,\n ): ToPatchItem<_Listener<K>> =>\n (node: Node): PatchItem<_Listener<K>> => ({\n source: listener,\n context: {node, extra: [type, options]},\n cmd: onCmd,\n });\n","import type {AnyView} from './view';\n\nexport const render = (viewArg: AnyView | (() => AnyView), node: Node) => {\n const view = typeof viewArg === 'function' ? viewArg() : viewArg;\n node.appendChild(view.node);\n};\n","import {type Boundary, repleaceWithNode, 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\nexport interface View<T = unknown, C extends CmdContext = CmdContext> {\n type: 'view';\n // frag: DocumentFragment;\n node: Node;\n bind?: Bind<T, C> | undefined;\n childCommits?: Commit<unknown, CmdContext>[];\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: any view\nexport type AnyView = View<any, any>;\n\nexport interface ViewContext<T> extends CmdContext {\n // kind: 'view';\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 };\n};\n\nexport const extractBoundary = (view: View): Boundary => toBoundary(view.node);\n\nexport const replaceWithView = (old: Boundary, view: View): Boundary => {\n return repleaceWithNode(old, view.node);\n};\n","import {\n type Boundary,\n removeBoundary,\n repleaceWithNode,\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\nexport interface Container {\n parent: ParentNode;\n startFence: Node;\n endFence: Node;\n}\n\nexport interface 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 = repleaceWithNode(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 = repleaceWithNode(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 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 newKeys = items.map((item) => ctx.prop.key(item));\n const oldKeys = ctx.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 );\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 );\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 );\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 );\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 ? 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 );\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): Track<T> => {\n const compare = prop.compare ?? isEqual;\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\nexport const _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 };\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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"}
|
package/package.json
CHANGED
|
@@ -1,33 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigula",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "zjh <zhanjh@126.com>",
|
|
5
|
+
"description": "Tiny web framework with fine-grained signal reactivity.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": "^24.21.0",
|
|
10
|
+
"pnpm": "^12.8.1"
|
|
11
|
+
},
|
|
9
12
|
"imports": {
|
|
10
13
|
"#/*": "./src/*",
|
|
11
14
|
"#root/*": "./*"
|
|
12
15
|
},
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"packageManager": {
|
|
18
|
-
"name": "pnpm",
|
|
19
|
-
"version": "^11.20.0",
|
|
20
|
-
"onFail": "download"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"type": "module",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
24
20
|
"devDependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"
|
|
27
|
-
"
|
|
21
|
+
"@biomejs/biome": "2.5.13",
|
|
22
|
+
"@types/node": "22.20.2",
|
|
23
|
+
"happy-dom": "20.14.5",
|
|
24
|
+
"publint": "0.3.24",
|
|
25
|
+
"tsdown": "0.23.0",
|
|
26
|
+
"tsx": "4.23.13",
|
|
27
|
+
"typescript": "7.0.2",
|
|
28
|
+
"vitest": "5.0.2"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"frontend",
|
|
35
|
+
"framework",
|
|
36
|
+
"signal",
|
|
37
|
+
"fine-grained",
|
|
38
|
+
"reactivity",
|
|
39
|
+
"reactive",
|
|
40
|
+
"no-virtual-dom",
|
|
41
|
+
"tiny",
|
|
42
|
+
"lightweight"
|
|
43
|
+
],
|
|
44
|
+
"exports": {
|
|
45
|
+
".": {
|
|
46
|
+
"types": "./dist/sigula.d.ts",
|
|
47
|
+
"import": "./dist/sigula.js",
|
|
48
|
+
"default": "./dist/sigula.js"
|
|
49
|
+
},
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/sigulajs/sigula.git"
|
|
28
55
|
},
|
|
29
56
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
57
|
+
"build": "tsdown",
|
|
58
|
+
"test:watch": "vitest",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run"
|
|
32
61
|
}
|
|
33
62
|
}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC"}
|