@solidjs/start 2.0.0-alpha.2 → 2.0.0-beta.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/CHANGELOG.md +35 -0
- package/dist/config/constants.d.ts +3 -3
- package/dist/config/constants.js +1 -1
- package/dist/config/dev-server.js +9 -1
- package/dist/config/env.d.ts +19 -0
- package/dist/config/env.js +81 -0
- package/dist/config/fs-routes/fs-watcher.js +32 -28
- package/dist/config/fs-routes/index.js +2 -2
- package/dist/config/fs-routes/router.d.ts +8 -3
- package/dist/config/fs-routes/router.js +26 -13
- package/dist/config/fs-routes/tree-shake.js +0 -43
- package/dist/config/index.d.ts +16 -1
- package/dist/config/index.js +31 -31
- package/dist/config/lazy.js +4 -2
- package/dist/config/manifest.js +41 -7
- package/dist/config/vite-utils.d.ts +1 -1
- package/dist/directives/bubble-function-declaration.d.ts +3 -0
- package/dist/directives/bubble-function-declaration.js +23 -0
- package/dist/directives/compile.d.ts +9 -0
- package/dist/directives/compile.js +40 -0
- package/dist/directives/generate-unique-name.d.ts +3 -0
- package/dist/directives/generate-unique-name.js +16 -0
- package/dist/directives/get-descriptive-name.d.ts +2 -0
- package/dist/directives/get-descriptive-name.js +37 -0
- package/dist/directives/get-import-identifier.d.ts +4 -0
- package/dist/directives/get-import-identifier.js +19 -0
- package/dist/directives/get-root-statement-path.d.ts +2 -0
- package/dist/directives/get-root-statement-path.js +12 -0
- package/dist/directives/index.d.ts +14 -0
- package/dist/directives/index.js +170 -0
- package/dist/directives/is-statement-top-level.d.ts +3 -0
- package/dist/directives/is-statement-top-level.js +9 -0
- package/dist/directives/paths.d.ts +9 -0
- package/dist/directives/paths.js +36 -0
- package/dist/directives/plugin.d.ts +21 -0
- package/dist/directives/plugin.js +302 -0
- package/dist/directives/remove-unused-variables.d.ts +3 -0
- package/dist/directives/remove-unused-variables.js +66 -0
- package/dist/directives/types.d.ts +10 -0
- package/dist/directives/xxhash32.d.ts +6 -0
- package/dist/directives/xxhash32.js +193 -0
- package/dist/{server/server-runtime.d.ts → fns/client.d.ts} +1 -1
- package/dist/fns/client.js +106 -0
- package/dist/fns/handler.d.ts +5 -0
- package/dist/{server/server-functions-handler.js → fns/handler.js} +55 -96
- package/dist/fns/registration.d.ts +2 -0
- package/dist/fns/registration.js +12 -0
- package/dist/fns/serialization.d.ts +6 -0
- package/dist/fns/serialization.js +208 -0
- package/dist/fns/server.d.ts +7 -0
- package/dist/{server/server-fns-runtime.js → fns/server.js} +7 -1
- package/dist/fns/shared.d.ts +17 -0
- package/dist/fns/shared.js +105 -0
- package/dist/http/index.d.ts +1 -1
- package/dist/middleware/index.d.ts +17 -0
- package/dist/middleware/index.js +15 -0
- package/dist/server/handler.d.ts +61 -3
- package/dist/server/handler.js +18 -16
- package/dist/server/spa/handler.d.ts +30 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/shared/dev-overlay/CodeView.jsx +4 -4
- package/dist/shared/dev-overlay/DevOverlayDialog.jsx +34 -34
- package/dist/shared/dev-overlay/index.jsx +2 -2
- package/dist/shared/dev-overlay/styles.css +40 -40
- package/dist/utils/debounce.d.ts +4 -0
- package/dist/utils/debounce.js +10 -0
- package/package.json +28 -21
- package/src/config/constants.ts +3 -3
- package/src/config/env.ts +105 -0
- package/src/config/fs-routes/fs-watcher.ts +38 -49
- package/src/config/fs-routes/index.ts +2 -2
- package/src/config/fs-routes/router.ts +29 -13
- package/src/config/fs-routes/tree-shake.ts +1 -48
- package/src/config/index.ts +45 -41
- package/src/config/lazy.ts +3 -2
- package/src/config/manifest.ts +45 -10
- package/src/config/vite-utils.ts +1 -1
- package/src/directives/bubble-function-declaration.ts +33 -0
- package/src/directives/compile.ts +54 -0
- package/src/directives/generate-unique-name.ts +22 -0
- package/src/directives/get-descriptive-name.ts +39 -0
- package/src/directives/get-import-identifier.ts +34 -0
- package/src/directives/get-root-statement-path.ts +14 -0
- package/src/directives/index.ts +233 -0
- package/src/directives/is-statement-top-level.ts +13 -0
- package/src/directives/paths.ts +63 -0
- package/src/directives/plugin.ts +389 -0
- package/src/directives/remove-unused-variables.ts +70 -0
- package/src/directives/types.ts +12 -0
- package/src/directives/xxhash32.ts +214 -0
- package/src/env.d.ts +1 -1
- package/src/fns/client.ts +141 -0
- package/src/fns/handler.spec.ts +85 -0
- package/src/{server/server-functions-handler.ts → fns/handler.ts} +65 -117
- package/src/fns/registration.ts +19 -0
- package/src/fns/serialization.ts +250 -0
- package/src/{server/server-fns-runtime.ts → fns/server.ts} +17 -2
- package/src/fns/shared.ts +116 -0
- package/src/middleware/index.ts +17 -0
- package/src/server/handler.ts +19 -17
- package/src/server/types.ts +1 -1
- package/src/shared/dev-overlay/CodeView.tsx +5 -7
- package/src/shared/dev-overlay/DevOverlayDialog.tsx +34 -34
- package/src/shared/dev-overlay/get-source-map.ts +1 -1
- package/src/shared/dev-overlay/index.tsx +4 -4
- package/src/shared/dev-overlay/styles.css +40 -40
- package/src/utils/debounce.ts +10 -0
- package/tsconfig.json +1 -0
- package/dist/server/fetchEvent.spec.js +0 -65
- package/dist/server/server-fns-runtime.d.ts +0 -1
- package/dist/server/server-functions-handler.d.ts +0 -2
- package/dist/server/server-runtime.js +0 -194
- package/src/server/server-runtime.ts +0 -240
- /package/dist/{server/fetchEvent.spec.d.ts → directives/types.js} +0 -0
package/dist/config/manifest.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { version as viteVersion } from "vite";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
1
5
|
import { findStylesInModuleGraph } from "../server/collect-styles.js";
|
|
2
6
|
import { VIRTUAL_MODULES } from "./constants.js";
|
|
3
7
|
import { wrapId } from "./vite-utils.js";
|
|
@@ -13,11 +17,11 @@ export function manifest(start) {
|
|
|
13
17
|
if (id === VIRTUAL_MODULES.clientViteManifest)
|
|
14
18
|
return `\0${VIRTUAL_MODULES.clientViteManifest}`;
|
|
15
19
|
if (id === VIRTUAL_MODULES.getClientManifest)
|
|
16
|
-
return this.resolve(new URL("../server/manifest/client-manifest", import.meta.url)
|
|
20
|
+
return this.resolve(fileURLToPath(new URL("../server/manifest/client-manifest", import.meta.url)));
|
|
17
21
|
if (id === VIRTUAL_MODULES.getManifest) {
|
|
18
22
|
return this.environment.config.consumer === "client"
|
|
19
|
-
? this.resolve(new URL("../server/manifest/client-manifest", import.meta.url)
|
|
20
|
-
: this.resolve(new URL("../server/manifest/ssr-manifest", import.meta.url)
|
|
23
|
+
? this.resolve(fileURLToPath(new URL("../server/manifest/client-manifest", import.meta.url)))
|
|
24
|
+
: this.resolve(fileURLToPath(new URL("../server/manifest/ssr-manifest", import.meta.url)));
|
|
21
25
|
}
|
|
22
26
|
if (id === VIRTUAL_MODULES.middleware) {
|
|
23
27
|
if (start.middleware)
|
|
@@ -35,7 +39,37 @@ export function manifest(start) {
|
|
|
35
39
|
const entry = Object.values(globalThis.START_CLIENT_BUNDLE).find(v => "isEntry" in v && v.isEntry);
|
|
36
40
|
if (!entry)
|
|
37
41
|
throw new Error("No client entry found");
|
|
38
|
-
|
|
42
|
+
let rawManifest;
|
|
43
|
+
const viteMajor = parseInt(viteVersion.split('.')[0], 10);
|
|
44
|
+
const manifestKey = Object.keys(globalThis.START_CLIENT_BUNDLE).find(k => k.endsWith("manifest.json"));
|
|
45
|
+
if (manifestKey && viteMajor < 8) {
|
|
46
|
+
const manifestAsset = globalThis.START_CLIENT_BUNDLE[manifestKey];
|
|
47
|
+
rawManifest = manifestAsset.source;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
try {
|
|
51
|
+
const appRoot = start.appRoot || "./src";
|
|
52
|
+
let outDir = ".solid-start/client";
|
|
53
|
+
if (devServer?.environments?.client?.config?.build?.outDir) {
|
|
54
|
+
outDir = devServer.environments.client.config.build.outDir;
|
|
55
|
+
}
|
|
56
|
+
else if (this.environment?.config?.build?.outDir && this.environment?.config?.consumer === "client") {
|
|
57
|
+
outDir = this.environment.config.build.outDir;
|
|
58
|
+
}
|
|
59
|
+
else if (globalThis.START_CLIENT_OUT_DIR) {
|
|
60
|
+
outDir = globalThis.START_CLIENT_OUT_DIR;
|
|
61
|
+
}
|
|
62
|
+
const manifestPath = path.resolve(appRoot, "..", outDir, ".vite/manifest.json");
|
|
63
|
+
rawManifest = fs.readFileSync(manifestPath, "utf-8");
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
throw new Error(`Manifest asset not found in bundle and could not be read from disk. Keys: ${Object.keys(globalThis.START_CLIENT_BUNDLE).join(", ")}. Error: ${e}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!rawManifest) {
|
|
70
|
+
throw new Error("Failed to extract or read raw manifest.");
|
|
71
|
+
}
|
|
72
|
+
clientViteManifest = JSON.parse(rawManifest);
|
|
39
73
|
}
|
|
40
74
|
return `export const clientViteManifest = ${JSON.stringify(clientViteManifest)};`;
|
|
41
75
|
}
|
|
@@ -44,12 +78,12 @@ export function manifest(start) {
|
|
|
44
78
|
else if (id.startsWith("/@manifest")) {
|
|
45
79
|
if (this.environment.mode !== "dev")
|
|
46
80
|
throw new Error("@manifest queries are only allowed in dev");
|
|
47
|
-
const [
|
|
81
|
+
const [urlPath, query] = id.split("?");
|
|
48
82
|
const target = id.split("/")[2];
|
|
49
83
|
const params = new URLSearchParams(query);
|
|
50
|
-
if (!
|
|
84
|
+
if (!urlPath || !query)
|
|
51
85
|
return;
|
|
52
|
-
if (
|
|
86
|
+
if (urlPath.endsWith("assets")) {
|
|
53
87
|
const id = params.get("id");
|
|
54
88
|
if (!id) {
|
|
55
89
|
throw new Error("Missing id to get assets.");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
export function bubbleFunctionDeclaration(path) {
|
|
3
|
+
const decl = path.node;
|
|
4
|
+
// Check if declaration is FunctionDeclaration
|
|
5
|
+
if (decl.id) {
|
|
6
|
+
const block = (path.findParent(current => current.isBlockStatement()) ||
|
|
7
|
+
path.scope.getProgramParent().path);
|
|
8
|
+
if (path.parentPath.isExportNamedDeclaration()) {
|
|
9
|
+
path.parentPath.replaceWith(t.exportNamedDeclaration(undefined, [t.exportSpecifier(decl.id, decl.id)]));
|
|
10
|
+
}
|
|
11
|
+
else if (path.parentPath.isExportDefaultDeclaration()) {
|
|
12
|
+
path.replaceWith(decl.id);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
path.remove();
|
|
16
|
+
}
|
|
17
|
+
const [tmp] = block.unshiftContainer("body", t.variableDeclaration("const", [
|
|
18
|
+
t.variableDeclarator(decl.id, t.functionExpression(decl.id, decl.params, decl.body, decl.generator, decl.async)),
|
|
19
|
+
]));
|
|
20
|
+
block.scope.registerDeclaration(tmp);
|
|
21
|
+
tmp.skip();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as babel from "@babel/core";
|
|
2
|
+
import { type StateContext } from "./plugin.ts";
|
|
3
|
+
export interface CompileResult {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
code: string;
|
|
6
|
+
map: babel.BabelFileResult["map"];
|
|
7
|
+
}
|
|
8
|
+
export type CompileOptions = Omit<StateContext, "count" | "hash" | "imports" | "valid">;
|
|
9
|
+
export declare function compile(id: string, code: string, options: CompileOptions): Promise<CompileResult>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as babel from "@babel/core";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { directivesPlugin } from "./plugin.js";
|
|
4
|
+
import xxHash32 from "./xxhash32.js";
|
|
5
|
+
export async function compile(id, code, options) {
|
|
6
|
+
const context = {
|
|
7
|
+
...options,
|
|
8
|
+
valid: false,
|
|
9
|
+
hash: xxHash32(id).toString(16),
|
|
10
|
+
count: 0,
|
|
11
|
+
imports: new Map(),
|
|
12
|
+
};
|
|
13
|
+
const pluginOption = [directivesPlugin, context];
|
|
14
|
+
const plugins = [
|
|
15
|
+
"jsx",
|
|
16
|
+
];
|
|
17
|
+
if (/\.[mc]?tsx?$/i.test(id)) {
|
|
18
|
+
plugins.push("typescript");
|
|
19
|
+
}
|
|
20
|
+
const result = await babel.transformAsync(code, {
|
|
21
|
+
plugins: [pluginOption],
|
|
22
|
+
parserOpts: {
|
|
23
|
+
plugins,
|
|
24
|
+
},
|
|
25
|
+
filename: path.basename(id),
|
|
26
|
+
ast: false,
|
|
27
|
+
sourceMaps: true,
|
|
28
|
+
configFile: false,
|
|
29
|
+
babelrc: false,
|
|
30
|
+
sourceFileName: id,
|
|
31
|
+
});
|
|
32
|
+
if (result) {
|
|
33
|
+
return {
|
|
34
|
+
valid: context.valid,
|
|
35
|
+
code: result.code || "",
|
|
36
|
+
map: result.map,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
throw new Error("invariant");
|
|
40
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
export function generateUniqueName(path, name) {
|
|
3
|
+
let uid;
|
|
4
|
+
let i = 1;
|
|
5
|
+
do {
|
|
6
|
+
uid = name + "_" + i;
|
|
7
|
+
i++;
|
|
8
|
+
} while (path.scope.hasLabel(uid) ||
|
|
9
|
+
path.scope.hasBinding(uid) ||
|
|
10
|
+
path.scope.hasGlobal(uid) ||
|
|
11
|
+
path.scope.hasReference(uid));
|
|
12
|
+
const program = path.scope.getProgramParent();
|
|
13
|
+
program.references[uid] = true;
|
|
14
|
+
program.uids[uid] = true;
|
|
15
|
+
return t.identifier(uid);
|
|
16
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function getDescriptiveName(path, defaultName) {
|
|
2
|
+
let current = path;
|
|
3
|
+
while (current) {
|
|
4
|
+
switch (current.node.type) {
|
|
5
|
+
case "FunctionDeclaration":
|
|
6
|
+
case "FunctionExpression": {
|
|
7
|
+
if (current.node.id) {
|
|
8
|
+
return current.node.id.name;
|
|
9
|
+
}
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
case "VariableDeclarator": {
|
|
13
|
+
if (current.node.id.type === "Identifier") {
|
|
14
|
+
return current.node.id.name;
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
case "ClassPrivateMethod":
|
|
19
|
+
case "ClassMethod":
|
|
20
|
+
case "ObjectMethod": {
|
|
21
|
+
switch (current.node.key.type) {
|
|
22
|
+
case "Identifier":
|
|
23
|
+
return current.node.key.name;
|
|
24
|
+
case "PrivateName":
|
|
25
|
+
return current.node.key.id.name;
|
|
26
|
+
default:
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
default:
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
current = current.parentPath;
|
|
35
|
+
}
|
|
36
|
+
return defaultName;
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type * as babel from "@babel/core";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import type { ImportDefinition } from "./types.ts";
|
|
4
|
+
export declare function getImportIdentifier(imports: Map<string, t.Identifier>, path: babel.NodePath, registration: ImportDefinition): t.Identifier;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { generateUniqueName } from "./generate-unique-name.js";
|
|
3
|
+
export function getImportIdentifier(imports, path, registration) {
|
|
4
|
+
const name = registration.kind === "named" ? registration.name : "default";
|
|
5
|
+
const target = `${registration.source}[${name}]`;
|
|
6
|
+
const current = imports.get(target);
|
|
7
|
+
if (current) {
|
|
8
|
+
return current;
|
|
9
|
+
}
|
|
10
|
+
const programParent = path.scope.getProgramParent();
|
|
11
|
+
const uid = generateUniqueName(programParent.path, name);
|
|
12
|
+
programParent.registerDeclaration(programParent.path.unshiftContainer("body", t.importDeclaration([
|
|
13
|
+
registration.kind === "named"
|
|
14
|
+
? t.importSpecifier(uid, t.identifier(registration.name))
|
|
15
|
+
: t.importDefaultSpecifier(uid),
|
|
16
|
+
], t.stringLiteral(registration.source)))[0]);
|
|
17
|
+
imports.set(target, uid);
|
|
18
|
+
return uid;
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
export function getRootStatementPath(path) {
|
|
3
|
+
let current = path.parentPath;
|
|
4
|
+
while (current) {
|
|
5
|
+
const next = current.parentPath;
|
|
6
|
+
if (next && t.isProgram(next.node)) {
|
|
7
|
+
return current;
|
|
8
|
+
}
|
|
9
|
+
current = next;
|
|
10
|
+
}
|
|
11
|
+
return path;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type FilterPattern, type Plugin } from "vite";
|
|
2
|
+
export interface ServerFunctionsFilter {
|
|
3
|
+
include?: FilterPattern;
|
|
4
|
+
exclude?: FilterPattern;
|
|
5
|
+
}
|
|
6
|
+
export interface ServerFunctionsOptions {
|
|
7
|
+
manifest: string;
|
|
8
|
+
runtime: {
|
|
9
|
+
server: string;
|
|
10
|
+
client: string;
|
|
11
|
+
};
|
|
12
|
+
filter?: ServerFunctionsFilter;
|
|
13
|
+
}
|
|
14
|
+
export declare function serverFunctionsPlugin(options: ServerFunctionsOptions): Plugin[];
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { createFilter, } from "vite";
|
|
2
|
+
import { compile } from "./compile.js";
|
|
3
|
+
const DEFAULT_INCLUDE = "src/**/*.{jsx,tsx,ts,js,mjs,cjs}";
|
|
4
|
+
const DEFAULT_EXCLUDE = "node_modules/**/*.{jsx,tsx,ts,js,mjs,cjs}";
|
|
5
|
+
const DIRECTIVE = "use server";
|
|
6
|
+
function createManifest() {
|
|
7
|
+
return {
|
|
8
|
+
server: new Set(),
|
|
9
|
+
client: new Set(),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function createDeferredPromise() {
|
|
13
|
+
let resolve;
|
|
14
|
+
let reject;
|
|
15
|
+
return {
|
|
16
|
+
reference: new Promise((res, rej) => {
|
|
17
|
+
resolve = res;
|
|
18
|
+
reject = rej;
|
|
19
|
+
}),
|
|
20
|
+
resolve(value) {
|
|
21
|
+
resolve(value);
|
|
22
|
+
},
|
|
23
|
+
reject(value) {
|
|
24
|
+
reject(value);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
class Debouncer {
|
|
29
|
+
source;
|
|
30
|
+
promise;
|
|
31
|
+
timeout;
|
|
32
|
+
constructor(source) {
|
|
33
|
+
this.source = source;
|
|
34
|
+
this.promise = createDeferredPromise();
|
|
35
|
+
this.defer();
|
|
36
|
+
}
|
|
37
|
+
defer() {
|
|
38
|
+
if (this.timeout) {
|
|
39
|
+
clearTimeout(this.timeout);
|
|
40
|
+
this.timeout = undefined;
|
|
41
|
+
}
|
|
42
|
+
this.timeout = setTimeout(() => {
|
|
43
|
+
this.promise.resolve(this.source());
|
|
44
|
+
}, 1000);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function mergeManifestRecord(source, target) {
|
|
48
|
+
const current = source.size;
|
|
49
|
+
for (const entry of target) {
|
|
50
|
+
source.add(entry);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
invalidPreload: current !== source.size,
|
|
54
|
+
invalidated: [...source],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function invalidateModule(moduleGraph, path) {
|
|
58
|
+
const target = moduleGraph.getModuleById(path);
|
|
59
|
+
if (target) {
|
|
60
|
+
moduleGraph.invalidateModule(target);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function invalidateModules(server, result, manifest) {
|
|
64
|
+
if (server) {
|
|
65
|
+
if (result.invalidPreload) {
|
|
66
|
+
invalidateModule(server.environments.client.moduleGraph, manifest);
|
|
67
|
+
invalidateModule(server.environments.ssr.moduleGraph, manifest);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function serverFunctionsPlugin(options) {
|
|
72
|
+
const filter = createFilter(options.filter?.include || DEFAULT_INCLUDE, options.filter?.exclude || DEFAULT_EXCLUDE);
|
|
73
|
+
let env;
|
|
74
|
+
const manifest = createManifest();
|
|
75
|
+
const preload = {
|
|
76
|
+
server: undefined,
|
|
77
|
+
client: undefined,
|
|
78
|
+
};
|
|
79
|
+
let currentServer;
|
|
80
|
+
const clientOptions = {
|
|
81
|
+
directive: DIRECTIVE,
|
|
82
|
+
definitions: {
|
|
83
|
+
register: {
|
|
84
|
+
kind: "named",
|
|
85
|
+
name: "createServerReference",
|
|
86
|
+
source: options.runtime.client,
|
|
87
|
+
},
|
|
88
|
+
clone: {
|
|
89
|
+
kind: "named",
|
|
90
|
+
name: "cloneServerReference",
|
|
91
|
+
source: options.runtime.client,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
const serverOptions = {
|
|
96
|
+
directive: DIRECTIVE,
|
|
97
|
+
definitions: {
|
|
98
|
+
register: {
|
|
99
|
+
kind: "named",
|
|
100
|
+
name: "createServerReference",
|
|
101
|
+
source: options.runtime.server,
|
|
102
|
+
},
|
|
103
|
+
clone: {
|
|
104
|
+
kind: "named",
|
|
105
|
+
name: "cloneServerReference",
|
|
106
|
+
source: options.runtime.server,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
name: "solid-start:server-functions/setup",
|
|
113
|
+
enforce: "pre",
|
|
114
|
+
configResolved(config) {
|
|
115
|
+
env = config.mode !== "production" ? "development" : "production";
|
|
116
|
+
},
|
|
117
|
+
configureServer(server) {
|
|
118
|
+
currentServer = server;
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "solid-start:server-functions/preload",
|
|
123
|
+
enforce: "pre",
|
|
124
|
+
resolveId(source) {
|
|
125
|
+
if (source === options.manifest) {
|
|
126
|
+
return { id: options.manifest, moduleSideEffects: true };
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
},
|
|
130
|
+
async load(id, opts) {
|
|
131
|
+
const mode = opts?.ssr ? "server" : "client";
|
|
132
|
+
if (id === options.manifest) {
|
|
133
|
+
const current = new Debouncer(() => [...manifest[mode]].map(entry => `import "${entry}";`).join("\n"));
|
|
134
|
+
preload[mode] = current;
|
|
135
|
+
const result = await current.promise.reference;
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "solid-start:server-functions/compiler",
|
|
143
|
+
enforce: 'pre',
|
|
144
|
+
async transform(code, fileId, opts) {
|
|
145
|
+
const mode = opts?.ssr ? "server" : "client";
|
|
146
|
+
const [id] = fileId.split("?");
|
|
147
|
+
if (!filter(id)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const result = await compile(id, code, {
|
|
151
|
+
...(mode === "server" ? serverOptions : clientOptions),
|
|
152
|
+
mode,
|
|
153
|
+
env,
|
|
154
|
+
});
|
|
155
|
+
if (result.valid) {
|
|
156
|
+
const preloader = preload[mode];
|
|
157
|
+
if (preloader) {
|
|
158
|
+
preloader.defer();
|
|
159
|
+
}
|
|
160
|
+
invalidateModules(currentServer, mergeManifestRecord(manifest.server, new Set([id])), options.manifest);
|
|
161
|
+
return {
|
|
162
|
+
code: result.code || "",
|
|
163
|
+
map: result.map,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function isStatementTopLevel(path) {
|
|
2
|
+
let blockParent = path.scope.getBlockParent();
|
|
3
|
+
const programParent = path.scope.getProgramParent();
|
|
4
|
+
// a FunctionDeclaration binding refers to itself as the block parent
|
|
5
|
+
if (blockParent.path === path) {
|
|
6
|
+
blockParent = blockParent.parent;
|
|
7
|
+
}
|
|
8
|
+
return programParent === blockParent;
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as t from "@babel/types";
|
|
2
|
+
type TypeFilter<V extends t.Node> = (node: t.Node) => node is V;
|
|
3
|
+
export declare function isPathValid<V extends t.Node>(path: unknown, key: TypeFilter<V>): path is babel.NodePath<V>;
|
|
4
|
+
export type NestedExpression = t.ParenthesizedExpression | t.TypeCastExpression | t.TSAsExpression | t.TSSatisfiesExpression | t.TSNonNullExpression | t.TSInstantiationExpression | t.TSTypeAssertion;
|
|
5
|
+
export declare function isNestedExpression(node: t.Node): node is NestedExpression;
|
|
6
|
+
type TypeCheck<K> = K extends TypeFilter<infer U> ? U : never;
|
|
7
|
+
export declare function unwrapNode<K extends (value: t.Node) => boolean>(node: t.Node, key: K): TypeCheck<K> | undefined;
|
|
8
|
+
export declare function unwrapPath<V extends t.Node>(path: unknown, key: TypeFilter<V>): babel.NodePath<V> | undefined;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function isPathValid(path, key) {
|
|
2
|
+
const node = path.node;
|
|
3
|
+
return node ? key(node) : false;
|
|
4
|
+
}
|
|
5
|
+
export function isNestedExpression(node) {
|
|
6
|
+
switch (node.type) {
|
|
7
|
+
case "ParenthesizedExpression":
|
|
8
|
+
case "TypeCastExpression":
|
|
9
|
+
case "TSAsExpression":
|
|
10
|
+
case "TSSatisfiesExpression":
|
|
11
|
+
case "TSNonNullExpression":
|
|
12
|
+
case "TSTypeAssertion":
|
|
13
|
+
case "TSInstantiationExpression":
|
|
14
|
+
return true;
|
|
15
|
+
default:
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function unwrapNode(node, key) {
|
|
20
|
+
if (key(node)) {
|
|
21
|
+
return node;
|
|
22
|
+
}
|
|
23
|
+
if (isNestedExpression(node)) {
|
|
24
|
+
return unwrapNode(node.expression, key);
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
export function unwrapPath(path, key) {
|
|
29
|
+
if (isPathValid(path, key)) {
|
|
30
|
+
return path;
|
|
31
|
+
}
|
|
32
|
+
if (isPathValid(path, isNestedExpression)) {
|
|
33
|
+
return unwrapPath(path.get("expression"), key);
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as babel from "@babel/core";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import type { ImportDefinition } from "./types.ts";
|
|
4
|
+
export interface StateContext {
|
|
5
|
+
env: "production" | "development";
|
|
6
|
+
mode: "server" | "client";
|
|
7
|
+
directive: string;
|
|
8
|
+
hash: string;
|
|
9
|
+
count: number;
|
|
10
|
+
imports: Map<string, t.Identifier>;
|
|
11
|
+
valid: boolean;
|
|
12
|
+
definitions: {
|
|
13
|
+
register: ImportDefinition;
|
|
14
|
+
clone: ImportDefinition;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
interface State extends babel.PluginPass {
|
|
18
|
+
opts: StateContext;
|
|
19
|
+
}
|
|
20
|
+
export declare function directivesPlugin(): babel.PluginObj<State>;
|
|
21
|
+
export {};
|