Merge pull request #8536 from remojansen/harmony-proxy

Added harmony-proxy type definitions and updated inversify.d.ts
This commit is contained in:
Basarat Ali Syed
2016-03-14 16:20:59 +11:00
5 changed files with 586 additions and 114 deletions
+27
View File
@@ -0,0 +1,27 @@
/// <reference path="./harmony-proxy.d.ts" />
import * as Proxy from "harmony-proxy";
interface IKatana {
use: () => void;
}
class Katana implements IKatana {
public use() {
console.log("Used Katana!");
}
}
let handler = {
apply: function(target: any, thisArg: any, argArray: any) {
console.log(`Starting: ${performance.now()}`);
let result = target.apply(thisArg, argArray);
console.log(`Finished: ${performance.now()}`);
return result;
}
};
let katana = new Katana();
let katanaProxy = new Proxy<IKatana>(katana, handler);
katanaProxy.use();
+35
View File
@@ -0,0 +1,35 @@
// Type definitions for harmony-proxy 1.0.0
// Project: https://www.npmjs.com/package/harmony-proxy
// Definitions by: Remo Jansen <https://github.com/remojansen/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module harmonyProxy {
type PropertyKey = string | number | symbol;
interface ProxyHandler<T> {
getPrototypeOf? (target: T): any;
setPrototypeOf? (target: T, v: any): boolean;
isExtensible? (target: T): boolean;
preventExtensions? (target: T): boolean;
getOwnPropertyDescriptor? (target: T, p: PropertyKey): PropertyDescriptor;
has? (target: T, p: PropertyKey): boolean;
get? (target: T, p: PropertyKey, receiver: any): any;
set? (target: T, p: PropertyKey, value: any, receiver: any): boolean;
deleteProperty? (target: T, p: PropertyKey): boolean;
defineProperty? (target: T, p: PropertyKey, attributes: PropertyDescriptor): boolean;
enumerate? (target: T): PropertyKey[];
ownKeys? (target: T): PropertyKey[];
apply? (target: T, thisArg: any, argArray?: any): any;
construct? (target: T, thisArg: any, argArray?: any): any;
}
interface ProxyConstructor {
revocable<T>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };
new <T>(target: T, handler: ProxyHandler<T>): T
}
}
declare module "harmony-proxy" {
let _Proxy: harmonyProxy.ProxyConstructor;
export = _Proxy;
}
+193
View File
@@ -0,0 +1,193 @@
/// <reference path="inversify.d.ts" />
module global_module_test {
interface INinja {
fight(): string;
sneak(): string;
}
interface IKatana {
hit(): string;
}
interface IShuriken {
throw(): string;
}
class Katana implements IKatana {
public hit() {
return "cut!";
}
}
class Shuriken implements IShuriken {
public throw() {
return "hit!";
}
}
@inversify.inject("IKatana", "IShuriken")
class Ninja implements INinja {
private _katana: IKatana;
private _shuriken: IShuriken;
public constructor(katana: IKatana, shuriken: IShuriken) {
this._katana = katana;
this._shuriken = shuriken;
}
public fight() { return this._katana.hit(); };
public sneak() { return this._shuriken.throw(); };
}
let kernel = new inversify.Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken).inSingletonScope();
let ninja = kernel.get<INinja>("INinja");
console.log(ninja);
// Unbind
kernel.unbind("INinja");
kernel.unbindAll();
// Kernel modules
let module: inversify.IKernelModule = (k: inversify.IKernel) => {
k.bind<INinja>("INinja").to(Ninja);
k.bind<IKatana>("IKatana").to(Katana).inTransientScope();
k.bind<IShuriken>("IShuriken").to(Shuriken).inSingletonScope();
};
let options: inversify.IKernelOptions = {
middleware: [],
modules: [module]
};
kernel = new inversify.Kernel(options);
let ninja2 = kernel.get<INinja>("INinja");
console.log(ninja2);
// binding types
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IKatana>("IKatana").toValue(new Katana());
kernel.bind<inversify.INewable<IKatana>>("IKatana").toConstructor<IKatana>(Katana);
kernel.bind<inversify.IFactory<IKatana>>("IKatana").toFactory<IKatana>((context) => {
return () => {
return kernel.get<IKatana>("IKatana");
};
});
kernel.bind<inversify.IFactory<IKatana>>("IKatana").toAutoFactory<IKatana>();
kernel.bind<inversify.IProvider<IKatana>>("IKatana").toProvider<IKatana>((context) => {
return () => {
return new Promise<IKatana>((resolve) => {
let katana = kernel.get<IKatana>("IKatana");
resolve(katana);
});
};
});
kernel.bind<IKatana>("IKatana").to(Katana).proxy((katanaToBeInjected: IKatana) => {
// BLOCK http://stackoverflow.com/questions/35906938/how-to-enable-harmony-proxies-in-gulp-mocha
/*
let handler = {
apply: function(target, thisArgument, argumentsList) {
console.log(`Starting: ${performance.now()}`);
let result = target.apply(thisArgument, argumentsList);
console.log(`Finished: ${performance.now()}`);
return result;
}
};
return new Proxy(katanaToBeInjected, handler);
*/
return katanaToBeInjected;
});
interface IWeapon {}
interface ISamurai {
katana: IWeapon;
shuriken: IWeapon;
}
@inversify.inject("IWeapon", "IWeapon")
class Samurai implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@inversify.tagged("canThrow", false) katana: IWeapon,
@inversify.tagged("canThrow", true) shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<Samurai>("Samurai").to(Samurai);
kernel.bind<IWeapon>("IWeapon").to(Katana).whenTargetTagged("canThrow", false);
kernel.bind<IWeapon>("IWeapon").to(Shuriken).whenTargetTagged("canThrow", true);
let throwable = inversify.tagged("canThrow", true);
let notThrowable = inversify.tagged("canThrow", false);
@inversify.inject("IWeapon", "IWeapon")
class Samurai2 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@throwable("canThrow", false) katana: IWeapon,
@notThrowable("canThrow", true) shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
@inversify.inject("IWeapon", "IWeapon")
class Samurai3 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@inversify.named("strong") katana: IWeapon,
@inversify.named("weak") shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<ISamurai>("ISamurai").to(Samurai3);
kernel.bind<IWeapon>("IWeapon").to(Katana).whenTargetNamed("strong");
kernel.bind<IWeapon>("IWeapon").to(Shuriken).whenTargetNamed("weak");
@inversify.inject("IWeapon", "IWeapon")
@inversify.paramNames("katana", "shuriken")
class Samurai4 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
katana: IWeapon,
shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<ISamurai>("ISamurai").to(Samurai4);
kernel.bind<IWeapon>("IWeapon").to(Katana).when((request: inversify.IRequest) => {
return request.target.name.equals("katana");
});
kernel.bind<IWeapon>("IWeapon").to(Shuriken).when((request: inversify.IRequest) => {
return request.target.name.equals("shuriken");
});
}
+197 -72
View File
@@ -1,75 +1,200 @@
/// <reference path="inversify.d.ts" />
interface FooInterface {
name : string;
greet() : string;
import {
Kernel,
inject, tagged, named, paramNames,
IKernel, IKernelOptions, INewable,
IKernelModule, IFactory, IProvider, IRequest
} from "inversify";
module external_module_test {
interface INinja {
fight(): string;
sneak(): string;
}
interface IKatana {
hit(): string;
}
interface IShuriken {
throw(): string;
}
class Katana implements IKatana {
public hit() {
return "cut!";
}
}
class Shuriken implements IShuriken {
public throw() {
return "hit!";
}
}
@inject("IKatana", "IShuriken")
class Ninja implements INinja {
private _katana: IKatana;
private _shuriken: IShuriken;
public constructor(katana: IKatana, shuriken: IShuriken) {
this._katana = katana;
this._shuriken = shuriken;
}
public fight() { return this._katana.hit(); };
public sneak() { return this._shuriken.throw(); };
}
let kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken).inSingletonScope();
let ninja = kernel.get<INinja>("INinja");
console.log(ninja);
// Unbind
kernel.unbind("INinja");
kernel.unbindAll();
// Kernel modules
let module: IKernelModule = (k: IKernel) => {
k.bind<INinja>("INinja").to(Ninja);
k.bind<IKatana>("IKatana").to(Katana).inTransientScope();
k.bind<IShuriken>("IShuriken").to(Shuriken).inSingletonScope();
};
let options: IKernelOptions = {
middleware: [],
modules: [module]
};
kernel = new Kernel(options);
let ninja2 = kernel.get<INinja>("INinja");
console.log(ninja2);
// binding types
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IKatana>("IKatana").toValue(new Katana());
kernel.bind<INewable<IKatana>>("IKatana").toConstructor<IKatana>(Katana);
kernel.bind<IFactory<IKatana>>("IKatana").toFactory<IKatana>((context) => {
return () => {
return kernel.get<IKatana>("IKatana");
};
});
kernel.bind<IFactory<IKatana>>("IKatana").toAutoFactory<IKatana>();
kernel.bind<IProvider<IKatana>>("IKatana").toProvider<IKatana>((context) => {
return () => {
return new Promise<IKatana>((resolve) => {
let katana = kernel.get<IKatana>("IKatana");
resolve(katana);
});
};
});
kernel.bind<IKatana>("IKatana").to(Katana).proxy((katanaToBeInjected: IKatana) => {
// BLOCK http://stackoverflow.com/questions/35906938/how-to-enable-harmony-proxies-in-gulp-mocha
/*
let handler = {
apply: function(target, thisArgument, argumentsList) {
console.log(`Starting: ${performance.now()}`);
let result = target.apply(thisArgument, argumentsList);
console.log(`Finished: ${performance.now()}`);
return result;
}
};
return new Proxy(katanaToBeInjected, handler);
*/
return katanaToBeInjected;
});
interface IWeapon {}
interface ISamurai {
katana: IWeapon;
shuriken: IWeapon;
}
@inject("IWeapon", "IWeapon")
class Samurai implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@tagged("canThrow", false) katana: IWeapon,
@tagged("canThrow", true) shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<Samurai>("Samurai").to(Samurai);
kernel.bind<IWeapon>("IWeapon").to(Katana).whenTargetTagged("canThrow", false);
kernel.bind<IWeapon>("IWeapon").to(Shuriken).whenTargetTagged("canThrow", true);
let throwable = tagged("canThrow", true);
let notThrowable = tagged("canThrow", false);
@inject("IWeapon", "IWeapon")
class Samurai2 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@throwable("canThrow", false) katana: IWeapon,
@notThrowable("canThrow", true) shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
@inject("IWeapon", "IWeapon")
class Samurai3 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
@named("strong") katana: IWeapon,
@named("weak") shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<ISamurai>("ISamurai").to(Samurai3);
kernel.bind<IWeapon>("IWeapon").to(Katana).whenTargetNamed("strong");
kernel.bind<IWeapon>("IWeapon").to(Shuriken).whenTargetNamed("weak");
@inject("IWeapon", "IWeapon")
@paramNames("katana", "shuriken")
class Samurai4 implements ISamurai {
public katana: IWeapon;
public shuriken: IWeapon;
public constructor(
katana: IWeapon,
shuriken: IWeapon
) {
this.katana = katana;
this.shuriken = shuriken;
}
}
kernel.bind<ISamurai>("ISamurai").to(Samurai4);
kernel.bind<IWeapon>("IWeapon").to(Katana).when((request: IRequest) => {
return request.target.name.equals("katana");
});
kernel.bind<IWeapon>("IWeapon").to(Shuriken).when((request: IRequest) => {
return request.target.name.equals("shuriken");
});
}
interface BarInterface {
name : string;
greet() : string;
}
interface FooBarInterface {
foo : FooInterface;
bar : BarInterface;
greet() : string;
}
class Foo implements FooInterface {
public name : string;
constructor() {
this.name = "foo";
}
public greet() : string {
return this.name;
}
}
class Bar implements BarInterface {
public name : string;
constructor() {
this.name = "bar";
}
public greet() : string {
return this.name;
}
}
class FooBar implements FooBarInterface {
public foo : FooInterface;
public bar : BarInterface;
constructor(FooInterface : FooInterface, BarInterface : BarInterface) {
this.foo = FooInterface;
this.bar = BarInterface;
}
public greet() : string{
return this.foo.greet() + this.bar.greet();
}
}
// Kernel
var kernel = new inversify.Kernel();
// Identifiers
var fooRuntimeIdentifier = "FooInterface";
var barRuntimeIdentifier = "BarInterface";
var fooBarRuntimeIdentifier = "FooBarInterface";
// Bindings
var fooBinding = new inversify.TypeBinding<FooInterface>(fooRuntimeIdentifier, Foo);
var barBinding = new inversify.TypeBinding<BarInterface>(barRuntimeIdentifier, Bar);
var fooBarBinding = new inversify.TypeBinding<FooBarInterface>(fooBarRuntimeIdentifier, FooBar);
kernel.bind(fooBinding);
kernel.bind(barBinding);
kernel.bind(fooBarBinding);
// Resolve
var foo = kernel.resolve<Foo>(fooRuntimeIdentifier);
var bar = kernel.resolve<Bar>(barRuntimeIdentifier);
var fooBar = kernel.resolve<FooBar>(fooBarRuntimeIdentifier);
// Unbind
kernel.unbind(fooRuntimeIdentifier);
kernel.unbindAll();
+134 -42
View File
@@ -1,51 +1,143 @@
// Type definitions for inversify 1.0.0
// Type definitions for inversify 2.0.0-alpha.3
// Project: https://github.com/inversify/InversifyJS
// Definitions by: inversify <https://github.com/inversify>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module inversify {
interface TypeBindingInterface<TServiceType> {
runtimeIdentifier : string;
implementationType : { new(): TServiceType ;};
cache : TServiceType;
scope : number; // TypeBindingScopeEnum
}
/// <reference path="../bluebird/bluebird.d.ts" />
interface KernelInterface {
bind(typeBinding : TypeBindingInterface<any>) : void;
unbind(runtimeIdentifier : string) : void;
unbindAll() : void;
resolve<TImplementationType>(runtimeIdentifier : string) : TImplementationType;
}
declare namespace inversify {
enum TypeBindingScopeEnum {
Transient = 0,
Singleton = 1,
}
interface IKernelConstructor {
new(options?: IKernelOptions): IKernel;
}
class TypeBinding<TServiceType> implements TypeBindingInterface<TServiceType> {
runtimeIdentifier: string;
implementationType: {
new (): TServiceType;
};
cache: TServiceType;
scope: TypeBindingScopeEnum;
constructor(runtimeIdentifier: string, implementationType: {
new (...args: any[]): TServiceType;
}, scopeType?: TypeBindingScopeEnum);
}
export interface IKernel {
bind<T>(runtimeIdentifier: string): IBindingToSyntax<T>;
unbind(runtimeIdentifier: string): void;
unbindAll(): void;
get<T>(runtimeIdentifier: string): T;
getAll<T>(runtimeIdentifier: string): T[];
}
class Kernel implements KernelInterface {
private _bindings;
bind(typeBinding: TypeBindingInterface<any>): void;
unbind(runtimeIdentifier: string): void;
unbindAll(): void;
resolve<TImplementationType>(runtimeIdentifier: string): TImplementationType;
private _validateBinding(typeBinding);
private _getConstructorArguments(func);
private _injectDependencies<TImplementationType>(func);
private _construct<TImplementationType>(constr, args);
constructor();
}
export interface IKernelOptions {
middleware?: IMiddleware[];
modules?: IKernelModule[];
}
interface IMiddleware extends Function {
(...args: any[]): any;
}
export interface IKernelModule extends Function {
(kernel: IKernel): void;
}
interface IBindingToSyntax<T> {
to(constructor: { new(...args: any[]): T; }): IBindingInWhenProxySyntax<T>;
toValue(value: T): IBindingInWhenProxySyntax<T>;
toConstructor<T2>(constructor: INewable<T2>): IBindingInWhenProxySyntax<T>;
toFactory<T2>(factory: IFactoryCreator<T2>): IBindingInWhenProxySyntax<T>;
toAutoFactory<T2>(): IBindingInWhenProxySyntax<T>;
toProvider<T2>(provider: IProviderCreator<T2>): IBindingInWhenProxySyntax<T>;
}
interface IBindingInWhenProxySyntax<T> {
inTransientScope(): IBindingInWhenProxySyntax<T>;
inSingletonScope(): IBindingInWhenProxySyntax<T>;
when(constraint: (request: IRequest) => boolean): IBindingInWhenProxySyntax<T>;
whenTargetNamed(name: string): IBindingInWhenProxySyntax<T>;
whenTargetTagged(tag: string, value: any): IBindingInWhenProxySyntax<T>;
proxy(fn: (injectable: T) => T): IBindingInWhenProxySyntax<T>;
}
export interface IFactory<T> extends Function {
(): T;
}
interface IFactoryCreator<T> extends Function {
(context: IContext): IFactory<T>;
}
export interface INewable<T> {
new(...args: any[]): T;
}
export interface IProvider<T> extends Function {
(): Promise<T>;
}
interface IProviderCreator<T> extends Function {
(context: IContext): IProvider<T>;
}
export interface IContext {
kernel: IKernel;
plan: IPlan;
addPlan(plan: IPlan): void;
}
export interface IPlan {
parentContext: IContext;
rootRequest: IRequest;
}
export interface IRequest {
service: string;
parentContext: IContext;
parentRequest: IRequest;
childRequests: IRequest[];
target: ITarget;
bindings: IBinding<any>[];
addChildRequest(
service: string,
bindings: (IBinding<any>|IBinding<any>[]),
target: ITarget): IRequest;
}
export interface IBinding<T> {
runtimeIdentifier: string;
implementationType: INewable<T>;
factory: IFactoryCreator<any>;
provider: IProviderCreator<any>;
constraint: (request: IRequest) => boolean;
proxyMaker: (injectable: T) => T;
cache: T;
scope: number; // BindingScope
type: number; // BindingType
}
export interface ITarget {
service: IQueryableString;
name: IQueryableString;
metadata: Array<IMetadata>;
isArray(): boolean;
isNamed(): boolean;
isTagged(): boolean;
matchesName(name: string): boolean;
matchesTag(name: IMetadata): boolean;
}
export interface IQueryableString {
startsWith(searchString: string): boolean;
endsWith(searchString: string): boolean;
contains(searchString: string): boolean;
equals(compareString: string): boolean;
value(): string;
}
export interface IMetadata {
key: string;
value: any;
}
export var Kernel: IKernelConstructor;
export var decorate: any;
export function inject(...typeIdentifiers: string[]): (typeConstructor: any) => void;
export var tagged: any;
export var named: any;
export var paramNames: any;
}
declare module "inversify" {
export = inversify;
}