Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support to give name for store dev tool #517

Merged
merged 9 commits into from
Nov 13, 2017
3 changes: 0 additions & 3 deletions modules/router-store/spec/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ describe('integration spec', () => {
{ type: 'router', event: 'NavigationStart', url: '/' },
{ type: 'router', event: 'RoutesRecognized', url: '/' },
{ type: 'store', state: '/' }, // ROUTER_NAVIGATION event in the store

/* new Router Lifecycle in Angular 4.3 */
{ type: 'router', event: 'GuardsCheckStart', url: '/' },
{ type: 'router', event: 'GuardsCheckEnd', url: '/' },
Expand Down Expand Up @@ -162,7 +161,6 @@ describe('integration spec', () => {
{ type: 'router', event: 'GuardsCheckEnd', url: '/next' },
// { type: 'router', event: 'ResolveStart', url: '/next' },
// { type: 'router', event: 'ResolveEnd', url: '/next' },

{
type: 'store',
state: {
Expand Down Expand Up @@ -451,7 +449,6 @@ describe('integration spec', () => {
{ type: 'router', event: 'NavigationStart', url: '/next' },
{ type: 'router', event: 'RoutesRecognized', url: '/next' },
{ type: 'store', state: undefined }, // after ROUTER_NAVIGATION

/* new Router Lifecycle in Angular 4.3 */
{ type: 'router', event: 'GuardsCheckStart', url: '/next' },
{ type: 'store', state: undefined }, // after USER_EVENT
Expand Down
1 change: 0 additions & 1 deletion modules/router-store/src/router_store_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ export class StoreRouterConnectingModule {

private dispatchTriggeredByRouter: boolean = false; // used only in dev mode in combination with routerReducer
private navigationTriggeredByDispatch: boolean = false; // used only in dev mode in combination with routerReducer

private stateKey: string;

constructor(
Expand Down
10 changes: 10 additions & 0 deletions modules/store-devtools/spec/config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ActionReducer, Action } from '@ngrx/store';
import { StoreDevtoolsConfig } from '../';

describe('StoreDevtoolsOptions', () => {
it('can be initialized with name', () => {
const options = new StoreDevtoolsConfig();
options.name = 'my instance';
expect(options.name).toBe('my instance');
});
});
79 changes: 79 additions & 0 deletions modules/store-devtools/spec/extension.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
StoreDevtools,
StoreDevtoolsModule,
LiftedState,
StoreDevtoolsConfig,
StoreDevtoolsOptions,
} from '../';
import {
StoreModule,
Store,
StateObservable,
ActionReducer,
Action,
ReducerManager,
} from '@ngrx/store';
import { of } from 'rxjs/observable/of';
import { createConfig, noMonitor } from '../src/instrument';
import { DevtoolsExtension, ReduxDevtoolsExtension } from '../src/extension';

describe('DevtoolsExtension', () => {
let reduxDevtoolsExtension: ReduxDevtoolsExtension;
let devtoolsExtension: DevtoolsExtension;

beforeEach(() => {
reduxDevtoolsExtension = jasmine.createSpyObj('reduxDevtoolsExtension', [
'send',
'connect',
]);
(reduxDevtoolsExtension.connect as jasmine.Spy).and.returnValue(of({}));
spyOn(Date, 'now').and.returnValue('1509655064369');
});

describe('notify', () => {
it('should send notification with default options', () => {
devtoolsExtension = new DevtoolsExtension(
reduxDevtoolsExtension,
createConfig({})
);
const defaultOptions = {
maxAge: false,
monitor: noMonitor,
name: 'NgRx Store DevTools',
serialize: false,
};
const action = {} as Action;
const state = {} as LiftedState;
devtoolsExtension.notify(action, state);
expect(reduxDevtoolsExtension.send).toHaveBeenCalledWith(
null,
{},
defaultOptions,
'ngrx-store-1509655064369'
);
});
it('should send notification with given options', () => {
devtoolsExtension = new DevtoolsExtension(
reduxDevtoolsExtension,
createConfig({
name: 'ngrx-store-devtool-todolist',
})
);
const defaultOptions = {
maxAge: false,
monitor: noMonitor,
name: 'ngrx-store-devtool-todolist',
serialize: false,
};
const action = {} as Action;
const state = {} as LiftedState;
devtoolsExtension.notify(action, state);
expect(reduxDevtoolsExtension.send).toHaveBeenCalledWith(
null,
{},
defaultOptions,
'ngrx-store-1509655064369'
);
});
});
});
8 changes: 5 additions & 3 deletions modules/store-devtools/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { ActionReducer } from '@ngrx/store';
import { ActionReducer, Action } from '@ngrx/store';
import { InjectionToken, Type } from '@angular/core';

export class StoreDevtoolsConfig {
maxAge: number | false;
monitor: ActionReducer<any, any>;
maxAge?: number | false;
monitor?: ActionReducer<any, any>;
name?: string;
serialize?: boolean;
}

export const STORE_DEVTOOLS_CONFIG = new InjectionToken<StoreDevtoolsConfig>(
Expand Down
10 changes: 7 additions & 3 deletions modules/store-devtools/src/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ export class StoreDevtools implements Observer<any> {
initialState,
liftedInitialState,
config.monitor,
config.maxAge ? { maxAge: config.maxAge } : {}
{
maxAge: config.maxAge as number,
name: config.name,
serialize: config.serialize,
}
);

const liftedAction$ = applyOperators(actions$.asObservable(), [
Expand Down Expand Up @@ -80,9 +84,9 @@ export class StoreDevtools implements Observer<any> {
liftedStateSubject.next(state);

if (action.type === Actions.PERFORM_ACTION) {
const unlifedAction = (action as Actions.PerformAction).action;
const unliftedAction = (action as Actions.PerformAction).action;

scannedActions.next(unlifedAction);
scannedActions.next(unliftedAction);
}
});

Expand Down
18 changes: 8 additions & 10 deletions modules/store-devtools/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { InjectionToken, Inject, Injectable } from '@angular/core';
import { Inject, Injectable, InjectionToken } from '@angular/core';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { empty } from 'rxjs/observable/empty';
import { filter } from 'rxjs/operator/filter';
import { map } from 'rxjs/operator/map';
import { share } from 'rxjs/operator/share';
import { switchMap } from 'rxjs/operator/switchMap';
import { takeUntil } from 'rxjs/operator/takeUntil';
import { Action } from '@ngrx/store';

import { STORE_DEVTOOLS_CONFIG, StoreDevtoolsConfig } from './config';
import { LiftedState } from './reducer';
import { applyOperators } from './utils';

Expand Down Expand Up @@ -35,7 +37,7 @@ export interface ReduxDevtoolsExtension {
send(
action: any,
state: any,
options?: boolean | { serialize: boolean | object },
options: StoreDevtoolsConfig,
instanceId?: string
): void;
}
Expand All @@ -49,7 +51,8 @@ export class DevtoolsExtension {
actions$: Observable<any>;

constructor(
@Inject(REDUX_DEVTOOLS_EXTENSION) devtoolsExtension: ReduxDevtoolsExtension
@Inject(REDUX_DEVTOOLS_EXTENSION) devtoolsExtension: ReduxDevtoolsExtension,
@Inject(STORE_DEVTOOLS_CONFIG) private config: StoreDevtoolsConfig
) {
this.devtoolsExtension = devtoolsExtension;
this.createActionStreams();
Expand All @@ -60,12 +63,7 @@ export class DevtoolsExtension {
return;
}

this.devtoolsExtension.send(
null,
state,
{ serialize: false },
this.instanceId
);
this.devtoolsExtension.send(null, state, this.config, this.instanceId);
}

private createChangesObservable(): Observable<any> {
Expand Down
4 changes: 4 additions & 0 deletions modules/store-devtools/src/instrument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ export function noMonitor(): null {
return null;
}

export const DEFAULT_NAME = 'NgRx Store DevTools';

export function createConfig(
_options: StoreDevtoolsOptions
): StoreDevtoolsConfig {
const DEFAULT_OPTIONS: StoreDevtoolsConfig = {
maxAge: false,
monitor: noMonitor,
name: DEFAULT_NAME,
serialize: false,
};

let options = typeof _options === 'function' ? _options() : _options;
Expand Down
3 changes: 2 additions & 1 deletion modules/store-devtools/src/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import { difference, liftAction } from './utils';
import * as Actions from './actions';
import { StoreDevtoolsConfig } from './config';

export type InitAction = {
readonly type: typeof INIT;
Expand Down Expand Up @@ -129,7 +130,7 @@ export function liftReducerWith(
initialCommittedState: any,
initialLiftedState: LiftedState,
monitorReducer?: any,
options: { maxAge?: number } = {}
options: Partial<StoreDevtoolsConfig> = {}
) {
/**
* Manages how the history actions modify the history state.
Expand Down