@holoscript/framework 6.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/ALL-test-results.json +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/ROADMAP.md +175 -0
  5. package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
  6. package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
  7. package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
  8. package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
  9. package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
  10. package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
  11. package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
  12. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
  13. package/dist/agents/index.cjs +4790 -0
  14. package/dist/agents/index.d.cts +1788 -0
  15. package/dist/agents/index.d.ts +1788 -0
  16. package/dist/agents/index.js +4695 -0
  17. package/dist/ai/index.cjs +5347 -0
  18. package/dist/ai/index.d.cts +1753 -0
  19. package/dist/ai/index.d.ts +1753 -0
  20. package/dist/ai/index.js +5244 -0
  21. package/dist/behavior.cjs +449 -0
  22. package/dist/behavior.d.cts +130 -0
  23. package/dist/behavior.d.ts +130 -0
  24. package/dist/behavior.js +407 -0
  25. package/dist/economy/index.cjs +3659 -0
  26. package/dist/economy/index.d.cts +747 -0
  27. package/dist/economy/index.d.ts +747 -0
  28. package/dist/economy/index.js +3617 -0
  29. package/dist/implementations-D9T3un9D.d.cts +236 -0
  30. package/dist/implementations-D9T3un9D.d.ts +236 -0
  31. package/dist/index.cjs +24550 -0
  32. package/dist/index.d.cts +1729 -0
  33. package/dist/index.d.ts +1729 -0
  34. package/dist/index.js +24277 -0
  35. package/dist/learning/index.cjs +219 -0
  36. package/dist/learning/index.d.cts +104 -0
  37. package/dist/learning/index.d.ts +104 -0
  38. package/dist/learning/index.js +189 -0
  39. package/dist/negotiation/index.cjs +970 -0
  40. package/dist/negotiation/index.d.cts +610 -0
  41. package/dist/negotiation/index.d.ts +610 -0
  42. package/dist/negotiation/index.js +931 -0
  43. package/dist/skills/index.cjs +1118 -0
  44. package/dist/skills/index.d.cts +289 -0
  45. package/dist/skills/index.d.ts +289 -0
  46. package/dist/skills/index.js +1079 -0
  47. package/dist/swarm/index.cjs +5268 -0
  48. package/dist/swarm/index.d.cts +2433 -0
  49. package/dist/swarm/index.d.ts +2433 -0
  50. package/dist/swarm/index.js +5221 -0
  51. package/dist/training/index.cjs +2745 -0
  52. package/dist/training/index.d.cts +1734 -0
  53. package/dist/training/index.d.ts +1734 -0
  54. package/dist/training/index.js +2687 -0
  55. package/extract-failures.js +10 -0
  56. package/package.json +82 -0
  57. package/src/__tests__/bounty-marketplace.test.ts +374 -0
  58. package/src/__tests__/delegation.test.ts +144 -0
  59. package/src/__tests__/distributed-claimer.test.ts +147 -0
  60. package/src/__tests__/done-log-audit.test.ts +342 -0
  61. package/src/__tests__/framework.test.ts +865 -0
  62. package/src/__tests__/goal-synthesizer.test.ts +236 -0
  63. package/src/__tests__/presence.test.ts +223 -0
  64. package/src/__tests__/protocol-agent.test.ts +254 -0
  65. package/src/__tests__/revenue-splitter.test.ts +114 -0
  66. package/src/__tests__/scenario-driven-todo.test.ts +197 -0
  67. package/src/__tests__/self-improve.test.ts +349 -0
  68. package/src/__tests__/service-lifecycle.test.ts +237 -0
  69. package/src/__tests__/skill-router.test.ts +121 -0
  70. package/src/agents/AgentManifest.ts +493 -0
  71. package/src/agents/AgentRegistry.ts +475 -0
  72. package/src/agents/AgentTypes.ts +585 -0
  73. package/src/agents/AgentWalletRegistry.ts +83 -0
  74. package/src/agents/AuthenticatedCRDT.ts +388 -0
  75. package/src/agents/CapabilityMatcher.ts +453 -0
  76. package/src/agents/CrossRealityHandoff.ts +305 -0
  77. package/src/agents/CulturalMemory.ts +454 -0
  78. package/src/agents/FederatedRegistryAdapter.ts +429 -0
  79. package/src/agents/NormEngine.ts +450 -0
  80. package/src/agents/OrchestratorAgent.ts +414 -0
  81. package/src/agents/SkillWorkflowEngine.ts +472 -0
  82. package/src/agents/TaskDelegationService.ts +551 -0
  83. package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
  84. package/src/agents/__tests__/AgentManifest.test.ts +182 -0
  85. package/src/agents/__tests__/AgentModule.test.ts +864 -0
  86. package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
  87. package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
  88. package/src/agents/__tests__/AgentTypes.test.ts +534 -0
  89. package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
  90. package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
  91. package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
  92. package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
  93. package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
  94. package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
  95. package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
  96. package/src/agents/__tests__/NormEngine.test.ts +276 -0
  97. package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
  98. package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
  99. package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
  100. package/src/agents/index.ts +107 -0
  101. package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
  102. package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
  103. package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
  104. package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
  105. package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
  106. package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
  107. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
  108. package/src/agents/spatial-comms/index.ts +66 -0
  109. package/src/ai/AIAdapter.ts +313 -0
  110. package/src/ai/AICopilot.ts +331 -0
  111. package/src/ai/AIOutputValidator.ts +203 -0
  112. package/src/ai/BTNodes.ts +239 -0
  113. package/src/ai/BehaviorSelector.ts +135 -0
  114. package/src/ai/BehaviorTree.ts +153 -0
  115. package/src/ai/Blackboard.ts +165 -0
  116. package/src/ai/GenerationAnalytics.ts +461 -0
  117. package/src/ai/GenerationCache.ts +265 -0
  118. package/src/ai/GoalPlanner.ts +165 -0
  119. package/src/ai/HoloScriptGenerator.ts +580 -0
  120. package/src/ai/InfluenceMap.ts +180 -0
  121. package/src/ai/NavMesh.ts +168 -0
  122. package/src/ai/PerceptionSystem.ts +178 -0
  123. package/src/ai/PromptTemplates.ts +453 -0
  124. package/src/ai/SemanticSearchService.ts +80 -0
  125. package/src/ai/StateMachine.ts +196 -0
  126. package/src/ai/SteeringBehavior.ts +150 -0
  127. package/src/ai/SteeringBehaviors.ts +244 -0
  128. package/src/ai/TrainingDataGenerator.ts +1082 -0
  129. package/src/ai/UtilityAI.ts +145 -0
  130. package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
  131. package/src/ai/__tests__/AIAdapter.test.ts +109 -0
  132. package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
  133. package/src/ai/__tests__/AICopilot.test.ts +178 -0
  134. package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
  135. package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
  136. package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
  137. package/src/ai/__tests__/BTNodes.test.ts +263 -0
  138. package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
  139. package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
  140. package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
  141. package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
  142. package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
  143. package/src/ai/__tests__/Blackboard.test.ts +183 -0
  144. package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
  145. package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
  146. package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
  147. package/src/ai/__tests__/GenerationCache.test.ts +171 -0
  148. package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
  149. package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
  150. package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
  151. package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
  152. package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
  153. package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
  154. package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
  155. package/src/ai/__tests__/NavMesh.test.ts +159 -0
  156. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
  157. package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
  158. package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
  159. package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
  160. package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
  161. package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
  162. package/src/ai/__tests__/StateMachine.test.ts +163 -0
  163. package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
  164. package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
  165. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
  166. package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
  167. package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
  168. package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
  169. package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
  170. package/src/ai/__tests__/UtilityAI.test.ts +155 -0
  171. package/src/ai/__tests__/adapters.prod.test.ts +263 -0
  172. package/src/ai/__tests__/adapters.test.ts +320 -0
  173. package/src/ai/adapters.ts +1585 -0
  174. package/src/ai/index.ts +130 -0
  175. package/src/behavior/BehaviorPresets.ts +140 -0
  176. package/src/behavior/BehaviorTree.ts +236 -0
  177. package/src/behavior/StateMachine.ts +176 -0
  178. package/src/behavior/StateTrait.ts +67 -0
  179. package/src/behavior/index.ts +8 -0
  180. package/src/behavior.ts +8 -0
  181. package/src/board/audit.ts +284 -0
  182. package/src/board/board-ops.ts +336 -0
  183. package/src/board/board-types.ts +302 -0
  184. package/src/board/index.ts +69 -0
  185. package/src/define-agent.ts +46 -0
  186. package/src/define-team.ts +33 -0
  187. package/src/delegation.ts +265 -0
  188. package/src/distributed-claimer.ts +228 -0
  189. package/src/economy/AgentBudgetEnforcer.ts +464 -0
  190. package/src/economy/BountyManager.ts +185 -0
  191. package/src/economy/CreatorRevenueAggregator.ts +460 -0
  192. package/src/economy/InvisibleWallet.ts +82 -0
  193. package/src/economy/KnowledgeMarketplace.ts +193 -0
  194. package/src/economy/PaymentWebhookService.ts +512 -0
  195. package/src/economy/RevenueSplitter.ts +156 -0
  196. package/src/economy/SubscriptionManager.ts +546 -0
  197. package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
  198. package/src/economy/UsageMeter.ts +440 -0
  199. package/src/economy/_core-stubs.ts +219 -0
  200. package/src/economy/index.ts +100 -0
  201. package/src/economy/x402-facilitator.ts +1978 -0
  202. package/src/index.ts +348 -0
  203. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
  204. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
  205. package/src/knowledge/brain.ts +167 -0
  206. package/src/knowledge/consolidation.ts +581 -0
  207. package/src/knowledge/knowledge-consolidator.ts +510 -0
  208. package/src/knowledge/knowledge-store.ts +616 -0
  209. package/src/learning/MemoryConsolidator.ts +102 -0
  210. package/src/learning/MemoryScorer.ts +69 -0
  211. package/src/learning/ProceduralCompiler.ts +45 -0
  212. package/src/learning/SemanticClusterer.ts +66 -0
  213. package/src/learning/index.ts +8 -0
  214. package/src/llm/llm-adapter.ts +159 -0
  215. package/src/mesh/index.ts +309 -0
  216. package/src/negotiation/NegotiationProtocol.ts +694 -0
  217. package/src/negotiation/NegotiationTypes.ts +473 -0
  218. package/src/negotiation/VotingMechanisms.ts +691 -0
  219. package/src/negotiation/index.ts +49 -0
  220. package/src/protocol/goal-synthesizer.ts +317 -0
  221. package/src/protocol/implementations.ts +474 -0
  222. package/src/protocol/micro-phase-decomposer.ts +299 -0
  223. package/src/protocol/micro-step-decomposer.test.ts +306 -0
  224. package/src/protocol-agent.test.ts +353 -0
  225. package/src/protocol-agent.ts +670 -0
  226. package/src/self-improve/absorb-scanner.ts +252 -0
  227. package/src/self-improve/evolution-engine.ts +149 -0
  228. package/src/self-improve/framework-absorber.ts +214 -0
  229. package/src/self-improve/index.ts +50 -0
  230. package/src/self-improve/prompt-optimizer.ts +212 -0
  231. package/src/self-improve/test-generator.ts +175 -0
  232. package/src/skill-router.ts +186 -0
  233. package/src/skills/index.ts +5 -0
  234. package/src/skills/skill-md-bridge.ts +1699 -0
  235. package/src/swarm/ACOEngine.ts +261 -0
  236. package/src/swarm/CollectiveIntelligence.ts +383 -0
  237. package/src/swarm/ContributionSynthesizer.ts +481 -0
  238. package/src/swarm/LeaderElection.ts +393 -0
  239. package/src/swarm/PSOEngine.ts +206 -0
  240. package/src/swarm/QuorumPolicy.ts +173 -0
  241. package/src/swarm/SwarmCoordinator.ts +335 -0
  242. package/src/swarm/SwarmManager.ts +442 -0
  243. package/src/swarm/SwarmMembership.ts +456 -0
  244. package/src/swarm/VotingRound.ts +255 -0
  245. package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
  246. package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
  247. package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
  248. package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
  249. package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
  250. package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
  251. package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
  252. package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
  253. package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
  254. package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
  255. package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
  256. package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
  257. package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
  258. package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
  259. package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
  260. package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
  261. package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
  262. package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
  263. package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
  264. package/src/swarm/__tests__/VotingRound.test.ts +174 -0
  265. package/src/swarm/analytics/SwarmInspector.ts +476 -0
  266. package/src/swarm/analytics/SwarmMetrics.ts +449 -0
  267. package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
  268. package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
  269. package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
  270. package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
  271. package/src/swarm/analytics/index.ts +7 -0
  272. package/src/swarm/index.ts +69 -0
  273. package/src/swarm/messaging/BroadcastChannel.ts +509 -0
  274. package/src/swarm/messaging/GossipProtocol.ts +565 -0
  275. package/src/swarm/messaging/SwarmEventBus.ts +443 -0
  276. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
  277. package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
  278. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
  279. package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
  280. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
  281. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
  282. package/src/swarm/messaging/index.ts +8 -0
  283. package/src/swarm/spatial/FlockingBehavior.ts +462 -0
  284. package/src/swarm/spatial/FormationController.ts +500 -0
  285. package/src/swarm/spatial/Vector3.ts +170 -0
  286. package/src/swarm/spatial/ZoneClaiming.ts +509 -0
  287. package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
  288. package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
  289. package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
  290. package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
  291. package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
  292. package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
  293. package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
  294. package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
  295. package/src/swarm/spatial/index.ts +28 -0
  296. package/src/team.ts +1245 -0
  297. package/src/training/LRScheduler.ts +377 -0
  298. package/src/training/QualityScoringPipeline.ts +139 -0
  299. package/src/training/SoftDedup.ts +461 -0
  300. package/src/training/SparsityMonitor.ts +685 -0
  301. package/src/training/SparsityMonitorTypes.ts +209 -0
  302. package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
  303. package/src/training/SpatialTrainingDataTypes.ts +216 -0
  304. package/src/training/TrainingPipelineConfig.ts +215 -0
  305. package/src/training/constants.ts +94 -0
  306. package/src/training/index.ts +138 -0
  307. package/src/training/schema.ts +147 -0
  308. package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  309. package/src/training/scripts/generate-spatial-dataset.ts +521 -0
  310. package/src/training/training/data/novel-use-cases.jsonl +153 -0
  311. package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
  312. package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  313. package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  314. package/src/training/trainingmonkey/index.ts +26 -0
  315. package/src/training/trait-mappings.ts +157 -0
  316. package/src/types/core-stubs.d.ts +113 -0
  317. package/src/types.ts +304 -0
  318. package/test-output.txt +0 -0
  319. package/test-result.json +1 -0
  320. package/tsc-errors.txt +4 -0
  321. package/tsc_output.txt +0 -0
  322. package/tsconfig.json +14 -0
  323. package/tsup-learning-esm.config.ts +12 -0
  324. package/tsup.config.ts +21 -0
  325. package/typescript-errors-2.txt +0 -0
  326. package/typescript-errors.txt +22 -0
  327. package/vitest-log-utf8.txt +268 -0
  328. package/vitest-log.txt +0 -0
  329. package/vitest.config.ts +8 -0
@@ -0,0 +1,565 @@
1
+ /**
2
+ * GossipProtocol - Epidemic-style message propagation
3
+ * HoloScript v3.2 - Autonomous Agent Swarms
4
+ *
5
+ * Implements gossip-based message spreading for decentralized swarms
6
+ */
7
+
8
+ /**
9
+ * Gossip message wrapper
10
+ */
11
+ export interface IGossipMessage {
12
+ id: string;
13
+ originId: string;
14
+ content: unknown;
15
+ type: 'data' | 'heartbeat' | 'membership' | 'custom';
16
+ version: number;
17
+ createdAt: number;
18
+ ttl: number;
19
+ hops: number;
20
+ path: string[];
21
+ signature?: string;
22
+ }
23
+
24
+ /**
25
+ * Peer information
26
+ */
27
+ export interface IGossipPeer {
28
+ id: string;
29
+ address: string;
30
+ lastSeen: number;
31
+ failureCount: number;
32
+ isActive: boolean;
33
+ metadata?: Record<string, unknown>;
34
+ }
35
+
36
+ /**
37
+ * Gossip protocol configuration
38
+ */
39
+ export interface IGossipConfig {
40
+ /** Number of peers to gossip to per round */
41
+ fanout: number;
42
+ /** Gossip interval in milliseconds */
43
+ gossipInterval: number;
44
+ /** Maximum TTL for messages */
45
+ maxTTL: number;
46
+ /** Maximum hops per message */
47
+ maxHops: number;
48
+ /** Failure threshold before marking peer inactive */
49
+ failureThreshold: number;
50
+ /** Time before peer considered stale */
51
+ peerTimeout: number;
52
+ /** Whether to deduplicate messages */
53
+ deduplicate: boolean;
54
+ }
55
+
56
+ /**
57
+ * Message handler for gossip
58
+ */
59
+ export type GossipHandler = (message: IGossipMessage, from: string) => void | Promise<void>;
60
+
61
+ /**
62
+ * Peer selector strategy
63
+ */
64
+ export type PeerSelector = (
65
+ peers: IGossipPeer[],
66
+ count: number,
67
+ exclude?: string[]
68
+ ) => IGossipPeer[];
69
+
70
+ /**
71
+ * GossipProtocol - Epidemic-style message propagation
72
+ */
73
+ export class GossipProtocol {
74
+ readonly nodeId: string;
75
+
76
+ private peers: Map<string, IGossipPeer> = new Map();
77
+ private seenMessages: Map<string, number> = new Map();
78
+ private messageQueue: IGossipMessage[] = [];
79
+ private handlers: Map<string, GossipHandler[]> = new Map();
80
+ private config: IGossipConfig;
81
+ private running = false;
82
+ private gossipTimer: ReturnType<typeof setInterval> | null = null;
83
+ private peerSelector: PeerSelector;
84
+ private nextMsgId = 1;
85
+
86
+ // Statistics
87
+ private stats = {
88
+ messagesSent: 0,
89
+ messagesReceived: 0,
90
+ messagesDropped: 0,
91
+ gossipRounds: 0,
92
+ duplicatesIgnored: 0,
93
+ };
94
+
95
+ constructor(nodeId: string, config?: Partial<IGossipConfig>) {
96
+ this.nodeId = nodeId;
97
+ this.config = {
98
+ fanout: 3,
99
+ gossipInterval: 1000,
100
+ maxTTL: 30000,
101
+ maxHops: 10,
102
+ failureThreshold: 3,
103
+ peerTimeout: 30000,
104
+ deduplicate: true,
105
+ ...config,
106
+ };
107
+
108
+ // Default random peer selection
109
+ this.peerSelector = this.randomPeerSelection.bind(this);
110
+ }
111
+
112
+ /**
113
+ * Start the gossip protocol
114
+ */
115
+ start(): void {
116
+ if (this.running) return;
117
+
118
+ this.running = true;
119
+ this.gossipTimer = setInterval(() => {
120
+ this.gossipRound();
121
+ }, this.config.gossipInterval);
122
+ }
123
+
124
+ /**
125
+ * Stop the gossip protocol
126
+ */
127
+ stop(): void {
128
+ this.running = false;
129
+ if (this.gossipTimer) {
130
+ clearInterval(this.gossipTimer);
131
+ this.gossipTimer = null;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Check if protocol is running
137
+ */
138
+ isRunning(): boolean {
139
+ return this.running;
140
+ }
141
+
142
+ /**
143
+ * Add a peer
144
+ */
145
+ addPeer(id: string, address: string, metadata?: Record<string, unknown>): void {
146
+ if (id === this.nodeId) return;
147
+
148
+ this.peers.set(id, {
149
+ id,
150
+ address,
151
+ lastSeen: Date.now(),
152
+ failureCount: 0,
153
+ isActive: true,
154
+ metadata,
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Remove a peer
160
+ */
161
+ removePeer(id: string): boolean {
162
+ return this.peers.delete(id);
163
+ }
164
+
165
+ /**
166
+ * Get a peer
167
+ */
168
+ getPeer(id: string): IGossipPeer | undefined {
169
+ return this.peers.get(id);
170
+ }
171
+
172
+ /**
173
+ * Get all active peers
174
+ */
175
+ getActivePeers(): IGossipPeer[] {
176
+ return [...this.peers.values()].filter((p) => p.isActive);
177
+ }
178
+
179
+ /**
180
+ * Get all peers
181
+ */
182
+ getAllPeers(): IGossipPeer[] {
183
+ return [...this.peers.values()];
184
+ }
185
+
186
+ /**
187
+ * Publish a message to the gossip network
188
+ */
189
+ publish(
190
+ content: unknown,
191
+ type: IGossipMessage['type'] = 'data',
192
+ options: { ttl?: number; signature?: string } = {}
193
+ ): string {
194
+ const messageId = `gossip-${this.nodeId}-${this.nextMsgId++}-${Date.now()}`;
195
+
196
+ const message: IGossipMessage = {
197
+ id: messageId,
198
+ originId: this.nodeId,
199
+ content,
200
+ type,
201
+ version: 1,
202
+ createdAt: Date.now(),
203
+ ttl: options.ttl ?? this.config.maxTTL,
204
+ hops: 0,
205
+ path: [this.nodeId],
206
+ signature: options.signature,
207
+ };
208
+
209
+ // Add to queue for gossip
210
+ this.messageQueue.push(message);
211
+ this.seenMessages.set(messageId, Date.now());
212
+
213
+ // Also emit locally (async fire-and-forget to allow synchronous handler invocation)
214
+ // Also emit locally - handlers are called synchronously
215
+ this.emitToHandlers(message, this.nodeId).catch(() => {});
216
+
217
+ this.stats.messagesSent++;
218
+ return messageId;
219
+ }
220
+
221
+ /**
222
+ * Receive a message from a peer
223
+ */
224
+ async receive(message: IGossipMessage, fromPeerId: string): Promise<boolean> {
225
+ // Update peer last seen
226
+ const peer = this.peers.get(fromPeerId);
227
+ if (peer) {
228
+ peer.lastSeen = Date.now();
229
+ peer.failureCount = 0;
230
+ peer.isActive = true;
231
+ }
232
+
233
+ // Check if we've seen this message
234
+ if (this.config.deduplicate && this.seenMessages.has(message.id)) {
235
+ this.stats.duplicatesIgnored++;
236
+ return false;
237
+ }
238
+
239
+ // Check TTL
240
+ if (Date.now() - message.createdAt > message.ttl) {
241
+ this.stats.messagesDropped++;
242
+ return false;
243
+ }
244
+
245
+ // Check hop limit
246
+ if (message.hops >= this.config.maxHops) {
247
+ this.stats.messagesDropped++;
248
+ return false;
249
+ }
250
+
251
+ // Mark as seen
252
+ this.seenMessages.set(message.id, Date.now());
253
+ this.stats.messagesReceived++;
254
+
255
+ // Emit to handlers
256
+ await this.emitToHandlers(message, fromPeerId);
257
+
258
+ // Prepare for re-gossip
259
+ const forwardMessage: IGossipMessage = {
260
+ ...message,
261
+ hops: message.hops + 1,
262
+ path: [...message.path, this.nodeId],
263
+ };
264
+
265
+ // Add to queue for further gossip
266
+ this.messageQueue.push(forwardMessage);
267
+
268
+ return true;
269
+ }
270
+
271
+ /**
272
+ * Subscribe to message types
273
+ */
274
+ subscribe(type: IGossipMessage['type'] | '*', handler: GossipHandler): () => void {
275
+ const key = type === '*' ? '*' : type;
276
+
277
+ if (!this.handlers.has(key)) {
278
+ this.handlers.set(key, []);
279
+ }
280
+ this.handlers.get(key)!.push(handler);
281
+
282
+ return () => {
283
+ const handlers = this.handlers.get(key);
284
+ if (handlers) {
285
+ const idx = handlers.indexOf(handler);
286
+ if (idx >= 0) handlers.splice(idx, 1);
287
+ }
288
+ };
289
+ }
290
+
291
+ /**
292
+ * Set custom peer selector
293
+ */
294
+ setPeerSelector(selector: PeerSelector): void {
295
+ this.peerSelector = selector;
296
+ }
297
+
298
+ /**
299
+ * Perform a gossip round
300
+ */
301
+ async gossipRound(): Promise<void> {
302
+ if (!this.running) return;
303
+
304
+ this.stats.gossipRounds++;
305
+
306
+ // Clean old seen messages
307
+ this.cleanSeenMessages();
308
+
309
+ // Clean stale peers
310
+ this.cleanStalePeers();
311
+
312
+ // Get messages to gossip
313
+ const messages = this.messageQueue.splice(0);
314
+ if (messages.length === 0) return;
315
+
316
+ // Select peers for gossip
317
+ const activePeers = this.getActivePeers();
318
+ if (activePeers.length === 0) return;
319
+
320
+ const selectedPeers = this.peerSelector(
321
+ activePeers,
322
+ Math.min(this.config.fanout, activePeers.length)
323
+ );
324
+
325
+ // Gossip each message to selected peers
326
+ for (const message of messages) {
327
+ // Exclude peers already in the path
328
+ const validPeers = selectedPeers.filter((p) => !message.path.includes(p.id));
329
+
330
+ for (const peer of validPeers) {
331
+ try {
332
+ await this.sendToPeer(peer, message);
333
+ } catch {
334
+ // Record failure
335
+ peer.failureCount++;
336
+ if (peer.failureCount >= this.config.failureThreshold) {
337
+ peer.isActive = false;
338
+ }
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Send a message to a peer (override for actual network)
346
+ */
347
+ protected async sendToPeer(_peer: IGossipPeer, _message: IGossipMessage): Promise<void> {
348
+ // Override this method for actual network transport
349
+ // Default implementation does nothing (for testing)
350
+ }
351
+
352
+ /**
353
+ * Emit message to handlers
354
+ */
355
+ private async emitToHandlers(message: IGossipMessage, from: string): Promise<void> {
356
+ // Emit to type-specific handlers
357
+ const typeHandlers = this.handlers.get(message.type);
358
+ const promises: Promise<void>[] = [];
359
+ if (typeHandlers) {
360
+ for (const handler of typeHandlers) {
361
+ try {
362
+ const result = handler(message, from);
363
+ if (result instanceof Promise) {
364
+ promises.push(result.catch(() => {}));
365
+ }
366
+ } catch {
367
+ // Continue on handler error
368
+ }
369
+ }
370
+ }
371
+
372
+ // Emit to wildcard handlers
373
+ const wildcardHandlers = this.handlers.get('*');
374
+ if (wildcardHandlers) {
375
+ for (const handler of wildcardHandlers) {
376
+ try {
377
+ const result = handler(message, from);
378
+ if (result instanceof Promise) {
379
+ promises.push(result.catch(() => {}));
380
+ }
381
+ } catch {
382
+ // Continue on handler error
383
+ }
384
+ }
385
+ }
386
+
387
+ // Wait for any async promises to complete (but don't block synchronous callers)
388
+ if (promises.length > 0) {
389
+ Promise.all(promises).catch(() => {});
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Random peer selection
395
+ */
396
+ private randomPeerSelection(
397
+ peers: IGossipPeer[],
398
+ count: number,
399
+ exclude: string[] = []
400
+ ): IGossipPeer[] {
401
+ const available = peers.filter((p) => !exclude.includes(p.id));
402
+ const selected: IGossipPeer[] = [];
403
+
404
+ while (selected.length < count && available.length > 0) {
405
+ const idx = Math.floor(Math.random() * available.length);
406
+ selected.push(available.splice(idx, 1)[0]);
407
+ }
408
+
409
+ return selected;
410
+ }
411
+
412
+ /**
413
+ * Clean old seen messages
414
+ */
415
+ private cleanSeenMessages(): void {
416
+ const now = Date.now();
417
+ for (const [id, timestamp] of this.seenMessages) {
418
+ if (now - timestamp > this.config.maxTTL) {
419
+ this.seenMessages.delete(id);
420
+ }
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Clean stale peers
426
+ */
427
+ private cleanStalePeers(): void {
428
+ const now = Date.now();
429
+ for (const peer of this.peers.values()) {
430
+ if (now - peer.lastSeen > this.config.peerTimeout) {
431
+ peer.isActive = false;
432
+ }
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Send a heartbeat
438
+ */
439
+ publishHeartbeat(metadata?: Record<string, unknown>): string {
440
+ return this.publish({ type: 'heartbeat', nodeId: this.nodeId, ...metadata }, 'heartbeat');
441
+ }
442
+
443
+ /**
444
+ * Announce membership change
445
+ */
446
+ publishMembership(action: 'join' | 'leave', metadata?: Record<string, unknown>): string {
447
+ return this.publish({ action, nodeId: this.nodeId, ...metadata }, 'membership');
448
+ }
449
+
450
+ /**
451
+ * Get statistics
452
+ */
453
+ getStats(): typeof this.stats & {
454
+ peerCount: number;
455
+ activePeerCount: number;
456
+ queueSize: number;
457
+ seenCount: number;
458
+ } {
459
+ return {
460
+ ...this.stats,
461
+ peerCount: this.peers.size,
462
+ activePeerCount: this.getActivePeers().length,
463
+ queueSize: this.messageQueue.length,
464
+ seenCount: this.seenMessages.size,
465
+ };
466
+ }
467
+
468
+ /**
469
+ * Reset statistics
470
+ */
471
+ resetStats(): void {
472
+ this.stats = {
473
+ messagesSent: 0,
474
+ messagesReceived: 0,
475
+ messagesDropped: 0,
476
+ gossipRounds: 0,
477
+ duplicatesIgnored: 0,
478
+ };
479
+ }
480
+
481
+ /**
482
+ * Get configuration
483
+ */
484
+ getConfig(): IGossipConfig {
485
+ return { ...this.config };
486
+ }
487
+ }
488
+
489
+ /**
490
+ * Anti-entropy sync for eventual consistency
491
+ */
492
+ export class AntiEntropySync {
493
+ private nodeId: string;
494
+ private protocol: GossipProtocol;
495
+ private dataStore: Map<string, { value: unknown; version: number; timestamp: number }> =
496
+ new Map();
497
+
498
+ constructor(nodeId: string, protocol: GossipProtocol) {
499
+ this.nodeId = nodeId;
500
+ this.protocol = protocol;
501
+
502
+ // Subscribe to data messages
503
+ this.protocol.subscribe('data', (msg) => {
504
+ const data = msg.content as { key: string; value: unknown; version: number };
505
+ if (data.key && data.version !== undefined) {
506
+ this.handleSync(data.key, data.value, data.version, msg.createdAt);
507
+ }
508
+ });
509
+ }
510
+
511
+ /**
512
+ * Set a value (stores locally and gossips)
513
+ */
514
+ set(key: string, value: unknown): void {
515
+ const existing = this.dataStore.get(key);
516
+ const version = existing ? existing.version + 1 : 1;
517
+ const timestamp = Date.now();
518
+
519
+ this.dataStore.set(key, { value, version, timestamp });
520
+
521
+ // Gossip the update
522
+ this.protocol.publish({ key, value, version }, 'data');
523
+ }
524
+
525
+ /**
526
+ * Get a value
527
+ */
528
+ get(key: string): unknown {
529
+ return this.dataStore.get(key)?.value;
530
+ }
531
+
532
+ /**
533
+ * Get all keys
534
+ */
535
+ keys(): string[] {
536
+ return [...this.dataStore.keys()];
537
+ }
538
+
539
+ /**
540
+ * Handle sync from gossip
541
+ */
542
+ private handleSync(key: string, value: unknown, version: number, timestamp: number): void {
543
+ const existing = this.dataStore.get(key);
544
+
545
+ // LWW (Last Writer Wins) with version tiebreaker
546
+ if (
547
+ !existing ||
548
+ version > existing.version ||
549
+ (version === existing.version && timestamp > existing.timestamp)
550
+ ) {
551
+ this.dataStore.set(key, { value, version, timestamp });
552
+ }
553
+ }
554
+
555
+ /**
556
+ * Get data snapshot
557
+ */
558
+ getSnapshot(): Map<string, unknown> {
559
+ const snapshot = new Map<string, unknown>();
560
+ for (const [key, data] of this.dataStore) {
561
+ snapshot.set(key, data.value);
562
+ }
563
+ return snapshot;
564
+ }
565
+ }