-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathswarm.js
77 lines (57 loc) · 1.71 KB
/
swarm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import React, { useEffect, useState, useContext, createContext } from 'react'
import Hyperswarm from 'hyperswarm'
import safetyCatch from 'safety-catch'
import { useDHT } from './dht.js'
const SwarmContext = createContext()
export const Swarm = ({ children, ...options }) => {
const { dht } = useDHT()
const [swarm, setSwarm] = useState(null)
useEffect(() => {
if (!dht) return
const swarm = new Hyperswarm({
keyPair: dht.defaultKeyPair,
...options,
dht
})
setSwarm(swarm)
return () => {
swarm.destroy().catch(safetyCatch) // Run on background
}
}, [dht])
return React.createElement(
SwarmContext.Provider,
{ value: { swarm } },
children
)
}
export const useSwarm = () => {
const context = useContext(SwarmContext)
if (context === undefined) {
throw new Error('useSwarm must be used within a Swarm component')
}
return context
}
export const useReplicate = (core, deps = []) => {
const { swarm } = useSwarm()
useEffect(() => {
if (!swarm || !core || core.closed) return
let cleanup = false
let session = null
const onsocket = socket => core.replicate(socket)
const ready = core.ready().catch(safetyCatch)
ready.then(() => {
if (cleanup) return
session = swarm.session({ keyPair: swarm.keyPair })
// + done could be outside of ready
const done = core.findingPeers()
session.on('connection', onsocket)
session.join(core.discoveryKey, { server: false, client: true })
session.flush().then(done, done)
})
return () => {
cleanup = true
if (!session) return
session.destroy().catch(safetyCatch) // Run on background
}
}, [swarm, core, ...deps])
}