@jagilber-org/index-server 1.19.1

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 (360) hide show
  1. package/CHANGELOG.md +1218 -0
  2. package/CODE_OF_CONDUCT.md +49 -0
  3. package/CONTRIBUTING.md +75 -0
  4. package/LICENSE +21 -0
  5. package/README.md +523 -0
  6. package/SECURITY.md +50 -0
  7. package/dist/config/configUtils.d.ts +11 -0
  8. package/dist/config/configUtils.js +87 -0
  9. package/dist/config/dashboardConfig.d.ts +45 -0
  10. package/dist/config/dashboardConfig.js +63 -0
  11. package/dist/config/defaultValues.d.ts +61 -0
  12. package/dist/config/defaultValues.js +70 -0
  13. package/dist/config/dirConstants.d.ts +17 -0
  14. package/dist/config/dirConstants.js +28 -0
  15. package/dist/config/featureConfig.d.ts +61 -0
  16. package/dist/config/featureConfig.js +121 -0
  17. package/dist/config/runtimeConfig.d.ts +145 -0
  18. package/dist/config/runtimeConfig.js +334 -0
  19. package/dist/config/serverConfig.d.ts +90 -0
  20. package/dist/config/serverConfig.js +164 -0
  21. package/dist/dashboard/analytics/AnalyticsEngine.d.ts +142 -0
  22. package/dist/dashboard/analytics/AnalyticsEngine.js +373 -0
  23. package/dist/dashboard/analytics/BusinessIntelligence.d.ts +187 -0
  24. package/dist/dashboard/analytics/BusinessIntelligence.js +594 -0
  25. package/dist/dashboard/client/admin.html +2150 -0
  26. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/chunk-SP2CHFBE.mjs +1 -0
  27. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/render-T6MDALS3.mjs +27 -0
  28. package/dist/dashboard/client/css/admin.css +1466 -0
  29. package/dist/dashboard/client/js/admin.boot.js +359 -0
  30. package/dist/dashboard/client/js/admin.config.js +196 -0
  31. package/dist/dashboard/client/js/admin.embeddings.js +425 -0
  32. package/dist/dashboard/client/js/admin.graph.js +583 -0
  33. package/dist/dashboard/client/js/admin.instances.js +120 -0
  34. package/dist/dashboard/client/js/admin.instructions.js +552 -0
  35. package/dist/dashboard/client/js/admin.logs.js +113 -0
  36. package/dist/dashboard/client/js/admin.maintenance.js +354 -0
  37. package/dist/dashboard/client/js/admin.messaging.js +635 -0
  38. package/dist/dashboard/client/js/admin.monitor.js +181 -0
  39. package/dist/dashboard/client/js/admin.overview.js +221 -0
  40. package/dist/dashboard/client/js/admin.performance.js +61 -0
  41. package/dist/dashboard/client/js/admin.sessions.js +293 -0
  42. package/dist/dashboard/client/js/admin.sqlite.js +366 -0
  43. package/dist/dashboard/client/js/admin.utils.js +49 -0
  44. package/dist/dashboard/client/js/chart.umd.js +14 -0
  45. package/dist/dashboard/client/js/elk.bundled.js +6696 -0
  46. package/dist/dashboard/client/js/marked.umd.js +74 -0
  47. package/dist/dashboard/client/js/mermaid.min.js +3022 -0
  48. package/dist/dashboard/client/mermaid-layout-elk.esm.min.mjs +1 -0
  49. package/dist/dashboard/export/DataExporter.d.ts +169 -0
  50. package/dist/dashboard/export/DataExporter.js +737 -0
  51. package/dist/dashboard/export/exporters/csvExporter.d.ts +11 -0
  52. package/dist/dashboard/export/exporters/csvExporter.js +46 -0
  53. package/dist/dashboard/export/exporters/exportTypes.d.ts +89 -0
  54. package/dist/dashboard/export/exporters/exportTypes.js +5 -0
  55. package/dist/dashboard/export/exporters/jsonExporter.d.ts +7 -0
  56. package/dist/dashboard/export/exporters/jsonExporter.js +22 -0
  57. package/dist/dashboard/export/exporters/xmlExporter.d.ts +17 -0
  58. package/dist/dashboard/export/exporters/xmlExporter.js +175 -0
  59. package/dist/dashboard/integration/APIIntegration.d.ts +41 -0
  60. package/dist/dashboard/integration/APIIntegration.js +95 -0
  61. package/dist/dashboard/security/SecurityMonitor.d.ts +167 -0
  62. package/dist/dashboard/security/SecurityMonitor.js +559 -0
  63. package/dist/dashboard/server/AdminPanel.d.ts +183 -0
  64. package/dist/dashboard/server/AdminPanel.js +792 -0
  65. package/dist/dashboard/server/AdminPanelConfig.d.ts +42 -0
  66. package/dist/dashboard/server/AdminPanelConfig.js +80 -0
  67. package/dist/dashboard/server/AdminPanelState.d.ts +47 -0
  68. package/dist/dashboard/server/AdminPanelState.js +214 -0
  69. package/dist/dashboard/server/ApiRoutes.d.ts +17 -0
  70. package/dist/dashboard/server/ApiRoutes.js +149 -0
  71. package/dist/dashboard/server/DashboardServer.d.ts +49 -0
  72. package/dist/dashboard/server/DashboardServer.js +159 -0
  73. package/dist/dashboard/server/FileMetricsStorage.d.ts +49 -0
  74. package/dist/dashboard/server/FileMetricsStorage.js +195 -0
  75. package/dist/dashboard/server/HttpTransport.d.ts +23 -0
  76. package/dist/dashboard/server/HttpTransport.js +116 -0
  77. package/dist/dashboard/server/InstanceManager.d.ts +53 -0
  78. package/dist/dashboard/server/InstanceManager.js +284 -0
  79. package/dist/dashboard/server/KnowledgeStore.d.ts +35 -0
  80. package/dist/dashboard/server/KnowledgeStore.js +105 -0
  81. package/dist/dashboard/server/LeaderElection.d.ts +81 -0
  82. package/dist/dashboard/server/LeaderElection.js +268 -0
  83. package/dist/dashboard/server/MetricsCollector.d.ts +200 -0
  84. package/dist/dashboard/server/MetricsCollector.js +803 -0
  85. package/dist/dashboard/server/SessionPersistenceManager.d.ts +88 -0
  86. package/dist/dashboard/server/SessionPersistenceManager.js +457 -0
  87. package/dist/dashboard/server/ThinClient.d.ts +64 -0
  88. package/dist/dashboard/server/ThinClient.js +237 -0
  89. package/dist/dashboard/server/WebSocketManager.d.ts +161 -0
  90. package/dist/dashboard/server/WebSocketManager.js +463 -0
  91. package/dist/dashboard/server/httpLifecycle.d.ts +17 -0
  92. package/dist/dashboard/server/httpLifecycle.js +35 -0
  93. package/dist/dashboard/server/legacyDashboardHtml.d.ts +9 -0
  94. package/dist/dashboard/server/legacyDashboardHtml.js +618 -0
  95. package/dist/dashboard/server/legacyDashboardStyles.d.ts +5 -0
  96. package/dist/dashboard/server/legacyDashboardStyles.js +490 -0
  97. package/dist/dashboard/server/metricsAggregation.d.ts +252 -0
  98. package/dist/dashboard/server/metricsAggregation.js +206 -0
  99. package/dist/dashboard/server/metricsSerializer.d.ts +25 -0
  100. package/dist/dashboard/server/metricsSerializer.js +195 -0
  101. package/dist/dashboard/server/routes/admin.routes.d.ts +16 -0
  102. package/dist/dashboard/server/routes/admin.routes.js +596 -0
  103. package/dist/dashboard/server/routes/alerts.routes.d.ts +7 -0
  104. package/dist/dashboard/server/routes/alerts.routes.js +93 -0
  105. package/dist/dashboard/server/routes/api.feedback.routes.d.ts +73 -0
  106. package/dist/dashboard/server/routes/api.feedback.routes.js +171 -0
  107. package/dist/dashboard/server/routes/api.instructions.routes.d.ts +101 -0
  108. package/dist/dashboard/server/routes/api.instructions.routes.js +213 -0
  109. package/dist/dashboard/server/routes/api.usage.routes.d.ts +57 -0
  110. package/dist/dashboard/server/routes/api.usage.routes.js +374 -0
  111. package/dist/dashboard/server/routes/embeddings.routes.d.ts +6 -0
  112. package/dist/dashboard/server/routes/embeddings.routes.js +246 -0
  113. package/dist/dashboard/server/routes/graph.routes.d.ts +6 -0
  114. package/dist/dashboard/server/routes/graph.routes.js +280 -0
  115. package/dist/dashboard/server/routes/index.d.ts +38 -0
  116. package/dist/dashboard/server/routes/index.js +194 -0
  117. package/dist/dashboard/server/routes/instances.routes.d.ts +6 -0
  118. package/dist/dashboard/server/routes/instances.routes.js +35 -0
  119. package/dist/dashboard/server/routes/instructions.routes.d.ts +8 -0
  120. package/dist/dashboard/server/routes/instructions.routes.js +336 -0
  121. package/dist/dashboard/server/routes/knowledge.routes.d.ts +6 -0
  122. package/dist/dashboard/server/routes/knowledge.routes.js +82 -0
  123. package/dist/dashboard/server/routes/logs.routes.d.ts +6 -0
  124. package/dist/dashboard/server/routes/logs.routes.js +164 -0
  125. package/dist/dashboard/server/routes/messaging.routes.d.ts +16 -0
  126. package/dist/dashboard/server/routes/messaging.routes.js +293 -0
  127. package/dist/dashboard/server/routes/metrics.routes.d.ts +10 -0
  128. package/dist/dashboard/server/routes/metrics.routes.js +346 -0
  129. package/dist/dashboard/server/routes/scripts.routes.d.ts +9 -0
  130. package/dist/dashboard/server/routes/scripts.routes.js +84 -0
  131. package/dist/dashboard/server/routes/sqlite.routes.d.ts +9 -0
  132. package/dist/dashboard/server/routes/sqlite.routes.js +569 -0
  133. package/dist/dashboard/server/routes/status.routes.d.ts +7 -0
  134. package/dist/dashboard/server/routes/status.routes.js +183 -0
  135. package/dist/dashboard/server/routes/synthetic.routes.d.ts +7 -0
  136. package/dist/dashboard/server/routes/synthetic.routes.js +195 -0
  137. package/dist/dashboard/server/routes/tools.routes.d.ts +6 -0
  138. package/dist/dashboard/server/routes/tools.routes.js +46 -0
  139. package/dist/dashboard/server/routes/usage.routes.d.ts +6 -0
  140. package/dist/dashboard/server/routes/usage.routes.js +25 -0
  141. package/dist/dashboard/server/wsInit.d.ts +16 -0
  142. package/dist/dashboard/server/wsInit.js +35 -0
  143. package/dist/externalClientLib.d.ts +1 -0
  144. package/dist/externalClientLib.js +2 -0
  145. package/dist/minimal/index.d.ts +1 -0
  146. package/dist/minimal/index.js +140 -0
  147. package/dist/models/SessionPersistence.d.ts +115 -0
  148. package/dist/models/SessionPersistence.js +66 -0
  149. package/dist/models/instruction.d.ts +45 -0
  150. package/dist/models/instruction.js +2 -0
  151. package/dist/perf/benchmark.d.ts +1 -0
  152. package/dist/perf/benchmark.js +50 -0
  153. package/dist/portableClientWrapper.d.ts +1 -0
  154. package/dist/portableClientWrapper.js +2 -0
  155. package/dist/schemas/index.d.ts +128 -0
  156. package/dist/schemas/index.js +371 -0
  157. package/dist/scripts/runPerformanceBaseline.d.ts +1 -0
  158. package/dist/scripts/runPerformanceBaseline.js +17 -0
  159. package/dist/server/handshakeManager.d.ts +25 -0
  160. package/dist/server/handshakeManager.js +472 -0
  161. package/dist/server/index-server.d.ts +56 -0
  162. package/dist/server/index-server.js +822 -0
  163. package/dist/server/registry.d.ts +44 -0
  164. package/dist/server/registry.js +236 -0
  165. package/dist/server/sdkServer.d.ts +8 -0
  166. package/dist/server/sdkServer.js +299 -0
  167. package/dist/server/shutdownGuard.d.ts +41 -0
  168. package/dist/server/shutdownGuard.js +52 -0
  169. package/dist/server/thin-client.d.ts +22 -0
  170. package/dist/server/thin-client.js +111 -0
  171. package/dist/server/transport.d.ts +41 -0
  172. package/dist/server/transport.js +312 -0
  173. package/dist/server/transportFactory.d.ts +21 -0
  174. package/dist/server/transportFactory.js +429 -0
  175. package/dist/services/atomicFs.d.ts +22 -0
  176. package/dist/services/atomicFs.js +103 -0
  177. package/dist/services/auditLog.d.ts +38 -0
  178. package/dist/services/auditLog.js +142 -0
  179. package/dist/services/autoBackup.d.ts +14 -0
  180. package/dist/services/autoBackup.js +171 -0
  181. package/dist/services/autoSplit.d.ts +32 -0
  182. package/dist/services/autoSplit.js +113 -0
  183. package/dist/services/backupZip.d.ts +25 -0
  184. package/dist/services/backupZip.js +110 -0
  185. package/dist/services/bootstrapGating.d.ts +123 -0
  186. package/dist/services/bootstrapGating.js +221 -0
  187. package/dist/services/canonical.d.ts +23 -0
  188. package/dist/services/canonical.js +65 -0
  189. package/dist/services/categoryRules.d.ts +7 -0
  190. package/dist/services/categoryRules.js +37 -0
  191. package/dist/services/classificationService.d.ts +42 -0
  192. package/dist/services/classificationService.js +168 -0
  193. package/dist/services/embeddingService.d.ts +62 -0
  194. package/dist/services/embeddingService.js +259 -0
  195. package/dist/services/errors.d.ts +22 -0
  196. package/dist/services/errors.js +31 -0
  197. package/dist/services/featureFlags.d.ts +25 -0
  198. package/dist/services/featureFlags.js +89 -0
  199. package/dist/services/features.d.ts +13 -0
  200. package/dist/services/features.js +35 -0
  201. package/dist/services/handlers/instructions.add.d.ts +1 -0
  202. package/dist/services/handlers/instructions.add.js +496 -0
  203. package/dist/services/handlers/instructions.groom.d.ts +1 -0
  204. package/dist/services/handlers/instructions.groom.js +523 -0
  205. package/dist/services/handlers/instructions.import.d.ts +1 -0
  206. package/dist/services/handlers/instructions.import.js +173 -0
  207. package/dist/services/handlers/instructions.patch.d.ts +1 -0
  208. package/dist/services/handlers/instructions.patch.js +167 -0
  209. package/dist/services/handlers/instructions.query.d.ts +163 -0
  210. package/dist/services/handlers/instructions.query.js +522 -0
  211. package/dist/services/handlers/instructions.reload.d.ts +1 -0
  212. package/dist/services/handlers/instructions.reload.js +13 -0
  213. package/dist/services/handlers/instructions.remove.d.ts +1 -0
  214. package/dist/services/handlers/instructions.remove.js +118 -0
  215. package/dist/services/handlers/instructions.shared.d.ts +31 -0
  216. package/dist/services/handlers/instructions.shared.js +124 -0
  217. package/dist/services/handlers.activation.d.ts +1 -0
  218. package/dist/services/handlers.activation.js +203 -0
  219. package/dist/services/handlers.bootstrap.d.ts +1 -0
  220. package/dist/services/handlers.bootstrap.js +38 -0
  221. package/dist/services/handlers.dashboardConfig.d.ts +34 -0
  222. package/dist/services/handlers.dashboardConfig.js +108 -0
  223. package/dist/services/handlers.diagnostics.d.ts +1 -0
  224. package/dist/services/handlers.diagnostics.js +64 -0
  225. package/dist/services/handlers.feedback.d.ts +15 -0
  226. package/dist/services/handlers.feedback.js +378 -0
  227. package/dist/services/handlers.gates.d.ts +1 -0
  228. package/dist/services/handlers.gates.js +46 -0
  229. package/dist/services/handlers.graph.d.ts +53 -0
  230. package/dist/services/handlers.graph.js +231 -0
  231. package/dist/services/handlers.help.d.ts +1 -0
  232. package/dist/services/handlers.help.js +119 -0
  233. package/dist/services/handlers.instructionSchema.d.ts +1 -0
  234. package/dist/services/handlers.instructionSchema.js +227 -0
  235. package/dist/services/handlers.instructions.d.ts +8 -0
  236. package/dist/services/handlers.instructions.js +14 -0
  237. package/dist/services/handlers.instructionsDiagnostics.d.ts +1 -0
  238. package/dist/services/handlers.instructionsDiagnostics.js +14 -0
  239. package/dist/services/handlers.integrity.d.ts +1 -0
  240. package/dist/services/handlers.integrity.js +35 -0
  241. package/dist/services/handlers.manifest.d.ts +1 -0
  242. package/dist/services/handlers.manifest.js +24 -0
  243. package/dist/services/handlers.messaging.d.ts +12 -0
  244. package/dist/services/handlers.messaging.js +203 -0
  245. package/dist/services/handlers.metrics.d.ts +1 -0
  246. package/dist/services/handlers.metrics.js +43 -0
  247. package/dist/services/handlers.promote.d.ts +1 -0
  248. package/dist/services/handlers.promote.js +306 -0
  249. package/dist/services/handlers.prompt.d.ts +1 -0
  250. package/dist/services/handlers.prompt.js +7 -0
  251. package/dist/services/handlers.search.d.ts +69 -0
  252. package/dist/services/handlers.search.js +645 -0
  253. package/dist/services/handlers.testPrimitive.d.ts +1 -0
  254. package/dist/services/handlers.testPrimitive.js +5 -0
  255. package/dist/services/handlers.trace.d.ts +1 -0
  256. package/dist/services/handlers.trace.js +31 -0
  257. package/dist/services/handlers.usage.d.ts +1 -0
  258. package/dist/services/handlers.usage.js +11 -0
  259. package/dist/services/hotScore.d.ts +137 -0
  260. package/dist/services/hotScore.js +244 -0
  261. package/dist/services/indexContext.d.ts +117 -0
  262. package/dist/services/indexContext.js +968 -0
  263. package/dist/services/indexLoader.d.ts +44 -0
  264. package/dist/services/indexLoader.js +921 -0
  265. package/dist/services/indexRepository.d.ts +32 -0
  266. package/dist/services/indexRepository.js +71 -0
  267. package/dist/services/indexingService.d.ts +1 -0
  268. package/dist/services/indexingService.js +2 -0
  269. package/dist/services/instructions.dispatcher.d.ts +1 -0
  270. package/dist/services/instructions.dispatcher.js +231 -0
  271. package/dist/services/logPrefix.d.ts +1 -0
  272. package/dist/services/logPrefix.js +30 -0
  273. package/dist/services/logger.d.ts +52 -0
  274. package/dist/services/logger.js +268 -0
  275. package/dist/services/manifestManager.d.ts +82 -0
  276. package/dist/services/manifestManager.js +200 -0
  277. package/dist/services/messaging/agentMailbox.d.ts +60 -0
  278. package/dist/services/messaging/agentMailbox.js +353 -0
  279. package/dist/services/messaging/messagingPersistence.d.ts +20 -0
  280. package/dist/services/messaging/messagingPersistence.js +111 -0
  281. package/dist/services/messaging/messagingTypes.d.ts +150 -0
  282. package/dist/services/messaging/messagingTypes.js +66 -0
  283. package/dist/services/ownershipService.d.ts +1 -0
  284. package/dist/services/ownershipService.js +38 -0
  285. package/dist/services/performanceBaseline.d.ts +19 -0
  286. package/dist/services/performanceBaseline.js +210 -0
  287. package/dist/services/preflight.d.ts +12 -0
  288. package/dist/services/preflight.js +79 -0
  289. package/dist/services/promptReviewService.d.ts +44 -0
  290. package/dist/services/promptReviewService.js +101 -0
  291. package/dist/services/responseEnvelope.d.ts +6 -0
  292. package/dist/services/responseEnvelope.js +25 -0
  293. package/dist/services/seedBootstrap.d.ts +34 -0
  294. package/dist/services/seedBootstrap.js +427 -0
  295. package/dist/services/storage/factory.d.ts +17 -0
  296. package/dist/services/storage/factory.js +35 -0
  297. package/dist/services/storage/hashUtils.d.ts +11 -0
  298. package/dist/services/storage/hashUtils.js +35 -0
  299. package/dist/services/storage/index.d.ts +12 -0
  300. package/dist/services/storage/index.js +18 -0
  301. package/dist/services/storage/jsonFileStore.d.ts +32 -0
  302. package/dist/services/storage/jsonFileStore.js +241 -0
  303. package/dist/services/storage/migrationEngine.d.ts +35 -0
  304. package/dist/services/storage/migrationEngine.js +93 -0
  305. package/dist/services/storage/sqliteMessageStore.d.ts +53 -0
  306. package/dist/services/storage/sqliteMessageStore.js +146 -0
  307. package/dist/services/storage/sqliteSchema.d.ts +12 -0
  308. package/dist/services/storage/sqliteSchema.js +122 -0
  309. package/dist/services/storage/sqliteStore.d.ts +41 -0
  310. package/dist/services/storage/sqliteStore.js +339 -0
  311. package/dist/services/storage/sqliteUsageStore.d.ts +35 -0
  312. package/dist/services/storage/sqliteUsageStore.js +94 -0
  313. package/dist/services/storage/types.d.ts +171 -0
  314. package/dist/services/storage/types.js +12 -0
  315. package/dist/services/toolHandlers.d.ts +23 -0
  316. package/dist/services/toolHandlers.js +50 -0
  317. package/dist/services/toolRegistry.d.ts +20 -0
  318. package/dist/services/toolRegistry.js +490 -0
  319. package/dist/services/toolRegistry.zod.d.ts +10 -0
  320. package/dist/services/toolRegistry.zod.js +323 -0
  321. package/dist/services/tracing.d.ts +26 -0
  322. package/dist/services/tracing.js +260 -0
  323. package/dist/services/usageBuckets.d.ts +161 -0
  324. package/dist/services/usageBuckets.js +364 -0
  325. package/dist/services/validationService.d.ts +38 -0
  326. package/dist/services/validationService.js +125 -0
  327. package/dist/utils/BufferRing.d.ts +203 -0
  328. package/dist/utils/BufferRing.js +551 -0
  329. package/dist/utils/BufferRingExamples.d.ts +55 -0
  330. package/dist/utils/BufferRingExamples.js +188 -0
  331. package/dist/utils/envUtils.d.ts +42 -0
  332. package/dist/utils/envUtils.js +80 -0
  333. package/dist/utils/memoryMonitor.d.ts +83 -0
  334. package/dist/utils/memoryMonitor.js +275 -0
  335. package/dist/versioning/schemaVersion.d.ts +6 -0
  336. package/dist/versioning/schemaVersion.js +93 -0
  337. package/package.json +134 -0
  338. package/schemas/README.md +13 -0
  339. package/schemas/feedback-entry.schema.json +27 -0
  340. package/schemas/graph-export-v2.schema.json +60 -0
  341. package/schemas/index-server.code-schema.json +38477 -0
  342. package/schemas/instruction.schema.json +262 -0
  343. package/schemas/json-schema/SessionPersistence-persisted-admin-session.schema.json +54 -0
  344. package/schemas/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +51 -0
  345. package/schemas/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +54 -0
  346. package/schemas/json-schema/SessionPersistence-session-persistence-config.schema.json +110 -0
  347. package/schemas/json-schema/SessionPersistence-session-persistence-data.schema.json +229 -0
  348. package/schemas/json-schema/SessionPersistence-session-persistence-manifest.schema.json +109 -0
  349. package/schemas/json-schema/SessionPersistence-session-persistence-metadata.schema.json +55 -0
  350. package/schemas/json-schema/instruction-audience-scope.schema.json +14 -0
  351. package/schemas/json-schema/instruction-content-type.schema.json +17 -0
  352. package/schemas/json-schema/instruction-instruction-entry.schema.json +206 -0
  353. package/schemas/json-schema/instruction-requirement-level.schema.json +16 -0
  354. package/schemas/manifest.json +78 -0
  355. package/schemas/manifest.schema.json +33 -0
  356. package/schemas/usage-batch.schema.json +16 -0
  357. package/schemas/usage-buckets.schema.json +30 -0
  358. package/schemas/usage-event.schema.json +17 -0
  359. package/scripts/copy-dashboard-assets.mjs +170 -0
  360. package/scripts/setup-hooks.cjs +28 -0
@@ -0,0 +1,737 @@
1
+ "use strict";
2
+ /**
3
+ * DataExporter - Phase 4 Advanced Data Export & Reporting System
4
+ *
5
+ * Comprehensive data export capabilities:
6
+ * - Multiple format support (JSON, CSV, Excel, PDF)
7
+ * - Scheduled reporting
8
+ * - Custom report templates
9
+ * - Data filtering and aggregation
10
+ * - Real-time streaming exports
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DataExporter = void 0;
14
+ const jsonExporter_js_1 = require("./exporters/jsonExporter.js");
15
+ const csvExporter_js_1 = require("./exporters/csvExporter.js");
16
+ const xmlExporter_js_1 = require("./exporters/xmlExporter.js");
17
+ class DataExporter {
18
+ exportConfigs = new Map();
19
+ exportJobs = new Map();
20
+ reportTemplates = new Map();
21
+ scheduledJobs = new Map();
22
+ jobCallbacks = [];
23
+ constructor() {
24
+ this.initializeDefaultTemplates();
25
+ this.initializeDefaultConfigs();
26
+ this.startScheduler();
27
+ }
28
+ /**
29
+ * Initialize default report templates
30
+ */
31
+ initializeDefaultTemplates() {
32
+ const defaultTemplates = [
33
+ {
34
+ id: 'daily_summary',
35
+ name: 'Daily Summary Report',
36
+ description: 'Comprehensive daily system summary with key metrics',
37
+ type: 'dashboard_summary',
38
+ sections: [
39
+ {
40
+ id: 'overview',
41
+ title: 'System Overview',
42
+ type: 'metrics',
43
+ dataSource: 'system_health',
44
+ config: { period: '24h' },
45
+ order: 1
46
+ },
47
+ {
48
+ id: 'security_alerts',
49
+ title: 'Security Alerts',
50
+ type: 'table',
51
+ dataSource: 'security_threats',
52
+ config: { severity: ['high', 'critical'] },
53
+ order: 2
54
+ },
55
+ {
56
+ id: 'performance_chart',
57
+ title: 'Performance Trends',
58
+ type: 'chart',
59
+ dataSource: 'performance_metrics',
60
+ config: { chartType: 'line', metrics: ['cpu', 'memory', 'api_latency'] },
61
+ order: 3
62
+ }
63
+ ],
64
+ formatting: {
65
+ pageSize: 'A4',
66
+ orientation: 'portrait',
67
+ margins: { top: 20, right: 20, bottom: 20, left: 20 },
68
+ fontSize: 12,
69
+ fontFamily: 'Arial',
70
+ includeHeader: true,
71
+ includeFooter: true,
72
+ headerText: 'Index Server - Daily Report',
73
+ footerText: 'Generated on {{date}} | Page {{page}}'
74
+ }
75
+ },
76
+ {
77
+ id: 'security_analysis',
78
+ name: 'Security Analysis Report',
79
+ description: 'Detailed security analysis with threat patterns and recommendations',
80
+ type: 'security_report',
81
+ sections: [
82
+ {
83
+ id: 'threat_summary',
84
+ title: 'Threat Summary',
85
+ type: 'metrics',
86
+ dataSource: 'threat_statistics',
87
+ config: { period: '7d' },
88
+ order: 1
89
+ },
90
+ {
91
+ id: 'threat_timeline',
92
+ title: 'Threat Timeline',
93
+ type: 'chart',
94
+ dataSource: 'security_threats',
95
+ config: { chartType: 'timeline', groupBy: 'type' },
96
+ order: 2
97
+ },
98
+ {
99
+ id: 'recommendations',
100
+ title: 'Security Recommendations',
101
+ type: 'text',
102
+ dataSource: 'security_analysis',
103
+ config: { includeActions: true },
104
+ order: 3
105
+ }
106
+ ],
107
+ formatting: {
108
+ pageSize: 'A4',
109
+ orientation: 'portrait',
110
+ margins: { top: 25, right: 25, bottom: 25, left: 25 },
111
+ fontSize: 11,
112
+ fontFamily: 'Times New Roman',
113
+ includeHeader: true,
114
+ includeFooter: true,
115
+ headerText: 'Security Analysis Report - {{dateRange}}',
116
+ footerText: 'Confidential | Page {{page}} of {{totalPages}}'
117
+ }
118
+ }
119
+ ];
120
+ defaultTemplates.forEach(template => {
121
+ this.reportTemplates.set(template.id, template);
122
+ });
123
+ }
124
+ /**
125
+ * Initialize default export configurations
126
+ */
127
+ initializeDefaultConfigs() {
128
+ const defaultConfigs = [
129
+ {
130
+ id: 'daily_metrics_csv',
131
+ name: 'Daily Metrics Export (CSV)',
132
+ format: 'csv',
133
+ dataSource: 'metrics',
134
+ filters: [
135
+ {
136
+ field: 'timestamp',
137
+ operator: 'greater_than',
138
+ value: Date.now() - 86400000 // Last 24 hours
139
+ }
140
+ ],
141
+ columns: [
142
+ { field: 'timestamp', header: 'Timestamp', type: 'date', format: 'ISO' },
143
+ { field: 'metric_type', header: 'Metric Type', type: 'string' },
144
+ { field: 'value', header: 'Value', type: 'number' },
145
+ { field: 'unit', header: 'Unit', type: 'string' }
146
+ ],
147
+ schedule: {
148
+ enabled: true,
149
+ frequency: 'daily',
150
+ interval: 1,
151
+ time: '06:00',
152
+ timezone: 'UTC'
153
+ },
154
+ compression: true,
155
+ encryption: false,
156
+ destination: {
157
+ type: 'local',
158
+ config: { path: './exports/daily-metrics' }
159
+ }
160
+ },
161
+ {
162
+ id: 'security_report_pdf',
163
+ name: 'Weekly Security Report (PDF)',
164
+ format: 'pdf',
165
+ dataSource: 'security',
166
+ filters: [
167
+ {
168
+ field: 'timestamp',
169
+ operator: 'between',
170
+ value: null,
171
+ values: [Date.now() - 604800000, Date.now()] // Last 7 days
172
+ }
173
+ ],
174
+ columns: [
175
+ { field: 'id', header: 'Threat ID', type: 'string' },
176
+ { field: 'type', header: 'Threat Type', type: 'string' },
177
+ { field: 'severity', header: 'Severity', type: 'string' },
178
+ { field: 'timestamp', header: 'Detected', type: 'date', format: 'readable' },
179
+ { field: 'status', header: 'Status', type: 'string' }
180
+ ],
181
+ template: 'security_analysis',
182
+ schedule: {
183
+ enabled: true,
184
+ frequency: 'weekly',
185
+ interval: 1,
186
+ dayOfWeek: 1, // Monday
187
+ time: '08:00',
188
+ timezone: 'UTC'
189
+ },
190
+ compression: false,
191
+ encryption: true,
192
+ destination: {
193
+ type: 'email',
194
+ config: {
195
+ to: ['security@example.com'],
196
+ subject: 'Weekly Security Report - {{dateRange}}',
197
+ body: 'Please find attached the weekly security report for the Index Server.'
198
+ }
199
+ }
200
+ }
201
+ ];
202
+ defaultConfigs.forEach(config => {
203
+ this.exportConfigs.set(config.id, config);
204
+ this.scheduleExport(config);
205
+ });
206
+ }
207
+ /**
208
+ * Start the export scheduler
209
+ */
210
+ startScheduler() {
211
+ // Check for scheduled exports every minute
212
+ setInterval(() => {
213
+ this.checkScheduledExports();
214
+ }, 60000);
215
+ }
216
+ /**
217
+ * Check for scheduled exports that need to run
218
+ */
219
+ checkScheduledExports() {
220
+ const now = Date.now();
221
+ this.exportConfigs.forEach(config => {
222
+ if (!config.schedule?.enabled)
223
+ return;
224
+ const nextRun = config.schedule.nextRun;
225
+ if (nextRun && now >= nextRun) {
226
+ this.executeExport(config.id);
227
+ this.scheduleExport(config);
228
+ }
229
+ });
230
+ }
231
+ /**
232
+ * Schedule an export based on its configuration
233
+ */
234
+ scheduleExport(config) {
235
+ if (!config.schedule?.enabled)
236
+ return;
237
+ const schedule = config.schedule;
238
+ const now = Date.now();
239
+ let nextRun;
240
+ switch (schedule.frequency) {
241
+ case 'hourly':
242
+ nextRun = now + (schedule.interval * 3600000);
243
+ break;
244
+ case 'daily':
245
+ nextRun = this.getNextDailyRun(schedule);
246
+ break;
247
+ case 'weekly':
248
+ nextRun = this.getNextWeeklyRun(schedule);
249
+ break;
250
+ case 'monthly':
251
+ nextRun = this.getNextMonthlyRun(schedule);
252
+ break;
253
+ case 'custom':
254
+ nextRun = now + (schedule.interval * 1000);
255
+ break;
256
+ default:
257
+ return;
258
+ }
259
+ schedule.nextRun = nextRun;
260
+ schedule.lastRun = now;
261
+ }
262
+ /**
263
+ * Calculate next daily run time
264
+ */
265
+ getNextDailyRun(schedule) {
266
+ const now = new Date();
267
+ const [hours, minutes] = (schedule.time || '00:00').split(':').map(Number);
268
+ const nextRun = new Date(now);
269
+ nextRun.setHours(hours, minutes, 0, 0);
270
+ // If time has passed today, schedule for tomorrow
271
+ if (nextRun.getTime() <= now.getTime()) {
272
+ nextRun.setDate(nextRun.getDate() + schedule.interval);
273
+ }
274
+ return nextRun.getTime();
275
+ }
276
+ /**
277
+ * Calculate next weekly run time
278
+ */
279
+ getNextWeeklyRun(schedule) {
280
+ const now = new Date();
281
+ const [hours, minutes] = (schedule.time || '00:00').split(':').map(Number);
282
+ const targetDay = schedule.dayOfWeek || 0;
283
+ const nextRun = new Date(now);
284
+ nextRun.setHours(hours, minutes, 0, 0);
285
+ const currentDay = now.getDay();
286
+ const daysUntilTarget = (targetDay - currentDay + 7) % 7;
287
+ if (daysUntilTarget === 0 && nextRun.getTime() <= now.getTime()) {
288
+ // Target day is today but time has passed, schedule for next week
289
+ nextRun.setDate(nextRun.getDate() + 7);
290
+ }
291
+ else if (daysUntilTarget > 0) {
292
+ nextRun.setDate(nextRun.getDate() + daysUntilTarget);
293
+ }
294
+ return nextRun.getTime();
295
+ }
296
+ /**
297
+ * Calculate next monthly run time
298
+ */
299
+ getNextMonthlyRun(schedule) {
300
+ const now = new Date();
301
+ const [hours, minutes] = (schedule.time || '00:00').split(':').map(Number);
302
+ const targetDay = schedule.dayOfMonth || 1;
303
+ const nextRun = new Date(now);
304
+ nextRun.setDate(targetDay);
305
+ nextRun.setHours(hours, minutes, 0, 0);
306
+ // If target day has passed this month, schedule for next month
307
+ if (nextRun.getTime() <= now.getTime()) {
308
+ nextRun.setMonth(nextRun.getMonth() + schedule.interval);
309
+ }
310
+ return nextRun.getTime();
311
+ }
312
+ /**
313
+ * Execute an export job
314
+ */
315
+ async executeExport(configId) {
316
+ const config = this.exportConfigs.get(configId);
317
+ if (!config) {
318
+ throw new Error(`Export configuration not found: ${configId}`);
319
+ }
320
+ const jobId = `export_${configId}_${Date.now()}`;
321
+ const job = {
322
+ id: jobId,
323
+ configId,
324
+ status: 'pending',
325
+ progress: 0,
326
+ recordsProcessed: 0,
327
+ totalRecords: 0,
328
+ startTime: Date.now()
329
+ };
330
+ this.exportJobs.set(jobId, job);
331
+ this.notifyJobUpdate(job);
332
+ try {
333
+ job.status = 'running';
334
+ this.notifyJobUpdate(job);
335
+ // Get data based on configuration
336
+ const data = await this.getData(config);
337
+ job.totalRecords = Array.isArray(data) ? data.length : 1;
338
+ // Filter data
339
+ const filteredData = this.applyFilters(data, config.filters);
340
+ // Transform data according to columns configuration
341
+ const transformedData = this.transformData(filteredData, config.columns);
342
+ // Export data in specified format
343
+ const outputPath = await this.exportData(transformedData, config);
344
+ job.status = 'completed';
345
+ job.progress = 100;
346
+ job.endTime = Date.now();
347
+ job.outputPath = outputPath;
348
+ job.fileSize = await this.getFileSize(outputPath);
349
+ }
350
+ catch (error) {
351
+ job.status = 'failed';
352
+ job.error = error instanceof Error ? error.message : 'Unknown error';
353
+ job.endTime = Date.now();
354
+ }
355
+ this.notifyJobUpdate(job);
356
+ return jobId;
357
+ }
358
+ /**
359
+ * Get data from specified source
360
+ */
361
+ async getData(config) {
362
+ switch (config.dataSource) {
363
+ case 'metrics':
364
+ return this.getMetricsData();
365
+ case 'analytics':
366
+ return this.getAnalyticsData();
367
+ case 'security':
368
+ return this.getSecurityData();
369
+ case 'feedback':
370
+ return this.getFeedbackData();
371
+ case 'instructions':
372
+ return this.getInstructionsData();
373
+ case 'custom':
374
+ return this.getCustomData(config);
375
+ default:
376
+ throw new Error(`Unsupported data source: ${config.dataSource}`);
377
+ }
378
+ }
379
+ /**
380
+ * Apply filters to data
381
+ */
382
+ applyFilters(data, filters) {
383
+ if (!filters.length)
384
+ return data;
385
+ return data.filter(item => {
386
+ return filters.every(filter => this.evaluateFilter(item, filter));
387
+ });
388
+ }
389
+ /**
390
+ * Evaluate a single filter against a data item
391
+ */
392
+ evaluateFilter(item, filter) {
393
+ if (!item || typeof item !== 'object')
394
+ return false;
395
+ const value = item[filter.field];
396
+ switch (filter.operator) {
397
+ case 'equals':
398
+ return value === filter.value;
399
+ case 'not_equals':
400
+ return value !== filter.value;
401
+ case 'contains':
402
+ return String(value).includes(String(filter.value));
403
+ case 'not_contains':
404
+ return !String(value).includes(String(filter.value));
405
+ case 'greater_than':
406
+ return Number(value) > Number(filter.value);
407
+ case 'less_than':
408
+ return Number(value) < Number(filter.value);
409
+ case 'between': {
410
+ if (!filter.values || filter.values.length !== 2)
411
+ return false;
412
+ const numValue = Number(value);
413
+ return numValue >= Number(filter.values[0]) && numValue <= Number(filter.values[1]);
414
+ }
415
+ case 'in':
416
+ return filter.values ? filter.values.includes(value) : false;
417
+ case 'not_in':
418
+ return filter.values ? !filter.values.includes(value) : true;
419
+ default:
420
+ return true;
421
+ }
422
+ }
423
+ /**
424
+ * Transform data according to column configuration
425
+ */
426
+ transformData(data, columns) {
427
+ if (!columns.length)
428
+ return data;
429
+ return data.map(item => {
430
+ if (!item || typeof item !== 'object')
431
+ return item;
432
+ const transformedItem = {};
433
+ const itemRecord = item;
434
+ columns.forEach(column => {
435
+ let value = itemRecord[column.field];
436
+ // Apply type conversion and formatting
437
+ switch (column.type) {
438
+ case 'date':
439
+ if (typeof value === 'number') {
440
+ const date = new Date(value);
441
+ value = column.format === 'ISO' ? date.toISOString() : date.toLocaleString();
442
+ }
443
+ break;
444
+ case 'number':
445
+ value = Number(value);
446
+ break;
447
+ case 'boolean':
448
+ value = Boolean(value);
449
+ break;
450
+ case 'json':
451
+ value = typeof value === 'object' ? JSON.stringify(value) : value;
452
+ break;
453
+ case 'string':
454
+ default:
455
+ value = String(value);
456
+ break;
457
+ }
458
+ transformedItem[column.header] = value;
459
+ });
460
+ return transformedItem;
461
+ });
462
+ }
463
+ /**
464
+ * Export data in specified format
465
+ */
466
+ async exportData(data, config) {
467
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
468
+ const fileName = `${config.name}_${timestamp}.${config.format}`;
469
+ const outputPath = this.getOutputPath(config, fileName);
470
+ switch (config.format) {
471
+ case 'json':
472
+ await this.exportJSON(data, outputPath, config);
473
+ break;
474
+ case 'csv':
475
+ await this.exportCSV(data, outputPath, config);
476
+ break;
477
+ case 'excel':
478
+ await this.exportExcel(data, outputPath, config);
479
+ break;
480
+ case 'pdf':
481
+ await this.exportPDF(data, outputPath, config);
482
+ break;
483
+ case 'xml':
484
+ await this.exportXML(data, outputPath, config);
485
+ break;
486
+ default:
487
+ throw new Error(`Unsupported export format: ${config.format}`);
488
+ }
489
+ return outputPath;
490
+ }
491
+ /**
492
+ * Get output path for export
493
+ */
494
+ getOutputPath(config, fileName) {
495
+ const destination = config.destination;
496
+ if (destination.type === 'local') {
497
+ const basePath = destination.config.path || './exports';
498
+ return `${basePath}/${fileName}`;
499
+ }
500
+ // For other destination types, use temporary local path
501
+ return `./tmp/exports/${fileName}`;
502
+ }
503
+ /**
504
+ * Export data as JSON
505
+ */
506
+ async exportJSON(data, outputPath, config) {
507
+ await (0, jsonExporter_js_1.exportJSON)(data, outputPath, config.compression);
508
+ }
509
+ /**
510
+ * Export data as CSV
511
+ */
512
+ async exportCSV(data, outputPath, config) {
513
+ await (0, csvExporter_js_1.exportCSV)(data, outputPath, config.compression);
514
+ }
515
+ /**
516
+ * Export data as Excel (simplified implementation)
517
+ */
518
+ async exportExcel(data, outputPath, _config) {
519
+ await (0, csvExporter_js_1.exportExcel)(data, outputPath, _config.compression);
520
+ }
521
+ /**
522
+ * Export data as PDF using template
523
+ */
524
+ async exportPDF(data, outputPath, config) {
525
+ const template = config.template ? this.reportTemplates.get(config.template) : undefined;
526
+ await (0, xmlExporter_js_1.exportPDF)(data, outputPath, template);
527
+ }
528
+ /**
529
+ * Export data as XML
530
+ */
531
+ async exportXML(data, outputPath, config) {
532
+ await (0, xmlExporter_js_1.exportXML)(data, outputPath, config.compression);
533
+ }
534
+ /**
535
+ * Get file size
536
+ */
537
+ async getFileSize(filePath) {
538
+ try {
539
+ const fs = await import('fs').then(m => m.promises);
540
+ const stats = await fs.stat(filePath);
541
+ return stats.size;
542
+ }
543
+ catch {
544
+ return 0;
545
+ }
546
+ }
547
+ /**
548
+ * Data source methods (simplified implementations)
549
+ */
550
+ getMetricsData() {
551
+ // Simulated metrics data
552
+ return Array.from({ length: 100 }, (_, i) => ({
553
+ id: `metric_${i}`,
554
+ timestamp: Date.now() - (i * 60000),
555
+ metric_type: ['cpu', 'memory', 'disk', 'network'][i % 4],
556
+ value: Math.random() * 100,
557
+ unit: ['percentage', 'MB', 'GB', 'Mbps'][i % 4]
558
+ }));
559
+ }
560
+ getAnalyticsData() {
561
+ // Simulated analytics data
562
+ return Array.from({ length: 50 }, (_, i) => ({
563
+ id: `analytics_${i}`,
564
+ timestamp: Date.now() - (i * 3600000),
565
+ event_type: ['page_view', 'api_call', 'error', 'warning'][i % 4],
566
+ count: Math.floor(Math.random() * 1000),
567
+ source: ['dashboard', 'api', 'webhook', 'scheduler'][i % 4]
568
+ }));
569
+ }
570
+ getSecurityData() {
571
+ // Simulated security data
572
+ return Array.from({ length: 20 }, (_, i) => ({
573
+ id: `threat_${i}`,
574
+ timestamp: Date.now() - (i * 7200000),
575
+ type: ['rate_limit_exceeded', 'suspicious_activity', 'authentication_failure'][i % 3],
576
+ severity: ['low', 'medium', 'high', 'critical'][i % 4],
577
+ source: `192.168.1.${100 + i}`,
578
+ status: ['active', 'mitigated', 'resolved'][i % 3]
579
+ }));
580
+ }
581
+ getFeedbackData() {
582
+ // Simulated feedback data
583
+ return Array.from({ length: 30 }, (_, i) => ({
584
+ id: `feedback_${i}`,
585
+ timestamp: Date.now() - (i * 86400000),
586
+ type: ['bug-report', 'feature-request', 'issue'][i % 3],
587
+ severity: ['low', 'medium', 'high'][i % 3],
588
+ title: `Sample feedback item ${i}`,
589
+ status: ['new', 'acknowledged', 'in-progress', 'resolved'][i % 4]
590
+ }));
591
+ }
592
+ getInstructionsData() {
593
+ // Simulated instructions data
594
+ return Array.from({ length: 40 }, (_, i) => ({
595
+ id: `instruction_${i}`,
596
+ timestamp: Date.now() - (i * 3600000),
597
+ type: 'instruction',
598
+ title: `Sample instruction ${i}`,
599
+ author: `user_${i % 5}`,
600
+ status: ['active', 'draft', 'archived'][i % 3]
601
+ }));
602
+ }
603
+ getCustomData(_config) {
604
+ // Placeholder for custom data sources
605
+ return [];
606
+ }
607
+ /**
608
+ * Notify job update
609
+ */
610
+ notifyJobUpdate(job) {
611
+ this.jobCallbacks.forEach(callback => {
612
+ try {
613
+ callback(job);
614
+ }
615
+ catch (error) {
616
+ console.error('Error in export job callback:', error);
617
+ }
618
+ });
619
+ }
620
+ // Public API methods
621
+ /**
622
+ * Create export configuration
623
+ */
624
+ createExportConfig(config) {
625
+ const id = `export_${Date.now()}`;
626
+ const fullConfig = { id, ...config };
627
+ this.exportConfigs.set(id, fullConfig);
628
+ if (fullConfig.schedule?.enabled) {
629
+ this.scheduleExport(fullConfig);
630
+ }
631
+ return id;
632
+ }
633
+ /**
634
+ * Get export configuration
635
+ */
636
+ getExportConfig(id) {
637
+ return this.exportConfigs.get(id);
638
+ }
639
+ /**
640
+ * List all export configurations
641
+ */
642
+ listExportConfigs() {
643
+ return Array.from(this.exportConfigs.values());
644
+ }
645
+ /**
646
+ * Update export configuration
647
+ */
648
+ updateExportConfig(id, updates) {
649
+ const config = this.exportConfigs.get(id);
650
+ if (!config)
651
+ return false;
652
+ Object.assign(config, updates);
653
+ if (config.schedule?.enabled) {
654
+ this.scheduleExport(config);
655
+ }
656
+ return true;
657
+ }
658
+ /**
659
+ * Delete export configuration
660
+ */
661
+ deleteExportConfig(id) {
662
+ const deleted = this.exportConfigs.delete(id);
663
+ // Cancel scheduled job if exists
664
+ const scheduledJob = this.scheduledJobs.get(id);
665
+ if (scheduledJob) {
666
+ clearTimeout(scheduledJob);
667
+ this.scheduledJobs.delete(id);
668
+ }
669
+ return deleted;
670
+ }
671
+ /**
672
+ * Get export job
673
+ */
674
+ getExportJob(id) {
675
+ return this.exportJobs.get(id);
676
+ }
677
+ /**
678
+ * List export jobs
679
+ */
680
+ listExportJobs(configId) {
681
+ const jobs = Array.from(this.exportJobs.values());
682
+ return configId ? jobs.filter(job => job.configId === configId) : jobs;
683
+ }
684
+ /**
685
+ * Cancel export job
686
+ */
687
+ cancelExportJob(id) {
688
+ const job = this.exportJobs.get(id);
689
+ if (!job || job.status !== 'running')
690
+ return false;
691
+ job.status = 'cancelled';
692
+ job.endTime = Date.now();
693
+ this.notifyJobUpdate(job);
694
+ return true;
695
+ }
696
+ /**
697
+ * Register job update callback
698
+ */
699
+ onJobUpdate(callback) {
700
+ this.jobCallbacks.push(callback);
701
+ }
702
+ /**
703
+ * Create report template
704
+ */
705
+ createReportTemplate(template) {
706
+ const id = `template_${Date.now()}`;
707
+ const fullTemplate = { id, ...template };
708
+ this.reportTemplates.set(id, fullTemplate);
709
+ return id;
710
+ }
711
+ /**
712
+ * Get report template
713
+ */
714
+ getReportTemplate(id) {
715
+ return this.reportTemplates.get(id);
716
+ }
717
+ /**
718
+ * List report templates
719
+ */
720
+ listReportTemplates() {
721
+ return Array.from(this.reportTemplates.values());
722
+ }
723
+ /**
724
+ * Get active export jobs
725
+ */
726
+ getActiveJobs() {
727
+ const activeJobs = [];
728
+ const jobValues = Array.from(this.exportJobs.values());
729
+ for (const job of jobValues) {
730
+ if (job.status === 'pending' || job.status === 'running') {
731
+ activeJobs.push(job);
732
+ }
733
+ }
734
+ return activeJobs;
735
+ }
736
+ }
737
+ exports.DataExporter = DataExporter;