fix(build): make oRPC/tRPC dist runnable under node ESM (deploy crashloop)

flake.nix only rewrote @/ aliases but left extensionless relative imports
(./router) in compiled dist/. node dist/index.js (how prod runs) cannot
resolve extensionless ESM specifiers -> ERR_MODULE_NOT_FOUND -> backend
crashlooped (444 restarts, port 4001 dead). Extract the fixer into a shared
scripts/fix-imports.mjs that appends .js to extensionless relative imports and
rewrites @/ aliases, and wire it into backend + discord-gateway build phases.

Verified: fresh tsc + fixer -> node dist/index.js boots; oRPC over /trpc
serves both HTTP POST and WebSocket (config/dashboard/voice/moderation/
media/chatbot/analysis) end-to-end against Postgres + Redis. next build
passes with the oRPC client + partysocket.
This commit is contained in:
asepharyana committed 2026-08-16 14:45:02 +07:00
1 parent 2fa1827f17
commit 726a8e116b
27 files changed
+646 -417

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
"use client";
import { createORPCClient } from "@orpc/client";
import { RPCLink } from "@orpc/client/websocket";
import PartySocket from "partysocket";
import type { ORPCClient } from "./types";
/**
* oRPC client over WebSocket (browser only).
*
* oRPC's own WebSocket RPCLink takes a caller-provided socket and does NOT
* auto-reconnect, so we back it with partysocket — a reconnecting WebSocket
* whose `host` + `basePath: "trpc"` resolves to exactly `/trpc`, matching the
* backend's oRPC WS mount. partysocket keeps a stable socket identity across
* reconnects, which is what oRPC's RPCLink expects.
*
* The client is loosely typed (see ./types): we do NOT import the backend
* router's type into the FE (fragile coupling). api/* wrappers assert leaf
* results to the frontend's local types.
*/
const orpc: ORPCClient = (() => {
if (typeof window === "undefined") {
// SSR fallback — api/* callers are client components, never run server-side.
return undefined as unknown as ORPCClient;
}
const socket = new PartySocket({
host: window.location.host,
basePath: "trpc",
});
const link = new RPCLink({ websocket: socket });
return createORPCClient(link) as unknown as ORPCClient;
})();
export { orpc };