import * as interfaces from './interfaces/index.js'; import * as plugins from './plugins.js'; import * as helpers from './helpers/index.js'; import { DomainRouter } from './classes.domainrouter.js'; import { Analyzer } from './analytics/analyzer.js'; import type { EdgeWorker } from './classes.edgeworker.js'; export interface ICworkerEventOptions { event: plugins.cloudflareTypes.FetchEvent edgeWorkerRef: EdgeWorker; passThroughOnException?: boolean; } export class WorkerEvent { public options: ICworkerEventOptions; public analyzer: Analyzer; private responseDeferred: plugins.smartpromise.Deferred; private waitUntilDeferred: plugins.smartpromise.Deferred; private response: Response = null; private waitList = []; // routing settings public responderInstruction: interfaces.IResponderInstruction; public routedThroughRendertron: boolean = false; public isPreflight: boolean = false; public request: plugins.cloudflareTypes.Request; public parsedUrl: URL; constructor(optionsArg: ICworkerEventOptions) { this.options = optionsArg; // lets create an Analyzer for this request this.analyzer = new Analyzer(this); // lets make sure we always answer this.options.passThroughOnException ? this.options.event.passThroughOnException() : null; // lets set up some better asnyc behaviour this.waitUntilDeferred = plugins.smartpromise.defer(); this.responseDeferred = plugins.smartpromise.defer(); this.addToWaitList(this.analyzer.finishedDeferred.promise); // lets entangle the event with this class instance this.request = this.options.event.request; // lets start with analytics this.analyzer.setRequestData({ requestAgent: this.request.headers.get('user-agent'), requestMethod: this.request.method, requestUrl: this.request.url }); this.options.event.respondWith(this.responseDeferred.promise); this.options.event.waitUntil(this.waitUntilDeferred.promise); // lets parse the url this.parsedUrl = new URL(this.request.url); // lets check the waitlist this.checkWaitList(); console.log(`Got request for ${this.request.url}`); } get hasResponse () { let returnValue: boolean; this.response ? returnValue = true : returnValue = false; return returnValue; } public addToWaitList(promiseArg: Promise) { this.waitList.push(promiseArg); } private async checkWaitList() { await this.responseDeferred.promise; const currentWaitList = this.waitList; this.waitList = []; await Promise.all(currentWaitList); if (this.waitList.length > 0) { this.checkWaitList(); } else { this.waitUntilDeferred.resolve(); } } public setResponse (responseArg: Response) { this.response = responseArg; this.responseDeferred.resolve(responseArg); this.analyzer.setResponseData({ responseStatus: this.response.status, responseEndTime: Date.now() }); } }