@source-crafter/xzor-runtime 0.1.15 → 0.1.17
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/fine.d.ts +43 -2
- package/{index-k290gfdd.js → index-45b6cjyv.js} +121 -13
- package/index-45b6cjyv.js.map +10 -0
- package/index.d.ts +23 -0
- package/index.js +6 -2
- package/index.js.map +1 -1
- package/model.d.ts +4 -0
- package/model.js +486 -51
- package/model.js.map +4 -4
- package/package.json +1 -1
- package/index-k290gfdd.js.map +0 -10
package/model.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
$inSvg,
|
|
3
3
|
$isFragment,
|
|
4
|
+
$leave,
|
|
4
5
|
ComponentBase,
|
|
5
6
|
FINE,
|
|
6
7
|
SVG,
|
|
@@ -8,7 +9,7 @@ import {
|
|
|
8
9
|
patchIsland,
|
|
9
10
|
setFineHooks,
|
|
10
11
|
setRenderObserver
|
|
11
|
-
} from "./index-
|
|
12
|
+
} from "./index-45b6cjyv.js";
|
|
12
13
|
|
|
13
14
|
// runtime/entity-set.ts
|
|
14
15
|
class EntitySet extends Array {
|
|
@@ -226,18 +227,31 @@ var ATTR = 1;
|
|
|
226
227
|
var REGION = 2;
|
|
227
228
|
var LIST = 3;
|
|
228
229
|
var ISLAND = 4;
|
|
230
|
+
var KEYED = 5;
|
|
231
|
+
var EFFECT = 6;
|
|
232
|
+
var MEMO = 7;
|
|
229
233
|
var KIND = 7;
|
|
230
234
|
var QUEUED = 8;
|
|
231
235
|
var MANY = 16;
|
|
232
236
|
var DEAD = 32;
|
|
233
237
|
var LOOSE = 64;
|
|
234
238
|
var ITEM = 128;
|
|
239
|
+
var OWNED = 256;
|
|
240
|
+
var FRESH = 512;
|
|
241
|
+
var SHOW = 1024;
|
|
242
|
+
var PAUSE = 2048;
|
|
243
|
+
var PAUSED = 4096;
|
|
244
|
+
var STALE = 8192;
|
|
235
245
|
var bitOf = (index) => index === -1 ? 1 << 31 : index < 30 ? 1 << index : 1 << 30;
|
|
246
|
+
var MEMOS = Symbol("xzor.fine.memos");
|
|
247
|
+
var EMPTY = Symbol("xzor.fine.empty");
|
|
236
248
|
var collecting;
|
|
237
249
|
var holder;
|
|
238
250
|
function collect(source, index) {
|
|
251
|
+
collectBits(source, bitOf(index));
|
|
252
|
+
}
|
|
253
|
+
function collectBits(source, bit) {
|
|
239
254
|
const b = collecting;
|
|
240
|
-
const bit = bitOf(index);
|
|
241
255
|
const own = b.model;
|
|
242
256
|
if (own === source) {
|
|
243
257
|
b.mask |= bit;
|
|
@@ -296,8 +310,31 @@ class Binding {
|
|
|
296
310
|
return (this.flags & (QUEUED | DEAD)) !== 0 ? 0 : -1;
|
|
297
311
|
}
|
|
298
312
|
set at(value) {
|
|
299
|
-
if ((this.flags & DEAD)
|
|
300
|
-
|
|
313
|
+
if ((this.flags & DEAD) !== 0)
|
|
314
|
+
return;
|
|
315
|
+
if ((this.flags & KIND) === MEMO) {
|
|
316
|
+
if (value >= 0)
|
|
317
|
+
this.flags &= ~FRESH;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.flags = value < 0 ? this.flags & ~QUEUED : this.flags | QUEUED;
|
|
321
|
+
}
|
|
322
|
+
$memo() {
|
|
323
|
+
if ((this.flags & FRESH) === 0) {
|
|
324
|
+
this.data = this.#run();
|
|
325
|
+
if (this.model !== undefined && (this.flags & DEAD) === 0)
|
|
326
|
+
this.flags |= FRESH;
|
|
327
|
+
}
|
|
328
|
+
if (collecting !== undefined) {
|
|
329
|
+
const own = this.model;
|
|
330
|
+
if ((this.flags & MANY) === 0) {
|
|
331
|
+
if (own !== undefined)
|
|
332
|
+
collectBits(own, this.mask);
|
|
333
|
+
} else
|
|
334
|
+
for (const dep of own.values())
|
|
335
|
+
collectBits(dep.model, dep.mask);
|
|
336
|
+
}
|
|
337
|
+
return this.data;
|
|
301
338
|
}
|
|
302
339
|
#reset() {
|
|
303
340
|
this.mask = 0;
|
|
@@ -330,7 +367,7 @@ class Binding {
|
|
|
330
367
|
}
|
|
331
368
|
}
|
|
332
369
|
#loose() {
|
|
333
|
-
if ((this.flags & (LOOSE | DEAD)) !== 0 || holder === undefined)
|
|
370
|
+
if ((this.flags & (LOOSE | DEAD | PAUSE)) !== 0 || (this.flags & KIND) >= EFFECT || holder === undefined)
|
|
334
371
|
return;
|
|
335
372
|
this.flags |= LOOSE;
|
|
336
373
|
holder.ctx.loose.push(this);
|
|
@@ -351,8 +388,13 @@ class Binding {
|
|
|
351
388
|
}
|
|
352
389
|
stateHasChanged() {
|
|
353
390
|
const flags = this.flags;
|
|
354
|
-
if ((flags & DEAD) !== 0)
|
|
391
|
+
if ((flags & (DEAD | PAUSED)) !== 0) {
|
|
392
|
+
if ((flags & DEAD) === 0)
|
|
393
|
+
this.flags |= STALE;
|
|
355
394
|
return;
|
|
395
|
+
}
|
|
396
|
+
if ((flags & SHOW) !== 0)
|
|
397
|
+
return this.#show();
|
|
356
398
|
switch (flags & KIND) {
|
|
357
399
|
case TEXT: {
|
|
358
400
|
const value = this.#run();
|
|
@@ -365,26 +407,76 @@ class Binding {
|
|
|
365
407
|
return;
|
|
366
408
|
}
|
|
367
409
|
case ATTR:
|
|
410
|
+
if ((flags & OWNED) !== 0)
|
|
411
|
+
return ownAttr(this.node, this.data, this.#run());
|
|
368
412
|
return setAttr(this.node, (flags & ITEM) !== 0 ? this.read.$n : this.data, this.#run());
|
|
369
413
|
case REGION: {
|
|
370
414
|
const region = this.data;
|
|
415
|
+
const branch = region.branch;
|
|
416
|
+
if (branch !== undefined) {
|
|
417
|
+
const index = this.#run();
|
|
418
|
+
if (index === region.index)
|
|
419
|
+
return;
|
|
420
|
+
region.index = index;
|
|
421
|
+
}
|
|
371
422
|
disposeAll(region);
|
|
372
423
|
const end = this.node;
|
|
373
424
|
const parent = end.parentNode;
|
|
374
|
-
|
|
375
|
-
|
|
425
|
+
for (let node = region.start.nextSibling;node !== end; ) {
|
|
426
|
+
const next = node.nextSibling;
|
|
427
|
+
$leave(node);
|
|
428
|
+
node = next;
|
|
429
|
+
}
|
|
376
430
|
const frag = document.createDocumentFragment();
|
|
377
|
-
within(region, () => this.#run(frag));
|
|
431
|
+
within(region, () => branch !== undefined ? untracked(() => branch(frag)) : this.#run(frag));
|
|
378
432
|
parent.insertBefore(frag, end);
|
|
379
433
|
return;
|
|
380
434
|
}
|
|
381
435
|
case LIST:
|
|
382
436
|
return reconcile(this, this.#run());
|
|
437
|
+
case KEYED: {
|
|
438
|
+
const keyed = this.data;
|
|
439
|
+
keyed.order = this.#run();
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
383
442
|
case ISLAND:
|
|
443
|
+
case EFFECT:
|
|
384
444
|
this.#run();
|
|
385
445
|
return;
|
|
446
|
+
case MEMO:
|
|
447
|
+
return;
|
|
386
448
|
}
|
|
387
449
|
}
|
|
450
|
+
#show() {
|
|
451
|
+
const show = this.data;
|
|
452
|
+
const index = this.#run();
|
|
453
|
+
if (index === show.index)
|
|
454
|
+
return;
|
|
455
|
+
const shown = show.branches[show.index];
|
|
456
|
+
if (shown !== undefined)
|
|
457
|
+
hideBranch(shown);
|
|
458
|
+
show.index = index;
|
|
459
|
+
let branch = show.branches[index];
|
|
460
|
+
if (branch !== undefined)
|
|
461
|
+
return showBranch(branch);
|
|
462
|
+
branch = { bindings: undefined, ctx: show.ctx, start: show.start, item: undefined, branch: undefined, index: -1, first: null, els: [], display: [] };
|
|
463
|
+
show.branches[index] = branch;
|
|
464
|
+
const frag = document.createDocumentFragment();
|
|
465
|
+
within(branch, () => untracked(() => show.build(frag)));
|
|
466
|
+
branch.first = frag.firstChild;
|
|
467
|
+
for (let node = frag.firstChild;node !== null; node = node.nextSibling)
|
|
468
|
+
if (node.nodeType === 1)
|
|
469
|
+
branch.els.push(node);
|
|
470
|
+
let before = this.node;
|
|
471
|
+
for (let i = index + 1;i < show.branches.length; i++) {
|
|
472
|
+
const next = show.branches[i]?.first;
|
|
473
|
+
if (next) {
|
|
474
|
+
before = next;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
before.parentNode.insertBefore(frag, before);
|
|
479
|
+
}
|
|
388
480
|
#becomeIsland() {
|
|
389
481
|
const read = this.read;
|
|
390
482
|
const h = this.data;
|
|
@@ -407,15 +499,19 @@ class Binding {
|
|
|
407
499
|
if ((this.flags & DEAD) !== 0)
|
|
408
500
|
return;
|
|
409
501
|
const kind = this.flags & KIND;
|
|
410
|
-
if (
|
|
502
|
+
if ((this.flags & SHOW) !== 0)
|
|
503
|
+
for (const branch of this.data.branches)
|
|
504
|
+
branch !== undefined && disposeAll(branch);
|
|
505
|
+
else if (kind === REGION)
|
|
411
506
|
disposeAll(this.data);
|
|
412
|
-
else if (kind === LIST)
|
|
507
|
+
else if (kind === LIST || kind === KEYED)
|
|
413
508
|
for (const row of this.data.order)
|
|
414
509
|
disposeAll(row);
|
|
415
510
|
else if (kind === ISLAND) {
|
|
416
511
|
disposeIsland(this.data.tree);
|
|
417
512
|
this.data.tree = [];
|
|
418
|
-
}
|
|
513
|
+
} else if ((this.flags & OWNED) !== 0)
|
|
514
|
+
undoAttr(this.node, this.data);
|
|
419
515
|
this.#reset();
|
|
420
516
|
this.#sweep();
|
|
421
517
|
this.flags = DEAD;
|
|
@@ -448,6 +544,18 @@ function afterHandler(ctx, result) {
|
|
|
448
544
|
if (result instanceof Promise)
|
|
449
545
|
result.then(() => refreshLoose(ctx));
|
|
450
546
|
}
|
|
547
|
+
function untracked(run) {
|
|
548
|
+
const prev = collecting;
|
|
549
|
+
const reader = Model.$reader;
|
|
550
|
+
collecting = undefined;
|
|
551
|
+
Model.$reader = undefined;
|
|
552
|
+
try {
|
|
553
|
+
return run();
|
|
554
|
+
} finally {
|
|
555
|
+
collecting = prev;
|
|
556
|
+
Model.$reader = reader;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
451
559
|
function within(h, run) {
|
|
452
560
|
const prev = holder;
|
|
453
561
|
holder = h;
|
|
@@ -470,14 +578,72 @@ function disposeAll(h) {
|
|
|
470
578
|
}
|
|
471
579
|
function refreshAll(h) {
|
|
472
580
|
for (let b = h.bindings;b !== undefined; b = b.next) {
|
|
581
|
+
const kind = b.flags & KIND;
|
|
582
|
+
const kept = kind === REGION ? b.data.index : -1;
|
|
473
583
|
b.stateHasChanged();
|
|
474
|
-
if ((b.flags &
|
|
584
|
+
if ((b.flags & SHOW) !== 0)
|
|
585
|
+
for (const branch of b.data.branches)
|
|
586
|
+
branch !== undefined && refreshAll(branch);
|
|
587
|
+
else if (kind === LIST || kind === KEYED)
|
|
475
588
|
for (const row of b.data.order)
|
|
476
589
|
refreshAll(row);
|
|
590
|
+
else if (kept !== -1 && kept === b.data.index)
|
|
591
|
+
refreshAll(b.data);
|
|
477
592
|
}
|
|
478
593
|
}
|
|
594
|
+
function under(b, f) {
|
|
595
|
+
const kind = b.flags & KIND;
|
|
596
|
+
if ((b.flags & SHOW) !== 0)
|
|
597
|
+
for (const branch of b.data.branches)
|
|
598
|
+
branch !== undefined && f(branch);
|
|
599
|
+
else if (kind === REGION)
|
|
600
|
+
f(b.data);
|
|
601
|
+
else if (kind === LIST || kind === KEYED)
|
|
602
|
+
for (const row of b.data.order)
|
|
603
|
+
f(row);
|
|
604
|
+
}
|
|
605
|
+
function pauseIn(h) {
|
|
606
|
+
for (let b = h.bindings;b !== undefined; b = b.next) {
|
|
607
|
+
if ((b.flags & PAUSE) !== 0)
|
|
608
|
+
under(b, freeze);
|
|
609
|
+
else
|
|
610
|
+
under(b, pauseIn);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function freeze(h) {
|
|
614
|
+
for (let b = h.bindings;b !== undefined; b = b.next) {
|
|
615
|
+
b.flags |= PAUSED;
|
|
616
|
+
under(b, freeze);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function thaw(h) {
|
|
620
|
+
for (let b = h.bindings;b !== undefined; b = b.next) {
|
|
621
|
+
const stale = (b.flags & STALE) !== 0;
|
|
622
|
+
b.flags &= ~(PAUSED | STALE);
|
|
623
|
+
if (stale)
|
|
624
|
+
b.stateHasChanged();
|
|
625
|
+
under(b, thaw);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function hideBranch(branch) {
|
|
629
|
+
for (let i = 0;i < branch.els.length; i++) {
|
|
630
|
+
const style = branch.els[i].style;
|
|
631
|
+
branch.display[i] = style.display;
|
|
632
|
+
style.display = "none";
|
|
633
|
+
}
|
|
634
|
+
pauseIn(branch);
|
|
635
|
+
}
|
|
636
|
+
function showBranch(branch) {
|
|
637
|
+
for (let i = 0;i < branch.els.length; i++)
|
|
638
|
+
branch.els[i].style.display = branch.display[i] ?? "";
|
|
639
|
+
thaw(branch);
|
|
640
|
+
}
|
|
479
641
|
var textOf = (value) => value === null || value === undefined || value === false ? "" : String(value);
|
|
480
642
|
function setAttr(el, name, value) {
|
|
643
|
+
if (typeof value === "boolean" && name.startsWith("aria-"))
|
|
644
|
+
value = String(value);
|
|
645
|
+
if (name.startsWith("class:"))
|
|
646
|
+
return void el.classList.toggle(name.slice(6), !!value);
|
|
481
647
|
if (name.charCodeAt(0) === 45 && name.charCodeAt(1) === 45) {
|
|
482
648
|
const style = el.style;
|
|
483
649
|
const text2 = value === null || value === undefined || value === false ? "" : String(value);
|
|
@@ -504,48 +670,68 @@ function setAttr(el, name, value) {
|
|
|
504
670
|
else if (name === "checked" && "checked" in el)
|
|
505
671
|
el.checked = true;
|
|
506
672
|
}
|
|
673
|
+
function ownAttr(el, s, value) {
|
|
674
|
+
if (s.name !== "class") {
|
|
675
|
+
if (s.prev === undefined)
|
|
676
|
+
s.prev = el.getAttribute(s.name);
|
|
677
|
+
return setAttr(el, s.name, value);
|
|
678
|
+
}
|
|
679
|
+
const text = value === null || value === undefined || value === false || value === true ? "" : String(value);
|
|
680
|
+
if (text === s.text)
|
|
681
|
+
return;
|
|
682
|
+
s.text = text;
|
|
683
|
+
for (const t of s.added)
|
|
684
|
+
el.classList.remove(t);
|
|
685
|
+
s.added = [];
|
|
686
|
+
for (const t of text.split(/\s+/))
|
|
687
|
+
if (t !== "" && !el.classList.contains(t)) {
|
|
688
|
+
el.classList.add(t);
|
|
689
|
+
s.added.push(t);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
function undoAttr(el, s) {
|
|
693
|
+
if (s.name === "class")
|
|
694
|
+
for (const t of s.added)
|
|
695
|
+
el.classList.remove(t);
|
|
696
|
+
else if (s.prev !== undefined)
|
|
697
|
+
setAttr(el, s.name, s.prev);
|
|
698
|
+
}
|
|
507
699
|
function removeRange(head, tail) {
|
|
508
|
-
const parent = head.parentNode;
|
|
509
700
|
for (let node = head;; ) {
|
|
510
701
|
const next = node.nextSibling;
|
|
511
|
-
|
|
702
|
+
$leave(node);
|
|
512
703
|
if (node === tail)
|
|
513
704
|
return;
|
|
514
705
|
node = next;
|
|
515
706
|
}
|
|
516
707
|
}
|
|
517
|
-
function
|
|
518
|
-
const
|
|
519
|
-
const
|
|
708
|
+
function newRow(ctx, item, reads, build) {
|
|
709
|
+
const frag = document.createDocumentFragment();
|
|
710
|
+
const row = { bindings: undefined, ctx, head: frag, tail: frag, item, reads };
|
|
711
|
+
within(row, () => build(frag, item));
|
|
712
|
+
seal(row, frag);
|
|
713
|
+
return row;
|
|
714
|
+
}
|
|
715
|
+
function seal(row, frag) {
|
|
716
|
+
if (frag.firstChild === null)
|
|
717
|
+
frag.appendChild(document.createComment(""));
|
|
718
|
+
row.head = frag.firstChild;
|
|
719
|
+
row.tail = frag.lastChild;
|
|
720
|
+
}
|
|
721
|
+
function dropRow(row) {
|
|
722
|
+
disposeAll(row);
|
|
723
|
+
removeRange(row.head, row.tail);
|
|
724
|
+
}
|
|
725
|
+
function place(end, old, order) {
|
|
520
726
|
const parent = end.parentNode;
|
|
521
|
-
const next = Array.isArray(items) ? items : [...items];
|
|
522
|
-
const keep = new Set(next);
|
|
523
|
-
for (const [item, row] of state.rows)
|
|
524
|
-
if (!keep.has(item)) {
|
|
525
|
-
disposeAll(row);
|
|
526
|
-
removeRange(row.head, row.tail);
|
|
527
|
-
state.rows.delete(item);
|
|
528
|
-
}
|
|
529
727
|
let cursor = end;
|
|
530
|
-
for (const row of
|
|
728
|
+
for (const row of old)
|
|
531
729
|
if (row.head.parentNode === parent) {
|
|
532
730
|
cursor = row.head;
|
|
533
731
|
break;
|
|
534
732
|
}
|
|
535
|
-
const order
|
|
536
|
-
|
|
537
|
-
let row = state.rows.get(item);
|
|
538
|
-
if (row === undefined) {
|
|
539
|
-
const frag = document.createDocumentFragment();
|
|
540
|
-
const made = { bindings: undefined, ctx: state.ctx, head: frag, tail: frag, item, reads: state.reads };
|
|
541
|
-
within(made, () => state.build(frag, item));
|
|
542
|
-
if (frag.firstChild === null)
|
|
543
|
-
frag.appendChild(document.createComment(""));
|
|
544
|
-
made.head = frag.firstChild;
|
|
545
|
-
made.tail = frag.lastChild;
|
|
546
|
-
parent.insertBefore(frag, cursor);
|
|
547
|
-
state.rows.set(item, row = made);
|
|
548
|
-
} else if (row.head !== cursor) {
|
|
733
|
+
for (const row of order) {
|
|
734
|
+
if (row.head !== cursor) {
|
|
549
735
|
for (let node = row.head;; ) {
|
|
550
736
|
const after = node.nextSibling;
|
|
551
737
|
parent.insertBefore(node, cursor);
|
|
@@ -555,10 +741,114 @@ function reconcile(list, items) {
|
|
|
555
741
|
}
|
|
556
742
|
} else
|
|
557
743
|
cursor = row.tail.nextSibling;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
var duplicate = (key) => new Error(`xzor: duplicate @key ${String(key)}`);
|
|
747
|
+
function reconcile(list, items) {
|
|
748
|
+
const state = list.data;
|
|
749
|
+
const rows = state.rows;
|
|
750
|
+
let next = Array.isArray(items) ? items : [...items];
|
|
751
|
+
if (next.length === 0 && state.empty !== undefined)
|
|
752
|
+
next = [EMPTY];
|
|
753
|
+
const named = state.key === undefined ? $keyName(next[0]) : undefined;
|
|
754
|
+
const keyOf = state.key ?? (named === undefined ? undefined : (item) => item[named]);
|
|
755
|
+
let keys = next;
|
|
756
|
+
if (keyOf === undefined) {
|
|
757
|
+
const keep = new Set(next);
|
|
758
|
+
for (const [item, row] of rows)
|
|
759
|
+
if (!keep.has(item)) {
|
|
760
|
+
dropRow(row);
|
|
761
|
+
rows.delete(item);
|
|
762
|
+
}
|
|
763
|
+
} else {
|
|
764
|
+
const at = new Map;
|
|
765
|
+
keys = next.map((item) => item === EMPTY ? EMPTY : keyOf(item));
|
|
766
|
+
for (let i = 0;i < next.length; i++) {
|
|
767
|
+
if (at.has(keys[i]))
|
|
768
|
+
throw duplicate(keys[i]);
|
|
769
|
+
at.set(keys[i], next[i]);
|
|
770
|
+
}
|
|
771
|
+
for (const [key, row] of rows)
|
|
772
|
+
if (!at.has(key) || at.get(key) !== row.item) {
|
|
773
|
+
dropRow(row);
|
|
774
|
+
rows.delete(key);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
const order = [];
|
|
778
|
+
for (let i = 0;i < next.length; i++) {
|
|
779
|
+
const item = next[i];
|
|
780
|
+
let row = rows.get(keys[i]);
|
|
781
|
+
if (row === undefined) {
|
|
782
|
+
row = item === EMPTY ? newRow(state.ctx, item, undefined, state.empty) : newRow(state.ctx, item, state.reads, state.build);
|
|
783
|
+
rows.set(keys[i], row);
|
|
784
|
+
}
|
|
558
785
|
order.push(row);
|
|
559
786
|
}
|
|
787
|
+
place(list.node, state.order, order);
|
|
560
788
|
state.order = order;
|
|
561
789
|
}
|
|
790
|
+
function sameValues(a, b) {
|
|
791
|
+
if (a.length !== b.length)
|
|
792
|
+
return false;
|
|
793
|
+
for (let i = 0;i < a.length; i++)
|
|
794
|
+
if (!Object.is(a[i], b[i]))
|
|
795
|
+
return false;
|
|
796
|
+
return true;
|
|
797
|
+
}
|
|
798
|
+
function runKeyed(s, end, run) {
|
|
799
|
+
const order = [];
|
|
800
|
+
const seen = new Set;
|
|
801
|
+
const outer = holder;
|
|
802
|
+
let building;
|
|
803
|
+
const finish = () => {
|
|
804
|
+
if (building === undefined)
|
|
805
|
+
return;
|
|
806
|
+
seal(building, building.head);
|
|
807
|
+
building = undefined;
|
|
808
|
+
holder = outer;
|
|
809
|
+
};
|
|
810
|
+
try {
|
|
811
|
+
run((key, values) => {
|
|
812
|
+
finish();
|
|
813
|
+
if (seen.has(key))
|
|
814
|
+
throw duplicate(key);
|
|
815
|
+
seen.add(key);
|
|
816
|
+
let row = s.rows.get(key);
|
|
817
|
+
if (row !== undefined && !sameValues(row.item, values)) {
|
|
818
|
+
dropRow(row);
|
|
819
|
+
row = undefined;
|
|
820
|
+
}
|
|
821
|
+
if (row !== undefined) {
|
|
822
|
+
order.push(row);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const frag = document.createDocumentFragment();
|
|
826
|
+
row = { bindings: undefined, ctx: s.ctx, head: frag, tail: frag, item: values, reads: undefined };
|
|
827
|
+
s.rows.set(key, row);
|
|
828
|
+
order.push(row);
|
|
829
|
+
building = row;
|
|
830
|
+
holder = row;
|
|
831
|
+
return frag;
|
|
832
|
+
});
|
|
833
|
+
finish();
|
|
834
|
+
} finally {
|
|
835
|
+
holder = outer;
|
|
836
|
+
}
|
|
837
|
+
if (order.length === 0 && s.empty !== undefined) {
|
|
838
|
+
let row = s.rows.get(EMPTY);
|
|
839
|
+
if (row === undefined)
|
|
840
|
+
s.rows.set(EMPTY, row = newRow(s.ctx, EMPTY, undefined, s.empty));
|
|
841
|
+
order.push(row);
|
|
842
|
+
seen.add(EMPTY);
|
|
843
|
+
}
|
|
844
|
+
for (const [key, row] of s.rows)
|
|
845
|
+
if (!seen.has(key)) {
|
|
846
|
+
dropRow(row);
|
|
847
|
+
s.rows.delete(key);
|
|
848
|
+
}
|
|
849
|
+
place(end, s.order, order);
|
|
850
|
+
return order;
|
|
851
|
+
}
|
|
562
852
|
function make(spec, svg = false) {
|
|
563
853
|
if (spec === null)
|
|
564
854
|
return document.createComment("");
|
|
@@ -612,15 +902,50 @@ function on(el, event, handler, h) {
|
|
|
612
902
|
} else
|
|
613
903
|
el.addEventListener(event, (e) => afterHandler(h.ctx, handler(e)));
|
|
614
904
|
}
|
|
615
|
-
function region(start, end, build, item, flags) {
|
|
616
|
-
const region2 = { bindings: undefined, ctx: holder.ctx, start, item };
|
|
905
|
+
function region(start, end, build, item, flags, branch) {
|
|
906
|
+
const region2 = { bindings: undefined, ctx: holder.ctx, start, item, branch, index: -1 };
|
|
617
907
|
track(new Binding(REGION | flags, end, build, region2));
|
|
618
908
|
}
|
|
619
|
-
function list(end, items, reads, build) {
|
|
620
|
-
const state = { build, ctx: holder.ctx, rows: new Map, order: [], reads };
|
|
909
|
+
function list(end, items, reads, build, empty, key) {
|
|
910
|
+
const state = { build, ctx: holder.ctx, rows: new Map, order: [], reads, empty, key };
|
|
621
911
|
track(new Binding(LIST, end, items, state));
|
|
622
912
|
}
|
|
623
913
|
var anchor = (parent) => parent.appendChild(document.createComment(""));
|
|
914
|
+
function awaiting(end, pending, then, fail) {
|
|
915
|
+
const state = { phase: 0, value: undefined, seq: 0 };
|
|
916
|
+
const view = new Binding(REGION, end, (p) => {
|
|
917
|
+
if (state.phase === 0)
|
|
918
|
+
pending?.(p);
|
|
919
|
+
else if (state.phase === 1)
|
|
920
|
+
then?.(p, state.value);
|
|
921
|
+
else
|
|
922
|
+
fail?.(p, state.value);
|
|
923
|
+
}, { bindings: undefined, ctx: holder.ctx, start: end.previousSibling, item: undefined, branch: undefined, index: -1 });
|
|
924
|
+
const show = (phase, value) => {
|
|
925
|
+
if ((view.flags & DEAD) !== 0)
|
|
926
|
+
return;
|
|
927
|
+
state.phase = phase;
|
|
928
|
+
state.value = value;
|
|
929
|
+
view.stateHasChanged();
|
|
930
|
+
};
|
|
931
|
+
track(view);
|
|
932
|
+
return (result) => {
|
|
933
|
+
const seq = ++state.seq;
|
|
934
|
+
if (typeof result?.then !== "function")
|
|
935
|
+
return show(1, result);
|
|
936
|
+
if (state.phase !== 0)
|
|
937
|
+
show(0, undefined);
|
|
938
|
+
result.then((value) => seq === state.seq && show(1, value), (error) => {
|
|
939
|
+
if (seq !== state.seq)
|
|
940
|
+
return;
|
|
941
|
+
show(2, error);
|
|
942
|
+
if (fail === undefined)
|
|
943
|
+
queueMicrotask(() => {
|
|
944
|
+
throw error;
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
};
|
|
948
|
+
}
|
|
624
949
|
var fine = {
|
|
625
950
|
template(specs) {
|
|
626
951
|
let node;
|
|
@@ -682,12 +1007,93 @@ var fine = {
|
|
|
682
1007
|
read.$n = name;
|
|
683
1008
|
track(new Binding(ATTR | ITEM, el, read, row));
|
|
684
1009
|
},
|
|
1010
|
+
attrOf(el, name, read) {
|
|
1011
|
+
track(new Binding(ATTR | OWNED, el, read, { name, text: undefined, prev: undefined, added: [] }));
|
|
1012
|
+
},
|
|
685
1013
|
region(parent, build) {
|
|
686
1014
|
region(anchor(parent), anchor(parent), build, undefined, 0);
|
|
687
1015
|
},
|
|
688
1016
|
regionAt(end, build) {
|
|
689
1017
|
region(end.previousSibling, end, build, undefined, 0);
|
|
690
1018
|
},
|
|
1019
|
+
branchAt(end, run) {
|
|
1020
|
+
region(end.previousSibling, end, run, undefined, 0, run);
|
|
1021
|
+
},
|
|
1022
|
+
showAt(end, run) {
|
|
1023
|
+
const show = { ctx: holder.ctx, start: end.previousSibling, index: -1, build: run, branches: [] };
|
|
1024
|
+
track(new Binding(REGION | SHOW, end, run, show));
|
|
1025
|
+
},
|
|
1026
|
+
pauseAt(end, build) {
|
|
1027
|
+
region(end.previousSibling, end, () => 0, undefined, PAUSE, build);
|
|
1028
|
+
},
|
|
1029
|
+
textOnce(node, read) {
|
|
1030
|
+
node.data = textOf(untracked(read));
|
|
1031
|
+
},
|
|
1032
|
+
onceAt(end, build) {
|
|
1033
|
+
const frag = document.createDocumentFragment();
|
|
1034
|
+
untracked(() => build(frag));
|
|
1035
|
+
end.parentNode.insertBefore(frag, end);
|
|
1036
|
+
},
|
|
1037
|
+
set(el, name, value) {
|
|
1038
|
+
setAttr(el, name, value);
|
|
1039
|
+
},
|
|
1040
|
+
setText(node, value) {
|
|
1041
|
+
node.data = textOf(value);
|
|
1042
|
+
},
|
|
1043
|
+
anchor,
|
|
1044
|
+
memo(cls, names) {
|
|
1045
|
+
const proto = cls.prototype;
|
|
1046
|
+
names.forEach((name, i) => {
|
|
1047
|
+
const desc = Object.getOwnPropertyDescriptor(proto, name);
|
|
1048
|
+
const get = desc?.get;
|
|
1049
|
+
if (get === undefined)
|
|
1050
|
+
return;
|
|
1051
|
+
const reader = Symbol(name);
|
|
1052
|
+
Object.defineProperty(proto, name, {
|
|
1053
|
+
...desc,
|
|
1054
|
+
get() {
|
|
1055
|
+
const memo = this[MEMOS]?.[i];
|
|
1056
|
+
if (memo !== undefined)
|
|
1057
|
+
return memo.$memo();
|
|
1058
|
+
const by = collecting;
|
|
1059
|
+
if (by === undefined)
|
|
1060
|
+
return get.call(this);
|
|
1061
|
+
const first = this[reader];
|
|
1062
|
+
if (first === undefined || first === by || (first.flags & DEAD) !== 0) {
|
|
1063
|
+
this[reader] = by;
|
|
1064
|
+
return get.call(this);
|
|
1065
|
+
}
|
|
1066
|
+
this[reader] = undefined;
|
|
1067
|
+
const b = new Binding(MEMO | QUEUED, null, () => get.call(this), undefined);
|
|
1068
|
+
(this[MEMOS] ??= [])[i] = b;
|
|
1069
|
+
return b.$memo();
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
});
|
|
1073
|
+
},
|
|
1074
|
+
awaitAt(end, read, pending, then, fail) {
|
|
1075
|
+
const show = awaiting(end, pending, then, fail);
|
|
1076
|
+
track(new Binding(EFFECT, end, () => show(read()), undefined));
|
|
1077
|
+
},
|
|
1078
|
+
awaitCallAt(end, args, call, pending, then, fail) {
|
|
1079
|
+
const show = awaiting(end, pending, then, fail);
|
|
1080
|
+
let last;
|
|
1081
|
+
const request = new Binding(EFFECT, end, () => show(call(...last)), undefined);
|
|
1082
|
+
track(new Binding(EFFECT, end, () => {
|
|
1083
|
+
const next = args();
|
|
1084
|
+
if (last !== undefined && next.every((v, i) => Object.is(v, last[i])))
|
|
1085
|
+
return;
|
|
1086
|
+
const first = last === undefined;
|
|
1087
|
+
last = next;
|
|
1088
|
+
if (!first)
|
|
1089
|
+
request.stateHasChanged();
|
|
1090
|
+
}, undefined));
|
|
1091
|
+
track(request);
|
|
1092
|
+
},
|
|
1093
|
+
anchors(parent) {
|
|
1094
|
+
anchor(parent);
|
|
1095
|
+
return anchor(parent);
|
|
1096
|
+
},
|
|
691
1097
|
regionItem(end, i) {
|
|
692
1098
|
const row = holder;
|
|
693
1099
|
region(end.previousSibling, end, row.reads[i], row.item, ITEM);
|
|
@@ -695,8 +1101,12 @@ var fine = {
|
|
|
695
1101
|
list(parent, items, build) {
|
|
696
1102
|
list(anchor(parent), items, undefined, build);
|
|
697
1103
|
},
|
|
698
|
-
listAt(end, items, reads, build) {
|
|
699
|
-
list(end, items, reads, build);
|
|
1104
|
+
listAt(end, items, reads, build, empty, key) {
|
|
1105
|
+
list(end, items, reads, build, empty, key);
|
|
1106
|
+
},
|
|
1107
|
+
keyedAt(end, run, empty) {
|
|
1108
|
+
const state = { ctx: holder.ctx, rows: new Map, order: [], empty };
|
|
1109
|
+
track(new Binding(KEYED, end, () => runKeyed(state, end, run), state));
|
|
700
1110
|
},
|
|
701
1111
|
island(parent, build) {
|
|
702
1112
|
fine.islandAt(anchor(parent), build);
|
|
@@ -765,8 +1175,22 @@ setFineHooks({
|
|
|
765
1175
|
root.end = frag.appendChild(document.createComment(""));
|
|
766
1176
|
return root;
|
|
767
1177
|
},
|
|
768
|
-
refresh
|
|
769
|
-
|
|
1178
|
+
refresh(root) {
|
|
1179
|
+
const memos = root.ctx.owner[MEMOS];
|
|
1180
|
+
if (memos !== undefined) {
|
|
1181
|
+
for (const m of memos)
|
|
1182
|
+
if (m !== undefined)
|
|
1183
|
+
m.flags &= ~FRESH;
|
|
1184
|
+
}
|
|
1185
|
+
refreshAll(root);
|
|
1186
|
+
},
|
|
1187
|
+
dispose(root) {
|
|
1188
|
+
const memos = root.ctx.owner[MEMOS];
|
|
1189
|
+
if (memos !== undefined)
|
|
1190
|
+
for (const m of memos)
|
|
1191
|
+
m?.dispose();
|
|
1192
|
+
disposeAll(root);
|
|
1193
|
+
},
|
|
770
1194
|
handled(owner, result) {
|
|
771
1195
|
const ctx = owner[CTX];
|
|
772
1196
|
if (ctx !== undefined)
|
|
@@ -804,6 +1228,7 @@ var meta = Symbol("xzor.model.meta");
|
|
|
804
1228
|
var empty = { names: [], tracked: new Set, persisted: [], ignored: new Set, validators: [], serialized: [] };
|
|
805
1229
|
var pendingPersist;
|
|
806
1230
|
var pendingIgnored;
|
|
1231
|
+
var pendingKey;
|
|
807
1232
|
var pendingValidators;
|
|
808
1233
|
var silent = 0;
|
|
809
1234
|
function metaOf(model) {
|
|
@@ -835,8 +1260,10 @@ class Model extends EventTarget {
|
|
|
835
1260
|
tracked: new Set(all),
|
|
836
1261
|
persisted: base ? base.persisted.slice() : [],
|
|
837
1262
|
ignored: new Set(base?.ignored),
|
|
838
|
-
validators: base ? base.validators.map(([name, list2]) => [name, list2.slice()]) : []
|
|
1263
|
+
validators: base ? base.validators.map(([name, list2]) => [name, list2.slice()]) : [],
|
|
1264
|
+
key: pendingKey ?? base?.key
|
|
839
1265
|
};
|
|
1266
|
+
pendingKey = undefined;
|
|
840
1267
|
if (pendingValidators) {
|
|
841
1268
|
for (const [name, list2] of pendingValidators) {
|
|
842
1269
|
const known = own.validators.find((entry) => entry[0] === name);
|
|
@@ -1230,6 +1657,12 @@ function Ignore(_member, context) {
|
|
|
1230
1657
|
(pendingIgnored ??= []).push(context.name);
|
|
1231
1658
|
}
|
|
1232
1659
|
function Untracked(_value, _context) {}
|
|
1660
|
+
function Key(_member, context) {
|
|
1661
|
+
pendingKey = context.name;
|
|
1662
|
+
}
|
|
1663
|
+
function $keyName(item) {
|
|
1664
|
+
return item instanceof Model ? metaOf(item).key : undefined;
|
|
1665
|
+
}
|
|
1233
1666
|
function isLike(a, b) {
|
|
1234
1667
|
return Model.same(a, b);
|
|
1235
1668
|
}
|
|
@@ -1440,10 +1873,12 @@ setRenderObserver({
|
|
|
1440
1873
|
});
|
|
1441
1874
|
export {
|
|
1442
1875
|
$flush,
|
|
1876
|
+
$keyName,
|
|
1443
1877
|
$notify,
|
|
1444
1878
|
EntitySet,
|
|
1445
1879
|
FineComponent,
|
|
1446
1880
|
Ignore,
|
|
1881
|
+
Key,
|
|
1447
1882
|
Model,
|
|
1448
1883
|
ModelChangeEvent,
|
|
1449
1884
|
Persist,
|
|
@@ -1465,5 +1900,5 @@ export {
|
|
|
1465
1900
|
requiredIdValue
|
|
1466
1901
|
};
|
|
1467
1902
|
|
|
1468
|
-
//# debugId=
|
|
1903
|
+
//# debugId=E7409C03C0112EDB64756E2164756E21
|
|
1469
1904
|
//# sourceMappingURL=model.js.map
|