Skip to content

Commit

Permalink
feat: update to NgRx Signals 18 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
rainerhahnekamp authored Jul 30, 2024
1 parent c24cba8 commit 3d61dd2
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 308 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Starting with 18.0.0-rc.2, we have a [strict version dependency](#why-is-the-ver
|----------------|----------------------------------|
| <= 18.0.0-rc.1 | 0.0.4 |
| 18.0.0-rc.2 | 18.0.0-rc.2.x |
| 18.0.0-rc.3 | (not supported) |
| 18.0.0 | 18.0.0 |

To install it, run

Expand Down
6 changes: 3 additions & 3 deletions apps/demo/src/app/lazy-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { FlightEditSimpleComponent } from './flight-search-data-service-simple/f
import { FlightSearchDynamicComponent } from './flight-search-data-service-dynamic/flight-search.component';
import { FlightEditDynamicComponent } from './flight-search-data-service-dynamic/flight-edit.component';
import { TodoStorageSyncComponent } from './todo-storage-sync/todo-storage-sync.component';
import { provideFlightStore } from './flight-search-redux-connector/+state/redux';
import { FlightSearchReducConnectorComponent } from './flight-search-redux-connector/flight-search.component';
import { FlightSearchWithPaginationComponent } from './flight-search-with-pagination/flight-search-with-pagination.component';
import { FlightSearchReducConnectorComponent } from './flight-search-redux-connector/flight-search.component';
import { provideFlightStore } from './flight-search-redux-connector/+state/redux';

export const lazyRoutes: Route[] = [
{ path: 'todo', component: TodoComponent },
Expand All @@ -24,7 +24,7 @@ export const lazyRoutes: Route[] = [
},
{
path: 'flight-search-with-pagination',
component: FlightSearchWithPaginationComponent
component: FlightSearchWithPaginationComponent,
},
{ path: 'flight-edit-dynamic/:id', component: FlightEditDynamicComponent },
{ path: 'todo-storage-sync', component: TodoStorageSyncComponent },
Expand Down
4 changes: 2 additions & 2 deletions libs/ngrx-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@angular-architects/ngrx-toolkit",
"version": "18.0.0-rc.2.0",
"version": "18.0.0",
"license": "MIT",
"repository": {
"type": "GitHub",
"url": "https://github.com/angular-architects/ngrx-toolkit"
},
"peerDependencies": {
"@ngrx/signals": "18.0.0-rc.2"
"@ngrx/signals": "18.0.0"
},
"dependencies": {
"tslib": "^2.3.0"
Expand Down
3 changes: 2 additions & 1 deletion libs/ngrx-toolkit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './lib/with-call-state';
export * from './lib/with-undo-redo';
export * from './lib/with-data-service';
export { withStorageSync, SyncConfig } from './lib/with-storage-sync';
export * from './lib/with-pagination';

export * from './lib/redux-connector';
export * from './lib/redux-connector/rxjs-interop';
export * from './lib/with-pagination';
100 changes: 58 additions & 42 deletions libs/ngrx-toolkit/src/lib/redux-connector/model.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
import { EnvironmentProviders, Signal, Type } from "@angular/core";
import { DeepSignal } from "@ngrx/signals/src/deep-signal";
import { SignalStoreFeatureResult } from "@ngrx/signals/src/signal-store-models";
import { StateSignal } from "@ngrx/signals/src/state-signal";
import { Action, ActionCreator, ActionType, Prettify } from "@ngrx/store/src/models";
import { Observable, Unsubscribable } from "rxjs";
import { EnvironmentProviders, Signal, Type } from '@angular/core';
import { DeepSignal } from '@ngrx/signals/src/deep-signal';
import {
SignalStoreFeatureResult,
StateSignals,
} from '@ngrx/signals/src/signal-store-models';
import {
Action,
ActionCreator,
ActionType,
Prettify,
} from '@ngrx/store/src/models';
import { Observable, Unsubscribable } from 'rxjs';


export type IncludePropType<T, V, WithNevers =
{ [K in keyof T]: Exclude<T[K], undefined> extends V
? T[K] extends Record<string, unknown>
? IncludePropType<T[K], V>
: T[K]
: never
}> = Prettify<
Pick<
WithNevers,
{ [K in keyof WithNevers]: WithNevers[K] extends never
export type IncludePropType<
T,
V,
WithNevers = {
[K in keyof T]: Exclude<T[K], undefined> extends V
? T[K] extends Record<string, unknown>
? IncludePropType<T[K], V>
: T[K]
: never;
}
> = Prettify<
Pick<
WithNevers,
{
[K in keyof WithNevers]: WithNevers[K] extends never
? never
: K extends string
? K
: never
}[keyof WithNevers]
>
>;
? K
: never;
}[keyof WithNevers]
>
>;

export type Store = Type<Record<string, unknown> & StateSignal<SignalStoreFeatureResult['state']>>;
export type Store = Type<
Record<string, unknown> & StateSignals<SignalStoreFeatureResult['state']>
>;

export type CreateReduxState<
StoreName extends string,
STORE extends Store
> = {
[K in StoreName as `provide${Capitalize<K>}Store`]: (connectReduxDevtools?: boolean) => EnvironmentProviders
export type CreateReduxState<StoreName extends string, STORE extends Store> = {
[K in StoreName as `provide${Capitalize<K>}Store`]: (
connectReduxDevtools?: boolean
) => EnvironmentProviders;
} & {
[K in StoreName as `inject${Capitalize<K>}Store`]: () => InjectableReduxSlice<STORE>
[K in StoreName as `inject${Capitalize<K>}Store`]: () => InjectableReduxSlice<STORE>;
};

export type Selectors<STORE extends Store> = IncludePropType<InstanceType<STORE>, Signal<unknown> | DeepSignal<unknown>>;
export type Dispatch = { dispatch: (input: Action | Observable<Action> | Signal<Action>) => Unsubscribable };
export type InjectableReduxSlice<STORE extends Store> = Selectors<STORE> & Dispatch;
export type Selectors<STORE extends Store> = IncludePropType<
InstanceType<STORE>,
Signal<unknown> | DeepSignal<unknown>
>;
export type Dispatch = {
dispatch: (
input: Action | Observable<Action> | Signal<Action>
) => Unsubscribable;
};
export type InjectableReduxSlice<STORE extends Store> = Selectors<STORE> &
Dispatch;

export type ExtractActionTypes<Creators extends readonly ActionCreator[]> = {
[Key in keyof Creators]: Creators[Key] extends ActionCreator<infer T>
Expand All @@ -51,17 +71,13 @@ export interface ActionMethod<T, V extends Action = Action> {

export interface StoreMethod<
Creators extends readonly ActionCreator[],
ResultState = unknown,
ResultState = unknown
> {
(
action: ActionType<Creators[number]>
): ResultState;
(action: ActionType<Creators[number]>): ResultState;
}

export interface MapperTypes<
Creators extends readonly ActionCreator[]
> {
types: ExtractActionTypes<Creators>,
storeMethod: StoreMethod<Creators>,
resultMethod?: (...args: unknown[]) => unknown
export interface MapperTypes<Creators extends readonly ActionCreator[]> {
types: ExtractActionTypes<Creators>;
storeMethod: StoreMethod<Creators>;
resultMethod?: (...args: unknown[]) => unknown;
}
1 change: 0 additions & 1 deletion libs/ngrx-toolkit/src/lib/shared/empty.ts

This file was deleted.

12 changes: 0 additions & 12 deletions libs/ngrx-toolkit/src/lib/shared/signal-store-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@
import { Signal } from '@angular/core';
import { EntityId } from '@ngrx/signals/entities';

export type SignalStoreFeatureResult = {
state: object;
computed: Record<string, Signal<unknown>>;
methods: Record<string, Function>;
};

export type EmptyFeatureResult = {
state: {};
computed: {};
methods: {};
};

// withEntites models
export type EntityState<Entity> = {
entityMap: Record<EntityId, Entity>;
Expand Down
9 changes: 6 additions & 3 deletions libs/ngrx-toolkit/src/lib/with-call-state.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { patchState, signalStore } from '@ngrx/signals';
import { setLoaded, setLoading, withCallState } from 'ngrx-toolkit';
import { setLoaded, setLoading, withCallState } from './with-call-state';

describe('withCallState', () => {
it('should use and update a callState', () => {
const DataStore = signalStore(withCallState());
const DataStore = signalStore({ protectedState: false }, withCallState());
const dataStore = new DataStore();

patchState(dataStore, setLoading());
Expand All @@ -13,7 +13,10 @@ describe('withCallState', () => {
});

it('should use the callState for a collection', () => {
const DataStore = signalStore(withCallState({ collection: 'entities' }));
const DataStore = signalStore(
{ protectedState: false },
withCallState({ collection: 'entities' })
);
const dataStore = new DataStore();

patchState(dataStore, setLoaded('entities'));
Expand Down
14 changes: 6 additions & 8 deletions libs/ngrx-toolkit/src/lib/with-call-state.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Signal, computed } from '@angular/core';
import {
EmptyFeatureResult,
SignalStoreFeature,
signalStoreFeature,
withComputed,
withState,
} from '@ngrx/signals';
import { Empty } from './shared/empty';

export type CallState = 'init' | 'loading' | 'loaded' | { error: string };

Expand Down Expand Up @@ -44,19 +44,17 @@ export function getCallStateKeys(config?: { collection?: string }) {
export function withCallState<Collection extends string>(config: {
collection: Collection;
}): SignalStoreFeature<
{ state: Empty; methods: Empty; computed: Empty },
{
EmptyFeatureResult,
EmptyFeatureResult & {
state: NamedCallStateSlice<Collection>;
computed: NamedCallStateSignals<Collection>;
methods: Empty;
}
>;
export function withCallState(): SignalStoreFeature<
{ state: Empty; methods: Empty; computed: Empty },
{
EmptyFeatureResult,
EmptyFeatureResult & {
state: CallStateSlice;
computed: CallStateSignals;
methods: Empty;
}
>;
export function withCallState<Collection extends string>(config?: {
Expand Down Expand Up @@ -106,7 +104,7 @@ export function setError<Prop extends string | undefined = undefined>(
error: unknown,
prop?: Prop
): SetCallState<Prop> {
let errorMessage = '';
let errorMessage: string;

if (!error) {
errorMessage = '';
Expand Down
Loading

0 comments on commit 3d61dd2

Please sign in to comment.