router-component-store icon indicating copy to clipboard operation
router-component-store copied to clipboard

feat: Add @ngworker/router-store package with pure Angular Signals

Open Copilot opened this issue 5 months ago • 0 comments

This PR introduces a new @ngworker/router-store package that provides a strictly typed, lightweight alternative to NgRx Router Store and ActivatedRoute using pure Angular Signals without any external state management dependencies.

What's New

The @ngworker/router-store package offers the same API surface as @ngworker/router-signal-store but with a key architectural difference: it uses only Angular's native signal primitives from @angular/core instead of relying on @ngrx/signals.

Key Features

  • RouterStore abstract class for dependency injection with signal-based API
  • GlobalRouterStore implementation that replaces @ngrx/router-store functionality
  • LocalRouterStore implementation that replaces ActivatedRoute with component-scoped reactivity
  • Provider functions: provideGlobalRouterStore() and provideLocalRouterStore()
  • Strict typing with StrictQueryParams, StrictRouteData, and StrictRouteParams
  • Serializable router state with MinimalActivatedRouteSnapshot

Example Usage

// Bootstrap with global router store
bootstrapApplication(AppComponent, {
  providers: [provideGlobalRouterStore()],
});

// Use in components
@Component({
  template: `<p>Hero ID: {{ heroId() }}</p>`,
})
export class HeroDetailComponent {
  #routerStore = inject(RouterStore);

  heroId = this.#routerStore.selectRouteParam('id');
  searchQuery = this.#routerStore.selectQueryParam('q');
  routeTitle = this.#routerStore.title;
}

Architecture

  • Pure Angular Signals: Uses signal(), computed(), and WritableSignal from @angular/core
  • No external dependencies: Zero dependencies on RxJS or @ngrx/* packages (except in tests)
  • Reactive state management: Router events trigger signal updates using Angular's native reactivity
  • Component lifecycle integration: Local store follows component lifecycle with proper cleanup

Implementation Details

The GlobalRouterStore maintains router state in a writable signal that updates on navigation events, while LocalRouterStore combines toSignal() for ActivatedRoute observables with custom state serialization for route snapshots.

Both implementations provide parameterized selectors for accessing specific route parameters, query parameters, and route data with full type safety.

Fixes #359.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot avatar Sep 24 '25 11:09 Copilot