@barefootjs/shared 0.33.2 → 0.33.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/index.d.ts +3 -1
- package/dist/index.js +14 -0
- package/dist/jsx-children-prop.d.ts +52 -0
- package/dist/markers.d.ts +15 -0
- package/package.json +1 -1
- package/src/index.ts +3 -0
- package/src/jsx-children-prop.ts +61 -0
- package/src/markers.ts +18 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { BF_SCOPE, BF_SLOT, BF_HOST, BF_AT, BF_ROOT, BF_PROPS, BF_COND, BF_ITEM, BF_PORTAL_OWNER, BF_PORTAL_ID, BF_PORTAL_PLACEHOLDER, BF_PARENT_OWNED_PREFIX, BF_SCOPE_COMMENT_PREFIX, BF_SCOPE_COMMENT_END_PREFIX, BF_LOOP_START, BF_LOOP_END, BF_LOOP_ITEM, loopItemMarker, loopStartMarker, loopEndMarker, BF_KEY, BF_KEY_PREFIX, BF_PLACEHOLDER, BF_ASYNC, BF_ASYNC_RESOLVE, BF_REGION, BF_PARENT_SCOPE_PLACEHOLDER, BF_SEAM_HYDRATE, BF_SEAM_HYDRATE_WITHIN, BF_SEAM_DISPOSE_WITHIN, BF_SEAM_PUSH_SEARCH, BF_SEAM_NAV_SEARCH, } from './markers.ts';
|
|
1
|
+
export { BF_SCOPE, BF_SLOT, BF_HOST, BF_AT, BF_ROOT, BF_PROPS, BF_COND, BF_ITEM, BF_PORTAL_OWNER, BF_PORTAL_ID, BF_PORTAL_PLACEHOLDER, BF_PARENT_OWNED_PREFIX, BF_SCOPE_COMMENT_PREFIX, BF_SCOPE_COMMENT_END_PREFIX, BF_LOOP_START, BF_LOOP_END, BF_LOOP_ITEM, loopItemMarker, loopStartMarker, loopEndMarker, BF_KEY, BF_KEY_PREFIX, keyAttrName, BF_PLACEHOLDER, BF_ASYNC, BF_ASYNC_RESOLVE, BF_REGION, BF_PARENT_SCOPE_PLACEHOLDER, BF_SEAM_HYDRATE, BF_SEAM_HYDRATE_WITHIN, BF_SEAM_DISPOSE_WITHIN, BF_SEAM_PUSH_SEARCH, BF_SEAM_NAV_SEARCH, } from './markers.ts';
|
|
2
2
|
export { classifyDOMProp, toHTMLAttrName, toHTMLAttrNameRuntime, isBooleanAttr, isEventProp, BOOLEAN_ATTRS, } from './dom-prop.ts';
|
|
3
3
|
export type { DOMPropKind, DOMPropClassification } from './dom-prop.ts';
|
|
4
4
|
export { decodeEntities, escapeHtml } from './html-entities.ts';
|
|
5
|
+
export { resolveJsxChildrenProp } from './jsx-children-prop.ts';
|
|
6
|
+
export type { ChildrenSlotPropLike } from './jsx-children-prop.ts';
|
|
5
7
|
export type { ProfilerEvent, ProfilerEventType, ProfilerSubscriberKind, } from './profiler-events.ts';
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,9 @@ function loopEndMarker(markerId) {
|
|
|
27
27
|
}
|
|
28
28
|
var BF_KEY = "data-key";
|
|
29
29
|
var BF_KEY_PREFIX = "data-key-";
|
|
30
|
+
function keyAttrName(loopDepth) {
|
|
31
|
+
return loopDepth > 0 ? `${BF_KEY_PREFIX}${loopDepth}` : BF_KEY;
|
|
32
|
+
}
|
|
30
33
|
var BF_PLACEHOLDER = "data-bf-ph";
|
|
31
34
|
var BF_ASYNC = "bf-async";
|
|
32
35
|
var BF_ASYNC_RESOLVE = "bf-async-resolve";
|
|
@@ -335,12 +338,23 @@ function decodeEntities(text) {
|
|
|
335
338
|
function escapeHtml(text) {
|
|
336
339
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
337
340
|
}
|
|
341
|
+
// src/jsx-children-prop.ts
|
|
342
|
+
function resolveJsxChildrenProp(props) {
|
|
343
|
+
const prop = props.find((p) => p.name === "children");
|
|
344
|
+
if (!prop)
|
|
345
|
+
return [];
|
|
346
|
+
if (prop.value.kind !== "jsx-children")
|
|
347
|
+
return [];
|
|
348
|
+
return prop.value.children ?? [];
|
|
349
|
+
}
|
|
338
350
|
export {
|
|
339
351
|
toHTMLAttrNameRuntime,
|
|
340
352
|
toHTMLAttrName,
|
|
353
|
+
resolveJsxChildrenProp,
|
|
341
354
|
loopStartMarker,
|
|
342
355
|
loopItemMarker,
|
|
343
356
|
loopEndMarker,
|
|
357
|
+
keyAttrName,
|
|
344
358
|
isEventProp,
|
|
345
359
|
isBooleanAttr,
|
|
346
360
|
escapeHtml,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS — reserved `children` JSX-prop resolver
|
|
3
|
+
*
|
|
4
|
+
* Answers one question for every adapter: "which prop on this component
|
|
5
|
+
* call supplies the reserved `children` slot?" Before this module existed,
|
|
6
|
+
* two independently-maintained answers had drifted apart (issue #2773):
|
|
7
|
+
*
|
|
8
|
+
* - The seven DSL adapters (Blade/ERB/Jinja/Mojolicious/minijinja/Twig/
|
|
9
|
+
* Xslate) each carried a byte-identical private copy of this function in
|
|
10
|
+
* their own `lib/ir-scope.ts`, matching on the prop NAMED `children`.
|
|
11
|
+
* - The Go template adapter's `jsxChildrenPropNodes` answered a different
|
|
12
|
+
* question: the FIRST prop of ANY name carrying a `jsx-children`
|
|
13
|
+
* payload. For a component with an earlier JSX-element prop (e.g.
|
|
14
|
+
* `header={<span/>}`) and no `children` prop at all, that silently
|
|
15
|
+
* backfilled `.Children` with the `header` payload — and when a
|
|
16
|
+
* `children` prop WAS also given, it lost `children`'s payload entirely
|
|
17
|
+
* in favor of the earlier prop's.
|
|
18
|
+
*
|
|
19
|
+
* Hono, the reference adapter, resolves `children` by name — ordinary JSX
|
|
20
|
+
* semantics: `<Card header={<A/>} children={<B/>} />` binds `header` and
|
|
21
|
+
* `children` to two separate props, exactly as `React.createElement`
|
|
22
|
+
* would. The DSL adapters already agreed with Hono; this module makes
|
|
23
|
+
* their shared answer the ONLY implementation, so Go template (and any
|
|
24
|
+
* future adapter) calls it instead of growing its own copy that can
|
|
25
|
+
* re-diverge.
|
|
26
|
+
*
|
|
27
|
+
* Generic and structurally typed rather than importing `IRProp`/`IRNode`
|
|
28
|
+
* from `@barefootjs/jsx`: `@barefootjs/jsx` itself depends on
|
|
29
|
+
* `@barefootjs/shared`, so importing the other direction would be a
|
|
30
|
+
* dependency cycle. Callers pass their real IR prop array and get back a
|
|
31
|
+
* concretely-typed node array — no cast, no parallel type declaration to
|
|
32
|
+
* keep in sync with `@barefootjs/jsx`'s `AttrValue` union.
|
|
33
|
+
*/
|
|
34
|
+
/** Structural shape of an `AttrValue`-like prop value, generic over the node type a `jsx-children` payload carries. */
|
|
35
|
+
interface JsxChildrenAttrValueLike<TNode> {
|
|
36
|
+
kind: string;
|
|
37
|
+
children?: TNode[];
|
|
38
|
+
}
|
|
39
|
+
/** Structural shape of one IR prop, generic over the node type. */
|
|
40
|
+
export interface ChildrenSlotPropLike<TNode> {
|
|
41
|
+
name: string;
|
|
42
|
+
value: JsxChildrenAttrValueLike<TNode>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Find the prop literally named `children` and, if its value carries a
|
|
46
|
+
* `jsx-children` payload, return that payload's nodes. Returns `[]` when
|
|
47
|
+
* no `children` prop exists, or when one exists but is not a resolved
|
|
48
|
+
* JSX-children payload (e.g. an ordinary expression prop that merely
|
|
49
|
+
* happens to be named `children`).
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveJsxChildrenProp<TNode>(props: ReadonlyArray<ChildrenSlotPropLike<TNode>>): TNode[];
|
|
52
|
+
export {};
|
package/dist/markers.d.ts
CHANGED
|
@@ -118,6 +118,21 @@ export declare function loopEndMarker(markerId: string): string;
|
|
|
118
118
|
export declare const BF_KEY = "data-key";
|
|
119
119
|
/** Nested loop key attribute prefix: `data-key-1`, `data-key-2` */
|
|
120
120
|
export declare const BF_KEY_PREFIX = "data-key-";
|
|
121
|
+
/**
|
|
122
|
+
* The row-key attribute NAME for a `.map()` nested `loopDepth` levels deep
|
|
123
|
+
* (0 = outermost): `data-key` at depth 0, `data-key-N` at depth N > 0.
|
|
124
|
+
*
|
|
125
|
+
* Single source of truth for a derivation that used to be re-implemented at
|
|
126
|
+
* every emission site — the CSR codegen path (`ir-to-client-js/utils.ts`,
|
|
127
|
+
* pre-existing re-export), IR-build time (`IRElement.keyAttr`,
|
|
128
|
+
* `jsx-to-ir.ts`), and — before that consolidation — independently again by
|
|
129
|
+
* each of the 9 SSR adapters (a mutable stack in Hono, a `currentLoopKeyDepth`
|
|
130
|
+
* field in every DSL adapter) and by the client runtime's `mapArray`, which
|
|
131
|
+
* used to skip depth entirely and always write plain `data-key` (#2753 Shape
|
|
132
|
+
* B). Living here, in the one package every one of those consumers already
|
|
133
|
+
* depends on, is what makes "compute it once" possible instead of aspirational.
|
|
134
|
+
*/
|
|
135
|
+
export declare function keyAttrName(loopDepth: number): string;
|
|
121
136
|
/** Component placeholder in loop templates: `data-bf-ph="s5"` */
|
|
122
137
|
export declare const BF_PLACEHOLDER = "data-bf-ph";
|
|
123
138
|
/** Async boundary placeholder: `bf-async="a0"` */
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ export {
|
|
|
21
21
|
loopEndMarker,
|
|
22
22
|
BF_KEY,
|
|
23
23
|
BF_KEY_PREFIX,
|
|
24
|
+
keyAttrName,
|
|
24
25
|
BF_PLACEHOLDER,
|
|
25
26
|
BF_ASYNC,
|
|
26
27
|
BF_ASYNC_RESOLVE,
|
|
@@ -43,6 +44,8 @@ export {
|
|
|
43
44
|
} from './dom-prop.ts'
|
|
44
45
|
export type { DOMPropKind, DOMPropClassification } from './dom-prop.ts'
|
|
45
46
|
export { decodeEntities, escapeHtml } from './html-entities.ts'
|
|
47
|
+
export { resolveJsxChildrenProp } from './jsx-children-prop.ts'
|
|
48
|
+
export type { ChildrenSlotPropLike } from './jsx-children-prop.ts'
|
|
46
49
|
|
|
47
50
|
export type {
|
|
48
51
|
ProfilerEvent,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS — reserved `children` JSX-prop resolver
|
|
3
|
+
*
|
|
4
|
+
* Answers one question for every adapter: "which prop on this component
|
|
5
|
+
* call supplies the reserved `children` slot?" Before this module existed,
|
|
6
|
+
* two independently-maintained answers had drifted apart (issue #2773):
|
|
7
|
+
*
|
|
8
|
+
* - The seven DSL adapters (Blade/ERB/Jinja/Mojolicious/minijinja/Twig/
|
|
9
|
+
* Xslate) each carried a byte-identical private copy of this function in
|
|
10
|
+
* their own `lib/ir-scope.ts`, matching on the prop NAMED `children`.
|
|
11
|
+
* - The Go template adapter's `jsxChildrenPropNodes` answered a different
|
|
12
|
+
* question: the FIRST prop of ANY name carrying a `jsx-children`
|
|
13
|
+
* payload. For a component with an earlier JSX-element prop (e.g.
|
|
14
|
+
* `header={<span/>}`) and no `children` prop at all, that silently
|
|
15
|
+
* backfilled `.Children` with the `header` payload — and when a
|
|
16
|
+
* `children` prop WAS also given, it lost `children`'s payload entirely
|
|
17
|
+
* in favor of the earlier prop's.
|
|
18
|
+
*
|
|
19
|
+
* Hono, the reference adapter, resolves `children` by name — ordinary JSX
|
|
20
|
+
* semantics: `<Card header={<A/>} children={<B/>} />` binds `header` and
|
|
21
|
+
* `children` to two separate props, exactly as `React.createElement`
|
|
22
|
+
* would. The DSL adapters already agreed with Hono; this module makes
|
|
23
|
+
* their shared answer the ONLY implementation, so Go template (and any
|
|
24
|
+
* future adapter) calls it instead of growing its own copy that can
|
|
25
|
+
* re-diverge.
|
|
26
|
+
*
|
|
27
|
+
* Generic and structurally typed rather than importing `IRProp`/`IRNode`
|
|
28
|
+
* from `@barefootjs/jsx`: `@barefootjs/jsx` itself depends on
|
|
29
|
+
* `@barefootjs/shared`, so importing the other direction would be a
|
|
30
|
+
* dependency cycle. Callers pass their real IR prop array and get back a
|
|
31
|
+
* concretely-typed node array — no cast, no parallel type declaration to
|
|
32
|
+
* keep in sync with `@barefootjs/jsx`'s `AttrValue` union.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/** Structural shape of an `AttrValue`-like prop value, generic over the node type a `jsx-children` payload carries. */
|
|
36
|
+
interface JsxChildrenAttrValueLike<TNode> {
|
|
37
|
+
kind: string
|
|
38
|
+
children?: TNode[]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Structural shape of one IR prop, generic over the node type. */
|
|
42
|
+
export interface ChildrenSlotPropLike<TNode> {
|
|
43
|
+
name: string
|
|
44
|
+
value: JsxChildrenAttrValueLike<TNode>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Find the prop literally named `children` and, if its value carries a
|
|
49
|
+
* `jsx-children` payload, return that payload's nodes. Returns `[]` when
|
|
50
|
+
* no `children` prop exists, or when one exists but is not a resolved
|
|
51
|
+
* JSX-children payload (e.g. an ordinary expression prop that merely
|
|
52
|
+
* happens to be named `children`).
|
|
53
|
+
*/
|
|
54
|
+
export function resolveJsxChildrenProp<TNode>(
|
|
55
|
+
props: ReadonlyArray<ChildrenSlotPropLike<TNode>>,
|
|
56
|
+
): TNode[] {
|
|
57
|
+
const prop = props.find(p => p.name === 'children')
|
|
58
|
+
if (!prop) return []
|
|
59
|
+
if (prop.value.kind !== 'jsx-children') return []
|
|
60
|
+
return prop.value.children ?? []
|
|
61
|
+
}
|
package/src/markers.ts
CHANGED
|
@@ -171,6 +171,24 @@ export const BF_KEY = 'data-key'
|
|
|
171
171
|
/** Nested loop key attribute prefix: `data-key-1`, `data-key-2` */
|
|
172
172
|
export const BF_KEY_PREFIX = 'data-key-'
|
|
173
173
|
|
|
174
|
+
/**
|
|
175
|
+
* The row-key attribute NAME for a `.map()` nested `loopDepth` levels deep
|
|
176
|
+
* (0 = outermost): `data-key` at depth 0, `data-key-N` at depth N > 0.
|
|
177
|
+
*
|
|
178
|
+
* Single source of truth for a derivation that used to be re-implemented at
|
|
179
|
+
* every emission site — the CSR codegen path (`ir-to-client-js/utils.ts`,
|
|
180
|
+
* pre-existing re-export), IR-build time (`IRElement.keyAttr`,
|
|
181
|
+
* `jsx-to-ir.ts`), and — before that consolidation — independently again by
|
|
182
|
+
* each of the 9 SSR adapters (a mutable stack in Hono, a `currentLoopKeyDepth`
|
|
183
|
+
* field in every DSL adapter) and by the client runtime's `mapArray`, which
|
|
184
|
+
* used to skip depth entirely and always write plain `data-key` (#2753 Shape
|
|
185
|
+
* B). Living here, in the one package every one of those consumers already
|
|
186
|
+
* depends on, is what makes "compute it once" possible instead of aspirational.
|
|
187
|
+
*/
|
|
188
|
+
export function keyAttrName(loopDepth: number): string {
|
|
189
|
+
return loopDepth > 0 ? `${BF_KEY_PREFIX}${loopDepth}` : BF_KEY
|
|
190
|
+
}
|
|
191
|
+
|
|
174
192
|
/** Component placeholder in loop templates: `data-bf-ph="s5"` */
|
|
175
193
|
export const BF_PLACEHOLDER = 'data-bf-ph'
|
|
176
194
|
|