diff --git a/src/component-store/immer-component-store.ts b/src/component-store/immer-component-store.ts new file mode 100644 index 0000000..bc791ab --- /dev/null +++ b/src/component-store/immer-component-store.ts @@ -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 { + updater< + ProvidedType = void, + OriginType = ProvidedType, + ValueType = OriginType, + ReturnType = OriginType extends void + ? () => void + : (observableOrValue: ValueType | Observable) => 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)); + } +} diff --git a/src/component-store/index.ts b/src/component-store/index.ts index bc791ab..db38693 100644 --- a/src/component-store/index.ts +++ b/src/component-store/index.ts @@ -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 { - updater< - ProvidedType = void, - OriginType = ProvidedType, - ValueType = OriginType, - ReturnType = OriginType extends void - ? () => void - : (observableOrValue: ValueType | Observable) => 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'; \ No newline at end of file diff --git a/src/component-store/provide-immer-component-store.ts b/src/component-store/provide-immer-component-store.ts new file mode 100644 index 0000000..9a601e4 --- /dev/null +++ b/src/component-store/provide-immer-component-store.ts @@ -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(componentStoreClass: Type>): Provider[] { + return provideComponentStore(componentStoreClass as Type>); +} \ No newline at end of file diff --git a/src/component-store/tests/provide-immer-component-store.test.ts b/src/component-store/tests/provide-immer-component-store.test.ts new file mode 100644 index 0000000..c6d7ed5 --- /dev/null +++ b/src/component-store/tests/provide-immer-component-store.test.ts @@ -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();