import { Evt } from "../Evt"; import { id, assert, typeGuard } from "../../tools/typeSafety"; import { EventTargetLike } from "../types/EventTargetLike"; import { mergeImpl } from "./merge"; type Ctx = import("../Ctx").Ctx; type OneOrMany = T | ArrayLike; function fromImpl( ctx: Ctx | undefined, target: OneOrMany>, eventName?: string, options?: EventTargetLike.HasEventTargetAddRemove.Options ): Evt { if ("length" in target) { return mergeImpl>( ctx, Array.from(target).map( target => fromImpl(ctx, target, eventName, options) ) ); } type ProxyMethod = ( listener: (data: T) => void, eventName: string, options?: EventTargetLike.HasEventTargetAddRemove.Options ) => void; let proxy: { on: ProxyMethod; off: ProxyMethod; }; if (EventTargetLike.NodeStyleEventEmitter.match(target)) { proxy = { "on": (listener, eventName) => target.addListener(eventName, listener), "off": (listener, eventName) => target.removeListener(eventName, listener) }; } else if (EventTargetLike.JQueryStyleEventEmitter.match(target)) { proxy = { "on": (listener, eventName) => target.on(eventName, listener), "off": (listener, eventName) => target.off(eventName, listener) }; } else if (EventTargetLike.HasEventTargetAddRemove.match(target)) { proxy = { "on": (listener, eventName, options) => target.addEventListener(eventName, listener, options), "off": (listener, eventName, options) => target.removeEventListener(eventName, listener, options) }; } else if (EventTargetLike.RxJSSubject.match(target)) { let subscription: EventTargetLike.RxJSSubject.Subscription; proxy = { "on": listener => subscription = target.subscribe(data => listener(data)), "off": () => subscription.unsubscribe() }; } else { id(target); assert(false); } const evt = new Evt(); const listener = (data: T) => evt.post(data); ctx?.getEvtDone().attachOnce( () => proxy.off( listener, eventName!, options ) ); proxy.on(listener, eventName!, options); return evt; } export function from( ctx: Ctx, target: OneOrMany< EventTargetLike.NodeStyleEventEmitter | EventTargetLike.JQueryStyleEventEmitter >, eventName: string ): Evt; export function from( ctx: Ctx, target: OneOrMany< EventTargetLike.HasEventTargetAddRemove >, eventName: string, options?: EventTargetLike.HasEventTargetAddRemove.Options ): Evt; export function from( ctx: Ctx, target: OneOrMany> ): Evt; export function from( target: OneOrMany< EventTargetLike.NodeStyleEventEmitter | EventTargetLike.JQueryStyleEventEmitter >, eventName: string ): Evt; export function from( target: OneOrMany< EventTargetLike.HasEventTargetAddRemove >, eventName: string, options?: EventTargetLike.HasEventTargetAddRemove.Options ): Evt; export function from( target: OneOrMany> ): Evt; export function from( ctxOrTarget: Ctx | OneOrMany>, targetOrEventName?: OneOrMany> | string, eventNameOrOptions?: string | EventTargetLike.HasEventTargetAddRemove.Options, options?: EventTargetLike.HasEventTargetAddRemove.Options ): Evt { if ("getEvtDone" in ctxOrTarget) { assert( typeGuard.dry>>(targetOrEventName) && typeGuard.dry(eventNameOrOptions) && typeGuard.dry(options) ); return fromImpl( ctxOrTarget, targetOrEventName, eventNameOrOptions, options ); } else { assert( typeGuard.dry(targetOrEventName) && typeGuard.dry(eventNameOrOptions) ); return fromImpl( undefined, ctxOrTarget, targetOrEventName, eventNameOrOptions ); } }