@swal/edge-mesh 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. package/LICENSE +128 -0
  2. package/NOTICE +37 -0
  3. package/README.md +470 -2
  4. package/dist/adapters/gpu-agent/index.d.ts +61 -0
  5. package/dist/adapters/gpu-agent/index.d.ts.map +1 -0
  6. package/dist/adapters/gpu-agent/index.js +364 -0
  7. package/dist/adapters/gpu-agent/index.js.map +1 -0
  8. package/dist/adapters/maloca-salud/citas-distribuidas.d.ts +19 -0
  9. package/dist/adapters/maloca-salud/citas-distribuidas.d.ts.map +1 -0
  10. package/dist/adapters/maloca-salud/citas-distribuidas.js +51 -0
  11. package/dist/adapters/maloca-salud/citas-distribuidas.js.map +1 -0
  12. package/dist/adapters/maloca-salud/eps-bridge.d.ts +15 -0
  13. package/dist/adapters/maloca-salud/eps-bridge.d.ts.map +1 -0
  14. package/dist/adapters/maloca-salud/eps-bridge.js +27 -0
  15. package/dist/adapters/maloca-salud/eps-bridge.js.map +1 -0
  16. package/dist/adapters/maloca-salud/patient-profile.d.ts +20 -0
  17. package/dist/adapters/maloca-salud/patient-profile.d.ts.map +1 -0
  18. package/dist/adapters/maloca-salud/patient-profile.js +36 -0
  19. package/dist/adapters/maloca-salud/patient-profile.js.map +1 -0
  20. package/dist/adapters/maloca-salud/types.d.ts +40 -0
  21. package/dist/adapters/maloca-salud/types.d.ts.map +1 -0
  22. package/dist/adapters/maloca-salud/types.js +2 -0
  23. package/dist/adapters/maloca-salud/types.js.map +1 -0
  24. package/dist/adapters/maloca-veeduria/contract-bridge.d.ts +31 -0
  25. package/dist/adapters/maloca-veeduria/contract-bridge.d.ts.map +1 -0
  26. package/dist/adapters/maloca-veeduria/contract-bridge.js +103 -0
  27. package/dist/adapters/maloca-veeduria/contract-bridge.js.map +1 -0
  28. package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts +14 -0
  29. package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts.map +1 -0
  30. package/dist/adapters/maloca-veeduria/evidentia-veeduria.js +40 -0
  31. package/dist/adapters/maloca-veeduria/evidentia-veeduria.js.map +1 -0
  32. package/dist/adapters/maloca-veeduria/licitante-profile.d.ts +21 -0
  33. package/dist/adapters/maloca-veeduria/licitante-profile.d.ts.map +1 -0
  34. package/dist/adapters/maloca-veeduria/licitante-profile.js +58 -0
  35. package/dist/adapters/maloca-veeduria/licitante-profile.js.map +1 -0
  36. package/dist/adapters/maloca-veeduria/types.d.ts +30 -0
  37. package/dist/adapters/maloca-veeduria/types.d.ts.map +1 -0
  38. package/dist/adapters/maloca-veeduria/types.js +2 -0
  39. package/dist/adapters/maloca-veeduria/types.js.map +1 -0
  40. package/dist/adapters/maloca-xavier/agent-profile.d.ts +32 -0
  41. package/dist/adapters/maloca-xavier/agent-profile.d.ts.map +1 -0
  42. package/dist/adapters/maloca-xavier/agent-profile.js +56 -0
  43. package/dist/adapters/maloca-xavier/agent-profile.js.map +1 -0
  44. package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts +27 -0
  45. package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts.map +1 -0
  46. package/dist/adapters/maloca-xavier/codegraph-bridge.js +58 -0
  47. package/dist/adapters/maloca-xavier/codegraph-bridge.js.map +1 -0
  48. package/dist/adapters/maloca-xavier/llm-router.d.ts +25 -0
  49. package/dist/adapters/maloca-xavier/llm-router.d.ts.map +1 -0
  50. package/dist/adapters/maloca-xavier/llm-router.js +58 -0
  51. package/dist/adapters/maloca-xavier/llm-router.js.map +1 -0
  52. package/dist/authz/index.d.ts +81 -0
  53. package/dist/authz/index.d.ts.map +1 -0
  54. package/dist/authz/index.js +271 -0
  55. package/dist/authz/index.js.map +1 -0
  56. package/dist/chat/index.d.ts +138 -0
  57. package/dist/chat/index.d.ts.map +1 -0
  58. package/dist/chat/index.js +394 -0
  59. package/dist/chat/index.js.map +1 -0
  60. package/dist/chat/offline-queue.d.ts +32 -0
  61. package/dist/chat/offline-queue.d.ts.map +1 -0
  62. package/dist/chat/offline-queue.js +93 -0
  63. package/dist/chat/offline-queue.js.map +1 -0
  64. package/dist/core/DefaultEdgeMeshNode.d.ts +17 -0
  65. package/dist/core/DefaultEdgeMeshNode.d.ts.map +1 -0
  66. package/dist/core/DefaultEdgeMeshNode.js +57 -0
  67. package/dist/core/DefaultEdgeMeshNode.js.map +1 -0
  68. package/dist/core/node.d.ts +26 -0
  69. package/dist/core/node.d.ts.map +1 -0
  70. package/dist/core/node.js +16 -0
  71. package/dist/core/node.js.map +1 -0
  72. package/dist/edge-mesh.d.ts +139 -0
  73. package/dist/edge-mesh.d.ts.map +1 -0
  74. package/dist/edge-mesh.js +1146 -0
  75. package/dist/edge-mesh.js.map +1 -0
  76. package/dist/gos/GosBridge.d.ts +49 -0
  77. package/dist/gos/GosBridge.d.ts.map +1 -0
  78. package/dist/gos/GosBridge.js +133 -0
  79. package/dist/gos/GosBridge.js.map +1 -0
  80. package/dist/governance/authority.d.ts +44 -0
  81. package/dist/governance/authority.d.ts.map +1 -0
  82. package/dist/governance/authority.js +123 -0
  83. package/dist/governance/authority.js.map +1 -0
  84. package/dist/governance/index.d.ts +66 -0
  85. package/dist/governance/index.d.ts.map +1 -0
  86. package/dist/governance/index.js +210 -0
  87. package/dist/governance/index.js.map +1 -0
  88. package/dist/governance/merge.d.ts +31 -0
  89. package/dist/governance/merge.d.ts.map +1 -0
  90. package/dist/governance/merge.js +167 -0
  91. package/dist/governance/merge.js.map +1 -0
  92. package/dist/identity/index.d.ts +199 -0
  93. package/dist/identity/index.d.ts.map +1 -0
  94. package/dist/identity/index.js +415 -0
  95. package/dist/identity/index.js.map +1 -0
  96. package/dist/index.d.ts +71 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +56 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/maloca/backoffice.d.ts +31 -0
  101. package/dist/maloca/backoffice.d.ts.map +1 -0
  102. package/dist/maloca/backoffice.js +40 -0
  103. package/dist/maloca/backoffice.js.map +1 -0
  104. package/dist/maloca/event-bus.d.ts +60 -0
  105. package/dist/maloca/event-bus.d.ts.map +1 -0
  106. package/dist/maloca/event-bus.js +175 -0
  107. package/dist/maloca/event-bus.js.map +1 -0
  108. package/dist/maloca/evidentia.d.ts +136 -0
  109. package/dist/maloca/evidentia.d.ts.map +1 -0
  110. package/dist/maloca/evidentia.js +447 -0
  111. package/dist/maloca/evidentia.js.map +1 -0
  112. package/dist/maloca/gateway/api.d.ts +146 -0
  113. package/dist/maloca/gateway/api.d.ts.map +1 -0
  114. package/dist/maloca/gateway/api.js +228 -0
  115. package/dist/maloca/gateway/api.js.map +1 -0
  116. package/dist/maloca/gateway/auth.d.ts +20 -0
  117. package/dist/maloca/gateway/auth.d.ts.map +1 -0
  118. package/dist/maloca/gateway/auth.js +115 -0
  119. package/dist/maloca/gateway/auth.js.map +1 -0
  120. package/dist/maloca/gateway/dashboard.d.ts +42 -0
  121. package/dist/maloca/gateway/dashboard.d.ts.map +1 -0
  122. package/dist/maloca/gateway/dashboard.js +67 -0
  123. package/dist/maloca/gateway/dashboard.js.map +1 -0
  124. package/dist/maloca/gateway/websocket.d.ts +34 -0
  125. package/dist/maloca/gateway/websocket.d.ts.map +1 -0
  126. package/dist/maloca/gateway/websocket.js +71 -0
  127. package/dist/maloca/gateway/websocket.js.map +1 -0
  128. package/dist/maloca/karma.d.ts +165 -0
  129. package/dist/maloca/karma.d.ts.map +1 -0
  130. package/dist/maloca/karma.js +307 -0
  131. package/dist/maloca/karma.js.map +1 -0
  132. package/dist/maloca/kernel.d.ts +20 -0
  133. package/dist/maloca/kernel.d.ts.map +1 -0
  134. package/dist/maloca/kernel.js +76 -0
  135. package/dist/maloca/kernel.js.map +1 -0
  136. package/dist/maloca/metadata.d.ts +30 -0
  137. package/dist/maloca/metadata.d.ts.map +1 -0
  138. package/dist/maloca/metadata.js +80 -0
  139. package/dist/maloca/metadata.js.map +1 -0
  140. package/dist/maloca/perfil.d.ts +57 -0
  141. package/dist/maloca/perfil.d.ts.map +1 -0
  142. package/dist/maloca/perfil.js +113 -0
  143. package/dist/maloca/perfil.js.map +1 -0
  144. package/dist/maloca/plugin-registry.d.ts +27 -0
  145. package/dist/maloca/plugin-registry.d.ts.map +1 -0
  146. package/dist/maloca/plugin-registry.js +76 -0
  147. package/dist/maloca/plugin-registry.js.map +1 -0
  148. package/dist/maloca/polygon-bridge.d.ts +63 -0
  149. package/dist/maloca/polygon-bridge.d.ts.map +1 -0
  150. package/dist/maloca/polygon-bridge.js +198 -0
  151. package/dist/maloca/polygon-bridge.js.map +1 -0
  152. package/dist/maloca/types.d.ts +44 -0
  153. package/dist/maloca/types.d.ts.map +1 -0
  154. package/dist/maloca/types.js +2 -0
  155. package/dist/maloca/types.js.map +1 -0
  156. package/dist/medico/aval.d.ts +149 -0
  157. package/dist/medico/aval.d.ts.map +1 -0
  158. package/dist/medico/aval.js +281 -0
  159. package/dist/medico/aval.js.map +1 -0
  160. package/dist/medico/canonica.d.ts +96 -0
  161. package/dist/medico/canonica.d.ts.map +1 -0
  162. package/dist/medico/canonica.js +148 -0
  163. package/dist/medico/canonica.js.map +1 -0
  164. package/dist/medico/credencial.d.ts +160 -0
  165. package/dist/medico/credencial.d.ts.map +1 -0
  166. package/dist/medico/credencial.js +240 -0
  167. package/dist/medico/credencial.js.map +1 -0
  168. package/dist/medico/index.d.ts +36 -0
  169. package/dist/medico/index.d.ts.map +1 -0
  170. package/dist/medico/index.js +39 -0
  171. package/dist/medico/index.js.map +1 -0
  172. package/dist/medico/malla.d.ts +218 -0
  173. package/dist/medico/malla.d.ts.map +1 -0
  174. package/dist/medico/malla.js +347 -0
  175. package/dist/medico/malla.js.map +1 -0
  176. package/dist/medico/registro-profesional.d.ts +84 -0
  177. package/dist/medico/registro-profesional.d.ts.map +1 -0
  178. package/dist/medico/registro-profesional.js +135 -0
  179. package/dist/medico/registro-profesional.js.map +1 -0
  180. package/dist/medico/registro.d.ts +149 -0
  181. package/dist/medico/registro.d.ts.map +1 -0
  182. package/dist/medico/registro.js +173 -0
  183. package/dist/medico/registro.js.map +1 -0
  184. package/dist/medico/types.d.ts +287 -0
  185. package/dist/medico/types.d.ts.map +1 -0
  186. package/dist/medico/types.js +135 -0
  187. package/dist/medico/types.js.map +1 -0
  188. package/dist/medico/verificacion-registro.d.ts +300 -0
  189. package/dist/medico/verificacion-registro.d.ts.map +1 -0
  190. package/dist/medico/verificacion-registro.js +319 -0
  191. package/dist/medico/verificacion-registro.js.map +1 -0
  192. package/dist/mesh/index.d.ts +457 -0
  193. package/dist/mesh/index.d.ts.map +1 -0
  194. package/dist/mesh/index.js +929 -0
  195. package/dist/mesh/index.js.map +1 -0
  196. package/dist/namespaces/encrypted-plugin.d.ts +56 -0
  197. package/dist/namespaces/encrypted-plugin.d.ts.map +1 -0
  198. package/dist/namespaces/encrypted-plugin.js +173 -0
  199. package/dist/namespaces/encrypted-plugin.js.map +1 -0
  200. package/dist/namespaces/index.d.ts +52 -0
  201. package/dist/namespaces/index.d.ts.map +1 -0
  202. package/dist/namespaces/index.js +134 -0
  203. package/dist/namespaces/index.js.map +1 -0
  204. package/dist/namespaces/ivn-proofs.d.ts +54 -0
  205. package/dist/namespaces/ivn-proofs.d.ts.map +1 -0
  206. package/dist/namespaces/ivn-proofs.js +162 -0
  207. package/dist/namespaces/ivn-proofs.js.map +1 -0
  208. package/dist/namespaces/offers-gossip.d.ts +95 -0
  209. package/dist/namespaces/offers-gossip.d.ts.map +1 -0
  210. package/dist/namespaces/offers-gossip.js +213 -0
  211. package/dist/namespaces/offers-gossip.js.map +1 -0
  212. package/dist/node-memory/idb-store.d.ts +22 -0
  213. package/dist/node-memory/idb-store.d.ts.map +1 -0
  214. package/dist/node-memory/idb-store.js +154 -0
  215. package/dist/node-memory/idb-store.js.map +1 -0
  216. package/dist/node-memory/index.d.ts +14 -0
  217. package/dist/node-memory/index.d.ts.map +1 -0
  218. package/dist/node-memory/index.js +159 -0
  219. package/dist/node-memory/index.js.map +1 -0
  220. package/dist/node-memory/sync-flush.d.ts +11 -0
  221. package/dist/node-memory/sync-flush.d.ts.map +1 -0
  222. package/dist/node-memory/sync-flush.js +37 -0
  223. package/dist/node-memory/sync-flush.js.map +1 -0
  224. package/dist/node-memory/types.d.ts +34 -0
  225. package/dist/node-memory/types.d.ts.map +1 -0
  226. package/dist/node-memory/types.js +2 -0
  227. package/dist/node-memory/types.js.map +1 -0
  228. package/dist/node-memory/xavier-store.d.ts +12 -0
  229. package/dist/node-memory/xavier-store.d.ts.map +1 -0
  230. package/dist/node-memory/xavier-store.js +75 -0
  231. package/dist/node-memory/xavier-store.js.map +1 -0
  232. package/dist/op-log/index.d.ts +49 -0
  233. package/dist/op-log/index.d.ts.map +1 -0
  234. package/dist/op-log/index.js +190 -0
  235. package/dist/op-log/index.js.map +1 -0
  236. package/dist/presence/health.d.ts +54 -0
  237. package/dist/presence/health.d.ts.map +1 -0
  238. package/dist/presence/health.js +139 -0
  239. package/dist/presence/health.js.map +1 -0
  240. package/dist/presence/index.d.ts +85 -0
  241. package/dist/presence/index.d.ts.map +1 -0
  242. package/dist/presence/index.js +255 -0
  243. package/dist/presence/index.js.map +1 -0
  244. package/dist/presence/peer-health.d.ts +40 -0
  245. package/dist/presence/peer-health.d.ts.map +1 -0
  246. package/dist/presence/peer-health.js +118 -0
  247. package/dist/presence/peer-health.js.map +1 -0
  248. package/dist/protocol/canonical.d.ts +10 -0
  249. package/dist/protocol/canonical.d.ts.map +1 -0
  250. package/dist/protocol/canonical.js +32 -0
  251. package/dist/protocol/canonical.js.map +1 -0
  252. package/dist/protocol/crypto.d.ts +299 -0
  253. package/dist/protocol/crypto.d.ts.map +1 -0
  254. package/dist/protocol/crypto.js +739 -0
  255. package/dist/protocol/crypto.js.map +1 -0
  256. package/dist/protocol/index.d.ts +30 -0
  257. package/dist/protocol/index.d.ts.map +1 -0
  258. package/dist/protocol/index.js +116 -0
  259. package/dist/protocol/index.js.map +1 -0
  260. package/dist/protocol/utils.d.ts +5 -0
  261. package/dist/protocol/utils.d.ts.map +1 -0
  262. package/dist/protocol/utils.js +27 -0
  263. package/dist/protocol/utils.js.map +1 -0
  264. package/dist/salones/manager.d.ts +100 -0
  265. package/dist/salones/manager.d.ts.map +1 -0
  266. package/dist/salones/manager.js +240 -0
  267. package/dist/salones/manager.js.map +1 -0
  268. package/dist/security/rate-limiter.d.ts +13 -0
  269. package/dist/security/rate-limiter.d.ts.map +1 -0
  270. package/dist/security/rate-limiter.js +32 -0
  271. package/dist/security/rate-limiter.js.map +1 -0
  272. package/dist/snapshot/index.d.ts +90 -0
  273. package/dist/snapshot/index.d.ts.map +1 -0
  274. package/dist/snapshot/index.js +189 -0
  275. package/dist/snapshot/index.js.map +1 -0
  276. package/dist/storage/index.d.ts +49 -0
  277. package/dist/storage/index.d.ts.map +1 -0
  278. package/dist/storage/index.js +176 -0
  279. package/dist/storage/index.js.map +1 -0
  280. package/dist/storage/optimizer.d.ts +28 -0
  281. package/dist/storage/optimizer.d.ts.map +1 -0
  282. package/dist/storage/optimizer.js +50 -0
  283. package/dist/storage/optimizer.js.map +1 -0
  284. package/dist/storage/ydoc-persistence.d.ts +27 -0
  285. package/dist/storage/ydoc-persistence.d.ts.map +1 -0
  286. package/dist/storage/ydoc-persistence.js +128 -0
  287. package/dist/storage/ydoc-persistence.js.map +1 -0
  288. package/dist/sync/ChunkSyncManager.d.ts +41 -0
  289. package/dist/sync/ChunkSyncManager.d.ts.map +1 -0
  290. package/dist/sync/ChunkSyncManager.js +115 -0
  291. package/dist/sync/ChunkSyncManager.js.map +1 -0
  292. package/dist/sync/conflict-resolver.d.ts +33 -0
  293. package/dist/sync/conflict-resolver.d.ts.map +1 -0
  294. package/dist/sync/conflict-resolver.js +54 -0
  295. package/dist/sync/conflict-resolver.js.map +1 -0
  296. package/dist/sync/engine.d.ts +168 -0
  297. package/dist/sync/engine.d.ts.map +1 -0
  298. package/dist/sync/engine.js +315 -0
  299. package/dist/sync/engine.js.map +1 -0
  300. package/dist/sync/index.d.ts +3 -0
  301. package/dist/sync/index.d.ts.map +1 -0
  302. package/dist/sync/index.js +3 -0
  303. package/dist/sync/index.js.map +1 -0
  304. package/dist/transport/TorTransportAdapter.d.ts +70 -0
  305. package/dist/transport/TorTransportAdapter.d.ts.map +1 -0
  306. package/dist/transport/TorTransportAdapter.js +192 -0
  307. package/dist/transport/TorTransportAdapter.js.map +1 -0
  308. package/dist/transport/memory.d.ts +31 -0
  309. package/dist/transport/memory.d.ts.map +1 -0
  310. package/dist/transport/memory.js +114 -0
  311. package/dist/transport/memory.js.map +1 -0
  312. package/dist/transport/peerjs.d.ts +45 -0
  313. package/dist/transport/peerjs.d.ts.map +1 -0
  314. package/dist/transport/peerjs.js +301 -0
  315. package/dist/transport/peerjs.js.map +1 -0
  316. package/dist/transport/pqc-handshake.d.ts +72 -0
  317. package/dist/transport/pqc-handshake.d.ts.map +1 -0
  318. package/dist/transport/pqc-handshake.js +129 -0
  319. package/dist/transport/pqc-handshake.js.map +1 -0
  320. package/dist/transport/relay-config.d.ts +11 -0
  321. package/dist/transport/relay-config.d.ts.map +1 -0
  322. package/dist/transport/relay-config.js +48 -0
  323. package/dist/transport/relay-config.js.map +1 -0
  324. package/dist/transport/relay-server.d.ts +37 -0
  325. package/dist/transport/relay-server.d.ts.map +1 -0
  326. package/dist/transport/relay-server.js +230 -0
  327. package/dist/transport/relay-server.js.map +1 -0
  328. package/dist/transport/tor.d.ts +47 -0
  329. package/dist/transport/tor.d.ts.map +1 -0
  330. package/dist/transport/tor.js +158 -0
  331. package/dist/transport/tor.js.map +1 -0
  332. package/dist/transport/types.d.ts +34 -0
  333. package/dist/transport/types.d.ts.map +1 -0
  334. package/dist/transport/types.js +2 -0
  335. package/dist/transport/types.js.map +1 -0
  336. package/dist/types/index.d.ts +293 -0
  337. package/dist/types/index.d.ts.map +1 -0
  338. package/dist/types/index.js +73 -0
  339. package/dist/types/index.js.map +1 -0
  340. package/dist/web/admission.d.ts +24 -0
  341. package/dist/web/admission.d.ts.map +1 -0
  342. package/dist/web/admission.js +41 -0
  343. package/dist/web/admission.js.map +1 -0
  344. package/dist/web/crypto.d.ts +18 -0
  345. package/dist/web/crypto.d.ts.map +1 -0
  346. package/dist/web/crypto.js +78 -0
  347. package/dist/web/crypto.js.map +1 -0
  348. package/dist/web/exchange.d.ts +23 -0
  349. package/dist/web/exchange.d.ts.map +1 -0
  350. package/dist/web/exchange.js +54 -0
  351. package/dist/web/exchange.js.map +1 -0
  352. package/dist/web/fragment.d.ts +58 -0
  353. package/dist/web/fragment.d.ts.map +1 -0
  354. package/dist/web/fragment.js +198 -0
  355. package/dist/web/fragment.js.map +1 -0
  356. package/dist/web/index.d.ts +25 -0
  357. package/dist/web/index.d.ts.map +1 -0
  358. package/dist/web/index.js +14 -0
  359. package/dist/web/index.js.map +1 -0
  360. package/dist/web/merge/index.d.ts +104 -0
  361. package/dist/web/merge/index.d.ts.map +1 -0
  362. package/dist/web/merge/index.js +236 -0
  363. package/dist/web/merge/index.js.map +1 -0
  364. package/dist/web/oplog/hlc.d.ts +19 -0
  365. package/dist/web/oplog/hlc.d.ts.map +1 -0
  366. package/dist/web/oplog/hlc.js +39 -0
  367. package/dist/web/oplog/hlc.js.map +1 -0
  368. package/dist/web/oplog/index.d.ts +10 -0
  369. package/dist/web/oplog/index.d.ts.map +1 -0
  370. package/dist/web/oplog/index.js +6 -0
  371. package/dist/web/oplog/index.js.map +1 -0
  372. package/dist/web/oplog/log.d.ts +182 -0
  373. package/dist/web/oplog/log.d.ts.map +1 -0
  374. package/dist/web/oplog/log.js +693 -0
  375. package/dist/web/oplog/log.js.map +1 -0
  376. package/dist/web/oplog/store.d.ts +40 -0
  377. package/dist/web/oplog/store.d.ts.map +1 -0
  378. package/dist/web/oplog/store.js +85 -0
  379. package/dist/web/oplog/store.js.map +1 -0
  380. package/dist/web/oplog/sync.d.ts +54 -0
  381. package/dist/web/oplog/sync.d.ts.map +1 -0
  382. package/dist/web/oplog/sync.js +162 -0
  383. package/dist/web/oplog/sync.js.map +1 -0
  384. package/dist/web/oplog/types.d.ts +119 -0
  385. package/dist/web/oplog/types.d.ts.map +1 -0
  386. package/dist/web/oplog/types.js +2 -0
  387. package/dist/web/oplog/types.js.map +1 -0
  388. package/dist/web/pairing.d.ts +186 -0
  389. package/dist/web/pairing.d.ts.map +1 -0
  390. package/dist/web/pairing.js +395 -0
  391. package/dist/web/pairing.js.map +1 -0
  392. package/dist/web/pq.d.ts +36 -0
  393. package/dist/web/pq.d.ts.map +1 -0
  394. package/dist/web/pq.js +59 -0
  395. package/dist/web/pq.js.map +1 -0
  396. package/dist/web/provider.d.ts +188 -0
  397. package/dist/web/provider.d.ts.map +1 -0
  398. package/dist/web/provider.js +2042 -0
  399. package/dist/web/provider.js.map +1 -0
  400. package/dist/web/rooms.d.ts +20 -0
  401. package/dist/web/rooms.d.ts.map +1 -0
  402. package/dist/web/rooms.js +51 -0
  403. package/dist/web/rooms.js.map +1 -0
  404. package/dist/web/rotation.d.ts +73 -0
  405. package/dist/web/rotation.d.ts.map +1 -0
  406. package/dist/web/rotation.js +130 -0
  407. package/dist/web/rotation.js.map +1 -0
  408. package/dist/web/secstate.d.ts +213 -0
  409. package/dist/web/secstate.d.ts.map +1 -0
  410. package/dist/web/secstate.js +789 -0
  411. package/dist/web/secstate.js.map +1 -0
  412. package/dist/web/store.d.ts +9 -0
  413. package/dist/web/store.d.ts.map +1 -0
  414. package/dist/web/store.js +32 -0
  415. package/dist/web/store.js.map +1 -0
  416. package/dist/web/transports/loopback.d.ts +11 -0
  417. package/dist/web/transports/loopback.d.ts.map +1 -0
  418. package/dist/web/transports/loopback.js +97 -0
  419. package/dist/web/transports/loopback.js.map +1 -0
  420. package/dist/web/transports/qr-sdp.d.ts +27 -0
  421. package/dist/web/transports/qr-sdp.d.ts.map +1 -0
  422. package/dist/web/transports/qr-sdp.js +131 -0
  423. package/dist/web/transports/qr-sdp.js.map +1 -0
  424. package/dist/web/transports/ws.d.ts +12 -0
  425. package/dist/web/transports/ws.d.ts.map +1 -0
  426. package/dist/web/transports/ws.js +139 -0
  427. package/dist/web/transports/ws.js.map +1 -0
  428. package/dist/web/trust/canonical.d.ts +8 -0
  429. package/dist/web/trust/canonical.d.ts.map +1 -0
  430. package/dist/web/trust/canonical.js +27 -0
  431. package/dist/web/trust/canonical.js.map +1 -0
  432. package/dist/web/trust/docs.d.ts +51 -0
  433. package/dist/web/trust/docs.d.ts.map +1 -0
  434. package/dist/web/trust/docs.js +170 -0
  435. package/dist/web/trust/docs.js.map +1 -0
  436. package/dist/web/trust/index.d.ts +10 -0
  437. package/dist/web/trust/index.d.ts.map +1 -0
  438. package/dist/web/trust/index.js +7 -0
  439. package/dist/web/trust/index.js.map +1 -0
  440. package/dist/web/trust/keys.d.ts +37 -0
  441. package/dist/web/trust/keys.d.ts.map +1 -0
  442. package/dist/web/trust/keys.js +75 -0
  443. package/dist/web/trust/keys.js.map +1 -0
  444. package/dist/web/trust/store.d.ts +150 -0
  445. package/dist/web/trust/store.d.ts.map +1 -0
  446. package/dist/web/trust/store.js +587 -0
  447. package/dist/web/trust/store.js.map +1 -0
  448. package/dist/web/trust/types.d.ts +134 -0
  449. package/dist/web/trust/types.d.ts.map +1 -0
  450. package/dist/web/trust/types.js +4 -0
  451. package/dist/web/trust/types.js.map +1 -0
  452. package/dist/web/types.d.ts +115 -0
  453. package/dist/web/types.d.ts.map +1 -0
  454. package/dist/web/types.js +2 -0
  455. package/dist/web/types.js.map +1 -0
  456. package/dist/web/util.d.ts +12 -0
  457. package/dist/web/util.d.ts.map +1 -0
  458. package/dist/web/util.js +54 -0
  459. package/dist/web/util.js.map +1 -0
  460. package/dist/web/webrtc.d.ts +35 -0
  461. package/dist/web/webrtc.d.ts.map +1 -0
  462. package/dist/web/webrtc.js +304 -0
  463. package/dist/web/webrtc.js.map +1 -0
  464. package/package.json +138 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,315 @@
1
+ // ─── CONSTANTS ─────────────────────────────────────────────────────────────
2
+ /**
3
+ * Tope de operaciones que ponemos en el cable en un solo lote. Tambien se usa
4
+ * como tope de entrada por defecto (ver `maxBatchOperations`).
5
+ *
6
+ * Por que 500: un documento CRDT que se ha dividido de verdad en mas de unos
7
+ * pocos cientos de operaciones es un documento que hay que resyncar con un
8
+ * snapshot, no fusionar operacion a operacion. 500 operaciones de una nota
9
+ * clinica tipica (~600 bytes de payload mas una firma ML-DSA-65 de ~3.3 KB)
10
+ * caben de sobra en el presupuesto de un datagrama WebRTC, asi que un par
11
+ * conforme nunca necesita un frame mayor.
12
+ */
13
+ export const MAX_BATCH_SIZE = 500;
14
+ /**
15
+ * Tope duro del tamano serializado de un sobre recibido.
16
+ *
17
+ * Por que 256 KiB: una operacion CRDT es una edicion (un campo de un registro),
18
+ * no un documento entero. Incluso una patologica — una insercion de texto completo
19
+ * o una referencia a un adjunto en base64 — queda muy por debajo de 256 KiB,
20
+ * mientras que algo mayor es mucho mas probable que un intento de agotamiento de
21
+ * memoria que datos clinicos reales. Tambien mantiene acotado el coste transitorio
22
+ * de validar un sobre, sea cual sea lo que el par haya puesto en `datos`.
23
+ */
24
+ export const MAX_ENVELOPE_BYTES = 262_144;
25
+ const TIEMPO_ESPERA_SYNC_MS = 2_000;
26
+ export class SyncEngine {
27
+ eventTarget;
28
+ docId;
29
+ opLog;
30
+ batchSize;
31
+ timeoutMs;
32
+ _direction;
33
+ maxBatchOperations;
34
+ maxEnvelopeBytes;
35
+ sincronizando = false;
36
+ clockLocal = 0;
37
+ clocksRemotos;
38
+ constructor(config) {
39
+ this.eventTarget = new EventTarget();
40
+ this.docId = config.docId;
41
+ this.opLog = config.opLog;
42
+ this.batchSize = config.batchSize ?? MAX_BATCH_SIZE;
43
+ this.timeoutMs = config.timeoutMs ?? TIEMPO_ESPERA_SYNC_MS;
44
+ this._direction = config.direction ?? "bidireccional";
45
+ this.maxBatchOperations = config.maxBatchOperations ?? MAX_BATCH_SIZE;
46
+ this.maxEnvelopeBytes = config.maxEnvelopeBytes ?? MAX_ENVELOPE_BYTES;
47
+ this.clocksRemotos = new Map();
48
+ }
49
+ // ─── SYNC ────────────────────────────────────────────────────────────
50
+ async sincronizar(peerId, enviar, recibir) {
51
+ if (this.sincronizando) {
52
+ throw new Error("Sync en progreso para este documento");
53
+ }
54
+ this.sincronizando = true;
55
+ const inicio = Date.now();
56
+ // Declarado fuera del `try` para que la ruta de error pueda informarlo: si
57
+ // el motor falla DESPUES de rechazar un lote sobredimensionado, ese rechazo
58
+ // ya ocurrio y no debe desaparecer del informe.
59
+ let operacionesRechazadas = 0;
60
+ this.emit("syncIniciado", {
61
+ docId: this.docId,
62
+ peerId,
63
+ direction: this._direction,
64
+ });
65
+ try {
66
+ let operacionesEnviadas = 0;
67
+ let operacionesRecibidas = 0;
68
+ let conflictos = 0;
69
+ // Fase 1: Enviar nuestras operaciones
70
+ if (this._direction === "bidireccional" ||
71
+ this._direction === "saliente") {
72
+ const clockRemoto = this.clocksRemotos.get(peerId) ?? 0;
73
+ const pendientes = await this.opLog.obtenerDesde(clockRemoto);
74
+ const batches = [];
75
+ for (let i = 0; i < pendientes.length; i += this.batchSize) {
76
+ batches.push(pendientes.slice(i, i + this.batchSize));
77
+ }
78
+ for (const batch of batches) {
79
+ await enviar(batch);
80
+ operacionesEnviadas += batch.length;
81
+ }
82
+ }
83
+ // Fase 2: Recibir operaciones remotas
84
+ if (this._direction === "bidireccional" ||
85
+ this._direction === "entrante") {
86
+ const operacionesRemotas = await recibir();
87
+ // Limites de recurso. Corren ANTES de cualquier otra cosa para que
88
+ // el tope acote el trabajo que un par no autenticado puede
89
+ // obligarnos a hacer, no solo el log.
90
+ const { lote, rechazadas: rechazadasPorLimite } = this.aplicarLimitesDeRecurso(peerId, operacionesRemotas);
91
+ operacionesRechazadas += rechazadasPorLimite;
92
+ const validadas = lote.filter(esOperacionValida);
93
+ for (const opRaw of validadas) {
94
+ const op = opRaw;
95
+ const clockLocal = this.opLog.obtenerUltimaSecuencia();
96
+ if (op.secuencia <= clockLocal) {
97
+ conflictos++;
98
+ this.emit("conflictoDetectado", {
99
+ docId: this.docId,
100
+ operacionLocal: op,
101
+ operacionRemota: op,
102
+ });
103
+ }
104
+ }
105
+ const aplicadas = await this.opLog.aplicarOperaciones(validadas);
106
+ operacionesRecibidas += aplicadas;
107
+ // Actualizar clock del peer
108
+ if (validadas.length > 0) {
109
+ const ultimaOp = validadas[validadas.length - 1];
110
+ this.clocksRemotos.set(peerId, ultimaOp.secuencia);
111
+ }
112
+ }
113
+ const duracionMs = Date.now() - inicio;
114
+ this.sincronizando = false;
115
+ const resultado = {
116
+ docId: this.docId,
117
+ operacionesEnviadas,
118
+ operacionesRecibidas,
119
+ conflictos,
120
+ operacionesRechazadas,
121
+ duracionMs,
122
+ exito: true,
123
+ };
124
+ this.emit("syncCompletado", { resultado, peerId });
125
+ return resultado;
126
+ }
127
+ catch (error) {
128
+ this.sincronizando = false;
129
+ const mensaje = error instanceof Error ? error.message : "Error de sincronizacion";
130
+ this.emit("syncError", {
131
+ docId: this.docId,
132
+ peerId,
133
+ error: mensaje,
134
+ });
135
+ return {
136
+ docId: this.docId,
137
+ operacionesEnviadas: 0,
138
+ operacionesRecibidas: 0,
139
+ conflictos: 0,
140
+ operacionesRechazadas,
141
+ duracionMs: Date.now() - inicio,
142
+ exito: false,
143
+ };
144
+ }
145
+ }
146
+ // ─── LÍMITES DE RECURSO ──────────────────────────────────────────────
147
+ /**
148
+ * Acota la memoria que un solo par puede hacer que este nodo asigne
149
+ * aplicando dos topes duros a un lote entrante.
150
+ *
151
+ * 1. **Tope de cantidad.** Un lote con mas de `maxBatchOperations` entradas se
152
+ * rechaza ENTERO, no en trozos. Esta comprobacion va primero, sobre el solo
153
+ * `length`, asi que un lote sobredimensionado se rechaza en tiempo constante.
154
+ *
155
+ * Compromiso, enunciado explicitamente porque es la decision discutible:
156
+ * - *Por que rechazar entero en vez de por trozos*: el rechazo es atomico y
157
+ * auditable. El par recibe un unico evento `loteRechazado` claro en vez de
158
+ * una fusion parcial silenciosa, el operador ve un solo rechazo contable en
159
+ * `operacionesRechazadas`, y `aplicarOperaciones` nunca se invoca con un
160
+ * array sin limite. Tambien significa que un par hostil no puede lograr una
161
+ * escritura parcial confirmada antes de descubrir que el resto es basura:
162
+ * trocear un lote envenenado aplicaria las primeras N operaciones y luego
163
+ * pararia, dejando en el log operaciones que ya le dijimos al par que no
164
+ * podemos verificar. Como el lote entero se descarta, la pasada por sobre
165
+ * se omite por completo: serializar 500k sobres solo para tirarlos seria
166
+ * justamente la tormenta de asignaciones que este tope existe para
167
+ * impedir.
168
+ * - *Que perdemos*: un par legitamente atrasado, con 800 operaciones
169
+ * pendientes, no obtiene nada esta ronda en vez de 500 de ellas. Eso es
170
+ * recuperable y correcto en el cable — `recibir()` es el closure de
171
+ * transporte del propio llamador, asi que un llamador conforme vuelve a
172
+ * ofrecer el resto desde el clock anunciado por el par, tal como ya debe
173
+ * hacer con los lotes salientes que troceamos en `batchSize`. No se pierde
174
+ * ninguna operacion; la puesta al dia simplemente tarda otra ronda. La
175
+ * siguiente ronda vuelve a estar acotada por el mismo tope, que es el punto.
176
+ *
177
+ * 2. **Tope de bytes por sobre.** Un sobre cuya forma serializada exceda
178
+ * `maxEnvelopeBytes` se descarta. NUNCA se trunca: un sobre truncado se
179
+ * parsea como una operacion parcial, lo que avanzaria la secuencia con un
180
+ * delta parcial y dejaria el log CRDT inconsistente. Rechazar es la unica
181
+ * opcion que mantiene el log entero.
182
+ *
183
+ * Los rechazos se cuentan en `SyncResult.operacionesRechazadas` para que un
184
+ * operador vea la basura junto a los rechazos de confianza.
185
+ */
186
+ aplicarLimitesDeRecurso(peerId, operaciones) {
187
+ // Tope 1 — cantidad de operaciones por lote. Se comprueba PRIMERO, sobre el
188
+ // solo `length`, asi que un lote sobredimensionado cuesta O(1) en vez de O(n)
189
+ // serializaciones. Medir 500k sobres que vamos a tirar es exactamente el
190
+ // trabajo que este tope existe para impedir, y emitiria ademas 500k eventos
191
+ // de rechazo. Nada sobrevive a un rechazo de lote entero, asi que el conteo
192
+ // informado es la longitud entrante en cualquier caso.
193
+ if (operaciones.length > this.maxBatchOperations) {
194
+ this.emit("loteRechazado", {
195
+ docId: this.docId,
196
+ peerId,
197
+ lotesOperaciones: operaciones.length,
198
+ maximoPermitido: this.maxBatchOperations,
199
+ });
200
+ return { lote: [], rechazadas: operaciones.length };
201
+ }
202
+ // Tope 2 — tamano serializado por sobre.
203
+ const lote = [];
204
+ let rechazadas = 0;
205
+ for (const op of operaciones) {
206
+ const bytes = tamanoSerializado(op);
207
+ if (bytes > this.maxEnvelopeBytes) {
208
+ rechazadas++;
209
+ this.emit("sobreRechazadoPorTamano", {
210
+ docId: this.docId,
211
+ peerId,
212
+ secuencia: leerSecuencia(op),
213
+ bytes,
214
+ maximoPermitido: this.maxEnvelopeBytes,
215
+ });
216
+ continue;
217
+ }
218
+ lote.push(op);
219
+ }
220
+ return { lote, rechazadas };
221
+ }
222
+ // ─── CLOCK ───────────────────────────────────────────────────────────
223
+ actualizarClockLocal(clock) {
224
+ this.clockLocal = Math.max(this.clockLocal, clock);
225
+ }
226
+ actualizarClockRemoto(peerId, clock) {
227
+ this.clocksRemotos.set(peerId, clock);
228
+ }
229
+ obtenerClockLocal() {
230
+ return this.clockLocal;
231
+ }
232
+ obtenerClockRemoto(peerId) {
233
+ return this.clocksRemotos.get(peerId) ?? 0;
234
+ }
235
+ // ─── ESTADO ──────────────────────────────────────────────────────────
236
+ estaSincronizando() {
237
+ return this.sincronizando;
238
+ }
239
+ // ─── EVENTOS ─────────────────────────────────────────────────────────
240
+ on(tipo, handler) {
241
+ this.eventTarget.addEventListener(tipo, handler);
242
+ }
243
+ off(tipo, handler) {
244
+ this.eventTarget.removeEventListener(tipo, handler);
245
+ }
246
+ emit(tipo, detalle) {
247
+ const evento = new CustomEvent(tipo, { detail: detalle });
248
+ this.eventTarget.dispatchEvent(evento);
249
+ }
250
+ }
251
+ // ─── TYPE GUARD ────────────────────────────────────────────────────────────
252
+ function esOperacionValida(valor) {
253
+ if (typeof valor !== "object" || valor === null)
254
+ return false;
255
+ const op = valor;
256
+ return (typeof op.id === "string" &&
257
+ typeof op.tipo === "string" &&
258
+ typeof op.secuencia === "number" &&
259
+ typeof op.timestamp === "number" &&
260
+ typeof op.autor === "string");
261
+ }
262
+ // ─── MEDICIÓN DE TAMAÑO ─────────────────────────────────────────────
263
+ /**
264
+ * Tamano en bytes serializados de un sobre entrante, usado por el tope por
265
+ * sobre.
266
+ *
267
+ * Un par hostil controla el payload, asi que esto nunca debe lanzar:
268
+ * `JSON.stringify` lanza sobre estructuras ciclicas y devuelve `undefined` en
269
+ * silencio para valores que no puede codificar (BigInt tambien lanza). Ambos
270
+ * casos significan "no es un sobre bien formado del que podemos hablar", asi que
271
+ * reportamos `Infinity` y dejamos que el llamador lo rechace. Un payload no
272
+ * serializable es exactamente el payload que no queremos meter en el CRDT.
273
+ */
274
+ function tamanoSerializado(valor) {
275
+ try {
276
+ const json = JSON.stringify(valor);
277
+ if (typeof json !== "string")
278
+ return Number.POSITIVE_INFINITY;
279
+ return byteLengthUtf8(json);
280
+ }
281
+ catch {
282
+ return Number.POSITIVE_INFINITY;
283
+ }
284
+ }
285
+ /**
286
+ * Longitud en bytes UTF-8 sin asignar un Buffer por cada sobre: dos bytes por
287
+ * unidad de codigo es el coste exacto para ASCII y Latin-1, y para cualquier cosa
288
+ * por encima de U+07FF solo sobrecuenta si hay caracteres astrales. Sobrecontar es
289
+ * la direccion segura para un limite de tamano, y el tope de 256 KiB deja varios
290
+ * ordenes de magnitud de margen para sobres reales, asi que la aproximacion nunca
291
+ * rechaza uno legitimo.
292
+ */
293
+ function byteLengthUtf8(json) {
294
+ let bytes = 0;
295
+ for (let i = 0; i < json.length; i++) {
296
+ const code = json.charCodeAt(i);
297
+ if (code < 0x80)
298
+ bytes += 1;
299
+ else if (code < 0x800)
300
+ bytes += 2;
301
+ else if (code >= 0xd800 && code <= 0xdbff)
302
+ bytes += 4; // par suplente
303
+ else
304
+ bytes += 3;
305
+ }
306
+ return bytes;
307
+ }
308
+ /** Lee `secuencia` solo para telemetria de rechazo; nunca para decisiones de confianza. */
309
+ function leerSecuencia(valor) {
310
+ if (typeof valor !== "object" || valor === null)
311
+ return 0;
312
+ const secuencia = valor.secuencia;
313
+ return typeof secuencia === "number" ? secuencia : 0;
314
+ }
315
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./ChunkSyncManager.js";
2
+ export * from "./engine.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./ChunkSyncManager.js";
2
+ export * from "./engine.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,70 @@
1
+ import type { NodoId, TipoTransporte } from "../types/index.js";
2
+ import type { ITransport, TransportEventMap } from "./types.js";
3
+ export interface TorTransportAdapterOptions {
4
+ /** SOCKS/HTTP Tor proxy URL (e.g., "socks5://127.0.0.1:9050") */
5
+ readonly proxyUrl?: string;
6
+ /** Tor Onion hidden service address for this node (e.g., "abcdef1234567890.onion") */
7
+ readonly onionAddress?: string;
8
+ /** SOCKS proxy port (default: 9050) */
9
+ readonly socksPort?: number;
10
+ /** Control port for Tor process management (default: 9051) */
11
+ readonly controlPort?: number;
12
+ /** Fallback transport if direct Tor proxy tunnel fails */
13
+ readonly fallbackTransport?: ITransport;
14
+ /** Custom tunnel handler function for proxying data over SOCKS/Tor socket */
15
+ readonly tunnelHandler?: (data: unknown, targetOnion?: string) => Promise<unknown>;
16
+ /** Automatically connect proxy tunnel upon creation (default: false) */
17
+ readonly autoConnect?: boolean;
18
+ }
19
+ /**
20
+ * TorTransportAdapter provides hidden service proxy tunnel fallback for NAT traversal
21
+ * when direct WebRTC or TCP connections fail behind severe CGNAT.
22
+ */
23
+ export declare class TorTransportAdapter implements ITransport {
24
+ readonly tipo: TipoTransporte;
25
+ readonly eventTarget: EventTarget;
26
+ readonly nodoId: NodoId;
27
+ private readonly options;
28
+ private readonly deduplicator;
29
+ private readonly onionPeerMap;
30
+ private readonly activeConnections;
31
+ private onionAddress;
32
+ private conectado;
33
+ private tunnelActive;
34
+ constructor(nodoId: NodoId, options?: TorTransportAdapterOptions);
35
+ on<K extends keyof TransportEventMap>(tipo: K, handler: (ev: TransportEventMap[K]) => void): void;
36
+ off<K extends keyof TransportEventMap>(tipo: K, handler: (ev: TransportEventMap[K]) => void): void;
37
+ private emit;
38
+ /**
39
+ * Establish Tor onion hidden service proxy tunnel.
40
+ */
41
+ conectar(): Promise<void>;
42
+ /**
43
+ * Register remote peer's onion hidden service address for proxy routing.
44
+ */
45
+ registerOnionPeer(peerId: string, onionAddress: string): void;
46
+ /**
47
+ * Get node's local onion hidden service address.
48
+ */
49
+ getOnionAddress(): string;
50
+ /**
51
+ * Returns true if the proxy tunnel is established and active.
52
+ */
53
+ isTunnelActive(): boolean;
54
+ /**
55
+ * Send envelope or payload to a remote node via Tor hidden service proxy tunnel.
56
+ */
57
+ enviar(destino: NodoId, payload: unknown, tipoMensaje?: string): Promise<void>;
58
+ /**
59
+ * Broadcast envelope or payload across all connected onion hidden service peers.
60
+ */
61
+ transmitir(payload: unknown, tipoMensaje?: string): Promise<void>;
62
+ /**
63
+ * Helper method to process incoming proxy tunnel payloads into the adapter.
64
+ */
65
+ receivePayload(datos: unknown, from?: NodoId): void;
66
+ estaConectado(): boolean;
67
+ obtenerConexiones(): readonly string[];
68
+ cerrar(): Promise<void>;
69
+ }
70
+ //# sourceMappingURL=TorTransportAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TorTransportAdapter.d.ts","sourceRoot":"","sources":["../../src/transport/TorTransportAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEX,MAAM,EAEN,cAAc,EACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,0BAA0B;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,CACxB,IAAI,EAAE,OAAO,EACb,WAAW,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,UAAU;IACrD,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAuB;IACpD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAc;IAChD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAAkB;IAEtC,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,EAiBnE;IAED,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EACnC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GACzC,IAAI,CAEN;IAED,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EACpC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GACzC,IAAI,CAKN;IAED,OAAO,CAAC,IAAI;IASZ;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA2B9B;IAED;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAG5D;IAED;;OAEG;IACH,eAAe,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,cAAc,IAAI,OAAO,CAExB;IAED;;OAEG;IACG,MAAM,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,WAAW,GAAE,MAA0B,GACrC,OAAO,CAAC,IAAI,CAAC,CAiCf;IAED;;OAEG;IACG,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,WAAW,GAAE,MAA0B,GACrC,OAAO,CAAC,IAAI,CAAC,CAiBf;IAED;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAWlD;IAED,aAAa,IAAI,OAAO,CAEvB;IAED,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAErC;IAEK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAe5B;CACD"}
@@ -0,0 +1,192 @@
1
+ import { createEnvelope, MessageDeduplicator } from "../protocol/index.js";
2
+ import { TIPO_MENSAJE, TIPO_TRANSPORTE } from "../types/index.js";
3
+ /**
4
+ * TorTransportAdapter provides hidden service proxy tunnel fallback for NAT traversal
5
+ * when direct WebRTC or TCP connections fail behind severe CGNAT.
6
+ */
7
+ export class TorTransportAdapter {
8
+ tipo = TIPO_TRANSPORTE.TOR;
9
+ eventTarget;
10
+ nodoId;
11
+ options;
12
+ deduplicator;
13
+ onionPeerMap; // peerId -> onionAddress
14
+ activeConnections; // set of remote peerIds/onionAddresses
15
+ onionAddress;
16
+ conectado = false;
17
+ tunnelActive = false;
18
+ constructor(nodoId, options = {}) {
19
+ this.nodoId = nodoId;
20
+ this.eventTarget = new EventTarget();
21
+ this.deduplicator = new MessageDeduplicator();
22
+ this.options = options;
23
+ this.onionPeerMap = new Map();
24
+ this.activeConnections = new Set();
25
+ this.onionAddress =
26
+ options.onionAddress ??
27
+ `${nodoId
28
+ .toLowerCase()
29
+ .replace(/[^a-z0-9]/g, "")
30
+ .slice(0, 16)}.onion`;
31
+ if (options.autoConnect) {
32
+ void this.conectar();
33
+ }
34
+ }
35
+ on(tipo, handler) {
36
+ this.eventTarget.addEventListener(tipo, handler);
37
+ }
38
+ off(tipo, handler) {
39
+ this.eventTarget.removeEventListener(tipo, handler);
40
+ }
41
+ emit(tipo, detalle) {
42
+ this.eventTarget.dispatchEvent(new CustomEvent(tipo, { detail: detalle }));
43
+ }
44
+ /**
45
+ * Establish Tor onion hidden service proxy tunnel.
46
+ */
47
+ async conectar() {
48
+ if (this.conectado)
49
+ return;
50
+ this.conectado = true;
51
+ this.tunnelActive = true;
52
+ this.emit("conectado", { nodoId: this.nodoId });
53
+ // Forward underlying fallback transport events if provided
54
+ if (this.options.fallbackTransport) {
55
+ if (!this.options.fallbackTransport.estaConectado()) {
56
+ try {
57
+ if ("conectar" in this.options.fallbackTransport &&
58
+ typeof this.options.fallbackTransport.conectar ===
59
+ "function") {
60
+ await this.options.fallbackTransport.conectar();
61
+ }
62
+ }
63
+ catch (err) {
64
+ this.emit("error", {
65
+ mensaje: `Fallback transport connection error: ${err?.message ?? err}`,
66
+ error: err,
67
+ });
68
+ }
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Register remote peer's onion hidden service address for proxy routing.
74
+ */
75
+ registerOnionPeer(peerId, onionAddress) {
76
+ this.onionPeerMap.set(peerId, onionAddress);
77
+ this.activeConnections.add(peerId);
78
+ }
79
+ /**
80
+ * Get node's local onion hidden service address.
81
+ */
82
+ getOnionAddress() {
83
+ return this.onionAddress;
84
+ }
85
+ /**
86
+ * Returns true if the proxy tunnel is established and active.
87
+ */
88
+ isTunnelActive() {
89
+ return this.conectado && this.tunnelActive;
90
+ }
91
+ /**
92
+ * Send envelope or payload to a remote node via Tor hidden service proxy tunnel.
93
+ */
94
+ async enviar(destino, payload, tipoMensaje = TIPO_MENSAJE.SYNC) {
95
+ if (!this.conectado) {
96
+ throw new Error("TorTransportAdapter no conectado");
97
+ }
98
+ const env = esEnvolvente(payload)
99
+ ? payload
100
+ : createEnvelope(tipoMensaje, this.nodoId, destino, payload);
101
+ const targetOnion = this.onionPeerMap.get(destino);
102
+ try {
103
+ if (this.options.tunnelHandler) {
104
+ await this.options.tunnelHandler(env, targetOnion);
105
+ }
106
+ else if (this.options.fallbackTransport) {
107
+ await this.options.fallbackTransport.enviar(destino, env, tipoMensaje);
108
+ }
109
+ else {
110
+ // Simulated hidden service proxy tunnel transmission
111
+ this.activeConnections.add(destino);
112
+ }
113
+ }
114
+ catch (err) {
115
+ const error = err instanceof Error ? err : new Error(String(err));
116
+ this.emit("error", {
117
+ mensaje: `Tor proxy tunnel error sending to ${destino}: ${error.message}`,
118
+ error,
119
+ });
120
+ throw error;
121
+ }
122
+ }
123
+ /**
124
+ * Broadcast envelope or payload across all connected onion hidden service peers.
125
+ */
126
+ async transmitir(payload, tipoMensaje = TIPO_MENSAJE.SYNC) {
127
+ if (!this.conectado)
128
+ return;
129
+ const env = esEnvolvente(payload)
130
+ ? payload
131
+ : createEnvelope(tipoMensaje, this.nodoId, "*", payload);
132
+ const peers = this.obtenerConexiones();
133
+ const promises = peers.map(async (peer) => {
134
+ try {
135
+ await this.enviar(peer, env, tipoMensaje);
136
+ }
137
+ catch {
138
+ // Ignore individual peer errors during broadcast
139
+ }
140
+ });
141
+ await Promise.all(promises);
142
+ }
143
+ /**
144
+ * Helper method to process incoming proxy tunnel payloads into the adapter.
145
+ */
146
+ receivePayload(datos, from) {
147
+ if (!esEnvolvente(datos))
148
+ return;
149
+ if (this.deduplicator.esDuplicado(datos))
150
+ return;
151
+ if (from) {
152
+ this.activeConnections.add(from);
153
+ }
154
+ else if (datos.origen) {
155
+ this.activeConnections.add(datos.origen);
156
+ }
157
+ this.emit("mensaje", { envolvente: datos, from });
158
+ }
159
+ estaConectado() {
160
+ return this.conectado;
161
+ }
162
+ obtenerConexiones() {
163
+ return Array.from(this.activeConnections.keys());
164
+ }
165
+ async cerrar() {
166
+ this.conectado = false;
167
+ this.tunnelActive = false;
168
+ this.activeConnections.clear();
169
+ this.deduplicator.reiniciar();
170
+ if (this.options.fallbackTransport) {
171
+ try {
172
+ await this.options.fallbackTransport.cerrar();
173
+ }
174
+ catch {
175
+ // Ignore errors on closing fallback transport
176
+ }
177
+ }
178
+ this.emit("desconectado", { nodoId: this.nodoId });
179
+ }
180
+ }
181
+ function esEnvolvente(valor) {
182
+ if (typeof valor !== "object" || valor === null)
183
+ return false;
184
+ const candidate = valor;
185
+ return (typeof candidate.id === "string" &&
186
+ typeof candidate.tipo === "string" &&
187
+ typeof candidate.origen === "string" &&
188
+ typeof candidate.destino === "string" &&
189
+ typeof candidate.timestamp === "number" &&
190
+ candidate.payload !== undefined);
191
+ }
192
+ //# sourceMappingURL=TorTransportAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TorTransportAdapter.js","sourceRoot":"","sources":["../../src/transport/TorTransportAdapter.ts"],"names":[],"mappings":"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"}