hsync 0.20.0 → 0.21.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/cli.js +0 -3
- package/connection.js +6 -0
- package/dist/hsync.js +2 -2
- package/dist/hsync.min.js +1 -1
- package/lib/peers.js +3 -6
- package/package.json +1 -1
package/cli.js
CHANGED
package/connection.js
CHANGED
|
@@ -202,6 +202,9 @@ async function createHsync(config) {
|
|
|
202
202
|
debug('ping called', remotePeer.hostName, greeting);
|
|
203
203
|
return `${greeting} back atcha, ${remotePeer.hostName}.`;
|
|
204
204
|
},
|
|
205
|
+
validatePeer: (remotePeer, secret) => {
|
|
206
|
+
return hsyncClient.getPeer(remotePeer.hostName).myAuth === secret;
|
|
207
|
+
},
|
|
205
208
|
connectSocket: hsyncClient.connectSocket,
|
|
206
209
|
// closeListenerSocket: hsyncClient.closeListenerSocket,
|
|
207
210
|
// closeRelaySocket: hsyncClient.closeRelaySocket,
|
|
@@ -210,6 +213,9 @@ async function createHsync(config) {
|
|
|
210
213
|
};
|
|
211
214
|
|
|
212
215
|
hsyncClient.serverPeer = hsyncClient.peers.createServerPeer(hsyncClient, serverReplyMethods);
|
|
216
|
+
hsyncClient.serverPeer.notifications.onexternal_message((msg) => {
|
|
217
|
+
hsyncClient.emit('external_message', msg);
|
|
218
|
+
});
|
|
213
219
|
hsyncClient.getPeer = (hostName) => {
|
|
214
220
|
return peers.getRPCPeer({ hostName });
|
|
215
221
|
};
|
package/dist/hsync.js
CHANGED
|
@@ -25,7 +25,7 @@ eval("let process = __webpack_require__.g.process || {env: {}};\n\nconst baseCon
|
|
|
25
25
|
\***********************/
|
|
26
26
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
27
27
|
|
|
28
|
-
eval("const EventEmitter = (__webpack_require__(/*! events */ \"./node_modules/events/events.js\").EventEmitter);\nconst debug = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:info');\nconst debugVerbose = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:verbose');\nconst debugError = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:error');\nconst { initPeers } = __webpack_require__(/*! ./lib/peers */ \"./lib/peers.js\");\nconst { createWebHandler, setNet: webSetNet } = __webpack_require__(/*! ./lib/web-handler */ \"./lib/web-handler.js\");\nconst { \n setNet: listenSetNet,\n initListeners,\n} = __webpack_require__(/*! ./lib/socket-listeners */ \"./lib/socket-listeners.js\");\nconst {\n setNet: relaySetNet,\n initRelays,\n} = __webpack_require__(/*! ./lib/socket-relays */ \"./lib/socket-relays.js\");\nconst fetch = __webpack_require__(/*! ./lib/fetch */ \"./lib/fetch.js\");\n\ndebug.color = 3;\ndebugVerbose.color = 2;\ndebugError.color = 1;\n\nlet mqtt;\n\nconsole.log('connection from hsync');\n\nfunction setNet(netImpl) {\n webSetNet(netImpl);\n listenSetNet(netImpl);\n relaySetNet(netImpl);\n}\n\nfunction setMqtt(mqttImpl) {\n mqtt = mqttImpl;\n}\n\nasync function createHsync(config) {\n let {\n hsyncServer,\n hsyncSecret,\n localHost,\n port,\n hsyncBase,\n keepalive,\n dynamicHost,\n listenerLocalPort,\n listenerTargetHost,\n listenerTargetPort,\n relayInboundPort,\n relayTargetHost,\n relayTargetPort,\n } = config;\n\n // console.log('config', config);\n\n let dynamicTimeout;\n\n if (dynamicHost && !hsyncSecret) {\n const result = await fetch.post(`${dynamicHost}/${hsyncBase}/dyn`, {});\n if (dynamicHost.toLowerCase().startsWith('https')) {\n hsyncServer = `wss://${result.url}`;\n } else {\n hsyncServer = `ws://${result.url}`;\n }\n hsyncSecret = result.secret;\n dynamicTimeout = result.timeout;\n }\n\n const hsyncClient = {\n setNet,\n config,\n };\n\n hsyncClient.peers = initPeers(hsyncClient);\n hsyncClient.listeners = initListeners(hsyncClient);\n hsyncClient.relays = initRelays(hsyncClient);\n\n const events = new EventEmitter();\n \n hsyncClient.on = events.on;\n hsyncClient.emit = events.emit;\n \n let lastConnect;\n const connectURL = `${hsyncServer}${hsyncServer.endsWith('/') ? '' : '/'}${hsyncBase}`;\n const myHostName = (new URL(connectURL)).hostname;\n hsyncClient.myHostName = myHostName;\n \n debug('connecting to', connectURL, '…' );\n const mqConn = mqtt.connect(connectURL, { password: hsyncSecret, username: myHostName, keepalive });\n mqConn.myHostName = myHostName;\n hsyncClient.mqConn = mqConn;\n\n const webHandler = config.webHandler || createWebHandler({myHostName, localHost, port, mqConn});\n hsyncClient.webHandler = webHandler;\n\n mqConn.on('connect', () => {\n const now = Date.now();\n debug('connected to', myHostName, lastConnect ? (now - lastConnect) : '', lastConnect ? 'since last connect' : '');\n lastConnect = now;\n hsyncClient.emit('connected', config);\n });\n\n mqConn.on('error', (error) => {\n debugError('error on mqConn', myHostName, error.code, error);\n if ((error.code === 4) || (error.code === 5)) {\n debug('ending');\n mqConn.end();\n if (globalThis.process) {\n process.exit(1);\n }\n }\n });\n\n mqConn.on('message', (topic, message) => {\n if (!topic) {\n return;\n }\n // message is Buffer\n const [name, hostName, segment3, action, segment5] = topic.split('/');\n debugVerbose('\\n↓ MQTT' , topic);\n if (name === 'web') {\n webHandler.handleWebRequest(hostName, segment3, action, message);\n return;\n } else if (name === 'msg') {\n const from = segment3;\n if (action === 'json') {\n try {\n const msg = JSON.parse(message.toString());\n msg.from = from;\n hsyncClient.emit('json', msg);\n } catch (e) {\n debugError('error parsing json message');\n }\n }\n else if (!action && (segment3 === 'srpc')) {\n hsyncClient.serverPeer.transport.receiveData(message.toString());\n }\n }\n\n });\n\n function endClient(force, callback) {\n if (force) {\n mqConn.end(force);\n if (webHandler.end) {\n webHandler.end();\n }\n return;\n }\n mqConn.end(force, (a, b) => {\n if (webHandler.end) {\n webHandler.end();\n }\n if (callback) {\n callback(a, b);\n }\n })\n }\n\n const serverReplyMethods = {\n ping: (greeting) => {\n return `${greeting} back atcha from client. ${Date.now()}`;\n },\n addSocketListener: hsyncClient.addSocketListener,\n getSocketListeners: hsyncClient.getSocketListeners,\n addSocketRelay: hsyncClient.addSocketRelay,\n getSocketRelays: hsyncClient.getSocketRelays,\n peerRpc: async (requestInfo) => {\n requestInfo.hsyncClient = hsyncClient;\n const { msg } = requestInfo;\n debug('peerRpc handler', requestInfo.fromHost, msg.method);\n const peer = hsyncClient.peers.getRPCPeer({hostName: requestInfo.fromHost, hsyncClient});\n if (!msg.id) {\n // notification\n if (Array.isArray(msg.params)) {\n msg.params.unshift(peer);\n }\n peer.transport.emit('rpc', msg);\n return { result: {}, id: msg.id};\n }\n const reply = {id: msg.id, jsonrpc:'2.0'};\n try {\n if (!peer.localMethods[msg.method]) {\n const notFoundError = new Error('method not found');\n notFoundError.code = -32601;\n throw notFoundError;\n }\n const result = await peer.localMethods[msg.method](requestInfo, ...msg.params);\n reply.result = result;\n return result;\n } catch (e) {\n debug('peer rpc error', e, msg);\n reply.error = {\n code: e.code || 500,\n message: e.toString(),\n };\n return reply;\n }\n }\n };\n\n const peerMethods = {\n ping: (remotePeer, greeting) => {\n debug('ping called', remotePeer.hostName, greeting);\n return `${greeting} back atcha, ${remotePeer.hostName}.`;\n },\n connectSocket: hsyncClient.connectSocket,\n // closeListenerSocket: hsyncClient.closeListenerSocket,\n // closeRelaySocket: hsyncClient.closeRelaySocket,\n // receiveListenerData: hsyncClient.receiveListenerData,\n // receiveRelayData: hsyncClient.receiveRelayData,\n };\n\n hsyncClient.serverPeer = hsyncClient.peers.createServerPeer(hsyncClient, serverReplyMethods);\n hsyncClient.getPeer = (hostName) => {\n return peers.getRPCPeer({ hostName });\n };\n hsyncClient.hsyncBase = hsyncBase;\n hsyncClient.endClient = endClient;\n hsyncClient.serverReplyMethods = serverReplyMethods;\n hsyncClient.getRPCPeer = hsyncClient.peers.getRPCPeer;\n hsyncClient.peerMethods = peerMethods;\n hsyncClient.hsyncSecret = hsyncSecret;\n hsyncClient.hsyncServer = hsyncServer;\n hsyncClient.dynamicTimeout = dynamicTimeout;\n const { host, protocol } = new URL(hsyncServer);\n if (protocol === 'wss:') {\n hsyncClient.webUrl = `https://${host}`;\n } else {\n hsyncClient.webUrl = `http://${host}`;\n }\n debug('url', host, protocol, hsyncClient.webUrl);\n hsyncClient.webAdmin = `${hsyncClient.webUrl}/${hsyncBase}/admin`;\n hsyncClient.webBase = `${hsyncClient.webUrl}/${hsyncBase}`;\n hsyncClient.port = port;\n\n if (listenerLocalPort) {\n listenerLocalPort.forEach((llp, i) => {\n let lth = listenerTargetHost ? listenerTargetHost[i] || listenerTargetHost[0] : null;\n if (lth) {\n if (lth.endsWith('/')) {\n lth = lth.substring(0, lth.length - 1);\n }\n const ltp = listenerTargetPort ? listenerTargetPort[i] : llp;\n hsyncClient.addSocketListener({ port: llp, targetPort: ltp, targetHost: lth });\n debug('relaying local', llp, 'to', lth, ltp);\n }\n });\n }\n\n if (relayInboundPort) {\n relayInboundPort.forEach((rip, i) => {\n debug('relayInboundPort', rip, i, relayTargetHost);\n const firstRth = relayTargetHost ? relayTargetHost[0] : null;\n const rth = relayTargetHost ? relayTargetHost[i] : firstRth || 'localhost';\n if (rth) {\n if (rth.endsWith('/')) {\n rth = rth.substring(0, rth.length - 1);\n }\n const rtp = relayTargetPort ? relayTargetPort[i] : rip;\n hsyncClient.addSocketRelay({ port: rip, targetHost: rth, targetPort: rtp });\n debug('relaying inbound', rip, 'to', rth, rtp);\n }\n });\n }\n\n return hsyncClient;\n}\n\nmodule.exports = {\n createHsync,\n setNet,\n setMqtt,\n};\n\n\n//# sourceURL=webpack://hsync/./connection.js?");
|
|
28
|
+
eval("const EventEmitter = (__webpack_require__(/*! events */ \"./node_modules/events/events.js\").EventEmitter);\nconst debug = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:info');\nconst debugVerbose = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:verbose');\nconst debugError = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:error');\nconst { initPeers } = __webpack_require__(/*! ./lib/peers */ \"./lib/peers.js\");\nconst { createWebHandler, setNet: webSetNet } = __webpack_require__(/*! ./lib/web-handler */ \"./lib/web-handler.js\");\nconst { \n setNet: listenSetNet,\n initListeners,\n} = __webpack_require__(/*! ./lib/socket-listeners */ \"./lib/socket-listeners.js\");\nconst {\n setNet: relaySetNet,\n initRelays,\n} = __webpack_require__(/*! ./lib/socket-relays */ \"./lib/socket-relays.js\");\nconst fetch = __webpack_require__(/*! ./lib/fetch */ \"./lib/fetch.js\");\n\ndebug.color = 3;\ndebugVerbose.color = 2;\ndebugError.color = 1;\n\nlet mqtt;\n\nconsole.log('connection from hsync');\n\nfunction setNet(netImpl) {\n webSetNet(netImpl);\n listenSetNet(netImpl);\n relaySetNet(netImpl);\n}\n\nfunction setMqtt(mqttImpl) {\n mqtt = mqttImpl;\n}\n\nasync function createHsync(config) {\n let {\n hsyncServer,\n hsyncSecret,\n localHost,\n port,\n hsyncBase,\n keepalive,\n dynamicHost,\n listenerLocalPort,\n listenerTargetHost,\n listenerTargetPort,\n relayInboundPort,\n relayTargetHost,\n relayTargetPort,\n } = config;\n\n // console.log('config', config);\n\n let dynamicTimeout;\n\n if (dynamicHost && !hsyncSecret) {\n const result = await fetch.post(`${dynamicHost}/${hsyncBase}/dyn`, {});\n if (dynamicHost.toLowerCase().startsWith('https')) {\n hsyncServer = `wss://${result.url}`;\n } else {\n hsyncServer = `ws://${result.url}`;\n }\n hsyncSecret = result.secret;\n dynamicTimeout = result.timeout;\n }\n\n const hsyncClient = {\n setNet,\n config,\n };\n\n hsyncClient.peers = initPeers(hsyncClient);\n hsyncClient.listeners = initListeners(hsyncClient);\n hsyncClient.relays = initRelays(hsyncClient);\n\n const events = new EventEmitter();\n \n hsyncClient.on = events.on;\n hsyncClient.emit = events.emit;\n \n let lastConnect;\n const connectURL = `${hsyncServer}${hsyncServer.endsWith('/') ? '' : '/'}${hsyncBase}`;\n const myHostName = (new URL(connectURL)).hostname;\n hsyncClient.myHostName = myHostName;\n \n debug('connecting to', connectURL, '…' );\n const mqConn = mqtt.connect(connectURL, { password: hsyncSecret, username: myHostName, keepalive });\n mqConn.myHostName = myHostName;\n hsyncClient.mqConn = mqConn;\n\n const webHandler = config.webHandler || createWebHandler({myHostName, localHost, port, mqConn});\n hsyncClient.webHandler = webHandler;\n\n mqConn.on('connect', () => {\n const now = Date.now();\n debug('connected to', myHostName, lastConnect ? (now - lastConnect) : '', lastConnect ? 'since last connect' : '');\n lastConnect = now;\n hsyncClient.emit('connected', config);\n });\n\n mqConn.on('error', (error) => {\n debugError('error on mqConn', myHostName, error.code, error);\n if ((error.code === 4) || (error.code === 5)) {\n debug('ending');\n mqConn.end();\n if (globalThis.process) {\n process.exit(1);\n }\n }\n });\n\n mqConn.on('message', (topic, message) => {\n if (!topic) {\n return;\n }\n // message is Buffer\n const [name, hostName, segment3, action, segment5] = topic.split('/');\n debugVerbose('\\n↓ MQTT' , topic);\n if (name === 'web') {\n webHandler.handleWebRequest(hostName, segment3, action, message);\n return;\n } else if (name === 'msg') {\n const from = segment3;\n if (action === 'json') {\n try {\n const msg = JSON.parse(message.toString());\n msg.from = from;\n hsyncClient.emit('json', msg);\n } catch (e) {\n debugError('error parsing json message');\n }\n }\n else if (!action && (segment3 === 'srpc')) {\n hsyncClient.serverPeer.transport.receiveData(message.toString());\n }\n }\n\n });\n\n function endClient(force, callback) {\n if (force) {\n mqConn.end(force);\n if (webHandler.end) {\n webHandler.end();\n }\n return;\n }\n mqConn.end(force, (a, b) => {\n if (webHandler.end) {\n webHandler.end();\n }\n if (callback) {\n callback(a, b);\n }\n })\n }\n\n const serverReplyMethods = {\n ping: (greeting) => {\n return `${greeting} back atcha from client. ${Date.now()}`;\n },\n addSocketListener: hsyncClient.addSocketListener,\n getSocketListeners: hsyncClient.getSocketListeners,\n addSocketRelay: hsyncClient.addSocketRelay,\n getSocketRelays: hsyncClient.getSocketRelays,\n peerRpc: async (requestInfo) => {\n requestInfo.hsyncClient = hsyncClient;\n const { msg } = requestInfo;\n debug('peerRpc handler', requestInfo.fromHost, msg.method);\n const peer = hsyncClient.peers.getRPCPeer({hostName: requestInfo.fromHost, hsyncClient});\n if (!msg.id) {\n // notification\n if (Array.isArray(msg.params)) {\n msg.params.unshift(peer);\n }\n peer.transport.emit('rpc', msg);\n return { result: {}, id: msg.id};\n }\n const reply = {id: msg.id, jsonrpc:'2.0'};\n try {\n if (!peer.localMethods[msg.method]) {\n const notFoundError = new Error('method not found');\n notFoundError.code = -32601;\n throw notFoundError;\n }\n const result = await peer.localMethods[msg.method](requestInfo, ...msg.params);\n reply.result = result;\n return result;\n } catch (e) {\n debug('peer rpc error', e, msg);\n reply.error = {\n code: e.code || 500,\n message: e.toString(),\n };\n return reply;\n }\n }\n };\n\n const peerMethods = {\n ping: (remotePeer, greeting) => {\n debug('ping called', remotePeer.hostName, greeting);\n return `${greeting} back atcha, ${remotePeer.hostName}.`;\n },\n validatePeer: (remotePeer, secret) => {\n return hsyncClient.getPeer(remotePeer.hostName).myAuth === secret;\n },\n connectSocket: hsyncClient.connectSocket,\n // closeListenerSocket: hsyncClient.closeListenerSocket,\n // closeRelaySocket: hsyncClient.closeRelaySocket,\n // receiveListenerData: hsyncClient.receiveListenerData,\n // receiveRelayData: hsyncClient.receiveRelayData,\n };\n\n hsyncClient.serverPeer = hsyncClient.peers.createServerPeer(hsyncClient, serverReplyMethods);\n hsyncClient.serverPeer.notifications.onexternal_message((msg) => {\n hsyncClient.emit('external_message', msg);\n });\n hsyncClient.getPeer = (hostName) => {\n return peers.getRPCPeer({ hostName });\n };\n hsyncClient.hsyncBase = hsyncBase;\n hsyncClient.endClient = endClient;\n hsyncClient.serverReplyMethods = serverReplyMethods;\n hsyncClient.getRPCPeer = hsyncClient.peers.getRPCPeer;\n hsyncClient.peerMethods = peerMethods;\n hsyncClient.hsyncSecret = hsyncSecret;\n hsyncClient.hsyncServer = hsyncServer;\n hsyncClient.dynamicTimeout = dynamicTimeout;\n const { host, protocol } = new URL(hsyncServer);\n if (protocol === 'wss:') {\n hsyncClient.webUrl = `https://${host}`;\n } else {\n hsyncClient.webUrl = `http://${host}`;\n }\n debug('url', host, protocol, hsyncClient.webUrl);\n hsyncClient.webAdmin = `${hsyncClient.webUrl}/${hsyncBase}/admin`;\n hsyncClient.webBase = `${hsyncClient.webUrl}/${hsyncBase}`;\n hsyncClient.port = port;\n\n if (listenerLocalPort) {\n listenerLocalPort.forEach((llp, i) => {\n let lth = listenerTargetHost ? listenerTargetHost[i] || listenerTargetHost[0] : null;\n if (lth) {\n if (lth.endsWith('/')) {\n lth = lth.substring(0, lth.length - 1);\n }\n const ltp = listenerTargetPort ? listenerTargetPort[i] : llp;\n hsyncClient.addSocketListener({ port: llp, targetPort: ltp, targetHost: lth });\n debug('relaying local', llp, 'to', lth, ltp);\n }\n });\n }\n\n if (relayInboundPort) {\n relayInboundPort.forEach((rip, i) => {\n debug('relayInboundPort', rip, i, relayTargetHost);\n const firstRth = relayTargetHost ? relayTargetHost[0] : null;\n const rth = relayTargetHost ? relayTargetHost[i] : firstRth || 'localhost';\n if (rth) {\n if (rth.endsWith('/')) {\n rth = rth.substring(0, rth.length - 1);\n }\n const rtp = relayTargetPort ? relayTargetPort[i] : rip;\n hsyncClient.addSocketRelay({ port: rip, targetHost: rth, targetPort: rtp });\n debug('relaying inbound', rip, 'to', rth, rtp);\n }\n });\n }\n\n return hsyncClient;\n}\n\nmodule.exports = {\n createHsync,\n setNet,\n setMqtt,\n};\n\n\n//# sourceURL=webpack://hsync/./connection.js?");
|
|
29
29
|
|
|
30
30
|
/***/ }),
|
|
31
31
|
|
|
@@ -55,7 +55,7 @@ eval("const fetch = __webpack_require__(/*! isomorphic-fetch */ \"./node_modules
|
|
|
55
55
|
\**********************/
|
|
56
56
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
57
57
|
|
|
58
|
-
eval("const rawr = __webpack_require__(/*! rawr */ \"./node_modules/rawr/index.js\");\nconst b64id = __webpack_require__(/*! b64id */ \"./node_modules/b64id/index.js\");\nconst debug = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:peers');\nconst EventEmitter = (__webpack_require__(/*! events */ \"./node_modules/events/events.js\").EventEmitter);\nconst buffer = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.js\");\nconst mqttPacket = __webpack_require__(/*! mqtt-packet-web */ \"./node_modules/mqtt-packet-web/index.js\");\n\nglobalThis.Buffer = buffer.Buffer;\n\nconst { handleSocketPacket } = __webpack_require__(/*! ./socket-map */ \"./lib/socket-map.js\");\nconst fetch = __webpack_require__(/*! ./fetch */ \"./lib/fetch.js\");\n\nfunction createPacket(topic, payload) {\n let payloadStr = payload;\n
|
|
58
|
+
eval("const rawr = __webpack_require__(/*! rawr */ \"./node_modules/rawr/index.js\");\nconst b64id = __webpack_require__(/*! b64id */ \"./node_modules/b64id/index.js\");\nconst debug = __webpack_require__(/*! debug */ \"./node_modules/debug/src/browser.js\")('hsync:peers');\nconst EventEmitter = (__webpack_require__(/*! events */ \"./node_modules/events/events.js\").EventEmitter);\nconst buffer = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.js\");\nconst mqttPacket = __webpack_require__(/*! mqtt-packet-web */ \"./node_modules/mqtt-packet-web/index.js\");\n\nglobalThis.Buffer = buffer.Buffer;\n\nconst { handleSocketPacket } = __webpack_require__(/*! ./socket-map */ \"./lib/socket-map.js\");\nconst fetch = __webpack_require__(/*! ./fetch */ \"./lib/fetch.js\");\n\nfunction createPacket(topic, payload) {\n let payloadStr = payload;\n const packet = mqttPacket.generate({\n qos: 0,\n cmd: 'publish',\n topic,\n payload: payloadStr,\n });\n // console.log('packet', packet);\n return packet;\n}\n\nfunction parsePacket(packet) {\n const parser = mqttPacket.parser();\n return new Promise((resolve, reject) => {\n parser.on('packet', resolve);\n parser.on('error', reject);\n parser.parse(packet);\n });\n}\n\n\nlet rtc;\n\nfunction setRTC(rtcImpl) {\n rtc = rtcImpl;\n}\n\nfunction initPeers(hsyncClient) {\n const cachedPeers = {};\n function getRPCPeer(options = {}) {\n const { hostName, temporary, timeout = 10000, hsyncClient } = options;\n let peer = cachedPeers[hostName];\n if (!peer) {\n debug('CREATING peer', hostName);\n peer = createRPCPeer({hostName, hsyncClient, timeout});\n peer.myAuth = b64id.generateId();\n if (temporary) {\n peer.rpcTemporary = true;\n }\n cachedPeers[hostName] = peer;\n }\n return peer;\n }\n \n function createRPCPeer(options = {}) {\n const { hostName, timeout = 10000, useRTC = true } = options;\n if (!hostName) {\n throw new Error('No hostname specified');\n }\n if (hostName === hsyncClient.myHostName) {\n throw new Error('Peer must be a different host');\n }\n const myAuth = b64id.generateId();\n const transport = new EventEmitter();\n const peer = rawr({transport, methods: Object.assign({}, hsyncClient.peerMethods), timeout, idGenerator: b64id.generateId});\n peer.hostName = hostName;\n peer.rtcEvents = new EventEmitter();\n peer.localMethods = Object.assign({}, hsyncClient.peerMethods);\n peer.sockets = {};\n \n peer.localMethods.rtcSignal = (peerInfo, signal) => {\n debug('rtcSignal', signal.type);\n if (signal.type === 'offer' && !peer.rtcCon && !signal.alreadySent) {\n rtc.answerPeer(peer, signal);\n } else if (signal.type === 'answer') {\n peer.handleRtcAnswer(signal);\n }\n return 'rtcSignal ok';\n }\n \n peer.rtcEvents.on('packet', async (packet) => {\n debug('↓ on packet', packet);\n let toParse = packet;\n try {\n if (packet instanceof Blob) {\n toParse = await packet.arrayBuffer();\n }\n const msg = await parsePacket(toParse);\n const [p1, p2, p3] = msg.topic.split('/');\n if (p1 === 'rpc') {\n const rpcMsg = JSON.parse(msg.payload.toString());\n debug('↓ peer RTC rpc', rpcMsg);\n // if (rpcMsg.method) {\n transport.receiveData(rpcMsg);\n // return;\n // }\n } else if (p1 === 'socketData') {\n handleSocketPacket(msg);\n } else if (p1 === 'test') {\n debug('test topic', msg.payload);\n } else {\n debug('other topic', msg.topic);\n }\n } catch (e) {\n debug('bad packet', e, packet);\n }\n });\n \n peer.rtcEvents.on('dcOpen', () => {\n debug('dcOpen');\n peer.packAndSend = (topic, payload) => {\n const packet = createPacket(topic, payload);\n if (topic === 'test') {\n debug('sending test packet', packet);\n }\n peer.rtcSend(packet);\n }\n // firefox is weird about the first bit of data, so send a test packet\n peer.packAndSend('test', 'test');\n });\n \n peer.rtcEvents.on('closed', () => {\n peer.dcOpen = false;\n delete peer.packAndSend;\n debug('rtc closed');\n for (s in peer.sockets) {\n try {\n debug('closing socket', s);\n peer.sockets[s].destroy();\n delete peer.sockets[s];\n } catch (e) {\n debug('error closing socket', e);\n }\n }\n });\n \n peer.rtcEvents.on('disconnected', () => {\n peer.dcOpen = false;\n delete peer.packAndSend;\n debug('rtc disconnected');\n for (s in peer.sockets) {\n try {\n debug('closing socket', s);\n peer.sockets[s].destroy();\n delete peer.sockets[s];\n } catch (e) {\n debug('error closing socket', e);\n }\n }\n });\n \n peer.connectRTC = async () => {\n debug('connectRTC');\n return new Promise(async (resolve, reject) => {\n try {\n const offer = await rtc.offerPeer(peer);\n debug('offer', offer);\n peer.rtcEvents.once('dcOpen', () => {\n debug('dcOpen!');\n resolve(offer);\n });\n } catch (e) {\n debug('error connecting to rtc', e);\n reject(e);\n }\n });\n };\n \n transport.send = async (msg) => {\n const fullMsg = {\n msg,\n myAuth,\n toHost: hostName,\n fromHost: hsyncClient.webUrl,\n };\n \n debug('↑ peer rpc', peer.dcOpen ? 'RTC' : 'REST', `${hostName}/_hs/rpc`, msg.method);\n \n if (peer.dcOpen) {\n let payload = msg;\n if (typeof msg === 'object') {\n payload = JSON.stringify(payload);\n }\n const packet = createPacket('rpc', payload);\n peer.rtcSend(packet);\n return;\n }\n \n try {\n const path = `${hostName}/_hs/rpc`;\n debug('fetching', path, fullMsg, useRTC);\n const result = await fetch.post(path, fullMsg);\n debug('fetch result', result);\n if (msg.id) {\n transport.receiveData({id: msg.id, result, jsonrpc: msg.jsonrpc});\n }\n } catch(e) {\n debug('error sending peer RPC request', e);\n if (msg.id) { // only send error if it's a request, not a notification\n transport.receiveData({\n id: msg.id,\n error: e.message,\n method: msg.method,\n jsonrpc: msg.jsonrpc\n });\n }\n }\n \n };\n \n transport.receiveData = (msg) => {\n debug('↓ transport.receiveData', msg);\n if(typeof msg === 'string') {\n msg = JSON.parse(msg);\n }\n debug('↓ peer rpc receivedData', msg);\n if (msg.params && Array.isArray(msg.params)) {\n debug('unshifting', msg.params);\n msg.params.unshift(peer);\n }\n transport.emit('rpc', msg);\n // debug('transport emitted', msg);\n };\n \n peer.myAuth = myAuth;\n peer.hostName = hostName;\n return peer;\n }\n \n function createServerPeer(hsyncClient, methods) {\n const transport = new EventEmitter();\n transport.send = (msg) => {\n if(typeof msg === 'object') {\n msg = JSON.stringify(msg);\n }\n const topic = `srpc/${hsyncClient.myHostName}`;\n debug('↑ server rpc outbound', msg);\n hsyncClient.mqConn.publish(topic, Buffer.from(msg));\n };\n transport.receiveData = (msg) => {\n if(msg) {\n msg = JSON.parse(msg);\n }\n debug('↓ server rpc inbound', msg);\n transport.emit('rpc', msg);\n };\n const peer = rawr({transport, methods, timeout: 5000});\n return peer;\n }\n\n hsyncClient.cachedPeers = cachedPeers;\n hsyncClient.getRPCPeer = getRPCPeer;\n hsyncClient.createServerPeer = createServerPeer;\n\n return {\n getRPCPeer,\n createRPCPeer,\n createServerPeer,\n };\n}\n\nmodule.exports = {\n initPeers,\n setRTC,\n};\n\n\n//# sourceURL=webpack://hsync/./lib/peers.js?");
|
|
59
59
|
|
|
60
60
|
/***/ }),
|
|
61
61
|
|