agency-lang 0.0.97 → 0.0.99

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.
@@ -1,6 +1,7 @@
1
1
  import { AgencyConfig } from "../config.js";
2
2
  import { AgencyProgram } from "../index.js";
3
3
  import { type SymbolTable } from "../symbolTable.js";
4
+ import { type ImportStrategy } from "../importStrategy.js";
4
5
  export declare function loadConfig(configPath?: string, verbose?: boolean): AgencyConfig;
5
6
  export declare function readStdin(): Promise<string>;
6
7
  export declare function parse(contents: string, config: AgencyConfig, applyTemplate?: boolean): AgencyProgram;
@@ -9,6 +10,7 @@ export declare function resetCompilationCache(): void;
9
10
  export declare function compile(config: AgencyConfig, inputFile: string, _outputFile?: string, options?: {
10
11
  ts?: boolean;
11
12
  symbolTable?: SymbolTable;
13
+ importStrategy?: ImportStrategy;
12
14
  }): string | null;
13
15
  export declare function run(config: AgencyConfig, inputFile: string, outputFile?: string, resumeFile?: string): void;
14
16
  export declare function format(contents: string, config: AgencyConfig): Promise<string>;
@@ -9,6 +9,7 @@ import { transformSync } from "esbuild";
9
9
  import * as fs from "fs";
10
10
  import * as path from "path";
11
11
  import { getStdlibDir, isPkgImport, isStdlibImport, resolveAgencyImportPath, } from "../importPaths.js";
12
+ import { CompileStrategy, RunStrategy } from "../importStrategy.js";
12
13
  import { parseAgency } from "../parser.js";
13
14
  import { findRecursively, getImports } from "./util.js";
14
15
  // Load configuration from agency.json
@@ -126,8 +127,11 @@ export function compile(config, inputFile, _outputFile, options) {
126
127
  }
127
128
  const imports = getImports(resolvedProgram);
128
129
  for (const importPath of imports) {
130
+ // stdlib and pkg imports are pre-compiled; don't recompile them
131
+ if (isStdlibImport(importPath) || isPkgImport(importPath))
132
+ continue;
129
133
  const absPath = resolveAgencyImportPath(importPath, absoluteInputFile);
130
- if (config.restrictImports && !isStdlibImport(importPath) && !isPkgImport(importPath)) {
134
+ if (config.restrictImports) {
131
135
  const projectRoot = process.cwd();
132
136
  if (!absPath.startsWith(projectRoot + path.sep) &&
133
137
  absPath !== projectRoot) {
@@ -136,12 +140,21 @@ export function compile(config, inputFile, _outputFile, options) {
136
140
  }
137
141
  compile(config, absPath, undefined, { ...options, symbolTable });
138
142
  }
139
- // Update the import path in the AST to reference the new .ts file
143
+ // Rewrite import paths in the AST using the import strategy
144
+ const strategy = options?.importStrategy ?? new CompileStrategy({ targetExt: ext });
145
+ const nonAgencyImports = [];
140
146
  resolvedProgram.nodes.forEach((node) => {
141
- if (node.type === "importStatement" && !isStdlibImport(node.modulePath) && !isPkgImport(node.modulePath)) {
142
- node.modulePath = node.modulePath.replace(".agency", ext);
147
+ if (node.type !== "importStatement")
148
+ return;
149
+ if (isStdlibImport(node.modulePath) || isPkgImport(node.modulePath))
150
+ return;
151
+ node.modulePath = strategy.rewriteImport(node.modulePath, absoluteInputFile);
152
+ // Collect non-Agency imports for dependency preparation
153
+ if (!node.modulePath.endsWith(".agency")) {
154
+ nonAgencyImports.push(node.modulePath);
143
155
  }
144
156
  });
157
+ strategy.prepareDependencies(nonAgencyImports, absoluteInputFile);
145
158
  const moduleId = path.relative(process.cwd(), absoluteInputFile);
146
159
  const generatedCode = generateTypeScript(resolvedProgram, config, info, moduleId);
147
160
  if (options?.ts) {
@@ -161,8 +174,8 @@ export function compile(config, inputFile, _outputFile, options) {
161
174
  return outputFile;
162
175
  }
163
176
  export function run(config, inputFile, outputFile, resumeFile) {
164
- // Compile the file
165
- const output = compile(config, inputFile, outputFile);
177
+ // Compile the file with RunStrategy so dependencies are prepared for execution
178
+ const output = compile(config, inputFile, outputFile, { importStrategy: new RunStrategy() });
166
179
  if (output === null) {
167
180
  console.error("Error: No output file generated.");
168
181
  process.exit(1);
@@ -4,4 +4,5 @@ export declare function debug(config: AgencyConfig, _inputFile: string, options?
4
4
  rewindSize?: number;
5
5
  trace?: string;
6
6
  checkpoint?: string;
7
+ distDir?: string;
7
8
  }): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import { compile } from "./commands.js";
2
- import { pickANode } from "./util.js";
2
+ import { RunStrategy } from "../importStrategy.js";
3
+ import { pickANode, resolveCompiledFile } from "./util.js";
3
4
  import { parseAgency } from "../parser.js";
4
5
  import { getNodesOfType } from "../utils/node.js";
5
6
  import { DebuggerDriver } from "../debugger/driver.js";
@@ -77,25 +78,45 @@ export async function debug(config, _inputFile, options = {}) {
77
78
  }
78
79
  traceCheckpoints = [cp];
79
80
  }
80
- // Force debugger mode so the builder emits debugStep() calls
81
- const debugConfig = { ...config, debugger: true };
82
- // Compile the .agency file to .js
83
- const outputFile = compile(debugConfig, inputFile);
84
- if (outputFile === null) {
85
- console.error("Error: No output file generated.");
86
- process.exit(1);
81
+ // Resolve distDir from CLI flag or config
82
+ const distDir = options.distDir ?? config.distDir;
83
+ let absOutput;
84
+ if (distDir) {
85
+ // distDir mode: import pre-compiled JS from the dist directory
86
+ const compiledPath = resolveCompiledFile(distDir, inputFile);
87
+ // Warn if source is newer than compiled output
88
+ const sourceMtime = fs.statSync(inputFile).mtimeMs;
89
+ const compiledMtime = fs.statSync(compiledPath).mtimeMs;
90
+ if (sourceMtime > compiledMtime) {
91
+ console.warn(`Warning: ${inputFile} is newer than ${compiledPath}.\n` +
92
+ `You may need to recompile before debugging.`);
93
+ }
94
+ absOutput = compiledPath;
95
+ }
96
+ else {
97
+ // Normal mode: compile the .agency file to .js on the fly
98
+ const debugConfig = { ...config, debugger: true };
99
+ const outputFile = compile(debugConfig, inputFile, undefined, { importStrategy: new RunStrategy() });
100
+ if (outputFile === null) {
101
+ console.error("Error: No output file generated.");
102
+ process.exit(1);
103
+ }
104
+ absOutput = path.resolve(outputFile);
87
105
  }
88
106
  // Signal to stdlib UI components that they should fall back to console.log
89
107
  // instead of drawing their own TUI, which would conflict with the debugger.
90
108
  process.env.AGENCY_DEBUGGER = "1";
91
109
  // Dynamically import the compiled module
92
- const absOutput = path.resolve(outputFile);
93
110
  const mod = await import(absOutput);
94
111
  // Get the source map from the module
95
112
  const sourceMap = mod.__sourceMap ?? {};
113
+ if (distDir && Object.keys(sourceMap).length === 0) {
114
+ console.warn("Warning: The compiled module has an empty source map. Was it compiled with instrument: false?\n" +
115
+ "The debugger may not be able to step through code.");
116
+ }
96
117
  // Parse the .agency file to get the list of graph nodes
97
118
  const contents = fs.readFileSync(inputFile, "utf-8");
98
- const parseResult = parseAgency(contents, debugConfig);
119
+ const parseResult = parseAgency(contents, config);
99
120
  if (!parseResult.success) {
100
121
  console.error("Error: Could not parse Agency file.");
101
122
  process.exit(1);
@@ -21,6 +21,11 @@ export type InterruptHandler = {
21
21
  resolvedValue?: any;
22
22
  expectedMessage?: string;
23
23
  };
24
+ /**
25
+ * Resolve the compiled .js file for an .agency file from a distDir.
26
+ * Throws if the compiled file doesn't exist.
27
+ */
28
+ export declare function resolveCompiledFile(distDir: string, agencyFile: string): string;
24
29
  type ExecuteNodeArgs = {
25
30
  config: AgencyConfig;
26
31
  agencyFile: string;
@@ -11,6 +11,7 @@ import { isAgencyImport, resolveAgencyImportPath, getStdlibDir } from "../import
11
11
  import renderEvaluate from "../templates/cli/evaluate.js";
12
12
  import renderJudgeEvaluate from "../templates/cli/judgeEvaluate.js";
13
13
  import { compile } from "./commands.js";
14
+ import { RunStrategy } from "../importStrategy.js";
14
15
  import { parseAgency } from "../parser.js";
15
16
  export function parseTarget(target) {
16
17
  const colonIndex = target.lastIndexOf(":");
@@ -103,13 +104,39 @@ export async function promptForArgs(selectedNode) {
103
104
  }
104
105
  return { hasArgs, argsString };
105
106
  }
107
+ /**
108
+ * Resolve the compiled .js file for an .agency file from a distDir.
109
+ * Throws if the compiled file doesn't exist.
110
+ */
111
+ export function resolveCompiledFile(distDir, agencyFile) {
112
+ const basename = path.basename(agencyFile, ".agency") + ".js";
113
+ const compiledPath = path.resolve(distDir, basename);
114
+ if (!fs.existsSync(compiledPath)) {
115
+ throw new Error(`Compiled file not found: ${compiledPath}\n` +
116
+ `Make sure you have compiled your Agency files and that distDir is correct.`);
117
+ }
118
+ return compiledPath;
119
+ }
106
120
  export async function executeNodeAsync({ config, agencyFile, nodeName, hasArgs, argsString, interruptHandlers, }) {
107
- compile(config, agencyFile);
121
+ const distDir = config.distDir;
122
+ let compiledPath;
123
+ if (distDir) {
124
+ compiledPath = resolveCompiledFile(distDir, agencyFile);
125
+ }
126
+ else {
127
+ compiledPath = compile(config, agencyFile, undefined, { importStrategy: new RunStrategy() });
128
+ }
108
129
  const baseName = agencyFile.replace(".agency", "");
109
130
  const evaluateFile = `${baseName}.evaluate.js`;
110
131
  const resultsFile = `${baseName}.evaluate.json`;
132
+ // The template imports via "./${filename}", so compute a relative path
133
+ // from the evaluate script's directory to the compiled module.
134
+ let importSpecifier = path.relative(path.dirname(evaluateFile), compiledPath).replace(/\\/g, "/");
135
+ if (!importSpecifier.startsWith(".")) {
136
+ importSpecifier = `./${importSpecifier}`;
137
+ }
111
138
  const evaluateScript = renderEvaluate({
112
- filename: path.basename(agencyFile).replace(".agency", ".js"),
139
+ filename: importSpecifier,
113
140
  nodeName,
114
141
  hasArgs,
115
142
  args: argsString,
@@ -137,10 +164,23 @@ export async function executeNodeAsync({ config, agencyFile, nodeName, hasArgs,
137
164
  }
138
165
  }
139
166
  export function executeNode(args) {
140
- const outFile = args.agencyFile.replace(".agency", ".js");
141
- compile(args.config, args.agencyFile);
167
+ const distDir = args.config.distDir;
168
+ let compiledPath;
169
+ if (distDir) {
170
+ compiledPath = resolveCompiledFile(distDir, args.agencyFile);
171
+ }
172
+ else {
173
+ compiledPath = compile(args.config, args.agencyFile, undefined, { importStrategy: new RunStrategy() });
174
+ }
175
+ const evaluateFile = "__evaluate.js";
176
+ // The template imports via "./${filename}", so compute a relative path
177
+ // from the evaluate script's directory to the compiled module.
178
+ let importSpecifier = path.relative(path.dirname(evaluateFile), compiledPath).replace(/\\/g, "/");
179
+ if (!importSpecifier.startsWith(".")) {
180
+ importSpecifier = `./${importSpecifier}`;
181
+ }
142
182
  const evaluateScript = renderEvaluate({
143
- filename: outFile,
183
+ filename: importSpecifier,
144
184
  nodeName: args.nodeName,
145
185
  hasArgs: args.hasArgs,
146
186
  args: args.argsString,
@@ -150,7 +190,6 @@ export function executeNode(args) {
150
190
  : undefined,
151
191
  resultsFilename: "__evaluate.json",
152
192
  });
153
- const evaluateFile = "__evaluate.js";
154
193
  fs.writeFileSync(evaluateFile, evaluateScript);
155
194
  execFileSync("node", [evaluateFile], { stdio: "inherit" });
156
195
  const results = readFileSync("__evaluate.json", "utf-8");
@@ -102,6 +102,10 @@ export interface AgencyConfig {
102
102
  /** Directory for auto-generated trace files. Each execution creates a new file
103
103
  * named <timestamp>_<id>.agencytrace. */
104
104
  traceDir?: string;
105
+ /** Directory containing pre-compiled JS output (e.g., "dist").
106
+ * When set, the debugger imports compiled modules from this directory
107
+ * instead of compiling on the fly. Resolved relative to cwd. */
108
+ distDir?: string;
105
109
  /** Test runner configuration */
106
110
  test?: {
107
111
  /** Number of test files to run in parallel. Default: 1 (sequential). */
@@ -395,7 +395,7 @@ export class DebuggerUI {
395
395
  renderSourcePane() {
396
396
  const moduleId = this.state.getModuleId();
397
397
  const currentLine = this.state.getCurrentLine();
398
- const filePath = moduleId;
398
+ const filePath = this.state.resolveModulePath(moduleId, [".agency"]) ?? moduleId;
399
399
  const fileContent = readSourceFile(filePath);
400
400
  const highlighted = syntaxHighlight(fileContent, "ts");
401
401
  const lines = highlighted.split("\n");
@@ -19,6 +19,12 @@ export declare class UIState {
19
19
  private sourceMapCache;
20
20
  constructor();
21
21
  static fromCheckpoint(checkpoint: Checkpoint | undefined): UIState;
22
+ /**
23
+ * Resolve a moduleId (e.g., "stdlib/index.agency") to an actual file path,
24
+ * trying the given extensions. Handles stdlib modules that live inside
25
+ * node_modules/agency-lang/stdlib/ when running from an external project.
26
+ */
27
+ resolveModulePath(moduleId: string, extensions: string[]): string | null;
22
28
  private agencyToJsFile;
23
29
  setCheckpoint(checkpoint: Checkpoint | undefined): Promise<void>;
24
30
  setWithOverrides(obj: Record<string, unknown>, array: ValWithOverride[]): void;
@@ -1,5 +1,6 @@
1
1
  import { Checkpoint } from "../runtime/state/checkpointStore.js";
2
2
  import { GlobalStore } from "../runtime/state/globalStore.js";
3
+ import { getStdlibDir } from "../importPaths.js";
3
4
  import fs from "fs";
4
5
  import path from "path";
5
6
  export class UIState {
@@ -30,17 +31,34 @@ export class UIState {
30
31
  uiState.setCheckpoint(checkpoint);
31
32
  return uiState;
32
33
  }
33
- agencyToJsFile(agencyFile) {
34
- const tsFile = agencyFile.replace(/\.agency$/, ".ts");
35
- if (fs.existsSync(tsFile)) {
36
- return tsFile;
34
+ /**
35
+ * Resolve a moduleId (e.g., "stdlib/index.agency") to an actual file path,
36
+ * trying the given extensions. Handles stdlib modules that live inside
37
+ * node_modules/agency-lang/stdlib/ when running from an external project.
38
+ */
39
+ resolveModulePath(moduleId, extensions) {
40
+ // Try the path as-is first (works when running from the agency-lang repo)
41
+ for (const ext of extensions) {
42
+ const candidate = moduleId.replace(/\.agency$/, ext);
43
+ if (fs.existsSync(candidate))
44
+ return candidate;
37
45
  }
38
- const jsFile = agencyFile.replace(/\.agency$/, ".js");
39
- if (fs.existsSync(jsFile)) {
40
- return jsFile;
46
+ // If the moduleId refers to a stdlib file, resolve against the actual
47
+ // stdlib directory (handles npm-installed packages where stdlib lives
48
+ // in node_modules/agency-lang/stdlib/)
49
+ if (moduleId.includes("stdlib")) {
50
+ const basename = path.basename(moduleId);
51
+ for (const ext of extensions) {
52
+ const candidate = path.join(getStdlibDir(), basename).replace(/\.agency$/, ext);
53
+ if (fs.existsSync(candidate))
54
+ return candidate;
55
+ }
41
56
  }
42
57
  return null;
43
58
  }
59
+ agencyToJsFile(agencyFile) {
60
+ return this.resolveModulePath(agencyFile, [".js", ".ts"]);
61
+ }
44
62
  async setCheckpoint(checkpoint) {
45
63
  const cp = Checkpoint.fromJSON(checkpoint);
46
64
  if (!cp) {
@@ -1,5 +1,6 @@
1
- import { describe, it, expect } from "vitest";
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
2
  import { findPackageRoot, resolveAgencyImportPath, getStdlibDir, toCompiledImportPath, isPkgImport, isAgencyImport, parsePkgImport, resolvePkgAgencyPath, } from "./importPaths.js";
3
+ import { CompileStrategy, RunStrategy } from "./importStrategy.js";
3
4
  import { buildSymbolTable } from "./symbolTable.js";
4
5
  import * as fs from "fs";
5
6
  import * as os from "os";
@@ -235,3 +236,73 @@ describe("buildSymbolTable with pkg:: imports", () => {
235
236
  }
236
237
  });
237
238
  });
239
+ describe("CompileStrategy", () => {
240
+ const jsStrategy = new CompileStrategy({ targetExt: ".js" });
241
+ const tsStrategy = new CompileStrategy({ targetExt: ".ts" });
242
+ it("should rewrite .agency to .js", () => {
243
+ expect(jsStrategy.rewriteImport("./foo.agency", "/src/main.agency")).toBe("./foo.js");
244
+ });
245
+ it("should rewrite .agency to .ts with --ts", () => {
246
+ expect(tsStrategy.rewriteImport("./foo.agency", "/src/main.agency")).toBe("./foo.ts");
247
+ });
248
+ it("should leave .js imports untouched", () => {
249
+ expect(jsStrategy.rewriteImport("./tools.js", "/src/main.agency")).toBe("./tools.js");
250
+ });
251
+ it("should leave .ts imports untouched", () => {
252
+ expect(jsStrategy.rewriteImport("./tools.ts", "/src/main.agency")).toBe("./tools.ts");
253
+ });
254
+ it("should leave bare specifiers untouched", () => {
255
+ expect(jsStrategy.rewriteImport("nanoid", "/src/main.agency")).toBe("nanoid");
256
+ });
257
+ });
258
+ describe("RunStrategy", () => {
259
+ const strategy = new RunStrategy();
260
+ it("should rewrite .agency to .js", () => {
261
+ expect(strategy.rewriteImport("./foo.agency", "/src/main.agency")).toBe("./foo.js");
262
+ });
263
+ it("should rewrite .ts to .js", () => {
264
+ expect(strategy.rewriteImport("./tools.ts", "/src/main.agency")).toBe("./tools.js");
265
+ });
266
+ it("should leave .js imports as-is", () => {
267
+ expect(strategy.rewriteImport("./tools.js", "/src/main.agency")).toBe("./tools.js");
268
+ });
269
+ it("should leave bare specifiers untouched", () => {
270
+ expect(strategy.rewriteImport("nanoid", "/src/main.agency")).toBe("nanoid");
271
+ });
272
+ });
273
+ describe("RunStrategy.prepareDependencies", () => {
274
+ let tmpDir;
275
+ const strategy = new RunStrategy();
276
+ beforeEach(() => {
277
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "agency-run-strategy-"));
278
+ });
279
+ afterEach(() => {
280
+ fs.rmSync(tmpDir, { recursive: true, force: true });
281
+ });
282
+ it("should compile .ts to .js when .js doesn't exist", () => {
283
+ const tsFile = path.join(tmpDir, "bar.ts");
284
+ const jsFile = path.join(tmpDir, "bar.js");
285
+ fs.writeFileSync(tsFile, "export const x: number = 1;");
286
+ const fromFile = path.join(tmpDir, "main.agency");
287
+ strategy.prepareDependencies(["./bar.js"], fromFile);
288
+ expect(fs.existsSync(jsFile)).toBe(true);
289
+ const content = fs.readFileSync(jsFile, "utf-8");
290
+ expect(content).toContain("const x = 1");
291
+ });
292
+ it("should not overwrite existing .js files", () => {
293
+ const jsFile = path.join(tmpDir, "bar.js");
294
+ fs.writeFileSync(jsFile, "// original");
295
+ const fromFile = path.join(tmpDir, "main.agency");
296
+ strategy.prepareDependencies(["./bar.js"], fromFile);
297
+ expect(fs.readFileSync(jsFile, "utf-8")).toBe("// original");
298
+ });
299
+ it("should throw when neither .js nor .ts exists", () => {
300
+ const fromFile = path.join(tmpDir, "main.agency");
301
+ expect(() => strategy.prepareDependencies(["./bar.js"], fromFile)).toThrow(/Cannot resolve import/);
302
+ });
303
+ it("should skip bare specifiers", () => {
304
+ const fromFile = path.join(tmpDir, "main.agency");
305
+ // Should not throw — bare specifiers are skipped
306
+ strategy.prepareDependencies(["nanoid"], fromFile);
307
+ });
308
+ });
@@ -0,0 +1,37 @@
1
+ export type CompileOptions = {
2
+ /** Extension for .agency rewrites: ".js" or ".ts" */
3
+ targetExt: ".js" | ".ts";
4
+ };
5
+ export interface ImportStrategy {
6
+ /**
7
+ * Rewrite an import path for the output.
8
+ * Handles .agency, .js, and .ts imports.
9
+ */
10
+ rewriteImport(modulePath: string, sourceFile: string): string;
11
+ /**
12
+ * Ensure all non-Agency dependencies are available for execution.
13
+ * Called after compilation, before the output is executed.
14
+ * Errors if a dependency can't be resolved.
15
+ */
16
+ prepareDependencies(imports: string[], sourceFile: string): void;
17
+ }
18
+ /**
19
+ * Strategy for `agency compile`: produces output for a downstream build pipeline.
20
+ * Leaves .js/.ts imports untouched. Only rewrites .agency imports.
21
+ */
22
+ export declare class CompileStrategy implements ImportStrategy {
23
+ protected options: CompileOptions;
24
+ constructor(options: CompileOptions);
25
+ rewriteImport(modulePath: string, _sourceFile: string): string;
26
+ prepareDependencies(_imports: string[], _sourceFile: string): void;
27
+ }
28
+ /**
29
+ * Strategy for `agency run` / `agency debug` / `agency test`: compiles and
30
+ * immediately executes. All imports must resolve to .js files that exist on disk.
31
+ * Compiles .ts dependencies to .js via esbuild when needed.
32
+ */
33
+ export declare class RunStrategy extends CompileStrategy {
34
+ constructor();
35
+ rewriteImport(modulePath: string, sourceFile: string): string;
36
+ prepareDependencies(imports: string[], sourceFile: string): void;
37
+ }
@@ -0,0 +1,64 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { transformSync } from "esbuild";
4
+ /**
5
+ * Strategy for `agency compile`: produces output for a downstream build pipeline.
6
+ * Leaves .js/.ts imports untouched. Only rewrites .agency imports.
7
+ */
8
+ export class CompileStrategy {
9
+ options;
10
+ constructor(options) {
11
+ this.options = options;
12
+ }
13
+ rewriteImport(modulePath, _sourceFile) {
14
+ if (modulePath.endsWith(".agency")) {
15
+ return modulePath.replace(/\.agency$/, this.options.targetExt);
16
+ }
17
+ return modulePath;
18
+ }
19
+ prepareDependencies(_imports, _sourceFile) {
20
+ // No-op — user's build pipeline handles dependencies
21
+ }
22
+ }
23
+ /**
24
+ * Strategy for `agency run` / `agency debug` / `agency test`: compiles and
25
+ * immediately executes. All imports must resolve to .js files that exist on disk.
26
+ * Compiles .ts dependencies to .js via esbuild when needed.
27
+ */
28
+ export class RunStrategy extends CompileStrategy {
29
+ constructor() {
30
+ super({ targetExt: ".js" });
31
+ }
32
+ rewriteImport(modulePath, sourceFile) {
33
+ if (modulePath.endsWith(".agency")) {
34
+ return super.rewriteImport(modulePath, sourceFile);
35
+ }
36
+ // Always produce .js — Node needs .js at runtime
37
+ return modulePath.replace(/\.ts$/, ".js");
38
+ }
39
+ prepareDependencies(imports, sourceFile) {
40
+ for (const imp of imports) {
41
+ if (!imp.startsWith("./") && !imp.startsWith("../"))
42
+ continue;
43
+ if (!imp.endsWith(".js"))
44
+ continue;
45
+ const resolved = path.resolve(path.dirname(sourceFile), imp);
46
+ if (fs.existsSync(resolved))
47
+ continue;
48
+ const tsPath = resolved.replace(/\.js$/, ".ts");
49
+ if (fs.existsSync(tsPath)) {
50
+ const tsCode = fs.readFileSync(tsPath, "utf-8");
51
+ const result = transformSync(tsCode, {
52
+ loader: "ts",
53
+ format: "esm",
54
+ supported: { "top-level-await": true },
55
+ });
56
+ fs.writeFileSync(resolved, result.code);
57
+ }
58
+ else {
59
+ throw new Error(`Cannot resolve import '${imp}' from '${sourceFile}'.\n` +
60
+ `Tried: ${resolved}, ${tsPath} — neither file exists.`);
61
+ }
62
+ }
63
+ }
64
+ }
@@ -1 +1 @@
1
- export declare const VERSION = "0.0.96";
1
+ export declare const VERSION = "0.0.99";
@@ -1 +1 @@
1
- export const VERSION = "0.0.96";
1
+ export const VERSION = "0.0.99";
@@ -339,6 +339,7 @@ program
339
339
  .option("--rewind-size <n>", "Rolling checkpoint window size", "30")
340
340
  .option("--trace <file>", "Load and inspect a trace file")
341
341
  .option("--checkpoint <file>", "Load and inspect a checkpoint file")
342
+ .option("--dist-dir <dir>", "Import pre-compiled JS from this directory instead of compiling on the fly")
342
343
  .action(async (file, options) => {
343
344
  const config = getConfig();
344
345
  await debug(config, file, {
@@ -346,6 +347,7 @@ program
346
347
  rewindSize: parseInt(options.rewindSize, 10),
347
348
  trace: options.trace,
348
349
  checkpoint: options.checkpoint,
350
+ distDir: options.distDir,
349
351
  });
350
352
  });
351
353
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.97",
3
+ "version": "0.0.99",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {