@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.
- package/CHANGELOG.md +1218 -0
- package/CODE_OF_CONDUCT.md +49 -0
- package/CONTRIBUTING.md +75 -0
- package/LICENSE +21 -0
- package/README.md +523 -0
- package/SECURITY.md +50 -0
- package/dist/config/configUtils.d.ts +11 -0
- package/dist/config/configUtils.js +87 -0
- package/dist/config/dashboardConfig.d.ts +45 -0
- package/dist/config/dashboardConfig.js +63 -0
- package/dist/config/defaultValues.d.ts +61 -0
- package/dist/config/defaultValues.js +70 -0
- package/dist/config/dirConstants.d.ts +17 -0
- package/dist/config/dirConstants.js +28 -0
- package/dist/config/featureConfig.d.ts +61 -0
- package/dist/config/featureConfig.js +121 -0
- package/dist/config/runtimeConfig.d.ts +145 -0
- package/dist/config/runtimeConfig.js +334 -0
- package/dist/config/serverConfig.d.ts +90 -0
- package/dist/config/serverConfig.js +164 -0
- package/dist/dashboard/analytics/AnalyticsEngine.d.ts +142 -0
- package/dist/dashboard/analytics/AnalyticsEngine.js +373 -0
- package/dist/dashboard/analytics/BusinessIntelligence.d.ts +187 -0
- package/dist/dashboard/analytics/BusinessIntelligence.js +594 -0
- package/dist/dashboard/client/admin.html +2150 -0
- package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/chunk-SP2CHFBE.mjs +1 -0
- package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/render-T6MDALS3.mjs +27 -0
- package/dist/dashboard/client/css/admin.css +1466 -0
- package/dist/dashboard/client/js/admin.boot.js +359 -0
- package/dist/dashboard/client/js/admin.config.js +196 -0
- package/dist/dashboard/client/js/admin.embeddings.js +425 -0
- package/dist/dashboard/client/js/admin.graph.js +583 -0
- package/dist/dashboard/client/js/admin.instances.js +120 -0
- package/dist/dashboard/client/js/admin.instructions.js +552 -0
- package/dist/dashboard/client/js/admin.logs.js +113 -0
- package/dist/dashboard/client/js/admin.maintenance.js +354 -0
- package/dist/dashboard/client/js/admin.messaging.js +635 -0
- package/dist/dashboard/client/js/admin.monitor.js +181 -0
- package/dist/dashboard/client/js/admin.overview.js +221 -0
- package/dist/dashboard/client/js/admin.performance.js +61 -0
- package/dist/dashboard/client/js/admin.sessions.js +293 -0
- package/dist/dashboard/client/js/admin.sqlite.js +366 -0
- package/dist/dashboard/client/js/admin.utils.js +49 -0
- package/dist/dashboard/client/js/chart.umd.js +14 -0
- package/dist/dashboard/client/js/elk.bundled.js +6696 -0
- package/dist/dashboard/client/js/marked.umd.js +74 -0
- package/dist/dashboard/client/js/mermaid.min.js +3022 -0
- package/dist/dashboard/client/mermaid-layout-elk.esm.min.mjs +1 -0
- package/dist/dashboard/export/DataExporter.d.ts +169 -0
- package/dist/dashboard/export/DataExporter.js +737 -0
- package/dist/dashboard/export/exporters/csvExporter.d.ts +11 -0
- package/dist/dashboard/export/exporters/csvExporter.js +46 -0
- package/dist/dashboard/export/exporters/exportTypes.d.ts +89 -0
- package/dist/dashboard/export/exporters/exportTypes.js +5 -0
- package/dist/dashboard/export/exporters/jsonExporter.d.ts +7 -0
- package/dist/dashboard/export/exporters/jsonExporter.js +22 -0
- package/dist/dashboard/export/exporters/xmlExporter.d.ts +17 -0
- package/dist/dashboard/export/exporters/xmlExporter.js +175 -0
- package/dist/dashboard/integration/APIIntegration.d.ts +41 -0
- package/dist/dashboard/integration/APIIntegration.js +95 -0
- package/dist/dashboard/security/SecurityMonitor.d.ts +167 -0
- package/dist/dashboard/security/SecurityMonitor.js +559 -0
- package/dist/dashboard/server/AdminPanel.d.ts +183 -0
- package/dist/dashboard/server/AdminPanel.js +792 -0
- package/dist/dashboard/server/AdminPanelConfig.d.ts +42 -0
- package/dist/dashboard/server/AdminPanelConfig.js +80 -0
- package/dist/dashboard/server/AdminPanelState.d.ts +47 -0
- package/dist/dashboard/server/AdminPanelState.js +214 -0
- package/dist/dashboard/server/ApiRoutes.d.ts +17 -0
- package/dist/dashboard/server/ApiRoutes.js +149 -0
- package/dist/dashboard/server/DashboardServer.d.ts +49 -0
- package/dist/dashboard/server/DashboardServer.js +159 -0
- package/dist/dashboard/server/FileMetricsStorage.d.ts +49 -0
- package/dist/dashboard/server/FileMetricsStorage.js +195 -0
- package/dist/dashboard/server/HttpTransport.d.ts +23 -0
- package/dist/dashboard/server/HttpTransport.js +116 -0
- package/dist/dashboard/server/InstanceManager.d.ts +53 -0
- package/dist/dashboard/server/InstanceManager.js +284 -0
- package/dist/dashboard/server/KnowledgeStore.d.ts +35 -0
- package/dist/dashboard/server/KnowledgeStore.js +105 -0
- package/dist/dashboard/server/LeaderElection.d.ts +81 -0
- package/dist/dashboard/server/LeaderElection.js +268 -0
- package/dist/dashboard/server/MetricsCollector.d.ts +200 -0
- package/dist/dashboard/server/MetricsCollector.js +803 -0
- package/dist/dashboard/server/SessionPersistenceManager.d.ts +88 -0
- package/dist/dashboard/server/SessionPersistenceManager.js +457 -0
- package/dist/dashboard/server/ThinClient.d.ts +64 -0
- package/dist/dashboard/server/ThinClient.js +237 -0
- package/dist/dashboard/server/WebSocketManager.d.ts +161 -0
- package/dist/dashboard/server/WebSocketManager.js +463 -0
- package/dist/dashboard/server/httpLifecycle.d.ts +17 -0
- package/dist/dashboard/server/httpLifecycle.js +35 -0
- package/dist/dashboard/server/legacyDashboardHtml.d.ts +9 -0
- package/dist/dashboard/server/legacyDashboardHtml.js +618 -0
- package/dist/dashboard/server/legacyDashboardStyles.d.ts +5 -0
- package/dist/dashboard/server/legacyDashboardStyles.js +490 -0
- package/dist/dashboard/server/metricsAggregation.d.ts +252 -0
- package/dist/dashboard/server/metricsAggregation.js +206 -0
- package/dist/dashboard/server/metricsSerializer.d.ts +25 -0
- package/dist/dashboard/server/metricsSerializer.js +195 -0
- package/dist/dashboard/server/routes/admin.routes.d.ts +16 -0
- package/dist/dashboard/server/routes/admin.routes.js +596 -0
- package/dist/dashboard/server/routes/alerts.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/alerts.routes.js +93 -0
- package/dist/dashboard/server/routes/api.feedback.routes.d.ts +73 -0
- package/dist/dashboard/server/routes/api.feedback.routes.js +171 -0
- package/dist/dashboard/server/routes/api.instructions.routes.d.ts +101 -0
- package/dist/dashboard/server/routes/api.instructions.routes.js +213 -0
- package/dist/dashboard/server/routes/api.usage.routes.d.ts +57 -0
- package/dist/dashboard/server/routes/api.usage.routes.js +374 -0
- package/dist/dashboard/server/routes/embeddings.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/embeddings.routes.js +246 -0
- package/dist/dashboard/server/routes/graph.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/graph.routes.js +280 -0
- package/dist/dashboard/server/routes/index.d.ts +38 -0
- package/dist/dashboard/server/routes/index.js +194 -0
- package/dist/dashboard/server/routes/instances.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/instances.routes.js +35 -0
- package/dist/dashboard/server/routes/instructions.routes.d.ts +8 -0
- package/dist/dashboard/server/routes/instructions.routes.js +336 -0
- package/dist/dashboard/server/routes/knowledge.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/knowledge.routes.js +82 -0
- package/dist/dashboard/server/routes/logs.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/logs.routes.js +164 -0
- package/dist/dashboard/server/routes/messaging.routes.d.ts +16 -0
- package/dist/dashboard/server/routes/messaging.routes.js +293 -0
- package/dist/dashboard/server/routes/metrics.routes.d.ts +10 -0
- package/dist/dashboard/server/routes/metrics.routes.js +346 -0
- package/dist/dashboard/server/routes/scripts.routes.d.ts +9 -0
- package/dist/dashboard/server/routes/scripts.routes.js +84 -0
- package/dist/dashboard/server/routes/sqlite.routes.d.ts +9 -0
- package/dist/dashboard/server/routes/sqlite.routes.js +569 -0
- package/dist/dashboard/server/routes/status.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/status.routes.js +183 -0
- package/dist/dashboard/server/routes/synthetic.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/synthetic.routes.js +195 -0
- package/dist/dashboard/server/routes/tools.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/tools.routes.js +46 -0
- package/dist/dashboard/server/routes/usage.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/usage.routes.js +25 -0
- package/dist/dashboard/server/wsInit.d.ts +16 -0
- package/dist/dashboard/server/wsInit.js +35 -0
- package/dist/externalClientLib.d.ts +1 -0
- package/dist/externalClientLib.js +2 -0
- package/dist/minimal/index.d.ts +1 -0
- package/dist/minimal/index.js +140 -0
- package/dist/models/SessionPersistence.d.ts +115 -0
- package/dist/models/SessionPersistence.js +66 -0
- package/dist/models/instruction.d.ts +45 -0
- package/dist/models/instruction.js +2 -0
- package/dist/perf/benchmark.d.ts +1 -0
- package/dist/perf/benchmark.js +50 -0
- package/dist/portableClientWrapper.d.ts +1 -0
- package/dist/portableClientWrapper.js +2 -0
- package/dist/schemas/index.d.ts +128 -0
- package/dist/schemas/index.js +371 -0
- package/dist/scripts/runPerformanceBaseline.d.ts +1 -0
- package/dist/scripts/runPerformanceBaseline.js +17 -0
- package/dist/server/handshakeManager.d.ts +25 -0
- package/dist/server/handshakeManager.js +472 -0
- package/dist/server/index-server.d.ts +56 -0
- package/dist/server/index-server.js +822 -0
- package/dist/server/registry.d.ts +44 -0
- package/dist/server/registry.js +236 -0
- package/dist/server/sdkServer.d.ts +8 -0
- package/dist/server/sdkServer.js +299 -0
- package/dist/server/shutdownGuard.d.ts +41 -0
- package/dist/server/shutdownGuard.js +52 -0
- package/dist/server/thin-client.d.ts +22 -0
- package/dist/server/thin-client.js +111 -0
- package/dist/server/transport.d.ts +41 -0
- package/dist/server/transport.js +312 -0
- package/dist/server/transportFactory.d.ts +21 -0
- package/dist/server/transportFactory.js +429 -0
- package/dist/services/atomicFs.d.ts +22 -0
- package/dist/services/atomicFs.js +103 -0
- package/dist/services/auditLog.d.ts +38 -0
- package/dist/services/auditLog.js +142 -0
- package/dist/services/autoBackup.d.ts +14 -0
- package/dist/services/autoBackup.js +171 -0
- package/dist/services/autoSplit.d.ts +32 -0
- package/dist/services/autoSplit.js +113 -0
- package/dist/services/backupZip.d.ts +25 -0
- package/dist/services/backupZip.js +110 -0
- package/dist/services/bootstrapGating.d.ts +123 -0
- package/dist/services/bootstrapGating.js +221 -0
- package/dist/services/canonical.d.ts +23 -0
- package/dist/services/canonical.js +65 -0
- package/dist/services/categoryRules.d.ts +7 -0
- package/dist/services/categoryRules.js +37 -0
- package/dist/services/classificationService.d.ts +42 -0
- package/dist/services/classificationService.js +168 -0
- package/dist/services/embeddingService.d.ts +62 -0
- package/dist/services/embeddingService.js +259 -0
- package/dist/services/errors.d.ts +22 -0
- package/dist/services/errors.js +31 -0
- package/dist/services/featureFlags.d.ts +25 -0
- package/dist/services/featureFlags.js +89 -0
- package/dist/services/features.d.ts +13 -0
- package/dist/services/features.js +35 -0
- package/dist/services/handlers/instructions.add.d.ts +1 -0
- package/dist/services/handlers/instructions.add.js +496 -0
- package/dist/services/handlers/instructions.groom.d.ts +1 -0
- package/dist/services/handlers/instructions.groom.js +523 -0
- package/dist/services/handlers/instructions.import.d.ts +1 -0
- package/dist/services/handlers/instructions.import.js +173 -0
- package/dist/services/handlers/instructions.patch.d.ts +1 -0
- package/dist/services/handlers/instructions.patch.js +167 -0
- package/dist/services/handlers/instructions.query.d.ts +163 -0
- package/dist/services/handlers/instructions.query.js +522 -0
- package/dist/services/handlers/instructions.reload.d.ts +1 -0
- package/dist/services/handlers/instructions.reload.js +13 -0
- package/dist/services/handlers/instructions.remove.d.ts +1 -0
- package/dist/services/handlers/instructions.remove.js +118 -0
- package/dist/services/handlers/instructions.shared.d.ts +31 -0
- package/dist/services/handlers/instructions.shared.js +124 -0
- package/dist/services/handlers.activation.d.ts +1 -0
- package/dist/services/handlers.activation.js +203 -0
- package/dist/services/handlers.bootstrap.d.ts +1 -0
- package/dist/services/handlers.bootstrap.js +38 -0
- package/dist/services/handlers.dashboardConfig.d.ts +34 -0
- package/dist/services/handlers.dashboardConfig.js +108 -0
- package/dist/services/handlers.diagnostics.d.ts +1 -0
- package/dist/services/handlers.diagnostics.js +64 -0
- package/dist/services/handlers.feedback.d.ts +15 -0
- package/dist/services/handlers.feedback.js +378 -0
- package/dist/services/handlers.gates.d.ts +1 -0
- package/dist/services/handlers.gates.js +46 -0
- package/dist/services/handlers.graph.d.ts +53 -0
- package/dist/services/handlers.graph.js +231 -0
- package/dist/services/handlers.help.d.ts +1 -0
- package/dist/services/handlers.help.js +119 -0
- package/dist/services/handlers.instructionSchema.d.ts +1 -0
- package/dist/services/handlers.instructionSchema.js +227 -0
- package/dist/services/handlers.instructions.d.ts +8 -0
- package/dist/services/handlers.instructions.js +14 -0
- package/dist/services/handlers.instructionsDiagnostics.d.ts +1 -0
- package/dist/services/handlers.instructionsDiagnostics.js +14 -0
- package/dist/services/handlers.integrity.d.ts +1 -0
- package/dist/services/handlers.integrity.js +35 -0
- package/dist/services/handlers.manifest.d.ts +1 -0
- package/dist/services/handlers.manifest.js +24 -0
- package/dist/services/handlers.messaging.d.ts +12 -0
- package/dist/services/handlers.messaging.js +203 -0
- package/dist/services/handlers.metrics.d.ts +1 -0
- package/dist/services/handlers.metrics.js +43 -0
- package/dist/services/handlers.promote.d.ts +1 -0
- package/dist/services/handlers.promote.js +306 -0
- package/dist/services/handlers.prompt.d.ts +1 -0
- package/dist/services/handlers.prompt.js +7 -0
- package/dist/services/handlers.search.d.ts +69 -0
- package/dist/services/handlers.search.js +645 -0
- package/dist/services/handlers.testPrimitive.d.ts +1 -0
- package/dist/services/handlers.testPrimitive.js +5 -0
- package/dist/services/handlers.trace.d.ts +1 -0
- package/dist/services/handlers.trace.js +31 -0
- package/dist/services/handlers.usage.d.ts +1 -0
- package/dist/services/handlers.usage.js +11 -0
- package/dist/services/hotScore.d.ts +137 -0
- package/dist/services/hotScore.js +244 -0
- package/dist/services/indexContext.d.ts +117 -0
- package/dist/services/indexContext.js +968 -0
- package/dist/services/indexLoader.d.ts +44 -0
- package/dist/services/indexLoader.js +921 -0
- package/dist/services/indexRepository.d.ts +32 -0
- package/dist/services/indexRepository.js +71 -0
- package/dist/services/indexingService.d.ts +1 -0
- package/dist/services/indexingService.js +2 -0
- package/dist/services/instructions.dispatcher.d.ts +1 -0
- package/dist/services/instructions.dispatcher.js +231 -0
- package/dist/services/logPrefix.d.ts +1 -0
- package/dist/services/logPrefix.js +30 -0
- package/dist/services/logger.d.ts +52 -0
- package/dist/services/logger.js +268 -0
- package/dist/services/manifestManager.d.ts +82 -0
- package/dist/services/manifestManager.js +200 -0
- package/dist/services/messaging/agentMailbox.d.ts +60 -0
- package/dist/services/messaging/agentMailbox.js +353 -0
- package/dist/services/messaging/messagingPersistence.d.ts +20 -0
- package/dist/services/messaging/messagingPersistence.js +111 -0
- package/dist/services/messaging/messagingTypes.d.ts +150 -0
- package/dist/services/messaging/messagingTypes.js +66 -0
- package/dist/services/ownershipService.d.ts +1 -0
- package/dist/services/ownershipService.js +38 -0
- package/dist/services/performanceBaseline.d.ts +19 -0
- package/dist/services/performanceBaseline.js +210 -0
- package/dist/services/preflight.d.ts +12 -0
- package/dist/services/preflight.js +79 -0
- package/dist/services/promptReviewService.d.ts +44 -0
- package/dist/services/promptReviewService.js +101 -0
- package/dist/services/responseEnvelope.d.ts +6 -0
- package/dist/services/responseEnvelope.js +25 -0
- package/dist/services/seedBootstrap.d.ts +34 -0
- package/dist/services/seedBootstrap.js +427 -0
- package/dist/services/storage/factory.d.ts +17 -0
- package/dist/services/storage/factory.js +35 -0
- package/dist/services/storage/hashUtils.d.ts +11 -0
- package/dist/services/storage/hashUtils.js +35 -0
- package/dist/services/storage/index.d.ts +12 -0
- package/dist/services/storage/index.js +18 -0
- package/dist/services/storage/jsonFileStore.d.ts +32 -0
- package/dist/services/storage/jsonFileStore.js +241 -0
- package/dist/services/storage/migrationEngine.d.ts +35 -0
- package/dist/services/storage/migrationEngine.js +93 -0
- package/dist/services/storage/sqliteMessageStore.d.ts +53 -0
- package/dist/services/storage/sqliteMessageStore.js +146 -0
- package/dist/services/storage/sqliteSchema.d.ts +12 -0
- package/dist/services/storage/sqliteSchema.js +122 -0
- package/dist/services/storage/sqliteStore.d.ts +41 -0
- package/dist/services/storage/sqliteStore.js +339 -0
- package/dist/services/storage/sqliteUsageStore.d.ts +35 -0
- package/dist/services/storage/sqliteUsageStore.js +94 -0
- package/dist/services/storage/types.d.ts +171 -0
- package/dist/services/storage/types.js +12 -0
- package/dist/services/toolHandlers.d.ts +23 -0
- package/dist/services/toolHandlers.js +50 -0
- package/dist/services/toolRegistry.d.ts +20 -0
- package/dist/services/toolRegistry.js +490 -0
- package/dist/services/toolRegistry.zod.d.ts +10 -0
- package/dist/services/toolRegistry.zod.js +323 -0
- package/dist/services/tracing.d.ts +26 -0
- package/dist/services/tracing.js +260 -0
- package/dist/services/usageBuckets.d.ts +161 -0
- package/dist/services/usageBuckets.js +364 -0
- package/dist/services/validationService.d.ts +38 -0
- package/dist/services/validationService.js +125 -0
- package/dist/utils/BufferRing.d.ts +203 -0
- package/dist/utils/BufferRing.js +551 -0
- package/dist/utils/BufferRingExamples.d.ts +55 -0
- package/dist/utils/BufferRingExamples.js +188 -0
- package/dist/utils/envUtils.d.ts +42 -0
- package/dist/utils/envUtils.js +80 -0
- package/dist/utils/memoryMonitor.d.ts +83 -0
- package/dist/utils/memoryMonitor.js +275 -0
- package/dist/versioning/schemaVersion.d.ts +6 -0
- package/dist/versioning/schemaVersion.js +93 -0
- package/package.json +134 -0
- package/schemas/README.md +13 -0
- package/schemas/feedback-entry.schema.json +27 -0
- package/schemas/graph-export-v2.schema.json +60 -0
- package/schemas/index-server.code-schema.json +38477 -0
- package/schemas/instruction.schema.json +262 -0
- package/schemas/json-schema/SessionPersistence-persisted-admin-session.schema.json +54 -0
- package/schemas/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +51 -0
- package/schemas/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +54 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-config.schema.json +110 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-data.schema.json +229 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-manifest.schema.json +109 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-metadata.schema.json +55 -0
- package/schemas/json-schema/instruction-audience-scope.schema.json +14 -0
- package/schemas/json-schema/instruction-content-type.schema.json +17 -0
- package/schemas/json-schema/instruction-instruction-entry.schema.json +206 -0
- package/schemas/json-schema/instruction-requirement-level.schema.json +16 -0
- package/schemas/manifest.json +78 -0
- package/schemas/manifest.schema.json +33 -0
- package/schemas/usage-batch.schema.json +16 -0
- package/schemas/usage-buckets.schema.json +30 -0
- package/schemas/usage-event.schema.json +17 -0
- package/scripts/copy-dashboard-assets.mjs +170 -0
- package/scripts/setup-hooks.cjs +28 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WebSocketManager - Phase 1 Dashboard Foundation
|
|
4
|
+
*
|
|
5
|
+
* Manages WebSocket connections for real-time dashboard updates.
|
|
6
|
+
* Provides bidirectional communication between dashboard clients and server.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.WebSocketManager = void 0;
|
|
10
|
+
exports.getWebSocketManager = getWebSocketManager;
|
|
11
|
+
exports.setWebSocketManager = setWebSocketManager;
|
|
12
|
+
const ws_1 = require("ws");
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const MetricsCollector_js_1 = require("./MetricsCollector.js");
|
|
15
|
+
const SessionPersistenceManager_1 = require("./SessionPersistenceManager");
|
|
16
|
+
const envUtils_1 = require("../../utils/envUtils");
|
|
17
|
+
class WebSocketManager {
|
|
18
|
+
wss = null;
|
|
19
|
+
clients = new Set();
|
|
20
|
+
options;
|
|
21
|
+
pingTimer;
|
|
22
|
+
persistenceManager;
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.options = {
|
|
25
|
+
path: options.path ?? '/ws',
|
|
26
|
+
maxConnections: options.maxConnections ?? 100,
|
|
27
|
+
pingInterval: options.pingInterval ?? 30000, // 30 seconds
|
|
28
|
+
pongTimeout: options.pongTimeout ?? 5000, // 5 seconds
|
|
29
|
+
};
|
|
30
|
+
// Initialize session persistence manager
|
|
31
|
+
this.persistenceManager = new SessionPersistenceManager_1.SessionPersistenceManager();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize WebSocket server
|
|
35
|
+
*/
|
|
36
|
+
initialize(server) {
|
|
37
|
+
this.wss = new ws_1.WebSocketServer({
|
|
38
|
+
server,
|
|
39
|
+
path: this.options.path,
|
|
40
|
+
});
|
|
41
|
+
this.wss.on('connection', (ws) => {
|
|
42
|
+
this.handleConnection(ws);
|
|
43
|
+
});
|
|
44
|
+
this.wss.on('error', (error) => {
|
|
45
|
+
console.error('[WebSocket] Server error:', error);
|
|
46
|
+
});
|
|
47
|
+
// Start ping/pong heartbeat
|
|
48
|
+
this.startHeartbeat();
|
|
49
|
+
console.log(`[WebSocket] Server initialized on path ${this.options.path}`);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Broadcast message to all connected clients
|
|
53
|
+
*/
|
|
54
|
+
broadcast(message) {
|
|
55
|
+
if (this.clients.size === 0)
|
|
56
|
+
return;
|
|
57
|
+
const payload = JSON.stringify(message);
|
|
58
|
+
const deadClients = [];
|
|
59
|
+
this.clients.forEach((ws) => {
|
|
60
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
61
|
+
try {
|
|
62
|
+
ws.send(payload);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('[WebSocket] Send error:', error);
|
|
66
|
+
deadClients.push(ws);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
deadClients.push(ws);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// Clean up dead connections
|
|
74
|
+
deadClients.forEach((ws) => {
|
|
75
|
+
this.clients.delete(ws);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Send message to specific client
|
|
80
|
+
*/
|
|
81
|
+
sendToClient(client, message) {
|
|
82
|
+
if (client.readyState === ws_1.WebSocket.OPEN) {
|
|
83
|
+
try {
|
|
84
|
+
client.send(JSON.stringify(message));
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error('[WebSocket] Send to client error:', error);
|
|
88
|
+
this.clients.delete(client);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get connected client count
|
|
94
|
+
*/
|
|
95
|
+
getClientCount() {
|
|
96
|
+
return this.clients.size;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get all connected clients
|
|
100
|
+
*/
|
|
101
|
+
getClients() {
|
|
102
|
+
return Array.from(this.clients);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Close all connections and cleanup
|
|
106
|
+
*/
|
|
107
|
+
close() {
|
|
108
|
+
if (this.pingTimer) {
|
|
109
|
+
clearInterval(this.pingTimer);
|
|
110
|
+
this.pingTimer = undefined;
|
|
111
|
+
}
|
|
112
|
+
this.clients.forEach((ws) => {
|
|
113
|
+
try {
|
|
114
|
+
ws.close(1000, 'Server shutting down');
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('[WebSocket] Close error:', error);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
this.clients.clear();
|
|
121
|
+
if (this.wss) {
|
|
122
|
+
this.wss.close();
|
|
123
|
+
this.wss = null;
|
|
124
|
+
}
|
|
125
|
+
console.log('[WebSocket] Server closed');
|
|
126
|
+
}
|
|
127
|
+
handleConnection(ws) {
|
|
128
|
+
// Add to client set
|
|
129
|
+
this.clients.add(ws);
|
|
130
|
+
// Assign client identity & timestamps
|
|
131
|
+
try {
|
|
132
|
+
ws.clientId = this.safeGenerateClientId();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Fallback simple id
|
|
136
|
+
ws.clientId = `client-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
|
|
137
|
+
}
|
|
138
|
+
ws.connectedAt = Date.now();
|
|
139
|
+
ws.lastActivity = Date.now();
|
|
140
|
+
// Extract client info from request if available
|
|
141
|
+
try {
|
|
142
|
+
const request = ws._socket?.remoteAddress;
|
|
143
|
+
if (request) {
|
|
144
|
+
ws.ipAddress = request;
|
|
145
|
+
}
|
|
146
|
+
// Note: User-Agent would come from upgrade request headers if needed
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Ignore if not available
|
|
150
|
+
}
|
|
151
|
+
// Record connection in metrics
|
|
152
|
+
try {
|
|
153
|
+
(0, MetricsCollector_js_1.getMetricsCollector)().recordConnection(ws.clientId);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.error('[WebSocket] metrics recordConnection failed:', err);
|
|
157
|
+
}
|
|
158
|
+
// Persist connection state
|
|
159
|
+
this.persistConnectionState().catch((error) => {
|
|
160
|
+
console.error('Failed to persist WebSocket connection state:', error);
|
|
161
|
+
});
|
|
162
|
+
// Broadcast connection event
|
|
163
|
+
this.broadcast({
|
|
164
|
+
type: 'client_connect',
|
|
165
|
+
timestamp: Date.now(),
|
|
166
|
+
data: { clientId: ws.clientId, timestamp: ws.connectedAt }
|
|
167
|
+
});
|
|
168
|
+
// Setup client event handlers
|
|
169
|
+
ws.on('message', (data) => {
|
|
170
|
+
try {
|
|
171
|
+
// Update activity timestamp
|
|
172
|
+
ws.lastActivity = Date.now();
|
|
173
|
+
const message = JSON.parse(data.toString());
|
|
174
|
+
this.handleClientMessage(ws, message);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
console.error('[WebSocket] Invalid message format:', error);
|
|
178
|
+
this.sendError(ws, 'Invalid message format');
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
ws.on('close', (code, reason) => {
|
|
182
|
+
this.clients.delete(ws);
|
|
183
|
+
const disconnectTs = Date.now();
|
|
184
|
+
const duration = ws.connectedAt ? disconnectTs - ws.connectedAt : 0;
|
|
185
|
+
const wantStructured = (0, envUtils_1.isDebugOrVerbose)();
|
|
186
|
+
const structuredDisc = { ts: disconnectTs, level: 'info', src: 'websocket', event: 'client_disconnected', code, reason: reason.toString(), id: ws.clientId, durationMs: duration, totalClients: this.clients.size };
|
|
187
|
+
try {
|
|
188
|
+
if (wantStructured) {
|
|
189
|
+
console.log(JSON.stringify(structuredDisc));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log(`[WebSocket] Client disconnected: code=${code} reason=${reason.toString()} id=${ws.clientId} duration=${duration}ms`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch { /* ignore */ }
|
|
196
|
+
if (ws.clientId) {
|
|
197
|
+
try {
|
|
198
|
+
(0, MetricsCollector_js_1.getMetricsCollector)().recordDisconnection(ws.clientId);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
console.error('[WebSocket] metrics recordDisconnection failed:', err);
|
|
202
|
+
}
|
|
203
|
+
this.broadcast({
|
|
204
|
+
type: 'client_disconnect',
|
|
205
|
+
timestamp: disconnectTs,
|
|
206
|
+
data: { clientId: ws.clientId, timestamp: disconnectTs, duration }
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// Persist connection state after disconnect
|
|
210
|
+
this.persistConnectionState().catch((error) => {
|
|
211
|
+
console.error('Failed to persist WebSocket state after disconnect:', error);
|
|
212
|
+
});
|
|
213
|
+
// Push fresh metrics snapshot after disconnect
|
|
214
|
+
this.broadcastMetricsSnapshot();
|
|
215
|
+
});
|
|
216
|
+
ws.on('error', (error) => {
|
|
217
|
+
this.clients.delete(ws);
|
|
218
|
+
const wantStructured = (0, envUtils_1.isDebugOrVerbose)();
|
|
219
|
+
const structuredErr = { ts: Date.now(), level: 'error', src: 'websocket', event: 'client_error', message: error.message, stack: error.stack, id: ws.clientId };
|
|
220
|
+
try {
|
|
221
|
+
if (wantStructured) {
|
|
222
|
+
console.log(JSON.stringify(structuredErr));
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.error('[WebSocket] Client error:', error);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch { /* ignore */ }
|
|
229
|
+
});
|
|
230
|
+
ws.on('pong', () => {
|
|
231
|
+
// Mark as alive (handled by ping/pong mechanism)
|
|
232
|
+
ws.isAlive = true;
|
|
233
|
+
});
|
|
234
|
+
// Send welcome message
|
|
235
|
+
this.sendToClient(ws, {
|
|
236
|
+
type: 'welcome',
|
|
237
|
+
timestamp: Date.now(),
|
|
238
|
+
data: {
|
|
239
|
+
message: 'Connected to Index Server Dashboard',
|
|
240
|
+
version: '1.0.0',
|
|
241
|
+
features: ['real-time-metrics', 'tool-monitoring', 'admin-controls'],
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
const wantStructured = (0, envUtils_1.isDebugOrVerbose)();
|
|
245
|
+
const structuredConn = { ts: Date.now(), level: 'info', src: 'websocket', event: 'client_connected', totalClients: this.clients.size };
|
|
246
|
+
try {
|
|
247
|
+
if (wantStructured) {
|
|
248
|
+
console.log(JSON.stringify(structuredConn));
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
console.log(`[WebSocket] Client connected. Total clients: ${this.clients.size}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch { /* ignore */ }
|
|
255
|
+
// Send immediate metrics snapshot to the new client
|
|
256
|
+
this.sendCurrentMetrics(ws);
|
|
257
|
+
// And broadcast updated snapshot to all clients (active connection count changed)
|
|
258
|
+
this.broadcastMetricsSnapshot();
|
|
259
|
+
}
|
|
260
|
+
handleClientMessage(client, message) {
|
|
261
|
+
try {
|
|
262
|
+
switch (message.type) {
|
|
263
|
+
case 'ping':
|
|
264
|
+
this.sendToClient(client, {
|
|
265
|
+
type: 'pong',
|
|
266
|
+
timestamp: Date.now(),
|
|
267
|
+
data: message.data,
|
|
268
|
+
});
|
|
269
|
+
break;
|
|
270
|
+
case 'subscribe': {
|
|
271
|
+
// Future: Handle subscription to specific events
|
|
272
|
+
const events = message.data?.events || ['all'];
|
|
273
|
+
this.sendToClient(client, {
|
|
274
|
+
type: 'subscribed',
|
|
275
|
+
timestamp: Date.now(),
|
|
276
|
+
data: { events },
|
|
277
|
+
});
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case 'get_metrics':
|
|
281
|
+
this.sendCurrentMetrics(client);
|
|
282
|
+
break;
|
|
283
|
+
default:
|
|
284
|
+
console.warn('[WebSocket] Unknown message type:', message.type);
|
|
285
|
+
this.sendError(client, `Unknown message type: ${message.type}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.error('[WebSocket] Message handling error:', error);
|
|
290
|
+
this.sendError(client, 'Message handling error');
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
sendError(client, message) {
|
|
294
|
+
this.sendToClient(client, {
|
|
295
|
+
type: 'error',
|
|
296
|
+
timestamp: Date.now(),
|
|
297
|
+
data: {
|
|
298
|
+
message,
|
|
299
|
+
severity: 'medium',
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
startHeartbeat() {
|
|
304
|
+
this.pingTimer = setInterval(() => {
|
|
305
|
+
this.clients.forEach((ws) => {
|
|
306
|
+
if (ws.isAlive === false) {
|
|
307
|
+
// Client didn't respond to ping, terminate
|
|
308
|
+
ws.terminate();
|
|
309
|
+
this.clients.delete(ws);
|
|
310
|
+
if (ws.clientId) {
|
|
311
|
+
try {
|
|
312
|
+
(0, MetricsCollector_js_1.getMetricsCollector)().recordDisconnection(ws.clientId);
|
|
313
|
+
}
|
|
314
|
+
catch (err) {
|
|
315
|
+
console.error('[WebSocket] heartbeat disconnect metrics error:', err);
|
|
316
|
+
}
|
|
317
|
+
this.broadcast({
|
|
318
|
+
type: 'client_disconnect',
|
|
319
|
+
timestamp: Date.now(),
|
|
320
|
+
data: { clientId: ws.clientId, timestamp: Date.now(), duration: ws.connectedAt ? Date.now() - ws.connectedAt : 0 }
|
|
321
|
+
});
|
|
322
|
+
this.broadcastMetricsSnapshot();
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
// Mark as potentially dead until pong received
|
|
327
|
+
ws.isAlive = false;
|
|
328
|
+
try {
|
|
329
|
+
ws.ping();
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error('[WebSocket] Ping error:', error);
|
|
333
|
+
this.clients.delete(ws);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}, this.options.pingInterval);
|
|
337
|
+
}
|
|
338
|
+
/** Generate a UUID using crypto.randomUUID if available */
|
|
339
|
+
safeGenerateClientId() {
|
|
340
|
+
if (typeof crypto_1.randomUUID === 'function')
|
|
341
|
+
return (0, crypto_1.randomUUID)();
|
|
342
|
+
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
343
|
+
return crypto.randomUUID();
|
|
344
|
+
}
|
|
345
|
+
return 'client-' + Math.random().toString(36).slice(2);
|
|
346
|
+
}
|
|
347
|
+
/** Send current metrics snapshot to a specific client */
|
|
348
|
+
sendCurrentMetrics(client) {
|
|
349
|
+
try {
|
|
350
|
+
const snapshot = (0, MetricsCollector_js_1.getMetricsCollector)().getCurrentSnapshot();
|
|
351
|
+
this.sendToClient(client, {
|
|
352
|
+
type: 'metrics_update',
|
|
353
|
+
timestamp: Date.now(),
|
|
354
|
+
data: snapshot,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
console.error('[WebSocket] Failed to send metrics snapshot:', err);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/** Broadcast fresh metrics snapshot to all clients */
|
|
362
|
+
broadcastMetricsSnapshot() {
|
|
363
|
+
try {
|
|
364
|
+
const snapshot = (0, MetricsCollector_js_1.getMetricsCollector)().getCurrentSnapshot();
|
|
365
|
+
this.broadcast({
|
|
366
|
+
type: 'metrics_update',
|
|
367
|
+
timestamp: Date.now(),
|
|
368
|
+
data: snapshot,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
console.error('[WebSocket] Failed to broadcast metrics snapshot:', err);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Return lightweight summaries of active websocket connections with real IDs and durations.
|
|
377
|
+
* Exposed via /api/admin/connections for dashboard consumption.
|
|
378
|
+
*/
|
|
379
|
+
getActiveConnectionSummaries() {
|
|
380
|
+
const now = Date.now();
|
|
381
|
+
return this.getClients().map(c => ({
|
|
382
|
+
id: c.clientId || 'unknown',
|
|
383
|
+
connectedAt: c.connectedAt || now,
|
|
384
|
+
durationMs: c.connectedAt ? now - c.connectedAt : 0
|
|
385
|
+
}));
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Persist current WebSocket connection state to disk
|
|
389
|
+
*/
|
|
390
|
+
async persistConnectionState() {
|
|
391
|
+
try {
|
|
392
|
+
// Convert current connections to persistable format
|
|
393
|
+
const webSocketConnections = this.getClients().map(client => ({
|
|
394
|
+
id: client.clientId || 'unknown',
|
|
395
|
+
clientId: client.clientId || 'unknown',
|
|
396
|
+
connectedAt: client.connectedAt ? new Date(client.connectedAt).toISOString() : new Date().toISOString(),
|
|
397
|
+
lastActivity: client.lastActivity ? new Date(client.lastActivity).toISOString() : new Date().toISOString(),
|
|
398
|
+
ipAddress: client.ipAddress,
|
|
399
|
+
userAgent: client.userAgent,
|
|
400
|
+
isActive: client.readyState === ws_1.WebSocket.OPEN,
|
|
401
|
+
persistedAt: new Date().toISOString(),
|
|
402
|
+
version: 1
|
|
403
|
+
}));
|
|
404
|
+
// Get existing data and update connections
|
|
405
|
+
const existingData = await this.persistenceManager.loadData();
|
|
406
|
+
const persistedData = {
|
|
407
|
+
adminSessions: existingData?.adminSessions || [],
|
|
408
|
+
webSocketConnections,
|
|
409
|
+
sessionHistory: existingData?.sessionHistory || [],
|
|
410
|
+
metadata: {
|
|
411
|
+
lastPersisted: new Date().toISOString(),
|
|
412
|
+
version: 1,
|
|
413
|
+
totalSessions: existingData?.adminSessions?.length || 0,
|
|
414
|
+
totalConnections: webSocketConnections.length,
|
|
415
|
+
totalHistoryEntries: existingData?.sessionHistory?.length || 0,
|
|
416
|
+
checksums: {
|
|
417
|
+
sessions: '',
|
|
418
|
+
connections: '',
|
|
419
|
+
history: ''
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
await this.persistenceManager.persistData(persistedData);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
console.error('Failed to persist WebSocket connection state:', error);
|
|
427
|
+
// Don't throw - continue operation
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Update connection activity timestamp
|
|
432
|
+
*/
|
|
433
|
+
updateConnectionActivity(clientId) {
|
|
434
|
+
const client = Array.from(this.clients).find(c => c.clientId === clientId);
|
|
435
|
+
if (client) {
|
|
436
|
+
client.lastActivity = Date.now();
|
|
437
|
+
// Persist activity update (but don't await to avoid blocking)
|
|
438
|
+
this.persistConnectionState().catch((error) => {
|
|
439
|
+
console.error('Failed to persist connection activity update:', error);
|
|
440
|
+
});
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
exports.WebSocketManager = WebSocketManager;
|
|
447
|
+
// Global singleton instance
|
|
448
|
+
let globalWebSocketManager = null;
|
|
449
|
+
/**
|
|
450
|
+
* Get or create the global WebSocket manager instance
|
|
451
|
+
*/
|
|
452
|
+
function getWebSocketManager() {
|
|
453
|
+
if (!globalWebSocketManager) {
|
|
454
|
+
globalWebSocketManager = new WebSocketManager();
|
|
455
|
+
}
|
|
456
|
+
return globalWebSocketManager;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Set a custom WebSocket manager instance (useful for testing)
|
|
460
|
+
*/
|
|
461
|
+
function setWebSocketManager(manager) {
|
|
462
|
+
globalWebSocketManager = manager;
|
|
463
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* httpLifecycle — HTTP/HTTPS server creation, port binding, and graceful shutdown.
|
|
3
|
+
* Extracted from DashboardServer.ts to keep the coordinator within line limits.
|
|
4
|
+
*/
|
|
5
|
+
import { Express } from 'express';
|
|
6
|
+
import { Server as HttpServer } from 'http';
|
|
7
|
+
export interface TlsOptions {
|
|
8
|
+
cert: string;
|
|
9
|
+
key: string;
|
|
10
|
+
ca?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Creates an HTTP or HTTPS server wrapping the given Express app. */
|
|
13
|
+
export declare function buildHttpServer(app: Express, tls?: TlsOptions): HttpServer;
|
|
14
|
+
/** Wraps `server.listen` in a promise; rejects on EADDRINUSE or any other error. */
|
|
15
|
+
export declare function bindToPort(server: HttpServer, port: number, host: string): Promise<void>;
|
|
16
|
+
/** Wraps `server.close` in a promise for graceful shutdown. */
|
|
17
|
+
export declare function closeHttpServer(server: HttpServer): Promise<void>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* httpLifecycle — HTTP/HTTPS server creation, port binding, and graceful shutdown.
|
|
4
|
+
* Extracted from DashboardServer.ts to keep the coordinator within line limits.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.buildHttpServer = buildHttpServer;
|
|
8
|
+
exports.bindToPort = bindToPort;
|
|
9
|
+
exports.closeHttpServer = closeHttpServer;
|
|
10
|
+
const http_1 = require("http");
|
|
11
|
+
const https_1 = require("https");
|
|
12
|
+
/** Creates an HTTP or HTTPS server wrapping the given Express app. */
|
|
13
|
+
function buildHttpServer(app, tls) {
|
|
14
|
+
if (tls) {
|
|
15
|
+
return (0, https_1.createServer)({ cert: tls.cert, key: tls.key, ca: tls.ca }, app);
|
|
16
|
+
}
|
|
17
|
+
return (0, http_1.createServer)(app);
|
|
18
|
+
}
|
|
19
|
+
/** Wraps `server.listen` in a promise; rejects on EADDRINUSE or any other error. */
|
|
20
|
+
function bindToPort(server, port, host) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
server.listen(port, host, () => resolve());
|
|
23
|
+
server.on('error', reject);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/** Wraps `server.close` in a promise for graceful shutdown. */
|
|
27
|
+
function closeHttpServer(server) {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
server.close(() => {
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.log('[Dashboard] Server stopped');
|
|
32
|
+
resolve();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* legacyDashboardHtml - generates the v1 legacy dashboard HTML page.
|
|
3
|
+
* Extracted from DashboardServer.ts to keep the coordinator within line limits.
|
|
4
|
+
* CSS lives in legacyDashboardStyles.ts to stay within per-file line limits.
|
|
5
|
+
*/
|
|
6
|
+
import { MetricsSnapshot } from "./MetricsCollector.js";
|
|
7
|
+
export declare function stripGraphTab(html: string): string;
|
|
8
|
+
export declare function formatUptime(ms: number): string;
|
|
9
|
+
export declare function generateDashboardHtml(nonce: string, snapshot: MetricsSnapshot, webSocketUrl: string | null): string;
|