11import { compose } from '@ngrx/store' ;
2- import { EffectMetadata , EffectConfig } from './models' ;
2+
3+ import {
4+ DEFAULT_EFFECT_CONFIG ,
5+ EffectConfig ,
6+ EffectMetadata ,
7+ EffectPropertyKey ,
8+ } from './models' ;
39import { getSourceForInstance } from './utils' ;
410
511const METADATA_KEY = '__@ngrx/effects__' ;
612
7- export function Effect < T > ( {
8- dispatch = true ,
9- resubscribeOnError = true ,
10- } : EffectConfig = { } ) : PropertyDecorator {
11- return function < K extends Extract < keyof T , string > > (
13+ export function Effect ( config : EffectConfig = { } ) {
14+ return function < T extends Object , K extends EffectPropertyKey < T > > (
1215 target : T ,
1316 propertyName : K
1417 ) {
15- // Right now both createEffect and @Effect decorator set default values.
16- // Ideally that should only be done in one place that aggregates that info,
17- // for example in mergeEffects().
1818 const metadata : EffectMetadata < T > = {
19+ ...DEFAULT_EFFECT_CONFIG ,
20+ ...config , // Overrides any defaults if values are provided
1921 propertyName,
20- dispatch,
21- resubscribeOnError,
2222 } ;
23- setEffectMetadataEntries < T > ( target , [ metadata ] ) ;
24- } as ( target : { } , propertyName : string | symbol ) => void ;
23+ addEffectMetadataEntry < T > ( target , metadata ) ;
24+ } ;
2525}
2626
2727export function getEffectDecoratorMetadata < T > (
@@ -35,23 +35,38 @@ export function getEffectDecoratorMetadata<T>(
3535 return effectsDecorators ;
3636}
3737
38- function setEffectMetadataEntries < T > (
38+ /**
39+ * Type guard to detemine whether METADATA_KEY is already present on the Class
40+ * constructor
41+ */
42+ function hasMetadataEntries < T extends Object > (
43+ sourceProto : T
44+ ) : sourceProto is typeof sourceProto & {
45+ constructor : typeof sourceProto . constructor & {
46+ [ METADATA_KEY ] : EffectMetadata < T > [ ] ;
47+ } ;
48+ } {
49+ return sourceProto . constructor . hasOwnProperty ( METADATA_KEY ) ;
50+ }
51+
52+ /** Add Effect Metadata to the Effect Class constructor under specific key */
53+ function addEffectMetadataEntry < T extends object > (
3954 sourceProto : T ,
40- entries : EffectMetadata < T > [ ]
55+ metadata : EffectMetadata < T >
4156) {
42- const constructor = sourceProto . constructor ;
43- const meta : Array < EffectMetadata < T > > = constructor . hasOwnProperty (
44- METADATA_KEY
45- )
46- ? ( constructor as any ) [ METADATA_KEY ]
47- : Object . defineProperty ( constructor , METADATA_KEY , { value : [ ] } ) [
48- METADATA_KEY
49- ] ;
50- Array . prototype . push . apply ( meta , entries ) ;
57+ if ( hasMetadataEntries ( sourceProto ) ) {
58+ sourceProto . constructor [ METADATA_KEY ] . push ( metadata ) ;
59+ } else {
60+ Object . defineProperty ( sourceProto . constructor , METADATA_KEY , {
61+ value : [ metadata ] ,
62+ } ) ;
63+ }
5164}
5265
53- function getEffectMetadataEntries < T > ( sourceProto : T ) : EffectMetadata < T > [ ] {
54- return sourceProto . constructor . hasOwnProperty ( METADATA_KEY )
55- ? ( sourceProto . constructor as any ) [ METADATA_KEY ]
66+ function getEffectMetadataEntries < T extends object > (
67+ sourceProto : T
68+ ) : EffectMetadata < T > [ ] {
69+ return hasMetadataEntries ( sourceProto )
70+ ? sourceProto . constructor [ METADATA_KEY ]
5671 : [ ] ;
5772}
0 commit comments