import { Message, MessageExecutorType, MessageImpl } from "base/Message"; import { SilenceUse } from "base/Silence"; import { ConstructorType } from "types/ConstructorType"; import { MessageType } from "types/MessageType"; import { MessageSourceType } from "types/SourceType"; /** * Base message source object, the message what can * accept new values * * @url https://silentium.pw/article/source/view */ export function Source( messageExecutor: MessageExecutorType, sourceExecutor: ConstructorType<[T]>, ) { return new SourceImpl(messageExecutor, sourceExecutor); } export class SourceImpl implements MessageSourceType { private message: MessageImpl; private silenceUse: ReturnType; public constructor( messageExecutor: MessageExecutorType, private sourceExecutor: ConstructorType<[T]>, ) { this.message = Message(messageExecutor); this.silenceUse = SilenceUse(); } public use(value: T): this { if (!this.message.destroyed()) { const sourceSilenceUse = (v: unknown) => { this.sourceExecutor(v as T); }; this.silenceUse.use(value, sourceSilenceUse); } return this; } public then(resolved: ConstructorType<[T]>): this { this.message.then(resolved); return this; } public catch(rejected: ConstructorType<[unknown]>): this { this.message.catch(rejected); return this; } public destroy() { this.message.destroy(); return this; } public chain(m: MessageType) { return m.then(this.use.bind(this)); } }