From cdff78f5ea50f7176c13884db647b8f967830cbd Mon Sep 17 00:00:00 2001 From: Philip Diffenderfer Date: Tue, 1 Nov 2016 23:29:25 -0400 Subject: [PATCH] Fixed for node/webpack --- bower.json | 2 +- build/rekord-session.js | 8 ++++---- build/rekord-session.min.js | 4 ++-- build/rekord-session.min.js.map | 2 +- package.json | 2 +- src/header.js | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bower.json b/bower.json index 9147ebd..a4ad670 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "rekord-session", - "version": "1.4.4", + "version": "1.4.5", "homepage": "https://github.com/Rekord/rekord-session", "authors": [ "Philip Diffenderfer " diff --git a/build/rekord-session.js b/build/rekord-session.js index d3c542a..03bba39 100644 --- a/build/rekord-session.js +++ b/build/rekord-session.js @@ -1,11 +1,11 @@ -/* rekord-session 1.4.4 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ +/* rekord-session 1.4.5 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ // UMD (Universal Module Definition) (function (root, factory) { if (typeof define === 'function' && define.amd) // jshint ignore:line { // AMD. Register as an anonymous module. - define(['Rekord'], function(Rekord) { // jshint ignore:line + define(['rekord'], function(Rekord) { // jshint ignore:line return factory(root, Rekord); }); } @@ -14,7 +14,7 @@ // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. - module.exports = factory(global, require('Rekord')); // jshint ignore:line + module.exports = factory(global, require('rekord')); // jshint ignore:line } else { @@ -23,7 +23,7 @@ } }(this, function(global, Rekord, undefined) { - + var Map = Rekord.Map; var Model = Rekord.Model; var Promise = Rekord.Promise; diff --git a/build/rekord-session.min.js b/build/rekord-session.min.js index 105c34f..f80aa18 100644 --- a/build/rekord-session.min.js +++ b/build/rekord-session.min.js @@ -1,3 +1,3 @@ -/* rekord-session 1.4.4 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ -!function(e,t){"function"==typeof define&&define.amd?define(["Rekord"],function(s){return t(e,s)}):"object"==typeof module&&module.exports?module.exports=t(global,require("Rekord")):e.Rekord=t(e,e.Rekord)}(this,function(e,t,s){function i(){this.status=i.Status.Active,this.watching=new o,this.removing=new o,this.unwatched=new o,this.validationRequired=!1,this.promise=c.resolve(this)}function n(e,t){this.key=e,this.object=t,this.state=null,this.relations=!1,this.parent=!1,this.children={},this.offs=[],this.save=!1,this.cascade=s,this.state=null}function a(e,t,i,n){for(var a=e.values,r=a.length-1;r>=0;r--){var o=a[r],h=i.call(n,o.object,o);if(h!==s)return h}return t}function r(e,t,i,n){for(var a=e.values,r=a.length-1;r>=0;r--){var o=a[r];if(o.object instanceof h){var c=i.call(n,o.object,o);if(c!==s)return c}}return t}var o=t.Map,h=t.Model,c=t.Promise,u=t.Database,d=t.Collection,v=t.ModelCollection,l=t.Relations.hasOne,f=t.Relations.belongsTo,g=t.Cascade,S=t.isObject,m=t.isNumber,y=t.uuid,w=t.equals,$=t.noop,p=t.addMethods,R=t.replaceMethod,b=t.addEventful,C=t.addEventFunction,D=t.createParser("$key()"),E={RelationUpdate:function(e,t,s,i,n){return function(s,i){e.isDestroyed()||(i.lastRelated&&e.isWatching(i.lastRelated)&&e.unwatch(i.lastRelated),i.related&&!e.isWatching(i.related)&&e.watch(i.related,t.relations[n],t))}},CollectionAdd:function(e,t){return function(s,i){e.isDestroyed()||e.watch(i,t.relations,t)}},CollectionAdds:function(e,t){return function(s,i){if(!e.isDestroyed())for(var n=0;n0)return!0;var t=r(this.unwatched,!1,function(t,s){return e&&!s.save||!t.$hasChanges()?void 0:!0});if(t)return!0;var s=r(this.watching,!1,function(t,s){return e&&!s.save||!t.$hasChanges()?void 0:!0});return s},getChanged:function(e,t){var s=t||new d;return s.push.apply(s,this.removing.values),r(this.watching,null,function(t,i){e&&!i.save||!t.$hasChanges()||s.push(t)}),r(this.unwatched,null,function(t,i){e&&!i.save||!t.$hasChanges()||s.push(t)}),s},validate:function(e){var s=!0;return t.Validation&&(r(this.watching,!0,function(t,i){return t.$validate&&!t.$validate()&&(s=!1,e)?!1:void 0}),s?this.trigger(i.Events.Valid,[this]):this.trigger(i.Events.Invalid,[this])),s},setValidationRequired:function(e){this.validationRequired=e},save:function(e){if(this.status!==i.Status.Active)return c.reject(this);if(this.validationRequired&&!this.validate(!e))return c.reject(this);if(this.promise.isPending())return c.reject(this);this.trigger(i.Events.SaveStart,[this]);var t=new c,s=c.singularity(t,this,this.handleSave);return t.resolve(this),s.success(this.onSaveSuccess,this),s.complete(this.onSaveComplete,this),this.promise=s,s},handleSave:function(e){this.status=i.Status.Saving,r(this.watching,!0,this.executeSave,this),r(this.removing,!0,this.executeRemove,this),a(this.unwatched,!0,this.executeUnwatchedSave,this),this.status=i.Status.Active},executeSave:function(e,t){t.save&&(e.$isSaved()||e.$db.models.remove(e.$key()),e.$save(t.cascade).success(this.afterSave(t)))},executeRemove:function(e,t){e.$status===h.Status.RemovePending&&(this.resync(e),e.$remove(t.cascade).success(this.afterRemove(t,this)))},executeUnwatchedSave:function(e,t){t.save&&(e.$isSaved()||e.$db.models.remove(e.$key()),e.$save(t.cascade).success(this.afterUnwatchSave(t)))},afterSave:function(e){return function(){e.resetSave(),e.saveState(!0)}},afterRemove:function(e,t){return function(){t.removing.remove(e.key),e.destroyReferences()}},afterUnwatchSave:function(e){return function(){e.destroy()}},onSaveComplete:function(){this.promise.isSuccess()?this.trigger(i.Events.SaveSuccess,[this]):this.trigger(i.Events.SaveFailure,[this])},onSaveSuccess:function(){a(this.unwatched,!0,this.onSaveSuccessUnwatched,this),this.removing.reset(),this.unwatched.reset()},onSaveSuccessUnwatched:function(e,t){t.destroy()},discard:function(){return r(this.removing,!0,this.discardRemove,this),a(this.unwatched,!0,this.discardUnwatched,this),r(this.watching,!0,this.discardSave,this),this.removing.reset(),this.unwatched.reset(),this},discardSave:function(e,t){t.save&&!e.$isSaved()&&e.$db.removeFromModels(e),t.resetSave(),t.restoreState(),e.$updated()},discardRemove:function(e,t){e.$status===h.Status.RemovePending&&(this.resync(e),t.reattach())},discardUnwatched:function(e,t){t.reattach()},disable:function(){this.status===i.Status.Active&&(this.status=i.Status.Disabled)},enable:function(){this.status===i.Status.Disabled&&(this.status=i.Status.Active)},isEnabled:function(){return this.status!==i.Status.Disabled&&this.status!==i.Status.Destroyed},isActive:function(){return this.status===i.Status.Active},isDisabled:function(){return this.status===i.Status.Disabled},isSaving:function(){return this.status===i.Status.Saving},isDestroyed:function(){return this.status===i.Status.Destroyed},destroy:function(){if(this.status!==i.Status.Destroyed){for(var e=this.watching.values,t=0;t=0;r--){var o=a[r],h=i.call(n,o.object,o);if(h!==s)return h}return t}function r(e,t,i,n){for(var a=e.values,r=a.length-1;r>=0;r--){var o=a[r];if(o.object instanceof h){var c=i.call(n,o.object,o);if(c!==s)return c}}return t}var o=t.Map,h=t.Model,c=t.Promise,u=t.Database,d=t.Collection,v=t.ModelCollection,l=t.Relations.hasOne,f=t.Relations.belongsTo,g=t.Cascade,S=t.isObject,m=t.isNumber,y=t.uuid,w=t.equals,$=t.noop,p=t.addMethods,b=t.replaceMethod,R=t.addEventful,C=t.addEventFunction,D=t.createParser("$key()"),E={RelationUpdate:function(e,t,s,i,n){return function(s,i){e.isDestroyed()||(i.lastRelated&&e.isWatching(i.lastRelated)&&e.unwatch(i.lastRelated),i.related&&!e.isWatching(i.related)&&e.watch(i.related,t.relations[n],t))}},CollectionAdd:function(e,t){return function(s,i){e.isDestroyed()||e.watch(i,t.relations,t)}},CollectionAdds:function(e,t){return function(s,i){if(!e.isDestroyed())for(var n=0;n0)return!0;var t=r(this.unwatched,!1,function(t,s){return e&&!s.save||!t.$hasChanges()?void 0:!0});if(t)return!0;var s=r(this.watching,!1,function(t,s){return e&&!s.save||!t.$hasChanges()?void 0:!0});return s},getChanged:function(e,t){var s=t||new d;return s.push.apply(s,this.removing.values),r(this.watching,null,function(t,i){e&&!i.save||!t.$hasChanges()||s.push(t)}),r(this.unwatched,null,function(t,i){e&&!i.save||!t.$hasChanges()||s.push(t)}),s},validate:function(e){var s=!0;return t.Validation&&(r(this.watching,!0,function(t,i){return t.$validate&&!t.$validate()&&(s=!1,e)?!1:void 0}),s?this.trigger(i.Events.Valid,[this]):this.trigger(i.Events.Invalid,[this])),s},setValidationRequired:function(e){this.validationRequired=e},save:function(e){if(this.status!==i.Status.Active)return c.reject(this);if(this.validationRequired&&!this.validate(!e))return c.reject(this);if(this.promise.isPending())return c.reject(this);this.trigger(i.Events.SaveStart,[this]);var t=new c,s=c.singularity(t,this,this.handleSave);return t.resolve(this),s.success(this.onSaveSuccess,this),s.complete(this.onSaveComplete,this),this.promise=s,s},handleSave:function(e){this.status=i.Status.Saving,r(this.watching,!0,this.executeSave,this),r(this.removing,!0,this.executeRemove,this),a(this.unwatched,!0,this.executeUnwatchedSave,this),this.status=i.Status.Active},executeSave:function(e,t){t.save&&(e.$isSaved()||e.$db.models.remove(e.$key()),e.$save(t.cascade).success(this.afterSave(t)))},executeRemove:function(e,t){e.$status===h.Status.RemovePending&&(this.resync(e),e.$remove(t.cascade).success(this.afterRemove(t,this)))},executeUnwatchedSave:function(e,t){t.save&&(e.$isSaved()||e.$db.models.remove(e.$key()),e.$save(t.cascade).success(this.afterUnwatchSave(t)))},afterSave:function(e){return function(){e.resetSave(),e.saveState(!0)}},afterRemove:function(e,t){return function(){t.removing.remove(e.key),e.destroyReferences()}},afterUnwatchSave:function(e){return function(){e.destroy()}},onSaveComplete:function(){this.promise.isSuccess()?this.trigger(i.Events.SaveSuccess,[this]):this.trigger(i.Events.SaveFailure,[this])},onSaveSuccess:function(){a(this.unwatched,!0,this.onSaveSuccessUnwatched,this),this.removing.reset(),this.unwatched.reset()},onSaveSuccessUnwatched:function(e,t){t.destroy()},discard:function(){return r(this.removing,!0,this.discardRemove,this),a(this.unwatched,!0,this.discardUnwatched,this),r(this.watching,!0,this.discardSave,this),this.removing.reset(),this.unwatched.reset(),this},discardSave:function(e,t){t.save&&!e.$isSaved()&&e.$db.removeFromModels(e),t.resetSave(),t.restoreState(),e.$updated()},discardRemove:function(e,t){e.$status===h.Status.RemovePending&&(this.resync(e),t.reattach())},discardUnwatched:function(e,t){t.reattach()},disable:function(){this.status===i.Status.Active&&(this.status=i.Status.Disabled)},enable:function(){this.status===i.Status.Disabled&&(this.status=i.Status.Active)},isEnabled:function(){return this.status!==i.Status.Disabled&&this.status!==i.Status.Destroyed},isActive:function(){return this.status===i.Status.Active},isDisabled:function(){return this.status===i.Status.Disabled},isSaving:function(){return this.status===i.Status.Saving},isDestroyed:function(){return this.status===i.Status.Destroyed},destroy:function(){if(this.status!==i.Status.Destroyed){for(var e=this.watching.values,t=0;t 0)\n {\n return true;\n }\n\n var unwatchedChanges = searchModels( this.unwatched, false, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n return true;\n }\n });\n\n if ( unwatchedChanges )\n {\n return true;\n }\n\n var watchedChanges = searchModels( this.watching, false, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n return true;\n }\n });\n\n return watchedChanges;\n },\n\n getChanged: function(checkSavedOnly, out)\n {\n var target = out || new Collection();\n\n target.push.apply( target, this.removing.values );\n\n searchModels( this.watching, null, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n target.push( model );\n }\n });\n\n searchModels( this.unwatched, null, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n target.push( model );\n }\n });\n\n return target;\n },\n\n validate: function(stopAtInvalid)\n {\n var valid = true;\n\n if ( Rekord.Validation )\n {\n searchModels( this.watching, true, function(model, watcher)\n {\n if ( model.$validate && !model.$validate() )\n {\n valid = false;\n\n if ( stopAtInvalid )\n {\n return false;\n }\n }\n });\n\n if ( valid )\n {\n this.trigger( Session.Events.Valid, [this] );\n }\n else\n {\n this.trigger( Session.Events.Invalid, [this] );\n }\n }\n\n return valid;\n },\n\n setValidationRequired: function(required)\n {\n this.validationRequired = required;\n },\n\n save: function(fullValidate)\n {\n if ( this.status !== Session.Status.Active )\n {\n return Promise.reject( this );\n }\n\n if ( this.validationRequired && !this.validate( !fullValidate ) )\n {\n return Promise.reject( this );\n }\n\n if ( this.promise.isPending() )\n {\n return Promise.reject( this );\n }\n\n this.trigger( Session.Events.SaveStart, [this] );\n\n var sessionPromise = new Promise();\n\n var savePromise = Promise.singularity( sessionPromise, this, this.handleSave );\n\n sessionPromise.resolve( this );\n\n savePromise.success( this.onSaveSuccess, this );\n savePromise.complete( this.onSaveComplete, this );\n\n this.promise = savePromise;\n\n return savePromise;\n },\n\n handleSave: function(singularity)\n {\n this.status = Session.Status.Saving;\n\n searchModels( this.watching, true, this.executeSave, this );\n\n searchModels( this.removing, true, this.executeRemove, this );\n\n searchAny( this.unwatched, true, this.executeUnwatchedSave, this );\n\n this.status = Session.Status.Active;\n },\n\n executeSave: function(model, watcher)\n {\n if ( watcher.save )\n {\n // Remove it so $save processes normally\n if ( !model.$isSaved() )\n {\n model.$db.models.remove( model.$key() );\n }\n\n model.$save( watcher.cascade ).success( this.afterSave( watcher ) );\n }\n },\n\n executeRemove: function(model, watcher)\n {\n if ( model.$status === Model.Status.RemovePending )\n {\n this.resync( model );\n\n model.$remove( watcher.cascade ).success( this.afterRemove( watcher, this ) );\n }\n },\n\n executeUnwatchedSave: function(model, watcher)\n {\n if ( watcher.save )\n {\n if ( !model.$isSaved() )\n {\n model.$db.models.remove( model.$key() );\n }\n\n model.$save( watcher.cascade ).success( this.afterUnwatchSave( watcher ) );\n }\n },\n\n afterSave: function(watcher)\n {\n return function onSave()\n {\n watcher.resetSave();\n watcher.saveState( true );\n };\n },\n\n afterRemove: function(watcher, session)\n {\n return function onRemove()\n {\n session.removing.remove( watcher.key );\n watcher.destroyReferences();\n };\n },\n\n afterUnwatchSave: function(watcher)\n {\n return function onSave()\n {\n watcher.destroy();\n };\n },\n\n onSaveComplete: function()\n {\n if ( this.promise.isSuccess() )\n {\n this.trigger( Session.Events.SaveSuccess, [this] );\n }\n else\n {\n this.trigger( Session.Events.SaveFailure, [this] );\n }\n },\n\n onSaveSuccess: function()\n {\n searchAny( this.unwatched, true, this.onSaveSuccessUnwatched, this );\n\n this.removing.reset();\n this.unwatched.reset();\n },\n\n onSaveSuccessUnwatched: function(model, watcher)\n {\n watcher.destroy();\n },\n\n discard: function()\n {\n searchModels( this.removing, true, this.discardRemove, this );\n\n searchAny( this.unwatched, true, this.discardUnwatched, this );\n\n searchModels( this.watching, true, this.discardSave, this );\n\n this.removing.reset();\n this.unwatched.reset();\n\n return this;\n },\n\n discardSave: function(model, watcher)\n {\n if ( watcher.save && !model.$isSaved() )\n {\n model.$db.removeFromModels( model );\n }\n\n watcher.resetSave();\n watcher.restoreState();\n\n model.$updated();\n },\n\n discardRemove: function(model, watcher)\n {\n if ( model.$status === Model.Status.RemovePending )\n {\n this.resync( model );\n\n watcher.reattach();\n }\n },\n\n discardUnwatched: function(model, watcher)\n {\n watcher.reattach();\n },\n\n disable: function()\n {\n if ( this.status === Session.Status.Active )\n {\n this.status = Session.Status.Disabled;\n }\n },\n\n enable: function()\n {\n if ( this.status === Session.Status.Disabled )\n {\n this.status = Session.Status.Active;\n }\n },\n\n isEnabled: function()\n {\n return this.status !== Session.Status.Disabled &&\n this.status !== Session.Status.Destroyed;\n },\n\n isActive: function()\n {\n return this.status === Session.Status.Active;\n },\n\n isDisabled: function()\n {\n return this.status === Session.Status.Disabled;\n },\n\n isSaving: function()\n {\n return this.status === Session.Status.Saving;\n },\n\n isDestroyed: function()\n {\n return this.status === Session.Status.Destroyed;\n },\n\n destroy: function()\n {\n if ( this.status !== Session.Status.Destroyed )\n {\n var watches = this.watching.values;\n\n for (var i = 0; i < watches.length; i++)\n {\n var watcher = watches[ i ];\n\n if ( !watcher.parent )\n {\n watcher.destroy();\n }\n }\n\n var unwatched = this.unwatched.values;\n\n for (var i = 0; i < unwatched.length; i++)\n {\n var watcher = unwatched[ i ];\n\n if ( !watcher.parent )\n {\n watcher.destroy();\n }\n }\n\n var removing = this.removing.values;\n\n for (var i = 0; i < removing.length; i++)\n {\n var remover = removing[ i ];\n\n remover.destroyReferences();\n }\n\n this.watching.reset();\n this.unwatched.reset();\n this.removing.reset();\n\n this.status = Session.Status.Destroyed;\n this.trigger( Session.Events.Destroy, [this] );\n }\n },\n\n getSessionKey: function(object, create)\n {\n if ( object instanceof Model )\n {\n return object.$uid();\n }\n else if ( object instanceof ModelCollection )\n {\n if ( !object.$sessionKey && create )\n {\n object.$sessionKey = uuid();\n }\n\n return object.$sessionKey;\n }\n else if ( create )\n {\n throw 'The object provided cannot be watched by session.';\n }\n },\n\n getSessionWatch: function(object, create)\n {\n var key = this.getSessionKey( object, create );\n\n if ( key )\n {\n var watch = this.watching.get( key );\n\n if ( !watch && create )\n {\n watch = this.unwatched.get( key );\n\n this.unwatched.remove( key );\n\n if ( watch )\n {\n this.watching.put( key, watch );\n }\n }\n\n if ( !watch && create )\n {\n watch = new SessionWatch( key, object );\n\n this.watching.put( key, watch );\n }\n\n return watch;\n }\n },\n\n getAnyWatch: function(object)\n {\n var key = this.getSessionKey( object );\n\n if ( key )\n {\n return this.watching.get( key ) || this.unwatched.get( key );\n }\n },\n\n getRemoveWatch: function(object)\n {\n var key = this.getSessionKey( object );\n\n if ( key )\n {\n return this.removing.get( key );\n }\n },\n\n isWatching: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.watching.has( key );\n },\n\n isUnwatched: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.unwatched.has( key );\n },\n\n isRemoved: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.removing.has( key );\n },\n\n hasWatched: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && ( this.watching.has( key ) || this.removing.has( key ) || this.unwatched.has( key ) );\n },\n\n watchMany: function(models, relations)\n {\n var watchers = [];\n\n for (var i = 0; i < models.length; i++)\n {\n watchers.push( this.watch( models[ i ], relations ) );\n }\n\n return watchers;\n },\n\n // Watching is typically performed on saved models without changes.\n watch: function(model, relations, parent)\n {\n var watcher = this.getSessionWatch( model, true );\n\n watcher.setRelations( relations );\n watcher.setSession( this );\n watcher.setParent( parent );\n watcher.saveState();\n\n if ( isObject( relations ) )\n {\n for (var property in relations)\n {\n var value = model[ property ];\n\n if ( value instanceof Model )\n {\n this.watch( value, relations[ property ], watcher );\n }\n else if ( value instanceof ModelCollection )\n {\n this.watchCollection( value, relations[ property ], watcher );\n }\n\n var relation = model.$getRelation( property );\n\n if ( relation instanceof RelationHasOne || relation instanceof RelationBelongsTo )\n {\n watcher.addListener( Model.Events.RelationUpdate, Listeners.RelationUpdate( this, watcher, model, value, property ) );\n }\n }\n }\n\n this.trigger( Session.Events.Watch, [this, model, watcher] );\n\n return watcher;\n },\n\n // Watching is typically performed on saved models without changes.\n watchCollection: function(collection, relations, parent)\n {\n var watcher = this.getSessionWatch( collection, true );\n\n watcher.setRelations( relations );\n watcher.setSession( this );\n watcher.setParent( parent );\n\n collection.each(function(model)\n {\n this.watch( model, relations, watcher );\n\n }, this );\n\n watcher.addListener( Collection.Events.Add, Listeners.CollectionAdd( this, watcher ) );\n watcher.addListener( Collection.Events.Adds, Listeners.CollectionAdds( this, watcher ) );\n watcher.addListener( Collection.Events.Reset, Listeners.CollectionReset( this, watcher ) );\n watcher.addListener( Collection.Events.Remove, Listeners.CollectionRemove( this, watcher ) );\n watcher.addListener( Collection.Events.Removes, Listeners.CollectionRemoves( this, watcher ) );\n watcher.addListener( Collection.Events.Cleared, Listeners.CollectionCleared( this, watcher ) );\n\n this.trigger( Session.Events.Watch, [this, collection, watcher] );\n\n return watcher;\n },\n\n unwatch: function(object)\n {\n if ( object )\n {\n var watcher = this.getSessionWatch( object );\n\n if ( watcher )\n {\n if ( this.isDestroyable( object ) )\n {\n watcher.destroy();\n }\n else\n {\n watcher.resetSave();\n watcher.moveTo( this.unwatched );\n }\n\n this.trigger( Session.Events.Unwatch, [this, object, watcher] );\n }\n }\n },\n\n saveModel: function(model, cascade)\n {\n // Search in either watching or unwatched. An unwatched model is one that\n // could have recently been reunlated from another model and might need\n // it's foreign key saved.\n var watcher = this.getAnyWatch( model );\n\n if ( watcher )\n {\n watcher.addCascade( cascade );\n\n if ( !watcher.save )\n {\n var key = model.$key();\n var db = model.$db;\n\n if ( db.models.has( key ) )\n {\n db.trigger( Database.Events.ModelUpdated, [model] );\n\n model.$trigger( Model.Events.UpdateAndSave );\n }\n else\n {\n db.models.put( key, model );\n db.trigger( Database.Events.ModelAdded, [model] );\n db.updated();\n\n model.$trigger( Model.Events.CreateAndSave );\n }\n\n watcher.save = true;\n }\n }\n },\n\n removeModel: function(model, cascade)\n {\n // Search in either watching or unwatched. An unwatched model is one that\n // could have recently been unrelated from another model.\n var watcher = this.getAnyWatch( model );\n\n if ( watcher )\n {\n if ( this.isDestroyable( model ) )\n {\n watcher.destroy();\n }\n else\n {\n watcher.resetSave();\n watcher.addCascade( cascade );\n watcher.moveTo( this.removing );\n\n model.$status = Model.Status.RemovePending;\n model.$db.removeFromModels( model );\n }\n }\n else\n {\n var removed = this.getRemoveWatch( model );\n\n if ( removed )\n {\n removed.addCascade( cascade );\n }\n }\n },\n\n isDestroyable: function(object)\n {\n return object instanceof Model && !object.$isSaved();\n },\n\n resync: function(model)\n {\n model.$status = Model.Status.Synced;\n model.$db.models.put( model.$key(), model );\n }\n\n});\n\naddEventful( Session.prototype );\n\naddEventFunction( Session.prototype, 'change', Session.Events.Changes );\n\n\nfunction SessionWatch( key, object )\n{\n this.key = key;\n this.object = object;\n this.state = null;\n this.relations = false;\n this.parent = false;\n this.children = {};\n this.offs = [];\n this.save = false;\n this.cascade = undefined;\n this.state = null;\n}\n\naddMethods( SessionWatch.prototype,\n{\n\n setRelations: function(relations)\n {\n if ( isObject( relations ) )\n {\n if ( this.relations && !equals( this.relations, relations ) )\n {\n throw 'Changing already watched relations is not allowed.';\n }\n\n this.relations = relations;\n }\n },\n\n setSession: function(session)\n {\n var object = this.object;\n var objectSession = object.$session;\n\n if ( objectSession && objectSession !== session && !objectSession.isDestroyed() )\n {\n throw 'An object can only be watched by one live session at a time.';\n }\n\n object.$session = session;\n },\n\n setParent: function(parent)\n {\n this.parent = parent;\n\n if ( parent )\n {\n parent.children[ this.key ] = this;\n }\n },\n\n addListener: function(eventName, listener)\n {\n var object = this.object;\n var off = noop;\n\n if ( object.$on )\n {\n off = object.$on( eventName, listener );\n }\n else if ( object.on )\n {\n off = object.on( eventName, listener );\n }\n\n this.offs.push( off );\n },\n\n addCascade: function(cascade)\n {\n if ( isNumber( cascade ) )\n {\n if ( this.cascade === undefined )\n {\n this.cascade = 0;\n }\n\n this.cascade = this.cascade | cascade;\n }\n },\n\n resetSave: function()\n {\n this.save = false;\n this.cascade = undefined;\n },\n\n saveState: function(override)\n {\n if ( this.state && !override )\n {\n return;\n }\n\n var model = this.object;\n var oldState = model.$savedState;\n\n model.$push();\n\n var relations = this.relations;\n var state = model.$savedState;\n\n if ( isObject( relations ) )\n {\n for (var relationName in relations)\n {\n var value = model[ relationName ];\n\n if ( value instanceof Model )\n {\n state[ relationName ] = value.$key();\n }\n else if ( value instanceof ModelCollection )\n {\n state[ relationName ] = value.pluck( keyParser );\n }\n else\n {\n state[ relationName ] = null;\n }\n }\n }\n\n this.state = state;\n\n model.$savedState = oldState;\n },\n\n restoreState: function()\n {\n var model = this.object;\n var state = this.state;\n\n if ( isObject( state ) )\n {\n var relations = model.$db.relations;\n var relationsWatched = this.relations;\n var relationsSnapshot = {};\n\n for (var relationName in relationsWatched)\n {\n var relation = relations[ relationName ];\n\n relationsSnapshot[ relationName ] = {\n clearKey: relation.clearKey,\n cascadeRemove: relation.cascadeRemove,\n cascade: relation.cascade\n };\n\n relation.clearKey = false;\n relation.cascadeRemove = Cascade.None;\n relation.cascade = Cascade.None;\n }\n\n model.$set( state, undefined, true, true );\n model.$decode();\n\n for (var relationName in relationsWatched)\n {\n var relation = relations[ relationName ];\n var snapshot = relationsSnapshot[ relationName ];\n\n relation.clearKey = snapshot.clearKey;\n relation.cascadeRemove = snapshot.cascadeRemove;\n relation.cascade = snapshot.cascade;\n }\n }\n },\n\n removeListeners: function()\n {\n var offs = this.offs;\n\n for (var i = 0; i < offs.length; i++)\n {\n offs[ i ]();\n }\n\n offs.length = 0;\n },\n\n moveTo: function(target)\n {\n var session = this.object.$session;\n\n this.removeListeners();\n this.moveChildren( target );\n\n if ( this.parent )\n {\n delete this.parent.children[ this.key ];\n }\n\n session.watching.remove( this.key );\n session.unwatched.remove( this.key );\n session.removing.remove( this.key );\n\n target.put( this.key, this );\n },\n\n reattach: function()\n {\n var session = this.object.$session;\n\n session.removing.remove( this.key );\n session.unwatched.remove( this.key );\n session.watching.put( this.key, this );\n\n session.watch( this.object, this.relations, this.parent );\n },\n\n destroy: function()\n {\n var children = this.children;\n\n this.children = {};\n this.removeListeners();\n this.destroyReferences();\n\n for (var childKey in children)\n {\n children[ childKey ].destroy();\n }\n },\n\n destroyReferences: function()\n {\n var session = this.object.$session;\n\n session.watching.remove( this.key );\n session.removing.remove( this.key );\n session.unwatched.remove( this.key );\n\n this.object.$session = null;\n this.state = null;\n\n this.parent = null;\n this.save = false;\n this.cascade = undefined;\n },\n\n moveChildren: function(target)\n {\n var children = this.children;\n\n for (var childKey in children)\n {\n children[ childKey ].moveTo( target );\n }\n }\n\n});\n\n\nfunction searchAny(map, defaultResult, callback, context)\n{\n var watchers = map.values;\n\n for (var i = watchers.length - 1; i >= 0; i--)\n {\n var watcher = watchers[ i ];\n var result = callback.call( context, watcher.object, watcher );\n\n if ( result !== undefined )\n {\n return result;\n }\n }\n\n return defaultResult;\n}\n\nfunction searchModels(map, defaultResult, callback, context)\n{\n var watchers = map.values;\n\n for (var i = watchers.length - 1; i >= 0; i--)\n {\n var watcher = watchers[ i ];\n\n if ( watcher.object instanceof Model )\n {\n var result = callback.call( context, watcher.object, watcher );\n\n if ( result !== undefined )\n {\n return result;\n }\n }\n }\n\n return defaultResult;\n}\n\n\n Rekord.Session = Session;\n Rekord.SessionWatch = SessionWatch;\n Rekord.SessionListeners = Listeners;\n\n return Rekord;\n\n}));\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["rekord-session.min.js"],"names":["root","factory","define","amd","Rekord","module","exports","global","require","this","undefined","Session","status","Status","Active","watching","Map","removing","unwatched","validationRequired","promise","Promise","resolve","SessionWatch","key","object","state","relations","parent","children","offs","save","cascade","searchAny","map","defaultResult","callback","context","watchers","values","i","length","watcher","result","call","searchModels","Model","Database","Collection","ModelCollection","RelationHasOne","Relations","hasOne","RelationBelongsTo","belongsTo","Cascade","isObject","isNumber","uuid","equals","noop","addMethods","replaceMethod","addEventful","addEventFunction","keyParser","createParser","Listeners","RelationUpdate","session","related","property","relator","relation","isDestroyed","lastRelated","isWatching","unwatch","watch","CollectionAdd","collection","added","CollectionAdds","CollectionRemove","removed","CollectionRemoves","CollectionReset","moveChildren","CollectionCleared","prototype","$save","setProperties","setValue","fakeIt","$session","isActive","$isDeleted","debug","Debugs","SAVE_DELETED","$db","arguments","$set","saveModel","apply","$remove","ignoreExists","isSaving","$exists","removeModel","Saving","Disabled","Destroyed","Events","Discard","SaveStart","SaveSuccess","SaveFailure","Destroy","Watch","Unwatch","Invalid","Valid","Changes","hasChanges","checkSavedOnly","size","unwatchedChanges","model","$hasChanges","watchedChanges","getChanged","out","target","push","validate","stopAtInvalid","valid","Validation","$validate","trigger","setValidationRequired","required","fullValidate","reject","isPending","sessionPromise","savePromise","singularity","handleSave","success","onSaveSuccess","complete","onSaveComplete","executeSave","executeRemove","executeUnwatchedSave","$isSaved","models","remove","$key","afterSave","$status","RemovePending","resync","afterRemove","afterUnwatchSave","resetSave","saveState","destroyReferences","destroy","isSuccess","onSaveSuccessUnwatched","reset","discard","discardRemove","discardUnwatched","discardSave","removeFromModels","restoreState","$updated","reattach","disable","enable","isEnabled","isDisabled","watches","remover","getSessionKey","create","$uid","$sessionKey","getSessionWatch","get","put","getAnyWatch","getRemoveWatch","has","isUnwatched","isRemoved","hasWatched","watchMany","setRelations","setSession","setParent","value","watchCollection","$getRelation","addListener","each","Add","Adds","Reset","Remove","Removes","Cleared","isDestroyable","moveTo","addCascade","db","ModelUpdated","$trigger","UpdateAndSave","ModelAdded","updated","CreateAndSave","Synced","objectSession","eventName","listener","off","$on","on","override","oldState","$savedState","$push","relationName","pluck","relationsWatched","relationsSnapshot","clearKey","cascadeRemove","None","$decode","snapshot","removeListeners","childKey","SessionListeners"],"mappings":"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","file":"rekord-session.min.js","sourcesContent":["/* rekord-session 1.4.5 - Adds mass changes & discards to Rekord by Philip Diffenderfer */\n// UMD (Universal Module Definition)\n(function (root, factory)\n{\n if (typeof define === 'function' && define.amd) // jshint ignore:line\n {\n // AMD. Register as an anonymous module.\n define(['rekord'], function(Rekord) { // jshint ignore:line\n return factory(root, Rekord);\n });\n }\n else if (typeof module === 'object' && module.exports) // jshint ignore:line\n {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory(global, require('rekord')); // jshint ignore:line\n }\n else\n {\n // Browser globals (root is window)\n root.Rekord = factory(root, root.Rekord);\n }\n}(this, function(global, Rekord, undefined)\n{\n\n var Map = Rekord.Map;\n var Model = Rekord.Model;\n var Promise = Rekord.Promise;\n var Database = Rekord.Database;\n var Collection = Rekord.Collection;\n var ModelCollection = Rekord.ModelCollection;\n var RelationHasOne = Rekord.Relations.hasOne;\n var RelationBelongsTo = Rekord.Relations.belongsTo;\n var Cascade = Rekord.Cascade;\n\n var isObject = Rekord.isObject;\n var isNumber = Rekord.isNumber;\n var uuid = Rekord.uuid;\n var equals = Rekord.equals;\n var noop = Rekord.noop;\n\n var addMethods = Rekord.addMethods;\n var replaceMethod = Rekord.replaceMethod;\n var addEventful = Rekord.addEventful;\n var addEventFunction = Rekord.addEventFunction;\n\n var keyParser = Rekord.createParser('$key()');\n\nvar Listeners = {\n\n RelationUpdate: function(session, watcher, parent, related, property)\n {\n return function onRelationUpdate(relator, relation)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n if ( relation.lastRelated && session.isWatching( relation.lastRelated ) )\n {\n session.unwatch( relation.lastRelated );\n }\n\n if ( relation.related && !session.isWatching( relation.related ) )\n {\n session.watch( relation.related, watcher.relations[ property ], watcher );\n }\n };\n },\n\n CollectionAdd: function(session, watcher)\n {\n return function onAdd(collection, added)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n session.watch( added, watcher.relations, watcher );\n };\n },\n\n CollectionAdds: function(session, watcher)\n {\n return function onAdds(collection, added)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n for (var i = 0; i < added.length; i++)\n {\n session.watch( added[ i ], watcher.relations, watcher );\n }\n };\n },\n\n CollectionRemove: function(session, watcher)\n {\n return function onRemove(collection, removed)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n session.unwatch( removed );\n };\n },\n\n CollectionRemoves: function(session, watcher)\n {\n return function onRemoves(collection, removed)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n for (var i = 0; i < removed.length; i++)\n {\n session.unwatch( removed[ i ] );\n }\n };\n },\n\n CollectionReset: function(session, watcher)\n {\n return function onReset(collection)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n watcher.moveChildren( session.unwatched );\n\n for (var i = 0; i < collection.length; i++)\n {\n session.watch( collection[ i ], watcher.relations, watcher );\n }\n };\n },\n\n CollectionCleared: function(session, watcher)\n {\n return function onCleared(collection)\n {\n if ( session.isDestroyed() )\n {\n return;\n }\n\n watcher.moveChildren( session.unwatched );\n };\n }\n\n};\n\n\nreplaceMethod( Model.prototype, '$save', function($save)\n{\n return function(setProperties, setValue, cascade)\n {\n var fakeIt = this.$session && this.$session.isActive();\n\n if ( this.$isDeleted() )\n {\n Rekord.debug( Rekord.Debugs.SAVE_DELETED, this.$db, this );\n\n return Promise.resolve( this );\n }\n\n if ( fakeIt )\n {\n var cascade =\n (arguments.length === 3 ? cascade :\n (arguments.length === 2 && isObject( setProperties ) && isNumber( setValue ) ? setValue :\n (arguments.length === 1 && isNumber( setProperties ) ? setProperties : this.$db.cascade ) ) );\n\n this.$set( setProperties, setValue );\n\n this.$session.saveModel( this, cascade );\n\n return Promise.resolve( this );\n }\n\n return $save.apply( this, arguments );\n };\n});\n\nreplaceMethod( Model.prototype, '$remove', function($remove)\n{\n return function(cascade)\n {\n var ignoreExists = this.$session && this.$session.isSaving();\n var fakeIt = this.$session && this.$session.isActive();\n\n if ( !this.$exists() && !ignoreExists )\n {\n return Promise.resolve( this );\n }\n\n if ( fakeIt )\n {\n this.$session.removeModel( this, cascade );\n\n return Promise.resolve( this );\n }\n\n return $remove.apply( this, arguments );\n };\n});\n\n\nfunction Session()\n{\n this.status = Session.Status.Active;\n this.watching = new Map();\n this.removing = new Map();\n this.unwatched = new Map();\n this.validationRequired = false;\n this.promise = Promise.resolve( this );\n}\n\nSession.Status =\n{\n Active: 'active',\n\n Saving: 'saving',\n\n Disabled: 'disabled',\n\n Destroyed: 'destroyed'\n};\n\nSession.Events =\n{\n Discard: 'discard', // (Session)\n\n SaveStart: 'save-start', // (Session)\n\n SaveSuccess: 'save-sucess', // (Session)\n\n SaveFailure: 'save-failure', // (Session)\n\n Destroy: 'destroy', // (Session)\n\n Watch: 'watch', // (Session, Model, SessionWatch)\n\n Unwatch: 'unwatch', // (Session, Collection, SessionWatch)\n\n Invalid: 'invalid', // (Session)\n\n Valid: 'valid', // (Session)\n\n Changes: 'discard save-start save-success save-failure destroy' // (Session)\n};\n\naddMethods( Session.prototype,\n{\n\n hasChanges: function(checkSavedOnly)\n {\n if (this.removing.size() > 0)\n {\n return true;\n }\n\n var unwatchedChanges = searchModels( this.unwatched, false, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n return true;\n }\n });\n\n if ( unwatchedChanges )\n {\n return true;\n }\n\n var watchedChanges = searchModels( this.watching, false, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n return true;\n }\n });\n\n return watchedChanges;\n },\n\n getChanged: function(checkSavedOnly, out)\n {\n var target = out || new Collection();\n\n target.push.apply( target, this.removing.values );\n\n searchModels( this.watching, null, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n target.push( model );\n }\n });\n\n searchModels( this.unwatched, null, function(model, watcher)\n {\n if ( (!checkSavedOnly || watcher.save) && model.$hasChanges() )\n {\n target.push( model );\n }\n });\n\n return target;\n },\n\n validate: function(stopAtInvalid)\n {\n var valid = true;\n\n if ( Rekord.Validation )\n {\n searchModels( this.watching, true, function(model, watcher)\n {\n if ( model.$validate && !model.$validate() )\n {\n valid = false;\n\n if ( stopAtInvalid )\n {\n return false;\n }\n }\n });\n\n if ( valid )\n {\n this.trigger( Session.Events.Valid, [this] );\n }\n else\n {\n this.trigger( Session.Events.Invalid, [this] );\n }\n }\n\n return valid;\n },\n\n setValidationRequired: function(required)\n {\n this.validationRequired = required;\n },\n\n save: function(fullValidate)\n {\n if ( this.status !== Session.Status.Active )\n {\n return Promise.reject( this );\n }\n\n if ( this.validationRequired && !this.validate( !fullValidate ) )\n {\n return Promise.reject( this );\n }\n\n if ( this.promise.isPending() )\n {\n return Promise.reject( this );\n }\n\n this.trigger( Session.Events.SaveStart, [this] );\n\n var sessionPromise = new Promise();\n\n var savePromise = Promise.singularity( sessionPromise, this, this.handleSave );\n\n sessionPromise.resolve( this );\n\n savePromise.success( this.onSaveSuccess, this );\n savePromise.complete( this.onSaveComplete, this );\n\n this.promise = savePromise;\n\n return savePromise;\n },\n\n handleSave: function(singularity)\n {\n this.status = Session.Status.Saving;\n\n searchModels( this.watching, true, this.executeSave, this );\n\n searchModels( this.removing, true, this.executeRemove, this );\n\n searchAny( this.unwatched, true, this.executeUnwatchedSave, this );\n\n this.status = Session.Status.Active;\n },\n\n executeSave: function(model, watcher)\n {\n if ( watcher.save )\n {\n // Remove it so $save processes normally\n if ( !model.$isSaved() )\n {\n model.$db.models.remove( model.$key() );\n }\n\n model.$save( watcher.cascade ).success( this.afterSave( watcher ) );\n }\n },\n\n executeRemove: function(model, watcher)\n {\n if ( model.$status === Model.Status.RemovePending )\n {\n this.resync( model );\n\n model.$remove( watcher.cascade ).success( this.afterRemove( watcher, this ) );\n }\n },\n\n executeUnwatchedSave: function(model, watcher)\n {\n if ( watcher.save )\n {\n if ( !model.$isSaved() )\n {\n model.$db.models.remove( model.$key() );\n }\n\n model.$save( watcher.cascade ).success( this.afterUnwatchSave( watcher ) );\n }\n },\n\n afterSave: function(watcher)\n {\n return function onSave()\n {\n watcher.resetSave();\n watcher.saveState( true );\n };\n },\n\n afterRemove: function(watcher, session)\n {\n return function onRemove()\n {\n session.removing.remove( watcher.key );\n watcher.destroyReferences();\n };\n },\n\n afterUnwatchSave: function(watcher)\n {\n return function onSave()\n {\n watcher.destroy();\n };\n },\n\n onSaveComplete: function()\n {\n if ( this.promise.isSuccess() )\n {\n this.trigger( Session.Events.SaveSuccess, [this] );\n }\n else\n {\n this.trigger( Session.Events.SaveFailure, [this] );\n }\n },\n\n onSaveSuccess: function()\n {\n searchAny( this.unwatched, true, this.onSaveSuccessUnwatched, this );\n\n this.removing.reset();\n this.unwatched.reset();\n },\n\n onSaveSuccessUnwatched: function(model, watcher)\n {\n watcher.destroy();\n },\n\n discard: function()\n {\n searchModels( this.removing, true, this.discardRemove, this );\n\n searchAny( this.unwatched, true, this.discardUnwatched, this );\n\n searchModels( this.watching, true, this.discardSave, this );\n\n this.removing.reset();\n this.unwatched.reset();\n\n return this;\n },\n\n discardSave: function(model, watcher)\n {\n if ( watcher.save && !model.$isSaved() )\n {\n model.$db.removeFromModels( model );\n }\n\n watcher.resetSave();\n watcher.restoreState();\n\n model.$updated();\n },\n\n discardRemove: function(model, watcher)\n {\n if ( model.$status === Model.Status.RemovePending )\n {\n this.resync( model );\n\n watcher.reattach();\n }\n },\n\n discardUnwatched: function(model, watcher)\n {\n watcher.reattach();\n },\n\n disable: function()\n {\n if ( this.status === Session.Status.Active )\n {\n this.status = Session.Status.Disabled;\n }\n },\n\n enable: function()\n {\n if ( this.status === Session.Status.Disabled )\n {\n this.status = Session.Status.Active;\n }\n },\n\n isEnabled: function()\n {\n return this.status !== Session.Status.Disabled &&\n this.status !== Session.Status.Destroyed;\n },\n\n isActive: function()\n {\n return this.status === Session.Status.Active;\n },\n\n isDisabled: function()\n {\n return this.status === Session.Status.Disabled;\n },\n\n isSaving: function()\n {\n return this.status === Session.Status.Saving;\n },\n\n isDestroyed: function()\n {\n return this.status === Session.Status.Destroyed;\n },\n\n destroy: function()\n {\n if ( this.status !== Session.Status.Destroyed )\n {\n var watches = this.watching.values;\n\n for (var i = 0; i < watches.length; i++)\n {\n var watcher = watches[ i ];\n\n if ( !watcher.parent )\n {\n watcher.destroy();\n }\n }\n\n var unwatched = this.unwatched.values;\n\n for (var i = 0; i < unwatched.length; i++)\n {\n var watcher = unwatched[ i ];\n\n if ( !watcher.parent )\n {\n watcher.destroy();\n }\n }\n\n var removing = this.removing.values;\n\n for (var i = 0; i < removing.length; i++)\n {\n var remover = removing[ i ];\n\n remover.destroyReferences();\n }\n\n this.watching.reset();\n this.unwatched.reset();\n this.removing.reset();\n\n this.status = Session.Status.Destroyed;\n this.trigger( Session.Events.Destroy, [this] );\n }\n },\n\n getSessionKey: function(object, create)\n {\n if ( object instanceof Model )\n {\n return object.$uid();\n }\n else if ( object instanceof ModelCollection )\n {\n if ( !object.$sessionKey && create )\n {\n object.$sessionKey = uuid();\n }\n\n return object.$sessionKey;\n }\n else if ( create )\n {\n throw 'The object provided cannot be watched by session.';\n }\n },\n\n getSessionWatch: function(object, create)\n {\n var key = this.getSessionKey( object, create );\n\n if ( key )\n {\n var watch = this.watching.get( key );\n\n if ( !watch && create )\n {\n watch = this.unwatched.get( key );\n\n this.unwatched.remove( key );\n\n if ( watch )\n {\n this.watching.put( key, watch );\n }\n }\n\n if ( !watch && create )\n {\n watch = new SessionWatch( key, object );\n\n this.watching.put( key, watch );\n }\n\n return watch;\n }\n },\n\n getAnyWatch: function(object)\n {\n var key = this.getSessionKey( object );\n\n if ( key )\n {\n return this.watching.get( key ) || this.unwatched.get( key );\n }\n },\n\n getRemoveWatch: function(object)\n {\n var key = this.getSessionKey( object );\n\n if ( key )\n {\n return this.removing.get( key );\n }\n },\n\n isWatching: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.watching.has( key );\n },\n\n isUnwatched: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.unwatched.has( key );\n },\n\n isRemoved: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && this.removing.has( key );\n },\n\n hasWatched: function(object)\n {\n var key = this.getSessionKey( object );\n\n return key && ( this.watching.has( key ) || this.removing.has( key ) || this.unwatched.has( key ) );\n },\n\n watchMany: function(models, relations)\n {\n var watchers = [];\n\n for (var i = 0; i < models.length; i++)\n {\n watchers.push( this.watch( models[ i ], relations ) );\n }\n\n return watchers;\n },\n\n // Watching is typically performed on saved models without changes.\n watch: function(model, relations, parent)\n {\n var watcher = this.getSessionWatch( model, true );\n\n watcher.setRelations( relations );\n watcher.setSession( this );\n watcher.setParent( parent );\n watcher.saveState();\n\n if ( isObject( relations ) )\n {\n for (var property in relations)\n {\n var value = model[ property ];\n\n if ( value instanceof Model )\n {\n this.watch( value, relations[ property ], watcher );\n }\n else if ( value instanceof ModelCollection )\n {\n this.watchCollection( value, relations[ property ], watcher );\n }\n\n var relation = model.$getRelation( property );\n\n if ( relation instanceof RelationHasOne || relation instanceof RelationBelongsTo )\n {\n watcher.addListener( Model.Events.RelationUpdate, Listeners.RelationUpdate( this, watcher, model, value, property ) );\n }\n }\n }\n\n this.trigger( Session.Events.Watch, [this, model, watcher] );\n\n return watcher;\n },\n\n // Watching is typically performed on saved models without changes.\n watchCollection: function(collection, relations, parent)\n {\n var watcher = this.getSessionWatch( collection, true );\n\n watcher.setRelations( relations );\n watcher.setSession( this );\n watcher.setParent( parent );\n\n collection.each(function(model)\n {\n this.watch( model, relations, watcher );\n\n }, this );\n\n watcher.addListener( Collection.Events.Add, Listeners.CollectionAdd( this, watcher ) );\n watcher.addListener( Collection.Events.Adds, Listeners.CollectionAdds( this, watcher ) );\n watcher.addListener( Collection.Events.Reset, Listeners.CollectionReset( this, watcher ) );\n watcher.addListener( Collection.Events.Remove, Listeners.CollectionRemove( this, watcher ) );\n watcher.addListener( Collection.Events.Removes, Listeners.CollectionRemoves( this, watcher ) );\n watcher.addListener( Collection.Events.Cleared, Listeners.CollectionCleared( this, watcher ) );\n\n this.trigger( Session.Events.Watch, [this, collection, watcher] );\n\n return watcher;\n },\n\n unwatch: function(object)\n {\n if ( object )\n {\n var watcher = this.getSessionWatch( object );\n\n if ( watcher )\n {\n if ( this.isDestroyable( object ) )\n {\n watcher.destroy();\n }\n else\n {\n watcher.resetSave();\n watcher.moveTo( this.unwatched );\n }\n\n this.trigger( Session.Events.Unwatch, [this, object, watcher] );\n }\n }\n },\n\n saveModel: function(model, cascade)\n {\n // Search in either watching or unwatched. An unwatched model is one that\n // could have recently been reunlated from another model and might need\n // it's foreign key saved.\n var watcher = this.getAnyWatch( model );\n\n if ( watcher )\n {\n watcher.addCascade( cascade );\n\n if ( !watcher.save )\n {\n var key = model.$key();\n var db = model.$db;\n\n if ( db.models.has( key ) )\n {\n db.trigger( Database.Events.ModelUpdated, [model] );\n\n model.$trigger( Model.Events.UpdateAndSave );\n }\n else\n {\n db.models.put( key, model );\n db.trigger( Database.Events.ModelAdded, [model] );\n db.updated();\n\n model.$trigger( Model.Events.CreateAndSave );\n }\n\n watcher.save = true;\n }\n }\n },\n\n removeModel: function(model, cascade)\n {\n // Search in either watching or unwatched. An unwatched model is one that\n // could have recently been unrelated from another model.\n var watcher = this.getAnyWatch( model );\n\n if ( watcher )\n {\n if ( this.isDestroyable( model ) )\n {\n watcher.destroy();\n }\n else\n {\n watcher.resetSave();\n watcher.addCascade( cascade );\n watcher.moveTo( this.removing );\n\n model.$status = Model.Status.RemovePending;\n model.$db.removeFromModels( model );\n }\n }\n else\n {\n var removed = this.getRemoveWatch( model );\n\n if ( removed )\n {\n removed.addCascade( cascade );\n }\n }\n },\n\n isDestroyable: function(object)\n {\n return object instanceof Model && !object.$isSaved();\n },\n\n resync: function(model)\n {\n model.$status = Model.Status.Synced;\n model.$db.models.put( model.$key(), model );\n }\n\n});\n\naddEventful( Session.prototype );\n\naddEventFunction( Session.prototype, 'change', Session.Events.Changes );\n\n\nfunction SessionWatch( key, object )\n{\n this.key = key;\n this.object = object;\n this.state = null;\n this.relations = false;\n this.parent = false;\n this.children = {};\n this.offs = [];\n this.save = false;\n this.cascade = undefined;\n this.state = null;\n}\n\naddMethods( SessionWatch.prototype,\n{\n\n setRelations: function(relations)\n {\n if ( isObject( relations ) )\n {\n if ( this.relations && !equals( this.relations, relations ) )\n {\n throw 'Changing already watched relations is not allowed.';\n }\n\n this.relations = relations;\n }\n },\n\n setSession: function(session)\n {\n var object = this.object;\n var objectSession = object.$session;\n\n if ( objectSession && objectSession !== session && !objectSession.isDestroyed() )\n {\n throw 'An object can only be watched by one live session at a time.';\n }\n\n object.$session = session;\n },\n\n setParent: function(parent)\n {\n this.parent = parent;\n\n if ( parent )\n {\n parent.children[ this.key ] = this;\n }\n },\n\n addListener: function(eventName, listener)\n {\n var object = this.object;\n var off = noop;\n\n if ( object.$on )\n {\n off = object.$on( eventName, listener );\n }\n else if ( object.on )\n {\n off = object.on( eventName, listener );\n }\n\n this.offs.push( off );\n },\n\n addCascade: function(cascade)\n {\n if ( isNumber( cascade ) )\n {\n if ( this.cascade === undefined )\n {\n this.cascade = 0;\n }\n\n this.cascade = this.cascade | cascade;\n }\n },\n\n resetSave: function()\n {\n this.save = false;\n this.cascade = undefined;\n },\n\n saveState: function(override)\n {\n if ( this.state && !override )\n {\n return;\n }\n\n var model = this.object;\n var oldState = model.$savedState;\n\n model.$push();\n\n var relations = this.relations;\n var state = model.$savedState;\n\n if ( isObject( relations ) )\n {\n for (var relationName in relations)\n {\n var value = model[ relationName ];\n\n if ( value instanceof Model )\n {\n state[ relationName ] = value.$key();\n }\n else if ( value instanceof ModelCollection )\n {\n state[ relationName ] = value.pluck( keyParser );\n }\n else\n {\n state[ relationName ] = null;\n }\n }\n }\n\n this.state = state;\n\n model.$savedState = oldState;\n },\n\n restoreState: function()\n {\n var model = this.object;\n var state = this.state;\n\n if ( isObject( state ) )\n {\n var relations = model.$db.relations;\n var relationsWatched = this.relations;\n var relationsSnapshot = {};\n\n for (var relationName in relationsWatched)\n {\n var relation = relations[ relationName ];\n\n relationsSnapshot[ relationName ] = {\n clearKey: relation.clearKey,\n cascadeRemove: relation.cascadeRemove,\n cascade: relation.cascade\n };\n\n relation.clearKey = false;\n relation.cascadeRemove = Cascade.None;\n relation.cascade = Cascade.None;\n }\n\n model.$set( state, undefined, true, true );\n model.$decode();\n\n for (var relationName in relationsWatched)\n {\n var relation = relations[ relationName ];\n var snapshot = relationsSnapshot[ relationName ];\n\n relation.clearKey = snapshot.clearKey;\n relation.cascadeRemove = snapshot.cascadeRemove;\n relation.cascade = snapshot.cascade;\n }\n }\n },\n\n removeListeners: function()\n {\n var offs = this.offs;\n\n for (var i = 0; i < offs.length; i++)\n {\n offs[ i ]();\n }\n\n offs.length = 0;\n },\n\n moveTo: function(target)\n {\n var session = this.object.$session;\n\n this.removeListeners();\n this.moveChildren( target );\n\n if ( this.parent )\n {\n delete this.parent.children[ this.key ];\n }\n\n session.watching.remove( this.key );\n session.unwatched.remove( this.key );\n session.removing.remove( this.key );\n\n target.put( this.key, this );\n },\n\n reattach: function()\n {\n var session = this.object.$session;\n\n session.removing.remove( this.key );\n session.unwatched.remove( this.key );\n session.watching.put( this.key, this );\n\n session.watch( this.object, this.relations, this.parent );\n },\n\n destroy: function()\n {\n var children = this.children;\n\n this.children = {};\n this.removeListeners();\n this.destroyReferences();\n\n for (var childKey in children)\n {\n children[ childKey ].destroy();\n }\n },\n\n destroyReferences: function()\n {\n var session = this.object.$session;\n\n session.watching.remove( this.key );\n session.removing.remove( this.key );\n session.unwatched.remove( this.key );\n\n this.object.$session = null;\n this.state = null;\n\n this.parent = null;\n this.save = false;\n this.cascade = undefined;\n },\n\n moveChildren: function(target)\n {\n var children = this.children;\n\n for (var childKey in children)\n {\n children[ childKey ].moveTo( target );\n }\n }\n\n});\n\n\nfunction searchAny(map, defaultResult, callback, context)\n{\n var watchers = map.values;\n\n for (var i = watchers.length - 1; i >= 0; i--)\n {\n var watcher = watchers[ i ];\n var result = callback.call( context, watcher.object, watcher );\n\n if ( result !== undefined )\n {\n return result;\n }\n }\n\n return defaultResult;\n}\n\nfunction searchModels(map, defaultResult, callback, context)\n{\n var watchers = map.values;\n\n for (var i = watchers.length - 1; i >= 0; i--)\n {\n var watcher = watchers[ i ];\n\n if ( watcher.object instanceof Model )\n {\n var result = callback.call( context, watcher.object, watcher );\n\n if ( result !== undefined )\n {\n return result;\n }\n }\n }\n\n return defaultResult;\n}\n\n\n Rekord.Session = Session;\n Rekord.SessionWatch = SessionWatch;\n Rekord.SessionListeners = Listeners;\n\n return Rekord;\n\n}));\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/package.json b/package.json index ead0aae..4d20a7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rekord-session", - "version": "1.4.4", + "version": "1.4.5", "description": "Adds mass changes & discards to Rekord", "author": "Philip Diffenderfer", "license": "MIT", diff --git a/src/header.js b/src/header.js index ee72929..9817a88 100644 --- a/src/header.js +++ b/src/header.js @@ -4,7 +4,7 @@ if (typeof define === 'function' && define.amd) // jshint ignore:line { // AMD. Register as an anonymous module. - define(['Rekord'], function(Rekord) { // jshint ignore:line + define(['rekord'], function(Rekord) { // jshint ignore:line return factory(root, Rekord); }); } @@ -13,7 +13,7 @@ // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. - module.exports = factory(global, require('Rekord')); // jshint ignore:line + module.exports = factory(global, require('rekord')); // jshint ignore:line } else { @@ -22,7 +22,7 @@ } }(this, function(global, Rekord, undefined) { - + var Map = Rekord.Map; var Model = Rekord.Model; var Promise = Rekord.Promise;