<commit_before>(function () {

var socket, attempts, attemptTimer;

window.send = function (msg) {
	if (connSM.state != 'synced' && connSM.state != 'syncing')
		return;
	msg = JSON.stringify(msg);
	if (DEBUG)
		console.log('<', msg);
	socket.send(msg);
};

function on_message(e) {
	if (DEBUG)
		console.log('>', e.data);
	var msgs = JSON.parse(e.data);

	with_dom(function () {

	for (var i = 0; i < msgs.length; i++) {
		var msg = msgs[i];
		var op = msg.shift();
		var type = msg.shift();
		if (is_pubsub(type) && op in syncs)
			syncs[op]++;
		dispatcher[type](msg, op);
	}

	});
}

function sync_status(msg, hover) {
	$('#sync').text(msg).attr('class', hover ? 'error' : '');
}

connSM.act('load + start -> conn', function () {
	sync_status('Connecting...', false);
	attempts = 0;
	connect();
});

function connect() {
	socket = new SockJS(SOCKET_PATH);
	socket.onopen = connSM.feeder('open');
	socket.onclose = connSM.feeder('close');
	socket.onmessage = on_message;
}

connSM.act('conn, reconn + open -> syncing', function () {
	sync_status('Syncing...', false);
	sessionId = random_id();
	send([SYNCHRONIZE, sessionId, BOARD, syncs, BUMP, document.cookie]);
});

connSM.act('syncing + sync -> synced', function () {
	sync_status('Synced.', false);
	attemptTimer = setTimeout(function () {
		attempts = 0;
	}, 10000);
});

connSM.act('* + close -> dropped', function (e) {
	if (DEBUG)
		console.error('E:', e);
	if (attemptTimer) {
		clearTimeout(attemptTimer);
		attemptTimer = 0;
	}
	sync_status('Dropped.', true);
	if (attempts++ < 10)
		setTimeout(connSM.feeder('retry'), 250 * Math.pow(2,attempts));
});

connSM.act('dropped + retry -> reconn', function () {
	sync_status('Dropped. Reconnecting...', true);
	connect();
});

connSM.act('* + invalid, desynced + close -> desynced', function (msg) {
	msg = (msg && msg[0]) ? 'Out of sync: ' + msg[0] : 'Out of sync.';
	sync_status(msg, true);
	if (attemptTimer) {
		clearTimeout(attemptTimer);
		attemptTimer = 0;
	}
	delete socket.onclose;
	socket.close();
	socket = null;
});

$(connSM.feeder('start'));

})();
<commit_msg>Always try to reconnect on window focus<commit_after>(function () {

var socket, attempts, attemptTimer;

window.send = function (msg) {
	if (connSM.state != 'synced' && connSM.state != 'syncing')
		return;
	msg = JSON.stringify(msg);
	if (DEBUG)
		console.log('<', msg);
	socket.send(msg);
};

function on_message(e) {
	if (DEBUG)
		console.log('>', e.data);
	var msgs = JSON.parse(e.data);

	with_dom(function () {

	for (var i = 0; i < msgs.length; i++) {
		var msg = msgs[i];
		var op = msg.shift();
		var type = msg.shift();
		if (is_pubsub(type) && op in syncs)
			syncs[op]++;
		dispatcher[type](msg, op);
	}

	});
}

function sync_status(msg, hover) {
	$('#sync').text(msg).attr('class', hover ? 'error' : '');
}

connSM.act('load + start -> conn', function () {
	sync_status('Connecting...', false);
	attempts = 0;
	connect();
});

function connect() {
	socket = new SockJS(SOCKET_PATH);
	socket.onopen = connSM.feeder('open');
	socket.onclose = connSM.feeder('close');
	socket.onmessage = on_message;
}

connSM.act('conn, reconn + open -> syncing', function () {
	sync_status('Syncing...', false);
	sessionId = random_id();
	send([SYNCHRONIZE, sessionId, BOARD, syncs, BUMP, document.cookie]);
});

connSM.act('syncing + sync -> synced', function () {
	sync_status('Synced.', false);
	attemptTimer = setTimeout(function () {
		attempts = 0;
	}, 10000);
});

connSM.act('* + close -> dropped', function (e) {
	if (DEBUG)
		console.error('E:', e);
	if (attemptTimer) {
		clearTimeout(attemptTimer);
		attemptTimer = 0;
	}
	sync_status('Dropped.', true);
	if (attempts++ < 10)
		setTimeout(connSM.feeder('retry'), 250 * Math.pow(2,attempts));
});

connSM.act('dropped + retry -> reconn', function () {
	sync_status('Dropped. Reconnecting...', true);
	connect();
});

connSM.act('* + invalid, desynced + close -> desynced', function (msg) {
	msg = (msg && msg[0]) ? 'Out of sync: ' + msg[0] : 'Out of sync.';
	sync_status(msg, true);
	if (attemptTimer) {
		clearTimeout(attemptTimer);
		attemptTimer = 0;
	}
	delete socket.onclose;
	socket.close();
	socket = null;
});

$(connSM.feeder('start'));

$(function () {
	$(window).focus(function () {
		setTimeout(connSM.feeder('retry'), 20);
	});
});

})();

{'fraction_non_alphanumeric': 0.20778010715117634, 'fraction_numerical': 0.008851618914511996, 'mean_word_length': 4.314356435643564, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3571097', 'n_tokens_mistral': 1698, 'n_tokens_neox': 1604, 'n_words': 344}