Skip to content

Commit

Permalink
add sync controller
Browse files Browse the repository at this point in the history
  • Loading branch information
gmaclennan committed Oct 24, 2023
1 parent 83ae9e0 commit 0785c56
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/sync/sync-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import Hypercore from 'hypercore'
import { TypedEmitter } from 'tiny-typed-emitter'
import Protomux from 'protomux'
import { SyncState } from './sync-state.js'
import { PeerSyncController } from './peer-sync-controller.js'

export class SyncController extends TypedEmitter {
#syncState
#coreManager
#capabilities
/** @type {Map<Protomux, PeerSyncController>} */
#peerSyncControllers = new Map()

/**
*
* @param {object} opts
* @param {import('../core-manager/index.js').CoreManager} opts.coreManager
* @param {import("../capabilities.js").Capabilities} opts.capabilities
* @param {number} [opts.throttleMs]
*/
constructor({ coreManager, throttleMs = 200, capabilities }) {
super()
this.#coreManager = coreManager
this.#capabilities = capabilities
this.#syncState = new SyncState({ coreManager, throttleMs })
}

getState() {
return this.#syncState.getState()
}

/**
* @param {Exclude<Parameters<Hypercore.createProtocolStream>[0], boolean>} stream A duplex stream, a @hyperswarm/secret-stream, or a Protomux instance
*/
replicate(stream) {
if (
Protomux.isProtomux(stream) ||
('userData' in stream && Protomux.isProtomux(stream.userData)) ||
('noiseStream' in stream &&
Protomux.isProtomux(stream.noiseStream.userData))
) {
console.warn(
'Passed an existing protocol stream to syncController.replicate(). Currently any pairing for the `hypercore/alpha` protocol is overwritten'
)
}
const protocolStream = Hypercore.createProtocolStream(stream, {
ondiscoverykey: /** @param {Buffer} discoveryKey */ (discoveryKey) => {
return this.#coreManager.handleDiscoveryKey(discoveryKey, stream)
},
})
const protomux =
// Need to coerce this until we update Hypercore.createProtocolStream types
/** @type {import('protomux')<import('@hyperswarm/secret-stream')>} */ (
protocolStream.noiseStream.userData
)
if (!protomux) throw new Error('Invalid stream')

if (this.#peerSyncControllers.has(protomux)) {
console.warn('Already replicating to this stream')
return
}

const peerSyncController = new PeerSyncController({
protomux,
coreManager: this.#coreManager,
syncState: this.#syncState,
capabilities: this.#capabilities,
})
this.#peerSyncControllers.set(protomux, peerSyncController)
}
}

0 comments on commit 0785c56

Please sign in to comment.