fix: lazy-load esbuild via createRequire (jsdom-safe engine import) + lint cleanup of dead helpers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-06-04 13:19:55 -07:00
parent 7076dd4516
commit 94da14cd81
3 changed files with 14 additions and 17 deletions

View File

@@ -24,7 +24,6 @@
import type {
WorkflowFieldDefinition,
WorkflowFieldType,
} from "./workflow-ir-types.js";
// ---------------------------------------------------------------------------
@@ -187,7 +186,6 @@ function validateValue(
return reject("type-mismatch", `field '${field.id}' (url) expects a string, got ${typeof value}`);
}
try {
// eslint-disable-next-line no-new
new URL(value);
} catch {
return reject("type-mismatch", `field '${field.id}' value '${value}' is not a valid URL`);
@@ -299,11 +297,6 @@ export function applyFieldDefaults(
// Reconciliation on workflow edit / switch
// ---------------------------------------------------------------------------
/** Two field types are "enum-kind" siblings (enum / multi-enum). */
function isEnumKind(type: WorkflowFieldType): boolean {
return type === "enum" || type === "multi-enum";
}
/**
* A stored value for `field` is type-compatible with a new field definition iff
* the new value re-validates cleanly. For enum-kind fields, compatibility also

View File

@@ -60,14 +60,6 @@ export interface TaskFieldsSectionProps {
readOnly?: boolean;
}
function optionLabel(field: WorkflowFieldDefinition, value: string): string {
return field.options?.find((o) => o.value === value)?.label ?? value;
}
function optionColor(field: WorkflowFieldDefinition, value: string): string | undefined {
return field.options?.find((o) => o.value === value)?.color;
}
/** Resolve the effective widget for a field, applying the per-type default. */
function resolveWidget(field: WorkflowFieldDefinition): NonNullable<WorkflowFieldDefinition["render"]>["widget"] {
const explicit = field.render?.widget;

View File

@@ -39,11 +39,23 @@
*/
import { execFile } from "node:child_process";
import { createRequire } from "node:module";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { transformSync } from "esbuild";
// esbuild is loaded lazily at first compile: a top-level import would run its
// environment invariant check (TextEncoder) at module-load time in any process
// that merely imports @fusion/engine — including jsdom test environments where
// that invariant fails. Lazy loading confines esbuild to actual code-node use.
let cachedTransformSync: typeof import("esbuild").transformSync | undefined;
function getTransformSync(): typeof import("esbuild").transformSync {
if (!cachedTransformSync) {
const req = createRequire(import.meta.url);
cachedTransformSync = (req("esbuild") as typeof import("esbuild")).transformSync;
}
return cachedTransformSync;
}
import type { CustomFieldRejection, TaskDetail, WorkflowIrNode } from "@fusion/core";
import type { WorkflowNodeResult } from "./workflow-graph-executor.js";
@@ -148,7 +160,7 @@ export async function compileCodeNodeSource(source: string): Promise<string> {
// `transformSync` runs a short-lived per-call child that exits cleanly,
// avoiding esbuild's long-lived service process (which the test harness's
// subprocess guard would otherwise flag as a lingering child).
const out = transformSync(source, {
const out = getTransformSync()(source, {
loader: "ts",
format: "esm",
target: "node18",