summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke "Jared" Bennett <lbennett@gitlab.com>2017-05-20 20:05:31 +0100
committerLuke "Jared" Bennett <lbennett@gitlab.com>2017-05-20 20:56:10 +0100
commit71c859616524a5af903d3c736e93d7655e8a144d (patch)
treeb09dbfcf20fe8230fb5e9b38e206ce0a5abb7623
parentf5f99c9037e52392ca388b6e839d93df88421c31 (diff)
downloadgitlab-ce-sockets-frontend.tar.gz
Added SocketManager, SubscriptionStore, Subscription, VisibilitySocketManager and refactored currently instances of Pollsockets-frontend
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js29
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue29
-rw-r--r--app/assets/javascripts/issue_show/services/index.js16
-rw-r--r--app/assets/javascripts/lib/utils/poll.js105
-rw-r--r--app/assets/javascripts/lib/utils/socket/socket_manager.js108
-rw-r--r--app/assets/javascripts/lib/utils/socket/subscription.js68
-rw-r--r--app/assets/javascripts/lib/utils/socket/subscription_store.js27
-rw-r--r--app/assets/javascripts/lib/utils/socket/visibility_socket_manager.js24
-rw-r--r--app/assets/javascripts/pipelines/components/graph/graph_component.vue22
-rw-r--r--app/assets/javascripts/pipelines/pipelines.js28
-rw-r--r--package.json2
-rw-r--r--spec/javascripts/lib/utils/poll_spec.js175
-rw-r--r--yarn.lock90
13 files changed, 329 insertions, 394 deletions
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js
index 98698143d22..1a9ceb5a102 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js
@@ -1,5 +1,4 @@
import Vue from 'vue';
-import Visibility from 'visibilityjs';
import pipelinesTableComponent from '../../vue_shared/components/pipelines_table';
import PipelinesService from '../../pipelines/services/pipelines_service';
import PipelineStore from '../../pipelines/stores/pipelines_store';
@@ -9,7 +8,7 @@ import errorState from '../../pipelines/components/error_state.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import '../../lib/utils/common_utils';
import '../../vue_shared/vue_resource_interceptor';
-import Poll from '../../lib/utils/poll';
+import VisibilitySocketManager from '../../lib/utils/socket/visibility_socket_manager';
/**
*
@@ -90,29 +89,9 @@ export default Vue.component('pipelines-table', {
this.helpPagePath = element.dataset.helpPagePath;
this.service = new PipelinesService(this.endpoint);
- this.poll = new Poll({
- resource: this.service,
- method: 'getPipelines',
- successCallback: this.successCallback,
+ this.subscription = VisibilitySocketManager.subscribe(this.endpoint, null, {
+ updateCallback: this.successCallback,
errorCallback: this.errorCallback,
- notificationCallback: this.setIsMakingRequest,
- });
-
- if (!Visibility.hidden()) {
- this.isLoading = true;
- this.poll.makeRequest();
- } else {
- // If tab is not visible we need to make the first request so we don't show the empty
- // state without knowing if there are any pipelines
- this.fetchPipelines();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- this.poll.restart();
- } else {
- this.poll.stop();
- }
});
eventHub.$on('refreshPipelines', this.fetchPipelines);
@@ -123,7 +102,7 @@ export default Vue.component('pipelines-table', {
},
destroyed() {
- this.poll.stop();
+ VisibilitySocketManager.remove(this.subscription);
},
methods: {
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index 770a0dcd27e..50853c79afd 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -1,7 +1,5 @@
<script>
-import Visibility from 'visibilityjs';
-import Poll from '../../lib/utils/poll';
-import Service from '../services/index';
+import VisibilitySocketManager from '../../lib/utils/socket/visibility_socket_manager';
import Store from '../stores';
import titleComponent from './title.vue';
import descriptionComponent from './description.vue';
@@ -52,29 +50,14 @@ export default {
titleComponent,
},
created() {
- const resource = new Service(this.endpoint);
- const poll = new Poll({
- resource,
- method: 'getData',
- successCallback: (res) => {
- this.store.updateState(res.json());
+ VisibilitySocketManager.subscribe(this.endpoint, null, {
+ updateCallback: (response) => {
+ this.store.updateState(response.json());
},
- errorCallback(err) {
- throw new Error(err);
+ errorCallback(error) {
+ throw new Error(error);
},
});
-
- if (!Visibility.hidden()) {
- poll.makeRequest();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- poll.restart();
- } else {
- poll.stop();
- }
- });
},
};
</script>
diff --git a/app/assets/javascripts/issue_show/services/index.js b/app/assets/javascripts/issue_show/services/index.js
deleted file mode 100644
index 348ad8d6813..00000000000
--- a/app/assets/javascripts/issue_show/services/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Vue from 'vue';
-import VueResource from 'vue-resource';
-
-Vue.use(VueResource);
-
-export default class Service {
- constructor(endpoint) {
- this.endpoint = endpoint;
-
- this.resource = Vue.resource(this.endpoint);
- }
-
- getData() {
- return this.resource.get();
- }
-}
diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js
deleted file mode 100644
index e31cc5fbabe..00000000000
--- a/app/assets/javascripts/lib/utils/poll.js
+++ /dev/null
@@ -1,105 +0,0 @@
-import httpStatusCodes from './http_status';
-
-/**
- * Polling utility for handling realtime updates.
- * Service for vue resouce and method need to be provided as props
- *
- * @example
- * new Poll({
- * resource: resource,
- * method: 'name',
- * data: {page: 1, scope: 'all'}, // optional
- * successCallback: () => {},
- * errorCallback: () => {},
- * notificationCallback: () => {}, // optional
- * }).makeRequest();
- *
- * Usage in pipelines table with visibility lib:
- *
- * const poll = new Poll({
- * resource: this.service,
- * method: 'getPipelines',
- * data: { page: pageNumber, scope },
- * successCallback: this.successCallback,
- * errorCallback: this.errorCallback,
- * notificationCallback: this.updateLoading,
- * });
- *
- * if (!Visibility.hidden()) {
- * poll.makeRequest();
- * }
- *
- * Visibility.change(() => {
- * if (!Visibility.hidden()) {
- * poll.restart();
- * } else {
- * poll.stop();
- * }
-* });
- *
- * 1. Checks for response and headers before start polling
- * 2. Interval is provided by `Poll-Interval` header.
- * 3. If `Poll-Interval` is -1, we stop polling
- * 4. If HTTP response is 200, we poll.
- * 5. If HTTP response is different from 200, we stop polling.
- *
- */
-export default class Poll {
- constructor(options = {}) {
- this.options = options;
- this.options.data = options.data || {};
- this.options.notificationCallback = options.notificationCallback ||
- function notificationCallback() {};
-
- this.intervalHeader = 'POLL-INTERVAL';
- this.timeoutID = null;
- this.canPoll = true;
- }
-
- checkConditions(response) {
- const headers = gl.utils.normalizeHeaders(response.headers);
- const pollInterval = parseInt(headers[this.intervalHeader], 10);
-
- if (pollInterval > 0 && response.status === httpStatusCodes.OK && this.canPoll) {
- this.timeoutID = setTimeout(() => {
- this.makeRequest();
- }, pollInterval);
- }
- this.options.successCallback(response);
- }
-
- makeRequest() {
- const { resource, method, data, errorCallback, notificationCallback } = this.options;
-
- // It's called everytime a new request is made. Useful to update the status.
- notificationCallback(true);
-
- return resource[method](data)
- .then((response) => {
- this.checkConditions(response);
- notificationCallback(false);
- })
- .catch((error) => {
- notificationCallback(false);
- errorCallback(error);
- });
- }
-
- /**
- * Stops the polling recursive chain
- * and guarantees if the timeout is already running it won't make another request by
- * cancelling the previously established timeout.
- */
- stop() {
- this.canPoll = false;
- clearTimeout(this.timeoutID);
- }
-
- /**
- * Restarts polling after it has been stoped
- */
- restart() {
- this.canPoll = true;
- this.makeRequest();
- }
-}
diff --git a/app/assets/javascripts/lib/utils/socket/socket_manager.js b/app/assets/javascripts/lib/utils/socket/socket_manager.js
new file mode 100644
index 00000000000..2f4f428ebee
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/socket/socket_manager.js
@@ -0,0 +1,108 @@
+import socketIO from 'socket.io-client';
+import Socket from 'socket.io-client/lib/socket';
+import Subscription from './subscription';
+import SubscriptionStore from './subscription_store';
+
+const SocketManager = {
+ socketPath: '',
+ socket: {},
+ store: SubscriptionStore,
+ subscriptionsCount: 0,
+
+ init(socketPath) {
+ this.socketPath = socketPath;
+
+ this.removeAll();
+ },
+
+ connect() {
+ if (this.socket instanceof Socket) return Promise.resolve();
+
+ return new Promise((resolve, reject) => {
+ this.socket = socketIO(this.socketPath);
+
+ this.socket.on('connect', resolve);
+ this.socket.on('connect_error', reject);
+ this.socket.on('connect_timeout', reject);
+ });
+ },
+
+ subscribe(endpointOrSubscription, data, callbacks) {
+ this.connect().then(() => {
+ const subscription = this.getSubscription(endpointOrSubscription, data, callbacks);
+
+ subscription.subscribe();
+
+ return subscription;
+ }).catch((error) => {
+ // temporary
+ // eslint-disable-next-line no-console
+ console.log('connect error', error);
+ });
+ },
+
+ remove(subscription) {
+ subscription.unsubscribe();
+
+ this.store.remove(subscription);
+ },
+
+ unsubscribeAll() {
+ const subscriptions = this.store.getAll();
+
+ if (!subscriptions) return;
+
+ subscriptions.forEach(subscription => subscription.unsubscribe());
+ },
+
+ subscribeAll() {
+ const subscriptions = this.store.getAll();
+
+ if (!subscriptions) return;
+
+ subscriptions.forEach(subscription => subscription.subscribe());
+ },
+
+ removeAll() {
+ this.unsubscribeAll();
+ this.store.removeAll();
+ },
+
+ getSubscription(endpointOrSubscription, data, callbacks) {
+ let subscription;
+
+ if (endpointOrSubscription instanceof Subscription) {
+ subscription = endpointOrSubscription;
+ } else {
+ subscription = this.createSubscription({
+ endpoint: endpointOrSubscription,
+ data,
+ callbacks,
+ });
+ }
+
+ return subscription;
+ },
+
+ createSubscription({
+ endpoint,
+ data,
+ callbacks,
+ }) {
+ this.subscriptionsCount += 1;
+
+ const subscription = new Subscription({
+ endpoint,
+ data,
+ callbacks,
+ socket: this.socket,
+ id: this.subscriptionsCount,
+ });
+
+ this.store.add(subscription);
+
+ return subscription;
+ },
+};
+
+export default SocketManager;
diff --git a/app/assets/javascripts/lib/utils/socket/subscription.js b/app/assets/javascripts/lib/utils/socket/subscription.js
new file mode 100644
index 00000000000..46373a78acb
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/socket/subscription.js
@@ -0,0 +1,68 @@
+class Subscription {
+ constructor({
+ id,
+ endpoint,
+ data,
+ socket,
+ callbacks,
+ }) {
+ this.id = id;
+ this.endpoint = endpoint;
+ this.data = data;
+ this.socket = socket;
+ this.updateCallback = callbacks.updateCallback;
+ this.errorCallback = callbacks.errorCallback;
+
+ this.setPayload();
+ this.setEventNames();
+ }
+
+ subscribe() {
+ this.socket.emit(this.eventNames.subscribe, this.payload, this.acknowledge);
+
+ this.bindListeners();
+ }
+
+ unsubscribe() {
+ this.socket.emit(this.eventNames.unsubscribe, this.payload, this.acknowledge);
+
+ this.unbindListeners();
+ }
+
+ bindListeners() {
+ this.socket.on(this.eventNames.update, this.updateCallback);
+ this.socket.on(this.eventNames.error, this.errorCallback);
+ }
+
+ unbindListeners() {
+ this.socket.removeListener(this.eventNames.update, this.updateCallback);
+ this.socket.removeListener(this.eventNames.error, this.errorCallback);
+ }
+
+ setPayload() {
+ this.payload = {
+ id: this.id,
+ endpoint: this.endpoint,
+ data: this.data,
+ };
+ }
+
+ setEventNames() {
+ this.eventNames = {
+ subscribe: `subscribe:${this.endpoint}`,
+ unsubscribe: `unsubscribe:${this.endpoint}`,
+ update: `update:${this.id}`,
+ error: `error:${this.id}`,
+ };
+ }
+
+ acknowledge(response, ...args) {
+ if (response.error) this.errorCallback(response.error, ...args);
+
+ // temporary
+ // eslint-disable-next-line no-console
+ console.log('ACK', ...args);
+ }
+}
+
+export default Subscription;
diff --git a/app/assets/javascripts/lib/utils/socket/subscription_store.js b/app/assets/javascripts/lib/utils/socket/subscription_store.js
new file mode 100644
index 00000000000..06b43da1360
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/socket/subscription_store.js
@@ -0,0 +1,27 @@
+const SocketStore = {
+ subscriptions: {},
+
+ add(subscription) {
+ this.subscriptions[subscription.id] = subscription;
+
+ return subscription;
+ },
+
+ remove(subscription) {
+ delete this.subscriptions[subscription.id];
+ },
+
+ get(subscriptionID) {
+ return this.subscriptions[subscriptionID];
+ },
+
+ getAll() {
+ Object.values(this.subscriptions);
+ },
+
+ removeAll() {
+ this.subscriptions = {};
+ },
+};
+
+export default SocketStore;
diff --git a/app/assets/javascripts/lib/utils/socket/visibility_socket_manager.js b/app/assets/javascripts/lib/utils/socket/visibility_socket_manager.js
new file mode 100644
index 00000000000..d363ae4bd44
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/socket/visibility_socket_manager.js
@@ -0,0 +1,24 @@
+import SocketManager from './socket_manager';
+
+const VisibilitySocketManager = {
+ init(socketPath) {
+ super.init(socketPath);
+
+ document.addEventListener('visibilitychange', () => this.toggleAllSockets());
+ },
+
+ toggleAllSockets() {
+ if (document.hidden) {
+ super.unsubscribeAll();
+ } else {
+ super.subscribeAll();
+ }
+ },
+};
+
+Object.setPrototypeOf(VisibilitySocketManager, SocketManager);
+
+// temporary
+VisibilitySocketManager.init('/broker');
+
+export default VisibilitySocketManager;
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
index 14c98847d93..f04eeae71ea 100644
--- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
@@ -1,11 +1,10 @@
<script>
/* global Flash */
- import Visibility from 'visibilityjs';
- import Poll from '../../../lib/utils/poll';
import PipelineService from '../../services/pipeline_service';
import PipelineStore from '../../stores/pipeline_store';
import stageColumnComponent from './stage_column_component.vue';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
+ import VisibilitySocketManager from '../../../lib/utils/socket/visibility_socket_manager';
import '../../../flash';
export default {
@@ -29,25 +28,10 @@
created() {
this.service = new PipelineService(this.endpoint);
- const poll = new Poll({
- resource: this.service,
- method: 'getPipeline',
- successCallback: this.successCallback,
+ VisibilitySocketManager.subscribe(this.endpoint, null, {
+ updateCallback: this.successCallback,
errorCallback: this.errorCallback,
});
-
- if (!Visibility.hidden()) {
- this.isLoading = true;
- poll.makeRequest();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- poll.restart();
- } else {
- poll.stop();
- }
- });
},
methods: {
diff --git a/app/assets/javascripts/pipelines/pipelines.js b/app/assets/javascripts/pipelines/pipelines.js
index d6952d1ee5f..18b91556e83 100644
--- a/app/assets/javascripts/pipelines/pipelines.js
+++ b/app/assets/javascripts/pipelines/pipelines.js
@@ -1,4 +1,3 @@
-import Visibility from 'visibilityjs';
import PipelinesService from './services/pipelines_service';
import eventHub from './event_hub';
import pipelinesTableComponent from '../vue_shared/components/pipelines_table';
@@ -8,7 +7,7 @@ import errorState from './components/error_state.vue';
import navigationTabs from './components/navigation_tabs';
import navigationControls from './components/nav_controls';
import loadingIcon from '../vue_shared/components/loading_icon.vue';
-import Poll from '../lib/utils/poll';
+import VisibilitySocketManager from '../lib/utils/socket/visibility_socket_manager';
export default {
props: {
@@ -140,30 +139,9 @@ export default {
created() {
this.service = new PipelinesService(this.endpoint);
- const poll = new Poll({
- resource: this.service,
- method: 'getPipelines',
- data: { page: this.pageParameter, scope: this.scopeParameter },
- successCallback: this.successCallback,
+ VisibilitySocketManager.subscribe(this.endpoint, null, {
+ updateCallback: this.successCallback,
errorCallback: this.errorCallback,
- notificationCallback: this.setIsMakingRequest,
- });
-
- if (!Visibility.hidden()) {
- this.isLoading = true;
- poll.makeRequest();
- } else {
- // If tab is not visible we need to make the first request so we don't show the empty
- // state without knowing if there are any pipelines
- this.fetchPipelines();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- poll.restart();
- } else {
- poll.stop();
- }
});
eventHub.$on('refreshPipelines', this.fetchPipelines);
diff --git a/package.json b/package.json
index 800327d8a08..44527eae584 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"raw-loader": "^0.5.1",
"react-dev-utils": "^0.5.2",
"select2": "3.5.2-browserify",
+ "socket.io-client": "^2.0.1",
"sql.js": "^0.4.0",
"stats-webpack-plugin": "^0.4.3",
"three": "^0.84.0",
@@ -52,7 +53,6 @@
"timeago.js": "^2.0.5",
"underscore": "^1.8.3",
"url-loader": "^0.5.8",
- "visibilityjs": "^1.2.4",
"vue": "^2.2.6",
"vue-loader": "^11.3.4",
"vue-resource": "^0.9.3",
diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js
deleted file mode 100644
index 22f30191ab9..00000000000
--- a/spec/javascripts/lib/utils/poll_spec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-import Poll from '~/lib/utils/poll';
-
-const waitForAllCallsToFinish = (service, waitForCount, successCallback) => {
- const timer = () => {
- setTimeout(() => {
- if (service.fetch.calls.count() === waitForCount) {
- successCallback();
- } else {
- timer();
- }
- }, 0);
- };
-
- timer();
-};
-
-function mockServiceCall(service, response, shouldFail = false) {
- const action = shouldFail ? Promise.reject : Promise.resolve;
- const responseObject = response;
-
- if (!responseObject.headers) responseObject.headers = {};
-
- service.fetch.and.callFake(action.bind(Promise, responseObject));
-}
-
-describe('Poll', () => {
- const service = jasmine.createSpyObj('service', ['fetch']);
- const callbacks = jasmine.createSpyObj('callbacks', ['success', 'error']);
-
- afterEach(() => {
- callbacks.success.calls.reset();
- callbacks.error.calls.reset();
- service.fetch.calls.reset();
- });
-
- it('calls the success callback when no header for interval is provided', (done) => {
- mockServiceCall(service, { status: 200 });
-
- new Poll({
- resource: service,
- method: 'fetch',
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- }).makeRequest();
-
- waitForAllCallsToFinish(service, 1, () => {
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
-
- done();
- });
- });
-
- it('calls the error callback whe the http request returns an error', (done) => {
- mockServiceCall(service, { status: 500 }, true);
-
- new Poll({
- resource: service,
- method: 'fetch',
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- }).makeRequest();
-
- waitForAllCallsToFinish(service, 1, () => {
- expect(callbacks.success).not.toHaveBeenCalled();
- expect(callbacks.error).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('should call the success callback when the interval header is -1', (done) => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': -1 } });
-
- new Poll({
- resource: service,
- method: 'fetch',
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- }).makeRequest().then(() => {
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
-
- done();
- }).catch(done.fail);
- });
-
- it('starts polling when http status is 200 and interval header is provided', (done) => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
-
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- });
-
- Polling.makeRequest();
-
- waitForAllCallsToFinish(service, 2, () => {
- Polling.stop();
-
- expect(service.fetch.calls.count()).toEqual(2);
- expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
-
- done();
- });
- });
-
- describe('stop', () => {
- it('stops polling when method is called', (done) => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
-
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: () => {
- Polling.stop();
- },
- errorCallback: callbacks.error,
- });
-
- spyOn(Polling, 'stop').and.callThrough();
-
- Polling.makeRequest();
-
- waitForAllCallsToFinish(service, 1, () => {
- expect(service.fetch.calls.count()).toEqual(1);
- expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
- expect(Polling.stop).toHaveBeenCalled();
-
- done();
- });
- });
- });
-
- describe('restart', () => {
- it('should restart polling when its called', (done) => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
-
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: () => {
- Polling.stop();
- setTimeout(() => {
- Polling.restart();
- }, 0);
- },
- errorCallback: callbacks.error,
- });
-
- spyOn(Polling, 'stop').and.callThrough();
- spyOn(Polling, 'restart').and.callThrough();
-
- Polling.makeRequest();
-
- waitForAllCallsToFinish(service, 2, () => {
- Polling.stop();
-
- expect(service.fetch.calls.count()).toEqual(2);
- expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
- expect(Polling.stop).toHaveBeenCalled();
- expect(Polling.restart).toHaveBeenCalled();
-
- done();
- });
- });
- });
-});
diff --git a/yarn.lock b/yarn.lock
index 8aac2b1b1cd..1b922ca6e58 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1560,6 +1560,12 @@ debug@2.6.0, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0:
dependencies:
ms "0.7.2"
+debug@2.6.4, debug@~2.6.4:
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.4.tgz#7586a9b3c39741c0282ae33445c4e8ac74734fe0"
+ dependencies:
+ ms "0.7.3"
+
decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -1785,6 +1791,23 @@ engine.io-client@1.8.2:
xmlhttprequest-ssl "1.5.3"
yeast "0.1.2"
+engine.io-client@~3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.1.tgz#415a9852badb14fa008fa3ef1e31608db6761325"
+ dependencies:
+ component-emitter "1.2.1"
+ component-inherit "0.0.3"
+ debug "~2.6.4"
+ engine.io-parser "~2.1.1"
+ has-cors "1.1.0"
+ indexof "0.0.1"
+ parsejson "0.0.3"
+ parseqs "0.0.5"
+ parseuri "0.0.5"
+ ws "~2.3.1"
+ xmlhttprequest-ssl "1.5.3"
+ yeast "0.1.2"
+
engine.io-parser@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a"
@@ -1796,6 +1819,16 @@ engine.io-parser@1.3.2:
has-binary "0.1.7"
wtf-8 "1.0.0"
+engine.io-parser@~2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.1.tgz#e0fb3f0e0462f7f58bb77c1a52e9f5a7e26e4668"
+ dependencies:
+ after "0.8.2"
+ arraybuffer.slice "0.0.6"
+ base64-arraybuffer "0.1.5"
+ blob "0.0.4"
+ has-binary2 "~1.0.2"
+
engine.io@1.8.2:
version "1.8.2"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.2.tgz#6b59be730b348c0125b0a4589de1c355abcf7a7e"
@@ -2580,6 +2613,12 @@ has-ansi@^2.0.0:
dependencies:
ansi-regex "^2.0.0"
+has-binary2@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98"
+ dependencies:
+ isarray "2.0.1"
+
has-binary@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c"
@@ -3000,6 +3039,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+isarray@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
+
isbinaryfile@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621"
@@ -3699,6 +3742,10 @@ ms@0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
+ms@0.7.3:
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
+
mute-stream@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
@@ -4913,7 +4960,7 @@ rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
-safe-buffer@^5.0.1:
+safe-buffer@^5.0.1, safe-buffer@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
@@ -5065,6 +5112,23 @@ socket.io-client@1.7.2:
socket.io-parser "2.3.1"
to-array "0.1.4"
+socket.io-client@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.1.tgz#1d52f8c74660c68bb6695953fa119971155fad93"
+ dependencies:
+ backo2 "1.0.2"
+ base64-arraybuffer "0.1.5"
+ component-bind "1.0.0"
+ component-emitter "1.2.1"
+ debug "2.6.4"
+ engine.io-client "~3.1.0"
+ has-cors "1.1.0"
+ indexof "0.0.1"
+ object-component "0.0.3"
+ parseuri "0.0.5"
+ socket.io-parser "~3.1.1"
+ to-array "0.1.4"
+
socket.io-parser@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0"
@@ -5074,6 +5138,15 @@ socket.io-parser@2.3.1:
isarray "0.0.1"
json3 "3.3.2"
+socket.io-parser@~3.1.1:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2"
+ dependencies:
+ component-emitter "1.2.1"
+ debug "~2.6.4"
+ has-binary2 "~1.0.2"
+ isarray "2.0.1"
+
socket.io@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.2.tgz#83bbbdf2e79263b378900da403e7843e05dc3b71"
@@ -5528,6 +5601,10 @@ ultron@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
+ultron@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864"
+
unc-path-regex@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
@@ -5654,10 +5731,6 @@ verror@1.3.6:
dependencies:
extsprintf "1.0.2"
-visibilityjs@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/visibilityjs/-/visibilityjs-1.2.4.tgz#bff8663da62c8c10ad4ee5ae6a1ae6fac4259d63"
-
vm-browserify@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
@@ -5898,6 +5971,13 @@ ws@1.1.1:
options ">=0.0.5"
ultron "1.0.x"
+ws@~2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80"
+ dependencies:
+ safe-buffer "~5.0.1"
+ ultron "~1.1.0"
+
wtf-8@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"