flowquery 1.0.15 → 1.0.17

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 (333) hide show
  1. package/.github/workflows/python-publish.yml +97 -0
  2. package/dist/compute/runner.d.ts +3 -2
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js +7 -7
  5. package/dist/compute/runner.js.map +1 -1
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/data.d.ts +31 -0
  8. package/dist/graph/data.d.ts.map +1 -0
  9. package/dist/graph/data.js +110 -0
  10. package/dist/graph/data.js.map +1 -0
  11. package/dist/graph/database.d.ts +20 -0
  12. package/dist/graph/database.d.ts.map +1 -0
  13. package/dist/graph/database.js +77 -0
  14. package/dist/graph/database.js.map +1 -0
  15. package/dist/graph/hops.d.ts +11 -0
  16. package/dist/graph/hops.d.ts.map +1 -0
  17. package/dist/graph/hops.js +25 -0
  18. package/dist/graph/hops.js.map +1 -0
  19. package/dist/graph/node.d.ts +35 -0
  20. package/dist/graph/node.d.ts.map +1 -0
  21. package/dist/graph/node.js +113 -0
  22. package/dist/graph/node.js.map +1 -0
  23. package/dist/graph/node_data.d.ts +11 -0
  24. package/dist/graph/node_data.d.ts.map +1 -0
  25. package/dist/graph/node_data.js +20 -0
  26. package/dist/graph/node_data.js.map +1 -0
  27. package/dist/graph/node_reference.d.ts +10 -0
  28. package/dist/graph/node_reference.d.ts.map +1 -0
  29. package/dist/graph/node_reference.js +52 -0
  30. package/dist/graph/node_reference.js.map +1 -0
  31. package/dist/graph/pattern.d.ts +18 -0
  32. package/dist/graph/pattern.d.ts.map +1 -0
  33. package/dist/graph/pattern.js +114 -0
  34. package/dist/graph/pattern.js.map +1 -0
  35. package/dist/graph/pattern_expression.d.ts +14 -0
  36. package/dist/graph/pattern_expression.d.ts.map +1 -0
  37. package/dist/graph/pattern_expression.js +58 -0
  38. package/dist/graph/pattern_expression.js.map +1 -0
  39. package/dist/graph/patterns.d.ts +11 -0
  40. package/dist/graph/patterns.d.ts.map +1 -0
  41. package/dist/graph/patterns.js +49 -0
  42. package/dist/graph/patterns.js.map +1 -0
  43. package/dist/graph/physical_node.d.ts +10 -0
  44. package/dist/graph/physical_node.d.ts.map +1 -0
  45. package/dist/graph/physical_node.js +40 -0
  46. package/dist/graph/physical_node.js.map +1 -0
  47. package/dist/graph/physical_relationship.d.ts +10 -0
  48. package/dist/graph/physical_relationship.d.ts.map +1 -0
  49. package/dist/graph/physical_relationship.js +40 -0
  50. package/dist/graph/physical_relationship.js.map +1 -0
  51. package/dist/graph/relationship.d.ts +40 -0
  52. package/dist/graph/relationship.d.ts.map +1 -0
  53. package/dist/graph/relationship.js +124 -0
  54. package/dist/graph/relationship.js.map +1 -0
  55. package/dist/graph/relationship_data.d.ts +12 -0
  56. package/dist/graph/relationship_data.d.ts.map +1 -0
  57. package/dist/graph/relationship_data.js +40 -0
  58. package/dist/graph/relationship_data.js.map +1 -0
  59. package/dist/graph/relationship_match_collector.d.ts +19 -0
  60. package/dist/graph/relationship_match_collector.d.ts.map +1 -0
  61. package/dist/graph/relationship_match_collector.js +55 -0
  62. package/dist/graph/relationship_match_collector.js.map +1 -0
  63. package/dist/graph/relationship_reference.d.ts +8 -0
  64. package/dist/graph/relationship_reference.d.ts.map +1 -0
  65. package/dist/graph/relationship_reference.js +37 -0
  66. package/dist/graph/relationship_reference.js.map +1 -0
  67. package/dist/parsing/base_parser.d.ts +1 -0
  68. package/dist/parsing/base_parser.d.ts.map +1 -1
  69. package/dist/parsing/base_parser.js +4 -1
  70. package/dist/parsing/base_parser.js.map +1 -1
  71. package/dist/parsing/context.d.ts +2 -2
  72. package/dist/parsing/context.js +5 -5
  73. package/dist/parsing/expressions/boolean.d.ts +8 -0
  74. package/dist/parsing/expressions/boolean.d.ts.map +1 -0
  75. package/dist/parsing/expressions/boolean.js +26 -0
  76. package/dist/parsing/expressions/boolean.js.map +1 -0
  77. package/dist/parsing/expressions/expression.d.ts +4 -1
  78. package/dist/parsing/expressions/expression.d.ts.map +1 -1
  79. package/dist/parsing/expressions/expression.js +15 -8
  80. package/dist/parsing/expressions/expression.js.map +1 -1
  81. package/dist/parsing/expressions/expression_map.d.ts +1 -0
  82. package/dist/parsing/expressions/expression_map.d.ts.map +1 -1
  83. package/dist/parsing/expressions/expression_map.js +3 -0
  84. package/dist/parsing/expressions/expression_map.js.map +1 -1
  85. package/dist/parsing/expressions/operator.d.ts +1 -1
  86. package/dist/parsing/expressions/operator.d.ts.map +1 -1
  87. package/dist/parsing/expressions/operator.js.map +1 -1
  88. package/dist/parsing/functions/function_factory.d.ts +13 -13
  89. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  90. package/dist/parsing/functions/function_factory.js +20 -18
  91. package/dist/parsing/functions/function_factory.js.map +1 -1
  92. package/dist/parsing/operations/call.d.ts.map +1 -1
  93. package/dist/parsing/operations/call.js +3 -1
  94. package/dist/parsing/operations/call.js.map +1 -1
  95. package/dist/parsing/operations/create_node.d.ts +14 -0
  96. package/dist/parsing/operations/create_node.d.ts.map +1 -0
  97. package/dist/parsing/operations/create_node.js +51 -0
  98. package/dist/parsing/operations/create_node.js.map +1 -0
  99. package/dist/parsing/operations/create_relationship.d.ts +14 -0
  100. package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
  101. package/dist/parsing/operations/create_relationship.js +51 -0
  102. package/dist/parsing/operations/create_relationship.js.map +1 -0
  103. package/dist/parsing/operations/match.d.ts +15 -0
  104. package/dist/parsing/operations/match.d.ts.map +1 -0
  105. package/dist/parsing/operations/match.js +45 -0
  106. package/dist/parsing/operations/match.js.map +1 -0
  107. package/dist/parsing/operations/operation.d.ts +1 -0
  108. package/dist/parsing/operations/operation.d.ts.map +1 -1
  109. package/dist/parsing/operations/operation.js +6 -0
  110. package/dist/parsing/operations/operation.js.map +1 -1
  111. package/dist/parsing/operations/return.d.ts +1 -0
  112. package/dist/parsing/operations/return.d.ts.map +1 -1
  113. package/dist/parsing/operations/return.js +7 -1
  114. package/dist/parsing/operations/return.js.map +1 -1
  115. package/dist/parsing/operations/where.d.ts +1 -1
  116. package/dist/parsing/operations/where.d.ts.map +1 -1
  117. package/dist/parsing/operations/where.js +4 -0
  118. package/dist/parsing/operations/where.js.map +1 -1
  119. package/dist/parsing/parser.d.ts +10 -0
  120. package/dist/parsing/parser.d.ts.map +1 -1
  121. package/dist/parsing/parser.js +344 -5
  122. package/dist/parsing/parser.js.map +1 -1
  123. package/dist/parsing/token_to_node.d.ts.map +1 -1
  124. package/dist/parsing/token_to_node.js +7 -0
  125. package/dist/parsing/token_to_node.js.map +1 -1
  126. package/dist/tokenization/keyword.d.ts +1 -0
  127. package/dist/tokenization/keyword.d.ts.map +1 -1
  128. package/dist/tokenization/keyword.js +1 -0
  129. package/dist/tokenization/keyword.js.map +1 -1
  130. package/dist/tokenization/token.d.ts +4 -0
  131. package/dist/tokenization/token.d.ts.map +1 -1
  132. package/dist/tokenization/token.js +14 -1
  133. package/dist/tokenization/token.js.map +1 -1
  134. package/dist/tokenization/token_type.d.ts +1 -0
  135. package/dist/tokenization/token_type.d.ts.map +1 -1
  136. package/dist/tokenization/token_type.js +1 -0
  137. package/dist/tokenization/token_type.js.map +1 -1
  138. package/dist/tokenization/tokenizer.d.ts +2 -1
  139. package/dist/tokenization/tokenizer.d.ts.map +1 -1
  140. package/dist/tokenization/tokenizer.js +25 -12
  141. package/dist/tokenization/tokenizer.js.map +1 -1
  142. package/docs/flowquery.min.js +1 -1
  143. package/flowquery-py/README.md +166 -0
  144. package/flowquery-py/pyproject.toml +75 -0
  145. package/flowquery-py/setup_env.ps1 +92 -0
  146. package/flowquery-py/setup_env.sh +87 -0
  147. package/flowquery-py/src/__init__.py +34 -0
  148. package/flowquery-py/src/__main__.py +10 -0
  149. package/flowquery-py/src/compute/__init__.py +5 -0
  150. package/flowquery-py/src/compute/runner.py +60 -0
  151. package/flowquery-py/src/extensibility.py +52 -0
  152. package/flowquery-py/src/graph/__init__.py +31 -0
  153. package/flowquery-py/src/graph/data.py +118 -0
  154. package/flowquery-py/src/graph/database.py +82 -0
  155. package/flowquery-py/src/graph/hops.py +43 -0
  156. package/flowquery-py/src/graph/node.py +112 -0
  157. package/flowquery-py/src/graph/node_data.py +26 -0
  158. package/flowquery-py/src/graph/node_reference.py +49 -0
  159. package/flowquery-py/src/graph/pattern.py +125 -0
  160. package/flowquery-py/src/graph/pattern_expression.py +62 -0
  161. package/flowquery-py/src/graph/patterns.py +42 -0
  162. package/flowquery-py/src/graph/physical_node.py +40 -0
  163. package/flowquery-py/src/graph/physical_relationship.py +36 -0
  164. package/flowquery-py/src/graph/relationship.py +135 -0
  165. package/flowquery-py/src/graph/relationship_data.py +33 -0
  166. package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
  167. package/flowquery-py/src/graph/relationship_reference.py +21 -0
  168. package/flowquery-py/src/io/__init__.py +5 -0
  169. package/flowquery-py/src/io/command_line.py +67 -0
  170. package/flowquery-py/src/parsing/__init__.py +17 -0
  171. package/flowquery-py/src/parsing/alias.py +20 -0
  172. package/flowquery-py/src/parsing/alias_option.py +11 -0
  173. package/flowquery-py/src/parsing/ast_node.py +146 -0
  174. package/flowquery-py/src/parsing/base_parser.py +84 -0
  175. package/flowquery-py/src/parsing/components/__init__.py +19 -0
  176. package/flowquery-py/src/parsing/components/csv.py +8 -0
  177. package/flowquery-py/src/parsing/components/from_.py +10 -0
  178. package/flowquery-py/src/parsing/components/headers.py +12 -0
  179. package/flowquery-py/src/parsing/components/json.py +8 -0
  180. package/flowquery-py/src/parsing/components/null.py +10 -0
  181. package/flowquery-py/src/parsing/components/post.py +8 -0
  182. package/flowquery-py/src/parsing/components/text.py +8 -0
  183. package/flowquery-py/src/parsing/context.py +50 -0
  184. package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
  185. package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
  186. package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
  187. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
  188. package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
  189. package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
  190. package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
  191. package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
  192. package/flowquery-py/src/parsing/expressions/expression.py +138 -0
  193. package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
  194. package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
  195. package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
  196. package/flowquery-py/src/parsing/expressions/number.py +32 -0
  197. package/flowquery-py/src/parsing/expressions/operator.py +169 -0
  198. package/flowquery-py/src/parsing/expressions/reference.py +47 -0
  199. package/flowquery-py/src/parsing/expressions/string.py +27 -0
  200. package/flowquery-py/src/parsing/functions/__init__.py +75 -0
  201. package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
  202. package/flowquery-py/src/parsing/functions/async_function.py +62 -0
  203. package/flowquery-py/src/parsing/functions/avg.py +55 -0
  204. package/flowquery-py/src/parsing/functions/collect.py +75 -0
  205. package/flowquery-py/src/parsing/functions/function.py +68 -0
  206. package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
  207. package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
  208. package/flowquery-py/src/parsing/functions/functions.py +59 -0
  209. package/flowquery-py/src/parsing/functions/join.py +47 -0
  210. package/flowquery-py/src/parsing/functions/keys.py +34 -0
  211. package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
  212. package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
  213. package/flowquery-py/src/parsing/functions/rand.py +28 -0
  214. package/flowquery-py/src/parsing/functions/range_.py +34 -0
  215. package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
  216. package/flowquery-py/src/parsing/functions/replace.py +37 -0
  217. package/flowquery-py/src/parsing/functions/round_.py +32 -0
  218. package/flowquery-py/src/parsing/functions/size.py +32 -0
  219. package/flowquery-py/src/parsing/functions/split.py +47 -0
  220. package/flowquery-py/src/parsing/functions/stringify.py +47 -0
  221. package/flowquery-py/src/parsing/functions/sum.py +51 -0
  222. package/flowquery-py/src/parsing/functions/to_json.py +33 -0
  223. package/flowquery-py/src/parsing/functions/type_.py +47 -0
  224. package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
  225. package/flowquery-py/src/parsing/logic/__init__.py +15 -0
  226. package/flowquery-py/src/parsing/logic/case.py +29 -0
  227. package/flowquery-py/src/parsing/logic/else_.py +12 -0
  228. package/flowquery-py/src/parsing/logic/end.py +8 -0
  229. package/flowquery-py/src/parsing/logic/then.py +12 -0
  230. package/flowquery-py/src/parsing/logic/when.py +10 -0
  231. package/flowquery-py/src/parsing/operations/__init__.py +35 -0
  232. package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
  233. package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
  234. package/flowquery-py/src/parsing/operations/call.py +74 -0
  235. package/flowquery-py/src/parsing/operations/create_node.py +34 -0
  236. package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
  237. package/flowquery-py/src/parsing/operations/group_by.py +130 -0
  238. package/flowquery-py/src/parsing/operations/limit.py +22 -0
  239. package/flowquery-py/src/parsing/operations/load.py +140 -0
  240. package/flowquery-py/src/parsing/operations/match.py +29 -0
  241. package/flowquery-py/src/parsing/operations/operation.py +69 -0
  242. package/flowquery-py/src/parsing/operations/projection.py +21 -0
  243. package/flowquery-py/src/parsing/operations/return_op.py +50 -0
  244. package/flowquery-py/src/parsing/operations/unwind.py +37 -0
  245. package/flowquery-py/src/parsing/operations/where.py +41 -0
  246. package/flowquery-py/src/parsing/operations/with_op.py +18 -0
  247. package/flowquery-py/src/parsing/parser.py +1011 -0
  248. package/flowquery-py/src/parsing/token_to_node.py +109 -0
  249. package/flowquery-py/src/tokenization/__init__.py +23 -0
  250. package/flowquery-py/src/tokenization/keyword.py +48 -0
  251. package/flowquery-py/src/tokenization/operator.py +29 -0
  252. package/flowquery-py/src/tokenization/string_walker.py +158 -0
  253. package/flowquery-py/src/tokenization/symbol.py +19 -0
  254. package/flowquery-py/src/tokenization/token.py +659 -0
  255. package/flowquery-py/src/tokenization/token_mapper.py +52 -0
  256. package/flowquery-py/src/tokenization/token_type.py +21 -0
  257. package/flowquery-py/src/tokenization/tokenizer.py +214 -0
  258. package/flowquery-py/src/tokenization/trie.py +124 -0
  259. package/flowquery-py/src/utils/__init__.py +6 -0
  260. package/flowquery-py/src/utils/object_utils.py +20 -0
  261. package/flowquery-py/src/utils/string_utils.py +113 -0
  262. package/flowquery-py/tests/__init__.py +1 -0
  263. package/flowquery-py/tests/compute/__init__.py +1 -0
  264. package/flowquery-py/tests/compute/test_runner.py +1335 -0
  265. package/flowquery-py/tests/graph/__init__.py +1 -0
  266. package/flowquery-py/tests/graph/test_create.py +56 -0
  267. package/flowquery-py/tests/graph/test_data.py +73 -0
  268. package/flowquery-py/tests/graph/test_match.py +40 -0
  269. package/flowquery-py/tests/parsing/__init__.py +1 -0
  270. package/flowquery-py/tests/parsing/test_context.py +34 -0
  271. package/flowquery-py/tests/parsing/test_expression.py +49 -0
  272. package/flowquery-py/tests/parsing/test_parser.py +674 -0
  273. package/flowquery-py/tests/test_extensibility.py +611 -0
  274. package/flowquery-py/tests/tokenization/__init__.py +1 -0
  275. package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
  276. package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
  277. package/flowquery-py/tests/tokenization/test_trie.py +30 -0
  278. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  279. package/misc/apps/RAG/package.json +1 -1
  280. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
  281. package/misc/apps/RAG/src/components/index.ts +19 -10
  282. package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +21 -26
  283. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +24 -25
  284. package/misc/apps/RAG/src/plugins/loaders/Form.ts +163 -147
  285. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +103 -90
  286. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +80 -130
  287. package/misc/apps/RAG/src/plugins/loaders/Table.ts +104 -101
  288. package/misc/apps/RAG/src/plugins/loaders/Weather.ts +47 -36
  289. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +89 -78
  290. package/package.json +1 -1
  291. package/src/compute/runner.ts +24 -19
  292. package/src/graph/data.ts +112 -0
  293. package/src/graph/database.ts +63 -0
  294. package/src/graph/hops.ts +22 -0
  295. package/src/graph/node.ts +99 -0
  296. package/src/graph/node_data.ts +18 -0
  297. package/src/graph/node_reference.ts +33 -0
  298. package/src/graph/pattern.ts +101 -0
  299. package/src/graph/pattern_expression.ts +37 -0
  300. package/src/graph/patterns.ts +36 -0
  301. package/src/graph/physical_node.ts +23 -0
  302. package/src/graph/physical_relationship.ts +23 -0
  303. package/src/graph/relationship.ts +116 -0
  304. package/src/graph/relationship_data.ts +27 -0
  305. package/src/graph/relationship_match_collector.ts +58 -0
  306. package/src/graph/relationship_reference.ts +24 -0
  307. package/src/parsing/base_parser.ts +20 -14
  308. package/src/parsing/context.ts +14 -14
  309. package/src/parsing/expressions/boolean.ts +21 -0
  310. package/src/parsing/expressions/expression.ts +34 -26
  311. package/src/parsing/expressions/expression_map.ts +3 -0
  312. package/src/parsing/expressions/operator.ts +19 -1
  313. package/src/parsing/functions/function_factory.ts +45 -45
  314. package/src/parsing/operations/call.ts +3 -1
  315. package/src/parsing/operations/create_node.ts +39 -0
  316. package/src/parsing/operations/create_relationship.ts +38 -0
  317. package/src/parsing/operations/match.ts +31 -0
  318. package/src/parsing/operations/operation.ts +3 -0
  319. package/src/parsing/operations/return.ts +11 -7
  320. package/src/parsing/operations/where.ts +10 -6
  321. package/src/parsing/parser.ts +346 -8
  322. package/src/parsing/token_to_node.ts +6 -0
  323. package/src/tokenization/keyword.ts +41 -40
  324. package/src/tokenization/token.ts +21 -1
  325. package/src/tokenization/token_type.ts +2 -1
  326. package/src/tokenization/tokenizer.ts +52 -31
  327. package/tests/compute/runner.test.ts +660 -6
  328. package/tests/extensibility.test.ts +97 -93
  329. package/tests/graph/create.test.ts +36 -0
  330. package/tests/graph/data.test.ts +58 -0
  331. package/tests/graph/match.test.ts +29 -0
  332. package/tests/parsing/parser.test.ts +276 -8
  333. package/tests/tokenization/tokenizer.test.ts +107 -17
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * FlowQuery System Prompt Generator
3
- *
3
+ *
4
4
  * Generates a system prompt that instructs the LLM to create FlowQuery statements
5
5
  * based on natural language queries, with awareness of available loader plugins.
6
- *
6
+ *
7
7
  * Uses FlowQuery's built-in functions() introspection to dynamically discover
8
8
  * available async data loaders and their metadata.
9
9
  */
10
+ import { FunctionMetadata, OutputSchema, ParameterSchema } from "flowquery/extensibility";
10
11
 
11
- import { FunctionMetadata, ParameterSchema, OutputSchema } from 'flowquery/extensibility';
12
- import { getAllPluginMetadata, getAvailableLoaders } from '../plugins';
12
+ import { getAllPluginMetadata, getAvailableLoaders } from "../plugins";
13
13
 
14
14
  /**
15
15
  * FlowQuery language reference documentation.
@@ -28,25 +28,29 @@ FlowQuery is a declarative query language for data processing pipelines. It uses
28
28
  WITH expression1 AS var1, expression2 AS var2
29
29
  \`\`\`
30
30
 
31
- 2. **LOAD JSON FROM** - Load data from a URL or async data provider
31
+ 2. **LOAD JSON FROM** - Load data from a URL
32
32
  \`\`\`
33
33
  LOAD JSON FROM 'https://api.example.com/data' AS item
34
- LOAD JSON FROM myFunction(arg1, arg2) AS item
34
+ \`\`\`
35
+
36
+ 3. **CALL ... YIELD** - Call an async data provider function and yield its fields
37
+ \`\`\`
38
+ CALL myFunction(arg1, arg2) YIELD field1, field2, field3
35
39
  \`\`\`
36
40
 
37
- **IMPORTANT**: Async data providers (functions used after LOAD JSON FROM) cannot be nested inside other function calls. If you need to pass data from one async provider to another, first load the data into a variable using collect(), then pass that variable:
41
+ **IMPORTANT**: Async data providers (functions used with CALL) cannot be nested inside other function calls. If you need to pass data from one async provider to another, first load the data into a variable using collect(), then pass that variable:
38
42
  \`\`\`
39
43
  // WRONG - async providers cannot be nested:
40
- // LOAD JSON FROM table(mockProducts(5), 'Products') AS card
44
+ // CALL table(mockProducts(5), 'Products') YIELD html
41
45
 
42
46
  // CORRECT - collect data first, then pass to next provider:
43
- LOAD JSON FROM mockProducts(5) AS p
44
- WITH collect(p) AS products
45
- LOAD JSON FROM table(products, 'Products') AS card
46
- RETURN card
47
+ CALL mockProducts(5) YIELD id, name, price
48
+ WITH collect({ id: id, name: name, price: price }) AS products
49
+ CALL table(products, 'Products') YIELD html
50
+ RETURN html
47
51
  \`\`\`
48
52
 
49
- 3. **LOAD JSON FROM ... HEADERS ... POST** - Make HTTP requests with headers and body
53
+ 4. **LOAD JSON FROM ... HEADERS ... POST** - Make HTTP requests with headers and body
50
54
  \`\`\`
51
55
  LOAD JSON FROM 'https://api.example.com/data'
52
56
  HEADERS {
@@ -59,42 +63,38 @@ FlowQuery is a declarative query language for data processing pipelines. It uses
59
63
  } AS response
60
64
  \`\`\`
61
65
 
62
- 4. **UNWIND** - Expand arrays into individual rows
66
+ 5. **UNWIND** - Expand arrays into individual rows
63
67
  \`\`\`
64
68
  UNWIND [1, 2, 3] AS number
65
69
  UNWIND myArray AS item
66
70
  UNWIND range(0, 10) AS index
67
71
  \`\`\`
72
+
73
+ **IMPORTANT**: An UNWIND statement cannot be followed directly by a WHERE statement. If you need to filter after unwinding, use a WITH clause in between:
74
+ \`\`\`
75
+ // WRONG - UNWIND cannot be directly followed by WHERE:
76
+ // UNWIND items AS item
77
+ // WHERE item.active = true
78
+
79
+ // CORRECT - use WITH between UNWIND and WHERE:
80
+ UNWIND items AS item
81
+ WITH item
82
+ WHERE item.active = true
83
+ \`\`\`
68
84
 
69
- 5. **WHERE** - Filter results
85
+ 6. **WHERE** - Filter results
70
86
  \`\`\`
71
87
  WHERE item.active = true
72
88
  WHERE user.age > 18 AND user.name CONTAINS 'John'
73
89
  \`\`\`
74
90
 
75
- 6. **RETURN** - Specify output columns
91
+ 7. **RETURN** - Specify output columns
76
92
  \`\`\`
77
93
  RETURN item.name, item.value
78
94
  RETURN item.name AS Name, item.price AS Price
79
95
  RETURN * -- Return all fields
80
96
  \`\`\`
81
97
 
82
- 7. **ORDER BY** - Sort results
83
- \`\`\`
84
- ORDER BY item.name ASC
85
- ORDER BY item.price DESC, item.name ASC
86
- \`\`\`
87
-
88
- 8. **LIMIT** - Limit number of results
89
- \`\`\`
90
- LIMIT 10
91
- \`\`\`
92
-
93
- 9. **SKIP** - Skip a number of results
94
- \`\`\`
95
- SKIP 5
96
- \`\`\`
97
-
98
98
  ### Built-in Functions
99
99
 
100
100
  - **String Functions**: \`size()\`, \`substring()\`, \`trim()\`, \`toLower()\`, \`toUpper()\`, \`split()\`, \`join()\`, \`replace()\`, \`startsWith()\`, \`endsWith()\`, \`contains()\`
@@ -154,9 +154,12 @@ export class FlowQuerySystemPrompt {
154
154
  * Format a parameter schema into a readable string.
155
155
  */
156
156
  private static formatParameter(param: ParameterSchema): string {
157
- const required = param.required ? ' (required)' : ' (optional)';
158
- const defaultVal = param.default !== undefined ? `, default: ${JSON.stringify(param.default)}` : '';
159
- const enumVals = param.enum ? `, values: [${param.enum.map(v => JSON.stringify(v)).join(', ')}]` : '';
157
+ const required = param.required ? " (required)" : " (optional)";
158
+ const defaultVal =
159
+ param.default !== undefined ? `, default: ${JSON.stringify(param.default)}` : "";
160
+ const enumVals = param.enum
161
+ ? `, values: [${param.enum.map((v) => JSON.stringify(v)).join(", ")}]`
162
+ : "";
160
163
  return ` - \`${param.name}\`: ${param.type}${required}${defaultVal}${enumVals} - ${param.description}`;
161
164
  }
162
165
 
@@ -165,18 +168,18 @@ export class FlowQuerySystemPrompt {
165
168
  */
166
169
  private static formatOutput(output: OutputSchema): string {
167
170
  let result = ` Returns: ${output.type} - ${output.description}`;
168
-
171
+
169
172
  if (output.properties) {
170
- result += '\n Output properties:';
173
+ result += "\n Output properties:";
171
174
  for (const [key, prop] of Object.entries(output.properties)) {
172
175
  result += `\n - \`${key}\`: ${prop.type} - ${prop.description}`;
173
176
  }
174
177
  }
175
-
178
+
176
179
  if (output.example) {
177
180
  result += `\n Example output: ${JSON.stringify(output.example, null, 2)}`;
178
181
  }
179
-
182
+
180
183
  return result;
181
184
  }
182
185
 
@@ -185,38 +188,38 @@ export class FlowQuerySystemPrompt {
185
188
  */
186
189
  private static formatPluginDocumentation(plugin: FunctionMetadata): string {
187
190
  const lines: string[] = [];
188
-
191
+
189
192
  lines.push(`### \`${plugin.name}\``);
190
193
  lines.push(`**Description**: ${plugin.description}`);
191
-
194
+
192
195
  if (plugin.category) {
193
196
  lines.push(`**Category**: ${plugin.category}`);
194
197
  }
195
-
198
+
196
199
  if (plugin.parameters.length > 0) {
197
- lines.push('\n**Parameters**:');
200
+ lines.push("\n**Parameters**:");
198
201
  for (const param of plugin.parameters) {
199
202
  lines.push(this.formatParameter(param));
200
203
  }
201
204
  } else {
202
- lines.push('\n**Parameters**: None');
205
+ lines.push("\n**Parameters**: None");
203
206
  }
204
-
205
- lines.push('\n**Output**:');
207
+
208
+ lines.push("\n**Output**:");
206
209
  lines.push(this.formatOutput(plugin.output));
207
-
210
+
208
211
  if (plugin.examples && plugin.examples.length > 0) {
209
- lines.push('\n**Usage Examples**:');
212
+ lines.push("\n**Usage Examples**:");
210
213
  for (const example of plugin.examples) {
211
214
  lines.push(`\`\`\`\n${example}\n\`\`\``);
212
215
  }
213
216
  }
214
-
217
+
215
218
  if (plugin.notes) {
216
219
  lines.push(`\n**Notes**: ${plugin.notes}`);
217
220
  }
218
-
219
- return lines.join('\n');
221
+
222
+ return lines.join("\n");
220
223
  }
221
224
 
222
225
  /**
@@ -224,33 +227,37 @@ export class FlowQuerySystemPrompt {
224
227
  */
225
228
  private static generatePluginDocumentation(plugins: FunctionMetadata[]): string {
226
229
  if (plugins.length === 0) {
227
- return 'No data loader plugins are currently available.';
230
+ return "No data loader plugins are currently available.";
228
231
  }
229
-
232
+
230
233
  const sections: string[] = [];
231
-
234
+
232
235
  // Group plugins by category
233
236
  const byCategory = new Map<string, FunctionMetadata[]>();
234
237
  for (const plugin of plugins) {
235
- const category = plugin.category || 'general';
238
+ const category = plugin.category || "general";
236
239
  if (!byCategory.has(category)) {
237
240
  byCategory.set(category, []);
238
241
  }
239
242
  byCategory.get(category)!.push(plugin);
240
243
  }
241
-
242
- sections.push('## Available Data Loader Plugins\n');
243
- sections.push('The following async data loader functions are available for use with `LOAD JSON FROM`:\n');
244
-
244
+
245
+ sections.push("## Available Data Loader Plugins\n");
246
+ sections.push(
247
+ "The following async data loader functions are available for use with `CALL ... YIELD`:\n"
248
+ );
249
+
245
250
  for (const [category, categoryPlugins] of byCategory) {
246
- sections.push(`\n### Category: ${category.charAt(0).toUpperCase() + category.slice(1)}\n`);
251
+ sections.push(
252
+ `\n### Category: ${category.charAt(0).toUpperCase() + category.slice(1)}\n`
253
+ );
247
254
  for (const plugin of categoryPlugins) {
248
255
  sections.push(this.formatPluginDocumentation(plugin));
249
- sections.push('---');
256
+ sections.push("---");
250
257
  }
251
258
  }
252
-
253
- return sections.join('\n');
259
+
260
+ return sections.join("\n");
254
261
  }
255
262
 
256
263
  /**
@@ -296,15 +303,15 @@ ${FLOWQUERY_LANGUAGE_REFERENCE}
296
303
 
297
304
  ${pluginDocs}
298
305
 
299
- ${additionalContext ? `## Additional Context\n\n${additionalContext}` : ''}
306
+ ${additionalContext ? `## Additional Context\n\n${additionalContext}` : ""}
300
307
 
301
308
  ## Example Response Format
302
309
 
303
310
  **When a query is needed**:
304
311
  \`\`\`flowquery
305
- LOAD JSON FROM pluginName(args) AS item
306
- WHERE item.field = 'value'
307
- RETURN item.name AS Name, item.value AS Value
312
+ CALL pluginName(args) YIELD field1, field2, field3
313
+ WHERE field1 = 'value'
314
+ RETURN field1 AS Name, field2 AS Value
308
315
  \`\`\`
309
316
 
310
317
  **When no query is needed** (e.g., general questions about FlowQuery):
@@ -317,7 +324,7 @@ Now help the user with their request.`;
317
324
  /**
318
325
  * Generate the complete FlowQuery system prompt.
319
326
  * Uses FlowQuery's introspection via functions() as the single source of truth.
320
- *
327
+ *
321
328
  * @param additionalContext - Optional additional context to include in the prompt
322
329
  * @returns The complete system prompt string
323
330
  */
@@ -325,14 +332,14 @@ Now help the user with their request.`;
325
332
  // Uses FlowQuery's introspection to get available async providers
326
333
  const plugins = getAllPluginMetadata();
327
334
  const pluginDocs = this.generatePluginDocumentation(plugins);
328
-
335
+
329
336
  return this.buildSystemPrompt(pluginDocs, additionalContext);
330
337
  }
331
338
 
332
339
  /**
333
340
  * Generate a system prompt for the interpretation phase.
334
341
  * Used after FlowQuery execution to interpret results.
335
- *
342
+ *
336
343
  * @returns The interpretation system prompt string
337
344
  */
338
345
  public static generateInterpretationPrompt(): string {
@@ -363,8 +370,8 @@ You are now receiving the execution results. Your job is to:
363
370
  */
364
371
  public static getMinimalPrompt(): string {
365
372
  const plugins = getAllPluginMetadata();
366
- const pluginList = plugins.map(p => `- \`${p.name}\`: ${p.description}`).join('\n');
367
-
373
+ const pluginList = plugins.map((p) => `- \`${p.name}\`: ${p.description}`).join("\n");
374
+
368
375
  return `You are a FlowQuery assistant. Generate FlowQuery statements based on user requests.
369
376
 
370
377
  Available data loader plugins:
@@ -379,7 +386,7 @@ Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
379
386
  /**
380
387
  * Generate the FlowQuery system prompt asynchronously using functions() introspection.
381
388
  * This is the preferred method that uses FlowQuery's built-in introspection.
382
- *
389
+ *
383
390
  * @param additionalContext - Optional additional context to include in the prompt
384
391
  * @returns Promise resolving to the complete system prompt string
385
392
  */
@@ -387,15 +394,19 @@ Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
387
394
  // Use FlowQuery's functions() introspection to discover available loaders
388
395
  const plugins = await getAvailableLoaders();
389
396
  const pluginDocs = this.generatePluginDocumentation(plugins);
390
-
397
+
391
398
  return this.buildSystemPrompt(pluginDocs, additionalContext);
392
399
  }
393
400
  }
394
401
 
395
402
  // Export functions for backward compatibility
396
- export const generateFlowQuerySystemPrompt = FlowQuerySystemPrompt.generate.bind(FlowQuerySystemPrompt);
397
- export const generateInterpretationPrompt = FlowQuerySystemPrompt.generateInterpretationPrompt.bind(FlowQuerySystemPrompt);
398
- export const getMinimalFlowQueryPrompt = FlowQuerySystemPrompt.getMinimalPrompt.bind(FlowQuerySystemPrompt);
399
- export const generateFlowQuerySystemPromptAsync = FlowQuerySystemPrompt.generateAsync.bind(FlowQuerySystemPrompt);
403
+ export const generateFlowQuerySystemPrompt =
404
+ FlowQuerySystemPrompt.generate.bind(FlowQuerySystemPrompt);
405
+ export const generateInterpretationPrompt =
406
+ FlowQuerySystemPrompt.generateInterpretationPrompt.bind(FlowQuerySystemPrompt);
407
+ export const getMinimalFlowQueryPrompt =
408
+ FlowQuerySystemPrompt.getMinimalPrompt.bind(FlowQuerySystemPrompt);
409
+ export const generateFlowQuerySystemPromptAsync =
410
+ FlowQuerySystemPrompt.generateAsync.bind(FlowQuerySystemPrompt);
400
411
 
401
412
  export default FlowQuerySystemPrompt;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowquery",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "A declarative query language for data processing pipelines.",
5
5
  "main": "dist/index.node.js",
6
6
  "types": "dist/index.node.d.ts",
@@ -1,14 +1,15 @@
1
+ import ASTNode from "../parsing/ast_node";
2
+ import Function from "../parsing/functions/function";
3
+ import { FunctionMetadata } from "../parsing/functions/function_metadata";
1
4
  import Operation from "../parsing/operations/operation";
2
5
  import Parser from "../parsing/parser";
3
- import { FunctionMetadata } from "../parsing/functions/function_metadata";
4
- import Function from "../parsing/functions/function";
5
6
 
6
7
  /**
7
8
  * Executes a FlowQuery statement and retrieves the results.
8
- *
9
+ *
9
10
  * The Runner class parses a FlowQuery statement into an AST and executes it,
10
11
  * managing the execution flow from the first operation to the final return statement.
11
- *
12
+ *
12
13
  * @example
13
14
  * ```typescript
14
15
  * const runner = new Runner("WITH 1 as x RETURN x");
@@ -24,7 +25,11 @@ class Runner {
24
25
  * List all registered functions with their metadata.
25
26
  * Added dynamically in index.browser.ts / index.node.ts
26
27
  */
27
- static listFunctions: (options?: { category?: string; asyncOnly?: boolean; syncOnly?: boolean }) => FunctionMetadata[];
28
+ static listFunctions: (options?: {
29
+ category?: string;
30
+ asyncOnly?: boolean;
31
+ syncOnly?: boolean;
32
+ }) => FunctionMetadata[];
28
33
 
29
34
  /**
30
35
  * Get metadata for a specific function.
@@ -37,32 +42,32 @@ class Runner {
37
42
  * Added dynamically in index.browser.ts / index.node.ts
38
43
  */
39
44
  static Function: typeof Function;
40
-
45
+
41
46
  /**
42
47
  * Creates a new Runner instance and parses the FlowQuery statement.
43
- *
48
+ *
44
49
  * @param statement - The FlowQuery statement to execute
45
50
  * @throws {Error} If the statement is null, empty, or contains syntax errors
46
51
  */
47
- constructor(statement: string | null = null) {
48
- if(statement === null || statement === "") {
49
- throw new Error("Statement cannot be null or empty");
52
+ constructor(statement: string | null = null, ast: ASTNode | null = null) {
53
+ if ((statement === null || statement === "") && ast === null) {
54
+ throw new Error("Either statement or AST must be provided");
50
55
  }
51
- const parser = new Parser();
52
- const ast = parser.parse(statement);
53
- this.first = ast.firstChild() as Operation;
54
- this.last = ast.lastChild() as Operation;
56
+ const _ast = ast !== null ? ast : new Parser().parse(statement!);
57
+ this.first = _ast.firstChild() as Operation;
58
+ this.last = _ast.lastChild() as Operation;
55
59
  }
56
-
60
+
57
61
  /**
58
62
  * Executes the parsed FlowQuery statement.
59
- *
63
+ *
60
64
  * @returns A promise that resolves when execution completes
61
65
  * @throws {Error} If an error occurs during execution
62
66
  */
63
67
  public async run(): Promise<void> {
64
68
  return new Promise<void>(async (resolve, reject) => {
65
69
  try {
70
+ await this.first.initialize();
66
71
  await this.first.run();
67
72
  await this.first.finish();
68
73
  resolve();
@@ -71,10 +76,10 @@ class Runner {
71
76
  }
72
77
  });
73
78
  }
74
-
79
+
75
80
  /**
76
81
  * Gets the results from the executed statement.
77
- *
82
+ *
78
83
  * @returns The results from the last operation (typically a RETURN statement)
79
84
  */
80
85
  public get results(): any {
@@ -82,4 +87,4 @@ class Runner {
82
87
  }
83
88
  }
84
89
 
85
- export default Runner;
90
+ export default Runner;
@@ -0,0 +1,112 @@
1
+ class IndexEntry {
2
+ private _positions: number[];
3
+ private _index: number = -1;
4
+
5
+ constructor(positions: number[] = []) {
6
+ this._positions = positions;
7
+ }
8
+ public add(position: number): void {
9
+ this._positions.push(position);
10
+ }
11
+ public get position(): number {
12
+ return this._positions[this._index];
13
+ }
14
+ public reset(): void {
15
+ this._index = -1;
16
+ }
17
+ public next(): boolean {
18
+ if (this._index < this._positions.length - 1) {
19
+ this._index++;
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ public clone(): IndexEntry {
25
+ return new IndexEntry([...this._positions]);
26
+ }
27
+ }
28
+
29
+ class Layer {
30
+ private _index: Map<string, IndexEntry> = new Map();
31
+ private _current: number = -1;
32
+ constructor(index: Map<string, IndexEntry>) {
33
+ this._index = index;
34
+ }
35
+ public get index(): Map<string, IndexEntry> {
36
+ return this._index;
37
+ }
38
+ public get current(): number {
39
+ return this._current;
40
+ }
41
+ public set current(value: number) {
42
+ this._current = value;
43
+ }
44
+ }
45
+
46
+ class Data {
47
+ protected _records: Record<string, any>[] = [];
48
+ private _layers: Map<number, Layer> = new Map();
49
+
50
+ constructor(records: Record<string, any>[] = []) {
51
+ this._records = records;
52
+ this._layers.set(0, new Layer(new Map()));
53
+ }
54
+ protected _buildIndex(key: string, level: number = 0): void {
55
+ this.layer(level).index.clear();
56
+ this._records.forEach((record, idx) => {
57
+ if (record.hasOwnProperty(key)) {
58
+ if (!this.layer(level).index.has(record[key])) {
59
+ this.layer(level).index.set(record[key], new IndexEntry());
60
+ }
61
+ this.layer(level).index.get(record[key])!.add(idx);
62
+ }
63
+ });
64
+ }
65
+ public layer(level: number = 0): Layer {
66
+ if (!this._layers.has(level)) {
67
+ const first = this._layers.get(0)!;
68
+ const cloned = new Map<string, IndexEntry>();
69
+ for (const [key, entry] of first.index) {
70
+ cloned.set(key, entry.clone());
71
+ }
72
+ this._layers.set(level, new Layer(cloned));
73
+ }
74
+ return this._layers.get(level)!;
75
+ }
76
+ protected _find(key: string, level: number = 0): boolean {
77
+ if (!this.layer(level).index.has(key)) {
78
+ this.layer(level).current = this._records.length; // Move to end
79
+ return false;
80
+ } else {
81
+ const entry = this.layer(level).index.get(key)!;
82
+ const more = entry.next();
83
+ if (!more) {
84
+ this.layer(level).current = this._records.length; // Move to end
85
+ return false;
86
+ }
87
+ this.layer(level).current = entry.position;
88
+ return true;
89
+ }
90
+ }
91
+ public reset(): void {
92
+ this.layer(0).current = -1;
93
+ for (const entry of this.layer(0).index.values()) {
94
+ entry.reset();
95
+ }
96
+ }
97
+ public next(level: number = 0): boolean {
98
+ if (this.layer(level).current < this._records.length - 1) {
99
+ this.layer(level).current++;
100
+ return true;
101
+ }
102
+ return false;
103
+ }
104
+ public current(level: number = 0): Record<string, any> | null {
105
+ if (this.layer(level).current < this._records.length) {
106
+ return this._records[this.layer(level).current];
107
+ }
108
+ return null;
109
+ }
110
+ }
111
+
112
+ export default Data;
@@ -0,0 +1,63 @@
1
+ import ASTNode from "../parsing/ast_node";
2
+ import Node from "./node";
3
+ import NodeData, { NodeRecord } from "./node_data";
4
+ import PhysicalNode from "./physical_node";
5
+ import PhysicalRelationship from "./physical_relationship";
6
+ import Relationship from "./relationship";
7
+ import RelationshipData, { RelationshipRecord } from "./relationship_data";
8
+
9
+ class Database {
10
+ private static instance: Database;
11
+ private static nodes: Map<string, PhysicalNode> = new Map();
12
+ private static relationships: Map<string, PhysicalRelationship> = new Map();
13
+
14
+ public static getInstance(): Database {
15
+ if (!Database.instance) {
16
+ Database.instance = new Database();
17
+ }
18
+ return Database.instance;
19
+ }
20
+ public addNode(node: Node, statement: ASTNode): void {
21
+ if (node.label === null) {
22
+ throw new Error("Node label is null");
23
+ }
24
+ const physical = new PhysicalNode(null, node.label);
25
+ physical.statement = statement;
26
+ Database.nodes.set(node.label, physical);
27
+ }
28
+ public getNode(node: Node): PhysicalNode | null {
29
+ return Database.nodes.get(node.label!) || null;
30
+ }
31
+ public addRelationship(relationship: Relationship, statement: ASTNode): void {
32
+ if (relationship.type === null) {
33
+ throw new Error("Relationship type is null");
34
+ }
35
+ const physical = new PhysicalRelationship(null, relationship.type);
36
+ physical.statement = statement;
37
+ Database.relationships.set(relationship.type, physical);
38
+ }
39
+ public getRelationship(relationship: Relationship): PhysicalRelationship | null {
40
+ return Database.relationships.get(relationship.type!) || null;
41
+ }
42
+ public async getData(element: Node | Relationship): Promise<NodeData | RelationshipData> {
43
+ if (element instanceof Node) {
44
+ const node = this.getNode(element);
45
+ if (node === null) {
46
+ throw new Error(`Physical node not found for label ${element.label}`);
47
+ }
48
+ const data = await node.data();
49
+ return new NodeData(data as NodeRecord[]);
50
+ } else if (element instanceof Relationship) {
51
+ const relationship = this.getRelationship(element);
52
+ if (relationship === null) {
53
+ throw new Error(`Physical relationship not found for type ${element.type}`);
54
+ }
55
+ const data = await relationship.data();
56
+ return new RelationshipData(data as RelationshipRecord[]);
57
+ } else {
58
+ throw new Error("Element is neither Node nor Relationship");
59
+ }
60
+ }
61
+ }
62
+
63
+ export default Database;
@@ -0,0 +1,22 @@
1
+ class Hops {
2
+ private _min: number = 0;
3
+ private _max: number = 1;
4
+
5
+ public set min(min: number) {
6
+ this._min = min;
7
+ }
8
+ public get min(): number {
9
+ return this._min;
10
+ }
11
+ public set max(max: number) {
12
+ this._max = max;
13
+ }
14
+ public get max(): number {
15
+ return this._max;
16
+ }
17
+ public multi(): boolean {
18
+ return this._max > 1 || this._max === -1;
19
+ }
20
+ }
21
+
22
+ export default Hops;