type-binder
Advanced tools
Comparing version 0.3.0 to 0.3.1
@@ -5,4 +5,4 @@ import "reflect-metadata"; | ||
export declare function generics(...generics: any[]): PropertyDecorator; | ||
export declare function track<V>(comparingCallback?: (v1: V, v2: V) => boolean, trackingCallback?: (value: V) => V): PropertyDecorator; | ||
export declare function trackIterable<V, I extends Iterable<V>>(comparingCallback?: (v1: V, v2: V) => boolean, trackingCallback?: (iterable: I) => V[]): PropertyDecorator; | ||
export declare function track<V>(trackingCallback?: (value: V) => V, comparingCallback?: (v1: V, v2: V) => boolean): PropertyDecorator; | ||
export declare function trackIterable<V, I extends Iterable<V>>(trackingCallback?: (iterable: I) => any[], comparingCallback?: (v1: V, v2: V) => boolean): PropertyDecorator; | ||
export declare function identifier<T>(identifier: (object: T, binder?: TypeBinder) => any, scope?: any): ClassDecorator; |
@@ -25,17 +25,17 @@ "use strict"; | ||
exports.generics = generics; | ||
function track(comparingCallback, trackingCallback) { | ||
function track(trackingCallback, comparingCallback) { | ||
if (trackingCallback === void 0) { trackingCallback = function (value) { return value; }; } | ||
if (comparingCallback === void 0) { comparingCallback = function (v1, v2) { return v1 === v2; }; } | ||
if (trackingCallback === void 0) { trackingCallback = function (value) { return value; }; } | ||
return function (target, key) { | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrack, trackingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrackCompare, comparingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrack, trackingCallback, target, key); | ||
}; | ||
} | ||
exports.track = track; | ||
function trackIterable(comparingCallback, trackingCallback) { | ||
function trackIterable(trackingCallback, comparingCallback) { | ||
if (trackingCallback === void 0) { trackingCallback = function (iterable) { return Array.from(iterable); }; } | ||
if (comparingCallback === void 0) { comparingCallback = function (v1, v2) { return v1 === v2; }; } | ||
if (trackingCallback === void 0) { trackingCallback = function (iterable) { return Array.from(iterable); }; } | ||
return function (target, key) { | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntries, trackingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntriesCompare, comparingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntries, trackingCallback, target, key); | ||
}; | ||
@@ -42,0 +42,0 @@ } |
@@ -9,2 +9,3 @@ import "reflect-metadata"; | ||
bind<T>(value: any, type: new (...args) => T, ...generics: any[]): T; | ||
update<T>(value: any, type: new (...args) => T, generics: any[], current?: T): T; | ||
isBound<T>(type: new (...args) => T, entity: T): boolean; | ||
@@ -11,0 +12,0 @@ private createObject<T>(type, source); |
@@ -10,8 +10,22 @@ "use strict"; | ||
this.bindingCallbacks = new Map(); | ||
this.bindingCallbacks.set(Map, function (value, generics) { return new Map(value.map(function (pair) { return [ | ||
_this.bind(pair[0], generics[0]), | ||
_this.bind(pair[1], generics[1]) | ||
]; })); }); | ||
this.bindingCallbacks.set(Set, function (value, generics) { return new Set(value.map(function (element) { return _this.bind(element, generics[0]); })); }); | ||
this.bindingCallbacks.set(Array, function (value, generics) { return value.map(function (element) { return _this.bind(element, generics[0]); }); }); | ||
this.bindingCallbacks.set(Map, function (value, generics, current) { | ||
if (generics === void 0) { generics = []; } | ||
if (current === void 0) { current = new Map(); } | ||
current.clear(); | ||
value.forEach(function (pair) { return current.set(_this.bind(pair[0], generics[0]), _this.bind(pair[1], generics[1])); }); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Set, function (value, generics, current) { | ||
if (generics === void 0) { generics = []; } | ||
if (current === void 0) { current = new Set(); } | ||
current.clear(); | ||
value.forEach(function (element) { return current.add(_this.bind(element, generics[0])); }); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Array, function (value, generics, current) { | ||
if (generics === void 0) { generics = []; } | ||
if (current === void 0) { current = []; } | ||
current.splice.apply(current, [0, current.length].concat(value.map(function (element) { return _this.bind(element, generics[0]); }))); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Number, this.identityBinding); | ||
@@ -30,10 +44,13 @@ this.bindingCallbacks.set(String, this.identityBinding); | ||
} | ||
return this.update(value, type, generics); | ||
}; | ||
TypeBinder.prototype.update = function (value, type, generics, current) { | ||
if (Array.isArray(type)) { | ||
generics = type.slice(1); | ||
type = type[0]; | ||
type = type.shift(); | ||
} | ||
if (this.bindingCallbacks.has(type)) { | ||
return this.bindingCallbacks.get(type)(value, generics); | ||
return this.bindingCallbacks.get(type)(value, generics, current); | ||
} | ||
else if (typeof value === "object") { | ||
else if (value !== null && typeof value === "object") { | ||
var object = this.createObject(type, value); | ||
@@ -84,17 +101,18 @@ var properties = this.createProperties(type, object, value); | ||
var propertyGenerics = Reflect.getMetadata(metadataKeys.designGenericTypes, type.prototype, property); | ||
properties[property] = { | ||
configurable: false, | ||
enumerable: true, | ||
writable: true, | ||
value: propertyType ? _this.bind.apply(_this, [source[property], propertyType].concat(propertyGenerics)) : source[property] | ||
}; | ||
var configurable = true; | ||
var enumerable = true; | ||
var writable = true; | ||
var value = propertyType | ||
? _this.update(source[property], propertyType, propertyGenerics, target[property]) | ||
: source[property]; | ||
properties[property] = { configurable: configurable, enumerable: enumerable, writable: writable, value: value }; | ||
if (Reflect.hasMetadata(metadataKeys.binderPropertyTrack, type.prototype, property)) { | ||
var trackingCallback = Reflect.getMetadata(metadataKeys.binderPropertyTrack, type.prototype, property); | ||
var value = trackingCallback(properties[property].value); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrackValue, value, target, property); | ||
var value_1 = trackingCallback(properties[property].value); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrackValue, value_1, target, property); | ||
} | ||
if (Reflect.hasMetadata(metadataKeys.binderPropertyEntries, type.prototype, property)) { | ||
var trackingCallback = Reflect.getMetadata(metadataKeys.binderPropertyEntries, type.prototype, property); | ||
var value = trackingCallback(properties[property].value); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntriesValue, value, target, property); | ||
var value_2 = trackingCallback(properties[property].value); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntriesValue, value_2, target, property); | ||
} | ||
@@ -101,0 +119,0 @@ }); |
@@ -53,2 +53,6 @@ "use strict"; | ||
__decorate([ | ||
decorators_1.bind(Array), | ||
__metadata("design:type", Array) | ||
], Baz.prototype, "digits", void 0); | ||
__decorate([ | ||
decorators_1.bind(Number), decorators_1.track(), | ||
@@ -75,2 +79,3 @@ __metadata("design:type", Number) | ||
], | ||
digits: [1, 2, 3], | ||
number: 123, | ||
@@ -77,0 +82,0 @@ bool: true, |
{ | ||
"name": "type-binder", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "A JavaScript type-binder.", | ||
@@ -26,3 +26,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/jasmine": "^2.5.38", | ||
"@types/jasmine": "^2.5.40", | ||
"babel-preset-es2015": "^6.18.0", | ||
@@ -38,3 +38,3 @@ "babel-register": "^6.18.0", | ||
"jasmine-reporters": "^2.2.0", | ||
"merge2": "^1.0.2", | ||
"merge2": "^1.0.3", | ||
"run-sequence": "^1.2.2", | ||
@@ -45,4 +45,4 @@ "typescript": "^2.1.4", | ||
"dependencies": { | ||
"reflect-metadata": "^0.1.8" | ||
"reflect-metadata": "^0.1.9" | ||
} | ||
} |
@@ -19,7 +19,8 @@ import "reflect-metadata"; | ||
export function track<V>( | ||
comparingCallback: (v1: V, v2: V) => boolean = (v1, v2) => v1 === v2, | ||
trackingCallback: (value: V) => V = value => value): PropertyDecorator { | ||
trackingCallback: (value: V) => V = value => value, | ||
comparingCallback: (v1: V, v2: V) => boolean = (v1, v2) => v1 === v2 | ||
): PropertyDecorator { | ||
return (target: Function, key: string) => { | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrack, trackingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrackCompare, comparingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyTrack, trackingCallback, target, key); | ||
}; | ||
@@ -29,7 +30,8 @@ } | ||
export function trackIterable<V, I extends Iterable<V>>( | ||
comparingCallback: (v1: V, v2: V) => boolean = (v1, v2) => v1 === v2, | ||
trackingCallback: (iterable: I) => V[] = iterable => Array.from(iterable)): PropertyDecorator { | ||
trackingCallback: (iterable: I) => any[] = iterable => Array.from(iterable), | ||
comparingCallback: (v1: V, v2: V) => boolean = (v1, v2) => v1 === v2 | ||
): PropertyDecorator { | ||
return (target: Function, key: string) => { | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntries, trackingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntriesCompare, comparingCallback, target, key); | ||
Reflect.defineMetadata(metadataKeys.binderPropertyEntries, trackingCallback, target, key); | ||
}; | ||
@@ -36,0 +38,0 @@ } |
@@ -10,18 +10,20 @@ import "reflect-metadata"; | ||
private bindingCallbacks: Map<any, (value: any, generics: any[]) => any>; | ||
private bindingCallbacks: Map<any, (value: any, generics: any[], current?: any) => any>; | ||
public constructor() { | ||
this.bindingCallbacks = new Map<any, (value: any, generics: any[]) => any>(); | ||
this.bindingCallbacks.set(Map, (value: [any, any][], generics: any[]) => new Map( | ||
value.map(pair => <[{ }, { }]> [ | ||
this.bind(pair[0], generics[0]), | ||
this.bind(pair[1], generics[1]) | ||
]) | ||
)); | ||
this.bindingCallbacks.set(Set, (value: any[], generics: any[]) => new Set( | ||
value.map(element => this.bind(element, generics[0])) | ||
)); | ||
this.bindingCallbacks.set(Array, (value: any[], generics: any[]) => value.map( | ||
element => this.bind(element, generics[0]) | ||
)); | ||
this.bindingCallbacks.set(Map, (value: [any, any][], generics: any[] = [], current: Map<any, any> = new Map()) => { | ||
current.clear(); | ||
value.forEach(pair => current.set(this.bind(pair[0], generics[0]), this.bind(pair[1], generics[1]))); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Set, (value: any[], generics: any[] = [], current: Set<any> = new Set()) => { | ||
current.clear(); | ||
value.forEach(element => current.add(this.bind(element, generics[0]))); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Array, (value: any[], generics: any[] = [], current: any[] = []) => { | ||
current.splice(0, current.length, ...value.map(element => this.bind(element, generics[0]))); | ||
return current; | ||
}); | ||
this.bindingCallbacks.set(Number, this.identityBinding); | ||
@@ -38,9 +40,13 @@ this.bindingCallbacks.set(String, this.identityBinding); | ||
public bind<T>(value: any, type: new(...args) => T, ...generics: any[]): T { | ||
return this.update(value, type, generics); | ||
} | ||
public update<T>(value: any, type: new(...args) => T, generics: any[], current?: T): T { | ||
if (Array.isArray(type)) { | ||
generics = type.slice(1); | ||
type = type[0]; | ||
type = type.shift(); | ||
} | ||
if (this.bindingCallbacks.has(type)) { | ||
return this.bindingCallbacks.get(type)(value, generics); | ||
} else if (typeof value === "object") { | ||
return this.bindingCallbacks.get(type)(value, generics, current); | ||
} else if (value !== null && typeof value === "object") { | ||
let object = this.createObject(type, value); | ||
@@ -86,12 +92,13 @@ let properties = this.createProperties(type, object, value); | ||
private createProperties<T>(type: new(...args) => T, target: T, source: Object): PropertyDescriptorMap { | ||
let properties: PropertyDescriptorMap = { }; | ||
let properties: PropertyDescriptorMap = {}; | ||
Object.getOwnPropertyNames(source).forEach(property => { | ||
let propertyType = Reflect.getMetadata(metadataKeys.designType, type.prototype, property); | ||
let propertyGenerics = Reflect.getMetadata(metadataKeys.designGenericTypes, type.prototype, property); | ||
properties[property] = { | ||
configurable: false, | ||
enumerable: true, | ||
writable: true, | ||
value: propertyType ? this.bind(source[property], propertyType, ...propertyGenerics) : source[property] | ||
}; | ||
let configurable = true; | ||
let enumerable = true; | ||
let writable = true; | ||
let value = propertyType | ||
? this.update(source[property], propertyType, propertyGenerics, target[property]) | ||
: source[property]; | ||
properties[property] = { configurable, enumerable, writable, value }; | ||
if (Reflect.hasMetadata(metadataKeys.binderPropertyTrack, type.prototype, property)) { | ||
@@ -98,0 +105,0 @@ let trackingCallback: <V>(value: V) => V = Reflect.getMetadata(metadataKeys.binderPropertyTrack, type.prototype, property); |
@@ -17,2 +17,3 @@ import "reflect-metadata"; | ||
@bind(Map) @generics(Foo, Bar) map: Map<Foo, Bar>; | ||
@bind(Array) digits: number[]; | ||
@bind(Number) @track() number: number; | ||
@@ -35,2 +36,3 @@ @bind(String) string: string; | ||
], | ||
digits: [ 1, 2, 3 ], | ||
number: 123, | ||
@@ -37,0 +39,0 @@ bool: true, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
65107
663
Updatedreflect-metadata@^0.1.9