flowquery 1.0.50 → 1.0.52

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 (56) hide show
  1. package/README.md +640 -75
  2. package/dist/compute/runner.d.ts +40 -5
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js +94 -10
  5. package/dist/compute/runner.js.map +1 -1
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/database.d.ts +5 -0
  8. package/dist/graph/database.d.ts.map +1 -1
  9. package/dist/graph/database.js +19 -3
  10. package/dist/graph/database.js.map +1 -1
  11. package/dist/graph/physical_node.d.ts +1 -1
  12. package/dist/graph/physical_node.d.ts.map +1 -1
  13. package/dist/graph/physical_node.js +2 -2
  14. package/dist/graph/physical_node.js.map +1 -1
  15. package/dist/graph/physical_relationship.d.ts +1 -1
  16. package/dist/graph/physical_relationship.d.ts.map +1 -1
  17. package/dist/graph/physical_relationship.js +2 -2
  18. package/dist/graph/physical_relationship.js.map +1 -1
  19. package/dist/index.browser.d.ts +2 -0
  20. package/dist/index.browser.d.ts.map +1 -1
  21. package/dist/index.browser.js.map +1 -1
  22. package/dist/index.node.d.ts +2 -1
  23. package/dist/index.node.d.ts.map +1 -1
  24. package/dist/index.node.js.map +1 -1
  25. package/dist/parsing/expressions/parameter_reference.d.ts +39 -0
  26. package/dist/parsing/expressions/parameter_reference.d.ts.map +1 -0
  27. package/dist/parsing/expressions/parameter_reference.js +56 -0
  28. package/dist/parsing/expressions/parameter_reference.js.map +1 -0
  29. package/dist/parsing/operations/match.d.ts +28 -0
  30. package/dist/parsing/operations/match.d.ts.map +1 -1
  31. package/dist/parsing/operations/match.js +100 -0
  32. package/dist/parsing/operations/match.js.map +1 -1
  33. package/dist/parsing/parser.d.ts +15 -0
  34. package/dist/parsing/parser.d.ts.map +1 -1
  35. package/dist/parsing/parser.js +86 -1
  36. package/dist/parsing/parser.js.map +1 -1
  37. package/dist/parsing/parser_state.d.ts +3 -0
  38. package/dist/parsing/parser_state.d.ts.map +1 -1
  39. package/dist/parsing/parser_state.js +7 -0
  40. package/dist/parsing/parser_state.js.map +1 -1
  41. package/dist/tokenization/string_walker.d.ts +1 -0
  42. package/dist/tokenization/string_walker.d.ts.map +1 -1
  43. package/dist/tokenization/string_walker.js +7 -0
  44. package/dist/tokenization/string_walker.js.map +1 -1
  45. package/dist/tokenization/symbol.d.ts +1 -0
  46. package/dist/tokenization/symbol.d.ts.map +1 -1
  47. package/dist/tokenization/symbol.js +1 -0
  48. package/dist/tokenization/symbol.js.map +1 -1
  49. package/dist/tokenization/token.d.ts +2 -0
  50. package/dist/tokenization/token.d.ts.map +1 -1
  51. package/dist/tokenization/token.js +6 -0
  52. package/dist/tokenization/token.js.map +1 -1
  53. package/dist/tokenization/tokenizer.d.ts.map +1 -1
  54. package/dist/tokenization/tokenizer.js +3 -1
  55. package/dist/tokenization/tokenizer.js.map +1 -1
  56. package/package.json +2 -2
@@ -1,40 +1,75 @@
1
1
  import ASTNode from "../parsing/ast_node";
2
+ /**
3
+ * Metadata about the operations performed by a Runner execution.
4
+ */
5
+ export interface RunnerMetadata {
6
+ virtual_nodes_created: number;
7
+ virtual_relationships_created: number;
8
+ virtual_nodes_deleted: number;
9
+ virtual_relationships_deleted: number;
10
+ }
2
11
  /**
3
12
  * Executes a FlowQuery statement and retrieves the results.
4
13
  *
5
14
  * The Runner class parses a FlowQuery statement into an AST and executes it,
6
15
  * managing the execution flow from the first operation to the final return statement.
7
16
  *
17
+ * Supports multi-statement queries separated by semicolons. Only CREATE and DELETE
18
+ * statements may appear before the last statement. If a retrieval statement is present,
19
+ * it must be the last statement.
20
+ *
8
21
  * @example
9
22
  * ```typescript
10
23
  * const runner = new Runner("WITH 1 as x RETURN x");
11
24
  * await runner.run();
12
25
  * console.log(runner.results); // [{ x: 1 }]
26
+ * console.log(runner.metadata); // { virtual_nodes_created: 0, ... }
13
27
  * ```
14
28
  */
15
29
  declare class Runner {
16
- private first;
17
- private last;
30
+ private _statements;
31
+ private _args;
32
+ private _metadata;
18
33
  /**
19
34
  * Creates a new Runner instance and parses the FlowQuery statement.
20
35
  *
21
- * @param statement - The FlowQuery statement to execute
36
+ * @param statement - The FlowQuery statement to execute (may contain semicolon-separated statements)
37
+ * @param ast - An optional pre-parsed AST to use instead of parsing the statement
38
+ * @param args - Optional parameters to inject into $-prefixed parameter references
22
39
  * @throws {Error} If the statement is null, empty, or contains syntax errors
23
40
  */
24
- constructor(statement?: string | null, ast?: ASTNode | null);
41
+ constructor(statement?: string | null, ast?: ASTNode | null, args?: Record<string, any> | null);
42
+ private static toStatement;
43
+ /**
44
+ * Walks all statement ASTs to count CREATE/DELETE operations for metadata.
45
+ */
46
+ private computeMetadata;
25
47
  /**
26
- * Executes the parsed FlowQuery statement.
48
+ * Executes the parsed FlowQuery statement(s).
27
49
  *
28
50
  * @returns A promise that resolves when execution completes
29
51
  * @throws {Error} If an error occurs during execution
30
52
  */
31
53
  run(): Promise<void>;
54
+ /**
55
+ * Recursively walks the AST to bind ParameterReference nodes
56
+ * to the args provided to this Runner.
57
+ * - $args resolves to the entire args map (for use with $args.key lookups)
58
+ * - $name resolves to args["name"] (shorthand for individual properties)
59
+ */
60
+ private bindParameters;
32
61
  /**
33
62
  * Gets the results from the executed statement.
34
63
  *
35
64
  * @returns The results from the last operation (typically a RETURN statement)
36
65
  */
37
66
  get results(): any;
67
+ /**
68
+ * Gets metadata about the operations in this query.
69
+ *
70
+ * @returns Counts of virtual nodes/relationships created and deleted
71
+ */
72
+ get metadata(): RunnerMetadata;
38
73
  }
39
74
  export default Runner;
40
75
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/compute/runner.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,qBAAqB,CAAC;AAI1C;;;;;;;;;;;;GAYG;AACH,cAAM,MAAM;IACR,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,IAAI,CAAY;IAExB;;;;;OAKG;gBACS,SAAS,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,GAAE,OAAO,GAAG,IAAW;IASvE;;;;;OAKG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;;;OAIG;IACH,IAAW,OAAO,IAAI,GAAG,CAExB;CACJ;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/compute/runner.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,qBAAqB,CAAC;AAS1C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,6BAA6B,EAAE,MAAM,CAAC;IACtC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,6BAA6B,EAAE,MAAM,CAAC;CACzC;AAQD;;;;;;;;;;;;;;;;;GAiBG;AACH,cAAM,MAAM;IACR,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,SAAS,CAAiB;IAElC;;;;;;;OAOG;gBAEC,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,GAAG,GAAE,OAAO,GAAG,IAAW,EAC1B,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAW;IAmB3C,OAAO,CAAC,MAAM,CAAC,WAAW;IAQ1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBvB;;;;;OAKG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBjC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAetB;;;;OAIG;IACH,IAAW,OAAO,IAAI,GAAG,CAExB;IAED;;;;OAIG;IACH,IAAW,QAAQ,IAAI,cAAc,CAEpC;CACJ;AAED,eAAe,MAAM,CAAC"}
@@ -12,6 +12,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ const parameter_reference_1 = __importDefault(require("../parsing/expressions/parameter_reference"));
16
+ const create_node_1 = __importDefault(require("../parsing/operations/create_node"));
17
+ const create_relationship_1 = __importDefault(require("../parsing/operations/create_relationship"));
18
+ const delete_node_1 = __importDefault(require("../parsing/operations/delete_node"));
19
+ const delete_relationship_1 = __importDefault(require("../parsing/operations/delete_relationship"));
15
20
  const parser_1 = __importDefault(require("../parsing/parser"));
16
21
  /**
17
22
  * Executes a FlowQuery statement and retrieves the results.
@@ -19,30 +24,76 @@ const parser_1 = __importDefault(require("../parsing/parser"));
19
24
  * The Runner class parses a FlowQuery statement into an AST and executes it,
20
25
  * managing the execution flow from the first operation to the final return statement.
21
26
  *
27
+ * Supports multi-statement queries separated by semicolons. Only CREATE and DELETE
28
+ * statements may appear before the last statement. If a retrieval statement is present,
29
+ * it must be the last statement.
30
+ *
22
31
  * @example
23
32
  * ```typescript
24
33
  * const runner = new Runner("WITH 1 as x RETURN x");
25
34
  * await runner.run();
26
35
  * console.log(runner.results); // [{ x: 1 }]
36
+ * console.log(runner.metadata); // { virtual_nodes_created: 0, ... }
27
37
  * ```
28
38
  */
29
39
  class Runner {
30
40
  /**
31
41
  * Creates a new Runner instance and parses the FlowQuery statement.
32
42
  *
33
- * @param statement - The FlowQuery statement to execute
43
+ * @param statement - The FlowQuery statement to execute (may contain semicolon-separated statements)
44
+ * @param ast - An optional pre-parsed AST to use instead of parsing the statement
45
+ * @param args - Optional parameters to inject into $-prefixed parameter references
34
46
  * @throws {Error} If the statement is null, empty, or contains syntax errors
35
47
  */
36
- constructor(statement = null, ast = null) {
48
+ constructor(statement = null, ast = null, args = null) {
49
+ this._args = null;
37
50
  if ((statement === null || statement === "") && ast === null) {
38
51
  throw new Error("Either statement or AST must be provided");
39
52
  }
40
- const _ast = ast !== null ? ast : new parser_1.default().parse(statement);
41
- this.first = _ast.firstChild();
42
- this.last = _ast.lastChild();
53
+ this._args = args;
54
+ if (ast !== null) {
55
+ this._statements = [Runner.toStatement(ast)];
56
+ }
57
+ else {
58
+ this._statements = Array.from(new parser_1.default().parseStatements(statement), Runner.toStatement);
59
+ }
60
+ this._metadata = this.computeMetadata();
61
+ }
62
+ static toStatement(ast) {
63
+ return {
64
+ ast,
65
+ first: ast.firstChild(),
66
+ last: ast.lastChild(),
67
+ };
43
68
  }
44
69
  /**
45
- * Executes the parsed FlowQuery statement.
70
+ * Walks all statement ASTs to count CREATE/DELETE operations for metadata.
71
+ */
72
+ computeMetadata() {
73
+ const metadata = {
74
+ virtual_nodes_created: 0,
75
+ virtual_relationships_created: 0,
76
+ virtual_nodes_deleted: 0,
77
+ virtual_relationships_deleted: 0,
78
+ };
79
+ for (const stmt of this._statements) {
80
+ let op = stmt.first;
81
+ while (op !== null) {
82
+ if (op instanceof create_node_1.default)
83
+ metadata.virtual_nodes_created++;
84
+ else if (op instanceof create_relationship_1.default)
85
+ metadata.virtual_relationships_created++;
86
+ else if (op instanceof delete_node_1.default)
87
+ metadata.virtual_nodes_deleted++;
88
+ else if (op instanceof delete_relationship_1.default)
89
+ metadata.virtual_relationships_deleted++;
90
+ op = op.next;
91
+ }
92
+ }
93
+ return metadata;
94
+ }
95
+ /**
96
+ * Executes the parsed FlowQuery statement(s).
46
97
  *
47
98
  * @returns A promise that resolves when execution completes
48
99
  * @throws {Error} If an error occurs during execution
@@ -51,9 +102,12 @@ class Runner {
51
102
  return __awaiter(this, void 0, void 0, function* () {
52
103
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
53
104
  try {
54
- yield this.first.initialize();
55
- yield this.first.run();
56
- yield this.first.finish();
105
+ for (const stmt of this._statements) {
106
+ this.bindParameters(stmt.ast);
107
+ yield stmt.first.initialize();
108
+ yield stmt.first.run();
109
+ yield stmt.first.finish();
110
+ }
57
111
  resolve();
58
112
  }
59
113
  catch (e) {
@@ -62,13 +116,43 @@ class Runner {
62
116
  }));
63
117
  });
64
118
  }
119
+ /**
120
+ * Recursively walks the AST to bind ParameterReference nodes
121
+ * to the args provided to this Runner.
122
+ * - $args resolves to the entire args map (for use with $args.key lookups)
123
+ * - $name resolves to args["name"] (shorthand for individual properties)
124
+ */
125
+ bindParameters(node) {
126
+ var _a;
127
+ if (node instanceof parameter_reference_1.default) {
128
+ const args = (_a = this._args) !== null && _a !== void 0 ? _a : {};
129
+ const key = node.name.startsWith("$") ? node.name.substring(1) : node.name;
130
+ if (key === "args") {
131
+ node.parameterValue = args;
132
+ }
133
+ else {
134
+ node.parameterValue = key in args ? args[key] : null;
135
+ }
136
+ }
137
+ for (const child of node.getChildren()) {
138
+ this.bindParameters(child);
139
+ }
140
+ }
65
141
  /**
66
142
  * Gets the results from the executed statement.
67
143
  *
68
144
  * @returns The results from the last operation (typically a RETURN statement)
69
145
  */
70
146
  get results() {
71
- return this.last.results;
147
+ return this._statements[this._statements.length - 1].last.results;
148
+ }
149
+ /**
150
+ * Gets metadata about the operations in this query.
151
+ *
152
+ * @returns Counts of virtual nodes/relationships created and deleted
153
+ */
154
+ get metadata() {
155
+ return Object.assign({}, this._metadata);
72
156
  }
73
157
  }
74
158
  exports.default = Runner;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/compute/runner.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,+DAAuC;AAEvC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM;IAIR;;;;;OAKG;IACH,YAAY,YAA2B,IAAI,EAAE,MAAsB,IAAI;QACnE,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,EAAE,CAAC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,gBAAM,EAAE,CAAC,KAAK,CAAC,SAAU,CAAC,CAAC;QACjE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAe,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,EAAe,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACU,GAAG;;YACZ,OAAO,IAAI,OAAO,CAAO,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC/C,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;oBAC9B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;oBACvB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC1B,OAAO,EAAE,CAAC;gBACd,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACT,MAAM,CAAC,CAAC,CAAC,CAAC;gBACd,CAAC;YACL,CAAC,CAAA,CAAC,CAAC;QACP,CAAC;KAAA;IAED;;;;OAIG;IACH,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,CAAC;CACJ;AAED,kBAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/compute/runner.ts"],"names":[],"mappings":"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"}