@nitrogenbuilder/client-core
Version:
Nitrogen Builder Core Client
61 lines (60 loc) • 2.14 kB
JavaScript
export class BatchFetchContext {
transport;
requests = [];
pendingResolvers = new Map();
flushed = false;
constructor(transport) {
this.transport = transport;
}
/**
* Called by getData functions to register a request.
* Returns a promise that resolves after flush() completes.
*/
fetch(endpoint, params = {}) {
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() {
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);
}
}
}
}
}