Skip to content

Commit

Permalink
Major refactoring. Creates a Descriptor class that wraps everything i…
Browse files Browse the repository at this point in the history
…n a much more elegant way
  • Loading branch information
jaubourg committed May 6, 2015
1 parent d73f163 commit 81ee81b
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 70 deletions.
11 changes: 0 additions & 11 deletions lib/createCopyFunction.js

This file was deleted.

53 changes: 53 additions & 0 deletions lib/createDescriptorClassFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use strict";

var _ = require( "lodash" );
var Attempt = require( "attempt-js" );

function assignToObject( data ) {
/* jshint validthis:true */
_.assign( this.instance, data );
}

var descriptorPrototypeFields = {
request: function( definition ) {
return function( args ) {
var self = this;
return Attempt.join( definition.request.apply( definition, args ) ).chain( function( data ) {
self.import( data );
return self.instance;
} );
};
},
export: function( definition ) {
return function() {
return _.pick( this.instance, definition.export );
};
},
update: function() {
return assignToObject;
},
import: function() {
return assignToObject;
}
};

module.exports = function( Serializable, getDefinition ) {
return function( name ) {
function Instance() {}
Instance.prototype = _.create( Serializable.prototype, {
constructor: Instance
} );
function Descriptor( instance ) {
this.instance = instance || new Instance();
}
Descriptor.prototype.name = Instance[ Serializable.marker ] = name;
Descriptor.pending = Attempt.join( getDefinition( name ) ).success( function( definition ) {
delete Descriptor.pending;
_.assign( Instance.prototype, definition.proto );
_.transform( descriptorPrototypeFields, function( proto, handler, methodName ) {
proto[ methodName ] = handler( definition );
}, Descriptor.prototype );
} );
return Descriptor;
};
};
14 changes: 7 additions & 7 deletions lib/createRequestClass.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ module.exports = function( Serializable ) {
if ( value.hasOwnProperty( marker ) ) {
value = value[ marker ];
} else {
Serializable.getDescriptorForObject( value, function( descriptor, name ) {
Serializable.getDescriptor( value, function( descriptor ) {
var id = value[ marker ] = lastId++;
objects[ id ] = value;
serialized[ id ] = stringify( [ name, descriptor.export( {}, value ) ] );
serialized[ id ] = stringify( [ descriptor.name, descriptor.export() ] );
value = id;
} );
}
Expand Down Expand Up @@ -83,12 +83,12 @@ module.exports = function( Serializable ) {
var value = element[ 1 ];
if ( typeof type === "number" ) {
var target = array[ index ] = this._objects[ value ];
Serializable.getDescriptorForObject( target ).update( target, evaluate( value ) );
Serializable.getDescriptor( target ).update( evaluate( value ) );
} else {
var pending = Serializable.instantiate( type, "success", function( instance, descriptor ) {
descriptor.update( instance, value );
}, function( instance ) {
array[ index ] = instance;
var pending = Serializable.instantiate( type, "success", function( descriptor ) {
descriptor.update( value );
}, function( descriptor ) {
array[ index ] = descriptor.instance;
value = evaluate( value );
} );
if ( pending ) {
Expand Down
57 changes: 16 additions & 41 deletions lib/createSerializableClass.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,40 @@
"use strict";

var _ = require( "lodash" );
var Attempt = require( "attempt-js" );
var createCopyFunction = require( "./createCopyFunction" );

var copyFunctionFields = {
export: true,
update: true,
import: true
};
var createDescriptorClassFactory = require( "./createDescriptorClassFactory" );

module.exports = function( getDefinition ) {
function Serializable() {}
var marker = Serializable.marker = "@@json@@";
var descriptors = {};
var descriptorClasses = {};
var getDescriptorClass = createDescriptorClassFactory( Serializable, getDefinition );
function getObjectName( object ) {
var constructor = object && object.constructor;
return constructor && constructor[ marker ] || false;
}
function getDescriptor( name ) {
function Constructor() {}
Constructor.prototype = _.create( Serializable.prototype, {
constructor: Constructor
} );
Constructor[ marker ] = name;
var descriptor = {
Constructor: Constructor,
pending: Attempt.join( getDefinition( name ) ).success( function( definition ) {
delete descriptor.pending;
_.assign( Constructor.prototype, definition.proto );
_.assign( descriptor, {
init: definition.init
}, _.mapValues( copyFunctionFields, function( unused, key ) {
return createCopyFunction( definition[ key ] || [] );
} ) );
} )
};
return descriptor;
}
return _.assign( Serializable, {
instantiate: function( name, type, handler, earlyHandler ) {
var descriptor = descriptors[ name ] || ( descriptors[ name ] = getDescriptor( name ) );
var instance = new descriptor.Constructor();
var Descriptor = descriptorClasses[ name ] || ( descriptorClasses[ name ] = getDescriptorClass( name ) );
var descriptor = new Descriptor();
if ( earlyHandler ) {
earlyHandler( instance, descriptor );
earlyHandler( descriptor );
}
return descriptor.pending ? descriptor.pending[ type ]( function() {
return handler( instance, descriptor );
} ) : handler( instance, descriptor );
return Descriptor.pending ? Descriptor.pending[ type ]( function() {
return handler( descriptor );
} ) : handler( descriptor );
},
getDescriptorForObject: function( object, callback ) {
var name = getObjectName( object );
var descriptor = name && descriptors[ name ];
if ( !descriptor ) {
getDescriptor: function( instance, callback ) {
var name = getObjectName( instance );
var Descriptor = name && descriptorClasses[ name ];
if ( !Descriptor ) {
throw new Error( "unable to find descriptor in memory" );
}
if ( descriptor.pending ) {
if ( Descriptor.pending ) {
throw new Error( "descriptor is pending" );
}
var descriptor = new Descriptor( instance );
if ( callback ) {
callback( descriptor, name );
callback( descriptor );
}
return descriptor;
}
Expand Down
7 changes: 2 additions & 5 deletions lib/jser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use strict";

var Attempt = require( "attempt-js" );
var createSerializableClass = require( "./createSerializableClass" );
var createRequestClass = require( "./createRequestClass" );

Expand All @@ -12,10 +11,8 @@ module.exports = function( getDefinition ) {
return {
newInstance: function( name ) {
var args = slice.call( arguments, 1 );
return Serializable.instantiate( name, "chain", function( instance, descriptor ) {
return Attempt.join( descriptor.init.apply( instance,args ) ).chain( function() {
return instance;
} );
return Serializable.instantiate( name, "chain", function( descriptor ) {
return descriptor.request( args );
} );
},
request: function( body ) {
Expand Down
10 changes: 6 additions & 4 deletions test/jser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ var JSER = require( "../lib/jser" );

var singleClassDefinitions = {
MyClass: {
init: function( preString, flag ) {
this.string = preString + " world";
this.num = 666;
this.boolean = flag || false;
request: function( preString, flag ) {
return {
string: preString + " world",
num: 666,
boolean: flag || false
};
},
proto: {},
export: [ "boolean", "string" ]
Expand Down
4 changes: 2 additions & 2 deletions test/util/createDefinitionsGetter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ module.exports = function( definitions ) {
} );
return function( name ) {
if ( !data.hasOwnProperty( name ) ) {
throw new Error( "unknown class " + name );
return Attempt.createFailure( new Error( "unknown class " + name ) );
}
var info = data[ name ];
if ( info.requested ) {
throw new Error( "class " + name + " was already requested" );
return Attempt.createFailure( new Error( "class " + name + " was already requested" ) );
}
info.requested = true;
return info.delay !== false ? Attempt( function( success ) {
Expand Down

0 comments on commit 81ee81b

Please sign in to comment.