Skip to content

Commit dc1b5aa

Browse files
authored
Import the app handler lazily in start.ts (#1710)
1 parent 91ee3db commit dc1b5aa

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

apps/cloud/src/start.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { createMiddleware, createStart } from "@tanstack/react-start";
22
import { decodeOAuthCallbackState } from "@executor-js/sdk/shared";
33

4-
import { cloudApiHandler } from "./app";
54
import { isAppOwnedPath } from "./app-paths";
65
import { authGateMiddleware } from "./auth/ssr-gate";
76
import { parseCookie } from "./auth/cookies";
@@ -35,8 +34,18 @@ import {
3534
// (a workerd-only virtual module) into the browser build, breaking it. Keeping
3635
// the call inside the server callback mirrors how every other server concern
3736
// here stays server-only.
38-
let app: ReturnType<typeof cloudApiHandler> | undefined;
39-
const getApp = () => (app ??= cloudApiHandler());
37+
//
38+
// The IMPORT is dynamic for a second, server-side reason: `server.ts` now
39+
// dispatches `/api/*` at the Worker entry, so the only paths that still reach
40+
// this middleware are the two Start's own chain claims first (the Sentry tunnel
41+
// and the OAuth callback's signed-out redirect) plus `/mcp`. A static import
42+
// would still put the entire Effect app in the graph every SSR page load
43+
// evaluates — 3.06 MB of the 12.94 MB page closure, for code a page never runs.
44+
// Deferring it takes the page closure to 9.88 MB; `scripts/start-closure.mjs`
45+
// reports both planes and will show it coming back if this becomes static.
46+
let app: ReturnType<typeof import("./app").cloudApiHandler> | undefined;
47+
const getApp = async (): Promise<NonNullable<typeof app>> =>
48+
(app ??= (await import("./app")).cloudApiHandler());
4049

4150
const SESSION_COOKIE = "wos-session";
4251
const OAUTH_CALLBACK_PATH = "/api/oauth/callback";
@@ -78,11 +87,11 @@ const oauthCallbackSignInMiddleware = createMiddleware({ type: "request" }).serv
7887
// envelope routes, pinning the org in an internal header (a no-op for everything
7988
// else, including `/api/*`).
8089
const appRequestMiddleware = createMiddleware({ type: "request" }).server(
81-
({ pathname, request, next }) => {
90+
async ({ pathname, request, next }) => {
8291
if (isAppOwnedPath(pathname)) {
8392
const scopedRequest =
8493
pathname === OAUTH_CALLBACK_PATH ? oauthCallbackOrgScopedRequest(request) : request;
85-
return getApp().handler(prepareMcpOrgScope(scopedRequest));
94+
return (await getApp()).handler(prepareMcpOrgScope(scopedRequest));
8695
}
8796
return next();
8897
},

0 commit comments

Comments
 (0)