<commit_before>

/**
 * Module dependencies.
 */

'use strict';

module.exports = function(io){

	var surge = new Surge();

	io.on('connection', function(socket) {
		surge.clients[socket.id] = socket;
		//	Send socketid to client so that he can reference himself
		// 	Check if valid for persistance.
		surge.emit(socket,'open',socket.id);
		
		socket.on('data', function(message) {
			if(message){
				surge.catchEvent(JSON.parse(message),socket);
			}
		});

		socket.on('close', function() {
			//remove client that disconnected from the socket
			surge.removeClient(socket)
		});
	});
}

function Surge(){
	this.clients = {};
	this.channels = {};
	this.events = [];
	this.init();
};

Surge.prototype.on = function(name,callback){
	if(!this.events[name]) {
		this.events[name] = [];
	}
	// Append event
	this.events[name].push(callback);
};

Surge.prototype.catchEvent = function(response,socket) {
	var _events = this.events[response.name];
	if(_events) {
		var parsed = (typeof(response) === "object" && response !== null) ? response : response;
		for(var i=0, l=_events.length; i<l; ++i) {
			var fct = _events[i];
			if(typeof(fct) === "function") {
				// Defer call on setTimeout
				(function(f) {
				    setTimeout(function() {f(parsed,socket);}, 0);
				})(fct);
			}
		}
	}
	//Not a known event name
	else{
		this.broadcast(socket,response.channel,response.name,response.message,response.broadcast);
	}
};

//Default functionallity for the surge server. For now its only for subscribing / unsubscribing
Surge.prototype.init = function(socket){
	var _this = this;
	this.on('surge-subscribe',function(data,socket){
		_this.subscribe(socket,data.message.room);
	});
	this.on('surge-unsubscribe',function(data,socket){
		_this.unsubscribe(socket,data.message.room);
	});
};

Surge.prototype.subscribe = function(socket,room){
	if(!room){
		this.emit(socket,'surge-error','You need to provide a valid room');
		return
	}
	if(!this.channels[room]){
		this.channels[room] = {
			subscribers : {}
		}
	}
	this.channels[room].subscribers[socket] = socket;

	var channel = Object.size(this.channels[room].subscribers);
	this.emit(socket,'surge-joined-room',{room:room,subscribers:channel});
	this.broadcast(socket,room,'member-joined',{room:room,subscribers:channel});
};

Surge.prototype.unsubscribe = function(socket,room){
	if(!this.channels[room]){
		this.emit(socket,'surge-error','There is no such room or this user is not subscribed for this room');
		return;
	}
	delete this.channels[room].subscribers[socket];
	var channel = Object.size(this.channels[room].subscribers);
	this.emit(socket,'surge-left-room',{room:room});
	this.broadcast(socket,room,'member-left',{room:room,subscribers:channel});
};

// Broadcast to all clients of a channel if provided, or to all connected sockets
Surge.prototype.broadcast = function(sender,channel,name,message,sendToSelf){<commit_msg>will not try to delete channels that dont exist and will not add channels that exist already<commit_after>

/**
 * Module dependencies.
 */

'use strict';

module.exports = function(io){

	var surge = new Surge();

	io.on('connection', function(socket) {
		surge.clients[socket.id] = socket;
		//	Send socketid to client so that he can reference himself
		// 	Check if valid for persistance.
		surge.emit(socket,'open',socket.id);
		
		socket.on('data', function(message) {
			if(message){
				surge.catchEvent(JSON.parse(message),socket);
			}
		});

		socket.on('close', function() {
			//remove client that disconnected from the socket
			surge.removeClient(socket)
		});
	});
}

function Surge(){
	this.clients = {};
	this.channels = {};
	this.events = [];
	this.init();
};

Surge.prototype.on = function(name,callback){
	if(!this.events[name]) {
		this.events[name] = [];
	}
	// Append event
	this.events[name].push(callback);
};

Surge.prototype.catchEvent = function(response,socket) {
	var _events = this.events[response.name];
	if(_events) {
		var parsed = (typeof(response) === "object" && response !== null) ? response : response;
		for(var i=0, l=_events.length; i<l; ++i) {
			var fct = _events[i];
			if(typeof(fct) === "function") {
				// Defer call on setTimeout
				(function(f) {
				    setTimeout(function() {f(parsed,socket);}, 0);
				})(fct);
			}
		}
	}
	//Not a known event name
	else{
		this.broadcast(socket,response.channel,response.name,response.message,response.broadcast);
	}
};

//Default functionallity for the surge server. For now its only for subscribing / unsubscribing
Surge.prototype.init = function(socket){
	var _this = this;
	this.on('surge-subscribe',function(data,socket){
		_this.subscribe(socket,data.message.room);
	});
	this.on('surge-unsubscribe',function(data,socket){
		_this.unsubscribe(socket,data.message.room);
	});
};

Surge.prototype.subscribe = function(socket,room){
	if(!room){
		this.emit(socket,'surge-error','You need to provide a valid room');
		return
	}
	if(!this.channels[room]){
		this.channels[room] = {
			subscribers : {}
		}
	}
	//If socket is already subscribed , dont subscribe it again
	if(!this.channels[room].subscribers[socket]){
		this.channels[room].subscribers[socket] = socket;

		var channel = Object.size(this.channels[room].subscribers);
		this.emit(socket,'surge-joined-room',{room:room,subscribers:channel});
		this.broadcast(socket,room,'member-joined',{room:room,subscribers:channel});
	}
	else{
		this.emit(socket,'surge-error','Socket already subscribed to room');
	}
};

Surge.prototype.unsubscribe = function(socket,room){
	if(!this.channels[room]){
		this.emit(socket,'surge-error','There is no such room or this user is not subscribed for this room');
		return;
	}
	if(this.channels[room].subscribers[socket]){
		delete this.channels[room].subscribers[socket];
		var channel = Object.size(this.channels[room].subscribers);
		this.emit(socket,'surge-left-room',{room:room});
		this.broadcast(socket,room,'member-left',{room:room,subscribers:channel});
	}
	else{
		this.emit(socket,'surge-error','Socket not in room');
	}
};

// Broadcast to all clients of a channel if provided, or to all connected sockets
Surge.prototype.broadcast = function(sender,channel,name,message,sendToSelf){
{'fraction_non_alphanumeric': 0.16482803374432187, 'fraction_numerical': 0.0006489292667099286, 'mean_word_length': 4.745573159366263, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '6456490', 'n_tokens_mistral': 2196, 'n_tokens_neox': 2064, 'n_words': 401}