storycrawler
Version:
Utilities to build Storybook crawling tools with Puppeteer
105 lines (104 loc) • 2.86 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceWatcher = void 0;
/**
*
* Helper to wait until requesting assets are resolved
*
* @example
*
* ```ts
* class Worker {
* constructor() {
* this.resourceWatcher = new ResourceWatcher(this.page).init();
* }
* async someTask() {
* this.resourceWatcher.clear();
* await this.doSomething(this.page); // Trigger some HTTP requests
* await this.resourceWatcher.waitForRequestsComplete();
* }
* }
* ```
*
**/
class ResourceWatcher {
/**
*
* @param page - Puppeteer page object
*
**/
constructor(page) {
this.page = page;
this.resolvedAssetsMap = new Map();
this.requestedAssetUrls = new Set();
}
/**
*
* Registers listeners to the Puppeteer page object.
*
* @returns The ResourceWatcher instance itself
*
**/
init() {
const setAsResolved = (url) => {
const metadata = this.resolvedAssetsMap.get(url);
if (!metadata)
return;
metadata.resolve();
};
this.page.on('request', request => {
const url = request.url();
if (request.method() !== 'GET')
return;
// Ignore the following resource types because they might create HTTP request never completed
if (['media', 'texttrack', 'websocket', 'eventsource', 'other'].includes(request.resourceType()))
return;
if (!url.startsWith('http'))
return;
this.requestedAssetUrls.add(url);
if (this.resolvedAssetsMap.has(url))
return;
let resolve = () => { };
const resolved = new Promise(res => (resolve = res));
const metadata = {
resolve,
resolved,
};
this.resolvedAssetsMap.set(url, metadata);
});
this.page.on('requestfinished', req => setAsResolved(req.url()));
this.page.on('requestfailed', req => setAsResolved(req.url()));
return this;
}
/**
*
* Clears requested URLs to wait for.
*
**/
clear() {
this.requestedAssetUrls = new Set();
}
/**
*
* @returns URLs requested
*
**/
getRequestedUrls() {
const urls = [...this.requestedAssetUrls.values()];
return urls;
}
/**
*
* Waits until the all resource requests are finished.
*
**/
async waitForRequestsComplete() {
const urls = this.getRequestedUrls();
await Promise.all(urls
.map(url => this.resolvedAssetsMap.get(url))
.filter(m => !!m)
.map(m => m.resolved));
return urls;
}
}
exports.ResourceWatcher = ResourceWatcher;
;