@barefootjs/client 0.33.0 → 0.33.2

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.
@@ -1737,8 +1737,7 @@ function hydrateCommentScope(comment) {
1737
1737
  if (hydratedScopes.has(proxyEl))
1738
1738
  return;
1739
1739
  commentScopeRegistry.set(proxyEl, { commentNode: comment, scopeId });
1740
- const parsed = parseProps(propsJson || null, `comment scope ${scopeId}`);
1741
- const props = parsed[name] ?? {};
1740
+ const props = parseProps(propsJson || null, `comment scope ${scopeId}`);
1742
1741
  runInit(proxyEl, def, props);
1743
1742
  }
1744
1743
  function nextElementSibling2(node) {
@@ -1818,8 +1817,9 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
1818
1817
  });
1819
1818
  const def = getRegisteredDef(name);
1820
1819
  const isCommentWrapper = def?.comment === true;
1820
+ const isFragmentRoot = def?.fragmentRoot === true;
1821
1821
  const derivedScopeId = slot?.parent && slot.mount ? `${slot.parent}_${slot.mount}` : null;
1822
- const scopeId = isCommentWrapper ? null : derivedScopeId ?? `${def?.name ?? name}_${generateId()}`;
1822
+ const scopeId = isCommentWrapper && !isFragmentRoot ? null : derivedScopeId ?? `${def?.name ?? name}_${generateId()}`;
1823
1823
  const prevParentScopeId = _parentScopeId;
1824
1824
  if (scopeId) {
1825
1825
  _parentScopeId = scopeId;
@@ -1832,12 +1832,18 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
1832
1832
  } finally {
1833
1833
  _parentScopeId = prevParentScopeId;
1834
1834
  }
1835
- const element = parseHTML(html.trim()).firstChild;
1835
+ const parsedFragment = parseHTML(html.trim());
1836
+ const roots = isFragmentRoot ? Array.from(parsedFragment.childNodes) : parsedFragment.firstChild ? [parsedFragment.firstChild] : [];
1837
+ const element = isFragmentRoot ? roots.find((node) => node.nodeType === Node.ELEMENT_NODE) : roots[0];
1838
+ if (isFragmentRoot && roots.length > 0 && !element) {
1839
+ console.warn(`[BarefootJS] Fragment-root component ${name} rendered no element root; ` + "a scope needs at least one element to attach to. Wrap the content in an element.");
1840
+ return createPlaceholder(name, key);
1841
+ }
1836
1842
  if (!element) {
1837
1843
  console.warn(`[BarefootJS] Template returned empty HTML for component: ${name}`);
1838
1844
  return createPlaceholder(name, key);
1839
1845
  }
1840
- if (scopeId) {
1846
+ if (scopeId && !isFragmentRoot) {
1841
1847
  element.setAttribute(BF_SCOPE, scopeId);
1842
1848
  }
1843
1849
  if (slot) {
@@ -1848,11 +1854,36 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
1848
1854
  if (key !== undefined) {
1849
1855
  element.setAttribute(BF_KEY, String(key));
1850
1856
  }
1857
+ const fragmentComments = isFragmentRoot && scopeId ? {
1858
+ start: document.createComment(`${BF_SCOPE_COMMENT_PREFIX}${scopeId}`),
1859
+ end: document.createComment(`${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}`)
1860
+ } : null;
1861
+ if (fragmentComments) {
1862
+ commentScopeRegistry.set(element, { commentNode: fragmentComments.start, scopeId });
1863
+ }
1851
1864
  const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
1865
+ let bareFragment = null;
1852
1866
  if (mountAt && !rootIsDeferredPlaceholder) {
1853
- mountAt.replaceWith(element);
1867
+ if (fragmentComments) {
1868
+ mountAt.replaceWith(fragmentComments.start, ...roots, fragmentComments.end);
1869
+ } else {
1870
+ mountAt.replaceWith(element);
1871
+ }
1854
1872
  } else if (rowMount && !rootIsDeferredPlaceholder) {
1855
- rowMount.container.insertBefore(element, rowMount.anchor);
1873
+ if (fragmentComments) {
1874
+ rowMount.container.insertBefore(fragmentComments.start, rowMount.anchor);
1875
+ rowMount.container.insertBefore(element, rowMount.anchor);
1876
+ rowMount.container.insertBefore(fragmentComments.end, rowMount.anchor);
1877
+ element.__bfScopeComments = fragmentComments;
1878
+ if (roots.length > 1) {
1879
+ console.warn(`[BarefootJS] Fragment-root component ${name} used as a loop row renders ` + `${roots.length} top-level nodes; only the first element is connected here. ` + "See https://github.com/piconic-ai/barefootjs/issues/2733");
1880
+ }
1881
+ } else {
1882
+ rowMount.container.insertBefore(element, rowMount.anchor);
1883
+ }
1884
+ } else if (fragmentComments && !rootIsDeferredPlaceholder) {
1885
+ bareFragment = document.createDocumentFragment();
1886
+ bareFragment.append(fragmentComments.start, ...roots, fragmentComments.end);
1856
1887
  }
1857
1888
  const prevScope = setCurrentScope(element);
1858
1889
  let placeholderWrapper = null;
@@ -1880,22 +1911,46 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
1880
1911
  }
1881
1912
  setCurrentScope(prevScope);
1882
1913
  hydratedScopes.add(element);
1883
- return element;
1914
+ return bareFragment ?? element;
1915
+ }
1916
+ var FIRST_TAG_PATTERN = /<([a-zA-Z][^\s/>]*)/;
1917
+ var TAG_HEAD_PATTERN = /^(<[a-zA-Z][^\s/>]*)/;
1918
+ function spliceAttrsAfterFirstTag(html, attrs) {
1919
+ const firstElMatch = html.match(FIRST_TAG_PATTERN);
1920
+ if (!firstElMatch)
1921
+ return html;
1922
+ const insertPos = firstElMatch.index;
1923
+ return html.slice(0, insertPos) + html.slice(insertPos).replace(TAG_HEAD_PATTERN, `$1${attrs}`);
1884
1924
  }
1885
1925
  function renderChild(name, props, key, slotSuffix) {
1886
1926
  const templateFn = getTemplate(name);
1887
1927
  const suffix = slotSuffix ? `_${slotSuffix}` : "";
1888
- const displayName = getRegisteredDef(name)?.name ?? name;
1928
+ const def = getRegisteredDef(name);
1929
+ const displayName = def?.name ?? name;
1930
+ const isFragmentRoot = def?.fragmentRoot === true;
1889
1931
  const scopePrefix = _parentScopeId && slotSuffix ? _parentScopeId : `${displayName}_${generateId()}`;
1932
+ const scopeId = `${scopePrefix}${suffix}`;
1890
1933
  const keyAttr = key !== undefined ? ` ${BF_KEY}="${key}"` : "";
1891
1934
  const slotAttrs = _parentScopeId && slotSuffix ? ` ${BF_HOST}="${_parentScopeId}" ${BF_AT}="${slotSuffix}"` : "";
1892
- const bfsAttr = `${BF_SCOPE}="${scopePrefix}${suffix}"`;
1935
+ const bfsAttr = `${BF_SCOPE}="${scopeId}"`;
1893
1936
  if (!templateFn) {
1894
- return `<div ${bfsAttr}${slotAttrs}${keyAttr}></div>`;
1937
+ return isFragmentRoot ? `<!--${BF_SCOPE_COMMENT_PREFIX}${scopeId}--><div></div><!--${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}-->` : `<div ${bfsAttr}${slotAttrs}${keyAttr}></div>`;
1938
+ }
1939
+ const prevParentScopeId = _parentScopeId;
1940
+ _parentScopeId = `${scopePrefix}${suffix}`;
1941
+ let raw;
1942
+ try {
1943
+ raw = templateFn(props);
1944
+ } finally {
1945
+ _parentScopeId = prevParentScopeId;
1895
1946
  }
1896
- const raw = templateFn(props);
1897
1947
  let html = raw.trim().replace(PLACEHOLDER_ATTR_PATTERN, _parentScopeId ? ` bf-s="${_parentScopeId}"` : "");
1898
- const firstElMatch = html.match(/<(\w+)/);
1948
+ if (isFragmentRoot) {
1949
+ const hostSuffix = _parentScopeId && slotSuffix ? `|h=${_parentScopeId}|m=${slotSuffix}` : "";
1950
+ const keyedHtml = keyAttr ? spliceAttrsAfterFirstTag(html, keyAttr) : html;
1951
+ return `<!--${BF_SCOPE_COMMENT_PREFIX}${scopeId}${hostSuffix}-->${keyedHtml}<!--${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}-->`;
1952
+ }
1953
+ const firstElMatch = html.match(FIRST_TAG_PATTERN);
1899
1954
  if (!firstElMatch)
1900
1955
  return html;
1901
1956
  const insertPos = firstElMatch.index;
@@ -1904,9 +1959,9 @@ function renderChild(name, props, key, slotSuffix) {
1904
1959
  if (ROOT_HAS_BFS_PATTERN.test(afterInsert)) {
1905
1960
  if (!extraAttrs)
1906
1961
  return html;
1907
- return html.slice(0, insertPos) + afterInsert.replace(/^(<\w+)/, `$1${extraAttrs}`);
1962
+ return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1${extraAttrs}`);
1908
1963
  }
1909
- return html.slice(0, insertPos) + afterInsert.replace(/^(<\w+)/, `$1 ${bfsAttr}${extraAttrs}`);
1964
+ return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1 ${bfsAttr}${extraAttrs}`);
1910
1965
  }
1911
1966
  var PLACEHOLDER_ATTR_PATTERN = new RegExp(`\\s+bf-s="${BF_PARENT_SCOPE_PLACEHOLDER}"`, "g");
1912
1967
  var ROOT_HAS_BFS_PATTERN = /^<\w+[^>]*\sbf-s="/;
@@ -2236,6 +2291,11 @@ function upsertChildItem(primaryEl, name, slotId, props, key, anchorScope) {
2236
2291
  return null;
2237
2292
  }
2238
2293
  // src/runtime/map-array.ts
2294
+ function scopeIdOf(start) {
2295
+ const rest = (start.nodeValue ?? "").slice(BF_SCOPE_COMMENT_PREFIX.length);
2296
+ const pipe = rest.indexOf("|");
2297
+ return pipe >= 0 ? rest.slice(0, pipe) : rest;
2298
+ }
2239
2299
  function findLoopMarkers2(container, markerId) {
2240
2300
  let start = null;
2241
2301
  let end = null;
@@ -2273,31 +2333,55 @@ function findItemRanges(start, end) {
2273
2333
  const ranges = [];
2274
2334
  let current = null;
2275
2335
  let sawItemMarker = false;
2336
+ let pendingScopeStart = null;
2337
+ let openScopeComments = null;
2276
2338
  let node = start.nextSibling;
2277
2339
  while (node && node !== end) {
2278
- if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === BF_LOOP_ITEM) {
2279
- sawItemMarker = true;
2280
- current = { startMarker: node, primaryEl: null, extras: [] };
2281
- ranges.push(current);
2340
+ if (node.nodeType === Node.COMMENT_NODE) {
2341
+ const value = node.nodeValue ?? "";
2342
+ if (value === BF_LOOP_ITEM) {
2343
+ sawItemMarker = true;
2344
+ current = { startMarker: node, primaryEl: null, extras: [], scopeComments: null };
2345
+ ranges.push(current);
2346
+ } else if (value.startsWith(BF_SCOPE_COMMENT_PREFIX)) {
2347
+ pendingScopeStart = node;
2348
+ } else if (openScopeComments && value === BF_SCOPE_COMMENT_END_PREFIX + scopeIdOf(openScopeComments.start)) {
2349
+ openScopeComments.end = node;
2350
+ openScopeComments = null;
2351
+ }
2282
2352
  } else if (node.nodeType === Node.ELEMENT_NODE) {
2283
2353
  const el = node;
2354
+ let scopeComments = null;
2355
+ if (pendingScopeStart) {
2356
+ scopeComments = { start: pendingScopeStart, end: null };
2357
+ openScopeComments = scopeComments;
2358
+ pendingScopeStart = null;
2359
+ }
2284
2360
  if (sawItemMarker) {
2285
- if (!current.primaryEl)
2361
+ if (!current.primaryEl) {
2286
2362
  current.primaryEl = el;
2287
- else
2363
+ current.scopeComments = scopeComments;
2364
+ } else
2288
2365
  current.extras.push(el);
2289
2366
  } else {
2290
- ranges.push({ startMarker: null, primaryEl: el, extras: [] });
2367
+ ranges.push({ startMarker: null, primaryEl: el, extras: [], scopeComments });
2291
2368
  }
2292
2369
  }
2293
2370
  node = node.nextSibling;
2294
2371
  }
2295
- return ranges.filter((r) => r.primaryEl !== null);
2372
+ return ranges.filter((r) => r.primaryEl !== null).map((r) => ({
2373
+ ...r,
2374
+ scopeComments: r.scopeComments?.end ? r.scopeComments : null
2375
+ }));
2296
2376
  }
2297
2377
  function insertScope(scope, target, anchor) {
2298
2378
  if (scope.startMarker)
2299
2379
  target.insertBefore(scope.startMarker, anchor);
2380
+ if (scope.scopeComments)
2381
+ target.insertBefore(scope.scopeComments.start, anchor);
2300
2382
  target.insertBefore(scope.primaryEl, anchor);
2383
+ if (scope.scopeComments)
2384
+ target.insertBefore(scope.scopeComments.end, anchor);
2301
2385
  for (const ex of scope.extras)
2302
2386
  target.insertBefore(ex, anchor);
2303
2387
  }
@@ -2336,19 +2420,24 @@ function longestIncreasingSubsequenceIndices(arr) {
2336
2420
  function removeScope(scope) {
2337
2421
  if (scope.startMarker?.parentNode)
2338
2422
  scope.startMarker.remove();
2423
+ if (scope.scopeComments?.start.parentNode)
2424
+ scope.scopeComments.start.remove();
2339
2425
  if (scope.primaryEl.parentNode)
2340
2426
  scope.primaryEl.remove();
2427
+ if (scope.scopeComments?.end.parentNode)
2428
+ scope.scopeComments.end.remove();
2341
2429
  for (const ex of scope.extras) {
2342
2430
  if (ex.parentNode)
2343
2431
  ex.remove();
2344
2432
  }
2345
2433
  }
2346
- function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, rowMount) {
2434
+ function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, existingScopeComments, rowMount) {
2347
2435
  let primaryEl;
2348
2436
  let dispose;
2349
2437
  let setItem;
2350
2438
  let extras = [];
2351
2439
  let startMarker = null;
2440
+ let scopeComments = null;
2352
2441
  createRoot((d) => {
2353
2442
  dispose = d;
2354
2443
  const [itemAccessor, itemSetter] = createSignal(item);
@@ -2371,6 +2460,7 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
2371
2460
  if (existingPrimary) {
2372
2461
  extras = existingExtras ?? [];
2373
2462
  startMarker = existingStart ?? null;
2463
+ scopeComments = existingScopeComments ?? null;
2374
2464
  } else {
2375
2465
  const stashed = primaryEl.__bfExtras;
2376
2466
  if (stashed && stashed.length > 0) {
@@ -2378,13 +2468,17 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
2378
2468
  startMarker = document.createComment(BF_LOOP_ITEM);
2379
2469
  }
2380
2470
  delete primaryEl.__bfExtras;
2471
+ const stashedScopeComments = primaryEl.__bfScopeComments;
2472
+ if (stashedScopeComments)
2473
+ scopeComments = stashedScopeComments;
2474
+ delete primaryEl.__bfScopeComments;
2381
2475
  }
2382
2476
  return;
2383
2477
  });
2384
2478
  if (rowMount && !existingPrimary && extras.length > 0 && primaryEl.parentNode) {
2385
2479
  primaryEl.remove();
2386
2480
  }
2387
- return { startMarker, primaryEl, extras, dispose, setItem };
2481
+ return { startMarker, primaryEl, extras, scopeComments, dispose, setItem };
2388
2482
  }
2389
2483
  function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2390
2484
  if (!container)
@@ -2410,7 +2504,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2410
2504
  const anchor = endMarker ?? null;
2411
2505
  if (!hydrated) {
2412
2506
  hydrated = true;
2413
- const existingRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [] }));
2507
+ const existingRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [], scopeComments: null }));
2414
2508
  const needsHydration = existingRanges.length > 0 && (!existingRanges[0]?.primaryEl.hasAttribute("data-key") || scopes.size === 0);
2415
2509
  if (needsHydration) {
2416
2510
  for (let i2 = 0;i2 < existingRanges.length && i2 < items.length; i2++) {
@@ -2418,14 +2512,14 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2418
2512
  const item = items[i2];
2419
2513
  const key = getKey ? getKey(item, i2) : String(i2);
2420
2514
  range.primaryEl.setAttribute(BF_KEY, key);
2421
- const scope = createItemScope(item, i2, renderItem, range.primaryEl, range.extras, range.startMarker);
2515
+ const scope = createItemScope(item, i2, renderItem, range.primaryEl, range.extras, range.startMarker, range.scopeComments);
2422
2516
  scopes.set(key, scope);
2423
2517
  hydratedScopes.add(range.primaryEl);
2424
2518
  }
2425
2519
  for (let i2 = existingRanges.length;i2 < items.length; i2++) {
2426
2520
  const item = items[i2];
2427
2521
  const key = getKey ? getKey(item, i2) : String(i2);
2428
- const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
2522
+ const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
2429
2523
  if (!scope.primaryEl.dataset.key)
2430
2524
  scope.primaryEl.setAttribute(BF_KEY, key);
2431
2525
  scopes.set(key, scope);
@@ -2435,8 +2529,12 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2435
2529
  const range = existingRanges[i2];
2436
2530
  if (range.startMarker?.parentNode)
2437
2531
  range.startMarker.remove();
2532
+ if (range.scopeComments?.start.parentNode)
2533
+ range.scopeComments.start.remove();
2438
2534
  if (range.primaryEl.parentNode)
2439
2535
  range.primaryEl.remove();
2536
+ if (range.scopeComments?.end.parentNode)
2537
+ range.scopeComments.end.remove();
2440
2538
  for (const ex of range.extras) {
2441
2539
  if (ex.parentNode)
2442
2540
  ex.remove();
@@ -2446,7 +2544,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2446
2544
  }
2447
2545
  }
2448
2546
  if (scopes.size === 0) {
2449
- const loopRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [] }));
2547
+ const loopRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [], scopeComments: null }));
2450
2548
  for (const range of loopRanges) {
2451
2549
  const existingKey = range.primaryEl.dataset?.key;
2452
2550
  if (existingKey && !scopes.has(existingKey)) {
@@ -2454,6 +2552,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2454
2552
  startMarker: range.startMarker,
2455
2553
  primaryEl: range.primaryEl,
2456
2554
  extras: range.extras,
2555
+ scopeComments: range.scopeComments,
2457
2556
  dispose: () => {},
2458
2557
  setItem: () => {}
2459
2558
  });
@@ -2472,7 +2571,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2472
2571
  } else {
2473
2572
  let expectedNodeCount = 0;
2474
2573
  for (const scope of scopes.values()) {
2475
- expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0);
2574
+ expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0) + (scope.scopeComments ? 2 : 0);
2476
2575
  }
2477
2576
  let actualNodeCount = 0;
2478
2577
  for (let node = container.firstChild;node; node = node.nextSibling)
@@ -2504,7 +2603,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2504
2603
  existing.setItem(item);
2505
2604
  desiredOrder.push(existing);
2506
2605
  } else {
2507
- const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
2606
+ const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
2508
2607
  if (!scope.primaryEl.dataset.key)
2509
2608
  scope.primaryEl.setAttribute(BF_KEY, key);
2510
2609
  scopes.set(key, scope);
@@ -2543,7 +2642,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
2543
2642
  let j = i;
2544
2643
  while (j < desiredOrder.length && !stationary[j])
2545
2644
  j++;
2546
- const before = j < desiredOrder.length ? desiredOrder[j].startMarker ?? desiredOrder[j].primaryEl : anchor;
2645
+ const before = j < desiredOrder.length ? desiredOrder[j].startMarker ?? desiredOrder[j].scopeComments?.start ?? desiredOrder[j].primaryEl : anchor;
2547
2646
  if (j - i === 1) {
2548
2647
  insertScope(desiredOrder[i], container, before);
2549
2648
  } else {
@@ -3316,6 +3415,15 @@ function findCondStartInRange(anchor, id) {
3316
3415
  }
3317
3416
  return null;
3318
3417
  }
3418
+ function findCondContainer(scope, id) {
3419
+ const want = `bf-cond-start:${id}`;
3420
+ for (const comment of commentsInScope(scope)) {
3421
+ if (comment.nodeValue === want) {
3422
+ return comment.parentElement ?? scope;
3423
+ }
3424
+ }
3425
+ return scope;
3426
+ }
3319
3427
  var EMPTY_SLOTS = [];
3320
3428
  function normalizeTemplate(value) {
3321
3429
  return typeof value === "string" ? { html: value, slots: EMPTY_SLOTS } : value;
@@ -3718,6 +3826,7 @@ export {
3718
3826
  flushHydration,
3719
3827
  findSiblingSlot,
3720
3828
  findScope,
3829
+ findCondContainer,
3721
3830
  find,
3722
3831
  escapeTextOrNode,
3723
3832
  escapeTextOrMarkup,
@@ -20,7 +20,25 @@ export interface ComponentDef {
20
20
  init: InitFn;
21
21
  /** Template function for client-side component creation */
22
22
  template?: (props: Record<string, unknown>) => string;
23
- /** When true, use comment-based scope hydration (fragment roots) */
23
+ /**
24
+ * When true, this component's scope has no `bf-s`-carrying element of
25
+ * its own — a proxy element stands in for it. Set for TWO distinct
26
+ * shapes (see `fragmentRoot` below, which tells them apart):
27
+ * - a genuine fragment root (`<>...</>`), where the proxy is the
28
+ * fragment's own rendered content;
29
+ * - a root that is itself a single child component call, where the
30
+ * proxy is that child's own already-scoped element (#2649).
31
+ */
24
32
  comment?: boolean;
33
+ /**
34
+ * True only for the genuine-fragment-root shape of `comment` above
35
+ * (`ir.root.type === 'fragment'`) — never for the root-is-a-child-call
36
+ * shape. `materializeComponent` (component.ts) uses this to decide
37
+ * whether a CSR mount must generate its OWN scope id (fragment root: yes,
38
+ * so nested `renderChild()` calls get parent-prefixed naming matching
39
+ * SSR/hydrate) or leave the scope id null to avoid overwriting the
40
+ * child's own (#2649's shape, #2722).
41
+ */
42
+ fragmentRoot?: boolean;
25
43
  }
26
44
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrD,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrD;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/client",
3
- "version": "0.33.0",
3
+ "version": "0.33.2",
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.33.0"
58
+ "@barefootjs/shared": "0.33.2"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@barefootjs/jsx": ">=0.2.0"