@sigil-dev/grimoire 0.7.5 → 0.7.7
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/.grimoire/_routes.dom.js +8 -0
- package/.grimoire/_routes.hydrate.js +8 -0
- package/.grimoire/tsconfig.generated.json +11 -0
- package/.grimoire/types/ambient.d.ts +59 -0
- package/.grimoire/types/api/hello/$types.d.ts +50 -0
- package/.grimoire/types/api/items/$types.d.ts +50 -0
- package/.grimoire/types/echo/$types.d.ts +50 -0
- package/.grimoire/types/env-private.d.ts +5 -0
- package/.grimoire/types/env-public.d.ts +5 -0
- package/.grimoire/types/mixed/$types.d.ts +50 -0
- package/.grimoire/types/params/[docId]/$types.d.ts +52 -0
- package/.grimoire/types/reject/$types.d.ts +50 -0
- package/index.ts +21 -20
- package/package.json +13 -7
- package/preload.js +3 -0
- package/public/__grimoire__/hydrate.js +585 -0
- package/public/__grimoire__/index.js +490 -0
- package/server.ts +13 -13
- package/src/client/head.ts +29 -0
- package/src/client/router.ts +254 -40
- package/src/dev/compile-module.ts +173 -0
- package/src/dev/effect-registry.ts +23 -0
- package/src/dev/graph.ts +114 -0
- package/src/dev/hmr-client.ts +158 -0
- package/src/dev/hmr-server.ts +187 -0
- package/src/dev/loader.ts +47 -0
- package/src/dev/paths.ts +14 -0
- package/src/dev/runtime-bundle.ts +49 -0
- package/src/dev/watcher.ts +44 -0
- package/src/env/index.ts +25 -0
- package/src/env/plugin.ts +13 -0
- package/src/env/private.ts +5 -0
- package/src/env/public.ts +7 -0
- package/src/env/typegen.ts +51 -0
- package/src/integrations/vite.ts +1 -0
- package/src/rendering/head.ts +22 -2
- package/src/rendering/hydrate.ts +111 -18
- package/src/rendering/index.ts +263 -153
- package/src/rendering/ssrPlugin.ts +59 -39
- package/src/routing/manifest-gen.ts +18 -2
- package/src/routing/router.ts +94 -83
- package/src/routing/scanner.ts +26 -14
- package/src/routing/transform-routes.ts +68 -68
- package/src/server/build.ts +225 -76
- package/src/server/coordinator.ts +9 -0
- package/src/server/hooks.ts +24 -3
- package/src/server/index.ts +388 -104
- package/src/typegen/index.ts +30 -14
- package/src/types.ts +12 -2
- package/test/middleware.test.ts +6 -4
- package/test/rendering.test.ts +510 -356
- package/test/routing.test.ts +36 -0
- package/test/scanning.test.ts +39 -8
- package/test/scope.test.ts +24 -8
- package/test/server.test.ts +27 -7
- package/test/streaming.test.ts +117 -98
- package/test/typegen.test.ts +52 -24
- package/tsconfig.json +1 -0
package/src/typegen/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
2
3
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
3
4
|
import type { RouteFile, RouteTree } from "../routing/scanner.ts";
|
|
4
5
|
|
|
@@ -11,6 +12,7 @@ export interface TypegenConfig {
|
|
|
11
12
|
export interface RouteGroup {
|
|
12
13
|
dir: string;
|
|
13
14
|
paramNames: string[];
|
|
15
|
+
restParamNames: string[];
|
|
14
16
|
page?: RouteFile;
|
|
15
17
|
pageServer?: RouteFile;
|
|
16
18
|
layout?: RouteFile;
|
|
@@ -45,12 +47,19 @@ export function groupByDirectory(tree: RouteTree): Map<string, RouteGroup> {
|
|
|
45
47
|
for (const file of files) {
|
|
46
48
|
const dir = dirname(file.filePath);
|
|
47
49
|
if (!groups.has(dir)) {
|
|
48
|
-
groups.set(dir, {
|
|
50
|
+
groups.set(dir, {
|
|
51
|
+
dir,
|
|
52
|
+
paramNames: file.paramNames,
|
|
53
|
+
restParamNames: file.restParamNames,
|
|
54
|
+
});
|
|
49
55
|
}
|
|
50
56
|
const g = groups.get(dir)!;
|
|
51
57
|
if (file.paramNames.length > g.paramNames.length) {
|
|
52
58
|
g.paramNames = file.paramNames;
|
|
53
59
|
}
|
|
60
|
+
if (file.restParamNames.length > g.restParamNames.length) {
|
|
61
|
+
g.restParamNames = file.restParamNames;
|
|
62
|
+
}
|
|
54
63
|
switch (file.type) {
|
|
55
64
|
case "page":
|
|
56
65
|
g.page = file;
|
|
@@ -82,9 +91,13 @@ export function toImportPath(from: string, to: string): string {
|
|
|
82
91
|
.replace(/\.tsx?$/, ".js");
|
|
83
92
|
}
|
|
84
93
|
|
|
85
|
-
export function buildParams(
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
export function buildParams(
|
|
95
|
+
paramNames: string[],
|
|
96
|
+
restParamNames: string[] = [],
|
|
97
|
+
): string {
|
|
98
|
+
const all = [...paramNames, ...restParamNames];
|
|
99
|
+
if (all.length === 0) return "{}";
|
|
100
|
+
const props = all.map((p) => ` ${p}: string;`).join("\n");
|
|
88
101
|
return `{\n${props}\n}`;
|
|
89
102
|
}
|
|
90
103
|
|
|
@@ -94,7 +107,7 @@ function generateTypesForGroup(group: RouteGroup, outFileDir: string): string {
|
|
|
94
107
|
"",
|
|
95
108
|
];
|
|
96
109
|
|
|
97
|
-
const paramsType = buildParams(group.paramNames);
|
|
110
|
+
const paramsType = buildParams(group.paramNames, group.restParamNames);
|
|
98
111
|
|
|
99
112
|
// --- Params ---
|
|
100
113
|
lines.push(`export type Params = ${paramsType};`, "");
|
|
@@ -217,7 +230,7 @@ function generateTypesForGroup(group: RouteGroup, outFileDir: string): string {
|
|
|
217
230
|
// --- +error.tsx ---
|
|
218
231
|
if (group.error) {
|
|
219
232
|
lines.push(
|
|
220
|
-
`export type ErrorProps = { status: number; message: string };`,
|
|
233
|
+
`export type ErrorProps = { status: number; message: string; error: unknown; route: string };`,
|
|
221
234
|
"",
|
|
222
235
|
);
|
|
223
236
|
}
|
|
@@ -276,7 +289,7 @@ function generateAmbient(): string {
|
|
|
276
289
|
" P extends Record<string, string> = Record<string, string>",
|
|
277
290
|
"> = { data: D; params: P; children?: unknown };",
|
|
278
291
|
"",
|
|
279
|
-
"type ErrorProps = { status: number; message: string };",
|
|
292
|
+
"type ErrorProps = { status: number; message: string; error: unknown; route: string };",
|
|
280
293
|
"",
|
|
281
294
|
"type UpgradeContext<",
|
|
282
295
|
" P extends Record<string, string> = Record<string, string>",
|
|
@@ -311,8 +324,9 @@ export async function generateTypes(
|
|
|
311
324
|
): Promise<void> {
|
|
312
325
|
const { projectRoot, outDir } = config;
|
|
313
326
|
|
|
314
|
-
|
|
315
|
-
|
|
327
|
+
// Skip rm — on Windows, rm+mkdir in quick succession can race and leave dirs
|
|
328
|
+
// in an unusable state. Stale type files are harmless; we overwrite what we need.
|
|
329
|
+
await mkdir(outDir, { recursive: true }).catch(() => {});
|
|
316
330
|
|
|
317
331
|
const groups = groupByDirectory(tree);
|
|
318
332
|
|
|
@@ -323,16 +337,18 @@ export async function generateTypes(
|
|
|
323
337
|
group.dir,
|
|
324
338
|
);
|
|
325
339
|
const outFileDir = join(outDir, routeRelDir);
|
|
326
|
-
|
|
340
|
+
// Use mkdirSync — async mkdir on Windows/Bun can report success before
|
|
341
|
+
// the directory is actually visible to subsequent fs calls
|
|
342
|
+
mkdirSync(outFileDir, { recursive: true });
|
|
327
343
|
|
|
328
344
|
const content = generateTypesForGroup(group, outFileDir);
|
|
329
|
-
|
|
345
|
+
writeFileSync(join(outFileDir, "$types.d.ts"), content, "utf-8");
|
|
330
346
|
}
|
|
331
347
|
|
|
332
|
-
|
|
348
|
+
writeFileSync(join(outDir, "ambient.d.ts"), generateAmbient(), "utf-8");
|
|
333
349
|
|
|
334
350
|
const grimoireDir = dirname(outDir);
|
|
335
|
-
|
|
351
|
+
writeFileSync(
|
|
336
352
|
join(grimoireDir, "tsconfig.generated.json"),
|
|
337
353
|
generateTsConfig(),
|
|
338
354
|
"utf-8",
|
package/src/types.ts
CHANGED
|
@@ -4,8 +4,14 @@ import type { RouteFile, RouteTree } from "./routing/scanner";
|
|
|
4
4
|
/// <reference types="bun-types">
|
|
5
5
|
declare global {
|
|
6
6
|
namespace App {
|
|
7
|
-
// augment in your own project
|
|
7
|
+
// augment in your own project via src/app.d.ts
|
|
8
8
|
interface Locals {}
|
|
9
|
+
interface Error {
|
|
10
|
+
message: string;
|
|
11
|
+
status?: number;
|
|
12
|
+
}
|
|
13
|
+
interface PageData {}
|
|
14
|
+
interface Platform {}
|
|
9
15
|
}
|
|
10
16
|
}
|
|
11
17
|
|
|
@@ -111,9 +117,9 @@ export interface GrimoirePlugin {
|
|
|
111
117
|
* Return WorkerEnv to inject env vars or set the worker name.
|
|
112
118
|
* ALL plugins are called and results are merged.
|
|
113
119
|
*/
|
|
114
|
-
// biome-ignore lint/suspicious/noConfusingVoidType: doesn't have to return a thing.
|
|
115
120
|
onWorkerSpawn?(
|
|
116
121
|
worker: WorkerDescriptor,
|
|
122
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: doesn't have to return a thing.
|
|
117
123
|
): WorkerEnv | void | Promise<WorkerEnv | void>;
|
|
118
124
|
|
|
119
125
|
/**
|
|
@@ -168,7 +174,11 @@ export interface GrimoireConfig {
|
|
|
168
174
|
plugins?: GrimoirePlugin[];
|
|
169
175
|
routes?: string; // glob, default 'src/routes/**';
|
|
170
176
|
dev?: boolean;
|
|
177
|
+
devEditor?: boolean;
|
|
171
178
|
vitePort?: number;
|
|
179
|
+
alias?: Record<string, string>; // e.g. { "$lib": "src/lib" } — resolved relative to cwd
|
|
180
|
+
cspNonce?: string; // CSP nonce for <script>/<style> tags
|
|
181
|
+
bundleStrategy?: "split" | "single"; // 'split' (default) or 'single' bundle
|
|
172
182
|
_skipBuild?: boolean;
|
|
173
183
|
}
|
|
174
184
|
|
package/test/middleware.test.ts
CHANGED
|
@@ -14,6 +14,8 @@ function fakeEvent(overrides?: Partial<RequestEvent>): RequestEvent {
|
|
|
14
14
|
set: () => {},
|
|
15
15
|
delete: () => {},
|
|
16
16
|
},
|
|
17
|
+
route: { id: "/" },
|
|
18
|
+
fetch: globalThis.fetch,
|
|
17
19
|
setHeaders: () => {},
|
|
18
20
|
...overrides,
|
|
19
21
|
};
|
|
@@ -71,12 +73,12 @@ describe("sequence()", () => {
|
|
|
71
73
|
|
|
72
74
|
test("can modify event.locals", async () => {
|
|
73
75
|
const a: Handle = async ({ event, resolve }) => {
|
|
74
|
-
event.locals.user = "alice";
|
|
76
|
+
(event.locals as any).user = "alice";
|
|
75
77
|
return resolve(event);
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
const b: Handle = async ({ event, resolve }) => {
|
|
79
|
-
event.locals.greet = `hello ${event.locals.user}`;
|
|
81
|
+
(event.locals as any).greet = `hello ${(event.locals as any).user}`;
|
|
80
82
|
return resolve(event);
|
|
81
83
|
};
|
|
82
84
|
|
|
@@ -89,8 +91,8 @@ describe("sequence()", () => {
|
|
|
89
91
|
},
|
|
90
92
|
});
|
|
91
93
|
|
|
92
|
-
expect(event.locals.user).toBe("alice");
|
|
93
|
-
expect(event.locals.greet).toBe("hello alice");
|
|
94
|
+
expect((event.locals as any).user).toBe("alice");
|
|
95
|
+
expect((event.locals as any).greet).toBe("hello alice");
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
test("can modify response", async () => {
|