History

Import the app handler lazily in start.ts (#1710)

Rhys Sullivan committed 2 months ago

Commit dc1b5aa1 parent 91ee3db1 file · +14 −5Browse files

Unified · Split

apps/cloud/src/start.ts+14−5
@@ -1,7 +1,6 @@
1import { createMiddleware, createStart } from "@tanstack/react-start";1import { createMiddleware, createStart } from "@tanstack/react-start";
2import { decodeOAuthCallbackState } from "@executor-js/sdk/shared";2import { decodeOAuthCallbackState } from "@executor-js/sdk/shared";
3 3
4import { cloudApiHandler } from "./app";
5import { isAppOwnedPath } from "./app-paths";4import { isAppOwnedPath } from "./app-paths";
6import { authGateMiddleware } from "./auth/ssr-gate";5import { authGateMiddleware } from "./auth/ssr-gate";
7import { parseCookie } from "./auth/cookies";6import { parseCookie } from "./auth/cookies";
@@ -35,8 +34,18 @@ import { · 27 unmodified lines
35// (a workerd-only virtual module) into the browser build, breaking it. Keeping34// (a workerd-only virtual module) into the browser build, breaking it. Keeping
36// the call inside the server callback mirrors how every other server concern35// the call inside the server callback mirrors how every other server concern
37// here stays server-only.36// here stays server-only.
38let app: ReturnType<typeof cloudApiHandler> | undefined;37//
39const getApp = () => (app ??= cloudApiHandler());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.
46let app: ReturnType<typeof import("./app").cloudApiHandler> | undefined;
47const getApp = async (): Promise<NonNullable<typeof app>> =>
48 (app ??= (await import("./app")).cloudApiHandler());
40 49
41const SESSION_COOKIE = "wos-session";50const SESSION_COOKIE = "wos-session";
42const OAUTH_CALLBACK_PATH = "/api/oauth/callback";51const OAUTH_CALLBACK_PATH = "/api/oauth/callback";
@@ -78,11 +87,11 @@ const oauthCallbackSignInMiddleware = createMiddleware({ type: "request" }).serv · 35 unmodified lines
78// envelope routes, pinning the org in an internal header (a no-op for everything87// envelope routes, pinning the org in an internal header (a no-op for everything
79// else, including `/api/*`).88// else, including `/api/*`).
80const appRequestMiddleware = createMiddleware({ type: "request" }).server(89const appRequestMiddleware = createMiddleware({ type: "request" }).server(
81 ({ pathname, request, next }) => {90 async ({ pathname, request, next }) => {
82 if (isAppOwnedPath(pathname)) {91 if (isAppOwnedPath(pathname)) {
83 const scopedRequest =92 const scopedRequest =
84 pathname === OAUTH_CALLBACK_PATH ? oauthCallbackOrgScopedRequest(request) : request;93 pathname === OAUTH_CALLBACK_PATH ? oauthCallbackOrgScopedRequest(request) : request;
85 return getApp().handler(prepareMcpOrgScope(scopedRequest));94 return (await getApp()).handler(prepareMcpOrgScope(scopedRequest));
86 }95 }
87 return next();96 return next();
88 },97 },