@barefootjs/client 0.28.1 → 0.29.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/runtime/component.d.ts +28 -1
- package/dist/runtime/component.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +17 -1
- package/dist/runtime/map-array.d.ts.map +1 -1
- package/dist/runtime/qsa-item.d.ts +15 -11
- package/dist/runtime/qsa-item.d.ts.map +1 -1
- package/dist/runtime/standalone.js +17 -1
- package/package.json +2 -2
- package/src/runtime/component.ts +37 -2
- package/src/runtime/index.ts +1 -0
- package/src/runtime/map-array.ts +15 -6
- package/src/runtime/qsa-item.ts +22 -12
|
@@ -6,12 +6,39 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { ComponentDef } from './types.ts';
|
|
8
8
|
export declare function setParentScopeId(id: string | null): void;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Where `mapArray` wants a fresh loop row connected before its `init` runs.
|
|
11
|
+
*
|
|
12
|
+
* `mounted` is written back by `mountRowRoot` so the caller can undo the
|
|
13
|
+
* connection if the rest of the row's body then throws — see `createItemScope`.
|
|
14
|
+
* Without it a half-built row stays visible, which detached rows never did.
|
|
15
|
+
*/
|
|
10
16
|
export type RowMountPoint = {
|
|
11
17
|
container: Node;
|
|
12
18
|
anchor: Node | null;
|
|
19
|
+
mounted?: Element | null;
|
|
13
20
|
};
|
|
14
21
|
export declare function setRowMountPoint(p: RowMountPoint | null): RowMountPoint | null;
|
|
22
|
+
/**
|
|
23
|
+
* Connect a loop row whose root is a template clone, before the emitted
|
|
24
|
+
* renderItem body's tail runs.
|
|
25
|
+
*
|
|
26
|
+
* The tail is where the row's nested children initialise (`upsertChild` and
|
|
27
|
+
* friends), and `useContext` resolves by walking `parentElement` — so a child
|
|
28
|
+
* that inits inside a detached row finds no ancestors and falls through to the
|
|
29
|
+
* global last-writer-wins context store, reading whichever provider on the page
|
|
30
|
+
* wrote last. `createComponent` row roots already avoid this by consuming the
|
|
31
|
+
* same ambient (step 7b); a clone root has no runtime function in the middle,
|
|
32
|
+
* so the compiler emits this call for it instead.
|
|
33
|
+
*
|
|
34
|
+
* Take-and-clear, like the `createComponent` path: a nested `createComponent`
|
|
35
|
+
* driven by this row's own children must not re-use the row's mount point.
|
|
36
|
+
*
|
|
37
|
+
* No-op when there is no ambient point — the hydration branch never calls this
|
|
38
|
+
* (its row came from SSR markup and is already in the document), and a loop
|
|
39
|
+
* runtime that does not hand one down leaves the row exactly as it was.
|
|
40
|
+
*/
|
|
41
|
+
export declare function mountRowRoot(el: Element): Element;
|
|
15
42
|
/**
|
|
16
43
|
* Create a component instance with DOM element and initialized state.
|
|
17
44
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/runtime/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAS9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExD;AAED
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/runtime/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAS9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAA;AAsB9F,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAI9E;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAQjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;;;GAGG;AACH;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,EAC9B,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,WAAW,CAcb;AA2ND;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAiDR;AA+DD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG9D;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAcjF"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { mapArrayLazy, type LazyRowEntry, type LazyRowPlan } from './map-array-l
|
|
|
15
15
|
export { patchLeaf } from './patch-leaf.ts';
|
|
16
16
|
export { claimSlots, lazySlots, lazyClaimSlots, textOrNode, type SlotSpec, type ClaimPlan, type ClaimedSlots, type ClaimedSlotsRW, type SlotWriter } from './claim-slots.ts';
|
|
17
17
|
export { registerTemplate, getTemplate, hasTemplate, type TemplateFn } from './template.ts';
|
|
18
|
-
export { createComponent, renderChild, parseHTML, escapeAttr, escapeText, escapeTextOrNode, } from './component.ts';
|
|
18
|
+
export { createComponent, mountRowRoot, renderChild, parseHTML, escapeAttr, escapeText, escapeTextOrNode, } from './component.ts';
|
|
19
19
|
export { applyRestAttrs } from './apply-rest-attrs.ts';
|
|
20
20
|
export { spreadAttrs } from './spread-attrs.ts';
|
|
21
21
|
export { styleToCss } from './style.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/index.js
CHANGED
|
@@ -1361,6 +1361,14 @@ function takeRowMountPoint() {
|
|
|
1361
1361
|
_rowMountPoint = null;
|
|
1362
1362
|
return p;
|
|
1363
1363
|
}
|
|
1364
|
+
function mountRowRoot(el) {
|
|
1365
|
+
const p = takeRowMountPoint();
|
|
1366
|
+
if (p) {
|
|
1367
|
+
p.container.insertBefore(el, p.anchor);
|
|
1368
|
+
p.mounted = el;
|
|
1369
|
+
}
|
|
1370
|
+
return el;
|
|
1371
|
+
}
|
|
1364
1372
|
function createComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1365
1373
|
const element = materializeComponent(nameOrDef, props, key, slot, mountAt);
|
|
1366
1374
|
if (mountAt && mountAt.parentNode && element !== mountAt) {
|
|
@@ -1738,7 +1746,7 @@ function* itemRootElements(primaryEl) {
|
|
|
1738
1746
|
if (n.nodeType === Node.COMMENT_NODE) {
|
|
1739
1747
|
const v = n.nodeValue ?? "";
|
|
1740
1748
|
if (v === BF_LOOP_ITEM || v === BF_LOOP_START || v.startsWith(startPrefix) || v === BF_LOOP_END || v.startsWith(endPrefix)) {
|
|
1741
|
-
|
|
1749
|
+
break;
|
|
1742
1750
|
}
|
|
1743
1751
|
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
|
1744
1752
|
yield n;
|
|
@@ -1911,9 +1919,16 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
1911
1919
|
const prevRowMount = ownsRowMount ? setRowMountPoint(rowMount) : null;
|
|
1912
1920
|
try {
|
|
1913
1921
|
primaryEl = renderItem(itemAccessor, index, existingPrimary);
|
|
1922
|
+
} catch (err) {
|
|
1923
|
+
const parked = rowMount?.mounted;
|
|
1924
|
+
if (parked?.parentNode)
|
|
1925
|
+
parked.remove();
|
|
1926
|
+
throw err;
|
|
1914
1927
|
} finally {
|
|
1915
1928
|
if (ownsRowMount)
|
|
1916
1929
|
setRowMountPoint(prevRowMount);
|
|
1930
|
+
if (rowMount)
|
|
1931
|
+
rowMount.mounted = null;
|
|
1917
1932
|
}
|
|
1918
1933
|
if (existingPrimary) {
|
|
1919
1934
|
extras = existingExtras ?? [];
|
|
@@ -3248,6 +3263,7 @@ export {
|
|
|
3248
3263
|
parseHTML,
|
|
3249
3264
|
onMount,
|
|
3250
3265
|
onCleanup,
|
|
3266
|
+
mountRowRoot,
|
|
3251
3267
|
mapArrayLazy,
|
|
3252
3268
|
mapArrayAnchored,
|
|
3253
3269
|
mapArray,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-array.d.ts","sourceRoot":"","sources":["../../src/runtime/map-array.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAqCH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,WAAW,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CA+BhD;AA8DD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA2B3E;
|
|
1
|
+
{"version":3,"file":"map-array.d.ts","sourceRoot":"","sources":["../../src/runtime/map-array.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAqCH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,WAAW,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CA+BhD;AA8DD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA2B3E;AA2FD;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,CAAC,EAAE,EACnB,SAAS,EAAE,WAAW,GAAG,IAAI,EAC7B,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,EACnD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,KAAK,WAAW,EACjF,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CA6RN;AAqHD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,EAAE,EACnB,SAAS,EAAE,WAAW,GAAG,IAAI,EAC7B,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,EACnD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,gBAAgB,GAAG,OAAO,EAC5F,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CA+FN"}
|
|
@@ -20,18 +20,22 @@
|
|
|
20
20
|
* cannot escape into a neighbouring item or into nodes outside the
|
|
21
21
|
* loop.
|
|
22
22
|
* 3. The CSR-only `__bfExtras` stash. During renderItem-body setup
|
|
23
|
-
* (between the template clone and the function's return), the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* lookups reach the still-pending extras before `mapArray` inserts
|
|
27
|
-
* them into the DOM.
|
|
23
|
+
* (between the template clone and the function's return), the extras
|
|
24
|
+
* are not siblings yet. Reading `__bfExtras` lets lookups reach them
|
|
25
|
+
* before `mapArray` inserts them into the DOM.
|
|
28
26
|
*
|
|
29
|
-
* Step 3
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
27
|
+
* Step 3 must stay reachable whether or not the primary is attached, which
|
|
28
|
+
* is why step 2 ends its walk with `break` rather than `return`. Only the
|
|
29
|
+
* sibling walk is bounded; ending the generator there would skip the stash.
|
|
30
|
+
*
|
|
31
|
+
* This used to be a `return`, and the difference was invisible: with a
|
|
32
|
+
* detached primary `nextSibling` is `null`, so the walk never runs and
|
|
33
|
+
* control reaches the stash regardless. Attaching the primary made the very
|
|
34
|
+
* first sibling a boundary comment, which ended the generator before the
|
|
35
|
+
* stash was consulted and left the item's child placeholders unreplaced.
|
|
36
|
+
* Measured, not deduced — and note this is NOT the failure the earlier
|
|
37
|
+
* comment here described: the walk never ran past the item into a
|
|
38
|
+
* neighbouring one, it stopped correctly and then gave up too early.
|
|
35
39
|
*/
|
|
36
40
|
/**
|
|
37
41
|
* Find an element matching `selector` within an item's range. Searches
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qsa-item.d.ts","sourceRoot":"","sources":["../../src/runtime/qsa-item.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"qsa-item.d.ts","sourceRoot":"","sources":["../../src/runtime/qsa-item.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AA4CH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAQnF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,GAC3B,WAAW,GAAG,IAAI,CAuBpB"}
|
|
@@ -1767,6 +1767,14 @@ function takeRowMountPoint() {
|
|
|
1767
1767
|
_rowMountPoint = null;
|
|
1768
1768
|
return p;
|
|
1769
1769
|
}
|
|
1770
|
+
function mountRowRoot(el) {
|
|
1771
|
+
const p = takeRowMountPoint();
|
|
1772
|
+
if (p) {
|
|
1773
|
+
p.container.insertBefore(el, p.anchor);
|
|
1774
|
+
p.mounted = el;
|
|
1775
|
+
}
|
|
1776
|
+
return el;
|
|
1777
|
+
}
|
|
1770
1778
|
function createComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1771
1779
|
const element = materializeComponent(nameOrDef, props, key, slot, mountAt);
|
|
1772
1780
|
if (mountAt && mountAt.parentNode && element !== mountAt) {
|
|
@@ -2144,7 +2152,7 @@ function* itemRootElements(primaryEl) {
|
|
|
2144
2152
|
if (n.nodeType === Node.COMMENT_NODE) {
|
|
2145
2153
|
const v = n.nodeValue ?? "";
|
|
2146
2154
|
if (v === BF_LOOP_ITEM || v === BF_LOOP_START || v.startsWith(startPrefix) || v === BF_LOOP_END || v.startsWith(endPrefix)) {
|
|
2147
|
-
|
|
2155
|
+
break;
|
|
2148
2156
|
}
|
|
2149
2157
|
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
|
2150
2158
|
yield n;
|
|
@@ -2316,9 +2324,16 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2316
2324
|
const prevRowMount = ownsRowMount ? setRowMountPoint(rowMount) : null;
|
|
2317
2325
|
try {
|
|
2318
2326
|
primaryEl = renderItem(itemAccessor, index, existingPrimary);
|
|
2327
|
+
} catch (err) {
|
|
2328
|
+
const parked = rowMount?.mounted;
|
|
2329
|
+
if (parked?.parentNode)
|
|
2330
|
+
parked.remove();
|
|
2331
|
+
throw err;
|
|
2319
2332
|
} finally {
|
|
2320
2333
|
if (ownsRowMount)
|
|
2321
2334
|
setRowMountPoint(prevRowMount);
|
|
2335
|
+
if (rowMount)
|
|
2336
|
+
rowMount.mounted = null;
|
|
2322
2337
|
}
|
|
2323
2338
|
if (existingPrimary) {
|
|
2324
2339
|
extras = existingExtras ?? [];
|
|
@@ -3647,6 +3662,7 @@ export {
|
|
|
3647
3662
|
parseHTML,
|
|
3648
3663
|
onMount,
|
|
3649
3664
|
onCleanup,
|
|
3665
|
+
mountRowRoot,
|
|
3650
3666
|
mapArrayLazy,
|
|
3651
3667
|
mapArrayAnchored,
|
|
3652
3668
|
mapArray,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"directory": "packages/client"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@barefootjs/shared": "0.
|
|
58
|
+
"@barefootjs/shared": "0.29.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@barefootjs/jsx": ">=0.2.0"
|
package/src/runtime/component.ts
CHANGED
|
@@ -25,8 +25,14 @@ export function setParentScopeId(id: string | null): void {
|
|
|
25
25
|
_parentScopeId = id
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Where `mapArray` wants a fresh loop row connected before its `init` runs.
|
|
30
|
+
*
|
|
31
|
+
* `mounted` is written back by `mountRowRoot` so the caller can undo the
|
|
32
|
+
* connection if the rest of the row's body then throws — see `createItemScope`.
|
|
33
|
+
* Without it a half-built row stays visible, which detached rows never did.
|
|
34
|
+
*/
|
|
35
|
+
export type RowMountPoint = { container: Node; anchor: Node | null; mounted?: Element | null }
|
|
30
36
|
|
|
31
37
|
// Ambient mount point for a loop row.
|
|
32
38
|
//
|
|
@@ -60,6 +66,35 @@ function takeRowMountPoint(): RowMountPoint | null {
|
|
|
60
66
|
return p
|
|
61
67
|
}
|
|
62
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Connect a loop row whose root is a template clone, before the emitted
|
|
71
|
+
* renderItem body's tail runs.
|
|
72
|
+
*
|
|
73
|
+
* The tail is where the row's nested children initialise (`upsertChild` and
|
|
74
|
+
* friends), and `useContext` resolves by walking `parentElement` — so a child
|
|
75
|
+
* that inits inside a detached row finds no ancestors and falls through to the
|
|
76
|
+
* global last-writer-wins context store, reading whichever provider on the page
|
|
77
|
+
* wrote last. `createComponent` row roots already avoid this by consuming the
|
|
78
|
+
* same ambient (step 7b); a clone root has no runtime function in the middle,
|
|
79
|
+
* so the compiler emits this call for it instead.
|
|
80
|
+
*
|
|
81
|
+
* Take-and-clear, like the `createComponent` path: a nested `createComponent`
|
|
82
|
+
* driven by this row's own children must not re-use the row's mount point.
|
|
83
|
+
*
|
|
84
|
+
* No-op when there is no ambient point — the hydration branch never calls this
|
|
85
|
+
* (its row came from SSR markup and is already in the document), and a loop
|
|
86
|
+
* runtime that does not hand one down leaves the row exactly as it was.
|
|
87
|
+
*/
|
|
88
|
+
export function mountRowRoot(el: Element): Element {
|
|
89
|
+
const p = takeRowMountPoint()
|
|
90
|
+
if (p) {
|
|
91
|
+
p.container.insertBefore(el, p.anchor)
|
|
92
|
+
// Record it so the row can be un-mounted if the body throws after this.
|
|
93
|
+
p.mounted = el
|
|
94
|
+
}
|
|
95
|
+
return el
|
|
96
|
+
}
|
|
97
|
+
|
|
63
98
|
/**
|
|
64
99
|
* Create a component instance with DOM element and initialized state.
|
|
65
100
|
*
|
package/src/runtime/index.ts
CHANGED
package/src/runtime/map-array.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import { createSignal, createEffect, createRoot } from '@barefootjs/client/reactive'
|
|
22
22
|
import { hydratedScopes } from './hydration-state.ts'
|
|
23
|
-
import { setRowMountPoint } from './component.ts'
|
|
23
|
+
import { setRowMountPoint, type RowMountPoint } from './component.ts'
|
|
24
24
|
import {
|
|
25
25
|
BF_KEY,
|
|
26
26
|
BF_LOOP_START,
|
|
@@ -234,7 +234,7 @@ function createItemScope<T>(
|
|
|
234
234
|
existingPrimary?: HTMLElement,
|
|
235
235
|
existingExtras?: HTMLElement[],
|
|
236
236
|
existingStart?: Comment | null,
|
|
237
|
-
rowMount?:
|
|
237
|
+
rowMount?: RowMountPoint | null,
|
|
238
238
|
): ItemScope<T> {
|
|
239
239
|
let primaryEl!: HTMLElement
|
|
240
240
|
let dispose!: () => void
|
|
@@ -246,10 +246,11 @@ function createItemScope<T>(
|
|
|
246
246
|
dispose = d
|
|
247
247
|
const [itemAccessor, itemSetter] = createSignal(item)
|
|
248
248
|
setItem = itemSetter
|
|
249
|
-
// Fresh row: hand the mount point
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
249
|
+
// Fresh row: hand the mount point down so the row's own root — whether a
|
|
250
|
+
// `createComponent` call or a `mountRowRoot(clone)` — observes a connected
|
|
251
|
+
// element when the body's tail initialises its children. A body that does
|
|
252
|
+
// neither (a plain loop's clone) leaves the point unconsumed, hence the
|
|
253
|
+
// restore below rather than a plain clear.
|
|
253
254
|
//
|
|
254
255
|
// Only touch the ambient when we are the one setting it, and put back what
|
|
255
256
|
// was there rather than `null`: this row's `init` can drive a nested
|
|
@@ -259,8 +260,16 @@ function createItemScope<T>(
|
|
|
259
260
|
const prevRowMount = ownsRowMount ? setRowMountPoint(rowMount) : null
|
|
260
261
|
try {
|
|
261
262
|
primaryEl = renderItem(itemAccessor, index, existingPrimary)
|
|
263
|
+
} catch (err) {
|
|
264
|
+
// A row that connected itself and then failed to finish would stay
|
|
265
|
+
// visible as a half-built row. Detached rows never could, so undo the
|
|
266
|
+
// connection before rethrowing and keep the failure mode as it was.
|
|
267
|
+
const parked = rowMount?.mounted
|
|
268
|
+
if (parked?.parentNode) parked.remove()
|
|
269
|
+
throw err
|
|
262
270
|
} finally {
|
|
263
271
|
if (ownsRowMount) setRowMountPoint(prevRowMount)
|
|
272
|
+
if (rowMount) rowMount.mounted = null
|
|
264
273
|
}
|
|
265
274
|
if (existingPrimary) {
|
|
266
275
|
extras = existingExtras ?? []
|
package/src/runtime/qsa-item.ts
CHANGED
|
@@ -20,18 +20,22 @@
|
|
|
20
20
|
* cannot escape into a neighbouring item or into nodes outside the
|
|
21
21
|
* loop.
|
|
22
22
|
* 3. The CSR-only `__bfExtras` stash. During renderItem-body setup
|
|
23
|
-
* (between the template clone and the function's return), the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* lookups reach the still-pending extras before `mapArray` inserts
|
|
27
|
-
* them into the DOM.
|
|
23
|
+
* (between the template clone and the function's return), the extras
|
|
24
|
+
* are not siblings yet. Reading `__bfExtras` lets lookups reach them
|
|
25
|
+
* before `mapArray` inserts them into the DOM.
|
|
28
26
|
*
|
|
29
|
-
* Step 3
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
27
|
+
* Step 3 must stay reachable whether or not the primary is attached, which
|
|
28
|
+
* is why step 2 ends its walk with `break` rather than `return`. Only the
|
|
29
|
+
* sibling walk is bounded; ending the generator there would skip the stash.
|
|
30
|
+
*
|
|
31
|
+
* This used to be a `return`, and the difference was invisible: with a
|
|
32
|
+
* detached primary `nextSibling` is `null`, so the walk never runs and
|
|
33
|
+
* control reaches the stash regardless. Attaching the primary made the very
|
|
34
|
+
* first sibling a boundary comment, which ended the generator before the
|
|
35
|
+
* stash was consulted and left the item's child placeholders unreplaced.
|
|
36
|
+
* Measured, not deduced — and note this is NOT the failure the earlier
|
|
37
|
+
* comment here described: the walk never ran past the item into a
|
|
38
|
+
* neighbouring one, it stopped correctly and then gave up too early.
|
|
35
39
|
*/
|
|
36
40
|
|
|
37
41
|
import { BF_LOOP_ITEM, BF_LOOP_START, BF_LOOP_END } from '@barefootjs/shared'
|
|
@@ -51,10 +55,16 @@ function* itemRootElements(primaryEl: Element): Iterable<Element> {
|
|
|
51
55
|
// Hard stops: another item starts, or the loop range ends. The
|
|
52
56
|
// BF_LOOP_START check defends against a sibling loop block whose
|
|
53
57
|
// start marker happens to follow ours.
|
|
58
|
+
// `break`, not `return`: stop the SIBLING walk, but still fall through
|
|
59
|
+
// to the `__bfExtras` stash below. A `return` ends the generator, and
|
|
60
|
+
// the stash is the only way to reach extras that are not siblings yet.
|
|
61
|
+
// That difference is invisible while the primary is detached — then
|
|
62
|
+
// `nextSibling` is `null`, this loop never runs, and control reaches the
|
|
63
|
+
// stash anyway — and decides the outcome the moment it is attached.
|
|
54
64
|
if (v === BF_LOOP_ITEM
|
|
55
65
|
|| v === BF_LOOP_START || v.startsWith(startPrefix)
|
|
56
66
|
|| v === BF_LOOP_END || v.startsWith(endPrefix)) {
|
|
57
|
-
|
|
67
|
+
break
|
|
58
68
|
}
|
|
59
69
|
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
|
60
70
|
yield n as Element
|