snow-flow 1.1.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 (240) hide show
  1. package/.env.example +49 -0
  2. package/.mcp.json +106 -0
  3. package/.mcp.json.template +106 -0
  4. package/LICENSE +21 -0
  5. package/README.md +236 -0
  6. package/bin/snow-flow +4 -0
  7. package/bin/snow-flow.js +3 -0
  8. package/claude-flow +79 -0
  9. package/claude-flow.bat +18 -0
  10. package/claude-flow.config.json +20 -0
  11. package/claude-flow.ps1 +24 -0
  12. package/dist/agents/app-creator.agent.d.ts +55 -0
  13. package/dist/agents/app-creator.agent.d.ts.map +1 -0
  14. package/dist/agents/app-creator.agent.js +1292 -0
  15. package/dist/agents/app-creator.agent.js.map +1 -0
  16. package/dist/agents/base-snow-agent.d.ts +63 -0
  17. package/dist/agents/base-snow-agent.d.ts.map +1 -0
  18. package/dist/agents/base-snow-agent.js +296 -0
  19. package/dist/agents/base-snow-agent.js.map +1 -0
  20. package/dist/agents/script-generator.agent.d.ts +32 -0
  21. package/dist/agents/script-generator.agent.d.ts.map +1 -0
  22. package/dist/agents/script-generator.agent.js +772 -0
  23. package/dist/agents/script-generator.agent.js.map +1 -0
  24. package/dist/agents/ui-builder.agent.d.ts +50 -0
  25. package/dist/agents/ui-builder.agent.d.ts.map +1 -0
  26. package/dist/agents/ui-builder.agent.js +1539 -0
  27. package/dist/agents/ui-builder.agent.js.map +1 -0
  28. package/dist/agents/widget-builder.agent.d.ts +32 -0
  29. package/dist/agents/widget-builder.agent.d.ts.map +1 -0
  30. package/dist/agents/widget-builder.agent.js +439 -0
  31. package/dist/agents/widget-builder.agent.js.map +1 -0
  32. package/dist/agents/workflow-designer.agent.d.ts +31 -0
  33. package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
  34. package/dist/agents/workflow-designer.agent.js +583 -0
  35. package/dist/agents/workflow-designer.agent.js.map +1 -0
  36. package/dist/api/error-handling.d.ts +214 -0
  37. package/dist/api/error-handling.d.ts.map +1 -0
  38. package/dist/api/error-handling.js +594 -0
  39. package/dist/api/error-handling.js.map +1 -0
  40. package/dist/api/flow-designer-api.d.ts +167 -0
  41. package/dist/api/flow-designer-api.d.ts.map +1 -0
  42. package/dist/api/flow-designer-api.js +555 -0
  43. package/dist/api/flow-designer-api.js.map +1 -0
  44. package/dist/api/natural-language-mapper.d.ts +126 -0
  45. package/dist/api/natural-language-mapper.d.ts.map +1 -0
  46. package/dist/api/natural-language-mapper.js +498 -0
  47. package/dist/api/natural-language-mapper.js.map +1 -0
  48. package/dist/api/performance-optimizer.d.ts +240 -0
  49. package/dist/api/performance-optimizer.d.ts.map +1 -0
  50. package/dist/api/performance-optimizer.js +701 -0
  51. package/dist/api/performance-optimizer.js.map +1 -0
  52. package/dist/api/transaction-manager.d.ts +189 -0
  53. package/dist/api/transaction-manager.d.ts.map +1 -0
  54. package/dist/api/transaction-manager.js +576 -0
  55. package/dist/api/transaction-manager.js.map +1 -0
  56. package/dist/cli/deploy-artifact.d.ts +7 -0
  57. package/dist/cli/deploy-artifact.d.ts.map +1 -0
  58. package/dist/cli/deploy-artifact.js +279 -0
  59. package/dist/cli/deploy-artifact.js.map +1 -0
  60. package/dist/cli.d.ts +6 -0
  61. package/dist/cli.d.ts.map +1 -0
  62. package/dist/cli.js +2057 -0
  63. package/dist/cli.js.map +1 -0
  64. package/dist/index.d.ts +10 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +35 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/managers/scope-manager.d.ts +75 -0
  69. package/dist/managers/scope-manager.d.ts.map +1 -0
  70. package/dist/managers/scope-manager.js +448 -0
  71. package/dist/managers/scope-manager.js.map +1 -0
  72. package/dist/mcp/mcp-wrapper.d.ts +8 -0
  73. package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
  74. package/dist/mcp/mcp-wrapper.js +77 -0
  75. package/dist/mcp/mcp-wrapper.js.map +1 -0
  76. package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
  77. package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
  78. package/dist/mcp/servicenow-automation-mcp.js +683 -0
  79. package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
  80. package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
  81. package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
  82. package/dist/mcp/servicenow-deployment-mcp.js +972 -0
  83. package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
  84. package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
  85. package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
  86. package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
  87. package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
  88. package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
  89. package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
  90. package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
  91. package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
  92. package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
  93. package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
  94. package/dist/mcp/servicenow-integration-mcp.js +689 -0
  95. package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
  96. package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
  97. package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
  98. package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
  99. package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
  100. package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
  101. package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
  102. package/dist/mcp/servicenow-mcp-server.js +648 -0
  103. package/dist/mcp/servicenow-mcp-server.js.map +1 -0
  104. package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
  105. package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
  106. package/dist/mcp/servicenow-operations-mcp.js +1287 -0
  107. package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
  108. package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
  109. package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
  110. package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
  111. package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
  112. package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
  113. package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
  114. package/dist/mcp/servicenow-progressive-indexer.js +320 -0
  115. package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
  116. package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
  117. package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
  118. package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
  119. package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
  120. package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
  121. package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
  122. package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
  123. package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
  124. package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
  125. package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
  126. package/dist/mcp/servicenow-update-set-mcp.js +599 -0
  127. package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
  128. package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
  129. package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
  130. package/dist/mcp/start-all-mcp-servers.js +65 -0
  131. package/dist/mcp/start-all-mcp-servers.js.map +1 -0
  132. package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
  133. package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
  134. package/dist/mcp/start-servicenow-mcp.js +64 -0
  135. package/dist/mcp/start-servicenow-mcp.js.map +1 -0
  136. package/dist/mcp/test-simple-mcp.d.ts +6 -0
  137. package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
  138. package/dist/mcp/test-simple-mcp.js +64 -0
  139. package/dist/mcp/test-simple-mcp.js.map +1 -0
  140. package/dist/orchestrator/flow-composer.d.ts +269 -0
  141. package/dist/orchestrator/flow-composer.d.ts.map +1 -0
  142. package/dist/orchestrator/flow-composer.js +2221 -0
  143. package/dist/orchestrator/flow-composer.js.map +1 -0
  144. package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
  145. package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
  146. package/dist/orchestrator/flow-pattern-templates.js +906 -0
  147. package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
  148. package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
  149. package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
  150. package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
  151. package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
  152. package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
  153. package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
  154. package/dist/orchestrator/flow-validation-engine.js +663 -0
  155. package/dist/orchestrator/flow-validation-engine.js.map +1 -0
  156. package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
  157. package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
  158. package/dist/orchestrator/snow-orchestrator.js +235 -0
  159. package/dist/orchestrator/snow-orchestrator.js.map +1 -0
  160. package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
  161. package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
  162. package/dist/orchestrator/subflow-creation-handler.js +791 -0
  163. package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
  164. package/dist/strategies/global-scope-strategy.d.ts +123 -0
  165. package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
  166. package/dist/strategies/global-scope-strategy.js +585 -0
  167. package/dist/strategies/global-scope-strategy.js.map +1 -0
  168. package/dist/types/index.d.ts +138 -0
  169. package/dist/types/index.d.ts.map +1 -0
  170. package/dist/types/index.js +4 -0
  171. package/dist/types/index.js.map +1 -0
  172. package/dist/types/servicenow.types.d.ts +260 -0
  173. package/dist/types/servicenow.types.d.ts.map +1 -0
  174. package/dist/types/servicenow.types.js +3 -0
  175. package/dist/types/servicenow.types.js.map +1 -0
  176. package/dist/types/snow-flow.types.d.ts +114 -0
  177. package/dist/types/snow-flow.types.d.ts.map +1 -0
  178. package/dist/types/snow-flow.types.js +3 -0
  179. package/dist/types/snow-flow.types.js.map +1 -0
  180. package/dist/utils/action-type-cache.d.ts +66 -0
  181. package/dist/utils/action-type-cache.d.ts.map +1 -0
  182. package/dist/utils/action-type-cache.js +237 -0
  183. package/dist/utils/action-type-cache.js.map +1 -0
  184. package/dist/utils/agent-detector.d.ts +35 -0
  185. package/dist/utils/agent-detector.d.ts.map +1 -0
  186. package/dist/utils/agent-detector.js +353 -0
  187. package/dist/utils/agent-detector.js.map +1 -0
  188. package/dist/utils/flow-api-discovery.d.ts +151 -0
  189. package/dist/utils/flow-api-discovery.d.ts.map +1 -0
  190. package/dist/utils/flow-api-discovery.js +440 -0
  191. package/dist/utils/flow-api-discovery.js.map +1 -0
  192. package/dist/utils/flow-xml-generator.d.ts +41 -0
  193. package/dist/utils/flow-xml-generator.d.ts.map +1 -0
  194. package/dist/utils/flow-xml-generator.js +258 -0
  195. package/dist/utils/flow-xml-generator.js.map +1 -0
  196. package/dist/utils/logger.d.ts +13 -0
  197. package/dist/utils/logger.d.ts.map +1 -0
  198. package/dist/utils/logger.js +51 -0
  199. package/dist/utils/logger.js.map +1 -0
  200. package/dist/utils/mcp-auth-middleware.d.ts +58 -0
  201. package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
  202. package/dist/utils/mcp-auth-middleware.js +227 -0
  203. package/dist/utils/mcp-auth-middleware.js.map +1 -0
  204. package/dist/utils/mcp-config-manager.d.ts +126 -0
  205. package/dist/utils/mcp-config-manager.d.ts.map +1 -0
  206. package/dist/utils/mcp-config-manager.js +209 -0
  207. package/dist/utils/mcp-config-manager.js.map +1 -0
  208. package/dist/utils/mcp-server-manager.d.ts +91 -0
  209. package/dist/utils/mcp-server-manager.d.ts.map +1 -0
  210. package/dist/utils/mcp-server-manager.js +338 -0
  211. package/dist/utils/mcp-server-manager.js.map +1 -0
  212. package/dist/utils/scope-utils.d.ts +72 -0
  213. package/dist/utils/scope-utils.d.ts.map +1 -0
  214. package/dist/utils/scope-utils.js +386 -0
  215. package/dist/utils/scope-utils.js.map +1 -0
  216. package/dist/utils/servicenow-client.d.ts +233 -0
  217. package/dist/utils/servicenow-client.d.ts.map +1 -0
  218. package/dist/utils/servicenow-client.js +1465 -0
  219. package/dist/utils/servicenow-client.js.map +1 -0
  220. package/dist/utils/snow-oauth-old.d.ts +65 -0
  221. package/dist/utils/snow-oauth-old.d.ts.map +1 -0
  222. package/dist/utils/snow-oauth-old.js +345 -0
  223. package/dist/utils/snow-oauth-old.js.map +1 -0
  224. package/dist/utils/snow-oauth.d.ts +85 -0
  225. package/dist/utils/snow-oauth.d.ts.map +1 -0
  226. package/dist/utils/snow-oauth.js +512 -0
  227. package/dist/utils/snow-oauth.js.map +1 -0
  228. package/dist/utils/template-engine.d.ts +76 -0
  229. package/dist/utils/template-engine.d.ts.map +1 -0
  230. package/dist/utils/template-engine.js +391 -0
  231. package/dist/utils/template-engine.js.map +1 -0
  232. package/dist/version.d.ts +35 -0
  233. package/dist/version.d.ts.map +1 -0
  234. package/dist/version.js +72 -0
  235. package/dist/version.js.map +1 -0
  236. package/mcp-wrapper.sh +12 -0
  237. package/package.json +77 -0
  238. package/reports/swarm-auto-centralized-1752649029776.json +13 -0
  239. package/scripts/postinstall.js +30 -0
  240. package/scripts/setup-mcp.js +89 -0
@@ -0,0 +1,701 @@
1
+ "use strict";
2
+ /**
3
+ * Performance Optimization and Caching Strategy
4
+ * Advanced caching and performance optimization for ServiceNow API calls
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.PerformanceOptimizer = void 0;
11
+ const logger_js_1 = require("../utils/logger.js");
12
+ const fs_1 = __importDefault(require("fs"));
13
+ const path_1 = __importDefault(require("path"));
14
+ class PerformanceOptimizer {
15
+ constructor(client, config) {
16
+ this.cache = new Map();
17
+ this.batchQueue = new Map();
18
+ this.rateLimiter = new Map();
19
+ this.connectionPool = new Map();
20
+ this.client = client;
21
+ this.logger = new logger_js_1.Logger('PerformanceOptimizer');
22
+ this.config = {
23
+ max_size: 1000,
24
+ default_ttl: 300000, // 5 minutes
25
+ cleanup_interval: 60000, // 1 minute
26
+ persistence_enabled: true,
27
+ compression_enabled: true,
28
+ ...config
29
+ };
30
+ this.metrics = {
31
+ cache_hit_rate: 0,
32
+ cache_miss_rate: 0,
33
+ average_response_time: 0,
34
+ api_call_count: 0,
35
+ cache_size: 0,
36
+ memory_usage: 0,
37
+ bandwidth_saved: 0
38
+ };
39
+ this.startCleanupTimer();
40
+ this.loadPersistedCache();
41
+ }
42
+ /**
43
+ * Optimized API call with caching and performance monitoring
44
+ */
45
+ async optimizedAPICall(request) {
46
+ const startTime = Date.now();
47
+ const cacheKey = request.cache_key || this.generateCacheKey(request);
48
+ // Check cache first
49
+ if (request.cacheable) {
50
+ const cached = this.getFromCache(cacheKey);
51
+ if (cached) {
52
+ const responseTime = Date.now() - startTime;
53
+ this.updateMetrics(true, responseTime);
54
+ return {
55
+ success: true,
56
+ data: cached,
57
+ cached: true,
58
+ response_time: responseTime,
59
+ cache_hit: true
60
+ };
61
+ }
62
+ }
63
+ // Apply rate limiting
64
+ if (this.isRateLimited(request.url)) {
65
+ await this.waitForRateLimit(request.url);
66
+ }
67
+ try {
68
+ // Execute API call
69
+ const response = await this.executeAPICall(request);
70
+ const responseTime = Date.now() - startTime;
71
+ // Cache successful responses
72
+ if (request.cacheable && response.success && response.data) {
73
+ this.setInCache(cacheKey, response.data, {
74
+ ttl: this.getTTLForRequest(request),
75
+ tags: this.getTagsForRequest(request)
76
+ });
77
+ }
78
+ this.updateMetrics(false, responseTime);
79
+ return {
80
+ ...response,
81
+ cached: false,
82
+ response_time: responseTime,
83
+ cache_hit: false
84
+ };
85
+ }
86
+ catch (error) {
87
+ const responseTime = Date.now() - startTime;
88
+ this.updateMetrics(false, responseTime);
89
+ return {
90
+ success: false,
91
+ error: error instanceof Error ? error.message : String(error),
92
+ cached: false,
93
+ response_time: responseTime,
94
+ cache_hit: false
95
+ };
96
+ }
97
+ }
98
+ /**
99
+ * Batch multiple API requests for better performance
100
+ */
101
+ async batchAPIRequests(requests) {
102
+ const batchId = this.generateBatchId();
103
+ const batchRequest = {
104
+ id: batchId,
105
+ requests: requests.sort((a, b) => b.priority - a.priority),
106
+ priority: 'medium',
107
+ timeout: 30000,
108
+ retry_count: 0
109
+ };
110
+ this.batchQueue.set(batchId, batchRequest);
111
+ try {
112
+ // Group requests by type for optimization
113
+ const groupedRequests = this.groupRequestsByType(requests);
114
+ const results = [];
115
+ // Execute groups in parallel
116
+ const groupPromises = Object.entries(groupedRequests).map(async ([type, groupRequests]) => {
117
+ return await this.executeBatchGroup(groupRequests, type);
118
+ });
119
+ const groupResults = await Promise.all(groupPromises);
120
+ // Flatten results
121
+ for (const groupResult of groupResults) {
122
+ results.push(...groupResult);
123
+ }
124
+ return results;
125
+ }
126
+ finally {
127
+ this.batchQueue.delete(batchId);
128
+ }
129
+ }
130
+ /**
131
+ * Preload commonly accessed data
132
+ */
133
+ async preloadData(preloadConfig) {
134
+ const preloadTasks = [];
135
+ if (preloadConfig.action_types) {
136
+ preloadTasks.push(this.preloadActionTypes());
137
+ }
138
+ if (preloadConfig.trigger_types) {
139
+ preloadTasks.push(this.preloadTriggerTypes());
140
+ }
141
+ if (preloadConfig.flow_templates) {
142
+ preloadTasks.push(this.preloadFlowTemplates());
143
+ }
144
+ if (preloadConfig.user_preferences) {
145
+ preloadTasks.push(this.preloadUserPreferences());
146
+ }
147
+ await Promise.all(preloadTasks);
148
+ this.logger.info('Data preloading completed');
149
+ }
150
+ /**
151
+ * Analyze performance and provide optimization suggestions
152
+ */
153
+ analyzePerformance() {
154
+ const bottlenecks = [];
155
+ const optimizationHints = [];
156
+ // Analyze cache hit rate
157
+ if (this.metrics.cache_hit_rate < 0.5) {
158
+ bottlenecks.push('Low cache hit rate');
159
+ optimizationHints.push({
160
+ type: 'cache',
161
+ description: 'Increase cache TTL for frequently accessed data',
162
+ estimated_improvement: 0.3,
163
+ implementation_complexity: 'low'
164
+ });
165
+ }
166
+ // Analyze response times
167
+ if (this.metrics.average_response_time > 2000) {
168
+ bottlenecks.push('High response times');
169
+ optimizationHints.push({
170
+ type: 'parallel',
171
+ description: 'Implement parallel processing for independent requests',
172
+ estimated_improvement: 0.5,
173
+ implementation_complexity: 'medium'
174
+ });
175
+ }
176
+ // Analyze cache size
177
+ if (this.cache.size > this.config.max_size * 0.8) {
178
+ bottlenecks.push('Cache nearing capacity');
179
+ optimizationHints.push({
180
+ type: 'compress',
181
+ description: 'Enable compression for cached data',
182
+ estimated_improvement: 0.4,
183
+ implementation_complexity: 'medium'
184
+ });
185
+ }
186
+ // Analyze API call patterns
187
+ const batchableRequests = this.identifyBatchableRequests();
188
+ if (batchableRequests.length > 0) {
189
+ optimizationHints.push({
190
+ type: 'batch',
191
+ description: `Batch ${batchableRequests.length} similar requests`,
192
+ estimated_improvement: 0.6,
193
+ implementation_complexity: 'high'
194
+ });
195
+ }
196
+ return {
197
+ metrics: this.metrics,
198
+ bottlenecks,
199
+ optimization_hints: optimizationHints
200
+ };
201
+ }
202
+ /**
203
+ * Implement adaptive caching based on usage patterns
204
+ */
205
+ optimizeCaching() {
206
+ const cacheAnalysis = this.analyzeCacheUsage();
207
+ // Adjust TTL based on access patterns
208
+ for (const [key, entry] of this.cache) {
209
+ const accessFrequency = entry.access_count / (Date.now() - entry.timestamp.getTime());
210
+ if (accessFrequency > 0.01) { // Frequently accessed
211
+ entry.ttl = this.config.default_ttl * 2;
212
+ }
213
+ else if (accessFrequency < 0.001) { // Rarely accessed
214
+ entry.ttl = this.config.default_ttl * 0.5;
215
+ }
216
+ }
217
+ // Implement cache warming for predicted requests
218
+ this.warmCache(cacheAnalysis.predicted_requests);
219
+ }
220
+ /**
221
+ * Get from cache with LRU eviction
222
+ */
223
+ getFromCache(key) {
224
+ const entry = this.cache.get(key);
225
+ if (!entry) {
226
+ return null;
227
+ }
228
+ // Check if expired
229
+ if (Date.now() - entry.timestamp.getTime() > entry.ttl) {
230
+ this.cache.delete(key);
231
+ return null;
232
+ }
233
+ // Update access statistics
234
+ entry.access_count++;
235
+ entry.last_accessed = new Date();
236
+ return entry.value;
237
+ }
238
+ /**
239
+ * Set in cache with size management
240
+ */
241
+ setInCache(key, value, options = {}) {
242
+ // Check if cache is full
243
+ if (this.cache.size >= this.config.max_size) {
244
+ this.evictLeastRecent();
245
+ }
246
+ const entry = {
247
+ key,
248
+ value,
249
+ timestamp: new Date(),
250
+ ttl: options.ttl || this.config.default_ttl,
251
+ access_count: 1,
252
+ last_accessed: new Date(),
253
+ tags: options.tags || [],
254
+ size: this.estimateSize(value)
255
+ };
256
+ this.cache.set(key, entry);
257
+ this.updateCacheMetrics();
258
+ }
259
+ /**
260
+ * Execute API call with connection pooling
261
+ */
262
+ async executeAPICall(request) {
263
+ const connection = this.getPooledConnection(request.url);
264
+ try {
265
+ let response;
266
+ switch (request.method) {
267
+ case 'GET':
268
+ response = await this.client.getRecords(this.extractTable(request.url), request.data);
269
+ break;
270
+ case 'POST':
271
+ response = await this.client.createRecord(this.extractTable(request.url), request.data);
272
+ break;
273
+ case 'PUT':
274
+ case 'PATCH':
275
+ response = await this.client.updateRecord(this.extractTable(request.url), request.data.sys_id, request.data);
276
+ break;
277
+ case 'DELETE':
278
+ response = await this.client.deleteRecord(this.extractTable(request.url), request.data.sys_id);
279
+ break;
280
+ default:
281
+ throw new Error(`Unsupported method: ${request.method}`);
282
+ }
283
+ return {
284
+ success: response.success,
285
+ data: response.data,
286
+ error: response.error
287
+ };
288
+ }
289
+ finally {
290
+ this.returnPooledConnection(request.url, connection);
291
+ }
292
+ }
293
+ /**
294
+ * Group requests by type for batch processing
295
+ */
296
+ groupRequestsByType(requests) {
297
+ const groups = {};
298
+ for (const request of requests) {
299
+ const type = `${request.method}_${this.extractTable(request.url)}`;
300
+ if (!groups[type]) {
301
+ groups[type] = [];
302
+ }
303
+ groups[type].push(request);
304
+ }
305
+ return groups;
306
+ }
307
+ /**
308
+ * Execute batch group with parallel processing
309
+ */
310
+ async executeBatchGroup(requests, type) {
311
+ const batchSize = this.getBatchSizeForType(type);
312
+ const results = [];
313
+ // Process requests in batches
314
+ for (let i = 0; i < requests.length; i += batchSize) {
315
+ const batch = requests.slice(i, i + batchSize);
316
+ const batchPromises = batch.map(request => this.optimizedAPICall(request));
317
+ const batchResults = await Promise.all(batchPromises);
318
+ results.push(...batchResults);
319
+ }
320
+ return results;
321
+ }
322
+ /**
323
+ * Preload action types
324
+ */
325
+ async preloadActionTypes() {
326
+ const request = {
327
+ id: 'preload_action_types',
328
+ method: 'GET',
329
+ url: '/api/now/table/sys_hub_action_type_base',
330
+ cacheable: true,
331
+ priority: 1
332
+ };
333
+ await this.optimizedAPICall(request);
334
+ }
335
+ /**
336
+ * Preload trigger types
337
+ */
338
+ async preloadTriggerTypes() {
339
+ const request = {
340
+ id: 'preload_trigger_types',
341
+ method: 'GET',
342
+ url: '/api/now/table/sys_hub_trigger_type',
343
+ cacheable: true,
344
+ priority: 1
345
+ };
346
+ await this.optimizedAPICall(request);
347
+ }
348
+ /**
349
+ * Preload flow templates
350
+ */
351
+ async preloadFlowTemplates() {
352
+ const request = {
353
+ id: 'preload_flow_templates',
354
+ method: 'GET',
355
+ url: '/api/now/table/sys_hub_flow_template',
356
+ cacheable: true,
357
+ priority: 1
358
+ };
359
+ await this.optimizedAPICall(request);
360
+ }
361
+ /**
362
+ * Preload user preferences
363
+ */
364
+ async preloadUserPreferences() {
365
+ const request = {
366
+ id: 'preload_user_preferences',
367
+ method: 'GET',
368
+ url: '/api/now/table/sys_user_preference',
369
+ cacheable: true,
370
+ priority: 1
371
+ };
372
+ await this.optimizedAPICall(request);
373
+ }
374
+ /**
375
+ * Analyze cache usage patterns
376
+ */
377
+ analyzeCacheUsage() {
378
+ const sortedEntries = Array.from(this.cache.entries())
379
+ .sort((a, b) => b[1].access_count - a[1].access_count);
380
+ const mostAccessed = sortedEntries.slice(0, 10).map(([key]) => key);
381
+ const leastAccessed = sortedEntries.slice(-10).map(([key]) => key);
382
+ // Predict likely requests based on patterns
383
+ const predictedRequests = this.predictLikelyRequests(mostAccessed);
384
+ return {
385
+ most_accessed: mostAccessed,
386
+ least_accessed: leastAccessed,
387
+ predicted_requests: predictedRequests
388
+ };
389
+ }
390
+ /**
391
+ * Warm cache with predicted requests
392
+ */
393
+ async warmCache(predictedRequests) {
394
+ const warmingTasks = predictedRequests.map(async (cacheKey) => {
395
+ if (!this.cache.has(cacheKey)) {
396
+ const request = this.reconstructRequestFromCacheKey(cacheKey);
397
+ if (request) {
398
+ await this.optimizedAPICall(request);
399
+ }
400
+ }
401
+ });
402
+ await Promise.all(warmingTasks);
403
+ }
404
+ /**
405
+ * Evict least recently used entries
406
+ */
407
+ evictLeastRecent() {
408
+ const entries = Array.from(this.cache.entries())
409
+ .sort((a, b) => a[1].last_accessed.getTime() - b[1].last_accessed.getTime());
410
+ const entriesToEvict = entries.slice(0, Math.ceil(this.config.max_size * 0.1));
411
+ for (const [key] of entriesToEvict) {
412
+ this.cache.delete(key);
413
+ }
414
+ }
415
+ /**
416
+ * Update performance metrics
417
+ */
418
+ updateMetrics(cacheHit, responseTime) {
419
+ this.metrics.api_call_count++;
420
+ if (cacheHit) {
421
+ this.metrics.cache_hit_rate = (this.metrics.cache_hit_rate * (this.metrics.api_call_count - 1) + 1) / this.metrics.api_call_count;
422
+ }
423
+ else {
424
+ this.metrics.cache_miss_rate = (this.metrics.cache_miss_rate * (this.metrics.api_call_count - 1) + 1) / this.metrics.api_call_count;
425
+ }
426
+ this.metrics.average_response_time = (this.metrics.average_response_time * (this.metrics.api_call_count - 1) + responseTime) / this.metrics.api_call_count;
427
+ }
428
+ /**
429
+ * Update cache metrics
430
+ */
431
+ updateCacheMetrics() {
432
+ this.metrics.cache_size = this.cache.size;
433
+ this.metrics.memory_usage = Array.from(this.cache.values())
434
+ .reduce((total, entry) => total + entry.size, 0);
435
+ }
436
+ /**
437
+ * Generate cache key for request
438
+ */
439
+ generateCacheKey(request) {
440
+ const keyParts = [
441
+ request.method,
442
+ request.url,
443
+ JSON.stringify(request.data),
444
+ JSON.stringify(request.headers)
445
+ ];
446
+ return Buffer.from(keyParts.join('|')).toString('base64');
447
+ }
448
+ /**
449
+ * Get TTL for specific request type
450
+ */
451
+ getTTLForRequest(request) {
452
+ const url = request.url.toLowerCase();
453
+ if (url.includes('action_type') || url.includes('trigger_type')) {
454
+ return 3600000; // 1 hour for metadata
455
+ }
456
+ if (url.includes('flow_template')) {
457
+ return 1800000; // 30 minutes for templates
458
+ }
459
+ if (url.includes('user_preference')) {
460
+ return 600000; // 10 minutes for preferences
461
+ }
462
+ return this.config.default_ttl;
463
+ }
464
+ /**
465
+ * Get tags for request
466
+ */
467
+ getTagsForRequest(request) {
468
+ const tags = [];
469
+ const url = request.url.toLowerCase();
470
+ if (url.includes('action_type'))
471
+ tags.push('action_type');
472
+ if (url.includes('trigger_type'))
473
+ tags.push('trigger_type');
474
+ if (url.includes('flow'))
475
+ tags.push('flow');
476
+ if (url.includes('user'))
477
+ tags.push('user');
478
+ return tags;
479
+ }
480
+ /**
481
+ * Estimate size of cached value
482
+ */
483
+ estimateSize(value) {
484
+ return JSON.stringify(value).length * 2; // Rough estimate
485
+ }
486
+ /**
487
+ * Extract table name from URL
488
+ */
489
+ extractTable(url) {
490
+ const match = url.match(/\/table\/([^\/\?]+)/);
491
+ return match ? match[1] : 'unknown';
492
+ }
493
+ /**
494
+ * Get batch size for request type
495
+ */
496
+ getBatchSizeForType(type) {
497
+ if (type.includes('GET'))
498
+ return 10;
499
+ if (type.includes('POST'))
500
+ return 5;
501
+ if (type.includes('PUT') || type.includes('PATCH'))
502
+ return 3;
503
+ if (type.includes('DELETE'))
504
+ return 3;
505
+ return 5;
506
+ }
507
+ /**
508
+ * Check if request is rate limited
509
+ */
510
+ isRateLimited(url) {
511
+ const domain = this.extractDomain(url);
512
+ const lastRequest = this.rateLimiter.get(domain);
513
+ if (!lastRequest)
514
+ return false;
515
+ const timeSinceLastRequest = Date.now() - lastRequest;
516
+ return timeSinceLastRequest < 100; // 100ms rate limit
517
+ }
518
+ /**
519
+ * Wait for rate limit to clear
520
+ */
521
+ async waitForRateLimit(url) {
522
+ const domain = this.extractDomain(url);
523
+ const lastRequest = this.rateLimiter.get(domain);
524
+ if (lastRequest) {
525
+ const waitTime = 100 - (Date.now() - lastRequest);
526
+ if (waitTime > 0) {
527
+ await new Promise(resolve => setTimeout(resolve, waitTime));
528
+ }
529
+ }
530
+ this.rateLimiter.set(domain, Date.now());
531
+ }
532
+ /**
533
+ * Extract domain from URL
534
+ */
535
+ extractDomain(url) {
536
+ try {
537
+ return new URL(url).hostname;
538
+ }
539
+ catch {
540
+ return 'default';
541
+ }
542
+ }
543
+ /**
544
+ * Get pooled connection
545
+ */
546
+ getPooledConnection(url) {
547
+ const domain = this.extractDomain(url);
548
+ return this.connectionPool.get(domain) || {};
549
+ }
550
+ /**
551
+ * Return pooled connection
552
+ */
553
+ returnPooledConnection(url, connection) {
554
+ const domain = this.extractDomain(url);
555
+ this.connectionPool.set(domain, connection);
556
+ }
557
+ /**
558
+ * Identify batchable requests
559
+ */
560
+ identifyBatchableRequests() {
561
+ // Implementation would analyze request patterns
562
+ return [];
563
+ }
564
+ /**
565
+ * Predict likely requests based on patterns
566
+ */
567
+ predictLikelyRequests(mostAccessed) {
568
+ // Implementation would use ML or pattern analysis
569
+ return mostAccessed.slice(0, 5);
570
+ }
571
+ /**
572
+ * Reconstruct request from cache key
573
+ */
574
+ reconstructRequestFromCacheKey(cacheKey) {
575
+ try {
576
+ const decoded = Buffer.from(cacheKey, 'base64').toString();
577
+ const [method, url, data, headers] = decoded.split('|');
578
+ return {
579
+ id: 'reconstructed',
580
+ method: method,
581
+ url,
582
+ data: JSON.parse(data),
583
+ headers: JSON.parse(headers),
584
+ cacheable: true,
585
+ priority: 1
586
+ };
587
+ }
588
+ catch {
589
+ return null;
590
+ }
591
+ }
592
+ /**
593
+ * Start cleanup timer
594
+ */
595
+ startCleanupTimer() {
596
+ this.cleanupTimer = setInterval(() => {
597
+ this.cleanupExpiredEntries();
598
+ }, this.config.cleanup_interval);
599
+ }
600
+ /**
601
+ * Cleanup expired entries
602
+ */
603
+ cleanupExpiredEntries() {
604
+ const now = Date.now();
605
+ const expiredKeys = [];
606
+ for (const [key, entry] of this.cache) {
607
+ if (now - entry.timestamp.getTime() > entry.ttl) {
608
+ expiredKeys.push(key);
609
+ }
610
+ }
611
+ for (const key of expiredKeys) {
612
+ this.cache.delete(key);
613
+ }
614
+ if (expiredKeys.length > 0) {
615
+ this.logger.debug(`Cleaned up ${expiredKeys.length} expired cache entries`);
616
+ this.updateCacheMetrics();
617
+ }
618
+ }
619
+ /**
620
+ * Load persisted cache
621
+ */
622
+ loadPersistedCache() {
623
+ if (!this.config.persistence_enabled)
624
+ return;
625
+ try {
626
+ const cacheFile = path_1.default.join(process.cwd(), '.snow-flow', 'cache', 'performance_cache.json');
627
+ if (fs_1.default.existsSync(cacheFile)) {
628
+ const cacheData = JSON.parse(fs_1.default.readFileSync(cacheFile, 'utf-8'));
629
+ for (const [key, entry] of Object.entries(cacheData)) {
630
+ this.cache.set(key, {
631
+ ...entry,
632
+ timestamp: new Date(entry.timestamp),
633
+ last_accessed: new Date(entry.last_accessed)
634
+ });
635
+ }
636
+ this.logger.info(`Loaded ${this.cache.size} entries from persisted cache`);
637
+ }
638
+ }
639
+ catch (error) {
640
+ this.logger.warn('Failed to load persisted cache:', error);
641
+ }
642
+ }
643
+ /**
644
+ * Save cache to disk
645
+ */
646
+ saveCacheToDisk() {
647
+ if (!this.config.persistence_enabled)
648
+ return;
649
+ try {
650
+ const cacheDir = path_1.default.join(process.cwd(), '.snow-flow', 'cache');
651
+ if (!fs_1.default.existsSync(cacheDir)) {
652
+ fs_1.default.mkdirSync(cacheDir, { recursive: true });
653
+ }
654
+ const cacheFile = path_1.default.join(cacheDir, 'performance_cache.json');
655
+ const cacheData = Object.fromEntries(this.cache.entries());
656
+ fs_1.default.writeFileSync(cacheFile, JSON.stringify(cacheData, null, 2));
657
+ this.logger.info(`Saved ${this.cache.size} entries to persisted cache`);
658
+ }
659
+ catch (error) {
660
+ this.logger.warn('Failed to save cache to disk:', error);
661
+ }
662
+ }
663
+ /**
664
+ * Clear cache
665
+ */
666
+ clearCache(tags) {
667
+ if (!tags || tags.length === 0) {
668
+ this.cache.clear();
669
+ this.logger.info('Cleared all cache entries');
670
+ }
671
+ else {
672
+ const keysToDelete = [];
673
+ for (const [key, entry] of this.cache) {
674
+ if (entry.tags.some(tag => tags.includes(tag))) {
675
+ keysToDelete.push(key);
676
+ }
677
+ }
678
+ for (const key of keysToDelete) {
679
+ this.cache.delete(key);
680
+ }
681
+ this.logger.info(`Cleared ${keysToDelete.length} cache entries with tags: ${tags.join(', ')}`);
682
+ }
683
+ this.updateCacheMetrics();
684
+ }
685
+ /**
686
+ * Destroy optimizer and cleanup
687
+ */
688
+ destroy() {
689
+ if (this.cleanupTimer) {
690
+ clearInterval(this.cleanupTimer);
691
+ }
692
+ this.saveCacheToDisk();
693
+ this.cache.clear();
694
+ this.batchQueue.clear();
695
+ this.rateLimiter.clear();
696
+ this.connectionPool.clear();
697
+ this.logger.info('Performance optimizer destroyed');
698
+ }
699
+ }
700
+ exports.PerformanceOptimizer = PerformanceOptimizer;
701
+ //# sourceMappingURL=performance-optimizer.js.map