Skip to content

Commit 5a166a4

Browse files
authored
refactor: adopt @tanstack/server-functions-plugin (#1715)
1 parent f9f1ff7 commit 5a166a4

5 files changed

Lines changed: 503 additions & 287 deletions

File tree

.changeset/violet-steaks-mate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@solidjs/start": patch
3+
---
4+
5+
Adopt tanstack server functions plugin

packages/start/config/index.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { serverFunctions } from "@vinxi/server-functions/plugin";
2-
import { server as serverFunctionServer, serverTransform } from "@vinxi/server-functions/server";
1+
import { createTanStackServerFnPlugin } from "@tanstack/server-functions-plugin";
32
import defu from "defu";
43
import { existsSync } from "node:fs";
54
import { join } from "node:path";
@@ -38,6 +37,36 @@ function solidStartServerFsRouter(config) {
3837
);
3938
}
4039

40+
const SolidStartServerFnsPlugin = createTanStackServerFnPlugin({
41+
// This is the ID that will be available to look up and import
42+
// our server function manifest and resolve its module
43+
manifestVirtualImportId: "solidstart:server-fn-manifest",
44+
client: {
45+
getRuntimeCode: () =>
46+
`import { createServerReference } from "${normalize(
47+
fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
48+
)}"`,
49+
replacer: opts =>
50+
`createServerReference(${() => {}}, '${opts.functionId}', '${opts.extractedFilename}')`
51+
},
52+
ssr: {
53+
getRuntimeCode: () =>
54+
`import { createServerReference } from '${normalize(
55+
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
56+
)}'`,
57+
replacer: opts =>
58+
`createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
59+
},
60+
server: {
61+
getRuntimeCode: () =>
62+
`import { createServerReference } from '${normalize(
63+
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
64+
)}'`,
65+
replacer: opts =>
66+
`createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
67+
}
68+
});
69+
4170
export function defineConfig(baseConfig = {}) {
4271
let { vite = {}, ...start } = baseConfig;
4372
const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])];
@@ -112,11 +141,7 @@ export function defineConfig(baseConfig = {}) {
112141
}
113142
}),
114143
...plugins,
115-
serverTransform({
116-
runtime: normalize(
117-
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
118-
)
119-
}),
144+
SolidStartServerFnsPlugin.ssr,
120145
start.experimental.islands ? serverComponents.server() : null,
121146
solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
122147
config("app-server", {
@@ -177,11 +202,7 @@ export function defineConfig(baseConfig = {}) {
177202
}
178203
}),
179204
...plugins,
180-
serverFunctions.client({
181-
runtime: normalize(
182-
fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
183-
)
184-
}),
205+
SolidStartServerFnsPlugin.client,
185206
start.experimental.islands ? serverComponents.client() : null,
186207
solid({ ...start.solid, ssr: start.ssr, extensions: extensions.map(ext => `.${ext}`) }),
187208
config("app-client", {
@@ -247,11 +268,7 @@ export function defineConfig(baseConfig = {}) {
247268
cacheDir: "node_modules/.vinxi/server-fns"
248269
}),
249270
...plugins,
250-
serverFunctionServer({
251-
runtime: normalize(
252-
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
253-
)
254-
}),
271+
SolidStartServerFnsPlugin.server,
255272
start.experimental.islands ? serverComponents.server() : null,
256273
solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
257274
config("app-server", {

packages/start/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"dependencies": {
6767
"@vinxi/plugin-directives": "^0.4.3",
6868
"@vinxi/server-components": "^0.4.3",
69-
"@vinxi/server-functions": "^0.4.3",
69+
"@tanstack/server-functions-plugin": "^1.97.2",
7070
"defu": "^6.1.2",
7171
"error-stack-parser": "^2.1.4",
7272
"html-to-image": "^1.11.11",

packages/start/src/runtime/server-handler.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import { getExpectedRedirectStatus } from "../server/handler";
2323
import { createPageEvent } from "../server/pageEvent";
2424
// @ts-ignore
2525
import { FetchEvent, PageEvent } from "../server";
26+
// @ts-ignore
27+
import serverFnManifest from "solidstart:server-fn-manifest";
2628

2729
function createChunk(data: string) {
2830
const encodeData = new TextEncoder().encode(data);
@@ -78,19 +80,34 @@ async function handleServerFunction(h3Event: HTTPEvent) {
7880
const instance = request.headers.get("X-Server-Instance");
7981
const singleFlight = request.headers.has("X-Single-Flight");
8082
const url = new URL(request.url);
81-
let filepath: string | undefined | null, name: string | undefined | null;
83+
let functionId: string | undefined | null, name: string | undefined | null;
8284
if (serverReference) {
8385
invariant(typeof serverReference === "string", "Invalid server function");
84-
[filepath, name] = serverReference.split("#");
86+
[functionId, name] = serverReference.split("#");
8587
} else {
86-
filepath = url.searchParams.get("id");
88+
functionId = url.searchParams.get("id");
8789
name = url.searchParams.get("name");
88-
if (!filepath || !name) throw new Error("Invalid request");
90+
if (!functionId || !name) throw new Error("Invalid request");
91+
}
92+
93+
const serverFnInfo = serverFnManifest[functionId];
94+
let fnModule: undefined | { [key: string]: any };
95+
96+
97+
if (process.env.NODE_ENV === "development") {
98+
// In dev, we use Vinxi to get the "server" server-side router
99+
// Then we use that router's devServer.ssrLoadModule to get the serverFn
100+
101+
// This code comes from:
102+
// https://github.com/TanStack/router/blob/266f5cc863cd1a99809d1af2669e58b6b6db9a67/packages/start-server-functions-handler/src/index.tsx#L83-L87
103+
fnModule = await (globalThis as any).app
104+
.getRouter("server-fns")
105+
.internals.devServer.ssrLoadModule(serverFnInfo.extractedFilename);
106+
} else {
107+
fnModule = await serverFnInfo.importer();
89108
}
109+
const serverFunction = fnModule![serverFnInfo.functionName];
90110

91-
const serverFunction = (
92-
await import.meta.env.MANIFEST[import.meta.env.ROUTER_NAME]!.chunks[filepath!]!.import()
93-
)[name!];
94111
let parsed: any[] = [];
95112

96113
// grab bound arguments from url when no JS
@@ -176,7 +193,7 @@ async function handleServerFunction(h3Event: HTTPEvent) {
176193
/* @ts-ignore */
177194
sharedConfig.context = { event };
178195
event.locals.serverFunctionMeta = {
179-
id: filepath + "#" + name
196+
id: functionId + "#" + name
180197
};
181198
return serverFunction(...parsed);
182199
});

0 commit comments

Comments
 (0)