type Ctx = import("../Ctx").Ctx; type VoidCtx= import("../Ctx").VoidCtx; import { typeGuard } from "../../tools/typeSafety"; export type Operator = Operator.fλ | ((data: U) => boolean) | //Filter (U extends T ? (data: T) => data is U : never) //Type guard ; export namespace Operator { export type fλ = fλ.Stateless | fλ.Stateful ; export namespace fλ { export type Stateless = (data: T, prev?: undefined, isPost?: true) => Result; export type Stateful = [ (data: T, prev: U, isPost?: true) => Result, U //Seed ]; export namespace Stateful { export function match(op: Operator): op is Stateful { return typeof op !== "function"; } } export type Result = Result.Matched | Result.NotMatched; export namespace Result { export function match(result: any): result is Result { return Matched.match(result) || NotMatched.match(result); } export function getDetachArg(result: Result): boolean | [Ctx, undefined | Error, any] { const detach = Matched.match(result) ? result[1] : result; if (Detach.FromEvt.match(detach)) { return true; } if (Detach.WithCtxArg.match(detach)) { return [ detach.DETACH, (detach as Extract, { err: any }>).err, (detach as Extract, { res: any }>).res ]; } return false; } export type NotMatched = Detach | null; export namespace NotMatched { export function match(result: any): result is NotMatched { return ( result === null || Detach.match(result) ); } } export type Matched = Matched.NoDetachArg | Matched.WithDetachArg; export namespace Matched { export type NoDetachArg = readonly [U]; export type WithDetachArg = readonly [U, Detach | null]; export function match( result: any, ): result is Matched { return ( typeGuard.dry>(result) && result instanceof Object && ( result.length === 1 || ( result.length === 2 && ( result[1] === null || Detach.match(result[1]) ) ) ) ); } } export type Detach = Detach.FromEvt | Detach.WithCtxArg; export namespace Detach { export type FromEvt = "DETACH"; export namespace FromEvt { export function match(detach: any): detach is FromEvt { return detach === "DETACH"; } } export type WithCtxArg = { DETACH: Ctx; err: Error; } | { DETACH: Ctx; res: T; } | { DETACH: VoidCtx; err: Error; } | { DETACH: VoidCtx; } ; export namespace WithCtxArg { export function match(detach: any): detach is WithCtxArg { return ( typeGuard.dry(detach) && detach instanceof Object && detach.DETACH instanceof Object ); } } export function match(detach: any): detach is Detach { return FromEvt.match(detach) || WithCtxArg.match(detach); } } } } export type Stateless = fλ.Stateless | ((data: U) => boolean) | (U extends T ? (data: T) => data is U : never) ; }