chore: remove symlink dead code #271

Merged
xiaomo merged 1 commits from chore/remove-symlink-dead-code into main 2026-05-16 06:22:35 +00:00
9 changed files with 4 additions and 77 deletions
@@ -110,7 +110,7 @@ export async function cmdAdd(
return validated;
}
const extracted = await extractBundleExports(resolvedPath, { storageRoot });
const extracted = await extractBundleExports(resolvedPath);
if (!extracted.ok) {
return extracted;
}
@@ -4,7 +4,6 @@ import { createServer, type Socket } from "node:net";
import { dirname, join } from "node:path";
import { createCasStore } from "@uncaged/workflow-cas";
import {
ensureUncagedWorkflowSymlink,
importWorkflowBundleModule,
} from "@uncaged/workflow-register";
import type { RoleOutput, WorkflowFn } from "@uncaged/workflow-runtime";
@@ -365,7 +364,6 @@ async function main(): Promise<void> {
return;
}
await ensureUncagedWorkflowSymlink(storageRoot);
// Dynamic import required: user bundle path resolved at runtime
const modUnknown: unknown = await importWorkflowBundleModule(bundlePath);
const modRec = modUnknown as Record<string, unknown>;
@@ -69,7 +69,7 @@ async function resolveWorkflowBundle(workflowName: string, storageRoot: string,
}
const bundlePath = join(storageRoot, "bundles", `${entry.hash}.esm.js`);
const bundleExportsResult = await extractBundleExports(bundlePath, { storageRoot });
const bundleExportsResult = await extractBundleExports(bundlePath);
if (!bundleExportsResult.ok) {
throw new Error(String(bundleExportsResult.error));
}
@@ -1,7 +1,7 @@
import { pathToFileURL } from "node:url";
/**
* Dynamic-import a workflow bundle path (see {@link extractBundleExports} — symlink must exist first).
* Dynamic-import a workflow bundle path.
*/
export async function importWorkflowBundleModule(bundlePath: string): Promise<unknown> {
return import(pathToFileURL(bundlePath).href);
@@ -1,56 +0,0 @@
import { mkdir, readlink, symlink, unlink } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
/** This module lives in `@uncaged/workflow-register/src/bundle`; grandparent dir is the package root. */
function installedWorkflowPackageDir(): string {
return fileURLToPath(new URL("../..", import.meta.url));
}
/**
* Resolve sibling @uncaged/* package directory relative to workflow-register.
* In a monorepo workspace layout the sibling packages live next to workflow-register.
*/
function siblingPackageDir(packageName: string): string {
const registerRoot = installedWorkflowPackageDir();
return path.resolve(registerRoot, "..", packageName);
}
async function ensureSymlink(linkDir: string, name: string, target: string): Promise<void> {
const linkPath = path.join(linkDir, name);
await mkdir(linkDir, { recursive: true });
try {
const existing = await readlink(linkPath);
const normalizedExisting = path.resolve(linkDir, existing);
if (normalizedExisting === target) {
return;
}
await unlink(linkPath);
} catch (e) {
const errObj = e as NodeJS.ErrnoException;
if (errObj.code !== "ENOENT" && errObj.code !== "EINVAL") {
throw e;
}
}
const linkType = process.platform === "win32" ? "junction" : "dir";
await symlink(target, linkPath, linkType);
}
/**
* Ensures `<storageRoot>/node_modules/@uncaged/*` symlinks point at installed packages
* so workflow bundles loaded from `<storageRoot>/bundles/*.esm.js` can resolve their imports.
*/
export async function ensureUncagedWorkflowSymlink(storageRoot: string): Promise<void> {
const linkDir = path.join(storageRoot, "node_modules", "@uncaged");
const packages = [
{ name: "workflow", dir: siblingPackageDir("workflow") },
{ name: "workflow-runtime", dir: siblingPackageDir("workflow-runtime") },
{ name: "workflow-cas", dir: siblingPackageDir("workflow-cas") },
{ name: "workflow-protocol", dir: siblingPackageDir("workflow-protocol") },
];
for (const pkg of packages) {
await ensureSymlink(linkDir, pkg.name, pkg.dir);
}
}
@@ -1,21 +1,15 @@
import type { WorkflowFn } from "@uncaged/workflow-protocol";
import { err, ok, type Result } from "@uncaged/workflow-util";
import { importWorkflowBundleModule } from "./bundle-import-env.js";
import { ensureUncagedWorkflowSymlink } from "./ensure-uncaged-workflow-symlink.js";
import type { ExtractBundleExportsOptions, ExtractedBundleExports } from "./types.js";
import type { ExtractedBundleExports } from "./types.js";
import { validateWorkflowDescriptor } from "./workflow-descriptor.js";
/** Load a workflow `.esm.js` bundle and read its named exports (`run`, `descriptor`). */
export async function extractBundleExports(
bundlePath: string,
options: ExtractBundleExportsOptions = { storageRoot: null },
): Promise<Result<ExtractedBundleExports, string>> {
let modUnknown: unknown;
try {
if (options.storageRoot !== null) {
await ensureUncagedWorkflowSymlink(options.storageRoot);
}
// Dynamic import required: user bundle path resolved at runtime
modUnknown = await importWorkflowBundleModule(bundlePath);
} catch (e) {
const message = e instanceof Error ? e.message : String(e);
@@ -1,11 +1,9 @@
export { buildDescriptor } from "./build-descriptor.js";
export { importWorkflowBundleModule } from "./bundle-import-env.js";
export { validateWorkflowBundle } from "./bundle-validator.js";
export { ensureUncagedWorkflowSymlink } from "./ensure-uncaged-workflow-symlink.js";
export { extractBundleExports } from "./extract-bundle-exports.js";
export { stringifyWorkflowDescriptor } from "./generate-descriptor.js";
export type {
ExtractBundleExportsOptions,
ExtractedBundleExports,
WorkflowBundleValidationInput,
WorkflowDescriptor,
@@ -20,8 +20,3 @@ export type ExtractedBundleExports = {
run: WorkflowFn;
descriptor: WorkflowDescriptor;
};
export type ExtractBundleExportsOptions = {
/** When set, ensures `node_modules/@uncaged/workflow` exists under this root before import. */
storageRoot: string | null;
};
-2
View File
@@ -1,5 +1,4 @@
export type {
ExtractBundleExportsOptions,
ExtractedBundleExports,
WorkflowBundleValidationInput,
WorkflowDescriptor,
@@ -10,7 +9,6 @@ export type {
} from "./bundle/index.js";
export {
buildDescriptor,
ensureUncagedWorkflowSymlink,
extractBundleExports,
importWorkflowBundleModule,
stringifyWorkflowDescriptor,