void-plugin-hono-jsx 0.1.0-alpha.2 → 0.1.0-alpha.4
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/CHANGELOG.md +59 -0
- package/README.md +73 -20
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/dist/browser/client.d.ts +2 -1
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/client.js +76 -22
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/document-head.d.ts +1 -1
- package/dist/browser/document-head.d.ts.map +1 -1
- package/dist/browser/document-head.js +22 -1
- package/dist/browser/document-head.js.map +1 -1
- package/dist/browser/form-view.d.ts +10 -0
- package/dist/browser/form-view.d.ts.map +1 -0
- package/dist/browser/form-view.js +16 -0
- package/dist/browser/form-view.js.map +1 -0
- package/dist/browser/form.d.ts +28 -12
- package/dist/browser/form.d.ts.map +1 -1
- package/dist/browser/form.js +84 -23
- package/dist/browser/form.js.map +1 -1
- package/dist/browser/markdown.d.ts +15 -0
- package/dist/browser/markdown.d.ts.map +1 -0
- package/dist/browser/markdown.js +6 -0
- package/dist/browser/markdown.js.map +1 -0
- package/dist/browser/navigation.d.ts +13 -0
- package/dist/browser/navigation.d.ts.map +1 -0
- package/dist/browser/navigation.js +83 -0
- package/dist/browser/navigation.js.map +1 -0
- package/dist/browser/pages.d.ts +33 -3
- package/dist/browser/pages.d.ts.map +1 -1
- package/dist/browser/pages.js +76 -13
- package/dist/browser/pages.js.map +1 -1
- package/dist/plugins/compatibility.d.ts +12 -1
- package/dist/plugins/compatibility.d.ts.map +1 -1
- package/dist/plugins/compatibility.js +65 -22
- package/dist/plugins/compatibility.js.map +1 -1
- package/dist/plugins/hono-islands.d.ts +1 -1
- package/dist/plugins/hono-islands.d.ts.map +1 -1
- package/dist/plugins/hono-islands.js +156 -24
- package/dist/plugins/hono-islands.js.map +1 -1
- package/dist/plugins/hono-markdown.d.ts +4 -0
- package/dist/plugins/hono-markdown.d.ts.map +1 -0
- package/dist/plugins/hono-markdown.js +91 -0
- package/dist/plugins/hono-markdown.js.map +1 -0
- package/dist/plugins/hono-pages.d.ts +10 -2
- package/dist/plugins/hono-pages.d.ts.map +1 -1
- package/dist/plugins/hono-pages.js +55 -18
- package/dist/plugins/hono-pages.js.map +1 -1
- package/dist/plugins/markdown-api.d.ts +10 -0
- package/dist/plugins/markdown-api.d.ts.map +1 -0
- package/dist/plugins/markdown-api.js +13 -0
- package/dist/plugins/markdown-api.js.map +1 -0
- package/dist/plugins/markdown-compiler.d.ts +43 -0
- package/dist/plugins/markdown-compiler.d.ts.map +1 -0
- package/dist/plugins/markdown-compiler.js +91 -0
- package/dist/plugins/markdown-compiler.js.map +1 -0
- package/dist/plugins/resolve-component.d.ts +3 -0
- package/dist/plugins/resolve-component.d.ts.map +1 -0
- package/dist/plugins/resolve-component.js +15 -0
- package/dist/plugins/resolve-component.js.map +1 -0
- package/dist/plugins/runtime-paths.d.ts +1 -0
- package/dist/plugins/runtime-paths.d.ts.map +1 -1
- package/dist/plugins/runtime-paths.js +2 -0
- package/dist/plugins/runtime-paths.js.map +1 -1
- package/dist/server/form-view.d.ts +10 -0
- package/dist/server/form-view.d.ts.map +1 -0
- package/dist/server/form-view.js +16 -0
- package/dist/server/form-view.js.map +1 -0
- package/dist/server/form.d.ts +28 -12
- package/dist/server/form.d.ts.map +1 -1
- package/dist/server/form.js +84 -23
- package/dist/server/form.js.map +1 -1
- package/dist/server/markdown.d.ts +15 -0
- package/dist/server/markdown.d.ts.map +1 -0
- package/dist/server/markdown.js +6 -0
- package/dist/server/markdown.js.map +1 -0
- package/dist/server/pages.d.ts +33 -3
- package/dist/server/pages.d.ts.map +1 -1
- package/dist/server/pages.js +76 -13
- package/dist/server/pages.js.map +1 -1
- package/package.json +24 -6
- package/src/plugins/compatibility.ts +56 -19
- package/src/plugins/hono-islands.ts +121 -23
- package/src/plugins/hono-markdown.ts +78 -0
- package/src/plugins/hono-pages.ts +54 -17
- package/src/plugins/markdown-api.ts +17 -0
- package/src/plugins/markdown-compiler.ts +77 -0
- package/src/plugins/resolve-component.ts +12 -0
- package/src/plugins/runtime-paths.ts +2 -0
- package/src/runtime/client.tsx +66 -24
- package/src/runtime/document-head.ts +20 -1
- package/src/runtime/form-view.tsx +23 -0
- package/src/runtime/form.ts +82 -41
- package/src/runtime/markdown.ts +7 -0
- package/src/runtime/navigation.ts +72 -0
- package/src/runtime/pages.tsx +77 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/runtime/pages.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAY,MAAM,UAAU,CAAC;AAK/D,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAC;AAElE,SAAS,OAAO;IACd,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,SAAS,KAAK,OAAO,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,MAAM,UAAU,SAAS,KAAK,OAAO,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,MAAM,UAAU,SAAS,KAAK,OAAO,OAAO,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;AAE9D,MAAM,UAAU,SAAS;IACvB,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC;AAChB,CAAC;AASD,MAAM,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,UAAU,EAAa;IACvF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,OAAO,eAAO,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,KAAiB,EAAE,EAAE;YACnE,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;YACjB,IAAI,KAAK,CAAC,gBAAgB,IAAI,cAAc,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO;YAC/I,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAAE,OAAO;YAC3J,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,OAAO;YACjG,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBAC3D,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YAC1F,CAAC,CAAC,CAAC;QACL,CAAC,GAAI,CAAC;AACR,CAAC","sourcesContent":["import { createContext, useContext, type JSX } from 'hono/jsx';\nimport type { VoidRouter } from 'void/pages-client';\nimport type { PageObject } from 'void/pages-protocol';\nexport type { DeferredState as Deferred } from 'void';\n\nexport const RouterContext = createContext<VoidRouter | null>(null);\nexport const PageContext = createContext<PageObject | null>(null);\n\nfunction usePage() {\n const page = useContext(PageContext);\n if (!page) throw new Error('Hono Pages: page data requires a page provider.');\n return page;\n}\n\nexport function useShared() { return usePage().shared; }\nexport function useParams() { return usePage().params; }\nexport function useErrors() { return usePage().errors ?? {}; }\n\nexport function useRouter(): VoidRouter {\n const router = useContext(RouterContext);\n if (!router) throw new Error('Hono Pages: useRouter requires a page provider.');\n return router;\n}\n\ntype LinkProps = Omit<JSX.IntrinsicElements['a'], 'href' | 'onClick'> & {\n href: string;\n reloadDocument?: boolean;\n replace?: boolean;\n onClick?: (event: MouseEvent) => void;\n};\n\nexport function Link({ href, reloadDocument, replace, onClick, ...attributes }: LinkProps) {\n const router = useRouter();\n return <a {...attributes} href={href} onClick={(event: MouseEvent) => {\n onClick?.(event);\n if (event.defaultPrevented || reloadDocument || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n if (attributes.download !== undefined || (attributes.target && attributes.target !== '_self') || attributes.rel?.split(/\\s+/).includes('external')) return;\n const url = new URL(href, window.location.href);\n if (url.origin !== window.location.origin || !['http:', 'https:'].includes(url.protocol)) return;\n event.preventDefault();\n void router.visit(url, { replace }).catch((error: unknown) => {\n window.dispatchEvent(new CustomEvent('hono-pages:navigation-error', { detail: error }));\n });\n }} />;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/runtime/pages.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useContext, useEffect, useRef, type JSX } from 'hono/jsx';\nimport { createActionClient, mergeDataIntoHref, type NavigationState, type NavigationMethod, type VoidRouter } from 'void/pages-client';\nimport type { CacheForInput } from 'void/pages-prefetch';\nimport type { PageObject } from 'void/pages-protocol';\nexport type { DeferredState as Deferred } from 'void';\n\nconst actionClient = createActionClient();\nexport const action = actionClient.action;\nexport const setActionRouter = actionClient.setActionRouter;\n\nexport const RouterContext = createContext<VoidRouter | null>(null);\nexport const NavigationContext = createContext<NavigationState | null>(null);\nexport const PageContext = createContext<PageObject | null>(null);\n\nfunction usePage() {\n const page = useContext(PageContext);\n if (!page) throw new Error('Hono Pages: page data requires a page provider.');\n return page;\n}\n\nexport function useNavigation(): NavigationState {\n const navigation = useContext(NavigationContext);\n if (!navigation) throw new Error('Hono Pages: useNavigation requires a page provider.');\n return navigation;\n}\n\nexport function useShared() { return usePage().shared; }\nexport function useParams() { return usePage().params; }\nexport function useErrors() { return usePage().errors ?? {}; }\n\nexport function useRouter(): VoidRouter {\n const router = useContext(RouterContext);\n if (!router) throw new Error('Hono Pages: useRouter requires a page provider.');\n return router;\n}\n\nexport type PrefetchStrategy = 'hover' | 'click' | 'mount' | 'visible';\nexport type LinkProps = Omit<JSX.IntrinsicElements['a'], 'href' | 'onClick'> & {\n href: string;\n method?: NavigationMethod | Lowercase<NavigationMethod>;\n data?: Record<string, unknown>;\n preserveScroll?: boolean;\n preserveState?: boolean;\n reloadDocument?: boolean;\n replace?: boolean;\n viewTransition?: boolean;\n prefetch?: boolean | PrefetchStrategy | ReadonlyArray<PrefetchStrategy>;\n cacheFor?: CacheForInput;\n onNavigate?: (event: { preventDefault(): void }) => void;\n onClick?: (event: MouseEvent) => void;\n};\n\nexport function Link({ href, method = 'GET', data, preserveScroll, preserveState, reloadDocument, replace, viewTransition,\n prefetch = false, cacheFor, onNavigate, onClick, onMouseEnter, onMouseLeave, onFocus, onMouseDown, onTouchStart,\n ...attributes }: LinkProps) {\n const router = useRouter();\n const element = useRef<HTMLAnchorElement | HTMLButtonElement | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const normalized = method.toUpperCase();\n const get = normalized === 'GET';\n if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(normalized)) throw new Error('Hono Link: unsupported method.');\n if (!get && (prefetch !== false || reloadDocument)) throw new Error('Hono Link: prefetch and reloadDocument only support GET links.');\n const destination = get ? mergeDataIntoHref(href, data) : href;\n const strategies = reloadDocument || prefetch === false ? [] : prefetch === true ? ['hover'] : typeof prefetch === 'string' ? [prefetch] : prefetch;\n if (strategies.some((strategy) => !['hover', 'click', 'mount', 'visible'].includes(strategy))) throw new Error('Hono Link: unsupported prefetch strategy.');\n const clear = () => { clearTimeout(timer.current); timer.current = undefined; };\n const canHandle = () => {\n const url = new URL(destination, window.location.href);\n return !reloadDocument && attributes.download === undefined && (!attributes.target || attributes.target === '_self') &&\n !attributes.rel?.split(/\\s+/).includes('external') && url.origin === window.location.origin && ['http:', 'https:'].includes(url.protocol);\n };\n const report = (error: unknown) => window.dispatchEvent(new CustomEvent('hono-pages:navigation-error', { detail: error }));\n const fetchAhead = () => {\n if (canHandle()) void router.prefetch(destination, { cacheFor }).catch(report);\n };\n useEffect(() => {\n if (strategies.includes('mount')) fetchAhead();\n let observer: IntersectionObserver | undefined;\n if (strategies.includes('visible') && element.current) {\n observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) { observer?.disconnect(); fetchAhead(); }\n });\n observer.observe(element.current);\n }\n return () => { clear(); observer?.disconnect(); };\n }, [destination, prefetch, cacheFor, reloadDocument, router]);\n const events = {\n onClick(event: MouseEvent) {\n onClick?.(event);\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || !canHandle()) return;\n let cancelled = false;\n onNavigate?.({ preventDefault() { cancelled = true; } });\n event.preventDefault();\n if (!cancelled) void router.visit(new URL(destination, window.location.href), { method: normalized, data: get ? undefined : data, preserveScroll, preserveState, replace, viewTransition }).catch(report);\n },\n onMouseEnter(event: MouseEvent) {\n onMouseEnter?.(event); clear();\n if (!event.defaultPrevented && strategies.includes('hover')) timer.current = setTimeout(fetchAhead, router._hoverDelay);\n },\n onMouseLeave(event: MouseEvent) { onMouseLeave?.(event); clear(); },\n onFocus(event: FocusEvent) { onFocus?.(event); if (!event.defaultPrevented && strategies.includes('hover')) fetchAhead(); },\n onMouseDown(event: MouseEvent) { onMouseDown?.(event); if (!event.defaultPrevented && strategies.includes('click')) fetchAhead(); },\n onTouchStart(event: TouchEvent) { onTouchStart?.(event); if (!event.defaultPrevented && strategies.includes('click')) fetchAhead(); },\n };\n if (get) return <a {...attributes} {...events} ref={element} href={destination} />;\n return <button {...attributes} {...events} ref={element} type=\"button\" />;\n}\n"]}
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare const supportedFrameworkRanges: {
|
|
2
|
+
void: string;
|
|
3
|
+
hono: string;
|
|
4
|
+
vite: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const supportedViteRange: string;
|
|
7
|
+
export declare function supportsFramework(name: keyof typeof supportedFrameworkRanges, version: unknown): boolean;
|
|
8
|
+
export declare const supportsVite: (version: unknown) => boolean;
|
|
9
|
+
export declare function assertSupportedFrameworks({ root, viteVersion }: {
|
|
10
|
+
root: string;
|
|
11
|
+
viteVersion: unknown;
|
|
12
|
+
}): void;
|
|
2
13
|
//# sourceMappingURL=compatibility.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../src/plugins/compatibility.ts"],"names":[],"mappings":"AAKA,wBAAgB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../src/plugins/compatibility.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,wBAAwB;IACnC,IAAI;IACJ,IAAI;IACJ,IAAI;CACL,CAAC;AACF,eAAO,MAAM,kBAAkB,QAAgC,CAAC;AAIhE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,OAAO,wBAAwB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CASxG;AACD,eAAO,MAAM,YAAY,YAAa,OAAO,KAAG,OAA6C,CAAC;AAwB9F,wBAAgB,yBAAyB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,QAetG"}
|
|
@@ -1,30 +1,73 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
import { version as helperViteVersion } from 'vite';
|
|
5
|
+
export const supportedFrameworkRanges = {
|
|
6
|
+
void: '>=0.26.1 <0.28.0',
|
|
7
|
+
hono: '>=4.13.13 <5.0.0',
|
|
8
|
+
vite: '>=8.0.16 <9.0.0',
|
|
9
|
+
};
|
|
10
|
+
export const supportedViteRange = supportedFrameworkRanges.vite;
|
|
11
|
+
// Only stable releases are admitted. Void is pre-1.0, so its next minor
|
|
12
|
+
// requires explicit validation; Hono and Vite use their current major lines.
|
|
13
|
+
export function supportsFramework(name, version) {
|
|
14
|
+
if (typeof version !== 'string')
|
|
15
|
+
return false;
|
|
16
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
|
|
17
|
+
if (!match)
|
|
18
|
+
return false;
|
|
19
|
+
const [major, minor, patch] = match.slice(1).map(Number);
|
|
20
|
+
if (![major, minor, patch].every(Number.isSafeInteger))
|
|
21
|
+
return false;
|
|
22
|
+
if (name === 'void')
|
|
23
|
+
return major === 0 && ((minor === 26 && patch >= 1) || minor === 27);
|
|
24
|
+
if (name === 'hono')
|
|
25
|
+
return major === 4 && (minor > 13 || (minor === 13 && patch >= 13));
|
|
26
|
+
return major === 8 && (minor > 0 || patch >= 16);
|
|
27
|
+
}
|
|
28
|
+
export const supportsVite = (version) => supportsFramework('vite', version);
|
|
29
|
+
function packageInfo(name, require) {
|
|
30
|
+
let directory = dirname(require.resolve(name));
|
|
31
|
+
while (true) {
|
|
32
|
+
const path = join(directory, 'package.json');
|
|
33
|
+
if (existsSync(path)) {
|
|
34
|
+
const metadata = JSON.parse(readFileSync(path, 'utf8'));
|
|
35
|
+
if (typeof metadata === 'object' && metadata !== null && 'name' in metadata && (metadata.name === name || (name === 'vite' && metadata.name === '@voidzero-dev/vite-plus-core'))) {
|
|
36
|
+
if (!('version' in metadata) || typeof metadata.version !== 'string')
|
|
37
|
+
throw new Error(`Hono Pages: ${name} package version is missing (${path}).`);
|
|
38
|
+
return { version: metadata.version, path };
|
|
20
39
|
}
|
|
21
|
-
const parent = dirname(directory);
|
|
22
|
-
if (parent === directory)
|
|
23
|
-
throw new Error(`Hono Pages: cannot locate ${name} package metadata.`);
|
|
24
|
-
directory = parent;
|
|
25
40
|
}
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
const parent = dirname(directory);
|
|
42
|
+
if (parent === directory)
|
|
43
|
+
throw new Error(`Hono Pages: cannot locate ${name} package metadata from ${require.resolve(name)}.`);
|
|
44
|
+
directory = parent;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function describe(name, require) {
|
|
48
|
+
try {
|
|
49
|
+
const info = packageInfo(name, require);
|
|
50
|
+
return `${info.path} (metadata ${info.version})`;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return `not resolved from ${require.resolve.paths(name)?.join(', ') ?? 'this context'}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function assertSupportedFrameworks({ root, viteVersion }) {
|
|
57
|
+
const adapter = createRequire(import.meta.url);
|
|
58
|
+
const project = createRequire(join(root, 'package.json'));
|
|
59
|
+
const diagnostic = () => `Running Vite from hook context: ${typeof viteVersion === 'string' ? viteVersion : 'unavailable'}. Adapter helper Vite: ${helperViteVersion}; package.json: ${describe('vite', adapter)}. Project Vite package.json: ${describe('vite', project)}. Package paths are diagnostics, not the running Vite identity.`;
|
|
60
|
+
if (!supportsVite(viteVersion)) {
|
|
61
|
+
throw new Error(`Hono Pages: running Vite ${typeof viteVersion === 'string' ? viteVersion : 'unavailable'} is unsupported; expected ${supportedViteRange}. ${diagnostic()} Update the CLI/launcher that executes Vite. For bundled launchers such as vp, installing project vite alone does not update the running Vite. For standard Vite, install vite@^8.3.4 and run vite directly.`);
|
|
62
|
+
}
|
|
63
|
+
if (!supportsVite(helperViteVersion)) {
|
|
64
|
+
throw new Error(`Hono Pages: adapter helper Vite ${helperViteVersion} is unsupported; expected ${supportedViteRange}. ${diagnostic()} Inspect the adapter's resolved peer copy; install vite@^8.3.4 and refresh the adapter's peer resolution/lockfile if a stale copy remains.`);
|
|
65
|
+
}
|
|
66
|
+
for (const name of ['void', 'hono']) {
|
|
67
|
+
const expected = supportedFrameworkRanges[name];
|
|
68
|
+
const info = packageInfo(name, adapter);
|
|
69
|
+
if (!supportsFramework(name, info.version))
|
|
70
|
+
throw new Error(`Hono Pages: ${name} ${info.version} is unsupported; install ${name}@"${expected}". Resolved package.json: ${info.path}. Project package.json: ${describe(name, project)}. ${diagnostic()}`);
|
|
28
71
|
}
|
|
29
72
|
}
|
|
30
73
|
//# sourceMappingURL=compatibility.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../../src/plugins/compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../../src/plugins/compatibility.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRequire } from 'node:module';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { version as helperViteVersion } from 'vite';\n\nexport const supportedFrameworkRanges = {\n void: '>=0.26.1 <0.28.0',\n hono: '>=4.13.13 <5.0.0',\n vite: '>=8.0.16 <9.0.0',\n};\nexport const supportedViteRange = supportedFrameworkRanges.vite;\n\n// Only stable releases are admitted. Void is pre-1.0, so its next minor\n// requires explicit validation; Hono and Vite use their current major lines.\nexport function supportsFramework(name: keyof typeof supportedFrameworkRanges, version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/.exec(version);\n if (!match) return false;\n const [major, minor, patch] = match.slice(1).map(Number);\n if (![major, minor, patch].every(Number.isSafeInteger)) return false;\n if (name === 'void') return major === 0 && ((minor === 26 && patch >= 1) || minor === 27);\n if (name === 'hono') return major === 4 && (minor > 13 || (minor === 13 && patch >= 13));\n return major === 8 && (minor > 0 || patch >= 16);\n}\nexport const supportsVite = (version: unknown): boolean => supportsFramework('vite', version);\n\ntype PackageInfo = { version: string; path: string };\nfunction packageInfo(name: string, require: NodeRequire): PackageInfo {\n let directory = dirname(require.resolve(name));\n while (true) {\n const path = join(directory, 'package.json');\n if (existsSync(path)) {\n const metadata: unknown = JSON.parse(readFileSync(path, 'utf8'));\n if (typeof metadata === 'object' && metadata !== null && 'name' in metadata && (metadata.name === name || (name === 'vite' && metadata.name === '@voidzero-dev/vite-plus-core'))) {\n if (!('version' in metadata) || typeof metadata.version !== 'string') throw new Error(`Hono Pages: ${name} package version is missing (${path}).`);\n return { version: metadata.version, path };\n }\n }\n const parent = dirname(directory);\n if (parent === directory) throw new Error(`Hono Pages: cannot locate ${name} package metadata from ${require.resolve(name)}.`);\n directory = parent;\n }\n}\nfunction describe(name: string, require: NodeRequire): string {\n try { const info = packageInfo(name, require); return `${info.path} (metadata ${info.version})`; }\n catch { return `not resolved from ${require.resolve.paths(name)?.join(', ') ?? 'this context'}`; }\n}\n\nexport function assertSupportedFrameworks({ root, viteVersion }: { root: string; viteVersion: unknown }) {\n const adapter = createRequire(import.meta.url);\n const project = createRequire(join(root, 'package.json'));\n const diagnostic = () => `Running Vite from hook context: ${typeof viteVersion === 'string' ? viteVersion : 'unavailable'}. Adapter helper Vite: ${helperViteVersion}; package.json: ${describe('vite', adapter)}. Project Vite package.json: ${describe('vite', project)}. Package paths are diagnostics, not the running Vite identity.`;\n if (!supportsVite(viteVersion)) {\n throw new Error(`Hono Pages: running Vite ${typeof viteVersion === 'string' ? viteVersion : 'unavailable'} is unsupported; expected ${supportedViteRange}. ${diagnostic()} Update the CLI/launcher that executes Vite. For bundled launchers such as vp, installing project vite alone does not update the running Vite. For standard Vite, install vite@^8.3.4 and run vite directly.`);\n }\n if (!supportsVite(helperViteVersion)) {\n throw new Error(`Hono Pages: adapter helper Vite ${helperViteVersion} is unsupported; expected ${supportedViteRange}. ${diagnostic()} Inspect the adapter's resolved peer copy; install vite@^8.3.4 and refresh the adapter's peer resolution/lockfile if a stale copy remains.`);\n }\n for (const name of ['void', 'hono'] as const) {\n const expected = supportedFrameworkRanges[name];\n const info = packageInfo(name, adapter);\n if (!supportsFramework(name, info.version)) throw new Error(`Hono Pages: ${name} ${info.version} is unsupported; install ${name}@\"${expected}\". Resolved package.json: ${info.path}. Project package.json: ${describe(name, project)}. ${diagnostic()}`);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono-islands.d.ts","sourceRoot":"","sources":["../../src/plugins/hono-islands.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"hono-islands.d.ts","sourceRoot":"","sources":["../../src/plugins/hono-islands.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAQ7D,4DAA4D;AAC5D,wBAAgB,WAAW,IAAI,MAAM,CA+LpC"}
|
|
@@ -1,30 +1,49 @@
|
|
|
1
1
|
import { readFileSync, realpathSync } from 'node:fs';
|
|
2
2
|
import { join, relative } from 'node:path';
|
|
3
3
|
import { normalizePath, parseSync } from 'vite';
|
|
4
|
-
import { scanPages, resolvePagesDir } from 'void/pages';
|
|
5
|
-
import { findIslandImports, editIslandSource,
|
|
6
|
-
|
|
4
|
+
import { scanPages, resolveEffectiveLayoutChain, resolvePagesDir } from 'void/pages';
|
|
5
|
+
import { findIslandImports, editIslandSource, computePagesNeedingClientJS, ISLANDS_RENDERER_ID, ISLANDS_CLIENT_ENTRY_ID } from 'void/pages-islands-plugin';
|
|
6
|
+
import { resolveComponent } from './resolve-component.js';
|
|
7
|
+
import { markdownApi, markdownDiagnostic } from './markdown-api.js';
|
|
8
|
+
/** Hono mounting through Void's shared island scheduler. */
|
|
7
9
|
export function honoIslands() {
|
|
8
10
|
const root = process.cwd();
|
|
9
11
|
const pagesDir = resolvePagesDir(root);
|
|
10
12
|
const islands = new Map();
|
|
11
13
|
const pageFiles = new Set();
|
|
14
|
+
const graph = new Map();
|
|
15
|
+
const directlyInteractive = new Set();
|
|
16
|
+
const interactivePages = new Set();
|
|
17
|
+
const scriptOnlyPages = new Set();
|
|
12
18
|
let scan;
|
|
19
|
+
let markdown;
|
|
13
20
|
function islandImports(code, filename) {
|
|
14
21
|
const found = findIslandImports(code, filename);
|
|
15
22
|
const attributed = parseSync(filename, code).program.body.filter((node) => node.type === 'ImportDeclaration' && node.attributes?.some(({ key }) => ('name' in key && key.name === 'island') || ('value' in key && key.value === 'island')));
|
|
16
23
|
if (attributed.length !== found.length)
|
|
17
|
-
throw new Error(`Hono islands: use one default import with exactly one island
|
|
24
|
+
throw new Error(`Hono islands: use one default import with exactly one island attribute using load, visible, idle or media:query in ${filename}.`);
|
|
18
25
|
return found;
|
|
19
26
|
}
|
|
20
27
|
function imports(code, filename) {
|
|
21
28
|
const found = islandImports(code, filename);
|
|
22
29
|
for (const entry of found) {
|
|
23
|
-
if (
|
|
24
|
-
|
|
30
|
+
if (!['load', 'visible', 'idle'].includes(entry.hydrate)) {
|
|
31
|
+
const query = entry.hydrate.startsWith('media:') ? entry.hydrate.slice(6).trim() : '';
|
|
32
|
+
let balance = 0;
|
|
33
|
+
for (const character of query) {
|
|
34
|
+
if (character === '(')
|
|
35
|
+
balance++;
|
|
36
|
+
if (character === ')')
|
|
37
|
+
balance--;
|
|
38
|
+
if (balance < 0)
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
if (!query || balance !== 0 || /[{};]/.test(query))
|
|
42
|
+
throw new Error(`Hono islands: unsupported policy or invalid media query '${entry.hydrate}' in ${filename}.`);
|
|
43
|
+
}
|
|
25
44
|
if (!entry.specifier.startsWith('.'))
|
|
26
45
|
throw new Error(`Hono islands: use a relative TSX/JSX component import in ${filename}.`);
|
|
27
|
-
const path =
|
|
46
|
+
const path = resolveComponent(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);
|
|
28
47
|
if (!path || !/\.[jt]sx$/.test(path))
|
|
29
48
|
throw new Error(`Hono islands: cannot resolve TSX/JSX component ${entry.specifier} in ${filename}.`);
|
|
30
49
|
const canonical = realpathSync(path);
|
|
@@ -35,21 +54,107 @@ export function honoIslands() {
|
|
|
35
54
|
}
|
|
36
55
|
async function rescan() {
|
|
37
56
|
scan = await scanPages(root, { pagesDir });
|
|
57
|
+
// Never pass Markdown text to the JavaScript static-graph parser.
|
|
58
|
+
for (const file of [...scan.pages.map(page => page.componentPath), ...scan.layouts.map(layout => layout.filePath), ...scan.namedLayouts.map(layout => layout.filePath)]) {
|
|
59
|
+
if (/\.md$/.test(file) && !markdown)
|
|
60
|
+
throw new Error(`${markdownDiagnostic} ${file}`);
|
|
61
|
+
}
|
|
38
62
|
islands.clear();
|
|
39
63
|
pageFiles.clear();
|
|
64
|
+
graph.clear();
|
|
65
|
+
directlyInteractive.clear();
|
|
66
|
+
interactivePages.clear();
|
|
67
|
+
scriptOnlyPages.clear();
|
|
68
|
+
const visit = (filename) => {
|
|
69
|
+
const canonical = realpathSync(filename);
|
|
70
|
+
if (graph.has(canonical))
|
|
71
|
+
return;
|
|
72
|
+
const dependencies = new Set();
|
|
73
|
+
graph.set(canonical, dependencies);
|
|
74
|
+
pageFiles.add(canonical);
|
|
75
|
+
const code = canonical.endsWith('.md') && markdown ? markdown.getGraphSource(canonical) : readFileSync(canonical, 'utf8');
|
|
76
|
+
const found = imports(code, canonical);
|
|
77
|
+
if (found.length) {
|
|
78
|
+
if (!/\.[jt]sx$/.test(canonical) && !(canonical.endsWith('.md') && markdown))
|
|
79
|
+
throw new Error('Hono islands: attributed imports require a static TSX/JSX module.');
|
|
80
|
+
directlyInteractive.add(canonical);
|
|
81
|
+
}
|
|
82
|
+
for (const node of parseSync(canonical, code).program.body) {
|
|
83
|
+
const source = node.type === 'ImportDeclaration' ? node.source : node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration' ? node.source : undefined;
|
|
84
|
+
const typeOnly = node.type === 'ImportDeclaration' ? node.importKind === 'type' || (node.specifiers.length > 0 && node.specifiers.every((entry) => entry.type === 'ImportSpecifier' && entry.importKind === 'type')) : (node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') && node.exportKind === 'type';
|
|
85
|
+
if (!source || typeOnly || !source.value.startsWith('.') || found.some((entry) => entry.specifier === source.value))
|
|
86
|
+
continue;
|
|
87
|
+
const target = resolveComponent(source.value, join(canonical, '..'), ['.tsx', '.jsx', '.ts', '.js']);
|
|
88
|
+
if (!target || !/\.[jt]sx?$/.test(target))
|
|
89
|
+
continue;
|
|
90
|
+
dependencies.add(realpathSync(target));
|
|
91
|
+
visit(target);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
for (const entry of [...scan.pages.filter((page) => page.island).map((page) => page.componentPath), ...scan.layouts.filter((layout) => layout.island).map((layout) => layout.filePath), ...scan.namedLayouts.filter((layout) => layout.island).map((layout) => layout.filePath)])
|
|
95
|
+
visit(join(pagesDir, entry));
|
|
96
|
+
const validateInteractive = (filename, seen = new Set()) => {
|
|
97
|
+
const canonical = realpathSync(filename);
|
|
98
|
+
if (seen.has(canonical))
|
|
99
|
+
return;
|
|
100
|
+
seen.add(canonical);
|
|
101
|
+
const code = canonical.endsWith('.md') && markdown ? markdown.getGraphSource(canonical) : readFileSync(canonical, 'utf8');
|
|
102
|
+
if (islandImports(code, canonical).length)
|
|
103
|
+
throw new Error('Hono islands: attributed imports inside an interactive component are unsupported; use ordinary component imports there.');
|
|
104
|
+
for (const node of parseSync(canonical, code).program.body) {
|
|
105
|
+
const source = node.type === 'ImportDeclaration' ? node.source : node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration' ? node.source : undefined;
|
|
106
|
+
const typeOnly = node.type === 'ImportDeclaration' ? node.importKind === 'type' || (node.specifiers.length > 0 && node.specifiers.every((entry) => entry.type === 'ImportSpecifier' && entry.importKind === 'type')) : (node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') && node.exportKind === 'type';
|
|
107
|
+
if (!source || typeOnly || !source.value.startsWith('.'))
|
|
108
|
+
continue;
|
|
109
|
+
const target = resolveComponent(source.value, join(canonical, '..'), ['.tsx', '.jsx', '.ts', '.js']);
|
|
110
|
+
if (target && /\.[jt]sx?$/.test(target))
|
|
111
|
+
validateInteractive(target, seen);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
for (const target of islands.values())
|
|
115
|
+
validateInteractive(target);
|
|
116
|
+
for (const page of scan.pages.filter((page) => !page.island)) {
|
|
117
|
+
for (const file of [page.componentPath, ...resolveEffectiveLayoutChain(page, scan.layouts, scan.namedLayouts).map((layout) => layout.filePath)])
|
|
118
|
+
validateInteractive(join(pagesDir, file));
|
|
119
|
+
}
|
|
120
|
+
const needsJS = new Set(directlyInteractive);
|
|
121
|
+
let changed = true;
|
|
122
|
+
while (changed) {
|
|
123
|
+
changed = false;
|
|
124
|
+
for (const [file, dependencies] of graph)
|
|
125
|
+
if (!needsJS.has(file) && [...dependencies].some((target) => needsJS.has(target))) {
|
|
126
|
+
needsJS.add(file);
|
|
127
|
+
changed = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
40
130
|
for (const page of scan.pages.filter((page) => page.island)) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
131
|
+
const files = [page.componentPath, ...resolveEffectiveLayoutChain(page, scan.layouts, scan.namedLayouts).map((layout) => layout.filePath)];
|
|
132
|
+
const hasIslands = files.some(file => needsJS.has(realpathSync(join(pagesDir, file))));
|
|
133
|
+
const hasScript = markdown?.getClientScripts().has(page.componentId);
|
|
134
|
+
if (hasIslands || hasScript)
|
|
135
|
+
interactivePages.add(page.componentId);
|
|
136
|
+
if (hasScript && !hasIslands)
|
|
137
|
+
scriptOnlyPages.add(page.componentId);
|
|
44
138
|
}
|
|
45
139
|
}
|
|
46
140
|
return {
|
|
47
141
|
name: 'void-hono:islands',
|
|
48
142
|
enforce: 'pre',
|
|
143
|
+
configResolved(config) { markdown = markdownApi(config.plugins); },
|
|
49
144
|
buildStart: rescan,
|
|
50
|
-
async hotUpdate({ file }) {
|
|
51
|
-
|
|
52
|
-
|
|
145
|
+
async hotUpdate({ file, modules, timestamp }) {
|
|
146
|
+
const inPages = normalizePath(file).startsWith(normalizePath(pagesDir) + '/');
|
|
147
|
+
if (!inPages && ![...pageFiles, ...islands.values()].some((path) => normalizePath(path) === normalizePath(file)))
|
|
148
|
+
return;
|
|
149
|
+
await rescan();
|
|
150
|
+
const invalidated = new Set();
|
|
151
|
+
for (const id of [ISLANDS_RENDERER_ID, ISLANDS_CLIENT_ENTRY_ID, 'virtual:void-pages-renderer']) {
|
|
152
|
+
const module = this.environment.moduleGraph.getModuleById(`\0${id}`);
|
|
153
|
+
if (module)
|
|
154
|
+
this.environment.moduleGraph.invalidateModule(module, invalidated, timestamp, true);
|
|
155
|
+
}
|
|
156
|
+
if (!inPages && this.environment.config.consumer === 'client')
|
|
157
|
+
this.environment.hot.send({ type: 'full-reload' });
|
|
53
158
|
},
|
|
54
159
|
config() {
|
|
55
160
|
return { build: { rollupOptions: { input: { 'islands-client': ISLANDS_CLIENT_ENTRY_ID } } } };
|
|
@@ -63,47 +168,74 @@ export function honoIslands() {
|
|
|
63
168
|
if (!/\.[jt]sx$/.test(filename) || filename.includes('/node_modules/'))
|
|
64
169
|
return;
|
|
65
170
|
const canonical = realpathSync(filename);
|
|
66
|
-
if ((pageFiles.has(canonical) || [...islands.values()].includes(canonical)) && parseSync(filename, code).program.body.some((node) => node.type === 'ImportDeclaration' && node.
|
|
67
|
-
throw new Error('Hono islands:
|
|
171
|
+
if ((pageFiles.has(canonical) || [...islands.values()].includes(canonical)) && parseSync(filename, code).program.body.some((node) => node.type === 'ImportDeclaration' && node.importKind !== 'type' && ['void-plugin-hono-jsx/form', 'void-plugin-hono-jsx/pages'].includes(node.source.value) && node.specifiers.some((entry) => entry.type !== 'ImportSpecifier' ? node.source.value.endsWith('/form') : entry.importKind !== 'type' && ['useForm', 'action', 'setActionRouter'].includes('name' in entry.imported ? entry.imported.name : entry.imported.value)))) {
|
|
172
|
+
throw new Error('Hono islands: useForm/action require full Pages; use named useIslandForm/Form imports for islands.');
|
|
68
173
|
}
|
|
69
174
|
const found = islandImports(code, filename);
|
|
70
175
|
if (!found.length)
|
|
71
176
|
return;
|
|
72
|
-
if (!pageFiles.has(
|
|
73
|
-
throw new Error('Hono islands: attributed imports
|
|
177
|
+
if (!pageFiles.has(canonical))
|
|
178
|
+
throw new Error('Hono islands: attributed imports require a static island page, layout or component graph; use ordinary imports inside interactive components.');
|
|
74
179
|
imports(code, filename);
|
|
180
|
+
// Void requests static modules in the client environment to collect CSS.
|
|
181
|
+
// Actual interactive entry graphs were validated above; strip attributes
|
|
182
|
+
// for that traversal rather than generating server-only marker wrappers.
|
|
183
|
+
if (this.environment?.config.consumer === 'client')
|
|
184
|
+
return editIslandSource(code, found.map((entry) => ({ start: entry.start, end: entry.end, text: `import ${entry.importName} from ${entry.specifierRaw};` })));
|
|
75
185
|
return editIslandSource(code, found.map((entry) => {
|
|
76
|
-
const path =
|
|
186
|
+
const path = resolveComponent(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);
|
|
77
187
|
if (!path)
|
|
78
188
|
throw new Error(`Hono islands: missing component ${entry.specifier}.`);
|
|
79
189
|
const islandId = normalizePath(relative(root, realpathSync(path)));
|
|
80
190
|
const component = `__honoIslandComponent${entry.start}`;
|
|
81
191
|
return { start: entry.start, end: entry.end, text: `import ${component} from ${entry.specifierRaw};
|
|
82
|
-
const ${entry.importName} = (props) => __honoIslandJsx('div', { 'data-island': ${JSON.stringify(islandId)}, 'data-hydrate':
|
|
192
|
+
const ${entry.importName} = (props) => __honoIslandJsx('div', { 'data-island': ${JSON.stringify(islandId)}, 'data-hydrate': ${JSON.stringify(entry.hydrate)}, 'data-props': JSON.stringify(props), children: __honoIslandJsx(${component}, props) });` };
|
|
83
193
|
}), { prepend: "import { jsx as __honoIslandJsx } from 'hono/jsx/jsx-runtime';\n" });
|
|
84
194
|
},
|
|
85
195
|
load(id) {
|
|
86
196
|
if (id === `\0${ISLANDS_RENDERER_ID}`) {
|
|
87
197
|
if (!scan)
|
|
88
198
|
throw new Error('Hono islands: page discovery has not completed.');
|
|
89
|
-
const interactive = [...computePagesNeedingClientJS(scan, pagesDir, null)];
|
|
199
|
+
const interactive = [...new Set([...computePagesNeedingClientJS(scan, pagesDir, null), ...interactivePages])];
|
|
90
200
|
return `import { renderPage } from 'virtual:void-pages-renderer';
|
|
91
201
|
const interactive = new Set(${JSON.stringify(interactive)});
|
|
202
|
+
const scriptOnly = new Set(${JSON.stringify([...scriptOnlyPages])});
|
|
203
|
+
const markdownScripts = new Set(${JSON.stringify([...(markdown?.getClientScripts().keys() ?? [])])});
|
|
92
204
|
export function renderIslandPage(page, assets) {
|
|
93
205
|
if (page.deferred?.length || page.deferredKeys) throw new Error('Hono islands: deferred props are unsupported.');
|
|
94
|
-
|
|
206
|
+
if (!markdownScripts.has(page.component)) assets = { ...assets,
|
|
207
|
+
body: assets.body.replace(/<script\\b[^>]*src=["'][^"']*(?:void-hono-markdown-client|markdown-client-)[^"']*["'][^>]*>\\s*<\\/script>/g, ''),
|
|
208
|
+
preloads: assets.preloads.replace(/<link\\b[^>]*href=["'][^"']*markdown-client-[^"']*["'][^>]*>/g, ''),
|
|
209
|
+
};
|
|
210
|
+
if (!interactive.has(page.component)) return renderPage(page, { ...assets, preloads: '', body: '' });
|
|
211
|
+
if (scriptOnly.has(page.component)) {
|
|
212
|
+
// Keep the Markdown entry; its dynamic import loads only this page's code.
|
|
213
|
+
// Framework preloads and the island scheduler have no work on this chain.
|
|
214
|
+
const body = assets.body.replace(/<script\\b[^>]*src=["'][^"']*(?:void-islands-client|islands-client-)[^"']*["'][^>]*>\\s*<\\/script>/g, '');
|
|
215
|
+
return renderPage(page, { ...assets, preloads: '', body });
|
|
216
|
+
}
|
|
217
|
+
return renderPage(page, assets);
|
|
95
218
|
}`;
|
|
96
219
|
}
|
|
97
220
|
if (id === `\0${ISLANDS_CLIENT_ENTRY_ID}`) {
|
|
98
|
-
if (!islands.size)
|
|
221
|
+
if (!islands.size || !interactivePages.size)
|
|
99
222
|
return 'export {};';
|
|
100
223
|
const loaders = [...islands].map(([name, path]) => `${JSON.stringify(name)}: () => import(${JSON.stringify(path)})`).join(',\n');
|
|
101
|
-
return
|
|
224
|
+
return `${markdown ? "import { MarkdownContext } from 'void-plugin-hono-jsx/markdown';" : ''}
|
|
225
|
+
import { initIslands } from 'void/pages-client';
|
|
102
226
|
import { jsx } from 'hono/jsx/dom/jsx-runtime';
|
|
103
227
|
import { render } from 'hono/jsx/dom';
|
|
228
|
+
for (const element of document.querySelectorAll('[data-hydrate^="media:"]')) {
|
|
229
|
+
const query = element.getAttribute('data-hydrate').slice(6).trim();
|
|
230
|
+
if (matchMedia(query).media === 'not all' && query !== 'not all') throw new Error('Hono islands: invalid or unsupported media query ' + query);
|
|
231
|
+
}
|
|
104
232
|
initIslands({ ${loaders} }, (element, module, props) => {
|
|
105
233
|
if (typeof module.default !== 'function') throw new Error('Hono islands: a component must export a default function.');
|
|
106
|
-
|
|
234
|
+
let content = jsx(module.default, props);
|
|
235
|
+
${markdown ? `const metadata = JSON.parse(document.getElementById('app')?.getAttribute('data-hono-markdown') || '{}');
|
|
236
|
+
const page = JSON.parse(document.getElementById('__VOID_PAGE_DATA__')?.textContent || '{}');
|
|
237
|
+
content = jsx(MarkdownContext.Provider, { value: { frontmatter: metadata.frontmatter ?? {}, headings: metadata.headings ?? [], props: page.props ?? {} }, children: content });` : ''}
|
|
238
|
+
render(content, element);
|
|
107
239
|
element.setAttribute('data-hono-island', 'mounted');
|
|
108
240
|
});`;
|
|
109
241
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono-islands.js","sourceRoot":"","sources":["../../src/plugins/hono-islands.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, realpathSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport { normalizePath, parseSync, type Plugin } from 'vite';\nimport { scanPages, resolvePagesDir, type PageScanResult } from 'void/pages';\nimport { findIslandImports, editIslandSource, resolveSpecifier, computePagesNeedingClientJS, ISLANDS_RENDERER_ID, ISLANDS_CLIENT_ENTRY_ID } from 'void/pages-islands-plugin';\n\n/** Narrow adapter for Void's load-on-page-load island convention. */\nexport function honoIslands(): Plugin {\n const root = process.cwd();\n const pagesDir = resolvePagesDir(root);\n const islands = new Map<string, string>();\n const pageFiles = new Set<string>();\n let scan: PageScanResult | undefined;\n\n function islandImports(code: string, filename: string) {\n const found = findIslandImports(code, filename);\n const attributed = parseSync(filename, code).program.body.filter((node) => node.type === 'ImportDeclaration' && node.attributes?.some(({ key }) => ('name' in key && key.name === 'island') || ('value' in key && key.value === 'island')));\n if (attributed.length !== found.length) throw new Error(`Hono islands: use one default import with exactly one island: 'load' attribute in ${filename}.`);\n return found;\n }\n\n function imports(code: string, filename: string) {\n const found = islandImports(code, filename);\n for (const entry of found) {\n if (entry.hydrate !== 'load') throw new Error(`Hono islands: unsupported policy '${entry.hydrate}' in ${filename}; use island: 'load'.`);\n if (!entry.specifier.startsWith('.')) throw new Error(`Hono islands: use a relative TSX/JSX component import in ${filename}.`);\n const path = resolveSpecifier(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);\n if (!path || !/\\.[jt]sx$/.test(path)) throw new Error(`Hono islands: cannot resolve TSX/JSX component ${entry.specifier} in ${filename}.`);\n const canonical = realpathSync(path);\n const id = normalizePath(relative(root, canonical));\n islands.set(id, canonical);\n }\n return found;\n }\n\n async function rescan() {\n scan = await scanPages(root, { pagesDir });\n islands.clear();\n pageFiles.clear();\n for (const page of scan.pages.filter((page) => page.island)) {\n const filename = realpathSync(join(pagesDir, page.componentPath));\n pageFiles.add(filename);\n imports(readFileSync(filename, 'utf8'), filename);\n }\n }\n\n return {\n name: 'void-hono:islands',\n enforce: 'pre',\n buildStart: rescan,\n async hotUpdate({ file }) {\n if (normalizePath(file).startsWith(normalizePath(pagesDir) + '/')) await rescan();\n },\n config() {\n return { build: { rollupOptions: { input: { 'islands-client': ISLANDS_CLIENT_ENTRY_ID } } } };\n },\n resolveId(id) {\n if (id === ISLANDS_RENDERER_ID || id === ISLANDS_CLIENT_ENTRY_ID) return `\\0${id}`;\n },\n transform(code, id) {\n const filename = id.split('?')[0];\n if (!/\\.[jt]sx$/.test(filename) || filename.includes('/node_modules/')) return;\n const canonical = realpathSync(filename);\n if ((pageFiles.has(canonical) || [...islands.values()].includes(canonical)) && parseSync(filename, code).program.body.some((node) => node.type === 'ImportDeclaration' && node.source.value === 'void-plugin-hono-jsx/form')) {\n throw new Error('Hono islands: form helpers are unsupported; use a full Pages component.');\n }\n const found = islandImports(code, filename);\n if (!found.length) return;\n if (!pageFiles.has(realpathSync(filename))) throw new Error('Hono islands: attributed imports are supported only directly in .island.tsx/.island.jsx pages.');\n imports(code, filename);\n return editIslandSource(code, found.map((entry) => {\n const path = resolveSpecifier(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);\n if (!path) throw new Error(`Hono islands: missing component ${entry.specifier}.`);\n const islandId = normalizePath(relative(root, realpathSync(path)));\n const component = `__honoIslandComponent${entry.start}`;\n return { start: entry.start, end: entry.end, text: `import ${component} from ${entry.specifierRaw};\nconst ${entry.importName} = (props) => __honoIslandJsx('div', { 'data-island': ${JSON.stringify(islandId)}, 'data-hydrate': 'load', 'data-props': JSON.stringify(props), children: __honoIslandJsx(${component}, props) });` };\n }), { prepend: \"import { jsx as __honoIslandJsx } from 'hono/jsx/jsx-runtime';\\n\" });\n },\n load(id) {\n if (id === `\\0${ISLANDS_RENDERER_ID}`) {\n if (!scan) throw new Error('Hono islands: page discovery has not completed.');\n const interactive = [...computePagesNeedingClientJS(scan, pagesDir, null)];\n return `import { renderPage } from 'virtual:void-pages-renderer';\nconst interactive = new Set(${JSON.stringify(interactive)});\nexport function renderIslandPage(page, assets) {\n if (page.deferred?.length || page.deferredKeys) throw new Error('Hono islands: deferred props are unsupported.');\n return renderPage(page, interactive.has(page.component) ? assets : { ...assets, preloads: '', body: '' });\n}`;\n }\n if (id === `\\0${ISLANDS_CLIENT_ENTRY_ID}`) {\n if (!islands.size) return 'export {};';\n const loaders = [...islands].map(([name, path]) => `${JSON.stringify(name)}: () => import(${JSON.stringify(path)})`).join(',\\n');\n return `import { initIslands } from 'void/pages-client';\nimport { jsx } from 'hono/jsx/dom/jsx-runtime';\nimport { render } from 'hono/jsx/dom';\ninitIslands({ ${loaders} }, (element, module, props) => {\n if (typeof module.default !== 'function') throw new Error('Hono islands: a component must export a default function.');\n render(jsx(module.default, props), element);\n element.setAttribute('data-hono-island', 'mounted');\n});`;\n }\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hono-islands.js","sourceRoot":"","sources":["../../src/plugins/hono-islands.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, realpathSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport { normalizePath, parseSync, type Plugin } from 'vite';\nimport { scanPages, resolveEffectiveLayoutChain, resolvePagesDir, type PageScanResult } from 'void/pages';\nimport { findIslandImports, editIslandSource, computePagesNeedingClientJS, ISLANDS_RENDERER_ID, ISLANDS_CLIENT_ENTRY_ID } from 'void/pages-islands-plugin';\n\nimport { resolveComponent } from './resolve-component.ts';\n\nimport { markdownApi, markdownDiagnostic, type HonoMarkdownApi } from './markdown-api.ts';\n\n/** Hono mounting through Void's shared island scheduler. */\nexport function honoIslands(): Plugin {\n const root = process.cwd();\n const pagesDir = resolvePagesDir(root);\n const islands = new Map<string, string>();\n const pageFiles = new Set<string>();\n const graph = new Map<string, Set<string>>();\n const directlyInteractive = new Set<string>();\n const interactivePages = new Set<string>();\n const scriptOnlyPages = new Set<string>();\n let scan: PageScanResult | undefined;\n let markdown: HonoMarkdownApi | undefined;\n\n function islandImports(code: string, filename: string) {\n const found = findIslandImports(code, filename);\n const attributed = parseSync(filename, code).program.body.filter((node) => node.type === 'ImportDeclaration' && node.attributes?.some(({ key }) => ('name' in key && key.name === 'island') || ('value' in key && key.value === 'island')));\n if (attributed.length !== found.length) throw new Error(`Hono islands: use one default import with exactly one island attribute using load, visible, idle or media:query in ${filename}.`);\n return found;\n }\n\n function imports(code: string, filename: string) {\n const found = islandImports(code, filename);\n for (const entry of found) {\n if (!['load', 'visible', 'idle'].includes(entry.hydrate)) {\n const query = entry.hydrate.startsWith('media:') ? entry.hydrate.slice(6).trim() : '';\n let balance = 0;\n for (const character of query) { if (character === '(') balance++; if (character === ')') balance--; if (balance < 0) break; }\n if (!query || balance !== 0 || /[{};]/.test(query)) throw new Error(`Hono islands: unsupported policy or invalid media query '${entry.hydrate}' in ${filename}.`);\n }\n if (!entry.specifier.startsWith('.')) throw new Error(`Hono islands: use a relative TSX/JSX component import in ${filename}.`);\n const path = resolveComponent(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);\n if (!path || !/\\.[jt]sx$/.test(path)) throw new Error(`Hono islands: cannot resolve TSX/JSX component ${entry.specifier} in ${filename}.`);\n const canonical = realpathSync(path);\n const id = normalizePath(relative(root, canonical));\n islands.set(id, canonical);\n }\n return found;\n }\n\n async function rescan() {\n scan = await scanPages(root, { pagesDir });\n // Never pass Markdown text to the JavaScript static-graph parser.\n for (const file of [...scan.pages.map(page => page.componentPath), ...scan.layouts.map(layout => layout.filePath), ...scan.namedLayouts.map(layout => layout.filePath)]) {\n if (/\\.md$/.test(file) && !markdown) throw new Error(`${markdownDiagnostic} ${file}`);\n }\n islands.clear(); pageFiles.clear(); graph.clear(); directlyInteractive.clear(); interactivePages.clear(); scriptOnlyPages.clear();\n const visit = (filename: string) => {\n const canonical = realpathSync(filename);\n if (graph.has(canonical)) return;\n const dependencies = new Set<string>(); graph.set(canonical, dependencies); pageFiles.add(canonical);\n const code = canonical.endsWith('.md') && markdown ? markdown.getGraphSource(canonical) : readFileSync(canonical, 'utf8');\n const found = imports(code, canonical);\n if (found.length) {\n if (!/\\.[jt]sx$/.test(canonical) && !(canonical.endsWith('.md') && markdown)) throw new Error('Hono islands: attributed imports require a static TSX/JSX module.');\n directlyInteractive.add(canonical);\n }\n for (const node of parseSync(canonical, code).program.body) {\n const source = node.type === 'ImportDeclaration' ? node.source : node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration' ? node.source : undefined;\n const typeOnly = node.type === 'ImportDeclaration' ? node.importKind === 'type' || (node.specifiers.length > 0 && node.specifiers.every((entry) => entry.type === 'ImportSpecifier' && entry.importKind === 'type')) : (node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') && node.exportKind === 'type';\n if (!source || typeOnly || !source.value.startsWith('.') || found.some((entry) => entry.specifier === source.value)) continue;\n const target = resolveComponent(source.value, join(canonical, '..'), ['.tsx', '.jsx', '.ts', '.js']);\n if (!target || !/\\.[jt]sx?$/.test(target)) continue;\n dependencies.add(realpathSync(target)); visit(target);\n }\n\n };\n for (const entry of [...scan.pages.filter((page) => page.island).map((page) => page.componentPath), ...scan.layouts.filter((layout) => layout.island).map((layout) => layout.filePath), ...scan.namedLayouts.filter((layout) => layout.island).map((layout) => layout.filePath)]) visit(join(pagesDir, entry));\n const validateInteractive = (filename: string, seen = new Set<string>()) => {\n const canonical = realpathSync(filename);\n if (seen.has(canonical)) return; seen.add(canonical);\n const code = canonical.endsWith('.md') && markdown ? markdown.getGraphSource(canonical) : readFileSync(canonical, 'utf8');\n if (islandImports(code, canonical).length) throw new Error('Hono islands: attributed imports inside an interactive component are unsupported; use ordinary component imports there.');\n for (const node of parseSync(canonical, code).program.body) {\n const source = node.type === 'ImportDeclaration' ? node.source : node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration' ? node.source : undefined;\n const typeOnly = node.type === 'ImportDeclaration' ? node.importKind === 'type' || (node.specifiers.length > 0 && node.specifiers.every((entry) => entry.type === 'ImportSpecifier' && entry.importKind === 'type')) : (node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') && node.exportKind === 'type';\n if (!source || typeOnly || !source.value.startsWith('.')) continue;\n const target = resolveComponent(source.value, join(canonical, '..'), ['.tsx', '.jsx', '.ts', '.js']);\n if (target && /\\.[jt]sx?$/.test(target)) validateInteractive(target, seen);\n }\n };\n for (const target of islands.values()) validateInteractive(target);\n for (const page of scan.pages.filter((page) => !page.island)) {\n for (const file of [page.componentPath, ...resolveEffectiveLayoutChain(page, scan.layouts, scan.namedLayouts).map((layout) => layout.filePath)]) validateInteractive(join(pagesDir, file));\n }\n const needsJS = new Set(directlyInteractive);\n let changed = true;\n while (changed) {\n changed = false;\n for (const [file, dependencies] of graph) if (!needsJS.has(file) && [...dependencies].some((target) => needsJS.has(target))) { needsJS.add(file); changed = true; }\n }\n for (const page of scan.pages.filter((page) => page.island)) {\n const files = [page.componentPath, ...resolveEffectiveLayoutChain(page, scan.layouts, scan.namedLayouts).map((layout) => layout.filePath)];\n const hasIslands = files.some(file => needsJS.has(realpathSync(join(pagesDir, file))));\n const hasScript = markdown?.getClientScripts().has(page.componentId);\n if (hasIslands || hasScript) interactivePages.add(page.componentId);\n if (hasScript && !hasIslands) scriptOnlyPages.add(page.componentId);\n }\n }\n\n return {\n name: 'void-hono:islands',\n enforce: 'pre',\n configResolved(config) { markdown = markdownApi(config.plugins); },\n buildStart: rescan,\n async hotUpdate({ file, modules, timestamp }) {\n const inPages = normalizePath(file).startsWith(normalizePath(pagesDir) + '/');\n if (!inPages && ![...pageFiles, ...islands.values()].some((path) => normalizePath(path) === normalizePath(file))) return;\n await rescan();\n const invalidated = new Set<(typeof modules)[number]>();\n for (const id of [ISLANDS_RENDERER_ID, ISLANDS_CLIENT_ENTRY_ID, 'virtual:void-pages-renderer']) {\n const module = this.environment.moduleGraph.getModuleById(`\\0${id}`);\n if (module) this.environment.moduleGraph.invalidateModule(module, invalidated, timestamp, true);\n }\n if (!inPages && this.environment.config.consumer === 'client') this.environment.hot.send({ type: 'full-reload' });\n },\n config() {\n return { build: { rollupOptions: { input: { 'islands-client': ISLANDS_CLIENT_ENTRY_ID } } } };\n },\n resolveId(id) {\n if (id === ISLANDS_RENDERER_ID || id === ISLANDS_CLIENT_ENTRY_ID) return `\\0${id}`;\n },\n transform(code, id) {\n const filename = id.split('?')[0];\n if (!/\\.[jt]sx$/.test(filename) || filename.includes('/node_modules/')) return;\n const canonical = realpathSync(filename);\n if ((pageFiles.has(canonical) || [...islands.values()].includes(canonical)) && parseSync(filename, code).program.body.some((node) => node.type === 'ImportDeclaration' && node.importKind !== 'type' && ['void-plugin-hono-jsx/form', 'void-plugin-hono-jsx/pages'].includes(node.source.value) && node.specifiers.some((entry) => entry.type !== 'ImportSpecifier' ? node.source.value.endsWith('/form') : entry.importKind !== 'type' && ['useForm', 'action', 'setActionRouter'].includes('name' in entry.imported ? entry.imported.name : entry.imported.value)))) {\n throw new Error('Hono islands: useForm/action require full Pages; use named useIslandForm/Form imports for islands.');\n }\n const found = islandImports(code, filename);\n if (!found.length) return;\n if (!pageFiles.has(canonical)) throw new Error('Hono islands: attributed imports require a static island page, layout or component graph; use ordinary imports inside interactive components.');\n imports(code, filename);\n // Void requests static modules in the client environment to collect CSS.\n // Actual interactive entry graphs were validated above; strip attributes\n // for that traversal rather than generating server-only marker wrappers.\n if (this.environment?.config.consumer === 'client') return editIslandSource(code, found.map((entry) => ({ start: entry.start, end: entry.end, text: `import ${entry.importName} from ${entry.specifierRaw};` })));\n return editIslandSource(code, found.map((entry) => {\n const path = resolveComponent(entry.specifier, join(filename, '..'), ['.tsx', '.jsx']);\n if (!path) throw new Error(`Hono islands: missing component ${entry.specifier}.`);\n const islandId = normalizePath(relative(root, realpathSync(path)));\n const component = `__honoIslandComponent${entry.start}`;\n return { start: entry.start, end: entry.end, text: `import ${component} from ${entry.specifierRaw};\nconst ${entry.importName} = (props) => __honoIslandJsx('div', { 'data-island': ${JSON.stringify(islandId)}, 'data-hydrate': ${JSON.stringify(entry.hydrate)}, 'data-props': JSON.stringify(props), children: __honoIslandJsx(${component}, props) });` };\n }), { prepend: \"import { jsx as __honoIslandJsx } from 'hono/jsx/jsx-runtime';\\n\" });\n },\n load(id) {\n if (id === `\\0${ISLANDS_RENDERER_ID}`) {\n if (!scan) throw new Error('Hono islands: page discovery has not completed.');\n const interactive = [...new Set([...computePagesNeedingClientJS(scan, pagesDir, null), ...interactivePages])];\n return `import { renderPage } from 'virtual:void-pages-renderer';\nconst interactive = new Set(${JSON.stringify(interactive)});\nconst scriptOnly = new Set(${JSON.stringify([...scriptOnlyPages])});\nconst markdownScripts = new Set(${JSON.stringify([...(markdown?.getClientScripts().keys() ?? [])])});\nexport function renderIslandPage(page, assets) {\n if (page.deferred?.length || page.deferredKeys) throw new Error('Hono islands: deferred props are unsupported.');\n if (!markdownScripts.has(page.component)) assets = { ...assets,\n body: assets.body.replace(/<script\\\\b[^>]*src=[\"'][^\"']*(?:void-hono-markdown-client|markdown-client-)[^\"']*[\"'][^>]*>\\\\s*<\\\\/script>/g, ''),\n preloads: assets.preloads.replace(/<link\\\\b[^>]*href=[\"'][^\"']*markdown-client-[^\"']*[\"'][^>]*>/g, ''),\n };\n if (!interactive.has(page.component)) return renderPage(page, { ...assets, preloads: '', body: '' });\n if (scriptOnly.has(page.component)) {\n // Keep the Markdown entry; its dynamic import loads only this page's code.\n // Framework preloads and the island scheduler have no work on this chain.\n const body = assets.body.replace(/<script\\\\b[^>]*src=[\"'][^\"']*(?:void-islands-client|islands-client-)[^\"']*[\"'][^>]*>\\\\s*<\\\\/script>/g, '');\n return renderPage(page, { ...assets, preloads: '', body });\n }\n return renderPage(page, assets);\n}`;\n }\n if (id === `\\0${ISLANDS_CLIENT_ENTRY_ID}`) {\n if (!islands.size || !interactivePages.size) return 'export {};';\n const loaders = [...islands].map(([name, path]) => `${JSON.stringify(name)}: () => import(${JSON.stringify(path)})`).join(',\\n');\n return `${markdown ? \"import { MarkdownContext } from 'void-plugin-hono-jsx/markdown';\" : ''}\nimport { initIslands } from 'void/pages-client';\nimport { jsx } from 'hono/jsx/dom/jsx-runtime';\nimport { render } from 'hono/jsx/dom';\nfor (const element of document.querySelectorAll('[data-hydrate^=\"media:\"]')) {\n const query = element.getAttribute('data-hydrate').slice(6).trim();\n if (matchMedia(query).media === 'not all' && query !== 'not all') throw new Error('Hono islands: invalid or unsupported media query ' + query);\n}\ninitIslands({ ${loaders} }, (element, module, props) => {\n if (typeof module.default !== 'function') throw new Error('Hono islands: a component must export a default function.');\n let content = jsx(module.default, props);\n ${markdown ? `const metadata = JSON.parse(document.getElementById('app')?.getAttribute('data-hono-markdown') || '{}');\n const page = JSON.parse(document.getElementById('__VOID_PAGE_DATA__')?.textContent || '{}');\n content = jsx(MarkdownContext.Provider, { value: { frontmatter: metadata.frontmatter ?? {}, headings: metadata.headings ?? [], props: page.props ?? {} }, children: content });` : ''}\n render(content, element);\n element.setAttribute('data-hono-island', 'mounted');\n});`;\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-markdown.d.ts","sourceRoot":"","sources":["../../src/plugins/hono-markdown.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAUlD,kFAAkF;AAClF,wBAAgB,gBAAgB,IAAI,MAAM,CAgEzC"}
|