flowquery 1.0.6 → 1.0.8

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 (49) hide show
  1. package/README.md +30 -138
  2. package/dist/compute/runner.d.ts +1 -22
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js.map +1 -1
  5. package/dist/extensibility.d.ts +28 -2
  6. package/dist/extensibility.d.ts.map +1 -1
  7. package/dist/extensibility.js +39 -15
  8. package/dist/extensibility.js.map +1 -1
  9. package/dist/flowquery.min.js +1 -1
  10. package/dist/index.browser.d.ts.map +1 -1
  11. package/dist/index.browser.js +0 -80
  12. package/dist/index.browser.js.map +1 -1
  13. package/dist/index.node.d.ts +3 -3
  14. package/dist/index.node.d.ts.map +1 -1
  15. package/dist/index.node.js +0 -80
  16. package/dist/index.node.js.map +1 -1
  17. package/dist/parsing/functions/function_factory.d.ts +3 -80
  18. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  19. package/dist/parsing/functions/function_factory.js +8 -127
  20. package/dist/parsing/functions/function_factory.js.map +1 -1
  21. package/dist/parsing/functions/function_metadata.d.ts +28 -35
  22. package/dist/parsing/functions/function_metadata.d.ts.map +1 -1
  23. package/dist/parsing/functions/function_metadata.js +88 -61
  24. package/dist/parsing/functions/function_metadata.js.map +1 -1
  25. package/docs/flowquery.min.js +1 -1
  26. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  27. package/misc/apps/RAG/package.json +1 -1
  28. package/misc/apps/RAG/src/plugins/index.ts +29 -33
  29. package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +28 -32
  30. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +29 -33
  31. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +55 -59
  32. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +61 -71
  33. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +8 -8
  34. package/package.json +1 -1
  35. package/src/compute/runner.ts +1 -26
  36. package/src/extensibility.ts +38 -2
  37. package/src/index.browser.ts +2 -88
  38. package/src/index.node.ts +3 -92
  39. package/src/parsing/functions/function_factory.ts +13 -154
  40. package/src/parsing/functions/function_metadata.ts +96 -94
  41. package/tests/extensibility.test.ts +601 -0
  42. package/dist/parsing/functions/extensibility/index.d.ts +0 -37
  43. package/dist/parsing/functions/extensibility/index.d.ts.map +0 -1
  44. package/dist/parsing/functions/extensibility/index.js +0 -50
  45. package/dist/parsing/functions/extensibility/index.js.map +0 -1
  46. package/misc/apps/RAG/src/plugins/PluginRegistry.ts +0 -136
  47. package/misc/apps/RAG/src/plugins/types.ts +0 -52
  48. package/src/parsing/functions/extensibility/index.ts +0 -54
  49. package/tests/parsing/function_plugins.test.ts +0 -369
@@ -6,13 +6,39 @@
6
6
  * RETURN fact.text
7
7
  */
8
8
 
9
- import { AsyncLoaderPlugin } from '../types';
9
+ import { FunctionDef } from 'flowquery/extensibility';
10
10
 
11
11
  const CAT_FACTS_API = 'https://catfact.ninja/facts';
12
12
 
13
13
  /**
14
14
  * CatFacts loader class - fetches random cat facts from the Cat Facts API.
15
15
  */
16
+ @FunctionDef({
17
+ isAsyncProvider: true,
18
+ description: 'Fetches random cat facts from the Cat Facts API (catfact.ninja)',
19
+ category: 'examples',
20
+ parameters: [
21
+ {
22
+ name: 'count',
23
+ description: 'Number of cat facts to fetch',
24
+ type: 'number',
25
+ required: false,
26
+ default: 1
27
+ }
28
+ ],
29
+ output: {
30
+ description: 'Cat fact object',
31
+ type: 'object',
32
+ properties: {
33
+ text: { description: 'The cat fact text', type: 'string' },
34
+ length: { description: 'Length of the fact text', type: 'number' }
35
+ }
36
+ },
37
+ examples: [
38
+ "LOAD JSON FROM catFacts() AS fact RETURN fact.text",
39
+ "LOAD JSON FROM catFacts(5) AS fact RETURN fact.text, fact.length AS length"
40
+ ]
41
+ })
16
42
  export class CatFactsLoader {
17
43
  private readonly apiUrl: string;
18
44
 
@@ -46,34 +72,4 @@ export class CatFactsLoader {
46
72
  }
47
73
  }
48
74
 
49
- export const catFactsPlugin: AsyncLoaderPlugin = {
50
- name: 'catFacts',
51
- provider: (count: number = 1) => new CatFactsLoader().fetch(count),
52
- metadata: {
53
- description: 'Fetches random cat facts from the Cat Facts API (catfact.ninja)',
54
- category: 'examples',
55
- parameters: [
56
- {
57
- name: 'count',
58
- description: 'Number of cat facts to fetch',
59
- type: 'number',
60
- required: false,
61
- default: 1
62
- }
63
- ],
64
- output: {
65
- description: 'Cat fact object',
66
- type: 'object',
67
- properties: {
68
- text: { description: 'The cat fact text', type: 'string' },
69
- length: { description: 'Length of the fact text', type: 'number' }
70
- }
71
- },
72
- examples: [
73
- "LOAD JSON FROM catFacts() AS fact RETURN fact.text",
74
- "LOAD JSON FROM catFacts(5) AS fact RETURN fact.text, fact.length AS length"
75
- ]
76
- }
77
- };
78
-
79
- export default catFactsPlugin;
75
+ export default CatFactsLoader;
@@ -6,11 +6,38 @@
6
6
  * RETURN item.name, item.value
7
7
  */
8
8
 
9
- import { AsyncLoaderPlugin } from '../types';
9
+ import { FunctionDef } from 'flowquery/extensibility';
10
10
 
11
11
  /**
12
12
  * FetchJson loader class - fetches JSON data from a URL and yields items.
13
13
  */
14
+ @FunctionDef({
15
+ isAsyncProvider: true,
16
+ description: 'Fetches JSON data from a URL. If the response is an array, yields each item individually.',
17
+ category: 'data',
18
+ parameters: [
19
+ {
20
+ name: 'url',
21
+ description: 'The URL to fetch JSON from',
22
+ type: 'string',
23
+ required: true
24
+ },
25
+ {
26
+ name: 'options',
27
+ description: 'Optional fetch options (headers, method, etc.)',
28
+ type: 'object',
29
+ required: false
30
+ }
31
+ ],
32
+ output: {
33
+ description: 'JSON data items',
34
+ type: 'object'
35
+ },
36
+ examples: [
37
+ "LOAD JSON FROM fetchJson('https://api.example.com/users') AS user RETURN user.name",
38
+ "LOAD JSON FROM fetchJson('https://api.example.com/data') AS item RETURN item WHERE item.active = true"
39
+ ]
40
+ })
14
41
  export class FetchJsonLoader {
15
42
  /**
16
43
  * Fetches JSON data from a URL and yields each item if array, or the object itself.
@@ -37,35 +64,4 @@ export class FetchJsonLoader {
37
64
  }
38
65
  }
39
66
 
40
- export const fetchJsonPlugin: AsyncLoaderPlugin = {
41
- name: 'fetchJson',
42
- provider: (url: string, options?: RequestInit) => new FetchJsonLoader().fetch(url, options),
43
- metadata: {
44
- description: 'Fetches JSON data from a URL. If the response is an array, yields each item individually.',
45
- category: 'data',
46
- parameters: [
47
- {
48
- name: 'url',
49
- description: 'The URL to fetch JSON from',
50
- type: 'string',
51
- required: true
52
- },
53
- {
54
- name: 'options',
55
- description: 'Optional fetch options (headers, method, etc.)',
56
- type: 'object',
57
- required: false
58
- }
59
- ],
60
- output: {
61
- description: 'JSON data items',
62
- type: 'object'
63
- },
64
- examples: [
65
- "LOAD JSON FROM fetchJson('https://api.example.com/users') AS user RETURN user.name",
66
- "LOAD JSON FROM fetchJson('https://api.example.com/data') AS item RETURN item WHERE item.active = true"
67
- ]
68
- }
69
- };
70
-
71
- export default fetchJsonPlugin;
67
+ export default FetchJsonLoader;
@@ -16,7 +16,7 @@
16
16
  * console.log(response.choices[0].message.content);
17
17
  */
18
18
 
19
- import { AsyncLoaderPlugin } from '../types';
19
+ import { FunctionDef } from 'flowquery/extensibility';
20
20
 
21
21
  // Default configuration - can be overridden via options
22
22
  const DEFAULT_CONFIG = {
@@ -80,6 +80,59 @@ export interface LlmResponse {
80
80
  /**
81
81
  * LLM Loader class - calls OpenAI-compatible APIs for chat completions.
82
82
  */
83
+ @FunctionDef({
84
+ isAsyncProvider: true,
85
+ description: 'Calls OpenAI-compatible chat completion APIs. Supports GPT models and any OpenAI-compatible endpoint.',
86
+ category: 'ai',
87
+ parameters: [
88
+ {
89
+ name: 'prompt',
90
+ description: 'The user prompt to send to the LLM',
91
+ type: 'string',
92
+ required: true,
93
+ example: 'What is the capital of France?'
94
+ },
95
+ {
96
+ name: 'options',
97
+ description: 'Optional configuration for the LLM request',
98
+ type: 'object',
99
+ required: false,
100
+ properties: {
101
+ apiKey: { description: 'OpenAI API key', type: 'string' },
102
+ apiUrl: { description: 'API endpoint URL (defaults to OpenAI chat completions)', type: 'string' },
103
+ model: { description: 'Model to use (defaults to gpt-4o-mini)', type: 'string' },
104
+ temperature: { description: 'Sampling temperature 0-2 (defaults to 0.7)', type: 'number' },
105
+ maxTokens: { description: 'Maximum tokens to generate', type: 'number' },
106
+ systemPrompt: { description: 'System prompt to set context', type: 'string' },
107
+ messages: { description: 'Additional conversation messages', type: 'array' },
108
+ organizationId: { description: 'OpenAI organization ID', type: 'string' },
109
+ headers: { description: 'Additional request headers', type: 'object' },
110
+ stream: { description: 'Enable streaming response', type: 'boolean' },
111
+ additionalParams: { description: 'Additional API parameters', type: 'object' }
112
+ }
113
+ }
114
+ ],
115
+ output: {
116
+ description: 'OpenAI chat completion response',
117
+ type: 'object',
118
+ properties: {
119
+ id: { description: 'Unique identifier for the completion', type: 'string' },
120
+ model: { description: 'Model used for completion', type: 'string' },
121
+ choices: {
122
+ description: 'Array of completion choices',
123
+ type: 'array',
124
+ example: [{ message: { role: 'assistant', content: 'Paris is the capital of France.' } }]
125
+ },
126
+ usage: { description: 'Token usage statistics', type: 'object' }
127
+ }
128
+ },
129
+ examples: [
130
+ "LOAD JSON FROM llm('What is 2+2?') AS response RETURN response.choices[0].message.content",
131
+ "LOAD JSON FROM llm('Translate to French: Hello', { model: 'gpt-4o', temperature: 0.3 }) AS response RETURN response.choices[0].message.content",
132
+ "LOAD JSON FROM llm('Write a haiku', { systemPrompt: 'You are a poet' }) AS response RETURN response.choices[0].message.content"
133
+ ],
134
+ notes: 'Requires API key configured in Settings or passed as apiKey option. Works with any OpenAI-compatible API by setting the apiUrl option.'
135
+ })
83
136
  export class LlmLoader {
84
137
  private readonly defaultOptions: Partial<LlmOptions>;
85
138
 
@@ -381,61 +434,4 @@ export function extractContent(response: LlmResponse): string {
381
434
  return LlmLoader.extractContent(response);
382
435
  }
383
436
 
384
- export const llmPlugin: AsyncLoaderPlugin = {
385
- name: 'llm',
386
- provider: (prompt: string, options?: LlmOptions) => new LlmLoader().fetch(prompt, options),
387
- metadata: {
388
- description: 'Calls OpenAI-compatible chat completion APIs. Supports GPT models and any OpenAI-compatible endpoint.',
389
- category: 'ai',
390
- parameters: [
391
- {
392
- name: 'prompt',
393
- description: 'The user prompt to send to the LLM',
394
- type: 'string',
395
- required: true,
396
- example: 'What is the capital of France?'
397
- },
398
- {
399
- name: 'options',
400
- description: 'Optional configuration for the LLM request',
401
- type: 'object',
402
- required: false,
403
- properties: {
404
- apiKey: { description: 'OpenAI API key', type: 'string' },
405
- apiUrl: { description: 'API endpoint URL (defaults to OpenAI chat completions)', type: 'string' },
406
- model: { description: 'Model to use (defaults to gpt-4o-mini)', type: 'string' },
407
- temperature: { description: 'Sampling temperature 0-2 (defaults to 0.7)', type: 'number' },
408
- maxTokens: { description: 'Maximum tokens to generate', type: 'number' },
409
- systemPrompt: { description: 'System prompt to set context', type: 'string' },
410
- messages: { description: 'Additional conversation messages', type: 'array' },
411
- organizationId: { description: 'OpenAI organization ID', type: 'string' },
412
- headers: { description: 'Additional request headers', type: 'object' },
413
- stream: { description: 'Enable streaming response', type: 'boolean' },
414
- additionalParams: { description: 'Additional API parameters', type: 'object' }
415
- }
416
- }
417
- ],
418
- output: {
419
- description: 'OpenAI chat completion response',
420
- type: 'object',
421
- properties: {
422
- id: { description: 'Unique identifier for the completion', type: 'string' },
423
- model: { description: 'Model used for completion', type: 'string' },
424
- choices: {
425
- description: 'Array of completion choices',
426
- type: 'array',
427
- example: [{ message: { role: 'assistant', content: 'Paris is the capital of France.' } }]
428
- },
429
- usage: { description: 'Token usage statistics', type: 'object' }
430
- }
431
- },
432
- examples: [
433
- "LOAD JSON FROM llm('What is 2+2?') AS response RETURN response.choices[0].message.content",
434
- "LOAD JSON FROM llm('Translate to French: Hello', { model: 'gpt-4o', temperature: 0.3 }) AS response RETURN response.choices[0].message.content",
435
- "LOAD JSON FROM llm('Write a haiku', { systemPrompt: 'You are a poet' }) AS response RETURN response.choices[0].message.content"
436
- ],
437
- notes: 'Requires API key configured in Settings or passed as apiKey option. Works with any OpenAI-compatible API by setting the apiUrl option.'
438
- }
439
- };
440
-
441
- export default llmPlugin;
437
+ export default LlmLoader;
@@ -6,11 +6,40 @@
6
6
  * RETURN user.name, user.email
7
7
  */
8
8
 
9
- import { AsyncLoaderPlugin } from '../types';
9
+ import { FunctionDef } from 'flowquery/extensibility';
10
10
 
11
11
  /**
12
12
  * MockUsers loader class - generates mock user data for testing.
13
13
  */
14
+ @FunctionDef({
15
+ isAsyncProvider: true,
16
+ description: 'Generates mock user data for testing purposes',
17
+ category: 'testing',
18
+ parameters: [
19
+ {
20
+ name: 'count',
21
+ description: 'Number of mock users to generate',
22
+ type: 'number',
23
+ required: false,
24
+ default: 5
25
+ }
26
+ ],
27
+ output: {
28
+ description: 'Mock user object',
29
+ type: 'object',
30
+ properties: {
31
+ id: { description: 'User ID', type: 'number' },
32
+ name: { description: 'Full name', type: 'string' },
33
+ email: { description: 'Email address', type: 'string' },
34
+ age: { description: 'Age in years', type: 'number' },
35
+ active: { description: 'Whether user is active', type: 'boolean' }
36
+ }
37
+ },
38
+ examples: [
39
+ "LOAD JSON FROM mockUsers(10) AS user RETURN user.name, user.email",
40
+ "LOAD JSON FROM mockUsers(20) AS user RETURN user WHERE user.active = true"
41
+ ]
42
+ })
14
43
  export class MockUsersLoader {
15
44
  private readonly firstNames: string[];
16
45
  private readonly lastNames: string[];
@@ -51,6 +80,36 @@ export class MockUsersLoader {
51
80
  /**
52
81
  * MockProducts loader class - generates mock product data for testing.
53
82
  */
83
+ @FunctionDef({
84
+ isAsyncProvider: true,
85
+ description: 'Generates mock product data for testing purposes',
86
+ category: 'testing',
87
+ parameters: [
88
+ {
89
+ name: 'count',
90
+ description: 'Number of mock products to generate',
91
+ type: 'number',
92
+ required: false,
93
+ default: 5
94
+ }
95
+ ],
96
+ output: {
97
+ description: 'Mock product object',
98
+ type: 'object',
99
+ properties: {
100
+ id: { description: 'Product ID', type: 'number' },
101
+ name: { description: 'Product name', type: 'string' },
102
+ category: { description: 'Product category', type: 'string' },
103
+ price: { description: 'Price in dollars', type: 'number' },
104
+ inStock: { description: 'Whether product is in stock', type: 'boolean' },
105
+ rating: { description: 'Customer rating (0-5)', type: 'number' }
106
+ }
107
+ },
108
+ examples: [
109
+ "LOAD JSON FROM mockProducts(10) AS p RETURN p.name, p.price",
110
+ "LOAD JSON FROM mockProducts(50) AS p RETURN p WHERE p.category = 'Electronics'"
111
+ ]
112
+ })
54
113
  export class MockProductsLoader {
55
114
  private readonly categories: string[];
56
115
  private readonly adjectives: string[];
@@ -89,73 +148,4 @@ export class MockProductsLoader {
89
148
  }
90
149
  }
91
150
 
92
- export const mockUsersPlugin: AsyncLoaderPlugin = {
93
- name: 'mockUsers',
94
- provider: (count: number = 5) => new MockUsersLoader().fetch(count),
95
- metadata: {
96
- description: 'Generates mock user data for testing purposes',
97
- category: 'testing',
98
- parameters: [
99
- {
100
- name: 'count',
101
- description: 'Number of mock users to generate',
102
- type: 'number',
103
- required: false,
104
- default: 5
105
- }
106
- ],
107
- output: {
108
- description: 'Mock user object',
109
- type: 'object',
110
- properties: {
111
- id: { description: 'User ID', type: 'number' },
112
- name: { description: 'Full name', type: 'string' },
113
- email: { description: 'Email address', type: 'string' },
114
- age: { description: 'Age in years', type: 'number' },
115
- active: { description: 'Whether user is active', type: 'boolean' }
116
- }
117
- },
118
- examples: [
119
- "LOAD JSON FROM mockUsers(10) AS user RETURN user.name, user.email",
120
- "LOAD JSON FROM mockUsers(20) AS user RETURN user WHERE user.active = true"
121
- ]
122
- }
123
- };
124
-
125
- export const mockProductsPlugin: AsyncLoaderPlugin = {
126
- name: 'mockProducts',
127
- provider: (count: number = 5) => new MockProductsLoader().fetch(count),
128
- metadata: {
129
- description: 'Generates mock product data for testing purposes',
130
- category: 'testing',
131
- parameters: [
132
- {
133
- name: 'count',
134
- description: 'Number of mock products to generate',
135
- type: 'number',
136
- required: false,
137
- default: 5
138
- }
139
- ],
140
- output: {
141
- description: 'Mock product object',
142
- type: 'object',
143
- properties: {
144
- id: { description: 'Product ID', type: 'number' },
145
- name: { description: 'Product name', type: 'string' },
146
- category: { description: 'Product category', type: 'string' },
147
- price: { description: 'Price in dollars', type: 'number' },
148
- inStock: { description: 'Whether product is in stock', type: 'boolean' },
149
- rating: { description: 'Customer rating (0-5)', type: 'number' }
150
- }
151
- },
152
- examples: [
153
- "LOAD JSON FROM mockProducts(10) AS p RETURN p.name, p.price",
154
- "LOAD JSON FROM mockProducts(50) AS p RETURN p WHERE p.category = 'Electronics'"
155
- ]
156
- }
157
- };
158
-
159
- export const plugins = [mockUsersPlugin, mockProductsPlugin];
160
-
161
- export default plugins;
151
+ export { MockUsersLoader as default };
@@ -8,8 +8,8 @@
8
8
  * available async data loaders and their metadata.
9
9
  */
10
10
 
11
- import { PluginMetadata, ParameterSchema, OutputSchema } from '../plugins/types';
12
- import { pluginRegistry } from '../plugins/PluginRegistry';
11
+ import { FunctionMetadata, ParameterSchema, OutputSchema } from 'flowquery/extensibility';
12
+ import { getAllPluginMetadata, getAvailableLoaders } from '../plugins';
13
13
 
14
14
  /**
15
15
  * FlowQuery language reference documentation.
@@ -171,7 +171,7 @@ export class FlowQuerySystemPrompt {
171
171
  /**
172
172
  * Format a plugin metadata into a readable documentation block.
173
173
  */
174
- private static formatPluginDocumentation(plugin: PluginMetadata): string {
174
+ private static formatPluginDocumentation(plugin: FunctionMetadata): string {
175
175
  const lines: string[] = [];
176
176
 
177
177
  lines.push(`### \`${plugin.name}\``);
@@ -210,7 +210,7 @@ export class FlowQuerySystemPrompt {
210
210
  /**
211
211
  * Generate documentation for all available plugins.
212
212
  */
213
- private static generatePluginDocumentation(plugins: PluginMetadata[]): string {
213
+ private static generatePluginDocumentation(plugins: FunctionMetadata[]): string {
214
214
  if (plugins.length === 0) {
215
215
  return 'No data loader plugins are currently available.';
216
216
  }
@@ -218,7 +218,7 @@ export class FlowQuerySystemPrompt {
218
218
  const sections: string[] = [];
219
219
 
220
220
  // Group plugins by category
221
- const byCategory = new Map<string, PluginMetadata[]>();
221
+ const byCategory = new Map<string, FunctionMetadata[]>();
222
222
  for (const plugin of plugins) {
223
223
  const category = plugin.category || 'general';
224
224
  if (!byCategory.has(category)) {
@@ -307,7 +307,7 @@ Now help the user with their request.`;
307
307
  */
308
308
  public static generate(additionalContext?: string): string {
309
309
  // Uses FlowQuery's introspection to get available async providers
310
- const plugins = pluginRegistry.getAllPluginMetadata();
310
+ const plugins = getAllPluginMetadata();
311
311
  const pluginDocs = this.generatePluginDocumentation(plugins);
312
312
 
313
313
  return this.buildSystemPrompt(pluginDocs, additionalContext);
@@ -346,7 +346,7 @@ You are now receiving the execution results. Your job is to:
346
346
  * Useful for contexts where token count is a concern.
347
347
  */
348
348
  public static getMinimalPrompt(): string {
349
- const plugins = pluginRegistry.getAllPluginMetadata();
349
+ const plugins = getAllPluginMetadata();
350
350
  const pluginList = plugins.map(p => `- \`${p.name}\`: ${p.description}`).join('\n');
351
351
 
352
352
  return `You are a FlowQuery assistant. Generate FlowQuery statements based on user requests.
@@ -369,7 +369,7 @@ Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
369
369
  */
370
370
  public static async generateAsync(additionalContext?: string): Promise<string> {
371
371
  // Use FlowQuery's functions() introspection to discover available loaders
372
- const plugins = await pluginRegistry.getAvailableLoadersAsync();
372
+ const plugins = await getAvailableLoaders();
373
373
  const pluginDocs = this.generatePluginDocumentation(plugins);
374
374
 
375
375
  return this.buildSystemPrompt(pluginDocs, additionalContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowquery",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
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,7 +1,6 @@
1
1
  import Operation from "../parsing/operations/operation";
2
2
  import Parser from "../parsing/parser";
3
- import { FunctionCreator, AsyncDataProvider } from "../parsing/functions/function_factory";
4
- import { FunctionMetadata, RegisterFunctionOptions, RegisterAsyncProviderOptions } from "../parsing/functions/function_metadata";
3
+ import { FunctionMetadata } from "../parsing/functions/function_metadata";
5
4
  import Function from "../parsing/functions/function";
6
5
 
7
6
  /**
@@ -21,30 +20,6 @@ class Runner {
21
20
  private first: Operation;
22
21
  private last: Operation;
23
22
 
24
- /**
25
- * Register a synchronous plugin function.
26
- * Added dynamically in index.browser.ts / index.node.ts
27
- */
28
- static registerFunction: (name: string, factoryOrOptions: FunctionCreator | RegisterFunctionOptions) => void;
29
-
30
- /**
31
- * Unregister a synchronous plugin function.
32
- * Added dynamically in index.browser.ts / index.node.ts
33
- */
34
- static unregisterFunction: (name: string) => void;
35
-
36
- /**
37
- * Register an async data provider function for use in LOAD operations.
38
- * Added dynamically in index.browser.ts / index.node.ts
39
- */
40
- static registerAsyncProvider: (name: string, providerOrOptions: AsyncDataProvider | RegisterAsyncProviderOptions) => void;
41
-
42
- /**
43
- * Unregister an async data provider function.
44
- * Added dynamically in index.browser.ts / index.node.ts
45
- */
46
- static unregisterAsyncProvider: (name: string) => void;
47
-
48
23
  /**
49
24
  * List all registered functions with their metadata.
50
25
  * Added dynamically in index.browser.ts / index.node.ts
@@ -1,9 +1,45 @@
1
1
  /**
2
2
  * FlowQuery Extensibility API
3
3
  *
4
- * This module re-exports the extensibility API from the parsing/functions/extensibility module.
4
+ * This module provides all the exports needed to create custom FlowQuery functions.
5
5
  *
6
6
  * @packageDocumentation
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Function, FunctionDef } from 'flowquery/extensibility';
11
+ *
12
+ * @FunctionDef({
13
+ * description: "Converts a string to uppercase",
14
+ * category: "string",
15
+ * parameters: [{ name: "text", description: "String to convert", type: "string" }],
16
+ * output: { description: "Uppercase string", type: "string" }
17
+ * })
18
+ * class UpperCase extends Function {
19
+ * constructor() {
20
+ * super("uppercase");
21
+ * this._expectedParameterCount = 1;
22
+ * }
23
+ * public value(): string {
24
+ * return String(this.getChildren()[0].value()).toUpperCase();
25
+ * }
26
+ * }
27
+ * ```
7
28
  */
8
29
 
9
- export * from "./parsing/functions/extensibility";
30
+ // Base function classes for creating custom functions
31
+ export { default as Function } from "./parsing/functions/function";
32
+ export { default as AggregateFunction } from "./parsing/functions/aggregate_function";
33
+ export { default as AsyncFunction } from "./parsing/functions/async_function";
34
+ export { default as PredicateFunction } from "./parsing/functions/predicate_function";
35
+ export { default as ReducerElement } from "./parsing/functions/reducer_element";
36
+
37
+ // Decorator and metadata types for function registration
38
+ export {
39
+ FunctionDef,
40
+ FunctionMetadata,
41
+ FunctionDefOptions,
42
+ ParameterSchema,
43
+ OutputSchema,
44
+ FunctionCategory
45
+ } from "./parsing/functions/function_metadata";