everything-dev 1.51.5 → 1.51.6
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/_virtual/_rolldown/runtime.mjs +1 -1
- package/dist/api-contract.cjs +0 -1
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs.map +1 -1
- package/dist/app.cjs +1 -1
- package/dist/app.cjs.map +1 -1
- package/dist/app.mjs +1 -1
- package/dist/app.mjs.map +1 -1
- package/dist/build.cjs +16 -22
- package/dist/build.cjs.map +1 -1
- package/dist/build.mjs +16 -22
- package/dist/build.mjs.map +1 -1
- package/dist/cli/catalog.cjs.map +1 -1
- package/dist/cli/catalog.mjs.map +1 -1
- package/dist/cli/db-doctor.cjs +0 -1
- package/dist/cli/db-doctor.cjs.map +1 -1
- package/dist/cli/db-doctor.mjs.map +1 -1
- package/dist/cli/db-repair.cjs +0 -1
- package/dist/cli/db-repair.cjs.map +1 -1
- package/dist/cli/db-repair.mjs.map +1 -1
- package/dist/cli/db-studio.cjs.map +1 -1
- package/dist/cli/db-studio.mjs.map +1 -1
- package/dist/cli/framework-version.cjs +2 -1
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs +1 -1
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/help.cjs.map +1 -1
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/infra.cjs +4 -0
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs +1 -1
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +3 -4
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +0 -1
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +0 -1
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +3 -3
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/parse.cjs.map +1 -1
- package/dist/cli/parse.mjs.map +1 -1
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/snapshot.cjs +0 -1
- package/dist/cli/snapshot.cjs.map +1 -1
- package/dist/cli/snapshot.mjs.map +1 -1
- package/dist/cli/status.cjs +0 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +2 -2
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +2 -2
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/timing.cjs.map +1 -1
- package/dist/cli/timing.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +3 -0
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +1 -1
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/code-artifacts.cjs +0 -1
- package/dist/code-artifacts.cjs.map +1 -1
- package/dist/code-artifacts.mjs.map +1 -1
- package/dist/components/dev-view.cjs +0 -1
- package/dist/components/dev-view.cjs.map +1 -1
- package/dist/components/dev-view.mjs.map +1 -1
- package/dist/components/streaming-view.cjs.map +1 -1
- package/dist/components/streaming-view.mjs.map +1 -1
- package/dist/config.cjs +0 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +0 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +0 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +58 -60
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +58 -60
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts.map +1 -1
- package/dist/contract.meta.d.mts.map +1 -1
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs.map +1 -1
- package/dist/db.cjs +0 -1
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts.map +1 -1
- package/dist/db.d.mts.map +1 -1
- package/dist/db.mjs.map +1 -1
- package/dist/dev-logs.cjs +2 -1
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs +1 -1
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/dev-session.cjs +3 -1
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +3 -2
- package/dist/dev-session.mjs.map +1 -1
- package/dist/fastkv.cjs +2 -7
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts.map +1 -1
- package/dist/fastkv.d.mts.map +1 -1
- package/dist/fastkv.mjs +2 -7
- package/dist/fastkv.mjs.map +1 -1
- package/dist/http-client.cjs +4 -1
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.mjs +1 -1
- package/dist/http-client.mjs.map +1 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/infra/planner.cjs +5 -1
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +1 -1
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/infra/preflight.cjs +0 -1
- package/dist/infra/preflight.cjs.map +1 -1
- package/dist/infra/preflight.mjs.map +1 -1
- package/dist/infra/types.cjs +0 -1
- package/dist/infra/types.cjs.map +1 -1
- package/dist/infra/types.mjs.map +1 -1
- package/dist/integrity.cjs +0 -1
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.d.cts.map +1 -1
- package/dist/integrity.d.mts.map +1 -1
- package/dist/integrity.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs +2 -2
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs +2 -2
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/merge.cjs +1 -2
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.d.cts.map +1 -1
- package/dist/merge.d.mts.map +1 -1
- package/dist/merge.mjs +1 -1
- package/dist/merge.mjs.map +1 -1
- package/dist/mf.cjs +0 -1
- package/dist/mf.cjs.map +1 -1
- package/dist/mf.d.cts +0 -1
- package/dist/mf.d.cts.map +1 -1
- package/dist/mf.d.mts +0 -1
- package/dist/mf.d.mts.map +1 -1
- package/dist/mf.mjs.map +1 -1
- package/dist/near-cli.cjs +3 -1
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +1 -1
- package/dist/near-cli.mjs.map +1 -1
- package/dist/network.cjs.map +1 -1
- package/dist/network.mjs.map +1 -1
- package/dist/orchestrator.cjs +5 -4
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +5 -3
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +50 -53
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +50 -53
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-registry.cjs +4 -1
- package/dist/process-registry.cjs.map +1 -1
- package/dist/process-registry.mjs +1 -1
- package/dist/process-registry.mjs.map +1 -1
- package/dist/publish.cjs +1 -0
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +1 -1
- package/dist/publish.mjs.map +1 -1
- package/dist/sdk.cjs +0 -1
- package/dist/service-descriptor.cjs +0 -1
- package/dist/service-descriptor.cjs.map +1 -1
- package/dist/service-descriptor.d.cts +1 -0
- package/dist/service-descriptor.d.cts.map +1 -1
- package/dist/service-descriptor.d.mts +0 -1
- package/dist/service-descriptor.d.mts.map +1 -1
- package/dist/service-descriptor.mjs.map +1 -1
- package/dist/shared-deps.cjs +0 -1
- package/dist/shared-deps.cjs.map +1 -1
- package/dist/shared-deps.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -3
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ui/head.cjs.map +1 -1
- package/dist/ui/head.d.cts +0 -1
- package/dist/ui/head.d.cts.map +1 -1
- package/dist/ui/head.d.mts +0 -1
- package/dist/ui/head.d.mts.map +1 -1
- package/dist/ui/head.mjs.map +1 -1
- package/dist/ui/index.d.cts +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/metadata.cjs +1 -1
- package/dist/ui/metadata.cjs.map +1 -1
- package/dist/ui/metadata.d.cts.map +1 -1
- package/dist/ui/metadata.d.mts.map +1 -1
- package/dist/ui/metadata.mjs +1 -1
- package/dist/ui/metadata.mjs.map +1 -1
- package/dist/ui/router.cjs.map +1 -1
- package/dist/ui/router.d.cts +0 -1
- package/dist/ui/router.d.cts.map +1 -1
- package/dist/ui/router.d.mts +0 -1
- package/dist/ui/router.d.mts.map +1 -1
- package/dist/ui/router.mjs.map +1 -1
- package/dist/ui/runtime.cjs.map +1 -1
- package/dist/ui/runtime.d.cts +0 -1
- package/dist/ui/runtime.d.cts.map +1 -1
- package/dist/ui/runtime.d.mts +0 -1
- package/dist/ui/runtime.d.mts.map +1 -1
- package/dist/ui/runtime.mjs.map +1 -1
- package/dist/ui/types.d.cts +0 -1
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.mts +0 -1
- package/dist/ui/types.d.mts.map +1 -1
- package/dist/utils/banner.cjs +0 -1
- package/dist/utils/banner.cjs.map +1 -1
- package/dist/utils/banner.mjs.map +1 -1
- package/dist/utils/linkify.cjs.map +1 -1
- package/dist/utils/linkify.mjs.map +1 -1
- package/dist/utils/run.cjs +0 -1
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs.map +1 -1
- package/dist/utils/save-config.cjs +0 -1
- package/dist/utils/save-config.cjs.map +1 -1
- package/dist/utils/save-config.mjs.map +1 -1
- package/dist/utils/string.cjs.map +1 -1
- package/dist/utils/string.mjs.map +1 -1
- package/dist/utils/theme.cjs.map +1 -1
- package/dist/utils/theme.mjs.map +1 -1
- package/package.json +2 -2
package/dist/mf.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
2
|
const require_integrity = require('./integrity.cjs');
|
|
4
3
|
let _module_federation_enhanced_runtime = require("@module-federation/enhanced/runtime");
|
|
5
4
|
let _module_federation_runtime_core = require("@module-federation/runtime-core");
|
package/dist/mf.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mf.cjs","names":["computeSriHash"],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"mf.cjs","names":["computeSriHash"],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
|
package/dist/mf.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { IntegrityRegistry } from "./integrity.cjs";
|
|
2
2
|
import { createInstance } from "@module-federation/enhanced/runtime";
|
|
3
|
-
|
|
4
3
|
//#region src/mf.d.ts
|
|
5
4
|
type FederationInstance = ReturnType<typeof createInstance>;
|
|
6
5
|
declare function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void;
|
package/dist/mf.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mf.d.cts","names":[],"sources":["../src/mf.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"mf.d.cts","names":[],"sources":["../src/mf.ts"],"mappings":";;;KAIK,qBAAqB,kBAAkB;iBAU5B,mCAAmC,IAAI;iBAyBvC,0BACd,IAAI,oBACJ,UAAU;iBAuCI,yBAAyB;iBAoBnB,eAAe;EACnC;EACA;EACA;IACE;iBAqBkB,iBAAiB,GACrC,mBACA;EAAY;EAAuB;IAClC,QAAQ;iBAeW,2BAA2B"}
|
package/dist/mf.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { IntegrityRegistry } from "./integrity.mjs";
|
|
2
2
|
import { createInstance } from "@module-federation/enhanced/runtime";
|
|
3
|
-
|
|
4
3
|
//#region src/mf.d.ts
|
|
5
4
|
type FederationInstance = ReturnType<typeof createInstance>;
|
|
6
5
|
declare function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void;
|
package/dist/mf.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mf.d.mts","names":[],"sources":["../src/mf.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"mf.d.mts","names":[],"sources":["../src/mf.ts"],"mappings":";;;KAIK,qBAAqB,kBAAkB;iBAU5B,mCAAmC,IAAI;iBAyBvC,0BACd,IAAI,oBACJ,UAAU;iBAuCI,yBAAyB;iBAoBnB,eAAe;EACnC;EACA;EACA;IACE;iBAqBkB,iBAAiB,GACrC,mBACA;EAAY;EAAuB;IAClC,QAAQ;iBAeW,2BAA2B"}
|
package/dist/mf.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mf.mjs","names":[],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":";;;;;AAMA,IAAI,aAAwC;AAE5C,SAAS,iBAAiB,KAAa,MAAmB,WAAsC;CAC9F,MAAM,aAAa,IAAI,
|
|
1
|
+
{"version":3,"file":"mf.mjs","names":[],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
|
package/dist/near-cli.cjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
1
|
const require_theme = require('./utils/theme.cjs');
|
|
3
2
|
let effect = require("effect");
|
|
4
3
|
let node_crypto = require("node:crypto");
|
|
@@ -221,10 +220,13 @@ async function addFunctionCallAccessKey(config) {
|
|
|
221
220
|
}
|
|
222
221
|
|
|
223
222
|
//#endregion
|
|
223
|
+
exports.NearCliNotFoundError = NearCliNotFoundError;
|
|
224
|
+
exports.NearTransactionError = NearTransactionError;
|
|
224
225
|
exports.addFunctionCallAccessKey = addFunctionCallAccessKey;
|
|
225
226
|
exports.deleteAccessKeys = deleteAccessKeys;
|
|
226
227
|
exports.ensureNearCli = ensureNearCli;
|
|
227
228
|
exports.executeTransaction = executeTransaction;
|
|
229
|
+
exports.generateNearKeyPair = generateNearKeyPair;
|
|
228
230
|
exports.listPublishKeys = listPublishKeys;
|
|
229
231
|
exports.resolveNearSigningMode = resolveNearSigningMode;
|
|
230
232
|
//# sourceMappingURL=near-cli.cjs.map
|
package/dist/near-cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"near-cli.cjs","names":["Effect","colors"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"near-cli.cjs","names":["Effect","colors"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
|
package/dist/near-cli.mjs
CHANGED
|
@@ -220,5 +220,5 @@ async function addFunctionCallAccessKey(config) {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
//#endregion
|
|
223
|
-
export { addFunctionCallAccessKey, deleteAccessKeys, ensureNearCli, executeTransaction, listPublishKeys, resolveNearSigningMode };
|
|
223
|
+
export { NearCliNotFoundError, NearTransactionError, addFunctionCallAccessKey, deleteAccessKeys, ensureNearCli, executeTransaction, generateNearKeyPair, listPublishKeys, resolveNearSigningMode };
|
|
224
224
|
//# sourceMappingURL=near-cli.mjs.map
|
package/dist/near-cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"near-cli.mjs","names":[],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"near-cli.mjs","names":[],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
|
package/dist/network.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.cjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,SAAwC;
|
|
1
|
+
{"version":3,"file":"network.cjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,SAAwC;CAC7E,OAAO,QAAQ,SAAS,UAAU,IAAI,YAAY;AACpD"}
|
package/dist/network.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.mjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,SAAwC;
|
|
1
|
+
{"version":3,"file":"network.mjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,SAAwC;CAC7E,OAAO,QAAQ,SAAS,UAAU,IAAI,YAAY;AACpD"}
|
package/dist/orchestrator.cjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
1
|
const require_mf = require('./mf.cjs');
|
|
3
2
|
const require_service_descriptor = require('./service-descriptor.cjs');
|
|
4
3
|
let effect = require("effect");
|
|
@@ -209,7 +208,8 @@ const spawnDevProcess = (descriptor, callbacks) => effect.Effect.gen(function* (
|
|
|
209
208
|
yield* effect.Effect.forkScoped(effect.Effect.gen(function* () {
|
|
210
209
|
const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;
|
|
211
210
|
if (port > 0) {
|
|
212
|
-
const
|
|
211
|
+
const readinessPath = descriptor.readinessPath;
|
|
212
|
+
const url = `http://127.0.0.1:${port}${readinessPath}`;
|
|
213
213
|
while (Date.now() < deadline) {
|
|
214
214
|
const status = yield* effect.Ref.get(statusRef);
|
|
215
215
|
if (status === "ready" || status === "error") return;
|
|
@@ -332,10 +332,11 @@ const makeDevProcess = (pkg, callbacks, portOverride) => effect.Effect.gen(funct
|
|
|
332
332
|
}
|
|
333
333
|
if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks);
|
|
334
334
|
if (descriptor.source === "remote" || !descriptor.localPath) return yield* spawnRemoteProbe(pkg, descriptor, callbacks);
|
|
335
|
-
|
|
335
|
+
const resolvedDescriptor = portOverride ? {
|
|
336
336
|
...descriptor,
|
|
337
337
|
port: portOverride
|
|
338
|
-
} : descriptor
|
|
338
|
+
} : descriptor;
|
|
339
|
+
return yield* spawnDevProcess(resolvedDescriptor, callbacks);
|
|
339
340
|
});
|
|
340
341
|
function getProcessStates(packages, services, portOverride) {
|
|
341
342
|
return packages.map((pkg) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.cjs","names":["Effect","DevRuntimeConfig","Deferred","Ref","Command","Stream","Option","ServiceDescriptorMap"],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n DevRuntimeConfig,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nprocess.on(\"unhandledRejection\", (reason) => {\n console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(\"[Orchestrator] Uncaught exception:\", err);\n});\n\nexport interface ProcessCallbacks {\n onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n name: string;\n pid: number | undefined;\n kill: Effect.Effect<void, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<ExitCode, unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: \"local\" | \"remote\";\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n Effect.tryPromise({\n try: async () => {\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 res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n },\n catch: () => false,\n });\n\nconst LOCAL_PROBE_DEADLINE_MS = 90_000;\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\n\nconst detectStatus = (\n line: string,\n descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n const errorPatterns = descriptor.errorPatterns ?? [];\n const readyPatterns = descriptor.readyPatterns ?? [];\n for (const pattern of errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\n port?: number;\n env?: Record<string, string>;\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n const originalLog = console.log;\n const originalError = console.error;\n const originalWarn = console.warn;\n const originalInfo = console.info;\n\n const formatArgs = (args: unknown[], isError = false): string => {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n const parts = [`${arg.name}: ${arg.message}`];\n if (arg.cause instanceof Error)\n parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n else if (arg.cause) parts.push(`(cause: ${String(arg.cause)})`);\n if (isError && arg.stack) parts.push(arg.stack);\n return parts.join(\"\\n\");\n }\n return typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg);\n })\n .join(\" \");\n };\n\n console.log = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.error = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args, true), true);\n };\n console.warn = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.info = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n\n return () => {\n console.log = originalLog;\n console.error = originalError;\n console.warn = originalWarn;\n console.info = originalInfo;\n };\n};\n\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n const remoteUrl = descriptor.remoteUrl;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\n }\n\n callbacks.onStatus(descriptor.key, \"starting\");\n callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(descriptor.key, callbacks);\n callbacks.onLog(descriptor.key, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n let res: Response;\n try {\n res = await fetch(manifestUrl, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n if (!res.ok) return remoteEntryUrl;\n const json = (await res.json()) as Record<string, unknown>;\n if (\n json &&\n typeof json === \"object\" &&\n \"metaData\" in json &&\n \"exposes\" in json &&\n \"shared\" in json\n ) {\n return manifestUrl;\n }\n } catch (e) {\n console.warn(\n `[Orchestrator] Failed to fetch or parse manifest from ${manifestUrl}, falling back to remoteEntryUrl: ${e}`,\n );\n }\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(descriptor.key, \"Starting server...\");\n const hostPort = runtimeConfig.host?.port;\n const hostEnv: Record<string, string> | undefined = hostPort\n ? { PORT: String(hostPort) }\n : undefined;\n const serverHandle = hostModule.runServer({\n config: runtimeConfig,\n port: hostPort,\n env: hostEnv,\n });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(descriptor.key, \"ready\");\n\n return {\n name: descriptor.key,\n pid: process.pid,\n kill: Effect.gen(function* () {\n callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n restoreConsole();\n yield* Effect.tryPromise({\n try: () => serverHandle.shutdown(),\n catch: () => {},\n }).pipe(Effect.ignore);\n }),\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n\n if (!descriptor.localPath) {\n return yield* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n }\n\n const fullCwd = descriptor.localPath;\n const command = descriptor.command ?? \"bun\";\n const args = descriptor.args ?? [\"run\", \"dev\"];\n const port = descriptor.port ?? descriptor.defaultPort;\n const name = descriptor.key;\n\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n FORCE_COLOR: \"1\",\n ...(port > 0 ? { PORT: String(port) } : {}),\n };\n\n if (name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const cmd = Command.make(command, ...args).pipe(\n Command.workingDirectory(fullCwd),\n Command.env(envVars),\n );\n\n const proc = yield* Command.start(cmd);\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n callbacks.onStatus(name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n const markError = (message: string) =>\n Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(name, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(message)).pipe(Effect.ignore);\n });\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;\n\n if (port > 0) {\n const readinessPath = descriptor.readinessPath;\n const url = `http://127.0.0.1:${port}${readinessPath}`;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = yield* probeHttpOk(url);\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(`${LOCAL_PROBE_INTERVAL_MS} millis`);\n }\n } else {\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n yield* Effect.sleep(\"500 millis\");\n }\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\" && status !== \"error\") {\n callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n yield* markError(`Probe deadline exceeded: ${name}`);\n }\n }),\n );\n\n const pid = Number(proc.pid);\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const exitCode = yield* proc.exitCode;\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n yield* markError(`Process exited before ready: ${name}`);\n }),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n const cleanLine = stripAnsi(line);\n const looksLikeError =\n isStderr &&\n /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n !/^\\$/.test(cleanLine);\n callbacks.onLog(name, line, looksLikeError);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n\n const detected = detectStatus(line, descriptor);\n if (detected) {\n if (detected.status === \"ready\") {\n yield* markReady;\n } else {\n yield* markError(`Process failed: ${name}`);\n }\n }\n });\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, false))(\n Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n ),\n );\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, true))(\n Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n ),\n );\n\n return {\n name,\n pid,\n kill: Effect.gen(function* () {\n const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n if (Option.isNone(result)) {\n const pid = Number(proc.pid);\n yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n yield* Effect.sleep(\"250 millis\");\n }\n }).pipe(Effect.ignore),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: proc.exitCode,\n } satisfies ProcessHandle;\n });\n\nconst spawnRemoteProbe = (\n pkg: string,\n descriptor: ServiceDescriptor,\n callbacks: ProcessCallbacks,\n) =>\n Effect.gen(function* () {\n callbacks.onStatus(pkg, \"starting\");\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n callbacks.onStatus(pkg, \"ready\", \"loaded\");\n });\n\n const markError = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`)).pipe(\n Effect.ignore,\n );\n callbacks.onStatus(pkg, \"error\", \"unreachable\");\n });\n\n const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + REMOTE_PROBE_DEADLINE_MS;\n let delay = REMOTE_PROBE_BACKOFF_INITIAL_MS;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n\n const ok = yield* probeHttpOk(probeUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (ok) {\n yield* markReady;\n return;\n }\n\n const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (fallbackOk) {\n yield* markReady;\n return;\n }\n\n yield* Effect.sleep(`${delay} millis`);\n delay = Math.min(Math.round(delay * 1.5), REMOTE_PROBE_BACKOFF_MAX_MS);\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\") {\n yield* markError;\n }\n }),\n );\n\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.gen(function* () {\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(\"Killed\")).pipe(Effect.ignore);\n }),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n Effect.gen(function* () {\n const services = yield* ServiceDescriptorMap;\n const descriptor = services.get(pkg);\n\n if (!descriptor) {\n callbacks.onStatus(pkg, \"ready\", \"Remote\");\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n }\n\n if (pkg === \"host\" && descriptor.source === \"remote\") {\n return yield* spawnRemoteHost(descriptor, callbacks);\n }\n\n if (descriptor.source === \"remote\" || !descriptor.localPath) {\n return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n }\n\n const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n });\n\nexport function getProcessStates(\n packages: string[],\n services: Map<string, ServiceDescriptor>,\n portOverride?: number,\n): ProcessState[] {\n return packages.map((pkg) => {\n const descriptor = services.get(pkg);\n return {\n name: pkg,\n status: \"pending\" as const,\n port:\n portOverride && pkg === \"host\"\n ? portOverride\n : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n source: descriptor?.source,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"orchestrator.cjs","names":["Effect","DevRuntimeConfig","Deferred","Ref","Command","Stream","Option","ServiceDescriptorMap"],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n DevRuntimeConfig,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nprocess.on(\"unhandledRejection\", (reason) => {\n console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(\"[Orchestrator] Uncaught exception:\", err);\n});\n\nexport interface ProcessCallbacks {\n onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n name: string;\n pid: number | undefined;\n kill: Effect.Effect<void, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<ExitCode, unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: \"local\" | \"remote\";\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n Effect.tryPromise({\n try: async () => {\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 res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n },\n catch: () => false,\n });\n\nconst LOCAL_PROBE_DEADLINE_MS = 90_000;\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\n\nconst detectStatus = (\n line: string,\n descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n const errorPatterns = descriptor.errorPatterns ?? [];\n const readyPatterns = descriptor.readyPatterns ?? [];\n for (const pattern of errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\n port?: number;\n env?: Record<string, string>;\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n const originalLog = console.log;\n const originalError = console.error;\n const originalWarn = console.warn;\n const originalInfo = console.info;\n\n const formatArgs = (args: unknown[], isError = false): string => {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n const parts = [`${arg.name}: ${arg.message}`];\n if (arg.cause instanceof Error)\n parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n else if (arg.cause) parts.push(`(cause: ${String(arg.cause)})`);\n if (isError && arg.stack) parts.push(arg.stack);\n return parts.join(\"\\n\");\n }\n return typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg);\n })\n .join(\" \");\n };\n\n console.log = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.error = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args, true), true);\n };\n console.warn = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.info = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n\n return () => {\n console.log = originalLog;\n console.error = originalError;\n console.warn = originalWarn;\n console.info = originalInfo;\n };\n};\n\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n const remoteUrl = descriptor.remoteUrl;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\n }\n\n callbacks.onStatus(descriptor.key, \"starting\");\n callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(descriptor.key, callbacks);\n callbacks.onLog(descriptor.key, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n let res: Response;\n try {\n res = await fetch(manifestUrl, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n if (!res.ok) return remoteEntryUrl;\n const json = (await res.json()) as Record<string, unknown>;\n if (\n json &&\n typeof json === \"object\" &&\n \"metaData\" in json &&\n \"exposes\" in json &&\n \"shared\" in json\n ) {\n return manifestUrl;\n }\n } catch (e) {\n console.warn(\n `[Orchestrator] Failed to fetch or parse manifest from ${manifestUrl}, falling back to remoteEntryUrl: ${e}`,\n );\n }\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(descriptor.key, \"Starting server...\");\n const hostPort = runtimeConfig.host?.port;\n const hostEnv: Record<string, string> | undefined = hostPort\n ? { PORT: String(hostPort) }\n : undefined;\n const serverHandle = hostModule.runServer({\n config: runtimeConfig,\n port: hostPort,\n env: hostEnv,\n });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(descriptor.key, \"ready\");\n\n return {\n name: descriptor.key,\n pid: process.pid,\n kill: Effect.gen(function* () {\n callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n restoreConsole();\n yield* Effect.tryPromise({\n try: () => serverHandle.shutdown(),\n catch: () => {},\n }).pipe(Effect.ignore);\n }),\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n\n if (!descriptor.localPath) {\n return yield* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n }\n\n const fullCwd = descriptor.localPath;\n const command = descriptor.command ?? \"bun\";\n const args = descriptor.args ?? [\"run\", \"dev\"];\n const port = descriptor.port ?? descriptor.defaultPort;\n const name = descriptor.key;\n\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n FORCE_COLOR: \"1\",\n ...(port > 0 ? { PORT: String(port) } : {}),\n };\n\n if (name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const cmd = Command.make(command, ...args).pipe(\n Command.workingDirectory(fullCwd),\n Command.env(envVars),\n );\n\n const proc = yield* Command.start(cmd);\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n callbacks.onStatus(name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n const markError = (message: string) =>\n Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(name, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(message)).pipe(Effect.ignore);\n });\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;\n\n if (port > 0) {\n const readinessPath = descriptor.readinessPath;\n const url = `http://127.0.0.1:${port}${readinessPath}`;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = yield* probeHttpOk(url);\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(`${LOCAL_PROBE_INTERVAL_MS} millis`);\n }\n } else {\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n yield* Effect.sleep(\"500 millis\");\n }\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\" && status !== \"error\") {\n callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n yield* markError(`Probe deadline exceeded: ${name}`);\n }\n }),\n );\n\n const pid = Number(proc.pid);\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const exitCode = yield* proc.exitCode;\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n yield* markError(`Process exited before ready: ${name}`);\n }),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n const cleanLine = stripAnsi(line);\n const looksLikeError =\n isStderr &&\n /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n !/^\\$/.test(cleanLine);\n callbacks.onLog(name, line, looksLikeError);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n\n const detected = detectStatus(line, descriptor);\n if (detected) {\n if (detected.status === \"ready\") {\n yield* markReady;\n } else {\n yield* markError(`Process failed: ${name}`);\n }\n }\n });\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, false))(\n Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n ),\n );\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, true))(\n Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n ),\n );\n\n return {\n name,\n pid,\n kill: Effect.gen(function* () {\n const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n if (Option.isNone(result)) {\n const pid = Number(proc.pid);\n yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n yield* Effect.sleep(\"250 millis\");\n }\n }).pipe(Effect.ignore),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: proc.exitCode,\n } satisfies ProcessHandle;\n });\n\nconst spawnRemoteProbe = (\n pkg: string,\n descriptor: ServiceDescriptor,\n callbacks: ProcessCallbacks,\n) =>\n Effect.gen(function* () {\n callbacks.onStatus(pkg, \"starting\");\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n callbacks.onStatus(pkg, \"ready\", \"loaded\");\n });\n\n const markError = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`)).pipe(\n Effect.ignore,\n );\n callbacks.onStatus(pkg, \"error\", \"unreachable\");\n });\n\n const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + REMOTE_PROBE_DEADLINE_MS;\n let delay = REMOTE_PROBE_BACKOFF_INITIAL_MS;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n\n const ok = yield* probeHttpOk(probeUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (ok) {\n yield* markReady;\n return;\n }\n\n const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (fallbackOk) {\n yield* markReady;\n return;\n }\n\n yield* Effect.sleep(`${delay} millis`);\n delay = Math.min(Math.round(delay * 1.5), REMOTE_PROBE_BACKOFF_MAX_MS);\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\") {\n yield* markError;\n }\n }),\n );\n\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.gen(function* () {\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(\"Killed\")).pipe(Effect.ignore);\n }),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n Effect.gen(function* () {\n const services = yield* ServiceDescriptorMap;\n const descriptor = services.get(pkg);\n\n if (!descriptor) {\n callbacks.onStatus(pkg, \"ready\", \"Remote\");\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n }\n\n if (pkg === \"host\" && descriptor.source === \"remote\") {\n return yield* spawnRemoteHost(descriptor, callbacks);\n }\n\n if (descriptor.source === \"remote\" || !descriptor.localPath) {\n return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n }\n\n const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n });\n\nexport function getProcessStates(\n packages: string[],\n services: Map<string, ServiceDescriptor>,\n portOverride?: number,\n): ProcessState[] {\n return packages.map((pkg) => {\n const descriptor = services.get(pkg);\n return {\n name: pkg,\n status: \"pending\" as const,\n port:\n portOverride && pkg === \"host\"\n ? portOverride\n : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n source: descriptor?.source,\n };\n });\n}\n"],"mappings":"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"}
|
package/dist/orchestrator.mjs
CHANGED
|
@@ -208,7 +208,8 @@ const spawnDevProcess = (descriptor, callbacks) => Effect.gen(function* () {
|
|
|
208
208
|
yield* Effect.forkScoped(Effect.gen(function* () {
|
|
209
209
|
const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;
|
|
210
210
|
if (port > 0) {
|
|
211
|
-
const
|
|
211
|
+
const readinessPath = descriptor.readinessPath;
|
|
212
|
+
const url = `http://127.0.0.1:${port}${readinessPath}`;
|
|
212
213
|
while (Date.now() < deadline) {
|
|
213
214
|
const status = yield* Ref.get(statusRef);
|
|
214
215
|
if (status === "ready" || status === "error") return;
|
|
@@ -331,10 +332,11 @@ const makeDevProcess = (pkg, callbacks, portOverride) => Effect.gen(function* ()
|
|
|
331
332
|
}
|
|
332
333
|
if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks);
|
|
333
334
|
if (descriptor.source === "remote" || !descriptor.localPath) return yield* spawnRemoteProbe(pkg, descriptor, callbacks);
|
|
334
|
-
|
|
335
|
+
const resolvedDescriptor = portOverride ? {
|
|
335
336
|
...descriptor,
|
|
336
337
|
port: portOverride
|
|
337
|
-
} : descriptor
|
|
338
|
+
} : descriptor;
|
|
339
|
+
return yield* spawnDevProcess(resolvedDescriptor, callbacks);
|
|
338
340
|
});
|
|
339
341
|
function getProcessStates(packages, services, portOverride) {
|
|
340
342
|
return packages.map((pkg) => {
|