@janit/fu 0.0.4 → 0.2.1
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 +56 -21
- package/dist/app.d.ts +0 -2
- package/dist/app.js +0 -4
- package/dist/app.js.map +1 -1
- package/dist/build.d.ts +0 -2
- package/dist/build.js +10 -85
- package/dist/build.js.map +1 -1
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +7 -1
- package/dist/client.js +18 -7
- package/dist/client.js.map +1 -1
- package/dist/dev.d.ts +8 -0
- package/dist/dev.js +53 -63
- package/dist/dev.js.map +1 -1
- package/dist/driver.d.ts +66 -0
- package/dist/driver.js +181 -0
- package/dist/driver.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +10 -5
- package/dist/errors.js.map +1 -1
- package/dist/hmr-runtime.js +24 -20
- package/dist/plugins.d.ts +7 -24
- package/dist/plugins.js +18 -58
- package/dist/plugins.js.map +1 -1
- package/dist/render.d.ts +10 -5
- package/dist/render.js +13 -11
- package/dist/render.js.map +1 -1
- package/dist/router.d.ts +17 -0
- package/dist/router.js +72 -12
- package/dist/router.js.map +1 -1
- package/package.json +6 -6
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,4CAA4C;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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"}
|
package/dist/driver.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { createNitro } from "nitro/builder";
|
|
2
|
+
import type { InputOptions } from "rolldown";
|
|
3
|
+
import type { Assets } from "./types.js";
|
|
4
|
+
/** Absolute paths of the runtime modules the generated code imports. */
|
|
5
|
+
export declare const runtime: {
|
|
6
|
+
client: string;
|
|
7
|
+
render: string;
|
|
8
|
+
hmr: string;
|
|
9
|
+
};
|
|
10
|
+
/** Everything a driver needs to know about a project, found once up front. */
|
|
11
|
+
export interface Project {
|
|
12
|
+
root: string;
|
|
13
|
+
/** Root-relative, e.g. "/routes/blog/[slug].tsx". */
|
|
14
|
+
routeFiles: string[];
|
|
15
|
+
islandFiles: string[];
|
|
16
|
+
/** Absolute path to `app.ts`, if the project has one. */
|
|
17
|
+
appPath: string | null;
|
|
18
|
+
/** Absolute path to `routes/_app.tsx`, if the project has one. */
|
|
19
|
+
shellPath: string | null;
|
|
20
|
+
/** Absolute path to `routes/_error.tsx`, if the project has one. */
|
|
21
|
+
errorPath: string | null;
|
|
22
|
+
/** Client bundle output, served as public assets. */
|
|
23
|
+
clientDir: string;
|
|
24
|
+
/** Generated server entry. */
|
|
25
|
+
genDir: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function scanProject(root: string): Project;
|
|
28
|
+
/**
|
|
29
|
+
* Recursively list source files under `<root>/<sub>`, as root-relative
|
|
30
|
+
* "/sub/a/b.tsx". Underscore-prefixed files are skipped: they are framework
|
|
31
|
+
* files (`routes/_app.tsx`), not routes.
|
|
32
|
+
*/
|
|
33
|
+
export declare function walk(root: string, sub: string): string[];
|
|
34
|
+
/** Absolute path to an optional project file, or null when absent. */
|
|
35
|
+
export declare function optional(root: string, ...names: string[]): string | null;
|
|
36
|
+
/** Recreate `dir` empty. */
|
|
37
|
+
export declare function emptyDir(dir: string): void;
|
|
38
|
+
/** Rolldown input for the client bundle. */
|
|
39
|
+
export declare function clientInput(project: Project, sheets: Map<string, string>, hmr?: boolean): InputOptions;
|
|
40
|
+
/**
|
|
41
|
+
* Nitro options both drivers share. `serverDir` is the generated dir, never the
|
|
42
|
+
* project root, or nitro claims `routes/` as its own server routes and shadows
|
|
43
|
+
* the catch-all. Islands are imported on the server too, so SSR needs the same
|
|
44
|
+
* CSS and JSX handling as the client.
|
|
45
|
+
*/
|
|
46
|
+
export declare function nitroOptions(project: Project, ssrEntry: string): Parameters<typeof createNitro>[0];
|
|
47
|
+
/** Concatenate collected stylesheets into one file; hashed unless a name is given. */
|
|
48
|
+
export declare function writeSheets(dir: string, sheets: Map<string, string>, name?: string): string | null;
|
|
49
|
+
/** The client entry: hydrate every island the page carries. */
|
|
50
|
+
export declare function bootModule(project: Pick<Project, "root" | "islandFiles">): string;
|
|
51
|
+
/**
|
|
52
|
+
* The server entry: the route manifest, the optional app, shell and error
|
|
53
|
+
* page, and the handler wired to nitro.
|
|
54
|
+
*
|
|
55
|
+
* Nitro invokes the handler with an H3Event, not a Request. The event exposes
|
|
56
|
+
* `url`/`headers` directly — which is why routing worked long before anyone
|
|
57
|
+
* read a body — but has no json()/text()/formData(). The real Request is
|
|
58
|
+
* `event.req`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function ssrModule(project: Pick<Project, "root" | "routeFiles" | "appPath" | "shellPath" | "errorPath">, assets: Assets): string;
|
|
61
|
+
/**
|
|
62
|
+
* Write the generated server entry and return its path. It has to be a real
|
|
63
|
+
* file: nitro path-resolves `handlers[].handler`, so a virtual id would not
|
|
64
|
+
* survive its routing codegen.
|
|
65
|
+
*/
|
|
66
|
+
export declare function writeSsrEntry(project: Project, assets: Assets): string;
|
package/dist/driver.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { css, hash, jsx, selfAlias, virtual } from "./plugins.js";
|
|
4
|
+
/**
|
|
5
|
+
* Directory holding the framework's own runtime modules, whose paths are handed
|
|
6
|
+
* to rolldown. `import.meta.dirname` is undefined when this module is loaded
|
|
7
|
+
* from a remote URL, and a bundler cannot fetch `https:` modules anyway — so
|
|
8
|
+
* fail with the reason rather than a TypeError three frames later.
|
|
9
|
+
*/
|
|
10
|
+
const HERE = import.meta.dirname ?? remoteFrameworkError();
|
|
11
|
+
/** `.ts` when running from source (this repo), `.js` from the compiled npm build. */
|
|
12
|
+
const EXT = import.meta.url.endsWith(".js") ? ".js" : ".ts";
|
|
13
|
+
function remoteFrameworkError() {
|
|
14
|
+
throw new Error("fu: the framework is loaded from a remote URL (" + import.meta.url + "), " +
|
|
15
|
+
"so its runtime modules cannot be handed to the bundler. Install it " +
|
|
16
|
+
"instead — `npm:@janit/fu` in a Deno import map, or `npm i @janit/fu` — " +
|
|
17
|
+
"so it resolves to a real directory.");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The framework's own package name, read from the package.json above the
|
|
21
|
+
* runtime modules: this repo's at the root, or the installed package's. Absent
|
|
22
|
+
* when neither exists, in which case apps must alias it themselves.
|
|
23
|
+
*/
|
|
24
|
+
const PACKAGE_NAME = (() => {
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(fs.readFileSync(path.join(HERE, "..", "package.json"), "utf8")).name ?? null;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
/** Plugins every bundle of app code needs, client and server alike. */
|
|
33
|
+
function shared(sheets, jsxOpts) {
|
|
34
|
+
return [
|
|
35
|
+
...(PACKAGE_NAME ? [selfAlias(PACKAGE_NAME, HERE, EXT)] : []),
|
|
36
|
+
css(sheets),
|
|
37
|
+
jsx(jsxOpts),
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
/** Absolute paths of the runtime modules the generated code imports. */
|
|
41
|
+
export const runtime = {
|
|
42
|
+
client: path.join(HERE, `client${EXT}`),
|
|
43
|
+
render: path.join(HERE, `render${EXT}`),
|
|
44
|
+
hmr: path.join(HERE, "hmr-runtime.js"),
|
|
45
|
+
};
|
|
46
|
+
export function scanProject(root) {
|
|
47
|
+
root = path.resolve(root);
|
|
48
|
+
return {
|
|
49
|
+
root,
|
|
50
|
+
routeFiles: walk(root, "routes"),
|
|
51
|
+
islandFiles: walk(root, "islands"),
|
|
52
|
+
appPath: optional(root, "app.ts", "app.tsx"),
|
|
53
|
+
shellPath: optional(root, "routes/_app.tsx"),
|
|
54
|
+
errorPath: optional(root, "routes/_error.tsx"),
|
|
55
|
+
clientDir: path.join(root, "dist/client"),
|
|
56
|
+
genDir: path.join(root, ".fu"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Recursively list source files under `<root>/<sub>`, as root-relative
|
|
61
|
+
* "/sub/a/b.tsx". Underscore-prefixed files are skipped: they are framework
|
|
62
|
+
* files (`routes/_app.tsx`), not routes.
|
|
63
|
+
*/
|
|
64
|
+
export function walk(root, sub) {
|
|
65
|
+
const out = [];
|
|
66
|
+
const visit = (dir) => {
|
|
67
|
+
if (!fs.existsSync(dir))
|
|
68
|
+
return;
|
|
69
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
70
|
+
const f = path.join(dir, e.name);
|
|
71
|
+
if (e.isDirectory())
|
|
72
|
+
visit(f);
|
|
73
|
+
else if (/\.[tj]sx?$/.test(e.name) && !e.name.startsWith("_")) {
|
|
74
|
+
out.push("/" + path.relative(root, f).split(path.sep).join("/"));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
visit(path.join(root, sub));
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
/** Absolute path to an optional project file, or null when absent. */
|
|
82
|
+
export function optional(root, ...names) {
|
|
83
|
+
for (const n of names) {
|
|
84
|
+
const p = path.resolve(root, n);
|
|
85
|
+
if (fs.existsSync(p))
|
|
86
|
+
return p;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** Recreate `dir` empty. */
|
|
91
|
+
export function emptyDir(dir) {
|
|
92
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
93
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
/** Rolldown input for the client bundle. */
|
|
96
|
+
export function clientInput(project, sheets, hmr = false) {
|
|
97
|
+
return {
|
|
98
|
+
input: { boot: "fu:boot" },
|
|
99
|
+
plugins: [virtual({ "fu:boot": bootModule(project) }), ...shared(sheets, { hmr })],
|
|
100
|
+
platform: "browser",
|
|
101
|
+
// rolldown types modules by extension and refuses to bundle CSS; css()
|
|
102
|
+
// has already replaced their contents with JS.
|
|
103
|
+
moduleTypes: { ".css": "js" },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Nitro options both drivers share. `serverDir` is the generated dir, never the
|
|
108
|
+
* project root, or nitro claims `routes/` as its own server routes and shadows
|
|
109
|
+
* the catch-all. Islands are imported on the server too, so SSR needs the same
|
|
110
|
+
* CSS and JSX handling as the client.
|
|
111
|
+
*/
|
|
112
|
+
export function nitroOptions(project, ssrEntry) {
|
|
113
|
+
return {
|
|
114
|
+
rootDir: project.root,
|
|
115
|
+
serverDir: project.genDir,
|
|
116
|
+
scanDirs: [],
|
|
117
|
+
publicAssets: [{ dir: project.clientDir, baseURL: "/" }],
|
|
118
|
+
handlers: [{ route: "/**", handler: ssrEntry, format: "web", lazy: false }],
|
|
119
|
+
rollupConfig: {
|
|
120
|
+
plugins: shared(new Map(), { stampIslands: true }),
|
|
121
|
+
moduleTypes: { ".css": "js" },
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Concatenate collected stylesheets into one file; hashed unless a name is given. */
|
|
126
|
+
export function writeSheets(dir, sheets, name) {
|
|
127
|
+
if (sheets.size === 0)
|
|
128
|
+
return null;
|
|
129
|
+
const merged = [...sheets.values()].join("\n");
|
|
130
|
+
const file = name ?? `style-${hash(merged)}.css`;
|
|
131
|
+
fs.writeFileSync(path.join(dir, file), merged);
|
|
132
|
+
return file;
|
|
133
|
+
}
|
|
134
|
+
const lazyImport = (root, file) => `${JSON.stringify(file)}: () => import(${JSON.stringify(path.resolve(root, "." + file))})`;
|
|
135
|
+
/** The client entry: hydrate every island the page carries. */
|
|
136
|
+
export function bootModule(project) {
|
|
137
|
+
const manifest = project.islandFiles.map((f) => " " + lazyImport(project.root, f)).join(",\n");
|
|
138
|
+
return `import { hydrateIslands } from ${JSON.stringify(runtime.client)};\n` +
|
|
139
|
+
`hydrateIslands({\n${manifest}\n});\n`;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The server entry: the route manifest, the optional app, shell and error
|
|
143
|
+
* page, and the handler wired to nitro.
|
|
144
|
+
*
|
|
145
|
+
* Nitro invokes the handler with an H3Event, not a Request. The event exposes
|
|
146
|
+
* `url`/`headers` directly — which is why routing worked long before anyone
|
|
147
|
+
* read a body — but has no json()/text()/formData(). The real Request is
|
|
148
|
+
* `event.req`.
|
|
149
|
+
*/
|
|
150
|
+
export function ssrModule(project, assets) {
|
|
151
|
+
const optionalImports = [
|
|
152
|
+
["app", project.appPath],
|
|
153
|
+
["Shell", project.shellPath],
|
|
154
|
+
["ErrorPage", project.errorPath],
|
|
155
|
+
];
|
|
156
|
+
const present = optionalImports.filter(([, file]) => file);
|
|
157
|
+
return [
|
|
158
|
+
`import { createHandler } from ${JSON.stringify(runtime.render)};`,
|
|
159
|
+
...present.map(([name, file]) => `import ${name} from ${JSON.stringify(file)};`),
|
|
160
|
+
`const manifest = {`,
|
|
161
|
+
project.routeFiles.map((f) => " " + lazyImport(project.root, f)).join(",\n"),
|
|
162
|
+
`};`,
|
|
163
|
+
`const assets = ${JSON.stringify(assets)};`,
|
|
164
|
+
`const handler = createHandler({ manifest, assets${present.map(([n]) => `, ${n}`).join("")} });`,
|
|
165
|
+
`const toRequest = (input) => input instanceof Request ? input : (input?.req ?? input);`,
|
|
166
|
+
`export default (input) => handler(toRequest(input));`,
|
|
167
|
+
``,
|
|
168
|
+
].join("\n");
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Write the generated server entry and return its path. It has to be a real
|
|
172
|
+
* file: nitro path-resolves `handlers[].handler`, so a virtual id would not
|
|
173
|
+
* survive its routing codegen.
|
|
174
|
+
*/
|
|
175
|
+
export function writeSsrEntry(project, assets) {
|
|
176
|
+
emptyDir(project.genDir);
|
|
177
|
+
const file = path.join(project.genDir, "ssr.ts");
|
|
178
|
+
fs.writeFileSync(file, ssrModule(project, assets));
|
|
179
|
+
return file;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ import type { RouteError } from "./types.js";
|
|
|
5
5
|
* ```ts
|
|
6
6
|
* if (!session) throw new HttpError(403, "Not your todo");
|
|
7
7
|
* ```
|
|
8
|
+
*
|
|
9
|
+
* In middleware, prefer returning the response: a throw there unwinds past the
|
|
10
|
+
* middleware that would have set headers on it.
|
|
8
11
|
*/
|
|
9
12
|
export declare class HttpError extends Error {
|
|
10
13
|
readonly status: number;
|
|
@@ -16,5 +19,8 @@ export declare function statusText(status: number): string;
|
|
|
16
19
|
*
|
|
17
20
|
* A `status` property is honoured wherever it appears, so errors from other
|
|
18
21
|
* libraries (h3, fetch wrappers) map sensibly instead of collapsing to 500.
|
|
22
|
+
* Their message is only carried through below 500: a foreign 5xx can say
|
|
23
|
+
* anything — node:sqlite names the database path, a driver quotes the SQL —
|
|
24
|
+
* and `message` is the one field the error page renders.
|
|
19
25
|
*/
|
|
20
26
|
export declare function toRouteError(err: unknown): RouteError;
|
package/dist/errors.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* ```ts
|
|
5
5
|
* if (!session) throw new HttpError(403, "Not your todo");
|
|
6
6
|
* ```
|
|
7
|
+
*
|
|
8
|
+
* In middleware, prefer returning the response: a throw there unwinds past the
|
|
9
|
+
* middleware that would have set headers on it.
|
|
7
10
|
*/
|
|
8
11
|
export class HttpError extends Error {
|
|
9
12
|
status;
|
|
@@ -35,6 +38,9 @@ export function statusText(status) {
|
|
|
35
38
|
*
|
|
36
39
|
* A `status` property is honoured wherever it appears, so errors from other
|
|
37
40
|
* libraries (h3, fetch wrappers) map sensibly instead of collapsing to 500.
|
|
41
|
+
* Their message is only carried through below 500: a foreign 5xx can say
|
|
42
|
+
* anything — node:sqlite names the database path, a driver quotes the SQL —
|
|
43
|
+
* and `message` is the one field the error page renders.
|
|
38
44
|
*/
|
|
39
45
|
export function toRouteError(err) {
|
|
40
46
|
if (err instanceof HttpError) {
|
|
@@ -43,11 +49,10 @@ export function toRouteError(err) {
|
|
|
43
49
|
const status = err?.status;
|
|
44
50
|
if (typeof status === "number" && status >= 400 && status <= 599) {
|
|
45
51
|
const message = err.message;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
52
|
+
const safe = status < 500 && typeof message === "string" && message
|
|
53
|
+
? message
|
|
54
|
+
: statusText(status);
|
|
55
|
+
return { status, message: safe, cause: err };
|
|
51
56
|
}
|
|
52
57
|
return { status: 500, message: statusText(500), cause: err };
|
|
53
58
|
}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,MAAM,CAAS;IAExB,YAAY,MAAc,EAAE,OAAgB;QAC1C,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,IAAI,GAA2B;IACnC,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,qBAAqB;CAC3B,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAClE,CAAC;IACD,MAAM,MAAM,GAAI,GAAmC,EAAE,MAAM,CAAC;IAC5D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QACjE,MAAM,OAAO,GAAI,GAA6B,CAAC,OAAO,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,GAAG,GAAG,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO;YACjE,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC/D,CAAC"}
|
package/dist/hmr-runtime.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
// Fresh Urquell HMR client runtime. Rolldown's default runtime registers new module
|
|
3
2
|
// factories but never *applies* them; this one does the apply walk:
|
|
4
3
|
// swap the module, re-run its factory, then fire its accept callbacks.
|
|
4
|
+
//
|
|
5
|
+
// Not type-checked: `DevRuntime` is injected by rolldown when this source is
|
|
6
|
+
// inlined via `devMode.implement`, so it does not exist as a module.
|
|
5
7
|
|
|
6
8
|
/** @type {any} */
|
|
7
|
-
|
|
9
|
+
const BaseDevRuntime = DevRuntime;
|
|
8
10
|
|
|
9
11
|
class ModuleHotContext {
|
|
10
12
|
/** @type {{ deps: string[], fn: (mod: any) => void }[]} */
|
|
@@ -17,11 +19,11 @@ class ModuleHotContext {
|
|
|
17
19
|
if (args.length === 1) {
|
|
18
20
|
this.acceptCallbacks.push({ deps: [this.moduleId], fn: args[0] });
|
|
19
21
|
} else if (args.length !== 0) {
|
|
20
|
-
throw new Error(
|
|
22
|
+
throw new Error("Invalid arguments for `import.meta.hot.accept`");
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
invalidate() {
|
|
24
|
-
socket.send(JSON.stringify({ type:
|
|
26
|
+
socket.send(JSON.stringify({ type: "hmr:invalidate", moduleId: this.moduleId }));
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -36,8 +38,8 @@ class FuDevRuntime extends BaseDevRuntime {
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
const clientId = crypto.randomUUID();
|
|
39
|
-
const addr = new URL(
|
|
40
|
-
addr.searchParams.set(
|
|
41
|
+
const addr = new URL("ws://$ADDR");
|
|
42
|
+
addr.searchParams.set("clientId", clientId);
|
|
41
43
|
const socket = new WebSocket(addr);
|
|
42
44
|
|
|
43
45
|
/** @type {any} */
|
|
@@ -54,21 +56,21 @@ async function applyPatch(url, allChangedIds) {
|
|
|
54
56
|
const rt = globalThis.__rolldown_runtime__;
|
|
55
57
|
// Stylesheets are swapped via the <link>, so they never need to accept and
|
|
56
58
|
// must not drag the page into a full reload.
|
|
57
|
-
const changedIds = (allChangedIds || []).filter((id) => !id.endsWith(
|
|
59
|
+
const changedIds = (allChangedIds || []).filter((id) => !id.endsWith(".css"));
|
|
58
60
|
const selfAccepting = changedIds.filter((id) => {
|
|
59
61
|
const ctx = rt.moduleHotContexts.get(id);
|
|
60
62
|
return ctx && ctx.acceptCallbacks.length > 0;
|
|
61
63
|
});
|
|
62
64
|
try {
|
|
63
|
-
await import(url + (url.includes(
|
|
65
|
+
await import(url + (url.includes("?") ? "&" : "?") + "t=" + Date.now());
|
|
64
66
|
} catch (err) {
|
|
65
|
-
console.error(
|
|
67
|
+
console.error("[hmr] failed to load patch", url, err);
|
|
66
68
|
location.reload();
|
|
67
69
|
return;
|
|
68
70
|
}
|
|
69
71
|
if (!changedIds || changedIds.length === 0) return;
|
|
70
72
|
if (selfAccepting.length !== changedIds.length) {
|
|
71
|
-
console.debug(
|
|
73
|
+
console.debug("[hmr] some modules did not accept; reloading");
|
|
72
74
|
location.reload();
|
|
73
75
|
return;
|
|
74
76
|
}
|
|
@@ -79,7 +81,7 @@ async function applyPatch(url, allChangedIds) {
|
|
|
79
81
|
const ctx = rt.moduleHotContexts.get(id);
|
|
80
82
|
for (const { fn } of ctx ? ctx.acceptCallbacks : []) fn(exports);
|
|
81
83
|
}
|
|
82
|
-
console.debug(
|
|
84
|
+
console.debug("[hmr] applied", selfAccepting.join(", "));
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
/**
|
|
@@ -90,23 +92,25 @@ async function applyPatch(url, allChangedIds) {
|
|
|
90
92
|
function swapStylesheet(href) {
|
|
91
93
|
const links = [...document.querySelectorAll('link[rel="stylesheet"]')];
|
|
92
94
|
const old = links[links.length - 1];
|
|
93
|
-
const next = document.createElement(
|
|
94
|
-
next.rel =
|
|
95
|
+
const next = document.createElement("link");
|
|
96
|
+
next.rel = "stylesheet";
|
|
95
97
|
next.href = href;
|
|
96
|
-
next.onload = () => {
|
|
98
|
+
next.onload = () => {
|
|
99
|
+
if (old && old !== next) old.remove();
|
|
100
|
+
};
|
|
97
101
|
(old ? old.parentNode : document.head).insertBefore(next, old ? old.nextSibling : null);
|
|
98
|
-
console.debug(
|
|
102
|
+
console.debug("[hmr] css swapped ->", href);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
socket.onmessage = function (event) {
|
|
102
106
|
const data = JSON.parse(event.data);
|
|
103
|
-
if (data.type ===
|
|
104
|
-
console.debug(
|
|
105
|
-
} else if (data.type ===
|
|
107
|
+
if (data.type === "connected") {
|
|
108
|
+
console.debug("[hmr] connected");
|
|
109
|
+
} else if (data.type === "hmr:update") {
|
|
106
110
|
applyPatch(data.url, data.changedIds);
|
|
107
|
-
} else if (data.type ===
|
|
111
|
+
} else if (data.type === "fu:css") {
|
|
108
112
|
swapStylesheet(data.href);
|
|
109
|
-
} else if (data.type ===
|
|
113
|
+
} else if (data.type === "hmr:reload") {
|
|
110
114
|
location.reload();
|
|
111
115
|
}
|
|
112
116
|
};
|
package/dist/plugins.d.ts
CHANGED
|
@@ -39,30 +39,13 @@ export declare function stampIslands(js: string, key: string, id: string): {
|
|
|
39
39
|
* module by extension and refuses to bundle it.
|
|
40
40
|
*/
|
|
41
41
|
export declare function css(collected: Map<string, string>): Plugin;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a bare package name (and its subpaths) to files under `dir`, so an
|
|
44
|
+
* app importing the framework by name gets the copy the driver is running
|
|
45
|
+
* from. Node resolution would otherwise pick whatever `package.json` claims —
|
|
46
|
+
* in this repo, a stale compiled `dist/` — and bundle a second framework.
|
|
47
|
+
*/
|
|
48
|
+
export declare function selfAlias(name: string, dir: string, ext: string): Plugin;
|
|
42
49
|
/** Serve generated modules by exact id. */
|
|
43
50
|
export declare function virtual(mods: Record<string, string>): Plugin;
|
|
44
51
|
export declare function hash(s: string): string;
|
|
45
|
-
/**
|
|
46
|
-
* Recursively list source files under `dir`, as root-relative "/a/b.tsx".
|
|
47
|
-
* Underscore-prefixed files are skipped: they are framework files
|
|
48
|
-
* (`routes/_app.tsx`), not routes.
|
|
49
|
-
*/
|
|
50
|
-
export declare function walk(root: string, dir: string, out?: string[]): string[];
|
|
51
|
-
/** Absolute path to an optional project file, or null when absent. */
|
|
52
|
-
export declare function optional(root: string, ...names: string[]): string | null;
|
|
53
|
-
/** Generated module bodies both drivers need. */
|
|
54
|
-
export declare function bootModule(clientPath: string, islandFiles: string[], root: string): string;
|
|
55
|
-
export interface SsrModuleOptions {
|
|
56
|
-
renderPath: string;
|
|
57
|
-
routeFiles: string[];
|
|
58
|
-
root: string;
|
|
59
|
-
/** Serialized Assets literal. */
|
|
60
|
-
assets: string;
|
|
61
|
-
/** Absolute path to the project's `app.ts`, if it has one. */
|
|
62
|
-
appPath?: string | null;
|
|
63
|
-
/** Absolute path to the project's `routes/_app.tsx`, if it has one. */
|
|
64
|
-
shellPath?: string | null;
|
|
65
|
-
/** Absolute path to the project's `routes/_error.tsx`, if it has one. */
|
|
66
|
-
errorPath?: string | null;
|
|
67
|
-
}
|
|
68
|
-
export declare function ssrModule(o: SsrModuleOptions): string;
|
package/dist/plugins.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { parseSync, transformSync } from "rolldown/experimental";
|
|
2
2
|
import { transform as lightning } from "lightningcss";
|
|
3
|
-
import * as fs from "node:fs";
|
|
4
|
-
import * as path from "node:path";
|
|
5
3
|
/** Files a source transform must never touch. */
|
|
6
4
|
function isInternal(id) {
|
|
7
5
|
return id.includes("node_modules") ||
|
|
@@ -173,6 +171,24 @@ export function css(collected) {
|
|
|
173
171
|
},
|
|
174
172
|
};
|
|
175
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Resolve a bare package name (and its subpaths) to files under `dir`, so an
|
|
176
|
+
* app importing the framework by name gets the copy the driver is running
|
|
177
|
+
* from. Node resolution would otherwise pick whatever `package.json` claims —
|
|
178
|
+
* in this repo, a stale compiled `dist/` — and bundle a second framework.
|
|
179
|
+
*/
|
|
180
|
+
export function selfAlias(name, dir, ext) {
|
|
181
|
+
return {
|
|
182
|
+
name: "fu:self-alias",
|
|
183
|
+
resolveId(id) {
|
|
184
|
+
if (id === name)
|
|
185
|
+
return `${dir}/mod${ext}`;
|
|
186
|
+
if (id.startsWith(name + "/"))
|
|
187
|
+
return `${dir}/${id.slice(name.length + 1)}${ext}`;
|
|
188
|
+
return null;
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
176
192
|
/** Serve generated modules by exact id. */
|
|
177
193
|
export function virtual(mods) {
|
|
178
194
|
return {
|
|
@@ -187,60 +203,4 @@ export function hash(s) {
|
|
|
187
203
|
h = (Math.imul(h, 31) + s.charCodeAt(i)) >>> 0;
|
|
188
204
|
return h.toString(36);
|
|
189
205
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Recursively list source files under `dir`, as root-relative "/a/b.tsx".
|
|
192
|
-
* Underscore-prefixed files are skipped: they are framework files
|
|
193
|
-
* (`routes/_app.tsx`), not routes.
|
|
194
|
-
*/
|
|
195
|
-
export function walk(root, dir, out = []) {
|
|
196
|
-
if (!fs.existsSync(dir))
|
|
197
|
-
return out;
|
|
198
|
-
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
199
|
-
const f = path.join(dir, e.name);
|
|
200
|
-
if (e.isDirectory())
|
|
201
|
-
walk(root, f, out);
|
|
202
|
-
else if (/\.[tj]sx?$/.test(e.name) && !e.name.startsWith("_")) {
|
|
203
|
-
out.push("/" + path.relative(root, f).split(path.sep).join("/"));
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return out;
|
|
207
|
-
}
|
|
208
|
-
/** Absolute path to an optional project file, or null when absent. */
|
|
209
|
-
export function optional(root, ...names) {
|
|
210
|
-
for (const n of names) {
|
|
211
|
-
const p = path.resolve(root, n);
|
|
212
|
-
if (fs.existsSync(p))
|
|
213
|
-
return p;
|
|
214
|
-
}
|
|
215
|
-
return null;
|
|
216
|
-
}
|
|
217
|
-
/** Generated module bodies both drivers need. */
|
|
218
|
-
export function bootModule(clientPath, islandFiles, root) {
|
|
219
|
-
return `
|
|
220
|
-
import { hydrateIslands } from ${JSON.stringify(clientPath)};
|
|
221
|
-
hydrateIslands({
|
|
222
|
-
${islandFiles.map((f) => ` ${JSON.stringify(f)}: () => import(${JSON.stringify(path.resolve(root, "." + f))})`).join(",\n")}
|
|
223
|
-
});
|
|
224
|
-
`;
|
|
225
|
-
}
|
|
226
|
-
export function ssrModule(o) {
|
|
227
|
-
const lines = [
|
|
228
|
-
`import { createHandler } from ${JSON.stringify(o.renderPath)};`,
|
|
229
|
-
];
|
|
230
|
-
if (o.appPath)
|
|
231
|
-
lines.push(`import app from ${JSON.stringify(o.appPath)};`);
|
|
232
|
-
if (o.shellPath)
|
|
233
|
-
lines.push(`import Shell from ${JSON.stringify(o.shellPath)};`);
|
|
234
|
-
if (o.errorPath)
|
|
235
|
-
lines.push(`import ErrorPage from ${JSON.stringify(o.errorPath)};`);
|
|
236
|
-
lines.push(`const routes = {`, o.routeFiles
|
|
237
|
-
.map((f) => ` ${JSON.stringify(f)}: () => import(${JSON.stringify(path.resolve(o.root, "." + f))})`)
|
|
238
|
-
.join(",\n"), `};`, `const assets = ${o.assets};`, `const handler = createHandler({`, ` manifest: routes,`, ` assets,`, o.appPath ? ` app,` : ` app: undefined,`, o.shellPath ? ` Shell,` : ` Shell: undefined,`, o.errorPath ? ` ErrorPage,` : ` ErrorPage: undefined,`, `});`,
|
|
239
|
-
// Nitro invokes the handler with an H3Event, not a Request. The event
|
|
240
|
-
// exposes `url`/`headers` directly — which is why routing worked long
|
|
241
|
-
// before anyone read a body — but has no json()/text()/formData(). The
|
|
242
|
-
// real Request is `event.req`.
|
|
243
|
-
`const toRequest = (input) => input instanceof Request ? input : (input?.req ?? input);`, `export default (input) => handler(toRequest(input));`, ``);
|
|
244
|
-
return lines.join("\n");
|
|
245
|
-
}
|
|
246
206
|
//# sourceMappingURL=plugins.js.map
|