vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
86 lines (85 loc) • 3 kB
JavaScript
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;
});
}