Skip to content

Commit

Permalink
feat: add tapRoutine
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaa2 committed Sep 9, 2022
1 parent 87cef65 commit 994f3f4
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export {
subscribeRoutine,
routine,
collectRoutines,
tapRoutine,
} from './routines';

export { derivedStream } from './derivedStream';
Expand Down
26 changes: 24 additions & 2 deletions src/routines.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import { ActionWithPayload } from './types/Action';
import {
Routine,
collectRoutines,
ensureArray,
routine,
subscribeRoutine,
tapRoutine,
} from './routines';
import { mockAction, stubRethrowErrorGlobally } from './internal/testing/utils';
import { extractPayload } from './operators/operators';
import { actionCreator } from './actionCreator';

const test = stubRethrowErrorGlobally(untypedTest);

Expand All @@ -19,11 +22,13 @@ const actions = {
b: mockAction('bravo', undefined, { letter: 'B' }),
c: mockAction('charlie', undefined, { letter: 'C' }),
e: mockAction('error'),
f: mockAction('[Mock] action', undefined, { letter: 'F' }),
};
const letters = {
A: 'A',
B: 'B',
C: 'C',
F: 'F',
};
const lengths = {
...letters,
Expand All @@ -40,6 +45,7 @@ const actionMarbles2 = ' -a----e----a---';
const errorMarbles = ' ------e';
const errorSub1 = ' ^-----!';
const errorSub2 = ' ------^--------';
const singleActionMarble = ' -f---f';

const errorRoutine: Routine<string> = map((a) => {
if (a.type === 'error') throw 'error';
Expand Down Expand Up @@ -72,11 +78,9 @@ test(
marbles((m) => {
const action$ = m.hot(actionMarbles1, actions);
const expected$ = m.hot(combinedMarbles, lengths);

const actual$ = action$.pipe(
collectRoutines(lettersRoutine, lengthRoutine)
);

m.expect(actual$).toBeObservable(expected$);
})
);
Expand Down Expand Up @@ -113,3 +117,21 @@ test(
m.expect(error$).toBeObservable(errorMarbles, errors);
})
);

test(
'tapRoutine register a routine',
marbles((m, t) => {
const action$ = m.hot(singleActionMarble, actions);
const action = actionCreator<{ letter: string }>('[Mock] action');
t.plan(2);
const routineToSubscribe = tapRoutine(action, (payload) =>
t.is(payload.letter, 'F')
);
subscribeRoutine(action$, routineToSubscribe);
})
);

test('ensureArray return an Array', (t) => {
t.assert(Array.isArray(ensureArray('a')));
t.assert(Array.isArray(ensureArray(['a'])));
});
35 changes: 34 additions & 1 deletion src/routines.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { OperatorFunction, Subject, pipe } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { catchError, tap } from 'rxjs/operators';
import { ActionStream } from './types/helpers';
import { Routine, RoutineFunc } from './internal/routineFunc';
import { defaultErrorSubject } from './internal/defaultErrorSubject';
import { mergeOperators } from './operators/mergeOperators';
import {
UnknownActionCreator,
UnknownActionCreatorWithPayload,
} from './internal';
import { extractPayload, ofType } from './operators';

export { Routine } from './internal/routineFunc';

Expand Down Expand Up @@ -70,3 +75,31 @@ export const subscribeRoutine = (
})
)
.subscribe();

type PlainOrArray<T> = T | T[];
export const ensureArray = <T>(a: PlainOrArray<T>): T[] =>
Array.isArray(a) ? a : [a];

type TapRoutine = {
<Payload>(
actionCreator: PlainOrArray<UnknownActionCreatorWithPayload<Payload>>,
body: (payload: Payload) => void
): Routine<void>;

(
actionCreator: PlainOrArray<UnknownActionCreator>,
body: () => void
): Routine<void>;
};

export const tapRoutine: TapRoutine = <Payload>(
actionCreator: PlainOrArray<
UnknownActionCreatorWithPayload<Payload> | UnknownActionCreator
>,
body: (payload?: Payload) => void
) =>
routine(
ofType(...(ensureArray(actionCreator) as any)),
extractPayload<Payload>(),
tap(body)
);
2 changes: 1 addition & 1 deletion src/types/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export type ActionWithPayload<Payload> = ActionWithoutPayload & {
*
* @template `Payload` - The payload type to dispatch on
*/
export type Action<Payload = VoidPayload> = Payload extends VoidPayload
export type Action<Payload = VoidPayload> = [Payload] extends [VoidPayload]
? ActionWithoutPayload
: ActionWithPayload<Payload>;
5 changes: 2 additions & 3 deletions src/types/Action.tspec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ type Action_expands_union_types2b = AssertTrue<
IsExact<Action<Enum>, ActionWithPayload<Enum>>
>;

type Action_Expands_union_types3a = AssertTrue<
type Action_Expands_union_types3a = AssertFalse<
IsExact<Action<Foo | Bar>, ActionWithPayload<Foo> | ActionWithPayload<Bar>>
>;
type Action_Expands_union_types3b = AssertFalse<
// This is how we would like it to work
type Action_Expands_union_types3b = AssertTrue<
IsExact<Action<Foo | Bar>, ActionWithPayload<Foo | Bar>>
>;

Expand Down

0 comments on commit 994f3f4

Please sign in to comment.