ts-action-operators
Version:
TypeScript action operators for NgRx and redux-observable
48 lines (47 loc) • 1.93 kB
JavaScript
import { defer, merge, Subject } from "rxjs";
import { concatMap, dematerialize, filter, finalize, map, materialize, } from "rxjs/operators";
export function act(projectOrConfig, optionalError) {
const config = typeof projectOrConfig === "function"
? {
error: optionalError,
project: projectOrConfig,
}
: projectOrConfig;
const { complete, error, operator = concatMap, project, unsubscribe, } = config;
return (source) => defer(() => {
const subject = new Subject();
return merge(source.pipe(operator((action, index) => defer(() => {
let completed = false;
let errored = false;
let projectedCount = 0;
return project(action, index).pipe(materialize(), map((notification) => {
switch (notification.kind) {
case "E":
errored = true;
return {
kind: "N",
value: error(notification.error, action),
};
case "C":
completed = true;
return complete
? {
kind: "N",
value: complete(projectedCount, action),
}
: undefined;
default:
++projectedCount;
return notification;
}
}), filter(isDefined), dematerialize(), finalize(() => {
if (!completed && !errored && unsubscribe) {
subject.next(unsubscribe(projectedCount, action));
}
}));
}))), subject);
});
}
function isDefined(value) {
return value !== undefined;
}