-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Shady Khalifa
committed
Aug 14, 2018
1 parent
0d32d64
commit 4177c59
Showing
8 changed files
with
9,132 additions
and
3 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const EVENT_EMITTER_TOKEN = '__event_emitter__'; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Module, DynamicModule, Global, Provider } from '@nestjs/common'; | ||
import { EVENT_EMITTER_TOKEN } from './constants'; | ||
import { StrictEventEmitter } from './strong-emitter'; | ||
@Global() | ||
@Module({}) | ||
export class NestEmitterModule { | ||
public static forRoot<TEventRecord, TEmitRecord = TEventRecord>( | ||
emitter: NodeJS.Events, | ||
): DynamicModule { | ||
// FIXME: fix the types errors here ! | ||
const instance: StrictEventEmitter<NodeJS.Events, TEventRecord, TEmitRecord> = emitter; | ||
const providers: Provider[] = [{ provide: EVENT_EMITTER_TOKEN, useValue: instance }]; | ||
return { module: NestEmitterModule, components: providers, exports: providers }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/** | ||
* Thanks to Brian Terlson @bterlson <[email protected]> | ||
* @author Brian Terlson @bterlson | ||
* @see https://github.com/bterlson/strict-event-emitter-types | ||
*/ | ||
|
||
// Returns any keys of TRecord with the type of TMatch | ||
export type MatchingKeys< | ||
TRecord, | ||
TMatch, | ||
K extends keyof TRecord = keyof TRecord | ||
> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never; | ||
|
||
// Returns any property keys of Record with a void type | ||
export type VoidKeys<Record> = MatchingKeys<Record, void>; | ||
|
||
// TODO: Stash under a symbol key once TS compiler bug is fixed | ||
export interface TypeRecord<T, U, V> { | ||
' _emitterType'?: T; | ||
' _eventsType'?: U; | ||
' _emitType'?: V; | ||
} | ||
|
||
export type ReturnTypeOfMethod<T> = T extends (...args: any[]) => any ? ReturnType<T> : void; | ||
|
||
export type ReturnTypeOfMethodIfExists<T, S extends string> = S extends keyof T | ||
? ReturnTypeOfMethod<T[S]> | ||
: void; | ||
|
||
export type InnerEEMethodReturnType<T, TValue, FValue> = T extends (...args: any[]) => any | ||
? ReturnType<T> extends void | undefined ? FValue : TValue | ||
: FValue; | ||
|
||
export type EEMethodReturnType<T, S extends string, TValue, FValue = void> = S extends keyof T | ||
? InnerEEMethodReturnType<T[S], TValue, FValue> | ||
: FValue; | ||
|
||
type ListenerType<T> = [T] extends [(...args: infer U) => any] ? U : [T, ...any[]]; | ||
|
||
// EventEmitter method overrides | ||
export type OverriddenMethods< | ||
TEmitter, | ||
TEventRecord, | ||
TEmitRecord = TEventRecord, | ||
EventVK extends VoidKeys<TEventRecord> = VoidKeys<TEventRecord>, | ||
EventNVK extends Exclude<keyof TEventRecord, EventVK> = Exclude<keyof TEventRecord, EventVK>, | ||
EmitVK extends VoidKeys<TEmitRecord> = VoidKeys<TEmitRecord>, | ||
EmitNVK extends Exclude<keyof TEmitRecord, EmitVK> = Exclude<keyof TEmitRecord, EmitVK> | ||
> = { | ||
on<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: (...args: ListenerType<TEventRecord[P]>) => void, | ||
): EEMethodReturnType<TEmitter, 'on', T>; | ||
|
||
on<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: () => void, | ||
): EEMethodReturnType<TEmitter, 'on', T>; | ||
|
||
addListener<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: (...args: ListenerType<TEventRecord[P]>) => void, | ||
): EEMethodReturnType<TEmitter, 'addListener', T>; | ||
|
||
addListener<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: () => void, | ||
): EEMethodReturnType<TEmitter, 'addListener', T>; | ||
|
||
addEventListener<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: (...args: ListenerType<TEventRecord[P]>) => void, | ||
): EEMethodReturnType<TEmitter, 'addEventListener', T>; | ||
|
||
addEventListener<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: () => void, | ||
): EEMethodReturnType<TEmitter, 'addEventListener', T>; | ||
|
||
removeListener<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: Function, | ||
): EEMethodReturnType<TEmitter, 'removeListener', T>; | ||
|
||
removeListener<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: Function, | ||
): EEMethodReturnType<TEmitter, 'removeListener', T>; | ||
|
||
removeEventListener<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: Function, | ||
): EEMethodReturnType<TEmitter, 'removeEventListener', T>; | ||
|
||
removeEventListener<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: Function, | ||
): EEMethodReturnType<TEmitter, 'removeEventListener', T>; | ||
|
||
once<P extends EventNVK, T>( | ||
this: T, | ||
event: P, | ||
listener: (...args: ListenerType<TEventRecord[P]>) => void, | ||
): EEMethodReturnType<TEmitter, 'once', T>; | ||
once<P extends EventVK, T>( | ||
this: T, | ||
event: P, | ||
listener: () => void, | ||
): EEMethodReturnType<TEmitter, 'once', T>; | ||
|
||
emit<P extends EmitNVK, T>( | ||
this: T, | ||
event: P, | ||
...args: ListenerType<TEmitRecord[P]> | ||
): EEMethodReturnType<TEmitter, 'emit', T>; | ||
|
||
emit<P extends EmitVK, T>(this: T, event: P): EEMethodReturnType<TEmitter, 'emit', T>; | ||
}; | ||
|
||
export type OverriddenKeys = keyof OverriddenMethods<any, any, any>; | ||
|
||
export type StrictEventEmitter< | ||
TEmitterType, | ||
TEventRecord, | ||
TEmitRecord = TEventRecord, | ||
UnneededMethods extends Exclude<OverriddenKeys, keyof TEmitterType> = Exclude< | ||
OverriddenKeys, | ||
keyof TEmitterType | ||
>, | ||
NeededMethods extends Exclude<OverriddenKeys, UnneededMethods> = Exclude< | ||
OverriddenKeys, | ||
UnneededMethods | ||
> | ||
> = | ||
// Store the type parameters we've instantiated with so we can refer to them later | ||
TypeRecord<TEmitterType, TEventRecord, TEmitRecord> & | ||
// Pick all the methods on the original type we aren't going to override | ||
Pick<TEmitterType, Exclude<keyof TEmitterType, OverriddenKeys>> & | ||
// Finally, pick the needed overrides (taking care not to add an override for a method | ||
// that doesn't exist) | ||
Pick<OverriddenMethods<TEmitterType, TEventRecord, TEmitRecord>, NeededMethods>; | ||
|
||
export type NoUndefined<T> = T extends undefined ? never : T; | ||
|
||
export type StrictBroadcast< | ||
TEmitter extends TypeRecord<any, any, any>, | ||
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']>, | ||
VK extends VoidKeys<TEmitRecord> = VoidKeys<TEmitRecord>, | ||
NVK extends Exclude<keyof TEmitRecord, VK> = Exclude<keyof TEmitRecord, VK> | ||
> = { | ||
<E extends NVK>(event: E, request: TEmitRecord[E]): any; | ||
<E extends VK>(event: E): any; | ||
}; | ||
|
||
export type EventNames< | ||
TEmitter extends TypeRecord<any, any, any>, | ||
TEventRecord extends NoUndefined<TEmitter[' _eventsType']> = NoUndefined< | ||
TEmitter[' _eventsType'] | ||
>, | ||
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']> | ||
> = keyof TEmitRecord | keyof TEventRecord; | ||
|
||
export type OnEventNames< | ||
TEmitter extends TypeRecord<any, any, any>, | ||
TEventRecord extends NoUndefined<TEmitter[' _eventsType']> = NoUndefined<TEmitter[' _eventsType']> | ||
> = keyof TEventRecord; | ||
|
||
export type EmitEventNames< | ||
TEmitter extends TypeRecord<any, any, any>, | ||
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']> | ||
> = keyof TEmitRecord; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"declaration": true, | ||
"noUnusedLocals": true, | ||
"strictNullChecks": true, | ||
"pretty": true, | ||
"noImplicitReturns": true, | ||
"noUnusedParameters": true, | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"outDir": "build", | ||
"preserveConstEnums": true, | ||
"rootDir": "./src", | ||
"baseUrl": ".", | ||
"experimentalDecorators": true, | ||
"emitDecoratorMetadata": true, | ||
"sourceMap": true, | ||
"target": "es6", | ||
"typeRoots": ["node_modules/@types"], | ||
"lib": ["es7"] | ||
}, | ||
"include": ["src/**/*"], | ||
"exclude": ["node_modules", "src/**/*.spec.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"defaultSeverity": "error", | ||
"extends": ["tslint:recommended"], | ||
"jsRules": { | ||
"no-unused-expression": true | ||
}, | ||
"rules": { | ||
"eofline": false, | ||
"quotemark": [true, "single"], | ||
"indent": false, | ||
"ordered-imports": [false], | ||
"max-line-length": [true, 100], | ||
"member-ordering": [false], | ||
"curly": false, | ||
"interface-name": [false], | ||
"array-type": [false], | ||
"no-empty-interface": false, | ||
"no-empty": false, | ||
"arrow-parens": false, | ||
"object-literal-sort-keys": false, | ||
"no-unused-expression": false, | ||
"max-classes-per-file": [false], | ||
"ban-types": false, | ||
"variable-name": [false], | ||
"one-line": [false], | ||
"one-variable-per-declaration": [false] | ||
}, | ||
"rulesDirectory": [] | ||
} |