From cc464afdfb8cd088a0fd8ecbad1d2ea82a93571c Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Fri, 18 Sep 2026 12:27:32 +0530 Subject: [PATCH] Give the generated server module the workspace's own @wrnexus/core The execution tests wrote the generated module to an OS tmpdir and junctioned @wrnexus/core in beside it. On Windows that tmpdir sits on another volume, and the junction resolved to a second copy of the package: the request context lives in an AsyncLocalStorage inside core, so the module read a store the test could never populate and all six execution tests failed with "needs a request context". The module is now written inside the repo, where resolution walks up to this workspace's node_modules and finds the same instance the test holds. That identity is the whole point, so the junction is gone. Co-Authored-By: Claude Opus 5 --- .gitignore | 3 ++ .../compiler/test/apis-server-emit.test.ts | 34 +++++++------------ 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index a2a5e4ec..711467a5 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ tsconfig.focus.json # Subagent-driven-development scratch (ledger, briefs, review packages) .superpowers/ + +# Scratch modules written by tests that must resolve this workspace. +.tmp-tests/ diff --git a/packages/compiler/test/apis-server-emit.test.ts b/packages/compiler/test/apis-server-emit.test.ts index 43536044..3f23279b 100644 --- a/packages/compiler/test/apis-server-emit.test.ts +++ b/packages/compiler/test/apis-server-emit.test.ts @@ -1,29 +1,20 @@ import { afterEach, expect, test } from "bun:test"; -import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { parse } from "@wrnexus/syntax"; import { runWithRequestContext } from "@wrnexus/core"; import { generate } from "../src/codegen.ts"; -// The generated module dynamically imported below is written to an OS -// tmpdir with no node_modules of its own, so Node's bare-specifier -// resolution for "@wrnexus/core" would otherwise walk up to whatever -// (possibly stale, globally-installed) copy happens to sit outside the -// workspace. Symlink the workspace package in so it resolves to the real, -// currently-built `@wrnexus/core` — the same one every other package in -// this repo gets via its own `node_modules/@wrnexus/core` symlink. -const WORKSPACE_CORE = join(import.meta.dir, "../../core"); - -function linkWorkspaceCore(root: string): void { - const scopeDir = join(root, "node_modules", "@wrnexus"); - mkdirSync(scopeDir, { recursive: true }); - symlinkSync( - WORKSPACE_CORE, - join(scopeDir, "core"), - process.platform === "win32" ? "junction" : "dir", - ); -} +// The generated module dynamically imported below resolves "@wrnexus/core" +// by walking up from its own directory, so it is written inside the repo +// rather than an OS tmpdir: the walk then reaches this workspace's +// node_modules and loads the very same module instance the test itself +// holds. That identity is what these tests rest on -- the request context +// lives in an AsyncLocalStorage inside `@wrnexus/core`, and a second copy of +// the package (which is what a junction from another volume produced) has a +// store of its own that the test could never populate. +const WORKSPACE_TMP = join(import.meta.dir, "../../../.tmp-tests"); const ROOT_TSCONFIG = join(import.meta.dir, "../../../tsconfig.json").replace(/\\/g, "/"); // The repo's own tsc, not a `bunx`-fetched one — `bunx tsc` can resolve an @@ -69,10 +60,9 @@ function typecheckGenerated(source: string): { ok: boolean; output: string } { } async function importServerModule(source: string): Promise { - const root = mkdtempSync(join(tmpdir(), "wrnexus-apis-server-exec-")); + mkdirSync(WORKSPACE_TMP, { recursive: true }); + const root = mkdtempSync(join(WORKSPACE_TMP, "apis-server-exec-")); roots.push(root); - mkdirSync(root, { recursive: true }); - linkWorkspaceCore(root); const file = join(root, "page.ts"); writeFileSync(file, source); return import(`${file.replace(/\\/g, "/")}?t=${Date.now()}`);