Skip to content

Commit

Permalink
fix(Effects): Simplify decorator handling for Closure compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
robwormald authored and MikeRyanDev committed Oct 4, 2017
1 parent 7fa0cf2 commit ad30d40
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 61 deletions.
20 changes: 0 additions & 20 deletions modules/effects/spec/effects_metadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@ describe('Effect Metadata', () => {
]);
});

it('should get the effects metadata for a downleveled class instance', () => {
class Fixture {
static get propDecorators() {
return {
a: [{ type: Effect, args: [{ dispatch: false }] }],
b: [{ type: Effect, args: [] }],
c: [{ type: Effect }],
};
}
}

const mock = new Fixture();

expect(getSourceMetadata(mock)).toEqual([
{ propertyName: 'a', dispatch: false },
{ propertyName: 'b', dispatch: true },
{ propertyName: 'c', dispatch: true },
]);
});

it('should return an empty array if the class has not been decorated', () => {
class Fixture {
a: any;
Expand Down
51 changes: 10 additions & 41 deletions modules/effects/src/effects_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,32 @@ import { ignoreElements } from 'rxjs/operator/ignoreElements';
import { Observable } from 'rxjs/Observable';
import { compose } from '@ngrx/store';

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

export interface EffectMetadata {
propertyName: string;
dispatch: boolean;
}

function hasStaticMetadata(sourceType: any): boolean {
return !!(sourceType as any).propDecorators;
}

function getStaticMetadata(sourceType: any): EffectMetadata[] {
const propDecorators = sourceType.propDecorators;
return Object.keys(propDecorators).reduce(
(all, key) => all.concat(getStaticMetadataEntry(propDecorators[key], key)),
[]
);
}

function getStaticMetadataEntry(metadataEntry: any, propertyName: string) {
return metadataEntry
.filter((entry: any) => entry.type === Effect)
.map((entry: any) => {
let dispatch = true;
if (entry.args && entry.args.length) {
dispatch = !!entry.args[0].dispatch;
}
return { propertyName, dispatch };
});
}

function getEffectMetadataEntries(sourceProto: any): EffectMetadata[] {
if (hasStaticMetadata(sourceProto.constructor)) {
return getStaticMetadata(sourceProto.constructor);
}

if (r.hasOwnMetadata(METADATA_KEY, sourceProto)) {
return r.getOwnMetadata(METADATA_KEY, sourceProto);
}

return [];
return sourceProto.constructor[METADATA_KEY] || [];
}

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

/**
* @Annotation
*/
export function Effect({ dispatch } = { dispatch: true }): PropertyDecorator {
return function(target: any, propertyName: string) {
const effects: EffectMetadata[] = getEffectMetadataEntries(target);
const metadata: EffectMetadata = { propertyName, dispatch };

setEffectMetadataEntries(target, [...effects, metadata]);
setEffectMetadataEntries(target, [metadata]);
};
}

Expand Down

0 comments on commit ad30d40

Please sign in to comment.