@devilsdev/rag-pipeline-utils 2.4.5 → 2.6.0

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 (258) hide show
  1. package/.ragrc.schema.json +83 -192
  2. package/CHANGELOG.md +431 -0
  3. package/README.md +418 -117
  4. package/SECURITY.md +5 -5
  5. package/dist/experimental.cjs +2 -0
  6. package/dist/experimental.d.ts +1 -0
  7. package/dist/experimental.mjs +5 -0
  8. package/dist/index.cjs +6442 -1355
  9. package/dist/index.d.ts +129 -2
  10. package/dist/index.mjs +1 -1
  11. package/dist/testing.cjs +2 -0
  12. package/dist/testing.d.ts +1 -0
  13. package/dist/testing.mjs +5 -0
  14. package/dist/types/adapters/ai-sdk.d.ts +53 -0
  15. package/dist/types/agentic/agentic-pipeline.d.ts +103 -0
  16. package/dist/types/agentic/iterative-retriever.d.ts +85 -0
  17. package/dist/types/agentic/query-planner.d.ts +145 -0
  18. package/dist/types/agentic/self-critique.d.ts +45 -0
  19. package/dist/types/ai/adaptive-retrieval.d.ts +44 -0
  20. package/dist/types/ai/federation/federated-learning-coordinator.d.ts +62 -0
  21. package/dist/types/ai/multimodal-processing.d.ts +32 -0
  22. package/dist/types/ai/multimodal.d.ts +39 -0
  23. package/dist/types/ai/retrieval-engine.d.ts +37 -0
  24. package/dist/types/ai/training/model-training-orchestrator.d.ts +31 -0
  25. package/dist/types/cache/component-keys.d.ts +7 -0
  26. package/dist/types/cache/memory-cache.d.ts +54 -0
  27. package/dist/types/cache/pipeline-cache.d.ts +66 -0
  28. package/dist/types/cache/redis-cache.d.ts +46 -0
  29. package/dist/types/chunking/chunking-engine.d.ts +70 -0
  30. package/dist/types/chunking/strategies/fixed-size.d.ts +17 -0
  31. package/dist/types/chunking/strategies/recursive.d.ts +20 -0
  32. package/dist/types/chunking/strategies/semantic.d.ts +19 -0
  33. package/dist/types/chunking/strategies/sentence.d.ts +13 -0
  34. package/dist/types/chunking/strategies/structure-aware.d.ts +19 -0
  35. package/dist/types/citation/citation-tracker.d.ts +64 -0
  36. package/dist/types/citation/hallucination-detector.d.ts +40 -0
  37. package/dist/types/citation/source-mapper.d.ts +37 -0
  38. package/dist/types/connectors/anthropic-connector.d.ts +97 -0
  39. package/dist/types/connectors/base-connector.d.ts +87 -0
  40. package/dist/types/connectors/cohere-connector.d.ts +94 -0
  41. package/dist/types/connectors/connector-utils.d.ts +110 -0
  42. package/dist/types/connectors/local-embedder.d.ts +95 -0
  43. package/dist/types/connectors/memory-retriever.d.ts +99 -0
  44. package/dist/types/connectors/ollama-connector.d.ts +115 -0
  45. package/dist/types/connectors/openai-connector.d.ts +129 -0
  46. package/dist/types/connectors/rag-prompt.d.ts +40 -0
  47. package/dist/types/core/create-pipeline.d.ts +8 -0
  48. package/dist/types/core/plugin-registry.d.ts +136 -0
  49. package/dist/types/core/stage-contracts.d.ts +36 -0
  50. package/dist/types/core/validate-plugin.d.ts +45 -0
  51. package/dist/types/cost/cost-calculator.d.ts +152 -0
  52. package/dist/types/cost/cost-tracker.d.ts +126 -0
  53. package/dist/types/cost/token-budget.d.ts +110 -0
  54. package/dist/types/dag/core/error-context.d.ts +239 -0
  55. package/dist/types/dag/core/execution-scheduler.d.ts +191 -0
  56. package/dist/types/dag/core/topology-validation.d.ts +226 -0
  57. package/dist/types/dag/dag-engine.d.ts +156 -0
  58. package/dist/types/dag/dag-node.d.ts +37 -0
  59. package/dist/types/dashboard/dashboard-generator.d.ts +127 -0
  60. package/dist/types/dashboard/metrics-aggregator.d.ts +218 -0
  61. package/dist/types/debug/execution-tracer.d.ts +57 -0
  62. package/dist/types/debug/trace-inspector.d.ts +31 -0
  63. package/dist/types/ecosystem/plugin-certification.d.ts +169 -0
  64. package/dist/types/enterprise/data-governance.d.ts +203 -0
  65. package/dist/types/enterprise/multi-tenancy.d.ts +137 -0
  66. package/dist/types/enterprise/sso-integration.d.ts +420 -0
  67. package/dist/types/evaluate/context-metrics.d.ts +55 -0
  68. package/dist/types/evaluate/faithfulness.d.ts +41 -0
  69. package/dist/types/evaluate/groundedness.d.ts +60 -0
  70. package/dist/types/evaluate/pipeline-evaluator.d.ts +88 -0
  71. package/dist/types/evaluate/relevance.d.ts +21 -0
  72. package/dist/types/evaluate/scoring.d.ts +123 -0
  73. package/dist/types/evaluate/semantic-similarity.d.ts +14 -0
  74. package/dist/types/experimental.d.ts +15 -0
  75. package/dist/types/graph/entity-extractor.d.ts +84 -0
  76. package/dist/types/graph/graph-index.d.ts +49 -0
  77. package/dist/types/graph/graph-retriever.d.ts +81 -0
  78. package/dist/types/graph/knowledge-graph.d.ts +129 -0
  79. package/dist/types/grounding/check-answer.d.ts +101 -0
  80. package/dist/types/guardrails/guardrails-pipeline.d.ts +63 -0
  81. package/dist/types/guardrails/injection-detector.d.ts +47 -0
  82. package/dist/types/guardrails/post-generation-guard.d.ts +61 -0
  83. package/dist/types/guardrails/pre-retrieval-guard.d.ts +64 -0
  84. package/dist/types/guardrails/retrieval-guard.d.ts +57 -0
  85. package/dist/types/mcp/mcp-server.d.ts +85 -0
  86. package/dist/types/mcp/mcp-tool-builder.d.ts +55 -0
  87. package/dist/types/reranker/cascade-reranker.d.ts +40 -0
  88. package/dist/types/reranker/embedding-reranker.d.ts +77 -0
  89. package/dist/types/reranker/scoring-reranker.d.ts +41 -0
  90. package/dist/types/retrieval/bm25-search.d.ts +43 -0
  91. package/dist/types/retrieval/file-vector-store.d.ts +99 -0
  92. package/dist/types/retrieval/hybrid-retriever.d.ts +35 -0
  93. package/dist/types/retrieval/rank-fusion.d.ts +10 -0
  94. package/dist/types/security/jwt-config.d.ts +80 -0
  95. package/dist/types/security/jwt-validator.d.ts +195 -0
  96. package/dist/types/security/plugin-sandbox.d.ts +158 -0
  97. package/dist/types/security/plugin-signature-verifier.d.ts +139 -0
  98. package/dist/types/security/validator.d.ts +5 -0
  99. package/dist/types/streaming/embedding-stream.d.ts +65 -0
  100. package/dist/types/streaming/sse-adapter.d.ts +59 -0
  101. package/dist/types/streaming/stream-router.d.ts +88 -0
  102. package/dist/types/streaming/streaming-embedder.d.ts +99 -0
  103. package/dist/types/streaming/websocket-adapter.d.ts +71 -0
  104. package/dist/types/templates/scaffold.d.ts +55 -0
  105. package/dist/types/templates/template-registry.d.ts +63 -0
  106. package/dist/types/testing.d.ts +168 -0
  107. package/dist/types/utils/embed-query.d.ts +20 -0
  108. package/dist/types/utils/logger.d.ts +50 -0
  109. package/dist/types/utils/rate-limiter.d.ts +66 -0
  110. package/dist/types/utils/retry.d.ts +27 -0
  111. package/dist/types/utils/run-abort.d.ts +34 -0
  112. package/dist/types/utils/secure-logging.d.ts +51 -0
  113. package/dist/types/utils/structured-logger.d.ts +126 -0
  114. package/package.json +72 -33
  115. package/src/adapters/ai-sdk.js +215 -0
  116. package/src/agentic/agentic-pipeline.js +75 -7
  117. package/src/agentic/iterative-retriever.js +47 -10
  118. package/src/agentic/query-planner.js +329 -78
  119. package/src/cache/component-keys.js +38 -0
  120. package/src/cache/memory-cache.js +87 -0
  121. package/src/cache/pipeline-cache.js +260 -0
  122. package/src/cache/redis-cache.js +83 -0
  123. package/src/citation/citation-tracker.js +6 -4
  124. package/src/citation/hallucination-detector.js +2 -2
  125. package/src/citation/source-mapper.js +15 -28
  126. package/src/cli/commands/ai.js +106 -0
  127. package/src/cli/commands/plugin-hub/event-handlers.js +6 -0
  128. package/src/cli/commands/plugin-hub/hub-commands.js +0 -74
  129. package/src/cli/commands/plugin-hub/local-commands.js +143 -0
  130. package/src/cli/commands/plugin-hub.js +114 -49
  131. package/src/cli/diagnostics/config-checker.js +76 -63
  132. package/src/cli/diagnostics/environment-checker.js +62 -31
  133. package/src/cli/diagnostics/plugin-checker.js +36 -89
  134. package/src/cli/doctor-command.js +39 -5
  135. package/src/cli/enhanced-cli-commands.js +104 -233
  136. package/src/cli/handlers/ai-handler.js +364 -0
  137. package/src/cli/handlers/diagnostics-handler.js +78 -31
  138. package/src/cli/handlers/ingest-handler.js +28 -22
  139. package/src/cli/handlers/init-handler.js +148 -25
  140. package/src/cli/handlers/query-handler.js +203 -25
  141. package/src/cli/handlers/run-handler.js +16 -167
  142. package/src/cli/handlers/serve-handler.js +60 -0
  143. package/src/cli/services/bench-stats.js +54 -0
  144. package/src/cli/services/benchmark.js +161 -0
  145. package/src/cli/services/feedback.js +155 -0
  146. package/src/cli/services/instrument.js +83 -0
  147. package/src/cli/services/rag-service.js +361 -0
  148. package/src/cli/shared/cli-utils.js +24 -7
  149. package/src/cli/shared/config-context.js +21 -0
  150. package/src/cli/wizard/config-builder.js +81 -0
  151. package/src/cli/wizard/init-wizard.js +602 -0
  152. package/src/config/component-factory.js +125 -0
  153. package/src/config/enhanced-ragrc-schema.js +0 -2
  154. package/src/config/load-config.js +29 -10
  155. package/src/config/load-plugin-config.js +46 -2
  156. package/src/config/validate-schema.js +4 -1
  157. package/src/connectors/anthropic-connector.js +115 -57
  158. package/src/connectors/base-connector.js +74 -19
  159. package/src/connectors/cohere-connector.js +108 -34
  160. package/src/connectors/connector-utils.js +302 -0
  161. package/src/connectors/local-embedder.js +63 -5
  162. package/src/connectors/memory-retriever.js +125 -14
  163. package/src/connectors/ollama-connector.js +112 -51
  164. package/src/connectors/openai-connector.js +153 -44
  165. package/src/connectors/rag-prompt.js +88 -0
  166. package/src/core/create-pipeline.js +307 -61
  167. package/src/core/performance/parallel-processor.js +62 -1
  168. package/src/core/plugin-registry.js +125 -26
  169. package/src/core/stage-contracts.js +36 -0
  170. package/src/core/validate-plugin.js +85 -0
  171. package/src/cost/cost-calculator.js +205 -32
  172. package/src/debug/execution-tracer.js +14 -4
  173. package/src/dev/dev-server.js +173 -11
  174. package/src/dev/hot-reload.js +44 -4
  175. package/src/ecosystem/plugin-checks.js +181 -0
  176. package/src/ecosystem/plugin-hub.js +50 -125
  177. package/src/ecosystem/plugin-installer.js +298 -0
  178. package/src/ecosystem/plugin-probe.js +127 -0
  179. package/src/ecosystem/plugin-scanner.js +185 -0
  180. package/src/ecosystem/tar-extract.js +114 -0
  181. package/src/enterprise/audit-logging.js +158 -29
  182. package/src/enterprise/sso-integration.js +716 -228
  183. package/src/evaluate/context-metrics.js +28 -16
  184. package/src/evaluate/evaluator.js +3 -3
  185. package/src/evaluate/faithfulness.js +18 -14
  186. package/src/evaluate/groundedness.js +43 -12
  187. package/src/evaluate/pipeline-evaluator.js +35 -8
  188. package/src/evaluate/scoring.js +251 -3
  189. package/src/evaluate/semantic-similarity.js +79 -0
  190. package/src/experimental.js +71 -0
  191. package/src/grounding/check-answer.js +173 -0
  192. package/src/guardrails/guardrails-pipeline.js +69 -7
  193. package/src/guardrails/injection-detector.js +283 -0
  194. package/src/guardrails/post-generation-guard.js +19 -0
  195. package/src/guardrails/pre-retrieval-guard.js +36 -36
  196. package/src/guardrails/retrieval-guard.js +58 -8
  197. package/src/index.js +58 -1
  198. package/src/loader/csv-loader.js +3 -2
  199. package/src/loader/document-reader.js +91 -0
  200. package/src/loader/html-loader.js +3 -1
  201. package/src/loader/markdown-loader.js +3 -2
  202. package/src/reranker/cascade-reranker.js +3 -0
  203. package/src/reranker/embedding-reranker.js +136 -21
  204. package/src/reranker/llm-reranker.js +79 -12
  205. package/src/reranker/scoring-reranker.js +3 -0
  206. package/src/retrieval/bm25-search.js +12 -6
  207. package/src/retrieval/file-vector-store.js +241 -0
  208. package/src/retrieval/hybrid-retriever.js +22 -19
  209. package/src/security/jwt-config.js +13 -2
  210. package/src/security/jwt-validator.js +139 -34
  211. package/src/security/plugin-sandbox.js +18 -1
  212. package/src/security/plugin-signature-verifier.js +245 -70
  213. package/src/testing.js +254 -0
  214. package/src/utils/deprecate.js +69 -0
  215. package/src/utils/embed-query.js +33 -0
  216. package/src/utils/input-sanitizer.js +19 -4
  217. package/src/utils/logger.js +34 -4
  218. package/src/utils/run-abort.js +102 -0
  219. package/src/ai/federated-learning.js +0 -211
  220. package/src/ai/federation.js +0 -71
  221. package/src/ai/index.js +0 -22
  222. package/src/ai/model-trainer.js +0 -217
  223. package/src/ai/model-training.js +0 -202
  224. package/src/ai/multimodal/multi-modal-processor.js +0 -345
  225. package/src/ai/orchestrator.js +0 -65
  226. package/src/ai/retrieval/adaptive-retrieval-engine.js +0 -398
  227. package/src/cli/commands/ai-ml/adaptive-commands.js +0 -178
  228. package/src/cli/commands/ai-ml/federated-commands.js +0 -207
  229. package/src/cli/commands/ai-ml/index.js +0 -17
  230. package/src/cli/commands/ai-ml/multimodal-commands.js +0 -187
  231. package/src/cli/commands/ai-ml/shared.js +0 -51
  232. package/src/cli/commands/ai-ml/training-commands.js +0 -228
  233. package/src/cli/commands/ai-ml.js +0 -386
  234. package/src/cli/commands/docs.js +0 -228
  235. package/src/cli/commands/dx.js +0 -538
  236. package/src/cli/commands/wizard.js +0 -627
  237. package/src/cli/input-sanitization-middleware.js +0 -356
  238. package/src/cli/interactive-wizard.js +0 -373
  239. package/src/cli/templates/development.template.json +0 -64
  240. package/src/cli/templates/minimal.template.json +0 -33
  241. package/src/cli/templates/production.template.json +0 -104
  242. package/src/cli/templates/testing.template.json +0 -45
  243. package/src/cli/wizard/configuration.js +0 -148
  244. package/src/cli/wizard/observability.js +0 -79
  245. package/src/cli/wizard/performance.js +0 -76
  246. package/src/cli/wizard/plugin-selection.js +0 -297
  247. package/src/cli/wizard/preview-save.js +0 -172
  248. package/src/cli/wizard/project-setup.js +0 -66
  249. package/src/core/pipeline-factory.js +0 -59
  250. package/src/dag/enhanced-dag-engine.js +0 -894
  251. package/src/dx/index.js +0 -40
  252. package/src/dx/integration-templates.js +0 -662
  253. package/src/dx/performance-profiler.js +0 -968
  254. package/src/dx/realtime-debugger.js +0 -755
  255. package/src/dx/visual-pipeline-builder.js +0 -578
  256. package/src/ingest.js +0 -59
  257. package/src/pipeline/pipeline.js +0 -18
  258. package/src/query.js +0 -117
@@ -0,0 +1,191 @@
1
+ export = ExecutionScheduler;
2
+ /**
3
+ * ExecutionScheduler class for managing DAG node execution
4
+ *
5
+ * Provides stateless execution scheduling with:
6
+ * - Concurrency control via semaphore
7
+ * - Timeout enforcement
8
+ * - Retry logic with exponential backoff
9
+ * - Dependency resolution
10
+ * - Error handling and reporting
11
+ *
12
+ * @class
13
+ * @since 2.2.3
14
+ */
15
+ declare class ExecutionScheduler {
16
+ /**
17
+ * Create an ExecutionScheduler instance
18
+ *
19
+ * @param {Object} options - Scheduler configuration
20
+ * @param {Function} options.getSinkIds - Function to get sink node IDs
21
+ * @param {Object} [options.logger] - Logger instance for debugging
22
+ */
23
+ constructor(options?: {
24
+ getSinkIds: Function;
25
+ logger?: any;
26
+ });
27
+ getSinkIds: Function;
28
+ logger: any;
29
+ errorContext: ErrorContext;
30
+ /**
31
+ * Schedule and execute all nodes with concurrency management
32
+ *
33
+ * Executes nodes in topological order, respecting dependencies and
34
+ * managing concurrency via semaphore. Each node is executed only after
35
+ * all its dependencies have completed or failed.
36
+ *
37
+ * @param {DAGNode[]} order - Topologically sorted array of nodes
38
+ * @param {Object} context - Execution context
39
+ * @param {number} [context.concurrency] - Maximum concurrent executions
40
+ * @param {Map} context.results - Results map (node ID -> result)
41
+ * @param {Map} context.errors - Errors map (node ID -> error)
42
+ * @param {Map} context.fwd - Forward adjacency map
43
+ * @param {boolean} [context.continueOnError] - Continue on non-critical errors
44
+ * @param {Set} context.requiredIds - Set of required node IDs
45
+ * @param {any} context.seed - Initial seed value
46
+ * @param {boolean} [context.gracefulDegradation] - Enable graceful degradation
47
+ * @param {string[]} [context.requiredNodes] - Array of required node IDs
48
+ * @param {boolean} [context.retryFailedNodes] - Enable retry for failed nodes
49
+ * @param {number} [context.maxRetries] - Maximum retry attempts
50
+ * @returns {Promise<void>}
51
+ *
52
+ * @example
53
+ * const scheduler = new ExecutionScheduler({ getSinkIds });
54
+ * await scheduler.scheduleExecution(sortedNodes, {
55
+ * concurrency: 5,
56
+ * results: new Map(),
57
+ * errors: new Map(),
58
+ * fwd: adjacencyMap,
59
+ * requiredIds: new Set(['critical-node']),
60
+ * seed: initialInput
61
+ * });
62
+ *
63
+ * @performance O(V) where V = number of nodes
64
+ * @since 2.2.3
65
+ */
66
+ scheduleExecution(order: DAGNode[], context: {
67
+ concurrency?: number;
68
+ results: Map<any, any>;
69
+ errors: Map<any, any>;
70
+ fwd: Map<any, any>;
71
+ continueOnError?: boolean;
72
+ requiredIds: Set<any>;
73
+ seed: any;
74
+ gracefulDegradation?: boolean;
75
+ requiredNodes?: string[];
76
+ retryFailedNodes?: boolean;
77
+ maxRetries?: number;
78
+ }): Promise<void>;
79
+ /**
80
+ * Execute a single DAG node with retry logic and error handling
81
+ *
82
+ * Executes node.run() with comprehensive error handling:
83
+ * - Validates node.run is a function
84
+ * - Determines node criticality
85
+ * - Prepares input from dependencies
86
+ * - Implements retry logic with configurable attempts
87
+ * - Reports errors with downstream impact analysis
88
+ *
89
+ * @param {DAGNode} node - Node to execute
90
+ * @param {Object} context - Execution context
91
+ * @param {Map} context.results - Results map
92
+ * @param {Map} context.errors - Errors map
93
+ * @param {Map} context.fwd - Forward adjacency map
94
+ * @param {boolean} [context.continueOnError] - Continue on non-critical errors
95
+ * @param {Set} context.requiredIds - Required node IDs
96
+ * @param {any} context.seed - Seed value for source nodes
97
+ * @param {boolean} [context.gracefulDegradation] - Enable graceful degradation
98
+ * @param {string[]} [context.requiredNodes] - Required node IDs array
99
+ * @param {boolean} [context.retryFailedNodes] - Enable retry
100
+ * @param {number} [context.maxRetries] - Max retry attempts
101
+ * @returns {Promise<any>} Node execution result or Symbol('failed-optional-node')
102
+ *
103
+ * @throws {Error} Node execution error (if node is critical)
104
+ *
105
+ * @example
106
+ * const result = await scheduler.executeNode(myNode, {
107
+ * results: new Map(),
108
+ * errors: new Map(),
109
+ * fwd: adjacencyMap,
110
+ * requiredIds: new Set(),
111
+ * seed: initialData,
112
+ * retryFailedNodes: true,
113
+ * maxRetries: 3
114
+ * });
115
+ *
116
+ * @performance O(1) for single execution, O(k) for k retry attempts
117
+ * @complexity Cyclomatic complexity: 12 (acceptable for critical execution path)
118
+ * @since 2.2.3
119
+ */
120
+ executeNode(node: DAGNode, context: {
121
+ results: Map<any, any>;
122
+ errors: Map<any, any>;
123
+ fwd: Map<any, any>;
124
+ continueOnError?: boolean;
125
+ requiredIds: Set<any>;
126
+ seed: any;
127
+ gracefulDegradation?: boolean;
128
+ requiredNodes?: string[];
129
+ retryFailedNodes?: boolean;
130
+ maxRetries?: number;
131
+ }): Promise<any>;
132
+ /**
133
+ * Execute function with optional timeout enforcement
134
+ *
135
+ * Uses Promise.race to enforce execution timeout. If timeout is not specified
136
+ * or is <= 0, executes without timeout constraint.
137
+ *
138
+ * @param {Function} runFn - Async function to execute
139
+ * @param {number} [timeout] - Timeout in milliseconds (0 or undefined = no timeout)
140
+ * @returns {Promise<void>}
141
+ *
142
+ * @throws {Error} 'Execution timeout' if execution exceeds timeout
143
+ *
144
+ * @example
145
+ * await scheduler.executeWithTimeout(
146
+ * () => executeLongRunningTask(),
147
+ * 30000 // 30 second timeout
148
+ * );
149
+ *
150
+ * @performance O(1) overhead for timeout setup
151
+ * @since 2.2.3
152
+ */
153
+ executeWithTimeout(runFn: Function, timeout?: number): Promise<void>;
154
+ /**
155
+ * Check if a node can be executed based on dependency satisfaction
156
+ *
157
+ * A node can execute if all its input dependencies have either:
158
+ * - Completed successfully (have a result)
159
+ * - Failed (have an error)
160
+ * - Are optional (graceful degradation enabled and not in required nodes)
161
+ *
162
+ * @param {DAGNode} node - Node to check
163
+ * @param {Object} context - Execution context
164
+ * @param {Map} context.results - Results map
165
+ * @param {Map} context.errors - Errors map
166
+ * @param {boolean} [context.gracefulDegradation] - Enable graceful degradation
167
+ * @param {string[]} [context.requiredNodes] - Required node IDs
168
+ * @returns {boolean} True if node can execute, false otherwise
169
+ *
170
+ * @example
171
+ * const canRun = scheduler.canExecuteNode(myNode, {
172
+ * results: new Map([['dep1', result1]]),
173
+ * errors: new Map(),
174
+ * gracefulDegradation: true,
175
+ * requiredNodes: ['critical-dep']
176
+ * });
177
+ *
178
+ * @performance O(d) where d = number of input dependencies
179
+ * @since 2.2.3
180
+ */
181
+ canExecuteNode(node: DAGNode, context: {
182
+ results: Map<any, any>;
183
+ errors: Map<any, any>;
184
+ gracefulDegradation?: boolean;
185
+ requiredNodes?: string[];
186
+ }): boolean;
187
+ }
188
+ declare namespace ExecutionScheduler {
189
+ export { ExecutionScheduler as default };
190
+ }
191
+ import ErrorContext = require("./error-context.js");
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @fileoverview DAG Topology Validation Module
3
+ *
4
+ * Provides topology validation utilities for Directed Acyclic Graphs (DAGs),
5
+ * including cycle detection, topological sorting, and structural validation.
6
+ *
7
+ * @module dag/core/topology-validation
8
+ * @author Ali Kahwaji
9
+ * @since 2.2.2
10
+ * @version 1.0.0
11
+ */
12
+ /**
13
+ * Builds forward and reverse adjacency maps for a DAG
14
+ *
15
+ * Creates two Maps:
16
+ * - Forward: Maps each node ID to a Set of its children (outgoing edges)
17
+ * - Reverse: Maps each node ID to a Set of its parents (incoming edges)
18
+ *
19
+ * @param {Map<string, DAGNode>} nodes - Map of node IDs to DAGNode instances
20
+ * @returns {{fwd: Map<string, Set<string>>, rev: Map<string, Set<string>>}}
21
+ * Adjacency maps for forward and reverse traversal
22
+ *
23
+ * @example
24
+ * const nodes = new Map([
25
+ * ['A', nodeA],
26
+ * ['B', nodeB],
27
+ * ['C', nodeC]
28
+ * ]);
29
+ * const { fwd, rev } = buildAdjacency(nodes);
30
+ * // fwd.get('A') => Set(['B', 'C']) - A points to B and C
31
+ * // rev.get('B') => Set(['A']) - B is pointed to by A
32
+ *
33
+ * @performance O(V + E) where V = number of nodes, E = number of edges
34
+ * @since 2.2.2
35
+ */
36
+ export function buildAdjacency(nodes: Map<string, DAGNode>): {
37
+ fwd: Map<string, Set<string>>;
38
+ rev: Map<string, Set<string>>;
39
+ };
40
+ /**
41
+ * Gets sink node IDs (nodes with no outgoing edges)
42
+ *
43
+ * Sink nodes are terminal nodes in the DAG that have no children.
44
+ * They represent final outputs of the pipeline.
45
+ *
46
+ * @param {Map<string, Set<string>>} fwd - Forward adjacency map
47
+ * @returns {string[]} Array of sink node IDs
48
+ *
49
+ * @example
50
+ * const fwd = new Map([
51
+ * ['A', new Set(['B'])],
52
+ * ['B', new Set()], // B is a sink
53
+ * ['C', new Set()] // C is a sink
54
+ * ]);
55
+ * const sinks = getSinkIds(fwd);
56
+ * console.log(sinks); // ['B', 'C']
57
+ *
58
+ * @performance O(V) where V = number of nodes
59
+ * @since 2.2.2
60
+ */
61
+ export function getSinkIds(fwd: Map<string, Set<string>>): string[];
62
+ /**
63
+ * Performs topological sort with comprehensive cycle detection
64
+ *
65
+ * Uses depth-first search (DFS) with path tracking to detect cycles.
66
+ * If a cycle is detected, the error includes the complete cycle path.
67
+ *
68
+ * @param {Map<string, DAGNode>} nodes - Map of node IDs to DAGNode instances
69
+ * @returns {DAGNode[]} Topologically sorted array of nodes
70
+ *
71
+ * @throws {Error} If a cycle is detected. Error includes:
72
+ * - message: Description with cycle path (e.g., "Cycle detected involving node: A -> B -> C -> A")
73
+ * - cycle: Array of node IDs forming the cycle
74
+ * @throws {Error} If topological sort fails for other reasons
75
+ *
76
+ * @example
77
+ * // Valid DAG
78
+ * const nodes = new Map([
79
+ * ['A', nodeA], // A -> B
80
+ * ['B', nodeB], // B -> C
81
+ * ['C', nodeC] // C (sink)
82
+ * ]);
83
+ * const sorted = topologicalSort(nodes);
84
+ * console.log(sorted.map(n => n.id)); // ['C', 'B', 'A'] (reverse dependency order)
85
+ *
86
+ * @example
87
+ * // Cyclic DAG (throws error)
88
+ * const nodes = new Map([
89
+ * ['A', nodeA], // A -> B
90
+ * ['B', nodeB], // B -> C
91
+ * ['C', nodeC] // C -> A (creates cycle)
92
+ * ]);
93
+ * try {
94
+ * topologicalSort(nodes);
95
+ * } catch (error) {
96
+ * console.log(error.message); // "Cycle detected involving node: A -> B -> C -> A"
97
+ * console.log(error.cycle); // ['A', 'B', 'C', 'A']
98
+ * }
99
+ *
100
+ * @algorithm
101
+ * 1. Initialize empty order array, visited set, and visiting set
102
+ * 2. For each unvisited node, perform DFS:
103
+ * a. If node is currently being visited (in visiting set), cycle detected
104
+ * b. Mark node as visiting
105
+ * c. Recursively visit all input nodes (dependencies)
106
+ * d. Mark node as visited, remove from visiting
107
+ * e. Add node to order array
108
+ * 3. Return order array (nodes in reverse topological order)
109
+ *
110
+ * @performance O(V + E) where V = number of nodes, E = number of edges
111
+ * @complexity Cyclomatic complexity: 6 (within acceptable limits)
112
+ * @since 2.2.2
113
+ */
114
+ export function topologicalSort(nodes: Map<string, DAGNode>): DAGNode[];
115
+ /**
116
+ * Validates basic DAG structure
117
+ *
118
+ * Performs fundamental validation checks:
119
+ * - DAG is not empty
120
+ * - No cycles exist (via topological sort)
121
+ * - At least one sink node exists
122
+ *
123
+ * This is the primary validation method called before DAG execution.
124
+ *
125
+ * @param {Map<string, DAGNode>} nodes - Map of node IDs to DAGNode instances
126
+ * @returns {boolean} True if validation passes
127
+ *
128
+ * @throws {Error} If DAG is empty - "DAG is empty - no nodes to execute"
129
+ * @throws {Error} If cycle detected - "DAG validation failed: DAG topological sort failed: Cycle detected involving node: ..."
130
+ * - error.cycle: Array of node IDs forming the cycle
131
+ * @throws {Error} If no sink nodes - "DAG has no sink nodes - no final output available"
132
+ * @throws {Error} For other validation failures
133
+ *
134
+ * @example
135
+ * // Valid DAG
136
+ * const nodes = new Map([
137
+ * ['load', loadNode],
138
+ * ['process', processNode],
139
+ * ['save', saveNode]
140
+ * ]);
141
+ * const isValid = validateDAG(nodes); // true
142
+ *
143
+ * @example
144
+ * // Empty DAG
145
+ * try {
146
+ * validateDAG(new Map());
147
+ * } catch (error) {
148
+ * console.log(error.message); // "DAG is empty - no nodes to execute"
149
+ * }
150
+ *
151
+ * @example
152
+ * // No sink nodes (all nodes have outputs)
153
+ * const nodes = new Map([
154
+ * ['A', nodeA] // A -> B
155
+ * ]);
156
+ * // Assuming all nodes have outputs
157
+ * try {
158
+ * validateDAG(nodes);
159
+ * } catch (error) {
160
+ * console.log(error.message); // "DAG has no sink nodes - no final output available"
161
+ * }
162
+ *
163
+ * @performance O(V + E) due to topological sort
164
+ * @since 2.2.2
165
+ */
166
+ export function validateDAG(nodes: Map<string, DAGNode>): boolean;
167
+ /**
168
+ * Validates DAG topology with advanced options and warnings
169
+ *
170
+ * Performs comprehensive validation including:
171
+ * - Empty DAG check
172
+ * - Self-loop detection
173
+ * - Cycle detection via topological sort
174
+ * - Isolated node detection (nodes with no connections)
175
+ *
176
+ * Supports strict and non-strict modes. In non-strict mode, some issues
177
+ * (like isolated nodes) generate warnings instead of throwing errors.
178
+ *
179
+ * @param {Map<string, DAGNode>} nodes - Map of node IDs to DAGNode instances
180
+ * @param {Object} options - Validation options
181
+ * @param {boolean} [options.strict=true] - If true, throw errors for all issues.
182
+ * If false, return warnings for non-critical issues
183
+ * @returns {string[]} Array of warning messages (empty if no warnings in strict mode)
184
+ *
185
+ * @throws {Error} If DAG is empty - "DAG cannot be empty"
186
+ * @throws {Error} If self-loop detected - "Self-loop detected"
187
+ * @throws {Error} If cycle detected - "Cycle detected in DAG"
188
+ * - error.cycle: Array of node IDs forming the cycle
189
+ * @throws {Error} If orphaned node found in strict mode
190
+ *
191
+ * @example
192
+ * // Strict mode (default)
193
+ * const nodes = new Map([['isolated', isolatedNode]]);
194
+ * try {
195
+ * validateTopology(nodes, { strict: true });
196
+ * } catch (error) {
197
+ * console.log(error.message); // "Orphaned node detected: isolated"
198
+ * }
199
+ *
200
+ * @example
201
+ * // Non-strict mode (warnings)
202
+ * const nodes = new Map([
203
+ * ['A', nodeA],
204
+ * ['isolated', isolatedNode]
205
+ * ]);
206
+ * const warnings = validateTopology(nodes, { strict: false });
207
+ * console.log(warnings); // ["Orphaned node detected: isolated"]
208
+ *
209
+ * @example
210
+ * // Self-loop detection
211
+ * const nodeWithSelfLoop = new DAGNode('X', () => {});
212
+ * nodeWithSelfLoop.outputs.push(nodeWithSelfLoop);
213
+ * const nodes = new Map([['X', nodeWithSelfLoop]]);
214
+ * try {
215
+ * validateTopology(nodes);
216
+ * } catch (error) {
217
+ * console.log(error.message); // "Self-loop detected"
218
+ * }
219
+ *
220
+ * @performance O(V + E) due to topological sort and graph traversal
221
+ * @complexity Cyclomatic complexity: 5 (within acceptable limits)
222
+ * @since 2.2.2
223
+ */
224
+ export function validateTopology(nodes: Map<string, DAGNode>, options?: {
225
+ strict?: boolean;
226
+ }): string[];
@@ -0,0 +1,156 @@
1
+ export class DAG {
2
+ nodes: Map<any, any>;
3
+ scheduler: ExecutionScheduler;
4
+ errorContext: ErrorContext;
5
+ addNode(id: any, _fn: any, options?: {}): DAGNode;
6
+ connect(fromId: any, toId: any): void;
7
+ /**
8
+ * Parse and normalize execute parameters
9
+ * @param {any} seedOrOptions - Seed data or options object
10
+ * @param {Object} _options - Additional options (if first param is seed)
11
+ * @returns {Object} - Normalized {seed, options} object
12
+ */
13
+ _parseExecuteParams(seedOrOptions: any, _options?: any): any;
14
+ /**
15
+ * Execute all nodes in topological order with concurrency control
16
+ * @param {Array} order - Topologically sorted nodes
17
+ * @param {Object} context - Execution context
18
+ * @returns {Promise<void>}
19
+ */
20
+ _runAllNodes(order: any[], context: any): Promise<void>;
21
+ /**
22
+ * Check if a node can be executed based on dependency satisfaction
23
+ * @param {DAGNode} node - Node to check
24
+ * @param {Object} context - Execution context
25
+ * @returns {boolean}
26
+ */
27
+ _canExecuteNode(node: DAGNode, context: any): boolean;
28
+ /**
29
+ * Initialize execution state and validate DAG
30
+ * @returns {Object} - Execution state object
31
+ */
32
+ _initializeExecutionState(): any;
33
+ /**
34
+ * Handle execution errors with appropriate wrapping
35
+ * @param {Error} error - Error to handle
36
+ * @throws {Error} - Appropriately wrapped error
37
+ */
38
+ _handleExecutionError(error: Error): void;
39
+ /**
40
+ * Execute function with optional timeout
41
+ * @param {Function} runFn - Function to execute
42
+ * @param {number} timeout - Timeout in milliseconds
43
+ * @returns {Promise<void>}
44
+ */
45
+ _executeWithTimeout(runFn: Function, timeout: number): Promise<void>;
46
+ /**
47
+ * Process execution results and handle checkpointing
48
+ * @param {Map} results - Node execution results
49
+ * @param {Map} errors - Node execution errors
50
+ * @param {Map} fwd - Forward adjacency map
51
+ * @param {Object} options - Processing options
52
+ * @returns {any} - Processed results
53
+ */
54
+ _processResults(results: Map<any, any>, errors: Map<any, any>, fwd: Map<any, any>, options: any): any;
55
+ /**
56
+ * Executes the DAG with optional seed data and configuration
57
+ * @param {any} seedOrOptions - Seed data or options object
58
+ * @param {Object} _options - Additional options (if first param is seed)
59
+ * @returns {Promise<any>} - Execution results
60
+ */
61
+ execute(seedOrOptions: any, _options?: any): Promise<any>;
62
+ /**
63
+ * Helper for running with optional global timeout
64
+ * @param {Function} runFn - Function to run
65
+ * @param {number} timeout - Timeout in milliseconds
66
+ * @returns {Promise} - Promise that resolves/rejects with timeout handling
67
+ */
68
+ _runWithOptionalGlobalTimeout(runFn: Function, timeout: number): Promise<any>;
69
+ /**
70
+ * Build adjacency lists for the DAG
71
+ * @returns {Object} - Object with fwd and rev adjacency maps
72
+ */
73
+ _buildAdjacency(): any;
74
+ /**
75
+ * Get sink node IDs (nodes with no outgoing edges)
76
+ * @param {Map} fwd - Forward adjacency map
77
+ * @returns {Array} - Array of sink node IDs
78
+ */
79
+ _getSinkIds(fwd: Map<any, any>): any[];
80
+ /**
81
+ * Get required node IDs (all sinks + all their ancestors)
82
+ * @param {Map} fwd - Forward adjacency map
83
+ * @param {Map} rev - Reverse adjacency map
84
+ * @returns {Set} - Set of required node IDs
85
+ */
86
+ _getRequiredIds(fwd: Map<any, any>, rev: Map<any, any>): Set<any>;
87
+ /**
88
+ * Build adjacency list for the DAG (legacy method for compatibility)
89
+ * @returns {Map} - Adjacency list mapping node IDs to arrays of dependent node IDs
90
+ */
91
+ buildAdjacencyList(): Map<any, any>;
92
+ /**
93
+ * Validates the DAG structure
94
+ * @returns {boolean} - True if valid
95
+ * @throws {Error} - If validation fails
96
+ */
97
+ validate(): boolean;
98
+ /**
99
+ * Execute a single node with input data
100
+ * @param {DAGNode} node - Node to execute
101
+ * @param {Object} context - Execution context
102
+ * @returns {Promise<any>} Node execution result
103
+ */
104
+ executeNode(node: DAGNode, context: any): Promise<any>;
105
+ /**
106
+ * Validate topology with advanced options
107
+ * @param {Object} _options - Validation options
108
+ * @returns {Array} - Array of warnings (empty if no issues)
109
+ */
110
+ validateTopology(_options?: any): any[];
111
+ /**
112
+ * Performs topological sort with cycle detection
113
+ * @returns {DAGNode[]} Topologically sorted nodes
114
+ * @throws {Error} If cycles are detected
115
+ */
116
+ topoSort(): DAGNode[];
117
+ /**
118
+ * Resume execution from checkpoint data
119
+ * @param {Object} checkpointData - Checkpoint data to resume from
120
+ * @returns {Promise<Map>} - Results Map from resumed execution
121
+ */
122
+ resume(checkpointData?: any): Promise<Map<any, any>>;
123
+ /**
124
+ * Save execution checkpoint
125
+ * @param {string} checkpointId - Unique checkpoint identifier
126
+ * @param {Object} state - Execution state to save
127
+ */
128
+ saveCheckpoint(checkpointId: string, state: any): void;
129
+ checkpoints: Map<any, any>;
130
+ /**
131
+ * Load execution checkpoint
132
+ * @param {string} checkpointId - Unique checkpoint identifier
133
+ * @returns {Object|null} - Saved execution state or null if not found
134
+ */
135
+ loadCheckpoint(checkpointId: string): any | null;
136
+ /**
137
+ * List all available checkpoints
138
+ * @returns {Array} - Array of checkpoint IDs with metadata
139
+ */
140
+ listCheckpoints(): any[];
141
+ /**
142
+ * Clear execution checkpoint
143
+ * @param {string} checkpointId - Unique checkpoint identifier
144
+ */
145
+ clearCheckpoint(checkpointId: string): void;
146
+ /**
147
+ * Get all downstream nodes that depend on the given node
148
+ * @param {DAGNode} node - Node to find downstream dependencies for
149
+ * @returns {DAGNode[]} Array of downstream nodes
150
+ */
151
+ getDownstreamNodes(node: DAGNode): DAGNode[];
152
+ }
153
+ import DAGNode = require("./dag-node.js");
154
+ import ExecutionScheduler = require("./core/execution-scheduler.js");
155
+ import ErrorContext = require("./core/error-context.js");
156
+ export { DAGNode };
@@ -0,0 +1,37 @@
1
+ export = DAGNode;
2
+ /**
3
+ * Version: 2.0.2
4
+ * Path: /src/dag/dag-node.js
5
+ * Description: DAG node class for representing individual nodes in the DAG
6
+ * Author: Ali Kahwaji
7
+ */
8
+ declare class DAGNode {
9
+ constructor(id: any, run: any, options?: {});
10
+ id: any;
11
+ run: any;
12
+ inputs: any[];
13
+ outputs: any[];
14
+ timeout: any;
15
+ retries: any;
16
+ priority: any;
17
+ /**
18
+ * Add an output connection to another node
19
+ * @param {DAGNode} node - Target node to connect to
20
+ */
21
+ addOutput(node: DAGNode): this;
22
+ /**
23
+ * Add an input connection from another node
24
+ * @param {DAGNode} node - Source node to connect from
25
+ */
26
+ addInput(node: DAGNode): this;
27
+ /**
28
+ * Remove an output connection
29
+ * @param {DAGNode} node - Target node to disconnect from
30
+ */
31
+ removeOutput(node: DAGNode): this;
32
+ /**
33
+ * Remove an input connection
34
+ * @param {DAGNode} node - Source node to disconnect from
35
+ */
36
+ removeInput(node: DAGNode): this;
37
+ }