<commit_before>module.exports = function(sails) {


	/**
	 * Module dependencies.
	 */


	var util = require('../../util');


	/**
	 * Expose Hook definition
	 */

	return {

		// Always ready-- doesn't need to bind any routes
		ready: true,

		initialize: function(cb) {

			// If `views` and `http` hook is not enabled, complain and respond w/ error
			if (!sails.config.hooks.sockets) {
				return cb(new Error('Cannot use `pubsub` hook without the `sockets` hook enabled!'));
			}

			// Augment models with room/socket logic (& bind context)
			for (var identity in sails.models) {
				sails.models[identity] = util.defaults(sails.models[identity], pubsub() );
				util.bindAll(sails.models[identity], 'subscribe', 'introduce', 'unsubscribe', 'publish', 'room', 'publishCreate', 'publishUpdate', 'publishDestroy');
			}

			cb();
		}
	};

	/**
	 * These methods get appended to the Model class objects
	 * They take in the request object as an argument in order to 
	 * get access to the user's socket
	 */

	function pubsub () {

		return {



			/**
			* Introduce a new instance 
			*
			* (1)	Take all of the subscribers to the class room and 'introduce' them 
			*		to a new instance room
			*
			* (2)	Then subscribe the creator (if it's a socket) to the new instance room
			*/
			introduce: function (id, socket) {
				var my = this;
				sails.log.verbose("Introduced model "+my.room(id));
				util.each(this.subscribers(),function (socket) {
					socket.join( my.room(id) );
				});

				if (socket && socket.broadcast) {
					this.subscribe(socket, id);
				}
			},



			/**
			* Broadcast a message to sockets connected to the specified models
			* (or null to broadcast to the entire class room)
			*
			* @param {Socket} socket - if specified, broadcast using this 
			* socket (effectively omitting it)
			*/

			publish: function (models, message, socket) {
				var my = this;

				// If no models provided, publish to the class room
				if (!models) {

					sails.log.verbose("Published "+message+" to "+my.classRoom());
					if (socket) {
						try {
							socket.broadcast.to( my.classRoom() ).json.send(message);
							return;
						}
						catch (e) {}
					}
					sails.io.sockets['in']( my.classRoom() ).json.send(message);
				}
				// Otherwise publish to each instance room
				else {
					models = this.pluralize(models);
					var ids = util.pluck(models,'id');
					util.each(ids,function eachInstance (id) {

						sails.log.verbose("Published "+message+" to "+my.room(id));
						if (socket && socket.broadcast) {
							socket.broadcast.to( my.classRoom() ).json.send(message);
							return;
						}
						sails.io.sockets['in']( my.room(id) ).json.send(message);
					});
				}
			},

			// Check that models are a list, if not, make them a list
			pluralize: function (models) {
				if (!util.isArray(models)) {

					// Convert id into simple object
					if (util.isFinite(models)) {
						var id = models;
						return [{ id: id }];
					}

					else if (!util.isDictionary(models)) {
						sails.log.error("Trying to pluralize invalid model(s)! "+models);
						return models;
					}

					// If `models` is a non-array object, 
					// turn it into a single-item array ("pluralize" it)
					else return [models];
				}
				else return models;
			},

			// Return the room name for an instance in this collection with the given id
			room: function (id) {
				if (!id) return this.classRoom();
				return 'sails_c_'+this.identity+'_'+id;
			},

			classRoom: function () {<commit_msg>Fixed pluralization to allow more flexibility around the pubsub/socket api<commit_after>module.exports = function(sails) {


	/**
	 * Module dependencies.
	 */


	var util = require('../../util');


	/**
	 * Expose Hook definition
	 */

	return {

		// Always ready-- doesn't need to bind any routes
		ready: true,

		initialize: function(cb) {

			// If `views` and `http` hook is not enabled, complain and respond w/ error
			if (!sails.config.hooks.sockets) {
				return cb(new Error('Cannot use `pubsub` hook without the `sockets` hook enabled!'));
			}

			// Augment models with room/socket logic (& bind context)
			for (var identity in sails.models) {
				sails.models[identity] = util.defaults(sails.models[identity], pubsub() );
				util.bindAll(sails.models[identity], 'subscribe', 'introduce', 'unsubscribe', 'publish', 'room', 'publishCreate', 'publishUpdate', 'publishDestroy');
			}

			cb();
		}
	};

	/**
	 * These methods get appended to the Model class objects
	 * They take in the request object as an argument in order to 
	 * get access to the user's socket
	 */

	function pubsub () {

		return {



			/**
			* Introduce a new instance 
			*
			* (1)	Take all of the subscribers to the class room and 'introduce' them 
			*		to a new instance room
			*
			* (2)	Then subscribe the creator (if it's a socket) to the new instance room
			*/
			introduce: function (id, socket) {
				var my = this;
				sails.log.verbose("Introduced model "+my.room(id));
				util.each(this.subscribers(),function (socket) {
					socket.join( my.room(id) );
				});

				if (socket && socket.broadcast) {
					this.subscribe(socket, id);
				}
			},



			/**
			* Broadcast a message to sockets connected to the specified models
			* (or null to broadcast to the entire class room)
			*
			* @param {Socket} socket - if specified, broadcast using this 
			* socket (effectively omitting it)
			*/

			publish: function (models, message, socket) {
				var my = this;

				// If no models provided, publish to the class room
				if (!models) {

					sails.log.verbose("Published "+message+" to "+my.classRoom());
					if (socket) {
						try {
							socket.broadcast.to( my.classRoom() ).json.send(message);
							return;
						}
						catch (e) {}
					}
					sails.io.sockets['in']( my.classRoom() ).json.send(message);
				}
				// Otherwise publish to each instance room
				else {
					models = this.pluralize(models);
					var ids = util.pluck(models,'id');
					util.each(ids,function eachInstance (id) {

						sails.log.verbose("Published "+message+" to "+my.room(id));
						if (socket && socket.broadcast) {
							socket.broadcast.to( my.classRoom() ).json.send(message);
							return;
						}
						sails.io.sockets['in']( my.room(id) ).json.send(message);
					});
				}
			},

			// Check that models are a list, if not, make them a list
			pluralize: function (models) {
				
				// If `models` is a non-array object, 
				// turn it into a single-item array ("pluralize" it)
				if (!util.isArray(models)) {
					var model = models;
					models = [model];
				}

				return _.map(models, function (model) {

					// Convert id into simple object
					if ( !util.isDictionary(model) ) {
						var id = model;
						return { id: id };
					}
					
					return model;
				});
			},

			// Return the room name for an instance in this collection with the given id
			room: function (id) {
				if (!id) return this.classRoom();
				return 'sails_c_'+this.identity+'_'+id;
			},

			classRoom: function () {
{'fraction_non_alphanumeric': 0.13698241633579125, 'fraction_numerical': 0.0005672149744753262, 'mean_word_length': 2.6076726342710996, 'pattern_counts': {'":': 0, '<': 3, '<?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': '4088807', 'n_tokens_mistral': 2825, 'n_tokens_neox': 2152, 'n_words': 683}