Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/violet-steaks-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solidjs/start": patch
---

Adopt tanstack server functions plugin
51 changes: 34 additions & 17 deletions packages/start/config/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { serverFunctions } from "@vinxi/server-functions/plugin";
import { server as serverFunctionServer, serverTransform } from "@vinxi/server-functions/server";
import { createTanStackServerFnPlugin } from "@tanstack/server-functions-plugin";
import defu from "defu";
import { existsSync } from "node:fs";
import { join } from "node:path";
Expand Down Expand Up @@ -38,6 +37,36 @@ function solidStartServerFsRouter(config) {
);
}

const SolidStartServerFnsPlugin = createTanStackServerFnPlugin({
// This is the ID that will be available to look up and import
// our server function manifest and resolve its module
manifestVirtualImportId: "solidstart:server-fn-manifest",
client: {
getRuntimeCode: () =>
`import { createServerReference } from "${normalize(
fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
Comment thread
katywings marked this conversation as resolved.
)}"`,
replacer: opts =>
`createServerReference(${() => {}}, '${opts.functionId}', '${opts.extractedFilename}')`
},
ssr: {
getRuntimeCode: () =>
`import { createServerReference } from '${normalize(
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
)}'`,
replacer: opts =>
`createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
},
server: {
getRuntimeCode: () =>
`import { createServerReference } from '${normalize(
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
)}'`,
replacer: opts =>
`createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
}
});

export function defineConfig(baseConfig = {}) {
let { vite = {}, ...start } = baseConfig;
const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])];
Expand Down Expand Up @@ -112,11 +141,7 @@ export function defineConfig(baseConfig = {}) {
}
}),
...plugins,
serverTransform({
runtime: normalize(
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
)
}),
SolidStartServerFnsPlugin.ssr,
start.experimental.islands ? serverComponents.server() : null,
solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
config("app-server", {
Expand Down Expand Up @@ -177,11 +202,7 @@ export function defineConfig(baseConfig = {}) {
}
}),
...plugins,
serverFunctions.client({
runtime: normalize(
fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
)
}),
SolidStartServerFnsPlugin.client,
start.experimental.islands ? serverComponents.client() : null,
solid({ ...start.solid, ssr: start.ssr, extensions: extensions.map(ext => `.${ext}`) }),
config("app-client", {
Expand Down Expand Up @@ -247,11 +268,7 @@ export function defineConfig(baseConfig = {}) {
cacheDir: "node_modules/.vinxi/server-fns"
}),
...plugins,
serverFunctionServer({
runtime: normalize(
fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
)
}),
SolidStartServerFnsPlugin.server,
start.experimental.islands ? serverComponents.server() : null,
solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
config("app-server", {
Expand Down
2 changes: 1 addition & 1 deletion packages/start/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"dependencies": {
"@vinxi/plugin-directives": "^0.4.3",
"@vinxi/server-components": "^0.4.3",
"@vinxi/server-functions": "^0.4.3",
"@tanstack/server-functions-plugin": "^1.97.2",
"defu": "^6.1.2",
"error-stack-parser": "^2.1.4",
"html-to-image": "^1.11.11",
Expand Down
33 changes: 25 additions & 8 deletions packages/start/src/runtime/server-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { getExpectedRedirectStatus } from "../server/handler";
import { createPageEvent } from "../server/pageEvent";
// @ts-ignore
import { FetchEvent, PageEvent } from "../server";
// @ts-ignore
import serverFnManifest from "solidstart:server-fn-manifest";

function createChunk(data: string) {
const encodeData = new TextEncoder().encode(data);
Expand Down Expand Up @@ -78,19 +80,34 @@ async function handleServerFunction(h3Event: HTTPEvent) {
const instance = request.headers.get("X-Server-Instance");
const singleFlight = request.headers.has("X-Single-Flight");
const url = new URL(request.url);
let filepath: string | undefined | null, name: string | undefined | null;
let functionId: string | undefined | null, name: string | undefined | null;
if (serverReference) {
invariant(typeof serverReference === "string", "Invalid server function");
[filepath, name] = serverReference.split("#");
[functionId, name] = serverReference.split("#");
} else {
filepath = url.searchParams.get("id");
functionId = url.searchParams.get("id");
name = url.searchParams.get("name");
if (!filepath || !name) throw new Error("Invalid request");
if (!functionId || !name) throw new Error("Invalid request");
}

const serverFnInfo = serverFnManifest[functionId];
let fnModule: undefined | { [key: string]: any };


if (process.env.NODE_ENV === "development") {
Comment thread
birkskyum marked this conversation as resolved.
// In dev, we use Vinxi to get the "server" server-side router
// Then we use that router's devServer.ssrLoadModule to get the serverFn

// This code comes from:
// https://github.com/TanStack/router/blob/266f5cc863cd1a99809d1af2669e58b6b6db9a67/packages/start-server-functions-handler/src/index.tsx#L83-L87
fnModule = await (globalThis as any).app
.getRouter("server-fns")
.internals.devServer.ssrLoadModule(serverFnInfo.extractedFilename);
} else {
fnModule = await serverFnInfo.importer();
}
const serverFunction = fnModule![serverFnInfo.functionName];

const serverFunction = (
await import.meta.env.MANIFEST[import.meta.env.ROUTER_NAME]!.chunks[filepath!]!.import()
)[name!];
let parsed: any[] = [];

// grab bound arguments from url when no JS
Expand Down Expand Up @@ -176,7 +193,7 @@ async function handleServerFunction(h3Event: HTTPEvent) {
/* @ts-ignore */
sharedConfig.context = { event };
event.locals.serverFunctionMeta = {
id: filepath + "#" + name
id: functionId + "#" + name
};
return serverFunction(...parsed);
});
Expand Down
Loading