agentic-qe 2.7.4 → 2.8.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.
- package/CHANGELOG.md +104 -0
- package/README.md +67 -2
- package/dist/cli/commands/agent/spawn.d.ts +12 -1
- package/dist/cli/commands/agent/spawn.d.ts.map +1 -1
- package/dist/cli/commands/agent/spawn.js +95 -8
- package/dist/cli/commands/agent/spawn.js.map +1 -1
- package/dist/cli/index.js +91 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/edge/adapters/BrowserHNSWAdapter.d.ts +134 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.d.ts.map +1 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.js +484 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.js.map +1 -0
- package/dist/edge/adapters/IndexedDBStorage.d.ts +114 -0
- package/dist/edge/adapters/IndexedDBStorage.d.ts.map +1 -0
- package/dist/edge/adapters/IndexedDBStorage.js +478 -0
- package/dist/edge/adapters/IndexedDBStorage.js.map +1 -0
- package/dist/edge/adapters/index.d.ts +12 -0
- package/dist/edge/adapters/index.d.ts.map +1 -0
- package/dist/edge/adapters/index.js +22 -0
- package/dist/edge/adapters/index.js.map +1 -0
- package/dist/edge/browser/BrowserAgent.d.ts +241 -0
- package/dist/edge/browser/BrowserAgent.d.ts.map +1 -0
- package/dist/edge/browser/BrowserAgent.js +743 -0
- package/dist/edge/browser/BrowserAgent.js.map +1 -0
- package/dist/edge/index.d.ts +34 -0
- package/dist/edge/index.d.ts.map +1 -0
- package/dist/edge/index.js +114 -0
- package/dist/edge/index.js.map +1 -0
- package/dist/edge/p2p/coordination/CoordinationManager.d.ts +181 -0
- package/dist/edge/p2p/coordination/CoordinationManager.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/CoordinationManager.js +851 -0
- package/dist/edge/p2p/coordination/CoordinationManager.js.map +1 -0
- package/dist/edge/p2p/coordination/HealthMonitor.d.ts +143 -0
- package/dist/edge/p2p/coordination/HealthMonitor.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/HealthMonitor.js +432 -0
- package/dist/edge/p2p/coordination/HealthMonitor.js.map +1 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.d.ts +146 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.js +783 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.js.map +1 -0
- package/dist/edge/p2p/coordination/index.d.ts +70 -0
- package/dist/edge/p2p/coordination/index.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/index.js +107 -0
- package/dist/edge/p2p/coordination/index.js.map +1 -0
- package/dist/edge/p2p/coordination/types.d.ts +572 -0
- package/dist/edge/p2p/coordination/types.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/types.js +366 -0
- package/dist/edge/p2p/coordination/types.js.map +1 -0
- package/dist/edge/p2p/crdt/CRDTStore.d.ts +324 -0
- package/dist/edge/p2p/crdt/CRDTStore.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/CRDTStore.js +839 -0
- package/dist/edge/p2p/crdt/CRDTStore.js.map +1 -0
- package/dist/edge/p2p/crdt/GCounter.d.ts +173 -0
- package/dist/edge/p2p/crdt/GCounter.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/GCounter.js +394 -0
- package/dist/edge/p2p/crdt/GCounter.js.map +1 -0
- package/dist/edge/p2p/crdt/LWWRegister.d.ts +200 -0
- package/dist/edge/p2p/crdt/LWWRegister.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/LWWRegister.js +456 -0
- package/dist/edge/p2p/crdt/LWWRegister.js.map +1 -0
- package/dist/edge/p2p/crdt/ORSet.d.ts +232 -0
- package/dist/edge/p2p/crdt/ORSet.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/ORSet.js +723 -0
- package/dist/edge/p2p/crdt/ORSet.js.map +1 -0
- package/dist/edge/p2p/crdt/PatternCRDT.d.ts +366 -0
- package/dist/edge/p2p/crdt/PatternCRDT.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/PatternCRDT.js +838 -0
- package/dist/edge/p2p/crdt/PatternCRDT.js.map +1 -0
- package/dist/edge/p2p/crdt/VectorClock.d.ts +274 -0
- package/dist/edge/p2p/crdt/VectorClock.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/VectorClock.js +499 -0
- package/dist/edge/p2p/crdt/VectorClock.js.map +1 -0
- package/dist/edge/p2p/crdt/index.d.ts +87 -0
- package/dist/edge/p2p/crdt/index.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/index.js +120 -0
- package/dist/edge/p2p/crdt/index.js.map +1 -0
- package/dist/edge/p2p/crdt/types.d.ts +667 -0
- package/dist/edge/p2p/crdt/types.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/types.js +208 -0
- package/dist/edge/p2p/crdt/types.js.map +1 -0
- package/dist/edge/p2p/crypto/Identity.d.ts +139 -0
- package/dist/edge/p2p/crypto/Identity.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/Identity.js +449 -0
- package/dist/edge/p2p/crypto/Identity.js.map +1 -0
- package/dist/edge/p2p/crypto/KeyManager.d.ts +196 -0
- package/dist/edge/p2p/crypto/KeyManager.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/KeyManager.js +576 -0
- package/dist/edge/p2p/crypto/KeyManager.js.map +1 -0
- package/dist/edge/p2p/crypto/Signer.d.ts +164 -0
- package/dist/edge/p2p/crypto/Signer.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/Signer.js +357 -0
- package/dist/edge/p2p/crypto/Signer.js.map +1 -0
- package/dist/edge/p2p/crypto/index.d.ts +90 -0
- package/dist/edge/p2p/crypto/index.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/index.js +158 -0
- package/dist/edge/p2p/crypto/index.js.map +1 -0
- package/dist/edge/p2p/crypto/types.d.ts +217 -0
- package/dist/edge/p2p/crypto/types.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/types.js +42 -0
- package/dist/edge/p2p/crypto/types.js.map +1 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.d.ts +270 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.d.ts.map +1 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.js +824 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.js.map +1 -0
- package/dist/edge/p2p/federated/FederatedRound.d.ts +295 -0
- package/dist/edge/p2p/federated/FederatedRound.d.ts.map +1 -0
- package/dist/edge/p2p/federated/FederatedRound.js +819 -0
- package/dist/edge/p2p/federated/FederatedRound.js.map +1 -0
- package/dist/edge/p2p/federated/GradientAggregator.d.ts +226 -0
- package/dist/edge/p2p/federated/GradientAggregator.d.ts.map +1 -0
- package/dist/edge/p2p/federated/GradientAggregator.js +826 -0
- package/dist/edge/p2p/federated/GradientAggregator.js.map +1 -0
- package/dist/edge/p2p/federated/ModelManager.d.ts +248 -0
- package/dist/edge/p2p/federated/ModelManager.d.ts.map +1 -0
- package/dist/edge/p2p/federated/ModelManager.js +724 -0
- package/dist/edge/p2p/federated/ModelManager.js.map +1 -0
- package/dist/edge/p2p/federated/index.d.ts +65 -0
- package/dist/edge/p2p/federated/index.d.ts.map +1 -0
- package/dist/edge/p2p/federated/index.js +110 -0
- package/dist/edge/p2p/federated/index.js.map +1 -0
- package/dist/edge/p2p/federated/types.d.ts +905 -0
- package/dist/edge/p2p/federated/types.d.ts.map +1 -0
- package/dist/edge/p2p/federated/types.js +339 -0
- package/dist/edge/p2p/federated/types.js.map +1 -0
- package/dist/edge/p2p/index.d.ts +156 -0
- package/dist/edge/p2p/index.d.ts.map +1 -0
- package/dist/edge/p2p/index.js +242 -0
- package/dist/edge/p2p/index.js.map +1 -0
- package/dist/edge/p2p/nat/ConnectivityTester.d.ts +128 -0
- package/dist/edge/p2p/nat/ConnectivityTester.d.ts.map +1 -0
- package/dist/edge/p2p/nat/ConnectivityTester.js +560 -0
- package/dist/edge/p2p/nat/ConnectivityTester.js.map +1 -0
- package/dist/edge/p2p/nat/HolePuncher.d.ts +159 -0
- package/dist/edge/p2p/nat/HolePuncher.d.ts.map +1 -0
- package/dist/edge/p2p/nat/HolePuncher.js +569 -0
- package/dist/edge/p2p/nat/HolePuncher.js.map +1 -0
- package/dist/edge/p2p/nat/NATDetector.d.ts +109 -0
- package/dist/edge/p2p/nat/NATDetector.d.ts.map +1 -0
- package/dist/edge/p2p/nat/NATDetector.js +472 -0
- package/dist/edge/p2p/nat/NATDetector.js.map +1 -0
- package/dist/edge/p2p/nat/TURNManager.d.ts +158 -0
- package/dist/edge/p2p/nat/TURNManager.d.ts.map +1 -0
- package/dist/edge/p2p/nat/TURNManager.js +547 -0
- package/dist/edge/p2p/nat/TURNManager.js.map +1 -0
- package/dist/edge/p2p/nat/index.d.ts +74 -0
- package/dist/edge/p2p/nat/index.d.ts.map +1 -0
- package/dist/edge/p2p/nat/index.js +104 -0
- package/dist/edge/p2p/nat/index.js.map +1 -0
- package/dist/edge/p2p/nat/types.d.ts +583 -0
- package/dist/edge/p2p/nat/types.d.ts.map +1 -0
- package/dist/edge/p2p/nat/types.js +267 -0
- package/dist/edge/p2p/nat/types.js.map +1 -0
- package/dist/edge/p2p/protocol/AgentChannel.d.ts +333 -0
- package/dist/edge/p2p/protocol/AgentChannel.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/AgentChannel.js +914 -0
- package/dist/edge/p2p/protocol/AgentChannel.js.map +1 -0
- package/dist/edge/p2p/protocol/MessageEncoder.d.ts +147 -0
- package/dist/edge/p2p/protocol/MessageEncoder.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/MessageEncoder.js +738 -0
- package/dist/edge/p2p/protocol/MessageEncoder.js.map +1 -0
- package/dist/edge/p2p/protocol/MessageRouter.d.ts +266 -0
- package/dist/edge/p2p/protocol/MessageRouter.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/MessageRouter.js +808 -0
- package/dist/edge/p2p/protocol/MessageRouter.js.map +1 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.d.ts +309 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.js +930 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.js.map +1 -0
- package/dist/edge/p2p/protocol/index.d.ts +114 -0
- package/dist/edge/p2p/protocol/index.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/index.js +206 -0
- package/dist/edge/p2p/protocol/index.js.map +1 -0
- package/dist/edge/p2p/protocol/types.d.ts +737 -0
- package/dist/edge/p2p/protocol/types.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/types.js +490 -0
- package/dist/edge/p2p/protocol/types.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.d.ts +284 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.js +644 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternIndex.d.ts +168 -0
- package/dist/edge/p2p/sharing/PatternIndex.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternIndex.js +781 -0
- package/dist/edge/p2p/sharing/PatternIndex.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternSerializer.d.ts +163 -0
- package/dist/edge/p2p/sharing/PatternSerializer.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternSerializer.js +696 -0
- package/dist/edge/p2p/sharing/PatternSerializer.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.d.ts +242 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.js +859 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.js.map +1 -0
- package/dist/edge/p2p/sharing/index.d.ts +90 -0
- package/dist/edge/p2p/sharing/index.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/index.js +152 -0
- package/dist/edge/p2p/sharing/index.js.map +1 -0
- package/dist/edge/p2p/sharing/types.d.ts +796 -0
- package/dist/edge/p2p/sharing/types.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/types.js +264 -0
- package/dist/edge/p2p/sharing/types.js.map +1 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.d.ts +218 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.js +562 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.js.map +1 -0
- package/dist/edge/p2p/webrtc/ICEManager.d.ts +171 -0
- package/dist/edge/p2p/webrtc/ICEManager.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/ICEManager.js +490 -0
- package/dist/edge/p2p/webrtc/ICEManager.js.map +1 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.d.ts +159 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.js +735 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.js.map +1 -0
- package/dist/edge/p2p/webrtc/SignalingClient.d.ts +191 -0
- package/dist/edge/p2p/webrtc/SignalingClient.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/SignalingClient.js +608 -0
- package/dist/edge/p2p/webrtc/SignalingClient.js.map +1 -0
- package/dist/edge/p2p/webrtc/index.d.ts +158 -0
- package/dist/edge/p2p/webrtc/index.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/index.js +164 -0
- package/dist/edge/p2p/webrtc/index.js.map +1 -0
- package/dist/edge/p2p/webrtc/types.d.ts +665 -0
- package/dist/edge/p2p/webrtc/types.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/types.js +245 -0
- package/dist/edge/p2p/webrtc/types.js.map +1 -0
- package/dist/edge/server/AgentSpawnAPI.d.ts +98 -0
- package/dist/edge/server/AgentSpawnAPI.d.ts.map +1 -0
- package/dist/edge/server/AgentSpawnAPI.js +264 -0
- package/dist/edge/server/AgentSpawnAPI.js.map +1 -0
- package/dist/edge/server/SignalingServer.d.ts +71 -0
- package/dist/edge/server/SignalingServer.d.ts.map +1 -0
- package/dist/edge/server/SignalingServer.js +429 -0
- package/dist/edge/server/SignalingServer.js.map +1 -0
- package/dist/edge/server/index.d.ts +64 -0
- package/dist/edge/server/index.d.ts.map +1 -0
- package/dist/edge/server/index.js +318 -0
- package/dist/edge/server/index.js.map +1 -0
- package/dist/edge/types/browser-agent.types.d.ts +455 -0
- package/dist/edge/types/browser-agent.types.d.ts.map +1 -0
- package/dist/edge/types/browser-agent.types.js +116 -0
- package/dist/edge/types/browser-agent.types.js.map +1 -0
- package/dist/edge/types/index.d.ts +11 -0
- package/dist/edge/types/index.d.ts.map +1 -0
- package/dist/edge/types/index.js +17 -0
- package/dist/edge/types/index.js.map +1 -0
- package/dist/edge/types/storage.types.d.ts +207 -0
- package/dist/edge/types/storage.types.d.ts.map +1 -0
- package/dist/edge/types/storage.types.js +47 -0
- package/dist/edge/types/storage.types.js.map +1 -0
- package/dist/edge/wasm/shims.d.ts +224 -0
- package/dist/edge/wasm/shims.d.ts.map +1 -0
- package/dist/edge/wasm/shims.js +667 -0
- package/dist/edge/wasm/shims.js.map +1 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +33 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.js +305 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -0
- package/dist/mcp/handlers/filtered/index.d.ts +15 -19
- package/dist/mcp/handlers/filtered/index.d.ts.map +1 -1
- package/dist/mcp/handlers/filtered/index.js +16 -27
- package/dist/mcp/handlers/filtered/index.js.map +1 -1
- package/dist/mcp/handlers/integration/index.d.ts +5 -4
- package/dist/mcp/handlers/integration/index.d.ts.map +1 -1
- package/dist/mcp/handlers/integration/index.js +7 -7
- package/dist/mcp/handlers/integration/index.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.js +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +8 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +412 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/planning/GOAPPlanner.d.ts +1 -0
- package/dist/planning/GOAPPlanner.d.ts.map +1 -1
- package/dist/planning/GOAPPlanner.js +12 -0
- package/dist/planning/GOAPPlanner.js.map +1 -1
- package/package.json +29 -8
- package/dist/alerting/AlertManager.d.ts +0 -120
- package/dist/alerting/AlertManager.d.ts.map +0 -1
- package/dist/alerting/AlertManager.js +0 -345
- package/dist/alerting/AlertManager.js.map +0 -1
- package/dist/alerting/FeedbackRouter.d.ts +0 -98
- package/dist/alerting/FeedbackRouter.d.ts.map +0 -1
- package/dist/alerting/FeedbackRouter.js +0 -331
- package/dist/alerting/FeedbackRouter.js.map +0 -1
- package/dist/alerting/StrategyApplicator.d.ts +0 -120
- package/dist/alerting/StrategyApplicator.d.ts.map +0 -1
- package/dist/alerting/StrategyApplicator.js +0 -299
- package/dist/alerting/StrategyApplicator.js.map +0 -1
- package/dist/alerting/index.d.ts +0 -68
- package/dist/alerting/index.d.ts.map +0 -1
- package/dist/alerting/index.js +0 -112
- package/dist/alerting/index.js.map +0 -1
- package/dist/alerting/types.d.ts +0 -118
- package/dist/alerting/types.d.ts.map +0 -1
- package/dist/alerting/types.js +0 -11
- package/dist/alerting/types.js.map +0 -1
- package/dist/cli/commands/fleet/backup.d.ts +0 -49
- package/dist/cli/commands/fleet/backup.d.ts.map +0 -1
- package/dist/cli/commands/fleet/backup.js +0 -88
- package/dist/cli/commands/fleet/backup.js.map +0 -1
- package/dist/cli/commands/fleet/health.d.ts +0 -154
- package/dist/cli/commands/fleet/health.d.ts.map +0 -1
- package/dist/cli/commands/fleet/health.js +0 -483
- package/dist/cli/commands/fleet/health.js.map +0 -1
- package/dist/cli/commands/fleet/init.d.ts +0 -11
- package/dist/cli/commands/fleet/init.d.ts.map +0 -1
- package/dist/cli/commands/fleet/init.js +0 -91
- package/dist/cli/commands/fleet/init.js.map +0 -1
- package/dist/cli/commands/fleet/logs.d.ts +0 -21
- package/dist/cli/commands/fleet/logs.d.ts.map +0 -1
- package/dist/cli/commands/fleet/logs.js +0 -267
- package/dist/cli/commands/fleet/logs.js.map +0 -1
- package/dist/cli/commands/fleet/metrics.d.ts +0 -27
- package/dist/cli/commands/fleet/metrics.d.ts.map +0 -1
- package/dist/cli/commands/fleet/metrics.js +0 -369
- package/dist/cli/commands/fleet/metrics.js.map +0 -1
- package/dist/cli/commands/fleet/monitor.d.ts +0 -18
- package/dist/cli/commands/fleet/monitor.d.ts.map +0 -1
- package/dist/cli/commands/fleet/monitor.js +0 -237
- package/dist/cli/commands/fleet/monitor.js.map +0 -1
- package/dist/cli/commands/fleet/optimize.d.ts +0 -42
- package/dist/cli/commands/fleet/optimize.d.ts.map +0 -1
- package/dist/cli/commands/fleet/optimize.js +0 -135
- package/dist/cli/commands/fleet/optimize.js.map +0 -1
- package/dist/cli/commands/fleet/recover.d.ts +0 -22
- package/dist/cli/commands/fleet/recover.d.ts.map +0 -1
- package/dist/cli/commands/fleet/recover.js +0 -99
- package/dist/cli/commands/fleet/recover.js.map +0 -1
- package/dist/cli/commands/fleet/restart.d.ts +0 -18
- package/dist/cli/commands/fleet/restart.d.ts.map +0 -1
- package/dist/cli/commands/fleet/restart.js +0 -290
- package/dist/cli/commands/fleet/restart.js.map +0 -1
- package/dist/cli/commands/fleet/scale.d.ts +0 -9
- package/dist/cli/commands/fleet/scale.d.ts.map +0 -1
- package/dist/cli/commands/fleet/scale.js +0 -77
- package/dist/cli/commands/fleet/scale.js.map +0 -1
- package/dist/cli/commands/fleet/shutdown.d.ts +0 -19
- package/dist/cli/commands/fleet/shutdown.d.ts.map +0 -1
- package/dist/cli/commands/fleet/shutdown.js +0 -307
- package/dist/cli/commands/fleet/shutdown.js.map +0 -1
- package/dist/cli/commands/fleet/status.d.ts +0 -10
- package/dist/cli/commands/fleet/status.d.ts.map +0 -1
- package/dist/cli/commands/fleet/status.js +0 -97
- package/dist/cli/commands/fleet/status.js.map +0 -1
- package/dist/cli/commands/fleet/topology.d.ts +0 -23
- package/dist/cli/commands/fleet/topology.d.ts.map +0 -1
- package/dist/cli/commands/fleet/topology.js +0 -376
- package/dist/cli/commands/fleet/topology.js.map +0 -1
- package/dist/cli/commands/monitor/alerts.d.ts +0 -45
- package/dist/cli/commands/monitor/alerts.d.ts.map +0 -1
- package/dist/cli/commands/monitor/alerts.js +0 -168
- package/dist/cli/commands/monitor/alerts.js.map +0 -1
- package/dist/cli/commands/monitor/analyze.d.ts +0 -49
- package/dist/cli/commands/monitor/analyze.d.ts.map +0 -1
- package/dist/cli/commands/monitor/analyze.js +0 -209
- package/dist/cli/commands/monitor/analyze.js.map +0 -1
- package/dist/cli/commands/monitor/compare.d.ts +0 -38
- package/dist/cli/commands/monitor/compare.d.ts.map +0 -1
- package/dist/cli/commands/monitor/compare.js +0 -177
- package/dist/cli/commands/monitor/compare.js.map +0 -1
- package/dist/cli/commands/monitor/dashboard.d.ts +0 -34
- package/dist/cli/commands/monitor/dashboard.d.ts.map +0 -1
- package/dist/cli/commands/monitor/dashboard.js +0 -157
- package/dist/cli/commands/monitor/dashboard.js.map +0 -1
- package/dist/cli/commands/monitor/export.d.ts +0 -36
- package/dist/cli/commands/monitor/export.d.ts.map +0 -1
- package/dist/cli/commands/monitor/export.js +0 -157
- package/dist/cli/commands/monitor/export.js.map +0 -1
- package/dist/cli/commands/monitor/index.d.ts +0 -11
- package/dist/cli/commands/monitor/index.d.ts.map +0 -1
- package/dist/cli/commands/monitor/index.js +0 -14
- package/dist/cli/commands/monitor/index.js.map +0 -1
- package/dist/cli/commands/quality/baseline.d.ts +0 -27
- package/dist/cli/commands/quality/baseline.d.ts.map +0 -1
- package/dist/cli/commands/quality/baseline.js +0 -124
- package/dist/cli/commands/quality/baseline.js.map +0 -1
- package/dist/cli/commands/quality/compare.d.ts +0 -36
- package/dist/cli/commands/quality/compare.d.ts.map +0 -1
- package/dist/cli/commands/quality/compare.js +0 -136
- package/dist/cli/commands/quality/compare.js.map +0 -1
- package/dist/cli/commands/quality/decision.d.ts +0 -81
- package/dist/cli/commands/quality/decision.d.ts.map +0 -1
- package/dist/cli/commands/quality/decision.js +0 -319
- package/dist/cli/commands/quality/decision.js.map +0 -1
- package/dist/cli/commands/quality/gate.d.ts +0 -47
- package/dist/cli/commands/quality/gate.d.ts.map +0 -1
- package/dist/cli/commands/quality/gate.js +0 -205
- package/dist/cli/commands/quality/gate.js.map +0 -1
- package/dist/cli/commands/quality/index.d.ts +0 -17
- package/dist/cli/commands/quality/index.d.ts.map +0 -1
- package/dist/cli/commands/quality/index.js +0 -41
- package/dist/cli/commands/quality/index.js.map +0 -1
- package/dist/cli/commands/quality/policy.d.ts +0 -57
- package/dist/cli/commands/quality/policy.d.ts.map +0 -1
- package/dist/cli/commands/quality/policy.js +0 -359
- package/dist/cli/commands/quality/policy.js.map +0 -1
- package/dist/cli/commands/quality/risk.d.ts +0 -41
- package/dist/cli/commands/quality/risk.d.ts.map +0 -1
- package/dist/cli/commands/quality/risk.js +0 -255
- package/dist/cli/commands/quality/risk.js.map +0 -1
- package/dist/cli/commands/quality/trends.d.ts +0 -40
- package/dist/cli/commands/quality/trends.d.ts.map +0 -1
- package/dist/cli/commands/quality/trends.js +0 -122
- package/dist/cli/commands/quality/trends.js.map +0 -1
- package/dist/cli/commands/quality/validate.d.ts +0 -44
- package/dist/cli/commands/quality/validate.d.ts.map +0 -1
- package/dist/cli/commands/quality/validate.js +0 -234
- package/dist/cli/commands/quality/validate.js.map +0 -1
- package/dist/cli/commands/test/analyze-failures.d.ts +0 -39
- package/dist/cli/commands/test/analyze-failures.d.ts.map +0 -1
- package/dist/cli/commands/test/analyze-failures.js +0 -113
- package/dist/cli/commands/test/analyze-failures.js.map +0 -1
- package/dist/cli/commands/test/clean.d.ts +0 -3
- package/dist/cli/commands/test/clean.d.ts.map +0 -1
- package/dist/cli/commands/test/clean.js +0 -148
- package/dist/cli/commands/test/clean.js.map +0 -1
- package/dist/cli/commands/test/debug.d.ts +0 -3
- package/dist/cli/commands/test/debug.d.ts.map +0 -1
- package/dist/cli/commands/test/debug.js +0 -167
- package/dist/cli/commands/test/debug.js.map +0 -1
- package/dist/cli/commands/test/diff.d.ts +0 -3
- package/dist/cli/commands/test/diff.d.ts.map +0 -1
- package/dist/cli/commands/test/diff.js +0 -195
- package/dist/cli/commands/test/diff.js.map +0 -1
- package/dist/cli/commands/test/flakiness.d.ts +0 -32
- package/dist/cli/commands/test/flakiness.d.ts.map +0 -1
- package/dist/cli/commands/test/flakiness.js +0 -121
- package/dist/cli/commands/test/flakiness.js.map +0 -1
- package/dist/cli/commands/test/index.d.ts +0 -17
- package/dist/cli/commands/test/index.d.ts.map +0 -1
- package/dist/cli/commands/test/index.js +0 -45
- package/dist/cli/commands/test/index.js.map +0 -1
- package/dist/cli/commands/test/mutate.d.ts +0 -29
- package/dist/cli/commands/test/mutate.d.ts.map +0 -1
- package/dist/cli/commands/test/mutate.js +0 -163
- package/dist/cli/commands/test/mutate.js.map +0 -1
- package/dist/cli/commands/test/parallel.d.ts +0 -3
- package/dist/cli/commands/test/parallel.d.ts.map +0 -1
- package/dist/cli/commands/test/parallel.js +0 -117
- package/dist/cli/commands/test/parallel.js.map +0 -1
- package/dist/cli/commands/test/profile.d.ts +0 -3
- package/dist/cli/commands/test/profile.d.ts.map +0 -1
- package/dist/cli/commands/test/profile.js +0 -156
- package/dist/cli/commands/test/profile.js.map +0 -1
- package/dist/cli/commands/test/queue.d.ts +0 -3
- package/dist/cli/commands/test/queue.d.ts.map +0 -1
- package/dist/cli/commands/test/queue.js +0 -140
- package/dist/cli/commands/test/queue.js.map +0 -1
- package/dist/cli/commands/test/retry.d.ts +0 -3
- package/dist/cli/commands/test/retry.d.ts.map +0 -1
- package/dist/cli/commands/test/retry.js +0 -105
- package/dist/cli/commands/test/retry.js.map +0 -1
- package/dist/cli/commands/test/snapshot.d.ts +0 -3
- package/dist/cli/commands/test/snapshot.d.ts.map +0 -1
- package/dist/cli/commands/test/snapshot.js +0 -176
- package/dist/cli/commands/test/snapshot.js.map +0 -1
- package/dist/cli/commands/test/trace.d.ts +0 -3
- package/dist/cli/commands/test/trace.d.ts.map +0 -1
- package/dist/cli/commands/test/trace.js +0 -137
- package/dist/cli/commands/test/trace.js.map +0 -1
- package/dist/cli/commands/test/watch.d.ts +0 -3
- package/dist/cli/commands/test/watch.d.ts.map +0 -1
- package/dist/cli/commands/test/watch.js +0 -130
- package/dist/cli/commands/test/watch.js.map +0 -1
- package/dist/cli/index-spec.d.ts +0 -3
- package/dist/cli/index-spec.d.ts.map +0 -1
- package/dist/cli/index-spec.js +0 -154
- package/dist/cli/index-spec.js.map +0 -1
- package/dist/cli/index-working.d.ts +0 -7
- package/dist/cli/index-working.d.ts.map +0 -1
- package/dist/cli/index-working.js +0 -617
- package/dist/cli/index-working.js.map +0 -1
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts +0 -83
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js +0 -130
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js.map +0 -1
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts +0 -58
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js +0 -84
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js.map +0 -1
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts +0 -54
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js +0 -73
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js.map +0 -1
- package/dist/mcp/handlers/integration/contract-validate.d.ts +0 -10
- package/dist/mcp/handlers/integration/contract-validate.d.ts.map +0 -1
- package/dist/mcp/handlers/integration/contract-validate.js +0 -348
- package/dist/mcp/handlers/integration/contract-validate.js.map +0 -1
- package/dist/reporting/ResultAggregator.d.ts +0 -107
- package/dist/reporting/ResultAggregator.d.ts.map +0 -1
- package/dist/reporting/ResultAggregator.js +0 -435
- package/dist/reporting/ResultAggregator.js.map +0 -1
- package/dist/reporting/index.d.ts +0 -48
- package/dist/reporting/index.d.ts.map +0 -1
- package/dist/reporting/index.js +0 -154
- package/dist/reporting/index.js.map +0 -1
- package/dist/reporting/reporters/ControlLoopReporter.d.ts +0 -128
- package/dist/reporting/reporters/ControlLoopReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/ControlLoopReporter.js +0 -417
- package/dist/reporting/reporters/ControlLoopReporter.js.map +0 -1
- package/dist/reporting/reporters/HumanReadableReporter.d.ts +0 -140
- package/dist/reporting/reporters/HumanReadableReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/HumanReadableReporter.js +0 -524
- package/dist/reporting/reporters/HumanReadableReporter.js.map +0 -1
- package/dist/reporting/reporters/JSONReporter.d.ts +0 -251
- package/dist/reporting/reporters/JSONReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/JSONReporter.js +0 -325
- package/dist/reporting/reporters/JSONReporter.js.map +0 -1
- package/dist/reporting/reporters/index.d.ts +0 -14
- package/dist/reporting/reporters/index.d.ts.map +0 -1
- package/dist/reporting/reporters/index.js +0 -19
- package/dist/reporting/reporters/index.js.map +0 -1
- package/dist/reporting/types.d.ts +0 -427
- package/dist/reporting/types.d.ts.map +0 -1
- package/dist/reporting/types.js +0 -12
- package/dist/reporting/types.js.map +0 -1
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pattern Sync Manager for P2P Synchronization
|
|
4
|
+
*
|
|
5
|
+
* Manages pattern synchronization between peers including pull/push operations,
|
|
6
|
+
* incremental sync using vector clocks, conflict resolution, and bandwidth management.
|
|
7
|
+
*
|
|
8
|
+
* @module edge/p2p/sharing/PatternSyncManager
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PatternSyncManager = void 0;
|
|
13
|
+
exports.createPatternSyncManager = createPatternSyncManager;
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
const PatternSerializer_1 = require("./PatternSerializer");
|
|
16
|
+
// ============================================
|
|
17
|
+
// Pattern Sync Manager Class
|
|
18
|
+
// ============================================
|
|
19
|
+
/**
|
|
20
|
+
* Manages pattern synchronization between P2P peers
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const syncManager = new PatternSyncManager({
|
|
25
|
+
* localAgentId: 'my-agent',
|
|
26
|
+
* index: patternIndex,
|
|
27
|
+
* channel: agentChannel,
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Pull patterns from peer
|
|
31
|
+
* const patterns = await syncManager.pull('peer-agent', {
|
|
32
|
+
* categories: ['test'],
|
|
33
|
+
* limit: 50,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Push local patterns to peer
|
|
37
|
+
* await syncManager.push('peer-agent', localPatterns);
|
|
38
|
+
*
|
|
39
|
+
* // Incremental sync
|
|
40
|
+
* await syncManager.syncWithPeer('peer-agent');
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
class PatternSyncManager {
|
|
44
|
+
constructor(config) {
|
|
45
|
+
// Sync state tracking
|
|
46
|
+
this.syncStates = new Map();
|
|
47
|
+
this.activeSessions = new Map();
|
|
48
|
+
this.pendingSyncs = new Map();
|
|
49
|
+
this.vectorClocks = new Map();
|
|
50
|
+
// Rate limiting
|
|
51
|
+
this.bytesThisSecond = 0;
|
|
52
|
+
this.lastRateReset = Date.now();
|
|
53
|
+
// Event handlers
|
|
54
|
+
this.eventHandlers = [];
|
|
55
|
+
this.localAgentId = config.localAgentId;
|
|
56
|
+
this.index = config.index;
|
|
57
|
+
this.channel = config.channel;
|
|
58
|
+
this.bandwidth = { ...types_1.DEFAULT_BANDWIDTH_CONFIG, ...config.bandwidth };
|
|
59
|
+
this.conflictStrategy = config.conflictStrategy ?? 'latest_wins';
|
|
60
|
+
this.maxBatchSize = config.maxBatchSize ?? types_1.MAX_BATCH_SIZE;
|
|
61
|
+
this.verifySignatures = config.verifySignatures ?? true;
|
|
62
|
+
this.serializer = new PatternSerializer_1.PatternSerializer();
|
|
63
|
+
// Setup channel handlers if provided
|
|
64
|
+
if (this.channel) {
|
|
65
|
+
this.setupChannelHandlers();
|
|
66
|
+
}
|
|
67
|
+
// Start auto-sync if configured
|
|
68
|
+
if (config.autoSyncInterval && config.autoSyncInterval > 0) {
|
|
69
|
+
this.startAutoSync(config.autoSyncInterval);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ============================================
|
|
73
|
+
// Pull Operations
|
|
74
|
+
// ============================================
|
|
75
|
+
/**
|
|
76
|
+
* Pull patterns from a peer
|
|
77
|
+
*/
|
|
78
|
+
async pull(peerId, query) {
|
|
79
|
+
if (!this.channel) {
|
|
80
|
+
throw new types_1.SharingError('No channel configured for sync', types_1.SharingErrorCode.NETWORK_ERROR);
|
|
81
|
+
}
|
|
82
|
+
const requestId = this.generateRequestId();
|
|
83
|
+
const session = this.createSession(requestId, peerId, 'pull');
|
|
84
|
+
try {
|
|
85
|
+
// Build sync request
|
|
86
|
+
const request = {
|
|
87
|
+
requestId,
|
|
88
|
+
requesterId: this.localAgentId,
|
|
89
|
+
query,
|
|
90
|
+
vectorClocks: this.getVectorClocksForPeer(peerId),
|
|
91
|
+
timestamp: new Date().toISOString(),
|
|
92
|
+
includeContent: true,
|
|
93
|
+
};
|
|
94
|
+
// Send request
|
|
95
|
+
const response = await this.sendSyncRequest(peerId, request);
|
|
96
|
+
// Process patterns
|
|
97
|
+
const patterns = [];
|
|
98
|
+
for (const pattern of response.patterns) {
|
|
99
|
+
await this.processReceivedPattern(pattern, peerId);
|
|
100
|
+
patterns.push(pattern);
|
|
101
|
+
session.patternsTransferred++;
|
|
102
|
+
}
|
|
103
|
+
// Handle conflicts
|
|
104
|
+
if (response.conflicts && response.conflicts.length > 0) {
|
|
105
|
+
for (const conflict of response.conflicts) {
|
|
106
|
+
await this.resolveConflict(conflict, peerId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Update sync state
|
|
110
|
+
this.updateSyncState(peerId, types_1.SyncStatus.SYNCED, patterns.map((p) => p.id));
|
|
111
|
+
session.status = types_1.SyncStatus.SYNCED;
|
|
112
|
+
this.emit({
|
|
113
|
+
type: types_1.SharingEventType.SYNC_COMPLETED,
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
details: {
|
|
116
|
+
peerId,
|
|
117
|
+
direction: 'pull',
|
|
118
|
+
patternsReceived: patterns.length,
|
|
119
|
+
conflicts: response.conflicts?.length ?? 0,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
return patterns;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
session.status = types_1.SyncStatus.FAILED;
|
|
126
|
+
session.error = error instanceof Error ? error.message : 'Unknown error';
|
|
127
|
+
this.updateSyncState(peerId, types_1.SyncStatus.FAILED);
|
|
128
|
+
this.emit({
|
|
129
|
+
type: types_1.SharingEventType.SYNC_FAILED,
|
|
130
|
+
timestamp: Date.now(),
|
|
131
|
+
details: { peerId, direction: 'pull', error: session.error },
|
|
132
|
+
});
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
this.activeSessions.delete(session.sessionId);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Pull specific patterns by ID
|
|
141
|
+
*/
|
|
142
|
+
async pullPatterns(peerId, patternIds) {
|
|
143
|
+
if (!this.channel) {
|
|
144
|
+
throw new types_1.SharingError('No channel configured for sync', types_1.SharingErrorCode.NETWORK_ERROR);
|
|
145
|
+
}
|
|
146
|
+
const requestId = this.generateRequestId();
|
|
147
|
+
const session = this.createSession(requestId, peerId, 'pull');
|
|
148
|
+
try {
|
|
149
|
+
const request = {
|
|
150
|
+
requestId,
|
|
151
|
+
requesterId: this.localAgentId,
|
|
152
|
+
patternIds,
|
|
153
|
+
timestamp: new Date().toISOString(),
|
|
154
|
+
includeContent: true,
|
|
155
|
+
};
|
|
156
|
+
const response = await this.sendSyncRequest(peerId, request);
|
|
157
|
+
const patterns = [];
|
|
158
|
+
for (const pattern of response.patterns) {
|
|
159
|
+
await this.processReceivedPattern(pattern, peerId);
|
|
160
|
+
patterns.push(pattern);
|
|
161
|
+
}
|
|
162
|
+
session.status = types_1.SyncStatus.SYNCED;
|
|
163
|
+
return patterns;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
session.status = types_1.SyncStatus.FAILED;
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
this.activeSessions.delete(session.sessionId);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// ============================================
|
|
174
|
+
// Push Operations
|
|
175
|
+
// ============================================
|
|
176
|
+
/**
|
|
177
|
+
* Push patterns to a peer
|
|
178
|
+
*/
|
|
179
|
+
async push(peerId, patterns) {
|
|
180
|
+
if (!this.channel) {
|
|
181
|
+
throw new types_1.SharingError('No channel configured for sync', types_1.SharingErrorCode.NETWORK_ERROR);
|
|
182
|
+
}
|
|
183
|
+
const session = this.createSession(this.generateRequestId(), peerId, 'push');
|
|
184
|
+
this.emit({
|
|
185
|
+
type: types_1.SharingEventType.SYNC_STARTED,
|
|
186
|
+
timestamp: Date.now(),
|
|
187
|
+
details: { peerId, direction: 'push', patternCount: patterns.length },
|
|
188
|
+
});
|
|
189
|
+
try {
|
|
190
|
+
// Send in batches respecting bandwidth limits
|
|
191
|
+
const batches = this.createBatches(patterns);
|
|
192
|
+
for (const batch of batches) {
|
|
193
|
+
await this.waitForBandwidth(batch.length * 1024); // Estimate
|
|
194
|
+
// Send batch via channel
|
|
195
|
+
await this.channel.publish('pattern:sync:push', {
|
|
196
|
+
senderId: this.localAgentId,
|
|
197
|
+
patterns: batch,
|
|
198
|
+
timestamp: new Date().toISOString(),
|
|
199
|
+
});
|
|
200
|
+
session.patternsTransferred += batch.length;
|
|
201
|
+
// Delay between batches
|
|
202
|
+
if (this.bandwidth.batchDelay > 0) {
|
|
203
|
+
await this.delay(this.bandwidth.batchDelay);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Update sync state
|
|
207
|
+
const patternIds = patterns.map((p) => p.id);
|
|
208
|
+
this.updateSyncState(peerId, types_1.SyncStatus.SYNCED, patternIds);
|
|
209
|
+
session.status = types_1.SyncStatus.SYNCED;
|
|
210
|
+
this.emit({
|
|
211
|
+
type: types_1.SharingEventType.SYNC_COMPLETED,
|
|
212
|
+
timestamp: Date.now(),
|
|
213
|
+
details: { peerId, direction: 'push', patternsSent: patterns.length },
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
session.status = types_1.SyncStatus.FAILED;
|
|
218
|
+
session.error = error instanceof Error ? error.message : 'Unknown error';
|
|
219
|
+
this.updateSyncState(peerId, types_1.SyncStatus.FAILED);
|
|
220
|
+
this.emit({
|
|
221
|
+
type: types_1.SharingEventType.SYNC_FAILED,
|
|
222
|
+
timestamp: Date.now(),
|
|
223
|
+
details: { peerId, direction: 'push', error: session.error },
|
|
224
|
+
});
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
this.activeSessions.delete(session.sessionId);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Push all local patterns to peer (full sync)
|
|
233
|
+
*/
|
|
234
|
+
async pushAll(peerId) {
|
|
235
|
+
const patterns = this.index.getAll();
|
|
236
|
+
await this.push(peerId, patterns);
|
|
237
|
+
}
|
|
238
|
+
// ============================================
|
|
239
|
+
// Incremental Sync
|
|
240
|
+
// ============================================
|
|
241
|
+
/**
|
|
242
|
+
* Perform incremental sync with a peer
|
|
243
|
+
* Uses vector clocks to sync only changed patterns
|
|
244
|
+
*/
|
|
245
|
+
async syncWithPeer(peerId) {
|
|
246
|
+
if (!this.channel) {
|
|
247
|
+
throw new types_1.SharingError('No channel configured for sync', types_1.SharingErrorCode.NETWORK_ERROR);
|
|
248
|
+
}
|
|
249
|
+
this.emit({
|
|
250
|
+
type: types_1.SharingEventType.SYNC_STARTED,
|
|
251
|
+
timestamp: Date.now(),
|
|
252
|
+
details: { peerId, direction: 'bidirectional' },
|
|
253
|
+
});
|
|
254
|
+
try {
|
|
255
|
+
// Get peer's vector clocks
|
|
256
|
+
const peerClocks = await this.getPeerVectorClocks(peerId);
|
|
257
|
+
// Determine what to pull (patterns peer has that are newer)
|
|
258
|
+
const toPull = this.findPatternsToPull(peerClocks);
|
|
259
|
+
// Determine what to push (patterns we have that are newer)
|
|
260
|
+
const toPush = this.findPatternsToPush(peerClocks);
|
|
261
|
+
// Execute sync
|
|
262
|
+
let pulled = 0;
|
|
263
|
+
let pushed = 0;
|
|
264
|
+
let conflicts = 0;
|
|
265
|
+
// Pull first
|
|
266
|
+
if (toPull.length > 0) {
|
|
267
|
+
const pulledPatterns = await this.pullPatterns(peerId, toPull);
|
|
268
|
+
pulled = pulledPatterns.length;
|
|
269
|
+
}
|
|
270
|
+
// Then push
|
|
271
|
+
if (toPush.length > 0) {
|
|
272
|
+
const patterns = toPush
|
|
273
|
+
.map((id) => this.index.get(id))
|
|
274
|
+
.filter((p) => p !== undefined);
|
|
275
|
+
await this.push(peerId, patterns);
|
|
276
|
+
pushed = patterns.length;
|
|
277
|
+
}
|
|
278
|
+
// Update local vector clock
|
|
279
|
+
this.updateLocalClock(peerId);
|
|
280
|
+
this.emit({
|
|
281
|
+
type: types_1.SharingEventType.SYNC_COMPLETED,
|
|
282
|
+
timestamp: Date.now(),
|
|
283
|
+
details: { peerId, pulled, pushed, conflicts },
|
|
284
|
+
});
|
|
285
|
+
return { pulled, pushed, conflicts };
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
this.emit({
|
|
289
|
+
type: types_1.SharingEventType.SYNC_FAILED,
|
|
290
|
+
timestamp: Date.now(),
|
|
291
|
+
details: {
|
|
292
|
+
peerId,
|
|
293
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ============================================
|
|
300
|
+
// Conflict Resolution
|
|
301
|
+
// ============================================
|
|
302
|
+
/**
|
|
303
|
+
* Resolve a pattern conflict
|
|
304
|
+
*/
|
|
305
|
+
async resolveConflict(conflict, peerId) {
|
|
306
|
+
this.emit({
|
|
307
|
+
type: types_1.SharingEventType.CONFLICT_DETECTED,
|
|
308
|
+
timestamp: Date.now(),
|
|
309
|
+
details: { conflict, peerId },
|
|
310
|
+
});
|
|
311
|
+
let resolution;
|
|
312
|
+
switch (this.conflictStrategy) {
|
|
313
|
+
case 'latest_wins':
|
|
314
|
+
resolution = this.resolveLatestWins(conflict);
|
|
315
|
+
break;
|
|
316
|
+
case 'prefer_local':
|
|
317
|
+
resolution = this.resolvePreferLocal(conflict);
|
|
318
|
+
break;
|
|
319
|
+
case 'prefer_remote':
|
|
320
|
+
resolution = await this.resolvePreferRemote(conflict, peerId);
|
|
321
|
+
break;
|
|
322
|
+
case 'manual':
|
|
323
|
+
default:
|
|
324
|
+
resolution = {
|
|
325
|
+
strategy: 'manual',
|
|
326
|
+
resolvedAt: new Date().toISOString(),
|
|
327
|
+
};
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
// Apply resolution if we have a resolved pattern
|
|
331
|
+
if (resolution.resolvedPattern) {
|
|
332
|
+
this.index.update(conflict.patternId, resolution.resolvedPattern);
|
|
333
|
+
}
|
|
334
|
+
this.emit({
|
|
335
|
+
type: types_1.SharingEventType.CONFLICT_RESOLVED,
|
|
336
|
+
timestamp: Date.now(),
|
|
337
|
+
details: { conflict, resolution },
|
|
338
|
+
});
|
|
339
|
+
return resolution;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Latest-wins conflict resolution
|
|
343
|
+
*/
|
|
344
|
+
resolveLatestWins(conflict) {
|
|
345
|
+
const localPattern = this.index.get(conflict.patternId);
|
|
346
|
+
if (!localPattern) {
|
|
347
|
+
return {
|
|
348
|
+
strategy: 'latest_wins',
|
|
349
|
+
resolvedAt: new Date().toISOString(),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
// Compare timestamps
|
|
353
|
+
const localTime = new Date(localPattern.updatedAt).getTime();
|
|
354
|
+
const remoteVersion = conflict.remoteVersion;
|
|
355
|
+
// Use vector clock comparison
|
|
356
|
+
const comparison = this.index.compareVectorClocks(conflict.localVersion.vectorClock, conflict.remoteVersion.vectorClock);
|
|
357
|
+
if (comparison === 'after') {
|
|
358
|
+
// Local is newer, keep local
|
|
359
|
+
return {
|
|
360
|
+
strategy: 'latest_wins',
|
|
361
|
+
resolvedPattern: localPattern,
|
|
362
|
+
resolvedAt: new Date().toISOString(),
|
|
363
|
+
resolvedBy: this.localAgentId,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
// Remote is newer or concurrent, need to fetch and use remote
|
|
367
|
+
return {
|
|
368
|
+
strategy: 'latest_wins',
|
|
369
|
+
resolvedAt: new Date().toISOString(),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Prefer local pattern resolution
|
|
374
|
+
*/
|
|
375
|
+
resolvePreferLocal(conflict) {
|
|
376
|
+
const localPattern = this.index.get(conflict.patternId);
|
|
377
|
+
return {
|
|
378
|
+
strategy: 'prefer_local',
|
|
379
|
+
resolvedPattern: localPattern,
|
|
380
|
+
resolvedAt: new Date().toISOString(),
|
|
381
|
+
resolvedBy: this.localAgentId,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Prefer remote pattern resolution
|
|
386
|
+
*/
|
|
387
|
+
async resolvePreferRemote(conflict, peerId) {
|
|
388
|
+
// Fetch the remote pattern
|
|
389
|
+
const patterns = await this.pullPatterns(peerId, [conflict.patternId]);
|
|
390
|
+
const remotePattern = patterns[0];
|
|
391
|
+
return {
|
|
392
|
+
strategy: 'prefer_remote',
|
|
393
|
+
resolvedPattern: remotePattern,
|
|
394
|
+
resolvedAt: new Date().toISOString(),
|
|
395
|
+
resolvedBy: peerId,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
// ============================================
|
|
399
|
+
// Request Handling
|
|
400
|
+
// ============================================
|
|
401
|
+
/**
|
|
402
|
+
* Handle incoming sync request from a peer
|
|
403
|
+
*/
|
|
404
|
+
async handleSyncRequest(request) {
|
|
405
|
+
const patterns = [];
|
|
406
|
+
const conflicts = [];
|
|
407
|
+
if (request.patternIds) {
|
|
408
|
+
// Specific patterns requested
|
|
409
|
+
for (const id of request.patternIds) {
|
|
410
|
+
const pattern = this.index.get(id);
|
|
411
|
+
if (pattern && this.canShareWith(pattern, request.requesterId)) {
|
|
412
|
+
patterns.push(pattern);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else if (request.query) {
|
|
417
|
+
// Query-based request
|
|
418
|
+
const results = this.index.search(request.query);
|
|
419
|
+
for (const match of results.matches) {
|
|
420
|
+
if (this.canShareWith(match.pattern, request.requesterId)) {
|
|
421
|
+
patterns.push(match.pattern);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// Check for conflicts using vector clocks
|
|
426
|
+
if (request.vectorClocks) {
|
|
427
|
+
for (const pattern of patterns) {
|
|
428
|
+
const peerClock = request.vectorClocks[pattern.id];
|
|
429
|
+
if (peerClock) {
|
|
430
|
+
const conflict = this.checkVectorClockConflict(pattern, peerClock);
|
|
431
|
+
if (conflict) {
|
|
432
|
+
conflicts.push(conflict);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// Apply pagination
|
|
438
|
+
const limit = request.query?.limit ?? this.maxBatchSize;
|
|
439
|
+
const paginatedPatterns = patterns.slice(0, limit);
|
|
440
|
+
return {
|
|
441
|
+
requestId: request.requestId,
|
|
442
|
+
responderId: this.localAgentId,
|
|
443
|
+
patterns: paginatedPatterns,
|
|
444
|
+
conflicts,
|
|
445
|
+
hasMore: patterns.length > limit,
|
|
446
|
+
continuationToken: patterns.length > limit ? this.generateContinuationToken() : undefined,
|
|
447
|
+
timestamp: new Date().toISOString(),
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Handle incoming pushed patterns from a peer
|
|
452
|
+
*/
|
|
453
|
+
async handlePushedPatterns(peerId, patterns) {
|
|
454
|
+
for (const pattern of patterns) {
|
|
455
|
+
await this.processReceivedPattern(pattern, peerId);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// ============================================
|
|
459
|
+
// Channel Setup
|
|
460
|
+
// ============================================
|
|
461
|
+
/**
|
|
462
|
+
* Setup channel handlers for sync protocol
|
|
463
|
+
*/
|
|
464
|
+
setupChannelHandlers() {
|
|
465
|
+
if (!this.channel)
|
|
466
|
+
return;
|
|
467
|
+
// Handle sync requests
|
|
468
|
+
this.channel.onRequest('pattern:sync:request', async (request) => {
|
|
469
|
+
return this.handleSyncRequest(request);
|
|
470
|
+
});
|
|
471
|
+
// Handle pushed patterns
|
|
472
|
+
this.channel.subscribe('pattern:sync:push', async (data) => {
|
|
473
|
+
await this.handlePushedPatterns(data.senderId, data.patterns);
|
|
474
|
+
});
|
|
475
|
+
// Handle vector clock requests
|
|
476
|
+
this.channel.onRequest('pattern:sync:clocks', () => {
|
|
477
|
+
return this.getAllVectorClocks();
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Set communication channel
|
|
482
|
+
*/
|
|
483
|
+
setChannel(channel) {
|
|
484
|
+
this.channel = channel;
|
|
485
|
+
this.setupChannelHandlers();
|
|
486
|
+
}
|
|
487
|
+
// ============================================
|
|
488
|
+
// Vector Clock Management
|
|
489
|
+
// ============================================
|
|
490
|
+
/**
|
|
491
|
+
* Get vector clocks for patterns to sync with peer
|
|
492
|
+
*/
|
|
493
|
+
getVectorClocksForPeer(peerId) {
|
|
494
|
+
const clocks = {};
|
|
495
|
+
for (const pattern of this.index.getAll()) {
|
|
496
|
+
clocks[pattern.id] = pattern.version.vectorClock;
|
|
497
|
+
}
|
|
498
|
+
return clocks;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Get all local vector clocks
|
|
502
|
+
*/
|
|
503
|
+
getAllVectorClocks() {
|
|
504
|
+
const clocks = {};
|
|
505
|
+
for (const pattern of this.index.getAll()) {
|
|
506
|
+
clocks[pattern.id] = pattern.version.vectorClock;
|
|
507
|
+
}
|
|
508
|
+
return clocks;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get peer's vector clocks
|
|
512
|
+
*/
|
|
513
|
+
async getPeerVectorClocks(peerId) {
|
|
514
|
+
if (!this.channel) {
|
|
515
|
+
return {};
|
|
516
|
+
}
|
|
517
|
+
try {
|
|
518
|
+
return await this.channel.request('pattern:sync:clocks', { peerId: this.localAgentId });
|
|
519
|
+
}
|
|
520
|
+
catch {
|
|
521
|
+
return {};
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Find patterns to pull based on peer's clocks
|
|
526
|
+
*/
|
|
527
|
+
findPatternsToPull(peerClocks) {
|
|
528
|
+
const toPull = [];
|
|
529
|
+
for (const [patternId, peerClock] of Object.entries(peerClocks)) {
|
|
530
|
+
const localPattern = this.index.get(patternId);
|
|
531
|
+
if (!localPattern) {
|
|
532
|
+
// Don't have it, need to pull
|
|
533
|
+
toPull.push(patternId);
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
// Compare clocks
|
|
537
|
+
const comparison = this.index.compareVectorClocks(localPattern.version.vectorClock, peerClock);
|
|
538
|
+
if (comparison === 'before') {
|
|
539
|
+
// Peer has newer version
|
|
540
|
+
toPull.push(patternId);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return toPull;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Find patterns to push based on peer's clocks
|
|
548
|
+
*/
|
|
549
|
+
findPatternsToPush(peerClocks) {
|
|
550
|
+
const toPush = [];
|
|
551
|
+
for (const pattern of this.index.getAll()) {
|
|
552
|
+
const peerClock = peerClocks[pattern.id];
|
|
553
|
+
if (!peerClock) {
|
|
554
|
+
// Peer doesn't have it
|
|
555
|
+
toPush.push(pattern.id);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
// Compare clocks
|
|
559
|
+
const comparison = this.index.compareVectorClocks(pattern.version.vectorClock, peerClock);
|
|
560
|
+
if (comparison === 'after') {
|
|
561
|
+
// We have newer version
|
|
562
|
+
toPush.push(pattern.id);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return toPush;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Update local vector clock after sync
|
|
570
|
+
*/
|
|
571
|
+
updateLocalClock(peerId) {
|
|
572
|
+
for (const pattern of this.index.getAll()) {
|
|
573
|
+
const newClock = this.index.incrementClock(pattern.version.vectorClock, this.localAgentId);
|
|
574
|
+
this.index.update(pattern.id, {
|
|
575
|
+
version: {
|
|
576
|
+
...pattern.version,
|
|
577
|
+
vectorClock: newClock,
|
|
578
|
+
},
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Check for conflict using vector clocks
|
|
584
|
+
*/
|
|
585
|
+
checkVectorClockConflict(pattern, peerClock) {
|
|
586
|
+
const comparison = this.index.compareVectorClocks(pattern.version.vectorClock, peerClock);
|
|
587
|
+
if (comparison === 'concurrent') {
|
|
588
|
+
return {
|
|
589
|
+
patternId: pattern.id,
|
|
590
|
+
localVersion: pattern.version,
|
|
591
|
+
remoteVersion: { ...pattern.version, vectorClock: peerClock },
|
|
592
|
+
conflictType: 'concurrent_update',
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
// ============================================
|
|
598
|
+
// Sync State Management
|
|
599
|
+
// ============================================
|
|
600
|
+
/**
|
|
601
|
+
* Get sync state for a peer
|
|
602
|
+
*/
|
|
603
|
+
getSyncState(peerId) {
|
|
604
|
+
return this.syncStates.get(peerId);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get all sync states
|
|
608
|
+
*/
|
|
609
|
+
getAllSyncStates() {
|
|
610
|
+
return new Map(this.syncStates);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Update sync state
|
|
614
|
+
*/
|
|
615
|
+
updateSyncState(peerId, status, patternIds) {
|
|
616
|
+
const existing = this.syncStates.get(peerId);
|
|
617
|
+
const now = new Date().toISOString();
|
|
618
|
+
const state = {
|
|
619
|
+
patternId: peerId, // Using peerId as the pattern sync identifier
|
|
620
|
+
status,
|
|
621
|
+
lastSyncAt: now,
|
|
622
|
+
lastSuccessAt: status === types_1.SyncStatus.SYNCED ? now : existing?.lastSuccessAt,
|
|
623
|
+
syncedPeers: patternIds ?? existing?.syncedPeers ?? [],
|
|
624
|
+
pendingPeers: [],
|
|
625
|
+
};
|
|
626
|
+
this.syncStates.set(peerId, state);
|
|
627
|
+
}
|
|
628
|
+
// ============================================
|
|
629
|
+
// Bandwidth Management
|
|
630
|
+
// ============================================
|
|
631
|
+
/**
|
|
632
|
+
* Wait for available bandwidth
|
|
633
|
+
*/
|
|
634
|
+
async waitForBandwidth(bytes) {
|
|
635
|
+
const now = Date.now();
|
|
636
|
+
// Reset counter every second
|
|
637
|
+
if (now - this.lastRateReset > 1000) {
|
|
638
|
+
this.bytesThisSecond = 0;
|
|
639
|
+
this.lastRateReset = now;
|
|
640
|
+
}
|
|
641
|
+
// Check if we need to wait
|
|
642
|
+
if (this.bytesThisSecond + bytes > this.bandwidth.maxUploadBps) {
|
|
643
|
+
const waitTime = 1000 - (now - this.lastRateReset);
|
|
644
|
+
await this.delay(waitTime);
|
|
645
|
+
this.bytesThisSecond = 0;
|
|
646
|
+
this.lastRateReset = Date.now();
|
|
647
|
+
}
|
|
648
|
+
this.bytesThisSecond += bytes;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Create batches for sending
|
|
652
|
+
*/
|
|
653
|
+
createBatches(patterns) {
|
|
654
|
+
const batches = [];
|
|
655
|
+
const batchSize = Math.min(this.maxBatchSize, this.bandwidth.batchSize);
|
|
656
|
+
for (let i = 0; i < patterns.length; i += batchSize) {
|
|
657
|
+
batches.push(patterns.slice(i, i + batchSize));
|
|
658
|
+
}
|
|
659
|
+
return batches;
|
|
660
|
+
}
|
|
661
|
+
// ============================================
|
|
662
|
+
// Auto Sync
|
|
663
|
+
// ============================================
|
|
664
|
+
/**
|
|
665
|
+
* Start automatic sync interval
|
|
666
|
+
*/
|
|
667
|
+
startAutoSync(intervalMs) {
|
|
668
|
+
if (this.autoSyncInterval) {
|
|
669
|
+
this.stopAutoSync();
|
|
670
|
+
}
|
|
671
|
+
this.autoSyncInterval = setInterval(() => {
|
|
672
|
+
this.runAutoSync();
|
|
673
|
+
}, intervalMs);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Stop automatic sync
|
|
677
|
+
*/
|
|
678
|
+
stopAutoSync() {
|
|
679
|
+
if (this.autoSyncInterval) {
|
|
680
|
+
clearInterval(this.autoSyncInterval);
|
|
681
|
+
this.autoSyncInterval = undefined;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Run automatic sync with all known peers
|
|
686
|
+
*/
|
|
687
|
+
async runAutoSync() {
|
|
688
|
+
// Get peers from sync states
|
|
689
|
+
for (const peerId of this.syncStates.keys()) {
|
|
690
|
+
try {
|
|
691
|
+
await this.syncWithPeer(peerId);
|
|
692
|
+
}
|
|
693
|
+
catch {
|
|
694
|
+
// Log error but continue with other peers
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
// ============================================
|
|
699
|
+
// Helper Methods
|
|
700
|
+
// ============================================
|
|
701
|
+
/**
|
|
702
|
+
* Send sync request and wait for response
|
|
703
|
+
*/
|
|
704
|
+
async sendSyncRequest(peerId, request) {
|
|
705
|
+
if (!this.channel) {
|
|
706
|
+
throw new types_1.SharingError('No channel for sync', types_1.SharingErrorCode.NETWORK_ERROR);
|
|
707
|
+
}
|
|
708
|
+
return this.channel.request('pattern:sync:request', request, 30000 // 30s timeout
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Process a received pattern
|
|
713
|
+
*/
|
|
714
|
+
async processReceivedPattern(pattern, fromPeer) {
|
|
715
|
+
// Validate pattern
|
|
716
|
+
if (!this.serializer.validatePattern(pattern)) {
|
|
717
|
+
throw new types_1.SharingError(`Invalid pattern: ${pattern.id}`, types_1.SharingErrorCode.INVALID_PATTERN);
|
|
718
|
+
}
|
|
719
|
+
// Check for conflicts
|
|
720
|
+
const conflict = this.index.checkConflict(pattern);
|
|
721
|
+
if (conflict) {
|
|
722
|
+
await this.resolveConflict(conflict, fromPeer);
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
// Add or update pattern
|
|
726
|
+
if (this.index.has(pattern.id)) {
|
|
727
|
+
this.index.update(pattern.id, pattern);
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
try {
|
|
731
|
+
this.index.add(pattern);
|
|
732
|
+
}
|
|
733
|
+
catch (error) {
|
|
734
|
+
if (error instanceof types_1.SharingError &&
|
|
735
|
+
error.code === types_1.SharingErrorCode.DUPLICATE_PATTERN) {
|
|
736
|
+
// Already exists (by content hash), skip
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
throw error;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Check if pattern can be shared with peer
|
|
745
|
+
*/
|
|
746
|
+
canShareWith(pattern, peerId) {
|
|
747
|
+
const { policy, allowedPeers, blockedPeers } = pattern.sharing;
|
|
748
|
+
// Check blocked list
|
|
749
|
+
if (blockedPeers?.includes(peerId)) {
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
switch (policy) {
|
|
753
|
+
case 'public':
|
|
754
|
+
return true;
|
|
755
|
+
case 'trusted':
|
|
756
|
+
// For now, all connected peers are considered trusted
|
|
757
|
+
return true;
|
|
758
|
+
case 'selective':
|
|
759
|
+
return allowedPeers?.includes(peerId) ?? false;
|
|
760
|
+
case 'private':
|
|
761
|
+
return false;
|
|
762
|
+
default:
|
|
763
|
+
return false;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Create a sync session
|
|
768
|
+
*/
|
|
769
|
+
createSession(sessionId, peerId, direction) {
|
|
770
|
+
const session = {
|
|
771
|
+
sessionId,
|
|
772
|
+
peerId,
|
|
773
|
+
direction,
|
|
774
|
+
startTime: Date.now(),
|
|
775
|
+
patternsTransferred: 0,
|
|
776
|
+
bytesTransferred: 0,
|
|
777
|
+
status: types_1.SyncStatus.SYNCING,
|
|
778
|
+
};
|
|
779
|
+
this.activeSessions.set(sessionId, session);
|
|
780
|
+
return session;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Generate unique request ID using cryptographically secure random
|
|
784
|
+
*/
|
|
785
|
+
generateRequestId() {
|
|
786
|
+
const timestamp = Date.now().toString(36);
|
|
787
|
+
const randomBytes = new Uint8Array(4);
|
|
788
|
+
crypto.getRandomValues(randomBytes);
|
|
789
|
+
const random = Array.from(randomBytes).map(b => b.toString(36)).join('').substring(0, 6);
|
|
790
|
+
return `sync-${timestamp}-${random}`;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Generate continuation token
|
|
794
|
+
*/
|
|
795
|
+
generateContinuationToken() {
|
|
796
|
+
return Buffer.from(Date.now().toString()).toString('base64');
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Delay helper
|
|
800
|
+
*/
|
|
801
|
+
delay(ms) {
|
|
802
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
803
|
+
}
|
|
804
|
+
// ============================================
|
|
805
|
+
// Events
|
|
806
|
+
// ============================================
|
|
807
|
+
/**
|
|
808
|
+
* Subscribe to events
|
|
809
|
+
*/
|
|
810
|
+
on(handler) {
|
|
811
|
+
this.eventHandlers.push(handler);
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Unsubscribe from events
|
|
815
|
+
*/
|
|
816
|
+
off(handler) {
|
|
817
|
+
const index = this.eventHandlers.indexOf(handler);
|
|
818
|
+
if (index !== -1) {
|
|
819
|
+
this.eventHandlers.splice(index, 1);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Emit an event
|
|
824
|
+
*/
|
|
825
|
+
emit(event) {
|
|
826
|
+
for (const handler of this.eventHandlers) {
|
|
827
|
+
try {
|
|
828
|
+
handler(event);
|
|
829
|
+
}
|
|
830
|
+
catch {
|
|
831
|
+
// Ignore handler errors
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
// ============================================
|
|
836
|
+
// Cleanup
|
|
837
|
+
// ============================================
|
|
838
|
+
/**
|
|
839
|
+
* Destroy the sync manager
|
|
840
|
+
*/
|
|
841
|
+
destroy() {
|
|
842
|
+
this.stopAutoSync();
|
|
843
|
+
this.activeSessions.clear();
|
|
844
|
+
this.pendingSyncs.clear();
|
|
845
|
+
this.syncStates.clear();
|
|
846
|
+
this.eventHandlers = [];
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
exports.PatternSyncManager = PatternSyncManager;
|
|
850
|
+
// ============================================
|
|
851
|
+
// Factory Functions
|
|
852
|
+
// ============================================
|
|
853
|
+
/**
|
|
854
|
+
* Create a new pattern sync manager
|
|
855
|
+
*/
|
|
856
|
+
function createPatternSyncManager(config) {
|
|
857
|
+
return new PatternSyncManager(config);
|
|
858
|
+
}
|
|
859
|
+
//# sourceMappingURL=PatternSyncManager.js.map
|