everything-dev 0.3.3 → 1.3.3

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.
Files changed (313) hide show
  1. package/README.md +64 -0
  2. package/cli.js +10 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  4. package/dist/api-contract.cjs +172 -0
  5. package/dist/api-contract.cjs.map +1 -0
  6. package/dist/api-contract.mjs +171 -0
  7. package/dist/api-contract.mjs.map +1 -0
  8. package/dist/api.cjs +124 -0
  9. package/dist/api.cjs.map +1 -0
  10. package/dist/api.d.cts +36 -0
  11. package/dist/api.d.cts.map +1 -0
  12. package/dist/api.d.mts +36 -0
  13. package/dist/api.d.mts.map +1 -0
  14. package/dist/api.mjs +119 -0
  15. package/dist/api.mjs.map +1 -0
  16. package/dist/app.cjs +156 -0
  17. package/dist/app.cjs.map +1 -0
  18. package/dist/app.mjs +153 -0
  19. package/dist/app.mjs.map +1 -0
  20. package/dist/cli/catalog.cjs +30 -0
  21. package/dist/cli/catalog.cjs.map +1 -0
  22. package/dist/cli/catalog.mjs +29 -0
  23. package/dist/cli/catalog.mjs.map +1 -0
  24. package/dist/cli/help.cjs +16 -0
  25. package/dist/cli/help.cjs.map +1 -0
  26. package/dist/cli/help.mjs +16 -0
  27. package/dist/cli/help.mjs.map +1 -0
  28. package/dist/cli/init.cjs +287 -0
  29. package/dist/cli/init.cjs.map +1 -0
  30. package/dist/cli/init.d.cts +36 -0
  31. package/dist/cli/init.d.cts.map +1 -0
  32. package/dist/cli/init.d.mts +36 -0
  33. package/dist/cli/init.d.mts.map +1 -0
  34. package/dist/cli/init.mjs +279 -0
  35. package/dist/cli/init.mjs.map +1 -0
  36. package/dist/cli/parse.cjs +96 -0
  37. package/dist/cli/parse.cjs.map +1 -0
  38. package/dist/cli/parse.mjs +95 -0
  39. package/dist/cli/parse.mjs.map +1 -0
  40. package/dist/cli/prompts.cjs +42 -0
  41. package/dist/cli/prompts.cjs.map +1 -0
  42. package/dist/cli/prompts.mjs +41 -0
  43. package/dist/cli/prompts.mjs.map +1 -0
  44. package/dist/cli.cjs +167 -0
  45. package/dist/cli.cjs.map +1 -0
  46. package/dist/cli.d.cts +1 -0
  47. package/dist/cli.d.mts +1 -0
  48. package/dist/cli.mjs +166 -0
  49. package/dist/cli.mjs.map +1 -0
  50. package/dist/components/dev-view.cjs +307 -0
  51. package/dist/components/dev-view.cjs.map +1 -0
  52. package/dist/components/dev-view.mjs +306 -0
  53. package/dist/components/dev-view.mjs.map +1 -0
  54. package/dist/components/streaming-view.cjs +146 -0
  55. package/dist/components/streaming-view.cjs.map +1 -0
  56. package/dist/components/streaming-view.mjs +144 -0
  57. package/dist/components/streaming-view.mjs.map +1 -0
  58. package/dist/config.cjs +280 -0
  59. package/dist/config.cjs.map +1 -0
  60. package/dist/config.d.cts +35 -0
  61. package/dist/config.d.cts.map +1 -0
  62. package/dist/config.d.mts +35 -0
  63. package/dist/config.d.mts.map +1 -0
  64. package/dist/config.mjs +266 -0
  65. package/dist/config.mjs.map +1 -0
  66. package/dist/contract.cjs +209 -0
  67. package/dist/contract.cjs.map +1 -0
  68. package/dist/contract.d.cts +490 -0
  69. package/dist/contract.d.cts.map +1 -0
  70. package/dist/contract.d.mts +490 -0
  71. package/dist/contract.d.mts.map +1 -0
  72. package/dist/contract.meta.cjs +104 -0
  73. package/dist/contract.meta.cjs.map +1 -0
  74. package/dist/contract.meta.d.cts +141 -0
  75. package/dist/contract.meta.d.cts.map +1 -0
  76. package/dist/contract.meta.d.mts +141 -0
  77. package/dist/contract.meta.d.mts.map +1 -0
  78. package/dist/contract.meta.mjs +102 -0
  79. package/dist/contract.meta.mjs.map +1 -0
  80. package/dist/contract.mjs +186 -0
  81. package/dist/contract.mjs.map +1 -0
  82. package/dist/dev-logs.cjs +53 -0
  83. package/dist/dev-logs.cjs.map +1 -0
  84. package/dist/dev-logs.mjs +51 -0
  85. package/dist/dev-logs.mjs.map +1 -0
  86. package/dist/dev-session.cjs +195 -0
  87. package/dist/dev-session.cjs.map +1 -0
  88. package/dist/dev-session.mjs +194 -0
  89. package/dist/dev-session.mjs.map +1 -0
  90. package/dist/fastkv.cjs +89 -0
  91. package/dist/fastkv.cjs.map +1 -0
  92. package/dist/fastkv.d.cts +11 -0
  93. package/dist/fastkv.d.cts.map +1 -0
  94. package/dist/fastkv.d.mts +11 -0
  95. package/dist/fastkv.d.mts.map +1 -0
  96. package/dist/fastkv.mjs +82 -0
  97. package/dist/fastkv.mjs.map +1 -0
  98. package/dist/federation.server.cjs +27 -0
  99. package/dist/federation.server.cjs.map +1 -0
  100. package/dist/federation.server.mjs +27 -0
  101. package/dist/federation.server.mjs.map +1 -0
  102. package/dist/host.cjs +367 -0
  103. package/dist/host.cjs.map +1 -0
  104. package/dist/host.d.cts +22 -0
  105. package/dist/host.d.cts.map +1 -0
  106. package/dist/host.d.mts +22 -0
  107. package/dist/host.d.mts.map +1 -0
  108. package/dist/host.mjs +364 -0
  109. package/dist/host.mjs.map +1 -0
  110. package/dist/index.cjs +122 -0
  111. package/dist/index.d.cts +7 -0
  112. package/dist/index.d.mts +7 -0
  113. package/dist/index.mjs +9 -0
  114. package/dist/integrity.cjs +39 -0
  115. package/dist/integrity.cjs.map +1 -0
  116. package/dist/integrity.d.cts +7 -0
  117. package/dist/integrity.d.cts.map +1 -0
  118. package/dist/integrity.d.mts +7 -0
  119. package/dist/integrity.d.mts.map +1 -0
  120. package/dist/integrity.mjs +35 -0
  121. package/dist/integrity.mjs.map +1 -0
  122. package/dist/internal/manifest-normalizer.cjs +140 -0
  123. package/dist/internal/manifest-normalizer.cjs.map +1 -0
  124. package/dist/internal/manifest-normalizer.mjs +138 -0
  125. package/dist/internal/manifest-normalizer.mjs.map +1 -0
  126. package/dist/mf.cjs +77 -0
  127. package/dist/mf.cjs.map +1 -0
  128. package/dist/mf.d.cts +19 -0
  129. package/dist/mf.d.cts.map +1 -0
  130. package/dist/mf.d.mts +19 -0
  131. package/dist/mf.d.mts.map +1 -0
  132. package/dist/mf.mjs +71 -0
  133. package/dist/mf.mjs.map +1 -0
  134. package/dist/near-cli.cjs +196 -0
  135. package/dist/near-cli.cjs.map +1 -0
  136. package/dist/near-cli.mjs +193 -0
  137. package/dist/near-cli.mjs.map +1 -0
  138. package/dist/network.cjs +9 -0
  139. package/dist/network.cjs.map +1 -0
  140. package/dist/network.mjs +8 -0
  141. package/dist/network.mjs.map +1 -0
  142. package/dist/orchestrator.cjs +441 -0
  143. package/dist/orchestrator.cjs.map +1 -0
  144. package/dist/orchestrator.d.cts +40 -0
  145. package/dist/orchestrator.d.cts.map +1 -0
  146. package/dist/orchestrator.d.mts +40 -0
  147. package/dist/orchestrator.d.mts.map +1 -0
  148. package/dist/orchestrator.mjs +436 -0
  149. package/dist/orchestrator.mjs.map +1 -0
  150. package/dist/plugin.cjs +830 -0
  151. package/dist/plugin.cjs.map +1 -0
  152. package/dist/plugin.d.cts +347 -0
  153. package/dist/plugin.d.cts.map +1 -0
  154. package/dist/plugin.d.mts +348 -0
  155. package/dist/plugin.d.mts.map +1 -0
  156. package/dist/plugin.mjs +827 -0
  157. package/dist/plugin.mjs.map +1 -0
  158. package/dist/process-registry.cjs +120 -0
  159. package/dist/process-registry.cjs.map +1 -0
  160. package/dist/process-registry.d.cts +25 -0
  161. package/dist/process-registry.d.cts.map +1 -0
  162. package/dist/process-registry.d.mts +25 -0
  163. package/dist/process-registry.d.mts.map +1 -0
  164. package/dist/process-registry.mjs +119 -0
  165. package/dist/process-registry.mjs.map +1 -0
  166. package/dist/sdk.cjs +61 -0
  167. package/dist/sdk.d.cts +5 -0
  168. package/dist/sdk.d.mts +5 -0
  169. package/dist/sdk.mjs +6 -0
  170. package/dist/shared.cjs +143 -0
  171. package/dist/shared.cjs.map +1 -0
  172. package/dist/shared.d.cts +33 -0
  173. package/dist/shared.d.cts.map +1 -0
  174. package/dist/shared.d.mts +33 -0
  175. package/dist/shared.d.mts.map +1 -0
  176. package/dist/shared.mjs +140 -0
  177. package/dist/shared.mjs.map +1 -0
  178. package/dist/types.cjs +160 -0
  179. package/dist/types.cjs.map +1 -0
  180. package/dist/types.d.cts +269 -0
  181. package/dist/types.d.cts.map +1 -0
  182. package/dist/types.d.mts +269 -0
  183. package/dist/types.d.mts.map +1 -0
  184. package/dist/types.mjs +144 -0
  185. package/dist/types.mjs.map +1 -0
  186. package/dist/ui/head.cjs +67 -0
  187. package/dist/ui/head.cjs.map +1 -0
  188. package/dist/ui/head.d.cts +19 -0
  189. package/dist/ui/head.d.cts.map +1 -0
  190. package/dist/ui/head.d.mts +19 -0
  191. package/dist/ui/head.d.mts.map +1 -0
  192. package/dist/ui/head.mjs +61 -0
  193. package/dist/ui/head.mjs.map +1 -0
  194. package/dist/ui/index.cjs +32 -0
  195. package/dist/ui/index.d.cts +7 -0
  196. package/dist/ui/index.d.mts +7 -0
  197. package/dist/ui/index.mjs +6 -0
  198. package/dist/ui/metadata.cjs +106 -0
  199. package/dist/ui/metadata.cjs.map +1 -0
  200. package/dist/ui/metadata.d.cts +35 -0
  201. package/dist/ui/metadata.d.cts.map +1 -0
  202. package/dist/ui/metadata.d.mts +35 -0
  203. package/dist/ui/metadata.d.mts.map +1 -0
  204. package/dist/ui/metadata.mjs +100 -0
  205. package/dist/ui/metadata.mjs.map +1 -0
  206. package/dist/ui/router.cjs +56 -0
  207. package/dist/ui/router.cjs.map +1 -0
  208. package/dist/ui/router.d.cts +11 -0
  209. package/dist/ui/router.d.cts.map +1 -0
  210. package/dist/ui/router.d.mts +11 -0
  211. package/dist/ui/router.d.mts.map +1 -0
  212. package/dist/ui/router.mjs +51 -0
  213. package/dist/ui/router.mjs.map +1 -0
  214. package/dist/ui/runtime.cjs +65 -0
  215. package/dist/ui/runtime.cjs.map +1 -0
  216. package/dist/ui/runtime.d.cts +29 -0
  217. package/dist/ui/runtime.d.cts.map +1 -0
  218. package/dist/ui/runtime.d.mts +29 -0
  219. package/dist/ui/runtime.d.mts.map +1 -0
  220. package/dist/ui/runtime.mjs +53 -0
  221. package/dist/ui/runtime.mjs.map +1 -0
  222. package/dist/ui/types.cjs +0 -0
  223. package/dist/ui/types.d.cts +52 -0
  224. package/dist/ui/types.d.cts.map +1 -0
  225. package/dist/ui/types.d.mts +52 -0
  226. package/dist/ui/types.d.mts.map +1 -0
  227. package/dist/ui/types.mjs +1 -0
  228. package/dist/utils/banner.cjs +24 -0
  229. package/dist/utils/banner.cjs.map +1 -0
  230. package/dist/utils/banner.mjs +23 -0
  231. package/dist/utils/banner.mjs.map +1 -0
  232. package/dist/utils/linkify.cjs +15 -0
  233. package/dist/utils/linkify.cjs.map +1 -0
  234. package/dist/utils/linkify.mjs +14 -0
  235. package/dist/utils/linkify.mjs.map +1 -0
  236. package/dist/utils/run.cjs +40 -0
  237. package/dist/utils/run.cjs.map +1 -0
  238. package/dist/utils/run.mjs +39 -0
  239. package/dist/utils/run.mjs.map +1 -0
  240. package/dist/utils/theme.cjs +44 -0
  241. package/dist/utils/theme.cjs.map +1 -0
  242. package/dist/utils/theme.mjs +37 -0
  243. package/dist/utils/theme.mjs.map +1 -0
  244. package/package.json +269 -80
  245. package/src/api-contract.ts +309 -0
  246. package/src/api.ts +181 -0
  247. package/src/app.ts +346 -0
  248. package/src/cli/catalog.ts +49 -0
  249. package/src/cli/help.ts +13 -0
  250. package/src/cli/init.ts +386 -0
  251. package/src/cli/parse.ts +130 -0
  252. package/src/cli/prompts.ts +64 -0
  253. package/src/cli.ts +203 -1507
  254. package/src/components/dev-view.tsx +307 -255
  255. package/src/components/streaming-view.ts +164 -128
  256. package/src/config.ts +462 -532
  257. package/src/contract.meta.ts +96 -0
  258. package/src/contract.ts +164 -561
  259. package/src/dev-logs.ts +85 -0
  260. package/src/dev-session.ts +318 -0
  261. package/src/fastkv.ts +153 -0
  262. package/src/federation.server.ts +43 -0
  263. package/src/host.ts +526 -0
  264. package/src/index.ts +6 -3
  265. package/src/integrity.ts +54 -0
  266. package/src/internal/manifest-normalizer.ts +251 -0
  267. package/src/mf.ts +105 -0
  268. package/src/near-cli.ts +284 -0
  269. package/src/network.ts +3 -0
  270. package/src/orchestrator.ts +648 -0
  271. package/src/plugin.ts +1130 -2311
  272. package/src/process-registry.ts +154 -0
  273. package/src/scripts/sync-api-contract.ts +24 -0
  274. package/src/sdk.ts +14 -0
  275. package/src/shared.ts +206 -0
  276. package/src/types.ts +152 -206
  277. package/src/ui/head.ts +34 -27
  278. package/src/ui/index.ts +3 -3
  279. package/src/ui/metadata.ts +95 -0
  280. package/src/ui/router.ts +22 -6
  281. package/src/ui/runtime.ts +55 -6
  282. package/src/ui/types.ts +24 -11
  283. package/src/utils/banner.ts +10 -6
  284. package/src/utils/run.ts +26 -27
  285. package/src/utils/theme.ts +3 -66
  286. package/src/components/monitor-view.tsx +0 -475
  287. package/src/components/status-view.tsx +0 -173
  288. package/src/lib/env.ts +0 -109
  289. package/src/lib/near-cli.ts +0 -289
  290. package/src/lib/nova.ts +0 -266
  291. package/src/lib/orchestrator.ts +0 -276
  292. package/src/lib/process-registry.ts +0 -166
  293. package/src/lib/process.ts +0 -550
  294. package/src/lib/resource-monitor/assertions.ts +0 -234
  295. package/src/lib/resource-monitor/command.ts +0 -283
  296. package/src/lib/resource-monitor/diff.ts +0 -157
  297. package/src/lib/resource-monitor/errors.ts +0 -127
  298. package/src/lib/resource-monitor/index.ts +0 -305
  299. package/src/lib/resource-monitor/platform/darwin.ts +0 -306
  300. package/src/lib/resource-monitor/platform/index.ts +0 -35
  301. package/src/lib/resource-monitor/platform/linux.ts +0 -332
  302. package/src/lib/resource-monitor/platform/windows.ts +0 -298
  303. package/src/lib/resource-monitor/snapshot.ts +0 -217
  304. package/src/lib/resource-monitor/types.ts +0 -74
  305. package/src/lib/session-recorder/errors.ts +0 -102
  306. package/src/lib/session-recorder/flows/login.ts +0 -210
  307. package/src/lib/session-recorder/index.ts +0 -361
  308. package/src/lib/session-recorder/playwright.ts +0 -257
  309. package/src/lib/session-recorder/report.ts +0 -353
  310. package/src/lib/session-recorder/server.ts +0 -268
  311. package/src/lib/session-recorder/types.ts +0 -115
  312. package/src/lib/sync.ts +0 -1
  313. package/src/ui/files.ts +0 -134
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastkv.d.mts","names":[],"sources":["../src/fastkv.ts"],"mappings":";KAAY,SAAA;AAAA,iBAgBI,0BAAA,CAA2B,OAAA,EAAS,SAAA;AAAA,iBAYpC,sBAAA,CAAuB,SAAA,UAAmB,SAAA;AAAA,iBAO1C,gCAAA,CACd,OAAA,EAAS,SAAA,EACT,SAAA,UACA,SAAA;AAAA,iBAQc,8BAAA,CAA+B,SAAA;AAAA,iBAM/B,8BAAA,CAA+B,OAAA,EAAS,SAAA;AAAA,iBAgDlC,wBAAA,GAAA,CAA4B,MAAA,WAAiB,OAAA,CAAQ,CAAA"}
@@ -0,0 +1,82 @@
1
+ //#region src/fastkv.ts
2
+ const FASTKV_TIMEOUT_MS = 1e4;
3
+ function getNetworkIdForAccount(accountId) {
4
+ return accountId.endsWith(".testnet") ? "testnet" : "mainnet";
5
+ }
6
+ function getFastKvBaseUrlForNetwork(network) {
7
+ return network === "testnet" ? process.env.REGISTRY_FASTKV_TESTNET_URL || "https://kv.test.fastnear.com" : process.env.REGISTRY_FASTKV_MAINNET_URL || "https://kv.main.fastnear.com";
8
+ }
9
+ function getFastKvBaseUrlForAccount(accountId) {
10
+ return getNetworkIdForAccount(accountId) === "testnet" ? getFastKvBaseUrlForNetwork("testnet") : getFastKvBaseUrlForNetwork("mainnet");
11
+ }
12
+ function buildRegistryConfigUrl(accountId, gatewayId) {
13
+ const baseUrl = getFastKvBaseUrlForAccount(accountId);
14
+ const namespace = getRegistryNamespaceForAccount(accountId);
15
+ const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));
16
+ return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;
17
+ }
18
+ function buildRegistryConfigUrlForNetwork(network, accountId, gatewayId) {
19
+ const baseUrl = getFastKvBaseUrlForNetwork(network);
20
+ const namespace = getRegistryNamespaceForNetwork(network);
21
+ const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));
22
+ return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;
23
+ }
24
+ function getRegistryNamespaceForAccount(accountId) {
25
+ return accountId.endsWith(".testnet") ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || "dev.everything.near" : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || accountId;
26
+ }
27
+ function getRegistryNamespaceForNetwork(network) {
28
+ return network === "testnet" ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || "dev.everything.near" : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || "dev.everything.near";
29
+ }
30
+ function getRegistryConfigKey(accountId, gatewayId, pathSegments = []) {
31
+ return `apps/${accountId}/${gatewayId}${pathSegments.length > 0 ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}` : ""}/bos.config.json`;
32
+ }
33
+ function parseBosUrl(bosUrl) {
34
+ const match = bosUrl.match(/^bos:\/\/([^/]+)\/(.+)$/);
35
+ if (!match?.[1] || !match[2]) throw new Error(`Invalid BOS URL: ${bosUrl}`);
36
+ const pathSegments = match[2].split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
37
+ if (pathSegments.length === 0) throw new Error(`Invalid BOS URL: ${bosUrl}`);
38
+ const [gatewayId, ...pathSegmentsTail] = pathSegments;
39
+ if (!gatewayId) throw new Error(`Invalid BOS URL: ${bosUrl}`);
40
+ return {
41
+ accountId: match[1],
42
+ gatewayId,
43
+ pathSegments: pathSegmentsTail
44
+ };
45
+ }
46
+ async function fetchBosConfigFromFastKv(bosUrl) {
47
+ const { accountId, gatewayId, pathSegments } = parseBosUrl(bosUrl);
48
+ const value = (await fetchJson(`${getFastKvBaseUrlForAccount(accountId)}/v0/latest/${encodeURIComponent(getRegistryNamespaceForAccount(accountId))}/${encodeURIComponent(accountId)}`, {
49
+ method: "POST",
50
+ body: JSON.stringify({
51
+ key: getRegistryConfigKey(accountId, gatewayId, pathSegments),
52
+ limit: 1
53
+ })
54
+ }))?.entries?.find(Boolean)?.value;
55
+ if (!value) throw new Error(`No config found for ${bosUrl}`);
56
+ if (typeof value === "string") return JSON.parse(value);
57
+ if (typeof value !== "object") throw new Error(`Invalid config value for ${bosUrl}`);
58
+ return value;
59
+ }
60
+ async function fetchJson(url, init) {
61
+ const controller = new AbortController();
62
+ const timeout = setTimeout(() => controller.abort(), FASTKV_TIMEOUT_MS);
63
+ try {
64
+ const response = await fetch(url, {
65
+ ...init,
66
+ headers: {
67
+ accept: "application/json",
68
+ "content-type": "application/json",
69
+ ...init?.headers ?? {}
70
+ },
71
+ signal: controller.signal
72
+ });
73
+ if (!response.ok) return null;
74
+ return await response.json();
75
+ } finally {
76
+ clearTimeout(timeout);
77
+ }
78
+ }
79
+
80
+ //#endregion
81
+ export { buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, getFastKvBaseUrlForNetwork, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork };
82
+ //# sourceMappingURL=fastkv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastkv.mjs","names":[],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n value: unknown;\n}\n\ninterface FastKvListResponse {\n entries?: Array<FastKvEntry | null>;\n}\n\nconst FASTKV_TIMEOUT_MS = 10_000;\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n return getNetworkIdForAccount(accountId) === \"testnet\"\n ? getFastKvBaseUrlForNetwork(\"testnet\")\n : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n const baseUrl = getFastKvBaseUrlForAccount(accountId);\n const namespace = getRegistryNamespaceForAccount(accountId);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n network: NetworkId,\n accountId: string,\n gatewayId: string,\n): string {\n const baseUrl = getFastKvBaseUrlForNetwork(network);\n const namespace = getRegistryNamespaceForNetwork(network);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n return accountId.endsWith(\".testnet\")\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || accountId;\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n accountId: string,\n gatewayId: string,\n pathSegments: string[] = [],\n): string {\n const suffix =\n pathSegments.length > 0\n ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n : \"\";\n return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nfunction parseBosUrl(bosUrl: string): {\n accountId: string;\n gatewayId: string;\n pathSegments: string[];\n} {\n const match = bosUrl.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match?.[1] || !match[2]) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const pathSegments = match[2]\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => decodeURIComponent(segment));\n if (pathSegments.length === 0) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const [gatewayId, ...pathSegmentsTail] = pathSegments;\n if (!gatewayId) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n return {\n accountId: match[1],\n gatewayId,\n pathSegments: pathSegmentsTail,\n };\n}\n\nexport async function fetchBosConfigFromFastKv<T>(bosUrl: string): Promise<T> {\n const { accountId, gatewayId, pathSegments } = parseBosUrl(bosUrl);\n const payload = await fetchJson<FastKvListResponse>(\n `${getFastKvBaseUrlForAccount(accountId)}/v0/latest/${encodeURIComponent(getRegistryNamespaceForAccount(accountId))}/${encodeURIComponent(accountId)}`,\n {\n method: \"POST\",\n body: JSON.stringify({\n key: getRegistryConfigKey(accountId, gatewayId, pathSegments),\n limit: 1,\n }),\n },\n );\n const value = payload?.entries?.find(Boolean)?.value;\n\n if (!value) {\n throw new Error(`No config found for ${bosUrl}`);\n }\n\n if (typeof value === \"string\") {\n return JSON.parse(value) as T;\n }\n\n if (typeof value !== \"object\") {\n throw new Error(`Invalid config value for ${bosUrl}`);\n }\n\n return value as T;\n}\n\nasync function fetchJson<T>(url: string, init?: RequestInit): Promise<T | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FASTKV_TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n ...init,\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return null;\n }\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timeout);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ const require_mf = require('./mf.cjs');
2
+ const require_integrity = require('./integrity.cjs');
3
+
4
+ //#region src/federation.server.ts
5
+ async function loadRouterModule(config) {
6
+ const isLocalDev = config.ui.source === "local";
7
+ const ssrUrl = config.ui.ssrUrl ?? (isLocalDev ? config.ui.url : void 0);
8
+ if (!ssrUrl) {
9
+ if (!isLocalDev) throw new Error("SSR URL not configured in production. Set app.ui.ssr in bos.config.json to enable SSR.");
10
+ throw new Error("SSR URL not configured. In local dev, set app.ui.ssr or use a UI package with SSR support.");
11
+ }
12
+ const ssrEntryUrl = `${ssrUrl.replace(/\/$/, "")}/remoteEntry.server.js`;
13
+ if (config.ui.ssrIntegrity) await require_integrity.verifySriForUrl(ssrEntryUrl, config.ui.ssrIntegrity);
14
+ await require_mf.ensureNodeRuntimePlugin();
15
+ await require_mf.registerRemote({
16
+ name: config.ui.name,
17
+ entry: ssrEntryUrl,
18
+ type: "script"
19
+ });
20
+ const loadedModule = await require_mf.loadRemoteModule(`${config.ui.name}/Router`, { from: "build" });
21
+ if (!loadedModule) throw new Error(`Module not found: ${config.ui.name}/Router`);
22
+ return loadedModule.default;
23
+ }
24
+
25
+ //#endregion
26
+ exports.loadRouterModule = loadRouterModule;
27
+ //# sourceMappingURL=federation.server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.server.cjs","names":["verifySriForUrl","ensureNodeRuntimePlugin","registerRemote","loadRemoteModule"],"sources":["../src/federation.server.ts"],"sourcesContent":["import { verifySriForUrl } from \"./integrity\";\nimport { ensureNodeRuntimePlugin, loadRemoteModule, registerRemote } from \"./mf\";\nimport type { RuntimeConfig } from \"./types\";\nimport type { RouterModule } from \"./ui/types\";\n\nexport type { RouterModule };\n\nexport async function loadRouterModule(config: RuntimeConfig): Promise<RouterModule> {\n const isLocalDev = config.ui.source === \"local\";\n const ssrUrl = config.ui.ssrUrl ?? (isLocalDev ? config.ui.url : undefined);\n\n if (!ssrUrl) {\n if (!isLocalDev) {\n throw new Error(\n \"SSR URL not configured in production. Set app.ui.ssr in bos.config.json to enable SSR.\",\n );\n }\n\n throw new Error(\n \"SSR URL not configured. In local dev, set app.ui.ssr or use a UI package with SSR support.\",\n );\n }\n\n const ssrEntryUrl = `${ssrUrl.replace(/\\/$/, \"\")}/remoteEntry.server.js`;\n\n if (config.ui.ssrIntegrity) {\n await verifySriForUrl(ssrEntryUrl, config.ui.ssrIntegrity);\n }\n\n await ensureNodeRuntimePlugin();\n await registerRemote({\n name: config.ui.name,\n entry: ssrEntryUrl,\n type: \"script\",\n });\n\n const loadedModule = await loadRemoteModule<any>(`${config.ui.name}/Router`, { from: \"build\" });\n if (!loadedModule) {\n throw new Error(`Module not found: ${config.ui.name}/Router`);\n }\n\n return loadedModule.default as RouterModule;\n}\n"],"mappings":";;;;AAOA,eAAsB,iBAAiB,QAA8C;CACnF,MAAM,aAAa,OAAO,GAAG,WAAW;CACxC,MAAM,SAAS,OAAO,GAAG,WAAW,aAAa,OAAO,GAAG,MAAM;AAEjE,KAAI,CAAC,QAAQ;AACX,MAAI,CAAC,WACH,OAAM,IAAI,MACR,yFACD;AAGH,QAAM,IAAI,MACR,6FACD;;CAGH,MAAM,cAAc,GAAG,OAAO,QAAQ,OAAO,GAAG,CAAC;AAEjD,KAAI,OAAO,GAAG,aACZ,OAAMA,kCAAgB,aAAa,OAAO,GAAG,aAAa;AAG5D,OAAMC,oCAAyB;AAC/B,OAAMC,0BAAe;EACnB,MAAM,OAAO,GAAG;EAChB,OAAO;EACP,MAAM;EACP,CAAC;CAEF,MAAM,eAAe,MAAMC,4BAAsB,GAAG,OAAO,GAAG,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/F,KAAI,CAAC,aACH,OAAM,IAAI,MAAM,qBAAqB,OAAO,GAAG,KAAK,SAAS;AAG/D,QAAO,aAAa"}
@@ -0,0 +1,27 @@
1
+ import { ensureNodeRuntimePlugin, loadRemoteModule, registerRemote } from "./mf.mjs";
2
+ import { verifySriForUrl } from "./integrity.mjs";
3
+
4
+ //#region src/federation.server.ts
5
+ async function loadRouterModule(config) {
6
+ const isLocalDev = config.ui.source === "local";
7
+ const ssrUrl = config.ui.ssrUrl ?? (isLocalDev ? config.ui.url : void 0);
8
+ if (!ssrUrl) {
9
+ if (!isLocalDev) throw new Error("SSR URL not configured in production. Set app.ui.ssr in bos.config.json to enable SSR.");
10
+ throw new Error("SSR URL not configured. In local dev, set app.ui.ssr or use a UI package with SSR support.");
11
+ }
12
+ const ssrEntryUrl = `${ssrUrl.replace(/\/$/, "")}/remoteEntry.server.js`;
13
+ if (config.ui.ssrIntegrity) await verifySriForUrl(ssrEntryUrl, config.ui.ssrIntegrity);
14
+ await ensureNodeRuntimePlugin();
15
+ await registerRemote({
16
+ name: config.ui.name,
17
+ entry: ssrEntryUrl,
18
+ type: "script"
19
+ });
20
+ const loadedModule = await loadRemoteModule(`${config.ui.name}/Router`, { from: "build" });
21
+ if (!loadedModule) throw new Error(`Module not found: ${config.ui.name}/Router`);
22
+ return loadedModule.default;
23
+ }
24
+
25
+ //#endregion
26
+ export { loadRouterModule };
27
+ //# sourceMappingURL=federation.server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.server.mjs","names":[],"sources":["../src/federation.server.ts"],"sourcesContent":["import { verifySriForUrl } from \"./integrity\";\nimport { ensureNodeRuntimePlugin, loadRemoteModule, registerRemote } from \"./mf\";\nimport type { RuntimeConfig } from \"./types\";\nimport type { RouterModule } from \"./ui/types\";\n\nexport type { RouterModule };\n\nexport async function loadRouterModule(config: RuntimeConfig): Promise<RouterModule> {\n const isLocalDev = config.ui.source === \"local\";\n const ssrUrl = config.ui.ssrUrl ?? (isLocalDev ? config.ui.url : undefined);\n\n if (!ssrUrl) {\n if (!isLocalDev) {\n throw new Error(\n \"SSR URL not configured in production. Set app.ui.ssr in bos.config.json to enable SSR.\",\n );\n }\n\n throw new Error(\n \"SSR URL not configured. In local dev, set app.ui.ssr or use a UI package with SSR support.\",\n );\n }\n\n const ssrEntryUrl = `${ssrUrl.replace(/\\/$/, \"\")}/remoteEntry.server.js`;\n\n if (config.ui.ssrIntegrity) {\n await verifySriForUrl(ssrEntryUrl, config.ui.ssrIntegrity);\n }\n\n await ensureNodeRuntimePlugin();\n await registerRemote({\n name: config.ui.name,\n entry: ssrEntryUrl,\n type: \"script\",\n });\n\n const loadedModule = await loadRemoteModule<any>(`${config.ui.name}/Router`, { from: \"build\" });\n if (!loadedModule) {\n throw new Error(`Module not found: ${config.ui.name}/Router`);\n }\n\n return loadedModule.default as RouterModule;\n}\n"],"mappings":";;;;AAOA,eAAsB,iBAAiB,QAA8C;CACnF,MAAM,aAAa,OAAO,GAAG,WAAW;CACxC,MAAM,SAAS,OAAO,GAAG,WAAW,aAAa,OAAO,GAAG,MAAM;AAEjE,KAAI,CAAC,QAAQ;AACX,MAAI,CAAC,WACH,OAAM,IAAI,MACR,yFACD;AAGH,QAAM,IAAI,MACR,6FACD;;CAGH,MAAM,cAAc,GAAG,OAAO,QAAQ,OAAO,GAAG,CAAC;AAEjD,KAAI,OAAO,GAAG,aACZ,OAAM,gBAAgB,aAAa,OAAO,GAAG,aAAa;AAG5D,OAAM,yBAAyB;AAC/B,OAAM,eAAe;EACnB,MAAM,OAAO,GAAG;EAChB,OAAO;EACP,MAAM;EACP,CAAC;CAEF,MAAM,eAAe,MAAM,iBAAsB,GAAG,OAAO,GAAG,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/F,KAAI,CAAC,aACH,OAAM,IAAI,MAAM,qBAAqB,OAAO,GAAG,KAAK,SAAS;AAG/D,QAAO,aAAa"}
package/dist/host.cjs ADDED
@@ -0,0 +1,367 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
3
+ const require_api = require('./api.cjs');
4
+ const require_federation_server = require('./federation.server.cjs');
5
+ let _hono_node_server = require("@hono/node-server");
6
+ let _orpc_openapi_fetch = require("@orpc/openapi/fetch");
7
+ let _orpc_openapi_plugins = require("@orpc/openapi/plugins");
8
+ let _orpc_server_fetch = require("@orpc/server/fetch");
9
+ let _orpc_server_plugins = require("@orpc/server/plugins");
10
+ let _orpc_zod_zod4 = require("@orpc/zod/zod4");
11
+ let hono = require("hono");
12
+ let hono_cors = require("hono/cors");
13
+ let hono_secure_headers = require("hono/secure-headers");
14
+
15
+ //#region src/host.ts
16
+ function buildClientRuntimeConfig(runtimeConfig) {
17
+ return {
18
+ env: runtimeConfig.env,
19
+ account: runtimeConfig.account,
20
+ networkId: runtimeConfig.networkId,
21
+ hostUrl: runtimeConfig.hostUrl,
22
+ assetsUrl: runtimeConfig.ui.url,
23
+ apiBase: "/api",
24
+ rpcBase: "/api/rpc",
25
+ ui: runtimeConfig.ui ? {
26
+ name: runtimeConfig.ui.name,
27
+ url: runtimeConfig.ui.url,
28
+ entry: runtimeConfig.ui.entry,
29
+ integrity: runtimeConfig.ui.integrity
30
+ } : void 0,
31
+ api: runtimeConfig.api ? {
32
+ name: runtimeConfig.api.name,
33
+ url: runtimeConfig.api.url,
34
+ entry: runtimeConfig.api.entry,
35
+ integrity: runtimeConfig.api.integrity
36
+ } : void 0,
37
+ plugins: runtimeConfig.plugins ? Object.fromEntries(Object.entries(runtimeConfig.plugins).map(([key, plugin]) => [key, {
38
+ name: plugin.name,
39
+ url: plugin.url,
40
+ entry: plugin.entry,
41
+ integrity: plugin.integrity
42
+ }])) : void 0
43
+ };
44
+ }
45
+ function renderLoadingShell(runtimeConfig, error) {
46
+ const bootstrap = `window.__RUNTIME_CONFIG__ = ${JSON.stringify(runtimeConfig)};window.addEventListener('load', function handleEverythingDevHydrate() { window.__hydrate?.(); }, { once: true });`;
47
+ const errorMarkup = error ? `<p style="color: #fca5a5;">Error loading UI: ${escapeHtml(error)}</p>` : "<p>Loading UI...</p>";
48
+ const uiIntegrity = runtimeConfig.ui?.integrity;
49
+ const sriAttr = uiIntegrity ? ` integrity="${uiIntegrity}" crossorigin="anonymous"` : "";
50
+ return `
51
+ <!DOCTYPE html>
52
+ <html lang="en">
53
+ <head>
54
+ <meta charset="utf-8" />
55
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
56
+ <title>Loading...</title>
57
+ <style>
58
+ body { background: #171717; color: #fafafa; display: flex; align-items: center; justify-content: center; height: 100vh; font-family: system-ui; }
59
+ .fade { animation: fadeIn 0.3s ease-in; text-align: center; padding: 2rem; }
60
+ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
61
+ </style>
62
+ ${runtimeConfig.assetsUrl ? `<script src="${runtimeConfig.assetsUrl}/remoteEntry.js"${sriAttr}><\/script>` : ""}
63
+ <script>${bootstrap}<\/script>
64
+ </head>
65
+ <body>
66
+ <div id="root" class="fade">${errorMarkup}</div>
67
+ </body>
68
+ </html>
69
+ `;
70
+ }
71
+ function escapeHtml(value) {
72
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
73
+ }
74
+ function createHostServer(config) {
75
+ const port = config.port ?? 3e3;
76
+ const { runtimeConfig } = config;
77
+ let shutdownImpl = null;
78
+ const ready = (async () => {
79
+ shutdownImpl = (await runHostServer({
80
+ runtimeConfig,
81
+ port
82
+ })).shutdown;
83
+ })();
84
+ const shutdown = async () => {
85
+ console.log("[Host] Shutting down...");
86
+ const timeout = setTimeout(() => {
87
+ console.log("[Host] Force exit");
88
+ process.exit(0);
89
+ }, 5e3);
90
+ await ready.catch(() => {});
91
+ if (shutdownImpl) await shutdownImpl().catch(() => {});
92
+ clearTimeout(timeout);
93
+ console.log("[Host] Shutdown complete");
94
+ };
95
+ return {
96
+ ready,
97
+ shutdown
98
+ };
99
+ }
100
+ async function runHostServer(opts) {
101
+ const { runtimeConfig, port } = opts;
102
+ let apiPlugins = [];
103
+ let baseApiPlugin = null;
104
+ let apiPluginError = null;
105
+ let apiPluginLoading = null;
106
+ let ssrRouterModule = null;
107
+ let ssrRouterError = null;
108
+ let ssrRouterLoading = null;
109
+ let rpcHandler = null;
110
+ let openApiHandler = null;
111
+ const clientRuntimeConfig = buildClientRuntimeConfig(runtimeConfig);
112
+ const initApiHandlers = () => {
113
+ const stitchedRouter = require_api.createStitchedRouter(baseApiPlugin?.router ?? {}, apiPlugins.filter((plugin) => plugin.key !== "api"));
114
+ if (!baseApiPlugin) {
115
+ rpcHandler = null;
116
+ openApiHandler = null;
117
+ return;
118
+ }
119
+ rpcHandler = new _orpc_server_fetch.RPCHandler(stitchedRouter, { plugins: [new _orpc_server_plugins.BatchHandlerPlugin()] });
120
+ openApiHandler = new _orpc_openapi_fetch.OpenAPIHandler(stitchedRouter, { plugins: [new _orpc_openapi_plugins.OpenAPIReferencePlugin({ schemaConverters: [new _orpc_zod_zod4.ZodToJsonSchemaConverter()] })] });
121
+ };
122
+ const ensureApiPluginLoaded = async () => {
123
+ if (apiPlugins.length > 0) return {
124
+ base: baseApiPlugin,
125
+ plugins: apiPlugins,
126
+ errors: []
127
+ };
128
+ if (!runtimeConfig.api) return null;
129
+ if (apiPluginLoading) return apiPluginLoading;
130
+ apiPluginLoading = require_api.loadApiPluginsFromRuntimeConfig(runtimeConfig, process.env).then((loaded) => {
131
+ if (loaded) {
132
+ apiPlugins = loaded.plugins;
133
+ baseApiPlugin = loaded.base;
134
+ apiPluginError = loaded.errors.length > 0 ? loaded.errors.map((item) => item.error).join("; ") : null;
135
+ initApiHandlers();
136
+ }
137
+ return loaded;
138
+ }).catch((e) => {
139
+ apiPluginError = e instanceof Error ? e.message : String(e);
140
+ return null;
141
+ }).finally(() => {
142
+ apiPluginLoading = null;
143
+ });
144
+ return apiPluginLoading;
145
+ };
146
+ const ensureRouterModuleLoaded = async () => {
147
+ if (ssrRouterModule) return ssrRouterModule;
148
+ if (ssrRouterLoading) return ssrRouterLoading;
149
+ ssrRouterLoading = require_federation_server.loadRouterModule(runtimeConfig).then((routerModule) => {
150
+ ssrRouterModule = routerModule;
151
+ ssrRouterError = null;
152
+ return routerModule;
153
+ }).catch((error) => {
154
+ ssrRouterError = error instanceof Error ? error.message : String(error);
155
+ return null;
156
+ }).finally(() => {
157
+ ssrRouterLoading = null;
158
+ });
159
+ return ssrRouterLoading;
160
+ };
161
+ ensureApiPluginLoaded();
162
+ ensureRouterModuleLoaded();
163
+ const app = new hono.Hono();
164
+ const corsOrigins = process.env.CORS_ORIGIN?.split(",").map((o) => o.trim()) ?? [runtimeConfig.hostUrl, ...runtimeConfig.ui?.url ? [runtimeConfig.ui.url] : []];
165
+ if (!process.env.CORS_ORIGIN && runtimeConfig.env === "production") console.warn("[Security] CORS_ORIGIN is not set in production. Using host and UI URLs as allowed origins.");
166
+ app.use("/*", (0, hono_cors.cors)({
167
+ origin: corsOrigins,
168
+ credentials: true
169
+ }));
170
+ app.use("*", (0, hono_secure_headers.secureHeaders)());
171
+ app.get("/health", (c) => c.text("OK"));
172
+ app.get("/ready", async (c) => {
173
+ const probe = async (url, timeoutMs = 400) => {
174
+ const started = Date.now();
175
+ const controller = new AbortController();
176
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
177
+ try {
178
+ const res = await fetch(url, { signal: controller.signal });
179
+ return {
180
+ name: "",
181
+ url,
182
+ required: true,
183
+ ok: res.ok,
184
+ status: res.status,
185
+ latencyMs: Date.now() - started
186
+ };
187
+ } catch (e) {
188
+ return {
189
+ name: "",
190
+ url,
191
+ required: true,
192
+ ok: false,
193
+ latencyMs: Date.now() - started,
194
+ error: e instanceof Error ? e.message : String(e)
195
+ };
196
+ } finally {
197
+ clearTimeout(timer);
198
+ }
199
+ };
200
+ const checks = [];
201
+ if (runtimeConfig.ui?.url) {
202
+ const base = runtimeConfig.ui.url.replace(/\/$/, "");
203
+ const manifest = await probe(`${base}/mf-manifest.json`);
204
+ manifest.name = "ui";
205
+ manifest.required = false;
206
+ checks.push(manifest);
207
+ if (!manifest.ok) {
208
+ const remoteEntry = await probe(`${base}/remoteEntry.js`);
209
+ remoteEntry.name = "ui";
210
+ remoteEntry.required = true;
211
+ checks.push(remoteEntry);
212
+ } else manifest.required = true;
213
+ }
214
+ if (runtimeConfig.ui?.ssrUrl) {
215
+ const ssr = await probe(`${runtimeConfig.ui.ssrUrl.replace(/\/$/, "")}/`);
216
+ ssr.name = "ui-ssr";
217
+ ssr.required = false;
218
+ checks.push(ssr);
219
+ }
220
+ if (runtimeConfig.api?.url) {
221
+ const api = await probe(`${runtimeConfig.api.url.replace(/\/$/, "")}/`);
222
+ api.name = "api";
223
+ api.required = true;
224
+ checks.push(api);
225
+ }
226
+ if (runtimeConfig.api) {
227
+ checks.push({
228
+ name: "api-plugin",
229
+ url: runtimeConfig.api.entry,
230
+ required: true,
231
+ ok: baseApiPlugin !== null,
232
+ status: baseApiPlugin !== null ? 200 : 503,
233
+ error: baseApiPlugin !== null ? void 0 : apiPluginLoading ? "loading" : apiPluginError ?? "not loaded"
234
+ });
235
+ if (!baseApiPlugin && !apiPluginLoading) ensureApiPluginLoaded();
236
+ }
237
+ for (const [key, plugin] of Object.entries(runtimeConfig.plugins ?? {})) {
238
+ const loaded = apiPlugins.find((item) => item.key === key);
239
+ checks.push({
240
+ name: key,
241
+ url: plugin.entry,
242
+ required: true,
243
+ ok: Boolean(loaded),
244
+ status: loaded ? 200 : 503,
245
+ error: loaded ? void 0 : apiPluginError ?? "not loaded"
246
+ });
247
+ }
248
+ const allRequiredOk = checks.filter((x) => x.required).every((x) => x.ok);
249
+ return c.json({
250
+ status: allRequiredOk ? "ready" : "not_ready",
251
+ host: {
252
+ url: runtimeConfig.hostUrl,
253
+ env: runtimeConfig.env
254
+ },
255
+ checks,
256
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
257
+ }, allRequiredOk ? 200 : 503);
258
+ });
259
+ app.get("/api/_health", (c) => c.json({
260
+ status: "ready",
261
+ mode: runtimeConfig.env,
262
+ ui: runtimeConfig.ui?.url ?? null,
263
+ uiSsr: runtimeConfig.ui?.ssrUrl ?? null,
264
+ ssrRouterLoaded: ssrRouterModule !== null,
265
+ ssrRouterLoading: ssrRouterLoading !== null,
266
+ ssrRouterError,
267
+ api: runtimeConfig.api?.url ?? null,
268
+ apiPluginLoaded: baseApiPlugin !== null,
269
+ apiPluginLoading: apiPluginLoading !== null,
270
+ apiPluginError
271
+ }));
272
+ app.all("/api/rpc/*", async (c) => {
273
+ if (!rpcHandler) await ensureApiPluginLoaded();
274
+ if (!rpcHandler) return c.json({
275
+ error: "API plugin not loaded",
276
+ detail: apiPluginError
277
+ }, 503);
278
+ const result = await rpcHandler.handle(c.req.raw, {
279
+ prefix: "/api/rpc",
280
+ context: {}
281
+ });
282
+ return result.response ? c.newResponse(result.response.body, result.response) : c.text("Not Found", 404);
283
+ });
284
+ app.all("/api/*", async (c) => {
285
+ if (!openApiHandler) await ensureApiPluginLoaded();
286
+ if (!openApiHandler) return c.json({
287
+ error: "API plugin not loaded",
288
+ detail: apiPluginError
289
+ }, 503);
290
+ const result = await openApiHandler.handle(c.req.raw, {
291
+ prefix: "/api",
292
+ context: {}
293
+ });
294
+ return result.response ? c.newResponse(result.response.body, result.response) : c.text("Not Found", 404);
295
+ });
296
+ if (runtimeConfig.ui) {
297
+ app.all("/__mf/ui/*", async (c) => {
298
+ const targetUrl = `${runtimeConfig.ui.url}${c.req.path.replace("/__mf/ui", "")}`;
299
+ return await fetch(targetUrl, {
300
+ method: c.req.method,
301
+ headers: c.req.header()
302
+ });
303
+ });
304
+ if (runtimeConfig.ui.ssrUrl) app.all("/__mf/ui/ssr/*", async (c) => {
305
+ const targetUrl = `${runtimeConfig.ui.ssrUrl}${c.req.path.replace("/__mf/ui/ssr", "")}`;
306
+ return await fetch(targetUrl, {
307
+ method: c.req.method,
308
+ headers: c.req.header()
309
+ });
310
+ });
311
+ }
312
+ app.get("*", async (c) => {
313
+ const routerModule = await ensureRouterModuleLoaded();
314
+ if (!routerModule) return c.html(renderLoadingShell(clientRuntimeConfig, ssrRouterError), 503);
315
+ try {
316
+ const apiClient = baseApiPlugin?.createClient();
317
+ const result = await routerModule.renderToStream(c.req.raw, {
318
+ assetsUrl: runtimeConfig.ui.url,
319
+ runtimeConfig: clientRuntimeConfig,
320
+ apiClient
321
+ });
322
+ return new Response(result.stream, {
323
+ status: result.statusCode,
324
+ headers: result.headers
325
+ });
326
+ } catch (error) {
327
+ const message = error instanceof Error ? error.message : String(error);
328
+ return c.html(renderLoadingShell(clientRuntimeConfig, message), 500);
329
+ }
330
+ });
331
+ const hostname = process.env.HOST ?? "0.0.0.0";
332
+ let resolveReady = null;
333
+ const ready = new Promise((resolve) => {
334
+ resolveReady = resolve;
335
+ });
336
+ const proxiedFetch = (req) => {
337
+ const url = new URL(req.url);
338
+ const forwardedProto = req.headers.get("x-forwarded-proto");
339
+ const forwardedHost = req.headers.get("x-forwarded-host");
340
+ if (forwardedProto) url.protocol = forwardedProto;
341
+ if (forwardedHost) url.host = forwardedHost;
342
+ if (forwardedProto || forwardedHost) req = new Request(url, req);
343
+ return app.fetch(req);
344
+ };
345
+ const server = (0, _hono_node_server.serve)({
346
+ fetch: proxiedFetch,
347
+ port,
348
+ hostname
349
+ }, (info) => {
350
+ console.log(`[Host] Server running at http://${hostname}:${info.port}`);
351
+ console.log(`[Host] API: http://${hostname}:${info.port}/api/rpc`);
352
+ resolveReady?.();
353
+ });
354
+ await ready;
355
+ return { shutdown: () => new Promise((resolve) => {
356
+ try {
357
+ server.close(() => resolve());
358
+ } catch {
359
+ resolve();
360
+ }
361
+ }) };
362
+ }
363
+
364
+ //#endregion
365
+ exports.createHostServer = createHostServer;
366
+ exports.runHostServer = runHostServer;
367
+ //# sourceMappingURL=host.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.cjs","names":["createStitchedRouter","RPCHandler","BatchHandlerPlugin","OpenAPIHandler","OpenAPIReferencePlugin","ZodToJsonSchemaConverter","loadApiPluginsFromRuntimeConfig","loadRouterModule","Hono"],"sources":["../src/host.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { BatchHandlerPlugin } from \"@orpc/server/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { secureHeaders } from \"hono/secure-headers\";\nimport {\n createStitchedRouter,\n type LoadedPluginResult,\n type LoadedPluginsResult,\n loadApiPluginsFromRuntimeConfig,\n} from \"./api\";\nimport { loadRouterModule, type RouterModule } from \"./federation.server\";\nimport type { ClientRuntimeConfig, RuntimeConfig } from \"./types\";\n\nexport interface HostServerConfig {\n runtimeConfig: RuntimeConfig;\n configDir: string;\n port?: number;\n}\n\nexport interface HostServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\nfunction buildClientRuntimeConfig(runtimeConfig: RuntimeConfig): ClientRuntimeConfig {\n return {\n env: runtimeConfig.env,\n account: runtimeConfig.account,\n networkId: runtimeConfig.networkId,\n hostUrl: runtimeConfig.hostUrl,\n assetsUrl: runtimeConfig.ui.url,\n apiBase: \"/api\",\n rpcBase: \"/api/rpc\",\n ui: runtimeConfig.ui\n ? {\n name: runtimeConfig.ui.name,\n url: runtimeConfig.ui.url,\n entry: runtimeConfig.ui.entry,\n integrity: runtimeConfig.ui.integrity,\n }\n : undefined,\n api: runtimeConfig.api\n ? {\n name: runtimeConfig.api.name,\n url: runtimeConfig.api.url,\n entry: runtimeConfig.api.entry,\n integrity: runtimeConfig.api.integrity,\n }\n : undefined,\n plugins: runtimeConfig.plugins\n ? Object.fromEntries(\n Object.entries(runtimeConfig.plugins).map(([key, plugin]) => [\n key,\n {\n name: plugin.name,\n url: plugin.url,\n entry: plugin.entry,\n integrity: plugin.integrity,\n },\n ]),\n )\n : undefined,\n };\n}\n\nfunction renderLoadingShell(runtimeConfig: ClientRuntimeConfig, error?: string | null) {\n const bootstrap = `window.__RUNTIME_CONFIG__ = ${JSON.stringify(runtimeConfig)};window.addEventListener('load', function handleEverythingDevHydrate() { window.__hydrate?.(); }, { once: true });`;\n const errorMarkup = error\n ? `<p style=\"color: #fca5a5;\">Error loading UI: ${escapeHtml(error)}</p>`\n : \"<p>Loading UI...</p>\";\n\n const uiIntegrity = runtimeConfig.ui?.integrity;\n const sriAttr = uiIntegrity ? ` integrity=\"${uiIntegrity}\" crossorigin=\"anonymous\"` : \"\";\n\n return `\n\t\t<!DOCTYPE html>\n\t\t<html lang=\"en\">\n\t\t\t<head>\n\t\t\t\t<meta charset=\"utf-8\" />\n\t\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t\t\t<title>Loading...</title>\n\t\t\t\t<style>\n\t\t\t\t\tbody { background: #171717; color: #fafafa; display: flex; align-items: center; justify-content: center; height: 100vh; font-family: system-ui; }\n\t\t\t\t\t.fade { animation: fadeIn 0.3s ease-in; text-align: center; padding: 2rem; }\n\t\t\t\t\t@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n\t\t\t\t</style>\n\t\t\t\t${runtimeConfig.assetsUrl ? `<script src=\"${runtimeConfig.assetsUrl}/remoteEntry.js\"${sriAttr}></script>` : \"\"}\n\t\t\t\t<script>${bootstrap}</script>\n\t\t\t</head>\n\t\t\t<body>\n\t\t\t\t<div id=\"root\" class=\"fade\">${errorMarkup}</div>\n\t\t\t</body>\n\t\t</html>\n\t`;\n}\n\nfunction escapeHtml(value: string) {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n\nexport function createHostServer(config: HostServerConfig): HostServerHandle {\n const port = config.port ?? 3000;\n const { runtimeConfig } = config;\n\n let shutdownImpl: (() => Promise<void>) | null = null;\n\n const ready = (async () => {\n const started = await runHostServer({ runtimeConfig, port });\n shutdownImpl = started.shutdown;\n })();\n\n const shutdown = async () => {\n console.log(\"[Host] Shutting down...\");\n const timeout = setTimeout(() => {\n console.log(\"[Host] Force exit\");\n process.exit(0);\n }, 5000);\n await ready.catch(() => {});\n if (shutdownImpl) {\n await shutdownImpl().catch(() => {});\n }\n clearTimeout(timeout);\n console.log(\"[Host] Shutdown complete\");\n };\n\n return { ready, shutdown };\n}\n\nasync function runHostServer(opts: {\n runtimeConfig: RuntimeConfig;\n port: number;\n}): Promise<{ shutdown: () => Promise<void> }> {\n const { runtimeConfig, port } = opts;\n\n let apiPlugins: LoadedPluginResult[] = [];\n let baseApiPlugin: LoadedPluginResult | null = null;\n let apiPluginError: string | null = null;\n let apiPluginLoading: Promise<LoadedPluginsResult | null> | null = null;\n let ssrRouterModule: RouterModule | null = null;\n let ssrRouterError: string | null = null;\n let ssrRouterLoading: Promise<RouterModule | null> | null = null;\n let rpcHandler: RPCHandler<any> | null = null;\n let openApiHandler: OpenAPIHandler<any> | null = null;\n\n const clientRuntimeConfig = buildClientRuntimeConfig(runtimeConfig);\n\n const initApiHandlers = () => {\n const baseRouter = baseApiPlugin?.router ?? {};\n const stitchedRouter = createStitchedRouter(\n baseRouter,\n apiPlugins.filter((plugin) => plugin.key !== \"api\"),\n );\n\n if (!baseApiPlugin) {\n rpcHandler = null;\n openApiHandler = null;\n return;\n }\n\n rpcHandler = new RPCHandler(stitchedRouter as any, {\n plugins: [new BatchHandlerPlugin()],\n });\n openApiHandler = new OpenAPIHandler(stitchedRouter as any, {\n plugins: [\n new OpenAPIReferencePlugin({\n schemaConverters: [new ZodToJsonSchemaConverter()],\n }),\n ],\n });\n };\n\n const ensureApiPluginLoaded = async (): Promise<LoadedPluginsResult | null> => {\n if (apiPlugins.length > 0) return { base: baseApiPlugin, plugins: apiPlugins, errors: [] };\n if (!runtimeConfig.api) return null;\n if (apiPluginLoading) return apiPluginLoading;\n\n apiPluginLoading = loadApiPluginsFromRuntimeConfig(runtimeConfig, process.env as any)\n .then((loaded) => {\n if (loaded) {\n apiPlugins = loaded.plugins;\n baseApiPlugin = loaded.base;\n apiPluginError =\n loaded.errors.length > 0 ? loaded.errors.map((item) => item.error).join(\"; \") : null;\n initApiHandlers();\n }\n return loaded;\n })\n .catch((e) => {\n apiPluginError = e instanceof Error ? e.message : String(e);\n return null;\n })\n .finally(() => {\n apiPluginLoading = null;\n });\n\n return apiPluginLoading;\n };\n\n const ensureRouterModuleLoaded = async (): Promise<RouterModule | null> => {\n if (ssrRouterModule) {\n return ssrRouterModule;\n }\n\n if (ssrRouterLoading) {\n return ssrRouterLoading;\n }\n\n ssrRouterLoading = loadRouterModule(runtimeConfig)\n .then((routerModule) => {\n ssrRouterModule = routerModule;\n ssrRouterError = null;\n return routerModule;\n })\n .catch((error) => {\n ssrRouterError = error instanceof Error ? error.message : String(error);\n return null;\n })\n .finally(() => {\n ssrRouterLoading = null;\n });\n\n return ssrRouterLoading;\n };\n\n // Kick off API plugin load in the background; host should still start even if\n // the remote isn't ready yet.\n void ensureApiPluginLoaded();\n void ensureRouterModuleLoaded();\n\n const app = new Hono();\n\n const corsOrigins = process.env.CORS_ORIGIN?.split(\",\").map((o) => o.trim()) ?? [\n runtimeConfig.hostUrl,\n ...(runtimeConfig.ui?.url ? [runtimeConfig.ui.url] : []),\n ];\n\n if (!process.env.CORS_ORIGIN && runtimeConfig.env === \"production\") {\n console.warn(\n \"[Security] CORS_ORIGIN is not set in production. Using host and UI URLs as allowed origins.\",\n );\n }\n\n app.use(\n \"/*\",\n cors({\n origin: corsOrigins,\n credentials: true,\n }),\n );\n\n app.use(\"*\", secureHeaders());\n\n app.get(\"/health\", (c) => c.text(\"OK\"));\n app.get(\"/ready\", async (c) => {\n type Check = {\n name: string;\n url: string;\n required: boolean;\n ok: boolean;\n status?: number;\n latencyMs?: number;\n error?: string;\n };\n\n const probe = async (url: string, timeoutMs = 400): Promise<Check> => {\n const started = Date.now();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return {\n name: \"\",\n url,\n required: true,\n ok: res.ok,\n status: res.status,\n latencyMs: Date.now() - started,\n };\n } catch (e) {\n return {\n name: \"\",\n url,\n required: true,\n ok: false,\n latencyMs: Date.now() - started,\n error: e instanceof Error ? e.message : String(e),\n };\n } finally {\n clearTimeout(timer);\n }\n };\n\n const checks: Check[] = [];\n\n if (runtimeConfig.ui?.url) {\n const base = runtimeConfig.ui.url.replace(/\\/$/, \"\");\n const manifest = await probe(`${base}/mf-manifest.json`);\n manifest.name = \"ui\";\n // mf-manifest.json is preferred but not always present; fall back to\n // remoteEntry.js for readiness.\n manifest.required = false;\n checks.push(manifest);\n if (!manifest.ok) {\n const remoteEntry = await probe(`${base}/remoteEntry.js`);\n remoteEntry.name = \"ui\";\n remoteEntry.required = true;\n checks.push(remoteEntry);\n } else {\n manifest.required = true;\n }\n }\n\n if (runtimeConfig.ui?.ssrUrl) {\n const base = runtimeConfig.ui.ssrUrl.replace(/\\/$/, \"\");\n const ssr = await probe(`${base}/`);\n ssr.name = \"ui-ssr\";\n ssr.required = false;\n checks.push(ssr);\n }\n\n if (runtimeConfig.api?.url) {\n const base = runtimeConfig.api.url.replace(/\\/$/, \"\");\n const api = await probe(`${base}/`);\n api.name = \"api\";\n api.required = true;\n checks.push(api);\n }\n\n if (runtimeConfig.api) {\n checks.push({\n name: \"api-plugin\",\n url: runtimeConfig.api.entry,\n required: true,\n ok: baseApiPlugin !== null,\n status: baseApiPlugin !== null ? 200 : 503,\n error:\n baseApiPlugin !== null\n ? undefined\n : apiPluginLoading\n ? \"loading\"\n : (apiPluginError ?? \"not loaded\"),\n });\n if (!baseApiPlugin && !apiPluginLoading) {\n void ensureApiPluginLoaded();\n }\n }\n\n for (const [key, plugin] of Object.entries(runtimeConfig.plugins ?? {})) {\n const loaded = apiPlugins.find((item) => item.key === key);\n checks.push({\n name: key,\n url: plugin.entry,\n required: true,\n ok: Boolean(loaded),\n status: loaded ? 200 : 503,\n error: loaded ? undefined : (apiPluginError ?? \"not loaded\"),\n });\n }\n\n const allRequiredOk = checks.filter((x) => x.required).every((x) => x.ok);\n\n return c.json(\n {\n status: allRequiredOk ? \"ready\" : \"not_ready\",\n host: {\n url: runtimeConfig.hostUrl,\n env: runtimeConfig.env,\n },\n checks,\n timestamp: new Date().toISOString(),\n },\n allRequiredOk ? 200 : 503,\n );\n });\n app.get(\"/api/_health\", (c) =>\n c.json({\n status: \"ready\",\n mode: runtimeConfig.env,\n ui: runtimeConfig.ui?.url ?? null,\n uiSsr: runtimeConfig.ui?.ssrUrl ?? null,\n ssrRouterLoaded: ssrRouterModule !== null,\n ssrRouterLoading: ssrRouterLoading !== null,\n ssrRouterError,\n api: runtimeConfig.api?.url ?? null,\n apiPluginLoaded: baseApiPlugin !== null,\n apiPluginLoading: apiPluginLoading !== null,\n apiPluginError,\n }),\n );\n\n app.all(\"/api/rpc/*\", async (c) => {\n if (!rpcHandler) {\n await ensureApiPluginLoaded();\n }\n if (!rpcHandler) {\n return c.json({ error: \"API plugin not loaded\", detail: apiPluginError }, 503);\n }\n const result = await rpcHandler.handle(c.req.raw, {\n prefix: \"/api/rpc\",\n context: {},\n });\n return result.response\n ? c.newResponse(result.response.body, result.response)\n : c.text(\"Not Found\", 404);\n });\n\n app.all(\"/api/*\", async (c) => {\n if (!openApiHandler) {\n await ensureApiPluginLoaded();\n }\n if (!openApiHandler) {\n return c.json({ error: \"API plugin not loaded\", detail: apiPluginError }, 503);\n }\n const result = await openApiHandler.handle(c.req.raw, {\n prefix: \"/api\",\n context: {},\n });\n return result.response\n ? c.newResponse(result.response.body, result.response)\n : c.text(\"Not Found\", 404);\n });\n\n if (runtimeConfig.ui) {\n app.all(\"/__mf/ui/*\", async (c) => {\n const targetUrl = `${runtimeConfig.ui!.url}${c.req.path.replace(\"/__mf/ui\", \"\")}`;\n const response = await fetch(targetUrl, {\n method: c.req.method,\n headers: c.req.header(),\n });\n return response;\n });\n\n if (runtimeConfig.ui.ssrUrl) {\n app.all(\"/__mf/ui/ssr/*\", async (c) => {\n const targetUrl = `${runtimeConfig.ui!.ssrUrl}${c.req.path.replace(\"/__mf/ui/ssr\", \"\")}`;\n const response = await fetch(targetUrl, {\n method: c.req.method,\n headers: c.req.header(),\n });\n return response;\n });\n }\n }\n\n app.get(\"*\", async (c) => {\n const routerModule = await ensureRouterModuleLoaded();\n\n if (!routerModule) {\n return c.html(renderLoadingShell(clientRuntimeConfig, ssrRouterError), 503);\n }\n\n try {\n const apiClient = baseApiPlugin?.createClient();\n\n const result = await routerModule.renderToStream(c.req.raw, {\n assetsUrl: runtimeConfig.ui.url,\n runtimeConfig: clientRuntimeConfig,\n apiClient,\n });\n\n return new Response(result.stream, {\n status: result.statusCode,\n headers: result.headers,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.html(renderLoadingShell(clientRuntimeConfig, message), 500);\n }\n });\n\n const hostname = process.env.HOST ?? \"0.0.0.0\";\n let resolveReady: (() => void) | null = null;\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n const proxiedFetch = (req: Request): Response | Promise<Response> => {\n const url = new URL(req.url);\n const forwardedProto = req.headers.get(\"x-forwarded-proto\");\n const forwardedHost = req.headers.get(\"x-forwarded-host\");\n\n if (forwardedProto) {\n url.protocol = forwardedProto;\n }\n if (forwardedHost) {\n url.host = forwardedHost;\n }\n\n if (forwardedProto || forwardedHost) {\n req = new Request(url, req);\n }\n\n return app.fetch(req);\n };\n\n const server = serve({ fetch: proxiedFetch, port, hostname }, (info) => {\n console.log(`[Host] Server running at http://${hostname}:${info.port}`);\n console.log(`[Host] API: http://${hostname}:${info.port}/api/rpc`);\n resolveReady?.();\n });\n\n await ready;\n\n return {\n shutdown: () =>\n new Promise<void>((resolve) => {\n try {\n server.close(() => resolve());\n } catch {\n resolve();\n }\n }),\n };\n}\n\nexport { runHostServer };\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { RuntimeConfig } from "./types.cjs";
2
+
3
+ //#region src/host.d.ts
4
+ interface HostServerConfig {
5
+ runtimeConfig: RuntimeConfig;
6
+ configDir: string;
7
+ port?: number;
8
+ }
9
+ interface HostServerHandle {
10
+ ready: Promise<void>;
11
+ shutdown: () => Promise<void>;
12
+ }
13
+ declare function createHostServer(config: HostServerConfig): HostServerHandle;
14
+ declare function runHostServer(opts: {
15
+ runtimeConfig: RuntimeConfig;
16
+ port: number;
17
+ }): Promise<{
18
+ shutdown: () => Promise<void>;
19
+ }>;
20
+ //#endregion
21
+ export { HostServerConfig, HostServerHandle, createHostServer, runHostServer };
22
+ //# sourceMappingURL=host.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.cts","names":[],"sources":["../src/host.ts"],"mappings":";;;UAkBiB,gBAAA;EACf,aAAA,EAAe,aAAA;EACf,SAAA;EACA,IAAA;AAAA;AAAA,UAGe,gBAAA;EACf,KAAA,EAAO,OAAA;EACP,QAAA,QAAgB,OAAA;AAAA;AAAA,iBAoFF,gBAAA,CAAiB,MAAA,EAAQ,gBAAA,GAAmB,gBAAA;AAAA,iBA4B7C,aAAA,CAAc,IAAA;EAC3B,aAAA,EAAe,aAAA;EACf,IAAA;AAAA,IACE,OAAA;EAAU,QAAA,QAAgB,OAAA;AAAA"}
@@ -0,0 +1,22 @@
1
+ import { RuntimeConfig } from "./types.mjs";
2
+
3
+ //#region src/host.d.ts
4
+ interface HostServerConfig {
5
+ runtimeConfig: RuntimeConfig;
6
+ configDir: string;
7
+ port?: number;
8
+ }
9
+ interface HostServerHandle {
10
+ ready: Promise<void>;
11
+ shutdown: () => Promise<void>;
12
+ }
13
+ declare function createHostServer(config: HostServerConfig): HostServerHandle;
14
+ declare function runHostServer(opts: {
15
+ runtimeConfig: RuntimeConfig;
16
+ port: number;
17
+ }): Promise<{
18
+ shutdown: () => Promise<void>;
19
+ }>;
20
+ //#endregion
21
+ export { HostServerConfig, HostServerHandle, createHostServer, runHostServer };
22
+ //# sourceMappingURL=host.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.mts","names":[],"sources":["../src/host.ts"],"mappings":";;;UAkBiB,gBAAA;EACf,aAAA,EAAe,aAAA;EACf,SAAA;EACA,IAAA;AAAA;AAAA,UAGe,gBAAA;EACf,KAAA,EAAO,OAAA;EACP,QAAA,QAAgB,OAAA;AAAA;AAAA,iBAoFF,gBAAA,CAAiB,MAAA,EAAQ,gBAAA,GAAmB,gBAAA;AAAA,iBA4B7C,aAAA,CAAc,IAAA;EAC3B,aAAA,EAAe,aAAA;EACf,IAAA;AAAA,IACE,OAAA;EAAU,QAAA,QAAgB,OAAA;AAAA"}