CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ngrx--store-devtools

Developer tools for @ngrx/store providing comprehensive debugging and time-travel capabilities for Angular applications.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

debugging-service.mddocs/

Core Debugging Service

The main devtools service providing programmatic access to debugging functionality including time-travel operations, state inspection, and recording controls.

Capabilities

StoreDevtools Service

Core service that manages devtools state and provides debugging methods.

/**
 * Main devtools service implementing Observer pattern for action handling
 */
class StoreDevtools implements Observer<any>, OnDestroy {
  /** Action dispatcher for devtools actions */
  dispatcher: ActionsSubject;
  /** Observable of enhanced state with devtools metadata */
  liftedState: Observable<LiftedState>;
  /** Observable of current application state */
  state: StateObservable;

  /**
   * Dispatch an action through the devtools system
   * @param action - Action to dispatch
   */
  dispatch(action: Action): void;

  /**
   * Observer interface method for handling next action
   * @param action - Action to handle
   */
  next(action: any): void;

  /**
   * Observer interface method for handling errors
   * @param error - Error to handle
   */
  error(error: any): void;

  /**
   * Observer interface method for completion
   */
  complete(): void;

  /**
   * Perform a user action through the devtools system
   * @param action - User action to perform
   */
  performAction(action: any): void;

  /**
   * Refresh the devtools state
   */
  refresh(): void;

  /**
   * Reset the devtools to initial state
   */
  reset(): void;

  /**
   * Rollback to the previous committed state
   */
  rollback(): void;

  /**
   * Commit the current state as the new baseline
   */
  commit(): void;

  /**
   * Remove all skipped actions from history
   */
  sweep(): void;

  /**
   * Toggle an action between active and inactive state
   * @param id - ID of the action to toggle
   */
  toggleAction(id: number): void;

  /**
   * Jump to a specific action in the history
   * @param actionId - ID of the action to jump to
   */
  jumpToAction(actionId: number): void;

  /**
   * Jump to a specific state index in the history
   * @param index - Index of the state to jump to
   */
  jumpToState(index: number): void;

  /**
   * Import a previously exported state
   * @param nextLiftedState - Lifted state to import
   */
  importState(nextLiftedState: any): void;

  /**
   * Lock or unlock state changes
   * @param status - True to lock changes, false to unlock
   */
  lockChanges(status: boolean): void;

  /**
   * Pause or resume recording of actions
   * @param status - True to pause recording, false to resume
   */
  pauseRecording(status: boolean): void;

  /**
   * Cleanup method called when service is destroyed
   */
  ngOnDestroy(): void;
}

Usage Examples:

import { Component, OnInit } from "@angular/core";
import { StoreDevtools } from "@ngrx/store-devtools";

@Component({
  selector: "app-debug-controls",
  template: `
    <button (click)="reset()">Reset</button>
    <button (click)="commit()">Commit</button>
    <button (click)="rollback()">Rollback</button>
    <button (click)="toggleRecording()">
      {{ isPaused ? 'Resume' : 'Pause' }} Recording
    </button>
  `,
})
export class DebugControlsComponent implements OnInit {
  isPaused = false;

  constructor(private devtools: StoreDevtools) {}

  ngOnInit() {
    // Subscribe to lifted state to monitor devtools state
    this.devtools.liftedState.subscribe((liftedState) => {
      this.isPaused = liftedState.isPaused;
      console.log("Current action count:", liftedState.nextActionId);
    });
  }

  reset() {
    this.devtools.reset();
  }

  commit() {
    this.devtools.commit();
  }

  rollback() {
    this.devtools.rollback();
  }

  toggleRecording() {
    this.devtools.pauseRecording(!this.isPaused);
  }
}

DevtoolsDispatcher

Specialized dispatcher extending ActionsSubject for devtools operations.

/**
 * Injectable dispatcher service extending ActionsSubject for devtools
 */
class DevtoolsDispatcher extends ActionsSubject {}

Extension Integration Service

Service managing connection to Redux DevTools browser extension.

/**
 * Service for integrating with Redux DevTools browser extension
 */
class DevtoolsExtension {
  /** Observable of actions from the extension */
  actions$: Observable<any>;
  /** Observable of lifted actions from the extension */
  liftedActions$: Observable<any>;
  /** Observable indicating when extension starts */
  start$: Observable<any>;

  /**
   * Notify the extension of state changes
   * @param action - Action that caused the change
   * @param state - New lifted state
   */
  notify(action: any, state: LiftedState): void;
}

/**
 * Interface for Redux DevTools extension connection
 */
interface ReduxDevtoolsExtensionConnection {
  /** Subscribe to extension changes */
  subscribe(listener: (change: any) => void): void;
  /** Unsubscribe from extension changes */
  unsubscribe(): void;
  /** Send action and state to extension */
  send(action: any, state: any): void;
  /** Initialize extension with state */
  init(state: any): void;
  /** Send error message to extension */
  error(message: string): void;
}

/**
 * Redux DevTools browser extension interface
 */
interface ReduxDevtoolsExtension {
  connect(options?: any): ReduxDevtoolsExtensionConnection;
}

State Observable Factory

Factory function for creating state observable from devtools service.

/**
 * Create state observable from devtools service
 * @param devtools - StoreDevtools service instance
 * @returns StateObservable for current application state
 */
function createStateObservable(devtools: StoreDevtools): StateObservable;

Zone Configuration

Zone configuration utilities for controlling Angular zone behavior with devtools.

/**
 * Zone configuration type for devtools connection
 */
type ZoneConfig = 
  | { connectInZone: true; ngZone: NgZone }
  | { connectInZone: false; ngZone: null };

/**
 * Inject zone configuration based on connectInZone setting
 * @param connectInZone - Whether to connect within Angular zone
 * @returns Zone configuration object
 */
function injectZoneConfig(connectInZone: boolean): ZoneConfig;

Advanced Usage Example:

import { Injectable } from "@angular/core";
import { StoreDevtools } from "@ngrx/store-devtools";
import { map, filter, take } from "rxjs/operators";

@Injectable({
  providedIn: "root",
})
export class CustomDebuggingService {
  constructor(private devtools: StoreDevtools) {}

  // Monitor specific action types
  watchActionType(actionType: string) {
    return this.devtools.liftedState.pipe(
      map((liftedState) => liftedState.actionsById),
      map((actions) =>
        Object.values(actions).filter((action) => action.action.type === actionType)
      )
    );
  }

  // Get current error state
  getCurrentErrors() {
    return this.devtools.liftedState.pipe(
      map((liftedState) => liftedState.computedStates),
      map((states) => states.filter((state) => state.error)),
      filter((errorStates) => errorStates.length > 0)
    );
  }

  // Jump to first occurrence of action type
  jumpToFirstAction(actionType: string) {
    this.devtools.liftedState.pipe(take(1)).subscribe((liftedState) => {
      const actionId = Object.keys(liftedState.actionsById).find(
        (id) => liftedState.actionsById[parseInt(id)].action.type === actionType
      );
      
      if (actionId) {
        this.devtools.jumpToAction(parseInt(actionId));
      }
    });
  }

  // Export current devtools state
  exportState() {
    return this.devtools.liftedState.pipe(
      take(1),
      map((liftedState) => JSON.stringify(liftedState, null, 2))
    );
  }

  // Import devtools state from JSON
  importStateFromJson(jsonState: string) {
    try {
      const liftedState = JSON.parse(jsonState);
      this.devtools.importState(liftedState);
    } catch (error) {
      console.error("Failed to import state:", error);
    }
  }
}

docs

actions.md

configuration.md

debugging-service.md

index.md

state-types.md

tile.json