/* @flow */

import { bus, config } from '../../core-client.js';
import packer from './../../lib/packer';

const {
	protocol,
	host,
} = config.server;

const poll = 'document' in window && 'createElement' in window.document; // Disable polling in non-web environments, e.g.- react-native

// engine.io needs the userAgent string to be present
if (!global.navigator.userAgent) {
	global.navigator.userAgent = 'React Native';
}

const eio = require('engine.io-client'); // eslint-disable-line import/no-commonjs

let	backOff = 1, client;

function disconnected() {

	/* eslint-disable no-use-before-define */

	if (backOff < 256) {
		backOff *= 2;
	} else {
		backOff = 256;
	}

	bus.emit('change', {
		state: { connectionStatus: 'offline', backOff }
	});

	setTimeout(connect, backOff * 1000);
}

function onMessage(message) {
	const frame = packer.decode(message);

	frame.message.source = 'server';
	bus.emit(frame.type, frame.message);
}

function connect() {

	client = new eio.Socket((protocol === 'https:' ? 'wss:' : 'ws:') + '//' + host, {
		jsonp: poll,
		transports: poll ? [ 'polling', 'websocket' ] : [ 'websocket' ]
	});

	client.on('close', disconnected);

	client.on('open', () => {
		backOff = 1;
		bus.emit('change', {
			state: { connectionStatus: 'online', backOff }
		});
	});

	client.on('message', onMessage);
}

bus.on('postchange', changes => {
	if (changes.source === 'server') return;

	const { queries, entities, auth } = changes;

	if (queries || entities || auth) {
		client.send(packer.encode({
			queries,
			entities,
			auth
		}));
	}
});

bus.on('state:init', state => {
	state.connectionStatus = 'connecting';
	connect();
});

@@ -1361,16 +1361,36 @@
 es =%3E %7B%0A
+%09const frame = %7B%7D;%0A%0A
 %09if (cha
@@ -1429,33 +1429,30 @@
 ;%0A%0A%09
-const %7B 
+%5B '
 queries
+'
 , 
+'
 entities
 , au
@@ -1451,131 +1451,151 @@
 ties
+'
 , 
+'
 auth
- %7D = changes;%0A%0A%09if (queries %7C%7C entities %7C%7C auth) %7B%0A%09%09client.send(packer.encode(%7B%0A%09%09%09queries,%0A%09%09%09entities,%0A%09%09%09auth%0A%09%09%7D
+' %5D.forEach(e =%3E %7B%0A%09%09if (e in changes) frame%5Be%5D = changes%5Be%5D;%0A%09%7D);%0A%0A%09if (Object.keys(frame).length) %7B%0A%09%09client.send(packer.encode(frame
 ));%0A

Fix sending undefined as part of changes to server