everything-dev 1.7.2 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.cjs +1 -1
- package/dist/api.mjs +1 -1
- package/dist/app.cjs +82 -51
- package/dist/app.cjs.map +1 -1
- package/dist/app.mjs +82 -51
- package/dist/app.mjs.map +1 -1
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/components/dev-view.cjs +6 -3
- package/dist/components/dev-view.cjs.map +1 -1
- package/dist/components/dev-view.mjs +6 -3
- package/dist/components/dev-view.mjs.map +1 -1
- package/dist/components/streaming-view.cjs +5 -2
- package/dist/components/streaming-view.cjs.map +1 -1
- package/dist/components/streaming-view.mjs +5 -2
- package/dist/components/streaming-view.mjs.map +1 -1
- package/dist/config.cjs +28 -5
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +28 -5
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +1 -0
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +10 -2
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +10 -2
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.mjs +1 -0
- package/dist/contract.mjs.map +1 -1
- package/dist/dev-logs.cjs +6 -2
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs +7 -2
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/dev-session.cjs +27 -23
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +27 -24
- package/dist/dev-session.mjs.map +1 -1
- package/dist/federation.server.cjs +1 -1
- package/dist/federation.server.mjs +1 -1
- package/dist/host.cjs +4 -3
- package/dist/host.cjs.map +1 -1
- package/dist/host.d.cts.map +1 -1
- package/dist/host.d.mts.map +1 -1
- package/dist/host.mjs +4 -3
- package/dist/host.mjs.map +1 -1
- package/dist/integrity.cjs +68 -2
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.d.cts +14 -1
- package/dist/integrity.d.cts.map +1 -1
- package/dist/integrity.d.mts +14 -1
- package/dist/integrity.d.mts.map +1 -1
- package/dist/integrity.mjs +66 -3
- package/dist/integrity.mjs.map +1 -1
- package/dist/mf.cjs +32 -0
- package/dist/mf.cjs.map +1 -1
- package/dist/mf.d.cts +3 -1
- package/dist/mf.d.cts.map +1 -1
- package/dist/mf.d.mts +3 -1
- package/dist/mf.d.mts.map +1 -1
- package/dist/mf.mjs +32 -1
- package/dist/mf.mjs.map +1 -1
- package/dist/orchestrator.cjs +167 -317
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.d.cts +24 -21
- package/dist/orchestrator.d.cts.map +1 -1
- package/dist/orchestrator.d.mts +24 -21
- package/dist/orchestrator.d.mts.map +1 -1
- package/dist/orchestrator.mjs +168 -316
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +38 -107
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +16 -2
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +16 -2
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +39 -108
- package/dist/plugin.mjs.map +1 -1
- package/dist/service-descriptor.cjs +188 -0
- package/dist/service-descriptor.cjs.map +1 -0
- package/dist/service-descriptor.d.cts +107 -0
- package/dist/service-descriptor.d.cts.map +1 -0
- package/dist/service-descriptor.d.mts +107 -0
- package/dist/service-descriptor.d.mts.map +1 -0
- package/dist/service-descriptor.mjs +182 -0
- package/dist/service-descriptor.mjs.map +1 -0
- package/dist/types.cjs +8 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +16 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +16 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +8 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ui/index.cjs +1 -0
- package/dist/ui/index.d.cts +2 -2
- package/dist/ui/index.d.mts +2 -2
- package/dist/ui/index.mjs +2 -2
- package/dist/ui/runtime.cjs +4 -0
- package/dist/ui/runtime.cjs.map +1 -1
- package/dist/ui/runtime.d.cts +2 -1
- package/dist/ui/runtime.d.cts.map +1 -1
- package/dist/ui/runtime.d.mts +2 -1
- package/dist/ui/runtime.d.mts.map +1 -1
- package/dist/ui/runtime.mjs +4 -1
- package/dist/ui/runtime.mjs.map +1 -1
- package/package.json +12 -4
- package/skills/dev-workflow/SKILL.md +105 -0
- package/skills/publish-sync/SKILL.md +130 -0
- package/src/app.ts +98 -204
- package/src/cli/upgrade.ts +20 -4
- package/src/components/dev-view.tsx +8 -3
- package/src/components/streaming-view.ts +7 -2
- package/src/config.ts +40 -8
- package/src/contract.ts +1 -0
- package/src/dev-logs.ts +8 -1
- package/src/dev-session.ts +56 -79
- package/src/host.ts +4 -3
- package/src/integrity.ts +96 -10
- package/src/mf.ts +42 -0
- package/src/orchestrator.ts +232 -411
- package/src/plugin.ts +48 -136
- package/src/service-descriptor.ts +258 -0
- package/src/types.ts +8 -1
- package/src/ui/runtime.ts +5 -0
- package/dist/process-registry.cjs +0 -120
- package/dist/process-registry.cjs.map +0 -1
- package/dist/process-registry.d.cts +0 -25
- package/dist/process-registry.d.cts.map +0 -1
- package/dist/process-registry.d.mts +0 -25
- package/dist/process-registry.d.mts.map +0 -1
- package/dist/process-registry.mjs +0 -119
- package/dist/process-registry.mjs.map +0 -1
- package/src/process-registry.ts +0 -154
package/src/plugin.ts
CHANGED
|
@@ -23,8 +23,6 @@ import {
|
|
|
23
23
|
getHostDevelopmentPort,
|
|
24
24
|
getProjectRoot,
|
|
25
25
|
loadConfig,
|
|
26
|
-
parsePort,
|
|
27
|
-
resolveDevelopmentHostUrl,
|
|
28
26
|
resolveLocalDevelopmentPath,
|
|
29
27
|
} from "./config";
|
|
30
28
|
import {
|
|
@@ -43,7 +41,7 @@ import {
|
|
|
43
41
|
type SyncOptions,
|
|
44
42
|
type UpgradeOptions,
|
|
45
43
|
} from "./contract";
|
|
46
|
-
import {
|
|
44
|
+
import { devApp, startApp } from "./dev-session";
|
|
47
45
|
import {
|
|
48
46
|
buildRegistryConfigUrlForNetwork,
|
|
49
47
|
fetchBosConfigFromFastKv,
|
|
@@ -58,6 +56,11 @@ import { computeSriHashForUrl } from "./integrity";
|
|
|
58
56
|
import { addFunctionCallAccessKey, ensureNearCli, executeTransaction } from "./near-cli";
|
|
59
57
|
import { getNetworkIdForAccount } from "./network";
|
|
60
58
|
import { createPlugin, z } from "./sdk";
|
|
59
|
+
import {
|
|
60
|
+
type AppOrchestrator,
|
|
61
|
+
buildDescription,
|
|
62
|
+
buildServiceDescriptorMap,
|
|
63
|
+
} from "./service-descriptor";
|
|
61
64
|
import { syncAndGenerateSharedUi } from "./shared";
|
|
62
65
|
import type { BosConfig, RuntimeConfig, SourceMode } from "./types";
|
|
63
66
|
import { run } from "./utils/run";
|
|
@@ -91,13 +94,6 @@ function ensureEnvFile(configDir: string): void {
|
|
|
91
94
|
console.log(`[CLI] Created .env from .env.example with generated BETTER_AUTH_SECRET`);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
const DEFAULT_DEV_CONFIG: AppConfig = {
|
|
95
|
-
host: "local",
|
|
96
|
-
ui: "local",
|
|
97
|
-
api: "local",
|
|
98
|
-
ssr: false,
|
|
99
|
-
};
|
|
100
|
-
|
|
101
97
|
const buildCommands: Record<string, { cmd: string; args: string[] }> = {
|
|
102
98
|
host: { cmd: "bun", args: ["run", "build"] },
|
|
103
99
|
ui: { cmd: "bun", args: ["run", "build"] },
|
|
@@ -119,35 +115,6 @@ function parseSourceMode(value: string | undefined, defaultValue: SourceMode): S
|
|
|
119
115
|
return defaultValue;
|
|
120
116
|
}
|
|
121
117
|
|
|
122
|
-
function buildAppConfig(options: {
|
|
123
|
-
host?: string;
|
|
124
|
-
ui?: string;
|
|
125
|
-
api?: string;
|
|
126
|
-
proxy?: boolean;
|
|
127
|
-
ssr?: boolean;
|
|
128
|
-
}): AppConfig {
|
|
129
|
-
return {
|
|
130
|
-
host: parseSourceMode(options.host, DEFAULT_DEV_CONFIG.host),
|
|
131
|
-
ui: parseSourceMode(options.ui, DEFAULT_DEV_CONFIG.ui),
|
|
132
|
-
api: parseSourceMode(options.api, DEFAULT_DEV_CONFIG.api),
|
|
133
|
-
proxy: options.proxy,
|
|
134
|
-
ssr: options.ssr ?? DEFAULT_DEV_CONFIG.ssr,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function buildDescription(config: AppConfig): string {
|
|
139
|
-
if (config.host === "local" && config.ui === "local" && config.api === "local" && !config.proxy) {
|
|
140
|
-
return "Full Local Development";
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const parts: string[] = [];
|
|
144
|
-
parts.push(config.host === "remote" ? "Remote Host" : "Local Host");
|
|
145
|
-
if (config.ui === "remote") parts.push("Remote UI");
|
|
146
|
-
if (config.proxy) parts.push("Proxy API → Production");
|
|
147
|
-
else if (config.api === "remote") parts.push("Remote API");
|
|
148
|
-
return parts.join(" + ");
|
|
149
|
-
}
|
|
150
|
-
|
|
151
118
|
function buildConfigResult(bosConfig: BosConfig | null): BosConfigResult {
|
|
152
119
|
const packages = bosConfig ? Object.keys(bosConfig.app) : [];
|
|
153
120
|
const remotes = packages.filter((name) => name !== "host");
|
|
@@ -194,30 +161,6 @@ function resolveWorkspaceTarget(
|
|
|
194
161
|
return null;
|
|
195
162
|
}
|
|
196
163
|
|
|
197
|
-
function determineProcesses(
|
|
198
|
-
config: AppConfig,
|
|
199
|
-
localPackages: string[],
|
|
200
|
-
runtimeConfig?: RuntimeConfig | null,
|
|
201
|
-
): string[] {
|
|
202
|
-
const processes: string[] = [];
|
|
203
|
-
if (config.ssr && config.ui === "local") processes.push("ui-ssr");
|
|
204
|
-
if (config.ui === "local") processes.push("ui");
|
|
205
|
-
if (localPackages.includes("auth") && runtimeConfig?.auth?.source === "local") {
|
|
206
|
-
processes.push("auth");
|
|
207
|
-
}
|
|
208
|
-
if (config.api === "local" && !config.proxy) processes.push("api");
|
|
209
|
-
for (const pkg of localPackages) {
|
|
210
|
-
if (pkg.startsWith("plugin:")) {
|
|
211
|
-
const pluginId = pkg.slice("plugin:".length);
|
|
212
|
-
if (runtimeConfig?.plugins?.[pluginId]?.source === "local") {
|
|
213
|
-
processes.push(pkg);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
processes.push("host");
|
|
218
|
-
return processes;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
164
|
function isValidProxyUrl(url: string): boolean {
|
|
222
165
|
try {
|
|
223
166
|
const parsed = new URL(url);
|
|
@@ -318,39 +261,6 @@ function extractPublishedUrl(output: string): string | null {
|
|
|
318
261
|
return match[match.length - 1] ?? null;
|
|
319
262
|
}
|
|
320
263
|
|
|
321
|
-
async function buildEnvVars(
|
|
322
|
-
config: AppConfig,
|
|
323
|
-
bosConfig?: BosConfig | null,
|
|
324
|
-
): Promise<Record<string, string>> {
|
|
325
|
-
const env: Record<string, string> = {
|
|
326
|
-
HOST_SOURCE: config.host,
|
|
327
|
-
UI_SOURCE: config.ui,
|
|
328
|
-
API_SOURCE: config.api,
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
if (config.host === "remote") {
|
|
332
|
-
const remoteUrl = bosConfig?.app.host.production;
|
|
333
|
-
if (remoteUrl) env.HOST_REMOTE_URL = remoteUrl;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (config.ui === "remote") {
|
|
337
|
-
const remoteUrl = bosConfig?.app.ui.production;
|
|
338
|
-
if (remoteUrl) env.UI_REMOTE_URL = remoteUrl;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (config.api === "remote") {
|
|
342
|
-
const remoteUrl = bosConfig?.app.api.production;
|
|
343
|
-
if (remoteUrl) env.API_REMOTE_URL = remoteUrl;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (config.proxy && bosConfig) {
|
|
347
|
-
const proxyUrl = resolveProxyUrl(bosConfig);
|
|
348
|
-
if (proxyUrl) env.API_PROXY = proxyUrl;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return env;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
264
|
async function buildEveryPluginQuietly(cwd: string) {
|
|
355
265
|
const packageDir = `${cwd}/packages/every-plugin`;
|
|
356
266
|
const packageExists = await Bun.file(`${packageDir}/package.json`).exists();
|
|
@@ -876,24 +786,31 @@ export default createPlugin({
|
|
|
876
786
|
deps.runtimeConfig ?? undefined,
|
|
877
787
|
);
|
|
878
788
|
|
|
879
|
-
const
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
789
|
+
const hostSource: SourceMode = localPackages.includes("host")
|
|
790
|
+
? parseSourceMode(input.host as string, "local")
|
|
791
|
+
: "remote";
|
|
792
|
+
const uiSource: SourceMode = localPackages.includes("ui")
|
|
793
|
+
? parseSourceMode(input.ui as string, "local")
|
|
794
|
+
: "remote";
|
|
795
|
+
const apiSource: SourceMode = localPackages.includes("api")
|
|
796
|
+
? parseSourceMode(input.api as string, "local")
|
|
797
|
+
: "remote";
|
|
798
|
+
const authSource: SourceMode = localPackages.includes("auth")
|
|
799
|
+
? parseSourceMode(input.auth as string, "local")
|
|
800
|
+
: "remote";
|
|
801
|
+
const ssr = input.ssr ?? false;
|
|
802
|
+
const proxy = input.proxy ?? false;
|
|
886
803
|
|
|
887
804
|
const sharedSync = await syncAndGenerateSharedUi({
|
|
888
805
|
configDir: deps.configDir,
|
|
889
|
-
hostMode:
|
|
806
|
+
hostMode: hostSource,
|
|
890
807
|
bosConfig: deps.bosConfig ?? undefined,
|
|
891
808
|
});
|
|
892
809
|
if (sharedSync.catalogChanged) {
|
|
893
810
|
await run("bun", ["install"], { cwd: deps.configDir });
|
|
894
811
|
}
|
|
895
812
|
if (
|
|
896
|
-
(
|
|
813
|
+
(apiSource === "local" && !proxy) ||
|
|
897
814
|
localPackages.some((pkg) => pkg.startsWith("plugin:"))
|
|
898
815
|
) {
|
|
899
816
|
await buildEveryPluginQuietly(deps.configDir);
|
|
@@ -913,7 +830,7 @@ export default createPlugin({
|
|
|
913
830
|
};
|
|
914
831
|
}
|
|
915
832
|
|
|
916
|
-
if (
|
|
833
|
+
if (proxy && !resolveProxyUrl(deps.bosConfig)) {
|
|
917
834
|
return {
|
|
918
835
|
status: "error" as const,
|
|
919
836
|
description: "No valid proxy URL configured in bos.config.json",
|
|
@@ -921,27 +838,29 @@ export default createPlugin({
|
|
|
921
838
|
};
|
|
922
839
|
}
|
|
923
840
|
|
|
924
|
-
const refreshedLocalPackages = detectLocalPackages(
|
|
925
|
-
deps.bosConfig ?? undefined,
|
|
926
|
-
deps.runtimeConfig ?? undefined,
|
|
927
|
-
);
|
|
928
|
-
const processes = determineProcesses(appConfig, refreshedLocalPackages, deps.runtimeConfig);
|
|
929
|
-
const env = await buildEnvVars(appConfig, deps.bosConfig);
|
|
930
841
|
const hostPort = input.port ?? getHostDevelopmentPort(deps.bosConfig.app.host.development);
|
|
931
842
|
const developmentRuntime = buildRuntimeConfig(deps.bosConfig, {
|
|
932
|
-
uiSource
|
|
933
|
-
apiSource
|
|
934
|
-
authSource
|
|
935
|
-
|
|
936
|
-
proxy: env.API_PROXY,
|
|
843
|
+
uiSource,
|
|
844
|
+
apiSource,
|
|
845
|
+
authSource,
|
|
846
|
+
hostSource,
|
|
937
847
|
env: "development",
|
|
938
848
|
plugins: deps.runtimeConfig?.plugins,
|
|
939
849
|
});
|
|
940
850
|
const runtimeConfig = await prepareDevelopmentRuntimeConfig(developmentRuntime, {
|
|
941
851
|
hostPort,
|
|
942
|
-
ssr
|
|
852
|
+
ssr,
|
|
943
853
|
});
|
|
944
854
|
|
|
855
|
+
const services = buildServiceDescriptorMap(runtimeConfig, { ssr, proxy });
|
|
856
|
+
const packages = [...services.keys()];
|
|
857
|
+
const displayEnv: Record<string, string> = {};
|
|
858
|
+
const apiDescriptor = services.get("api");
|
|
859
|
+
if (apiDescriptor?.proxy) {
|
|
860
|
+
const proxyUrl = resolveProxyUrl(deps.bosConfig);
|
|
861
|
+
if (proxyUrl) displayEnv.API_PROXY = proxyUrl;
|
|
862
|
+
}
|
|
863
|
+
|
|
945
864
|
await syncApiContractBridge({
|
|
946
865
|
configDir: deps.configDir,
|
|
947
866
|
runtimeConfig: runtimeConfig,
|
|
@@ -949,22 +868,19 @@ export default createPlugin({
|
|
|
949
868
|
});
|
|
950
869
|
|
|
951
870
|
const orchestrator: AppOrchestrator = {
|
|
952
|
-
packages
|
|
953
|
-
env,
|
|
954
|
-
description: buildDescription(
|
|
955
|
-
|
|
956
|
-
bosConfig: deps.bosConfig,
|
|
957
|
-
runtimeConfig,
|
|
958
|
-
port: parsePort(runtimeConfig.hostUrl),
|
|
871
|
+
packages,
|
|
872
|
+
env: displayEnv,
|
|
873
|
+
description: buildDescription(services),
|
|
874
|
+
port: runtimeConfig.host.port,
|
|
959
875
|
interactive: input.interactive,
|
|
960
876
|
};
|
|
961
877
|
|
|
962
|
-
|
|
878
|
+
devApp(orchestrator, services, runtimeConfig);
|
|
963
879
|
|
|
964
880
|
return {
|
|
965
881
|
status: "started" as const,
|
|
966
882
|
description: orchestrator.description,
|
|
967
|
-
processes,
|
|
883
|
+
processes: packages,
|
|
968
884
|
};
|
|
969
885
|
}),
|
|
970
886
|
|
|
@@ -992,8 +908,6 @@ export default createPlugin({
|
|
|
992
908
|
}
|
|
993
909
|
|
|
994
910
|
const port = input.port ?? getHostDevelopmentPort(config.app.host.development);
|
|
995
|
-
const appConfig: AppConfig = { host: "remote", ui: "remote", api: "remote" };
|
|
996
|
-
const env = await buildEnvVars(appConfig, config);
|
|
997
911
|
const isStaging = input.env === "staging";
|
|
998
912
|
const runtimePlugins = remoteConfig
|
|
999
913
|
? await buildRuntimePluginsForConfig(config, deps.configDir, "production")
|
|
@@ -1002,11 +916,13 @@ export default createPlugin({
|
|
|
1002
916
|
uiSource: "remote",
|
|
1003
917
|
apiSource: "remote",
|
|
1004
918
|
authSource: "remote",
|
|
1005
|
-
|
|
919
|
+
hostSource: "remote",
|
|
1006
920
|
env: "production",
|
|
1007
921
|
plugins: runtimePlugins,
|
|
1008
922
|
});
|
|
1009
923
|
|
|
924
|
+
const services = buildServiceDescriptorMap(runtimeConfig);
|
|
925
|
+
|
|
1010
926
|
await syncApiContractBridge({
|
|
1011
927
|
configDir: deps.configDir,
|
|
1012
928
|
runtimeConfig: runtimeConfig,
|
|
@@ -1021,19 +937,15 @@ export default createPlugin({
|
|
|
1021
937
|
packages: ["host"],
|
|
1022
938
|
env: {
|
|
1023
939
|
NODE_ENV: "production",
|
|
1024
|
-
...env,
|
|
1025
940
|
...stagingEnvVars,
|
|
1026
941
|
},
|
|
1027
942
|
description: `${isStaging ? "Staging" : "Production"} Mode (${config.account})`,
|
|
1028
|
-
appConfig,
|
|
1029
|
-
bosConfig: config,
|
|
1030
|
-
runtimeConfig,
|
|
1031
943
|
port,
|
|
1032
944
|
interactive: input.interactive,
|
|
1033
945
|
noLogs: true,
|
|
1034
946
|
};
|
|
1035
947
|
|
|
1036
|
-
startApp(orchestrator);
|
|
948
|
+
startApp(orchestrator, services, runtimeConfig);
|
|
1037
949
|
return {
|
|
1038
950
|
status: "running" as const,
|
|
1039
951
|
url: `http://localhost:${port}`,
|
|
@@ -1062,7 +974,7 @@ export default createPlugin({
|
|
|
1062
974
|
uiSource: deps.bosConfig.app.ui?.development ? "local" : "remote",
|
|
1063
975
|
apiSource: deps.bosConfig.app.api?.development ? "local" : "remote",
|
|
1064
976
|
authSource: deps.bosConfig.app.auth?.development ? "local" : "remote",
|
|
1065
|
-
|
|
977
|
+
hostSource: deps.bosConfig.app.host?.development ? "local" : "remote",
|
|
1066
978
|
env: "development",
|
|
1067
979
|
plugins: deps.runtimeConfig?.plugins,
|
|
1068
980
|
});
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import type { RuntimeConfig, SourceMode } from "./types";
|
|
3
|
+
|
|
4
|
+
export interface ServiceDescriptor {
|
|
5
|
+
key: string;
|
|
6
|
+
source: SourceMode;
|
|
7
|
+
url: string;
|
|
8
|
+
remoteUrl?: string;
|
|
9
|
+
entry: string;
|
|
10
|
+
name: string;
|
|
11
|
+
localPath?: string;
|
|
12
|
+
port?: number;
|
|
13
|
+
readinessPath: string;
|
|
14
|
+
defaultPort: number;
|
|
15
|
+
integrity?: string;
|
|
16
|
+
proxy?: string;
|
|
17
|
+
variables?: Record<string, string>;
|
|
18
|
+
secrets?: string[];
|
|
19
|
+
ssr?: boolean;
|
|
20
|
+
command?: string;
|
|
21
|
+
args?: string[];
|
|
22
|
+
readyPatterns?: RegExp[];
|
|
23
|
+
errorPatterns?: RegExp[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class ServiceDescriptorMap extends Context.Tag("ServiceDescriptorMap")<
|
|
27
|
+
ServiceDescriptorMap,
|
|
28
|
+
Map<string, ServiceDescriptor>
|
|
29
|
+
>() {}
|
|
30
|
+
|
|
31
|
+
export class DevRuntimeConfig extends Context.Tag("DevRuntimeConfig")<
|
|
32
|
+
DevRuntimeConfig,
|
|
33
|
+
RuntimeConfig
|
|
34
|
+
>() {}
|
|
35
|
+
|
|
36
|
+
const PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];
|
|
37
|
+
|
|
38
|
+
const PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];
|
|
39
|
+
|
|
40
|
+
const SERVICE_CONFIGS: Record<
|
|
41
|
+
string,
|
|
42
|
+
Pick<
|
|
43
|
+
ServiceDescriptor,
|
|
44
|
+
"command" | "args" | "readyPatterns" | "errorPatterns" | "defaultPort" | "readinessPath"
|
|
45
|
+
>
|
|
46
|
+
> = {
|
|
47
|
+
host: {
|
|
48
|
+
command: "bun",
|
|
49
|
+
args: ["run", "dev"],
|
|
50
|
+
readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],
|
|
51
|
+
errorPatterns: [/error:/i, /failed/i, /exception/i],
|
|
52
|
+
defaultPort: 3000,
|
|
53
|
+
readinessPath: "/health",
|
|
54
|
+
},
|
|
55
|
+
auth: {
|
|
56
|
+
command: "bun",
|
|
57
|
+
args: ["run", "dev"],
|
|
58
|
+
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
59
|
+
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
60
|
+
defaultPort: 3002,
|
|
61
|
+
readinessPath: "/remoteEntry.js",
|
|
62
|
+
},
|
|
63
|
+
ui: {
|
|
64
|
+
command: "bun",
|
|
65
|
+
args: ["run", "dev"],
|
|
66
|
+
readyPatterns: [/\bready\s+built in\b/i, /\bLocal:\b/i, /\bcompiled\b.*successfully/i],
|
|
67
|
+
errorPatterns: [/error/i, /failed to compile/i],
|
|
68
|
+
defaultPort: 3003,
|
|
69
|
+
readinessPath: "/remoteEntry.js",
|
|
70
|
+
},
|
|
71
|
+
"ui-ssr": {
|
|
72
|
+
command: "bun",
|
|
73
|
+
args: ["run", "dev:ssr"],
|
|
74
|
+
readyPatterns: [/\bready\s+built in\b/i, /\bcompiled\b.*successfully/i],
|
|
75
|
+
errorPatterns: [/error/i, /failed/i],
|
|
76
|
+
defaultPort: 3004,
|
|
77
|
+
readinessPath: "/",
|
|
78
|
+
},
|
|
79
|
+
api: {
|
|
80
|
+
command: "bun",
|
|
81
|
+
args: ["run", "dev"],
|
|
82
|
+
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
83
|
+
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
84
|
+
defaultPort: 3001,
|
|
85
|
+
readinessPath: "/remoteEntry.js",
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export function buildServiceDescriptorMap(
|
|
90
|
+
runtimeConfig: RuntimeConfig,
|
|
91
|
+
options?: { ssr?: boolean; proxy?: boolean },
|
|
92
|
+
): Map<string, ServiceDescriptor> {
|
|
93
|
+
const map = new Map<string, ServiceDescriptor>();
|
|
94
|
+
const ssr = options?.ssr ?? false;
|
|
95
|
+
|
|
96
|
+
const hostIsRemote = runtimeConfig.host.source === "remote";
|
|
97
|
+
const hostProbeUrl = hostIsRemote
|
|
98
|
+
? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)
|
|
99
|
+
: runtimeConfig.host.url;
|
|
100
|
+
map.set("host", {
|
|
101
|
+
key: "host",
|
|
102
|
+
source: runtimeConfig.host.source,
|
|
103
|
+
url: hostProbeUrl,
|
|
104
|
+
remoteUrl: runtimeConfig.host.remoteUrl,
|
|
105
|
+
entry: hostIsRemote
|
|
106
|
+
? hostProbeUrl
|
|
107
|
+
? `${hostProbeUrl}/mf-manifest.json`
|
|
108
|
+
: "/mf-manifest.json"
|
|
109
|
+
: runtimeConfig.host.entry,
|
|
110
|
+
name: runtimeConfig.host.name,
|
|
111
|
+
localPath: runtimeConfig.host.localPath,
|
|
112
|
+
port: runtimeConfig.host.port,
|
|
113
|
+
integrity: runtimeConfig.host.integrity,
|
|
114
|
+
secrets: runtimeConfig.host.secrets,
|
|
115
|
+
...SERVICE_CONFIGS.host,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
map.set("ui", {
|
|
119
|
+
key: "ui",
|
|
120
|
+
source: runtimeConfig.ui.source,
|
|
121
|
+
url: runtimeConfig.ui.url,
|
|
122
|
+
remoteUrl: runtimeConfig.ui.source === "remote" ? runtimeConfig.ui.url : undefined,
|
|
123
|
+
entry: runtimeConfig.ui.entry,
|
|
124
|
+
name: runtimeConfig.ui.name,
|
|
125
|
+
localPath: runtimeConfig.ui.localPath,
|
|
126
|
+
port: runtimeConfig.ui.port,
|
|
127
|
+
integrity: runtimeConfig.ui.integrity,
|
|
128
|
+
ssr,
|
|
129
|
+
...SERVICE_CONFIGS.ui,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (ssr && runtimeConfig.ui.source === "local") {
|
|
133
|
+
map.set("ui-ssr", {
|
|
134
|
+
key: "ui-ssr",
|
|
135
|
+
source: runtimeConfig.ui.source,
|
|
136
|
+
url: runtimeConfig.ui.ssrUrl ?? "",
|
|
137
|
+
entry: "",
|
|
138
|
+
name: "ui-ssr",
|
|
139
|
+
localPath: runtimeConfig.ui.localPath,
|
|
140
|
+
port: runtimeConfig.ui.ssrUrl
|
|
141
|
+
? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)
|
|
142
|
+
: (runtimeConfig.ui.port ?? 3003) + 1,
|
|
143
|
+
...SERVICE_CONFIGS["ui-ssr"],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
map.set("api", {
|
|
148
|
+
key: "api",
|
|
149
|
+
source: runtimeConfig.api.source,
|
|
150
|
+
url: runtimeConfig.api.url,
|
|
151
|
+
remoteUrl: runtimeConfig.api.source === "remote" ? runtimeConfig.api.url : undefined,
|
|
152
|
+
entry: runtimeConfig.api.entry,
|
|
153
|
+
name: runtimeConfig.api.name,
|
|
154
|
+
localPath: runtimeConfig.api.localPath,
|
|
155
|
+
port: runtimeConfig.api.port,
|
|
156
|
+
integrity: runtimeConfig.api.integrity,
|
|
157
|
+
proxy: runtimeConfig.api.proxy,
|
|
158
|
+
variables: runtimeConfig.api.variables,
|
|
159
|
+
secrets: runtimeConfig.api.secrets,
|
|
160
|
+
...SERVICE_CONFIGS.api,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (runtimeConfig.auth) {
|
|
164
|
+
map.set("auth", {
|
|
165
|
+
key: "auth",
|
|
166
|
+
source: runtimeConfig.auth.source,
|
|
167
|
+
url: runtimeConfig.auth.url,
|
|
168
|
+
remoteUrl: runtimeConfig.auth.source === "remote" ? runtimeConfig.auth.url : undefined,
|
|
169
|
+
entry: runtimeConfig.auth.entry,
|
|
170
|
+
name: runtimeConfig.auth.name,
|
|
171
|
+
localPath: runtimeConfig.auth.localPath,
|
|
172
|
+
port: runtimeConfig.auth.port,
|
|
173
|
+
integrity: runtimeConfig.auth.integrity,
|
|
174
|
+
proxy: runtimeConfig.auth.proxy,
|
|
175
|
+
variables: runtimeConfig.auth.variables,
|
|
176
|
+
secrets: runtimeConfig.auth.secrets,
|
|
177
|
+
...SERVICE_CONFIGS.auth,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (runtimeConfig.plugins) {
|
|
182
|
+
let pluginBasePort = 3010;
|
|
183
|
+
for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {
|
|
184
|
+
const pluginKey = `plugin:${pluginId}`;
|
|
185
|
+
const resolvedPort = pluginConfig.port ?? pluginBasePort;
|
|
186
|
+
pluginBasePort = resolvedPort + 1;
|
|
187
|
+
|
|
188
|
+
map.set(pluginKey, {
|
|
189
|
+
key: pluginKey,
|
|
190
|
+
source: pluginConfig.source,
|
|
191
|
+
url: pluginConfig.url,
|
|
192
|
+
remoteUrl: pluginConfig.source === "remote" ? pluginConfig.url : undefined,
|
|
193
|
+
entry: pluginConfig.entry,
|
|
194
|
+
name: pluginConfig.name,
|
|
195
|
+
localPath: pluginConfig.localPath,
|
|
196
|
+
port: resolvedPort,
|
|
197
|
+
integrity: pluginConfig.integrity,
|
|
198
|
+
proxy: pluginConfig.proxy,
|
|
199
|
+
variables: pluginConfig.variables,
|
|
200
|
+
secrets: pluginConfig.secrets,
|
|
201
|
+
command: "bun",
|
|
202
|
+
args: ["run", "dev"],
|
|
203
|
+
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
204
|
+
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
205
|
+
defaultPort: resolvedPort,
|
|
206
|
+
readinessPath: "/remoteEntry.js",
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return map;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface AppOrchestrator {
|
|
215
|
+
packages: string[];
|
|
216
|
+
description: string;
|
|
217
|
+
env: Record<string, string>;
|
|
218
|
+
port?: number;
|
|
219
|
+
interactive?: boolean;
|
|
220
|
+
noLogs?: boolean;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>
|
|
224
|
+
Layer.succeed(ServiceDescriptorMap, map);
|
|
225
|
+
|
|
226
|
+
export const DevRuntimeConfigLive = (config: RuntimeConfig) =>
|
|
227
|
+
Layer.succeed(DevRuntimeConfig, config);
|
|
228
|
+
|
|
229
|
+
export function buildDescription(map: Map<string, ServiceDescriptor>): string {
|
|
230
|
+
const descriptors = [...map.values()].filter(
|
|
231
|
+
(d) => d.key !== "ui-ssr" && !d.key.startsWith("plugin:"),
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const allLocal = descriptors.every((d) => d.source === "local");
|
|
235
|
+
const hasProxy = [...map.values()].some((d) => d.proxy && d.source === "local");
|
|
236
|
+
if (allLocal && !hasProxy) return "Full Local Development";
|
|
237
|
+
|
|
238
|
+
const parts: string[] = [];
|
|
239
|
+
for (const d of descriptors) {
|
|
240
|
+
if (d.source === "remote") {
|
|
241
|
+
const label =
|
|
242
|
+
d.key === "host"
|
|
243
|
+
? "Remote Host"
|
|
244
|
+
: d.key === "ui"
|
|
245
|
+
? "Remote UI"
|
|
246
|
+
: d.key === "api"
|
|
247
|
+
? hasProxy
|
|
248
|
+
? undefined
|
|
249
|
+
: "Remote API"
|
|
250
|
+
: d.key === "auth"
|
|
251
|
+
? "Remote Auth"
|
|
252
|
+
: undefined;
|
|
253
|
+
if (label) parts.push(label);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (hasProxy) parts.push("Proxy API → Production");
|
|
257
|
+
return parts.join(" + ") || "Remote Mode";
|
|
258
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -144,7 +144,12 @@ export const RuntimeConfigSchema = z.object({
|
|
|
144
144
|
networkId: z.enum(["mainnet", "testnet"]),
|
|
145
145
|
title: z.string().optional(),
|
|
146
146
|
repository: z.string().optional(),
|
|
147
|
-
|
|
147
|
+
host: FederationEntrySchema.extend({
|
|
148
|
+
localPath: z.string().optional(),
|
|
149
|
+
port: z.number().optional(),
|
|
150
|
+
secrets: z.array(z.string()).optional(),
|
|
151
|
+
remoteUrl: z.string().optional(),
|
|
152
|
+
}),
|
|
148
153
|
shared: z
|
|
149
154
|
.object({
|
|
150
155
|
ui: z.record(z.string(), SharedConfigSchema).optional(),
|
|
@@ -175,6 +180,7 @@ export const RuntimeConfigSchema = z.object({
|
|
|
175
180
|
export type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;
|
|
176
181
|
|
|
177
182
|
export const ClientRuntimeConfigSchema = z.object({
|
|
183
|
+
cspNonce: z.string().optional(),
|
|
178
184
|
env: z.enum(["development", "production"]),
|
|
179
185
|
account: z.string(),
|
|
180
186
|
networkId: z.enum(["mainnet", "testnet"]),
|
|
@@ -183,6 +189,7 @@ export const ClientRuntimeConfigSchema = z.object({
|
|
|
183
189
|
apiBase: z.string(),
|
|
184
190
|
rpcBase: z.string(),
|
|
185
191
|
repository: z.string().optional(),
|
|
192
|
+
authAvailable: z.boolean().optional(),
|
|
186
193
|
runtime: ClientRuntimeInfoSchema.optional(),
|
|
187
194
|
ui: z
|
|
188
195
|
.object({
|
package/src/ui/runtime.ts
CHANGED
|
@@ -82,3 +82,8 @@ export function getRepository(config?: Partial<ClientRuntimeConfig>): string | u
|
|
|
82
82
|
const cfg = config ?? getRuntimeConfig();
|
|
83
83
|
return cfg?.repository;
|
|
84
84
|
}
|
|
85
|
+
|
|
86
|
+
export function getCspNonce(config?: Partial<ClientRuntimeConfig>): string | undefined {
|
|
87
|
+
const cfg = config ?? getRuntimeConfig();
|
|
88
|
+
return cfg?.cspNonce;
|
|
89
|
+
}
|