@source-crafter/xzor-runtime 0.1.15 → 0.1.16
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 +32 -2
- package/{index-k290gfdd.js → index-w2yxrgd1.js} +119 -13
- package/index-w2yxrgd1.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 +351 -46
- 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-w2yxrgd1.js";
|
|
12
13
|
|
|
13
14
|
// runtime/entity-set.ts
|
|
14
15
|
class EntitySet extends Array {
|
|
@@ -226,18 +227,27 @@ 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;
|
|
235
241
|
var bitOf = (index) => index === -1 ? 1 << 31 : index < 30 ? 1 << index : 1 << 30;
|
|
242
|
+
var MEMOS = Symbol("xzor.fine.memos");
|
|
243
|
+
var EMPTY = Symbol("xzor.fine.empty");
|
|
236
244
|
var collecting;
|
|
237
245
|
var holder;
|
|
238
246
|
function collect(source, index) {
|
|
247
|
+
collectBits(source, bitOf(index));
|
|
248
|
+
}
|
|
249
|
+
function collectBits(source, bit) {
|
|
239
250
|
const b = collecting;
|
|
240
|
-
const bit = bitOf(index);
|
|
241
251
|
const own = b.model;
|
|
242
252
|
if (own === source) {
|
|
243
253
|
b.mask |= bit;
|
|
@@ -296,8 +306,31 @@ class Binding {
|
|
|
296
306
|
return (this.flags & (QUEUED | DEAD)) !== 0 ? 0 : -1;
|
|
297
307
|
}
|
|
298
308
|
set at(value) {
|
|
299
|
-
if ((this.flags & DEAD)
|
|
300
|
-
|
|
309
|
+
if ((this.flags & DEAD) !== 0)
|
|
310
|
+
return;
|
|
311
|
+
if ((this.flags & KIND) === MEMO) {
|
|
312
|
+
if (value >= 0)
|
|
313
|
+
this.flags &= ~FRESH;
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
this.flags = value < 0 ? this.flags & ~QUEUED : this.flags | QUEUED;
|
|
317
|
+
}
|
|
318
|
+
$memo() {
|
|
319
|
+
if ((this.flags & FRESH) === 0) {
|
|
320
|
+
this.data = this.#run();
|
|
321
|
+
if (this.model !== undefined && (this.flags & DEAD) === 0)
|
|
322
|
+
this.flags |= FRESH;
|
|
323
|
+
}
|
|
324
|
+
if (collecting !== undefined) {
|
|
325
|
+
const own = this.model;
|
|
326
|
+
if ((this.flags & MANY) === 0) {
|
|
327
|
+
if (own !== undefined)
|
|
328
|
+
collectBits(own, this.mask);
|
|
329
|
+
} else
|
|
330
|
+
for (const dep of own.values())
|
|
331
|
+
collectBits(dep.model, dep.mask);
|
|
332
|
+
}
|
|
333
|
+
return this.data;
|
|
301
334
|
}
|
|
302
335
|
#reset() {
|
|
303
336
|
this.mask = 0;
|
|
@@ -330,7 +363,7 @@ class Binding {
|
|
|
330
363
|
}
|
|
331
364
|
}
|
|
332
365
|
#loose() {
|
|
333
|
-
if ((this.flags & (LOOSE | DEAD)) !== 0 || holder === undefined)
|
|
366
|
+
if ((this.flags & (LOOSE | DEAD)) !== 0 || (this.flags & KIND) >= EFFECT || holder === undefined)
|
|
334
367
|
return;
|
|
335
368
|
this.flags |= LOOSE;
|
|
336
369
|
holder.ctx.loose.push(this);
|
|
@@ -365,14 +398,19 @@ class Binding {
|
|
|
365
398
|
return;
|
|
366
399
|
}
|
|
367
400
|
case ATTR:
|
|
401
|
+
if ((flags & OWNED) !== 0)
|
|
402
|
+
return ownAttr(this.node, this.data, this.#run());
|
|
368
403
|
return setAttr(this.node, (flags & ITEM) !== 0 ? this.read.$n : this.data, this.#run());
|
|
369
404
|
case REGION: {
|
|
370
405
|
const region = this.data;
|
|
371
406
|
disposeAll(region);
|
|
372
407
|
const end = this.node;
|
|
373
408
|
const parent = end.parentNode;
|
|
374
|
-
|
|
375
|
-
|
|
409
|
+
for (let node = region.start.nextSibling;node !== end; ) {
|
|
410
|
+
const next = node.nextSibling;
|
|
411
|
+
$leave(node);
|
|
412
|
+
node = next;
|
|
413
|
+
}
|
|
376
414
|
const frag = document.createDocumentFragment();
|
|
377
415
|
within(region, () => this.#run(frag));
|
|
378
416
|
parent.insertBefore(frag, end);
|
|
@@ -380,9 +418,17 @@ class Binding {
|
|
|
380
418
|
}
|
|
381
419
|
case LIST:
|
|
382
420
|
return reconcile(this, this.#run());
|
|
421
|
+
case KEYED: {
|
|
422
|
+
const keyed = this.data;
|
|
423
|
+
keyed.order = this.#run();
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
383
426
|
case ISLAND:
|
|
427
|
+
case EFFECT:
|
|
384
428
|
this.#run();
|
|
385
429
|
return;
|
|
430
|
+
case MEMO:
|
|
431
|
+
return;
|
|
386
432
|
}
|
|
387
433
|
}
|
|
388
434
|
#becomeIsland() {
|
|
@@ -409,13 +455,14 @@ class Binding {
|
|
|
409
455
|
const kind = this.flags & KIND;
|
|
410
456
|
if (kind === REGION)
|
|
411
457
|
disposeAll(this.data);
|
|
412
|
-
else if (kind === LIST)
|
|
458
|
+
else if (kind === LIST || kind === KEYED)
|
|
413
459
|
for (const row of this.data.order)
|
|
414
460
|
disposeAll(row);
|
|
415
461
|
else if (kind === ISLAND) {
|
|
416
462
|
disposeIsland(this.data.tree);
|
|
417
463
|
this.data.tree = [];
|
|
418
|
-
}
|
|
464
|
+
} else if ((this.flags & OWNED) !== 0)
|
|
465
|
+
undoAttr(this.node, this.data);
|
|
419
466
|
this.#reset();
|
|
420
467
|
this.#sweep();
|
|
421
468
|
this.flags = DEAD;
|
|
@@ -448,6 +495,18 @@ function afterHandler(ctx, result) {
|
|
|
448
495
|
if (result instanceof Promise)
|
|
449
496
|
result.then(() => refreshLoose(ctx));
|
|
450
497
|
}
|
|
498
|
+
function untracked(run) {
|
|
499
|
+
const prev = collecting;
|
|
500
|
+
const reader = Model.$reader;
|
|
501
|
+
collecting = undefined;
|
|
502
|
+
Model.$reader = undefined;
|
|
503
|
+
try {
|
|
504
|
+
return run();
|
|
505
|
+
} finally {
|
|
506
|
+
collecting = prev;
|
|
507
|
+
Model.$reader = reader;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
451
510
|
function within(h, run) {
|
|
452
511
|
const prev = holder;
|
|
453
512
|
holder = h;
|
|
@@ -471,13 +530,18 @@ function disposeAll(h) {
|
|
|
471
530
|
function refreshAll(h) {
|
|
472
531
|
for (let b = h.bindings;b !== undefined; b = b.next) {
|
|
473
532
|
b.stateHasChanged();
|
|
474
|
-
|
|
533
|
+
const kind = b.flags & KIND;
|
|
534
|
+
if (kind === LIST || kind === KEYED)
|
|
475
535
|
for (const row of b.data.order)
|
|
476
536
|
refreshAll(row);
|
|
477
537
|
}
|
|
478
538
|
}
|
|
479
539
|
var textOf = (value) => value === null || value === undefined || value === false ? "" : String(value);
|
|
480
540
|
function setAttr(el, name, value) {
|
|
541
|
+
if (typeof value === "boolean" && name.startsWith("aria-"))
|
|
542
|
+
value = String(value);
|
|
543
|
+
if (name.startsWith("class:"))
|
|
544
|
+
return void el.classList.toggle(name.slice(6), !!value);
|
|
481
545
|
if (name.charCodeAt(0) === 45 && name.charCodeAt(1) === 45) {
|
|
482
546
|
const style = el.style;
|
|
483
547
|
const text2 = value === null || value === undefined || value === false ? "" : String(value);
|
|
@@ -504,48 +568,68 @@ function setAttr(el, name, value) {
|
|
|
504
568
|
else if (name === "checked" && "checked" in el)
|
|
505
569
|
el.checked = true;
|
|
506
570
|
}
|
|
571
|
+
function ownAttr(el, s, value) {
|
|
572
|
+
if (s.name !== "class") {
|
|
573
|
+
if (s.prev === undefined)
|
|
574
|
+
s.prev = el.getAttribute(s.name);
|
|
575
|
+
return setAttr(el, s.name, value);
|
|
576
|
+
}
|
|
577
|
+
const text = value === null || value === undefined || value === false || value === true ? "" : String(value);
|
|
578
|
+
if (text === s.text)
|
|
579
|
+
return;
|
|
580
|
+
s.text = text;
|
|
581
|
+
for (const t of s.added)
|
|
582
|
+
el.classList.remove(t);
|
|
583
|
+
s.added = [];
|
|
584
|
+
for (const t of text.split(/\s+/))
|
|
585
|
+
if (t !== "" && !el.classList.contains(t)) {
|
|
586
|
+
el.classList.add(t);
|
|
587
|
+
s.added.push(t);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function undoAttr(el, s) {
|
|
591
|
+
if (s.name === "class")
|
|
592
|
+
for (const t of s.added)
|
|
593
|
+
el.classList.remove(t);
|
|
594
|
+
else if (s.prev !== undefined)
|
|
595
|
+
setAttr(el, s.name, s.prev);
|
|
596
|
+
}
|
|
507
597
|
function removeRange(head, tail) {
|
|
508
|
-
const parent = head.parentNode;
|
|
509
598
|
for (let node = head;; ) {
|
|
510
599
|
const next = node.nextSibling;
|
|
511
|
-
|
|
600
|
+
$leave(node);
|
|
512
601
|
if (node === tail)
|
|
513
602
|
return;
|
|
514
603
|
node = next;
|
|
515
604
|
}
|
|
516
605
|
}
|
|
517
|
-
function
|
|
518
|
-
const
|
|
519
|
-
const
|
|
606
|
+
function newRow(ctx, item, reads, build) {
|
|
607
|
+
const frag = document.createDocumentFragment();
|
|
608
|
+
const row = { bindings: undefined, ctx, head: frag, tail: frag, item, reads };
|
|
609
|
+
within(row, () => build(frag, item));
|
|
610
|
+
seal(row, frag);
|
|
611
|
+
return row;
|
|
612
|
+
}
|
|
613
|
+
function seal(row, frag) {
|
|
614
|
+
if (frag.firstChild === null)
|
|
615
|
+
frag.appendChild(document.createComment(""));
|
|
616
|
+
row.head = frag.firstChild;
|
|
617
|
+
row.tail = frag.lastChild;
|
|
618
|
+
}
|
|
619
|
+
function dropRow(row) {
|
|
620
|
+
disposeAll(row);
|
|
621
|
+
removeRange(row.head, row.tail);
|
|
622
|
+
}
|
|
623
|
+
function place(end, old, order) {
|
|
520
624
|
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
625
|
let cursor = end;
|
|
530
|
-
for (const row of
|
|
626
|
+
for (const row of old)
|
|
531
627
|
if (row.head.parentNode === parent) {
|
|
532
628
|
cursor = row.head;
|
|
533
629
|
break;
|
|
534
630
|
}
|
|
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) {
|
|
631
|
+
for (const row of order) {
|
|
632
|
+
if (row.head !== cursor) {
|
|
549
633
|
for (let node = row.head;; ) {
|
|
550
634
|
const after = node.nextSibling;
|
|
551
635
|
parent.insertBefore(node, cursor);
|
|
@@ -555,10 +639,114 @@ function reconcile(list, items) {
|
|
|
555
639
|
}
|
|
556
640
|
} else
|
|
557
641
|
cursor = row.tail.nextSibling;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
var duplicate = (key) => new Error(`xzor: duplicate @key ${String(key)}`);
|
|
645
|
+
function reconcile(list, items) {
|
|
646
|
+
const state = list.data;
|
|
647
|
+
const rows = state.rows;
|
|
648
|
+
let next = Array.isArray(items) ? items : [...items];
|
|
649
|
+
if (next.length === 0 && state.empty !== undefined)
|
|
650
|
+
next = [EMPTY];
|
|
651
|
+
const named = state.key === undefined ? $keyName(next[0]) : undefined;
|
|
652
|
+
const keyOf = state.key ?? (named === undefined ? undefined : (item) => item[named]);
|
|
653
|
+
let keys = next;
|
|
654
|
+
if (keyOf === undefined) {
|
|
655
|
+
const keep = new Set(next);
|
|
656
|
+
for (const [item, row] of rows)
|
|
657
|
+
if (!keep.has(item)) {
|
|
658
|
+
dropRow(row);
|
|
659
|
+
rows.delete(item);
|
|
660
|
+
}
|
|
661
|
+
} else {
|
|
662
|
+
const at = new Map;
|
|
663
|
+
keys = next.map((item) => item === EMPTY ? EMPTY : keyOf(item));
|
|
664
|
+
for (let i = 0;i < next.length; i++) {
|
|
665
|
+
if (at.has(keys[i]))
|
|
666
|
+
throw duplicate(keys[i]);
|
|
667
|
+
at.set(keys[i], next[i]);
|
|
668
|
+
}
|
|
669
|
+
for (const [key, row] of rows)
|
|
670
|
+
if (!at.has(key) || at.get(key) !== row.item) {
|
|
671
|
+
dropRow(row);
|
|
672
|
+
rows.delete(key);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
const order = [];
|
|
676
|
+
for (let i = 0;i < next.length; i++) {
|
|
677
|
+
const item = next[i];
|
|
678
|
+
let row = rows.get(keys[i]);
|
|
679
|
+
if (row === undefined) {
|
|
680
|
+
row = item === EMPTY ? newRow(state.ctx, item, undefined, state.empty) : newRow(state.ctx, item, state.reads, state.build);
|
|
681
|
+
rows.set(keys[i], row);
|
|
682
|
+
}
|
|
558
683
|
order.push(row);
|
|
559
684
|
}
|
|
685
|
+
place(list.node, state.order, order);
|
|
560
686
|
state.order = order;
|
|
561
687
|
}
|
|
688
|
+
function sameValues(a, b) {
|
|
689
|
+
if (a.length !== b.length)
|
|
690
|
+
return false;
|
|
691
|
+
for (let i = 0;i < a.length; i++)
|
|
692
|
+
if (!Object.is(a[i], b[i]))
|
|
693
|
+
return false;
|
|
694
|
+
return true;
|
|
695
|
+
}
|
|
696
|
+
function runKeyed(s, end, run) {
|
|
697
|
+
const order = [];
|
|
698
|
+
const seen = new Set;
|
|
699
|
+
const outer = holder;
|
|
700
|
+
let building;
|
|
701
|
+
const finish = () => {
|
|
702
|
+
if (building === undefined)
|
|
703
|
+
return;
|
|
704
|
+
seal(building, building.head);
|
|
705
|
+
building = undefined;
|
|
706
|
+
holder = outer;
|
|
707
|
+
};
|
|
708
|
+
try {
|
|
709
|
+
run((key, values) => {
|
|
710
|
+
finish();
|
|
711
|
+
if (seen.has(key))
|
|
712
|
+
throw duplicate(key);
|
|
713
|
+
seen.add(key);
|
|
714
|
+
let row = s.rows.get(key);
|
|
715
|
+
if (row !== undefined && !sameValues(row.item, values)) {
|
|
716
|
+
dropRow(row);
|
|
717
|
+
row = undefined;
|
|
718
|
+
}
|
|
719
|
+
if (row !== undefined) {
|
|
720
|
+
order.push(row);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
const frag = document.createDocumentFragment();
|
|
724
|
+
row = { bindings: undefined, ctx: s.ctx, head: frag, tail: frag, item: values, reads: undefined };
|
|
725
|
+
s.rows.set(key, row);
|
|
726
|
+
order.push(row);
|
|
727
|
+
building = row;
|
|
728
|
+
holder = row;
|
|
729
|
+
return frag;
|
|
730
|
+
});
|
|
731
|
+
finish();
|
|
732
|
+
} finally {
|
|
733
|
+
holder = outer;
|
|
734
|
+
}
|
|
735
|
+
if (order.length === 0 && s.empty !== undefined) {
|
|
736
|
+
let row = s.rows.get(EMPTY);
|
|
737
|
+
if (row === undefined)
|
|
738
|
+
s.rows.set(EMPTY, row = newRow(s.ctx, EMPTY, undefined, s.empty));
|
|
739
|
+
order.push(row);
|
|
740
|
+
seen.add(EMPTY);
|
|
741
|
+
}
|
|
742
|
+
for (const [key, row] of s.rows)
|
|
743
|
+
if (!seen.has(key)) {
|
|
744
|
+
dropRow(row);
|
|
745
|
+
s.rows.delete(key);
|
|
746
|
+
}
|
|
747
|
+
place(end, s.order, order);
|
|
748
|
+
return order;
|
|
749
|
+
}
|
|
562
750
|
function make(spec, svg = false) {
|
|
563
751
|
if (spec === null)
|
|
564
752
|
return document.createComment("");
|
|
@@ -616,8 +804,8 @@ function region(start, end, build, item, flags) {
|
|
|
616
804
|
const region2 = { bindings: undefined, ctx: holder.ctx, start, item };
|
|
617
805
|
track(new Binding(REGION | flags, end, build, region2));
|
|
618
806
|
}
|
|
619
|
-
function list(end, items, reads, build) {
|
|
620
|
-
const state = { build, ctx: holder.ctx, rows: new Map, order: [], reads };
|
|
807
|
+
function list(end, items, reads, build, empty, key) {
|
|
808
|
+
const state = { build, ctx: holder.ctx, rows: new Map, order: [], reads, empty, key };
|
|
621
809
|
track(new Binding(LIST, end, items, state));
|
|
622
810
|
}
|
|
623
811
|
var anchor = (parent) => parent.appendChild(document.createComment(""));
|
|
@@ -682,12 +870,100 @@ var fine = {
|
|
|
682
870
|
read.$n = name;
|
|
683
871
|
track(new Binding(ATTR | ITEM, el, read, row));
|
|
684
872
|
},
|
|
873
|
+
attrOf(el, name, read) {
|
|
874
|
+
track(new Binding(ATTR | OWNED, el, read, { name, text: undefined, prev: undefined, added: [] }));
|
|
875
|
+
},
|
|
685
876
|
region(parent, build) {
|
|
686
877
|
region(anchor(parent), anchor(parent), build, undefined, 0);
|
|
687
878
|
},
|
|
688
879
|
regionAt(end, build) {
|
|
689
880
|
region(end.previousSibling, end, build, undefined, 0);
|
|
690
881
|
},
|
|
882
|
+
textOnce(node, read) {
|
|
883
|
+
node.data = textOf(untracked(read));
|
|
884
|
+
},
|
|
885
|
+
onceAt(end, build) {
|
|
886
|
+
const frag = document.createDocumentFragment();
|
|
887
|
+
untracked(() => build(frag));
|
|
888
|
+
end.parentNode.insertBefore(frag, end);
|
|
889
|
+
},
|
|
890
|
+
set(el, name, value) {
|
|
891
|
+
setAttr(el, name, value);
|
|
892
|
+
},
|
|
893
|
+
setText(node, value) {
|
|
894
|
+
node.data = textOf(value);
|
|
895
|
+
},
|
|
896
|
+
anchor,
|
|
897
|
+
memo(cls, names) {
|
|
898
|
+
const proto = cls.prototype;
|
|
899
|
+
names.forEach((name, i) => {
|
|
900
|
+
const desc = Object.getOwnPropertyDescriptor(proto, name);
|
|
901
|
+
const get = desc?.get;
|
|
902
|
+
if (get === undefined)
|
|
903
|
+
return;
|
|
904
|
+
const reader = Symbol(name);
|
|
905
|
+
Object.defineProperty(proto, name, {
|
|
906
|
+
...desc,
|
|
907
|
+
get() {
|
|
908
|
+
const memo = this[MEMOS]?.[i];
|
|
909
|
+
if (memo !== undefined)
|
|
910
|
+
return memo.$memo();
|
|
911
|
+
const by = collecting;
|
|
912
|
+
if (by === undefined)
|
|
913
|
+
return get.call(this);
|
|
914
|
+
const first = this[reader];
|
|
915
|
+
if (first === undefined || first === by || (first.flags & DEAD) !== 0) {
|
|
916
|
+
this[reader] = by;
|
|
917
|
+
return get.call(this);
|
|
918
|
+
}
|
|
919
|
+
this[reader] = undefined;
|
|
920
|
+
const b = new Binding(MEMO | QUEUED, null, () => get.call(this), undefined);
|
|
921
|
+
(this[MEMOS] ??= [])[i] = b;
|
|
922
|
+
return b.$memo();
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
});
|
|
926
|
+
},
|
|
927
|
+
awaitAt(end, read, pending, then, fail) {
|
|
928
|
+
const state = { phase: 0, value: undefined, seq: 0 };
|
|
929
|
+
const view = new Binding(REGION, end, (p) => {
|
|
930
|
+
if (state.phase === 0)
|
|
931
|
+
pending?.(p);
|
|
932
|
+
else if (state.phase === 1)
|
|
933
|
+
then?.(p, state.value);
|
|
934
|
+
else
|
|
935
|
+
fail?.(p, state.value);
|
|
936
|
+
}, { bindings: undefined, ctx: holder.ctx, start: end.previousSibling, item: undefined });
|
|
937
|
+
const show = (phase, value) => {
|
|
938
|
+
if ((view.flags & DEAD) !== 0)
|
|
939
|
+
return;
|
|
940
|
+
state.phase = phase;
|
|
941
|
+
state.value = value;
|
|
942
|
+
view.stateHasChanged();
|
|
943
|
+
};
|
|
944
|
+
track(view);
|
|
945
|
+
track(new Binding(EFFECT, end, () => {
|
|
946
|
+
const result = read();
|
|
947
|
+
const seq = ++state.seq;
|
|
948
|
+
if (typeof result?.then !== "function")
|
|
949
|
+
return show(1, result);
|
|
950
|
+
if (state.phase !== 0)
|
|
951
|
+
show(0, undefined);
|
|
952
|
+
result.then((value) => seq === state.seq && show(1, value), (error) => {
|
|
953
|
+
if (seq !== state.seq)
|
|
954
|
+
return;
|
|
955
|
+
show(2, error);
|
|
956
|
+
if (fail === undefined)
|
|
957
|
+
queueMicrotask(() => {
|
|
958
|
+
throw error;
|
|
959
|
+
});
|
|
960
|
+
});
|
|
961
|
+
}, undefined));
|
|
962
|
+
},
|
|
963
|
+
anchors(parent) {
|
|
964
|
+
anchor(parent);
|
|
965
|
+
return anchor(parent);
|
|
966
|
+
},
|
|
691
967
|
regionItem(end, i) {
|
|
692
968
|
const row = holder;
|
|
693
969
|
region(end.previousSibling, end, row.reads[i], row.item, ITEM);
|
|
@@ -695,8 +971,12 @@ var fine = {
|
|
|
695
971
|
list(parent, items, build) {
|
|
696
972
|
list(anchor(parent), items, undefined, build);
|
|
697
973
|
},
|
|
698
|
-
listAt(end, items, reads, build) {
|
|
699
|
-
list(end, items, reads, build);
|
|
974
|
+
listAt(end, items, reads, build, empty, key) {
|
|
975
|
+
list(end, items, reads, build, empty, key);
|
|
976
|
+
},
|
|
977
|
+
keyedAt(end, run, empty) {
|
|
978
|
+
const state = { ctx: holder.ctx, rows: new Map, order: [], empty };
|
|
979
|
+
track(new Binding(KEYED, end, () => runKeyed(state, end, run), state));
|
|
700
980
|
},
|
|
701
981
|
island(parent, build) {
|
|
702
982
|
fine.islandAt(anchor(parent), build);
|
|
@@ -765,8 +1045,22 @@ setFineHooks({
|
|
|
765
1045
|
root.end = frag.appendChild(document.createComment(""));
|
|
766
1046
|
return root;
|
|
767
1047
|
},
|
|
768
|
-
refresh
|
|
769
|
-
|
|
1048
|
+
refresh(root) {
|
|
1049
|
+
const memos = root.ctx.owner[MEMOS];
|
|
1050
|
+
if (memos !== undefined) {
|
|
1051
|
+
for (const m of memos)
|
|
1052
|
+
if (m !== undefined)
|
|
1053
|
+
m.flags &= ~FRESH;
|
|
1054
|
+
}
|
|
1055
|
+
refreshAll(root);
|
|
1056
|
+
},
|
|
1057
|
+
dispose(root) {
|
|
1058
|
+
const memos = root.ctx.owner[MEMOS];
|
|
1059
|
+
if (memos !== undefined)
|
|
1060
|
+
for (const m of memos)
|
|
1061
|
+
m?.dispose();
|
|
1062
|
+
disposeAll(root);
|
|
1063
|
+
},
|
|
770
1064
|
handled(owner, result) {
|
|
771
1065
|
const ctx = owner[CTX];
|
|
772
1066
|
if (ctx !== undefined)
|
|
@@ -804,6 +1098,7 @@ var meta = Symbol("xzor.model.meta");
|
|
|
804
1098
|
var empty = { names: [], tracked: new Set, persisted: [], ignored: new Set, validators: [], serialized: [] };
|
|
805
1099
|
var pendingPersist;
|
|
806
1100
|
var pendingIgnored;
|
|
1101
|
+
var pendingKey;
|
|
807
1102
|
var pendingValidators;
|
|
808
1103
|
var silent = 0;
|
|
809
1104
|
function metaOf(model) {
|
|
@@ -835,8 +1130,10 @@ class Model extends EventTarget {
|
|
|
835
1130
|
tracked: new Set(all),
|
|
836
1131
|
persisted: base ? base.persisted.slice() : [],
|
|
837
1132
|
ignored: new Set(base?.ignored),
|
|
838
|
-
validators: base ? base.validators.map(([name, list2]) => [name, list2.slice()]) : []
|
|
1133
|
+
validators: base ? base.validators.map(([name, list2]) => [name, list2.slice()]) : [],
|
|
1134
|
+
key: pendingKey ?? base?.key
|
|
839
1135
|
};
|
|
1136
|
+
pendingKey = undefined;
|
|
840
1137
|
if (pendingValidators) {
|
|
841
1138
|
for (const [name, list2] of pendingValidators) {
|
|
842
1139
|
const known = own.validators.find((entry) => entry[0] === name);
|
|
@@ -1230,6 +1527,12 @@ function Ignore(_member, context) {
|
|
|
1230
1527
|
(pendingIgnored ??= []).push(context.name);
|
|
1231
1528
|
}
|
|
1232
1529
|
function Untracked(_value, _context) {}
|
|
1530
|
+
function Key(_member, context) {
|
|
1531
|
+
pendingKey = context.name;
|
|
1532
|
+
}
|
|
1533
|
+
function $keyName(item) {
|
|
1534
|
+
return item instanceof Model ? metaOf(item).key : undefined;
|
|
1535
|
+
}
|
|
1233
1536
|
function isLike(a, b) {
|
|
1234
1537
|
return Model.same(a, b);
|
|
1235
1538
|
}
|
|
@@ -1440,10 +1743,12 @@ setRenderObserver({
|
|
|
1440
1743
|
});
|
|
1441
1744
|
export {
|
|
1442
1745
|
$flush,
|
|
1746
|
+
$keyName,
|
|
1443
1747
|
$notify,
|
|
1444
1748
|
EntitySet,
|
|
1445
1749
|
FineComponent,
|
|
1446
1750
|
Ignore,
|
|
1751
|
+
Key,
|
|
1447
1752
|
Model,
|
|
1448
1753
|
ModelChangeEvent,
|
|
1449
1754
|
Persist,
|
|
@@ -1465,5 +1770,5 @@ export {
|
|
|
1465
1770
|
requiredIdValue
|
|
1466
1771
|
};
|
|
1467
1772
|
|
|
1468
|
-
//# debugId=
|
|
1773
|
+
//# debugId=55A54F7D726CA15364756E2164756E21
|
|
1469
1774
|
//# sourceMappingURL=model.js.map
|