@barefootjs/hono 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/hono-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +13 -3
- package/dist/app.d.ts +35 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +12 -7
- package/dist/build.js +13 -3
- package/dist/index.js +13 -3
- package/dist/scripts.js +12 -7
- package/package.json +4 -4
- package/src/__tests__/import-map.test.ts +88 -0
- package/src/adapter/hono-adapter.ts +18 -3
- package/src/app.ts +55 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/hono-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,MAAM,EAIX,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAElB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,UAAU,EAMX,MAAM,iBAAiB,CAAA;AAExB;;;;;GAKG;AACH,KAAK,aAAa,GAAG;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAGD,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAuBD,qBAAa,WAAY,SAAQ,UAAW,YAAW,aAAa,CAAC,aAAa,CAAC;IACjF,IAAI,SAAS;IACb,SAAS,SAAS;IAClB,gBAAgB,SAAiC;IAmBjD,mBAAmB,QAAO,OAAO,CAAQ;IAEzC,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAA0B;IAE/D,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,wBAAwB,CAAiB;IACjD;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAAC,CAAgC;IAC9D,uFAAuF;IACvF,OAAO,CAAC,YAAY,CAAmD;IAEvE,YAAY,OAAO,GAAE,kBAAuB,EAQ3C;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CAyCzE;IAED,OAAO,CAAC,kCAAkC;IAkB1C,OAAO,CAAC,eAAe;IAyDvB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+EpE;IAED,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,iBAAiB;IAmNzB;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,CAEpD;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAEzF;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAElG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAEpF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAE7F;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAE5F;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9B;IAED,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAKnG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAwB5F;IAED,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAEtF;IAED,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAwC5E;IAED,OAAO,CAAC,UAAU;IAIlB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAgB3C;IAED,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA0B7C;IAED,OAAO,CAAC,kBAAkB;IA2B1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"hono-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/hono-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -447,14 +447,24 @@ export default ${this.componentName}` : "";
|
|
|
447
447
|
if (loop.bodyIsMultiRoot) {
|
|
448
448
|
safeChildren = `<>{bfComment('bf-loop-i')}${children}</>`;
|
|
449
449
|
}
|
|
450
|
-
|
|
450
|
+
let chainedArray = applyHonoLoopChain(loop);
|
|
451
451
|
const iterMethod = loop.method ?? "map";
|
|
452
|
+
let callbackParam;
|
|
453
|
+
if (loop.iterationShape === "entries" && loop.index) {
|
|
454
|
+
chainedArray = `[...${chainedArray}.entries()]`;
|
|
455
|
+
callbackParam = `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])`;
|
|
456
|
+
} else if (loop.iterationShape === "keys") {
|
|
457
|
+
chainedArray = `[...${chainedArray}.keys()]`;
|
|
458
|
+
callbackParam = `(${loop.param}${paramAnnotation})`;
|
|
459
|
+
} else {
|
|
460
|
+
callbackParam = `(${loop.param}${paramAnnotation}${indexParam})`;
|
|
461
|
+
}
|
|
452
462
|
if (loop.flatMapCallback) {
|
|
453
463
|
mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`;
|
|
454
464
|
} else if (preamble) {
|
|
455
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
465
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => { ${preamble} return ${safeChildren} })}`;
|
|
456
466
|
} else {
|
|
457
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
467
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => ${safeChildren})}`;
|
|
458
468
|
}
|
|
459
469
|
return `{bfComment('loop:${loop.markerId}')}${mapExpr}{bfComment('/loop:${loop.markerId}')}`;
|
|
460
470
|
}
|
package/dist/app.d.ts
CHANGED
|
@@ -63,14 +63,48 @@ export interface BarefootBuildManifest {
|
|
|
63
63
|
*/
|
|
64
64
|
export declare function manifestToScriptUrls(manifest: BarefootBuildManifest, base: string): string[];
|
|
65
65
|
export declare function relPathFromComponentsBase(p: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Shape of `barefoot-externals.json`, written by `bf build` when
|
|
68
|
+
* `externals` / `bundleEntries` are configured. Only the fields
|
|
69
|
+
* `BfImportMap` consumes are typed here; the build also emits an
|
|
70
|
+
* `externals` array (the `--external` list) which the importmap
|
|
71
|
+
* doesn't need. Fields are optional so a partial/hand-written
|
|
72
|
+
* manifest still type-checks. See issue #1639.
|
|
73
|
+
*/
|
|
74
|
+
export interface BarefootExternalsManifest {
|
|
75
|
+
/** Entries for the `<script type="importmap">`. */
|
|
76
|
+
importmap?: {
|
|
77
|
+
imports?: Record<string, string>;
|
|
78
|
+
};
|
|
79
|
+
/** URLs to emit as `<link rel="modulepreload">`. */
|
|
80
|
+
preloads?: string[];
|
|
81
|
+
}
|
|
66
82
|
export interface BfImportMapProps {
|
|
67
83
|
/** Base URL where the runtime + component bundles are served. */
|
|
68
84
|
base: string;
|
|
85
|
+
/**
|
|
86
|
+
* Contents of `barefoot-externals.json` (import it and pass it
|
|
87
|
+
* through). Its `importmap.imports` are merged on top of the
|
|
88
|
+
* built-in `@barefootjs/client*` mappings so islands importing
|
|
89
|
+
* configured externals (e.g. `zod`, `@barefootjs/form`) resolve in
|
|
90
|
+
* the browser. When omitted, only the `@barefootjs/client*`
|
|
91
|
+
* mappings are emitted — the pre-#1639 behavior.
|
|
92
|
+
*/
|
|
93
|
+
externals?: BarefootExternalsManifest;
|
|
94
|
+
/**
|
|
95
|
+
* Whether to also emit `<link rel="modulepreload">` for the
|
|
96
|
+
* manifest's `preloads`. Defaults to `true`; set `false` to emit
|
|
97
|
+
* the importmap only.
|
|
98
|
+
*/
|
|
99
|
+
preload?: boolean;
|
|
69
100
|
}
|
|
70
101
|
/**
|
|
71
102
|
* Emits the `<script type="importmap">` that maps the bare
|
|
72
103
|
* `@barefootjs/client` / `@barefootjs/client/runtime` specifiers to
|
|
73
|
-
* the runtime bundle
|
|
104
|
+
* the runtime bundle, plus any externals from `barefoot-externals.json`
|
|
105
|
+
* passed via the `externals` prop. Also emits `<link rel="modulepreload">`
|
|
106
|
+
* for the manifest's `preloads` unless `preload` is `false`. Place in
|
|
107
|
+
* `<head>`.
|
|
74
108
|
*/
|
|
75
109
|
export declare function BfImportMap(props: BfImportMapProps): HtmlEscapedString | Promise<HtmlEscapedString>;
|
|
76
110
|
export interface BfScriptsProps {
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAE7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQxD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,CAAC,aAAa,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,SAAS,CAAA;CAChF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAWV;AAED,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAID,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAE7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQxD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,CAAC,aAAa,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,SAAS,CAAA;CAChF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAWV;AAED,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,mDAAmD;IACnD,SAAS,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IAChD,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,yBAAyB,CAAA;IACrC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkBnG;AAOD,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,QAAQ,EAAE,qBAAqB,CAAA;CAChC;AAQD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAa/F;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,GAAE,gBAAqB,GAAG,iBAAiB,GAAG,IAAI,CAelF;AAID,MAAM,WAAW,wBAAwB;IACvC,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,iBAAiB,CAanF"}
|
package/dist/app.js
CHANGED
|
@@ -84,13 +84,18 @@ function relPathFromComponentsBase(p) {
|
|
|
84
84
|
}
|
|
85
85
|
function BfImportMap(props) {
|
|
86
86
|
const base = props.base.replace(/\/$/, "");
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
|
|
87
|
+
const imports = {
|
|
88
|
+
"@barefootjs/client": `${base}/barefoot.js`,
|
|
89
|
+
"@barefootjs/client/runtime": `${base}/barefoot.js`,
|
|
90
|
+
...props.externals?.importmap?.imports ?? {}
|
|
91
|
+
};
|
|
92
|
+
const json = JSON.stringify({ imports });
|
|
93
|
+
const preloads = props.preload === false ? [] : props.externals?.preloads ?? [];
|
|
94
|
+
const links = preloads.map((href) => `<link rel="modulepreload" href="${escapeAttr(href)}">`).join("");
|
|
95
|
+
return html`<script type="importmap">${raw(json)}</script>${raw(links)}`;
|
|
96
|
+
}
|
|
97
|
+
function escapeAttr(value) {
|
|
98
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
94
99
|
}
|
|
95
100
|
var __bfEmptyManifestWarned = false;
|
|
96
101
|
function BfScripts(props) {
|
package/dist/build.js
CHANGED
|
@@ -447,14 +447,24 @@ export default ${this.componentName}` : "";
|
|
|
447
447
|
if (loop.bodyIsMultiRoot) {
|
|
448
448
|
safeChildren = `<>{bfComment('bf-loop-i')}${children}</>`;
|
|
449
449
|
}
|
|
450
|
-
|
|
450
|
+
let chainedArray = applyHonoLoopChain(loop);
|
|
451
451
|
const iterMethod = loop.method ?? "map";
|
|
452
|
+
let callbackParam;
|
|
453
|
+
if (loop.iterationShape === "entries" && loop.index) {
|
|
454
|
+
chainedArray = `[...${chainedArray}.entries()]`;
|
|
455
|
+
callbackParam = `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])`;
|
|
456
|
+
} else if (loop.iterationShape === "keys") {
|
|
457
|
+
chainedArray = `[...${chainedArray}.keys()]`;
|
|
458
|
+
callbackParam = `(${loop.param}${paramAnnotation})`;
|
|
459
|
+
} else {
|
|
460
|
+
callbackParam = `(${loop.param}${paramAnnotation}${indexParam})`;
|
|
461
|
+
}
|
|
452
462
|
if (loop.flatMapCallback) {
|
|
453
463
|
mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`;
|
|
454
464
|
} else if (preamble) {
|
|
455
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
465
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => { ${preamble} return ${safeChildren} })}`;
|
|
456
466
|
} else {
|
|
457
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
467
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => ${safeChildren})}`;
|
|
458
468
|
}
|
|
459
469
|
return `{bfComment('loop:${loop.markerId}')}${mapExpr}{bfComment('/loop:${loop.markerId}')}`;
|
|
460
470
|
}
|
package/dist/index.js
CHANGED
|
@@ -447,14 +447,24 @@ export default ${this.componentName}` : "";
|
|
|
447
447
|
if (loop.bodyIsMultiRoot) {
|
|
448
448
|
safeChildren = `<>{bfComment('bf-loop-i')}${children}</>`;
|
|
449
449
|
}
|
|
450
|
-
|
|
450
|
+
let chainedArray = applyHonoLoopChain(loop);
|
|
451
451
|
const iterMethod = loop.method ?? "map";
|
|
452
|
+
let callbackParam;
|
|
453
|
+
if (loop.iterationShape === "entries" && loop.index) {
|
|
454
|
+
chainedArray = `[...${chainedArray}.entries()]`;
|
|
455
|
+
callbackParam = `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])`;
|
|
456
|
+
} else if (loop.iterationShape === "keys") {
|
|
457
|
+
chainedArray = `[...${chainedArray}.keys()]`;
|
|
458
|
+
callbackParam = `(${loop.param}${paramAnnotation})`;
|
|
459
|
+
} else {
|
|
460
|
+
callbackParam = `(${loop.param}${paramAnnotation}${indexParam})`;
|
|
461
|
+
}
|
|
452
462
|
if (loop.flatMapCallback) {
|
|
453
463
|
mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`;
|
|
454
464
|
} else if (preamble) {
|
|
455
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
465
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => { ${preamble} return ${safeChildren} })}`;
|
|
456
466
|
} else {
|
|
457
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
467
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => ${safeChildren})}`;
|
|
458
468
|
}
|
|
459
469
|
return `{bfComment('loop:${loop.markerId}')}${mapExpr}{bfComment('/loop:${loop.markerId}')}`;
|
|
460
470
|
}
|
package/dist/scripts.js
CHANGED
|
@@ -84,13 +84,18 @@ function relPathFromComponentsBase(p) {
|
|
|
84
84
|
}
|
|
85
85
|
function BfImportMap(props) {
|
|
86
86
|
const base = props.base.replace(/\/$/, "");
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
|
|
87
|
+
const imports = {
|
|
88
|
+
"@barefootjs/client": `${base}/barefoot.js`,
|
|
89
|
+
"@barefootjs/client/runtime": `${base}/barefoot.js`,
|
|
90
|
+
...props.externals?.importmap?.imports ?? {}
|
|
91
|
+
};
|
|
92
|
+
const json = JSON.stringify({ imports });
|
|
93
|
+
const preloads = props.preload === false ? [] : props.externals?.preloads ?? [];
|
|
94
|
+
const links = preloads.map((href) => `<link rel="modulepreload" href="${escapeAttr(href)}">`).join("");
|
|
95
|
+
return html`<script type="importmap">${raw(json)}</script>${raw(links)}`;
|
|
96
|
+
}
|
|
97
|
+
function escapeAttr(value) {
|
|
98
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
94
99
|
}
|
|
95
100
|
var __bfEmptyManifestWarned = false;
|
|
96
101
|
function BfScripts(props) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/hono",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Hono integration for BarefootJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -101,9 +101,9 @@
|
|
|
101
101
|
"directory": "packages/adapter-hono"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
|
-
"@barefootjs/client": "0.
|
|
105
|
-
"@barefootjs/jsx": "0.
|
|
106
|
-
"@barefootjs/shared": "0.
|
|
104
|
+
"@barefootjs/client": ">=0.2.0",
|
|
105
|
+
"@barefootjs/jsx": ">=0.2.0",
|
|
106
|
+
"@barefootjs/shared": ">=0.2.0",
|
|
107
107
|
"hono": "^4.0.0"
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BfImportMap tests
|
|
3
|
+
*
|
|
4
|
+
* Verifies the importmap merges configured externals from
|
|
5
|
+
* `barefoot-externals.json` (issue #1639) and emits modulepreload
|
|
6
|
+
* links, while preserving the pre-#1639 `@barefootjs/client*` defaults
|
|
7
|
+
* when no externals are passed.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, test, expect } from 'bun:test'
|
|
10
|
+
import { BfImportMap, type BarefootExternalsManifest } from '../app'
|
|
11
|
+
|
|
12
|
+
function parseImportMap(html: string): Record<string, string> {
|
|
13
|
+
const match = html.match(/<script type="importmap">(.*?)<\/script>/s)
|
|
14
|
+
if (!match) throw new Error(`no importmap in: ${html}`)
|
|
15
|
+
return JSON.parse(match[1]).imports
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('BfImportMap', () => {
|
|
19
|
+
test('emits @barefootjs/client defaults when no externals passed', () => {
|
|
20
|
+
const html = String(BfImportMap({ base: '/components' }))
|
|
21
|
+
expect(parseImportMap(html)).toEqual({
|
|
22
|
+
'@barefootjs/client': '/components/barefoot.js',
|
|
23
|
+
'@barefootjs/client/runtime': '/components/barefoot.js',
|
|
24
|
+
})
|
|
25
|
+
expect(html).not.toContain('modulepreload')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('strips trailing slash from base', () => {
|
|
29
|
+
const html = String(BfImportMap({ base: '/components/' }))
|
|
30
|
+
expect(parseImportMap(html)['@barefootjs/client']).toBe('/components/barefoot.js')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('merges externals importmap on top of the client defaults', () => {
|
|
34
|
+
const externals: BarefootExternalsManifest = {
|
|
35
|
+
importmap: {
|
|
36
|
+
imports: {
|
|
37
|
+
zod: 'https://esm.sh/zod@4.4.3',
|
|
38
|
+
'@barefootjs/form': '/components/form.js',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
preloads: [],
|
|
42
|
+
}
|
|
43
|
+
const imports = parseImportMap(String(BfImportMap({ base: '/components', externals })))
|
|
44
|
+
expect(imports).toEqual({
|
|
45
|
+
'@barefootjs/client': '/components/barefoot.js',
|
|
46
|
+
'@barefootjs/client/runtime': '/components/barefoot.js',
|
|
47
|
+
zod: 'https://esm.sh/zod@4.4.3',
|
|
48
|
+
'@barefootjs/form': '/components/form.js',
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('manifest @barefootjs/client mapping wins over the prop-derived one', () => {
|
|
53
|
+
const externals: BarefootExternalsManifest = {
|
|
54
|
+
importmap: { imports: { '@barefootjs/client': '/vendor/barefoot.js' } },
|
|
55
|
+
}
|
|
56
|
+
const imports = parseImportMap(String(BfImportMap({ base: '/components', externals })))
|
|
57
|
+
expect(imports['@barefootjs/client']).toBe('/vendor/barefoot.js')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('emits modulepreload links for manifest preloads', () => {
|
|
61
|
+
const externals: BarefootExternalsManifest = {
|
|
62
|
+
importmap: { imports: {} },
|
|
63
|
+
preloads: ['/components/form.js', 'https://esm.sh/zod@4.4.3'],
|
|
64
|
+
}
|
|
65
|
+
const html = String(BfImportMap({ base: '/components', externals }))
|
|
66
|
+
expect(html).toContain('<link rel="modulepreload" href="/components/form.js">')
|
|
67
|
+
expect(html).toContain('<link rel="modulepreload" href="https://esm.sh/zod@4.4.3">')
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('preload=false suppresses modulepreload links', () => {
|
|
71
|
+
const externals: BarefootExternalsManifest = {
|
|
72
|
+
preloads: ['/components/form.js'],
|
|
73
|
+
}
|
|
74
|
+
const html = String(BfImportMap({ base: '/components', externals, preload: false }))
|
|
75
|
+
expect(html).not.toContain('modulepreload')
|
|
76
|
+
// importmap still emitted
|
|
77
|
+
expect(parseImportMap(html)['@barefootjs/client']).toBe('/components/barefoot.js')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('escapes double quotes in preload hrefs', () => {
|
|
81
|
+
const externals: BarefootExternalsManifest = {
|
|
82
|
+
preloads: ['/components/"onerror=alert(1).js'],
|
|
83
|
+
}
|
|
84
|
+
const html = String(BfImportMap({ base: '/components', externals }))
|
|
85
|
+
expect(html).not.toContain('"onerror=alert(1)')
|
|
86
|
+
expect(html).toContain('"onerror=alert(1)')
|
|
87
|
+
})
|
|
88
|
+
})
|
|
@@ -822,17 +822,32 @@ export class HonoAdapter extends JsxAdapter implements IRNodeEmitter<HonoRenderC
|
|
|
822
822
|
// for both SSR (runtime-eval) and CSR (template fallback).
|
|
823
823
|
// `.toSorted` (non-mutating) preserves shared prop arrays across
|
|
824
824
|
// renders — `.sort()` here would reorder `_p.items` in place.
|
|
825
|
-
|
|
825
|
+
let chainedArray = applyHonoLoopChain(loop)
|
|
826
826
|
const iterMethod = loop.method ?? 'map'
|
|
827
827
|
|
|
828
|
+
// Re-emit `.entries()` / `.keys()` / `.values()` for Hono's runtime
|
|
829
|
+
// JS evaluation. The IR stripped the iterator call and synthesised
|
|
830
|
+
// param/index, so we reconstruct proper JS: `[...arr.entries()]`
|
|
831
|
+
// (spread into an array so `.map()` works).
|
|
832
|
+
let callbackParam: string
|
|
833
|
+
if (loop.iterationShape === 'entries' && loop.index) {
|
|
834
|
+
chainedArray = `[...${chainedArray}.entries()]`
|
|
835
|
+
callbackParam = `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])`
|
|
836
|
+
} else if (loop.iterationShape === 'keys') {
|
|
837
|
+
chainedArray = `[...${chainedArray}.keys()]`
|
|
838
|
+
callbackParam = `(${loop.param}${paramAnnotation})`
|
|
839
|
+
} else {
|
|
840
|
+
callbackParam = `(${loop.param}${paramAnnotation}${indexParam})`
|
|
841
|
+
}
|
|
842
|
+
|
|
828
843
|
if (loop.flatMapCallback) {
|
|
829
844
|
// Complex flatMap: use the original raw callback body (preserves JSX
|
|
830
845
|
// for Hono's runtime JSX evaluation).
|
|
831
846
|
mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`
|
|
832
847
|
} else if (preamble) {
|
|
833
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
848
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => { ${preamble} return ${safeChildren} })}`
|
|
834
849
|
} else {
|
|
835
|
-
mapExpr = `{${chainedArray}.${iterMethod}(
|
|
850
|
+
mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => ${safeChildren})}`
|
|
836
851
|
}
|
|
837
852
|
// Wrap with loop boundary markers so reconciliation doesn't affect siblings.
|
|
838
853
|
// bfComment('loop:<id>') → <!--bf-loop:<id>-->. The marker id is unique
|
package/src/app.ts
CHANGED
|
@@ -88,25 +88,72 @@ export function relPathFromComponentsBase(p: string): string {
|
|
|
88
88
|
|
|
89
89
|
// ── JSX components ─────────────────────────────────────────────────────────
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Shape of `barefoot-externals.json`, written by `bf build` when
|
|
93
|
+
* `externals` / `bundleEntries` are configured. Only the fields
|
|
94
|
+
* `BfImportMap` consumes are typed here; the build also emits an
|
|
95
|
+
* `externals` array (the `--external` list) which the importmap
|
|
96
|
+
* doesn't need. Fields are optional so a partial/hand-written
|
|
97
|
+
* manifest still type-checks. See issue #1639.
|
|
98
|
+
*/
|
|
99
|
+
export interface BarefootExternalsManifest {
|
|
100
|
+
/** Entries for the `<script type="importmap">`. */
|
|
101
|
+
importmap?: { imports?: Record<string, string> }
|
|
102
|
+
/** URLs to emit as `<link rel="modulepreload">`. */
|
|
103
|
+
preloads?: string[]
|
|
104
|
+
}
|
|
105
|
+
|
|
91
106
|
export interface BfImportMapProps {
|
|
92
107
|
/** Base URL where the runtime + component bundles are served. */
|
|
93
108
|
base: string
|
|
109
|
+
/**
|
|
110
|
+
* Contents of `barefoot-externals.json` (import it and pass it
|
|
111
|
+
* through). Its `importmap.imports` are merged on top of the
|
|
112
|
+
* built-in `@barefootjs/client*` mappings so islands importing
|
|
113
|
+
* configured externals (e.g. `zod`, `@barefootjs/form`) resolve in
|
|
114
|
+
* the browser. When omitted, only the `@barefootjs/client*`
|
|
115
|
+
* mappings are emitted — the pre-#1639 behavior.
|
|
116
|
+
*/
|
|
117
|
+
externals?: BarefootExternalsManifest
|
|
118
|
+
/**
|
|
119
|
+
* Whether to also emit `<link rel="modulepreload">` for the
|
|
120
|
+
* manifest's `preloads`. Defaults to `true`; set `false` to emit
|
|
121
|
+
* the importmap only.
|
|
122
|
+
*/
|
|
123
|
+
preload?: boolean
|
|
94
124
|
}
|
|
95
125
|
|
|
96
126
|
/**
|
|
97
127
|
* Emits the `<script type="importmap">` that maps the bare
|
|
98
128
|
* `@barefootjs/client` / `@barefootjs/client/runtime` specifiers to
|
|
99
|
-
* the runtime bundle
|
|
129
|
+
* the runtime bundle, plus any externals from `barefoot-externals.json`
|
|
130
|
+
* passed via the `externals` prop. Also emits `<link rel="modulepreload">`
|
|
131
|
+
* for the manifest's `preloads` unless `preload` is `false`. Place in
|
|
132
|
+
* `<head>`.
|
|
100
133
|
*/
|
|
101
134
|
export function BfImportMap(props: BfImportMapProps): HtmlEscapedString | Promise<HtmlEscapedString> {
|
|
102
135
|
const base = props.base.replace(/\/$/, '')
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
136
|
+
// Built-in defaults first, then manifest imports so a configured
|
|
137
|
+
// `@barefootjs/client` mapping (emitted by `bf build` against the
|
|
138
|
+
// build's `externalsBasePath`) wins over the prop-derived one.
|
|
139
|
+
const imports: Record<string, string> = {
|
|
140
|
+
'@barefootjs/client': `${base}/barefoot.js`,
|
|
141
|
+
'@barefootjs/client/runtime': `${base}/barefoot.js`,
|
|
142
|
+
...(props.externals?.importmap?.imports ?? {}),
|
|
143
|
+
}
|
|
144
|
+
const json = JSON.stringify({ imports })
|
|
145
|
+
|
|
146
|
+
const preloads = props.preload === false ? [] : props.externals?.preloads ?? []
|
|
147
|
+
const links = preloads
|
|
148
|
+
.map((href) => `<link rel="modulepreload" href="${escapeAttr(href)}">`)
|
|
149
|
+
.join('')
|
|
150
|
+
|
|
151
|
+
return html`<script type="importmap">${raw(json)}</script>${raw(links)}`
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Minimal double-quoted-attribute escaping for config-derived URLs. */
|
|
155
|
+
function escapeAttr(value: string): string {
|
|
156
|
+
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<')
|
|
110
157
|
}
|
|
111
158
|
|
|
112
159
|
export interface BfScriptsProps {
|