Skip to content

Commit a40e231

Browse files
committed
Fix server function handler
1 parent 9942be9 commit a40e231

3 files changed

Lines changed: 61 additions & 41 deletions

File tree

packages/start/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"@babel/traverse": "^7.28.3",
4242
"@babel/types": "^7.28.5",
4343
"@solidjs/meta": "^0.29.4",
44-
"dismantle": "^0.6.0",
44+
"dismantle": "^0.6.1",
4545
"@types/babel__traverse": "^7.28.0",
4646
"@types/micromatch": "^4.0.9",
4747
"cookie-es": "^2.0.0",

packages/start/src/config/server-functions.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export function serverFunctionsPlugin(
231231
}
232232
return null;
233233
},
234-
load(id, opts) {
234+
async load(id, opts) {
235235
const mode = opts?.ssr ? 'server' : 'client';
236236
if (id === VIRTUAL_MODULE) {
237237
const current = new Debouncer(() =>
@@ -240,7 +240,8 @@ export function serverFunctionsPlugin(
240240
.join('\n'),
241241
);
242242
preload[mode] = current;
243-
return current.promise.reference;
243+
const result = await current.promise.reference;
244+
return result;
244245
}
245246
return null;
246247
},
@@ -278,24 +279,37 @@ export function serverFunctionsPlugin(
278279
if (!filter(id)) {
279280
return null;
280281
}
281-
const preloader = preload[mode];
282-
if (preloader) {
283-
preloader.defer();
282+
const clientPreloader = preload[mode];
283+
if (clientPreloader) {
284+
clientPreloader.defer();
284285
}
285-
const result = await compile(id, code, {
286+
const clientResult = await compile(id!, code, {
286287
...options,
287-
mode,
288+
mode: 'client',
289+
env,
290+
});
291+
invalidateModules(
292+
currentServer,
293+
mergeManifestRecord(manifest.client, {
294+
files: clientResult.files,
295+
entries: new Set(clientResult.entries),
296+
}),
297+
);
298+
const serverResult = await compile(id!, code, {
299+
...options,
300+
mode: 'server',
288301
env,
289302
});
290-
291303
invalidateModules(
292304
currentServer,
293-
mergeManifestRecord(manifest[mode], {
294-
files: result.files,
295-
entries: new Set(result.entries),
305+
mergeManifestRecord(manifest.server, {
306+
files: serverResult.files,
307+
entries: new Set(serverResult.entries),
296308
}),
297309
);
298310

311+
const result = opts?.ssr ? serverResult : clientResult;
312+
299313
return {
300314
code: result.code || '',
301315
map: result.map,

packages/start/src/fns/server.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,53 @@ import { getRequestEvent } from "solid-js/web";
22
import { provideRequestEvent } from "solid-js/web/storage";
33
import { registerServerFunction } from "./manifest.ts";
44

5+
function enhanceServerFunction<T extends any[], R>(
6+
id: string,
7+
fn: (...args: T) => Promise<R>,
8+
) {
9+
let baseURL = import.meta.env.BASE_URL ?? "/";
10+
if (!baseURL.endsWith("/")) baseURL += "/";
11+
12+
return new Proxy(fn, {
13+
get(target, prop, receiver) {
14+
if (prop === "url") {
15+
return `${baseURL}_server?id=${encodeURIComponent(id)}`;
16+
}
17+
if (prop === "GET") return receiver;
18+
return (target as any)[prop];
19+
},
20+
apply(target, thisArg, args: T) {
21+
const ogEvt = getRequestEvent();
22+
if (!ogEvt)
23+
throw new Error("Cannot call server function outside of a request");
24+
const evt = { ...ogEvt };
25+
evt.locals.serverFunctionMeta = {
26+
id,
27+
};
28+
evt.serverOnly = true;
29+
return provideRequestEvent(evt, () => {
30+
return fn.apply(thisArg, args);
31+
});
32+
},
33+
});
34+
}
35+
536
export function createServerReference<T extends any[], R>(
637
id: string,
738
fn: (...args: T) => Promise<R>,
839
) {
940
let baseURL = import.meta.env.BASE_URL ?? "/";
1041
if (!baseURL.endsWith("/")) baseURL += "/";
1142

12-
return registerServerFunction(
13-
id,
14-
new Proxy(fn, {
15-
get(target, prop, receiver) {
16-
if (prop === "url") {
17-
return `${baseURL}_server?id=${encodeURIComponent(id)}`;
18-
}
19-
if (prop === "GET") return receiver;
20-
return (target as any)[prop];
21-
},
22-
apply(target, thisArg, args: T) {
23-
const ogEvt = getRequestEvent();
24-
if (!ogEvt)
25-
throw new Error("Cannot call server function outside of a request");
26-
const evt = { ...ogEvt };
27-
evt.locals.serverFunctionMeta = {
28-
id,
29-
};
30-
evt.serverOnly = true;
31-
return provideRequestEvent(evt, () => {
32-
return fn.apply(thisArg, args);
33-
});
34-
},
35-
}),
36-
);
43+
return registerServerFunction(id, enhanceServerFunction(id, fn));
3744
}
3845

3946
export function createServerFunction<T extends any[], R>(
4047
id: string,
4148
fn: () => Promise<(...args: T) => Promise<R>>,
4249
) {
43-
let instance: (...args: T) => Promise<R>;
44-
return createServerReference(id, async (...args: T) => {
45-
instance = instance || (await fn());
46-
return instance(...args);
50+
let instance = fn();
51+
return enhanceServerFunction(id, async (...args: T) => {
52+
return (await instance)(...args);
4753
});
4854
}

0 commit comments

Comments
 (0)