Skip to content

Instantly share code, notes, and snippets.

@zakhenry
Created December 14, 2017 20:52
Show Gist options
  • Save zakhenry/5f5d8ef51c6453dc7025834c9bf708dd to your computer and use it in GitHub Desktop.
Save zakhenry/5f5d8ef51c6453dc7025834c9bf708dd to your computer and use it in GitHub Desktop.
import { EntityAdapter, EntityState } from '@ngrx/entity';
import { ActionReducer } from '@ngrx/store';
import { CommandReducer, ReducerCommand } from 'ngrx-command-reducer';
import { BaseAction, StaticAction } from './base.actions';
type PayloadActionFunction<S, P> = (p: P, s: S) => S;
type PayloadlessActionFunction<S> = (s: S) => S;
export type EntityFunction<S, P> = PayloadActionFunction<S, P> | PayloadlessActionFunction<S>;
export class EntityCommandReducer<Entity, State extends EntityState<Entity>, Action extends BaseAction> {
private commandReducer: CommandReducer<State, Action>;
constructor(initialState: State, private adapter: EntityAdapter<Entity>) {
this.commandReducer = new CommandReducer(initialState, a => a.payload);
}
public mapAction<Payload>(action: StaticAction<Payload, Action>,
adapterFunctionGetter: (adapter: EntityAdapter<Entity>) => EntityFunction<State, Payload>): this {
const adapterFunction = adapterFunctionGetter(this.adapter);
return this.add(action, (state: State, payload: Payload) => {
if (this.isPayloadFunction(adapterFunction)) {
return adapterFunction(payload, state);
}
return adapterFunction(state);
});
}
public add<Payload>(action: StaticAction<Payload, Action>, handler: ReducerCommand<State, Payload>): this {
this.commandReducer.add(action, handler);
return this;
}
public reducer(): ActionReducer<State> {
return this.commandReducer.reducer();
}
private isPayloadFunction<S, P>(fn: EntityFunction<S, P>): fn is PayloadActionFunction<S, P> {
return fn.length === 2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment