sigula 1.0.0 → 1.0.2
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 +491 -19
- package/dist/sigula.d.ts +5 -16
- package/dist/sigula.d.ts.map +1 -1
- package/dist/sigula.js +1 -1
- package/dist/sigula.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,19 +10,20 @@ A minimal, signal-based web framework with fine-grained reactivity. No virtual D
|
|
|
10
10
|
- Declarative signal sources + precise bindings — describe data sources declaratively with signals, then bind them precisely to the DOM or any effect
|
|
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 — under ~4KB minified + gzipped
|
|
14
15
|
- TypeScript friendly — full type inference for signals and template bindings
|
|
15
16
|
- Simple but performant — tiny API surface, low mental overhead, no compromise on performance
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
|
|
19
20
|
```sh
|
|
20
|
-
npm install
|
|
21
|
-
pnpm add
|
|
22
|
-
yarn add
|
|
21
|
+
npm install sigula
|
|
22
|
+
pnpm add sigula
|
|
23
|
+
yarn add sigula
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
##
|
|
26
|
+
## Quick Start
|
|
26
27
|
|
|
27
28
|
```ts
|
|
28
29
|
import {compute, html, on, patch, render, sig, text, type View} from 'sigula';
|
|
@@ -46,11 +47,11 @@ const Equation = (): View => {
|
|
|
46
47
|
return html`<div>
|
|
47
48
|
<h1>Equation</h1>
|
|
48
49
|
<div>
|
|
49
|
-
<p>x: ${text(x)} -
|
|
50
|
+
<p>x: ${text(x)} -
|
|
50
51
|
<button ${patch(on('click', () => x.trans((v) => v + 1)))}>+1</button>
|
|
51
52
|
<button ${patch(on('click', () => x.trans((v) => v - 1)))}>-1</button>
|
|
52
53
|
</p>
|
|
53
|
-
<p>y: ${text(y)} -
|
|
54
|
+
<p>y: ${text(y)} -
|
|
54
55
|
<button ${patch(on('click', () => y.trans((v) => v + 1)))}>+1</button>
|
|
55
56
|
<button ${patch(on('click', () => y.trans((v) => v - 1)))}>-1</button>
|
|
56
57
|
</p>
|
|
@@ -59,8 +60,8 @@ const Equation = (): View => {
|
|
|
59
60
|
<p>product: x * y = ${text(x)} * ${text(y)} = ${text(product)}</p>
|
|
60
61
|
<p>quotient: x / y = ${text(x)} / ${text(y)} = ${text(quotient)}</p>
|
|
61
62
|
<p>
|
|
62
|
-
(x + y)(x - y)
|
|
63
|
-
= (${text(x)} + ${text(y)})(${text(x)} - ${text(y)})
|
|
63
|
+
(x + y)(x - y)
|
|
64
|
+
= (${text(x)} + ${text(y)})(${text(x)} - ${text(y)})
|
|
64
65
|
= ${text(sum)}*${text(diff)} = ${text(sumDiffProduct)}
|
|
65
66
|
<br />
|
|
66
67
|
= x^2 - y^2 = ${text(xSquare)} - ${text(ySquare)} = ${text(squareDiff)}
|
|
@@ -81,17 +82,17 @@ render(Equation(), appNode);
|
|
|
81
82
|
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
|
|
|
83
84
|
```ts
|
|
84
|
-
import {html text} from 'sigula';
|
|
85
|
+
import {html, text} from 'sigula';
|
|
85
86
|
|
|
86
|
-
const name = sig('Alice')
|
|
87
|
+
const name = sig('Alice');
|
|
87
88
|
|
|
88
|
-
const App = html`<h1>Hello, ${text(name)}!</h1
|
|
89
|
+
const App = html`<h1>Hello, ${text(name)}!</h1>`;
|
|
89
90
|
|
|
90
91
|
// 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
|
+
name.update('Bob'); // → the text changes from "Hello, Alice!" to "Hello, Bob!"
|
|
92
93
|
```
|
|
93
94
|
|
|
94
|
-
Only the exact text node that depends on name is updated. Everything else stays untouched.
|
|
95
|
+
Only the exact text node that depends on `name` is updated. Everything else stays untouched.
|
|
95
96
|
|
|
96
97
|
### Declarative signal sources + precise bindings
|
|
97
98
|
|
|
@@ -180,7 +181,7 @@ const Todos = (): View => {
|
|
|
180
181
|
<button>Add</button>
|
|
181
182
|
</form>
|
|
182
183
|
<div>
|
|
183
|
-
filter:
|
|
184
|
+
filter:
|
|
184
185
|
<button ${patch(on('click', () => filter.update('all')))}>all</button>
|
|
185
186
|
<button ${patch(on('click', () => filter.update('active')))}>active</button>
|
|
186
187
|
<button ${patch(on('click', () => filter.update('done')))}>done</button>
|
|
@@ -214,7 +215,7 @@ This means:
|
|
|
214
215
|
|
|
215
216
|
### Minimal HTML templates
|
|
216
217
|
|
|
217
|
-
Templates are plain JavaScript native string templates. No custom compiler, no
|
|
218
|
+
Templates are plain JavaScript native string templates. No custom compiler, no `.vue` files, no JSX transform:
|
|
218
219
|
|
|
219
220
|
```ts
|
|
220
221
|
const App: View = html`
|
|
@@ -223,13 +224,484 @@ const App: View = html`
|
|
|
223
224
|
<p>${text(description)}</p>
|
|
224
225
|
<button ${patch(on('click', handleClick))}>Click me</button>
|
|
225
226
|
</div>
|
|
226
|
-
|
|
227
|
+
`;
|
|
227
228
|
```
|
|
228
229
|
|
|
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
|
+
`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. Templates are cached per call site, so rendering the same template twice only parses it once.
|
|
230
231
|
|
|
231
232
|
### Ultra small
|
|
232
233
|
|
|
233
|
-
minified + gzipped: ~3.
|
|
234
|
+
minified + gzipped: ~3.8KB
|
|
234
235
|
|
|
236
|
+
## 📖 Reference
|
|
235
237
|
|
|
238
|
+
All exports are named exports from `sigula`.
|
|
239
|
+
|
|
240
|
+
- [Reactivity](#reactivity)
|
|
241
|
+
- [Templates](#templates)
|
|
242
|
+
- [DOM bindings](#dom-bindings)
|
|
243
|
+
- [Control flow](#control-flow)
|
|
244
|
+
- [Rendering](#rendering)
|
|
245
|
+
- [Low-level API](#low-level-api)
|
|
246
|
+
- [Reactivity model](#reactivity-model)
|
|
247
|
+
|
|
248
|
+
### Reactivity
|
|
249
|
+
|
|
250
|
+
#### `sig`
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
const sig: <T>(v: T) => Sig<T>;
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Creates a writable signal holding `v`.
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
const count = sig(0);
|
|
260
|
+
count.get(); // 0
|
|
261
|
+
count.update(1); // schedules dependents
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### `Sig<T>`
|
|
265
|
+
|
|
266
|
+
The core reactive value.
|
|
267
|
+
|
|
268
|
+
| Member | Signature | Description |
|
|
269
|
+
| --- | --- | --- |
|
|
270
|
+
| `get` | `(): T` | Reads the current value. |
|
|
271
|
+
| `update` | `(v: T): void` | Sets the value and notifies dependents, but only if `isEqual(v, current)` is `false`. |
|
|
272
|
+
| `forceUpdate` | `(v: T): void` | Sets the value and always notifies dependents, even when deeply equal. |
|
|
273
|
+
| `trans` | `(fn: (v: T) => T): void` | Applies `fn` to the current value via `update`, so an equal result is skipped. |
|
|
274
|
+
| `equals` | `(other: unknown): boolean` | `Equatable` implementation; two `Sig`s are equal when their values are deeply equal. |
|
|
275
|
+
| `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
|
+
| `getBinds` | `(): Bind<T, CmdContext>[]` | Returns the current bindings. |
|
|
278
|
+
| `cleanup` | `(): void` | Overridable hook called when a signal loses all bindings. No-op on `Sig`. |
|
|
279
|
+
|
|
280
|
+
#### `DerivedSig<T>`
|
|
281
|
+
|
|
282
|
+
A `Sig` produced by `compute`. Extends `Sig` and additionally tracks the source bindings that feed it.
|
|
283
|
+
|
|
284
|
+
| Member | Signature | Description |
|
|
285
|
+
| --- | --- | --- |
|
|
286
|
+
| `addFromBind` | `<S, C>(bind: Bind<S, C>): void` | Registers a source binding. |
|
|
287
|
+
| `cleanup` | `(): void` | Removes every source binding when the derived signal has no consumers. |
|
|
288
|
+
|
|
289
|
+
#### `compute`
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
function compute<S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T>;
|
|
293
|
+
function compute<S extends SigRecord, T>(
|
|
294
|
+
source: S,
|
|
295
|
+
fn: (v: ValRecord<S>) => T,
|
|
296
|
+
): DerivedSig<T>;
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Derives a signal from one source signal, or from a record of signals (whose values are passed as a matching record). The result is recomputed whenever any source changes.
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
const x = sig(1);
|
|
303
|
+
const y = sig(2);
|
|
304
|
+
|
|
305
|
+
const sum = compute({x, y}, (v) => v.x + v.y); // DerivedSig<number>
|
|
306
|
+
const doubled = compute(x, (v) => v * 2); // DerivedSig<number>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Supporting types:
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
interface SigRecord {
|
|
313
|
+
[key: string]: Sig<any>;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
type ValRecord<K extends SigRecord> = {
|
|
317
|
+
[P in keyof K]: K[P] extends Sig<infer U> ? U : never;
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`ValRecord` maps a record of signals to the record of their values, which is what `compute`'s record overload passes to `fn`.
|
|
322
|
+
|
|
323
|
+
#### `isEqual`
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
const isEqual: <T>(a: T, b: T) => boolean;
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Deep structural equality. Compares primitives, arrays, `Date`, `RegExp`, `Map`, `Set`, and plain objects, and defers to `a.equals(b)` when `a` implements `Equatable`. This is the default comparator for `Sig.update` and `repeat`.
|
|
330
|
+
|
|
331
|
+
#### `Equatable`
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
interface Equatable {
|
|
335
|
+
equals(other: unknown): boolean;
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Implement this on a value type to give `isEqual` custom semantics.
|
|
340
|
+
|
|
341
|
+
#### `UnknownRecord`
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
type UnknownRecord = Record<string, unknown>;
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Convenience alias for an arbitrary string-keyed object, used by the equality and signal-record helpers.
|
|
348
|
+
|
|
349
|
+
#### `createBind` / `removeBind`
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
const createBind: <T, C extends CmdContext>(
|
|
353
|
+
sig: Sig<T>,
|
|
354
|
+
context: C,
|
|
355
|
+
cmd: Cmd<T, C>,
|
|
356
|
+
) => Bind<T, C>;
|
|
357
|
+
|
|
358
|
+
const removeBind: (bind: Bind<unknown, CmdContext>) => void;
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Low-level bind management. `createBind` wires `cmd(sig.get(), context)` to run whenever `sig` changes; `removeBind` detaches it. `Bind` is the resulting record:
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
interface Bind<T, C extends CmdContext> {
|
|
365
|
+
sig: Sig<T>;
|
|
366
|
+
context: C;
|
|
367
|
+
cmd: Cmd<T, C>;
|
|
368
|
+
removed: boolean;
|
|
369
|
+
queued?: boolean;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
type AnyBind = Bind<any, any>;
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Templates
|
|
376
|
+
|
|
377
|
+
#### `html`
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
const html: (
|
|
381
|
+
strs: TemplateStringsArray,
|
|
382
|
+
...items: (Patch | AnyView)[]
|
|
383
|
+
) => View;
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Tagged template that parses native HTML and returns a `View`. Two kinds of interpolation are supported:
|
|
387
|
+
|
|
388
|
+
- a `View` (from `text`, `view`, `repeat`, or another `html`) fills a content position
|
|
389
|
+
- a `Patch` (from `patch(...)`) fills an attribute position
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
html`<p>${text(label)}</p>`;
|
|
393
|
+
html`<button ${patch(on('click', handler))}>Go</button>`;
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
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`.
|
|
397
|
+
|
|
398
|
+
#### `text`
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
const text: <T>(source: T | Sig<T>) => View<T, PatchContext>;
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Creates a text-node view. With a `Sig`, the text updates whenever the signal changes; with a plain value it is static.
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
html`<span>${text(count)}</span>`;
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### `View<T, C>` / `AnyView`
|
|
411
|
+
|
|
412
|
+
```ts
|
|
413
|
+
interface View<T = unknown, C extends CmdContext = CmdContext> {
|
|
414
|
+
type: 'view';
|
|
415
|
+
node: Node;
|
|
416
|
+
bind?: Bind<T, C> | undefined;
|
|
417
|
+
childCommits?: Commit<unknown, CmdContext>[];
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
type AnyView = View<any, any>;
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
`View` is the unit returned by `html`, `text`, `view`, and `repeat`. Its `node` is a DOM node or `DocumentFragment`.
|
|
424
|
+
|
|
425
|
+
#### `extractBoundary` / `replaceWithView`
|
|
426
|
+
|
|
427
|
+
```ts
|
|
428
|
+
const extractBoundary: (view: View) => Boundary;
|
|
429
|
+
const replaceWithView: (old: Boundary, view: View) => Boundary;
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
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.
|
|
433
|
+
|
|
434
|
+
### DOM bindings
|
|
435
|
+
|
|
436
|
+
#### `patch`
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
const patch: (...toPatchItems: ToAnyPatchItem[]) => Patch;
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Declares one or more bindings to apply to the same element. Must be interpolated in an attribute position. Each command (`id`, `val`, `attr`, ...) receives either a plain value (applied once) or a `Sig` (applied on mount and re-applied on change).
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
html`<input ${patch(val(name), attr(placeholder, 'name'))} />`;
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
#### `id`
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
const id: <T>(source: T | Sig<T>) => ToPatchItem<T>;
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Sets the element's `id`.
|
|
455
|
+
|
|
456
|
+
#### `val`
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
const val: <T>(source: T | Sig<T>) => ToPatchItem<T>;
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Sets the element's `value` property (form controls).
|
|
463
|
+
|
|
464
|
+
#### `attr`
|
|
465
|
+
|
|
466
|
+
```ts
|
|
467
|
+
const attr: <T>(source: T | Sig<T>, key: string) => ToPatchItem<T>;
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Sets attribute `key`. Use this for boolean/ARIA/data attributes.
|
|
471
|
+
|
|
472
|
+
#### `style`
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
const style: <T>(
|
|
476
|
+
source: T | Sig<T>,
|
|
477
|
+
key: WritableStyleKey,
|
|
478
|
+
) => ToPatchItem<T>;
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Sets an inline style property by typed name.
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
html`<span ${patch(style(color, 'color'))}>text</span>`;
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
`WritableStyleKey` is the union of `CSSStyleDeclaration` keys whose values are strings.
|
|
488
|
+
|
|
489
|
+
#### `styleProperty`
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
const styleProperty: <T>(source: T | Sig<T>, key: string) => ToPatchItem<T>;
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Sets a style property via `CSSStyleDeclaration.setProperty`. Use this for custom properties (`--my-var`) or untyped names.
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
html`<div ${patch(styleProperty(size, '--size'))}></div>`;
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
#### `toggleClass`
|
|
502
|
+
|
|
503
|
+
```ts
|
|
504
|
+
const toggleClass: <T>(source: T | Sig<T>, token: string) => ToPatchItem<T>;
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Toggles a single class from the truthiness of the value.
|
|
508
|
+
|
|
509
|
+
#### `toggleClasses`
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
const toggleClasses: <T>(
|
|
513
|
+
source: T | Sig<T>,
|
|
514
|
+
...tokens: string[]
|
|
515
|
+
) => ToPatchItem<T>;
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
Toggles several classes from one value.
|
|
519
|
+
|
|
520
|
+
#### `act`
|
|
521
|
+
|
|
522
|
+
```ts
|
|
523
|
+
type ActFn<T> = (node: Node, val?: T) => void;
|
|
524
|
+
const act: <T>(source: T | Sig<T>, fn: ActFn<T>) => ToPatchItem<T>;
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Runs arbitrary code with the bound node and value; runs on mount and again on change. Use it as the escape hatch for anything the built-in commands do not cover.
|
|
528
|
+
|
|
529
|
+
```ts
|
|
530
|
+
html`<canvas ${patch(act(frame, (node, v) => draw(node, v)))}></canvas>`;
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
#### `on`
|
|
534
|
+
|
|
535
|
+
```ts
|
|
536
|
+
const on: <K extends keyof HTMLElementEventMap>(
|
|
537
|
+
type: K,
|
|
538
|
+
listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown,
|
|
539
|
+
options?: boolean | AddEventListenerOptions,
|
|
540
|
+
) => ToPatchItem<
|
|
541
|
+
(this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown
|
|
542
|
+
>;
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
Adds a DOM event listener. The listener is registered once at mount; it is not a reactive source, so combine it with `sig` writes to drive updates.
|
|
546
|
+
|
|
547
|
+
```ts
|
|
548
|
+
html`<button ${patch(on('click', () => count.trans((v) => v + 1)))}>+1</button>`;
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
#### Patch types
|
|
552
|
+
|
|
553
|
+
```ts
|
|
554
|
+
interface PatchContext extends CmdContext {
|
|
555
|
+
node: Node;
|
|
556
|
+
extra?: unknown[];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
interface PatchItem<T> {
|
|
560
|
+
source: T | Sig<T>;
|
|
561
|
+
context: PatchContext;
|
|
562
|
+
cmd: Cmd<T, PatchContext>;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
type ToPatchItem<T> = (el: Element) => PatchItem<T>;
|
|
566
|
+
type AnyPatchItem = PatchItem<any>;
|
|
567
|
+
type ToAnyPatchItem = (el: Element) => AnyPatchItem;
|
|
568
|
+
|
|
569
|
+
interface Patch {
|
|
570
|
+
type: 'patch';
|
|
571
|
+
toPatchItems: ToAnyPatchItem[];
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
`ToPatchItem` defers reading the target element until mount. `patch` collects these factories into a single `Patch`.
|
|
576
|
+
|
|
577
|
+
### Control flow
|
|
578
|
+
|
|
579
|
+
#### `view`
|
|
580
|
+
|
|
581
|
+
```ts
|
|
582
|
+
const view: <T>(
|
|
583
|
+
sig: Sig<T>,
|
|
584
|
+
viewFn: (val: T) => AnyView,
|
|
585
|
+
) => View<T>;
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Conditionally renders one view or another. Whenever `sig` changes, `viewFn` is called with the new value, the previous view is torn down, and a new one is mounted in its place.
|
|
589
|
+
|
|
590
|
+
```ts
|
|
591
|
+
html`<div>${view(isEmpty, (v) => (v ? text('empty') : list))}</div>`;
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
#### `repeat`
|
|
595
|
+
|
|
596
|
+
```ts
|
|
597
|
+
interface RepeatProp<T> {
|
|
598
|
+
key: (item: T) => string;
|
|
599
|
+
view: (item: T) => AnyView;
|
|
600
|
+
compare?: (a: T, b: T) => boolean;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const repeat: <T>(sig: Sig<T[]>, prop: RepeatProp<T>) => View<T[]>;
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
Keyed list rendering. On each change Sigula matches items by `key`, then reuses, moves, creates, or removes as few DOM nodes as possible. `compare` defaults to `isEqual`; when an item is deeply equal to the track it already occupies, the track is reused without rebuilding its view. An empty array renders `<!--empty-list-->`.
|
|
607
|
+
|
|
608
|
+
```ts
|
|
609
|
+
html`<ul>${repeat(todos, {
|
|
610
|
+
key: (item) => item.id.toString(),
|
|
611
|
+
view: (item) => html`<li>${text(item.label)}</li>`,
|
|
612
|
+
})}</ul>`;
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
`key` must be unique and stable for a given item. `compare` is useful when item identity is structural but you want to force or skip updates.
|
|
616
|
+
|
|
617
|
+
### Rendering
|
|
618
|
+
|
|
619
|
+
#### `render`
|
|
620
|
+
|
|
621
|
+
```ts
|
|
622
|
+
const render: (viewArg: AnyView | (() => AnyView), node: Node) => void;
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
Mounts a view into `node` by appending `view.node`. Accepts a `View` directly or a factory function that returns one.
|
|
626
|
+
|
|
627
|
+
```ts
|
|
628
|
+
render(App(), document.querySelector('#app')!);
|
|
629
|
+
render(() => html`<p>lazy</p>`, document.body);
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Low-level API
|
|
633
|
+
|
|
634
|
+
These utilities power the framework and are exported for extension and testing.
|
|
635
|
+
|
|
636
|
+
#### `Boundary`
|
|
637
|
+
|
|
638
|
+
```ts
|
|
639
|
+
interface Boundary {
|
|
640
|
+
start: Node;
|
|
641
|
+
end: Node;
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
An inclusive range of sibling nodes (`start` through `end`).
|
|
646
|
+
|
|
647
|
+
#### `toBoundary`
|
|
648
|
+
|
|
649
|
+
```ts
|
|
650
|
+
const toBoundary: (node: Node) => Boundary;
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
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.
|
|
654
|
+
|
|
655
|
+
#### `removeBoundary`
|
|
656
|
+
|
|
657
|
+
```ts
|
|
658
|
+
const removeBoundary: (b: Boundary) => void;
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
Removes every node in the boundary. A no-op if the boundary has no parent.
|
|
662
|
+
|
|
663
|
+
#### `replaceWithNode`
|
|
664
|
+
|
|
665
|
+
```ts
|
|
666
|
+
const replaceWithNode: (old: Boundary, node: Node) => Boundary;
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
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.
|
|
670
|
+
|
|
671
|
+
#### `Cmd` / `AnyCmd` / `CmdContext`
|
|
672
|
+
|
|
673
|
+
```ts
|
|
674
|
+
interface CmdContext {
|
|
675
|
+
[key: string]: unknown;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
type Cmd<T, C extends CmdContext> = (val: T, context: C) => void;
|
|
679
|
+
type AnyCmd = Cmd<any, any>;
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
A `Cmd` is the unit of work a binding runs: it receives the current signal value and its context.
|
|
683
|
+
|
|
684
|
+
#### `Commit` / `cleanCommit`
|
|
685
|
+
|
|
686
|
+
```ts
|
|
687
|
+
interface Commit<T, C extends CmdContext> {
|
|
688
|
+
binds: Bind<T, C> | Bind<T, C>[] | undefined;
|
|
689
|
+
children?: Commit<unknown, CmdContext>[] | undefined;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const cleanCommit: (commit: Commit<unknown, CmdContext>) => void;
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
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.
|
|
696
|
+
|
|
697
|
+
### Reactivity model
|
|
698
|
+
|
|
699
|
+
- **Batched.** When a signal changes, its bindings are queued, not run synchronously.
|
|
700
|
+
- **Coalesced per binding.** A binding that is written to multiple times before the microtask flush runs once, reading the signal's final value. `sig.update(1); sig.update(2); sig.update(3)` runs each dependent binding a single time against `3`.
|
|
701
|
+
- **`update` vs `forceUpdate`.** `update` skips work when the new value is deeply equal to the current one; `forceUpdate` always notifies. Use `forceUpdate` when a value is structurally equal but you still need a re-render (for example, mutating an object in place).
|
|
702
|
+
- **Error isolation.** A throwing binding does not stop the rest of the queue; the error is logged as `console.error('[Queue] task failed:', error, bind)`.
|
|
703
|
+
- **Deep equality by default.** `update`, `compute`, and `repeat` compare with `isEqual`, so replacing `{a: 1}` with another `{a: 1}` is a no-op.
|
|
704
|
+
|
|
705
|
+
## License
|
|
706
|
+
|
|
707
|
+
MIT
|
package/dist/sigula.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface Boundary {
|
|
|
5
5
|
}
|
|
6
6
|
export declare const removeBoundary: (b: Boundary) => void;
|
|
7
7
|
export declare const toBoundary: (node: Node) => Boundary;
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const replaceWithNode: (old: Boundary, node: Node) => Boundary;
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/cmd.d.ts
|
|
11
11
|
export interface CmdContext {
|
|
@@ -27,6 +27,7 @@ export interface Bind<T, C extends CmdContext> {
|
|
|
27
27
|
context: C;
|
|
28
28
|
cmd: Cmd<T, C>;
|
|
29
29
|
removed: boolean;
|
|
30
|
+
queued?: boolean;
|
|
30
31
|
}
|
|
31
32
|
export type AnyBind = Bind<any, any>;
|
|
32
33
|
export declare class Sig<T> implements Equatable {
|
|
@@ -64,11 +65,6 @@ export interface SigRecord {
|
|
|
64
65
|
[key: string]: Sig<any>;
|
|
65
66
|
}
|
|
66
67
|
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
68
|
export declare function compute<S, T>(source: Sig<S>, fn: (v: S) => T): DerivedSig<T>;
|
|
73
69
|
export declare function compute<S extends SigRecord, T>(source: S, fn: (v: ValRecord<S>) => T): DerivedSig<T>;
|
|
74
70
|
//#endregion
|
|
@@ -111,7 +107,7 @@ export interface View<T = unknown, C extends CmdContext = CmdContext> {
|
|
|
111
107
|
childCommits?: Commit<unknown, CmdContext>[];
|
|
112
108
|
}
|
|
113
109
|
export type AnyView = View<any, any>;
|
|
114
|
-
|
|
110
|
+
interface ViewContext<T> extends CmdContext {
|
|
115
111
|
boundary: Boundary;
|
|
116
112
|
bind?: AnyBind | undefined;
|
|
117
113
|
childCommits?: Commit<unknown, CmdContext>[] | undefined;
|
|
@@ -122,7 +118,6 @@ export declare const extractBoundary: (view: View) => Boundary;
|
|
|
122
118
|
export declare const replaceWithView: (old: Boundary, view: View) => Boundary;
|
|
123
119
|
//#endregion
|
|
124
120
|
//#region src/html.d.ts
|
|
125
|
-
export declare const MARK: string;
|
|
126
121
|
export declare const html: (strs: TemplateStringsArray, ...items: (Patch | AnyView)[]) => View;
|
|
127
122
|
//#endregion
|
|
128
123
|
//#region src/render.d.ts
|
|
@@ -134,12 +129,7 @@ export type RepeatProp<T> = {
|
|
|
134
129
|
view: (item: T) => AnyView;
|
|
135
130
|
compare?: (a: T, b: T) => boolean;
|
|
136
131
|
};
|
|
137
|
-
|
|
138
|
-
parent: ParentNode;
|
|
139
|
-
startFence: Node;
|
|
140
|
-
endFence: Node;
|
|
141
|
-
}
|
|
142
|
-
export interface Track<T> {
|
|
132
|
+
interface Track<T> {
|
|
143
133
|
boundary: Boundary;
|
|
144
134
|
bind?: AnyBind | undefined;
|
|
145
135
|
item: T;
|
|
@@ -148,12 +138,11 @@ export interface Track<T> {
|
|
|
148
138
|
checked?: boolean;
|
|
149
139
|
cleaned?: boolean;
|
|
150
140
|
}
|
|
151
|
-
|
|
141
|
+
interface RepeatContext<T> extends CmdContext {
|
|
152
142
|
prop: RepeatProp<T>;
|
|
153
143
|
boundary: Boundary;
|
|
154
144
|
tracks: Track<T>[];
|
|
155
145
|
}
|
|
156
|
-
export declare const _init: <T>(items: T[], prop: RepeatProp<T>, tracks: Track<T>[]) => DocumentFragment;
|
|
157
146
|
export declare const repeat: <T>(sig: Sig<T[]>, prop: RepeatProp<T>) => View<T[], RepeatContext<T>>;
|
|
158
147
|
//#endregion
|
|
159
148
|
//#region src/text.d.ts
|
package/dist/sigula.d.ts.map
CHANGED
|
@@ -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":";iBAAiB;EACf,OAAO;EACP,KAAK;;qBAGM,iBAAc,GAAO;qBA0BrB,aAAU,MAAU,SAAO;qBAS3B,
|
|
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
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`);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};
|
|
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=>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;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++];if(e)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 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.addAll(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);t>=0&&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,queued:!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),C=e=>e.type===`patch`?b:`<!--${b}-->`,ee=e=>e.hasAttribute(b),te=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,n,r,i)=>{S.currentNode=e;let a=S.nextNode(),o=0,s=0;for(;a!==null&&s<t.length;)r(a,o,s)&&(n.push({item:y(t,s),node:a}),i&&i.push(o),s++,a.nodeType===Node.ELEMENT_NODE&&te(a)),a=S.nextNode(),o++;S.currentNode=document},ae=(e,...t)=>{let n,r=[],i=x.get(e);if(i)n=document.importNode(i.el.content,!0),t&&t.length>0&&w(n,t,r,(e,t,n)=>t===i.indexes[n]);else{let i=document.createElement(`template`);i.innerHTML=oe(e,...t);let a={el:i,indexes:[]};n=document.importNode(i.content,!0),t&&t.length>0&&w(n,t,r,e=>e.nodeType===Node.ELEMENT_NODE?ee(e):e.nodeType===Node.COMMENT_NODE&&ne(e),a.indexes),x.set(e,a)}if(r.length!==t.length)throw Error(`html: unmatched interpolation; patch() must be in attribute position`);let a=[];return r.forEach(({item:e,node:t})=>{e.type===`patch`?a.push(ie(e,t)):e.type===`view`&&a.push(re(e,t))}),{type:`view`,node:n,childCommits:a}},oe=(e,...t)=>{let n=e[0]??``;for(let r=0;r<t.length;r++)n+=C(y(t,r))+(e[r+1]??``);return n},T=(...e)=>({type:`patch`,toPatchItems:e}),E=(e,t,n)=>r=>({source:e,context:t?{node:r,extra:t}:{node:r},cmd:n}),D=e=>{let t=e.extra?.[0];if(!t)throw Error(`patch: empty key`);return t},se=(e,t)=>{t.node.id=String(e)},ce=e=>E(e,void 0,se),le=(e,t)=>{t.node.value=String(e)},O=e=>E(e,void 0,le),k=(e,t)=>{t.node.setAttribute(D(t),String(e))},A=(e,t)=>E(e,[t],k),j=(e,t)=>{t.node.style[D(t)]=String(e)},M=(e,t)=>E(e,[t],j),N=(e,t)=>{t.node.style.setProperty(D(t),String(e))},P=(e,t)=>E(e,[t],N),F=(e,t)=>{t.node.classList.toggle(D(t),!!e)},I=(e,t)=>E(e,[t],F),L=(e,t)=>{t.extra?.forEach(n=>{t.node.classList.toggle(n,!!e)})},R=(e,...t)=>E(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)=>E(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)},H=(e,t,n)=>E(t,[e,n],V),ue=(e,t)=>{let n=typeof e==`function`?e():e;t.appendChild(n.node)},U=(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},de=(e,t)=>{let n=t(e.get()),r={boundary:W(n),bind:n.bind,viewFn:t,childCommits:n.childCommits},i=d(e,r,U);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},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 i=t.boundary.start,o=t.boundary.end,s=i.parentNode;if(!s)throw Error(`no parent node`);let c=t.prop.compare??a,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,i),s.insertBefore(f,o.nextSibling);let p={parent:s,startFence:d,endFence:f},m=u.map(e=>e.key),h,g,_=0,v=t.tracks.length-1,b=0,x=e.length-1;for(;_<=v&&b<=x;)if(t.tracks[_]?.checked)_++;else if(t.tracks[v]?.checked)v--;else if(t.tracks[_]?.key===l[b])r[b]=Q(y(t.tracks,_),y(e,b),t.prop,c),_++,b++;else if(t.tracks[v]?.key===l[x])r[x]=Q(y(t.tracks,v),y(e,x),t.prop,c),v--,x--;else if(t.tracks[_]?.key===l[x])r[x]=Q(y(t.tracks,_),y(e,x),t.prop,c),X(p,y(r,x),pe(p,r[x+1])),_++,x--;else if(t.tracks[v]?.key===l[b])r[b]=Q(y(t.tracks,v),y(e,b),t.prop,c),X(p,y(r,b),J(p,r[b-1])),v--,b++;else if((h===void 0||g===void 0)&&(h=q(l,b,x),g=q(m,_,v)),!h.has(m[_]))K(y(t.tracks,_)),_++;else if(!h.has(m[v]))K(y(t.tracks,v)),v--;else{let n=g.get(l[b]),i=n===void 0?null:t.tracks[n];i?(r[b]=Q(i,y(e,b),t.prop,c),X(p,y(r,b),J(p,r[b-1])),i.checked=!0):r[b]=Z(p,y(e,b),t.prop,J(p,r[b-1])),b++}for(;b<=x;)r[b]=Z(p,y(e,b),t.prop,J(p,r[b-1])),b++;for(;_<=v;)!t.tracks[_]?.cleaned&&!t.tracks[_]?.checked&&K(y(t.tracks,_)),_++;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:d(e,a,fe)}},he=(e,t)=>{t.node.textContent=String(e)},ge=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,he):void 0}};export{c as DerivedSig,s as Sig,B as act,A as attr,f as cleanCommit,v as compute,d as createBind,W as extractBoundary,ae as html,ce as id,a as isEqual,H as on,T as patch,u as removeBind,e as removeBoundary,ue as render,me as repeat,n as replaceWithNode,G as replaceWithView,l 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};
|
|
2
2
|
//# sourceMappingURL=sigula.js.map
|
package/dist/sigula.js.map
CHANGED
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"file":"sigula.js","names":["removeBoundary","parent","b","next","toBoundary","node","replaceWithNode","newBoundary","old","n","isEquatable","value","isRecord","v","isEqual","a","i","key","val","arrA","arrB","aKeys","bKeys","QUEUE","bind","binds","removed","cmd","sig","context","err","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","_scan","frag","nodeIndex","itemIndex","items","hit","wraps","indexes","html","exist","strs","template","_text","tpl","commits","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","boundary","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 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 // 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 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 if (bind) {\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 }\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.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 as unknown as Bind<T, CmdContext>);\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 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, queued: 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\nconst 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\ninterface 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\nconst 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\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 walker.currentNode = frag;\n let node = walker.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 = walker.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 walker.currentNode = document;\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 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 _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: []};\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, 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\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 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, 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\nexport interface View<T = unknown, C extends CmdContext = CmdContext> {\n type: 'view';\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\ninterface 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 };\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\ninterface 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 };\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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"}
|