1 | import * as i3 from '@ngrx/store';
|
2 | import { compose, ScannedActionsSubject, createAction } from '@ngrx/store';
|
3 | import * as i1 from 'rxjs';
|
4 | import { merge, Observable, Subject, defer, Notification, pipe, of } from 'rxjs';
|
5 | import { ignoreElements, materialize, map, catchError, filter, groupBy, mergeMap, exhaustMap, dematerialize, take, concatMap, finalize, withLatestFrom } from 'rxjs/operators';
|
6 | import * as i0 from '@angular/core';
|
7 | import { Injectable, Inject, InjectionToken, NgModule, Optional, Injector, SkipSelf, Self } from '@angular/core';
|
8 |
|
9 | const DEFAULT_EFFECT_CONFIG = {
|
10 | dispatch: true,
|
11 | useEffectsErrorHandler: true,
|
12 | };
|
13 | const CREATE_EFFECT_METADATA_KEY = '__@ngrx/effects_create__';
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 | function createEffect(source, config) {
|
48 | const effect = source();
|
49 | const value = Object.assign(Object.assign({}, DEFAULT_EFFECT_CONFIG), config);
|
50 | Object.defineProperty(effect, CREATE_EFFECT_METADATA_KEY, {
|
51 | value,
|
52 | });
|
53 | return effect;
|
54 | }
|
55 | function getCreateEffectMetadata(instance) {
|
56 | const propertyNames = Object.getOwnPropertyNames(instance);
|
57 | const metadata = propertyNames
|
58 | .filter((propertyName) => {
|
59 | if (instance[propertyName] &&
|
60 | instance[propertyName].hasOwnProperty(CREATE_EFFECT_METADATA_KEY)) {
|
61 |
|
62 |
|
63 |
|
64 | const property = instance[propertyName];
|
65 | return property[CREATE_EFFECT_METADATA_KEY].hasOwnProperty('dispatch');
|
66 | }
|
67 | return false;
|
68 | })
|
69 | .map((propertyName) => {
|
70 | const metaData = instance[propertyName][CREATE_EFFECT_METADATA_KEY];
|
71 | return Object.assign({ propertyName }, metaData);
|
72 | });
|
73 | return metadata;
|
74 | }
|
75 |
|
76 | function getSourceForInstance(instance) {
|
77 | return Object.getPrototypeOf(instance);
|
78 | }
|
79 |
|
80 | const METADATA_KEY = '__@ngrx/effects__';
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | function Effect(config = {}) {
|
86 | return function (target, propertyName) {
|
87 | const metadata = Object.assign(Object.assign(Object.assign({}, DEFAULT_EFFECT_CONFIG), config), { propertyName });
|
88 | addEffectMetadataEntry(target, metadata);
|
89 | };
|
90 | }
|
91 | function getEffectDecoratorMetadata(instance) {
|
92 | const effectsDecorators = compose(getEffectMetadataEntries, getSourceForInstance)(instance);
|
93 | return effectsDecorators;
|
94 | }
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | function hasMetadataEntries(sourceProto) {
|
100 | return sourceProto.constructor.hasOwnProperty(METADATA_KEY);
|
101 | }
|
102 |
|
103 | function addEffectMetadataEntry(sourceProto, metadata) {
|
104 | if (hasMetadataEntries(sourceProto)) {
|
105 | sourceProto.constructor[METADATA_KEY].push(metadata);
|
106 | }
|
107 | else {
|
108 | Object.defineProperty(sourceProto.constructor, METADATA_KEY, {
|
109 | value: [metadata],
|
110 | });
|
111 | }
|
112 | }
|
113 | function getEffectMetadataEntries(sourceProto) {
|
114 | return hasMetadataEntries(sourceProto)
|
115 | ? sourceProto.constructor[METADATA_KEY]
|
116 | : [];
|
117 | }
|
118 |
|
119 | function getEffectsMetadata(instance) {
|
120 | return getSourceMetadata(instance).reduce((acc, { propertyName, dispatch, useEffectsErrorHandler }) => {
|
121 | acc[propertyName] = { dispatch, useEffectsErrorHandler };
|
122 | return acc;
|
123 | }, {});
|
124 | }
|
125 | function getSourceMetadata(instance) {
|
126 | const effects = [
|
127 | getEffectDecoratorMetadata,
|
128 | getCreateEffectMetadata,
|
129 | ];
|
130 | return effects.reduce((sources, source) => sources.concat(source(instance)), []);
|
131 | }
|
132 |
|
133 | function mergeEffects(sourceInstance, globalErrorHandler, effectsErrorHandler) {
|
134 | const sourceName = getSourceForInstance(sourceInstance).constructor.name;
|
135 | const observables$ = getSourceMetadata(sourceInstance).map(({ propertyName, dispatch, useEffectsErrorHandler, }) => {
|
136 | const observable$ = typeof sourceInstance[propertyName] === 'function'
|
137 | ? sourceInstance[propertyName]()
|
138 | : sourceInstance[propertyName];
|
139 | const effectAction$ = useEffectsErrorHandler
|
140 | ? effectsErrorHandler(observable$, globalErrorHandler)
|
141 | : observable$;
|
142 | if (dispatch === false) {
|
143 | return effectAction$.pipe(ignoreElements());
|
144 | }
|
145 | const materialized$ = effectAction$.pipe(materialize());
|
146 | return materialized$.pipe(map((notification) => ({
|
147 | effect: sourceInstance[propertyName],
|
148 | notification,
|
149 | propertyName,
|
150 | sourceName,
|
151 | sourceInstance,
|
152 | })));
|
153 | });
|
154 | return merge(...observables$);
|
155 | }
|
156 |
|
157 | const MAX_NUMBER_OF_RETRY_ATTEMPTS = 10;
|
158 | function defaultEffectsErrorHandler(observable$, errorHandler, retryAttemptLeft = MAX_NUMBER_OF_RETRY_ATTEMPTS) {
|
159 | return observable$.pipe(catchError((error) => {
|
160 | if (errorHandler)
|
161 | errorHandler.handleError(error);
|
162 | if (retryAttemptLeft <= 1) {
|
163 | return observable$;
|
164 | }
|
165 |
|
166 | return defaultEffectsErrorHandler(observable$, errorHandler, retryAttemptLeft - 1);
|
167 | }));
|
168 | }
|
169 |
|
170 | class Actions extends Observable {
|
171 | constructor(source) {
|
172 | super();
|
173 | if (source) {
|
174 | this.source = source;
|
175 | }
|
176 | }
|
177 | lift(operator) {
|
178 | const observable = new Actions();
|
179 | observable.source = this;
|
180 | observable.operator = operator;
|
181 | return observable;
|
182 | }
|
183 | }
|
184 | Actions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: Actions, deps: [{ token: ScannedActionsSubject }], target: i0.ɵɵFactoryTarget.Injectable });
|
185 | Actions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: Actions });
|
186 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: Actions, decorators: [{
|
187 | type: Injectable
|
188 | }], ctorParameters: function () {
|
189 | return [{ type: i1.Observable, decorators: [{
|
190 | type: Inject,
|
191 | args: [ScannedActionsSubject]
|
192 | }] }];
|
193 | } });
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 | function ofType(...allowedTypes) {
|
230 | return filter((action) => allowedTypes.some((typeOrActionCreator) => {
|
231 | if (typeof typeOrActionCreator === 'string') {
|
232 |
|
233 | return typeOrActionCreator === action.type;
|
234 | }
|
235 |
|
236 | return typeOrActionCreator.type === action.type;
|
237 | }));
|
238 | }
|
239 |
|
240 | function reportInvalidActions(output, reporter) {
|
241 | if (output.notification.kind === 'N') {
|
242 | const action = output.notification.value;
|
243 | const isInvalidAction = !isAction(action);
|
244 | if (isInvalidAction) {
|
245 | reporter.handleError(new Error(`Effect ${getEffectName(output)} dispatched an invalid action: ${stringify(action)}`));
|
246 | }
|
247 | }
|
248 | }
|
249 | function isAction(action) {
|
250 | return (typeof action !== 'function' &&
|
251 | action &&
|
252 | action.type &&
|
253 | typeof action.type === 'string');
|
254 | }
|
255 | function getEffectName({ propertyName, sourceInstance, sourceName, }) {
|
256 | const isMethod = typeof sourceInstance[propertyName] === 'function';
|
257 | return `"${sourceName}.${String(propertyName)}${isMethod ? '()' : ''}"`;
|
258 | }
|
259 | function stringify(action) {
|
260 | try {
|
261 | return JSON.stringify(action);
|
262 | }
|
263 | catch (_a) {
|
264 | return action;
|
265 | }
|
266 | }
|
267 |
|
268 | const onIdentifyEffectsKey = 'ngrxOnIdentifyEffects';
|
269 | function isOnIdentifyEffects(instance) {
|
270 | return isFunction(instance, onIdentifyEffectsKey);
|
271 | }
|
272 | const onRunEffectsKey = 'ngrxOnRunEffects';
|
273 | function isOnRunEffects(instance) {
|
274 | return isFunction(instance, onRunEffectsKey);
|
275 | }
|
276 | const onInitEffects = 'ngrxOnInitEffects';
|
277 | function isOnInitEffects(instance) {
|
278 | return isFunction(instance, onInitEffects);
|
279 | }
|
280 | function isFunction(instance, functionName) {
|
281 | return (instance &&
|
282 | functionName in instance &&
|
283 | typeof instance[functionName] === 'function');
|
284 | }
|
285 |
|
286 | const _ROOT_EFFECTS_GUARD = new InjectionToken('@ngrx/effects Internal Root Guard');
|
287 | const USER_PROVIDED_EFFECTS = new InjectionToken('@ngrx/effects User Provided Effects');
|
288 | const _ROOT_EFFECTS = new InjectionToken('@ngrx/effects Internal Root Effects');
|
289 | const ROOT_EFFECTS = new InjectionToken('@ngrx/effects Root Effects');
|
290 | const _FEATURE_EFFECTS = new InjectionToken('@ngrx/effects Internal Feature Effects');
|
291 | const FEATURE_EFFECTS = new InjectionToken('@ngrx/effects Feature Effects');
|
292 | const EFFECTS_ERROR_HANDLER = new InjectionToken('@ngrx/effects Effects Error Handler');
|
293 |
|
294 | class EffectSources extends Subject {
|
295 | constructor(errorHandler, effectsErrorHandler) {
|
296 | super();
|
297 | this.errorHandler = errorHandler;
|
298 | this.effectsErrorHandler = effectsErrorHandler;
|
299 | }
|
300 | addEffects(effectSourceInstance) {
|
301 | this.next(effectSourceInstance);
|
302 | }
|
303 | |
304 |
|
305 |
|
306 | toActions() {
|
307 | return this.pipe(groupBy(getSourceForInstance), mergeMap((source$) => {
|
308 | return source$.pipe(groupBy(effectsInstance));
|
309 | }), mergeMap((source$) => {
|
310 | const effect$ = source$.pipe(exhaustMap((sourceInstance) => {
|
311 | return resolveEffectSource(this.errorHandler, this.effectsErrorHandler)(sourceInstance);
|
312 | }), map((output) => {
|
313 | reportInvalidActions(output, this.errorHandler);
|
314 | return output.notification;
|
315 | }), filter((notification) => notification.kind === 'N' && notification.value != null), dematerialize());
|
316 |
|
317 |
|
318 | const init$ = source$.pipe(take(1), filter(isOnInitEffects), map((instance) => instance.ngrxOnInitEffects()));
|
319 | return merge(effect$, init$);
|
320 | }));
|
321 | }
|
322 | }
|
323 | EffectSources.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectSources, deps: [{ token: i0.ErrorHandler }, { token: EFFECTS_ERROR_HANDLER }], target: i0.ɵɵFactoryTarget.Injectable });
|
324 | EffectSources.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectSources });
|
325 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectSources, decorators: [{
|
326 | type: Injectable
|
327 | }], ctorParameters: function () {
|
328 | return [{ type: i0.ErrorHandler }, { type: undefined, decorators: [{
|
329 | type: Inject,
|
330 | args: [EFFECTS_ERROR_HANDLER]
|
331 | }] }];
|
332 | } });
|
333 | function effectsInstance(sourceInstance) {
|
334 | if (isOnIdentifyEffects(sourceInstance)) {
|
335 | return sourceInstance.ngrxOnIdentifyEffects();
|
336 | }
|
337 | return '';
|
338 | }
|
339 | function resolveEffectSource(errorHandler, effectsErrorHandler) {
|
340 | return (sourceInstance) => {
|
341 | const mergedEffects$ = mergeEffects(sourceInstance, errorHandler, effectsErrorHandler);
|
342 | if (isOnRunEffects(sourceInstance)) {
|
343 | return sourceInstance.ngrxOnRunEffects(mergedEffects$);
|
344 | }
|
345 | return mergedEffects$;
|
346 | };
|
347 | }
|
348 |
|
349 | class EffectsRunner {
|
350 | constructor(effectSources, store) {
|
351 | this.effectSources = effectSources;
|
352 | this.store = store;
|
353 | this.effectsSubscription = null;
|
354 | }
|
355 | start() {
|
356 | if (!this.effectsSubscription) {
|
357 | this.effectsSubscription = this.effectSources
|
358 | .toActions()
|
359 | .subscribe(this.store);
|
360 | }
|
361 | }
|
362 | ngOnDestroy() {
|
363 | if (this.effectsSubscription) {
|
364 | this.effectsSubscription.unsubscribe();
|
365 | this.effectsSubscription = null;
|
366 | }
|
367 | }
|
368 | }
|
369 | EffectsRunner.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRunner, deps: [{ token: EffectSources }, { token: i3.Store }], target: i0.ɵɵFactoryTarget.Injectable });
|
370 | EffectsRunner.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRunner });
|
371 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRunner, decorators: [{
|
372 | type: Injectable
|
373 | }], ctorParameters: function () { return [{ type: EffectSources }, { type: i3.Store }]; } });
|
374 |
|
375 | const ROOT_EFFECTS_INIT = '@ngrx/effects/init';
|
376 | const rootEffectsInit = createAction(ROOT_EFFECTS_INIT);
|
377 | class EffectsRootModule {
|
378 | constructor(sources, runner, store, rootEffects, storeRootModule, storeFeatureModule, guard) {
|
379 | this.sources = sources;
|
380 | runner.start();
|
381 | rootEffects.forEach((effectSourceInstance) => sources.addEffects(effectSourceInstance));
|
382 | store.dispatch({ type: ROOT_EFFECTS_INIT });
|
383 | }
|
384 | addEffects(effectSourceInstance) {
|
385 | this.sources.addEffects(effectSourceInstance);
|
386 | }
|
387 | }
|
388 | EffectsRootModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRootModule, deps: [{ token: EffectSources }, { token: EffectsRunner }, { token: i3.Store }, { token: ROOT_EFFECTS }, { token: i3.StoreRootModule, optional: true }, { token: i3.StoreFeatureModule, optional: true }, { token: _ROOT_EFFECTS_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
|
389 | EffectsRootModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRootModule });
|
390 | EffectsRootModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRootModule });
|
391 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsRootModule, decorators: [{
|
392 | type: NgModule,
|
393 | args: [{}]
|
394 | }], ctorParameters: function () {
|
395 | return [{ type: EffectSources }, { type: EffectsRunner }, { type: i3.Store }, { type: undefined, decorators: [{
|
396 | type: Inject,
|
397 | args: [ROOT_EFFECTS]
|
398 | }] }, { type: i3.StoreRootModule, decorators: [{
|
399 | type: Optional
|
400 | }] }, { type: i3.StoreFeatureModule, decorators: [{
|
401 | type: Optional
|
402 | }] }, { type: undefined, decorators: [{
|
403 | type: Optional
|
404 | }, {
|
405 | type: Inject,
|
406 | args: [_ROOT_EFFECTS_GUARD]
|
407 | }] }];
|
408 | } });
|
409 |
|
410 | class EffectsFeatureModule {
|
411 | constructor(root, effectSourceGroups, storeRootModule, storeFeatureModule) {
|
412 | effectSourceGroups.forEach((group) => group.forEach((effectSourceInstance) => root.addEffects(effectSourceInstance)));
|
413 | }
|
414 | }
|
415 | EffectsFeatureModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsFeatureModule, deps: [{ token: EffectsRootModule }, { token: FEATURE_EFFECTS }, { token: i3.StoreRootModule, optional: true }, { token: i3.StoreFeatureModule, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
|
416 | EffectsFeatureModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsFeatureModule });
|
417 | EffectsFeatureModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsFeatureModule });
|
418 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsFeatureModule, decorators: [{
|
419 | type: NgModule,
|
420 | args: [{}]
|
421 | }], ctorParameters: function () {
|
422 | return [{ type: EffectsRootModule }, { type: undefined, decorators: [{
|
423 | type: Inject,
|
424 | args: [FEATURE_EFFECTS]
|
425 | }] }, { type: i3.StoreRootModule, decorators: [{
|
426 | type: Optional
|
427 | }] }, { type: i3.StoreFeatureModule, decorators: [{
|
428 | type: Optional
|
429 | }] }];
|
430 | } });
|
431 |
|
432 | class EffectsModule {
|
433 | static forFeature(featureEffects = []) {
|
434 | return {
|
435 | ngModule: EffectsFeatureModule,
|
436 | providers: [
|
437 | featureEffects,
|
438 | {
|
439 | provide: _FEATURE_EFFECTS,
|
440 | multi: true,
|
441 | useValue: featureEffects,
|
442 | },
|
443 | {
|
444 | provide: USER_PROVIDED_EFFECTS,
|
445 | multi: true,
|
446 | useValue: [],
|
447 | },
|
448 | {
|
449 | provide: FEATURE_EFFECTS,
|
450 | multi: true,
|
451 | useFactory: createEffects,
|
452 | deps: [Injector, _FEATURE_EFFECTS, USER_PROVIDED_EFFECTS],
|
453 | },
|
454 | ],
|
455 | };
|
456 | }
|
457 | static forRoot(rootEffects = []) {
|
458 | return {
|
459 | ngModule: EffectsRootModule,
|
460 | providers: [
|
461 | {
|
462 | provide: EFFECTS_ERROR_HANDLER,
|
463 | useValue: defaultEffectsErrorHandler,
|
464 | },
|
465 | EffectsRunner,
|
466 | EffectSources,
|
467 | Actions,
|
468 | rootEffects,
|
469 | {
|
470 | provide: _ROOT_EFFECTS,
|
471 | useValue: [rootEffects],
|
472 | },
|
473 | {
|
474 | provide: _ROOT_EFFECTS_GUARD,
|
475 | useFactory: _provideForRootGuard,
|
476 | deps: [
|
477 | [EffectsRunner, new Optional(), new SkipSelf()],
|
478 | [_ROOT_EFFECTS, new Self()],
|
479 | ],
|
480 | },
|
481 | {
|
482 | provide: USER_PROVIDED_EFFECTS,
|
483 | multi: true,
|
484 | useValue: [],
|
485 | },
|
486 | {
|
487 | provide: ROOT_EFFECTS,
|
488 | useFactory: createEffects,
|
489 | deps: [Injector, _ROOT_EFFECTS, USER_PROVIDED_EFFECTS],
|
490 | },
|
491 | ],
|
492 | };
|
493 | }
|
494 | }
|
495 | EffectsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
496 | EffectsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsModule });
|
497 | EffectsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsModule });
|
498 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: EffectsModule, decorators: [{
|
499 | type: NgModule,
|
500 | args: [{}]
|
501 | }] });
|
502 | function createEffects(injector, effectGroups, userProvidedEffectGroups) {
|
503 | const mergedEffects = [];
|
504 | for (const effectGroup of effectGroups) {
|
505 | mergedEffects.push(...effectGroup);
|
506 | }
|
507 | for (const userProvidedEffectGroup of userProvidedEffectGroups) {
|
508 | mergedEffects.push(...userProvidedEffectGroup);
|
509 | }
|
510 | return createEffectInstances(injector, mergedEffects);
|
511 | }
|
512 | function createEffectInstances(injector, effects) {
|
513 | return effects.map((effect) => injector.get(effect));
|
514 | }
|
515 | function _provideForRootGuard(runner, rootEffects) {
|
516 |
|
517 | const hasEffects = !(rootEffects.length === 1 && rootEffects[0].length === 0);
|
518 | if (hasEffects && runner) {
|
519 | throw new TypeError(`EffectsModule.forRoot() called twice. Feature modules should use EffectsModule.forFeature() instead.`);
|
520 | }
|
521 | return 'guarded';
|
522 | }
|
523 |
|
524 |
|
525 |
|
526 |
|
527 |
|
528 |
|
529 | function act(
|
530 | /** Allow to take either config object or project/error functions */
|
531 | configOrProject, errorFn) {
|
532 | const { project, error, complete, operator, unsubscribe } = typeof configOrProject === 'function'
|
533 | ? {
|
534 | project: configOrProject,
|
535 |
|
536 | error: errorFn,
|
537 | operator: concatMap,
|
538 | complete: undefined,
|
539 | unsubscribe: undefined,
|
540 | }
|
541 | : Object.assign(Object.assign({}, configOrProject), { operator: configOrProject.operator || concatMap });
|
542 | return (source) => defer(() => {
|
543 | const subject = new Subject();
|
544 | return merge(source.pipe(operator((input, index) => defer(() => {
|
545 | let completed = false;
|
546 | let errored = false;
|
547 | let projectedCount = 0;
|
548 | return project(input, index).pipe(materialize(), map((notification) => {
|
549 | switch (notification.kind) {
|
550 | case 'E':
|
551 | errored = true;
|
552 | return new Notification('N', error(notification.error, input));
|
553 | case 'C':
|
554 | completed = true;
|
555 | return complete
|
556 | ? new Notification('N', complete(projectedCount, input))
|
557 | : undefined;
|
558 | default:
|
559 | ++projectedCount;
|
560 | return notification;
|
561 | }
|
562 | }), filter((n) => n != null), dematerialize(), finalize(() => {
|
563 | if (!completed && !errored && unsubscribe) {
|
564 | subject.next(unsubscribe(projectedCount, input));
|
565 | }
|
566 | }));
|
567 | }))), subject);
|
568 | });
|
569 | }
|
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 |
|
586 |
|
587 |
|
588 |
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 |
|
595 |
|
596 |
|
597 |
|
598 |
|
599 |
|
600 | function concatLatestFrom(observablesFactory) {
|
601 | return pipe(concatMap((value) => {
|
602 | const observables = observablesFactory(value);
|
603 | const observablesAsArray = Array.isArray(observables)
|
604 | ? observables
|
605 | : [observables];
|
606 | return of(value).pipe(withLatestFrom(...observablesAsArray));
|
607 | }));
|
608 | }
|
609 |
|
610 |
|
611 |
|
612 |
|
613 |
|
614 |
|
615 |
|
616 |
|
617 |
|
618 |
|
619 |
|
620 | export { Actions, EFFECTS_ERROR_HANDLER, Effect, EffectSources, EffectsFeatureModule, EffectsModule, EffectsRootModule, EffectsRunner, ROOT_EFFECTS_INIT, USER_PROVIDED_EFFECTS, act, concatLatestFrom, createEffect, defaultEffectsErrorHandler, getEffectsMetadata, mergeEffects, ofType, rootEffectsInit };
|
621 |
|