@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.
- package/LICENSE +128 -0
- package/NOTICE +37 -0
- package/README.md +470 -2
- package/dist/adapters/gpu-agent/index.d.ts +61 -0
- package/dist/adapters/gpu-agent/index.d.ts.map +1 -0
- package/dist/adapters/gpu-agent/index.js +364 -0
- package/dist/adapters/gpu-agent/index.js.map +1 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.d.ts +19 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.js +51 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.js.map +1 -0
- package/dist/adapters/maloca-salud/eps-bridge.d.ts +15 -0
- package/dist/adapters/maloca-salud/eps-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/eps-bridge.js +27 -0
- package/dist/adapters/maloca-salud/eps-bridge.js.map +1 -0
- package/dist/adapters/maloca-salud/patient-profile.d.ts +20 -0
- package/dist/adapters/maloca-salud/patient-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/patient-profile.js +36 -0
- package/dist/adapters/maloca-salud/patient-profile.js.map +1 -0
- package/dist/adapters/maloca-salud/types.d.ts +40 -0
- package/dist/adapters/maloca-salud/types.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/types.js +2 -0
- package/dist/adapters/maloca-salud/types.js.map +1 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.d.ts +31 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.js +103 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.js.map +1 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts +14 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.js +40 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.js.map +1 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.d.ts +21 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.js +58 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.js.map +1 -0
- package/dist/adapters/maloca-veeduria/types.d.ts +30 -0
- package/dist/adapters/maloca-veeduria/types.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/types.js +2 -0
- package/dist/adapters/maloca-veeduria/types.js.map +1 -0
- package/dist/adapters/maloca-xavier/agent-profile.d.ts +32 -0
- package/dist/adapters/maloca-xavier/agent-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/agent-profile.js +56 -0
- package/dist/adapters/maloca-xavier/agent-profile.js.map +1 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts +27 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.js +58 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.js.map +1 -0
- package/dist/adapters/maloca-xavier/llm-router.d.ts +25 -0
- package/dist/adapters/maloca-xavier/llm-router.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/llm-router.js +58 -0
- package/dist/adapters/maloca-xavier/llm-router.js.map +1 -0
- package/dist/authz/index.d.ts +81 -0
- package/dist/authz/index.d.ts.map +1 -0
- package/dist/authz/index.js +271 -0
- package/dist/authz/index.js.map +1 -0
- package/dist/chat/index.d.ts +138 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +394 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/offline-queue.d.ts +32 -0
- package/dist/chat/offline-queue.d.ts.map +1 -0
- package/dist/chat/offline-queue.js +93 -0
- package/dist/chat/offline-queue.js.map +1 -0
- package/dist/core/DefaultEdgeMeshNode.d.ts +17 -0
- package/dist/core/DefaultEdgeMeshNode.d.ts.map +1 -0
- package/dist/core/DefaultEdgeMeshNode.js +57 -0
- package/dist/core/DefaultEdgeMeshNode.js.map +1 -0
- package/dist/core/node.d.ts +26 -0
- package/dist/core/node.d.ts.map +1 -0
- package/dist/core/node.js +16 -0
- package/dist/core/node.js.map +1 -0
- package/dist/edge-mesh.d.ts +139 -0
- package/dist/edge-mesh.d.ts.map +1 -0
- package/dist/edge-mesh.js +1146 -0
- package/dist/edge-mesh.js.map +1 -0
- package/dist/gos/GosBridge.d.ts +49 -0
- package/dist/gos/GosBridge.d.ts.map +1 -0
- package/dist/gos/GosBridge.js +133 -0
- package/dist/gos/GosBridge.js.map +1 -0
- package/dist/governance/authority.d.ts +44 -0
- package/dist/governance/authority.d.ts.map +1 -0
- package/dist/governance/authority.js +123 -0
- package/dist/governance/authority.js.map +1 -0
- package/dist/governance/index.d.ts +66 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +210 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/merge.d.ts +31 -0
- package/dist/governance/merge.d.ts.map +1 -0
- package/dist/governance/merge.js +167 -0
- package/dist/governance/merge.js.map +1 -0
- package/dist/identity/index.d.ts +199 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +415 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/maloca/backoffice.d.ts +31 -0
- package/dist/maloca/backoffice.d.ts.map +1 -0
- package/dist/maloca/backoffice.js +40 -0
- package/dist/maloca/backoffice.js.map +1 -0
- package/dist/maloca/event-bus.d.ts +60 -0
- package/dist/maloca/event-bus.d.ts.map +1 -0
- package/dist/maloca/event-bus.js +175 -0
- package/dist/maloca/event-bus.js.map +1 -0
- package/dist/maloca/evidentia.d.ts +136 -0
- package/dist/maloca/evidentia.d.ts.map +1 -0
- package/dist/maloca/evidentia.js +447 -0
- package/dist/maloca/evidentia.js.map +1 -0
- package/dist/maloca/gateway/api.d.ts +146 -0
- package/dist/maloca/gateway/api.d.ts.map +1 -0
- package/dist/maloca/gateway/api.js +228 -0
- package/dist/maloca/gateway/api.js.map +1 -0
- package/dist/maloca/gateway/auth.d.ts +20 -0
- package/dist/maloca/gateway/auth.d.ts.map +1 -0
- package/dist/maloca/gateway/auth.js +115 -0
- package/dist/maloca/gateway/auth.js.map +1 -0
- package/dist/maloca/gateway/dashboard.d.ts +42 -0
- package/dist/maloca/gateway/dashboard.d.ts.map +1 -0
- package/dist/maloca/gateway/dashboard.js +67 -0
- package/dist/maloca/gateway/dashboard.js.map +1 -0
- package/dist/maloca/gateway/websocket.d.ts +34 -0
- package/dist/maloca/gateway/websocket.d.ts.map +1 -0
- package/dist/maloca/gateway/websocket.js +71 -0
- package/dist/maloca/gateway/websocket.js.map +1 -0
- package/dist/maloca/karma.d.ts +165 -0
- package/dist/maloca/karma.d.ts.map +1 -0
- package/dist/maloca/karma.js +307 -0
- package/dist/maloca/karma.js.map +1 -0
- package/dist/maloca/kernel.d.ts +20 -0
- package/dist/maloca/kernel.d.ts.map +1 -0
- package/dist/maloca/kernel.js +76 -0
- package/dist/maloca/kernel.js.map +1 -0
- package/dist/maloca/metadata.d.ts +30 -0
- package/dist/maloca/metadata.d.ts.map +1 -0
- package/dist/maloca/metadata.js +80 -0
- package/dist/maloca/metadata.js.map +1 -0
- package/dist/maloca/perfil.d.ts +57 -0
- package/dist/maloca/perfil.d.ts.map +1 -0
- package/dist/maloca/perfil.js +113 -0
- package/dist/maloca/perfil.js.map +1 -0
- package/dist/maloca/plugin-registry.d.ts +27 -0
- package/dist/maloca/plugin-registry.d.ts.map +1 -0
- package/dist/maloca/plugin-registry.js +76 -0
- package/dist/maloca/plugin-registry.js.map +1 -0
- package/dist/maloca/polygon-bridge.d.ts +63 -0
- package/dist/maloca/polygon-bridge.d.ts.map +1 -0
- package/dist/maloca/polygon-bridge.js +198 -0
- package/dist/maloca/polygon-bridge.js.map +1 -0
- package/dist/maloca/types.d.ts +44 -0
- package/dist/maloca/types.d.ts.map +1 -0
- package/dist/maloca/types.js +2 -0
- package/dist/maloca/types.js.map +1 -0
- package/dist/medico/aval.d.ts +149 -0
- package/dist/medico/aval.d.ts.map +1 -0
- package/dist/medico/aval.js +281 -0
- package/dist/medico/aval.js.map +1 -0
- package/dist/medico/canonica.d.ts +96 -0
- package/dist/medico/canonica.d.ts.map +1 -0
- package/dist/medico/canonica.js +148 -0
- package/dist/medico/canonica.js.map +1 -0
- package/dist/medico/credencial.d.ts +160 -0
- package/dist/medico/credencial.d.ts.map +1 -0
- package/dist/medico/credencial.js +240 -0
- package/dist/medico/credencial.js.map +1 -0
- package/dist/medico/index.d.ts +36 -0
- package/dist/medico/index.d.ts.map +1 -0
- package/dist/medico/index.js +39 -0
- package/dist/medico/index.js.map +1 -0
- package/dist/medico/malla.d.ts +218 -0
- package/dist/medico/malla.d.ts.map +1 -0
- package/dist/medico/malla.js +347 -0
- package/dist/medico/malla.js.map +1 -0
- package/dist/medico/registro-profesional.d.ts +84 -0
- package/dist/medico/registro-profesional.d.ts.map +1 -0
- package/dist/medico/registro-profesional.js +135 -0
- package/dist/medico/registro-profesional.js.map +1 -0
- package/dist/medico/registro.d.ts +149 -0
- package/dist/medico/registro.d.ts.map +1 -0
- package/dist/medico/registro.js +173 -0
- package/dist/medico/registro.js.map +1 -0
- package/dist/medico/types.d.ts +287 -0
- package/dist/medico/types.d.ts.map +1 -0
- package/dist/medico/types.js +135 -0
- package/dist/medico/types.js.map +1 -0
- package/dist/medico/verificacion-registro.d.ts +300 -0
- package/dist/medico/verificacion-registro.d.ts.map +1 -0
- package/dist/medico/verificacion-registro.js +319 -0
- package/dist/medico/verificacion-registro.js.map +1 -0
- package/dist/mesh/index.d.ts +457 -0
- package/dist/mesh/index.d.ts.map +1 -0
- package/dist/mesh/index.js +929 -0
- package/dist/mesh/index.js.map +1 -0
- package/dist/namespaces/encrypted-plugin.d.ts +56 -0
- package/dist/namespaces/encrypted-plugin.d.ts.map +1 -0
- package/dist/namespaces/encrypted-plugin.js +173 -0
- package/dist/namespaces/encrypted-plugin.js.map +1 -0
- package/dist/namespaces/index.d.ts +52 -0
- package/dist/namespaces/index.d.ts.map +1 -0
- package/dist/namespaces/index.js +134 -0
- package/dist/namespaces/index.js.map +1 -0
- package/dist/namespaces/ivn-proofs.d.ts +54 -0
- package/dist/namespaces/ivn-proofs.d.ts.map +1 -0
- package/dist/namespaces/ivn-proofs.js +162 -0
- package/dist/namespaces/ivn-proofs.js.map +1 -0
- package/dist/namespaces/offers-gossip.d.ts +95 -0
- package/dist/namespaces/offers-gossip.d.ts.map +1 -0
- package/dist/namespaces/offers-gossip.js +213 -0
- package/dist/namespaces/offers-gossip.js.map +1 -0
- package/dist/node-memory/idb-store.d.ts +22 -0
- package/dist/node-memory/idb-store.d.ts.map +1 -0
- package/dist/node-memory/idb-store.js +154 -0
- package/dist/node-memory/idb-store.js.map +1 -0
- package/dist/node-memory/index.d.ts +14 -0
- package/dist/node-memory/index.d.ts.map +1 -0
- package/dist/node-memory/index.js +159 -0
- package/dist/node-memory/index.js.map +1 -0
- package/dist/node-memory/sync-flush.d.ts +11 -0
- package/dist/node-memory/sync-flush.d.ts.map +1 -0
- package/dist/node-memory/sync-flush.js +37 -0
- package/dist/node-memory/sync-flush.js.map +1 -0
- package/dist/node-memory/types.d.ts +34 -0
- package/dist/node-memory/types.d.ts.map +1 -0
- package/dist/node-memory/types.js +2 -0
- package/dist/node-memory/types.js.map +1 -0
- package/dist/node-memory/xavier-store.d.ts +12 -0
- package/dist/node-memory/xavier-store.d.ts.map +1 -0
- package/dist/node-memory/xavier-store.js +75 -0
- package/dist/node-memory/xavier-store.js.map +1 -0
- package/dist/op-log/index.d.ts +49 -0
- package/dist/op-log/index.d.ts.map +1 -0
- package/dist/op-log/index.js +190 -0
- package/dist/op-log/index.js.map +1 -0
- package/dist/presence/health.d.ts +54 -0
- package/dist/presence/health.d.ts.map +1 -0
- package/dist/presence/health.js +139 -0
- package/dist/presence/health.js.map +1 -0
- package/dist/presence/index.d.ts +85 -0
- package/dist/presence/index.d.ts.map +1 -0
- package/dist/presence/index.js +255 -0
- package/dist/presence/index.js.map +1 -0
- package/dist/presence/peer-health.d.ts +40 -0
- package/dist/presence/peer-health.d.ts.map +1 -0
- package/dist/presence/peer-health.js +118 -0
- package/dist/presence/peer-health.js.map +1 -0
- package/dist/protocol/canonical.d.ts +10 -0
- package/dist/protocol/canonical.d.ts.map +1 -0
- package/dist/protocol/canonical.js +32 -0
- package/dist/protocol/canonical.js.map +1 -0
- package/dist/protocol/crypto.d.ts +299 -0
- package/dist/protocol/crypto.d.ts.map +1 -0
- package/dist/protocol/crypto.js +739 -0
- package/dist/protocol/crypto.js.map +1 -0
- package/dist/protocol/index.d.ts +30 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +116 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/utils.d.ts +5 -0
- package/dist/protocol/utils.d.ts.map +1 -0
- package/dist/protocol/utils.js +27 -0
- package/dist/protocol/utils.js.map +1 -0
- package/dist/salones/manager.d.ts +100 -0
- package/dist/salones/manager.d.ts.map +1 -0
- package/dist/salones/manager.js +240 -0
- package/dist/salones/manager.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +13 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +32 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/snapshot/index.d.ts +90 -0
- package/dist/snapshot/index.d.ts.map +1 -0
- package/dist/snapshot/index.js +189 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/storage/index.d.ts +49 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +176 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/optimizer.d.ts +28 -0
- package/dist/storage/optimizer.d.ts.map +1 -0
- package/dist/storage/optimizer.js +50 -0
- package/dist/storage/optimizer.js.map +1 -0
- package/dist/storage/ydoc-persistence.d.ts +27 -0
- package/dist/storage/ydoc-persistence.d.ts.map +1 -0
- package/dist/storage/ydoc-persistence.js +128 -0
- package/dist/storage/ydoc-persistence.js.map +1 -0
- package/dist/sync/ChunkSyncManager.d.ts +41 -0
- package/dist/sync/ChunkSyncManager.d.ts.map +1 -0
- package/dist/sync/ChunkSyncManager.js +115 -0
- package/dist/sync/ChunkSyncManager.js.map +1 -0
- package/dist/sync/conflict-resolver.d.ts +33 -0
- package/dist/sync/conflict-resolver.d.ts.map +1 -0
- package/dist/sync/conflict-resolver.js +54 -0
- package/dist/sync/conflict-resolver.js.map +1 -0
- package/dist/sync/engine.d.ts +168 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +315 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/index.d.ts +3 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +3 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/transport/TorTransportAdapter.d.ts +70 -0
- package/dist/transport/TorTransportAdapter.d.ts.map +1 -0
- package/dist/transport/TorTransportAdapter.js +192 -0
- package/dist/transport/TorTransportAdapter.js.map +1 -0
- package/dist/transport/memory.d.ts +31 -0
- package/dist/transport/memory.d.ts.map +1 -0
- package/dist/transport/memory.js +114 -0
- package/dist/transport/memory.js.map +1 -0
- package/dist/transport/peerjs.d.ts +45 -0
- package/dist/transport/peerjs.d.ts.map +1 -0
- package/dist/transport/peerjs.js +301 -0
- package/dist/transport/peerjs.js.map +1 -0
- package/dist/transport/pqc-handshake.d.ts +72 -0
- package/dist/transport/pqc-handshake.d.ts.map +1 -0
- package/dist/transport/pqc-handshake.js +129 -0
- package/dist/transport/pqc-handshake.js.map +1 -0
- package/dist/transport/relay-config.d.ts +11 -0
- package/dist/transport/relay-config.d.ts.map +1 -0
- package/dist/transport/relay-config.js +48 -0
- package/dist/transport/relay-config.js.map +1 -0
- package/dist/transport/relay-server.d.ts +37 -0
- package/dist/transport/relay-server.d.ts.map +1 -0
- package/dist/transport/relay-server.js +230 -0
- package/dist/transport/relay-server.js.map +1 -0
- package/dist/transport/tor.d.ts +47 -0
- package/dist/transport/tor.d.ts.map +1 -0
- package/dist/transport/tor.js +158 -0
- package/dist/transport/tor.js.map +1 -0
- package/dist/transport/types.d.ts +34 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +2 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/types/index.d.ts +293 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +73 -0
- package/dist/types/index.js.map +1 -0
- package/dist/web/admission.d.ts +24 -0
- package/dist/web/admission.d.ts.map +1 -0
- package/dist/web/admission.js +41 -0
- package/dist/web/admission.js.map +1 -0
- package/dist/web/crypto.d.ts +18 -0
- package/dist/web/crypto.d.ts.map +1 -0
- package/dist/web/crypto.js +78 -0
- package/dist/web/crypto.js.map +1 -0
- package/dist/web/exchange.d.ts +23 -0
- package/dist/web/exchange.d.ts.map +1 -0
- package/dist/web/exchange.js +54 -0
- package/dist/web/exchange.js.map +1 -0
- package/dist/web/fragment.d.ts +58 -0
- package/dist/web/fragment.d.ts.map +1 -0
- package/dist/web/fragment.js +198 -0
- package/dist/web/fragment.js.map +1 -0
- package/dist/web/index.d.ts +25 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +14 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/merge/index.d.ts +104 -0
- package/dist/web/merge/index.d.ts.map +1 -0
- package/dist/web/merge/index.js +236 -0
- package/dist/web/merge/index.js.map +1 -0
- package/dist/web/oplog/hlc.d.ts +19 -0
- package/dist/web/oplog/hlc.d.ts.map +1 -0
- package/dist/web/oplog/hlc.js +39 -0
- package/dist/web/oplog/hlc.js.map +1 -0
- package/dist/web/oplog/index.d.ts +10 -0
- package/dist/web/oplog/index.d.ts.map +1 -0
- package/dist/web/oplog/index.js +6 -0
- package/dist/web/oplog/index.js.map +1 -0
- package/dist/web/oplog/log.d.ts +182 -0
- package/dist/web/oplog/log.d.ts.map +1 -0
- package/dist/web/oplog/log.js +693 -0
- package/dist/web/oplog/log.js.map +1 -0
- package/dist/web/oplog/store.d.ts +40 -0
- package/dist/web/oplog/store.d.ts.map +1 -0
- package/dist/web/oplog/store.js +85 -0
- package/dist/web/oplog/store.js.map +1 -0
- package/dist/web/oplog/sync.d.ts +54 -0
- package/dist/web/oplog/sync.d.ts.map +1 -0
- package/dist/web/oplog/sync.js +162 -0
- package/dist/web/oplog/sync.js.map +1 -0
- package/dist/web/oplog/types.d.ts +119 -0
- package/dist/web/oplog/types.d.ts.map +1 -0
- package/dist/web/oplog/types.js +2 -0
- package/dist/web/oplog/types.js.map +1 -0
- package/dist/web/pairing.d.ts +186 -0
- package/dist/web/pairing.d.ts.map +1 -0
- package/dist/web/pairing.js +395 -0
- package/dist/web/pairing.js.map +1 -0
- package/dist/web/pq.d.ts +36 -0
- package/dist/web/pq.d.ts.map +1 -0
- package/dist/web/pq.js +59 -0
- package/dist/web/pq.js.map +1 -0
- package/dist/web/provider.d.ts +188 -0
- package/dist/web/provider.d.ts.map +1 -0
- package/dist/web/provider.js +2042 -0
- package/dist/web/provider.js.map +1 -0
- package/dist/web/rooms.d.ts +20 -0
- package/dist/web/rooms.d.ts.map +1 -0
- package/dist/web/rooms.js +51 -0
- package/dist/web/rooms.js.map +1 -0
- package/dist/web/rotation.d.ts +73 -0
- package/dist/web/rotation.d.ts.map +1 -0
- package/dist/web/rotation.js +130 -0
- package/dist/web/rotation.js.map +1 -0
- package/dist/web/secstate.d.ts +213 -0
- package/dist/web/secstate.d.ts.map +1 -0
- package/dist/web/secstate.js +789 -0
- package/dist/web/secstate.js.map +1 -0
- package/dist/web/store.d.ts +9 -0
- package/dist/web/store.d.ts.map +1 -0
- package/dist/web/store.js +32 -0
- package/dist/web/store.js.map +1 -0
- package/dist/web/transports/loopback.d.ts +11 -0
- package/dist/web/transports/loopback.d.ts.map +1 -0
- package/dist/web/transports/loopback.js +97 -0
- package/dist/web/transports/loopback.js.map +1 -0
- package/dist/web/transports/qr-sdp.d.ts +27 -0
- package/dist/web/transports/qr-sdp.d.ts.map +1 -0
- package/dist/web/transports/qr-sdp.js +131 -0
- package/dist/web/transports/qr-sdp.js.map +1 -0
- package/dist/web/transports/ws.d.ts +12 -0
- package/dist/web/transports/ws.d.ts.map +1 -0
- package/dist/web/transports/ws.js +139 -0
- package/dist/web/transports/ws.js.map +1 -0
- package/dist/web/trust/canonical.d.ts +8 -0
- package/dist/web/trust/canonical.d.ts.map +1 -0
- package/dist/web/trust/canonical.js +27 -0
- package/dist/web/trust/canonical.js.map +1 -0
- package/dist/web/trust/docs.d.ts +51 -0
- package/dist/web/trust/docs.d.ts.map +1 -0
- package/dist/web/trust/docs.js +170 -0
- package/dist/web/trust/docs.js.map +1 -0
- package/dist/web/trust/index.d.ts +10 -0
- package/dist/web/trust/index.d.ts.map +1 -0
- package/dist/web/trust/index.js +7 -0
- package/dist/web/trust/index.js.map +1 -0
- package/dist/web/trust/keys.d.ts +37 -0
- package/dist/web/trust/keys.d.ts.map +1 -0
- package/dist/web/trust/keys.js +75 -0
- package/dist/web/trust/keys.js.map +1 -0
- package/dist/web/trust/store.d.ts +150 -0
- package/dist/web/trust/store.d.ts.map +1 -0
- package/dist/web/trust/store.js +587 -0
- package/dist/web/trust/store.js.map +1 -0
- package/dist/web/trust/types.d.ts +134 -0
- package/dist/web/trust/types.d.ts.map +1 -0
- package/dist/web/trust/types.js +4 -0
- package/dist/web/trust/types.js.map +1 -0
- package/dist/web/types.d.ts +115 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +2 -0
- package/dist/web/types.js.map +1 -0
- package/dist/web/util.d.ts +12 -0
- package/dist/web/util.d.ts.map +1 -0
- package/dist/web/util.js +54 -0
- package/dist/web/util.js.map +1 -0
- package/dist/web/webrtc.d.ts +35 -0
- package/dist/web/webrtc.d.ts.map +1 -0
- package/dist/web/webrtc.js +304 -0
- package/dist/web/webrtc.js.map +1 -0
- package/package.json +138 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work.
|
|
38
|
+
|
|
39
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
40
|
+
form, that is based on (or derived from) the Work and for which the
|
|
41
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
42
|
+
represent, as a whole, an original work of authorship.
|
|
43
|
+
|
|
44
|
+
"Contribution" shall mean any work of authorship, including
|
|
45
|
+
the original version of the Work and any modifications or additions
|
|
46
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
47
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
48
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
49
|
+
the copyright owner.
|
|
50
|
+
|
|
51
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
52
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
53
|
+
subsequently incorporated within the Work.
|
|
54
|
+
|
|
55
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
56
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
57
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
58
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
59
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
60
|
+
Work and such Derivative Works in Source or Object form.
|
|
61
|
+
|
|
62
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
63
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
64
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
65
|
+
(except as stated in this section) patent license to make, have made,
|
|
66
|
+
use, offer to sell, sell, import, and otherwise transfer the Work.
|
|
67
|
+
|
|
68
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
69
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
70
|
+
modifications, and in Source or Object form, provided that You
|
|
71
|
+
meet the following conditions:
|
|
72
|
+
|
|
73
|
+
(a) You must give any other recipients of the Work or
|
|
74
|
+
Derivative Works a copy of this License; and
|
|
75
|
+
|
|
76
|
+
(b) You must cause any modified files to carry prominent notices
|
|
77
|
+
stating that You changed the files; and
|
|
78
|
+
|
|
79
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
80
|
+
that You distribute, all copyright, patent, trademark, and
|
|
81
|
+
attribution notices from the Source form of the Work; and
|
|
82
|
+
|
|
83
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
84
|
+
distribution, then any Derivative Works that You distribute must
|
|
85
|
+
include a readable copy of the attribution notices contained
|
|
86
|
+
within such NOTICE file.
|
|
87
|
+
|
|
88
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
89
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
90
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
91
|
+
this License, without any additional terms or conditions.
|
|
92
|
+
|
|
93
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
94
|
+
names, trademarks, service marks, or product names of the Licensor.
|
|
95
|
+
|
|
96
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
97
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
98
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
99
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
100
|
+
implied.
|
|
101
|
+
|
|
102
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
103
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
104
|
+
unless required by applicable law (such as deliberate and grossly
|
|
105
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
106
|
+
liable to You for damages.
|
|
107
|
+
|
|
108
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
109
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
110
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
111
|
+
or other liability obligations and/or rights consistent with this
|
|
112
|
+
License.
|
|
113
|
+
|
|
114
|
+
END OF TERMS AND CONDITIONS
|
|
115
|
+
|
|
116
|
+
Copyright 2026 SouthWest AI Labs (SWAL)
|
|
117
|
+
|
|
118
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
119
|
+
you may not use this file except in compliance with the License.
|
|
120
|
+
You may obtain a copy of the License at
|
|
121
|
+
|
|
122
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
123
|
+
|
|
124
|
+
Unless required by applicable law or agreed to in writing, software
|
|
125
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
126
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
127
|
+
See the License for the specific language governing permissions and
|
|
128
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Edge Mesh (@swal/edge-mesh)
|
|
2
|
+
Copyright 2026 SouthWest AI Labs (SWAL)
|
|
3
|
+
|
|
4
|
+
This product includes software developed at SouthWest AI Labs (SWAL).
|
|
5
|
+
|
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
7
|
+
use these files except in compliance with the License. You may obtain a copy of
|
|
8
|
+
the License at:
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
13
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
14
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
15
|
+
specific language governing permissions and limitations under the License.
|
|
16
|
+
|
|
17
|
+
--------------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
THIRD-PARTY NOTICES
|
|
20
|
+
|
|
21
|
+
Runtime dependencies (bundled by the consumer's toolchain, not redistributed
|
|
22
|
+
in this package):
|
|
23
|
+
|
|
24
|
+
- yjs (MIT) — CRDT sync core.
|
|
25
|
+
- y-protocols (MIT) — sync protocol helpers.
|
|
26
|
+
- y-indexeddb (MIT) — IndexedDB persistence adapter.
|
|
27
|
+
- @noble/ciphers, @noble/hashes, @noble/post-quantum (MIT) — symmetric
|
|
28
|
+
primitives and post-quantum signatures/KEM (ML-DSA-65, ML-KEM-768).
|
|
29
|
+
|
|
30
|
+
Optional peer dependencies (none bundled; install only what you use):
|
|
31
|
+
|
|
32
|
+
- peerjs (MIT), ws (MIT), ethers (MIT), idb (ISC), cbor-x (MIT),
|
|
33
|
+
@bokuweb/zstd-wasm (MIT).
|
|
34
|
+
|
|
35
|
+
License texts of the above are available in their respective repositories.
|
|
36
|
+
Previously (before 1.0.0 under the @swal scope) this project was distributed
|
|
37
|
+
under FSL-1.1-ALv2; see CHANGELOG.md.
|
package/README.md
CHANGED
|
@@ -1,3 +1,471 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Edge Mesh
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/iberi22/edge-mesh/actions)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](tools/relay)
|
|
6
|
+
|
|
7
|
+
> P2P mesh networking library with CRDT sync, post-quantum identity, and peer-to-peer transport.
|
|
8
|
+
|
|
9
|
+
`@swal/edge-mesh` is the interconnection layer of the SWAL ecosystem: distributed browsers, Progressive Web Apps and
|
|
10
|
+
edge nodes that replicate state with no central server.
|
|
11
|
+
|
|
12
|
+
Its browser entry point, **`@swal/edge-mesh/web`**, is an **owner-controlled P2P mesh for PWAs**. The first device
|
|
13
|
+
that hosts a pairing owns the mesh; every other device joins with a QR pairing confirmed by a 6-digit code. Everything
|
|
14
|
+
on the wire is encrypted and signed with **post-quantum ML-DSA-65** identities and **hybrid ML-KEM-768 + ECDH P-256**
|
|
15
|
+
key exchange, and the security state (grants, revocations, key records, rotations) is a set of signed documents kept
|
|
16
|
+
by each device, never by the shared `Y.Doc`.
|
|
17
|
+
|
|
18
|
+
The Node side of the package (relay client, governance, presence, agent memory) is documented further down.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @swal/edge-mesh yjs
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`yjs` is the CRDT layer and a peer of this package; `@noble/post-quantum` comes with it. ESM only (`import`), no
|
|
29
|
+
CommonJS build. License: [Apache-2.0](LICENSE).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick start — the browser mesh
|
|
34
|
+
|
|
35
|
+
Two devices, one owner, one pairing, one encrypted `Y.Doc`. `examples/web-basic.ts` is this exact code (typechecked by
|
|
36
|
+
`tsc`), executed by `tests/web/public-api.test.ts`.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import * as Y from "yjs";
|
|
40
|
+
import {
|
|
41
|
+
createLoopbackHub,
|
|
42
|
+
createMesh,
|
|
43
|
+
deviceIdOf,
|
|
44
|
+
identityKeygen,
|
|
45
|
+
identitySign,
|
|
46
|
+
memoryStore,
|
|
47
|
+
} from "@swal/edge-mesh/web";
|
|
48
|
+
import type { Mesh, VaultClient } from "@swal/edge-mesh/web";
|
|
49
|
+
|
|
50
|
+
export interface QuickStart {
|
|
51
|
+
/** The device that hosted the pairing: the owner of the mesh. */
|
|
52
|
+
owner: Mesh;
|
|
53
|
+
/** The paired guest. */
|
|
54
|
+
guest: Mesh;
|
|
55
|
+
/** Its device id: the fingerprint of its ML-DSA-65 identity key. */
|
|
56
|
+
guestId: string;
|
|
57
|
+
/** The two documents, so you can watch them replicate: [owner's, guest's]. */
|
|
58
|
+
docs: [Y.Doc, Y.Doc];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** What your app provides: this device's ML-DSA-65 identity plus the mesh key, kept in IndexedDB. */
|
|
62
|
+
async function makeVault(): Promise<VaultClient> {
|
|
63
|
+
const kp = identityKeygen();
|
|
64
|
+
let meshKey: Uint8Array = crypto.getRandomValues(new Uint8Array(32));
|
|
65
|
+
return {
|
|
66
|
+
deviceId: await deviceIdOf(kp.publicKey),
|
|
67
|
+
devicePublicKey: kp.publicKey,
|
|
68
|
+
getOrCreateMeshKey: async () => meshKey,
|
|
69
|
+
setMeshKey: async (raw) => void (meshKey = raw),
|
|
70
|
+
sign: async (data) => identitySign(kp.secretKey, data),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function quickStart(): Promise<QuickStart> {
|
|
75
|
+
// 1. In-memory links, so this runs with no signaling server.
|
|
76
|
+
// In a browser: signaling: [wsTransport("wss://signal.example/ws")] (docs/SIGNALING-PROTOCOL.md).
|
|
77
|
+
const hub = createLoopbackHub();
|
|
78
|
+
const mk = async (name: string) => {
|
|
79
|
+
const doc = new Y.Doc();
|
|
80
|
+
const vault = await makeVault();
|
|
81
|
+
const mesh = createMesh({
|
|
82
|
+
appId: "acme",
|
|
83
|
+
topic: "acme/data",
|
|
84
|
+
doc,
|
|
85
|
+
vault,
|
|
86
|
+
deviceName: name,
|
|
87
|
+
store: memoryStore(), // device-local security state; nothing of it lives in the shared doc
|
|
88
|
+
signaling: [hub.transport()],
|
|
89
|
+
});
|
|
90
|
+
await mesh.ready;
|
|
91
|
+
return { doc, vault, mesh };
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// 2. The first device that hosts a pairing is the owner; until then the mesh is off (no network at all).
|
|
95
|
+
const owner = await mk("owner");
|
|
96
|
+
const guest = await mk("guest");
|
|
97
|
+
owner.doc.getMap("state").set("hello", "world"); // replicates to every member, encrypted and signed
|
|
98
|
+
|
|
99
|
+
// 3. Pair: the guest scans the offer as a QR and both sides confirm the same 6-digit SAS.
|
|
100
|
+
owner.mesh.on("sas", (p) => p.confirm());
|
|
101
|
+
await guest.mesh.pairJoin((await owner.mesh.pairHost()).payload, { confirmSas: () => true });
|
|
102
|
+
return {
|
|
103
|
+
owner: owner.mesh,
|
|
104
|
+
guest: guest.mesh,
|
|
105
|
+
guestId: guest.vault.deviceId,
|
|
106
|
+
docs: [owner.doc, guest.doc],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The example uses the in-memory loopback transport so it runs with no signaling server; a browser app passes
|
|
112
|
+
`wsTransport("wss://signal.example/ws")` (self-hosted, see [`docs/SIGNALING-PROTOCOL.md`](docs/SIGNALING-PROTOCOL.md))
|
|
113
|
+
or its own `LinkTransport` instead. The owner controls the mesh from there:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const { owner, guest, guestId } = await quickStart();
|
|
117
|
+
owner.devices(); // this device, the owner, every member (role, admittedBy)
|
|
118
|
+
owner.security?.trust.can(guestId, "mesh", "administrar"); // false: only admins may administer the mesh module
|
|
119
|
+
await owner.revoke(guestId); // signed revocations, then a re-key for the remaining members
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Subpaths
|
|
125
|
+
|
|
126
|
+
| Subpath | What you get |
|
|
127
|
+
| :--- | :--- |
|
|
128
|
+
| `@swal/edge-mesh/web` | The mesh: `createMesh`, pairing (QR + SAS), encrypted `Y.Doc` sync, revocation, re-key, channels, signaling transports, ML-DSA-65 / ML-KEM-768 primitives and the stores |
|
|
129
|
+
| `@swal/edge-mesh/web/trust` | Signed **grants** and **revocations** with a delegation budget, a root-anchored `TrustStore` and `can(device, module, level)` |
|
|
130
|
+
| `@swal/edge-mesh/web/oplog` | One append-only, signed, hash-chained log per device, gated by the grants, with quarantine and a catch-up protocol |
|
|
131
|
+
| `@swal/edge-mesh/web/merge` | Deterministic projections of accepted ops: `lwwField`, `eventLog`, `ledger` |
|
|
132
|
+
|
|
133
|
+
Details of each one, and how an app plugs them together: [Browser permissions](#browser-permissions-webtrust-weboplog-webmerge).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Security model
|
|
138
|
+
|
|
139
|
+
- **The owner is the root.** The first device that hosts a pairing pins its ML-DSA-65 key as the trust root of the
|
|
140
|
+
mesh; until then the mesh is off (it opens no connection). A device id is the fingerprint of its identity key, so
|
|
141
|
+
membership cannot be claimed by copying an id.
|
|
142
|
+
- **The security state is signed documents, not the shared doc.** Grants, revocations, key-agreement records and
|
|
143
|
+
owner rotations are content-addressed signed documents kept in a device-local store (`store`, `vault.store` or
|
|
144
|
+
`persist: "idb"`) and exchanged over an authenticated channel. A member can only add documents: there is no slot to
|
|
145
|
+
squat, overwrite or delete.
|
|
146
|
+
- **Revocation is a signed document, and only owner devices re-key.** The owner revokes any grant, an admin the ones
|
|
147
|
+
it issued (revocations cascade); a revoked device is cut at once everywhere, and the new mesh key reaches the rest
|
|
148
|
+
pairwise, wrapped with hybrid ML-KEM-768 + ECDH P-256 (both secrets required) and signed with ML-DSA-65.
|
|
149
|
+
- **Admins are tier 2.** `owner -> admins -> members`: an admin may admit members but not admins, may not grant
|
|
150
|
+
permissions it does not hold itself, and revoking it revokes what it admitted (the owner can `reanchor` them).
|
|
151
|
+
- **Links authenticate before they carry data.** Every frame is signed by the sender's identity key and encrypted
|
|
152
|
+
under a per-sender AES-256-GCM subkey; a link only becomes usable after a signed `K_HELLO`/`K_AUTH` handshake, and
|
|
153
|
+
membership never depends on a device clock.
|
|
154
|
+
|
|
155
|
+
Design and audit history: [`docs/WEB-MESH-CRYPTO.md`](docs/WEB-MESH-CRYPTO.md),
|
|
156
|
+
[`docs/security/audits/`](docs/security/audits/README.md) (rounds 1-5, each finding with its regression test).
|
|
157
|
+
Vulnerability reports: [`SECURITY.md`](SECURITY.md) (never a public issue).
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Browser and Node support
|
|
162
|
+
|
|
163
|
+
| Target | Support |
|
|
164
|
+
| :--- | :--- |
|
|
165
|
+
| Browsers (PWA) | Any browser with WebCrypto and WebRTC. The `./web*` subpaths are browser-pure: WebCrypto only, no Node built-ins, so they also run under workerd. |
|
|
166
|
+
| Node | **>= 22**, **ESM only** (`"type": "module"`, no CommonJS entry). `./web` runs in Node too: the loopback and WebSocket transports need no browser, and the whole `tests/web` suite exercises them there. |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Features
|
|
171
|
+
|
|
172
|
+
- 🔗 **P2P Mesh Network** — PeerJS/WebRTC transport with dynamic peer auto-discovery and Gossip protocol fan-out routing.
|
|
173
|
+
- 📝 **CRDT Synchronization** — Yjs-based conflict-free replicated data types (`Y.Doc`, `Y.Map`, `Y.Text`) for real-time collaboration.
|
|
174
|
+
- 🛡️ **Post-Quantum Cryptography** — Native ML-DSA-65 identity signatures (FIPS 205) and ML-KEM-768 key encapsulation for quantum-resistant authentication and handshake encryption.
|
|
175
|
+
- 💬 **Persistent Chat Channels** — Real-time peer-to-peer chat streams with offline message queueing and storage rehydration.
|
|
176
|
+
- 🏛️ **Decentralized Governance** — Proposal creation, voting management (accept, reject, abstain), host seniority resolution, and high-availability authority failovers.
|
|
177
|
+
- 📍 **Presence & Health Monitoring** — Post-quantum signed heartbeats with anti-replay timestamp verification and dead peer detection.
|
|
178
|
+
- 🔐 **Granular Authorization** — Logical namespace-based access control (`swalNamespace`) with standard capabilities (`CAPACIDAD_ESTANDAR`).
|
|
179
|
+
- 💾 **Offline-First Storage** — IndexedDB persistence with seamless `InMemoryStorage` fallback for environments without storage access.
|
|
180
|
+
- 🧠 **Node Memory & Xavier Sync** — `node-memory` persistence with SHA-256 deduplication and automatic RAG synchronization with Xavier API endpoints.
|
|
181
|
+
- 🧅 **Tor Onion v3 Transport** — Opt-in onion routing via `TorTransportAdapter` and hidden service proxy tunneling for CGNAT traversal.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Quickstart (Node and Rust)
|
|
186
|
+
|
|
187
|
+
The browser mesh is the [quick start](#quick-start--the-browser-mesh) above. This section covers the Rust relay server
|
|
188
|
+
and the Node-side mesh.
|
|
189
|
+
|
|
190
|
+
### Rust Relay Server (`swal-relay`)
|
|
191
|
+
|
|
192
|
+
Add `swal-relay` to your `Cargo.toml` dependencies:
|
|
193
|
+
|
|
194
|
+
```toml
|
|
195
|
+
[dependencies]
|
|
196
|
+
swal-relay = "0.1.0"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Construct and run a cross-device WebSocket relay server in Rust:
|
|
200
|
+
|
|
201
|
+
```rust
|
|
202
|
+
use std::net::SocketAddr;
|
|
203
|
+
use swal_relay::{RelayServer, PeerId, MAX_MEMBERS, MAX_FRAME_SIZE, DEFAULT_CHANNEL_TTL_SECS};
|
|
204
|
+
|
|
205
|
+
#[tokio::main]
|
|
206
|
+
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
207
|
+
// Bind the relay server to a local TCP socket address
|
|
208
|
+
let addr: SocketAddr = "127.0.0.1:8080".parse()?;
|
|
209
|
+
let server = RelayServer::new(addr);
|
|
210
|
+
|
|
211
|
+
println!("Relay server bound to listening address: {}", server.addr());
|
|
212
|
+
println!(
|
|
213
|
+
"Relay constraints -> MAX_MEMBERS: {}, MAX_FRAME_SIZE: {} bytes, TTL: {}s",
|
|
214
|
+
MAX_MEMBERS, MAX_FRAME_SIZE, DEFAULT_CHANNEL_TTL_SECS
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Spawn the asynchronous WebSocket listener and routing loop
|
|
218
|
+
let actual_addr = server.run().await?;
|
|
219
|
+
println!("Relay server active and accepting connections on {}", actual_addr);
|
|
220
|
+
|
|
221
|
+
Ok(())
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### TypeScript Node (`@swal/edge-mesh`)
|
|
226
|
+
|
|
227
|
+
Install the package into your JavaScript or TypeScript project:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npm install @swal/edge-mesh yjs
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Initialize an EdgeMesh node, establish post-quantum identity, and synchronize CRDT documents:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import {
|
|
237
|
+
EdgeMesh,
|
|
238
|
+
YjsAdapter,
|
|
239
|
+
createPostQuantumIdentity,
|
|
240
|
+
generateKeypair,
|
|
241
|
+
swalNamespace,
|
|
242
|
+
} from "@swal/edge-mesh";
|
|
243
|
+
import * as Y from "yjs";
|
|
244
|
+
|
|
245
|
+
// 1. Generate post-quantum ML-DSA-65 identity keypair
|
|
246
|
+
const keypair = await generateKeypair();
|
|
247
|
+
const identity = createPostQuantumIdentity(keypair);
|
|
248
|
+
|
|
249
|
+
// 2. Initialize EdgeMesh node instance
|
|
250
|
+
const mesh = new EdgeMesh({
|
|
251
|
+
nodoId: "swal-node-alpha",
|
|
252
|
+
peerId: "peer-alpha-001",
|
|
253
|
+
});
|
|
254
|
+
await mesh.iniciar();
|
|
255
|
+
|
|
256
|
+
// 3. Connect a Y.Doc to the P2P mesh network using YjsAdapter
|
|
257
|
+
const doc = new Y.Doc();
|
|
258
|
+
const namespace = swalNamespace("documents", "shared-workspace");
|
|
259
|
+
const adapter = new YjsAdapter(doc, mesh, namespace);
|
|
260
|
+
|
|
261
|
+
// 4. Mutate CRDT data locally — changes replicate automatically to online peers
|
|
262
|
+
const text = doc.getText("content");
|
|
263
|
+
text.insert(0, "Collaborative P2P editing with post-quantum security!");
|
|
264
|
+
|
|
265
|
+
// 5. Create a real-time P2P chat channel
|
|
266
|
+
const channel = mesh.chat.crearCanal("general", "publico");
|
|
267
|
+
channel.on("mensaje", (event) => {
|
|
268
|
+
console.log("Received P2P chat message:", event.detail);
|
|
269
|
+
});
|
|
270
|
+
channel.enviarMensaje("Hello from node alpha!");
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Browser mesh (`@swal/edge-mesh/web`)
|
|
274
|
+
|
|
275
|
+
`createMesh({ appId, topic, doc, vault, signaling })` syncs a `Y.Doc` between paired devices over WebRTC, end-to-end
|
|
276
|
+
encrypted: see the [quick start](#quick-start--the-browser-mesh) and the [security model](#security-model) above for the
|
|
277
|
+
code and the guarantees. The rest of the surface, in one place:
|
|
278
|
+
|
|
279
|
+
- **Hooks for a permissions layer**: `authorizeDevice(deviceId, pub)`, `canRotate(issuer, target)` and
|
|
280
|
+
`authorizeUpdate(sender, update)` gate membership, rotation wraps and every incoming Yjs update;
|
|
281
|
+
`mesh.channel(kind)` is a private encrypted message stream per kind.
|
|
282
|
+
- **Membership and authority** live in one place, the mesh's `web/trust` store (`mesh.security.trust`); an admin
|
|
283
|
+
revokes the devices it admitted, revocations cascade and the owner can `reanchor` them. `mesh.security.add(doc)` /
|
|
284
|
+
`addMany(docs)` ingest app-issued documents, `issueGrant(subjectPub, { role })` signs one with this device's
|
|
285
|
+
identity.
|
|
286
|
+
- **Large messages are fragmented** (64 KiB per frame, 64 MiB per message), and a re-key is executed by the next owner
|
|
287
|
+
device online (`mesh.rekeyPending`) after an admin's revocation cut a device off.
|
|
288
|
+
- **Give the mesh a persistent device-local store** (`persist: "idb"`, `store` or `vault.store`): with the in-memory
|
|
289
|
+
fallback a reloaded device has to be paired again.
|
|
290
|
+
|
|
291
|
+
Details and breaking changes: [`docs/WEB-MESH-CRYPTO.md`](docs/WEB-MESH-CRYPTO.md).
|
|
292
|
+
|
|
293
|
+
### Browser permissions: `web/trust`, `web/oplog`, `web/merge`
|
|
294
|
+
|
|
295
|
+
Browser-pure (WebCrypto only; works in browsers and workerd), app-agnostic building blocks for "every device is a node
|
|
296
|
+
with its own permissions". The core never hard-codes modules or roles: each app passes a schema.
|
|
297
|
+
|
|
298
|
+
| Entry point | What it does |
|
|
299
|
+
| :--- | :--- |
|
|
300
|
+
| `@swal/edge-mesh/web/trust` | Device keys (**ML-DSA-65**, post-quantum; fingerprint = SHA-256 of canonical `{alg, pub}`), signed **grants** (role + per-module `ver`/`editar`/`administrar` + delegation budget + validity + optional seq cut-off + issuer chain) and **revocations** (issued by the root or a strict ancestor of the target grant, cut by the revoker's last-seen `seq`, always cascading). `TrustStore` ingests documents from any source in any order, keeps only chains that reach the configured root, enforces delegation (depth, admins cannot mint admins, permissions ⊆ issuer's) and answers `can(deviceFp, module, level, { seq, time })` |
|
|
301
|
+
| `@swal/edge-mesh/web/oplog` | One append-only, signed, hash-chained log per device (`seq`, `prev`, HLC). Receivers verify signature → chain (gap = pending, fork = equivocation evidence) → capability at the op's `seq`/HLC. Rejected ops go to quarantine with a reason; held ops are re-evaluated when grants/revocations arrive. Catch-up protocol (`have` version vector → `want` ranges → `ops` frames ≤ 64 KiB) and a channel adapter |
|
|
302
|
+
| `@swal/edge-mesh/web/merge` | Deterministic projections of accepted ops: `lwwField` (per-field LWW by HLC, causal `base`, optional owner precedence, tombstones), `eventLog` (app reducer / state machine, invalid transitions become conflicts), `ledger` (signed movements summed, negative rejected/flagged/allowed) |
|
|
303
|
+
|
|
304
|
+
Signatures use the same canonical JSON as Fize's `publicMenuSignature.ts` (`canonicalJson` is byte-identical), signed
|
|
305
|
+
with **ML-DSA-65** (base64url signature, base64url public key), as AGENTS.md requires for identity signatures. Apps
|
|
306
|
+
migrate with `signCanonical` / `verifyCanonical` / `keyFingerprint` from `web/trust`; ES256 documents are rejected
|
|
307
|
+
(Fize migrates its signed public-menu snapshots separately). Yjs stays for presence and the device list only.
|
|
308
|
+
|
|
309
|
+
Integration sketch (Fize as the example app; the module list lives in the app, not in the core):
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { createTrustStore, generateSigner, issueGrant, issueRevocation, rolePreset } from "@swal/edge-mesh/web/trust";
|
|
313
|
+
import { attachOpLogSync, openOpLog } from "@swal/edge-mesh/web/oplog";
|
|
314
|
+
import { createProjector, eventLog, ledger, lwwField } from "@swal/edge-mesh/web/merge";
|
|
315
|
+
|
|
316
|
+
const schema = {
|
|
317
|
+
modules: ["carta", "pedidos", "cocina", "caja", "inventario", "recetas", "costos", "compras",
|
|
318
|
+
"analitica", "ajustes", "personal", "publicar", "copias"],
|
|
319
|
+
roles: {
|
|
320
|
+
admin: { permissions: { carta: "administrar", pedidos: "administrar", personal: "ver" /* … */ }, delegate: 1 },
|
|
321
|
+
mesero: { permissions: { carta: "ver", pedidos: "editar", cocina: "editar" } },
|
|
322
|
+
cocina: { permissions: { carta: "ver", pedidos: "ver", cocina: "editar", inventario: "ver", recetas: "ver" } },
|
|
323
|
+
},
|
|
324
|
+
actionLevel: (module, action) => (action.endsWith(".void") ? "administrar" : "editar"),
|
|
325
|
+
maxDepth: 2, // root (owner) -> admin -> staff
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Owner device: the restaurant root key signs a grant for a newly paired device (pub key from the SAS-confirmed pairing).
|
|
329
|
+
const trust = await createTrustStore({ inst: "local-<fp>", root: rootPublicJwk, schema });
|
|
330
|
+
const grant = await issueGrant(rootSigner, { subject: { pub: guestPub }, name: "Ana", ...rolePreset(schema, "mesero") },
|
|
331
|
+
{ inst: trust.inst });
|
|
332
|
+
await trust.add(grant); // replicate trust.docs() to every node; they re-add them on boot
|
|
333
|
+
|
|
334
|
+
// Every device: its own non-extractable key signs its own log.
|
|
335
|
+
const device = await generateSigner(); // keep device.keyPair in IndexedDB
|
|
336
|
+
const log = await openOpLog({ trust, signer: device /*, store: idbOpStore, quarantine: idbQuarantine */ });
|
|
337
|
+
attachOpLogSync(log, meshChannel); // T2: the provider's channel("oplog")
|
|
338
|
+
await log.append({ module: "pedidos", action: "order.created", entity: "order", entityId: id, payload: { table: 4 } });
|
|
339
|
+
|
|
340
|
+
// Projections: recompute a module on "change" (late grants, revocations or forks can retract ops).
|
|
341
|
+
const projector = createProjector({ carta: lwwField({ rank }), pedidos: eventLog(orderMachine), inventario: ledger() });
|
|
342
|
+
log.on("change", async ({ modules }) => {
|
|
343
|
+
for (const m of modules) render(m, projector.project(m, await log.accepted(m)));
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Revoking a device: cut by what this device has already seen from it (and from devices it added). `headIds()` also
|
|
347
|
+
// anchors that history (seq + op id): the revoked key cannot later fork it to replicas that had not seen it.
|
|
348
|
+
await trust.add(await issueRevocation(rootSigner, trust.prepareRevocation(grant.id, await log.headIds()), { inst: trust.inst }));
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Transport contract expected by `attachOpLogSync` (wired to `web/provider.ts` in T2): `send(to | null, bytes)`,
|
|
352
|
+
`onMessage((from, bytes) => …)` and optional `onPeer(peer => …)`. The provider should also call
|
|
353
|
+
`trust.isMember(deviceFp)` to admit devices and `trust.can(fp, "personal", "administrar")` before honouring a rotation.
|
|
354
|
+
Pruning/checkpoints are an interface only (`CheckpointHook`, `OpStore.prune`); an IndexedDB `OpStore` lives in the app
|
|
355
|
+
for now.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Feature Matrix
|
|
360
|
+
|
|
361
|
+
| Feature | Capabilities & Description | Module Path | Status |
|
|
362
|
+
| :--- | :--- | :--- | :--- |
|
|
363
|
+
| **CRDT Sync** | Real-time state vector exchange, incremental delta replication, and mutation revert guards | `src/sync/`, `src/edge-mesh.ts` | Production |
|
|
364
|
+
| **PQ Identity** | ML-DSA-65 identity keypairs, signed heartbeats, and ML-KEM-768 key encapsulation handshakes | `src/identity/`, `src/transport/pqc-handshake.ts` | Production |
|
|
365
|
+
| **P2P Transport** | WebRTC signaling via PeerJS, WebSocket relay (`swal-relay`), and Tor v3 onion transport | `src/transport/` | Production |
|
|
366
|
+
| **Offline Tolerance** | IndexedDB backing store, `PersistentOfflineQueue`, and automatic rehydration on reconnect | `src/storage/`, `src/chat/` | Production |
|
|
367
|
+
| **Mesh Routing** | Dynamic peer table management, topic subscription filter, and limited Gossip fan-out | `src/mesh/`, `src/namespaces/` | Production |
|
|
368
|
+
| **Node Memory & AI** | Offline agent memory persistence with SHA-256 deduplication and Xavier HTTP RAG sync | `src/node-memory/` | Production |
|
|
369
|
+
| **Governance & Authz** | Proposal management, quorum validation, host authority failover, and namespace authorization | `src/governance/`, `src/authz/` | Production |
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## In the SWAL Ecosystem
|
|
374
|
+
|
|
375
|
+
Edge Mesh acts as the fundamental networking and persistence fabric across the SWAL architecture:
|
|
376
|
+
|
|
377
|
+
1. **Powers Xavier Synchronization:** Serves as the transport and persistence layer for `node-memory`, enabling offline agent RAG storage that flushes queued decisions directly to Xavier endpoints (`http://127.0.0.1:8006`).
|
|
378
|
+
2. **SWAL Agent Runner Storage Links:** Used by agent runners to manage decentralized state transitions, share encrypted identity proofs (`IvnProofs`), and exchange market commons data offers (`OffersGossip`).
|
|
379
|
+
3. **Telemetry & Backoffice Integration:** Integrated into `MalocaBackoffice` and `GosBridge` to provide real-time bandwidth metrics, node health status, and continuous topology monitoring.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Architecture
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
edge-mesh/
|
|
387
|
+
├── src/
|
|
388
|
+
│ ├── index.ts # Canonical package exports
|
|
389
|
+
│ ├── edge-mesh.ts # Main EdgeMesh node orchestrator & YjsAdapter
|
|
390
|
+
│ ├── core/ # Node state lifecycle & transition management
|
|
391
|
+
│ ├── types/ # Core type definitions, interfaces, and enums
|
|
392
|
+
│ ├── protocol/ # Canonical serialization, envelopes & deduplication
|
|
393
|
+
│ ├── transport/ # Transport layer (PeerJS, Relay, Memory, Tor)
|
|
394
|
+
│ ├── identity/ # Post-quantum identity primitives (ML-DSA-65)
|
|
395
|
+
│ ├── governance/ # Decentralized governance & AuthorityManager failover
|
|
396
|
+
│ ├── presence/ # Signed heartbeat system & PeerHealthMonitor
|
|
397
|
+
│ ├── authz/ # Namespace authorization & capability checks
|
|
398
|
+
│ ├── namespaces/ # Isolation helpers, encrypted plugins & OffersGossip
|
|
399
|
+
│ ├── storage/ # Storage abstractions (IndexedDB & InMemoryStorage)
|
|
400
|
+
│ ├── op-log/ # Operation log engine for auditability
|
|
401
|
+
│ ├── sync/ # CRDT state sync engine
|
|
402
|
+
│ ├── snapshot/ # Snapshot state persistence and recovery
|
|
403
|
+
│ ├── chat/ # Generic P2P chat channels & offline queueing
|
|
404
|
+
│ ├── salones/ # Virtual salon room orchestration
|
|
405
|
+
│ ├── node-memory/ # Agent memory persistence & Xavier sync
|
|
406
|
+
│ ├── mesh/ # Gossip fan-out mesh manager
|
|
407
|
+
│ └── web/ # Browser P2P mesh (@swal/edge-mesh/web)
|
|
408
|
+
│ ├── trust/ # Capability store, grants & revocations
|
|
409
|
+
│ ├── oplog/ # Signed operation log and sync
|
|
410
|
+
│ ├── merge/ # Deterministic merge strategies (LWW, ledger)
|
|
411
|
+
│ └── transports/ # WebRTC, loopback & WebSocket transports
|
|
412
|
+
├── tools/
|
|
413
|
+
│ └── relay/ # Rust WebSocket relay server (swal-relay)
|
|
414
|
+
├── packages/ # Monorepo workspace packages (e.g. edge-mesh-react)
|
|
415
|
+
└── tests/ # Vitest unit and integration test suites
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Data Layer Unification
|
|
419
|
+
|
|
420
|
+
Edge Mesh provides dual complementary data persistence mechanisms:
|
|
421
|
+
- **Yjs CRDT Path (`YjsAdapter`):** Optimized for real-time document collaboration and interactive UI state using commutative state vectors and delta updates.
|
|
422
|
+
- **OpLog Path (`SyncEngine`):** Optimized for structured, append-only operation ledgers and historical audit trails.
|
|
423
|
+
|
|
424
|
+
Both components operate seamlessly over the underlying network transport layer and utilize common post-quantum envelope verification (`validateEnvelope`).
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Workspace Distribution & SSOT
|
|
429
|
+
|
|
430
|
+
This repository is structured as a single unified monorepo workspace. Under the **Single Source of Truth (SSOT)** policy:
|
|
431
|
+
- The core engine (`@swal/edge-mesh`) is maintained in `src/`.
|
|
432
|
+
- Sibling packages (such as `@swal/edge-mesh-react` in `packages/edge-mesh-react`) consume the core build directly without code duplication.
|
|
433
|
+
|
|
434
|
+
To build all packages across the workspace:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
npm run build
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Documentation
|
|
443
|
+
|
|
444
|
+
- [Documentation Index](docs/README.md) — Comprehensive guide and module listing.
|
|
445
|
+
- [Architecture Overview](docs/architecture.md) — System layers, browser mesh pairing, and CRDT sync flow.
|
|
446
|
+
- [API Reference](docs/api.md) — Complete API documentation for all package exports.
|
|
447
|
+
- [Cookbook](docs/cookbook.md) — Common recipes for browser and Node.js environments.
|
|
448
|
+
- [Signaling Protocol](docs/SIGNALING-PROTOCOL.md) — WebSocket signaling relay specification.
|
|
449
|
+
- [Web Mesh Cryptography](docs/WEB-MESH-CRYPTO.md) — Post-quantum key exchange, frame format, and forward secrecy.
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Testing & Verification
|
|
454
|
+
|
|
455
|
+
Run the comprehensive Vitest test suite covering core networking, CRDT sync, post-quantum handshakes, governance, and storage persistence:
|
|
456
|
+
|
|
457
|
+
```bash
|
|
458
|
+
npm test
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Execute performance benchmark gates:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
npm run bench
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## License
|
|
470
|
+
|
|
471
|
+
[Apache License 2.0](LICENSE). See [NOTICE](NOTICE) for attributions.
|