@barefootjs/jsx 0.26.4 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +321 -104
- package/dist/ir-to-client-js/client-only-elision.d.ts +103 -0
- package/dist/ir-to-client-js/client-only-elision.d.ts.map +1 -0
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/shared.d.ts +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/claim-plan.d.ts +54 -0
- package/dist/ir-to-client-js/control-flow/stringify/claim-plan.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/stringify/inner-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/insert.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/loop-child-arm.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/loop.d.ts +17 -20
- package/dist/ir-to-client-js/control-flow/stringify/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/reactive-effects.d.ts +63 -4
- package/dist/ir-to-client-js/control-flow/stringify/reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow.d.ts +1 -1
- package/dist/ir-to-client-js/element-refs.d.ts +8 -3
- package/dist/ir-to-client-js/element-refs.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts +8 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +24 -0
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/imports.d.ts +2 -2
- package/dist/ir-to-client-js/imports.d.ts.map +1 -1
- package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
- package/dist/ir-to-client-js/types.d.ts +9 -1
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/dist/ir-to-client-js/utils.d.ts +1 -1
- package/dist/types.d.ts +25 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +398 -671
- package/src/__tests__/child-components-in-map.test.ts +4 -4
- package/src/__tests__/client-js-generation.test.ts +19 -11
- package/src/__tests__/composite-branch-loop.test.ts +2 -2
- package/src/__tests__/cross-file-client-signal.test.ts +5 -1
- package/src/__tests__/early-return-scope-var-ref.test.ts +10 -11
- package/src/__tests__/inline-jsx-callback.test.ts +6 -4
- package/src/__tests__/ir-jsx-props.test.ts +6 -5
- package/src/__tests__/loop-fallback-wrap.test.ts +3 -4
- package/src/__tests__/module-level-signal.audit.test.ts +7 -2
- package/src/__tests__/nested-loop-conditional.test.ts +9 -7
- package/src/__tests__/nested-loop-reactive-attrs.test.ts +2 -2
- package/src/__tests__/preamble-region-patch.test.ts +18 -12
- package/src/__tests__/profile-cond-binding-ids.test.ts +3 -2
- package/src/__tests__/profile-loop-binding-ids.test.ts +4 -3
- package/src/__tests__/profile-nested-binding-ids.test.ts +11 -6
- package/src/__tests__/reactive-attrs-in-map.test.ts +6 -4
- package/src/__tests__/template-closure.test.ts +1 -1
- package/src/compiler.ts +11 -0
- package/src/index.ts +1 -0
- package/src/ir-to-client-js/client-only-elision.ts +273 -0
- package/src/ir-to-client-js/collect-elements.ts +8 -4
- package/src/ir-to-client-js/control-flow/shared.ts +1 -1
- package/src/ir-to-client-js/control-flow/stringify/branch-loop.ts +12 -4
- package/src/ir-to-client-js/control-flow/stringify/claim-plan.ts +68 -0
- package/src/ir-to-client-js/control-flow/stringify/inner-loop.ts +18 -9
- package/src/ir-to-client-js/control-flow/stringify/insert.ts +17 -11
- package/src/ir-to-client-js/control-flow/stringify/loop-child-arm.ts +35 -16
- package/src/ir-to-client-js/control-flow/stringify/loop.ts +48 -46
- package/src/ir-to-client-js/control-flow/stringify/reactive-effects.ts +241 -31
- package/src/ir-to-client-js/control-flow.ts +1 -1
- package/src/ir-to-client-js/element-refs.ts +9 -11
- package/src/ir-to-client-js/emit-reactive.ts +50 -14
- package/src/ir-to-client-js/html-template.ts +29 -9
- package/src/ir-to-client-js/imports.ts +7 -4
- package/src/ir-to-client-js/reactivity.ts +3 -2
- package/src/ir-to-client-js/types.ts +10 -2
- package/src/ir-to-client-js/utils.ts +1 -1
- package/src/jsx-to-ir.ts +8 -7
- package/src/types.ts +25 -2
|
@@ -126,7 +126,11 @@ export function createTemplateAwareStringProtector(): {
|
|
|
126
126
|
return { protect, restore, replaceProtectedCall }
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
// Exported (not just module-local) so `client-only-elision.ts` (slot
|
|
130
|
+
// unification Step B) can reuse the exact same void-element list when it
|
|
131
|
+
// walks the IR tree computing markerless-eligible child-index paths —
|
|
132
|
+
// duplicating this list would risk the two walks silently drifting apart.
|
|
133
|
+
export const VOID_ELEMENTS = new Set([
|
|
130
134
|
'area', 'base', 'br', 'col', 'embed', 'hr', 'img',
|
|
131
135
|
'input', 'link', 'meta', 'param', 'source', 'track', 'wbr',
|
|
132
136
|
])
|
|
@@ -794,6 +798,16 @@ export function irToHtmlTemplate(node: IRNode, restSpreadNames?: Set<string>, lo
|
|
|
794
798
|
|
|
795
799
|
case 'expression': {
|
|
796
800
|
if (node.expr === 'null' || node.expr === 'undefined') return ''
|
|
801
|
+
// Slot unification Step B (`markerless`, decided once by
|
|
802
|
+
// `client-only-elision.ts` before this CSR pass runs): drop the
|
|
803
|
+
// marker pair and fall through to the same bare `${...}` shape the
|
|
804
|
+
// no-slotId branch below already uses — `elidedPath` (not this
|
|
805
|
+
// string) is what the claim plan resolves against, so no marker
|
|
806
|
+
// anchor is needed here at all.
|
|
807
|
+
if (node.markerless) {
|
|
808
|
+
const bare = wrapInterpolation(wrapExpr(node.expr))
|
|
809
|
+
return `\${${bare}}`
|
|
810
|
+
}
|
|
797
811
|
const inner = wrapInterpolation(wrapExpr(node.expr))
|
|
798
812
|
// Stage 3 / D4 — an element-array child ({out}) built by an arbitrary
|
|
799
813
|
// .map() preamble is an array of HTML strings; join it rather than let
|
|
@@ -908,8 +922,8 @@ export function irToHtmlTemplate(node: IRNode, restSpreadNames?: Set<string>, lo
|
|
|
908
922
|
// (Go's `bf_sort`, etc.) applied the sort separately and
|
|
909
923
|
// hydration only needed to match, but broken on Hono / CSR
|
|
910
924
|
// where the template is the only source of truth. The chain
|
|
911
|
-
// mirrors `buildChainedArrayExpr` so
|
|
912
|
-
// same array shape this template emits.
|
|
925
|
+
// mirrors `buildChainedArrayExpr` so mapArray/mapArrayAnchored sees
|
|
926
|
+
// the same array shape this template emits.
|
|
913
927
|
const rawChainedArray = applyLoopChain(node)
|
|
914
928
|
const { array: iterArray, callbackParam } = applyIterationShape(node, rawChainedArray, indexParam)
|
|
915
929
|
const wrappedArray = wrapExpr(iterArray)
|
|
@@ -1120,7 +1134,9 @@ export interface SkeletonSlotPaths {
|
|
|
1120
1134
|
* the loop keeps its hoisted-clone fast path, but every slot lookup falls
|
|
1121
1135
|
* back to `qsa`/`$t`.
|
|
1122
1136
|
*/
|
|
1123
|
-
|
|
1137
|
+
// Exported for reuse by `client-only-elision.ts` (Step B) — same hazard
|
|
1138
|
+
// class, same reasoning, must never drift out of sync with a second copy.
|
|
1139
|
+
export const SKELETON_PATH_HAZARD_TAGS = new Set([
|
|
1124
1140
|
'table', 'thead', 'tbody', 'tfoot', 'caption', 'colgroup', 'col',
|
|
1125
1141
|
'select', 'optgroup',
|
|
1126
1142
|
'p',
|
|
@@ -1136,7 +1152,7 @@ const SKELETON_PATH_HAZARD_TAGS = new Set([
|
|
|
1136
1152
|
* `<dt>` closes the `<dt>`). A skeleton hitting this bails on path
|
|
1137
1153
|
* computation entirely (see `SKELETON_PATH_HAZARD_TAGS` doc).
|
|
1138
1154
|
*/
|
|
1139
|
-
const SKELETON_PATH_FORCE_CLOSE_GROUPS: ReadonlyArray<ReadonlySet<string>> = [
|
|
1155
|
+
export const SKELETON_PATH_FORCE_CLOSE_GROUPS: ReadonlyArray<ReadonlySet<string>> = [
|
|
1140
1156
|
new Set(['a']),
|
|
1141
1157
|
new Set(['button']),
|
|
1142
1158
|
new Set(['form']),
|
|
@@ -1146,7 +1162,7 @@ const SKELETON_PATH_FORCE_CLOSE_GROUPS: ReadonlyArray<ReadonlySet<string>> = [
|
|
|
1146
1162
|
new Set(['li']),
|
|
1147
1163
|
]
|
|
1148
1164
|
|
|
1149
|
-
function skeletonForceCloseGroup(tag: string): number {
|
|
1165
|
+
export function skeletonForceCloseGroup(tag: string): number {
|
|
1150
1166
|
return SKELETON_PATH_FORCE_CLOSE_GROUPS.findIndex(group => group.has(tag))
|
|
1151
1167
|
}
|
|
1152
1168
|
|
|
@@ -1204,7 +1220,7 @@ function walkSkeletonPathNode(
|
|
|
1204
1220
|
}
|
|
1205
1221
|
|
|
1206
1222
|
/** True if `children` (already flattened) contains anything the HTML parser would foster-parent out of a `<tr>`. */
|
|
1207
|
-
function hasForeignTableRowContent(children: readonly IRNode[]): boolean {
|
|
1223
|
+
export function hasForeignTableRowContent(children: readonly IRNode[]): boolean {
|
|
1208
1224
|
for (const child of children) {
|
|
1209
1225
|
if (child.type === 'text') {
|
|
1210
1226
|
if (child.value.trim() !== '') return true
|
|
@@ -1218,7 +1234,7 @@ function hasForeignTableRowContent(children: readonly IRNode[]): boolean {
|
|
|
1218
1234
|
}
|
|
1219
1235
|
|
|
1220
1236
|
/** Splice fragment children inline — a fragment contributes no DOM node of its own. */
|
|
1221
|
-
function flattenSkeletonChildren(children: readonly IRNode[]): IRNode[] {
|
|
1237
|
+
export function flattenSkeletonChildren(children: readonly IRNode[]): IRNode[] {
|
|
1222
1238
|
const out: IRNode[] = []
|
|
1223
1239
|
for (const child of children) {
|
|
1224
1240
|
if (child.type === 'fragment') {
|
|
@@ -2322,7 +2338,11 @@ function generateCsrTemplateWithOpts(node: IRNode, opts: TemplateOptions): strin
|
|
|
2322
2338
|
case 'expression':
|
|
2323
2339
|
if (node.expr === 'null' || node.expr === 'undefined') return ''
|
|
2324
2340
|
if (node.clientOnly && node.slotId) {
|
|
2325
|
-
|
|
2341
|
+
// Ordinary claimed 'text' slot pair (slot unification A3) — matches
|
|
2342
|
+
// the SSR adapters' `renderExpression` byte-for-byte (byte parity):
|
|
2343
|
+
// empty at CSR mount too, since the expression is evaluated only
|
|
2344
|
+
// once init's createEffect runs, same as the SSR case.
|
|
2345
|
+
return `<!--bf:${node.slotId}--><!--/-->`
|
|
2326
2346
|
}
|
|
2327
2347
|
{
|
|
2328
2348
|
const transformed = transformExpr(node.expr, node.templateExpr)
|
|
@@ -8,13 +8,16 @@ import { isClientBuiltinName } from '../builtins.ts'
|
|
|
8
8
|
// All exports from @barefootjs/client/runtime that may be used in generated code
|
|
9
9
|
export const RUNTIME_IMPORT_CANDIDATES = [
|
|
10
10
|
'createSignal', 'createMemo', 'createEffect', 'onCleanup', 'onMount',
|
|
11
|
-
'hydrate', 'insert', '
|
|
12
|
-
'createComponent', 'renderChild', 'registerComponent', 'registerTemplate', 'initChild', 'upsertChild',
|
|
11
|
+
'hydrate', 'insert', 'getLoopChildren', 'getLoopNodes', 'mapArray', 'mapArrayAnchored', 'patchLeaf', 'createDisposableEffect',
|
|
12
|
+
'createComponent', 'renderChild', 'registerComponent', 'registerTemplate', 'initChild', 'upsertChild',
|
|
13
13
|
'createPortal',
|
|
14
14
|
'provideContext', 'createContext', 'useContext',
|
|
15
|
-
'forwardProps', 'applyRestAttrs', 'splitProps', 'spreadAttrs', 'styleToCss', 'escapeAttr', 'escapeText',
|
|
15
|
+
'forwardProps', 'applyRestAttrs', 'splitProps', 'spreadAttrs', 'styleToCss', 'escapeAttr', 'escapeText', 'escapeTextOrNode',
|
|
16
16
|
'qsa', 'qsaItem', 'qsaChildScope', 'qsaChildScopes', 'upsertChildItem', '__slot', '__bfSlot', '__bfText',
|
|
17
|
-
|
|
17
|
+
// Claim-plan interpreter (slot unification A2/A3, spec/slot-unification.md)
|
|
18
|
+
// — the "one claim mechanism" that replaced `patchSlotRange` and
|
|
19
|
+
// `updateClientMarker` (both deleted) as the content-slot update door.
|
|
20
|
+
'claimSlots', 'lazySlots',
|
|
18
21
|
// Profile mode (#1690, SR3) — turn-boundary markers around event handlers.
|
|
19
22
|
'beginTurn', 'endTurn',
|
|
20
23
|
// Catalogued `Date` lowering (#2274/#2292) — the client counterpart to
|
|
@@ -571,8 +571,9 @@ export function collectLoopChildReactiveTexts(
|
|
|
571
571
|
expression: ({ node: n, scope: insideConditional }) => {
|
|
572
572
|
if (!n.slotId) return
|
|
573
573
|
// #2389 — a preamble-patched region (see `IRLoop.preambleRegions`) has
|
|
574
|
-
// its own
|
|
575
|
-
// client-JS loop plan
|
|
574
|
+
// its own claimed 'markup'-slot effect (`preambleRegions` in the
|
|
575
|
+
// client-JS loop plan; slot unification A3, `@barefootjs/client/
|
|
576
|
+
// runtime/claim-slots.ts`); it must never ALSO become a `reactiveTexts`
|
|
576
577
|
// entry, which would patch it via `.textContent` and corrupt markup
|
|
577
578
|
// (a `joinArrayChild` region's value is raw HTML, not text).
|
|
578
579
|
if (n.preambleRegion) return
|
|
@@ -255,7 +255,7 @@ export interface LoopCore {
|
|
|
255
255
|
/**
|
|
256
256
|
* Unique id for this loop's `<!--bf-loop:<id>--> ... <!--bf-/loop:<id>-->`
|
|
257
257
|
* marker pair, threaded from `IRLoop.markerId`. Each `mapArray()` /
|
|
258
|
-
* `
|
|
258
|
+
* `mapArrayAnchored()` call passes this id so sibling loops under the
|
|
259
259
|
* same parent reconcile their own range (#1087).
|
|
260
260
|
*/
|
|
261
261
|
markerId: string
|
|
@@ -609,7 +609,7 @@ export interface TopLevelLoop extends LoopCore {
|
|
|
609
609
|
// Per-item bindings (events / reactiveAttrs / reactiveTexts / refs / conditionals)
|
|
610
610
|
// now live on `LoopCore.bindings` — see issue #1244 §B.
|
|
611
611
|
isStaticArray: boolean // True if array is a static prop (not a signal)
|
|
612
|
-
useElementReconciliation?: boolean // True:
|
|
612
|
+
useElementReconciliation?: boolean // True: mapArray/mapArrayAnchored + composite rendering (native root with child components)
|
|
613
613
|
/** Inner loop metadata for composite element reconciliation (array, param, key, container) */
|
|
614
614
|
innerLoops?: NestedLoop[]
|
|
615
615
|
/** Offset of this loop's items past its preceding container siblings (#1693). */
|
|
@@ -654,6 +654,14 @@ export interface ReactiveAttribute extends AttrMeta {
|
|
|
654
654
|
export interface ClientOnlyElement {
|
|
655
655
|
slotId: string
|
|
656
656
|
expression: string
|
|
657
|
+
/**
|
|
658
|
+
* Slot unification Step B (`spec/slot-unification.md` §3(b), §5 Step B):
|
|
659
|
+
* copied from `IRExpression.elidedPath` (`client-only-elision.ts`) when
|
|
660
|
+
* the compiler proved this slot's marker pair can be elided. Absent
|
|
661
|
+
* (`undefined`) is always safe — the claim plan falls back to `path: []`
|
|
662
|
+
* / marker-based resolution exactly as before Step B.
|
|
663
|
+
*/
|
|
664
|
+
elidedPath?: readonly number[]
|
|
657
665
|
}
|
|
658
666
|
|
|
659
667
|
|
|
@@ -180,7 +180,7 @@ export function applyObjectIterationWrap(
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
/**
|
|
183
|
-
* Build the chained array expression for
|
|
183
|
+
* Build the chained array expression for mapArray/mapArrayAnchored. Thin
|
|
184
184
|
* adapter over `buildLoopChainExpr` that unpacks the collected
|
|
185
185
|
* `TopLevelLoop` / `BranchLoop` shape into the primitive inputs.
|
|
186
186
|
* Branch loops carry the same `filterPredicate` / `sortComparator`
|
package/src/jsx-to-ir.ts
CHANGED
|
@@ -4610,8 +4610,8 @@ function transformMapCall(
|
|
|
4610
4610
|
const bodyIsMultiRoot = loopBodyIsMultiRoot(children)
|
|
4611
4611
|
|
|
4612
4612
|
// Determine if array is static (prop) or dynamic (signal/memo).
|
|
4613
|
-
// Static arrays don't need
|
|
4614
|
-
// directly. Signal / memo arrays need
|
|
4613
|
+
// Static arrays don't need mapArray/mapArrayAnchored — SSR elements are
|
|
4614
|
+
// hydrated directly. Signal / memo arrays need mapArray for dynamic DOM
|
|
4615
4615
|
// updates.
|
|
4616
4616
|
//
|
|
4617
4617
|
// Solid-style wrap-by-default fallback (#943, follow-up to
|
|
@@ -4621,7 +4621,7 @@ function transformMapCall(
|
|
|
4621
4621
|
// where `getItems` is an imported helper previously silent-dropped
|
|
4622
4622
|
// into the static-render path, freezing the SSR-time list on the
|
|
4623
4623
|
// client. Over-reconciling an array that happens to contain a pure
|
|
4624
|
-
// call costs one extra `
|
|
4624
|
+
// call costs one extra `mapArray` per loop; under-reconciling
|
|
4625
4625
|
// is the silent-drop bug this closes.
|
|
4626
4626
|
//
|
|
4627
4627
|
// Destructured map params (`([, cfg]) => ...`, `({ a, b }) => ...`,
|
|
@@ -4660,8 +4660,9 @@ function transformMapCall(
|
|
|
4660
4660
|
|
|
4661
4661
|
// Collect nested components for both static and dynamic arrays.
|
|
4662
4662
|
// Static arrays: needed for initChild hydration.
|
|
4663
|
-
// Dynamic arrays with native root + component descendants: enables
|
|
4664
|
-
// with composite rendering (placeholder +
|
|
4663
|
+
// Dynamic arrays with native root + component descendants: enables
|
|
4664
|
+
// mapArray/mapArrayAnchored with composite rendering (placeholder +
|
|
4665
|
+
// createComponent replacement).
|
|
4665
4666
|
const nestedComponents = collectNestedComponents(children).filter(c => c.name !== childComponent?.name)
|
|
4666
4667
|
|
|
4667
4668
|
return {
|
|
@@ -6564,7 +6565,7 @@ function isArrayExprDirectPropRef(arrayExpr: ts.Expression, ctx: TransformContex
|
|
|
6564
6565
|
|
|
6565
6566
|
/**
|
|
6566
6567
|
* Check if array expression is a signal or memo getter call.
|
|
6567
|
-
* Used to determine if a loop needs
|
|
6568
|
+
* Used to determine if a loop needs mapArray for dynamic DOM updates.
|
|
6568
6569
|
* Props and local constants are considered static (don't change at runtime).
|
|
6569
6570
|
*/
|
|
6570
6571
|
function isSignalOrMemoArray(array: string, ctx: TransformContext): boolean {
|
|
@@ -6767,7 +6768,7 @@ function attrValueReactivityProbe(value: AttrValue): string | null {
|
|
|
6767
6768
|
|
|
6768
6769
|
/**
|
|
6769
6770
|
* Propagate slotId to loop children that need it.
|
|
6770
|
-
* Loops need to use their parent element's slotId for
|
|
6771
|
+
* Loops need to use their parent element's slotId for mapArray.
|
|
6771
6772
|
* This handles loops directly in children or nested in fragments.
|
|
6772
6773
|
*/
|
|
6773
6774
|
function propagateSlotIdToLoops(children: IRNode[], slotId: string): void {
|
package/src/types.ts
CHANGED
|
@@ -386,7 +386,8 @@ export interface IRExpression {
|
|
|
386
386
|
* intersect the enclosing loop's `preamble.declaredNames`. Excludes the
|
|
387
387
|
* node from `collectLoopChildReactiveTexts` (which patches via
|
|
388
388
|
* `.textContent`, wrong for markup) regardless of `reactive` / `slotId` —
|
|
389
|
-
* the region-patch effect (
|
|
389
|
+
* the region-patch effect (a claimed 'markup' slot writer, slot
|
|
390
|
+
* unification A3) is its only wiring.
|
|
390
391
|
*/
|
|
391
392
|
preambleRegion?: boolean
|
|
392
393
|
/** When true, expression calls signal getters or memos (has reactive `foo()` pattern). */
|
|
@@ -400,6 +401,28 @@ export interface IRExpression {
|
|
|
400
401
|
* source of truth for free-reference / reactivity classification.
|
|
401
402
|
*/
|
|
402
403
|
origin: OriginInfo
|
|
404
|
+
/**
|
|
405
|
+
* Slot unification Step B (`spec/slot-unification.md` §3(b), §5 Step B):
|
|
406
|
+
* true when this slot's `<!--bf:sN-->…<!--/-->` marker pair can be safely
|
|
407
|
+
* omitted from BOTH SSR and CSR output, because `elidedPath` already gives
|
|
408
|
+
* every claimer a real compile-time DOM path to the slot's position.
|
|
409
|
+
* Decided EXACTLY ONCE, by `client-only-elision.ts`, before either
|
|
410
|
+
* `adapter.generate()` (SSR) or `generateClientJs()` (CSR) run — every one
|
|
411
|
+
* of the nine SSR adapters' `renderExpression` and the CSR template
|
|
412
|
+
* emitters (`html-template.ts`) read this single flag and must never
|
|
413
|
+
* re-derive their own elision decision. Unset/false is always safe
|
|
414
|
+
* (keeps markers, today's behavior); only the compiler pass above may
|
|
415
|
+
* ever set it true.
|
|
416
|
+
*/
|
|
417
|
+
markerless?: boolean
|
|
418
|
+
/**
|
|
419
|
+
* Root-relative child-index path to this slot's position (parent index
|
|
420
|
+
* chain, LAST element = the index of the slot itself within its parent's
|
|
421
|
+
* `childNodes`). Valid, and required, only when `markerless` is true —
|
|
422
|
+
* see `SlotSpec.markerless` in `@barefootjs/client/runtime/claim-slots.ts`
|
|
423
|
+
* for the claim-time resolve-or-create semantics this path feeds.
|
|
424
|
+
*/
|
|
425
|
+
elidedPath?: readonly number[]
|
|
403
426
|
}
|
|
404
427
|
|
|
405
428
|
export interface IRConditional {
|
|
@@ -723,7 +746,7 @@ export interface IRLoop {
|
|
|
723
746
|
* `slotId` is emitted as the usual `<!--bf:sN-->...<!--/-->` marker pair
|
|
724
747
|
* (same door as a reactive text slot — `irToHtmlTemplate` / Hono's
|
|
725
748
|
* `renderExpression` key off `slotId` alone), but the CLIENT wiring is a
|
|
726
|
-
* distinct
|
|
749
|
+
* distinct claimed 'markup'-slot region-patch effect (`preambleRegions`
|
|
727
750
|
* in the client-JS loop plan), NOT a `reactiveTexts` entry — patching via
|
|
728
751
|
* `.textContent` would escape markup that a `joinArrayChild` region must
|
|
729
752
|
* render raw. `collectLoopChildReactiveTexts` excludes any node collected
|