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

fix(StoreDevtools): Do not send full liftedState on simple actions. #790

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions modules/store-devtools/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { takeUntil } from 'rxjs/operator/takeUntil';

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

export const ExtensionActionTypes = {
Expand All @@ -28,11 +29,13 @@ export interface ReduxDevtoolsExtensionConnection {
unsubscribe(): void;
send(action: any, state: any): void;
init(state?: any): void;
error(any: any): void;
}
export interface ReduxDevtoolsExtensionConfig {
features?: object | boolean;
name: string | undefined;
instanceId: string;
maxAge?: number;
}

export interface ReduxDevtoolsExtension {
Expand All @@ -51,6 +54,7 @@ export interface ReduxDevtoolsExtension {
export class DevtoolsExtension {
private instanceId = `ngrx-store-${Date.now()}`;
private devtoolsExtension: ReduxDevtoolsExtension;
private extensionConnection: ReduxDevtoolsExtensionConnection;

liftedActions$: Observable<any>;
actions$: Observable<any>;
Expand All @@ -68,7 +72,26 @@ export class DevtoolsExtension {
return;
}

this.devtoolsExtension.send(null, state, this.config, this.instanceId);
// Check to see if the action requires a full update of the liftedState.
// If it is a simple action generated by the user's app, only send the
// action and the current state (fast).
//
// A full liftedState update (slow: serializes the entire liftedState) is
// only required when:
// a) redux-devtools-extension fires the @@Init action (ignored by
// @ngrx/store-devtools)
// b) an action is generated by an @ngrx module (e.g. @ngrx/effects/init
// or @ngrx/store/update-reducers)
// c) the state has been recomputed due to time-traveling
// d) any action that is not a PerformAction to err on the side of
// caution.
if (action instanceof PerformAction) {
const currentState = state.computedStates[state.currentStateIndex].state;
this.extensionConnection.send(action.action, currentState);
} else {
// Requires full state update;
this.devtoolsExtension.send(null, state, this.config, this.instanceId);
}
}

private createChangesObservable(): Observable<any> {
Expand All @@ -77,15 +100,19 @@ export class DevtoolsExtension {
}

return new Observable(subscriber => {
const connection = this.devtoolsExtension.connect({
let extensionOptions: ReduxDevtoolsExtensionConfig = {
instanceId: this.instanceId,
name: this.config.name,
features: this.config.features,
});
};
if (this.config.maxAge !== false /* support === 0 */) {
extensionOptions.maxAge = this.config.maxAge;
}
const connection = this.devtoolsExtension.connect(extensionOptions);
this.extensionConnection = connection;
connection.init();

connection.subscribe((change: any) => subscriber.next(change));

return connection.unsubscribe;
});
}
Expand Down