UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

86 lines (85 loc) 3 kB
export { executeHook }; export { getPageContext }; export { providePageContext }; export { isUserHookError }; import { getProjectError, assertWarning } from '../../utils/assert.js'; import { getGlobalObject } from '../../utils/getGlobalObject.js'; import { humanizeTime } from '../../utils/humanizeTime.js'; import { isObject } from '../../utils/isObject.js'; const globalObject = getGlobalObject('utils/executeHook.ts', { userHookErrors: new WeakMap(), pageContext: null }); function isUserHookError(err) { if (!isObject(err)) return false; return globalObject.userHookErrors.get(err) ?? false; } function executeHook(hookFnCaller, hook, pageContext) { const { hookName, hookFilePath, hookTimeout: { error: timeoutErr, warning: timeoutWarn } } = hook; let resolve; let reject; const promise = new Promise((resolve_, reject_) => { resolve = (ret) => { clearTimeouts(); resolve_(ret); }; reject = (err) => { clearTimeouts(); reject_(err); }; }); const clearTimeouts = () => { if (currentTimeoutWarn) clearTimeout(currentTimeoutWarn); if (currentTimeoutErr) clearTimeout(currentTimeoutErr); }; const currentTimeoutWarn = isNotDisabled(timeoutWarn) && setTimeout(() => { assertWarning(false, `The ${hookName}() hook defined by ${hookFilePath} is slow: it's taking more than ${humanizeTime(timeoutWarn)} (https://vike.dev/hooksTimeout)`, { onlyOnce: false }); }, timeoutWarn); const currentTimeoutErr = isNotDisabled(timeoutErr) && setTimeout(() => { const err = getProjectError(`The ${hookName}() hook defined by ${hookFilePath} timed out: it didn't finish after ${humanizeTime(timeoutErr)} (https://vike.dev/hooksTimeout)`); reject(err); }, timeoutErr); (async () => { try { providePageContext(pageContext); const ret = await hookFnCaller(); resolve(ret); } catch (err) { if (isObject(err)) { globalObject.userHookErrors.set(err, { hookName, hookFilePath }); } reject(err); } })(); return promise; } function isNotDisabled(timeout) { return !!timeout && timeout !== Infinity; } /** * Access `pageContext` object inside Vike hooks, in order to create universal hooks. * * https://vike.dev/getPageContext */ function getPageContext() { return globalObject.pageContext; } /** * Provide `pageContext` for universal hooks. * * https://vike.dev/getPageContext */ function providePageContext(pageContext) { globalObject.pageContext = pageContext; // Promise.resolve() is quicker than process.nextTick() and setImmediate() // https://stackoverflow.com/questions/67949576/process-nexttick-before-promise-resolve-then Promise.resolve().then(() => { globalObject.pageContext = null; }); }