diff --git a/examples/next-js/src/app/api/counter/route.ts b/examples/next-js/src/app/api/counter/route.ts deleted file mode 100644 index d3c604797..000000000 --- a/examples/next-js/src/app/api/counter/route.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { counter } from "@/lib/counter"; - -export const runtime = "nodejs"; // optional, fine for Node runtime - -console.log("=== LOAD ROUTE ==="); - -export async function GET() { - return Response.json({ value: counter.value }); -} - -export async function POST(req: Request) { - const body = await req.json().catch(() => ({})); - const by = Number(body?.by ?? 1); - counter.value += Number.isFinite(by) ? by : 1; - return Response.json({ value: counter.value }); -} diff --git a/examples/next-js/src/app/api/rivet/[...all]/route.ts b/examples/next-js/src/app/api/rivet/[...all]/route.ts index 32663d263..6c9669741 100644 --- a/examples/next-js/src/app/api/rivet/[...all]/route.ts +++ b/examples/next-js/src/app/api/rivet/[...all]/route.ts @@ -1,3 +1,4 @@ -import { handlers } from "@/lib/rivet-server"; +import { toNextHandler } from "@rivetkit/next-js"; +import { registry } from "@/rivet/registry"; -export const { GET, POST, PUT, PATCH, HEAD, OPTIONS } = handlers.value; +export const { GET, POST, PUT, PATCH, HEAD, OPTIONS } = toNextHandler(registry); diff --git a/examples/next-js/src/lib/counter.ts b/examples/next-js/src/lib/counter.ts deleted file mode 100644 index 17191a161..000000000 --- a/examples/next-js/src/lib/counter.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare global { - // eslint-disable-next-line no-var - var _counter: { value: number } | undefined; -} - -// one shared object, cached on globalThis in dev -export const counter = global._counter ?? { value: 0 }; - -if (process.env.NODE_ENV !== "production") { - global._counter = counter; -} diff --git a/examples/next-js/src/lib/rivet-client.ts b/examples/next-js/src/lib/rivet-client.ts index d01647047..5c05d4d35 100644 --- a/examples/next-js/src/lib/rivet-client.ts +++ b/examples/next-js/src/lib/rivet-client.ts @@ -2,16 +2,7 @@ import { createClient, createRivetKit } from "@rivetkit/next-js/client"; import type { registry } from "@/rivet/registry"; -const getOrigin = () => { - if (typeof window !== "undefined") { - return window.location.origin; - } - // Fallback for SSR or when window is not available - return process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"; -}; +// TODO: Auto-trigger start by sending request to health endpoint -const client = createClient({ - endpoint: `${getOrigin()}/api/rivet`, - transport: "sse", -}); +const client = createClient(); export const { useActor } = createRivetKit(client); diff --git a/examples/next-js/src/lib/rivet-server.ts b/examples/next-js/src/lib/rivet-server.ts deleted file mode 100644 index 463085032..000000000 --- a/examples/next-js/src/lib/rivet-server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { toNextHandler } from "@rivetkit/next-js"; -import { registry } from "@/rivet/registry"; - -declare global { - // eslint-disable-next-line no-var - var _handlers: { value: any } | undefined; -} - -// one shared object, cached on globalThis in dev -export const handlers = global._handlers ?? { value: toNextHandler(registry) }; - -if (process.env.NODE_ENV !== "production") { - global._handlers = handlers; -} diff --git a/packages/next-js/src/mod.ts b/packages/next-js/src/mod.ts index 16c3eafe0..b73be941e 100644 --- a/packages/next-js/src/mod.ts +++ b/packages/next-js/src/mod.ts @@ -1,44 +1,27 @@ import type { Registry, RunConfigInput } from "rivetkit"; -type RegistryInstance = { - fetch: (request: Request) => Response | Promise; -}; - -const createRegistryInstance = ( +export const toNextHandler = ( registry: Registry, inputConfig: RunConfigInput = {}, -): RegistryInstance => { - console.log("=== CREATE NEXT HANDLER ==="); - +) => { // Don't run server locally since we're using the fetch handler directly inputConfig.disableDefaultServer = true; - // inputConfig.disableActorDriver = true; + + // Configure serverless + const publicUrl = + process.env.NEXT_PUBLIC_SITE_URL ?? + process.env.NEXT_PUBLIC_VERCEL_URL ?? + `http://127.0.0.1:${process.env.PORT ?? 8080}`; + inputConfig.runnerKind = "serverless"; + inputConfig.runEngine = true; + inputConfig.autoConfigureServerless = { + url: `${publicUrl}/api/rivet/start`, + }; // Next logs this on every request inputConfig.noWelcome = true; const { fetch } = registry.start(inputConfig); - return { fetch }; -}; - -declare global { - // eslint-disable-next-line no-var - var rivetRegistry: RegistryInstance | undefined; -} - -export const toNextHandler = ( - registry: Registry, - inputConfig: RunConfigInput = {}, -) => { - console.log("=== CREATE REGISTRY INSTANCE ==="); - - // Store registry instance globally to survive Next.js hot reloads in development. - // Without this, the registry would reinitialize on every code change, losing actor state. - const registryInstance = - global.rivetRegistry ?? createRegistryInstance(registry, inputConfig); - if (process.env.NODE_ENV !== "production") { - global.rivetRegistry = registryInstance; - } const fetchWrapper = async ( request: Request, @@ -50,7 +33,7 @@ export const toNextHandler = ( newUrl.pathname = all.join("/"); const newReq = new Request(newUrl, request); - return await registryInstance.fetch(newReq); + return await fetch(newReq); }; return {