@@ -12,7 +12,6 @@ import { getBaseStyles, getHydrateScript, getThemeInitScript } from "everything-
1212import { type Context , Hono } from "hono" ;
1313import { cors } from "hono/cors" ;
1414import { secureHeaders } from "hono/secure-headers" ;
15- import { getRegistryApp , getRegistryAppByHost } from "../../api/src/services/registry" ;
1615import { BaseLive , PluginsLive } from "./layers" ;
1716import { type Auth , AuthService } from "./services/auth" ;
1817import { type ClientRuntimeConfig , ConfigService , type RuntimeConfig } from "./services/config" ;
@@ -21,14 +20,13 @@ import { type Database, DatabaseService } from "./services/database";
2120import { loadRouterModule , type RouterModule } from "./services/federation.server" ;
2221import { createAggregateApiClient , type PluginResult , PluginsService } from "./services/plugins" ;
2322import { createRouterMounts } from "./services/router" ;
24- import { installSsrApiClientGlobal , runWithSsrApiClient } from "./services/ssr-api-client" ;
2523import { logger } from "./utils/logger" ;
2624
2725type ActiveRuntimeState = NonNullable < ClientRuntimeConfig [ "runtime" ] > ;
2826
29- type RuntimeClientConfig = ClientRuntimeConfig & {
30- runtime ?: ActiveRuntimeState ;
31- } ;
27+ type RuntimeClientConfig = ClientRuntimeConfig & { runtime ?: ActiveRuntimeState } ;
28+
29+ type RuntimePlugin = NonNullable < RuntimeConfig [ "plugins" ] > [ string ] ;
3230
3331function normalizeUrl ( url ?: string | null ) {
3432 if ( ! url ) {
@@ -76,49 +74,18 @@ async function resolveActiveRuntime(config: RuntimeConfig, request: Request) {
7674 const override = getRuntimeOverride ( url . pathname ) ;
7775
7876 if ( override ) {
79- const runtime = await getRegistryApp ( override . accountId , override . gatewayId ) ;
80- if ( ! runtime ) {
81- return null ;
82- }
83-
8477 return {
85- accountId : runtime . accountId ,
86- gatewayId : runtime . gatewayId ,
78+ accountId : override . accountId ,
79+ gatewayId : override . gatewayId ,
8780 runtimeBasePath : override . runtimeBasePath ,
88- canonicalConfigUrl : runtime . canonicalConfigUrl ,
89- resolvedConfig : runtime . resolvedConfig ,
90- title : runtime . metadata ?. title ?? runtime . gatewayId ,
91- hostUrl : runtime . hostUrl ,
92- } satisfies ActiveRuntimeState ;
93- }
94-
95- const hostRuntime = await getRegistryAppByHost ( url . origin ) . catch ( ( ) => null ) ;
96- if ( hostRuntime ) {
97- return {
98- accountId : hostRuntime . accountId ,
99- gatewayId : hostRuntime . gatewayId ,
100- runtimeBasePath : "/" ,
101- canonicalConfigUrl : hostRuntime . canonicalConfigUrl ,
102- resolvedConfig : hostRuntime . resolvedConfig ,
103- title : hostRuntime . metadata ?. title ?? hostRuntime . gatewayId ,
104- hostUrl : hostRuntime . hostUrl ,
81+ canonicalConfigUrl : null ,
82+ resolvedConfig : null ,
83+ title : `${ override . accountId } /${ override . gatewayId } ` ,
84+ hostUrl : url . origin ,
10585 } satisfies ActiveRuntimeState ;
10686 }
10787
10888 const fallbackGatewayId = getFallbackGatewayId ( config ) ;
109- const fallbackRuntime = await getRegistryApp ( config . account , fallbackGatewayId ) . catch ( ( ) => null ) ;
110- if ( fallbackRuntime ) {
111- return {
112- accountId : fallbackRuntime . accountId ,
113- gatewayId : fallbackRuntime . gatewayId ,
114- runtimeBasePath : "/" ,
115- canonicalConfigUrl : fallbackRuntime . canonicalConfigUrl ,
116- resolvedConfig : fallbackRuntime . resolvedConfig ,
117- title : fallbackRuntime . metadata ?. title ?? fallbackRuntime . gatewayId ,
118- hostUrl : fallbackRuntime . hostUrl ,
119- } satisfies ActiveRuntimeState ;
120- }
121-
12289 return {
12390 accountId : config . account ,
12491 gatewayId : fallbackGatewayId ,
@@ -130,6 +97,16 @@ async function resolveActiveRuntime(config: RuntimeConfig, request: Request) {
13097 } satisfies ActiveRuntimeState ;
13198}
13299
100+ function registerAllPaths (
101+ app : Hono ,
102+ paths : string [ ] ,
103+ handler : ( c : Context ) => Response | Promise < Response > ,
104+ ) {
105+ for ( const path of paths ) {
106+ app . all ( path , handler ) ;
107+ }
108+ }
109+
133110function buildRuntimeClientConfig (
134111 config : RuntimeConfig ,
135112 request : Request ,
@@ -157,14 +134,16 @@ function buildRuntimeClientConfig(
157134 entry : uiConfig . entry ,
158135 } ,
159136 plugins : Object . fromEntries (
160- Object . entries ( config . plugins ?? { } ) . map ( ( [ key , plugin ] ) => [
161- key ,
162- {
163- name : plugin . name ,
164- url : plugin . url ,
165- entry : plugin . entry ,
166- } ,
167- ] ) ,
137+ ( Object . entries ( config . plugins ?? { } ) as Array < [ string , RuntimePlugin ] > ) . map (
138+ ( [ key , plugin ] ) => [
139+ key ,
140+ {
141+ name : plugin . name ,
142+ url : plugin . url ,
143+ entry : plugin . entry ,
144+ } ,
145+ ] ,
146+ ) ,
168147 ) ,
169148 runtime : activeRuntime ,
170149 } as RuntimeClientConfig ;
@@ -399,10 +378,10 @@ export function setupApiRoutes(
399378 ] ,
400379 } ) ;
401380
402- app . all ( basePath , ( c : Context ) => handleOrpc ( c , apiHandler , basePath ) ) ;
403- app . all ( `${ basePath } /*` , ( c : Context ) => handleOrpc ( c , apiHandler , basePath ) ) ;
404381 app . all ( rpcPath , ( c : Context ) => handleOrpc ( c , rpcHandler , rpcPath ) ) ;
405382 app . all ( `${ rpcPath } /*` , ( c : Context ) => handleOrpc ( c , rpcHandler , rpcPath ) ) ;
383+ app . all ( basePath , ( c : Context ) => handleOrpc ( c , apiHandler , basePath ) ) ;
384+ app . all ( `${ basePath } /*` , ( c : Context ) => handleOrpc ( c , apiHandler , basePath ) ) ;
406385 } ;
407386
408387 app . on ( [ "POST" , "GET" ] , "/api/auth/*" , ( c : Context ) => auth . handler ( c . req . raw ) ) ;
@@ -423,13 +402,9 @@ export const createStartServer = (onReady?: () => void) =>
423402 const auth = yield * AuthService ;
424403 const plugins = yield * PluginsService ;
425404
426- // Ensure the UI SSR remote can always resolve `$apiClient` safely.
427- // This uses AsyncLocalStorage to prevent cross-request client leakage.
428- installSsrApiClientGlobal ( ) ;
429-
430405 const app = new Hono ( ) ;
431406
432- app . onError ( ( err , c ) => {
407+ app . onError ( ( err : unknown , c : Context ) => {
433408 const details = extractErrorDetails ( err ) ;
434409 logger . error ( `[Hono Error] ${ c . req . method } ${ c . req . path } ` ) ;
435410 logger . error ( `[Hono Error] Message: ${ details . message } ` ) ;
@@ -445,7 +420,7 @@ export const createStartServer = (onReady?: () => void) =>
445420 app . use (
446421 "/*" ,
447422 cors ( {
448- origin : process . env . CORS_ORIGIN ?. split ( "," ) . map ( ( o ) => o . trim ( ) ) ?? [
423+ origin : process . env . CORS_ORIGIN ?. split ( "," ) . map ( ( o : string ) => o . trim ( ) ) ?? [
449424 config . hostUrl ,
450425 uiConfig . url ,
451426 ] ,
@@ -524,30 +499,28 @@ export const createStartServer = (onReady?: () => void) =>
524499 } ;
525500
526501 const proxyUiAssetRequest = ( c : Context ) => proxyRequest ( c . req . raw , uiConfig . url ) ;
502+ const staticAssetPaths = [
503+ "/static/*" ,
504+ "/.well-known/*" ,
505+ "/favicon.ico" ,
506+ "/icon.svg" ,
507+ "/manifest.json" ,
508+ "/robots.txt" ,
509+ "/README.md" ,
510+ "/skill.md" ,
511+ "/llms.txt" ,
512+ ] ;
527513
528514 setupApiRoutes ( app , config , auth , db , plugins , loadingState ) ;
529515
530516 const shouldProxyUiAssets = isDev || uiConfig . source === "remote" ;
531517
532518 if ( ! shouldProxyUiAssets ) {
533- app . use ( "/static/*" , serveStatic ( { root : "./dist" } ) ) ;
534- app . use ( "/favicon.ico" , serveStatic ( { root : "./dist" } ) ) ;
535- app . use ( "/icon.svg" , serveStatic ( { root : "./dist" } ) ) ;
536- app . use ( "/manifest.json" , serveStatic ( { root : "./dist" } ) ) ;
537- app . use ( "/robots.txt" , serveStatic ( { root : "./dist" } ) ) ;
538- app . use ( "/README.md" , serveStatic ( { root : "./dist" } ) ) ;
539- app . use ( "/skill.md" , serveStatic ( { root : "./dist" } ) ) ;
540- app . use ( "/llms.txt" , serveStatic ( { root : "./dist" } ) ) ;
519+ for ( const path of staticAssetPaths ) {
520+ app . use ( path , serveStatic ( { root : "./dist" } ) ) ;
521+ }
541522 } else {
542- app . all ( "/static/*" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
543- app . all ( "/.well-known/*" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
544- app . all ( "/favicon.ico" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
545- app . all ( "/icon.svg" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
546- app . all ( "/manifest.json" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
547- app . all ( "/robots.txt" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
548- app . all ( "/README.md" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
549- app . all ( "/skill.md" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
550- app . all ( "/llms.txt" , ( c : Context ) => proxyUiAssetRequest ( c ) ) ;
523+ registerAllPaths ( app , staticAssetPaths , proxyUiAssetRequest ) ;
551524 }
552525
553526 if ( uiConfig . ssrUrl ) {
@@ -570,23 +543,6 @@ export const createStartServer = (onReady?: () => void) =>
570543 app . get ( "*" , async ( c : Context ) => {
571544 const activeRuntime = await resolveActiveRuntime ( config , c . req . raw ) ;
572545
573- if ( ! activeRuntime ) {
574- return c . html (
575- `<!DOCTYPE html>
576- <html lang="en">
577- <head>
578- <meta charset="utf-8" />
579- <title>Runtime Not Found</title>
580- </head>
581- <body>
582- <h1>Runtime Not Found</h1>
583- <p>The requested published runtime could not be resolved.</p>
584- </body>
585- </html>` ,
586- 404 ,
587- ) ;
588- }
589-
590546 const runtimeConfig = buildRuntimeClientConfig ( config , c . req . raw , activeRuntime ) ;
591547
592548 if ( ! uiConfig . ssrUrl ) {
@@ -609,9 +565,10 @@ export const createStartServer = (onReady?: () => void) =>
609565 session : requestContext . session ,
610566 basepath : runtimeConfig . runtime ?. runtimeBasePath ,
611567 runtimeConfig,
568+ apiClient : ssrApiClient ,
612569 } as any ) ;
613570
614- const result = await runWithSsrApiClient ( ssrApiClient , render ) ;
571+ const result = await render ( ) ;
615572 return new Response ( result ?. stream , {
616573 status : result ?. statusCode ,
617574 headers : result ?. headers ,
0 commit comments