UNPKG

@nitrogenbuilder/client-core

Version:

Nitrogen Builder Core Client

86 lines (75 loc) 2.18 kB
export type BatchRequest = { key: string; endpoint: string; params: Record<string, string>; }; export type BatchResult = { data: any; total: number; totalPages: number; }; export type BatchTransport = ( requests: BatchRequest[] ) => Promise<Record<string, BatchResult>>; export class BatchFetchContext { private requests: BatchRequest[] = []; private pendingResolvers = new Map< string, Array<{ resolve: (value: BatchResult) => void; reject: (reason?: any) => void }> >(); private flushed = false; constructor(private transport: BatchTransport) {} /** * Called by getData functions to register a request. * Returns a promise that resolves after flush() completes. */ fetch( endpoint: string, params: Record<string, string> = {} ): Promise<BatchResult> { const key = `${endpoint}?${new URLSearchParams(params).toString()}`; if (this.flushed) { // Late registration — batch already sent, fall back to individual request return this.transport([{ key, endpoint, params }]).then( (r) => r[key] ); } // Deduplicate: same endpoint+params shares the same promise resolution if (!this.pendingResolvers.has(key)) { this.requests.push({ key, endpoint, params }); this.pendingResolvers.set(key, []); } return new Promise((resolve, reject) => { this.pendingResolvers.get(key)!.push({ resolve, reject }); }); } /** * Called after all getData functions have registered their requests. * Sends a single batch request via the transport and resolves all pending promises. */ async flush(): Promise<void> { this.flushed = true; if (this.requests.length === 0) return; try { const results = await this.transport(this.requests); for (const [key, resolvers] of this.pendingResolvers) { const result = results[key]; if (result) { for (const { resolve } of resolvers) { resolve(result); } } else { for (const { reject } of resolvers) { reject(new Error(`No batch result for key: ${key}`)); } } } } catch (error) { for (const [, resolvers] of this.pendingResolvers) { for (const { reject } of resolvers) { reject(error); } } } } }