flowquery 1.0.11 → 1.0.12
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 +141 -37
- package/dist/flowquery.min.js +1 -1
- package/dist/parsing/functions/function_metadata.d.ts +3 -3
- package/dist/parsing/functions/function_metadata.d.ts.map +1 -1
- package/dist/parsing/functions/function_metadata.js +6 -12
- package/dist/parsing/functions/function_metadata.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/README.md +0 -12
- package/misc/apps/RAG/package.json +1 -1
- package/package.json +1 -1
- package/src/parsing/functions/function_metadata.ts +6 -13
- package/tests/extensibility.test.ts +42 -4
package/README.md
CHANGED
|
@@ -145,45 +145,137 @@ return data
|
|
|
145
145
|
|
|
146
146
|
## Extending FlowQuery with Custom Functions
|
|
147
147
|
|
|
148
|
-
FlowQuery
|
|
148
|
+
FlowQuery supports extending its functionality with custom functions using the `@FunctionDef` decorator. You can create scalar functions, aggregate functions, predicate functions, and async data providers.
|
|
149
|
+
|
|
150
|
+
### Installing the Extensibility API
|
|
151
|
+
|
|
152
|
+
Import the necessary classes and decorators from the extensibility module:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import {
|
|
156
|
+
Function,
|
|
157
|
+
AggregateFunction,
|
|
158
|
+
PredicateFunction,
|
|
159
|
+
ReducerElement,
|
|
160
|
+
FunctionDef
|
|
161
|
+
} from 'flowquery/extensibility';
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Creating a Custom Scalar Function
|
|
165
|
+
|
|
166
|
+
Scalar functions operate on individual values and return a result:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { Function, FunctionDef } from 'flowquery/extensibility';
|
|
170
|
+
|
|
171
|
+
@FunctionDef({
|
|
172
|
+
description: "Doubles a number",
|
|
173
|
+
category: "scalar",
|
|
174
|
+
parameters: [{ name: "value", description: "Number to double", type: "number" }],
|
|
175
|
+
output: { description: "Doubled value", type: "number" }
|
|
176
|
+
})
|
|
177
|
+
class Double extends Function {
|
|
178
|
+
constructor() {
|
|
179
|
+
super("double");
|
|
180
|
+
this._expectedParameterCount = 1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public value(): number {
|
|
184
|
+
return this.getChildren()[0].value() * 2;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Once defined, use it in your queries:
|
|
190
|
+
|
|
191
|
+
```cypher
|
|
192
|
+
WITH 5 AS num RETURN double(num) AS result
|
|
193
|
+
// Returns: [{ result: 10 }]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Creating a Custom String Function
|
|
149
197
|
|
|
150
198
|
```typescript
|
|
151
|
-
import { Function, FunctionDef } from
|
|
199
|
+
import { Function, FunctionDef } from 'flowquery/extensibility';
|
|
152
200
|
|
|
153
201
|
@FunctionDef({
|
|
154
|
-
description: "
|
|
155
|
-
category: "
|
|
156
|
-
parameters: [
|
|
157
|
-
|
|
158
|
-
],
|
|
159
|
-
output: {
|
|
160
|
-
description: "Uppercase string",
|
|
161
|
-
type: "string",
|
|
162
|
-
example: "HELLO WORLD"
|
|
163
|
-
},
|
|
164
|
-
examples: ["WITH 'hello' AS s RETURN uppercase(s)"]
|
|
202
|
+
description: "Reverses a string",
|
|
203
|
+
category: "scalar",
|
|
204
|
+
parameters: [{ name: "text", description: "String to reverse", type: "string" }],
|
|
205
|
+
output: { description: "Reversed string", type: "string" }
|
|
165
206
|
})
|
|
166
|
-
class
|
|
207
|
+
class StrReverse extends Function {
|
|
167
208
|
constructor() {
|
|
168
|
-
super("
|
|
169
|
-
this._expectedParameterCount = 1;
|
|
209
|
+
super("strreverse");
|
|
210
|
+
this._expectedParameterCount = 1;
|
|
170
211
|
}
|
|
171
212
|
|
|
172
213
|
public value(): string {
|
|
173
|
-
const input = this.getChildren()[0].value();
|
|
174
|
-
return
|
|
214
|
+
const input = String(this.getChildren()[0].value());
|
|
215
|
+
return input.split('').reverse().join('');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Usage:
|
|
221
|
+
|
|
222
|
+
```cypher
|
|
223
|
+
WITH 'hello' AS s RETURN strreverse(s) AS reversed
|
|
224
|
+
// Returns: [{ reversed: 'olleh' }]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Creating a Custom Aggregate Function
|
|
228
|
+
|
|
229
|
+
Aggregate functions process multiple values and return a single result. They require a `ReducerElement` to track state:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { AggregateFunction, ReducerElement, FunctionDef } from 'flowquery/extensibility';
|
|
233
|
+
|
|
234
|
+
class ProductElement extends ReducerElement {
|
|
235
|
+
private _value: number = 1;
|
|
236
|
+
public get value(): number {
|
|
237
|
+
return this._value;
|
|
238
|
+
}
|
|
239
|
+
public set value(v: number) {
|
|
240
|
+
this._value *= v;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@FunctionDef({
|
|
245
|
+
description: "Calculates the product of values",
|
|
246
|
+
category: "aggregate",
|
|
247
|
+
parameters: [{ name: "value", description: "Number to multiply", type: "number" }],
|
|
248
|
+
output: { description: "Product of all values", type: "number" }
|
|
249
|
+
})
|
|
250
|
+
class Product extends AggregateFunction {
|
|
251
|
+
constructor() {
|
|
252
|
+
super("product");
|
|
253
|
+
this._expectedParameterCount = 1;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
public reduce(element: ReducerElement): void {
|
|
257
|
+
element.value = this.firstChild().value();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public element(): ReducerElement {
|
|
261
|
+
return new ProductElement();
|
|
175
262
|
}
|
|
176
263
|
}
|
|
177
264
|
```
|
|
178
265
|
|
|
179
|
-
|
|
266
|
+
Usage:
|
|
267
|
+
|
|
268
|
+
```cypher
|
|
269
|
+
UNWIND [2, 3, 4] AS num RETURN product(num) AS result
|
|
270
|
+
// Returns: [{ result: 24 }]
|
|
271
|
+
```
|
|
180
272
|
|
|
181
|
-
### Creating Async Data
|
|
273
|
+
### Creating a Custom Async Data Provider
|
|
182
274
|
|
|
183
|
-
|
|
275
|
+
Async providers allow you to create custom data sources that can be used with `LOAD JSON FROM`:
|
|
184
276
|
|
|
185
277
|
```typescript
|
|
186
|
-
import { FunctionDef } from
|
|
278
|
+
import { FunctionDef } from 'flowquery/extensibility';
|
|
187
279
|
|
|
188
280
|
@FunctionDef({
|
|
189
281
|
description: "Provides example data for testing",
|
|
@@ -191,7 +283,7 @@ import { FunctionDef } from "flowquery/extensibility";
|
|
|
191
283
|
parameters: [],
|
|
192
284
|
output: { description: "Example data object", type: "object" }
|
|
193
285
|
})
|
|
194
|
-
class
|
|
286
|
+
class GetExampleData {
|
|
195
287
|
async *fetch(): AsyncGenerator<any> {
|
|
196
288
|
yield { id: 1, name: "Alice" };
|
|
197
289
|
yield { id: 2, name: "Bob" };
|
|
@@ -199,23 +291,35 @@ class GetExampleDataLoader {
|
|
|
199
291
|
}
|
|
200
292
|
```
|
|
201
293
|
|
|
202
|
-
|
|
294
|
+
Usage:
|
|
295
|
+
|
|
296
|
+
```cypher
|
|
297
|
+
LOAD JSON FROM getExampleData() AS data RETURN data.id AS id, data.name AS name
|
|
298
|
+
// Returns: [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }]
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Using Custom Functions with Expressions
|
|
203
302
|
|
|
204
|
-
|
|
303
|
+
Custom functions integrate seamlessly with FlowQuery expressions and can be combined with other functions:
|
|
205
304
|
|
|
206
305
|
```cypher
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
- `
|
|
217
|
-
|
|
218
|
-
|
|
306
|
+
// Using custom function with expressions
|
|
307
|
+
WITH 5 * 3 AS num RETURN addhundred(num) + 1 AS result
|
|
308
|
+
|
|
309
|
+
// Using multiple custom functions together
|
|
310
|
+
WITH 2 AS num RETURN triple(num) AS tripled, square(num) AS squared
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Introspecting Registered Functions
|
|
314
|
+
|
|
315
|
+
You can use the built-in `functions()` function to discover registered functions including your custom ones:
|
|
316
|
+
|
|
317
|
+
```cypher
|
|
318
|
+
WITH functions() AS funcs
|
|
319
|
+
UNWIND funcs AS f
|
|
320
|
+
WITH f WHERE f.name = 'double'
|
|
321
|
+
RETURN f.name AS name, f.description AS description, f.category AS category
|
|
322
|
+
```
|
|
219
323
|
|
|
220
324
|
## Contributing
|
|
221
325
|
|