{"version":3,"sources":["../../src/AsapQueue.ts"],"sourcesContent":["/* eslint-disable no-restricted-globals, @typescript-eslint/ban-ts-comment, @typescript-eslint/no-unused-vars, @typescript-eslint/no-non-null-assertion */\nimport type { Task } from './types.js'\nimport { makeRequestCall, makeRequestCallFromTimer } from './makeRequestCall.js'\n\nexport class AsapQueue {\n\tprivate queue: Task[] = []\n\t// We queue errors to ensure they are thrown in right order (FIFO).\n\t// Array-as-queue is good enough here, since we are just dealing with exceptions.\n\tprivate pendingErrors: any[] = []\n\t// Once a flush has been requested, no further calls to `requestFlush` are\n\t// necessary until the next `flush` completes.\n\t// @ts-ignore\n\tprivate flushing = false\n\t// `requestFlush` is an implementation-specific method that attempts to kick\n\t// off a `flush` event as quickly as possible. `flush` will attempt to exhaust\n\t// the event queue before yielding to the browser's own event loop.\n\tprivate requestFlush: () => void\n\n\tprivate requestErrorThrow: () => void\n\t// The position of the next task to execute in the task queue. This is\n\t// preserved between calls to `flush` so that it can be resumed if\n\t// a task throws an exception.\n\tprivate index = 0\n\t// If a task schedules additional tasks recursively, the task queue can grow\n\t// unbounded. To prevent memory exhaustion, the task queue will periodically\n\t// truncate already-completed tasks.\n\tprivate capacity = 1024\n\n\tpublic constructor() {\n\t\t// `requestFlush` requests that the high priority event queue be flushed as\n\t\t// soon as possible.\n\t\t// This is useful to prevent an error thrown in a task from stalling the event\n\t\t// queue if the exception handled by Node.js’s\n\t\t// `process.on(\"uncaughtException\")` or by a domain.\n\n\t\t// `requestFlush` is implemented using a strategy based on data collected from\n\t\t// every available SauceLabs Selenium web driver worker at time of writing.\n\t\t// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593\n\t\tthis.requestFlush = makeRequestCall(this.flush)\n\t\tthis.requestErrorThrow = makeRequestCallFromTimer(() => {\n\t\t\t// Throw first error\n\t\t\tif (this.pendingErrors.length) {\n\t\t\t\tthrow this.pendingErrors.shift()\n\t\t\t}\n\t\t})\n\t}\n\n\t// Use the fastest means possible to execute a task in its own turn, with\n\t// priority over other events including IO, animation, reflow, and redraw\n\t// events in browsers.\n\t//\n\t// An exception thrown by a task will permanently interrupt the processing of\n\t// subsequent tasks. The higher level `asap` function ensures that if an\n\t// exception is thrown by a task, that the task queue will continue flushing as\n\t// soon as possible, but if you use `rawAsap` directly, you are responsible to\n\t// either ensure that no exceptions are thrown from your task, or to manually\n\t// call `rawAsap.requestFlush` if an exception is thrown.\n\tpublic enqueueTask(task: Task): void {\n\t\tconst { queue: q, requestFlush } = this\n\t\tif (!q.length) {\n\t\t\trequestFlush()\n\t\t\tthis.flushing = true\n\t\t}\n\t\t// Equivalent to push, but avoids a function call.\n\t\tq[q.length] = task\n\t}\n\n\t// The flush function processes all tasks that have been scheduled with\n\t// `rawAsap` unless and until one of those tasks throws an exception.\n\t// If a task throws an exception, `flush` ensures that its state will remain\n\t// consistent and will resume where it left off when called again.\n\t// However, `flush` does not make any arrangements to be called again if an\n\t// exception is thrown.\n\tprivate flush = () => {\n\t\tconst { queue: q } = this\n\t\twhile (this.index < q.length) {\n\t\t\tconst currentIndex = this.index\n\t\t\t// Advance the index before calling the task. This ensures that we will\n\t\t\t// begin flushing on the next task the task throws an error.\n\t\t\tthis.index++\n\t\t\tq[currentIndex]!.call()\n\t\t\t// Prevent leaking memory for long chains of recursive calls to `asap`.\n\t\t\t// If we call `asap` within tasks scheduled by `asap`, the queue will\n\t\t\t// grow, but to avoid an O(n) walk for every task we execute, we don't\n\t\t\t// shift tasks off the queue after they have been executed.\n\t\t\t// Instead, we periodically shift 1024 tasks off the queue.\n\t\t\tif (this.index > this.capacity) {\n\t\t\t\t// Manually shift all values starting at the index back to the\n\t\t\t\t// beginning of the queue.\n\t\t\t\tfor (\n\t\t\t\t\tlet scan = 0, newLength = q.length - this.index;\n\t\t\t\t\tscan < newLength;\n\t\t\t\t\tscan++\n\t\t\t\t) {\n\t\t\t\t\tq[scan] = q[scan + this.index]!\n\t\t\t\t}\n\t\t\t\tq.length -= this.index\n\t\t\t\tthis.index = 0\n\t\t\t}\n\t\t}\n\t\tq.length = 0\n\t\tthis.index = 0\n\t\tthis.flushing = false\n\t}\n\n\t// In a web browser, exceptions are not fatal. However, to avoid\n\t// slowing down the queue of pending tasks, we rethrow the error in a\n\t// lower priority turn.\n\tpublic registerPendingError = (err: any) => {\n\t\tthis.pendingErrors.push(err)\n\t\tthis.requestErrorThrow()\n\t}\n}\n\n// The message channel technique was discovered by Malte Ubl and was the\n// original foundation for this library.\n// http://www.nonblocking.io/2011/06/windownexttick.html\n\n// Safari 6.0.5 (at least) intermittently fails to create message ports on a\n// page's first load. Thankfully, this version of Safari supports\n// MutationObservers, so we don't need to fall back in that case.\n\n// function makeRequestCallFromMessageChannel(callback) {\n// var channel = new MessageChannel();\n// channel.port1.onmessage = callback;\n// return function requestCall() {\n// channel.port2.postMessage(0);\n// };\n// }\n\n// For reasons explained above, we are also unable to use `setImmediate`\n// under any circumstances.\n// Even if we were, there is another bug in Internet Explorer 10.\n// It is not sufficient to assign `setImmediate` to `requestFlush` because\n// `setImmediate` must be called *by name* and therefore must be wrapped in a\n// closure.\n// Never forget.\n\n// function makeRequestCallFromSetImmediate(callback) {\n// return function requestCall() {\n// setImmediate(callback);\n// };\n// }\n\n// Safari 6.0 has a problem where timers will get lost while the user is\n// scrolling. This problem does not impact ASAP because Safari 6.0 supports\n// mutation observers, so that implementation is used instead.\n// However, if we ever elect to use timers in Safari, the prevalent work-around\n// is to add a scroll event listener that calls for a flush.\n\n// `setTimeout` does not call the passed callback if the delay is less than\n// approximately 7 in web workers in Firefox 8 through 18, and sometimes not\n// even then.\n\n// This is for `asap.js` only.\n// Its name will be periodically randomized to break any code that depends on\n// // its existence.\n// rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer\n\n// ASAP was originally a nextTick shim included in Q. This was factored out\n// into this ASAP package. It was later adapted to RSVP which made further\n// amendments. These decisions, particularly to marginalize MessageChannel and\n// to capture the MutationObserver implementation in a closure, were integrated\n// back into ASAP proper.\n// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js\n"],"names":["makeRequestCall","makeRequestCallFromTimer","AsapQueue","enqueueTask","task","queue","q","requestFlush","length","flushing","pendingErrors","index","capacity","flush","currentIndex","call","scan","newLength","registerPendingError","err","push","requestErrorThrow","shift"],"mappings":"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"}