From ba67154336b4d97a6f17e44863d2a72213cdae3f Mon Sep 17 00:00:00 2001 From: Juneil Date: Tue, 27 Mar 2018 11:27:01 +0200 Subject: [PATCH 1/3] feat(event-manager): new extension --- src/extensions/event-manager/extension.ts | 37 ++++++++++++++++ src/extensions/event-manager/index.ts | 3 ++ src/extensions/event-manager/manager.ts | 53 +++++++++++++++++++++++ src/extensions/event-manager/service.ts | 32 ++++++++++++++ src/extensions/socket-server/extension.ts | 4 +- test/integration/event-manager.test.ts | 53 +++++++++++++++++++++++ 6 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 src/extensions/event-manager/extension.ts create mode 100644 src/extensions/event-manager/index.ts create mode 100644 src/extensions/event-manager/manager.ts create mode 100644 src/extensions/event-manager/service.ts create mode 100644 test/integration/event-manager.test.ts diff --git a/src/extensions/event-manager/extension.ts b/src/extensions/event-manager/extension.ts new file mode 100644 index 0000000..9a502ef --- /dev/null +++ b/src/extensions/event-manager/extension.ts @@ -0,0 +1,37 @@ +import { CoreModule, Extension, OnExtensionLoad, OnShutdown } from '../../core/interfaces'; +import { Observable } from 'rxjs/Observable'; +import { ExtensionShutdown, ExtensionShutdownPriority } from '../../core'; +import { EventManager } from './manager'; + +export class EventManagerExt implements OnExtensionLoad, OnShutdown { + + /** + * Initilization of the extension + * + * @param {CoreModule} module + * @returns Observable + */ + onExtensionLoad(module: CoreModule): Observable { + return Observable + .of(new EventManager()) + .map(_ => ({ + instance: this, + token: EventManagerExt, + value: _ + })); + } + + /** + * Shutdown Event manager + * + * @param {CoreModule} module + * @param {EventManager} manager + * @returns ExtensionShutdown + */ + onShutdown(module: CoreModule, manager: EventManager): ExtensionShutdown { + return { + priority: ExtensionShutdownPriority.NORMAL, + resolver: Observable.of(manager.close()) + } + } +} diff --git a/src/extensions/event-manager/index.ts b/src/extensions/event-manager/index.ts new file mode 100644 index 0000000..c30313e --- /dev/null +++ b/src/extensions/event-manager/index.ts @@ -0,0 +1,3 @@ +export * from './extension'; +export * from './manager'; +export * from './service'; diff --git a/src/extensions/event-manager/manager.ts b/src/extensions/event-manager/manager.ts new file mode 100644 index 0000000..4a157e3 --- /dev/null +++ b/src/extensions/event-manager/manager.ts @@ -0,0 +1,53 @@ +import { Subject, Observable } from 'rxjs'; +import { InternalLogger } from '../../core'; + +export interface EventData { + type: string; + data: any; +} + +export class EventManager { + + private stream$ = new Subject(); + private logger = new InternalLogger('event-manager'); + + /** + * Add a listener filtered on type + * + * @param {string} type + * @returns Observable + */ + public on(type: string): Observable { + this.logger.debug(`listener added on ${type}`); + return this + .stream$ + .filter(_ => !!_ && _.type === type); + } + + /** + * Emit data for type + * + * @param {string} type + * @param {any} data + * @returns void + */ + public emit(type: string, data: any): void { + this.logger.debug(`send data on ${type}`); + this + .stream$ + .next({ type, data }); + } + + /** + * Close the stream event + * + * @returns void + */ + public close(): void { + this.logger.debug(`manager closed`); + this + .stream$ + .complete(); + } + +} diff --git a/src/extensions/event-manager/service.ts b/src/extensions/event-manager/service.ts new file mode 100644 index 0000000..63817c6 --- /dev/null +++ b/src/extensions/event-manager/service.ts @@ -0,0 +1,32 @@ +import { Injectable, Inject } from '../../core'; +import { EventManagerExt, EventManager, EventData } from './'; +import { Observable } from 'rxjs'; + +@Injectable() +export class EventService { + + constructor( + @Inject(EventManagerExt) private manager: EventManager + ) {} + + /** + * Add listener on type + * + * @returns EventData + */ + on(type: string): Observable { + return this.manager.on(type); + } + + /** + * Send data for type + * + * @param {string} type + * @param {any} data + * @returns void + */ + emit(type: string, data: any): void { + this.manager.emit(type, data); + } + +} diff --git a/src/extensions/socket-server/extension.ts b/src/extensions/socket-server/extension.ts index 036658c..a73511b 100644 --- a/src/extensions/socket-server/extension.ts +++ b/src/extensions/socket-server/extension.ts @@ -1,4 +1,4 @@ -import { CoreModule, Extension, ExtensionWithConfig, OnExtensionLoad, OnModuleInstantiated } from '../../core/interfaces'; +import { CoreModule, Extension, ExtensionWithConfig, OnExtensionLoad, OnModuleInstantiated, OnShutdown } from '../../core/interfaces'; import { Observable } from 'rxjs/Observable'; import { WebSocketServer } from './server'; import { ExtensionShutdown, ExtensionShutdownPriority } from '../../core'; @@ -16,7 +16,7 @@ export interface SocketConfig { } } -export class SocketServerExt implements OnExtensionLoad, OnModuleInstantiated { +export class SocketServerExt implements OnExtensionLoad, OnModuleInstantiated, OnShutdown { public static setConfig(config: SocketConfig): ExtensionWithConfig { return { diff --git a/test/integration/event-manager.test.ts b/test/integration/event-manager.test.ts new file mode 100644 index 0000000..47ad3c9 --- /dev/null +++ b/test/integration/event-manager.test.ts @@ -0,0 +1,53 @@ +import { suite, test } from 'mocha-typescript'; +import { Hapiness, HapinessModule, OnStart, OnRegister } from '../../src/core'; +import * as unit from 'unit.js'; +import { EventManagerExt, EventService } from '../../src/extensions/event-manager'; + +@suite('Integration - EventManager') +export class TestSuite { + + @test('EventManager - event inter modules') + test1(done) { + + @HapinessModule({ + version: '', + providers: [ EventService ] + }) + class SubModule1 implements OnRegister { + + constructor(private event: EventService) {} + + onRegister() { + this + .event + .on('test') + .subscribe( + _ => { + unit.number(_.data).is(1); + done(); + } + ) + } + + } + + @HapinessModule({ + version: '', + providers: [ EventService ], + imports: [ SubModule1 ] + }) + class Module1 implements OnStart { + + constructor(private event: EventService) {} + + onStart() { + this.event.emit('test', 1); + } + + } + + Hapiness + .bootstrap(Module1, [ EventManagerExt ]); + + } +} From a8e0a7f6c01971a24478ef01a31ea751f4d7f028 Mon Sep 17 00:00:00 2001 From: Juneil Date: Tue, 27 Mar 2018 11:45:20 +0200 Subject: [PATCH 2/3] docs(event-manager) --- API.md | 6 ++- README.md | 7 +++- package.json | 2 +- src/extensions/event-manager/README.md | 51 ++++++++++++++++++++++++++ src/index.ts | 7 ++++ test/integration/event-manager.test.ts | 51 ++++++++++++++++++++++++++ 6 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 src/extensions/event-manager/README.md diff --git a/API.md b/API.md index c04ba6d..9b6b28d 100644 --- a/API.md +++ b/API.md @@ -193,4 +193,8 @@ See the documentation: [here](src/extensions/http-server/README.md) # Socket Server Extension -See the documentation: [here](src/extensions/socket-server/README.md) \ No newline at end of file +See the documentation: [here](src/extensions/socket-server/README.md) + +# EventManager Extension + +See the documentation: [here](src/extensions/event-manager/README.md) \ No newline at end of file diff --git a/README.md b/README.md index 3d69084..940577c 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ $ yarn add @hapiness/core rxjs ```javascript "dependencies": { - "@hapiness/core": "^1.4.0", + "@hapiness/core": "^1.5.0", //... } //... @@ -95,7 +95,7 @@ $ yarn add @hapiness/core rxjs ### Use Hapiness API -Actually, we're in : **v1.4.0** +Actually, we're in : **v1.5.0** See [API](https://github.com/hapinessjs/hapiness/blob/master/API.md) Reference to know what's already implemented. @@ -115,6 +115,9 @@ To set up your development environment: [Back to top](#table-of-contents) ## Change History +* v1.5.0 (2018-03-27) + * EventManager Extension + * Documentation * v1.4.0 (2018-03-26) * Extensions: add timeout * Extensions: shutdown diff --git a/package.json b/package.json index f8e2a5d..1833ef2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hapiness/core", - "version": "1.4.0", + "version": "1.5.0", "description": "Project to have a HapiJS (https://hapijs.com/) based framework to create easier NodeJS back-end with some awesome features", "main": "commonjs/index.js", "types": "index.d.ts", diff --git a/src/extensions/event-manager/README.md b/src/extensions/event-manager/README.md new file mode 100644 index 0000000..46279ae --- /dev/null +++ b/src/extensions/event-manager/README.md @@ -0,0 +1,51 @@ +# EventManager Extension + +Extension that allow to send events through all modules + +## Usage + +```javascript + + @HapinessModule({ + version: '...', + providers: [ EventService ] + }) + class SubModule { + + constructor(private event: EventService) {} + + onRegister() { + this.event + .on('type') + .subscribe(_ => console.log(_.data)); + } + } + + @HapinessModule({ + version: '...', + providers: [ EventService ], + imports: [ SubModule ] + }) + class Module { + + constructor(private event: EventService) {} + + onStart() { + this.event.emit('type', { data: {} }); + } + } + + Hapiness.bootstrap(Module, + [ + EventManagerExt + ] + ); +``` + +## Extension provider + +```javascript + ... + constructor(@Inject(EventManagerExt) private eventManager: EventManager) {} + ... +``` diff --git a/src/index.ts b/src/index.ts index 9ef1433..606131c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,3 +41,10 @@ export { WebSocketServer, SocketServerService } from './extensions/socket-server'; + +export { + EventManagerExt, + EventManager, + EventService, + EventData +} from './extensions/event-manager'; diff --git a/test/integration/event-manager.test.ts b/test/integration/event-manager.test.ts index 47ad3c9..f03ffc9 100644 --- a/test/integration/event-manager.test.ts +++ b/test/integration/event-manager.test.ts @@ -50,4 +50,55 @@ export class TestSuite { .bootstrap(Module1, [ EventManagerExt ]); } + + @test('EventManager - event inter modules multiple times') + test2(done) { + + @HapinessModule({ + version: '', + providers: [ EventService ] + }) + class SubModule1 implements OnRegister { + + incr = 0; + + constructor(private event: EventService) {} + + onRegister() { + this + .event + .on('test') + .subscribe( + _ => { + this.incr++; + if (this.incr === 3) { + done(); + } + } + ) + } + + } + + @HapinessModule({ + version: '', + providers: [ EventService ], + imports: [ SubModule1 ] + }) + class Module1 implements OnStart { + + constructor(private event: EventService) {} + + onStart() { + this.event.emit('test', 1); + this.event.emit('test', 1); + this.event.emit('test', 1); + } + + } + + Hapiness + .bootstrap(Module1, [ EventManagerExt ]); + + } } From 9600e9f1e0d6469923f71d1a592ec2d616a4508a Mon Sep 17 00:00:00 2001 From: Juneil Date: Tue, 27 Mar 2018 11:53:53 +0200 Subject: [PATCH 3/3] fix(export): onShutdown --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 606131c..00054d2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,7 +25,8 @@ export { DependencyInjection, errorHandler, ExtensionShutdown, - ExtensionShutdownPriority + ExtensionShutdownPriority, + OnShutdown } from './core'; export {