Skip to content

Remove the @ngrx dependency — final elimination of ngrx from the frontend - #5428

Merged
norman-abramovitz merged 6 commits into
cloudfoundry:developfrom
nabramovitz:feature/ngrx-removal-closer
Jun 7, 2026
Merged

Remove the @ngrx dependency — final elimination of ngrx from the frontend#5428
norman-abramovitz merged 6 commits into
cloudfoundry:developfrom
nabramovitz:feature/ngrx-removal-closer

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Summary

Completes the long-running migration off @ngrx/{store,effects,store-devtools} (+ ngrx-store-localstorage). The console is now fully signal-native; this series removes the last ngrx scaffolding and the dependency itself. End state: zero @ngrx in the codebase.

This is the closer of a multi-PR effort — earlier PRs deleted the request/pagination/entity-catalog pipeline and migrated each page to signals. The runtime store, effects, and devtools were already gone before this branch; what remained was vestigial type-only carriers, a public-api compatibility shim, dead test scaffolding, and the package dependency.

What changed (6 commits, leaves-first)

  1. Caller-less dead code — dispatch-sequencer, a dead CF service-instance effect, an unused signal-selectors helper.
  2. Dead lists view-state slice — superseded by the signal-native ListStateStore (per-list-key localStorage).
  3. Entity-catalog detach — drop the InitCatalogEntitiesAction dispatch / ReducerManager; catalog registration stays a plain global map.
  4. Last vestigial dispatches — endpoint-disconnect cleanup (keeps its signal effect()), localStorage pagination hydration.
  5. Runtime store removal — root StoreModule/EffectsModule.forRoot, StoreDevtools, ~13 vestigial Store injections; registeredLimit swapped from a Store carrier to Injector.
  6. Dependency elimination (this commit) — replace the remaining type-only @ngrx/store imports with a tiny local action.types.ts (mirrors Action/ActionReducer/Store shapes, no runtime behaviour); inline the two ngrx selector helpers (createSelector, compose); remove the public-api ngrx re-export shim; neutralise the test scaffolding; sweep dead ngrx test providers from 63 specs; remove the deps from package.json + lockfile.

Behaviour preservation

Every removal is backed by a verified signal-native replacement, not a blind strip — e.g. list view/page/sort persistence (ListStateStore), endpoint state (EndpointsDataService), session/dashboard restore. Specs that injected the store purely as dead scaffolding had it removed; the two endpoint-edit specs were re-pointed to seed EndpointsDataService directly.

Verification

  • git grep '@ngrx' → doc-comments only, zero functional references
  • Full quality gate green: lint 0 errors, 2573 unit tests pass / 0 fail, production build complete

Slice 1 of the final ngrx-removal closer (engine already gone in cloudfoundry#5413).
All three targets are dead with the request/pagination pipeline removed:

- dispatch-sequencer.ts: no callers anywhere.
- service-instance.effects.ts: self-documented dead (CF delete is V3 async-job
  HTTP; no live producer of DELETE_SERVICE_INSTANCE_ACTIONS). Drops the only
  CF effect, so EffectsModule.forFeature leaves cloud-foundry.store.module.
- signal-selectors.ts (getSignal helper): no consumers, not exported.

No behavior change; nothing dispatched or read these.
Slice 2 of the ngrx-removal closer. The legacy `lists` ngrx slice
(view/page/sort persistence) was superseded by the signal-native
ListStateStore (core), which persists per-list-key to localStorage via a
signal effect and is wired into every signal list config. The ngrx slice
had zero live dispatchers (no SetListViewAction/SetListStateAction) and
zero readers (getListStateObservables unconsumed).

- Delete list.reducer.ts + list.actions.ts.
- appReducers -> {} (root store now holds no slices).
- Drop `lists`/ListsState/ListsOnlyAppState from app-state.
- Drop the lists localStorage hydration + metaReducer LISTS sync key
  (ListStateStore owns stratos.list-state.v1.* keys; the old
  <userId>-lists key is independent, so saved prefs are unaffected).
- Remove the lists re-exports from public-api.

Pagination localStorage + dashboard/theme persistence untouched. No
behavior change: card/table view + sort still persist via ListStateStore.
Slice 3 of the ngrx-removal closer. Entity registration is done by the
global `entityCatalog` singleton (synchronous Map.set); the
InitCatalogEntitiesAction dispatch had no reducer consuming it (pure
no-op) and ReducerManager was provided but never used (no addReducer
call). Drop both from EntityCatalogModule.forFeature + the test module,
and delete entity-catalog.actions.ts. Catalog registration unchanged.
Slice 4 of the ngrx-removal closer. After the engine removal (cloudfoundry#5413) the
remaining store.dispatch calls all targeted deleted reducers (no-ops):

- endpoint-disconnect-cleanup: drop the ResetPaginationOfType +
  RemoveEntitiesForEndpoint dispatches (pagination/entity-data reducers
  are gone; signal data services own their caches). Keep the live
  signal-native cleanup (error-events clear, recents prune) + the Store
  injection goes. Delete remove-entities-for-endpoint.actions.ts.
- local-storage-service: drop the pagination hydration + its now-orphaned
  helpers (localStorageToStoreSection, decrypt); localStorageToStore is
  dashboard-only and no longer needs the Store. Dashboard/theme/version/
  clear utilities + the (still-wired) sync metaReducer untouched.
- auth-data.service: drop the Store injection (session is signal-native
  via SessionService; the VerifiedSession/auth-reducer comment was stale).
- Specs updated to the new signatures/behavior.

No prod store.dispatch remains. No behavior change: list/page/sort persist
via ListStateStore; session/dashboard restore via signal services.
Slice 5 of the ngrx-removal closer. After the engine removal (cloudfoundry#5413) every
remaining Store injection was either vestigial (inject-but-never-use) or used
the store purely as an injector carrier. Removes all runtime ngrx:

- Drop ~13 vestigial Store injections across core/cloud-foundry/cf-autoscaler
  (endpoints, app-tabs-base, log-stream, ssh, orgs-signal, backup/restore,
  create-endpoint-cf-step-1, endpoints-signal-config, page-header-events,
  long-running-op, autoscaler-tab-extension).
- global-events.service: the ngrx event-config channel had no live
  addEventConfig callers; drop the Store from getEventsAndPriorityType (the
  live banner runs on the signal EndpointErrorEventsService).
- extension visible(store) hook: dead public API (zero implementers) that took
  a Store — removed; buttons already fall back to of(true).
- registeredLimit entity-catalog hook: only ever used the store as an injector
  carrier — re-typed to (injector: Injector); helm + base-endpoint-tile-manager
  updated; subclasses pass the injector.
- Remove the root store: StoreModule.forRoot + EffectsModule.forRoot
  (reducers.module/store.module), the localStorage sync metaReducer +
  encrypt/parseStorePart helpers, and StoreDevtoolsModule (app.module).
- acme-login example: LoginPageComponent is inject()-based; drop the store arg.

appReducers ({}) stays exported only for component specs' throwaway test store
(removed when specs migrate off ngrx in the final slice). No runtime inject(Store)
remains. Full make check gate green. Behavior preserved (signal banner, session
restore, endpoint registration limits).
The closer of the ngrx-removal workstream. After slices 1-5 left the running
app with zero runtime ngrx, this removes the last traces and the dependency
itself. End state: zero @ngrx anywhere in the codebase, full gate green.

- Type-only carriers: replace the remaining `@ngrx/store` *type* imports
  (Action, ActionReducer, Store) with a local store/src/types/action.types.ts
  that mirrors the shapes 1:1 (no runtime behaviour). Inline the two ngrx
  selector helpers — cf-entity.selectors `createSelector` becomes plain state
  projection (no memoization relied upon), api.selectors `compose` becomes a
  direct function composition.
- Remove the @stratosui/store public-api ngrx re-export shim (Action, Store,
  StoreModule, createSelector, provideStore, select, EffectsModule, Actions,
  createEffect, ofType) — verified no production consumer imported these.
- Neutralise the test scaffolding so signal-era specs keep compiling: the
  store-module factory helpers return an inert module, populateStoreWithTest-
  Endpoint seeds the signal-native EndpointsDataService (new helper
  seedEndpointsDataService), and the CF test modules drop EffectsModule /
  StoreModule.forRoot / Store injection.
- Sweep 63 spec files: remove dead ngrx test providers (StoreModule.forRoot,
  provideStore, provideMockStore, { provide: Store }) and imports — no spec
  injected or read the store. The two edit-endpoint specs swap their ngrx
  dispatch endpoint-seeding for seedEndpointsDataService; the home-page spec
  drops a test that asserted an ngrx-dispatch non-behavior now structurally
  impossible.
- Delete the empty reducers.module.ts / appReducers and the now-unused
  ActionReducerMap local type.
- Remove @ngrx/{store,effects,store-devtools} and ngrx-store-localstorage from
  the root and core package.json, refresh the lockfile, and drop the @ngrx
  entries from the vitest configs.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reached the end of removing ngrx

@norman-abramovitz
norman-abramovitz merged commit 108bd46 into cloudfoundry:develop Jun 7, 2026
12 checks passed
@nabramovitz
nabramovitz deleted the feature/ngrx-removal-closer branch June 9, 2026 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants