agency-lang 0.0.57 → 0.0.59

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.
package/README.md CHANGED
@@ -25,7 +25,7 @@ agency infile.agency
25
25
  Note that the generated files use several other libraries that you will need to install as well:
26
26
 
27
27
  ```bash
28
- pnpm i nanoid openai piemachine statelog-client zod
28
+ pnpm i nanoid openai zod smoltalk
29
29
  ```
30
30
 
31
31
  ## troubleshooting
@@ -5,9 +5,9 @@ import { TimeBlock } from "../types/timeBlock.js";
5
5
  import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
6
6
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
7
7
  import { FunctionCall, FunctionDefinition } from "../types/function.js";
8
- import { GraphNodeDefinition } from "../types/graphNode.js";
8
+ import { GraphNodeDefinition, Visibility } from "../types/graphNode.js";
9
9
  import { IfElse } from "../types/ifElse.js";
10
- import { ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
10
+ import { ImportNameType, ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
11
11
  import { MatchBlock } from "../types/matchBlock.js";
12
12
  import { ReturnStatement } from "../types/returnStatement.js";
13
13
  import { UsesTool } from "../types/tools.js";
@@ -55,8 +55,10 @@ export declare class AgencyGenerator extends BaseGenerator {
55
55
  protected processReturnStatement(node: ReturnStatement): string;
56
56
  protected processComment(node: AgencyComment): string;
57
57
  protected processImportStatement(node: ImportStatement): string;
58
+ protected processImportNameType(node: ImportNameType): string;
58
59
  protected processImportNodeStatement(node: ImportNodeStatement): string;
59
60
  protected processImportToolStatement(node: ImportToolStatement): string;
61
+ protected visibilityToString(vis: Visibility): string;
60
62
  protected processGraphNode(node: GraphNodeDefinition): string;
61
63
  protected processTool(node: FunctionDefinition): string;
62
64
  protected processUsesTool(node: UsesTool): string;
@@ -341,15 +341,36 @@ export class AgencyGenerator extends BaseGenerator {
341
341
  return this.indentStr(`//${node.content}`);
342
342
  }
343
343
  processImportStatement(node) {
344
- const str = this.indentStr(`import ${node.importedNames}from "${node.modulePath}"`);
344
+ const importedNames = node.importedNames.map((name) => this.processImportNameType(name));
345
+ const str = this.indentStr(`import ${importedNames.join(", ")} from "${node.modulePath}"`);
345
346
  return str;
346
347
  }
348
+ processImportNameType(node) {
349
+ switch (node.type) {
350
+ case "namedImport":
351
+ return `{ ${node.importedNames.join(", ")} }`;
352
+ case "namespaceImport":
353
+ return `* as ${node.importedNames}`;
354
+ case "defaultImport":
355
+ return `${node.importedNames}`;
356
+ }
357
+ }
347
358
  processImportNodeStatement(node) {
348
359
  return `import node { ${node.importedNodes.join(", ")} } from "${node.agencyFile}"`;
349
360
  }
350
361
  processImportToolStatement(node) {
351
362
  return `import tool { ${node.importedTools.join(", ")} } from "${node.agencyFile}"`;
352
363
  }
364
+ visibilityToString(vis) {
365
+ switch (vis) {
366
+ case "public":
367
+ return "public ";
368
+ case "private":
369
+ return "private ";
370
+ case undefined:
371
+ return "";
372
+ }
373
+ }
353
374
  processGraphNode(node) {
354
375
  // Graph nodes use similar syntax to functions
355
376
  const { nodeName, body, parameters } = node;
@@ -361,7 +382,8 @@ export class AgencyGenerator extends BaseGenerator {
361
382
  const returnTypeStr = node.returnType
362
383
  ? ": " + variableTypeToString(node.returnType, this.typeAliases)
363
384
  : "";
364
- let result = this.indentStr(`node ${nodeName}(${params})${returnTypeStr} {\n`);
385
+ const visibilityStr = this.visibilityToString(node.visibility);
386
+ let result = this.indentStr(`${visibilityStr}node ${nodeName}(${params})${returnTypeStr} {\n`);
365
387
  this.increaseIndent();
366
388
  const lines = [];
367
389
  for (const stmt of body) {
@@ -6,7 +6,7 @@ import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../
6
6
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
7
7
  import { FunctionCall, FunctionDefinition } from "../types/function.js";
8
8
  import { IfElse } from "../types/ifElse.js";
9
- import { ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
9
+ import { ImportNameType, ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
10
10
  import { MatchBlock } from "../types/matchBlock.js";
11
11
  import { ReturnStatement } from "../types/returnStatement.js";
12
12
  import { UsesTool } from "../types/tools.js";
@@ -68,6 +68,7 @@ export declare class TypeScriptGenerator extends BaseGenerator {
68
68
  prompt: PromptLiteral;
69
69
  }): string;
70
70
  protected processImportStatement(node: ImportStatement): string;
71
+ protected processImportNameType(node: ImportNameType): string;
71
72
  protected processImportNodeStatement(node: ImportNodeStatement): string;
72
73
  protected processImportToolStatement(node: ImportToolStatement): string;
73
74
  protected processWhileLoop(node: WhileLoop): string;
@@ -479,7 +479,18 @@ export class TypeScriptGenerator extends BaseGenerator {
479
479
  });
480
480
  }
481
481
  processImportStatement(node) {
482
- return `import ${node.importedNames} from "${node.modulePath.replace(/\.agency$/, ".js")}";`;
482
+ const importedNames = node.importedNames.map((name) => this.processImportNameType(name));
483
+ return `import ${importedNames.join(", ")} from "${node.modulePath.replace(/\.agency$/, ".js")}";`;
484
+ }
485
+ processImportNameType(node) {
486
+ switch (node.type) {
487
+ case "namedImport":
488
+ return `{ ${node.importedNames.join(", ")} }`;
489
+ case "namespaceImport":
490
+ return `* as ${node.importedNames}`;
491
+ case "defaultImport":
492
+ return `${node.importedNames}`;
493
+ }
483
494
  }
484
495
  processImportNodeStatement(node) {
485
496
  return ""; // handled in preprocess in graphgenerator
@@ -18,7 +18,7 @@ function writeTestCase(agencyFilename, nodeName, input, expectedOutput, evaluati
18
18
  tests = JSON.parse(fs.readFileSync(testFilePath, "utf-8"));
19
19
  }
20
20
  else {
21
- tests = { sourceFile: agencyFilename, tests: [] };
21
+ tests = { sourceFile: path.basename(agencyFilename), tests: [] };
22
22
  }
23
23
  const testCase = {
24
24
  nodeName,
@@ -1,3 +1,5 @@
1
1
  export * from "./parser.js";
2
2
  export * from "./types.js";
3
3
  export * from "./backends/index.js";
4
+ export * from "./simplemachine/index.js";
5
+ export * from "./statelogClient.js";
package/dist/lib/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from "./parser.js";
2
2
  export * from "./types.js";
3
3
  export * from "./backends/index.js";
4
+ export * from "./simplemachine/index.js";
5
+ export * from "./statelogClient.js";
@@ -100,4 +100,5 @@ export const syncFunctionParser = (input) => {
100
100
  return mappedParser(input);
101
101
  };
102
102
  export const functionParser = or(asyncFunctionParser, syncFunctionParser, _functionParser);
103
- export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpacesOrNewline, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
103
+ const visibilityParser = or(str("public"), str("private"), succeed(undefined));
104
+ export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), capture(visibilityParser, "visibility"), optionalSpaces, str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpacesOrNewline, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
@@ -1,4 +1,4 @@
1
- import { alphanum, capture, captureCaptures, char, many1Till, many1WithJoin, map, newline, oneOf, optional, or, parseError, sepBy1, seqC, set, spaces, str, trace, } from "tarsec";
1
+ import { alphanum, capture, captureCaptures, char, many1Till, many1WithJoin, map, newline, oneOf, optional, or, parseError, sepBy, sepBy1, seqC, set, spaces, str, trace, } from "tarsec";
2
2
  import { optionalSemicolon } from "./parserUtils.js";
3
3
  import { comma, optionalSpaces } from "./utils.js";
4
4
  // Helper parser for quoted file paths - supports both single and double quotes
@@ -7,4 +7,8 @@ const singleQuotedPath = seqC(char("'"), capture(many1Till(char("'")), "path"),
7
7
  const quotedPath = map(or(doubleQuotedPath, singleQuotedPath), (res) => res.path);
8
8
  export const importNodeStatmentParser = trace("importNodeStatement", seqC(set("type", "importNodeStatement"), str("import"), spaces, or(str("nodes"), str("node")), captureCaptures(parseError("expected a statement of the form `import nodes { x, y } from 'filename.agency'`", spaces, char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedNodes"), optionalSpaces, char("}"), spaces, str("from"), spaces, capture(quotedPath, "agencyFile"), optionalSemicolon, optional(newline)))));
9
9
  export const importToolStatmentParser = trace("importToolStatement", seqC(set("type", "importToolStatement"), str("import"), spaces, or(str("tools"), str("tool")), captureCaptures(parseError("expected a statement of the form `import tools { x, y } from 'filename.agency'`", spaces, char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedTools"), optionalSpaces, char("}"), spaces, str("from"), spaces, capture(quotedPath, "agencyFile"), optionalSemicolon, optional(newline)))));
10
- export const importStatmentParser = trace("importStatement", seqC(set("type", "importStatement"), str("import"), captureCaptures(parseError("expected a statement of the form `import { x, y } from 'filename'`", spaces, capture(many1Till(str("from")), "importedNames"), str("from"), spaces, oneOf(`'"`), capture(many1Till(oneOf(`'"`)), "modulePath"), oneOf(`'"`), optionalSemicolon, optional(newline)))));
10
+ const namedImportParser = trace("namedImportParser", seqC(char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedNames"), optionalSpaces, char("}"), set("type", "namedImport")));
11
+ const namespaceImportParser = trace("namespaceImportParser", seqC(many1Till(spaces), spaces, str("as"), spaces, capture(many1WithJoin(alphanum), "importedNames"), set("type", "namespaceImport")));
12
+ const defaultImportParser = trace("defaultImportParser", seqC(capture(many1WithJoin(alphanum), "importedNames"), set("type", "defaultImport")));
13
+ const importNameTypeParser = sepBy(comma, or(namedImportParser, namespaceImportParser, defaultImportParser));
14
+ export const importStatmentParser = trace("importStatement", seqC(set("type", "importStatement"), str("import"), captureCaptures(parseError("expected a statement of the form `import { x, y } from 'filename'`", spaces, capture(importNameTypeParser, "importedNames"), spaces, str("from"), spaces, oneOf(`'"`), capture(many1Till(oneOf(`'"`)), "modulePath"), oneOf(`'"`), optionalSemicolon, optional(newline)))));
@@ -1,249 +1,147 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import { importStatmentParser, importNodeStatmentParser, importToolStatmentParser, } from "./importStatement.js";
3
3
  describe("importStatmentParser", () => {
4
- const testCases = [
5
- // Unquoted module paths are no longer supported (start with "import" -> throw)
6
- {
7
- input: "import foo from bar;",
8
- expected: { success: false },
9
- throws: true,
10
- },
11
- {
12
- input: "import myModule from path/to/module;",
13
- expected: { success: false },
14
- throws: true,
15
- },
16
- // Module paths with double quotes
17
- {
18
- input: 'import foo from "bar";',
19
- expected: {
20
- success: true,
21
- result: {
22
- type: "importStatement",
23
- importedNames: "foo ",
24
- modulePath: "bar",
25
- },
26
- },
27
- },
28
- {
29
- input: 'import foo from "./local/path.js";',
30
- expected: {
31
- success: true,
32
- result: {
33
- type: "importStatement",
34
- importedNames: "foo ",
35
- modulePath: "./local/path.js",
36
- },
37
- },
38
- },
39
- {
40
- input: 'import bar from "../utils/helper.js";',
41
- expected: {
42
- success: true,
43
- result: {
44
- type: "importStatement",
45
- importedNames: "bar ",
46
- modulePath: "../utils/helper.js",
47
- },
48
- },
49
- },
50
- {
51
- input: 'import { useState } from "react";',
52
- expected: {
53
- success: true,
54
- result: {
55
- type: "importStatement",
56
- importedNames: "{ useState } ",
57
- modulePath: "react",
58
- },
59
- },
60
- },
61
- // Module paths with single quotes
62
- {
63
- input: "import foo from 'bar';",
64
- expected: {
65
- success: true,
66
- result: {
67
- type: "importStatement",
68
- importedNames: "foo ",
69
- modulePath: "bar",
70
- },
71
- },
72
- },
73
- {
74
- input: "import test from './module.js';",
75
- expected: {
76
- success: true,
77
- result: {
78
- type: "importStatement",
79
- importedNames: "test ",
80
- modulePath: "./module.js",
81
- },
82
- },
83
- },
84
- // Without semicolon - unquoted paths no longer supported (start with "import" -> throw)
85
- {
86
- input: "import foo from bar\n",
87
- expected: { success: false },
88
- throws: true,
89
- },
90
- {
91
- input: "import test from module",
92
- expected: { success: false },
93
- throws: true,
94
- },
95
- {
96
- input: 'import foo from "bar"\n',
97
- expected: {
98
- success: true,
99
- result: {
100
- type: "importStatement",
101
- importedNames: "foo ",
102
- modulePath: "bar",
103
- },
104
- },
105
- },
106
- // Multiple imported names (destructured imports) - unquoted paths no longer supported (start with "import" -> throw)
107
- {
108
- input: "import { foo, bar } from module;",
109
- expected: { success: false },
110
- throws: true,
111
- },
112
- {
113
- input: 'import { foo, bar, baz } from "myModule";',
114
- expected: {
115
- success: true,
116
- result: {
117
- type: "importStatement",
118
- importedNames: "{ foo, bar, baz } ",
119
- modulePath: "myModule",
120
- },
121
- },
122
- },
123
- // Default and named imports
124
- {
125
- input: 'import React, { useState } from "react";',
126
- expected: {
127
- success: true,
128
- result: {
129
- type: "importStatement",
130
- importedNames: "React, { useState } ",
131
- modulePath: "react",
132
- },
133
- },
134
- },
135
- // Namespace imports
136
- {
137
- input: 'import * as utils from "utils";',
138
- expected: {
139
- success: true,
140
- result: {
141
- type: "importStatement",
142
- importedNames: "* as utils ",
143
- modulePath: "utils",
144
- },
145
- },
146
- },
147
- // Scoped packages
148
- {
149
- input: 'import { Parser } from "@typescript-eslint/parser";',
150
- expected: {
151
- success: true,
152
- result: {
153
- type: "importStatement",
154
- importedNames: "{ Parser } ",
155
- modulePath: "@typescript-eslint/parser",
156
- },
157
- },
158
- },
159
- // Spaces around keywords - unquoted paths no longer supported (start with "import" -> throw)
160
- {
161
- input: "import foo from bar;",
162
- expected: { success: false },
163
- throws: true,
164
- },
165
- // Edge cases - single character names with unquoted path (start with "import" -> throw)
166
- {
167
- input: "import x from y;",
168
- expected: { success: false },
169
- throws: true,
170
- },
171
- {
172
- input: 'import x from "y";',
173
- expected: {
174
- success: true,
175
- result: {
176
- type: "importStatement",
177
- importedNames: "x ",
178
- modulePath: "y",
179
- },
180
- },
181
- },
182
- // Complex paths - unquoted paths no longer supported (start with "import" -> throw)
183
- {
184
- input: "import foo from ../../../utils/helpers;",
185
- expected: { success: false },
186
- throws: true,
187
- },
188
- {
189
- input: 'import foo from "../../../utils/helpers.js";',
190
- expected: {
191
- success: true,
192
- result: {
193
- type: "importStatement",
194
- importedNames: "foo ",
195
- modulePath: "../../../utils/helpers.js",
196
- },
197
- },
198
- },
199
- // Aliased imports
200
- {
201
- input: 'import { foo as bar } from "module";',
202
- expected: {
203
- success: true,
204
- result: {
205
- type: "importStatement",
206
- importedNames: "{ foo as bar } ",
207
- modulePath: "module",
208
- },
209
- },
210
- },
211
- // Failure cases - missing keywords (don't start with "import" -> don't throw)
212
- { input: "foo from bar;", expected: { success: false }, throws: false },
213
- { input: "from bar;", expected: { success: false }, throws: false },
214
- { input: "import foo bar;", expected: { success: false }, throws: true },
215
- // Failure cases - missing parts (start with "import" -> throw)
216
- { input: "import from bar;", expected: { success: false }, throws: true },
217
- { input: "import foo from;", expected: { success: false }, throws: true },
218
- { input: "import;", expected: { success: false }, throws: true },
219
- // Failure cases - empty input (doesn't start with "import" -> don't throw)
220
- { input: "", expected: { success: false }, throws: false },
221
- // Failure cases - just keyword
222
- { input: "import", expected: { success: false }, throws: true },
223
- { input: "from", expected: { success: false }, throws: false },
224
- ];
225
- testCases.forEach(({ input, expected, throws }) => {
226
- if (expected.success) {
227
- it(`should parse "${input}" successfully`, () => {
228
- const result = importStatmentParser(input);
229
- expect(result.success).toBe(true);
230
- if (result.success) {
231
- expect(result.result).toEqual(expected.result);
232
- }
4
+ // Default imports
5
+ it('should parse: import foo from "./foo.ts"', () => {
6
+ const result = importStatmentParser('import foo from "./foo.ts"');
7
+ expect(result.success).toBe(true);
8
+ if (result.success) {
9
+ expect(result.result).toEqual({
10
+ type: "importStatement",
11
+ importedNames: [{ type: "defaultImport", importedNames: "foo" }],
12
+ modulePath: "./foo.ts",
233
13
  });
234
14
  }
235
- else if (throws) {
236
- it(`should fail to parse "${input}"`, () => {
237
- expect(() => importStatmentParser(input)).toThrow();
15
+ });
16
+ // Named imports
17
+ it('should parse: import { foo } from "./foo.ts"', () => {
18
+ const result = importStatmentParser('import { foo } from "./foo.ts"');
19
+ expect(result.success).toBe(true);
20
+ if (result.success) {
21
+ expect(result.result).toEqual({
22
+ type: "importStatement",
23
+ importedNames: [{ type: "namedImport", importedNames: ["foo"] }],
24
+ modulePath: "./foo.ts",
238
25
  });
239
26
  }
240
- else {
241
- it(`should fail to parse "${input}"`, () => {
242
- const result = importStatmentParser(input);
243
- expect(result.success).toBe(false);
27
+ });
28
+ // Default + named imports
29
+ it('should parse: import foo, { bar } from "./foo.ts"', () => {
30
+ const result = importStatmentParser('import foo, { bar } from "./foo.ts"');
31
+ expect(result.success).toBe(true);
32
+ if (result.success) {
33
+ expect(result.result).toEqual({
34
+ type: "importStatement",
35
+ importedNames: [
36
+ { type: "defaultImport", importedNames: "foo" },
37
+ { type: "namedImport", importedNames: ["bar"] },
38
+ ],
39
+ modulePath: "./foo.ts",
40
+ });
41
+ }
42
+ });
43
+ // Namespace imports
44
+ it('should parse: import * as foo from "./foo.ts"', () => {
45
+ const result = importStatmentParser('import * as foo from "./foo.ts"');
46
+ expect(result.success).toBe(true);
47
+ if (result.success) {
48
+ expect(result.result).toEqual({
49
+ type: "importStatement",
50
+ importedNames: [{ type: "namespaceImport", importedNames: "foo" }],
51
+ modulePath: "./foo.ts",
52
+ });
53
+ }
54
+ });
55
+ // Default + namespace imports
56
+ it('should parse: import foo, * as bar from "./foo.ts"', () => {
57
+ const result = importStatmentParser('import foo, * as bar from "./foo.ts"');
58
+ expect(result.success).toBe(true);
59
+ if (result.success) {
60
+ expect(result.result).toEqual({
61
+ type: "importStatement",
62
+ importedNames: [
63
+ { type: "defaultImport", importedNames: "foo" },
64
+ { type: "namespaceImport", importedNames: "bar" },
65
+ ],
66
+ modulePath: "./foo.ts",
67
+ });
68
+ }
69
+ });
70
+ // .agency file imports
71
+ it('should parse: import foo from "./foo.agency"', () => {
72
+ const result = importStatmentParser('import foo from "./foo.agency"');
73
+ expect(result.success).toBe(true);
74
+ if (result.success) {
75
+ expect(result.result).toEqual({
76
+ type: "importStatement",
77
+ importedNames: [{ type: "defaultImport", importedNames: "foo" }],
78
+ modulePath: "./foo.agency",
244
79
  });
245
80
  }
246
81
  });
82
+ it('should parse: import { foo } from "./foo.agency"', () => {
83
+ const result = importStatmentParser('import { foo } from "./foo.agency"');
84
+ expect(result.success).toBe(true);
85
+ if (result.success) {
86
+ expect(result.result).toEqual({
87
+ type: "importStatement",
88
+ importedNames: [{ type: "namedImport", importedNames: ["foo"] }],
89
+ modulePath: "./foo.agency",
90
+ });
91
+ }
92
+ });
93
+ // node/tool imports are handled by their own parsers, not importStatmentParser
94
+ it('should not parse: import node { foo } from "./foo.agency"', () => {
95
+ expect(() => importStatmentParser('import node { foo } from "./foo.agency"')).toThrow();
96
+ });
97
+ it('should not parse: import tool { foo } from "./foo.agency"', () => {
98
+ expect(() => importStatmentParser('import tool { foo } from "./foo.agency"')).toThrow();
99
+ });
100
+ // Multiple named imports
101
+ it('should parse: import { foo, bar, baz } from "myModule"', () => {
102
+ const result = importStatmentParser('import { foo, bar, baz } from "myModule"');
103
+ expect(result.success).toBe(true);
104
+ if (result.success) {
105
+ expect(result.result).toEqual({
106
+ type: "importStatement",
107
+ importedNames: [
108
+ { type: "namedImport", importedNames: ["foo", "bar", "baz"] },
109
+ ],
110
+ modulePath: "myModule",
111
+ });
112
+ }
113
+ });
114
+ // With semicolons
115
+ it('should parse imports with semicolons', () => {
116
+ const result = importStatmentParser('import foo from "./foo.ts";');
117
+ expect(result.success).toBe(true);
118
+ if (result.success) {
119
+ expect(result.result.modulePath).toBe("./foo.ts");
120
+ }
121
+ });
122
+ // With single quotes
123
+ it("should parse imports with single quotes", () => {
124
+ const result = importStatmentParser("import foo from './foo.ts'");
125
+ expect(result.success).toBe(true);
126
+ if (result.success) {
127
+ expect(result.result.modulePath).toBe("./foo.ts");
128
+ }
129
+ });
130
+ // Failure cases
131
+ it("should fail on empty input", () => {
132
+ const result = importStatmentParser("");
133
+ expect(result.success).toBe(false);
134
+ });
135
+ it("should fail on non-import input", () => {
136
+ const result = importStatmentParser("foo from bar;");
137
+ expect(result.success).toBe(false);
138
+ });
139
+ it("should throw on unquoted paths", () => {
140
+ expect(() => importStatmentParser("import foo from bar;")).toThrow();
141
+ });
142
+ it("should throw on missing parts", () => {
143
+ expect(() => importStatmentParser("import foo from;")).toThrow();
144
+ });
247
145
  });
248
146
  describe("importNodeStatmentParser", () => {
249
147
  const testCases = [
@@ -0,0 +1,3 @@
1
+ export declare class SimpleMachineError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,6 @@
1
+ export class SimpleMachineError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "SimpleMachineError";
5
+ }
6
+ }
@@ -0,0 +1,37 @@
1
+ import { ConditionalFunc, Edge, SimpleMachineConfig } from "./types.js";
2
+ export declare class GoToNode<T> {
3
+ to: string;
4
+ data: T;
5
+ constructor(to: string, data: T);
6
+ }
7
+ export declare function goToNode<T>(to: string, data: T): GoToNode<T>;
8
+ export declare class SimpleMachine<T> {
9
+ private nodes;
10
+ private edges;
11
+ private config;
12
+ private statelogClient;
13
+ private nodesTraversed;
14
+ constructor(config?: SimpleMachineConfig<T>);
15
+ node(id: string, func: (data: T) => Promise<T | GoToNode<T>>): void;
16
+ edge(from: string, to: string): void;
17
+ conditionalEdge<const Adjacent extends string>(from: string, adjacentNodes: readonly Adjacent[], to?: ConditionalFunc<T, Adjacent>): void;
18
+ debug(message: string, data?: T): void;
19
+ getNodesTraversed(): readonly string[];
20
+ run(startId: string, input: T): Promise<T>;
21
+ runAndValidate(nodeFunc: (data: T) => Promise<T | GoToNode<T>>, currentId: string, _data: T, retries?: number): Promise<T | GoToNode<T>>;
22
+ prettyPrint(): void;
23
+ prettyPrintEdge(edge: Edge<T, string>): string;
24
+ toMermaid(): string;
25
+ merge(another: SimpleMachine<T>): void;
26
+ toJSON(): {
27
+ nodes: string[];
28
+ edges: Record<string, string[]>;
29
+ config: {
30
+ debug: {
31
+ log?: boolean;
32
+ logData?: boolean;
33
+ } | undefined;
34
+ };
35
+ };
36
+ private validateGoToNodeTarget;
37
+ }