From de833ebcef66d8846ac1e121327243735f740aa1 Mon Sep 17 00:00:00 2001 From: Katja Lutz Date: Sun, 31 Dec 2023 17:02:43 +0100 Subject: [PATCH] feat: implement getServerFunctionMeta Refs: nksaraf/vinxi#51 --- docs/routes/api/server.md | 23 +++++++++++++++++++++ packages/start/config/server-fns-runtime.ts | 3 +++ packages/start/server/index.ts | 2 +- packages/start/server/serverFunction.tsx | 6 ++++++ packages/start/server/types.ts | 4 ++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 packages/start/server/serverFunction.tsx diff --git a/docs/routes/api/server.md b/docs/routes/api/server.md index 4d1faf751..7b90a6cf7 100644 --- a/docs/routes/api/server.md +++ b/docs/routes/api/server.md @@ -44,3 +44,26 @@ In this example, regardless of whether we are rendering this on the server or in ### Serialization Server functions allow the serialization of many different data types in the response. The full list is available [here](https://github.com/lxsmnsyc/seroval/blob/main/docs/compatibility.md#supported-types). + +### Meta information + +Depending on your hosting, the server function might be running in parallel on multiple cpu cores or workers. You can use `getServerFunctionMeta` to retrieve a function-specific `id`, which is stable across all instances. + +Keep in mind: this `id` can and will change between builds! + +```tsx twoslash +import { getServerFunctionMeta } from "@solidjs/start/server"; + +// or some in-memory db +const appCache: any = globalThis; + +const counter = async () => { + "use server"; + const { id } = getServerFunctionMeta()!; + const key = `counter_${id}`; + appCache[key] = appCache[key] ?? 0; + appCache[key]++; + + return appCache[key] as number; +}; +``` diff --git a/packages/start/config/server-fns-runtime.ts b/packages/start/config/server-fns-runtime.ts index 55ad077e6..b21347c31 100644 --- a/packages/start/config/server-fns-runtime.ts +++ b/packages/start/config/server-fns-runtime.ts @@ -16,6 +16,9 @@ export function createServerReference(fn: Function, id: string, name: string) { const ogEvt = getRequestEvent(); if (!ogEvt) throw new Error("Cannot call server function outside of a request"); const evt = cloneEvent(ogEvt); + evt.locals.serverFunctionMeta = { + id: id + "#" + name, + }; evt.serverOnly = true; return provideRequestEvent(evt, () => { return fn.apply(thisArg, args); diff --git a/packages/start/server/index.ts b/packages/start/server/index.ts index c34c8b4cb..25b8f3859 100644 --- a/packages/start/server/index.ts +++ b/packages/start/server/index.ts @@ -1,4 +1,4 @@ export { StartServer } from "./StartServer"; export { createHandler } from "./handler"; +export { getServerFunctionMeta } from "./serverFunction"; export * from "./types"; - diff --git a/packages/start/server/serverFunction.tsx b/packages/start/server/serverFunction.tsx new file mode 100644 index 000000000..26ac8b539 --- /dev/null +++ b/packages/start/server/serverFunction.tsx @@ -0,0 +1,6 @@ +import { getRequestEvent } from "solid-js/web"; +import type { ServerFunctionMeta } from "./types"; + +export function getServerFunctionMeta(): ServerFunctionMeta | undefined { + return getRequestEvent()?.locals.serverFunctionMeta; +} diff --git a/packages/start/server/types.ts b/packages/start/server/types.ts index bbadc370f..a6bc5c4fc 100644 --- a/packages/start/server/types.ts +++ b/packages/start/server/types.ts @@ -71,6 +71,10 @@ export interface APIHandler { (event: APIEvent): Promise; } +export interface ServerFunctionMeta { + id: string; +} + declare module "solid-js/web" { interface RequestEvent extends FetchEvent { serverOnly?: boolean;