vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
88 lines (87 loc) • 3.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeHook = executeHook;
exports.getPageContext = getPageContext;
exports.providePageContext = providePageContext;
exports.isUserHookError = isUserHookError;
const assert_js_1 = require("../../utils/assert.js");
const getGlobalObject_js_1 = require("../../utils/getGlobalObject.js");
const humanizeTime_js_1 = require("../../utils/humanizeTime.js");
const isObject_js_1 = require("../../utils/isObject.js");
const globalObject = (0, getGlobalObject_js_1.getGlobalObject)('utils/executeHook.ts', {
userHookErrors: new WeakMap(),
pageContext: null
});
function isUserHookError(err) {
if (!(0, isObject_js_1.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(() => {
(0, assert_js_1.assertWarning)(false, `The ${hookName}() hook defined by ${hookFilePath} is slow: it's taking more than ${(0, humanizeTime_js_1.humanizeTime)(timeoutWarn)} (https://vike.dev/hooksTimeout)`, { onlyOnce: false });
}, timeoutWarn);
const currentTimeoutErr = isNotDisabled(timeoutErr) &&
setTimeout(() => {
const err = (0, assert_js_1.getProjectError)(`The ${hookName}() hook defined by ${hookFilePath} timed out: it didn't finish after ${(0, humanizeTime_js_1.humanizeTime)(timeoutErr)} (https://vike.dev/hooksTimeout)`);
reject(err);
}, timeoutErr);
(async () => {
try {
providePageContext(pageContext);
const ret = await hookFnCaller();
resolve(ret);
}
catch (err) {
if ((0, isObject_js_1.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;
});
}