Unified · Split
| @@ -1,7 +1,6 @@ | |||
| 1 | import { createMiddleware, createStart } from "@tanstack/react-start"; | 1 | import { createMiddleware, createStart } from "@tanstack/react-start"; |
| 2 | import { decodeOAuthCallbackState } from "@executor-js/sdk/shared"; | 2 | import { decodeOAuthCallbackState } from "@executor-js/sdk/shared"; |
| 3 | 3 | ||
| 4 | import { cloudApiHandler } from "./app"; | ||
| 5 | import { isAppOwnedPath } from "./app-paths"; | 4 | import { isAppOwnedPath } from "./app-paths"; |
| 6 | import { authGateMiddleware } from "./auth/ssr-gate"; | 5 | import { authGateMiddleware } from "./auth/ssr-gate"; |
| 7 | import { parseCookie } from "./auth/cookies"; | 6 | import { parseCookie } from "./auth/cookies"; |
| @@ -35,8 +34,18 @@ import { · 27 unmodified lines | |||
| 35 | // (a workerd-only virtual module) into the browser build, breaking it. Keeping | 34 | // (a workerd-only virtual module) into the browser build, breaking it. Keeping |
| 36 | // the call inside the server callback mirrors how every other server concern | 35 | // the call inside the server callback mirrors how every other server concern |
| 37 | // here stays server-only. | 36 | // here stays server-only. |
| 38 | let app: ReturnType<typeof cloudApiHandler> | undefined; | 37 | // |
| 39 | const 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. | ||
| 46 | let app: ReturnType<typeof import("./app").cloudApiHandler> | undefined; | ||
| 47 | const getApp = async (): Promise<NonNullable<typeof app>> => | ||
| 48 | (app ??= (await import("./app")).cloudApiHandler()); | ||
| 40 | 49 | ||
| 41 | const SESSION_COOKIE = "wos-session"; | 50 | const SESSION_COOKIE = "wos-session"; |
| 42 | const OAUTH_CALLBACK_PATH = "/api/oauth/callback"; | 51 | const 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 everything | 87 | // envelope routes, pinning the org in an internal header (a no-op for everything |
| 79 | // else, including `/api/*`). | 88 | // else, including `/api/*`). |
| 80 | const appRequestMiddleware = createMiddleware({ type: "request" }).server( | 89 | const 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 | }, |