Skip to content

Commit

Permalink
feat: add provideImmerComponentStore() (#18)
Browse files Browse the repository at this point in the history
Closes #18
  • Loading branch information
yevit authored Jul 31, 2023
1 parent 34e79dc commit f55e543
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 29 deletions.
29 changes: 29 additions & 0 deletions src/component-store/immer-component-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { ComponentStore } from '@ngrx/component-store';

import { immerReducer } from 'ngrx-immer/shared';

/**
* Immer wrapper around `ImmerComponentStore` to mutate state
* with `updater` and `setState`
*/
@Injectable()
export class ImmerComponentStore<
State extends object
> extends ComponentStore<State> {
updater<
ProvidedType = void,
OriginType = ProvidedType,
ValueType = OriginType,
ReturnType = OriginType extends void
? () => void
: (observableOrValue: ValueType | Observable<ValueType>) => Subscription
>(updaterFn: (state: State, value: OriginType) => void | State): ReturnType {
return super.updater(immerReducer(updaterFn));
}

setState(stateOrUpdaterFn: State | ((state: State) => void | State)): void {
super.setState(stateOrUpdaterFn as State | ((state: State) => State));
}
}
31 changes: 2 additions & 29 deletions src/component-store/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,2 @@
import { Injectable } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { ComponentStore } from '@ngrx/component-store';

import { immerReducer } from 'ngrx-immer/shared';

/**
* Immer wrapper around `ImmerComponentStore` to mutate state
* with `updater` and `setState`
*/
@Injectable()
export class ImmerComponentStore<
State extends object
> extends ComponentStore<State> {
updater<
ProvidedType = void,
OriginType = ProvidedType,
ValueType = OriginType,
ReturnType = OriginType extends void
? () => void
: (observableOrValue: ValueType | Observable<ValueType>) => Subscription
>(updaterFn: (state: State, value: OriginType) => void | State): ReturnType {
return super.updater(immerReducer(updaterFn));
}

setState(stateOrUpdaterFn: State | ((state: State) => void | State)): void {
super.setState(stateOrUpdaterFn as State | ((state: State) => State));
}
}
export { ImmerComponentStore } from './immer-component-store';
export { provideImmerComponentStore } from './provide-immer-component-store';
12 changes: 12 additions & 0 deletions src/component-store/provide-immer-component-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ComponentStore, provideComponentStore } from '@ngrx/component-store';
import { Provider, Type } from '@angular/core';
import { ImmerComponentStore } from '.';

/**
* @description
* Immer wrapper around `provideComponentStore()` in `@ngrx/component-store`.
* @returns the ImmerComponentStore class registered as a provider
*/
export function provideImmerComponentStore<T extends object>(componentStoreClass: Type<ImmerComponentStore<T>>): Provider[] {
return provideComponentStore(componentStoreClass as Type<ComponentStore<T>>);
}
22 changes: 22 additions & 0 deletions src/component-store/tests/provide-immer-component-store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import '@angular/compiler';
import { test } from 'uvu';
import * as assert from 'uvu/assert';

import { ImmerComponentStore, provideImmerComponentStore } from 'ngrx-immer/component-store';
import { provideComponentStore } from '@ngrx/component-store';


test('provideImmerComponentStore() should equal provideComponentStore()', () => {
const ngrxProviders = provideComponentStore(DummyImmerComponentStore as any);

const ngrxImmerProviders = provideImmerComponentStore(DummyImmerComponentStore);

// assert
assert.instance(ngrxImmerProviders, Array);
assert.is.not(ngrxImmerProviders.length, 0);
assert.equal(ngrxImmerProviders.toString(), ngrxProviders.toString());
});

class DummyImmerComponentStore extends ImmerComponentStore<{}> { }

test.run();

0 comments on commit f55e543

Please sign in to comment.