@barefootjs/cli 0.5.1 → 0.5.3
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/docs/core/llms.txt +1 -0
- package/dist/docs/core/reactivity/batch.md +135 -0
- package/dist/docs/core/reactivity.md +2 -1
- package/dist/index.js +395 -148
- package/package.json +2 -2
package/dist/docs/core/llms.txt
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
## Reactivity
|
|
14
14
|
|
|
15
|
+
- [batch](https://barefootjs.dev/docs/reactivity/batch.md): Groups multiple signal writes so dependent effects and memos run once, after all writes complete.
|
|
15
16
|
- [createEffect](https://barefootjs.dev/docs/reactivity/create-effect.md): Runs a function and re-runs it whenever its tracked signal dependencies change.
|
|
16
17
|
- [createMemo](https://barefootjs.dev/docs/reactivity/create-memo.md): Creates a cached derived value that recomputes only when its dependencies change.
|
|
17
18
|
- [createSignal](https://barefootjs.dev/docs/reactivity/create-signal.md): Creates a reactive getter/setter pair for managing state.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: batch
|
|
3
|
+
description: Groups multiple signal writes so dependent effects and memos run once, after all writes complete.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# batch
|
|
7
|
+
|
|
8
|
+
Groups multiple signal writes so that dependent effects and memos run **once**,
|
|
9
|
+
after all the writes inside the batch complete — instead of once per write.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { batch } from '@barefootjs/client'
|
|
13
|
+
|
|
14
|
+
batch<T>(fn: () => T): T
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Returns the value produced by `fn`.
|
|
18
|
+
|
|
19
|
+
## Default behavior (no batch)
|
|
20
|
+
|
|
21
|
+
BarefootJS propagates updates **synchronously**: each setter call immediately
|
|
22
|
+
re-runs every subscriber. This keeps reads-after-writes predictable — after a
|
|
23
|
+
setter returns, derived memos, effects, and the DOM already reflect the new value.
|
|
24
|
+
|
|
25
|
+
The cost is that writing N signals that share a subscriber re-runs that
|
|
26
|
+
subscriber N times, and the subscriber briefly observes intermediate states
|
|
27
|
+
where some signals are updated and others are not:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
const [x, setX] = createSignal(40)
|
|
31
|
+
const [y, setY] = createSignal(60)
|
|
32
|
+
|
|
33
|
+
createEffect(() => {
|
|
34
|
+
// depends on both x and y
|
|
35
|
+
send({ x: x(), y: y() })
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
setX(70) // effect runs — observes x=70, y=60 (intermediate)
|
|
39
|
+
setY(30) // effect runs again — observes x=70, y=30
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Beyond its initial run on creation, the effect ran twice more — once per write —
|
|
43
|
+
and saw a transient `x=70, y=60` state.
|
|
44
|
+
|
|
45
|
+
## With batch
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
batch(() => {
|
|
49
|
+
setX(70)
|
|
50
|
+
setY(30)
|
|
51
|
+
})
|
|
52
|
+
// effect runs once, observing x=70, y=30
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Inside `batch`, writes are collected and dependent subscribers are de-duplicated,
|
|
56
|
+
so each runs **exactly once** after the batch ends — and never observes an
|
|
57
|
+
intermediate, half-updated state.
|
|
58
|
+
|
|
59
|
+
## When to use
|
|
60
|
+
|
|
61
|
+
When a single handler updates several signals that feed shared effects/memos,
|
|
62
|
+
`batch` collapses the work into one update pass — and keeps the subscriber from
|
|
63
|
+
running while a cross-field invariant is temporarily broken:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
const reset = () => {
|
|
67
|
+
batch(() => {
|
|
68
|
+
setName('')
|
|
69
|
+
setEmail('')
|
|
70
|
+
setAge(0)
|
|
71
|
+
// ...20 more fields
|
|
72
|
+
})
|
|
73
|
+
// every subscriber ran once, not once-per-field
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Caveats
|
|
78
|
+
|
|
79
|
+
### Derived values are stale *inside* the batch
|
|
80
|
+
|
|
81
|
+
`batch` defers the work that recomputes derived values. Plain signal reads return
|
|
82
|
+
the new value immediately, but **memos and effect-driven values stay stale until
|
|
83
|
+
the batch ends**:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const [n, setN] = createSignal(1)
|
|
87
|
+
const doubled = createMemo(() => n() * 2)
|
|
88
|
+
|
|
89
|
+
batch(() => {
|
|
90
|
+
setN(10)
|
|
91
|
+
n() // 10 — plain signal read is fresh
|
|
92
|
+
doubled() // 2 — STALE; the memo hasn't recomputed yet
|
|
93
|
+
})
|
|
94
|
+
doubled() // 20 — recomputed after the batch ends
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If you need the recomputed value, read it after the batch.
|
|
98
|
+
|
|
99
|
+
### `await` escapes the batch
|
|
100
|
+
|
|
101
|
+
`batch` only covers the **synchronous** portion of `fn`. Wrapping an async
|
|
102
|
+
function in `batch` groups only the writes before the first `await` — everything
|
|
103
|
+
after runs ungrouped, and the promise `batch` returns is easy to leave floating.
|
|
104
|
+
|
|
105
|
+
Instead, wrap each synchronous group of writes in its own `batch`, with `await`
|
|
106
|
+
between the groups:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
const onSubmit = async () => {
|
|
110
|
+
batch(() => {
|
|
111
|
+
setLoading(true)
|
|
112
|
+
setError(null)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const result = await save()
|
|
117
|
+
batch(() => {
|
|
118
|
+
setLoading(false)
|
|
119
|
+
setResult(result)
|
|
120
|
+
})
|
|
121
|
+
} catch (err) {
|
|
122
|
+
batch(() => {
|
|
123
|
+
setLoading(false)
|
|
124
|
+
setError(err)
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Note
|
|
131
|
+
|
|
132
|
+
`batch` is an **opt-in** optimization. Forgetting it is never a correctness bug —
|
|
133
|
+
code still works, just with extra subscriber runs. Reach for `batch` when a
|
|
134
|
+
handler writes many signals that share subscribers, or when an effect must not
|
|
135
|
+
observe a partially-updated state.
|
|
@@ -9,7 +9,7 @@ All reactive primitives are imported from `@barefootjs/client`:
|
|
|
9
9
|
|
|
10
10
|
```tsx
|
|
11
11
|
"use client"
|
|
12
|
-
import { createSignal, createEffect, createMemo, onMount, onCleanup, untrack } from '@barefootjs/client'
|
|
12
|
+
import { createSignal, createEffect, createMemo, onMount, onCleanup, untrack, batch } from '@barefootjs/client'
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## API Reference
|
|
@@ -22,6 +22,7 @@ import { createSignal, createEffect, createMemo, onMount, onCleanup, untrack } f
|
|
|
22
22
|
| [`onMount`](./reactivity/on-mount.md) | Run once on component initialization |
|
|
23
23
|
| [`onCleanup`](./reactivity/on-cleanup.md) | Register cleanup for effects and lifecycle |
|
|
24
24
|
| [`untrack`](./reactivity/untrack.md) | Read signals without tracking dependencies |
|
|
25
|
+
| [`batch`](./reactivity/batch.md) | Group signal writes so subscribers run once |
|
|
25
26
|
|
|
26
27
|
## Guides
|
|
27
28
|
|
package/dist/index.js
CHANGED
|
@@ -518,6 +518,19 @@ function buildChainedArrayExpr(elem) {
|
|
|
518
518
|
chainOrder: elem.chainOrder
|
|
519
519
|
});
|
|
520
520
|
}
|
|
521
|
+
function loopOffsetTerms(offset) {
|
|
522
|
+
if (!offset) return [];
|
|
523
|
+
const terms = [];
|
|
524
|
+
if (offset.staticCount) terms.push(String(offset.staticCount));
|
|
525
|
+
terms.push(...offset.dynamicTerms);
|
|
526
|
+
return terms;
|
|
527
|
+
}
|
|
528
|
+
function buildLoopChildIndexExpr(indexParam, offset) {
|
|
529
|
+
return [indexParam, ...loopOffsetTerms(offset)].join(" + ");
|
|
530
|
+
}
|
|
531
|
+
function buildLoopChildIndexSubtraction(offset) {
|
|
532
|
+
return loopOffsetTerms(offset).map((term) => ` - ${term}`).join("");
|
|
533
|
+
}
|
|
521
534
|
function toDomEventName(eventName) {
|
|
522
535
|
return jsxToDomEventMap[eventName] ?? eventName;
|
|
523
536
|
}
|
|
@@ -1274,16 +1287,28 @@ function maybeHoistedScopeAttr(inHoistedChildren, node) {
|
|
|
1274
1287
|
return inHoistedChildren && node.needsScope ? `${BF_SCOPE}="${BF_PARENT_SCOPE_PLACEHOLDER}"` : null;
|
|
1275
1288
|
}
|
|
1276
1289
|
function templateAttrExpr(attrName, valExpr, presenceOrUndefined) {
|
|
1290
|
+
if (attrName === "dangerouslySetInnerHTML") return "";
|
|
1277
1291
|
if (isBooleanAttr(attrName) || presenceOrUndefined) {
|
|
1278
1292
|
return `\${${valExpr} ? '${attrName}' : ''}`;
|
|
1279
1293
|
}
|
|
1280
1294
|
if (attrName === "style") {
|
|
1281
|
-
return `\${((v) => v != null ? 'style="' + v + '"' : '')(styleToCss(${valExpr}))}`;
|
|
1295
|
+
return `\${((v) => v != null ? 'style="' + ${escapeAttrValueExpr("v")} + '"' : '')(styleToCss(${valExpr}))}`;
|
|
1282
1296
|
}
|
|
1283
1297
|
if (attrName === "data-key" || attrName.startsWith("data-key-")) {
|
|
1284
1298
|
return `${attrName}="\${${valExpr}}"`;
|
|
1285
1299
|
}
|
|
1286
|
-
return `\${(${valExpr}) != null ? '${attrName}="' +
|
|
1300
|
+
return `\${(${valExpr}) != null ? '${attrName}="' + ${escapeAttrValueExpr(valExpr)} + '"' : ''}`;
|
|
1301
|
+
}
|
|
1302
|
+
function escapeAttrValueExpr(valExpr) {
|
|
1303
|
+
return `escapeAttr(${valExpr})`;
|
|
1304
|
+
}
|
|
1305
|
+
function escapeTextSlotExpr(innerExpr) {
|
|
1306
|
+
return `escapeText(${innerExpr})`;
|
|
1307
|
+
}
|
|
1308
|
+
function dangerouslyHtmlChildren(attrs, toExpr) {
|
|
1309
|
+
const attr = attrs.find((a) => a.name === "dangerouslySetInnerHTML");
|
|
1310
|
+
if (!attr || attr.value.kind !== "expression") return null;
|
|
1311
|
+
return `\${((${toExpr(attr.value)}) ?? {}).__html ?? ''}`;
|
|
1287
1312
|
}
|
|
1288
1313
|
function transformKeyValue(value, transformExpr) {
|
|
1289
1314
|
switch (value.kind) {
|
|
@@ -1328,6 +1353,7 @@ function renderTemplateAttrPart(attr, attrName, wrap, restSpreadNames) {
|
|
|
1328
1353
|
function isMergeableAttr(a, ctx2) {
|
|
1329
1354
|
if (ctx2.honorClientOnly && a.clientOnly) return false;
|
|
1330
1355
|
if (a.name === "key") return false;
|
|
1356
|
+
if (a.name === "dangerouslySetInnerHTML") return false;
|
|
1331
1357
|
const v = a.value;
|
|
1332
1358
|
if (v.kind === "jsx-children") return false;
|
|
1333
1359
|
if (v.kind === "boolean-shorthand") return false;
|
|
@@ -1415,7 +1441,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
1415
1441
|
}
|
|
1416
1442
|
const attrs = attrParts.join(" ");
|
|
1417
1443
|
const childrenRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, false);
|
|
1418
|
-
const children = node.children.map(childrenRecurse).join("");
|
|
1444
|
+
const children = dangerouslyHtmlChildren(node.attrs, (v) => wrapExpr(v.expr)) ?? node.children.map(childrenRecurse).join("");
|
|
1419
1445
|
if (children || !VOID_ELEMENTS.has(node.tag)) {
|
|
1420
1446
|
return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
|
|
1421
1447
|
}
|
|
@@ -1426,7 +1452,9 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
1426
1452
|
case "expression":
|
|
1427
1453
|
if (node.expr === "null" || node.expr === "undefined") return "";
|
|
1428
1454
|
if (node.slotId) {
|
|
1429
|
-
|
|
1455
|
+
const inner = wrapInterpolation(wrapExpr(node.expr));
|
|
1456
|
+
const slotted = branchSlotsVar ? inner : escapeTextSlotExpr(inner);
|
|
1457
|
+
return `<!--bf:${node.slotId}-->\${${slotted}}<!--/-->`;
|
|
1430
1458
|
}
|
|
1431
1459
|
return `\${${wrapInterpolation(wrapExpr(node.expr))}}`;
|
|
1432
1460
|
case "conditional": {
|
|
@@ -1522,7 +1550,7 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
|
|
|
1522
1550
|
attrParts.push(`bf="${node.slotId}"`);
|
|
1523
1551
|
}
|
|
1524
1552
|
const attrs = attrParts.join(" ");
|
|
1525
|
-
const children = node.children.map(recurse).join("");
|
|
1553
|
+
const children = dangerouslyHtmlChildren(node.attrs, (v) => wrapExpr(v.expr)) ?? node.children.map(recurse).join("");
|
|
1526
1554
|
if (children || !VOID_ELEMENTS.has(node.tag)) {
|
|
1527
1555
|
return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
|
|
1528
1556
|
}
|
|
@@ -1533,7 +1561,7 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
|
|
|
1533
1561
|
case "expression":
|
|
1534
1562
|
if (node.expr === "null" || node.expr === "undefined") return "";
|
|
1535
1563
|
if (node.slotId) {
|
|
1536
|
-
return `<!--bf:${node.slotId}-->\${${wrapExpr(node.expr)}}<!--/-->`;
|
|
1564
|
+
return `<!--bf:${node.slotId}-->\${${escapeTextSlotExpr(wrapExpr(node.expr))}}<!--/-->`;
|
|
1537
1565
|
}
|
|
1538
1566
|
return `\${${wrapExpr(node.expr)}}`;
|
|
1539
1567
|
case "conditional": {
|
|
@@ -1752,7 +1780,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
1752
1780
|
attrParts.push(`bf="${node.slotId}"`);
|
|
1753
1781
|
}
|
|
1754
1782
|
const attrs = attrParts.join(" ");
|
|
1755
|
-
const children = node.children.map(childrenRecurse).join("");
|
|
1783
|
+
const children = dangerouslyHtmlChildren(node.attrs, (v) => transformExpr(v.expr, v.templateExpr)) ?? node.children.map(childrenRecurse).join("");
|
|
1756
1784
|
if (children || !VOID_ELEMENTS.has(node.tag)) {
|
|
1757
1785
|
return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
|
|
1758
1786
|
}
|
|
@@ -1763,7 +1791,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
1763
1791
|
case "expression":
|
|
1764
1792
|
if (node.expr === "null" || node.expr === "undefined") return "";
|
|
1765
1793
|
if (node.slotId) {
|
|
1766
|
-
return `<!--bf:${node.slotId}-->\${${transformExpr(node.expr, node.templateExpr)}}<!--/-->`;
|
|
1794
|
+
return `<!--bf:${node.slotId}-->\${${escapeTextSlotExpr(transformExpr(node.expr, node.templateExpr))}}<!--/-->`;
|
|
1767
1795
|
}
|
|
1768
1796
|
return `\${${transformExpr(node.expr, node.templateExpr)}}`;
|
|
1769
1797
|
case "conditional": {
|
|
@@ -1966,7 +1994,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
1966
1994
|
attrParts.push(`bf="${node.slotId}"`);
|
|
1967
1995
|
}
|
|
1968
1996
|
const attrs = attrParts.join(" ");
|
|
1969
|
-
const children = node.children.map(childrenRecurse).join("");
|
|
1997
|
+
const children = dangerouslyHtmlChildren(node.attrs, (v) => transformExpr(v.expr, v.templateExpr)) ?? node.children.map(childrenRecurse).join("");
|
|
1970
1998
|
if (children || !VOID_ELEMENTS.has(node.tag)) {
|
|
1971
1999
|
return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
|
|
1972
2000
|
}
|
|
@@ -1983,7 +2011,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
1983
2011
|
const transformed = transformExpr(node.expr, node.templateExpr);
|
|
1984
2012
|
const expr = transformed === UNSAFE_TEMPLATE_EXPR ? "''" : transformed;
|
|
1985
2013
|
if (node.slotId) {
|
|
1986
|
-
return `<!--bf:${node.slotId}-->\${${expr}}<!--/-->`;
|
|
2014
|
+
return `<!--bf:${node.slotId}-->\${${escapeTextSlotExpr(expr)}}<!--/-->`;
|
|
1987
2015
|
}
|
|
1988
2016
|
return `\${${expr}}`;
|
|
1989
2017
|
}
|
|
@@ -2450,6 +2478,24 @@ function getSourceLocation(node, sourceFile, filePath) {
|
|
|
2450
2478
|
}
|
|
2451
2479
|
};
|
|
2452
2480
|
}
|
|
2481
|
+
function membersToProperties(members, sourceFile) {
|
|
2482
|
+
return members.filter(ts6.isPropertySignature).map((member) => ({
|
|
2483
|
+
name: propertyNameText(member.name, sourceFile),
|
|
2484
|
+
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
2485
|
+
kind: "unknown",
|
|
2486
|
+
raw: "unknown"
|
|
2487
|
+
},
|
|
2488
|
+
optional: !!member.questionToken,
|
|
2489
|
+
readonly: !!member.modifiers?.some(
|
|
2490
|
+
(m) => m.kind === ts6.SyntaxKind.ReadonlyKeyword
|
|
2491
|
+
)
|
|
2492
|
+
}));
|
|
2493
|
+
}
|
|
2494
|
+
function propertyNameText(name, sourceFile) {
|
|
2495
|
+
if (!name) return "";
|
|
2496
|
+
if (ts6.isStringLiteral(name) || ts6.isNumericLiteral(name)) return name.text;
|
|
2497
|
+
return name.getText(sourceFile);
|
|
2498
|
+
}
|
|
2453
2499
|
function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
2454
2500
|
if (!typeNode) return null;
|
|
2455
2501
|
const raw = typeNode.getText(sourceFile);
|
|
@@ -2488,20 +2534,21 @@ function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
|
2488
2534
|
return {
|
|
2489
2535
|
kind: "object",
|
|
2490
2536
|
raw,
|
|
2491
|
-
properties: typeNode.members
|
|
2492
|
-
name: member.name?.getText(sourceFile) ?? "",
|
|
2493
|
-
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
2494
|
-
kind: "unknown",
|
|
2495
|
-
raw: "unknown"
|
|
2496
|
-
},
|
|
2497
|
-
optional: !!member.questionToken,
|
|
2498
|
-
readonly: !!member.modifiers?.some(
|
|
2499
|
-
(m) => m.kind === ts6.SyntaxKind.ReadonlyKeyword
|
|
2500
|
-
)
|
|
2501
|
-
}))
|
|
2537
|
+
properties: membersToProperties(typeNode.members, sourceFile)
|
|
2502
2538
|
};
|
|
2503
2539
|
}
|
|
2504
2540
|
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
2541
|
+
const refName = ts6.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : "";
|
|
2542
|
+
if ((refName === "Array" || refName === "ReadonlyArray") && typeNode.typeArguments?.length === 1) {
|
|
2543
|
+
return {
|
|
2544
|
+
kind: "array",
|
|
2545
|
+
raw,
|
|
2546
|
+
elementType: typeNodeToTypeInfo(typeNode.typeArguments[0], sourceFile) ?? {
|
|
2547
|
+
kind: "unknown",
|
|
2548
|
+
raw: "unknown"
|
|
2549
|
+
}
|
|
2550
|
+
};
|
|
2551
|
+
}
|
|
2505
2552
|
return {
|
|
2506
2553
|
kind: "interface",
|
|
2507
2554
|
raw
|
|
@@ -3679,14 +3726,17 @@ function collectInterfaceDefinition(node, ctx2) {
|
|
|
3679
3726
|
kind: "interface",
|
|
3680
3727
|
name: node.name.text,
|
|
3681
3728
|
definition: node.getText(ctx2.sourceFile),
|
|
3729
|
+
properties: membersToProperties(node.members, ctx2.sourceFile),
|
|
3682
3730
|
loc: getSourceLocation(node, ctx2.sourceFile, ctx2.filePath)
|
|
3683
3731
|
});
|
|
3684
3732
|
}
|
|
3685
3733
|
function collectTypeAliasDefinition(node, ctx2) {
|
|
3734
|
+
const properties = ts7.isTypeLiteralNode(node.type) ? membersToProperties(node.type.members, ctx2.sourceFile) : void 0;
|
|
3686
3735
|
ctx2.typeDefinitions.push({
|
|
3687
3736
|
kind: "type",
|
|
3688
3737
|
name: node.name.text,
|
|
3689
3738
|
definition: node.getText(ctx2.sourceFile),
|
|
3739
|
+
properties,
|
|
3690
3740
|
loc: getSourceLocation(node, ctx2.sourceFile, ctx2.filePath)
|
|
3691
3741
|
});
|
|
3692
3742
|
}
|
|
@@ -5882,7 +5932,7 @@ function checkSupport(expr) {
|
|
|
5882
5932
|
return {
|
|
5883
5933
|
supported: false,
|
|
5884
5934
|
level: "L5_UNSUPPORTED",
|
|
5885
|
-
reason: `
|
|
5935
|
+
reason: `Method '${methodName}()' has no template lowering and requires client-side evaluation. Wrap the expression in /* @client */ to defer it to hydration, or pre-compute the value before rendering.`
|
|
5886
5936
|
};
|
|
5887
5937
|
}
|
|
5888
5938
|
}
|
|
@@ -6172,7 +6222,7 @@ var init_expression_parser = __esm({
|
|
|
6172
6222
|
"some",
|
|
6173
6223
|
"forEach",
|
|
6174
6224
|
"flatMap",
|
|
6175
|
-
"flat"
|
|
6225
|
+
"flat",
|
|
6176
6226
|
// #1448 Tier A — Array methods. Each method PR adds the lowering
|
|
6177
6227
|
// (typically a new `array-method` variant or runtime helper) and
|
|
6178
6228
|
// removes its row here. See packages/adapter-tests/fixtures/methods/.
|
|
@@ -6202,6 +6252,34 @@ var init_expression_parser = __esm({
|
|
|
6202
6252
|
// `bf_lower` / `bf_upper` (Go) and Perl's native `lc` / `uc` (Mojo).
|
|
6203
6253
|
// `trim` lowers via the `array-method` IR + `bf_trim` (Go) and a
|
|
6204
6254
|
// Perl regex strip (Mojo).
|
|
6255
|
+
//
|
|
6256
|
+
// #1448 follow-up — String methods that have NO lowering yet. These
|
|
6257
|
+
// were previously absent from this gate, so `isSupported` reported
|
|
6258
|
+
// them "supported" and the adapters emitted a raw method call
|
|
6259
|
+
// (`{{.Name.StartsWith "a"}}` on Go, `$name->{startsWith}('a')` on
|
|
6260
|
+
// Mojo) with no build diagnostic — a silent footgun that only
|
|
6261
|
+
// surfaced as a crash at template-render time. Listing them here
|
|
6262
|
+
// makes the build fail loudly with BF101 (the same treatment the
|
|
6263
|
+
// unsupported array methods above get), pointing users at the
|
|
6264
|
+
// `/* @client */` escape hatch. Each name drops off as its lowering
|
|
6265
|
+
// lands. See #1448 "Unsupported string methods" Tier B / Tier C.
|
|
6266
|
+
"split",
|
|
6267
|
+
"startsWith",
|
|
6268
|
+
"endsWith",
|
|
6269
|
+
"replace",
|
|
6270
|
+
"replaceAll",
|
|
6271
|
+
"repeat",
|
|
6272
|
+
"padStart",
|
|
6273
|
+
"padEnd",
|
|
6274
|
+
"charAt",
|
|
6275
|
+
"charCodeAt",
|
|
6276
|
+
"codePointAt",
|
|
6277
|
+
"normalize",
|
|
6278
|
+
"substring",
|
|
6279
|
+
"substr",
|
|
6280
|
+
"match",
|
|
6281
|
+
"matchAll",
|
|
6282
|
+
"search"
|
|
6205
6283
|
]);
|
|
6206
6284
|
}
|
|
6207
6285
|
});
|
|
@@ -8260,11 +8338,11 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8260
8338
|
if (stmt === returnStmt) break;
|
|
8261
8339
|
const js = ctx2.getJS(stmt);
|
|
8262
8340
|
const tjs = ctx2.getTemplateJS(stmt);
|
|
8263
|
-
const
|
|
8341
|
+
const ts21 = stmt.getText(ctx2.sourceFile);
|
|
8264
8342
|
preambleStmts.push(js.endsWith(";") ? js : js + ";");
|
|
8265
8343
|
templatePreambleStmts.push(tjs.endsWith(";") ? tjs : tjs + ";");
|
|
8266
|
-
typedPreambleStmts.push(
|
|
8267
|
-
if (js !==
|
|
8344
|
+
typedPreambleStmts.push(ts21.endsWith(";") ? ts21 : ts21 + ";");
|
|
8345
|
+
if (js !== ts21) hasTypeDiff = true;
|
|
8268
8346
|
if (js !== tjs) hasTemplateDiff = true;
|
|
8269
8347
|
}
|
|
8270
8348
|
if (preambleStmts.length > 0) {
|
|
@@ -9540,29 +9618,100 @@ var init_reactivity = __esm({
|
|
|
9540
9618
|
});
|
|
9541
9619
|
|
|
9542
9620
|
// ../jsx/src/ir-to-client-js/collect-elements.ts
|
|
9543
|
-
function
|
|
9544
|
-
|
|
9621
|
+
function domElementCount(node) {
|
|
9622
|
+
switch (node.type) {
|
|
9623
|
+
case "element":
|
|
9624
|
+
case "component":
|
|
9625
|
+
case "provider":
|
|
9626
|
+
case "async":
|
|
9627
|
+
return 1;
|
|
9628
|
+
case "text":
|
|
9629
|
+
return 0;
|
|
9630
|
+
case "expression":
|
|
9631
|
+
return EMPTY_RENDER_EXPRS.has(node.expr.trim()) ? 0 : null;
|
|
9632
|
+
case "loop":
|
|
9633
|
+
if (node.bodyIsItemConditional || node.method === "flatMap") return null;
|
|
9634
|
+
return `(${buildLoopChainExpr({
|
|
9635
|
+
base: node.array,
|
|
9636
|
+
sortComparator: node.sortComparator,
|
|
9637
|
+
filterPredicate: node.filterPredicate,
|
|
9638
|
+
chainOrder: node.chainOrder
|
|
9639
|
+
})}).length`;
|
|
9640
|
+
case "conditional": {
|
|
9641
|
+
const t = domElementCount(node.whenTrue);
|
|
9642
|
+
const f = domElementCount(node.whenFalse);
|
|
9643
|
+
if (t === null || f === null) return null;
|
|
9644
|
+
if (typeof t === "number" && typeof f === "number" && t === f) return t;
|
|
9645
|
+
return `(${node.condition} ? ${t} : ${f})`;
|
|
9646
|
+
}
|
|
9647
|
+
case "fragment":
|
|
9648
|
+
return sumElementCounts(node.children);
|
|
9649
|
+
default:
|
|
9650
|
+
return null;
|
|
9651
|
+
}
|
|
9652
|
+
}
|
|
9653
|
+
function sumElementCounts(nodes) {
|
|
9654
|
+
let staticCount = 0;
|
|
9655
|
+
const dynamic = [];
|
|
9656
|
+
for (const n of nodes) {
|
|
9657
|
+
const c = domElementCount(n);
|
|
9658
|
+
if (c === null) return null;
|
|
9659
|
+
if (typeof c === "number") staticCount += c;
|
|
9660
|
+
else dynamic.push(c);
|
|
9661
|
+
}
|
|
9662
|
+
if (dynamic.length === 0) return staticCount;
|
|
9663
|
+
const parts = staticCount > 0 ? [String(staticCount), ...dynamic] : dynamic;
|
|
9664
|
+
return parts.length === 1 ? parts[0] : `(${parts.join(" + ")})`;
|
|
9665
|
+
}
|
|
9666
|
+
function legacyElementCount(node) {
|
|
9667
|
+
return node.type === "element" || node.type === "component" || node.type === "provider" || node.type === "async" || node.type === "text" || node.type === "expression" && !node.reactive || node.type === "conditional" ? 1 : 0;
|
|
9545
9668
|
}
|
|
9546
9669
|
function computeLoopSiblingOffsets(root) {
|
|
9547
9670
|
const offsets = /* @__PURE__ */ new Map();
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
if (nonLoopCount > 0) offsets.set(child, nonLoopCount);
|
|
9554
|
-
} else if (producesDomChild(child)) {
|
|
9555
|
-
nonLoopCount++;
|
|
9671
|
+
const recordRun = (children, preceding) => {
|
|
9672
|
+
for (const child of children) {
|
|
9673
|
+
if (child.type === "loop") {
|
|
9674
|
+
if (preceding.length > 0 && !offsets.has(child)) {
|
|
9675
|
+
offsets.set(child, [...preceding]);
|
|
9556
9676
|
}
|
|
9677
|
+
preceding.push(child);
|
|
9678
|
+
} else if (child.type === "fragment" || child.type === "provider" || child.type === "async") {
|
|
9679
|
+
recordRun(child.children, preceding);
|
|
9680
|
+
} else {
|
|
9681
|
+
preceding.push(child);
|
|
9557
9682
|
}
|
|
9558
|
-
descend();
|
|
9559
9683
|
}
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9684
|
+
};
|
|
9685
|
+
const containerVisit = ({ node, descend }) => {
|
|
9686
|
+
recordRun(node.children, []);
|
|
9687
|
+
descend();
|
|
9688
|
+
};
|
|
9689
|
+
walkIR(root, null, {
|
|
9690
|
+
element: containerVisit,
|
|
9691
|
+
component: containerVisit,
|
|
9692
|
+
fragment: containerVisit,
|
|
9693
|
+
provider: containerVisit,
|
|
9694
|
+
async: containerVisit
|
|
9695
|
+
// `loop` / `conditional` / `if-statement` are not flat sibling
|
|
9696
|
+
// containers (their children are item bodies / branches), and leaves
|
|
9697
|
+
// (text / expression / slot) have no children — all rely on walkIR's
|
|
9698
|
+
// default descent with the same scope.
|
|
9563
9699
|
});
|
|
9564
9700
|
return offsets;
|
|
9565
9701
|
}
|
|
9702
|
+
function resolveLoopOffset(preceding) {
|
|
9703
|
+
if (!preceding || preceding.length === 0) return void 0;
|
|
9704
|
+
let staticCount = 0;
|
|
9705
|
+
const dynamicTerms = [];
|
|
9706
|
+
for (const node of preceding) {
|
|
9707
|
+
const c = domElementCount(node);
|
|
9708
|
+
if (c === null) staticCount += legacyElementCount(node);
|
|
9709
|
+
else if (typeof c === "number") staticCount += c;
|
|
9710
|
+
else dynamicTerms.push(c);
|
|
9711
|
+
}
|
|
9712
|
+
if (staticCount === 0 && dynamicTerms.length === 0) return void 0;
|
|
9713
|
+
return { staticCount, dynamicTerms };
|
|
9714
|
+
}
|
|
9566
9715
|
function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options) {
|
|
9567
9716
|
const result = [];
|
|
9568
9717
|
const flat = options?.flatBranchMode === true;
|
|
@@ -9648,7 +9797,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options)
|
|
|
9648
9797
|
refsOuterParam: refsOuter,
|
|
9649
9798
|
childComponents,
|
|
9650
9799
|
insideConditional: !flat && scope.insideCond ? true : void 0,
|
|
9651
|
-
|
|
9800
|
+
offset: flat ? void 0 : resolveLoopOffset(siblingOffsets.get(n)),
|
|
9652
9801
|
bindings
|
|
9653
9802
|
});
|
|
9654
9803
|
if (!flat) {
|
|
@@ -9858,7 +10007,7 @@ function collectElements(node, ctx2, siblingOffsets, insideConditional = false)
|
|
|
9858
10007
|
isStaticArray: l.isStaticArray,
|
|
9859
10008
|
useElementReconciliation,
|
|
9860
10009
|
innerLoops: useElementReconciliation || l.isStaticArray && innerLoops?.length ? innerLoops : void 0,
|
|
9861
|
-
|
|
10010
|
+
offset: resolveLoopOffset(siblingOffsets.get(l)),
|
|
9862
10011
|
filterPredicate: l.filterPredicate ? {
|
|
9863
10012
|
param: l.filterPredicate.param,
|
|
9864
10013
|
raw: l.filterPredicate.raw
|
|
@@ -10159,7 +10308,7 @@ function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopPar
|
|
|
10159
10308
|
events: collectConditionalBranchEvents(node)
|
|
10160
10309
|
};
|
|
10161
10310
|
}
|
|
10162
|
-
var branchInnerLoopOptions;
|
|
10311
|
+
var EMPTY_RENDER_EXPRS, branchInnerLoopOptions;
|
|
10163
10312
|
var init_collect_elements = __esm({
|
|
10164
10313
|
"../jsx/src/ir-to-client-js/collect-elements.ts"() {
|
|
10165
10314
|
"use strict";
|
|
@@ -10169,6 +10318,8 @@ var init_collect_elements = __esm({
|
|
|
10169
10318
|
init_html_template();
|
|
10170
10319
|
init_prop_handling();
|
|
10171
10320
|
init_walker();
|
|
10321
|
+
init_loop_chain();
|
|
10322
|
+
EMPTY_RENDER_EXPRS = /* @__PURE__ */ new Set(["null", "undefined", "false", "''", '""', "``"]);
|
|
10172
10323
|
branchInnerLoopOptions = {
|
|
10173
10324
|
collectItemBindings: true,
|
|
10174
10325
|
templateDepth: 1,
|
|
@@ -10728,6 +10879,8 @@ var init_imports = __esm({
|
|
|
10728
10879
|
"splitProps",
|
|
10729
10880
|
"spreadAttrs",
|
|
10730
10881
|
"styleToCss",
|
|
10882
|
+
"escapeAttr",
|
|
10883
|
+
"escapeText",
|
|
10731
10884
|
"qsa",
|
|
10732
10885
|
"qsaItem",
|
|
10733
10886
|
"qsaChildScope",
|
|
@@ -12565,7 +12718,7 @@ function buildOuterNestedPlan(elem, comp) {
|
|
|
12565
12718
|
arrayExpr: elem.array,
|
|
12566
12719
|
param: elem.param,
|
|
12567
12720
|
indexParam,
|
|
12568
|
-
offsetExpr:
|
|
12721
|
+
offsetExpr: buildLoopChildIndexExpr(indexParam, elem.offset),
|
|
12569
12722
|
outerPreludeStatements: elem.mapPreamble ? [elem.mapPreamble] : [],
|
|
12570
12723
|
propsExpr: buildStaticPropsExpr(comp.props)
|
|
12571
12724
|
};
|
|
@@ -12583,12 +12736,12 @@ function buildInnerLoopNestedPlan(elem, innerLoop, innerComps) {
|
|
|
12583
12736
|
outerArrayExpr: elem.array,
|
|
12584
12737
|
outerParam: elem.param,
|
|
12585
12738
|
outerIndexParam,
|
|
12586
|
-
outerOffsetExpr:
|
|
12739
|
+
outerOffsetExpr: buildLoopChildIndexExpr(outerIndexParam, elem.offset),
|
|
12587
12740
|
outerPreludeStatements: elem.mapPreamble ? [elem.mapPreamble] : [],
|
|
12588
12741
|
innerContainerSlotId: innerLoop.containerSlotId ?? null,
|
|
12589
12742
|
innerArrayExpr: innerLoop.array,
|
|
12590
12743
|
innerParam: innerLoop.param,
|
|
12591
|
-
innerOffsetExpr:
|
|
12744
|
+
innerOffsetExpr: buildLoopChildIndexExpr("__innerIdx", innerLoop.offset),
|
|
12592
12745
|
innerPreludeStatements: innerLoop.mapPreamble ? [innerLoop.mapPreamble] : [],
|
|
12593
12746
|
depth: innerLoop.depth,
|
|
12594
12747
|
comps
|
|
@@ -13405,7 +13558,7 @@ function buildStaticArrayDelegationPlan(elem) {
|
|
|
13405
13558
|
arrayExpr: buildChainedArrayExpr(elem),
|
|
13406
13559
|
param: elem.param,
|
|
13407
13560
|
mapPreamble: elem.mapPreamble ?? null,
|
|
13408
|
-
|
|
13561
|
+
offset: elem.offset ?? null
|
|
13409
13562
|
}
|
|
13410
13563
|
};
|
|
13411
13564
|
}
|
|
@@ -13559,6 +13712,11 @@ var init_build_insert = __esm({
|
|
|
13559
13712
|
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
13560
13713
|
function emitAttrUpdate(target, attrName, expression, meta) {
|
|
13561
13714
|
const htmlName = toHTMLAttrName(attrName);
|
|
13715
|
+
if (attrName === "dangerouslySetInnerHTML" || htmlName === "dangerouslySetInnerHTML") {
|
|
13716
|
+
return [
|
|
13717
|
+
`{ const __v = ${expression}; ${target}.innerHTML = __v != null && __v.__html != null ? String(__v.__html) : '' }`
|
|
13718
|
+
];
|
|
13719
|
+
}
|
|
13562
13720
|
if (htmlName === "style") {
|
|
13563
13721
|
return [
|
|
13564
13722
|
`{ const __v = styleToCss(${expression}); if (__v != null) ${target}.setAttribute('style', __v); else ${target}.removeAttribute('style') }`
|
|
@@ -14622,11 +14780,11 @@ function emitDynamicIndexLookup(ls, ev, handlerCall, lookup) {
|
|
|
14622
14780
|
ls.push(` }`);
|
|
14623
14781
|
}
|
|
14624
14782
|
function emitStaticIndexLookup(ls, ev, handlerCall, lookup, containerVar) {
|
|
14625
|
-
const { arrayExpr, param, mapPreamble,
|
|
14783
|
+
const { arrayExpr, param, mapPreamble, offset } = lookup;
|
|
14626
14784
|
ls.push(` let __el = ${varSlotId(ev.childSlotId)}El`);
|
|
14627
14785
|
ls.push(` while (__el.parentElement && __el.parentElement !== ${containerVar}) __el = __el.parentElement`);
|
|
14628
14786
|
ls.push(` if (__el.parentElement === ${containerVar}) {`);
|
|
14629
|
-
const idxOffset =
|
|
14787
|
+
const idxOffset = buildLoopChildIndexSubtraction(offset ?? void 0);
|
|
14630
14788
|
ls.push(` const __idx = Array.from(${containerVar}.children).indexOf(__el)${idxOffset}`);
|
|
14631
14789
|
ls.push(` const ${param} = ${arrayExpr}[__idx]`);
|
|
14632
14790
|
if (mapPreamble) ls.push(` ${mapPreamble}`);
|
|
@@ -14954,7 +15112,7 @@ function buildStaticLoopPlan(elem, unsafeLocalNames) {
|
|
|
14954
15112
|
}
|
|
14955
15113
|
}
|
|
14956
15114
|
const indexParam = elem.index || "__idx";
|
|
14957
|
-
const childIndexExpr =
|
|
15115
|
+
const childIndexExpr = buildLoopChildIndexExpr(indexParam, elem.offset);
|
|
14958
15116
|
return {
|
|
14959
15117
|
kind: "static",
|
|
14960
15118
|
containerVar: `_${varSlotId(elem.slotId)}`,
|
|
@@ -17350,6 +17508,7 @@ var init_attr_value_emitter = __esm({
|
|
|
17350
17508
|
});
|
|
17351
17509
|
|
|
17352
17510
|
// ../jsx/src/combine-client-js.ts
|
|
17511
|
+
import ts18 from "typescript";
|
|
17353
17512
|
function combineParentChildClientJs(files) {
|
|
17354
17513
|
const result = /* @__PURE__ */ new Map();
|
|
17355
17514
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -17406,30 +17565,48 @@ function combineParentChildClientJs(files) {
|
|
|
17406
17565
|
return result;
|
|
17407
17566
|
}
|
|
17408
17567
|
function parseAndMerge(content, importsBySource, otherImports, codeSections) {
|
|
17409
|
-
const
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
|
|
17415
|
-
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
|
|
17423
|
-
|
|
17424
|
-
|
|
17425
|
-
|
|
17426
|
-
|
|
17568
|
+
const sourceFile = ts18.createSourceFile(
|
|
17569
|
+
"combine.js",
|
|
17570
|
+
content,
|
|
17571
|
+
ts18.ScriptTarget.Latest,
|
|
17572
|
+
/*setParentNodes*/
|
|
17573
|
+
false,
|
|
17574
|
+
ts18.ScriptKind.JS
|
|
17575
|
+
);
|
|
17576
|
+
const importSpans = [];
|
|
17577
|
+
for (const stmt of sourceFile.statements) {
|
|
17578
|
+
if (!ts18.isImportDeclaration(stmt)) continue;
|
|
17579
|
+
const start = stmt.getStart(sourceFile);
|
|
17580
|
+
const end = stmt.getEnd();
|
|
17581
|
+
importSpans.push([start, end]);
|
|
17582
|
+
const stmtText = content.slice(start, end);
|
|
17583
|
+
if (stmtText.includes("@bf-child:")) continue;
|
|
17584
|
+
const clause = stmt.importClause;
|
|
17585
|
+
const bindings = clause?.namedBindings;
|
|
17586
|
+
const specifier = ts18.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
|
|
17587
|
+
if (clause && !clause.name && bindings && ts18.isNamedImports(bindings)) {
|
|
17588
|
+
if (!importsBySource.has(specifier)) {
|
|
17589
|
+
importsBySource.set(specifier, /* @__PURE__ */ new Set());
|
|
17590
|
+
}
|
|
17591
|
+
const set = importsBySource.get(specifier);
|
|
17592
|
+
for (const el of bindings.elements) {
|
|
17593
|
+
const name = el.propertyName ? `${el.propertyName.text} as ${el.name.text}` : el.name.text;
|
|
17594
|
+
set.add(name);
|
|
17427
17595
|
}
|
|
17428
17596
|
} else {
|
|
17429
|
-
|
|
17597
|
+
if (!otherImports.includes(stmtText)) {
|
|
17598
|
+
otherImports.push(stmtText);
|
|
17599
|
+
}
|
|
17430
17600
|
}
|
|
17431
17601
|
}
|
|
17432
|
-
|
|
17602
|
+
let code = "";
|
|
17603
|
+
let cursor = 0;
|
|
17604
|
+
for (const [start, end] of importSpans) {
|
|
17605
|
+
code += content.slice(cursor, start);
|
|
17606
|
+
cursor = end;
|
|
17607
|
+
}
|
|
17608
|
+
code += content.slice(cursor);
|
|
17609
|
+
code = code.trim();
|
|
17433
17610
|
if (code) {
|
|
17434
17611
|
codeSections.push(code);
|
|
17435
17612
|
}
|
|
@@ -18862,7 +19039,7 @@ var init_runtime = __esm({
|
|
|
18862
19039
|
|
|
18863
19040
|
// src/lib/resolve-imports.ts
|
|
18864
19041
|
import { dirname as dirname2, resolve as resolve2 } from "node:path";
|
|
18865
|
-
import
|
|
19042
|
+
import ts19 from "typescript";
|
|
18866
19043
|
function shapeFromDecl(decl) {
|
|
18867
19044
|
const clause = decl.importClause;
|
|
18868
19045
|
if (!clause) return null;
|
|
@@ -18872,7 +19049,7 @@ function shapeFromDecl(decl) {
|
|
|
18872
19049
|
}
|
|
18873
19050
|
const bindings = clause.namedBindings;
|
|
18874
19051
|
if (bindings) {
|
|
18875
|
-
if (
|
|
19052
|
+
if (ts19.isNamespaceImport(bindings)) {
|
|
18876
19053
|
shape.namespace = bindings.name.text;
|
|
18877
19054
|
} else {
|
|
18878
19055
|
for (const el of bindings.elements) {
|
|
@@ -18886,38 +19063,38 @@ function shapeFromDecl(decl) {
|
|
|
18886
19063
|
}
|
|
18887
19064
|
function collectExportedNames(source) {
|
|
18888
19065
|
const names = /* @__PURE__ */ new Set();
|
|
18889
|
-
const sourceFile =
|
|
19066
|
+
const sourceFile = ts19.createSourceFile(
|
|
18890
19067
|
"mod.ts",
|
|
18891
19068
|
source,
|
|
18892
|
-
|
|
19069
|
+
ts19.ScriptTarget.Latest,
|
|
18893
19070
|
/*setParents*/
|
|
18894
19071
|
false,
|
|
18895
|
-
|
|
19072
|
+
ts19.ScriptKind.TS
|
|
18896
19073
|
);
|
|
18897
19074
|
function hasExport(node) {
|
|
18898
|
-
if (!
|
|
18899
|
-
const mods =
|
|
18900
|
-
return mods?.some((m) => m.kind ===
|
|
19075
|
+
if (!ts19.canHaveModifiers(node)) return false;
|
|
19076
|
+
const mods = ts19.getModifiers(node);
|
|
19077
|
+
return mods?.some((m) => m.kind === ts19.SyntaxKind.ExportKeyword) ?? false;
|
|
18901
19078
|
}
|
|
18902
19079
|
function collectFromBindingName(name) {
|
|
18903
|
-
if (
|
|
19080
|
+
if (ts19.isIdentifier(name)) {
|
|
18904
19081
|
names.add(name.text);
|
|
18905
19082
|
return;
|
|
18906
19083
|
}
|
|
18907
19084
|
for (const el of name.elements) {
|
|
18908
|
-
if (
|
|
19085
|
+
if (ts19.isBindingElement(el)) collectFromBindingName(el.name);
|
|
18909
19086
|
}
|
|
18910
19087
|
}
|
|
18911
19088
|
for (const stmt of sourceFile.statements) {
|
|
18912
|
-
if (
|
|
19089
|
+
if (ts19.isVariableStatement(stmt) && hasExport(stmt)) {
|
|
18913
19090
|
for (const d of stmt.declarationList.declarations) {
|
|
18914
19091
|
collectFromBindingName(d.name);
|
|
18915
19092
|
}
|
|
18916
|
-
} else if (
|
|
19093
|
+
} else if (ts19.isFunctionDeclaration(stmt) && hasExport(stmt) && stmt.name) {
|
|
18917
19094
|
names.add(stmt.name.text);
|
|
18918
|
-
} else if (
|
|
19095
|
+
} else if (ts19.isClassDeclaration(stmt) && hasExport(stmt) && stmt.name) {
|
|
18919
19096
|
names.add(stmt.name.text);
|
|
18920
|
-
} else if (
|
|
19097
|
+
} else if (ts19.isExportDeclaration(stmt) && !stmt.moduleSpecifier && stmt.exportClause && ts19.isNamedExports(stmt.exportClause)) {
|
|
18921
19098
|
if (stmt.isTypeOnly) continue;
|
|
18922
19099
|
for (const el of stmt.exportClause.elements) {
|
|
18923
19100
|
if (el.isTypeOnly) continue;
|
|
@@ -18928,16 +19105,16 @@ function collectExportedNames(source) {
|
|
|
18928
19105
|
return [...names];
|
|
18929
19106
|
}
|
|
18930
19107
|
function hasUseClientDirective(source) {
|
|
18931
|
-
const sourceFile =
|
|
19108
|
+
const sourceFile = ts19.createSourceFile(
|
|
18932
19109
|
"check.tsx",
|
|
18933
19110
|
source,
|
|
18934
|
-
|
|
19111
|
+
ts19.ScriptTarget.Latest,
|
|
18935
19112
|
/*setParents*/
|
|
18936
19113
|
false,
|
|
18937
|
-
|
|
19114
|
+
ts19.ScriptKind.TSX
|
|
18938
19115
|
);
|
|
18939
19116
|
for (const stmt of sourceFile.statements) {
|
|
18940
|
-
if (!
|
|
19117
|
+
if (!ts19.isExpressionStatement(stmt) || !ts19.isStringLiteral(stmt.expression)) {
|
|
18941
19118
|
return false;
|
|
18942
19119
|
}
|
|
18943
19120
|
if (stmt.expression.text === "use client") return true;
|
|
@@ -18946,53 +19123,53 @@ function hasUseClientDirective(source) {
|
|
|
18946
19123
|
}
|
|
18947
19124
|
function collectTopLevelBindings(source) {
|
|
18948
19125
|
const names = /* @__PURE__ */ new Set();
|
|
18949
|
-
const sourceFile =
|
|
19126
|
+
const sourceFile = ts19.createSourceFile(
|
|
18950
19127
|
"bundle.ts",
|
|
18951
19128
|
source,
|
|
18952
|
-
|
|
19129
|
+
ts19.ScriptTarget.Latest,
|
|
18953
19130
|
/*setParents*/
|
|
18954
19131
|
false,
|
|
18955
|
-
|
|
19132
|
+
ts19.ScriptKind.TS
|
|
18956
19133
|
);
|
|
18957
19134
|
function collectFromBindingName(name) {
|
|
18958
|
-
if (
|
|
19135
|
+
if (ts19.isIdentifier(name)) {
|
|
18959
19136
|
names.add(name.text);
|
|
18960
19137
|
return;
|
|
18961
19138
|
}
|
|
18962
19139
|
for (const el of name.elements) {
|
|
18963
|
-
if (
|
|
19140
|
+
if (ts19.isBindingElement(el)) collectFromBindingName(el.name);
|
|
18964
19141
|
}
|
|
18965
19142
|
}
|
|
18966
19143
|
for (const stmt of sourceFile.statements) {
|
|
18967
|
-
if (
|
|
19144
|
+
if (ts19.isVariableStatement(stmt)) {
|
|
18968
19145
|
for (const d of stmt.declarationList.declarations) {
|
|
18969
19146
|
collectFromBindingName(d.name);
|
|
18970
19147
|
}
|
|
18971
|
-
} else if (
|
|
19148
|
+
} else if (ts19.isFunctionDeclaration(stmt) && stmt.name) {
|
|
18972
19149
|
names.add(stmt.name.text);
|
|
18973
|
-
} else if (
|
|
19150
|
+
} else if (ts19.isClassDeclaration(stmt) && stmt.name) {
|
|
18974
19151
|
names.add(stmt.name.text);
|
|
18975
19152
|
}
|
|
18976
19153
|
}
|
|
18977
19154
|
return names;
|
|
18978
19155
|
}
|
|
18979
19156
|
function stripImportsAndExports(body) {
|
|
18980
|
-
const sourceFile =
|
|
19157
|
+
const sourceFile = ts19.createSourceFile(
|
|
18981
19158
|
"body.ts",
|
|
18982
19159
|
body,
|
|
18983
|
-
|
|
19160
|
+
ts19.ScriptTarget.Latest,
|
|
18984
19161
|
/*setParents*/
|
|
18985
19162
|
false,
|
|
18986
|
-
|
|
19163
|
+
ts19.ScriptKind.TS
|
|
18987
19164
|
);
|
|
18988
19165
|
const spans = [];
|
|
18989
19166
|
const hoistedImports = [];
|
|
18990
19167
|
for (const stmt of sourceFile.statements) {
|
|
18991
|
-
if (
|
|
19168
|
+
if (ts19.isImportDeclaration(stmt)) {
|
|
18992
19169
|
const start = stmt.getStart(sourceFile);
|
|
18993
19170
|
const end = stmt.getEnd();
|
|
18994
19171
|
const specifier = stmt.moduleSpecifier;
|
|
18995
|
-
if (
|
|
19172
|
+
if (ts19.isStringLiteral(specifier)) {
|
|
18996
19173
|
const path23 = specifier.text;
|
|
18997
19174
|
const isRelative = path23.startsWith("./") || path23.startsWith("../");
|
|
18998
19175
|
if (!isRelative) {
|
|
@@ -19002,24 +19179,24 @@ function stripImportsAndExports(body) {
|
|
|
19002
19179
|
spans.push([start, end]);
|
|
19003
19180
|
continue;
|
|
19004
19181
|
}
|
|
19005
|
-
if (
|
|
19182
|
+
if (ts19.isExportDeclaration(stmt)) {
|
|
19006
19183
|
spans.push([stmt.getStart(sourceFile), stmt.getEnd()]);
|
|
19007
19184
|
continue;
|
|
19008
19185
|
}
|
|
19009
|
-
if (
|
|
19010
|
-
const exportKw = stmt.getChildren(sourceFile).find((c) => c.kind ===
|
|
19011
|
-
const defaultKw = stmt.getChildren(sourceFile).find((c) => c.kind ===
|
|
19012
|
-
const equalsKw = stmt.getChildren(sourceFile).find((c) => c.kind ===
|
|
19186
|
+
if (ts19.isExportAssignment(stmt)) {
|
|
19187
|
+
const exportKw = stmt.getChildren(sourceFile).find((c) => c.kind === ts19.SyntaxKind.ExportKeyword);
|
|
19188
|
+
const defaultKw = stmt.getChildren(sourceFile).find((c) => c.kind === ts19.SyntaxKind.DefaultKeyword);
|
|
19189
|
+
const equalsKw = stmt.getChildren(sourceFile).find((c) => c.kind === ts19.SyntaxKind.EqualsToken);
|
|
19013
19190
|
const start = exportKw?.getStart(sourceFile) ?? stmt.getStart(sourceFile);
|
|
19014
19191
|
const end = (defaultKw ?? equalsKw)?.getEnd() ?? exportKw?.getEnd() ?? stmt.getStart(sourceFile);
|
|
19015
19192
|
if (end > start) spans.push([start, end]);
|
|
19016
19193
|
continue;
|
|
19017
19194
|
}
|
|
19018
|
-
if (
|
|
19019
|
-
const mods =
|
|
19195
|
+
if (ts19.canHaveModifiers(stmt)) {
|
|
19196
|
+
const mods = ts19.getModifiers(stmt);
|
|
19020
19197
|
if (!mods) continue;
|
|
19021
19198
|
for (const mod of mods) {
|
|
19022
|
-
if (mod.kind ===
|
|
19199
|
+
if (mod.kind === ts19.SyntaxKind.ExportKeyword) {
|
|
19023
19200
|
const start = mod.getStart(sourceFile);
|
|
19024
19201
|
let end = mod.getEnd();
|
|
19025
19202
|
while (end < body.length && /\s/.test(body[end])) end++;
|
|
@@ -19128,48 +19305,48 @@ function buildDanglingReferenceMessage(binding, s) {
|
|
|
19128
19305
|
function isValueReference(id) {
|
|
19129
19306
|
const parent = id.parent;
|
|
19130
19307
|
if (!parent) return false;
|
|
19131
|
-
if (
|
|
19132
|
-
if (
|
|
19133
|
-
if ((
|
|
19308
|
+
if (ts19.isPropertyAccessExpression(parent) && parent.name === id) return false;
|
|
19309
|
+
if (ts19.isPropertyAssignment(parent) && parent.name === id) return false;
|
|
19310
|
+
if ((ts19.isMethodDeclaration(parent) || ts19.isGetAccessorDeclaration(parent) || ts19.isSetAccessorDeclaration(parent)) && parent.name === id) {
|
|
19134
19311
|
return false;
|
|
19135
19312
|
}
|
|
19136
|
-
if (
|
|
19137
|
-
if (
|
|
19138
|
-
if (
|
|
19139
|
-
if (
|
|
19140
|
-
if (
|
|
19141
|
-
if (
|
|
19142
|
-
if (
|
|
19143
|
-
if (
|
|
19144
|
-
if (
|
|
19145
|
-
if (
|
|
19146
|
-
if (
|
|
19147
|
-
if (
|
|
19148
|
-
if (
|
|
19149
|
-
if (
|
|
19313
|
+
if (ts19.isVariableDeclaration(parent) && parent.name === id) return false;
|
|
19314
|
+
if (ts19.isFunctionDeclaration(parent) && parent.name === id) return false;
|
|
19315
|
+
if (ts19.isFunctionExpression(parent) && parent.name === id) return false;
|
|
19316
|
+
if (ts19.isClassDeclaration(parent) && parent.name === id) return false;
|
|
19317
|
+
if (ts19.isClassExpression(parent) && parent.name === id) return false;
|
|
19318
|
+
if (ts19.isParameter(parent) && parent.name === id) return false;
|
|
19319
|
+
if (ts19.isBindingElement(parent) && (parent.name === id || parent.propertyName === id)) return false;
|
|
19320
|
+
if (ts19.isLabeledStatement(parent) && parent.label === id) return false;
|
|
19321
|
+
if (ts19.isBreakOrContinueStatement(parent) && parent.label === id) return false;
|
|
19322
|
+
if (ts19.isImportSpecifier(parent) && (parent.name === id || parent.propertyName === id)) return false;
|
|
19323
|
+
if (ts19.isExportSpecifier(parent) && (parent.name === id || parent.propertyName === id)) return false;
|
|
19324
|
+
if (ts19.isImportClause(parent) && parent.name === id) return false;
|
|
19325
|
+
if (ts19.isNamespaceImport(parent) && parent.name === id) return false;
|
|
19326
|
+
if (ts19.isQualifiedName(parent) && parent.right === id) return false;
|
|
19150
19327
|
return true;
|
|
19151
19328
|
}
|
|
19152
19329
|
function detectStrippedReferences(bundleSource, stripped) {
|
|
19153
19330
|
if (stripped.length === 0) return [];
|
|
19154
19331
|
let sf;
|
|
19155
19332
|
try {
|
|
19156
|
-
sf =
|
|
19333
|
+
sf = ts19.createSourceFile(
|
|
19157
19334
|
"bundle.js",
|
|
19158
19335
|
bundleSource,
|
|
19159
|
-
|
|
19336
|
+
ts19.ScriptTarget.Latest,
|
|
19160
19337
|
/*setParents*/
|
|
19161
19338
|
true,
|
|
19162
|
-
|
|
19339
|
+
ts19.ScriptKind.JS
|
|
19163
19340
|
);
|
|
19164
19341
|
} catch {
|
|
19165
19342
|
return [];
|
|
19166
19343
|
}
|
|
19167
19344
|
const firstReference = /* @__PURE__ */ new Map();
|
|
19168
19345
|
function visit3(node) {
|
|
19169
|
-
if (
|
|
19346
|
+
if (ts19.isIdentifier(node) && isValueReference(node)) {
|
|
19170
19347
|
if (!firstReference.has(node.text)) firstReference.set(node.text, node);
|
|
19171
19348
|
}
|
|
19172
|
-
|
|
19349
|
+
ts19.forEachChild(node, visit3);
|
|
19173
19350
|
}
|
|
19174
19351
|
visit3(sf);
|
|
19175
19352
|
const errors = [];
|
|
@@ -19199,18 +19376,18 @@ function detectStrippedReferences(bundleSource, stripped) {
|
|
|
19199
19376
|
return errors;
|
|
19200
19377
|
}
|
|
19201
19378
|
async function walkAndCollect(content, searchDirs, modules, visiting, loggingPath, stripped, stubDeps, nextId) {
|
|
19202
|
-
const sourceFile =
|
|
19379
|
+
const sourceFile = ts19.createSourceFile(
|
|
19203
19380
|
"walk.js",
|
|
19204
19381
|
content,
|
|
19205
|
-
|
|
19382
|
+
ts19.ScriptTarget.Latest,
|
|
19206
19383
|
/*setParents*/
|
|
19207
19384
|
false,
|
|
19208
|
-
|
|
19385
|
+
ts19.ScriptKind.JS
|
|
19209
19386
|
);
|
|
19210
19387
|
const sites = [];
|
|
19211
19388
|
for (const stmt of sourceFile.statements) {
|
|
19212
|
-
if (!
|
|
19213
|
-
if (!
|
|
19389
|
+
if (!ts19.isImportDeclaration(stmt)) continue;
|
|
19390
|
+
if (!ts19.isStringLiteral(stmt.moduleSpecifier)) continue;
|
|
19214
19391
|
const spec = stmt.moduleSpecifier.text;
|
|
19215
19392
|
if (!spec.startsWith("./") && !spec.startsWith("../")) continue;
|
|
19216
19393
|
const start = stmt.getStart(sourceFile);
|
|
@@ -19662,7 +19839,7 @@ var init_assets_ignore = __esm({
|
|
|
19662
19839
|
});
|
|
19663
19840
|
|
|
19664
19841
|
// src/lib/build.ts
|
|
19665
|
-
import
|
|
19842
|
+
import ts20 from "typescript";
|
|
19666
19843
|
import { mkdir, readdir, stat, unlink } from "node:fs/promises";
|
|
19667
19844
|
import { resolve as resolve6, basename, relative as relative2, dirname as dirname3, isAbsolute as isAbsolute2 } from "node:path";
|
|
19668
19845
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -20119,12 +20296,7 @@ async function build(config, options = {}) {
|
|
|
20119
20296
|
try {
|
|
20120
20297
|
let content = await readText(filePath);
|
|
20121
20298
|
const before = content;
|
|
20122
|
-
|
|
20123
|
-
content = content.replace(
|
|
20124
|
-
/from ['"]@barefootjs\/client(?:\/[^'"]*)?['"]/g,
|
|
20125
|
-
`from '${rel}'`
|
|
20126
|
-
);
|
|
20127
|
-
}
|
|
20299
|
+
content = rewriteBarefootClientSpecifiers(content, rel);
|
|
20128
20300
|
content = mergeDuplicateNamedImports(content);
|
|
20129
20301
|
if (content !== before && await writeIfChanged(filePath, content)) {
|
|
20130
20302
|
anyOutputChanged = true;
|
|
@@ -20213,7 +20385,7 @@ async function build(config, options = {}) {
|
|
|
20213
20385
|
};
|
|
20214
20386
|
}
|
|
20215
20387
|
function extractBareImports(code) {
|
|
20216
|
-
const { importedFiles } =
|
|
20388
|
+
const { importedFiles } = ts20.preProcessFile(code, true, true);
|
|
20217
20389
|
const specifiers = /* @__PURE__ */ new Set();
|
|
20218
20390
|
for (const { fileName } of importedFiles) {
|
|
20219
20391
|
if (!fileName.startsWith(".") && !fileName.startsWith("/") && !fileName.includes("://")) {
|
|
@@ -20278,13 +20450,82 @@ function effectiveOutName(tplPath, entryBaseNoExt) {
|
|
|
20278
20450
|
const entryDir = entryBaseNoExt.includes("/") ? entryBaseNoExt.slice(0, entryBaseNoExt.lastIndexOf("/")) : "";
|
|
20279
20451
|
return entryDir ? `${entryDir}/${bn}` : bn;
|
|
20280
20452
|
}
|
|
20453
|
+
function topLevelImportLines(content) {
|
|
20454
|
+
const lines = /* @__PURE__ */ new Set();
|
|
20455
|
+
const sourceFile = ts20.createSourceFile(
|
|
20456
|
+
"merge.js",
|
|
20457
|
+
content,
|
|
20458
|
+
ts20.ScriptTarget.Latest,
|
|
20459
|
+
/*setParentNodes*/
|
|
20460
|
+
true,
|
|
20461
|
+
ts20.ScriptKind.JS
|
|
20462
|
+
);
|
|
20463
|
+
for (const stmt of sourceFile.statements) {
|
|
20464
|
+
if (ts20.isImportDeclaration(stmt)) {
|
|
20465
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(stmt.getStart(sourceFile));
|
|
20466
|
+
lines.add(line);
|
|
20467
|
+
}
|
|
20468
|
+
}
|
|
20469
|
+
return lines;
|
|
20470
|
+
}
|
|
20471
|
+
function rewriteBarefootClientSpecifiers(content, rel) {
|
|
20472
|
+
if (!content.includes("@barefootjs/client")) return content;
|
|
20473
|
+
const sourceFile = ts20.createSourceFile(
|
|
20474
|
+
"client.js",
|
|
20475
|
+
content,
|
|
20476
|
+
ts20.ScriptTarget.Latest,
|
|
20477
|
+
/*setParentNodes*/
|
|
20478
|
+
true,
|
|
20479
|
+
ts20.ScriptKind.JS
|
|
20480
|
+
);
|
|
20481
|
+
const isBarefootClient = (s) => s === "@barefootjs/client" || s.startsWith("@barefootjs/client/");
|
|
20482
|
+
const spans = [];
|
|
20483
|
+
const visit3 = (node) => {
|
|
20484
|
+
if (ts20.isImportDeclaration(node) || ts20.isExportDeclaration(node)) {
|
|
20485
|
+
const ms = node.moduleSpecifier;
|
|
20486
|
+
if (ms && ts20.isStringLiteral(ms) && isBarefootClient(ms.text)) {
|
|
20487
|
+
spans.push([ms.getStart(sourceFile), ms.getEnd()]);
|
|
20488
|
+
}
|
|
20489
|
+
} else if (ts20.isCallExpression(node) && node.expression.kind === ts20.SyntaxKind.ImportKeyword) {
|
|
20490
|
+
const arg = node.arguments[0];
|
|
20491
|
+
if (arg && ts20.isStringLiteral(arg) && isBarefootClient(arg.text)) {
|
|
20492
|
+
spans.push([arg.getStart(sourceFile), arg.getEnd()]);
|
|
20493
|
+
}
|
|
20494
|
+
}
|
|
20495
|
+
ts20.forEachChild(node, visit3);
|
|
20496
|
+
};
|
|
20497
|
+
visit3(sourceFile);
|
|
20498
|
+
if (spans.length === 0) return content;
|
|
20499
|
+
spans.sort((a, b) => b[0] - a[0]);
|
|
20500
|
+
let out = content;
|
|
20501
|
+
for (const [start, end] of spans) {
|
|
20502
|
+
out = out.slice(0, start) + `'${rel}'` + out.slice(end);
|
|
20503
|
+
}
|
|
20504
|
+
return out;
|
|
20505
|
+
}
|
|
20281
20506
|
function mergeDuplicateNamedImports(content) {
|
|
20282
20507
|
const lines = content.split("\n");
|
|
20283
20508
|
const namedImportRe = /^import\s+\{\s*([^}]+)\s*\}\s+from\s+(['"])([^'"]+)\2\s*;?\s*$/;
|
|
20284
20509
|
const bySource = /* @__PURE__ */ new Map();
|
|
20285
20510
|
const dropIndices = /* @__PURE__ */ new Set();
|
|
20286
20511
|
let changed = false;
|
|
20512
|
+
{
|
|
20513
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20514
|
+
let possibleDuplicate = false;
|
|
20515
|
+
for (const line of lines) {
|
|
20516
|
+
const m = line.match(namedImportRe);
|
|
20517
|
+
if (!m) continue;
|
|
20518
|
+
if (seen.has(m[3])) {
|
|
20519
|
+
possibleDuplicate = true;
|
|
20520
|
+
break;
|
|
20521
|
+
}
|
|
20522
|
+
seen.add(m[3]);
|
|
20523
|
+
}
|
|
20524
|
+
if (!possibleDuplicate) return content;
|
|
20525
|
+
}
|
|
20526
|
+
const realImportLines = topLevelImportLines(content);
|
|
20287
20527
|
lines.forEach((line, idx) => {
|
|
20528
|
+
if (!realImportLines.has(idx)) return;
|
|
20288
20529
|
const m = line.match(namedImportRe);
|
|
20289
20530
|
if (!m) return;
|
|
20290
20531
|
const names = m[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -23788,7 +24029,13 @@ export default createConfig({
|
|
|
23788
24029
|
}
|
|
23789
24030
|
},
|
|
23790
24031
|
"include": ["**/*.ts", "**/*.tsx"],
|
|
23791
|
-
|
|
24032
|
+
// Do NOT exclude dist/components here. The server imports the compiled
|
|
24033
|
+
// SSR templates from there (see the @/components/* paths above), and
|
|
24034
|
+
// tsx applies the JSX transform per-file honouring this include/
|
|
24035
|
+
// exclude \u2014 an excluded .tsx loses jsxImportSource and falls back to
|
|
24036
|
+
// the classic React runtime, so SSR throws "ReferenceError: React is
|
|
24037
|
+
// not defined" at the first render. They must stay in scope.
|
|
24038
|
+
"exclude": ["node_modules"]
|
|
23792
24039
|
}
|
|
23793
24040
|
`;
|
|
23794
24041
|
HONO_NODE_ADAPTER = {
|
|
@@ -27508,9 +27755,9 @@ function findProjectConfig(startDir) {
|
|
|
27508
27755
|
let dir = path.resolve(startDir);
|
|
27509
27756
|
const { root: fsRoot } = path.parse(dir);
|
|
27510
27757
|
while (true) {
|
|
27511
|
-
const
|
|
27512
|
-
if (existsSync2(
|
|
27513
|
-
return { dir, tsConfigPath:
|
|
27758
|
+
const ts21 = path.join(dir, "barefoot.config.ts");
|
|
27759
|
+
if (existsSync2(ts21)) {
|
|
27760
|
+
return { dir, tsConfigPath: ts21 };
|
|
27514
27761
|
}
|
|
27515
27762
|
if (dir === fsRoot) return null;
|
|
27516
27763
|
dir = path.dirname(dir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "CLI for agent-driven UI component discovery and scaffolding",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typescript": "^5.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@barefootjs/jsx": "0.5.
|
|
34
|
+
"@barefootjs/jsx": "0.5.3",
|
|
35
35
|
"@types/node": "^22.0.0"
|
|
36
36
|
}
|
|
37
37
|
}
|