From 625d4a35fffc3d228bd382e7c5b9db0cdb77ad82 Mon Sep 17 00:00:00 2001 From: Philip Diffenderfer Date: Fri, 28 Oct 2016 00:36:38 -0400 Subject: [PATCH] Added main to package.json for node --- bower.json | 2 +- build/rekord-session.js | 2 +- build/rekord-session.min.js | 2 +- build/rekord-session.min.js.map | 2 +- package.json | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bower.json b/bower.json index 24de149..ffbb367 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "rekord-session", - "version": "1.4.2", + "version": "1.4.3", "homepage": "https://github.com/Rekord/rekord-session", "authors": [ "Philip Diffenderfer " diff --git a/build/rekord-session.js b/build/rekord-session.js index bcc36ee..93826c7 100644 --- a/build/rekord-session.js +++ b/build/rekord-session.js @@ -1,4 +1,4 @@ -/* rekord-session 1.4.2 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ +/* rekord-session 1.4.3 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ (function(global, Rekord, undefined) { var Map = Rekord.Map; diff --git a/build/rekord-session.min.js b/build/rekord-session.min.js index 0c6b44b..8fbbbd1 100644 --- a/build/rekord-session.min.js +++ b/build/rekord-session.min.js @@ -1,3 +1,3 @@ -/* rekord-session 1.4.2 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ +/* rekord-session 1.4.3 - Adds mass changes & discards to Rekord by Philip Diffenderfer */ !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,y=t.isNumber,m=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})(this, this.Rekord);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["rekord-session.min.js"],"names":["global","Rekord","undefined","Session","this","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":"CACA,SAAUA,EAAQC,EAAQC,GAmM1B,QAASC,KAEPC,KAAKC,OAASF,EAAQG,OAAOC,OAC7BH,KAAKI,SAAW,GAAIC,GACpBL,KAAKM,SAAW,GAAID,GACpBL,KAAKO,UAAY,GAAIF,GACrBL,KAAKQ,oBAAqB,EAC1BR,KAAKS,QAAUC,EAAQC,QAASX,MA6qBlC,QAASY,GAAcC,EAAKC,GAE1Bd,KAAKa,IAAMA,EACXb,KAAKc,OAASA,EACdd,KAAKe,MAAQ,KACbf,KAAKgB,WAAY,EACjBhB,KAAKiB,QAAS,EACdjB,KAAKkB,YACLlB,KAAKmB,QACLnB,KAAKoB,MAAO,EACZpB,KAAKqB,QAAUvB,EACfE,KAAKe,MAAQ,KAqPf,QAASO,GAAUC,EAAKC,EAAeC,EAAUC,GAI/C,IAAK,GAFDC,GAAWJ,EAAIK,OAEVC,EAAIF,EAASG,OAAS,EAAGD,GAAK,EAAGA,IAC1C,CACE,GAAIE,GAAUJ,EAAUE,GACpBG,EAASP,EAASQ,KAAMP,EAASK,EAAQjB,OAAQiB,EAErD,IAAKC,IAAWlC,EAEd,MAAOkC,GAIX,MAAOR,GAGT,QAASU,GAAaX,EAAKC,EAAeC,EAAUC,GAIlD,IAAK,GAFDC,GAAWJ,EAAIK,OAEVC,EAAIF,EAASG,OAAS,EAAGD,GAAK,EAAGA,IAC1C,CACE,GAAIE,GAAUJ,EAAUE,EAExB,IAAKE,EAAQjB,iBAAkBqB,GAC/B,CACE,GAAIH,GAASP,EAASQ,KAAMP,EAASK,EAAQjB,OAAQiB,EAErD,IAAKC,IAAWlC,EAEd,MAAOkC,IAKb,MAAOR,GA1pCP,GAAInB,GAAMR,EAAOQ,IACb8B,EAAQtC,EAAOsC,MACfzB,EAAUb,EAAOa,QACjB0B,EAAWvC,EAAOuC,SAClBC,EAAaxC,EAAOwC,WACpBC,EAAkBzC,EAAOyC,gBACzBC,EAAiB1C,EAAO2C,UAAUC,OAClCC,EAAoB7C,EAAO2C,UAAUG,UACrCC,EAAU/C,EAAO+C,QAEjBC,EAAWhD,EAAOgD,SAClBC,EAAWjD,EAAOiD,SAClBC,EAAOlD,EAAOkD,KACdC,EAASnD,EAAOmD,OAChBC,EAAOpD,EAAOoD,KAEdC,EAAarD,EAAOqD,WACpBC,EAAgBtD,EAAOsD,cACvBC,EAAcvD,EAAOuD,YACrBC,EAAmBxD,EAAOwD,iBAE1BC,EAAYzD,EAAO0D,aAAa,UAElCC,GAEFC,eAAgB,SAASC,EAAS3B,EAASd,EAAQ0C,EAASC,GAE1D,MAAO,UAA0BC,EAASC,GAEnCJ,EAAQK,gBAKRD,EAASE,aAAeN,EAAQO,WAAYH,EAASE,cAExDN,EAAQQ,QAASJ,EAASE,aAGvBF,EAASH,UAAYD,EAAQO,WAAYH,EAASH,UAErDD,EAAQS,MAAOL,EAASH,QAAS5B,EAAQf,UAAW4C,GAAY7B,MAKtEqC,cAAe,SAASV,EAAS3B,GAE/B,MAAO,UAAesC,EAAYC,GAE3BZ,EAAQK,eAKbL,EAAQS,MAAOG,EAAOvC,EAAQf,UAAWe,KAI7CwC,eAAgB,SAASb,EAAS3B,GAEhC,MAAO,UAAgBsC,EAAYC,GAEjC,IAAKZ,EAAQK,cAKb,IAAK,GAAIlC,GAAI,EAAGA,EAAIyC,EAAMxC,OAAQD,IAEhC6B,EAAQS,MAAOG,EAAOzC,GAAKE,EAAQf,UAAWe,KAKpDyC,iBAAkB,SAASd,EAAS3B,GAElC,MAAO,UAAkBsC,EAAYI,GAE9Bf,EAAQK,eAKbL,EAAQQ,QAASO,KAIrBC,kBAAmB,SAAShB,EAAS3B,GAEnC,MAAO,UAAmBsC,EAAYI,GAEpC,IAAKf,EAAQK,cAKb,IAAK,GAAIlC,GAAI,EAAGA,EAAI4C,EAAQ3C,OAAQD,IAElC6B,EAAQQ,QAASO,EAAS5C,MAKhC8C,gBAAiB,SAASjB,EAAS3B,GAEjC,MAAO,UAAiBsC,GAEtB,IAAKX,EAAQK,cAAb,CAKAhC,EAAQ6C,aAAclB,EAAQnD,UAE9B,KAAK,GAAIsB,GAAI,EAAGA,EAAIwC,EAAWvC,OAAQD,IAErC6B,EAAQS,MAAOE,EAAYxC,GAAKE,EAAQf,UAAWe,MAKzD8C,kBAAmB,SAASnB,EAAS3B,GAEnC,MAAO,UAAmBsC,GAEnBX,EAAQK,eAKbhC,EAAQ6C,aAAclB,EAAQnD,aAOpC4C,GAAehB,EAAM2C,UAAW,QAAS,SAASC,GAEhD,MAAO,UAASC,EAAeC,EAAU5D,GAEvC,GAAI6D,GAASlF,KAAKmF,UAAYnF,KAAKmF,SAASC,UAE5C,IAAKpF,KAAKqF,aAIR,MAFAxF,GAAOyF,MAAOzF,EAAO0F,OAAOC,aAAcxF,KAAKyF,IAAKzF,MAE7CU,EAAQC,QAASX,KAG1B,IAAKkF,EACL,CACE,GAAI7D,GACoB,IAArBqE,UAAU5D,OAAeT,EACF,IAArBqE,UAAU5D,QAAgBe,EAAUmC,IAAmBlC,EAAUmC,GAAaA,EACvD,IAArBS,UAAU5D,QAAgBgB,EAAUkC,GAAmBA,EAAgBhF,KAAKyF,IAAIpE,OAMvF,OAJArB,MAAK2F,KAAMX,EAAeC,GAE1BjF,KAAKmF,SAASS,UAAW5F,KAAMqB,GAExBX,EAAQC,QAASX,MAG1B,MAAO+E,GAAMc,MAAO7F,KAAM0F,cAI9BvC,EAAehB,EAAM2C,UAAW,UAAW,SAASgB,GAElD,MAAO,UAASzE,GAEd,GAAI0E,GAAe/F,KAAKmF,UAAYnF,KAAKmF,SAASa,WAC9Cd,EAASlF,KAAKmF,UAAYnF,KAAKmF,SAASC,UAE5C,OAAMpF,MAAKiG,WAAcF,EAKpBb,GAEHlF,KAAKmF,SAASe,YAAalG,KAAMqB,GAE1BX,EAAQC,QAASX,OAGnB8F,EAAQD,MAAO7F,KAAM0F,WAVnBhF,EAAQC,QAASX,SAyB9BD,EAAQG,QAENC,OAAQ,SAERgG,OAAQ,SAERC,SAAU,WAEVC,UAAW,aAGbtG,EAAQuG,QAENC,QAAS,UAETC,UAAW,aAEXC,YAAa,cAEbC,YAAa,eAEbC,QAAS,UAETC,MAAO,QAEPC,QAAS,UAETC,QAAS,UAETC,MAAO,QAEPC,QAAS,wDAGX9D,EAAYnD,EAAQ+E,WAGlBmC,WAAY,SAASC,GAEnB,GAAIlH,KAAKM,SAAS6G,OAAS,EAEzB,OAAO,CAGT,IAAIC,GAAmBlF,EAAclC,KAAKO,WAAW,EAAO,SAAS8G,EAAOtF,GAE1E,MAAOmF,KAAkBnF,EAAQX,OAASiG,EAAMC,cAAhD,QAES,GAIX,IAAKF,EAEH,OAAO,CAGT,IAAIG,GAAiBrF,EAAclC,KAAKI,UAAU,EAAO,SAASiH,EAAOtF,GAEvE,MAAOmF,KAAkBnF,EAAQX,OAASiG,EAAMC,cAAhD,QAES,GAIX,OAAOC,IAGTC,WAAY,SAASN,EAAgBO,GAEnC,GAAIC,GAASD,GAAO,GAAIpF,EAoBxB,OAlBAqF,GAAOC,KAAK9B,MAAO6B,EAAQ1H,KAAKM,SAASsB,QAEzCM,EAAclC,KAAKI,SAAU,KAAM,SAASiH,EAAOtF,GAE1CmF,IAAkBnF,EAAQX,OAASiG,EAAMC,eAE9CI,EAAOC,KAAMN,KAIjBnF,EAAclC,KAAKO,UAAW,KAAM,SAAS8G,EAAOtF,GAE3CmF,IAAkBnF,EAAQX,OAASiG,EAAMC,eAE9CI,EAAOC,KAAMN,KAIVK,GAGTE,SAAU,SAASC,GAEjB,GAAIC,IAAQ,CA2BZ,OAzBKjI,GAAOkI,aAEV7F,EAAclC,KAAKI,UAAU,EAAM,SAASiH,EAAOtF,GAEjD,MAAKsF,GAAMW,YAAcX,EAAMW,cAE7BF,GAAQ,EAEHD,IAEI,EANX,SAWGC,EAEH9H,KAAKiI,QAASlI,EAAQuG,OAAOS,OAAQ/G,OAIrCA,KAAKiI,QAASlI,EAAQuG,OAAOQ,SAAU9G,QAIpC8H,GAGTI,sBAAuB,SAASC,GAE9BnI,KAAKQ,mBAAqB2H,GAG5B/G,KAAM,SAASgH,GAEb,GAAKpI,KAAKC,SAAWF,EAAQG,OAAOC,OAElC,MAAOO,GAAQ2H,OAAQrI,KAGzB,IAAKA,KAAKQ,qBAAuBR,KAAK4H,UAAWQ,GAE/C,MAAO1H,GAAQ2H,OAAQrI,KAGzB,IAAKA,KAAKS,QAAQ6H,YAEhB,MAAO5H,GAAQ2H,OAAQrI,KAGzBA,MAAKiI,QAASlI,EAAQuG,OAAOE,WAAYxG,MAEzC,IAAIuI,GAAiB,GAAI7H,GAErB8H,EAAc9H,EAAQ+H,YAAaF,EAAgBvI,KAAMA,KAAK0I,WASlE,OAPAH,GAAe5H,QAASX,MAExBwI,EAAYG,QAAS3I,KAAK4I,cAAe5I,MACzCwI,EAAYK,SAAU7I,KAAK8I,eAAgB9I,MAE3CA,KAAKS,QAAU+H,EAERA,GAGTE,WAAY,SAASD,GAEnBzI,KAAKC,OAASF,EAAQG,OAAOiG,OAE7BjE,EAAclC,KAAKI,UAAU,EAAMJ,KAAK+I,YAAa/I,MAErDkC,EAAclC,KAAKM,UAAU,EAAMN,KAAKgJ,cAAehJ,MAEvDsB,EAAWtB,KAAKO,WAAW,EAAMP,KAAKiJ,qBAAsBjJ,MAE5DA,KAAKC,OAASF,EAAQG,OAAOC,QAG/B4I,YAAa,SAAS1B,EAAOtF,GAEtBA,EAAQX,OAGLiG,EAAM6B,YAEV7B,EAAM5B,IAAI0D,OAAOC,OAAQ/B,EAAMgC,QAGjChC,EAAMtC,MAAOhD,EAAQV,SAAUsH,QAAS3I,KAAKsJ,UAAWvH,MAI5DiH,cAAe,SAAS3B,EAAOtF,GAExBsF,EAAMkC,UAAYpH,EAAMjC,OAAOsJ,gBAElCxJ,KAAKyJ,OAAQpC,GAEbA,EAAMvB,QAAS/D,EAAQV,SAAUsH,QAAS3I,KAAK0J,YAAa3H,EAAS/B,SAIzEiJ,qBAAsB,SAAS5B,EAAOtF,GAE/BA,EAAQX,OAELiG,EAAM6B,YAEV7B,EAAM5B,IAAI0D,OAAOC,OAAQ/B,EAAMgC,QAGjChC,EAAMtC,MAAOhD,EAAQV,SAAUsH,QAAS3I,KAAK2J,iBAAkB5H,MAInEuH,UAAW,SAASvH,GAElB,MAAO,YAELA,EAAQ6H,YACR7H,EAAQ8H,WAAW,KAIvBH,YAAa,SAAS3H,EAAS2B,GAE7B,MAAO,YAELA,EAAQpD,SAAS8I,OAAQrH,EAAQlB,KACjCkB,EAAQ+H,sBAIZH,iBAAkB,SAAS5H,GAEzB,MAAO,YAELA,EAAQgI,YAIZjB,eAAgB,WAET9I,KAAKS,QAAQuJ,YAEhBhK,KAAKiI,QAASlI,EAAQuG,OAAOG,aAAczG,OAI3CA,KAAKiI,QAASlI,EAAQuG,OAAOI,aAAc1G,QAI/C4I,cAAe,WAEbtH,EAAWtB,KAAKO,WAAW,EAAMP,KAAKiK,uBAAwBjK,MAE9DA,KAAKM,SAAS4J,QACdlK,KAAKO,UAAU2J,SAGjBD,uBAAwB,SAAS5C,EAAOtF,GAEtCA,EAAQgI,WAGVI,QAAS,WAWP,MATAjI,GAAclC,KAAKM,UAAU,EAAMN,KAAKoK,cAAepK,MAEvDsB,EAAWtB,KAAKO,WAAW,EAAMP,KAAKqK,iBAAkBrK,MAExDkC,EAAclC,KAAKI,UAAU,EAAMJ,KAAKsK,YAAatK,MAErDA,KAAKM,SAAS4J,QACdlK,KAAKO,UAAU2J,QAERlK,MAGTsK,YAAa,SAASjD,EAAOtF,GAEtBA,EAAQX,OAASiG,EAAM6B,YAE1B7B,EAAM5B,IAAI8E,iBAAkBlD,GAG9BtF,EAAQ6H,YACR7H,EAAQyI,eAERnD,EAAMoD,YAGRL,cAAe,SAAS/C,EAAOtF,GAExBsF,EAAMkC,UAAYpH,EAAMjC,OAAOsJ,gBAElCxJ,KAAKyJ,OAAQpC,GAEbtF,EAAQ2I,aAIZL,iBAAkB,SAAShD,EAAOtF,GAEhCA,EAAQ2I,YAGVC,QAAS,WAEF3K,KAAKC,SAAWF,EAAQG,OAAOC,SAElCH,KAAKC,OAASF,EAAQG,OAAOkG,WAIjCwE,OAAQ,WAED5K,KAAKC,SAAWF,EAAQG,OAAOkG,WAElCpG,KAAKC,OAASF,EAAQG,OAAOC,SAIjC0K,UAAW,WAET,MAAO7K,MAAKC,SAAWF,EAAQG,OAAOkG,UAC/BpG,KAAKC,SAAWF,EAAQG,OAAOmG,WAGxCjB,SAAU,WAER,MAAOpF,MAAKC,SAAWF,EAAQG,OAAOC,QAGxC2K,WAAY,WAEV,MAAO9K,MAAKC,SAAWF,EAAQG,OAAOkG,UAGxCJ,SAAU,WAER,MAAOhG,MAAKC,SAAWF,EAAQG,OAAOiG,QAGxCpC,YAAa,WAEX,MAAO/D,MAAKC,SAAWF,EAAQG,OAAOmG,WAGxC0D,QAAS,WAEP,GAAK/J,KAAKC,SAAWF,EAAQG,OAAOmG,UACpC,CAGE,IAAK,GAFD0E,GAAU/K,KAAKI,SAASwB,OAEnBC,EAAI,EAAGA,EAAIkJ,EAAQjJ,OAAQD,IACpC,CACE,GAAIE,GAAUgJ,EAASlJ,EAEjBE,GAAQd,QAEZc,EAAQgI,UAMZ,IAAK,GAFDxJ,GAAYP,KAAKO,UAAUqB,OAEtBC,EAAI,EAAGA,EAAItB,EAAUuB,OAAQD,IACtC,CACE,GAAIE,GAAUxB,EAAWsB,EAEnBE,GAAQd,QAEZc,EAAQgI,UAMZ,IAAK,GAFDzJ,GAAWN,KAAKM,SAASsB,OAEpBC,EAAI,EAAGA,EAAIvB,EAASwB,OAAQD,IACrC,CACE,GAAImJ,GAAU1K,EAAUuB,EAExBmJ,GAAQlB,oBAGV9J,KAAKI,SAAS8J,QACdlK,KAAKO,UAAU2J,QACflK,KAAKM,SAAS4J,QAEdlK,KAAKC,OAASF,EAAQG,OAAOmG,UAC7BrG,KAAKiI,QAASlI,EAAQuG,OAAOK,SAAU3G,SAI3CiL,cAAe,SAASnK,EAAQoK,GAE9B,GAAKpK,YAAkBqB,GAErB,MAAOrB,GAAOqK,MAEX,IAAKrK,YAAkBwB,GAO1B,OALMxB,EAAOsK,aAAeF,IAE1BpK,EAAOsK,YAAcrI,KAGhBjC,EAAOsK,WAEX,IAAKF,EAER,KAAM,qDAIVG,gBAAiB,SAASvK,EAAQoK,GAEhC,GAAIrK,GAAMb,KAAKiL,cAAenK,EAAQoK,EAEtC,IAAKrK,EACL,CACE,GAAIsD,GAAQnE,KAAKI,SAASkL,IAAKzK,EAqB/B,QAnBMsD,GAAS+G,IAEb/G,EAAQnE,KAAKO,UAAU+K,IAAKzK,GAE5Bb,KAAKO,UAAU6I,OAAQvI,GAElBsD,GAEHnE,KAAKI,SAASmL,IAAK1K,EAAKsD,KAItBA,GAAS+G,IAEb/G,EAAQ,GAAIvD,GAAcC,EAAKC,GAE/Bd,KAAKI,SAASmL,IAAK1K,EAAKsD,IAGnBA,IAIXqH,YAAa,SAAS1K,GAEpB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAKD,GAEIb,KAAKI,SAASkL,IAAKzK,IAASb,KAAKO,UAAU+K,IAAKzK,GAFzD,QAMF4K,eAAgB,SAAS3K,GAEvB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAKD,GAEIb,KAAKM,SAASgL,IAAKzK,GAF5B,QAMFoD,WAAY,SAASnD,GAEnB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAOD,IAAOb,KAAKI,SAASsL,IAAK7K,IAGnC8K,YAAa,SAAS7K,GAEpB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAOD,IAAOb,KAAKO,UAAUmL,IAAK7K,IAGpC+K,UAAW,SAAS9K,GAElB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAOD,IAAOb,KAAKM,SAASoL,IAAK7K,IAGnCgL,WAAY,SAAS/K,GAEnB,GAAID,GAAMb,KAAKiL,cAAenK,EAE9B,OAAOD,KAASb,KAAKI,SAASsL,IAAK7K,IAASb,KAAKM,SAASoL,IAAK7K,IAASb,KAAKO,UAAUmL,IAAK7K,KAG9FiL,UAAW,SAAS3C,EAAQnI,GAI1B,IAAK,GAFDW,MAEKE,EAAI,EAAGA,EAAIsH,EAAOrH,OAAQD,IAEjCF,EAASgG,KAAM3H,KAAKmE,MAAOgF,EAAQtH,GAAKb,GAG1C,OAAOW,IAITwC,MAAO,SAASkD,EAAOrG,EAAWC,GAEhC,GAAIc,GAAU/B,KAAKqL,gBAAiBhE,GAAO,EAO3C,IALAtF,EAAQgK,aAAc/K,GACtBe,EAAQiK,WAAYhM,MACpB+B,EAAQkK,UAAWhL,GACnBc,EAAQ8H,YAEHhH,EAAU7B,GAEb,IAAK,GAAI4C,KAAY5C,GACrB,CACE,GAAIkL,GAAQ7E,EAAOzD,EAEdsI,aAAiB/J,GAEpBnC,KAAKmE,MAAO+H,EAAOlL,EAAW4C,GAAY7B,GAElCmK,YAAiB5J,IAEzBtC,KAAKmM,gBAAiBD,EAAOlL,EAAW4C,GAAY7B,EAGtD,IAAI+B,GAAWuD,EAAM+E,aAAcxI,IAE9BE,YAAoBvB,IAAkBuB,YAAoBpB,KAE7DX,EAAQsK,YAAalK,EAAMmE,OAAO7C,eAAgBD,EAAUC,eAAgBzD,KAAM+B,EAASsF,EAAO6E,EAAOtI,IAO/G,MAFA5D,MAAKiI,QAASlI,EAAQuG,OAAOM,OAAQ5G,KAAMqH,EAAOtF,IAE3CA,GAIToK,gBAAiB,SAAS9H,EAAYrD,EAAWC,GAE/C,GAAIc,GAAU/B,KAAKqL,gBAAiBhH,GAAY,EAqBhD,OAnBAtC,GAAQgK,aAAc/K,GACtBe,EAAQiK,WAAYhM,MACpB+B,EAAQkK,UAAWhL,GAEnBoD,EAAWiI,KAAK,SAASjF,GAEvBrH,KAAKmE,MAAOkD,EAAOrG,EAAWe,IAE7B/B,MAEH+B,EAAQsK,YAAahK,EAAWiE,OAAOiG,IAAK/I,EAAUY,cAAepE,KAAM+B,IAC3EA,EAAQsK,YAAahK,EAAWiE,OAAOkG,KAAMhJ,EAAUe,eAAgBvE,KAAM+B,IAC7EA,EAAQsK,YAAahK,EAAWiE,OAAOmG,MAAOjJ,EAAUmB,gBAAiB3E,KAAM+B,IAC/EA,EAAQsK,YAAahK,EAAWiE,OAAOoG,OAAQlJ,EAAUgB,iBAAkBxE,KAAM+B,IACjFA,EAAQsK,YAAahK,EAAWiE,OAAOqG,QAASnJ,EAAUkB,kBAAmB1E,KAAM+B,IACnFA,EAAQsK,YAAahK,EAAWiE,OAAOsG,QAASpJ,EAAUqB,kBAAmB7E,KAAM+B,IAEnF/B,KAAKiI,QAASlI,EAAQuG,OAAOM,OAAQ5G,KAAMqE,EAAYtC,IAEhDA,GAGTmC,QAAS,SAASpD,GAEhB,GAAKA,EACL,CACE,GAAIiB,GAAU/B,KAAKqL,gBAAiBvK,EAE/BiB,KAEE/B,KAAK6M,cAAe/L,GAEvBiB,EAAQgI,WAIRhI,EAAQ6H,YACR7H,EAAQ+K,OAAQ9M,KAAKO,YAGvBP,KAAKiI,QAASlI,EAAQuG,OAAOO,SAAU7G,KAAMc,EAAQiB,OAK3D6D,UAAW,SAASyB,EAAOhG,GAKzB,GAAIU,GAAU/B,KAAKwL,YAAanE,EAEhC,IAAKtF,IAEHA,EAAQgL,WAAY1L,IAEdU,EAAQX,MACd,CACE,GAAIP,GAAMwG,EAAMgC,OACZ2D,EAAK3F,EAAM5B,GAEVuH,GAAG7D,OAAOuC,IAAK7K,IAElBmM,EAAG/E,QAAS7F,EAASkE,OAAO2G,cAAe5F,IAE3CA,EAAM6F,SAAU/K,EAAMmE,OAAO6G,iBAI7BH,EAAG7D,OAAOoC,IAAK1K,EAAKwG,GACpB2F,EAAG/E,QAAS7F,EAASkE,OAAO8G,YAAa/F,IACzC2F,EAAGK,UAEHhG,EAAM6F,SAAU/K,EAAMmE,OAAOgH,gBAG/BvL,EAAQX,MAAO,IAKrB8E,YAAa,SAASmB,EAAOhG,GAI3B,GAAIU,GAAU/B,KAAKwL,YAAanE,EAEhC,IAAKtF,EAEE/B,KAAK6M,cAAexF,GAEvBtF,EAAQgI,WAIRhI,EAAQ6H,YACR7H,EAAQgL,WAAY1L,GACpBU,EAAQ+K,OAAQ9M,KAAKM,UAErB+G,EAAMkC,QAAUpH,EAAMjC,OAAOsJ,cAC7BnC,EAAM5B,IAAI8E,iBAAkBlD,QAIhC,CACE,GAAI5C,GAAUzE,KAAKyL,eAAgBpE,EAE9B5C,IAEHA,EAAQsI,WAAY1L,KAK1BwL,cAAe,SAAS/L,GAEtB,MAAOA,aAAkBqB,KAAUrB,EAAOoI,YAG5CO,OAAQ,SAASpC,GAEfA,EAAMkC,QAAUpH,EAAMjC,OAAOqN,OAC7BlG,EAAM5B,IAAI0D,OAAOoC,IAAKlE,EAAMgC,OAAQhC,MAKxCjE,EAAarD,EAAQ+E,WAErBzB,EAAkBtD,EAAQ+E,UAAW,SAAU/E,EAAQuG,OAAOU,SAiB9D9D,EAAYtC,EAAakE,WAGvBiH,aAAc,SAAS/K,GAErB,GAAK6B,EAAU7B,GACf,CACE,GAAKhB,KAAKgB,YAAcgC,EAAQhD,KAAKgB,UAAWA,GAE9C,KAAM,oDAGRhB,MAAKgB,UAAYA,IAIrBgL,WAAY,SAAStI,GAEnB,GAAI5C,GAASd,KAAKc,OACd0M,EAAgB1M,EAAOqE,QAE3B,IAAKqI,GAAiBA,IAAkB9J,IAAY8J,EAAczJ,cAEhE,KAAM,8DAGRjD,GAAOqE,SAAWzB,GAGpBuI,UAAW,SAAShL,GAElBjB,KAAKiB,OAASA,EAETA,IAEHA,EAAOC,SAAUlB,KAAKa,KAAQb,OAIlCqM,YAAa,SAASoB,EAAWC,GAE/B,GAAI5M,GAASd,KAAKc,OACd6M,EAAM1K,CAELnC,GAAO8M,IAEVD,EAAM7M,EAAO8M,IAAKH,EAAWC,GAErB5M,EAAO+M,KAEfF,EAAM7M,EAAO+M,GAAIJ,EAAWC,IAG9B1N,KAAKmB,KAAKwG,KAAMgG,IAGlBZ,WAAY,SAAS1L,GAEdyB,EAAUzB,KAERrB,KAAKqB,UAAYvB,IAEpBE,KAAKqB,QAAU,GAGjBrB,KAAKqB,QAAUrB,KAAKqB,QAAUA,IAIlCuI,UAAW,WAET5J,KAAKoB,MAAO,EACZpB,KAAKqB,QAAUvB,GAGjB+J,UAAW,SAASiE,GAElB,IAAK9N,KAAKe,OAAU+M,EAApB,CAKA,GAAIzG,GAAQrH,KAAKc,OACbiN,EAAW1G,EAAM2G,WAErB3G,GAAM4G,OAEN,IAAIjN,GAAYhB,KAAKgB,UACjBD,EAAQsG,EAAM2G,WAElB,IAAKnL,EAAU7B,GAEb,IAAK,GAAIkN,KAAgBlN,GACzB,CACE,GAAIkL,GAAQ7E,EAAO6G,EAEdhC,aAAiB/J,GAEpBpB,EAAOmN,GAAiBhC,EAAM7C,OAEtB6C,YAAiB5J,GAEzBvB,EAAOmN,GAAiBhC,EAAMiC,MAAO7K,GAIrCvC,EAAOmN,GAAiB,KAK9BlO,KAAKe,MAAQA,EAEbsG,EAAM2G,YAAcD,IAGtBvD,aAAc,WAEZ,GAAInD,GAAQrH,KAAKc,OACbC,EAAQf,KAAKe,KAEjB,IAAK8B,EAAU9B,GACf,CACE,GAAIC,GAAYqG,EAAM5B,IAAIzE,UACtBoN,EAAmBpO,KAAKgB,UACxBqN,IAEJ,KAAK,GAAIH,KAAgBE,GACzB,CACE,GAAItK,GAAW9C,EAAWkN,EAE1BG,GAAmBH,IACjBI,SAAUxK,EAASwK,SACnBC,cAAezK,EAASyK,cACxBlN,QAASyC,EAASzC,SAGpByC,EAASwK,UAAW,EACpBxK,EAASyK,cAAgB3L,EAAQ4L,KACjC1K,EAASzC,QAAUuB,EAAQ4L,KAG7BnH,EAAM1B,KAAM5E,EAAOjB,GAAW,GAAM,GACpCuH,EAAMoH,SAEN,KAAK,GAAIP,KAAgBE,GACzB,CACE,GAAItK,GAAW9C,EAAWkN,GACtBQ,EAAWL,EAAmBH,EAElCpK,GAASwK,SAAWI,EAASJ,SAC7BxK,EAASyK,cAAgBG,EAASH,cAClCzK,EAASzC,QAAUqN,EAASrN,WAKlCsN,gBAAiB,WAIf,IAAK,GAFDxN,GAAOnB,KAAKmB,KAEPU,EAAI,EAAGA,EAAIV,EAAKW,OAAQD,IAE/BV,EAAMU,IAGRV,GAAKW,OAAS,GAGhBgL,OAAQ,SAASpF,GAEf,GAAIhE,GAAU1D,KAAKc,OAAOqE,QAE1BnF,MAAK2O,kBACL3O,KAAK4E,aAAc8C,GAEd1H,KAAKiB,cAEDjB,MAAKiB,OAAOC,SAAUlB,KAAKa,KAGpC6C,EAAQtD,SAASgJ,OAAQpJ,KAAKa,KAC9B6C,EAAQnD,UAAU6I,OAAQpJ,KAAKa,KAC/B6C,EAAQpD,SAAS8I,OAAQpJ,KAAKa,KAE9B6G,EAAO6D,IAAKvL,KAAKa,IAAKb,OAGxB0K,SAAU,WAER,GAAIhH,GAAU1D,KAAKc,OAAOqE,QAE1BzB,GAAQpD,SAAS8I,OAAQpJ,KAAKa,KAC9B6C,EAAQnD,UAAU6I,OAAQpJ,KAAKa,KAC/B6C,EAAQtD,SAASmL,IAAKvL,KAAKa,IAAKb,MAEhC0D,EAAQS,MAAOnE,KAAKc,OAAQd,KAAKgB,UAAWhB,KAAKiB,SAGnD8I,QAAS,WAEP,GAAI7I,GAAWlB,KAAKkB,QAEpBlB,MAAKkB,YACLlB,KAAK2O,kBACL3O,KAAK8J,mBAEL,KAAK,GAAI8E,KAAY1N,GAEnBA,EAAU0N,GAAW7E,WAIzBD,kBAAmB,WAEjB,GAAIpG,GAAU1D,KAAKc,OAAOqE,QAE1BzB,GAAQtD,SAASgJ,OAAQpJ,KAAKa,KAC9B6C,EAAQpD,SAAS8I,OAAQpJ,KAAKa,KAC9B6C,EAAQnD,UAAU6I,OAAQpJ,KAAKa,KAE/Bb,KAAKc,OAAOqE,SAAW,KACvBnF,KAAKe,MAAQ,KAEbf,KAAKiB,OAAS,KACdjB,KAAKoB,MAAO,EACZpB,KAAKqB,QAAUvB,GAGjB8E,aAAc,SAAS8C,GAErB,GAAIxG,GAAWlB,KAAKkB,QAEpB,KAAK,GAAI0N,KAAY1N,GAEnBA,EAAU0N,GAAW9B,OAAQpF,MAgDjC7H,EAAOE,QAAUA,EACjBF,EAAOe,aAAeA,EACtBf,EAAOgP,iBAAmBrL,GAEzBxD,KAAMA,KAAKH","file":"rekord-session.min.js","sourcesContent":["/* rekord-session 1.4.3 - Adds mass changes & discards to Rekord by Philip Diffenderfer */\n(function(global, Rekord, undefined)\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})(this, this.Rekord);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/package.json b/package.json index 74ba332..76a357c 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "rekord-session", - "version": "1.4.2", + "version": "1.4.3", "description": "Adds mass changes & discards to Rekord", "author": "Philip Diffenderfer", "license": "MIT", + "main": "build/rekord-session.js", "repository": { "type": "git", "url": "git://github.com/Rekord/rekord-session.git"