@barefootjs/hono 0.3.0 → 0.5.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 +1 -0
- package/dist/adapter/hono-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +1 -0
- package/dist/app.d.ts +15 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +2 -6
- package/dist/build.js +1 -0
- package/dist/index.js +1 -0
- package/dist/scripts.js +2 -6
- package/package.json +1 -1
- package/src/__tests__/import-map.test.ts +18 -8
- package/src/adapter/hono-adapter.ts +3 -0
- package/src/app.ts +18 -27
|
@@ -44,6 +44,7 @@ export declare class HonoAdapter extends JsxAdapter implements IRNodeEmitter<Hon
|
|
|
44
44
|
name: string;
|
|
45
45
|
extension: string;
|
|
46
46
|
clientShimSource: string;
|
|
47
|
+
importMapInjection: 'component';
|
|
47
48
|
acceptsTemplateCall: () => boolean;
|
|
48
49
|
protected jsxConfig: JsxAdapterConfig;
|
|
49
50
|
private options;
|
|
@@ -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;
|
|
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
package/dist/app.d.ts
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import type { MiddlewareHandler } from 'hono';
|
|
29
29
|
import type { HtmlEscapedString } from 'hono/utils/html';
|
|
30
|
+
import { type ImportMapManifest } from '@barefootjs/jsx/import-map';
|
|
30
31
|
/**
|
|
31
32
|
* Build manifest shape produced by `bf build`. Each compiled
|
|
32
33
|
* component is keyed by its manifest name; `__barefoot__` is the
|
|
@@ -63,22 +64,6 @@ export interface BarefootBuildManifest {
|
|
|
63
64
|
*/
|
|
64
65
|
export declare function manifestToScriptUrls(manifest: BarefootBuildManifest, base: string): string[];
|
|
65
66
|
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
|
-
}
|
|
82
67
|
export interface BfImportMapProps {
|
|
83
68
|
/** Base URL where the runtime + component bundles are served. */
|
|
84
69
|
base: string;
|
|
@@ -89,8 +74,12 @@ export interface BfImportMapProps {
|
|
|
89
74
|
* configured externals (e.g. `zod`, `@barefootjs/form`) resolve in
|
|
90
75
|
* the browser. When omitted, only the `@barefootjs/client*`
|
|
91
76
|
* mappings are emitted — the pre-#1639 behavior.
|
|
77
|
+
*
|
|
78
|
+
* Typed with the shared {@link ImportMapManifest} from `@barefootjs/jsx`,
|
|
79
|
+
* so the component and the `bf build` snippet path describe the manifest
|
|
80
|
+
* with one type.
|
|
92
81
|
*/
|
|
93
|
-
externals?:
|
|
82
|
+
externals?: ImportMapManifest;
|
|
94
83
|
/**
|
|
95
84
|
* Whether to also emit `<link rel="modulepreload">` for the
|
|
96
85
|
* manifest's `preloads`. Defaults to `true`; set `false` to emit
|
|
@@ -105,6 +94,15 @@ export interface BfImportMapProps {
|
|
|
105
94
|
* passed via the `externals` prop. Also emits `<link rel="modulepreload">`
|
|
106
95
|
* for the manifest's `preloads` unless `preload` is `false`. Place in
|
|
107
96
|
* `<head>`.
|
|
97
|
+
*
|
|
98
|
+
* The merge of the `@barefootjs/client*` defaults (synthesized from `base`
|
|
99
|
+
* for prop-less / hand-written manifests) is Hono-specific; the actual HTML
|
|
100
|
+
* rendering — importmap JSON escaping, `<link rel="modulepreload">`
|
|
101
|
+
* emission with `crossorigin` (#1648) — is delegated to the shared
|
|
102
|
+
* `renderImportMapHtml` so this path can never drift from the static
|
|
103
|
+
* `barefoot-importmap.html` snippet `bf build` emits for template-string
|
|
104
|
+
* adapters (#1644). Imported from the `@barefootjs/jsx/import-map` subpath,
|
|
105
|
+
* a zero-dependency module, to keep this runtime file free of the compiler.
|
|
108
106
|
*/
|
|
109
107
|
export declare function BfImportMap(props: BfImportMapProps): HtmlEscapedString | Promise<HtmlEscapedString>;
|
|
110
108
|
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;
|
|
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;AAIxD,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAOxF;;;;;;;;;;;;;;;;;;;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;IACZ;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAA;IAC7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAanG;AAED,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
|
@@ -64,6 +64,7 @@ data: ${BOOT_ID}
|
|
|
64
64
|
// src/app.ts
|
|
65
65
|
import { html, raw } from "hono/html";
|
|
66
66
|
import { useRequestContext } from "hono/jsx-renderer";
|
|
67
|
+
import { renderImportMapHtml } from "@barefootjs/jsx/import-map";
|
|
67
68
|
var DEV_RELOAD_ENDPOINT_KEY = "bfDevReloadEndpoint";
|
|
68
69
|
function manifestToScriptUrls(manifest, base) {
|
|
69
70
|
const out = [];
|
|
@@ -89,13 +90,8 @@ function BfImportMap(props) {
|
|
|
89
90
|
"@barefootjs/client/runtime": `${base}/barefoot.js`,
|
|
90
91
|
...props.externals?.importmap?.imports ?? {}
|
|
91
92
|
};
|
|
92
|
-
const json = JSON.stringify({ imports });
|
|
93
93
|
const preloads = props.preload === false ? [] : props.externals?.preloads ?? [];
|
|
94
|
-
|
|
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
|
+
return html`${raw(renderImportMapHtml({ importmap: { imports }, preloads }))}`;
|
|
99
95
|
}
|
|
100
96
|
var __bfEmptyManifestWarned = false;
|
|
101
97
|
function BfScripts(props) {
|
package/dist/build.js
CHANGED
package/dist/index.js
CHANGED
package/dist/scripts.js
CHANGED
|
@@ -64,6 +64,7 @@ data: ${BOOT_ID}
|
|
|
64
64
|
// src/app.ts
|
|
65
65
|
import { html, raw } from "hono/html";
|
|
66
66
|
import { useRequestContext } from "hono/jsx-renderer";
|
|
67
|
+
import { renderImportMapHtml } from "@barefootjs/jsx/import-map";
|
|
67
68
|
var DEV_RELOAD_ENDPOINT_KEY = "bfDevReloadEndpoint";
|
|
68
69
|
function manifestToScriptUrls(manifest, base) {
|
|
69
70
|
const out = [];
|
|
@@ -89,13 +90,8 @@ function BfImportMap(props) {
|
|
|
89
90
|
"@barefootjs/client/runtime": `${base}/barefoot.js`,
|
|
90
91
|
...props.externals?.importmap?.imports ?? {}
|
|
91
92
|
};
|
|
92
|
-
const json = JSON.stringify({ imports });
|
|
93
93
|
const preloads = props.preload === false ? [] : props.externals?.preloads ?? [];
|
|
94
|
-
|
|
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
|
+
return html`${raw(renderImportMapHtml({ importmap: { imports }, preloads }))}`;
|
|
99
95
|
}
|
|
100
96
|
var __bfEmptyManifestWarned = false;
|
|
101
97
|
function BfScripts(props) {
|
package/package.json
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* when no externals are passed.
|
|
8
8
|
*/
|
|
9
9
|
import { describe, test, expect } from 'bun:test'
|
|
10
|
-
import { BfImportMap
|
|
10
|
+
import { BfImportMap } from '../app'
|
|
11
|
+
import type { ImportMapManifest } from '@barefootjs/jsx'
|
|
11
12
|
|
|
12
13
|
function parseImportMap(html: string): Record<string, string> {
|
|
13
14
|
const match = html.match(/<script type="importmap">(.*?)<\/script>/s)
|
|
@@ -31,7 +32,7 @@ describe('BfImportMap', () => {
|
|
|
31
32
|
})
|
|
32
33
|
|
|
33
34
|
test('merges externals importmap on top of the client defaults', () => {
|
|
34
|
-
const externals:
|
|
35
|
+
const externals: ImportMapManifest = {
|
|
35
36
|
importmap: {
|
|
36
37
|
imports: {
|
|
37
38
|
zod: 'https://esm.sh/zod@4.4.3',
|
|
@@ -50,7 +51,7 @@ describe('BfImportMap', () => {
|
|
|
50
51
|
})
|
|
51
52
|
|
|
52
53
|
test('manifest @barefootjs/client mapping wins over the prop-derived one', () => {
|
|
53
|
-
const externals:
|
|
54
|
+
const externals: ImportMapManifest = {
|
|
54
55
|
importmap: { imports: { '@barefootjs/client': '/vendor/barefoot.js' } },
|
|
55
56
|
}
|
|
56
57
|
const imports = parseImportMap(String(BfImportMap({ base: '/components', externals })))
|
|
@@ -58,17 +59,26 @@ describe('BfImportMap', () => {
|
|
|
58
59
|
})
|
|
59
60
|
|
|
60
61
|
test('emits modulepreload links for manifest preloads', () => {
|
|
61
|
-
const externals:
|
|
62
|
+
const externals: ImportMapManifest = {
|
|
62
63
|
importmap: { imports: {} },
|
|
63
64
|
preloads: ['/components/form.js', 'https://esm.sh/zod@4.4.3'],
|
|
64
65
|
}
|
|
65
66
|
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">')
|
|
67
|
+
expect(html).toContain('<link rel="modulepreload" href="/components/form.js" crossorigin>')
|
|
68
|
+
expect(html).toContain('<link rel="modulepreload" href="https://esm.sh/zod@4.4.3" crossorigin>')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('emits crossorigin on modulepreload so cross-origin CDN preloads are reused', () => {
|
|
72
|
+
const externals: ImportMapManifest = {
|
|
73
|
+
preloads: ['https://esm.sh/zod@4.4.3'],
|
|
74
|
+
}
|
|
75
|
+
const html = String(BfImportMap({ base: '/components', externals }))
|
|
76
|
+
const match = html.match(/<link rel="modulepreload"[^>]*>/)
|
|
77
|
+
expect(match?.[0]).toContain('crossorigin')
|
|
68
78
|
})
|
|
69
79
|
|
|
70
80
|
test('preload=false suppresses modulepreload links', () => {
|
|
71
|
-
const externals:
|
|
81
|
+
const externals: ImportMapManifest = {
|
|
72
82
|
preloads: ['/components/form.js'],
|
|
73
83
|
}
|
|
74
84
|
const html = String(BfImportMap({ base: '/components', externals, preload: false }))
|
|
@@ -78,7 +88,7 @@ describe('BfImportMap', () => {
|
|
|
78
88
|
})
|
|
79
89
|
|
|
80
90
|
test('escapes double quotes in preload hrefs', () => {
|
|
81
|
-
const externals:
|
|
91
|
+
const externals: ImportMapManifest = {
|
|
82
92
|
preloads: ['/components/"onerror=alert(1).js'],
|
|
83
93
|
}
|
|
84
94
|
const html = String(BfImportMap({ base: '/components', externals }))
|
|
@@ -103,6 +103,9 @@ export class HonoAdapter extends JsxAdapter implements IRNodeEmitter<HonoRenderC
|
|
|
103
103
|
name = 'hono'
|
|
104
104
|
extension = '.tsx'
|
|
105
105
|
clientShimSource = '@barefootjs/hono/client-shim'
|
|
106
|
+
// Importmap is injected at render time by the `BfImportMap` component
|
|
107
|
+
// (reads `barefoot-externals.json`), so `bf build` emits no static snippet.
|
|
108
|
+
importMapInjection = 'component' as const
|
|
106
109
|
|
|
107
110
|
// The Hono SSR runtime is JavaScript (Node / Bun / CF Workers), so any
|
|
108
111
|
// synchronous JS call the user writes can be rendered as-is at template
|
package/src/app.ts
CHANGED
|
@@ -30,6 +30,9 @@ import type { MiddlewareHandler } from 'hono'
|
|
|
30
30
|
import { html, raw } from 'hono/html'
|
|
31
31
|
import type { HtmlEscapedString } from 'hono/utils/html'
|
|
32
32
|
import { useRequestContext } from 'hono/jsx-renderer'
|
|
33
|
+
// Zero-dependency subpath — keeps the compiler (and its `typescript` dep) out
|
|
34
|
+
// of this runtime/Workers-bundled module while sharing one importmap renderer.
|
|
35
|
+
import { renderImportMapHtml, type ImportMapManifest } from '@barefootjs/jsx/import-map'
|
|
33
36
|
import { createDevReloader } from './dev-worker'
|
|
34
37
|
|
|
35
38
|
const DEV_RELOAD_ENDPOINT_KEY = 'bfDevReloadEndpoint'
|
|
@@ -88,21 +91,6 @@ export function relPathFromComponentsBase(p: string): string {
|
|
|
88
91
|
|
|
89
92
|
// ── JSX components ─────────────────────────────────────────────────────────
|
|
90
93
|
|
|
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
|
-
|
|
106
94
|
export interface BfImportMapProps {
|
|
107
95
|
/** Base URL where the runtime + component bundles are served. */
|
|
108
96
|
base: string
|
|
@@ -113,8 +101,12 @@ export interface BfImportMapProps {
|
|
|
113
101
|
* configured externals (e.g. `zod`, `@barefootjs/form`) resolve in
|
|
114
102
|
* the browser. When omitted, only the `@barefootjs/client*`
|
|
115
103
|
* mappings are emitted — the pre-#1639 behavior.
|
|
104
|
+
*
|
|
105
|
+
* Typed with the shared {@link ImportMapManifest} from `@barefootjs/jsx`,
|
|
106
|
+
* so the component and the `bf build` snippet path describe the manifest
|
|
107
|
+
* with one type.
|
|
116
108
|
*/
|
|
117
|
-
externals?:
|
|
109
|
+
externals?: ImportMapManifest
|
|
118
110
|
/**
|
|
119
111
|
* Whether to also emit `<link rel="modulepreload">` for the
|
|
120
112
|
* manifest's `preloads`. Defaults to `true`; set `false` to emit
|
|
@@ -130,6 +122,15 @@ export interface BfImportMapProps {
|
|
|
130
122
|
* passed via the `externals` prop. Also emits `<link rel="modulepreload">`
|
|
131
123
|
* for the manifest's `preloads` unless `preload` is `false`. Place in
|
|
132
124
|
* `<head>`.
|
|
125
|
+
*
|
|
126
|
+
* The merge of the `@barefootjs/client*` defaults (synthesized from `base`
|
|
127
|
+
* for prop-less / hand-written manifests) is Hono-specific; the actual HTML
|
|
128
|
+
* rendering — importmap JSON escaping, `<link rel="modulepreload">`
|
|
129
|
+
* emission with `crossorigin` (#1648) — is delegated to the shared
|
|
130
|
+
* `renderImportMapHtml` so this path can never drift from the static
|
|
131
|
+
* `barefoot-importmap.html` snippet `bf build` emits for template-string
|
|
132
|
+
* adapters (#1644). Imported from the `@barefootjs/jsx/import-map` subpath,
|
|
133
|
+
* a zero-dependency module, to keep this runtime file free of the compiler.
|
|
133
134
|
*/
|
|
134
135
|
export function BfImportMap(props: BfImportMapProps): HtmlEscapedString | Promise<HtmlEscapedString> {
|
|
135
136
|
const base = props.base.replace(/\/$/, '')
|
|
@@ -141,19 +142,9 @@ export function BfImportMap(props: BfImportMapProps): HtmlEscapedString | Promis
|
|
|
141
142
|
'@barefootjs/client/runtime': `${base}/barefoot.js`,
|
|
142
143
|
...(props.externals?.importmap?.imports ?? {}),
|
|
143
144
|
}
|
|
144
|
-
const json = JSON.stringify({ imports })
|
|
145
|
-
|
|
146
145
|
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
146
|
|
|
154
|
-
|
|
155
|
-
function escapeAttr(value: string): string {
|
|
156
|
-
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<')
|
|
147
|
+
return html`${raw(renderImportMapHtml({ importmap: { imports }, preloads }))}`
|
|
157
148
|
}
|
|
158
149
|
|
|
159
150
|
export interface BfScriptsProps {
|