Skip to content

Commit

Permalink
refactor(effects): cleanup metadata and add types (#1131)
Browse files Browse the repository at this point in the history
Closes #623
  • Loading branch information
alex-okrushko authored and brandonroberts committed Jul 5, 2018
1 parent b4f22ad commit e7ae8a2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 34 deletions.
56 changes: 29 additions & 27 deletions modules/effects/src/effects_metadata.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,59 @@
import { compose } from '@ngrx/store';

const METADATA_KEY = '__@ngrx/effects__';
const r: any = Reflect;

export interface EffectMetadata {
propertyName: string;
export interface EffectMetadata<T> {
propertyName: keyof T;
dispatch: boolean;
}

function getEffectMetadataEntries(sourceProto: any): EffectMetadata[] {
return sourceProto.constructor[METADATA_KEY] || [];
function getEffectMetadataEntries<T>(sourceProto: T): Array<EffectMetadata<T>> {
return sourceProto.constructor.hasOwnProperty(METADATA_KEY)
? (sourceProto.constructor as any)[METADATA_KEY]
: [];
}

function setEffectMetadataEntries(sourceProto: any, entries: EffectMetadata[]) {
function setEffectMetadataEntries<T>(
sourceProto: T,
entries: Array<EffectMetadata<T>>
) {
const constructor = sourceProto.constructor;
const meta: EffectMetadata[] = constructor.hasOwnProperty(METADATA_KEY)
const meta: Array<EffectMetadata<T>> = constructor.hasOwnProperty(
METADATA_KEY
)
? (constructor as any)[METADATA_KEY]
: Object.defineProperty(constructor, METADATA_KEY, { value: [] })[
METADATA_KEY
];
Array.prototype.push.apply(meta, entries);
}

export function Effect({ dispatch } = { dispatch: true }): PropertyDecorator {
return function(target: any, propertyName: string) {
const metadata: EffectMetadata = { propertyName, dispatch };
setEffectMetadataEntries(target, [metadata]);
} /*TODO(#823)*/ as any;
export function Effect<T>({ dispatch = true } = {}): PropertyDecorator {
return function(target: T, propertyName: keyof T) {
const metadata: EffectMetadata<T> = { propertyName, dispatch };
setEffectMetadataEntries<T>(target, [metadata]);
} as (target: {}, propertyName: string | symbol) => void;
}

export function getSourceForInstance(instance: Object): any {
export function getSourceForInstance<T>(instance: T): T {
return Object.getPrototypeOf(instance);
}

export const getSourceMetadata = compose(
getEffectMetadataEntries,
getSourceForInstance
);
export function getSourceMetadata<T>(instance: T): Array<EffectMetadata<T>> {
return compose(
getEffectMetadataEntries,
getSourceForInstance
)(instance);
}

export type EffectsMetadata<T> = {
[key in keyof T]?:
| undefined
| {
dispatch: boolean;
}
};
export type EffectsMetadata<T> = { [key in keyof T]?: { dispatch: boolean } };

export function getEffectsMetadata<T>(instance: T): EffectsMetadata<T> {
const metadata: EffectsMetadata<T> = {};

getSourceMetadata(instance).forEach(({ propertyName, dispatch }) => {
(metadata /*TODO(#823)*/ as any)[propertyName] = { dispatch };
});
for (const { propertyName, dispatch } of getSourceMetadata(instance)) {
metadata[propertyName] = { dispatch };
}

return metadata;
}
16 changes: 9 additions & 7 deletions modules/effects/src/on_run_effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { Observable } from 'rxjs';
import { EffectNotification } from './effect_notification';
import { getSourceForInstance } from './effects_metadata';

export type onRunEffectsFn = (
resolvedEffects$: Observable<EffectNotification>
) => Observable<EffectNotification>;

export interface OnRunEffects {
ngrxOnRunEffects(
resolvedEffects$: Observable<EffectNotification>
): Observable<EffectNotification>;
ngrxOnRunEffects: onRunEffectsFn;
}

const onRunEffectsKey: keyof OnRunEffects = 'ngrxOnRunEffects';
export const onRunEffectsKey: keyof OnRunEffects = 'ngrxOnRunEffects';

export function isOnRunEffects(
sourceInstance: Object
): sourceInstance is OnRunEffects {
export function isOnRunEffects(sourceInstance: {
[onRunEffectsKey]?: onRunEffectsFn;
}): sourceInstance is OnRunEffects {
const source = getSourceForInstance(sourceInstance);

return (
Expand Down

0 comments on commit e7ae8a2

Please sign in to comment.