@ngrx/store-devtools 12.3.0 → 13.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,15 @@
1
- import { InjectionToken, Injectable, Inject, ErrorHandler, NgModule } from '@angular/core';
2
- import { ActionsSubject, UPDATE, INIT, ReducerObservable, ScannedActionsSubject, INITIAL_STATE, StateObservable, ReducerManagerDispatcher } from '@ngrx/store';
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Injectable, Inject, NgModule } from '@angular/core';
3
+ import * as i2 from '@ngrx/store';
4
+ import { INIT, UPDATE, ActionsSubject, INITIAL_STATE, StateObservable, ReducerManagerDispatcher } from '@ngrx/store';
3
5
  import { EMPTY, Observable, of, merge, queueScheduler, ReplaySubject } from 'rxjs';
4
6
  import { share, filter, map, concatMap, timeout, debounceTime, catchError, take, takeUntil, switchMap, skip, observeOn, withLatestFrom, scan } from 'rxjs/operators';
5
7
 
6
8
  /**
7
- * @see http://extension.remotedev.io/docs/API/Arguments.html
9
+ * Chrome extension documentation
10
+ * @see https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md
11
+ * Firefox extension documentation
12
+ * @see https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md
8
13
  */
9
14
  class StoreDevtoolsConfig {
10
15
  constructor() {
@@ -157,12 +162,6 @@ class PauseRecording {
157
162
  }
158
163
  }
159
164
 
160
- class DevtoolsDispatcher extends ActionsSubject {
161
- }
162
- DevtoolsDispatcher.decorators = [
163
- { type: Injectable }
164
- ];
165
-
166
165
  function difference(first, second) {
167
166
  return first.filter((item) => second.indexOf(item) < 0);
168
167
  }
@@ -268,151 +267,6 @@ function escapeRegExp(s) {
268
267
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
269
268
  }
270
269
 
271
- const ExtensionActionTypes = {
272
- START: 'START',
273
- DISPATCH: 'DISPATCH',
274
- STOP: 'STOP',
275
- ACTION: 'ACTION',
276
- };
277
- const REDUX_DEVTOOLS_EXTENSION = new InjectionToken('@ngrx/store-devtools Redux Devtools Extension');
278
- class DevtoolsExtension {
279
- constructor(devtoolsExtension, config, dispatcher) {
280
- this.config = config;
281
- this.dispatcher = dispatcher;
282
- this.devtoolsExtension = devtoolsExtension;
283
- this.createActionStreams();
284
- }
285
- notify(action, state) {
286
- if (!this.devtoolsExtension) {
287
- return;
288
- }
289
- // Check to see if the action requires a full update of the liftedState.
290
- // If it is a simple action generated by the user's app and the recording
291
- // is not locked/paused, only send the action and the current state (fast).
292
- //
293
- // A full liftedState update (slow: serializes the entire liftedState) is
294
- // only required when:
295
- // a) redux-devtools-extension fires the @@Init action (ignored by
296
- // @ngrx/store-devtools)
297
- // b) an action is generated by an @ngrx module (e.g. @ngrx/effects/init
298
- // or @ngrx/store/update-reducers)
299
- // c) the state has been recomputed due to time-traveling
300
- // d) any action that is not a PerformAction to err on the side of
301
- // caution.
302
- if (action.type === PERFORM_ACTION) {
303
- if (state.isLocked || state.isPaused) {
304
- return;
305
- }
306
- const currentState = unliftState(state);
307
- if (shouldFilterActions(this.config) &&
308
- isActionFiltered(currentState, action, this.config.predicate, this.config.actionsSafelist, this.config.actionsBlocklist)) {
309
- return;
310
- }
311
- const sanitizedState = this.config.stateSanitizer
312
- ? sanitizeState(this.config.stateSanitizer, currentState, state.currentStateIndex)
313
- : currentState;
314
- const sanitizedAction = this.config.actionSanitizer
315
- ? sanitizeAction(this.config.actionSanitizer, action, state.nextActionId)
316
- : action;
317
- this.sendToReduxDevtools(() => this.extensionConnection.send(sanitizedAction, sanitizedState));
318
- }
319
- else {
320
- // Requires full state update
321
- const sanitizedLiftedState = Object.assign(Object.assign({}, state), { stagedActionIds: state.stagedActionIds, actionsById: this.config.actionSanitizer
322
- ? sanitizeActions(this.config.actionSanitizer, state.actionsById)
323
- : state.actionsById, computedStates: this.config.stateSanitizer
324
- ? sanitizeStates(this.config.stateSanitizer, state.computedStates)
325
- : state.computedStates });
326
- this.sendToReduxDevtools(() => this.devtoolsExtension.send(null, sanitizedLiftedState, this.getExtensionConfig(this.config)));
327
- }
328
- }
329
- createChangesObservable() {
330
- if (!this.devtoolsExtension) {
331
- return EMPTY;
332
- }
333
- return new Observable((subscriber) => {
334
- const connection = this.devtoolsExtension.connect(this.getExtensionConfig(this.config));
335
- this.extensionConnection = connection;
336
- connection.init();
337
- connection.subscribe((change) => subscriber.next(change));
338
- return connection.unsubscribe;
339
- });
340
- }
341
- createActionStreams() {
342
- // Listens to all changes
343
- const changes$ = this.createChangesObservable().pipe(share());
344
- // Listen for the start action
345
- const start$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.START));
346
- // Listen for the stop action
347
- const stop$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.STOP));
348
- // Listen for lifted actions
349
- const liftedActions$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.DISPATCH), map((change) => this.unwrapAction(change.payload)), concatMap((action) => {
350
- if (action.type === IMPORT_STATE) {
351
- // State imports may happen in two situations:
352
- // 1. Explicitly by user
353
- // 2. User activated the "persist state accross reloads" option
354
- // and now the state is imported during reload.
355
- // Because of option 2, we need to give possible
356
- // lazy loaded reducers time to instantiate.
357
- // As soon as there is no UPDATE action within 1 second,
358
- // it is assumed that all reducers are loaded.
359
- return this.dispatcher.pipe(filter((action) => action.type === UPDATE), timeout(1000), debounceTime(1000), map(() => action), catchError(() => of(action)), take(1));
360
- }
361
- else {
362
- return of(action);
363
- }
364
- }));
365
- // Listen for unlifted actions
366
- const actions$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.ACTION), map((change) => this.unwrapAction(change.payload)));
367
- const actionsUntilStop$ = actions$.pipe(takeUntil(stop$));
368
- const liftedUntilStop$ = liftedActions$.pipe(takeUntil(stop$));
369
- this.start$ = start$.pipe(takeUntil(stop$));
370
- // Only take the action sources between the start/stop events
371
- this.actions$ = this.start$.pipe(switchMap(() => actionsUntilStop$));
372
- this.liftedActions$ = this.start$.pipe(switchMap(() => liftedUntilStop$));
373
- }
374
- unwrapAction(action) {
375
- return typeof action === 'string' ? eval(`(${action})`) : action;
376
- }
377
- getExtensionConfig(config) {
378
- var _a;
379
- const extensionOptions = {
380
- name: config.name,
381
- features: config.features,
382
- serialize: config.serialize,
383
- autoPause: (_a = config.autoPause) !== null && _a !== void 0 ? _a : false,
384
- // The action/state sanitizers are not added to the config
385
- // because sanitation is done in this class already.
386
- // It is done before sending it to the devtools extension for consistency:
387
- // - If we call extensionConnection.send(...),
388
- // the extension would call the sanitizers.
389
- // - If we call devtoolsExtension.send(...) (aka full state update),
390
- // the extension would NOT call the sanitizers, so we have to do it ourselves.
391
- };
392
- if (config.maxAge !== false /* support === 0 */) {
393
- extensionOptions.maxAge = config.maxAge;
394
- }
395
- return extensionOptions;
396
- }
397
- sendToReduxDevtools(send) {
398
- try {
399
- send();
400
- }
401
- catch (err) {
402
- console.warn('@ngrx/store-devtools: something went wrong inside the redux devtools', err);
403
- }
404
- }
405
- }
406
- DevtoolsExtension.decorators = [
407
- { type: Injectable }
408
- ];
409
- /** @nocollapse */
410
- DevtoolsExtension.ctorParameters = () => [
411
- { type: undefined, decorators: [{ type: Inject, args: [REDUX_DEVTOOLS_EXTENSION,] }] },
412
- { type: StoreDevtoolsConfig, decorators: [{ type: Inject, args: [STORE_DEVTOOLS_CONFIG,] }] },
413
- { type: DevtoolsDispatcher }
414
- ];
415
-
416
270
  const INIT_ACTION = { type: INIT };
417
271
  const RECOMPUTE = '@ngrx/store-devtools/recompute';
418
272
  const RECOMPUTE_ACTION = { type: RECOMPUTE };
@@ -774,6 +628,161 @@ function liftReducerWith(initialCommittedState, initialLiftedState, errorHandler
774
628
  };
775
629
  }
776
630
 
631
+ class DevtoolsDispatcher extends ActionsSubject {
632
+ }
633
+ /** @nocollapse */ DevtoolsDispatcher.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsDispatcher, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
634
+ /** @nocollapse */ DevtoolsDispatcher.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsDispatcher });
635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsDispatcher, decorators: [{
636
+ type: Injectable
637
+ }] });
638
+
639
+ const ExtensionActionTypes = {
640
+ START: 'START',
641
+ DISPATCH: 'DISPATCH',
642
+ STOP: 'STOP',
643
+ ACTION: 'ACTION',
644
+ };
645
+ const REDUX_DEVTOOLS_EXTENSION = new InjectionToken('@ngrx/store-devtools Redux Devtools Extension');
646
+ class DevtoolsExtension {
647
+ constructor(devtoolsExtension, config, dispatcher) {
648
+ this.config = config;
649
+ this.dispatcher = dispatcher;
650
+ this.devtoolsExtension = devtoolsExtension;
651
+ this.createActionStreams();
652
+ }
653
+ notify(action, state) {
654
+ if (!this.devtoolsExtension) {
655
+ return;
656
+ }
657
+ // Check to see if the action requires a full update of the liftedState.
658
+ // If it is a simple action generated by the user's app and the recording
659
+ // is not locked/paused, only send the action and the current state (fast).
660
+ //
661
+ // A full liftedState update (slow: serializes the entire liftedState) is
662
+ // only required when:
663
+ // a) redux-devtools-extension fires the @@Init action (ignored by
664
+ // @ngrx/store-devtools)
665
+ // b) an action is generated by an @ngrx module (e.g. @ngrx/effects/init
666
+ // or @ngrx/store/update-reducers)
667
+ // c) the state has been recomputed due to time-traveling
668
+ // d) any action that is not a PerformAction to err on the side of
669
+ // caution.
670
+ if (action.type === PERFORM_ACTION) {
671
+ if (state.isLocked || state.isPaused) {
672
+ return;
673
+ }
674
+ const currentState = unliftState(state);
675
+ if (shouldFilterActions(this.config) &&
676
+ isActionFiltered(currentState, action, this.config.predicate, this.config.actionsSafelist, this.config.actionsBlocklist)) {
677
+ return;
678
+ }
679
+ const sanitizedState = this.config.stateSanitizer
680
+ ? sanitizeState(this.config.stateSanitizer, currentState, state.currentStateIndex)
681
+ : currentState;
682
+ const sanitizedAction = this.config.actionSanitizer
683
+ ? sanitizeAction(this.config.actionSanitizer, action, state.nextActionId)
684
+ : action;
685
+ this.sendToReduxDevtools(() => this.extensionConnection.send(sanitizedAction, sanitizedState));
686
+ }
687
+ else {
688
+ // Requires full state update
689
+ const sanitizedLiftedState = Object.assign(Object.assign({}, state), { stagedActionIds: state.stagedActionIds, actionsById: this.config.actionSanitizer
690
+ ? sanitizeActions(this.config.actionSanitizer, state.actionsById)
691
+ : state.actionsById, computedStates: this.config.stateSanitizer
692
+ ? sanitizeStates(this.config.stateSanitizer, state.computedStates)
693
+ : state.computedStates });
694
+ this.sendToReduxDevtools(() => this.devtoolsExtension.send(null, sanitizedLiftedState, this.getExtensionConfig(this.config)));
695
+ }
696
+ }
697
+ createChangesObservable() {
698
+ if (!this.devtoolsExtension) {
699
+ return EMPTY;
700
+ }
701
+ return new Observable((subscriber) => {
702
+ const connection = this.devtoolsExtension.connect(this.getExtensionConfig(this.config));
703
+ this.extensionConnection = connection;
704
+ connection.init();
705
+ connection.subscribe((change) => subscriber.next(change));
706
+ return connection.unsubscribe;
707
+ });
708
+ }
709
+ createActionStreams() {
710
+ // Listens to all changes
711
+ const changes$ = this.createChangesObservable().pipe(share());
712
+ // Listen for the start action
713
+ const start$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.START));
714
+ // Listen for the stop action
715
+ const stop$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.STOP));
716
+ // Listen for lifted actions
717
+ const liftedActions$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.DISPATCH), map((change) => this.unwrapAction(change.payload)), concatMap((action) => {
718
+ if (action.type === IMPORT_STATE) {
719
+ // State imports may happen in two situations:
720
+ // 1. Explicitly by user
721
+ // 2. User activated the "persist state accross reloads" option
722
+ // and now the state is imported during reload.
723
+ // Because of option 2, we need to give possible
724
+ // lazy loaded reducers time to instantiate.
725
+ // As soon as there is no UPDATE action within 1 second,
726
+ // it is assumed that all reducers are loaded.
727
+ return this.dispatcher.pipe(filter((action) => action.type === UPDATE), timeout(1000), debounceTime(1000), map(() => action), catchError(() => of(action)), take(1));
728
+ }
729
+ else {
730
+ return of(action);
731
+ }
732
+ }));
733
+ // Listen for unlifted actions
734
+ const actions$ = changes$.pipe(filter((change) => change.type === ExtensionActionTypes.ACTION), map((change) => this.unwrapAction(change.payload)));
735
+ const actionsUntilStop$ = actions$.pipe(takeUntil(stop$));
736
+ const liftedUntilStop$ = liftedActions$.pipe(takeUntil(stop$));
737
+ this.start$ = start$.pipe(takeUntil(stop$));
738
+ // Only take the action sources between the start/stop events
739
+ this.actions$ = this.start$.pipe(switchMap(() => actionsUntilStop$));
740
+ this.liftedActions$ = this.start$.pipe(switchMap(() => liftedUntilStop$));
741
+ }
742
+ unwrapAction(action) {
743
+ return typeof action === 'string' ? eval(`(${action})`) : action;
744
+ }
745
+ getExtensionConfig(config) {
746
+ var _a;
747
+ const extensionOptions = {
748
+ name: config.name,
749
+ features: config.features,
750
+ serialize: config.serialize,
751
+ autoPause: (_a = config.autoPause) !== null && _a !== void 0 ? _a : false,
752
+ // The action/state sanitizers are not added to the config
753
+ // because sanitation is done in this class already.
754
+ // It is done before sending it to the devtools extension for consistency:
755
+ // - If we call extensionConnection.send(...),
756
+ // the extension would call the sanitizers.
757
+ // - If we call devtoolsExtension.send(...) (aka full state update),
758
+ // the extension would NOT call the sanitizers, so we have to do it ourselves.
759
+ };
760
+ if (config.maxAge !== false /* support === 0 */) {
761
+ extensionOptions.maxAge = config.maxAge;
762
+ }
763
+ return extensionOptions;
764
+ }
765
+ sendToReduxDevtools(send) {
766
+ try {
767
+ send();
768
+ }
769
+ catch (err) {
770
+ console.warn('@ngrx/store-devtools: something went wrong inside the redux devtools', err);
771
+ }
772
+ }
773
+ }
774
+ /** @nocollapse */ DevtoolsExtension.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsExtension, deps: [{ token: REDUX_DEVTOOLS_EXTENSION }, { token: STORE_DEVTOOLS_CONFIG }, { token: DevtoolsDispatcher }], target: i0.ɵɵFactoryTarget.Injectable });
775
+ /** @nocollapse */ DevtoolsExtension.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsExtension });
776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: DevtoolsExtension, decorators: [{
777
+ type: Injectable
778
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
779
+ type: Inject,
780
+ args: [REDUX_DEVTOOLS_EXTENSION]
781
+ }] }, { type: StoreDevtoolsConfig, decorators: [{
782
+ type: Inject,
783
+ args: [STORE_DEVTOOLS_CONFIG]
784
+ }] }, { type: DevtoolsDispatcher }]; } });
785
+
777
786
  class StoreDevtools {
778
787
  constructor(dispatcher, actions$, reducers$, extension, scannedActions, errorHandler, initialState, config) {
779
788
  const liftedInitialState = liftInitialState(initialState, config.monitor);
@@ -856,20 +865,17 @@ class StoreDevtools {
856
865
  this.dispatch(new PauseRecording(status));
857
866
  }
858
867
  }
859
- StoreDevtools.decorators = [
860
- { type: Injectable }
861
- ];
862
- /** @nocollapse */
863
- StoreDevtools.ctorParameters = () => [
864
- { type: DevtoolsDispatcher },
865
- { type: ActionsSubject },
866
- { type: ReducerObservable },
867
- { type: DevtoolsExtension },
868
- { type: ScannedActionsSubject },
869
- { type: ErrorHandler },
870
- { type: undefined, decorators: [{ type: Inject, args: [INITIAL_STATE,] }] },
871
- { type: StoreDevtoolsConfig, decorators: [{ type: Inject, args: [STORE_DEVTOOLS_CONFIG,] }] }
872
- ];
868
+ /** @nocollapse */ StoreDevtools.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtools, deps: [{ token: DevtoolsDispatcher }, { token: i2.ActionsSubject }, { token: i2.ReducerObservable }, { token: DevtoolsExtension }, { token: i2.ScannedActionsSubject }, { token: i0.ErrorHandler }, { token: INITIAL_STATE }, { token: STORE_DEVTOOLS_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
869
+ /** @nocollapse */ StoreDevtools.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtools });
870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtools, decorators: [{
871
+ type: Injectable
872
+ }], ctorParameters: function () { return [{ type: DevtoolsDispatcher }, { type: i2.ActionsSubject }, { type: i2.ReducerObservable }, { type: DevtoolsExtension }, { type: i2.ScannedActionsSubject }, { type: i0.ErrorHandler }, { type: undefined, decorators: [{
873
+ type: Inject,
874
+ args: [INITIAL_STATE]
875
+ }] }, { type: StoreDevtoolsConfig, decorators: [{
876
+ type: Inject,
877
+ args: [STORE_DEVTOOLS_CONFIG]
878
+ }] }]; } });
873
879
 
874
880
  const IS_EXTENSION_OR_MONITOR_PRESENT = new InjectionToken('@ngrx/store-devtools Is Devtools Extension or Monitor Present');
875
881
  function createIsExtensionOrMonitorPresent(extension, config) {
@@ -927,9 +933,13 @@ class StoreDevtoolsModule {
927
933
  };
928
934
  }
929
935
  }
930
- StoreDevtoolsModule.decorators = [
931
- { type: NgModule, args: [{},] }
932
- ];
936
+ /** @nocollapse */ StoreDevtoolsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtoolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
937
+ /** @nocollapse */ StoreDevtoolsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtoolsModule });
938
+ /** @nocollapse */ StoreDevtoolsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtoolsModule });
939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.6", ngImport: i0, type: StoreDevtoolsModule, decorators: [{
940
+ type: NgModule,
941
+ args: [{}]
942
+ }] });
933
943
 
934
944
  /**
935
945
  * DO NOT EDIT
@@ -941,5 +951,5 @@ StoreDevtoolsModule.decorators = [
941
951
  * Generated bundle index. Do not edit.
942
952
  */
943
953
 
944
- export { INITIAL_OPTIONS, RECOMPUTE, StoreDevtools, StoreDevtoolsConfig, StoreDevtoolsModule, IS_EXTENSION_OR_MONITOR_PRESENT as ɵa, createIsExtensionOrMonitorPresent as ɵb, createReduxDevtoolsExtension as ɵc, createStateObservable as ɵd, STORE_DEVTOOLS_CONFIG as ɵe, noMonitor as ɵf, createConfig as ɵg, REDUX_DEVTOOLS_EXTENSION as ɵh, DevtoolsExtension as ɵi, DevtoolsDispatcher as ɵj };
954
+ export { INITIAL_OPTIONS, RECOMPUTE, StoreDevtools, StoreDevtoolsConfig, StoreDevtoolsModule };
945
955
  //# sourceMappingURL=ngrx-store-devtools.js.map