UNPKG

2.32 kBJavaScriptView Raw
1const multicb = require('multicb')
2const compose = require('./compose')
3const isArray = Array.isArray
4
5function split(str) {
6 return isArray(str) ? str : str.split(';')
7}
8
9module.exports = function Multiserver(plugs, wrap) {
10 plugs = plugs.map((e) => (isArray(e) ? compose(e, wrap) : e))
11
12 const _self = {
13 name: plugs.map((e) => e.name).join(';'),
14
15 client(addr, cb) {
16 let plug
17 const _addr = split(addr).find((addr) => {
18 // connect with the first plug that understands this string.
19 plug = plugs.find((plug) => (plug.parse(addr) ? plug : null))
20 if (plug) return addr
21 })
22 if (plug) plug.client(_addr, cb)
23 else
24 cb(
25 new Error(
26 'could not connect to:' + addr + ', only know:' + _self.name
27 )
28 )
29 },
30
31 server(onConnect, onError, startedCb) {
32 //start all servers
33
34 if (!startedCb) {
35 // If a callback is not registered to be called back when the servers are
36 // fully started, our default behaviour is just to print any errors starting
37 // the servers to the log
38 startedCb = (err, result) => {
39 if (err) {
40 console.error('Error starting multiserver server: ' + err)
41 }
42 }
43 }
44
45 const started = multicb()
46
47 const closes = plugs
48 .map((plug) => plug.server(onConnect, onError, started()))
49 .filter(Boolean)
50
51 started(startedCb)
52
53 return function closeMultiserverServer(cb) {
54 let done
55 if (cb) done = multicb()
56 for (const close of closes) {
57 if (done && close.length) close(done())
58 else close()
59 }
60 if (done) done(cb)
61 }
62 },
63
64 stringify(scope) {
65 if (!scope) scope = 'device'
66 return plugs
67 .filter((plug) => {
68 const _scope = plug.scope()
69 return Array.isArray(_scope)
70 ? ~_scope.indexOf(scope)
71 : _scope === scope
72 })
73 .map((plug) => plug.stringify(scope))
74 .filter(Boolean)
75 .join(';')
76 },
77
78 // parse doesn't really make sense here...
79 // like, what if you only have a partial match?
80 // maybe just parse the ones you understand?
81 parse(str) {
82 return str.split(';').map((e, i) => plugs[i].parse(e))
83 },
84 }
85 return _self
86}