@push.rocks/webrequest
Version:
Modern, fetch-compatible web request library with intelligent HTTP caching, retry strategies, and fault tolerance.
85 lines • 4.99 kB
JavaScript
/**
* Request deduplication system
* Prevents multiple simultaneous identical requests
*/
import * as plugins from '../webrequest.plugins.js';
export class RequestDeduplicator {
constructor() {
this.inFlightRequests = new Map();
}
/**
* Generate a deduplication key from a request
*/
generateKey(request) {
// Use URL + method as the base key
const url = request.url;
const method = request.method;
// For GET/HEAD requests, just use URL + method
if (method === 'GET' || method === 'HEAD') {
return `${method}:${url}`;
}
// For other methods, we can't deduplicate as easily
// (body might be different)
// Use a timestamp to make it unique
return `${method}:${url}:${Date.now()}`;
}
/**
* Execute a request with deduplication
*/
async execute(key, executeFn) {
// Check if request is already in flight
const existingDeferred = this.inFlightRequests.get(key);
if (existingDeferred) {
// Wait for the existing request to complete
const response = await existingDeferred.promise;
// Clone the response so it can be used multiple times
return {
response: response.clone(),
wasDeduplicated: true,
};
}
// Create a new deferred for this request
const deferred = plugins.smartpromise.defer();
this.inFlightRequests.set(key, deferred);
try {
// Execute the request
const response = await executeFn();
// Resolve the deferred
deferred.resolve(response);
// Clean up
this.inFlightRequests.delete(key);
// Return the original response
return {
response,
wasDeduplicated: false,
};
}
catch (error) {
// Reject the deferred
deferred.reject(error);
// Clean up
this.inFlightRequests.delete(key);
// Re-throw the error
throw error;
}
}
/**
* Check if a request is currently in flight
*/
isInFlight(key) {
return this.inFlightRequests.has(key);
}
/**
* Get the number of in-flight requests
*/
getInFlightCount() {
return this.inFlightRequests.size;
}
/**
* Clear all in-flight requests
*/
clear() {
this.inFlightRequests.clear();
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVkdXBsaWNhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvdXRpbHMvZGVkdXBsaWNhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sS0FBSyxPQUFPLE1BQU0sMEJBQTBCLENBQUM7QUFFcEQsTUFBTSxPQUFPLG1CQUFtQjtJQUFoQztRQUNVLHFCQUFnQixHQUdwQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBNkZoQixDQUFDO0lBM0ZDOztPQUVHO0lBQ0ksV0FBVyxDQUFDLE9BQWdCO1FBQ2pDLG1DQUFtQztRQUNuQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3hCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFFOUIsK0NBQStDO1FBQy9DLElBQUksTUFBTSxLQUFLLEtBQUssSUFBSSxNQUFNLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDMUMsT0FBTyxHQUFHLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUM1QixDQUFDO1FBRUQsb0RBQW9EO1FBQ3BELDRCQUE0QjtRQUM1QixvQ0FBb0M7UUFDcEMsT0FBTyxHQUFHLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLE9BQU8sQ0FDbEIsR0FBVyxFQUNYLFNBQWtDO1FBRWxDLHdDQUF3QztRQUN4QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFeEQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLDRDQUE0QztZQUM1QyxNQUFNLFFBQVEsR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztZQUVoRCxzREFBc0Q7WUFDdEQsT0FBTztnQkFDTCxRQUFRLEVBQUUsUUFBUSxDQUFDLEtBQUssRUFBRTtnQkFDMUIsZUFBZSxFQUFFLElBQUk7YUFDdEIsQ0FBQztRQUNKLENBQUM7UUFFRCx5Q0FBeUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQVksQ0FBQztRQUN4RCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUV6QyxJQUFJLENBQUM7WUFDSCxzQkFBc0I7WUFDdEIsTUFBTSxRQUFRLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQztZQUVuQyx1QkFBdUI7WUFDdkIsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUzQixXQUFXO1lBQ1gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVsQywrQkFBK0I7WUFDL0IsT0FBTztnQkFDTCxRQUFRO2dCQUNSLGVBQWUsRUFBRSxLQUFLO2FBQ3ZCLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLHNCQUFzQjtZQUN0QixRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXZCLFdBQVc7WUFDWCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWxDLHFCQUFxQjtZQUNyQixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVLENBQUMsR0FBVztRQUMzQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLO1FBQ1YsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2hDLENBQUM7Q0FDRiJ9