(function() {
this.LiveRecord || (this.LiveRecord = {});
}).call(this); (function() {
var base; (base = this.LiveRecord).helpers || (base.helpers = {});
}).call(this); (function() {
this.LiveRecord.helpers.caseConverter = { toCamel: function(string) { return string.replace(/(\-[a-z])/g, function($1) { return $1.toUpperCase().replace('-', ''); }); }, toUnderscore: function(string) { return string.replace(/([A-Z])/g, function($1) { return "_" + $1.toLowerCase(); }); } };
}).call(this); (function() {
this.LiveRecord.helpers.loadRecords = function(args) { args['modelName'] || (function() { throw new Error(':modelName argument required'); })(); if (LiveRecord.Model.all[args['modelName']] === void 0) { throw new Error(':modelName is not defined in LiveRecord.Model.all'); } args['url'] || (args['url'] = window.location.href); return $.getJSON(args['url']).done(function(data) { var i, len, record, record_attributes, record_or_records, records, records_attributes; record_or_records = void 0; if ($.isArray(data)) { records_attributes = data; records = []; for (i = 0, len = records_attributes.length; i < len; i++) { record_attributes = records_attributes[i]; record = new LiveRecord.Model.all[args['modelName']](record_attributes); record.create(); records.push(record); } record_or_records = records; } else if (data) { record_attributes = data; record = new LiveRecord.Model.all[args['modelName']](record_attributes); record.create(); record_or_records = record; } if (args['onLoad']) { return args['onLoad'].call(this, record_or_records); } }).fail(function(jqxhr, textStatus, error) { if (args['onError']) { return args['onError'].call(this, jqxhr, textStatus, error); } }); };
}).call(this); (function() {
this.LiveRecord.helpers.spaceship = function(val1, val2) { if (val1 === null || val2 === null || typeof val1 !== typeof val2) { return null; } if (typeof val1 === 'string') { return val1.localeCompare(val2); } else { if (val1 > val2) { return 1; } else if (val1 < val2) { return -1; } return 0; } };
}).call(this); (function() {
var base; (base = this.LiveRecord).init || (base.init = function(cable) { return this.cable = cable; });
}).call(this); (function() {
var base; (base = this.LiveRecord).Model || (base.Model = {});
}).call(this); (function() {
this.LiveRecord.Model.all = {};
}).call(this); (function() {
this.LiveRecord.Model.create = function(config) { var Model, callbackFunction, callbackFunctions, callbackKey, i, index, len, methodKey, methodValue, pluginKey, pluginValue, ref, ref1, ref2, ref3; config.modelName !== void 0 || (function() { throw new Error('missing :modelName argument'); })(); config.callbacks !== void 0 || (config.callbacks = {}); config.plugins !== void 0 || (config.callbacks = {}); Model = function(attributes) { if (attributes == null) { attributes = {}; } this.attributes = attributes; Object.keys(this.attributes).forEach(function(attribute_key) { if (Model.prototype[attribute_key] === void 0) { return Model.prototype[attribute_key] = function() { return this.attributes[attribute_key]; }; } }); this._callbacks = { 'on:connect': [], 'on:disconnect': [], 'on:responseError': [], 'before:create': [], 'after:create': [], 'before:update': [], 'after:update': [], 'before:destroy': [], 'after:destroy': [] }; return this; }; Model.modelName = config.modelName; Model.associations = { hasMany: config.hasMany, belongsTo: config.belongsTo }; if (Model.associations.hasMany) { Object.keys(Model.associations.hasMany).forEach(function(key, index) { var associationConfig, associationName; associationName = key; associationConfig = Model.associations.hasMany[associationName]; return Model.prototype[associationName] = function() { var associatedModel, associatedRecords, id, isAssociated, record, ref, self; self = this; associatedModel = LiveRecord.Model.all[associationConfig.modelName]; if (!associatedModel) { throw new Error('No defined model for "' + associationConfig.modelName + '"'); } associatedRecords = []; ref = associatedModel.all; for (id in ref) { record = ref[id]; isAssociated = record[associationConfig.foreignKey]() === self.id(); if (isAssociated) { associatedRecords.push(record); } } return associatedRecords; }; }); } if (Model.associations.belongsTo) { Object.keys(Model.associations.belongsTo).forEach(function(key, index) { var associationConfig, associationName; associationName = key; associationConfig = Model.associations.belongsTo[associationName]; return Model.prototype[associationName] = function() { var associatedModel, belongsToID, self; self = this; associatedModel = LiveRecord.Model.all[associationConfig.modelName]; if (!associatedModel) { throw new Error('No defined model for "' + associationConfig.modelName + '"'); } belongsToID = self[associationConfig.foreignKey](); return associatedModel.all[belongsToID]; }; }); } Model.all = {}; Model.subscriptions = []; Model.autoload = function(config) { var subscription; if (config == null) { config = {}; } config.callbacks || (config.callbacks = {}); config.reload || (config.reload = false); if (config.callbacks.afterReload && !config.reload) { throw new Error('`afterReload` callback only works with `reload: true`'); } subscription = LiveRecord.cable.subscriptions.create({ channel: 'LiveRecord::AutoloadsChannel', model_name: Model.modelName, where: config.where }, { connected: function() { if (config.reload) { config.reload = false; this.syncRecords(); } if (this.liveRecord._staleSince !== void 0) { this.syncRecords(); } if (config.callbacks['on:connect']) { return config.callbacks['on:connect'].call(this); } }, disconnected: function() { if (!this.liveRecord._staleSince) { this.liveRecord._staleSince = (new Date()).toISOString(); } if (config.callbacks['on:disconnect']) { return config.callbacks['on:disconnect'].call(this); } }, received: function(data) { if (data.error) { if (!this.liveRecord._staleSince) { this.liveRecord._staleSince = (new Date()).toISOString(); } return this.onError[data.error.code].call(this, data); } else { return this.onAction[data.action].call(this, data); } }, onAction: { createOrUpdate: function(data) { var doesRecordAlreadyExist, record; record = Model.all[data.attributes.id]; if (record) { doesRecordAlreadyExist = true; } else { record = new Model(data.attributes); doesRecordAlreadyExist = false; } if (config.callbacks['before:createOrUpdate']) { config.callbacks['before:createOrUpdate'].call(this, record); } if (doesRecordAlreadyExist) { record.update(data.attributes); } else { record.create(); } if (config.callbacks['after:createOrUpdate']) { return config.callbacks['after:createOrUpdate'].call(this, record); } }, afterReload: function(data) { if (config.callbacks['after:reload']) { return config.callbacks['after:reload'].call(this, data.recordIds); } } }, onError: { forbidden: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this); }, bad_request: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this); } }, syncRecords: function() { this.perform('sync_records', { model_name: Model.modelName, where: config.where, stale_since: this.liveRecord._staleSince }); return this.liveRecord._staleSince = void 0; } }); subscription.liveRecord = {}; subscription.liveRecord.modelName = Model.modelName; subscription.liveRecord.where = config.where; subscription.liveRecord.callbacks = config.callbacks; this.subscriptions.push(subscription); return subscription; }; Model.subscribe = function(config) { var subscription; if (config == null) { config = {}; } config.callbacks || (config.callbacks = {}); config.reload || (config.reload = false); if (config.callbacks.afterReload && !config.reload) { throw new Error('`afterReload` callback only works with `reload: true`'); } subscription = LiveRecord.cable.subscriptions.create({ channel: 'LiveRecord::PublicationsChannel', model_name: Model.modelName, where: config.where }, { connected: function() { if (config.reload) { config.reload = false; this.syncRecords(); } if (this.liveRecord._staleSince !== void 0) { this.syncRecords(); } if (config.callbacks['on:connect']) { return config.callbacks['on:connect'].call(this); } }, disconnected: function() { if (!this.liveRecord._staleSince) { this.liveRecord._staleSince = (new Date()).toISOString(); } if (config.callbacks['on:disconnect']) { return config.callbacks['on:disconnect'].call(this); } }, received: function(data) { if (data.error) { if (!this.liveRecord._staleSince) { this.liveRecord._staleSince = (new Date()).toISOString(); } return this.onError[data.error.code].call(this, data); } else { return this.onAction[data.action].call(this, data); } }, onAction: { create: function(data) { var record; record = new Model(data.attributes); if (config.callbacks['before:create']) { config.callbacks['before:create'].call(this, record); } record.create(); if (config.callbacks['after:create']) { return config.callbacks['after:create'].call(this, record); } }, afterReload: function(data) { if (config.callbacks['after:reload']) { return config.callbacks['after:reload'].call(this, data.recordIds); } } }, onError: { forbidden: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this); }, bad_request: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this); } }, syncRecords: function() { this.perform('sync_records', { model_name: Model.modelName, where: config.where, stale_since: this.liveRecord._staleSince }); return this.liveRecord._staleSince = void 0; } }); subscription.liveRecord = {}; subscription.liveRecord.modelName = Model.modelName; subscription.liveRecord.where = config.where; subscription.liveRecord.callbacks = config.callbacks; this.subscriptions.push(subscription); return subscription; }; Model.unsubscribe = function(subscription) { var index; index = this.subscriptions.indexOf(subscription); if (index === -1) { throw new Error('`subscription` argument does not exist in ' + this.modelName + ' subscriptions list'); } LiveRecord.cable.subscriptions.remove(subscription); this.subscriptions.splice(index, 1); return subscription; }; ref = config.classMethods; for (methodKey in ref) { methodValue = ref[methodKey]; if (Model[methodKey] !== void 0) { throw new Error('Cannot use reserved name as class method: ', methodKey); } Model[methodKey] = methodValue; } Model.prototype.subscribe = function(config) { var subscription; if (config == null) { config = {}; } if (this.subscription !== void 0) { return this.subscription; } config.reload || (config.reload = false); subscription = App['live_record_' + this.modelName() + '_' + this.id()] = LiveRecord.cable.subscriptions.create({ channel: 'LiveRecord::ChangesChannel', model_name: this.modelName(), record_id: this.id() }, { record: function() { var identifier; if (this._record) { return this._record; } identifier = JSON.parse(this.identifier); return this._record = Model.all[identifier.record_id]; }, connected: function() { if (config.reload) { config.reload = false; this.syncRecord(this.record()); } if (this.record()._staleSince !== void 0) { this.syncRecord(this.record()); } return this.record()._callCallbacks('on:connect', void 0); }, disconnected: function() { if (!this.record()._staleSince) { this.record()._staleSince = (new Date()).toISOString(); } return this.record()._callCallbacks('on:disconnect', void 0); }, received: function(data) { if (data.error) { if (!this.record()._staleSince) { this.record()._staleSince = (new Date()).toISOString(); } this.onError[data.error.code].call(this, data); this.record()._callCallbacks('on:responseError', [data.error.code]); return delete this.record()['subscription']; } else { return this.onAction[data.action].call(this, data); } }, onAction: { update: function(data) { this.record()._setChangesFrom(data.attributes); this.record().update(data.attributes); return this.record()._unsetChanges(); }, destroy: function(data) { return this.record().destroy(); } }, onError: { forbidden: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this.record()); }, bad_request: function(data) { return console.error('[LiveRecord Response Error]', data.error.code, ':', data.error.message, 'for', this.record()); } }, syncRecord: function() { this.perform('sync_record', { model_name: this.record().modelName(), record_id: this.record().id(), stale_since: this.record()._staleSince }); return this.record()._staleSince = void 0; } }); return this.subscription = subscription; }; Model.prototype.model = function() { return Model; }; Model.prototype.modelName = function() { return Model.modelName; }; Model.prototype.unsubscribe = function() { if (this.subscription === void 0) { return; } LiveRecord.cable.subscriptions.remove(this.subscription); return delete this['subscription']; }; Model.prototype.isSubscribed = function() { return this.subscription !== void 0; }; Model.prototype.create = function(options) { if (Model.all[this.attributes.id]) { throw new Error(Model.modelName + '(' + this.id() + ') is already in the store'); } this._callCallbacks('before:create', void 0); Model.all[this.attributes.id] = this; this.subscribe({ reload: true }); this._callCallbacks('after:create', void 0); return this; }; Model.prototype.update = function(attributes) { var self; self = this; Object.keys(attributes).forEach(function(attribute_key) { if (Model.prototype[attribute_key] === void 0) { return Model.prototype[attribute_key] = function() { return this.attributes[attribute_key]; }; } }); this._callCallbacks('before:update', void 0); Object.keys(attributes).forEach(function(attribute_key) { return self.attributes[attribute_key] = attributes[attribute_key]; }); this._callCallbacks('after:update', void 0); return true; }; Model.prototype.destroy = function() { this._callCallbacks('before:destroy', void 0); this.unsubscribe(); delete Model.all[this.attributes.id]; this._callCallbacks('after:destroy', void 0); return this; }; Model._callbacks = { 'on:connect': [], 'on:disconnect': [], 'on:responseError': [], 'before:create': [], 'after:create': [], 'before:update': [], 'after:update': [], 'before:destroy': [], 'after:destroy': [] }; Model.prototype.addCallback = Model.addCallback = function(callbackKey, callbackFunction) { var index; index = this._callbacks[callbackKey].indexOf(callbackFunction); if (index === -1) { this._callbacks[callbackKey].push(callbackFunction); return callbackFunction; } }; Model.prototype.removeCallback = Model.removeCallback = function(callbackKey, callbackFunction) { var index; index = this._callbacks[callbackKey].indexOf(callbackFunction); if (index !== -1) { this._callbacks[callbackKey].splice(index, 1); return callbackFunction; } }; Model.prototype._callCallbacks = function(callbackKey, args) { var callback, i, j, len, len1, ref1, ref2, results; ref1 = Model._callbacks[callbackKey]; for (i = 0, len = ref1.length; i < len; i++) { callback = ref1[i]; callback.apply(this, args); } ref2 = this._callbacks[callbackKey]; results = []; for (j = 0, len1 = ref2.length; j < len1; j++) { callback = ref2[j]; results.push(callback.apply(this, args)); } return results; }; Model.prototype._setChangesFrom = function(attributes) { var attributeName, attributeValue, results; this.changes = {}; results = []; for (attributeName in attributes) { attributeValue = attributes[attributeName]; if (this.attributes[attributeName] !== attributeValue) { results.push(this.changes[attributeName] = [this.attributes[attributeName], attributeValue]); } else { results.push(void 0); } } return results; }; Model.prototype._unsetChanges = function() { return delete this['changes']; }; ref1 = config.instanceMethods; for (methodKey in ref1) { methodValue = ref1[methodKey]; if (Model.prototype[methodKey] !== void 0) { throw new Error('Cannot use reserved name as instance method: ', methodKey); } Model.prototype[methodKey] = methodValue; } ref2 = config.callbacks; for (callbackKey in ref2) { callbackFunctions = ref2[callbackKey]; for (i = 0, len = callbackFunctions.length; i < len; i++) { callbackFunction = callbackFunctions[i]; Model.addCallback(callbackKey, callbackFunction); } } ref3 = config.plugins; for (pluginKey in ref3) { pluginValue = ref3[pluginKey]; if (LiveRecord.plugins) { index = Object.keys(LiveRecord.plugins).indexOf(pluginKey); if (index !== -1) { LiveRecord.plugins[pluginKey].applyToModel(Model, pluginValue); } } } LiveRecord.Model.all[config.modelName] = Model; return Model; };
}).call(this); (function() {
var base; (base = this.LiveRecord).plugins || (base.plugins = {});
}).call(this);