@pracht/vite-plugin 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +20 -5
- package/dist/index.mjs +478 -451
- package/dist/pages-router.mjs +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
|
-
import { RenderMode } from "@pracht/core";
|
|
2
|
+
import { RenderMode, RenderMode as RenderMode$1 } from "@pracht/core";
|
|
3
3
|
|
|
4
|
-
//#region src/
|
|
4
|
+
//#region src/plugin-assets.d.ts
|
|
5
5
|
declare const PRACHT_CLIENT_MODULE_ID = "virtual:pracht/client";
|
|
6
6
|
declare const PRACHT_SERVER_MODULE_ID = "virtual:pracht/server";
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/plugin-adapter.d.ts
|
|
7
9
|
/**
|
|
8
10
|
* An adapter object that bridges pracht's platform-agnostic core to a specific
|
|
9
11
|
* deployment target. Built-in adapters are provided by `@pracht/adapter-node`,
|
|
@@ -36,7 +38,16 @@ interface PrachtAdapter {
|
|
|
36
38
|
* (e.g. Cloudflare workerd via `@cloudflare/vite-plugin`).
|
|
37
39
|
*/
|
|
38
40
|
ownsDevServer?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* If true, the adapter targets an edge runtime that cannot resolve
|
|
43
|
+
* dependencies from `node_modules` at runtime. The Vite plugin will set
|
|
44
|
+
* `ssr.noExternal = true` for SSR builds so all dependencies are bundled
|
|
45
|
+
* into the server output.
|
|
46
|
+
*/
|
|
47
|
+
edge?: boolean;
|
|
39
48
|
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/plugin-options.d.ts
|
|
40
51
|
interface PrachtPluginOptions {
|
|
41
52
|
appFile?: string;
|
|
42
53
|
routesDir?: string;
|
|
@@ -48,9 +59,10 @@ interface PrachtPluginOptions {
|
|
|
48
59
|
/** Enable file-system pages routing by pointing to the pages directory (e.g. "/src/pages"). */
|
|
49
60
|
pagesDir?: string;
|
|
50
61
|
/** Default render mode for pages when RENDER_MODE is not exported. Defaults to "ssr". */
|
|
51
|
-
pagesDefaultRender?: RenderMode;
|
|
62
|
+
pagesDefaultRender?: RenderMode$1;
|
|
52
63
|
}
|
|
53
|
-
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/plugin-codegen.d.ts
|
|
54
66
|
declare function createPrachtClientModuleSource(options?: PrachtPluginOptions, buildOptions?: {
|
|
55
67
|
root?: string;
|
|
56
68
|
}): string;
|
|
@@ -60,4 +72,7 @@ declare function createPrachtServerModuleSource(options?: PrachtPluginOptions, b
|
|
|
60
72
|
}): string;
|
|
61
73
|
declare function createPrachtRegistryModuleSource(options?: PrachtPluginOptions): string;
|
|
62
74
|
//#endregion
|
|
63
|
-
|
|
75
|
+
//#region src/index.d.ts
|
|
76
|
+
declare function pracht(options?: PrachtPluginOptions): Promise<Plugin[]>;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { PRACHT_CLIENT_MODULE_ID, PRACHT_SERVER_MODULE_ID, type PrachtAdapter, type PrachtPluginOptions, type RenderMode, createPrachtClientModuleSource, createPrachtRegistryModuleSource, createPrachtServerModuleSource, pracht };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { generatePagesManifestSource, scanPagesDirectory } from "./pages-router.mjs";
|
|
2
2
|
import preact from "@preact/preset-vite";
|
|
3
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
4
3
|
import { resolve } from "node:path";
|
|
5
4
|
import { parseAst } from "vite";
|
|
6
|
-
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
//#region src/client-module-query.ts
|
|
7
|
+
const CLIENT_MODULE_QUERY = "pracht-client";
|
|
8
|
+
const PRACHT_CLIENT_MODULE_QUERY = `?${CLIENT_MODULE_QUERY}`;
|
|
9
|
+
function isPrachtClientModuleId(id) {
|
|
10
|
+
const queryStart = id.indexOf("?");
|
|
11
|
+
if (queryStart === -1) return false;
|
|
12
|
+
return id.slice(queryStart + 1).split("&").includes(CLIENT_MODULE_QUERY);
|
|
13
|
+
}
|
|
14
|
+
function stripPrachtClientModuleQuery(id) {
|
|
15
|
+
const queryStart = id.indexOf("?");
|
|
16
|
+
if (queryStart === -1) return id;
|
|
17
|
+
const path = id.slice(0, queryStart);
|
|
18
|
+
const query = id.slice(queryStart + 1).split("&").filter((part) => part !== CLIENT_MODULE_QUERY);
|
|
19
|
+
return query.length > 0 ? `${path}?${query.join("&")}` : path;
|
|
20
|
+
}
|
|
21
|
+
function getRolldownLang(id) {
|
|
22
|
+
const path = stripPrachtClientModuleQuery(id).split("?")[0];
|
|
23
|
+
if (/\.(c|m)?tsx$/i.test(path)) return "tsx";
|
|
24
|
+
if (/\.(c|m)?ts$/i.test(path)) return "ts";
|
|
25
|
+
if (/\.(c|m)?jsx$/i.test(path)) return "jsx";
|
|
26
|
+
if (/\.mdx?$/i.test(path)) return "jsx";
|
|
27
|
+
if (/\.(c|m)?js$/i.test(path)) return "js";
|
|
28
|
+
return "tsx";
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/scope-analysis-types.ts
|
|
7
32
|
const JSX_COMPONENT_RE = /^[A-Z]/;
|
|
8
33
|
const SKIPPED_KEYS = new Set([
|
|
9
34
|
"attributes",
|
|
@@ -23,20 +48,187 @@ const SKIPPED_KEYS = new Set([
|
|
|
23
48
|
"typeParameters",
|
|
24
49
|
"value"
|
|
25
50
|
]);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/scope-analysis-helpers.ts
|
|
53
|
+
function getStatementDeclaration(statement) {
|
|
54
|
+
if (statement.type === "ExportNamedDeclaration") return statement.declaration ?? null;
|
|
55
|
+
if (statement.type === "ExportDefaultDeclaration" && (statement.declaration.type === "FunctionDeclaration" || statement.declaration.type === "ClassDeclaration")) return statement.declaration;
|
|
56
|
+
if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration" || statement.type === "VariableDeclaration") return statement;
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function collectBindingNamesFromPattern(pattern) {
|
|
60
|
+
if (!pattern) return [];
|
|
61
|
+
switch (pattern.type) {
|
|
62
|
+
case "Identifier": return [pattern.name];
|
|
63
|
+
case "AssignmentPattern": return collectBindingNamesFromPattern(pattern.left);
|
|
64
|
+
case "RestElement": return collectBindingNamesFromPattern(pattern.argument);
|
|
65
|
+
case "ObjectPattern": return pattern.properties.flatMap((property) => {
|
|
66
|
+
if (property.type === "Property") return collectBindingNamesFromPattern(property.value);
|
|
67
|
+
return collectBindingNamesFromPattern(property.argument);
|
|
68
|
+
});
|
|
69
|
+
case "ArrayPattern": return pattern.elements.flatMap((element) => collectBindingNamesFromPattern(element));
|
|
70
|
+
default: return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function getIdentifierName(node) {
|
|
74
|
+
if (!node) return null;
|
|
75
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier") return node.name;
|
|
76
|
+
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function isNode(value) {
|
|
80
|
+
return !!value && typeof value === "object" && "type" in value;
|
|
81
|
+
}
|
|
82
|
+
function getTsRuntimeChildren(node) {
|
|
83
|
+
switch (node.type) {
|
|
84
|
+
case "TSAsExpression":
|
|
85
|
+
case "TSInstantiationExpression":
|
|
86
|
+
case "TSNonNullExpression":
|
|
87
|
+
case "TSSatisfiesExpression":
|
|
88
|
+
case "TSTypeAssertion": return [node.expression];
|
|
89
|
+
default: return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function collectFunctionScopedVarBindings(node) {
|
|
93
|
+
const names = /* @__PURE__ */ new Set();
|
|
94
|
+
collectFunctionScopedVarBindingsInto(node, names);
|
|
95
|
+
return names;
|
|
96
|
+
}
|
|
97
|
+
function collectFunctionScopedVarBindingsInto(node, names) {
|
|
98
|
+
if (!node) return;
|
|
99
|
+
if (node.type.startsWith("TS")) {
|
|
100
|
+
for (const child of getTsRuntimeChildren(node)) collectFunctionScopedVarBindingsInto(child, names);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
switch (node.type) {
|
|
104
|
+
case "ArrowFunctionExpression":
|
|
105
|
+
case "FunctionDeclaration":
|
|
106
|
+
case "FunctionExpression":
|
|
107
|
+
case "ClassDeclaration":
|
|
108
|
+
case "ClassExpression": return;
|
|
109
|
+
case "VariableDeclaration":
|
|
110
|
+
if (node.kind === "var") for (const declarator of node.declarations) for (const name of collectBindingNamesFromPattern(declarator.id)) names.add(name);
|
|
111
|
+
return;
|
|
112
|
+
default: for (const [key, value] of Object.entries(node)) {
|
|
113
|
+
if (SKIPPED_KEYS.has(key)) continue;
|
|
114
|
+
if (key === "id" || key === "implements" || key === "superTypeArguments") continue;
|
|
115
|
+
collectFunctionScopedVarBindingsFromUnknown(value, names);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function collectFunctionScopedVarBindingsFromUnknown(value, names) {
|
|
120
|
+
if (Array.isArray(value)) {
|
|
121
|
+
for (const item of value) collectFunctionScopedVarBindingsFromUnknown(item, names);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (!isNode(value)) return;
|
|
125
|
+
collectFunctionScopedVarBindingsInto(value, names);
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/client-module-transform-state.ts
|
|
129
|
+
function createStatementStates(program) {
|
|
130
|
+
return program.body.map((node) => ({
|
|
131
|
+
node,
|
|
132
|
+
removed: false,
|
|
133
|
+
removedDeclarators: /* @__PURE__ */ new Set(),
|
|
134
|
+
removedSpecifiers: /* @__PURE__ */ new Set()
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
function getRemainingDeclaratorIndices(state) {
|
|
138
|
+
const declaration = getStatementDeclaration(state.node);
|
|
139
|
+
if (!declaration || declaration.type !== "VariableDeclaration") return [];
|
|
140
|
+
return declaration.declarations.map((_item, index) => index).filter((index) => !state.removedDeclarators.has(index));
|
|
141
|
+
}
|
|
142
|
+
function getRemainingSpecifierIndices(state) {
|
|
143
|
+
const statement = state.node;
|
|
144
|
+
if (!("specifiers" in statement) || !Array.isArray(statement.specifiers)) return [];
|
|
145
|
+
return statement.specifiers.map((_item, index) => index).filter((index) => !state.removedSpecifiers.has(index));
|
|
146
|
+
}
|
|
147
|
+
function collectBindingNamesFromDeclaration(declaration) {
|
|
148
|
+
if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") return declaration.id ? [declaration.id.name] : [];
|
|
149
|
+
if (declaration.type === "VariableDeclaration") return declaration.declarations.flatMap((declarator) => collectBindingNamesFromPattern(declarator.id));
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
function normalizeRetainedStatements(states) {
|
|
153
|
+
return states.map((state) => normalizeRetainedStatement(state)).filter((state) => state !== null);
|
|
154
|
+
}
|
|
155
|
+
function normalizeRetainedStatement(state) {
|
|
156
|
+
if (state.removed) return null;
|
|
157
|
+
const statement = state.node;
|
|
158
|
+
if (statement.type === "ImportDeclaration" && state.removedSpecifiers.size > 0) return { node: {
|
|
159
|
+
...statement,
|
|
160
|
+
specifiers: getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index])
|
|
161
|
+
} };
|
|
162
|
+
if (statement.type === "ExportNamedDeclaration" && !statement.declaration && state.removedSpecifiers.size > 0) return { node: {
|
|
163
|
+
...statement,
|
|
164
|
+
specifiers: getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index])
|
|
165
|
+
} };
|
|
166
|
+
const declaration = getStatementDeclaration(statement);
|
|
167
|
+
if (declaration?.type === "VariableDeclaration" && state.removedDeclarators.size > 0) {
|
|
168
|
+
const retainedDeclaration = {
|
|
169
|
+
...declaration,
|
|
170
|
+
declarations: getRemainingDeclaratorIndices(state).map((index) => declaration.declarations[index])
|
|
171
|
+
};
|
|
172
|
+
if (statement.type === "ExportNamedDeclaration") return { node: {
|
|
173
|
+
...statement,
|
|
174
|
+
declaration: retainedDeclaration
|
|
175
|
+
} };
|
|
176
|
+
return { node: retainedDeclaration };
|
|
177
|
+
}
|
|
178
|
+
return { node: statement };
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/client-module-transform-render.ts
|
|
182
|
+
function renderProgram(code, states) {
|
|
183
|
+
let cursor = 0;
|
|
184
|
+
let out = "";
|
|
185
|
+
for (const state of states) {
|
|
186
|
+
const statement = state.node;
|
|
187
|
+
out += code.slice(cursor, statement.start);
|
|
188
|
+
out += renderStatement(code, state);
|
|
189
|
+
cursor = statement.end;
|
|
190
|
+
}
|
|
191
|
+
out += code.slice(cursor);
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
function renderStatement(code, state) {
|
|
195
|
+
if (state.removed) return "";
|
|
196
|
+
const statement = state.node;
|
|
197
|
+
const declaration = getStatementDeclaration(statement);
|
|
198
|
+
if (statement.type === "ImportDeclaration" && state.removedSpecifiers.size > 0) return renderImportDeclaration(code, statement, state);
|
|
199
|
+
if (statement.type === "ExportNamedDeclaration" && !statement.declaration && state.removedSpecifiers.size > 0) return renderExportSpecifiers(code, statement, state);
|
|
200
|
+
if (declaration?.type === "VariableDeclaration" && state.removedDeclarators.size > 0) return renderVariableDeclaration(code, statement, declaration, state);
|
|
201
|
+
return code.slice(statement.start, statement.end);
|
|
202
|
+
}
|
|
203
|
+
function renderImportDeclaration(code, statement, state) {
|
|
204
|
+
const remaining = getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index]);
|
|
205
|
+
if (remaining.length === 0) return "";
|
|
206
|
+
const defaultSpecifier = remaining.find((specifier) => specifier.type === "ImportDefaultSpecifier");
|
|
207
|
+
const namespaceSpecifier = remaining.find((specifier) => specifier.type === "ImportNamespaceSpecifier");
|
|
208
|
+
const namedSpecifiers = remaining.filter((specifier) => specifier.type === "ImportSpecifier");
|
|
209
|
+
const clauseParts = [];
|
|
210
|
+
if (defaultSpecifier) clauseParts.push(code.slice(defaultSpecifier.start, defaultSpecifier.end));
|
|
211
|
+
if (namespaceSpecifier) clauseParts.push(code.slice(namespaceSpecifier.start, namespaceSpecifier.end));
|
|
212
|
+
if (namedSpecifiers.length > 0) clauseParts.push(`{ ${namedSpecifiers.map((specifier) => code.slice(specifier.start, specifier.end)).join(", ")} }`);
|
|
213
|
+
const importPrefix = ["import"];
|
|
214
|
+
if (statement.importKind === "type") importPrefix.push("type");
|
|
215
|
+
if (typeof statement.phase === "string" && statement.phase.length > 0) importPrefix.push(statement.phase);
|
|
216
|
+
return `${importPrefix.join(" ")} ${clauseParts.join(", ")} from ${code.slice(statement.source.start, statement.end)}`;
|
|
217
|
+
}
|
|
218
|
+
function renderExportSpecifiers(code, statement, state) {
|
|
219
|
+
const remaining = getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index]);
|
|
220
|
+
if (remaining.length === 0) return "";
|
|
221
|
+
const exportPrefix = statement.exportKind === "type" ? "export type" : "export";
|
|
222
|
+
const sourceSuffix = statement.source ? ` from ${code.slice(statement.source.start, statement.end)}` : ";";
|
|
223
|
+
return `${exportPrefix} { ${remaining.map((specifier) => code.slice(specifier.start, specifier.end)).join(", ")} }${sourceSuffix}`;
|
|
39
224
|
}
|
|
225
|
+
function renderVariableDeclaration(code, statement, declaration, state) {
|
|
226
|
+
const remaining = getRemainingDeclaratorIndices(state).map((index) => declaration.declarations[index]);
|
|
227
|
+
if (remaining.length === 0) return "";
|
|
228
|
+
return `${statement.type === "ExportNamedDeclaration" ? "export " : ""}${declaration.kind} ${remaining.map((item) => code.slice(item.start, item.end)).join(", ")};`;
|
|
229
|
+
}
|
|
230
|
+
//#endregion
|
|
231
|
+
//#region src/scope-analysis-declare.ts
|
|
40
232
|
function createScope(type, parent, node) {
|
|
41
233
|
return {
|
|
42
234
|
bindings: /* @__PURE__ */ new Map(),
|
|
@@ -45,6 +237,16 @@ function createScope(type, parent, node) {
|
|
|
45
237
|
type
|
|
46
238
|
};
|
|
47
239
|
}
|
|
240
|
+
function declareBinding(scope, name, kind, node) {
|
|
241
|
+
const binding = {
|
|
242
|
+
kind,
|
|
243
|
+
name,
|
|
244
|
+
node,
|
|
245
|
+
scope
|
|
246
|
+
};
|
|
247
|
+
scope.bindings.set(name, binding);
|
|
248
|
+
return binding;
|
|
249
|
+
}
|
|
48
250
|
function declareProgramScopes(statements, programScope, scopesByNode) {
|
|
49
251
|
for (const statement of statements) declareTopLevelStatement(statement.node, programScope);
|
|
50
252
|
for (const statement of statements) declareNodeScopes(statement.node, programScope, scopesByNode);
|
|
@@ -54,19 +256,19 @@ function declareTopLevelStatement(statement, programScope) {
|
|
|
54
256
|
if (statement.importKind === "type") return;
|
|
55
257
|
for (const specifier of statement.specifiers) {
|
|
56
258
|
if (specifier.type === "ImportSpecifier" && specifier.importKind === "type") continue;
|
|
57
|
-
const localName = getIdentifierName
|
|
259
|
+
const localName = getIdentifierName(specifier.local);
|
|
58
260
|
if (localName) declareBinding(programScope, localName, "import", specifier);
|
|
59
261
|
}
|
|
60
262
|
return;
|
|
61
263
|
}
|
|
62
|
-
const declaration = getStatementDeclaration
|
|
264
|
+
const declaration = getStatementDeclaration(statement);
|
|
63
265
|
if (!declaration) return;
|
|
64
266
|
declareDeclarationBindings(programScope, declaration);
|
|
65
267
|
}
|
|
66
268
|
function declareNodeScopes(node, currentScope, scopesByNode) {
|
|
67
269
|
if (!node) return;
|
|
68
270
|
if (node.type.startsWith("TS")) {
|
|
69
|
-
|
|
271
|
+
for (const child of getTsRuntimeChildren(node)) declareNodeScopes(child, currentScope, scopesByNode);
|
|
70
272
|
return;
|
|
71
273
|
}
|
|
72
274
|
switch (node.type) {
|
|
@@ -144,7 +346,7 @@ function declareNodeScopes(node, currentScope, scopesByNode) {
|
|
|
144
346
|
declareNodeScopes(node.superClass, currentScope, scopesByNode);
|
|
145
347
|
const classScope = createScope("class", currentScope, node);
|
|
146
348
|
scopesByNode.set(node, classScope);
|
|
147
|
-
const name = getIdentifierName
|
|
349
|
+
const name = getIdentifierName(node.id);
|
|
148
350
|
if (name) declareBinding(classScope, name, "class", node);
|
|
149
351
|
declareNodeScopes(node.body, classScope, scopesByNode);
|
|
150
352
|
return;
|
|
@@ -171,14 +373,14 @@ function declareUnknownValue(value, currentScope, scopesByNode) {
|
|
|
171
373
|
declareNodeScopes(value, currentScope, scopesByNode);
|
|
172
374
|
}
|
|
173
375
|
function declareFunctionBindings(node, scope) {
|
|
174
|
-
const functionName = getIdentifierName
|
|
376
|
+
const functionName = getIdentifierName(node.id);
|
|
175
377
|
if (functionName) declareBinding(scope, functionName, "function", node);
|
|
176
|
-
for (const param of node.params) for (const name of collectBindingNamesFromPattern
|
|
378
|
+
for (const param of node.params) for (const name of collectBindingNamesFromPattern(param)) declareBinding(scope, name, "param", param);
|
|
177
379
|
for (const name of collectFunctionScopedVarBindings(node.body)) declareBinding(scope, name, "var", node.body);
|
|
178
380
|
}
|
|
179
381
|
function declareBlockBindings(statements, scope) {
|
|
180
382
|
for (const statement of statements) {
|
|
181
|
-
const declaration = getStatementDeclaration
|
|
383
|
+
const declaration = getStatementDeclaration(statement);
|
|
182
384
|
if (!declaration) continue;
|
|
183
385
|
if (declaration.type === "VariableDeclaration" && declaration.kind === "var") continue;
|
|
184
386
|
declareDeclarationBindings(scope, declaration);
|
|
@@ -186,7 +388,7 @@ function declareBlockBindings(statements, scope) {
|
|
|
186
388
|
}
|
|
187
389
|
function declareCatchBindings(node, scope) {
|
|
188
390
|
if (!node.param) return;
|
|
189
|
-
for (const name of collectBindingNamesFromPattern
|
|
391
|
+
for (const name of collectBindingNamesFromPattern(node.param)) declareBinding(scope, name, "catch", node.param);
|
|
190
392
|
}
|
|
191
393
|
function declareSwitchBindings(cases, scope) {
|
|
192
394
|
const statements = [];
|
|
@@ -195,28 +397,20 @@ function declareSwitchBindings(cases, scope) {
|
|
|
195
397
|
}
|
|
196
398
|
function declareDeclarationBindings(scope, declaration) {
|
|
197
399
|
if (declaration.type === "FunctionDeclaration") {
|
|
198
|
-
const name = getIdentifierName
|
|
400
|
+
const name = getIdentifierName(declaration.id);
|
|
199
401
|
if (name) declareBinding(scope, name, "function", declaration);
|
|
200
402
|
return;
|
|
201
403
|
}
|
|
202
404
|
if (declaration.type === "ClassDeclaration") {
|
|
203
|
-
const name = getIdentifierName
|
|
405
|
+
const name = getIdentifierName(declaration.id);
|
|
204
406
|
if (name) declareBinding(scope, name, "class", declaration);
|
|
205
407
|
return;
|
|
206
408
|
}
|
|
207
409
|
if (declaration.type !== "VariableDeclaration") return;
|
|
208
|
-
for (const declarator of declaration.declarations) for (const name of collectBindingNamesFromPattern
|
|
209
|
-
}
|
|
210
|
-
function declareBinding(scope, name, kind, node) {
|
|
211
|
-
const binding = {
|
|
212
|
-
kind,
|
|
213
|
-
name,
|
|
214
|
-
node,
|
|
215
|
-
scope
|
|
216
|
-
};
|
|
217
|
-
scope.bindings.set(name, binding);
|
|
218
|
-
return binding;
|
|
410
|
+
for (const declarator of declaration.declarations) for (const name of collectBindingNamesFromPattern(declarator.id)) declareBinding(scope, name, declaration.kind, declarator);
|
|
219
411
|
}
|
|
412
|
+
//#endregion
|
|
413
|
+
//#region src/scope-analysis-references.ts
|
|
220
414
|
function collectStatementReferences(statement, currentScope, scopesByNode, result, excludedNames) {
|
|
221
415
|
if (statement.type === "ImportDeclaration") return;
|
|
222
416
|
if (statement.type === "ExportNamedDeclaration") {
|
|
@@ -234,7 +428,7 @@ function collectStatementReferences(statement, currentScope, scopesByNode, resul
|
|
|
234
428
|
function collectNodeReferences(node, currentScope, scopesByNode, result, excludedNames) {
|
|
235
429
|
if (!node) return;
|
|
236
430
|
if (node.type.startsWith("TS")) {
|
|
237
|
-
|
|
431
|
+
for (const child of getTsRuntimeChildren(node)) collectNodeReferences(child, currentScope, scopesByNode, result, excludedNames);
|
|
238
432
|
return;
|
|
239
433
|
}
|
|
240
434
|
switch (node.type) {
|
|
@@ -375,7 +569,7 @@ function collectVariableDeclaratorReferences(declarator, currentScope, scopesByN
|
|
|
375
569
|
function collectPatternReferences(node, currentScope, scopesByNode, result, excludedNames) {
|
|
376
570
|
if (!node) return;
|
|
377
571
|
if (node.type.startsWith("TS")) {
|
|
378
|
-
|
|
572
|
+
for (const child of getTsRuntimeChildren(node)) collectNodeReferences(child, currentScope, scopesByNode, result, excludedNames);
|
|
379
573
|
return;
|
|
380
574
|
}
|
|
381
575
|
switch (node.type) {
|
|
@@ -423,111 +617,30 @@ function resolveBinding(name, currentScope) {
|
|
|
423
617
|
}
|
|
424
618
|
return null;
|
|
425
619
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
});
|
|
442
|
-
case "ArrayPattern": return pattern.elements.flatMap((element) => collectBindingNamesFromPattern$1(element));
|
|
443
|
-
default: return [];
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
function collectFunctionScopedVarBindings(node) {
|
|
447
|
-
const names = /* @__PURE__ */ new Set();
|
|
448
|
-
collectFunctionScopedVarBindingsInto(node, names);
|
|
449
|
-
return names;
|
|
450
|
-
}
|
|
451
|
-
function collectFunctionScopedVarBindingsInto(node, names) {
|
|
452
|
-
if (!node) return;
|
|
453
|
-
if (node.type.startsWith("TS")) {
|
|
454
|
-
collectFunctionScopedVarBindingsFromTsNode(node, names);
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
switch (node.type) {
|
|
458
|
-
case "ArrowFunctionExpression":
|
|
459
|
-
case "FunctionDeclaration":
|
|
460
|
-
case "FunctionExpression":
|
|
461
|
-
case "ClassDeclaration":
|
|
462
|
-
case "ClassExpression": return;
|
|
463
|
-
case "VariableDeclaration":
|
|
464
|
-
if (node.kind === "var") for (const declarator of node.declarations) for (const name of collectBindingNamesFromPattern$1(declarator.id)) names.add(name);
|
|
465
|
-
return;
|
|
466
|
-
default: for (const [key, value] of Object.entries(node)) {
|
|
467
|
-
if (SKIPPED_KEYS.has(key)) continue;
|
|
468
|
-
if (key === "id" || key === "implements" || key === "superTypeArguments") continue;
|
|
469
|
-
collectFunctionScopedVarBindingsFromUnknown(value, names);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
function collectFunctionScopedVarBindingsFromUnknown(value, names) {
|
|
474
|
-
if (Array.isArray(value)) {
|
|
475
|
-
for (const item of value) collectFunctionScopedVarBindingsFromUnknown(item, names);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
if (!isNode(value)) return;
|
|
479
|
-
collectFunctionScopedVarBindingsInto(value, names);
|
|
480
|
-
}
|
|
481
|
-
function declareTsRuntimeChildren(node, currentScope, scopesByNode) {
|
|
482
|
-
for (const child of getTsRuntimeChildren(node)) declareNodeScopes(child, currentScope, scopesByNode);
|
|
483
|
-
}
|
|
484
|
-
function collectTsRuntimeReferences(node, currentScope, scopesByNode, result, excludedNames) {
|
|
485
|
-
for (const child of getTsRuntimeChildren(node)) collectNodeReferences(child, currentScope, scopesByNode, result, excludedNames);
|
|
486
|
-
}
|
|
487
|
-
function collectFunctionScopedVarBindingsFromTsNode(node, names) {
|
|
488
|
-
for (const child of getTsRuntimeChildren(node)) collectFunctionScopedVarBindingsInto(child, names);
|
|
489
|
-
}
|
|
490
|
-
function getTsRuntimeChildren(node) {
|
|
491
|
-
switch (node.type) {
|
|
492
|
-
case "TSAsExpression":
|
|
493
|
-
case "TSInstantiationExpression":
|
|
494
|
-
case "TSNonNullExpression":
|
|
495
|
-
case "TSSatisfiesExpression":
|
|
496
|
-
case "TSTypeAssertion": return [node.expression];
|
|
497
|
-
default: return [];
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
function getIdentifierName$1(node) {
|
|
501
|
-
if (!node) return null;
|
|
502
|
-
if (node.type === "Identifier" || node.type === "JSXIdentifier") return node.name;
|
|
503
|
-
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
504
|
-
return null;
|
|
505
|
-
}
|
|
506
|
-
function isNode(value) {
|
|
507
|
-
return !!value && typeof value === "object" && "type" in value;
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/client-module-scope-analysis.ts
|
|
622
|
+
function analyzeRetainedStatements(statements, options = {}) {
|
|
623
|
+
const programScope = createScope("program", null, null);
|
|
624
|
+
for (const name of options.knownTopLevelNames ?? []) declareBinding(programScope, name, "placeholder", null);
|
|
625
|
+
const scopesByNode = /* @__PURE__ */ new WeakMap();
|
|
626
|
+
declareProgramScopes(statements, programScope, scopesByNode);
|
|
627
|
+
const result = {
|
|
628
|
+
programScope,
|
|
629
|
+
referencedTopLevelNames: /* @__PURE__ */ new Set(),
|
|
630
|
+
references: []
|
|
631
|
+
};
|
|
632
|
+
const excludedNames = new Set(options.excludedNames);
|
|
633
|
+
for (const statement of statements) collectStatementReferences(statement.node, programScope, scopesByNode, result, excludedNames);
|
|
634
|
+
return result;
|
|
508
635
|
}
|
|
509
636
|
//#endregion
|
|
510
637
|
//#region src/client-module-transform.ts
|
|
511
|
-
const CLIENT_MODULE_QUERY = "pracht-client";
|
|
512
638
|
const SERVER_ONLY_EXPORTS = new Set([
|
|
513
639
|
"loader",
|
|
514
640
|
"head",
|
|
515
641
|
"headers",
|
|
516
642
|
"getStaticPaths"
|
|
517
643
|
]);
|
|
518
|
-
const PRACHT_CLIENT_MODULE_QUERY = `?${CLIENT_MODULE_QUERY}`;
|
|
519
|
-
function isPrachtClientModuleId(id) {
|
|
520
|
-
const queryStart = id.indexOf("?");
|
|
521
|
-
if (queryStart === -1) return false;
|
|
522
|
-
return id.slice(queryStart + 1).split("&").includes(CLIENT_MODULE_QUERY);
|
|
523
|
-
}
|
|
524
|
-
function stripPrachtClientModuleQuery(id) {
|
|
525
|
-
const queryStart = id.indexOf("?");
|
|
526
|
-
if (queryStart === -1) return id;
|
|
527
|
-
const path = id.slice(0, queryStart);
|
|
528
|
-
const query = id.slice(queryStart + 1).split("&").filter((part) => part !== CLIENT_MODULE_QUERY);
|
|
529
|
-
return query.length > 0 ? `${path}?${query.join("&")}` : path;
|
|
530
|
-
}
|
|
531
644
|
function stripServerOnlyExportsForClient(code, id = "pracht-client-route.tsx") {
|
|
532
645
|
const states = createStatementStates(parseAst(code, { lang: getRolldownLang(id) }));
|
|
533
646
|
const initialBindingNames = collectCurrentTopLevelBindingNames(states);
|
|
@@ -536,14 +649,6 @@ function stripServerOnlyExportsForClient(code, id = "pracht-client-route.tsx") {
|
|
|
536
649
|
pruneDeadBindings(states, initialBindingNames, candidates);
|
|
537
650
|
return renderProgram(code, states);
|
|
538
651
|
}
|
|
539
|
-
function createStatementStates(program) {
|
|
540
|
-
return program.body.map((node) => ({
|
|
541
|
-
node,
|
|
542
|
-
removed: false,
|
|
543
|
-
removedDeclarators: /* @__PURE__ */ new Set(),
|
|
544
|
-
removedSpecifiers: /* @__PURE__ */ new Set()
|
|
545
|
-
}));
|
|
546
|
-
}
|
|
547
652
|
function removeServerOnlyExports(states, initialBindingNames) {
|
|
548
653
|
let changed = false;
|
|
549
654
|
const candidates = /* @__PURE__ */ new Set();
|
|
@@ -759,64 +864,6 @@ function removeBinding(states, binding) {
|
|
|
759
864
|
}
|
|
760
865
|
state.removed = true;
|
|
761
866
|
}
|
|
762
|
-
function renderProgram(code, states) {
|
|
763
|
-
let cursor = 0;
|
|
764
|
-
let out = "";
|
|
765
|
-
for (const state of states) {
|
|
766
|
-
const statement = state.node;
|
|
767
|
-
out += code.slice(cursor, statement.start);
|
|
768
|
-
out += renderStatement(code, state);
|
|
769
|
-
cursor = statement.end;
|
|
770
|
-
}
|
|
771
|
-
out += code.slice(cursor);
|
|
772
|
-
return out;
|
|
773
|
-
}
|
|
774
|
-
function renderStatement(code, state) {
|
|
775
|
-
if (state.removed) return "";
|
|
776
|
-
const statement = state.node;
|
|
777
|
-
const declaration = getStatementDeclaration(statement);
|
|
778
|
-
if (statement.type === "ImportDeclaration" && state.removedSpecifiers.size > 0) return renderImportDeclaration(code, statement, state);
|
|
779
|
-
if (statement.type === "ExportNamedDeclaration" && !statement.declaration && state.removedSpecifiers.size > 0) return renderExportSpecifiers(code, statement, state);
|
|
780
|
-
if (declaration?.type === "VariableDeclaration" && state.removedDeclarators.size > 0) return renderVariableDeclaration(code, statement, declaration, state);
|
|
781
|
-
return code.slice(statement.start, statement.end);
|
|
782
|
-
}
|
|
783
|
-
function renderImportDeclaration(code, statement, state) {
|
|
784
|
-
const remaining = getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index]);
|
|
785
|
-
if (remaining.length === 0) return "";
|
|
786
|
-
const defaultSpecifier = remaining.find((specifier) => specifier.type === "ImportDefaultSpecifier");
|
|
787
|
-
const namespaceSpecifier = remaining.find((specifier) => specifier.type === "ImportNamespaceSpecifier");
|
|
788
|
-
const namedSpecifiers = remaining.filter((specifier) => specifier.type === "ImportSpecifier");
|
|
789
|
-
const clauseParts = [];
|
|
790
|
-
if (defaultSpecifier) clauseParts.push(code.slice(defaultSpecifier.start, defaultSpecifier.end));
|
|
791
|
-
if (namespaceSpecifier) clauseParts.push(code.slice(namespaceSpecifier.start, namespaceSpecifier.end));
|
|
792
|
-
if (namedSpecifiers.length > 0) clauseParts.push(`{ ${namedSpecifiers.map((specifier) => code.slice(specifier.start, specifier.end)).join(", ")} }`);
|
|
793
|
-
const importPrefix = ["import"];
|
|
794
|
-
if (statement.importKind === "type") importPrefix.push("type");
|
|
795
|
-
if (typeof statement.phase === "string" && statement.phase.length > 0) importPrefix.push(statement.phase);
|
|
796
|
-
return `${importPrefix.join(" ")} ${clauseParts.join(", ")} from ${code.slice(statement.source.start, statement.end)}`;
|
|
797
|
-
}
|
|
798
|
-
function renderExportSpecifiers(code, statement, state) {
|
|
799
|
-
const remaining = getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index]);
|
|
800
|
-
if (remaining.length === 0) return "";
|
|
801
|
-
const exportPrefix = statement.exportKind === "type" ? "export type" : "export";
|
|
802
|
-
const sourceSuffix = statement.source ? ` from ${code.slice(statement.source.start, statement.end)}` : ";";
|
|
803
|
-
return `${exportPrefix} { ${remaining.map((specifier) => code.slice(specifier.start, specifier.end)).join(", ")} }${sourceSuffix}`;
|
|
804
|
-
}
|
|
805
|
-
function renderVariableDeclaration(code, statement, declaration, state) {
|
|
806
|
-
const remaining = getRemainingDeclaratorIndices(state).map((index) => declaration.declarations[index]);
|
|
807
|
-
if (remaining.length === 0) return "";
|
|
808
|
-
return `${statement.type === "ExportNamedDeclaration" ? "export " : ""}${declaration.kind} ${remaining.map((item) => code.slice(item.start, item.end)).join(", ")};`;
|
|
809
|
-
}
|
|
810
|
-
function getRemainingDeclaratorIndices(state) {
|
|
811
|
-
const declaration = getStatementDeclaration(state.node);
|
|
812
|
-
if (!declaration || declaration.type !== "VariableDeclaration") return [];
|
|
813
|
-
return declaration.declarations.map((_item, index) => index).filter((index) => !state.removedDeclarators.has(index));
|
|
814
|
-
}
|
|
815
|
-
function getRemainingSpecifierIndices(state) {
|
|
816
|
-
const statement = state.node;
|
|
817
|
-
if (!("specifiers" in statement) || !Array.isArray(statement.specifiers)) return [];
|
|
818
|
-
return statement.specifiers.map((_item, index) => index).filter((index) => !state.removedSpecifiers.has(index));
|
|
819
|
-
}
|
|
820
867
|
function collectVariableDeclaratorDependencies(declarator, declarationKind, topLevelBindingNames, excludedNames) {
|
|
821
868
|
return collectTopLevelReferences({
|
|
822
869
|
declarations: [declarator],
|
|
@@ -832,88 +879,66 @@ function collectTopLevelReferences(node, topLevelBindingNames, excludedNames) {
|
|
|
832
879
|
knownTopLevelNames: topLevelBindingNames
|
|
833
880
|
}).referencedTopLevelNames;
|
|
834
881
|
}
|
|
835
|
-
function normalizeRetainedStatements(states) {
|
|
836
|
-
return states.map((state) => normalizeRetainedStatement(state)).filter((state) => state !== null);
|
|
837
|
-
}
|
|
838
|
-
function normalizeRetainedStatement(state) {
|
|
839
|
-
if (state.removed) return null;
|
|
840
|
-
const statement = state.node;
|
|
841
|
-
if (statement.type === "ImportDeclaration" && state.removedSpecifiers.size > 0) return { node: {
|
|
842
|
-
...statement,
|
|
843
|
-
specifiers: getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index])
|
|
844
|
-
} };
|
|
845
|
-
if (statement.type === "ExportNamedDeclaration" && !statement.declaration && state.removedSpecifiers.size > 0) return { node: {
|
|
846
|
-
...statement,
|
|
847
|
-
specifiers: getRemainingSpecifierIndices(state).map((index) => statement.specifiers[index])
|
|
848
|
-
} };
|
|
849
|
-
const declaration = getStatementDeclaration(statement);
|
|
850
|
-
if (declaration?.type === "VariableDeclaration" && state.removedDeclarators.size > 0) {
|
|
851
|
-
const retainedDeclaration = {
|
|
852
|
-
...declaration,
|
|
853
|
-
declarations: getRemainingDeclaratorIndices(state).map((index) => declaration.declarations[index])
|
|
854
|
-
};
|
|
855
|
-
if (statement.type === "ExportNamedDeclaration") return { node: {
|
|
856
|
-
...statement,
|
|
857
|
-
declaration: retainedDeclaration
|
|
858
|
-
} };
|
|
859
|
-
return { node: retainedDeclaration };
|
|
860
|
-
}
|
|
861
|
-
return { node: statement };
|
|
862
|
-
}
|
|
863
|
-
function getStatementDeclaration(statement) {
|
|
864
|
-
if (statement.type === "ExportNamedDeclaration") return statement.declaration ?? null;
|
|
865
|
-
if (statement.type === "ExportDefaultDeclaration" && (statement.declaration.type === "FunctionDeclaration" || statement.declaration.type === "ClassDeclaration")) return statement.declaration;
|
|
866
|
-
if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration" || statement.type === "VariableDeclaration") return statement;
|
|
867
|
-
return null;
|
|
868
|
-
}
|
|
869
|
-
function collectBindingNamesFromDeclaration(declaration) {
|
|
870
|
-
if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") return declaration.id ? [declaration.id.name] : [];
|
|
871
|
-
if (declaration.type === "VariableDeclaration") return declaration.declarations.flatMap((declarator) => collectBindingNamesFromPattern(declarator.id));
|
|
872
|
-
return [];
|
|
873
|
-
}
|
|
874
|
-
function collectBindingNamesFromPattern(pattern) {
|
|
875
|
-
if (!pattern) return [];
|
|
876
|
-
switch (pattern.type) {
|
|
877
|
-
case "Identifier": return [pattern.name];
|
|
878
|
-
case "AssignmentPattern": return collectBindingNamesFromPattern(pattern.left);
|
|
879
|
-
case "RestElement": return collectBindingNamesFromPattern(pattern.argument);
|
|
880
|
-
case "ObjectPattern": return pattern.properties.flatMap((property) => {
|
|
881
|
-
if (property.type === "Property") return collectBindingNamesFromPattern(property.value);
|
|
882
|
-
return collectBindingNamesFromPattern(property.argument);
|
|
883
|
-
});
|
|
884
|
-
case "ArrayPattern": return pattern.elements.flatMap((element) => collectBindingNamesFromPattern(element));
|
|
885
|
-
default: return [];
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
882
|
function enqueueDependencies(target, dependencies) {
|
|
889
883
|
for (const name of dependencies) target.add(name);
|
|
890
884
|
}
|
|
891
|
-
function getIdentifierName(node) {
|
|
892
|
-
if (!node) return null;
|
|
893
|
-
if (node.type === "Identifier" || node.type === "JSXIdentifier") return node.name;
|
|
894
|
-
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
895
|
-
return null;
|
|
896
|
-
}
|
|
897
|
-
function getRolldownLang(id) {
|
|
898
|
-
const path = stripPrachtClientModuleQuery(id).split("?")[0];
|
|
899
|
-
if (/\.(c|m)?tsx$/i.test(path)) return "tsx";
|
|
900
|
-
if (/\.(c|m)?ts$/i.test(path)) return "ts";
|
|
901
|
-
if (/\.(c|m)?jsx$/i.test(path)) return "jsx";
|
|
902
|
-
if (/\.mdx?$/i.test(path)) return "jsx";
|
|
903
|
-
if (/\.(c|m)?js$/i.test(path)) return "js";
|
|
904
|
-
return "tsx";
|
|
905
|
-
}
|
|
906
885
|
//#endregion
|
|
907
|
-
//#region src/
|
|
886
|
+
//#region src/plugin-assets.ts
|
|
908
887
|
const PRACHT_CLIENT_MODULE_ID = "virtual:pracht/client";
|
|
909
888
|
const PRACHT_SERVER_MODULE_ID = "virtual:pracht/server";
|
|
910
889
|
const CLIENT_BROWSER_PATH = "/@pracht/client.js";
|
|
890
|
+
function readClientBuildAssets(root = process.cwd()) {
|
|
891
|
+
const manifestPath = ["dist/client/.vite/manifest.json", "dist/.vite/manifest.json"].map((candidate) => resolve(root, candidate)).find((candidate) => existsSync(candidate));
|
|
892
|
+
if (!manifestPath) return {
|
|
893
|
+
clientEntryUrl: null,
|
|
894
|
+
cssManifest: {},
|
|
895
|
+
jsManifest: {}
|
|
896
|
+
};
|
|
897
|
+
const rawManifest = readFileSync(manifestPath, "utf-8");
|
|
898
|
+
const manifest = JSON.parse(rawManifest);
|
|
899
|
+
const clientEntry = manifest[PRACHT_CLIENT_MODULE_ID];
|
|
900
|
+
const cssManifest = {};
|
|
901
|
+
const jsManifest = {};
|
|
902
|
+
for (const [key, entry] of Object.entries(manifest)) {
|
|
903
|
+
if (!entry.src) continue;
|
|
904
|
+
const deps = collectTransitiveDeps(manifest, key);
|
|
905
|
+
const manifestKey = stripPrachtClientModuleQuery(entry.src);
|
|
906
|
+
if (deps.css.length > 0) cssManifest[manifestKey] = deps.css.map((f) => `/${f}`);
|
|
907
|
+
if (deps.js.length > 0) jsManifest[manifestKey] = deps.js.map((f) => `/${f}`);
|
|
908
|
+
}
|
|
909
|
+
return {
|
|
910
|
+
clientEntryUrl: clientEntry ? `/${clientEntry.file}` : null,
|
|
911
|
+
cssManifest,
|
|
912
|
+
jsManifest
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
function collectTransitiveDeps(manifest, key) {
|
|
916
|
+
const css = /* @__PURE__ */ new Set();
|
|
917
|
+
const js = /* @__PURE__ */ new Set();
|
|
918
|
+
const visited = /* @__PURE__ */ new Set();
|
|
919
|
+
function collect(k) {
|
|
920
|
+
if (visited.has(k)) return;
|
|
921
|
+
visited.add(k);
|
|
922
|
+
const entry = manifest[k];
|
|
923
|
+
if (!entry) return;
|
|
924
|
+
for (const c of entry.css ?? []) css.add(c);
|
|
925
|
+
js.add(entry.file);
|
|
926
|
+
for (const imp of entry.imports ?? []) collect(imp);
|
|
927
|
+
}
|
|
928
|
+
collect(key);
|
|
929
|
+
return {
|
|
930
|
+
css: [...css],
|
|
931
|
+
js: [...js]
|
|
932
|
+
};
|
|
933
|
+
}
|
|
911
934
|
function isClientModule(id) {
|
|
912
|
-
return id === "virtual:pracht/client" || id ===
|
|
935
|
+
return id === "virtual:pracht/client" || id === "/@pracht/client.js" || id.endsWith("virtual:pracht/client");
|
|
913
936
|
}
|
|
914
937
|
function isServerModule(id) {
|
|
915
938
|
return id === "virtual:pracht/server" || id.endsWith("virtual:pracht/server");
|
|
916
939
|
}
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region src/plugin-adapter.ts
|
|
917
942
|
function createDefaultNodeAdapter() {
|
|
918
943
|
return {
|
|
919
944
|
id: "node",
|
|
@@ -957,6 +982,8 @@ function createDefaultNodeAdapter() {
|
|
|
957
982
|
}
|
|
958
983
|
};
|
|
959
984
|
}
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region src/plugin-options.ts
|
|
960
987
|
const DEFAULTS = {
|
|
961
988
|
appFile: "/src/routes.ts",
|
|
962
989
|
middlewareDir: "/src/middleware",
|
|
@@ -968,115 +995,14 @@ const DEFAULTS = {
|
|
|
968
995
|
pagesDir: "",
|
|
969
996
|
pagesDefaultRender: "ssr"
|
|
970
997
|
};
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
if (isPagesMode && options.appFile) console.warn("[pracht] Both `pagesDir` and `appFile` are set. `pagesDir` takes precedence — `appFile` will be ignored.");
|
|
976
|
-
let isBuild = false;
|
|
977
|
-
const prachtPlugin = {
|
|
978
|
-
name: "pracht",
|
|
979
|
-
enforce: "pre",
|
|
980
|
-
config(_config, env) {
|
|
981
|
-
const isEdge = resolved.adapter.id === "vercel" || resolved.adapter.id === "cloudflare";
|
|
982
|
-
const isSSRBuild = env.isSsrBuild;
|
|
983
|
-
return {
|
|
984
|
-
appType: "custom",
|
|
985
|
-
build: { rollupOptions: { output: { manualChunks(id) {
|
|
986
|
-
if (id.includes("node_modules/preact") || id.includes("node_modules/preact-suspense")) return "vendor";
|
|
987
|
-
} } } },
|
|
988
|
-
...isEdge && isSSRBuild ? { ssr: { noExternal: true } } : {}
|
|
989
|
-
};
|
|
990
|
-
},
|
|
991
|
-
configResolved(config) {
|
|
992
|
-
root = config.root;
|
|
993
|
-
isBuild = config.command === "build";
|
|
994
|
-
},
|
|
995
|
-
resolveId(id) {
|
|
996
|
-
if (isClientModule(id)) return PRACHT_CLIENT_MODULE_ID;
|
|
997
|
-
if (isServerModule(id)) return PRACHT_SERVER_MODULE_ID;
|
|
998
|
-
return null;
|
|
999
|
-
},
|
|
1000
|
-
load(id) {
|
|
1001
|
-
if (isClientModule(id)) return createPrachtClientModuleSource(resolved, { root });
|
|
1002
|
-
if (isServerModule(id)) return createPrachtServerModuleSource(resolved, {
|
|
1003
|
-
root,
|
|
1004
|
-
isBuild
|
|
1005
|
-
});
|
|
1006
|
-
return null;
|
|
1007
|
-
},
|
|
1008
|
-
transform(code, id) {
|
|
1009
|
-
if (id !== resolve(root, resolved.appFile.slice(1))) return null;
|
|
1010
|
-
const transformed = code.replace(/\(\)\s*=>\s*import\(\s*(['"])([^'"]+)\1\s*\)/g, "$1$2$1");
|
|
1011
|
-
if (transformed === code) return null;
|
|
1012
|
-
return {
|
|
1013
|
-
code: transformed,
|
|
1014
|
-
map: null
|
|
1015
|
-
};
|
|
1016
|
-
},
|
|
1017
|
-
configureServer(server) {
|
|
1018
|
-
if (isPagesMode) {
|
|
1019
|
-
const abs = resolve(root, resolved.pagesDir.slice(1));
|
|
1020
|
-
server.watcher.on("add", (f) => {
|
|
1021
|
-
if (f.startsWith(abs)) server.restart();
|
|
1022
|
-
});
|
|
1023
|
-
server.watcher.on("unlink", (f) => {
|
|
1024
|
-
if (f.startsWith(abs)) server.restart();
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
if (resolved.adapter.ownsDevServer) return;
|
|
1028
|
-
return () => {
|
|
1029
|
-
server.middlewares.use(createDevSSRMiddleware(server, resolved));
|
|
1030
|
-
};
|
|
1031
|
-
},
|
|
1032
|
-
handleHotUpdate({ file, server }) {
|
|
1033
|
-
const root = server.config.root;
|
|
1034
|
-
const relative = file.startsWith(root) ? file.slice(root.length) : file;
|
|
1035
|
-
if (isPagesMode && relative.startsWith(resolved.pagesDir)) {
|
|
1036
|
-
const clientMod = server.moduleGraph.getModuleById(PRACHT_CLIENT_MODULE_ID);
|
|
1037
|
-
const serverMod = server.moduleGraph.getModuleById(PRACHT_SERVER_MODULE_ID);
|
|
1038
|
-
if (clientMod) server.moduleGraph.invalidateModule(clientMod);
|
|
1039
|
-
if (serverMod) server.moduleGraph.invalidateModule(serverMod);
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
if (!isPagesMode && relative === resolved.appFile) {
|
|
1043
|
-
server.restart();
|
|
1044
|
-
return [];
|
|
1045
|
-
}
|
|
1046
|
-
if ([
|
|
1047
|
-
resolved.routesDir,
|
|
1048
|
-
resolved.shellsDir,
|
|
1049
|
-
resolved.middlewareDir,
|
|
1050
|
-
resolved.apiDir,
|
|
1051
|
-
resolved.serverDir
|
|
1052
|
-
].some((dir) => relative.startsWith(dir))) {
|
|
1053
|
-
const serverMod = server.moduleGraph.getModuleById(PRACHT_SERVER_MODULE_ID);
|
|
1054
|
-
if (serverMod) server.moduleGraph.invalidateModule(serverMod);
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
};
|
|
1058
|
-
const clientModuleTransformPlugin = {
|
|
1059
|
-
name: "pracht:client-module-transform",
|
|
1060
|
-
enforce: "post",
|
|
1061
|
-
transform(code, id) {
|
|
1062
|
-
if (!isPrachtClientModuleId(id)) return null;
|
|
1063
|
-
const transformed = stripServerOnlyExportsForClient(code, id);
|
|
1064
|
-
if (transformed === code) return null;
|
|
1065
|
-
return {
|
|
1066
|
-
code: transformed,
|
|
1067
|
-
map: null
|
|
1068
|
-
};
|
|
1069
|
-
}
|
|
998
|
+
function resolveOptions(options) {
|
|
999
|
+
return {
|
|
1000
|
+
...DEFAULTS,
|
|
1001
|
+
...options
|
|
1070
1002
|
};
|
|
1071
|
-
const plugins = [
|
|
1072
|
-
...preact(),
|
|
1073
|
-
prachtPlugin,
|
|
1074
|
-
clientModuleTransformPlugin
|
|
1075
|
-
];
|
|
1076
|
-
const adapterPlugins = await resolved.adapter.vitePlugins?.();
|
|
1077
|
-
if (adapterPlugins?.length) plugins.push(...adapterPlugins);
|
|
1078
|
-
return plugins;
|
|
1079
1003
|
}
|
|
1004
|
+
//#endregion
|
|
1005
|
+
//#region src/plugin-codegen.ts
|
|
1080
1006
|
function createPrachtClientModuleSource(options = {}, buildOptions = {}) {
|
|
1081
1007
|
const resolved = resolveOptions(options);
|
|
1082
1008
|
const isPagesMode = !!resolved.pagesDir;
|
|
@@ -1140,7 +1066,7 @@ function createPrachtServerModuleSource(options = {}, buildOptions = {}) {
|
|
|
1140
1066
|
"export const resolvedApp = resolveApp(app);",
|
|
1141
1067
|
`export const apiRoutes = resolveApiRoutes(Object.keys(apiModules), ${JSON.stringify(resolved.apiDir)});`,
|
|
1142
1068
|
`export const buildTarget = ${JSON.stringify(adapter?.id ?? "node")};`,
|
|
1143
|
-
`export const clientEntryUrl = ${JSON.stringify(clientBuild.clientEntryUrl ??
|
|
1069
|
+
`export const clientEntryUrl = ${JSON.stringify(clientBuild.clientEntryUrl ?? "/@pracht/client.js")};`,
|
|
1144
1070
|
`export const cssManifest = ${JSON.stringify(clientBuild.cssManifest)};`,
|
|
1145
1071
|
`export const jsManifest = ${JSON.stringify(clientBuild.jsManifest)};`,
|
|
1146
1072
|
"export { prerenderApp };",
|
|
@@ -1178,7 +1104,11 @@ function generatePagesAppInlineSource(options, root = process.cwd()) {
|
|
|
1178
1104
|
pagesDirPrefix: options.pagesDir
|
|
1179
1105
|
});
|
|
1180
1106
|
}
|
|
1181
|
-
|
|
1107
|
+
//#endregion
|
|
1108
|
+
//#region src/plugin-dev-ssr.ts
|
|
1109
|
+
const BODYLESS_METHODS = new Set(["GET", "HEAD"]);
|
|
1110
|
+
const MAX_BODY_SIZE = 1024 * 1024;
|
|
1111
|
+
function createDevSSRMiddleware(server) {
|
|
1182
1112
|
return async (req, res, next) => {
|
|
1183
1113
|
const url = req.url ?? "/";
|
|
1184
1114
|
const pathname = new URL(url, "http://localhost").pathname;
|
|
@@ -1214,34 +1144,36 @@ function createDevSSRMiddleware(server, _pluginOptions) {
|
|
|
1214
1144
|
});
|
|
1215
1145
|
res.end(body);
|
|
1216
1146
|
} catch (error) {
|
|
1217
|
-
|
|
1218
|
-
if (req.headers["x-pracht-route-state-request"] === "1") {
|
|
1219
|
-
res.statusCode = 500;
|
|
1220
|
-
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
1221
|
-
res.end(JSON.stringify({ error: {
|
|
1222
|
-
message: error instanceof Error ? error.message : String(error),
|
|
1223
|
-
name: error instanceof Error ? error.name : "Error",
|
|
1224
|
-
status: 500
|
|
1225
|
-
} }));
|
|
1226
|
-
return;
|
|
1227
|
-
}
|
|
1228
|
-
try {
|
|
1229
|
-
const { buildErrorOverlayHtml } = await server.ssrLoadModule("pracht/error-overlay");
|
|
1230
|
-
let html = buildErrorOverlayHtml({
|
|
1231
|
-
message: error instanceof Error ? error.message : String(error),
|
|
1232
|
-
stack: error instanceof Error ? error.stack : void 0
|
|
1233
|
-
});
|
|
1234
|
-
html = await server.transformIndexHtml(url, html);
|
|
1235
|
-
res.statusCode = 500;
|
|
1236
|
-
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
1237
|
-
res.end(html);
|
|
1238
|
-
} catch {
|
|
1239
|
-
next(error);
|
|
1240
|
-
}
|
|
1147
|
+
await handleDevError(server, req, res, next, url, error);
|
|
1241
1148
|
}
|
|
1242
1149
|
};
|
|
1243
1150
|
}
|
|
1244
|
-
|
|
1151
|
+
async function handleDevError(server, req, res, next, url, error) {
|
|
1152
|
+
if (error instanceof Error) server.ssrFixStacktrace(error);
|
|
1153
|
+
if (req.headers["x-pracht-route-state-request"] === "1") {
|
|
1154
|
+
res.statusCode = 500;
|
|
1155
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
1156
|
+
res.end(JSON.stringify({ error: {
|
|
1157
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1158
|
+
name: error instanceof Error ? error.name : "Error",
|
|
1159
|
+
status: 500
|
|
1160
|
+
} }));
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
try {
|
|
1164
|
+
const { buildErrorOverlayHtml } = await server.ssrLoadModule("pracht/error-overlay");
|
|
1165
|
+
let html = buildErrorOverlayHtml({
|
|
1166
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1167
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
1168
|
+
});
|
|
1169
|
+
html = await server.transformIndexHtml(url, html);
|
|
1170
|
+
res.statusCode = 500;
|
|
1171
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
1172
|
+
res.end(html);
|
|
1173
|
+
} catch {
|
|
1174
|
+
next(error);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1245
1177
|
async function nodeToWebRequest(req) {
|
|
1246
1178
|
const protocol = "http";
|
|
1247
1179
|
const host = req.headers.host ?? "localhost";
|
|
@@ -1258,7 +1190,6 @@ async function nodeToWebRequest(req) {
|
|
|
1258
1190
|
headers
|
|
1259
1191
|
};
|
|
1260
1192
|
if (!BODYLESS_METHODS.has(method.toUpperCase())) {
|
|
1261
|
-
const MAX_BODY_SIZE = 1024 * 1024;
|
|
1262
1193
|
const chunks = [];
|
|
1263
1194
|
let totalSize = 0;
|
|
1264
1195
|
for await (const chunk of req) {
|
|
@@ -1275,55 +1206,151 @@ async function nodeToWebRequest(req) {
|
|
|
1275
1206
|
}
|
|
1276
1207
|
return new Request(url, init);
|
|
1277
1208
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1209
|
+
//#endregion
|
|
1210
|
+
//#region src/index.ts
|
|
1211
|
+
async function pracht(options = {}) {
|
|
1212
|
+
const resolved = resolveOptions(options);
|
|
1213
|
+
const isPagesMode = !!resolved.pagesDir;
|
|
1214
|
+
let root = process.cwd();
|
|
1215
|
+
let routeFileDirs = [];
|
|
1216
|
+
if (isPagesMode && options.appFile) console.warn("[pracht] Both `pagesDir` and `appFile` are set. `pagesDir` takes precedence — `appFile` will be ignored.");
|
|
1217
|
+
let isBuild = false;
|
|
1218
|
+
const prachtPlugin = {
|
|
1219
|
+
name: "pracht",
|
|
1220
|
+
enforce: "pre",
|
|
1221
|
+
config(_config, env) {
|
|
1222
|
+
const isEdge = resolved.adapter.edge === true;
|
|
1223
|
+
const isSSRBuild = env.isSsrBuild;
|
|
1224
|
+
return {
|
|
1225
|
+
appType: "custom",
|
|
1226
|
+
build: { rollupOptions: { output: { manualChunks(id) {
|
|
1227
|
+
if (id.includes("node_modules/preact") || id.includes("node_modules/preact-suspense")) return "vendor";
|
|
1228
|
+
} } } },
|
|
1229
|
+
...isEdge && isSSRBuild ? { ssr: { noExternal: true } } : {}
|
|
1230
|
+
};
|
|
1231
|
+
},
|
|
1232
|
+
configResolved(config) {
|
|
1233
|
+
root = config.root;
|
|
1234
|
+
isBuild = config.command === "build";
|
|
1235
|
+
routeFileDirs = computeRouteFileDirs(root, resolved);
|
|
1236
|
+
},
|
|
1237
|
+
resolveId(id) {
|
|
1238
|
+
if (isClientModule(id)) return PRACHT_CLIENT_MODULE_ID;
|
|
1239
|
+
if (isServerModule(id)) return PRACHT_SERVER_MODULE_ID;
|
|
1240
|
+
return null;
|
|
1241
|
+
},
|
|
1242
|
+
load(id) {
|
|
1243
|
+
if (isClientModule(id)) return createPrachtClientModuleSource(resolved, { root });
|
|
1244
|
+
if (isServerModule(id)) return createPrachtServerModuleSource(resolved, {
|
|
1245
|
+
root,
|
|
1246
|
+
isBuild
|
|
1247
|
+
});
|
|
1248
|
+
return null;
|
|
1249
|
+
},
|
|
1250
|
+
transform(code, id) {
|
|
1251
|
+
if (id !== resolve(root, resolved.appFile.slice(1))) return null;
|
|
1252
|
+
const transformed = code.replace(/\(\)\s*=>\s*import\(\s*(['"])([^'"]+)\1\s*\)/g, "$1$2$1");
|
|
1253
|
+
if (transformed === code) return null;
|
|
1254
|
+
return {
|
|
1255
|
+
code: transformed,
|
|
1256
|
+
map: null
|
|
1257
|
+
};
|
|
1258
|
+
},
|
|
1259
|
+
configureServer(server) {
|
|
1260
|
+
if (isPagesMode) watchPagesDirectory(server, resolved, root);
|
|
1261
|
+
if (resolved.adapter.ownsDevServer) return;
|
|
1262
|
+
return () => {
|
|
1263
|
+
server.middlewares.use(createDevSSRMiddleware(server));
|
|
1264
|
+
};
|
|
1265
|
+
},
|
|
1266
|
+
handleHotUpdate({ file, server }) {
|
|
1267
|
+
const serverRoot = server.config.root;
|
|
1268
|
+
const relative = file.startsWith(serverRoot) ? file.slice(serverRoot.length) : file;
|
|
1269
|
+
if (isPagesMode && relative.startsWith(resolved.pagesDir)) {
|
|
1270
|
+
invalidateVirtualModules(server);
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
if (!isPagesMode && relative === resolved.appFile) {
|
|
1274
|
+
server.restart();
|
|
1275
|
+
return [];
|
|
1276
|
+
}
|
|
1277
|
+
if ([
|
|
1278
|
+
resolved.routesDir,
|
|
1279
|
+
resolved.shellsDir,
|
|
1280
|
+
resolved.middlewareDir,
|
|
1281
|
+
resolved.apiDir,
|
|
1282
|
+
resolved.serverDir
|
|
1283
|
+
].some((dir) => relative.startsWith(dir))) {
|
|
1284
|
+
const serverMod = server.moduleGraph.getModuleById(PRACHT_SERVER_MODULE_ID);
|
|
1285
|
+
if (serverMod) server.moduleGraph.invalidateModule(serverMod);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1290
1288
|
};
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
if (!entry) return;
|
|
1303
|
-
for (const c of entry.css ?? []) css.add(c);
|
|
1304
|
-
js.add(entry.file);
|
|
1305
|
-
for (const imp of entry.imports ?? []) collect(imp);
|
|
1289
|
+
const clientModuleTransformPlugin = {
|
|
1290
|
+
name: "pracht:client-module-transform",
|
|
1291
|
+
enforce: "post",
|
|
1292
|
+
transform(code, id, transformOptions) {
|
|
1293
|
+
if (!(isPrachtClientModuleId(id) || !transformOptions?.ssr && isRouteOrShellFile(id, routeFileDirs))) return null;
|
|
1294
|
+
const transformed = stripServerOnlyExportsForClient(code, id);
|
|
1295
|
+
if (transformed === code) return null;
|
|
1296
|
+
return {
|
|
1297
|
+
code: transformed,
|
|
1298
|
+
map: null
|
|
1299
|
+
};
|
|
1306
1300
|
}
|
|
1307
|
-
collect(key);
|
|
1308
|
-
return {
|
|
1309
|
-
css: [...css],
|
|
1310
|
-
js: [...js]
|
|
1311
|
-
};
|
|
1312
|
-
}
|
|
1313
|
-
const cssManifest = {};
|
|
1314
|
-
const jsManifest = {};
|
|
1315
|
-
for (const [key, entry] of Object.entries(manifest)) {
|
|
1316
|
-
if (!entry.src) continue;
|
|
1317
|
-
const deps = collectTransitiveDeps(key);
|
|
1318
|
-
const manifestKey = stripPrachtClientModuleQuery(entry.src);
|
|
1319
|
-
if (deps.css.length > 0) cssManifest[manifestKey] = deps.css.map((f) => `/${f}`);
|
|
1320
|
-
if (deps.js.length > 0) jsManifest[manifestKey] = deps.js.map((f) => `/${f}`);
|
|
1321
|
-
}
|
|
1322
|
-
return {
|
|
1323
|
-
clientEntryUrl: clientEntry ? `/${clientEntry.file}` : null,
|
|
1324
|
-
cssManifest,
|
|
1325
|
-
jsManifest
|
|
1326
1301
|
};
|
|
1302
|
+
const plugins = [
|
|
1303
|
+
...preact(),
|
|
1304
|
+
prachtPlugin,
|
|
1305
|
+
clientModuleTransformPlugin
|
|
1306
|
+
];
|
|
1307
|
+
const adapterPlugins = await resolved.adapter.vitePlugins?.();
|
|
1308
|
+
if (adapterPlugins?.length) plugins.push(...adapterPlugins);
|
|
1309
|
+
return plugins;
|
|
1310
|
+
}
|
|
1311
|
+
function watchPagesDirectory(server, resolved, root) {
|
|
1312
|
+
const abs = resolve(root, resolved.pagesDir.slice(1));
|
|
1313
|
+
server.watcher.on("add", (f) => {
|
|
1314
|
+
if (f.startsWith(abs)) server.restart();
|
|
1315
|
+
});
|
|
1316
|
+
server.watcher.on("unlink", (f) => {
|
|
1317
|
+
if (f.startsWith(abs)) server.restart();
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
function invalidateVirtualModules(server) {
|
|
1321
|
+
const clientMod = server.moduleGraph.getModuleById(PRACHT_CLIENT_MODULE_ID);
|
|
1322
|
+
const serverMod = server.moduleGraph.getModuleById(PRACHT_SERVER_MODULE_ID);
|
|
1323
|
+
if (clientMod) server.moduleGraph.invalidateModule(clientMod);
|
|
1324
|
+
if (serverMod) server.moduleGraph.invalidateModule(serverMod);
|
|
1325
|
+
}
|
|
1326
|
+
const ROUTE_FILE_EXTENSIONS = new Set([
|
|
1327
|
+
".ts",
|
|
1328
|
+
".tsx",
|
|
1329
|
+
".js",
|
|
1330
|
+
".jsx",
|
|
1331
|
+
".md",
|
|
1332
|
+
".mdx"
|
|
1333
|
+
]);
|
|
1334
|
+
function computeRouteFileDirs(root, resolved) {
|
|
1335
|
+
return (resolved.pagesDir ? [resolved.pagesDir] : [resolved.routesDir, resolved.shellsDir]).map((dir) => toPosixPath(resolve(root, dir.replace(/^\//, "")))).map(withTrailingSep);
|
|
1336
|
+
}
|
|
1337
|
+
function isRouteOrShellFile(id, dirs) {
|
|
1338
|
+
if (dirs.length === 0) return false;
|
|
1339
|
+
const queryStart = id.indexOf("?");
|
|
1340
|
+
const path = queryStart === -1 ? id : id.slice(0, queryStart);
|
|
1341
|
+
if (path.startsWith("\0") || path.startsWith("virtual:")) return false;
|
|
1342
|
+
const extIndex = path.lastIndexOf(".");
|
|
1343
|
+
if (extIndex === -1) return false;
|
|
1344
|
+
const ext = path.slice(extIndex);
|
|
1345
|
+
if (!ROUTE_FILE_EXTENSIONS.has(ext)) return false;
|
|
1346
|
+
const normalized = toPosixPath(path);
|
|
1347
|
+
return dirs.some((dir) => normalized.startsWith(dir));
|
|
1348
|
+
}
|
|
1349
|
+
function toPosixPath(p) {
|
|
1350
|
+
return p.replace(/\\/g, "/");
|
|
1351
|
+
}
|
|
1352
|
+
function withTrailingSep(p) {
|
|
1353
|
+
return p.endsWith("/") ? p : `${p}/`;
|
|
1327
1354
|
}
|
|
1328
1355
|
//#endregion
|
|
1329
1356
|
export { PRACHT_CLIENT_MODULE_ID, PRACHT_SERVER_MODULE_ID, createPrachtClientModuleSource, createPrachtRegistryModuleSource, createPrachtServerModuleSource, pracht };
|
package/dist/pages-router.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
2
1
|
import { basename, extname, join, relative } from "node:path";
|
|
2
|
+
import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
//#region src/pages-router.ts
|
|
4
4
|
const PAGE_EXTENSIONS = new Set([
|
|
5
5
|
".tsx",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pracht/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://github.com/JoviDeCroock/pracht/tree/main/packages/vite-plugin",
|
|
6
6
|
"bugs": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@preact/preset-vite": "^2.10.5",
|
|
33
33
|
"@prefresh/vite": "^2.0.0",
|
|
34
|
-
"@pracht/adapter-node": "0.1.
|
|
35
|
-
"@pracht/core": "0.
|
|
34
|
+
"@pracht/adapter-node": "0.1.9",
|
|
35
|
+
"@pracht/core": "0.3.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"vite": "^8.0.0"
|