Skip to content

Commit b01f7ae

Browse files
committed
working app pages
1 parent 5add2c7 commit b01f7ae

117 files changed

Lines changed: 976 additions & 16785 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/bright-jars-fly.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"everything-dev": minor
3+
---
4+
5+
Add plugin workspace commands and tighten dev/runtime orchestration so plugin attachments, contract generation, and client composition behave consistently.

api/rspack.config.js

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import crypto from "node:crypto";
21
import fs from "node:fs";
32
import { createRequire } from "node:module";
43
import path from "node:path";
54
import { fileURLToPath } from "node:url";
6-
import { EveryPluginDevServer } from "every-plugin/build/rspack";
5+
import { EmitPluginManifest, EveryPluginDevServer } from "every-plugin/build/rspack";
76
import { withZephyr } from "zephyr-rspack-plugin";
87

98
const require = createRequire(import.meta.url);
@@ -32,70 +31,9 @@ function updateHostConfig(name, url) {
3231
}
3332
}
3433

35-
function emitPluginManifest() {
36-
return {
37-
apply(compiler) {
38-
compiler.hooks.thisCompilation.tap("EmitPluginManifest", (compilation) => {
39-
const webpack = compiler.webpack;
40-
const RawSource = webpack?.sources?.RawSource;
41-
const stage = webpack?.Compilation?.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;
42-
43-
compilation.hooks.processAssets.tapPromise(
44-
{ name: "EmitPluginManifest", stage },
45-
async () => {
46-
const sourceContractPath = path.join(__dirname, "types", "api", "src", "contract.d.ts");
47-
48-
let contractTypes;
49-
try {
50-
contractTypes = await fs.promises.readFile(sourceContractPath, "utf8");
51-
} catch (error) {
52-
console.error(
53-
`[EmitPluginManifest] Failed to read contract file: ${sourceContractPath}`,
54-
);
55-
console.error(`[EmitPluginManifest] Error: ${error.message}`);
56-
return;
57-
}
58-
59-
const contractSha256 = crypto.createHash("sha256").update(contractTypes).digest("hex");
60-
61-
const manifest = {
62-
schemaVersion: 1,
63-
kind: "every-plugin/manifest",
64-
plugin: {
65-
name: pkg.name,
66-
version: pkg.version,
67-
},
68-
runtime: {
69-
remoteEntry: "./remoteEntry.js",
70-
},
71-
contract: {
72-
kind: "orpc",
73-
types: {
74-
path: "./types/api/src/contract.d.ts",
75-
exportName: "contract",
76-
typeName: "ContractType",
77-
sha256: contractSha256,
78-
},
79-
},
80-
};
81-
82-
if (RawSource) {
83-
compilation.emitAsset(
84-
"plugin.manifest.json",
85-
new RawSource(`${JSON.stringify(manifest, null, 2)}\n`),
86-
);
87-
compilation.emitAsset("types/api/src/contract.d.ts", new RawSource(contractTypes));
88-
}
89-
},
90-
);
91-
});
92-
},
93-
};
94-
}
95-
9634
const baseConfig = {
9735
externals: [/^@libsql\/.*/],
98-
plugins: [new EveryPluginDevServer(), emitPluginManifest()],
36+
plugins: [new EveryPluginDevServer(), ...(shouldDeploy ? [new EmitPluginManifest()] : [])],
9937
infrastructureLogging: {
10038
level: "error",
10139
},

api/src/services/fastkv.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Context, Effect, Layer } from "every-plugin/effect";
1+
import { Context, Layer } from "every-plugin/effect";
22

33
export type NetworkId = "mainnet" | "testnet";
44

@@ -53,7 +53,10 @@ export function getFastKvBaseUrlForAccount(accountId: string): string {
5353
return getFastKvBaseUrlForNetwork(getNetworkIdForAccount(accountId));
5454
}
5555

56-
export function getRegistryNamespaceForNetwork(network: NetworkId, config: RegistryConfig): string {
56+
export function getRegistryNamespaceForNetwork(
57+
_network: NetworkId,
58+
config: RegistryConfig,
59+
): string {
5760
return config.namespace;
5861
}
5962

bos.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"plugins": {
66
"template": {
77
"development": "local:plugins/_template",
8-
"production": "https://elliot-braem-2608-every-plugin-template-everythin-f122115e8-ze.zephyrcloud.app"
8+
"production": "https://elliot-braem-2617-every-plugin-template-everythin-577d3fdfa-ze.zephyrcloud.app"
99
}
1010
},
1111
"app": {
@@ -25,7 +25,7 @@
2525
"development": "local:api",
2626
"variables": {},
2727
"secrets": [],
28-
"production": "https://elliot-braem-2607-api-everything-dev-nearbuilders-8955afb16-ze.zephyrcloud.app"
28+
"production": "https://elliot-braem-2616-api-everything-dev-nearbuilders-9f203cd13-ze.zephyrcloud.app"
2929
}
3030
},
3131
"testnet": "dev.allthethings.testnet",

host/src/env.d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ interface ImportMeta {
99
readonly env: ImportMetaEnv;
1010
}
1111

12-
declare module "virtual:drizzle-migrations.sql" {
13-
const migrations: { default: Array<{ sql: string[]; name: string }> };
14-
export default migrations;
12+
export {};
13+
14+
declare global {
15+
// Temporary compatibility for legacy tests during apiClient refactor.
16+
// Runtime code no longer reads this.
17+
// eslint-disable-next-line no-var
18+
var $apiClient: unknown;
1519
}

host/src/everything-dev-ui.d.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

host/src/program.ts

Lines changed: 50 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { getBaseStyles, getHydrateScript, getThemeInitScript } from "everything-
1212
import { type Context, Hono } from "hono";
1313
import { cors } from "hono/cors";
1414
import { secureHeaders } from "hono/secure-headers";
15-
import { getRegistryApp, getRegistryAppByHost } from "../../api/src/services/registry";
1615
import { BaseLive, PluginsLive } from "./layers";
1716
import { type Auth, AuthService } from "./services/auth";
1817
import { type ClientRuntimeConfig, ConfigService, type RuntimeConfig } from "./services/config";
@@ -21,14 +20,13 @@ import { type Database, DatabaseService } from "./services/database";
2120
import { loadRouterModule, type RouterModule } from "./services/federation.server";
2221
import { createAggregateApiClient, type PluginResult, PluginsService } from "./services/plugins";
2322
import { createRouterMounts } from "./services/router";
24-
import { installSsrApiClientGlobal, runWithSsrApiClient } from "./services/ssr-api-client";
2523
import { logger } from "./utils/logger";
2624

2725
type 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

3331
function 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+
133110
function 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

Comments
 (0)