|
| 1 | +const globalObj = typeof window === 'undefined' ? global : window |
| 2 | + |
| 3 | +let Scheduler = globalObj.Scheduler |
| 4 | +try { |
| 5 | + const requireString = `require${Math.random()}`.slice(0, 7) |
| 6 | + const nodeRequire = module && module[requireString] |
| 7 | + // import React's scheduler so we'll be able to schedule our tasks later on. |
| 8 | + Scheduler = nodeRequire.call(module, 'scheduler') |
| 9 | +} catch (_err) { |
| 10 | + console.error("The react version you're using doesn't support Scheduling") |
| 11 | +} |
| 12 | +// in case this react version has a Scheduler implementation, we use it, |
| 13 | +// if not, we just create a function calling our callback |
| 14 | +const NormalPriority = Scheduler |
| 15 | + ? Scheduler.NormalPriority || Scheduler.unstable_NormalPriority |
| 16 | + : null |
| 17 | + |
| 18 | +const isScheduleCallbackSupported = Scheduler !== undefined |
| 19 | +let isModernScheduleCallbackSupported = null |
| 20 | + |
| 21 | +const errorHandler = e => { |
| 22 | + // If the error originated from Scheduler, it means we're in v16.8.6 |
| 23 | + if ( |
| 24 | + e.message === 'callback is not a function' && |
| 25 | + e.filename.includes('scheduler') |
| 26 | + ) { |
| 27 | + console.error(e.error.stack, e.error.detail) |
| 28 | + e.preventDefault() |
| 29 | + } else { |
| 30 | + console.error(e.error) |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +export default function scheduleCallback(_, cb) { |
| 35 | + if (!isScheduleCallbackSupported) { |
| 36 | + return cb() |
| 37 | + } |
| 38 | + |
| 39 | + if (isModernScheduleCallbackSupported === null) { |
| 40 | + // patch console.error here |
| 41 | + const originalConsoleError = console.error |
| 42 | + console.error = function error(...args) { |
| 43 | + /* if console.error fired *with that specific message* */ |
| 44 | + /* istanbul ignore next */ |
| 45 | + const firstArgIsString = typeof args[0] === 'string' |
| 46 | + if ( |
| 47 | + firstArgIsString && |
| 48 | + args[0].indexOf('TypeError: callback is not a function') === 0 |
| 49 | + ) { |
| 50 | + // v16.8.6 |
| 51 | + isModernScheduleCallbackSupported = false |
| 52 | + globalObj.removeEventListener('error', errorHandler) |
| 53 | + console.error = originalConsoleError |
| 54 | + return cb() |
| 55 | + } else { |
| 56 | + originalConsoleError.apply(console, args) |
| 57 | + console.error = originalConsoleError |
| 58 | + return cb() |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + globalObj.addEventListener('error', errorHandler) |
| 63 | + return Scheduler.unstable_scheduleCallback(NormalPriority, () => { |
| 64 | + console.error = originalConsoleError |
| 65 | + isModernScheduleCallbackSupported = true |
| 66 | + globalObj.removeEventListener('error', errorHandler) |
| 67 | + return cb() |
| 68 | + }) |
| 69 | + } else if (isModernScheduleCallbackSupported === false) { |
| 70 | + return cb() |
| 71 | + } |
| 72 | + |
| 73 | + return Scheduler.unstable_scheduleCallback(NormalPriority, cb) |
| 74 | +} |
| 75 | + |
| 76 | +/* eslint no-console:0 */ |
0 commit comments