eventloop.js.map
27.2 KB
{"version":3,"sources":["eventloop.js"],"names":[],"mappings":"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","file":"eventloop.js","sourcesContent":["// The event loop.\n//\n// Each browser has an event loop, which processes asynchronous events like\n// loading pages and resources, XHR, timeouts and intervals, etc. These are\n// procesed in order.\n//\n// The purpose of the event loop is two fold:\n// - To get events processed in the right order for the active window (and only\n// the active window)\n// - And to allow the code to wait until all events have been processed\n// (browser.wait, .visit, .pressButton, etc)\n//\n// The event loop has one interesting method: `wait`.\n//\n// Each window maintains its own event queue. Its interesting methods are\n// `enqueue`, `http`, `dispatch` and the timeout/interval methods.\n\n\nconst assert = require('assert');\nconst { EventEmitter } = require('events');\n\n\n// Wrapper for a timeout (setTimeout)\nclass Timeout {\n\n // eventQueue - Reference to the event queue\n // fn - When timer fires, evaluate this function\n // delay - How long to wait\n // remove - Call this to discard timer\n //\n // Instance variables add:\n // handle - Node.js timeout handle\n // next - When is this timer firing next\n constructor(eventQueue, fn, delay, remove) {\n this.eventQueue = eventQueue;\n this.fn = fn;\n this.delay = Math.max(delay || 0, 0);\n this.remove = remove;\n\n this.handle = global.setTimeout(this.fire.bind(this), this.delay);\n this.next = Date.now() + this.delay;\n }\n\n fire() {\n // In response to Node firing setTimeout, but only allowed to process this\n // event during a wait()\n this.eventQueue.enqueue(()=> {\n const { eventLoop } = this.eventQueue;\n eventLoop.emit('setTimeout', this.fn, this.delay);\n try {\n this.eventQueue.window._evaluate(this.fn);\n } catch (error) {\n eventLoop.emit('error', error);\n }\n });\n this.remove();\n }\n\n // clearTimeout\n stop() {\n global.clearTimeout(this.handle);\n this.remove();\n }\n\n}\n\n\n// Wrapper for an interval (setInterval)\nclass Interval {\n\n // eventQueue - Reference to the event queue\n // fn - When timer fires, evaluate this function\n // interval - Interval between firing\n // remove - Call this to discard timer\n //\n // Instance variables add:\n // handle - Node.js interval handle\n // next - When is this timer firing next\n constructor(eventQueue, fn, interval, remove) {\n this.eventQueue = eventQueue;\n this.fn = fn;\n this.interval = Math.max(interval || 0, 0);\n this.remove = remove;\n this.fireInProgress = false;\n this.handle = global.setInterval(this.fire.bind(this), this.interval);\n this.next = Date.now() + this.interval;\n }\n\n fire() {\n // In response to Node firing setInterval, but only allowed to process this\n // event during a wait()\n this.next = Date.now() + this.interval;\n\n // setInterval events not allowed to overlap, don't queue two at once\n if (this.fireInProgress)\n return;\n this.fireInProgress = true;\n this.eventQueue.enqueue(()=> {\n this.fireInProgress = false;\n\n const { eventLoop } = this.eventQueue;\n eventLoop.emit('setInterval', this.fn, this.interval);\n try {\n this.eventQueue.window._evaluate(this.fn);\n } catch (error) {\n eventLoop.emit('error', error);\n }\n });\n }\n\n // clearTimeout\n stop() {\n global.clearInterval(this.handle);\n this.remove();\n }\n\n}\n\n\n// Each window has an event queue that holds all pending events. Various\n// browser features push new functions into the queue (e.g. process XHR\n// response, setTimeout fires). The event loop is responsible to pop these\n// events from the queue and run them, but only during browser.wait().\n//\n// In addition, the event queue keeps track of all outstanding timers\n// (setTimeout/setInterval) so it can return consecutive handles and clean them\n// up during window.destroy().\n//\n// In addition, we keep track of when the browser is expecting an event to\n// arrive in the queue (e.g. sent XHR request, expecting an event to process the\n// response soon enough). The event loop uses that to determine if it's worth\n// waiting.\nclass EventQueue {\n\n // Instance variables:\n // browser - Reference to the browser\n // eventLoop - Reference to the browser's event loop\n // queue - FIFO queue of functions to call\n // expecting - These are holding back the event loop\n // timers - Sparse array of timers (index is the timer handle)\n // eventSources - Additional sources for events (SSE, WS, etc)\n // nextTimerHandle - Value of next timer handler\n constructor(window) {\n this.window = window;\n this.browser = window.browser;\n this.eventLoop = this.browser._eventLoop;\n this.queue = [];\n this.expecting = 0;\n this.timers = [];\n this.eventSources = [];\n this.nextTimerHandle = 1;\n }\n\n\n // Cleanup when we dispose of the window\n destroy() {\n if (!this.queue)\n return;\n this.queue = null;\n\n for (let timer of this.timers) {\n if (timer)\n timer.stop();\n }\n this.timers = null;\n\n for (let eventSource of this.eventSources) {\n //if (eventSource)\n eventSource.close();\n }\n this.eventSources = null;\n }\n\n\n // -- Events --\n\n // Any events expected in the future?\n get expected() {\n return !!(this.expecting ||\n Array.from(this.window.frames).filter(frame => frame._eventQueue.expected).length);\n }\n\n // Add a function to the event queue, to be executed in order.\n enqueue(fn) {\n assert(this.queue, 'This browser has been destroyed');\n assert(typeof fn === 'function', 'eventLoop.enqueue called without a function');\n\n if (fn) {\n this.queue.push(fn);\n this.eventLoop.run();\n }\n }\n\n\n // Wait for completion. Returns a completion function, event loop will remain\n // active until the completion function is called;\n waitForCompletion() {\n ++this.expecting;\n return ()=> {\n --this.expecting;\n setImmediate(()=> {\n this.eventLoop.run();\n });\n };\n }\n\n\n // Event loop uses this to grab event from top of the queue.\n dequeue() {\n assert(this.queue, 'This browser has been destroyed');\n\n const fn = this.queue.shift();\n if (fn)\n return fn;\n for (let frame of Array.from(this.window.frames)) {\n let childFn = frame._eventQueue.dequeue();\n if (childFn)\n return childFn;\n }\n return null;\n }\n\n\n // Makes an HTTP request.\n //\n // request - Request object\n // callback - Called with Response object to process the response\n //\n // Because the callback is added to the queue, we can't use promises\n http(request, callback) {\n assert(this.queue, 'This browser has been destroyed');\n\n const done = this.waitForCompletion();\n this.window\n .fetch(request)\n .then((response)=> {\n // We can't cancel pending requests, but we can ignore the response if\n // window already closed\n if (this.queue)\n // This will get completion function to execute, e.g. to check a page\n // before meta tag refresh\n this.enqueue(()=> {\n callback(null, response);\n });\n })\n .catch((error)=> {\n if (this.queue)\n callback(error);\n })\n .then(done);\n }\n\n // Fire an error event. Used by JSDOM patches.\n onerror(error) {\n assert(this.queue, 'This browser has been destroyed');\n\n this.eventLoop.emit('error', error);\n\n const event = this.window.document.createEvent('Event');\n event.initEvent('error', false, false);\n event.message = error.message;\n event.error = error;\n this.window.dispatchEvent(event);\n }\n\n\n // -- EventSource --\n\n addEventSource(eventSource) {\n assert(this.queue, 'This browser has been destroyed');\n\n this.eventSources.push(eventSource);\n\n const emit = eventSource.emit;\n eventSource.emit = (...args)=> {\n this.eventLoop.emit('serverEvent');\n this.enqueue(()=> {\n emit.apply(eventSource, args);\n });\n };\n }\n\n\n // -- Timers --\n\n // Window.setTimeout\n setTimeout(fn, delay = 0) {\n assert(this.queue, 'This browser has been destroyed');\n if (!fn)\n return null;\n\n const handle = this.nextTimerHandle;\n ++this.nextTimerHandle;\n this.timers[handle] = new Timeout(this, fn, delay, ()=> {\n delete this.timers[handle];\n });\n return handle;\n }\n\n // Window.clearTimeout\n clearTimeout(handle) {\n assert(this.queue, 'This browser has been destroyed');\n\n const timer = this.timers[handle];\n if (timer)\n timer.stop();\n }\n\n // Window.setInterval\n setInterval(fn, interval = 0) {\n assert(this.queue, 'This browser has been destroyed');\n if (!fn)\n return null;\n\n const handle = this.nextTimerHandle;\n ++this.nextTimerHandle;\n this.timers[handle] = new Interval(this, fn, interval, ()=> {\n delete this.timers[handle];\n });\n return handle;\n }\n\n // Window.clearInterval\n clearInterval(handle) {\n assert(this.queue, 'This browser has been destroyed');\n\n const timer = this.timers[handle];\n if (timer)\n timer.stop();\n }\n\n // Returns the timestamp of the next timer event\n get next() {\n const timers = this.timers.map(timer => timer.next);\n const frames = Array.from(this.window.frames).map(frame => frame._eventQueue.next);\n return timers.concat(frames).sort()[0] || Infinity;\n }\n\n}\n\n\n// The browser event loop.\n//\n// Each browser has one event loop that processes events from the queues of the\n// currently active window and its frames (child windows).\n//\n// The wait method is responsible to process all pending events. It goes idle\n// once:\n// - There are no more events waiting in the queue (of the active window)\n// - There are no more timers waiting to fire (next -> Infinity)\n// - No future events are expected to arrive (e.g. in-progress XHR requests)\n//\n// The wait method will complete before the loop goes idle, if:\n// - Past the specified timeout\n// - The next scheduled timer is past the specified timeout\n// - The completio function evaluated to true\n//\n// While processing, the event loop emits the following events (on the browser\n// object):\n// tick(next) - Emitted after executing a single event; the argument is the\n// expected duration until the next event (in ms)\n// idle - Emitted when there are no more events (queued or expected)\n// error(err) - Emitted after an error\nmodule.exports = class EventLoop extends EventEmitter {\n\n // Instance variables are:\n // active - Currently active window\n // browser - Reference to the browser\n // running - True when inside a run loop\n // waiting - Counts in-progess calls to wait (waiters?)\n constructor(browser) {\n super();\n this.browser = browser;\n this.active = null;\n this.running = false;\n this.waiting = 0;\n }\n\n\n // -- The wait function --\n\n // Wait until one of these happen:\n // 1. We run out of events to process; callback is called with null and false\n // 2. The completion function evaluates to true; callback is called with null\n // and false\n // 3. The time duration elapsed; callback is called with null and true\n // 2. An error occurs; callback is called with an error\n //\n // Duration is specifies in milliseconds or string form (e.g. \"15s\").\n //\n // Completion function is called with the currently active window (may change\n // during page navigation or form submission) and how long until the next\n // event, and returns true to stop waiting, any other value to continue\n // processing events.\n //\n //\n // waitDuration - How long to wait (ms)\n // completionFunction - Returns true for early completion\n wait(waitDuration, completionFunction, callback) {\n assert(waitDuration, 'Wait duration required, cannot be 0');\n const eventLoop = this;\n\n ++eventLoop.waiting;\n // Someone (us) just started paying attention, start processing events\n if (eventLoop.waiting === 1)\n setImmediate(()=> eventLoop.run());\n\n // The timer fires when we waited long enough, we need timeoutOn to tell if\n // the next event is past the wait duration and there's no point in waiting\n // further\n const timer = global.setTimeout(timeout, waitDuration); // eslint-disable-line no-use-before-define\n const timeoutOn = Date.now() + waitDuration;\n\n // Fired after every event, decide if we want to stop waiting\n function ontick(next) {\n // No point in waiting that long\n if (next >= timeoutOn) {\n timeout();\n return;\n }\n\n const activeWindow = eventLoop.active;\n if (completionFunction && activeWindow.document.documentElement)\n try {\n const waitFor = Math.max(next - Date.now(), 0);\n // Event processed, are we ready to complete?\n const completed = completionFunction(activeWindow, waitFor);\n if (completed)\n done();\n } catch (error) {\n done(error);\n }\n\n }\n\n // The wait is over ...\n function done(error) {\n global.clearTimeout(timer);\n eventLoop.removeListener('tick', ontick);\n eventLoop.removeListener('idle', done);\n eventLoop.browser.removeListener('error', done);\n\n --eventLoop.waiting;\n try {\n callback(error);\n } catch (error) {\n // If callback makes an assertion that fails, we end here.\n // If we throw error synchronously, it gets swallowed.\n setImmediate(function() {\n throw error;\n });\n }\n }\n\n // We gave up, could be result of slow response ...\n function timeout() {\n if (eventLoop.expected)\n done(new Error('Timeout: did not get to load all resources on this page'));\n else\n done();\n }\n\n eventLoop.on('tick', ontick);\n\n // Fired when there are no more events to process\n eventLoop.once('idle', done);\n\n // Stop on first error reported (document load, script, etc)\n // Event loop errors also propagated to the browser\n eventLoop.browser.once('error', done);\n }\n\n\n dump(output = process.stdout) {\n if (this.running)\n output.write('Event loop: running\\n');\n else if (this.expected)\n output.write(`Event loop: waiting for ${this.expected} events\\n`);\n else if (this.waiting)\n output.write('Event loop: waiting\\n');\n else\n output.write('Event loop: idle\\n');\n }\n\n\n // -- Event queue management --\n\n // Creates and returns a new event queue (see EventQueue).\n createEventQueue(window) {\n return new EventQueue(window);\n }\n\n // Set the active window. Suspends processing events from any other window, and\n // switches to processing events from this window's queue.\n setActiveWindow(window) {\n if (window === this.active)\n return;\n this.active = window;\n this.run(); // new window, new events?\n }\n\n // Are there any expected events for the active window?\n get expected() {\n return this.active && this.active._eventQueue.expected;\n }\n\n\n // -- Event processing --\n\n // Grabs next event from the queue, processes it and notifies all listeners.\n // Keeps processing until the queue is empty or all listeners are gone. You\n // only need to bootstrap this when you suspect it's not recursing.\n run() {\n // A lot of code calls run() without checking first, so not uncommon to have\n // concurrent executions of this function\n if (this.running)\n return;\n // Is there anybody out there?\n if (this.waiting === 0)\n return;\n\n // Give other (Node) events a chance to process\n this.running = true;\n setImmediate(()=> {\n this.running = false;\n try {\n\n // Are there any open windows?\n if (!this.active) {\n this.emit('idle');\n return;\n }\n // Don't run event outside browser.wait()\n if (this.waiting === 0)\n return;\n\n const jsdomQueue = this.active.document._queue;\n const event = this.active._eventQueue.dequeue();\n if (event) {\n // Process queued function, tick, and on to next event\n event();\n this.emit('tick', 0);\n this.run();\n } else if (this.expected > 0)\n // We're waiting for some events to come along, don't know when,\n // but they'll call run for us\n this.emit('tick', 0);\n else if (jsdomQueue.tail) {\n jsdomQueue.resume();\n this.run();\n } else {\n // All that's left are timers, and not even that if next == Infinity\n const next = this.active._eventQueue.next;\n if (isFinite(next))\n this.emit('tick', next);\n else\n this.emit('idle');\n }\n\n } catch (error) {\n this.emit('error', error);\n }\n });\n }\n\n};\n\n"]}