@pajecawav/yamf 0.0.6 → 0.0.8
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/README.md +32 -1
- package/dist/components/Head.d.ts +2 -3
- package/dist/components/Head.d.ts.map +1 -1
- package/dist/context/ssr.d.ts +1 -2
- package/dist/context/ssr.d.ts.map +1 -1
- package/dist/hooks/useEvent.d.ts +1 -2
- package/dist/hooks/useEvent.d.ts.map +1 -1
- package/dist/hooks/useHead.d.ts +2 -3
- package/dist/hooks/useHead.d.ts.map +1 -1
- package/dist/hooks/useHead.js.map +1 -1
- package/dist/island/types.d.ts +2 -3
- package/dist/island/types.d.ts.map +1 -1
- package/dist/page.d.ts +3 -4
- package/dist/page.d.ts.map +1 -1
- package/dist/server/entry.d.mts +3 -4
- package/dist/server/entry.d.mts.map +1 -1
- package/dist/server/entry.mjs +11 -1
- package/dist/server/entry.mjs.map +1 -1
- package/dist/server/island/server.d.mts +2 -3
- package/dist/server/island/server.d.mts.map +1 -1
- package/dist/server/island/server.mjs +2 -2
- package/dist/server/island/server.mjs.map +1 -1
- package/dist/server/island/types.d.mts +1 -2
- package/dist/server/island/types.d.mts.map +1 -1
- package/dist/server/shared/assets.d.mts +1 -2
- package/dist/server/shared/assets.d.mts.map +1 -1
- package/dist/server/shared/head.d.mts +1 -2
- package/dist/server/shared/head.d.mts.map +1 -1
- package/dist/shared/assets.d.ts +2 -3
- package/dist/shared/assets.d.ts.map +1 -1
- package/dist/shared/head.d.ts +1 -2
- package/dist/shared/head.d.ts.map +1 -1
- package/dist/vite/index.d.mts +2 -2
- package/dist/vite/index.d.mts.map +1 -1
- package/dist/vite/index.mjs +3 -1
- package/dist/vite/index.mjs.map +1 -1
- package/dist/vite/islands.mjs +38 -59
- package/dist/vite/islands.mjs.map +1 -1
- package/dist/vite/virtual-assets.mjs +1 -1
- package/dist/vite/virtual-assets.mjs.map +1 -1
- package/dist/vite/virtual-error-handler.mjs +23 -0
- package/dist/vite/virtual-error-handler.mjs.map +1 -0
- package/dist/vite/virtual-pages.mjs +1 -1
- package/dist/vite/virtual-pages.mjs.map +1 -1
- package/dist/vite/virtual-root.mjs +1 -1
- package/dist/vite/virtual-root.mjs.map +1 -1
- package/dist/vite/virtual-template.mjs +1 -1
- package/dist/vite/virtual-template.mjs.map +1 -1
- package/package.json +22 -31
- package/src/island/server.tsx +7 -5
- package/src/server/entry.tsx +25 -3
- package/src/virtual.d.ts +8 -0
- package/src/vite/index.ts +2 -0
- package/src/vite/islands.ts +76 -175
- package/src/vite/virtual-error-handler.ts +40 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# yamf
|
|
2
2
|
|
|
3
|
-
SSR meta-framework on top of [Vite](https://vite.dev), [Nitro](https://nitro.build/), and [Hono JSX](https://hono.dev/docs/guides/jsx). File-based routing for HTML pages, islands architecture for client interactivity, head/SEO via [unhead](https://unhead.unjs.io/), and full Nitro feature set (presets, caching, middleware, API routes).
|
|
3
|
+
SSR meta-framework on top of [Vite](https://vite.dev), [Nitro](https://nitro.build/), and [Hono JSX](https://hono.dev/docs/guides/jsx). File-based routing for HTML pages, islands architecture for client interactivity, client-side routing via [wouter](https://github.com/molefrog/wouter), React-ecosystem compatibility through [@hono/react-compat](https://github.com/honojs/react-compat), head/SEO via [unhead](https://unhead.unjs.io/), and full Nitro feature set (presets, caching, middleware, API routes).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -149,6 +149,37 @@ export default definePage({
|
|
|
149
149
|
|
|
150
150
|
Props are serialized with `devalue` (supports `Date`, `Map`, `Set`, `URL`, `RegExp`, `Error`, `BigInt`, cycles).
|
|
151
151
|
|
|
152
|
+
### React ecosystem compatibility
|
|
153
|
+
|
|
154
|
+
The Vite plugin aliases `react` and `react-dom` to [`@hono/react-compat`](https://github.com/honojs/react-compat), which reimplements the React API on top of `hono/jsx`. This means libraries from the React ecosystem (wouter, tanstack/react-query, etc.) work inside islands and the render tree without shipping React. `use-sync-external-store` is also aliased to `@hono/react-compat`.
|
|
155
|
+
|
|
156
|
+
## Routing
|
|
157
|
+
|
|
158
|
+
Every page renders inside a [wouter](https://github.com/molefrog/wouter) `<Router>`, seeded with the current request's `pathname` and `search` for SSR. After hydration, navigation is client-side — wouter hooks and components work inside islands and the root layout:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// src/components/Search.island.tsx
|
|
162
|
+
import { useSearchParams } from "wouter";
|
|
163
|
+
|
|
164
|
+
export const Search = () => {
|
|
165
|
+
const [params, setParams] = useSearchParams();
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<input
|
|
169
|
+
value={params.get("q") ?? ""}
|
|
170
|
+
onChange={e =>
|
|
171
|
+
setParams(prev => {
|
|
172
|
+
prev.set("q", e.target.value);
|
|
173
|
+
return prev;
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
/>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
wouter's `Link`, `Route`, `useLocation`, `useRoute`, and `useSearchParams` are all available. Note that yamf's file-based routing (see [File routing](#file-routing)) handles full-page SSR routes, while wouter handles client-side navigation and query-param state within a page.
|
|
182
|
+
|
|
152
183
|
## Client entry
|
|
153
184
|
|
|
154
185
|
```ts
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ResolvableHead } from "unhead/types";
|
|
2
2
|
//#region src/components/Head.d.ts
|
|
3
|
-
type HeadProps = ResolvableHead;
|
|
4
|
-
declare const Head: (props: HeadProps) => void;
|
|
3
|
+
export type HeadProps = ResolvableHead;
|
|
4
|
+
export declare const Head: (props: HeadProps) => void;
|
|
5
5
|
//#endregion
|
|
6
|
-
export { Head, HeadProps };
|
|
7
6
|
//# sourceMappingURL=Head.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Head.d.ts","names":[],"sources":["../../src/components/Head.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"Head.d.ts","names":[],"sources":["../../src/components/Head.tsx"],"mappings":";;YAGY,YAAY;qBAEX,OAAQ,OAAO"}
|
package/dist/context/ssr.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ interface SSRContextValue {
|
|
|
6
6
|
head: ServerUnhead;
|
|
7
7
|
event: H3Event;
|
|
8
8
|
}
|
|
9
|
-
declare const useSSRContext: () => SSRContextValue | null;
|
|
9
|
+
export declare const useSSRContext: () => SSRContextValue | null;
|
|
10
10
|
//#endregion
|
|
11
|
-
export { useSSRContext };
|
|
12
11
|
//# sourceMappingURL=ssr.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr.d.ts","names":[],"sources":["../../src/context/ssr.ts"],"mappings":";;;;UAIU;EACT,MAAM;EACN,OAAO;;
|
|
1
|
+
{"version":3,"file":"ssr.d.ts","names":[],"sources":["../../src/context/ssr.ts"],"mappings":";;;;UAIU;EACT,MAAM;EACN,OAAO;;qBAOK,qBAAoB"}
|
package/dist/hooks/useEvent.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEvent.d.ts","names":[],"sources":["../../src/hooks/useEvent.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useEvent.d.ts","names":[],"sources":["../../src/hooks/useEvent.tsx"],"mappings":";;qBAGa,gBAAe"}
|
package/dist/hooks/useHead.d.ts
CHANGED
|
@@ -6,8 +6,7 @@ declare global {
|
|
|
6
6
|
__UNHEAD__?: ClientUnhead;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
declare const useHead: (input?: ResolvableHead) => void;
|
|
10
|
-
declare const useSeoMeta: (input?: UseSeoMetaInput) => void;
|
|
9
|
+
export declare const useHead: (input?: ResolvableHead) => void;
|
|
10
|
+
export declare const useSeoMeta: (input?: UseSeoMetaInput) => void;
|
|
11
11
|
//#endregion
|
|
12
|
-
export { useHead, useSeoMeta };
|
|
13
12
|
//# sourceMappingURL=useHead.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHead.d.ts","names":[],"sources":["../../src/hooks/useHead.tsx"],"mappings":";;;QAMe;YACJ;IACT,aAAa;;;
|
|
1
|
+
{"version":3,"file":"useHead.d.ts","names":[],"sources":["../../src/hooks/useHead.tsx"],"mappings":";;;QAMe;YACJ;IACT,aAAa;;;qBAQF,UAAW,QAAQ;qBAYnB,aAAc,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHead.js","names":["useHead","useSeoMeta"],"sources":["../../src/hooks/useHead.tsx"],"sourcesContent":["import { useHead as _useHead, useSeoMeta as _useSeoMeta } from \"unhead\";\nimport type { ClientUnhead } from \"unhead/client\";\nimport { createHead } from \"unhead/client\";\nimport type { ResolvableHead, UseSeoMetaInput } from \"unhead/types\";\nimport { useSSRContext } from \"#/context/ssr\";\n\ndeclare global {\n\tinterface Window {\n\t\t__UNHEAD__?: ClientUnhead;\n\t}\n}\n\nif (!import.meta.env.SSR) {\n\twindow.__UNHEAD__ = createHead();\n}\n\nexport const useHead = (input?: ResolvableHead): void => {\n\tif (import.meta.env.SSR) {\n\t\tconst ctx = useSSRContext();\n\n\t\tif (ctx?.head) {\n\t\t\t_useHead(ctx.head, input);\n\t\t}\n\t} else if (window.__UNHEAD__) {\n\t\t_useHead(window.__UNHEAD__, input);\n\t}\n};\n\nexport const useSeoMeta = (input?: UseSeoMetaInput): void => {\n\tif (import.meta.env.SSR) {\n\t\tconst ctx = useSSRContext();\n\n\t\tif (ctx?.head) {\n\t\t\t_useSeoMeta(ctx.head, input);\n\t\t}\n\t} else if (window.__UNHEAD__) {\n\t\t_useSeoMeta(window.__UNHEAD__, input);\n\t}\n};\n"],"mappings":";;;;AAYA,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"useHead.js","names":["useHead","useSeoMeta"],"sources":["../../src/hooks/useHead.tsx"],"sourcesContent":["import { useHead as _useHead, useSeoMeta as _useSeoMeta } from \"unhead\";\nimport type { ClientUnhead } from \"unhead/client\";\nimport { createHead } from \"unhead/client\";\nimport type { ResolvableHead, UseSeoMetaInput } from \"unhead/types\";\nimport { useSSRContext } from \"#/context/ssr\";\n\ndeclare global {\n\tinterface Window {\n\t\t__UNHEAD__?: ClientUnhead;\n\t}\n}\n\nif (!import.meta.env.SSR) {\n\twindow.__UNHEAD__ = createHead();\n}\n\nexport const useHead = (input?: ResolvableHead): void => {\n\tif (import.meta.env.SSR) {\n\t\tconst ctx = useSSRContext();\n\n\t\tif (ctx?.head) {\n\t\t\t_useHead(ctx.head, input);\n\t\t}\n\t} else if (window.__UNHEAD__) {\n\t\t_useHead(window.__UNHEAD__, input);\n\t}\n};\n\nexport const useSeoMeta = (input?: UseSeoMetaInput): void => {\n\tif (import.meta.env.SSR) {\n\t\tconst ctx = useSSRContext();\n\n\t\tif (ctx?.head) {\n\t\t\t_useSeoMeta(ctx.head, input);\n\t\t}\n\t} else if (window.__UNHEAD__) {\n\t\t_useSeoMeta(window.__UNHEAD__, input);\n\t}\n};\n"],"mappings":";;;;AAYA,IAAI,CAAC,YAAY,IAAI,KACpB,OAAO,aAAa,WAAW;AAGhC,MAAaA,aAAW,UAAiC;CACxD,IAAI,YAAY,IAAI,KAAK;EACxB,MAAM,MAAM,cAAc;EAE1B,IAAI,KAAK,MACR,QAAS,IAAI,MAAM,KAAK;CAE1B,OAAO,IAAI,OAAO,YACjB,QAAS,OAAO,YAAY,KAAK;AAEnC;AAEA,MAAaC,gBAAc,UAAkC;CAC5D,IAAI,YAAY,IAAI,KAAK;EACxB,MAAM,MAAM,cAAc;EAE1B,IAAI,KAAK,MACR,WAAY,IAAI,MAAM,KAAK;CAE7B,OAAO,IAAI,OAAO,YACjB,WAAY,OAAO,YAAY,KAAK;AAEtC"}
|
package/dist/island/types.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//#region src/island/types.d.ts
|
|
2
|
-
type IslandClientDirective = "load" | "idle" | "visible" | "skip" | boolean;
|
|
3
|
-
interface IslandProps {
|
|
2
|
+
export type IslandClientDirective = "load" | "idle" | "visible" | "skip" | boolean;
|
|
3
|
+
export interface IslandProps {
|
|
4
4
|
"yamf-client"?: IslandClientDirective;
|
|
5
5
|
}
|
|
6
6
|
//#endregion
|
|
7
|
-
export { IslandClientDirective, IslandProps };
|
|
8
7
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/island/types.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/island/types.ts"],"mappings":";YAAY;iBASK;EAChB,gBAAgB"}
|
package/dist/page.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { EventHandlerResponse, H3Event, HTTPResponse } from "nitro/h3";
|
|
|
5
5
|
import { Unhead } from "unhead/server";
|
|
6
6
|
import { UseSeoMetaInput } from "unhead/types";
|
|
7
7
|
//#region src/page.d.ts
|
|
8
|
-
type PageHandler = (event: H3Event, params: {
|
|
8
|
+
export type PageHandler = (event: H3Event, params: {
|
|
9
9
|
assets: ImportAssetsResult;
|
|
10
10
|
head?: YamfHead;
|
|
11
11
|
}) => EventHandlerResponse;
|
|
12
|
-
type PageRenderer = (event: H3Event, params: {
|
|
12
|
+
export type PageRenderer = (event: H3Event, params: {
|
|
13
13
|
head: Unhead;
|
|
14
14
|
seoHead: (input: UseSeoMetaInput) => void;
|
|
15
15
|
}) => HTTPResponse | Child | Promise<Child | HTTPResponse>;
|
|
@@ -17,7 +17,6 @@ interface DefinePageOptions {
|
|
|
17
17
|
render: PageRenderer;
|
|
18
18
|
stream?: boolean;
|
|
19
19
|
}
|
|
20
|
-
declare const definePage: (options: DefinePageOptions) => PageHandler;
|
|
20
|
+
export declare const definePage: (options: DefinePageOptions) => PageHandler;
|
|
21
21
|
//#endregion
|
|
22
|
-
export { PageHandler, PageRenderer, definePage };
|
|
23
22
|
//# sourceMappingURL=page.d.ts.map
|
package/dist/page.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","names":[],"sources":["../src/page.tsx"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"page.d.ts","names":[],"sources":["../src/page.tsx"],"mappings":";;;;;;;YAiBY,eACX,OAAO,SACP;EACC,QAAQ;EACR,OAAO;MAEJ;YAEO,gBACX,OAAO,SACP;EACC,MAAM;EACN,UAAU,OAAO;MAEd,eAAe,QAAQ,QAAQ,QAAQ;UAElC;EACT,QAAQ;EACR;;qBAGY,aAAc,SAAS,sBAAoB"}
|
package/dist/server/entry.d.mts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { YamfHead } from "./shared/head.mjs";
|
|
2
2
|
import { EventHandlerRequest, EventHandlerWithFetch, H3Event } from "nitro/h3";
|
|
3
3
|
//#region src/server/entry.d.ts
|
|
4
|
-
type ServerEntry = EventHandlerWithFetch<EventHandlerRequest, Promise<unknown>>;
|
|
5
|
-
interface DefineServerEntryOptions {
|
|
4
|
+
export type ServerEntry = EventHandlerWithFetch<EventHandlerRequest, Promise<unknown>>;
|
|
5
|
+
export interface DefineServerEntryOptions {
|
|
6
6
|
head?: YamfHead | ((event: H3Event) => YamfHead);
|
|
7
7
|
disableEarlyHints?: boolean;
|
|
8
8
|
}
|
|
9
|
-
declare const defineServerEntry: (options?: DefineServerEntryOptions) => ServerEntry;
|
|
9
|
+
export declare const defineServerEntry: (options?: DefineServerEntryOptions) => ServerEntry;
|
|
10
10
|
//#endregion
|
|
11
|
-
export { DefineServerEntryOptions, ServerEntry, defineServerEntry };
|
|
12
11
|
//# sourceMappingURL=entry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.d.mts","names":[],"sources":["../../src/server/entry.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"entry.d.mts","names":[],"sources":["../../src/server/entry.tsx"],"mappings":";;;YAsDY,cAAc,sBAAsB,qBAAqB;iBAEpD;EAChB,OAAO,aAAa,OAAO,YAAY;EACvC;;qBAGY,oBAAqB,UAAU,6BAA2B"}
|
package/dist/server/entry.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { HTTPError, defineHandler, writeEarlyHints } from "nitro/h3";
|
|
|
3
3
|
import { addRoute, createRouter, findRoute } from "rou3";
|
|
4
4
|
import { withLeadingSlash, withoutTrailingSlash } from "ufo";
|
|
5
5
|
import { clientAssets } from "virtual:yamf:assets";
|
|
6
|
+
import { errorHandler } from "virtual:yamf:error-handler";
|
|
6
7
|
import { assets, pages } from "virtual:yamf:pages";
|
|
7
8
|
import { rootAssets } from "virtual:yamf:root";
|
|
8
9
|
//#region src/server/entry.tsx
|
|
@@ -19,7 +20,7 @@ for (const [relativePath, handler] of Object.entries(pages).toSorted((a, b) => a
|
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
const defineServerEntry = (options) => {
|
|
22
|
-
|
|
23
|
+
const rootHandler = async (event) => {
|
|
23
24
|
const route = findRoute(router, "GET", event.url.pathname);
|
|
24
25
|
if (!route) throw new HTTPError("Not found", { status: 404 });
|
|
25
26
|
const { handler, serverAssets } = route.data;
|
|
@@ -33,6 +34,15 @@ const defineServerEntry = (options) => {
|
|
|
33
34
|
assets,
|
|
34
35
|
head: typeof options?.head === "function" ? options.head(event) : options?.head
|
|
35
36
|
});
|
|
37
|
+
};
|
|
38
|
+
return defineHandler(async (event) => {
|
|
39
|
+
if (!errorHandler) return rootHandler(event);
|
|
40
|
+
try {
|
|
41
|
+
return await rootHandler(event);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const httpError = error instanceof HTTPError ? error : new HTTPError({ cause: error });
|
|
44
|
+
return errorHandler(httpError, event);
|
|
45
|
+
}
|
|
36
46
|
});
|
|
37
47
|
};
|
|
38
48
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.mjs","names":["pagesServerAssets"],"sources":["../../src/server/entry.tsx"],"sourcesContent":["import path from \"node:path\";\nimport
|
|
1
|
+
{"version":3,"file":"entry.mjs","names":["pagesServerAssets"],"sources":["../../src/server/entry.tsx"],"sourcesContent":["import path from \"node:path\";\nimport {\n\tdefineHandler,\n\tEventHandler,\n\tH3Event,\n\tHTTPError,\n\twriteEarlyHints,\n\ttype EventHandlerRequest,\n\ttype EventHandlerWithFetch,\n} from \"nitro/h3\";\nimport { addRoute, createRouter, findRoute } from \"rou3\";\nimport { withLeadingSlash, withoutTrailingSlash } from \"ufo\";\nimport { clientAssets } from \"virtual:yamf:assets\";\nimport { errorHandler } from \"virtual:yamf:error-handler\";\nimport { pages, assets as pagesServerAssets } from \"virtual:yamf:pages\";\nimport { rootAssets } from \"virtual:yamf:root\";\nimport type { PageHandler } from \"#/page\";\nimport { YamfHead } from \"#/shared/head\";\n\ninterface Route {\n\thandler: () => Promise<PageHandler>;\n\tserverAssets?: ImportAssetsResult;\n}\n\nconst router = createRouter<Route>();\n\nfor (const [relativePath, handler] of Object.entries(pages).toSorted((a, b) =>\n\ta[0].localeCompare(b[0]),\n)) {\n\tconst ext = path.extname(relativePath);\n\n\tlet route = path.relative(\"/src/pages\", relativePath);\n\n\tif (ext.length) {\n\t\troute = route.slice(0, -ext.length);\n\t}\n\n\troute =\n\t\troute\n\t\t\t.replace(/\\.[A-Za-z]+$/, \"\")\n\t\t\t.replace(/\\(([^(/\\\\]+)\\)[/\\\\]/g, \"\")\n\t\t\t.replace(/\\[\\.{3}]/g, \"**\")\n\t\t\t.replace(/\\[\\.{3}([^\\]]+)]/g, (_, p: string) => \"**:\" + p.replace(/[^\\w-]/g, \"_\"))\n\t\t\t.replace(/\\[([^/\\]]+)]/g, (_, p: string) => \":\" + p.replace(/[^\\w-]/g, \"_\"))\n\t\t\t.replace(/(\\/|^)index$/, \"\") || \"/\";\n\n\troute = withLeadingSlash(withoutTrailingSlash(route));\n\n\taddRoute(router, \"GET\", route, {\n\t\thandler,\n\t\tserverAssets: pagesServerAssets[relativePath],\n\t});\n}\n\nexport type ServerEntry = EventHandlerWithFetch<EventHandlerRequest, Promise<unknown>>;\n\nexport interface DefineServerEntryOptions {\n\thead?: YamfHead | ((event: H3Event) => YamfHead);\n\tdisableEarlyHints?: boolean;\n}\n\nexport const defineServerEntry = (options?: DefineServerEntryOptions): ServerEntry => {\n\tconst rootHandler: EventHandler<EventHandlerRequest, Promise<unknown>> = async event => {\n\t\tconst route = findRoute(router, \"GET\", event.url.pathname);\n\n\t\tif (!route) {\n\t\t\tthrow new HTTPError(\"Not found\", { status: 404 });\n\t\t}\n\n\t\tconst { handler, serverAssets } = route.data;\n\t\tevent.context.params = route.params;\n\n\t\tconst assets = clientAssets.merge(...[rootAssets, serverAssets].filter(x => !!x));\n\n\t\tif (!options?.disableEarlyHints) {\n\t\t\tconst link = [\n\t\t\t\t...assets.js.map(script => `<${script.href}>; rel=modulepreload`),\n\t\t\t\t...assets.css.map(style => `<${style.href}>; rel=preload; as=style`),\n\t\t\t];\n\n\t\t\tif (link.length) {\n\t\t\t\tawait writeEarlyHints(event, { link });\n\t\t\t}\n\t\t}\n\n\t\treturn (await handler())(event, {\n\t\t\tassets,\n\t\t\thead: typeof options?.head === \"function\" ? options.head(event) : options?.head,\n\t\t});\n\t};\n\n\treturn defineHandler(async event => {\n\t\tif (!errorHandler) {\n\t\t\treturn rootHandler(event);\n\t\t}\n\n\t\ttry {\n\t\t\treturn await rootHandler(event);\n\t\t} catch (error) {\n\t\t\tconst httpError = error instanceof HTTPError ? error : new HTTPError({ cause: error });\n\n\t\t\treturn errorHandler(httpError, event);\n\t\t}\n\t});\n};\n"],"mappings":";;;;;;;;;AAwBA,MAAM,SAAS,aAAoB;AAEnC,KAAK,MAAM,CAAC,cAAc,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,UAAU,GAAG,MACxE,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CACxB,GAAG;CACF,MAAM,MAAM,KAAK,QAAQ,YAAY;CAErC,IAAI,QAAQ,KAAK,SAAS,cAAc,YAAY;CAEpD,IAAI,IAAI,QACP,QAAQ,MAAM,MAAM,GAAG,CAAC,IAAI,MAAM;CAGnC,QACC,MACE,QAAQ,gBAAgB,EAAE,CAAC,CAC3B,QAAQ,wBAAwB,EAAE,CAAC,CACnC,QAAQ,aAAa,IAAI,CAAC,CAC1B,QAAQ,sBAAsB,GAAG,MAAc,QAAQ,EAAE,QAAQ,WAAW,GAAG,CAAC,CAAC,CACjF,QAAQ,kBAAkB,GAAG,MAAc,MAAM,EAAE,QAAQ,WAAW,GAAG,CAAC,CAAC,CAC3E,QAAQ,gBAAgB,EAAE,KAAK;CAElC,QAAQ,iBAAiB,qBAAqB,KAAK,CAAC;CAEpD,SAAS,QAAQ,OAAO,OAAO;EAC9B;EACA,cAAcA,OAAkB;CACjC,CAAC;AACF;AASA,MAAa,qBAAqB,YAAoD;CACrF,MAAM,cAAmE,OAAM,UAAS;EACvF,MAAM,QAAQ,UAAU,QAAQ,OAAO,MAAM,IAAI,QAAQ;EAEzD,IAAI,CAAC,OACJ,MAAM,IAAI,UAAU,aAAa,EAAE,QAAQ,IAAI,CAAC;EAGjD,MAAM,EAAE,SAAS,iBAAiB,MAAM;EACxC,MAAM,QAAQ,SAAS,MAAM;EAE7B,MAAM,SAAS,aAAa,MAAM,GAAG,CAAC,YAAY,YAAY,CAAC,CAAC,QAAO,MAAK,CAAC,CAAC,CAAC,CAAC;EAEhF,IAAI,CAAC,SAAS,mBAAmB;GAChC,MAAM,OAAO,CACZ,GAAG,OAAO,GAAG,KAAI,WAAU,IAAI,OAAO,KAAK,qBAAqB,GAChE,GAAG,OAAO,IAAI,KAAI,UAAS,IAAI,MAAM,KAAK,yBAAyB,CACpE;GAEA,IAAI,KAAK,QACR,MAAM,gBAAgB,OAAO,EAAE,KAAK,CAAC;EAEvC;EAEA,QAAQ,MAAM,QAAQ,EAAA,CAAG,OAAO;GAC/B;GACA,MAAM,OAAO,SAAS,SAAS,aAAa,QAAQ,KAAK,KAAK,IAAI,SAAS;EAC5E,CAAC;CACF;CAEA,OAAO,cAAc,OAAM,UAAS;EACnC,IAAI,CAAC,cACJ,OAAO,YAAY,KAAK;EAGzB,IAAI;GACH,OAAO,MAAM,YAAY,KAAK;EAC/B,SAAS,OAAO;GACf,MAAM,YAAY,iBAAiB,YAAY,QAAQ,IAAI,UAAU,EAAE,OAAO,MAAM,CAAC;GAErF,OAAO,aAAa,WAAW,KAAK;EACrC;CACD,CAAC;AACF"}
|
|
@@ -9,14 +9,13 @@ declare module "hono/jsx" {
|
|
|
9
9
|
"island-props"?: string;
|
|
10
10
|
"island-src": string;
|
|
11
11
|
"island-entry": string;
|
|
12
|
-
"island-client"
|
|
12
|
+
"island-client"?: IslandClientDirective;
|
|
13
13
|
children: Child;
|
|
14
14
|
style?: JSX.CSSProperties;
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
declare const createIsland: (Component: FC, exportName: string, assets: ImportAssetsResultRaw) => FC;
|
|
19
|
+
export declare const createIsland: (Component: FC, exportName: string, assets: ImportAssetsResultRaw) => FC;
|
|
20
20
|
//#endregion
|
|
21
|
-
export { createIsland };
|
|
22
21
|
//# sourceMappingURL=server.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.mts","names":[],"sources":["../../../src/island/server.tsx"],"mappings":";;;;;YAMW;cACC;MACT;QACC;QACA;QACA;QACA,
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../../src/island/server.tsx"],"mappings":";;;;;YAMW;cACC;MACT;QACC;QACA;QACA;QACA,kBAAkB;QAClB,UAAU;QACV,QAAQ,IAAI;;;;;qBAMH,eACZ,WAAW,IACX,oBACA,QAAQ,0BACN"}
|
|
@@ -2,13 +2,13 @@ import { stringify } from "devalue";
|
|
|
2
2
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
3
3
|
//#region src/island/server.tsx
|
|
4
4
|
const createIsland = (Component, exportName, assets) => {
|
|
5
|
-
const ComponentWrapper = (props) => {
|
|
5
|
+
const ComponentWrapper = ({ "yamf-client": clientDirective, ...props }) => {
|
|
6
6
|
if (!assets.entry) throw new Error(`Missing island entry for island ${Component.name}`);
|
|
7
7
|
return /* @__PURE__ */ jsx("yamf-island", {
|
|
8
8
|
"island-props": stringify(props),
|
|
9
9
|
"island-src": assets.entry,
|
|
10
10
|
"island-entry": exportName,
|
|
11
|
-
"island-client":
|
|
11
|
+
"island-client": clientDirective,
|
|
12
12
|
style: { display: "contents" },
|
|
13
13
|
children: /* @__PURE__ */ jsx(Component, { ...props })
|
|
14
14
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../../../src/island/server.tsx"],"sourcesContent":["import { stringify } from \"devalue\";\nimport type { Child, FC } from \"hono/jsx\";\nimport type { ImportAssetsResultRaw } from \"#/shared/assets\";\nimport type { IslandClientDirective } from \"./types\";\n\ndeclare module \"hono/jsx\" {\n\tnamespace JSX {\n\t\tinterface IntrinsicElements {\n\t\t\t\"yamf-island\": {\n\t\t\t\t\"island-props\"?: string;\n\t\t\t\t\"island-src\": string;\n\t\t\t\t\"island-entry\": string;\n\t\t\t\t\"island-client\"
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../../../src/island/server.tsx"],"sourcesContent":["import { stringify } from \"devalue\";\nimport type { Child, FC } from \"hono/jsx\";\nimport type { ImportAssetsResultRaw } from \"#/shared/assets\";\nimport type { IslandClientDirective, IslandProps } from \"./types\";\n\ndeclare module \"hono/jsx\" {\n\tnamespace JSX {\n\t\tinterface IntrinsicElements {\n\t\t\t\"yamf-island\": {\n\t\t\t\t\"island-props\"?: string;\n\t\t\t\t\"island-src\": string;\n\t\t\t\t\"island-entry\": string;\n\t\t\t\t\"island-client\"?: IslandClientDirective;\n\t\t\t\tchildren: Child;\n\t\t\t\tstyle?: JSX.CSSProperties;\n\t\t\t};\n\t\t}\n\t}\n}\n\nexport const createIsland = (\n\tComponent: FC,\n\texportName: string,\n\tassets: ImportAssetsResultRaw,\n): FC => {\n\tconst ComponentWrapper: FC<IslandProps> & { name: string } = ({\n\t\t\"yamf-client\": clientDirective,\n\t\t...props\n\t}) => {\n\t\tif (!assets.entry) {\n\t\t\tthrow new Error(`Missing island entry for island ${Component.name}`);\n\t\t}\n\n\t\treturn (\n\t\t\t<yamf-island\n\t\t\t\tisland-props={stringify(props)}\n\t\t\t\tisland-src={assets.entry}\n\t\t\t\tisland-entry={exportName}\n\t\t\t\tisland-client={clientDirective}\n\t\t\t\t// TODO: export CSS?\n\t\t\t\tstyle={{ display: \"contents\" }}\n\t\t\t>\n\t\t\t\t<Component {...props} />\n\t\t\t</yamf-island>\n\t\t);\n\t};\n\n\tObject.defineProperty(ComponentWrapper, \"name\", {\n\t\tvalue: Component.name,\n\t});\n\n\treturn ComponentWrapper;\n};\n"],"mappings":";;;AAoBA,MAAa,gBACZ,WACA,YACA,WACQ;CACR,MAAM,oBAAwD,EAC7D,eAAe,iBACf,GAAG,YACE;EACL,IAAI,CAAC,OAAO,OACX,MAAM,IAAI,MAAM,mCAAmC,UAAU,MAAM;EAGpE,OACC,oBAAC,eAAD;GACC,gBAAc,UAAU,KAAK;GAC7B,cAAY,OAAO;GACnB,gBAAc;GACd,iBAAe;GAEf,OAAO,EAAE,SAAS,WAAW;GAE7B,UAAA,oBAAC,WAAD,EAAW,GAAI,MAAQ,CAAA;EACX,CAAA;CAEf;CAEA,OAAO,eAAe,kBAAkB,QAAQ,EAC/C,OAAO,UAAU,KAClB,CAAC;CAED,OAAO;AACR"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
//#region src/island/types.d.ts
|
|
2
|
-
type IslandClientDirective = "load" | "idle" | "visible" | "skip" | boolean;
|
|
2
|
+
export type IslandClientDirective = "load" | "idle" | "visible" | "skip" | boolean;
|
|
3
3
|
//#endregion
|
|
4
|
-
export { IslandClientDirective };
|
|
5
4
|
//# sourceMappingURL=types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/island/types.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/island/types.ts"],"mappings":";YAAY"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/shared/assets.d.ts
|
|
2
|
-
type ImportAssetsResultRaw = {
|
|
2
|
+
export type ImportAssetsResultRaw = {
|
|
3
3
|
entry?: string;
|
|
4
4
|
js: {
|
|
5
5
|
href: string;
|
|
@@ -10,5 +10,4 @@ type ImportAssetsResultRaw = {
|
|
|
10
10
|
}[];
|
|
11
11
|
};
|
|
12
12
|
//#endregion
|
|
13
|
-
export { ImportAssetsResultRaw };
|
|
14
13
|
//# sourceMappingURL=assets.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.mts","names":[],"sources":["../../../src/shared/assets.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"assets.d.mts","names":[],"sources":["../../../src/shared/assets.ts"],"mappings":";YAKY;EACX;EACA;IAAM;;EACN;IAAO;IAAc"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ResolvableHead, UseSeoMetaInput } from "unhead/types";
|
|
2
2
|
//#region src/shared/head.d.ts
|
|
3
|
-
type YamfHead = ResolvableHead & {
|
|
3
|
+
export type YamfHead = ResolvableHead & {
|
|
4
4
|
seo?: UseSeoMetaInput;
|
|
5
5
|
};
|
|
6
6
|
//#endregion
|
|
7
|
-
export { YamfHead };
|
|
8
7
|
//# sourceMappingURL=head.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.mts","names":[],"sources":["../../../src/shared/head.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"head.d.mts","names":[],"sources":["../../../src/shared/head.ts"],"mappings":";;YAEY,WAAW;EAAmB,MAAM"}
|
package/dist/shared/assets.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/shared/assets.d.ts
|
|
2
|
-
type ImportAssetsResult = ImportAssetsResultRaw & {
|
|
2
|
+
export type ImportAssetsResult = ImportAssetsResultRaw & {
|
|
3
3
|
merge(...args: ImportAssetsResultRaw[]): ImportAssetsResult;
|
|
4
4
|
};
|
|
5
|
-
type ImportAssetsResultRaw = {
|
|
5
|
+
export type ImportAssetsResultRaw = {
|
|
6
6
|
entry?: string;
|
|
7
7
|
js: {
|
|
8
8
|
href: string;
|
|
@@ -13,5 +13,4 @@ type ImportAssetsResultRaw = {
|
|
|
13
13
|
}[];
|
|
14
14
|
};
|
|
15
15
|
//#endregion
|
|
16
|
-
export { ImportAssetsResult, ImportAssetsResultRaw };
|
|
17
16
|
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","names":[],"sources":["../../src/shared/assets.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"assets.d.ts","names":[],"sources":["../../src/shared/assets.ts"],"mappings":";YACY,qBAAqB;EAChC,SAAS,MAAM,0BAA0B;;YAG9B;EACX;EACA;IAAM;;EACN;IAAO;IAAc"}
|
package/dist/shared/head.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ResolvableHead, UseSeoMetaInput } from "unhead/types";
|
|
2
2
|
//#region src/shared/head.d.ts
|
|
3
|
-
type YamfHead = ResolvableHead & {
|
|
3
|
+
export type YamfHead = ResolvableHead & {
|
|
4
4
|
seo?: UseSeoMetaInput;
|
|
5
5
|
};
|
|
6
6
|
//#endregion
|
|
7
|
-
export { YamfHead };
|
|
8
7
|
//# sourceMappingURL=head.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.ts","names":[],"sources":["../../src/shared/head.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"head.d.ts","names":[],"sources":["../../src/shared/head.ts"],"mappings":";;YAEY,WAAW;EAAmB,MAAM"}
|
package/dist/vite/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { NitroPluginConfig } from "nitro/vite";
|
|
2
2
|
import { PluginOption } from "vite";
|
|
3
3
|
//#region src/vite/index.d.ts
|
|
4
|
-
interface YamfOptions {
|
|
4
|
+
export interface YamfOptions {
|
|
5
5
|
nitro?: NitroPluginConfig;
|
|
6
6
|
}
|
|
7
7
|
declare const yamf: (options?: YamfOptions) => PluginOption[];
|
|
8
8
|
//#endregion
|
|
9
|
-
export {
|
|
9
|
+
export { yamf as default };
|
|
10
10
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/vite/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/vite/index.ts"],"mappings":";;;iBAWiB;EAChB,QAAQ;;cAGH,OAAQ,UAAU,gBAAc"}
|
package/dist/vite/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { islands } from "./islands.mjs";
|
|
2
2
|
import { virtualAssets } from "./virtual-assets.mjs";
|
|
3
|
+
import { virtualErrorHandler } from "./virtual-error-handler.mjs";
|
|
3
4
|
import { virtualPages } from "./virtual-pages.mjs";
|
|
4
5
|
import { virtualRoot } from "./virtual-root.mjs";
|
|
5
6
|
import { virtualTemplate } from "./virtual-template.mjs";
|
|
@@ -45,6 +46,7 @@ const yamf = (options) => {
|
|
|
45
46
|
}
|
|
46
47
|
});
|
|
47
48
|
plugins.push(islands());
|
|
49
|
+
plugins.push(virtualErrorHandler(options));
|
|
48
50
|
plugins.push(virtualAssets());
|
|
49
51
|
plugins.push(virtualPages());
|
|
50
52
|
plugins.push(virtualTemplate());
|
|
@@ -60,7 +62,7 @@ const yamf = (options) => {
|
|
|
60
62
|
publicAssets: [{
|
|
61
63
|
baseURL: "assets",
|
|
62
64
|
dir: "./public/assets",
|
|
63
|
-
maxAge:
|
|
65
|
+
maxAge: 31536e3
|
|
64
66
|
}]
|
|
65
67
|
}));
|
|
66
68
|
return plugins;
|
package/dist/vite/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/vite/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport type { NitroPluginConfig } from \"nitro/vite\";\nimport { nitro } from \"nitro/vite\";\nimport type { EnvironmentOptions, PluginOption } from \"vite\";\nimport { islands } from \"./islands\";\nimport { virtualAssets } from \"./virtual-assets\";\nimport { virtualPages } from \"./virtual-pages\";\nimport { virtualRoot } from \"./virtual-root\";\nimport { virtualTemplate } from \"./virtual-template\";\n\nexport interface YamfOptions {\n\tnitro?: NitroPluginConfig;\n}\n\nconst yamf = (options?: YamfOptions): PluginOption[] => {\n\tconst plugins: PluginOption[] = [];\n\n\t// TODO: extendable config\n\tplugins.push({\n\t\tname: \"yamf:config\",\n\t\tconfig() {\n\t\t\tconst ssrEnv: EnvironmentOptions = {\n\t\t\t\tbuild: {\n\t\t\t\t\t// TODO: figure out if this should be true\n\t\t\t\t\tcssCodeSplit: false,\n\t\t\t\t\trolldownOptions: {\n\t\t\t\t\t\tinput: \"./src/server.tsx\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\t\treturn {\n\t\t\t\tssr: {\n\t\t\t\t\t// we need to inline because otherwise fullstack plugin fails to build manifest for assets imports\n\t\t\t\t\t// also, we need to bundle everything so that the `react` -> `@hono/react-compat` alias\n\t\t\t\t\t// is applied to all dependencies (e.g. wouter) in dev mode. Externalized deps are\n\t\t\t\t\t// loaded natively by Node, bypassing Vite's resolve.alias.\n\t\t\t\t\tnoExternal: true,\n\t\t\t\t},\n\t\t\t\toptimizeDeps: {\n\t\t\t\t\tinclude: [\n\t\t\t\t\t\t\"hono\",\n\t\t\t\t\t\t\"hono/jsx/dom/client\",\n\t\t\t\t\t\t\"hono/jsx/jsx-runtime\",\n\t\t\t\t\t\t\"devalue\",\n\t\t\t\t\t\t\"ufo\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tresolve: {\n\t\t\t\t\talias: [\n\t\t\t\t\t\t{ find: \"react\", replacement: \"@hono/react-compat\" },\n\t\t\t\t\t\t{ find: \"react-dom\", replacement: \"@hono/react-compat\" },\n\t\t\t\t\t\t// use-sync-external-store is a CJS package that requires(\"react\").\n\t\t\t\t\t\t// Vite's SSR module runner can't process CJS, so we alias it to\n\t\t\t\t\t\t// @hono/react-compat which exports useSyncExternalStore from hono/jsx.\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfind: /^use-sync-external-store(?:\\/shim(?:\\/.*)?)?$/,\n\t\t\t\t\t\t\treplacement: \"@hono/react-compat\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tenvironments: {\n\t\t\t\t\t...(existsSync(\"./src/server.tsx\") ? { ssr: ssrEnv } : {}),\n\t\t\t\t\tclient: {\n\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\trolldownOptions: {\n\t\t\t\t\t\t\t\tinput: \"./src/client/index.ts\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t});\n\n\tplugins.push(islands());\n\n\tplugins.push(virtualAssets());\n\tplugins.push(virtualPages());\n\tplugins.push(virtualTemplate());\n\tplugins.push(virtualRoot());\n\n\tplugins.push(\n\t\tnitro({\n\t\t\tserverDir: \"./src\",\n\t\t\trenderer: false,\n\t\t\t...options?.nitro,\n\t\t\tcompressPublicAssets: {\n\t\t\t\tgzip: true,\n\t\t\t\tbrotli: true,\n\t\t\t},\n\t\t\tpublicAssets: [\n\t\t\t\t{\n\t\t\t\t\tbaseURL: \"assets\",\n\t\t\t\t\tdir: \"./public/assets\",\n\t\t\t\t\tmaxAge: 365 * 24 * 60 * 60,\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t);\n\n\treturn plugins;\n};\n\nexport default yamf;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/vite/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport type { NitroPluginConfig } from \"nitro/vite\";\nimport { nitro } from \"nitro/vite\";\nimport type { EnvironmentOptions, PluginOption } from \"vite\";\nimport { islands } from \"./islands\";\nimport { virtualAssets } from \"./virtual-assets\";\nimport { virtualErrorHandler } from \"./virtual-error-handler\";\nimport { virtualPages } from \"./virtual-pages\";\nimport { virtualRoot } from \"./virtual-root\";\nimport { virtualTemplate } from \"./virtual-template\";\n\nexport interface YamfOptions {\n\tnitro?: NitroPluginConfig;\n}\n\nconst yamf = (options?: YamfOptions): PluginOption[] => {\n\tconst plugins: PluginOption[] = [];\n\n\t// TODO: extendable config\n\tplugins.push({\n\t\tname: \"yamf:config\",\n\t\tconfig() {\n\t\t\tconst ssrEnv: EnvironmentOptions = {\n\t\t\t\tbuild: {\n\t\t\t\t\t// TODO: figure out if this should be true\n\t\t\t\t\tcssCodeSplit: false,\n\t\t\t\t\trolldownOptions: {\n\t\t\t\t\t\tinput: \"./src/server.tsx\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\t\treturn {\n\t\t\t\tssr: {\n\t\t\t\t\t// we need to inline because otherwise fullstack plugin fails to build manifest for assets imports\n\t\t\t\t\t// also, we need to bundle everything so that the `react` -> `@hono/react-compat` alias\n\t\t\t\t\t// is applied to all dependencies (e.g. wouter) in dev mode. Externalized deps are\n\t\t\t\t\t// loaded natively by Node, bypassing Vite's resolve.alias.\n\t\t\t\t\tnoExternal: true,\n\t\t\t\t},\n\t\t\t\toptimizeDeps: {\n\t\t\t\t\tinclude: [\n\t\t\t\t\t\t\"hono\",\n\t\t\t\t\t\t\"hono/jsx/dom/client\",\n\t\t\t\t\t\t\"hono/jsx/jsx-runtime\",\n\t\t\t\t\t\t\"devalue\",\n\t\t\t\t\t\t\"ufo\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tresolve: {\n\t\t\t\t\talias: [\n\t\t\t\t\t\t{ find: \"react\", replacement: \"@hono/react-compat\" },\n\t\t\t\t\t\t{ find: \"react-dom\", replacement: \"@hono/react-compat\" },\n\t\t\t\t\t\t// use-sync-external-store is a CJS package that requires(\"react\").\n\t\t\t\t\t\t// Vite's SSR module runner can't process CJS, so we alias it to\n\t\t\t\t\t\t// @hono/react-compat which exports useSyncExternalStore from hono/jsx.\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfind: /^use-sync-external-store(?:\\/shim(?:\\/.*)?)?$/,\n\t\t\t\t\t\t\treplacement: \"@hono/react-compat\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tenvironments: {\n\t\t\t\t\t...(existsSync(\"./src/server.tsx\") ? { ssr: ssrEnv } : {}),\n\t\t\t\t\tclient: {\n\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\trolldownOptions: {\n\t\t\t\t\t\t\t\tinput: \"./src/client/index.ts\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t});\n\n\tplugins.push(islands());\n\n\tplugins.push(virtualErrorHandler(options));\n\tplugins.push(virtualAssets());\n\tplugins.push(virtualPages());\n\tplugins.push(virtualTemplate());\n\tplugins.push(virtualRoot());\n\n\tplugins.push(\n\t\tnitro({\n\t\t\tserverDir: \"./src\",\n\t\t\trenderer: false,\n\t\t\t...options?.nitro,\n\t\t\tcompressPublicAssets: {\n\t\t\t\tgzip: true,\n\t\t\t\tbrotli: true,\n\t\t\t},\n\t\t\tpublicAssets: [\n\t\t\t\t{\n\t\t\t\t\tbaseURL: \"assets\",\n\t\t\t\t\tdir: \"./public/assets\",\n\t\t\t\t\tmaxAge: 365 * 24 * 60 * 60,\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t);\n\n\treturn plugins;\n};\n\nexport default yamf;\n"],"mappings":";;;;;;;;;AAeA,MAAM,QAAQ,YAA0C;CACvD,MAAM,UAA0B,CAAC;CAGjC,QAAQ,KAAK;EACZ,MAAM;EACN,SAAS;GAWR,OAAO;IACN,KAAK,EAKJ,YAAY,KACb;IACA,cAAc,EACb,SAAS;KACR;KACA;KACA;KACA;KACA;IACD,EACD;IACA,SAAS,EACR,OAAO;KACN;MAAE,MAAM;MAAS,aAAa;KAAqB;KACnD;MAAE,MAAM;MAAa,aAAa;KAAqB;KAIvD;MACC,MAAM;MACN,aAAa;KACd;IACD,EACD;IACA,cAAc;KACb,GAAI,WAAW,kBAAkB,IAAI,EAAE,KAAK,EAxC7C,OAAO;MAEN,cAAc;MACd,iBAAiB,EAChB,OAAO,mBACR;KACD,EAkCkD,EAAE,IAAI,CAAC;KACxD,QAAQ,EACP,OAAO,EACN,iBAAiB,EAChB,OAAO,wBACR,EACD,EACD;IACD;GACD;EACD;CACD,CAAC;CAED,QAAQ,KAAK,QAAQ,CAAC;CAEtB,QAAQ,KAAK,oBAAoB,OAAO,CAAC;CACzC,QAAQ,KAAK,cAAc,CAAC;CAC5B,QAAQ,KAAK,aAAa,CAAC;CAC3B,QAAQ,KAAK,gBAAgB,CAAC;CAC9B,QAAQ,KAAK,YAAY,CAAC;CAE1B,QAAQ,KACP,MAAM;EACL,WAAW;EACX,UAAU;EACV,GAAG,SAAS;EACZ,sBAAsB;GACrB,MAAM;GACN,QAAQ;EACT;EACA,cAAc,CACb;GACC,SAAS;GACT,KAAK;GACL,QAAQ;EACT,CACD;CACD,CAAC,CACF;CAEA,OAAO;AACR"}
|
package/dist/vite/islands.mjs
CHANGED
|
@@ -1,81 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import _traverse from "@babel/traverse";
|
|
4
|
-
import { callExpression, exportDefaultDeclaration, exportNamedDeclaration, functionDeclaration, functionExpression, identifier, importDeclaration, importDefaultSpecifier, importNamespaceSpecifier, memberExpression, stringLiteral, variableDeclaration, variableDeclarator } from "@babel/types";
|
|
1
|
+
import { withMagicString } from "rolldown-string";
|
|
2
|
+
import { Visitor } from "vite";
|
|
5
3
|
//#region src/vite/islands.ts
|
|
6
|
-
const traverse = _traverse.default ?? _traverse;
|
|
7
4
|
const ISLAND_REGEX = /\.island\.(j|t)sx?$/;
|
|
5
|
+
function langFromId(id) {
|
|
6
|
+
if (id.endsWith(".tsx")) return "tsx";
|
|
7
|
+
if (id.endsWith(".ts")) return "ts";
|
|
8
|
+
if (id.endsWith(".jsx")) return "jsx";
|
|
9
|
+
return "js";
|
|
10
|
+
}
|
|
8
11
|
const islands = () => {
|
|
9
12
|
return [{
|
|
10
13
|
name: "yamf:islands",
|
|
11
14
|
transform: {
|
|
12
15
|
filter: { id: ISLAND_REGEX },
|
|
13
|
-
handler(
|
|
16
|
+
handler: withMagicString(function(s, id) {
|
|
14
17
|
if (this.environment.name !== "ssr") return;
|
|
18
|
+
const program = this.parse(s.original, { lang: langFromId(id) });
|
|
19
|
+
s.prepend(`import * as __runtime from "@pajecawav/yamf/server";\n`);
|
|
20
|
+
s.prepend(`import __assets from "${id}?assets=client";\n`);
|
|
15
21
|
const seenExports = /* @__PURE__ */ new Set();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
path.unshiftContainer("body", importDeclaration([importNamespaceSpecifier(identifier("__runtime"))], stringLiteral("@pajecawav/yamf/server")));
|
|
23
|
-
path.unshiftContainer("body", importDeclaration([importDefaultSpecifier(identifier("__assets"))], stringLiteral(`${id}?assets=client`)));
|
|
22
|
+
new Visitor({
|
|
23
|
+
ExportDefaultDeclaration(node) {
|
|
24
|
+
const declaration = node.declaration;
|
|
25
|
+
if (declaration.type !== "FunctionDeclaration" && declaration.type !== "FunctionExpression" && declaration.type !== "ArrowFunctionExpression") return;
|
|
26
|
+
s.overwrite(node.start, declaration.start, "const __ISLAND__ = ");
|
|
27
|
+
s.appendRight(declaration.end, `; export default __runtime.createIsland(__ISLAND__, "default", __assets)`);
|
|
24
28
|
},
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
path.replaceWith(exportDefaultDeclaration(callExpression(memberExpression(identifier("__runtime"), identifier("createIsland")), [
|
|
32
|
-
islandIdentifier,
|
|
33
|
-
stringLiteral("default"),
|
|
34
|
-
identifier("__assets")
|
|
35
|
-
])));
|
|
36
|
-
},
|
|
37
|
-
ExportNamedDeclaration(path) {
|
|
38
|
-
if (path.node.declaration?.type === "VariableDeclaration") {
|
|
39
|
-
const declaration = path.node.declaration.declarations.at(0);
|
|
40
|
-
if (!declaration || declaration.id.type !== "Identifier" || seenExports.has(declaration.id.name)) return;
|
|
41
|
-
const exportName = declaration.id.name;
|
|
29
|
+
ExportNamedDeclaration(node) {
|
|
30
|
+
const declaration = node.declaration;
|
|
31
|
+
if (declaration?.type === "VariableDeclaration") {
|
|
32
|
+
const declarator = declaration.declarations[0];
|
|
33
|
+
if (!declarator || declarator.id.type !== "Identifier" || !declarator.init || seenExports.has(declarator.id.name)) return;
|
|
34
|
+
const exportName = declarator.id.name;
|
|
42
35
|
seenExports.add(exportName);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
]))])));
|
|
50
|
-
} else if (path.node.declaration?.type === "FunctionDeclaration") {
|
|
51
|
-
const declaration = path.node.declaration;
|
|
52
|
-
if (!declaration || declaration.id?.type !== "Identifier" || seenExports.has(declaration.id.name)) return;
|
|
53
|
-
const exportName = declaration.id.name;
|
|
36
|
+
s.overwrite(node.start, declarator.init.start, `const __wrap_${exportName} = `);
|
|
37
|
+
s.appendRight(declarator.init.end, `; export const ${exportName} = __runtime.createIsland(__wrap_${exportName}, "${exportName}", __assets)`);
|
|
38
|
+
} else if (declaration?.type === "FunctionDeclaration") {
|
|
39
|
+
const fnId = declaration.id;
|
|
40
|
+
if (!fnId || fnId.type !== "Identifier" || seenExports.has(fnId.name)) return;
|
|
41
|
+
const exportName = fnId.name;
|
|
54
42
|
seenExports.add(exportName);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
islandIdentifier,
|
|
59
|
-
stringLiteral(exportName),
|
|
60
|
-
identifier("__assets")
|
|
61
|
-
]))])));
|
|
43
|
+
s.remove(node.start, declaration.start);
|
|
44
|
+
s.overwrite(fnId.start, fnId.end, `__wrap_${exportName}`);
|
|
45
|
+
s.appendRight(declaration.end, `; export const ${exportName} = __runtime.createIsland(__wrap_${exportName}, "${exportName}", __assets)`);
|
|
62
46
|
}
|
|
63
47
|
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
code: result.code,
|
|
68
|
-
map: result.map
|
|
69
|
-
};
|
|
70
|
-
}
|
|
48
|
+
}).visit(program);
|
|
49
|
+
})
|
|
71
50
|
}
|
|
72
51
|
}, {
|
|
73
52
|
name: "yamf:islands:raw-import",
|
|
74
53
|
transform: {
|
|
75
54
|
order: "post",
|
|
76
|
-
handler(
|
|
77
|
-
if (
|
|
78
|
-
}
|
|
55
|
+
handler: withMagicString(function(s) {
|
|
56
|
+
if (s.original.includes("__island_raw_import__")) s.replaceAll("__island_raw_import__", "import");
|
|
57
|
+
})
|
|
79
58
|
}
|
|
80
59
|
}];
|
|
81
60
|
};
|