UNPKG

@redpc/core

Version:

Remoted Procedure Call (RedPC) - A javascript RPC library written with TypeScript

94 lines (65 loc) 2.17 kB
import { RpcTimeout } from "errors"; import { IMessage } from "./IMessage"; export type AsyncMessageTrackerTimeoutCallback = (entry: AsyncMessageTrackerEntry) => void | Promise<void>; export interface AsyncMessageTrackerConfig { forcedTimeoutInMilliseconds?: number; } export interface AsyncMessageTrackerEntry { id: string; message: IMessage; timeoutInMilliseconds?: number; } export interface AsyncMessageTrackerWaitResult { id: string; message: IMessage; } export class AsyncMessageTracker { private entries: Record<string, { entry: AsyncMessageTrackerEntry, resolve: (value: AsyncMessageTrackerWaitResult) => void, reject: (reason: any) => void }>; constructor( private config?: AsyncMessageTrackerConfig ) { this.entries = {}; } public waitForResponseOrTimeout(entry: AsyncMessageTrackerEntry): Promise<AsyncMessageTrackerWaitResult> { return new Promise<AsyncMessageTrackerWaitResult>((resolve, reject) => { const timeout = entry.timeoutInMilliseconds ?? this.config?.forcedTimeoutInMilliseconds; this.entries[entry.id] = { entry, resolve, reject }; if (timeout) { setTimeout(() => { delete this.entries[entry.id]; reject(new RpcTimeout('Request was timed out.')); }, timeout); } }); } public respond(id: string, message: IMessage): boolean { const entry = this.entries[id]; if (!!entry) { entry.resolve({ id, message }); delete this.entries[id]; return true; } return false; } public reject(id: string, reason: any): boolean { const entry = this.entries[id]; if (!!entry) { entry.reject(reason); delete this.entries[id]; return true; } return false; } }