This commit is contained in:
crusader 2017-08-01 19:28:42 +09:00
parent c5358742ce
commit d08a77a279
61 changed files with 334 additions and 637 deletions

View File

@ -0,0 +1,33 @@
import {
ClassType,
} from '@loafer/core/constants';
import AppContext from '@loafer/context/AppContext';
import DefaultAppContext from '@loafer/context/implement/DefaultAppContext';
import ApplicationStater from '@loafer/application/ApplicationStater';
class Application {
private appContext: AppContext;
private appClass: ClassType;
private appInstance: ApplicationStater;
public constructor(clazz: ClassType) {
this.appClass = clazz;
}
public run(): AppContext {
this.appContext = new DefaultAppContext();
this.appInstance = this.appContext.getPouchByClass(this.appClass, undefined);
this.appInstance.start();
return this.appContext;
}
public static run(clazz: ClassType): AppContext {
return new Application(clazz).run();
}
}
export default Application;

View File

@ -0,0 +1,5 @@
interface ApplicationStater {
start(): void;
}
export default ApplicationStater;

View File

@ -1 +0,0 @@
export * from './reflect';

View File

@ -1,2 +0,0 @@
export const CONTEXT_CONFIGURATION_DEFINITION = 'loafer:context/configuration_definition';
export const CONTEXT_INJECTABLE_DEFINITION = 'loafer:context/injectable_definition';

View File

@ -0,0 +1,28 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import GetAppContext from '@loafer/context';
import { InjectableSterotype } from '@loafer/pouches/constants';
import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory';
import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
import { validateQualifier } from '@loafer/pouches/util/qualifier';
const App = (qualifier?: string | symbol ) => createDecorator('App', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let configurationDefinition = getInjectableDefinition(target.prototype, ConfigurationDefinition, false);
if (undefined !== configurationDefinition) {
throw new Error('Cannot apply @Injectable or @Injectable stereotype decorator multiple times.');
}
configurationDefinition = getInjectableDefinition(target.prototype, ConfigurationDefinition, true);
configurationDefinition.Stereotype = InjectableSterotype.APP;
configurationDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
return target;
},
});
export default App;

View File

@ -1,6 +1,6 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDefinition';
import { getConfigurationDefinition } from '@loafer/context/util/metadata';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import GetAppContext from '@loafer/context';
import { InjectableSterotype } from '@loafer/pouches/constants';
@ -10,19 +10,15 @@ import { validateQualifier } from '@loafer/pouches/util/qualifier';
const Configuration = (qualifier?: string | symbol ) => createDecorator('Configuration', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target.prototype, false);
let configurationDefinition: ConfigurationDefinition = getInjectableDefinition(target.prototype, ConfigurationDefinition, false);
if (undefined !== configurationDefinition) {
throw new Error('Cannot apply @Injectable or @Injectable stereotype decorator multiple times.');
}
configurationDefinition = getConfigurationDefinition(target.prototype, true);
configurationDefinition = getInjectableDefinition(target.prototype, ConfigurationDefinition, true);
configurationDefinition.Stereotype = InjectableSterotype.CONFIGURATION;
configurationDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;
pouchDefinitionRegistry.registerPouchDefinition(configurationDefinition);
return target;
},

View File

@ -1,12 +1,14 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDefinition';
import { getConfigurationDefinition } from '@loafer/context/util/metadata';
import { InjectableSterotype } from '@loafer/pouches/constants';
import PouchConfig from '@loafer/context/decorator/PouchConfig';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import { InjectableSterotype } from '@loafer/pouches/constants';
const Pouch = (pouchConfig: PouchConfig = {}) => createDecorator('Pouch', {
methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target, false);
let configurationDefinition: ConfigurationDefinition = getInjectableDefinition(target, ConfigurationDefinition, false);
if (undefined === configurationDefinition || InjectableSterotype.CONFIGURATION !== configurationDefinition.Stereotype) {
throw new Error('Cannot apply @Pouch decorator on not @Configuration class.');
}

View File

@ -1,6 +1,6 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/context/util/metadata';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import GetAppContext from '@loafer/context';
import { InjectableSterotype } from '@loafer/pouches/constants';
@ -10,19 +10,15 @@ import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefin
const Service = (qualifier?: string | symbol ) => createDecorator('Service', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false);
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, InjectableDefinition, false);
if (undefined !== injectableDefinition) {
throw new Error('Cannot apply @Injectable or @Injectable stereotype decorator multiple times.');
}
injectableDefinition = getInjectableDefinition(target.prototype, true);
injectableDefinition = getInjectableDefinition(target.prototype, InjectableDefinition, true);
injectableDefinition.Stereotype = InjectableSterotype.SERVICE;
injectableDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;
pouchDefinitionRegistry.registerPouchDefinition(injectableDefinition);
return target;
},

View File

@ -1,6 +1,6 @@
import { ClassType, DESIGN_RETURNTYPE, PropertyType } from '@loafer/core/constants';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import PouchConfig from '@loafer/context/decorator/PouchConfig';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
class ConfigurationDefinition extends InjectableDefinition {
protected _qualifier: PropertyType = undefined;

View File

@ -21,8 +21,8 @@ class DefaultAppContext implements AppContext {
public getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any {
return this.pouchFactory.getPouch(qualifier, clazz, args);
}
public getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
return this.pouchFactory.getPouchByType(clazz, qualifier, args);
public getPouchByClass(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
return this.pouchFactory.getPouchByClass(clazz, qualifier, args);
}
}

View File

@ -1,7 +0,0 @@
import { ClassType } from '@loafer/core/constants';
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
import { CONTEXT_INJECTABLE_DEFINITION } from '@loafer/context/constants';
import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDefinition';
export const getConfigurationDefinition = (clazz: ClassType, isCreate: boolean = false) =>
getClassMetadata(clazz, CONTEXT_INJECTABLE_DEFINITION, ConfigurationDefinition, isCreate);

View File

@ -1,2 +0,0 @@
export * from './configuration';
export * from './injectable';

View File

@ -1,7 +0,0 @@
import { ClassType } from '@loafer/core/constants';
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
import { CONTEXT_INJECTABLE_DEFINITION } from '@loafer/context/constants';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
export const getInjectableDefinition = (clazz: ClassType, isCreate: boolean = false) =>
getClassMetadata(clazz, CONTEXT_INJECTABLE_DEFINITION, InjectableDefinition, isCreate);

View File

@ -1 +1,2 @@
export const POUCH_INJECTABLE_DEFINITION = 'loafer:pouch/injectable_definition';
export const POUCH_INJECT_DEFINITION = 'loafer:pouch/inject_definition';

View File

@ -1,5 +1,6 @@
export enum InjectableSterotype {
INJECTABLE = 'Injectable',
APP = 'App',
CONFIGURATION = 'Configuration',
SERVICE = 'Service',
}

View File

@ -5,11 +5,11 @@ import { getInjectDefinition } from '@loafer/pouches/util/metadata';
const Inject = (injectConfig: InjectConfig = {}) => createDecorator('Inject', {
propertyDecorator: (target: Object, propertyKey: string | symbol): void => {
let injectDefinition: InjectDefinition = getInjectDefinition(target, true);
let injectDefinition: InjectDefinition = getInjectDefinition(target, InjectDefinition, true);
injectDefinition.addInject(injectConfig, propertyKey);
},
parameterDecorator: (target: Object, propertyKey: string | symbol, parameterIndex: number): void => {
let injectDefinition: InjectDefinition = getInjectDefinition(target, true);
let injectDefinition: InjectDefinition = getInjectDefinition(target, InjectDefinition, true);
injectDefinition.addInject(injectConfig, propertyKey, parameterIndex);
},

View File

@ -1,6 +1,6 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/context/util/metadata';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import GetAppContext from '@loafer/context';
import { validateQualifier } from '@loafer/pouches/util/qualifier';
@ -9,18 +9,14 @@ import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefin
const Injectable = (qualifier?: string | symbol ) => createDecorator('Injectable', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false);
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, InjectableDefinition, false);
if (undefined !== injectableDefinition) {
throw new Error('Cannot apply @Injectable decorator multiple times.');
}
injectableDefinition = getInjectableDefinition(target.prototype, true);
injectableDefinition = getInjectableDefinition(target.prototype, InjectableDefinition, true);
injectableDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;
pouchDefinitionRegistry.registerPouchDefinition(injectableDefinition);
return target;
},

View File

@ -1,10 +1,10 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/context/util/metadata';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
const PostConstruct = createDecorator('PostConstruct', {
methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
let injectableDefinition = getInjectableDefinition(target, false);
let injectableDefinition = getInjectableDefinition(target, InjectableDefinition, false);
if (undefined === injectableDefinition) {
throw new Error('Cannot apply @PostConstruct decorator on the not @Injectable or @Injectable stereotype class.');
}

View File

@ -1,10 +1,10 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/context/util/metadata';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
const PreDestroy = createDecorator('PreDestroy', {
methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
let injectableDefinition = getInjectableDefinition(target, false);
let injectableDefinition = getInjectableDefinition(target, InjectableDefinition, false);
if (undefined === injectableDefinition) {
throw new Error('Cannot apply @PreDestroy decorator on the not @Injectable or @Injectable stereotype class.');
}

View File

@ -1,11 +1,11 @@
import createDecorator from '@loafer/core/util/decorators/createDecorator';
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/context/util/metadata';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import { getInjectableDefinition } from '@loafer/pouches/util/metadata';
import { PouchScope } from '@loafer/pouches/constants';
const Scope = (scope: PouchScope = PouchScope.SINGLETON) => createDecorator('Scope', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let injectableDefinition = getInjectableDefinition(target.prototype, false);
let injectableDefinition = getInjectableDefinition(target.prototype, InjectableDefinition, false);
if (undefined === injectableDefinition) {
throw new Error('Cannot apply @Scope decorator on the not @Injectable or @Injectable stereotype class.');
}

View File

@ -4,11 +4,11 @@ import { getInjectDefinition } from '@loafer/pouches/util/metadata';
const Value = (value: string) => createDecorator('Value', {
propertyDecorator: (target: Object, propertyKey: string | symbol): void => {
let injectDefinition: InjectDefinition = getInjectDefinition(target, true);
let injectDefinition: InjectDefinition = getInjectDefinition(target, InjectDefinition, true);
injectDefinition.addValue(value, propertyKey);
},
parameterDecorator: (target: Object, propertyKey: string | symbol, parameterIndex: number): void => {
let injectDefinition: InjectDefinition = getInjectDefinition(target, true);
let injectDefinition: InjectDefinition = getInjectDefinition(target, InjectDefinition, true);
injectDefinition.addValue(value, propertyKey, parameterIndex);
},

View File

@ -17,7 +17,7 @@ interface PouchFactory {
* @param args are argument of target constructor
* @returns an instance of pouch
*/
getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any;
getPouchByClass(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any;
}

View File

@ -3,6 +3,10 @@ import {
PropertyType,
} from '@loafer/core/constants';
import {
InjectableSterotype,
} from '@loafer/pouches/constants';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
@ -15,16 +19,19 @@ import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/Def
abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implements PouchDefinitionRegistry {
protected pouchDefinitionMap: Map<PropertyType, Map<ClassType, PouchDefinition>>;
protected pouchDefinitionStereotypeMap: Map<InjectableSterotype, Map<ClassType, PouchDefinition>>;
public constructor() {
super();
this.pouchDefinitionMap = new Map();
this.pouchDefinitionStereotypeMap = new Map();
}
public registerPouchDefinition(pouchDefinition: PouchDefinition): void {
let clazz = pouchDefinition.Clazz;
let qualifier = validateQualifier(clazz, pouchDefinition.Qualifier);
if (this.hasPouchDefinition(clazz, qualifier)) {
if (this.hasPouchDefinition(qualifier, clazz)) {
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
}
let map = this.pouchDefinitionMap.get(qualifier);
@ -34,30 +41,68 @@ abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implem
}
map.set(clazz, pouchDefinition);
}
public removePouchDefinition(clazz: ClassType, qualifier?: PropertyType): void {
const _qualifier = validateQualifier(clazz, qualifier);
if (!this.hasPouchDefinition(clazz, _qualifier)) {
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is not exist`);
}
this.pouchDefinitionMap.get(_qualifier).delete(clazz);
if (0 === this.pouchDefinitionMap.get(_qualifier).size) {
this.pouchDefinitionMap.delete(_qualifier);
}
}
public getPouchDefinition(clazz: ClassType, qualifier?: PropertyType): PouchDefinition {
const _qualifier = validateQualifier(clazz, qualifier);
if (!this.pouchDefinitionMap.has(_qualifier)) {
public getPouchDefinition(qualifier: PropertyType, clazz?: ClassType): PouchDefinition {
if (!this.pouchDefinitionMap.has(qualifier)) {
return undefined;
}
return this.pouchDefinitionMap.get(_qualifier).get(clazz);
let map = this.pouchDefinitionMap.get(qualifier);
let count = map.size;
let pouchDefinition: PouchDefinition;
try {
pouchDefinition = this._getDefinition(map, clazz);
} catch(e) {
console.log(`Type of Pouch Definition[${qualifier}] cannot be specified (count:${count})`);
}
return pouchDefinition;
}
public hasPouchDefinition(clazz: ClassType, qualifier?: PropertyType): boolean {
return undefined === this.getPouchDefinition(clazz, qualifier) ? false : true;
public getPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): PouchDefinition {
const _qualifier = validateQualifier(clazz, qualifier);
return this.getPouchDefinition(_qualifier, clazz);
}
public hasPouchDefinition(qualifier: PropertyType, clazz?: ClassType): boolean {
return undefined === this.getPouchDefinition(qualifier, clazz) ? false : true;
}
public hasPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): boolean {
const _qualifier = validateQualifier(clazz, qualifier);
return this.hasPouchDefinition(_qualifier, clazz);
}
public removePouchDefinition(qualifier: PropertyType, clazz?: ClassType): void {
if (!this.hasPouchDefinition(qualifier, clazz)) {
console.log(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is not exist`);
return;
}
this.pouchDefinitionMap.get(qualifier).delete(clazz);
if (0 === this.pouchDefinitionMap.get(qualifier).size) {
this.pouchDefinitionMap.delete(qualifier);
}
}
public removePouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): void {
const _qualifier = validateQualifier(clazz, qualifier);
this.removePouchDefinition(_qualifier, clazz);
}
private _getDefinition(map: Map<ClassType, PouchDefinition>, clazz?: ClassType): PouchDefinition {
if (undefined !== clazz) {
return map.get(clazz);
}
const count = map.size;
if (1 < count) {
throw new Error('Type of Pouch Definition cannot be specified.');
}
for (let value of Array.from(map.values())) {
return value;
}
}
}
export default AbstractPouchFactory;

View File

@ -6,11 +6,24 @@ import {
import {
PouchScope,
POUCH_INJECT_DEFINITION,
POUCH_INJECTABLE_DEFINITION,
} from '@loafer/pouches/constants';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
import InjectConfig from '@loafer/pouches/decorator/InjectConfig';
import InjectDefinition, {
InjectItem,
} from '@loafer/pouches/definition/InjectDefinition';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
import PouchFactory from '@loafer/pouches/factory/PouchFactory';
import AbstractPouchFactory from '@loafer/pouches/factory/implement/AbstractPouchFactory';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
@ -21,15 +34,99 @@ class DefaultPouchFactory extends AbstractPouchFactory implements PouchFactory,
super();
}
public getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any {
let pouchDefinition = this._getPouchDefinition(qualifier, clazz);
if (undefined === pouchDefinition) {
throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`);
}
return null;
return this._getPouch(pouchDefinition, ...args);
}
public getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
public getPouchByClass(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
let _qualifier = validateQualifier(clazz, qualifier);
return null;
let pouchDefinition = this._getPouchDefinition(_qualifier, clazz);
if (undefined === pouchDefinition) {
throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`);
}
return this._getPouch(pouchDefinition, ...args);
}
private _getPouchDefinition(qualifier: PropertyType, clazz: ClassType): PouchDefinition {
let pouchDefinition = this.getPouchDefinition(qualifier, clazz);
if (undefined === pouchDefinition) {
pouchDefinition = this._getInjectableDefinition(clazz);
if (undefined !== pouchDefinition) {
this.registerPouchDefinition(pouchDefinition);
}
}
return pouchDefinition;
}
private _getPouch(pouchDefinition: PouchDefinition, ...args: any[]): any {
let instance;
if (pouchDefinition.isSingleton()) {
instance = this.getSingleton(pouchDefinition.Qualifier, pouchDefinition.Clazz);
if (undefined !== instance) {
return instance;
}
}
instance = Object.create(pouchDefinition.Clazz);
instance.constructor.apply(instance, ...args);
this._injectDependency(instance, pouchDefinition.Clazz);
}
private _injectDependency(instance: any, clazz: ClassType): void {
if (clazz.constructor === Object) {
return;
}
let injectDefinition: InjectDefinition = this._getInjectDefinition(clazz);
if (undefined !== injectDefinition) {
let injectors: Map<PropertyType, InjectItem> = injectDefinition.injectors;
let propertyDescriptor: PropertyDescriptor;
injectors.forEach((injectItem, key, map) => {
propertyDescriptor = Object.getOwnPropertyDescriptor(clazz, key);
switch (injectItem.decoratorType) {
case DecoratorType.PROPERTY:
this._injectDependencyProperty(instance, clazz, key, propertyDescriptor, injectItem.propertyConfig);
break;
case DecoratorType.PARAMETER:
this._injectDependencyParameter(instance, propertyDescriptor, injectItem.parameterConfigMap);
break;
default:
break;
}
});
}
this._injectDependency(instance, Object.getPrototypeOf(clazz));
}
private _injectDependencyProperty(instance: any, clazz: ClassType, propertyKey: PropertyType,
propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void {
let pouch = this.getPouchByClass(injectConfig.clazz, injectConfig.qualifier);
if (injectConfig.required && undefined === instance) {
throw new Error(`Pouch which used by [${clazz.constructor.name}.${propertyKey}] is not exist in the context.`);
}
instance[propertyKey] = pouch;
}
private _injectDependencyParameter(target: object, propertyDescriptor: PropertyDescriptor,
parameterConfigs: Map<number, InjectConfig>): void {
console.log('');
}
private _getInjectableDefinition(clazz: ClassType): InjectableDefinition {
return Reflect.getMetadata(POUCH_INJECTABLE_DEFINITION, clazz);
}
private _getInjectDefinition(clazz: ClassType): InjectDefinition {
return Reflect.getMetadata(POUCH_INJECT_DEFINITION, clazz);
}
}
export default DefaultPouchFactory;

View File

@ -13,6 +13,7 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
protected singletonInstanceMap: Map<PropertyType, Map<ClassType, any>>;
protected constructor() {
this.singletonInstanceMap = new Map();
}
public registerSingleton(pouch: any, qualifier?: PropertyType): void {

View File

@ -7,9 +7,14 @@ import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
interface PouchDefinitionRegistry {
registerPouchDefinition(pouchDefinition: PouchDefinition): void;
removePouchDefinition(clazz: ClassType, qualifier?: PropertyType): void;
getPouchDefinition(clazz: ClassType, qualifier?: PropertyType): PouchDefinition;
hasPouchDefinition(clazz: ClassType, qualifier?: PropertyType): boolean;
removePouchDefinition(qualifier: PropertyType, clazz?: ClassType): void;
getPouchDefinition(qualifier: PropertyType, clazz?: ClassType): PouchDefinition;
hasPouchDefinition(qualifier: PropertyType, clazz?: ClassType): boolean;
removePouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): void;
getPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): PouchDefinition;
hasPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): boolean;
}
export default PouchDefinitionRegistry;

View File

@ -1 +1,2 @@
export * from './inject';
export * from './injectable';

View File

@ -1,9 +1,11 @@
import { ClassType } from '@loafer/core/constants';
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
import getClassMetadata, {
MetadataDefinable,
} from '@loafer/core/util/metadata/getClassMetadata';
import { POUCH_INJECT_DEFINITION } from '@loafer/pouches/constants';
import InjectDefinition from '@loafer/pouches/definition/InjectDefinition';
export const getInjectDefinition =
(clazz: ClassType, isCreate: boolean = false) =>
getClassMetadata(clazz, POUCH_INJECT_DEFINITION, InjectDefinition, isCreate);
<T>(clazz: ClassType, definitionType: MetadataDefinable<T>, isCreate: boolean = false) =>
getClassMetadata(clazz, POUCH_INJECT_DEFINITION, definitionType, isCreate);

View File

@ -0,0 +1,9 @@
import { ClassType } from '@loafer/core/constants';
import getClassMetadata, {
MetadataDefinable,
} from '@loafer/core/util/metadata/getClassMetadata';
import { POUCH_INJECTABLE_DEFINITION } from '@loafer/pouches/constants';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
export const getInjectableDefinition = <T>(clazz: ClassType, definitionType: MetadataDefinable<T>, isCreate: boolean = false) =>
getClassMetadata(clazz, POUCH_INJECTABLE_DEFINITION, definitionType, isCreate);

View File

@ -1,23 +0,0 @@
import Service from '@overflow/commons/api/Service';
import ApiKey from '../model/ApiKey';
import Domain from '@overflow/domain/api/model/Domain';
class ApiKeyService extends Service {
public constructor() {
super('ApiKeyService');
}
public regist(apikey: ApiKey): ApiKey {
return null;
}
public read(domain: Domain): ApiKey {
return null;
}
}
export default ApiKeyService;

View File

@ -1,15 +0,0 @@
import Configuration from '@loafer/context/decorator/Configuration';
import Pouch from '@loafer/context/decorator/Pouch';
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
@Configuration()
class AppConfig {
/**
* setWebsocket
*/
@Pouch()
public setWebsocket(): WebSocketRPC {
return null;
}
}

View File

@ -2,7 +2,7 @@ import { ReducersMapObject } from 'redux';
import { SagaWatcher } from '@overflow/commons/constant';
import signInReducer from '@overflow/member/redux/reducer/signIn';
// import signInSagaWatchers from '@overflow/member/redux/saga/signIn';
import asyncRequestSagaWatchers from '@overflow/commons/redux/saga/asyncRequest';
// Container Configuration
export interface ContainerConfig {
@ -39,6 +39,7 @@ const reduxConfig: ReduxConfig = {
signInReducer,
],
sagaWarchers: [
...asyncRequestSagaWatchers,
],
};

View File

@ -41,7 +41,11 @@ import {
import * as injectTapEventPlugin from 'react-tap-event-plugin';
import Application from '@loafer/application/Application';
import ApplicationStater from '@loafer/application/ApplicationStater';
import Platform from '@overflow/commons/platform';
import App from '@loafer/context/decorator/App';
import Inject from '@loafer/pouches/decorator/Inject';
import AppContext from '@loafer/context/AppContext';
import GetAppContext from '@loafer/context';
@ -52,7 +56,9 @@ import { SagaWatcher } from '@overflow/commons/constant';
import appConfig, { Config, ReduxState } from './config';
import App from './views/App';
import * as AppView from './views/App';
declare global {
interface Window {
@ -64,12 +70,14 @@ declare global {
injectTapEventPlugin();
class Application {
@App()
class OFApplication implements ApplicationStater {
private static isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
private static useReduxDevTools:boolean = window.devToolsExtension && !Application.isProduction ? true : false;
private static useReduxDevTools:boolean = window.devToolsExtension && !OFApplication.isProduction ? true : false;
private config: Config;
private container: HTMLElement;
@Inject()
private context: AppContext;
private rpcClient: WebSocketRPC;
private store: Store<any>;
@ -83,11 +91,10 @@ class Application {
}
public static main(): void {
let application = new Application();
application.start();
Application.run(OFApplication.prototype);
}
private async start(): Promise<void> {
public async start(): Promise<void> {
try {
this.container = await Platform.getAppContainer(this.config.container.placeholderID);
this.displayLoading();
@ -152,7 +159,7 @@ class Application {
this.store = createStore(
ReducerContext.reducer,
this.config.redux.state,
Application.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
OFApplication.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
);
// saga
this.sagaMiddleware.run(this.initReduxSagaWarchers, this.config.redux.sagaWarchers);
@ -202,13 +209,13 @@ class Application {
private displayApp(): void {
Application.isProduction ? this.displayProductionApp() : this.displayDebugApp();
OFApplication.isProduction ? this.displayProductionApp() : this.displayDebugApp();
}
private displayProductionApp(): void {
ReactDOM.render(
<Provider store={this.store}>
<ConnectedRouter history={this.history}>
<App />
<AppView.default />
</ConnectedRouter>
</Provider>,
this.container,
@ -236,7 +243,7 @@ class Application {
<AppContainer>
<Provider store={this.store}>
<ConnectedRouter history={this.history}>
<App />
<AppView.default />
</ConnectedRouter>
</Provider>
</AppContainer>
@ -247,4 +254,4 @@ class Application {
}
Application.main();
OFApplication.main();

View File

@ -8,6 +8,8 @@ export const REQUEST: REQUEST = '@@overflow/anync/REQUEST';
// Action Creater
export type request = (service: string, method: string, requestType: string, ...args: any[]) => Action<AsyncRequestPayload>;
export type requestSuccess = (requestType: string, result: any) => Action<any>;
export type requestFailure = (requestType: string, error: any) => Action<any>;
export const request: request = (service: string, method: string, requestType: string, ...args: any[]): Action<AsyncRequestPayload> => {
return {
@ -20,3 +22,17 @@ export const request: request = (service: string, method: string, requestType: s
},
};
};
export const requestSuccess: requestSuccess = (requestType: string, result: any): Action<any> => {
return {
type: `${requestType}/SUCCESS`,
payload: result,
};
};
export const requestFailure: requestFailure = (requestType: string, error: any): Action<any> => {
return {
type: `${requestType}/FAILURE`,
payload: error,
};
};

View File

@ -5,26 +5,26 @@ import GetAppContext from '@loafer/context';
import AppContext from '@loafer/context/AppContext';
import { SagaWatcher } from '@overflow/commons/constant';
import Action from '@overflow/commons/redux/Action';
import * as AsyncRequestActions from '@overflow/commons/redux/action/asyncRequest';
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
import * as AsyncRequestActions from '../action/asyncRequest';
import AsyncRequestPayload from '../payload/AsyncRequestPayload';
function* request(action: Action<AsyncRequestPayload>): SagaIterator {
const {service, method, requestType, args} = action.payload;
try {
const {service, method, requestType, args} = action.payload;
// yield put({
// type: types.SENDING_REQUEST,
// payload: {sendingRequest: true},
// });
// let serviceInstance = GetAppContext().getPouch(service);
// const member = yield call({context: memberService, fn: memberService.signin}, signinId, signinPw);
// });`${service}.${method}`
let webSocketRPC: WebSocketRPC = GetAppContext().getPouchByClass(WebSocketRPC.prototype, undefined);
let result = yield call({context: webSocketRPC, fn: webSocketRPC.Call}, `${service}.${method}`, args);
// if (responseBody.token === undefined) {
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
// }
// yield put(SigninActions.requestSuccess(member));
yield put(AsyncRequestActions.requestSuccess(requestType, result));
} catch (e) {
// yield put(SigninActions.requestFailure(e));
yield put(AsyncRequestActions.requestFailure(requestType, e));
} finally {
// yield put({
// type: types.SENDING_REQUEST,

View File

@ -10,7 +10,7 @@ import {
RPCResponse,
} from './protocol/rpc';
import Injectable from '@loafer/context/decorator/Injectable';
import Injectable from '@loafer/pouches/decorator/Injectable';
export type OnDisconnectFunc = () => void;
export type OnResponseFunc = (response: any) => void;

View File

@ -1,18 +0,0 @@
import Service from '@overflow/commons/api/Service';
import DomainMember from '../model/DomainMember';
class DomainMemberService extends Service {
public constructor() {
super('DomainMemberService');
}
public regist(domainMember: DomainMember): void {
return null;
}
}
export default DomainMemberService;

View File

@ -1,18 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Domain from '../model/Domain';
class DomainService extends Service {
public constructor() {
super('DomainService');
}
public regist(domain: Domain): void {
return null;
}
}
export default DomainService;

View File

@ -1,35 +0,0 @@
import Service from '@overflow/commons/api/Service';
import EmailAuth from '../model/EmailAuth';
class EmailAuthService extends Service {
public constructor() {
super('EmailAuthService');
}
public sendEmailByMember(id: number, email: string): Promise<EmailAuth> {
return new Promise<EmailAuth>((resolve) => {
const json = this.send('sendEmailByMember', [id, email]);
});
}
public read(id: number): Promise<EmailAuth> {
return null;
}
public readByAuthKey(authKey: string): Promise<EmailAuth> {
return null;
}
public readByMember(memberId: number): Promise<EmailAuth[]> {
return null;
}
public modify(auth:EmailAuth): Promise<EmailAuth> {
return null;
}
}
export default EmailAuthService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraHost from '../model/InfraHost';
class InfraHostService extends Service {
public constructor() {
super('InfraHostService');
}
public regist(infraHost: InfraHost): InfraHost {
return null;
}
public read(id: number): InfraHost {
return null;
}
}
export default InfraHostService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraMachine from '../model/InfraMachine';
class InfraMachinetService extends Service {
public constructor() {
super('InfraMachinetService');
}
public regist(infraMachine: InfraMachine): InfraMachine {
return null;
}
public read(id: number): InfraMachine {
return null;
}
}
export default InfraMachinetService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraOSApplication from '../model/InfraOSApplication';
class InfraOSApplicationService extends Service {
public constructor() {
super('InfraOSApplicationService');
}
public regist(infraOSApplication: InfraOSApplication): InfraOSApplication {
return null;
}
public read(id: number): InfraOSApplication {
return null;
}
}
export default InfraOSApplicationService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraOSDaemon from '../model/InfraOSDaemon';
class InfraOSDaemonService extends Service {
public constructor() {
super('InfraOSDaemonService');
}
public regist(infraOSDaemon: InfraOSDaemon): InfraOSDaemon {
return null;
}
public read(id: number): InfraOSDaemon {
return null;
}
}
export default InfraOSDaemonService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraOSPort from '../model/InfraOSPort';
class InfraOSDaemonService extends Service {
public constructor() {
super('InfraOSDaemonService');
}
public regist(infraOSPort: InfraOSPort): InfraOSPort {
return null;
}
public read(id: number): InfraOSPort {
return null;
}
}
export default InfraOSDaemonService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraOS from '../model/InfraOS';
class InfraOSService extends Service {
public constructor() {
super('InfraOSService');
}
public regist(infraOS: InfraOS): InfraOS {
return null;
}
public read(id: number): InfraOS {
return null;
}
}
export default InfraOSService;

View File

@ -1,22 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Infra from '../model/Infra';
class InfraService extends Service {
public constructor() {
super('InfraService');
}
public regist(infra: Infra): Infra {
return null;
}
public read(id: number): Infra {
return null;
}
}
export default InfraService;

View File

@ -1,23 +0,0 @@
import Service from '@overflow/commons/api/Service';
import InfraService from '../model/InfraService';
class InfraServiceService extends Service {
public constructor() {
super('InfraServiceService');
}
public regist(infraService: InfraService): InfraService {
return null;
}
public read(id: number): InfraService {
return null;
}
}
export default InfraServiceService;

View File

@ -1,42 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Member from '../model/Member';
import Injectable from '@loafer/context/decorator/Injectable';
@Injectable()
export class MemberService extends Service {
public constructor() {
super('MemberService');
}
public signin(signinId: string, signinPw: string): Promise<Member> {
return this.send<Member>('signin', [signinId, signinPw]);
}
public signout(member: Member): Member {
return null;
}
public signup(member: Member): Member {
return null;
}
public read(id: number): Member {
return null;
}
public withdrawal(id: number): Member {
return null;
}
public modify(member: Member): Member {
return null;
}
}
export default MemberService;

View File

@ -1,25 +0,0 @@
import Service from '@overflow/commons/api/Service';
import NoAuthProbe from '../model/NoAuthProbe';
import Domain from '@overflow/domain/api/model/Domain';
export class NoAuthProbeService extends Service {
public constructor() {
super('NoAuthProbeService');
}
public regist(noAuthProbe: NoAuthProbe): NoAuthProbe {
return null;
}
// Todo List<NoAuthProbe>
public readAllByDomain(domain: Domain): NoAuthProbe[] {
return null;
}
public read(id: number): NoAuthProbe {
return null;
}
}
export default NoAuthProbeService;

View File

@ -1,25 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Probe from '../model/Probe';
import Domain from '@overflow/domain/api/model/Domain';
export class ProbeService extends Service {
public constructor() {
super('ProbeService');
}
public regist(probe: Probe): Promise<Probe> {
return null;
}
public readAllByDomain(domain: Domain): Promise<Probe[]> {
return null;
}
public readByProbeKey(probeKey: string): Promise<Probe> {
return null;
}
}
export default ProbeService;

View File

@ -1,20 +0,0 @@
import Service from '@overflow/commons/api/Service';
import ProbeTask from '../model/ProbeTask';
import Probe from '../model/Probe';
export class ProbeTaskService extends Service {
public constructor() {
super('ProbeService');
}
public regist(probeTask:ProbeTask): void {
return null;
}
public readAllByProbe(probe:Probe): Promise<ProbeTask[]> {
return null;
}
}
export default ProbeTaskService;

View File

@ -1,28 +0,0 @@
import Service from '@overflow/commons/api/Service';
import SensorItem from '../model/SensorItem';
import Sensor from '../model/Sensor';
export class SensorItemService extends Service {
public constructor() {
super('SensorItemService');
}
public regist(sensorItem:SensorItem): Promise<SensorItem> {
return null;
}
public readAllBySensor(sensor:Sensor): Promise<SensorItem[]> {
return null;
}
public read(id:number): Promise<Sensor> {
return null;
}
public remove(sensorItem:SensorItem): Promise<Sensor> {
return null;
}
}
export default SensorItemService;

View File

@ -1,47 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Sensor from '../model/Sensor';
import Target from '@overflow/target/api/model/Target';
import Probe from '@overflow/probe/api/model/Probe';
import Domain from '@overflow/domain/api/model/Domain';
export class SensorService extends Service {
public constructor() {
super('SensorService');
}
public regist(sensor:Sensor): Promise<Sensor> {
return this.send<Sensor>('regist', [sensor]);
}
public readAllByTarget(target:Target): Promise<Sensor[]> {
return this.send<Sensor[]>('readAllByTarget', [target]);
}
public readAllByProbe(probe: Probe): Promise<Sensor[]> {
return this.send<Sensor[]>('readAllByProbe', [probe]);
}
public readAllByDomain(domain: Domain): Promise<Sensor[]> {
return this.send<Sensor[]>('readAllByDomain', [domain]);
}
public read(id:number): Promise<Sensor> {
return this.send<Sensor>('read', [id]);
}
public remove(sensor:Sensor): Promise<Sensor> {
return null;
}
public start(sensor:Sensor): Promise<Sensor> {
return null;
}
public stop(sensor:Sensor): Promise<Sensor> {
return null;
}
}
export default SensorService;

View File

@ -1,17 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Probe from '@overflow/probe/api/model/Probe';
import Host from '@overflow/discovery/api/model/Host';
export class TargetDiscoveryService extends Service {
public constructor() {
super('TargetDiscoveryService');
}
public saveAllTarget(hosts:Host[], probe:Probe): void {
return null;
}
}
export default TargetDiscoveryService;

View File

@ -1,36 +0,0 @@
import Service from '@overflow/commons/api/Service';
import Target from '../model/Target';
import Probe from '@overflow/probe/api/model/Probe';
export class TargetService extends Service {
public constructor() {
super('TargetService');
}
public regist(target: Target): Promise<Target> {
return new Promise<Target>(resolve => {
const json = this.send('regist', target);
let tempTarget: Target;
resolve(tempTarget);
});
}
public read(id:string): Promise<Target> {
return new Promise<Target>(resolve => {
resolve(null);
});
}
public readAllByProbe(probe:Probe): Promise<Target[]> {
return null;
}
public remove(target:Target): Promise<Target> {
return null;
}
}
export default TargetService;