diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..1ecfd11 --- /dev/null +++ b/.env.local.example @@ -0,0 +1 @@ +TEST_DATABASE_URL=postgres://teletype:password@localhost:5433/teletype-server-test diff --git a/.gitignore b/.gitignore index 837f7f8..bdf0bc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .env .DS_Store +test-database diff --git a/README.md b/README.md index 3de9c0a..5145889 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,13 @@ To run teletype-client tests locally, you'll first need to have: npm test ``` +3. Create postgresql docker instance: + + ``` + docker-compose up -d + cp .env.local.example .env + ``` + ## TODO * [ ] Document APIs diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b7cb1e7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3' + +services: + test-database: + image: postgres + ports: + - 5433:5432 + volumes: + - ./test-database:/var/lib/postgresql/data + restart: always + environment: + POSTGRES_USER: teletype + POSTGRES_PASSWORD: password + POSTGRES_DB: teletype-server-test + networks: + teletype: + +networks: + teletype: diff --git a/lib/socketcluster-pub-sub-gateway.js b/lib/socketcluster-pub-sub-gateway.js new file mode 100644 index 0000000..5a0652d --- /dev/null +++ b/lib/socketcluster-pub-sub-gateway.js @@ -0,0 +1,30 @@ +const socketCluster = require('socketcluster-client'); +const {Disposable} = require('event-kit') +const Errors = require('./errors') + +module.exports = +class SocketClusterPubSubGateway { + constructor ({}) { + this.socketClusterClient = createDisconnectedSocketClusterClient() + } + + async subscribe (channelName, eventName, callback) { + channelName = channelName.replace(/\//g, '.') + let eventChannel = this.socketClusterClient.subscribe(`${channelName}.${eventName}`); + + eventChannel.watch(callback); + + return new Disposable(() => { + this.socketClusterClient.unsubscribe(`${channelName}.${eventName}`) + }) + } +} + +function createDisconnectedSocketClusterClient () { + const options = { + port: 8000 + }; + + const socket = socketCluster.create(options); + return socket +} diff --git a/lib/teletype-client.js b/lib/teletype-client.js index 05b7964..c995d64 100644 --- a/lib/teletype-client.js +++ b/lib/teletype-client.js @@ -5,6 +5,7 @@ const PeerPool = require('./peer-pool') const Portal = require('./portal') const Errors = require('./errors') const PusherPubSubGateway = require('./pusher-pub-sub-gateway') +const SocketClusterPubSubGateway = require('./socketcluster-pub-sub-gateway') const RestGateway = require('./rest-gateway') const {Emitter} = require('event-kit') const NOOP = () => {} @@ -13,9 +14,21 @@ const LOCAL_PROTOCOL_VERSION = 9 module.exports = class TeletypeClient { - constructor ({restGateway, pubSubGateway, connectionTimeout, tetherDisconnectWindow, testEpoch, pusherKey, pusherOptions, baseURL, didCreateOrJoinPortal}) { + constructor ({restGateway, pubSubGateway, connectionTimeout, tetherDisconnectWindow, testEpoch, activePubSubGateway, pusherKey, pusherOptions, baseURL, didCreateOrJoinPortal}) { + function getActivePubSubGateway(activePubSubGateway) { + switch(activePubSubGateway) { + case 'socketcluster': + return new SocketClusterPubSubGateway({}) + break; + + case 'pusher': + default: + return new PusherPubSubGateway({key: pusherKey, options: pusherOptions}) + break; + } + } this.restGateway = restGateway || new RestGateway({baseURL}) - this.pubSubGateway = pubSubGateway || new PusherPubSubGateway({key: pusherKey, options: pusherOptions}) + this.pubSubGateway = pubSubGateway || getActivePubSubGateway(activePubSubGateway) this.connectionTimeout = connectionTimeout || 5000 this.tetherDisconnectWindow = tetherDisconnectWindow || DEFAULT_TETHER_DISCONNECT_WINDOW this.testEpoch = testEpoch diff --git a/package-lock.json b/package-lock.json index 893e8f5..2b6245e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -171,6 +171,11 @@ "lodash": "^4.14.0" } }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -195,6 +200,11 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" + }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -385,6 +395,11 @@ } } }, + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -412,6 +427,11 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1450,6 +1470,11 @@ "invert-kv": "^1.0.0" } }, + "linked-list": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-0.1.0.tgz", + "integrity": "sha1-eYsP+X0bkqT9CEgPVa6k6dSdN78=" + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -2238,6 +2263,11 @@ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", "dev": true }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -2506,6 +2536,24 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "sc-channel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", + "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", + "requires": { + "component-emitter": "1.2.1" + } + }, + "sc-errors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-1.4.0.tgz", + "integrity": "sha512-h+jRWx/xRJmkPFDd0IltoTl/QJ6hAr5Y+3ZVeBQRLuWZKe+dHdf2uVwFp2OYqlLQ7GHht4y9eXG2zOf2Ik6PTw==" + }, + "sc-formatter": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.2.tgz", + "integrity": "sha512-9PbqYBpCq+OoEeRQ3QfFIGE6qwjjBcd2j7UjgDlhnZbtSnuGgHdcRklPKYGuYFH82V/dwd+AIpu8XvA1zqTd+A==" + }, "sdp": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.7.0.tgz", @@ -2637,6 +2685,23 @@ "hoek": "2.x.x" } }, + "socketcluster-client": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-13.0.0.tgz", + "integrity": "sha512-Fdgm6j0TgdXIkVrMI2oBzjW6WL22HmGaX6Uky5I/DmhfJGAu9hoG45VnBxUf+jE+ciZHx5NHorSp00A1YMLvCw==", + "requires": { + "base-64": "0.1.0", + "clone": "2.1.1", + "component-emitter": "1.2.1", + "linked-list": "0.1.0", + "querystring": "0.2.0", + "sc-channel": "^1.2.0", + "sc-errors": "^1.4.0", + "sc-formatter": "^3.0.1", + "uuid": "3.2.1", + "ws": "5.1.1" + } + }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", @@ -3094,6 +3159,14 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "ws": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.1.1.tgz", + "integrity": "sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", diff --git a/package.json b/package.json index 2188e47..f6fb459 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "event-kit": "^2.3.0", "google-protobuf": "^3.5.0", "pusher-js": "^4.2.2", + "socketcluster-client": "^13.0.0", "uuid": "^3.2.1", "webrtc-adapter": "~6.1" },