@srfnstack/fntags 1.2.6 → 1.2.7
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/package.json +1 -1
- package/src/fntags.d.mts.map +1 -1
- package/src/fntags.mjs +62 -3
package/package.json
CHANGED
package/src/fntags.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fntags.d.mts","sourceRoot":"","sources":["fntags.mjs"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,2DALW,MAAM,eACH,CAAC,IAAI,MAAO,CAAC,OA6C1B;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;GAGG;AAEH;;;;;;;;;;GAUG;AACH,iEAPgB,GAAG,cAqIlB;
|
|
1
|
+
{"version":3,"file":"fntags.d.mts","sourceRoot":"","sources":["fntags.mjs"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,2DALW,MAAM,eACH,CAAC,IAAI,MAAO,CAAC,OA6C1B;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;GAGG;AAEH;;;;;;;;;;GAUG;AACH,iEAPgB,GAAG,cAqIlB;AAgjBD;;;;GAIG;AACH,iCAHW,GAAG,GACD,IAAI,CAuBhB;AAqFD;;;;GAIG;AACH,6BAHW,GAAG,GACD,OAAO,CAInB;AAED;;;;GAIG;AACH,mCAHW,GAAG,GACF,MAAM,CAIjB;AAED;;;;;;;;;;GAUG;AACH,kEALW,MAAM,GAAC,MAAM,OACb,MAAM,YACN,MAAM,EAAE,GAAC,IAAI,EAAE,KAezB;AAOD;;;;;;;;GAQG;AACH,wCAJW,MAAM,0BAiBhB;AAED;;;;;;;;;GASG;AACH,oCALW,MAAM,gBACN,GAAG,eACE,GAAG,KAAK,MAAM,OAc7B;AAED;;;;;;;;GAQG;AACH,mCAJW,WAAW,SACX,CAAC,MAAI,IAAI,CAAC,GAAC,IAAI,GACb,WAAW,CAWvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qDAJkB,IAAI,iBACH,IAAI,CA+DtB;;;;;;;;;kCArgCmC,CAAC,YAAY,CAAC,KAAG,CAAC,IAAI,GAAC,GAAG,CAAC,KAAG,IAAI;;;;;;2BAE/C,CAAC,MAAI,CAAC,IAAI,GAAC,GAAG,CAAC,CAAC,GAAC,GAAG,GAAC,IAAI,gCAAkC,CAAC,IAAI,GAAC,GAAG,CAAC,KAAG,IAAI;;;;;qBAG9E,MAAM,KAAG,IAAI;;;;sCAEI,CAAC,YAAY,CAAC,KAAG,CAAC,MAAM,GAAC,GAAG,CAAC,KAAG,GAAG;;;;mCACvC,CAAC,YAAY,CAAC,KAAG,MAAM,KAAK,MAAM;;;;yCAC7B,GAAG,KAAG,CAAC,IAAI,GAAC,GAAG,CAAC,KAAG,IAAI;;;;+CACrB,GAAG,KAAG,CAAC,MAAM,GAAC,GAAG,CAAC,KAAG,GAAG;;;;;;kBAC7C,GAAG,KAAG,IAAI;;;;cAGhB,MAAK,GAAG;;;;;qBACC,CAAC,KAAG,IAAI;;;;;;oBAEV,MAAM,KAAG,GAAG;;;;oBAGZ,MAAM,SAAS,GAAG,mBAAmB,OAAO,KAAG,IAAI;;;;uCAClC,CAAC,YAAY,CAAC,KAAG,IAAI,KAAK,IAAI;;;;eACtD,OAAO;;;;;sDAKqB,CAAC,KAAG,CAAC"}
|
package/src/fntags.mjs
CHANGED
|
@@ -489,7 +489,17 @@ const doBind = function (ctx, element, handleReplace) {
|
|
|
489
489
|
const prevRenderCleanups = activeRenderCleanups
|
|
490
490
|
const thisRenderCleanups = []
|
|
491
491
|
activeRenderCleanups = thisRenderCleanups
|
|
492
|
-
const
|
|
492
|
+
const evaluated = evaluateElement(element, ctx.currentValue)
|
|
493
|
+
const childElCtx = (typeof evaluated === 'function' && evaluated.isBindGetter)
|
|
494
|
+
? evaluated.elCtx
|
|
495
|
+
: null
|
|
496
|
+
const elCtx = { current: renderNode(evaluated), cleanups: thisRenderCleanups }
|
|
497
|
+
// When the evaluated element is itself a bind getter (a nested bindAs/bindSelect),
|
|
498
|
+
// register this elCtx as a back-ref on the child so that later child-driven
|
|
499
|
+
// node swaps keep this elCtx.current in sync with the live DOM node.
|
|
500
|
+
if (childElCtx && childElCtx.current === elCtx.current) {
|
|
501
|
+
addParentRef(childElCtx, elCtx)
|
|
502
|
+
}
|
|
493
503
|
// Suppress tracking during handleReplace — the driving subscription is
|
|
494
504
|
// registered separately below as part of a cascading cleanup.
|
|
495
505
|
activeRenderCleanups = null
|
|
@@ -504,10 +514,46 @@ const doBind = function (ctx, element, handleReplace) {
|
|
|
504
514
|
if (elCtx.drivingUnsub) elCtx.drivingUnsub()
|
|
505
515
|
if (elCtx.selectUnsub) elCtx.selectUnsub()
|
|
506
516
|
runCleanups(elCtx)
|
|
517
|
+
// Mark dead so any child elCtx that still holds us in its parentRefs
|
|
518
|
+
// can prune us lazily on its next propagateReplace walk.
|
|
519
|
+
elCtx.dead = true
|
|
507
520
|
})
|
|
508
521
|
}
|
|
509
522
|
|
|
510
|
-
|
|
523
|
+
const getter = () => elCtx.current
|
|
524
|
+
getter.isBindGetter = true
|
|
525
|
+
getter.elCtx = elCtx
|
|
526
|
+
return getter
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Register a back-ref from a child bind elCtx to a parent elCtx, avoiding
|
|
530
|
+
// duplicate entries when the same parent re-renders against the same child.
|
|
531
|
+
function addParentRef (childElCtx, parentElCtx) {
|
|
532
|
+
if (!childElCtx.parentRefs) {
|
|
533
|
+
childElCtx.parentRefs = [parentElCtx]
|
|
534
|
+
} else if (!childElCtx.parentRefs.includes(parentElCtx)) {
|
|
535
|
+
childElCtx.parentRefs.push(parentElCtx)
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Walk the back-ref chain and update any ancestor elCtx whose .current still
|
|
540
|
+
// points at the old DOM node. Used when a nested bindAs swaps its node so the
|
|
541
|
+
// outer bindAs keeps a live reference instead of a detached one. Prunes any
|
|
542
|
+
// dead ancestors encountered so parentRefs does not retain torn-down elCtxs.
|
|
543
|
+
function propagateReplace (elCtx, oldNode, newNode) {
|
|
544
|
+
const refs = elCtx.parentRefs
|
|
545
|
+
if (!refs) return
|
|
546
|
+
for (let i = refs.length - 1; i >= 0; i--) {
|
|
547
|
+
const parent = refs[i]
|
|
548
|
+
if (parent.dead) {
|
|
549
|
+
refs.splice(i, 1)
|
|
550
|
+
continue
|
|
551
|
+
}
|
|
552
|
+
if (parent.current === oldNode) {
|
|
553
|
+
parent.current = newNode
|
|
554
|
+
propagateReplace(parent, oldNode, newNode)
|
|
555
|
+
}
|
|
556
|
+
}
|
|
511
557
|
}
|
|
512
558
|
|
|
513
559
|
const updateReplacer = (ctx, element, elCtx) => (_, oldValue) => {
|
|
@@ -520,7 +566,11 @@ const updateReplacer = (ctx, element, elCtx) => (_, oldValue) => {
|
|
|
520
566
|
const prevRenderCleanups = activeRenderCleanups
|
|
521
567
|
const thisRenderCleanups = []
|
|
522
568
|
activeRenderCleanups = thisRenderCleanups
|
|
523
|
-
|
|
569
|
+
const evaluated = evaluateElement(element, ctx.currentValue, oldValue)
|
|
570
|
+
const childElCtx = (typeof evaluated === 'function' && evaluated.isBindGetter)
|
|
571
|
+
? evaluated.elCtx
|
|
572
|
+
: null
|
|
573
|
+
let rendered = renderNode(evaluated)
|
|
524
574
|
activeRenderCleanups = prevRenderCleanups
|
|
525
575
|
elCtx.cleanups = thisRenderCleanups
|
|
526
576
|
|
|
@@ -533,14 +583,23 @@ const updateReplacer = (ctx, element, elCtx) => (_, oldValue) => {
|
|
|
533
583
|
bindContext.boundElementByKey[elCtx.current.key] = rendered
|
|
534
584
|
}
|
|
535
585
|
}
|
|
586
|
+
// Re-establish the parent-ref link when a re-render resolves to another
|
|
587
|
+
// nested bind getter, so future child swaps propagate back to this elCtx.
|
|
588
|
+
if (childElCtx && childElCtx.current === rendered) {
|
|
589
|
+
addParentRef(childElCtx, elCtx)
|
|
590
|
+
}
|
|
536
591
|
// Perform this action on the next event loop to give the parent a chance to render
|
|
537
592
|
new Promise((resolve) => {
|
|
538
593
|
// Guard: skip replaceWith when the same element is returned (e.g. when
|
|
539
594
|
// toggling between two pre-built element references). el.replaceWith(el)
|
|
540
595
|
// is a no-op in the DOM but wastes a microtask.
|
|
541
596
|
if (rendered !== elCtx.current) {
|
|
597
|
+
const oldCurrent = elCtx.current
|
|
542
598
|
elCtx.current.replaceWith(rendered)
|
|
543
599
|
elCtx.current = rendered
|
|
600
|
+
// Keep any ancestor bindAs whose elCtx shared this node in sync with
|
|
601
|
+
// the new node, so their next replaceWith targets a live DOM node.
|
|
602
|
+
propagateReplace(elCtx, oldCurrent, rendered)
|
|
544
603
|
}
|
|
545
604
|
rendered = null
|
|
546
605
|
resolve()
|