diff --git a/libs/common/src/index.ts b/libs/common/src/index.ts index 7adfc48d..4170836d 100644 --- a/libs/common/src/index.ts +++ b/libs/common/src/index.ts @@ -17,6 +17,7 @@ export { EffectConfig, EFFECT_METADATA_KEY, } from './lib/create-rx-effect'; +export { createRxEffectForStore } from './lib/rx-effect'; export { LoggerExtension } from './lib/extensions/logger/logger.extension'; export { UndoExtension } from './lib/extensions/undo/undo-extension'; export { undo } from './lib/extensions/undo/undo'; diff --git a/libs/common/src/lib/rx-effect.ts b/libs/common/src/lib/rx-effect.ts new file mode 100644 index 00000000..8208631a --- /dev/null +++ b/libs/common/src/lib/rx-effect.ts @@ -0,0 +1,30 @@ +import { Observable } from 'rxjs'; +import { + EFFECT_METADATA_KEY, + EffectConfig, + hasEffectMetaData, + HasEffectMetadata, +} from './create-rx-effect'; +import { Action } from './models'; +import { defaultEffectsErrorHandler } from './default-effects-error-handler'; + +export function createRxEffectForStore(dispatchFn: (action: Action) => void) { + function rxEffect(effect$: Observable & HasEffectMetadata): void; + function rxEffect(effect$: Observable): void; + function rxEffect(effect$: any): void { + const effectWithErrorHandler$: Observable = + defaultEffectsErrorHandler(effect$); + effectWithErrorHandler$.subscribe((action) => { + let shouldDispatch = true; + if (hasEffectMetaData(effect$)) { + const metaData: EffectConfig = effect$[EFFECT_METADATA_KEY]; + shouldDispatch = !!metaData.dispatch; + } + if (shouldDispatch) { + dispatchFn(action); + } + }); + } + + return rxEffect; +} diff --git a/libs/mini-rx-store/src/lib/store-core.ts b/libs/mini-rx-store/src/lib/store-core.ts index e25384f5..a9c8a20b 100644 --- a/libs/mini-rx-store/src/lib/store-core.ts +++ b/libs/mini-rx-store/src/lib/store-core.ts @@ -1,17 +1,12 @@ -import { Observable, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { createState } from './state'; import { - Action, AppState, createActionsOnQueue, createMiniRxActionType, createReducerManager, - defaultEffectsErrorHandler, - EFFECT_METADATA_KEY, - EffectConfig, + createRxEffectForStore, ExtensionId, - HasEffectMetadata, - hasEffectMetaData, MetaReducer, miniRxError, OperationType, @@ -35,26 +30,26 @@ function getReducerManager(): ReducerManager { } // ACTIONS -export const { dispatch, actions$ } = createActionsOnQueue(); +export const { actions$, dispatch } = createActionsOnQueue(); // APP STATE export const appState = createState(); // Wire up the Redux Store: subscribe to the actions stream, calc next state for every action // Called by `configureStore` and `addReducer` -function initStore() { +function initStore(): void { if (actionSubscription) { return; } - // Listen to the Actions stream and update state accordingly + // Listen to the Actions stream and update state actionSubscription = actions$.subscribe((action) => { const nextState: AppState = getReducerManager().reducer(appState.get() ?? {}, action); appState.set(nextState); }); } -export function configureStore(config: StoreConfig = {}) { +export function configureStore(config: StoreConfig = {}): void { initStore(); if (getReducerManager().hasFeatureReducers()) { @@ -100,29 +95,14 @@ export function addFeature( dispatch({ type: createMiniRxActionType(OperationType.INIT, featureKey) }); } -export function removeFeature(featureKey: string) { +export function removeFeature(featureKey: string): void { getReducerManager().removeFeatureReducer(featureKey); dispatch({ type: createMiniRxActionType(OperationType.DESTROY, featureKey) }); } -export function effect(effect$: Observable & HasEffectMetadata): void; -export function effect(effect$: Observable): void; -export function effect(effect$: any): void { - const effectWithErrorHandler$: Observable = defaultEffectsErrorHandler(effect$); - effectWithErrorHandler$.subscribe((action) => { - let shouldDispatch = true; - if (hasEffectMetaData(effect$)) { - const metaData: EffectConfig = effect$[EFFECT_METADATA_KEY]; - shouldDispatch = !!metaData.dispatch; - } - - if (shouldDispatch) { - dispatch(action); - } - }); -} +export const effect = createRxEffectForStore(dispatch); -function addExtension(extension: StoreExtension) { +function addExtension(extension: StoreExtension): void { const metaReducer: MetaReducer | void = extension.init(); if (metaReducer) { diff --git a/libs/signal-store/src/lib/store-core.ts b/libs/signal-store/src/lib/store-core.ts index f86258d2..2d3802ab 100644 --- a/libs/signal-store/src/lib/store-core.ts +++ b/libs/signal-store/src/lib/store-core.ts @@ -1,17 +1,12 @@ import { signal, WritableSignal } from '@angular/core'; -import { Observable, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { - Action, AppState, createActionsOnQueue, createMiniRxActionType, createReducerManager, - defaultEffectsErrorHandler, - EFFECT_METADATA_KEY, - EffectConfig, + createRxEffectForStore, ExtensionId, - HasEffectMetadata, - hasEffectMetaData, MetaReducer, OperationType, Reducer, @@ -61,12 +56,15 @@ export function configureStore(config: StoreConfig = {}): void { if (config.metaReducers) { getReducerManager().addMetaReducers(...config.metaReducers); } + if (config.extensions) { sortExtensions(config.extensions).forEach((extension) => addExtension(extension)); } + if (config.reducers) { getReducerManager().setFeatureReducers(config.reducers); } + if (config.initialState) { appState.set(config.initialState); } @@ -97,21 +95,7 @@ export function removeFeature(featureKey: string): void { dispatch({ type: createMiniRxActionType(OperationType.DESTROY, featureKey) }); } -export function rxEffect(effect$: Observable & HasEffectMetadata): void; -export function rxEffect(effect$: Observable): void; -export function rxEffect(effect$: any): void { - const effectWithErrorHandler$: Observable = defaultEffectsErrorHandler(effect$); - effectWithErrorHandler$.subscribe((action) => { - let shouldDispatch = true; - if (hasEffectMetaData(effect$)) { - const metaData: EffectConfig = effect$[EFFECT_METADATA_KEY]; - shouldDispatch = !!metaData.dispatch; - } - if (shouldDispatch) { - dispatch(action); - } - }); -} +export const rxEffect = createRxEffectForStore(dispatch); function addExtension(extension: StoreExtension): void { const metaReducer: MetaReducer | void = extension.init();