agentlang 0.7.0 → 0.7.2

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.
Files changed (63) hide show
  1. package/out/api/http.d.ts.map +1 -1
  2. package/out/api/http.js +46 -26
  3. package/out/api/http.js.map +1 -1
  4. package/out/cli/main.d.ts +1 -0
  5. package/out/cli/main.d.ts.map +1 -1
  6. package/out/cli/main.js +15 -2
  7. package/out/cli/main.js.map +1 -1
  8. package/out/language/generated/ast.d.ts +15 -6
  9. package/out/language/generated/ast.d.ts.map +1 -1
  10. package/out/language/generated/ast.js +16 -2
  11. package/out/language/generated/ast.js.map +1 -1
  12. package/out/language/generated/grammar.d.ts.map +1 -1
  13. package/out/language/generated/grammar.js +215 -164
  14. package/out/language/generated/grammar.js.map +1 -1
  15. package/out/language/main.cjs +227 -166
  16. package/out/language/main.cjs.map +2 -2
  17. package/out/runtime/defs.d.ts +16 -1
  18. package/out/runtime/defs.d.ts.map +1 -1
  19. package/out/runtime/defs.js +29 -1
  20. package/out/runtime/defs.js.map +1 -1
  21. package/out/runtime/exec-graph.d.ts.map +1 -1
  22. package/out/runtime/exec-graph.js +8 -0
  23. package/out/runtime/exec-graph.js.map +1 -1
  24. package/out/runtime/interpreter.d.ts +2 -1
  25. package/out/runtime/interpreter.d.ts.map +1 -1
  26. package/out/runtime/interpreter.js +10 -0
  27. package/out/runtime/interpreter.js.map +1 -1
  28. package/out/runtime/jsmodules.d.ts +8 -0
  29. package/out/runtime/jsmodules.d.ts.map +1 -1
  30. package/out/runtime/jsmodules.js +139 -22
  31. package/out/runtime/jsmodules.js.map +1 -1
  32. package/out/runtime/loader.d.ts +1 -0
  33. package/out/runtime/loader.d.ts.map +1 -1
  34. package/out/runtime/loader.js +9 -2
  35. package/out/runtime/loader.js.map +1 -1
  36. package/out/runtime/module-transform.d.ts +77 -0
  37. package/out/runtime/module-transform.d.ts.map +1 -0
  38. package/out/runtime/module-transform.js +201 -0
  39. package/out/runtime/module-transform.js.map +1 -0
  40. package/out/runtime/modules/ai.d.ts.map +1 -1
  41. package/out/runtime/modules/ai.js +18 -6
  42. package/out/runtime/modules/ai.js.map +1 -1
  43. package/out/runtime/modules/core.d.ts +5 -0
  44. package/out/runtime/modules/core.d.ts.map +1 -1
  45. package/out/runtime/modules/core.js +58 -6
  46. package/out/runtime/modules/core.js.map +1 -1
  47. package/out/syntaxes/agentlang.monarch.js +1 -1
  48. package/out/syntaxes/agentlang.monarch.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/api/http.ts +51 -25
  51. package/src/cli/main.ts +20 -0
  52. package/src/language/agentlang.langium +3 -1
  53. package/src/language/generated/ast.ts +32 -8
  54. package/src/language/generated/grammar.ts +215 -164
  55. package/src/runtime/defs.ts +47 -0
  56. package/src/runtime/exec-graph.ts +13 -0
  57. package/src/runtime/interpreter.ts +12 -0
  58. package/src/runtime/jsmodules.ts +189 -22
  59. package/src/runtime/loader.ts +10 -2
  60. package/src/runtime/module-transform.ts +277 -0
  61. package/src/runtime/modules/ai.ts +20 -6
  62. package/src/runtime/modules/core.ts +80 -5
  63. package/src/syntaxes/agentlang.monarch.ts +1 -1
@@ -94,6 +94,26 @@ export function setSubscriptionFn(f: Function) {
94
94
  SetSubscription = f;
95
95
  }
96
96
 
97
+ // Module loader configuration for browser-compatible resolver loading
98
+ export type FileReader = (filePath: string) => Promise<string>;
99
+ export type DependencyProvider = (moduleName: string) => any | undefined;
100
+
101
+ export interface ModuleLoaderConfig {
102
+ fileReader: FileReader;
103
+ dependencyProvider?: DependencyProvider;
104
+ basePath?: string;
105
+ }
106
+
107
+ let _moduleLoader: ModuleLoaderConfig | undefined = undefined;
108
+
109
+ export function setModuleLoader(config: ModuleLoaderConfig) {
110
+ _moduleLoader = config;
111
+ }
112
+
113
+ export function getModuleLoader(): ModuleLoaderConfig | undefined {
114
+ return _moduleLoader;
115
+ }
116
+
97
117
  export const ForceReadPermFlag = 'f-r-f';
98
118
  export const FlowSuspensionTag = `--`;
99
119
 
@@ -105,6 +125,7 @@ export enum SubGraphType {
105
125
  PURGE,
106
126
  RETURN,
107
127
  AGENT,
128
+ THROW,
108
129
  NONE,
109
130
  }
110
131
 
@@ -386,3 +407,29 @@ export function isRuntimeMode_generate_migration(): boolean {
386
407
  export function isRuntimeMode_undo_migration(): boolean {
387
408
  return RuntimeMode === RuntimeModeTag.UNDO_MIGRATION;
388
409
  }
410
+
411
+ let UpdateEventEndpoints: Function | undefined;
412
+ let UpdateEntityEndpoints: Function | undefined;
413
+
414
+ export function setEventEndpointsUpdater(f: Function) {
415
+ UpdateEventEndpoints = f;
416
+ }
417
+
418
+ export function setEntityEndpointsUpdater(f: Function) {
419
+ UpdateEntityEndpoints = f;
420
+ }
421
+
422
+ export function updateEndpoints(moduleName: string) {
423
+ if (UpdateEventEndpoints !== undefined) {
424
+ UpdateEventEndpoints(moduleName);
425
+ }
426
+ if (UpdateEntityEndpoints !== undefined) {
427
+ UpdateEntityEndpoints(moduleName);
428
+ }
429
+ }
430
+
431
+ export let InternDynamicModule: Function | undefined;
432
+
433
+ export function setInternDynamicModuleFn(f: Function) {
434
+ InternDynamicModule = f;
435
+ }
@@ -13,6 +13,7 @@ import {
13
13
  Purge,
14
14
  Return,
15
15
  Statement,
16
+ ThrowError,
16
17
  } from '../language/generated/ast.js';
17
18
  import { parseModule, parseStatement } from '../language/parser.js';
18
19
  import { ExecGraph, ExecGraphNode, ExecGraphWalker, SubGraphType } from './defs.js';
@@ -157,6 +158,15 @@ class GraphGenerator extends PatternHandler {
157
158
  this.handleSubPattern(SubGraphType.RETURN, ret.pattern, env);
158
159
  }
159
160
 
161
+ override async handleThrow(throwErr: ThrowError, env: Environment) {
162
+ const handler = new GraphGenerator();
163
+ await handler.handleExpression(
164
+ throwErr.reason,
165
+ Environment.from(env).setActiveUserData(throwErr.reason)
166
+ );
167
+ this.addSubGraph(SubGraphType.THROW, handler.getGraph(), env);
168
+ }
169
+
160
170
  getGraph(): ExecGraph {
161
171
  return this.graph;
162
172
  }
@@ -261,6 +271,9 @@ export async function executeGraph(execGraph: ExecGraph, env: Environment): Prom
261
271
  case SubGraphType.RETURN:
262
272
  await executeReturnSubGraph(subg, env);
263
273
  return;
274
+ case SubGraphType.THROW:
275
+ await evaluateExpression(subg.getRootNodes()[0].code as Expr, env);
276
+ throw new Error(env.getLastResult());
264
277
  default:
265
278
  throw new Error(`Invalid sub-graph type: ${node.subGraphType}`);
266
279
  }
@@ -27,6 +27,7 @@ import {
27
27
  SelectIntoSpec,
28
28
  SetAttribute,
29
29
  Statement,
30
+ ThrowError,
30
31
  } from '../language/generated/ast.js';
31
32
  import {
32
33
  maybeInstanceAsString,
@@ -1217,6 +1218,10 @@ export class PatternHandler {
1217
1218
  async handleReturn(ret: Return, env: Environment) {
1218
1219
  await evaluatePattern(ret.pattern, env);
1219
1220
  }
1221
+
1222
+ async handleThrow(throwErr: ThrowError, env: Environment) {
1223
+ await evaluateThrowError(throwErr, env);
1224
+ }
1220
1225
  }
1221
1226
 
1222
1227
  const DefaultPatternHandler = new PatternHandler();
@@ -1243,9 +1248,16 @@ export async function evaluatePattern(
1243
1248
  } else if (pat.return) {
1244
1249
  await handler.handleReturn(pat.return, env);
1245
1250
  env.markForReturn();
1251
+ } else if (pat.throwError) {
1252
+ await handler.handleThrow(pat.throwError, env);
1246
1253
  }
1247
1254
  }
1248
1255
 
1256
+ async function evaluateThrowError(throwErr: ThrowError, env: Environment) {
1257
+ await evaluateExpression(throwErr.reason, env);
1258
+ throw new Error(env.getLastResult());
1259
+ }
1260
+
1249
1261
  async function evaluateFullTextSearch(fts: FullTextSearch, env: Environment): Promise<void> {
1250
1262
  let n = escapeQueryName(fts.name);
1251
1263
  if (!isFqName(n)) {
@@ -1,7 +1,14 @@
1
1
  import { logger } from './logger.js';
2
2
  import { now, splitRefs } from './util.js';
3
3
  import { isNodeEnv } from '../utils/runtime.js';
4
- import { setModuleFnFetcher } from './defs.js';
4
+ import { setModuleFnFetcher, getModuleLoader } from './defs.js';
5
+ import {
6
+ transformModule,
7
+ wrapModuleCode,
8
+ evaluateModule,
9
+ wrapCommonJSCode,
10
+ evaluateCommonJS,
11
+ } from './module-transform.js';
5
12
 
6
13
  let dirname: any = undefined;
7
14
  let sep: any = undefined;
@@ -24,39 +31,199 @@ if (isNodeEnv) {
24
31
 
25
32
  const importedModules = new Map<string, any>();
26
33
 
27
- // Usage: importModule("./mymodels/acme.js")
28
- export async function importModule(path: string, name: string, moduleFileName?: string) {
29
- if (isNodeEnv) {
30
- if (importedModules.has(name)) {
31
- logger.warn(`Alias '${name}' will overwrite a previously imported module`);
34
+ /**
35
+ * Load dependencies for a module using the configured dependency provider
36
+ */
37
+ async function loadModuleDependencies(
38
+ imports: Array<{ defaultImport?: string; namedImports?: string[]; moduleSpecifier: string }>
39
+ ): Promise<Map<string, any>> {
40
+ const loadedDeps = new Map<string, any>();
41
+
42
+ for (const imp of imports) {
43
+ const moduleSpecifier = imp.moduleSpecifier;
44
+
45
+ logger.debug(`Loading dependency: ${moduleSpecifier}`);
46
+
47
+ // Try to get from dependency provider first
48
+ let module: any;
49
+ const moduleLoader = getModuleLoader();
50
+ if (moduleLoader?.dependencyProvider) {
51
+ module = moduleLoader.dependencyProvider(moduleSpecifier);
32
52
  }
33
- if (moduleFileName) {
34
- let s: string = dirname(moduleFileName);
35
- if (s.startsWith('./')) {
36
- s = s.substring(2);
37
- } else if (s == '.') {
38
- s = process.cwd();
53
+
54
+ if (!module) {
55
+ // In browser without dependency provider, we can't load external modules
56
+ if (!isNodeEnv) {
57
+ throw new Error(
58
+ `Failed to load dependency "${moduleSpecifier}". ` +
59
+ `Please add it to the dependency provider via setModuleLoader().`
60
+ );
61
+ }
62
+
63
+ // In Node.js, try dynamic import
64
+ try {
65
+ module = await import(/* @vite-ignore */ moduleSpecifier);
66
+ logger.debug(`Loaded ${moduleSpecifier} via dynamic import`);
67
+ } catch (error) {
68
+ throw new Error(`Failed to load dependency "${moduleSpecifier}": ${error}`);
39
69
  }
40
- path = `${s}${sep}${path}`;
70
+ } else {
71
+ logger.debug(`Using pre-imported dependency: ${moduleSpecifier}`);
41
72
  }
42
- if (!(path.startsWith(sep) || path.startsWith('.'))) {
43
- path = process.cwd() + sep + path;
73
+
74
+ // Handle default import
75
+ if (imp.defaultImport) {
76
+ loadedDeps.set(imp.defaultImport, module.default || module);
44
77
  }
45
- const m = await import(/* @vite-ignore */ path);
46
- importedModules.set(name, m);
47
- // e.g of dynamic fn-call:
48
- //// let f = eval("(a, b) => m.add(a, b)");
49
- //// console.log(f(10, 20))
50
- return m;
51
- } else {
78
+
79
+ // Handle named imports
80
+ if (imp.namedImports) {
81
+ for (const name of imp.namedImports) {
82
+ loadedDeps.set(name, module[name]);
83
+ }
84
+ }
85
+ }
86
+
87
+ return loadedDeps;
88
+ }
89
+
90
+ /**
91
+ * Load a JavaScript module in the browser environment
92
+ */
93
+ async function loadModuleInBrowser(
94
+ path: string,
95
+ name: string,
96
+ moduleFileName?: string
97
+ ): Promise<any> {
98
+ const moduleLoader = getModuleLoader();
99
+ if (!moduleLoader) {
100
+ throw new Error(
101
+ 'ModuleLoader not configured. Call setModuleLoader() with a fileReader and dependencyProvider.'
102
+ );
103
+ }
104
+
105
+ logger.info(`Loading module in browser: ${path} as ${name}`);
106
+
107
+ // Resolve path relative to the module file
108
+ let resolvedPath = path;
109
+ if (moduleFileName) {
110
+ const dir = dirname(moduleFileName);
111
+ resolvedPath = dir ? `${dir}${sep}${path}` : path;
112
+ }
113
+
114
+ // Add basePath if configured
115
+ if (moduleLoader.basePath) {
116
+ if (!resolvedPath.startsWith('/')) {
117
+ resolvedPath = `${moduleLoader.basePath}${sep}${resolvedPath}`;
118
+ }
119
+ }
120
+
121
+ logger.debug(`Resolved path: ${resolvedPath}`);
122
+
123
+ // Read the module content
124
+ const content = await moduleLoader.fileReader(resolvedPath);
125
+
126
+ if (!content || content.trim().length === 0) {
127
+ logger.warn(`Module file ${resolvedPath} is empty`);
52
128
  return {};
53
129
  }
130
+
131
+ logger.debug(`Read ${content.length} characters from ${resolvedPath}`);
132
+
133
+ // Check if the file uses ES6 import syntax
134
+ const hasImports = /\bimport\s+/.test(content);
135
+
136
+ let moduleExports: any;
137
+
138
+ if (hasImports) {
139
+ logger.debug(`Processing ES6 imports for: ${name}`);
140
+
141
+ // Transform the module
142
+ const { transformedCode, imports } = transformModule(content);
143
+
144
+ // Load all import dependencies
145
+ const loadedDeps = await loadModuleDependencies(imports);
146
+
147
+ logger.debug(`Loaded ${loadedDeps.size} dependencies, executing transformed code...`);
148
+
149
+ // Create wrapped code with injected dependencies
150
+ const wrappedCode = wrapModuleCode(transformedCode, loadedDeps);
151
+
152
+ // Evaluate and get exports
153
+ moduleExports = evaluateModule(wrappedCode, loadedDeps);
154
+
155
+ logger.debug(`Module exports:`, Object.keys(moduleExports));
156
+ } else {
157
+ logger.debug(`Loading as CommonJS module: ${name}`);
158
+
159
+ // Wrap and evaluate as CommonJS
160
+ const wrappedCode = wrapCommonJSCode(content);
161
+ moduleExports = evaluateCommonJS(wrappedCode);
162
+ }
163
+
164
+ return moduleExports;
165
+ }
166
+
167
+ /**
168
+ * Load a JavaScript module in Node.js environment
169
+ */
170
+ async function loadModuleInNode(path: string, name: string, moduleFileName?: string): Promise<any> {
171
+ if (moduleFileName) {
172
+ let s: string = dirname(moduleFileName);
173
+ if (s.startsWith('./')) {
174
+ s = s.substring(2);
175
+ } else if (s == '.') {
176
+ s = process.cwd();
177
+ }
178
+ path = `${s}${sep}${path}`;
179
+ }
180
+ if (!(path.startsWith(sep) || path.startsWith('.'))) {
181
+ path = process.cwd() + sep + path;
182
+ }
183
+
184
+ const m = await import(/* @vite-ignore */ path);
185
+ return m;
186
+ }
187
+
188
+ // Usage: importModule("./mymodels/acme.js")
189
+ export async function importModule(path: string, name: string, moduleFileName?: string) {
190
+ if (importedModules.has(name)) {
191
+ logger.warn(`Alias '${name}' will overwrite a previously imported module`);
192
+ }
193
+
194
+ let moduleExports: any;
195
+
196
+ if (isNodeEnv) {
197
+ moduleExports = await loadModuleInNode(path, name, moduleFileName);
198
+ } else {
199
+ moduleExports = await loadModuleInBrowser(path, name, moduleFileName);
200
+ }
201
+
202
+ importedModules.set(name, moduleExports);
203
+
204
+ logger.info(`Successfully imported module: ${name}`, Object.keys(moduleExports));
205
+
206
+ return moduleExports;
54
207
  }
55
208
 
56
209
  export function moduleImported(moduleName: string): boolean {
57
210
  return importedModules.has(moduleName);
58
211
  }
59
212
 
213
+ /**
214
+ * Get an imported module by its alias name
215
+ */
216
+ export function getImportedModule(moduleName: string): any | undefined {
217
+ return importedModules.get(moduleName);
218
+ }
219
+
220
+ /**
221
+ * Get all imported module names
222
+ */
223
+ export function getImportedModuleNames(): string[] {
224
+ return Array.from(importedModules.keys());
225
+ }
226
+
60
227
  function maybeEvalFunction(fnName: string): Function | undefined {
61
228
  try {
62
229
  return eval(fnName);
@@ -1137,15 +1137,23 @@ export async function parseAndIntern(code: string, moduleName?: string) {
1137
1137
  await internModule(r.parseResult.value);
1138
1138
  }
1139
1139
 
1140
+ export async function refreshModuleDefinition(moduleName: string, moduleDefinition: string) {
1141
+ removeModule(moduleName);
1142
+ const r = await parse(moduleDefinition);
1143
+ maybeRaiseParserErrors(r);
1144
+ await internModule(r.parseResult.value);
1145
+ }
1146
+
1140
1147
  export async function internModule(
1141
1148
  module: ModuleDefinition,
1142
1149
  moduleFileName?: string
1143
1150
  ): Promise<Module> {
1144
1151
  const mn = module.name;
1145
1152
  const r = addModule(mn);
1146
- module.imports.forEach(async (imp: Import) => {
1153
+ // Process imports sequentially to ensure all JS modules are loaded before definitions
1154
+ for (const imp of module.imports as Import[]) {
1147
1155
  await importModule(imp.path, imp.name, moduleFileName);
1148
- });
1156
+ }
1149
1157
  for (let i = 0; i < module.defs.length; ++i) {
1150
1158
  const def = module.defs[i];
1151
1159
  await addFromDef(def, mn);
@@ -0,0 +1,277 @@
1
+ /**
2
+ * ES6 Module Transformation Utilities
3
+ *
4
+ * Transforms ES6 import/export syntax into code that can be evaluated
5
+ * in a browser environment without native ES6 module support.
6
+ */
7
+
8
+ import { logger } from './logger.js';
9
+
10
+ export interface ImportInfo {
11
+ defaultImport?: string;
12
+ namedImports?: string[];
13
+ moduleSpecifier: string;
14
+ fullStatement: string;
15
+ }
16
+
17
+ export interface DynamicImportInfo {
18
+ fullMatch: string;
19
+ templateString: string;
20
+ }
21
+
22
+ export interface TransformResult {
23
+ transformedCode: string;
24
+ imports: ImportInfo[];
25
+ dynamicImports: DynamicImportInfo[];
26
+ exports: string[];
27
+ }
28
+
29
+ /**
30
+ * Parse ES6 import statements from code
31
+ * Matches: import ... from 'url'
32
+ */
33
+ export function parseImports(content: string): ImportInfo[] {
34
+ const imports: ImportInfo[] = [];
35
+
36
+ // Match: import ... from 'url'
37
+ const importRegex = /import\s+(?:(\w+)|{([^}]+)})\s+from\s+['"]([^'"]+)['"]/g;
38
+ let match;
39
+
40
+ while ((match = importRegex.exec(content)) !== null) {
41
+ const [fullStatement, defaultImport, namedImports, moduleSpecifier] = match;
42
+
43
+ imports.push({
44
+ defaultImport,
45
+ namedImports: namedImports ? namedImports.split(',').map(n => n.trim()) : undefined,
46
+ moduleSpecifier,
47
+ fullStatement,
48
+ });
49
+ }
50
+
51
+ return imports;
52
+ }
53
+
54
+ /**
55
+ * Parse dynamic import statements
56
+ * Matches: await import(`${process.cwd()}/...`)
57
+ */
58
+ export function parseDynamicImports(content: string): DynamicImportInfo[] {
59
+ const dynamicImports: DynamicImportInfo[] = [];
60
+
61
+ const dynamicImportRegex = /await\s+import\s*\(\s*`([^`]+)`\s*\)/g;
62
+ let match;
63
+
64
+ while ((match = dynamicImportRegex.exec(content)) !== null) {
65
+ const [fullMatch, templateString] = match;
66
+ dynamicImports.push({
67
+ fullMatch,
68
+ templateString,
69
+ });
70
+ }
71
+
72
+ return dynamicImports;
73
+ }
74
+
75
+ /**
76
+ * Parse export statements and extract exported names
77
+ */
78
+ export function parseExports(content: string): string[] {
79
+ const exportedNames: string[] = [];
80
+
81
+ // Handle: export function name() {}
82
+ const exportFnRegex = /export\s+(async\s+)?function\s+(\w+)/g;
83
+ let match;
84
+
85
+ while ((match = exportFnRegex.exec(content)) !== null) {
86
+ exportedNames.push(match[2]);
87
+ }
88
+
89
+ // Handle: export const name = ...
90
+ const exportConstRegex = /export\s+(const|let|var)\s+(\w+)/g;
91
+
92
+ while ((match = exportConstRegex.exec(content)) !== null) {
93
+ exportedNames.push(match[2]);
94
+ }
95
+
96
+ // Handle: export { name1, name2 }
97
+ const exportListRegex = /export\s*{\s*([^}]+)\s*}/g;
98
+
99
+ while ((match = exportListRegex.exec(content)) !== null) {
100
+ const names = match[1].split(',').map(n => n.trim().split(' as ')[0].trim());
101
+ exportedNames.push(...names);
102
+ }
103
+
104
+ return exportedNames;
105
+ }
106
+
107
+ /**
108
+ * Remove import statements from code
109
+ */
110
+ export function removeImportStatements(content: string, imports: ImportInfo[]): string {
111
+ let result = content;
112
+
113
+ for (const imp of imports) {
114
+ result = result.replace(imp.fullStatement, '');
115
+ }
116
+
117
+ return result;
118
+ }
119
+
120
+ /**
121
+ * Remove export keywords from code
122
+ */
123
+ export function removeExportKeywords(content: string): string {
124
+ let result = content;
125
+
126
+ // Remove: export function name() {}
127
+ result = result.replace(
128
+ /export\s+(async\s+)?function\s+(\w+)/g,
129
+ (match, async, name) => `${async || ''}function ${name}`
130
+ );
131
+
132
+ // Remove: export const name = ...
133
+ result = result.replace(
134
+ /export\s+(const|let|var)\s+(\w+)/g,
135
+ (match, keyword, name) => `${keyword} ${name}`
136
+ );
137
+
138
+ // Remove: export { name1, name2 }
139
+ result = result.replace(/export\s*{\s*[^}]+\s*}/g, '');
140
+
141
+ return result;
142
+ }
143
+
144
+ /**
145
+ * Replace dynamic imports with variable references
146
+ */
147
+ export function replaceDynamicImports(
148
+ content: string,
149
+ dynamicImports: DynamicImportInfo[]
150
+ ): { code: string; varNames: Map<string, string> } {
151
+ let result = content;
152
+ const varNames = new Map<string, string>();
153
+
154
+ for (const dynImp of dynamicImports) {
155
+ // Clean up process.cwd() references
156
+ const cleanedPath = dynImp.templateString.replace(/\$\{process\.cwd\(\)\}/g, '');
157
+
158
+ // Create a variable name from the path
159
+ const varName = cleanedPath.split('/').pop()?.replace(/\.js$/, '') || 'dynamicModule';
160
+
161
+ varNames.set(cleanedPath, varName);
162
+ result = result.replace(dynImp.fullMatch, varName);
163
+ }
164
+
165
+ return { code: result, varNames };
166
+ }
167
+
168
+ /**
169
+ * Generate export assignments
170
+ */
171
+ export function generateExportAssignments(exportedNames: string[]): string {
172
+ if (exportedNames.length === 0) {
173
+ return '';
174
+ }
175
+
176
+ const assignments = exportedNames.map(name => `exports.${name} = ${name};`).join('\n');
177
+
178
+ return `\n\n// Export assignments\n${assignments}`;
179
+ }
180
+
181
+ /**
182
+ * Transform ES6 module code to CommonJS-style code
183
+ */
184
+ export function transformModule(content: string): TransformResult {
185
+ logger.debug('Transforming ES6 module code');
186
+
187
+ // Parse imports, exports, and dynamic imports
188
+ const imports = parseImports(content);
189
+ const dynamicImports = parseDynamicImports(content);
190
+ const exports = parseExports(content);
191
+
192
+ // Remove import statements
193
+ let transformedCode = removeImportStatements(content, imports);
194
+
195
+ // Handle dynamic imports
196
+ const { code: codeWithoutDynImports } = replaceDynamicImports(transformedCode, dynamicImports);
197
+ transformedCode = codeWithoutDynImports;
198
+
199
+ // Remove export keywords
200
+ transformedCode = removeExportKeywords(transformedCode);
201
+
202
+ // Add export assignments
203
+ transformedCode += generateExportAssignments(exports);
204
+
205
+ logger.debug(
206
+ `Found ${imports.length} imports, ${dynamicImports.length} dynamic imports, ${exports.length} exports`
207
+ );
208
+
209
+ return {
210
+ transformedCode,
211
+ imports,
212
+ dynamicImports,
213
+ exports,
214
+ };
215
+ }
216
+
217
+ /**
218
+ * Create a wrapped function that evaluates the transformed code
219
+ * with injected dependencies
220
+ */
221
+ export function wrapModuleCode(transformedCode: string, importedModules: Map<string, any>): string {
222
+ const importNames = Array.from(importedModules.keys());
223
+
224
+ const wrappedCode = `
225
+ (function(exports, ${importNames.join(', ')}) {
226
+ ${transformedCode}
227
+ return exports;
228
+ })
229
+ `;
230
+
231
+ return wrappedCode;
232
+ }
233
+
234
+ /**
235
+ * Evaluate wrapped module code and return the exports
236
+ */
237
+ export function evaluateModule(wrappedCode: string, importedModules: Map<string, any>): any {
238
+ const exportObj: any = {};
239
+ const importValues = Array.from(importedModules.values());
240
+
241
+ try {
242
+ const moduleFactory = eval(wrappedCode);
243
+ return moduleFactory(exportObj, ...importValues);
244
+ } catch (error) {
245
+ logger.error('Failed to evaluate module:', error);
246
+ throw error;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Create CommonJS-style wrapper for code without ES6 imports
252
+ */
253
+ export function wrapCommonJSCode(content: string): string {
254
+ return `
255
+ (function(module, exports) {
256
+ ${content}
257
+ return module.exports || exports;
258
+ })
259
+ `;
260
+ }
261
+
262
+ /**
263
+ * Evaluate CommonJS-style code
264
+ */
265
+ export function evaluateCommonJS(wrappedCode: string): any {
266
+ const moduleObj: any = { exports: {} };
267
+ const exportsObj: any = {};
268
+
269
+ try {
270
+ const moduleFactory = eval(wrappedCode);
271
+ const result = moduleFactory(moduleObj, exportsObj);
272
+ return result || moduleObj.exports || exportsObj;
273
+ } catch (error) {
274
+ logger.error('Failed to evaluate CommonJS module:', error);
275
+ throw error;
276
+ }
277
+ }