hono
Version:
Web framework built on Web Standards
371 lines (370 loc) • 11.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var hooks_exports = {};
__export(hooks_exports, {
STASH_EFFECT: () => STASH_EFFECT,
createRef: () => createRef,
forwardRef: () => forwardRef,
startTransition: () => startTransition,
startViewTransition: () => startViewTransition,
use: () => use,
useCallback: () => useCallback,
useDebugValue: () => useDebugValue,
useDeferredValue: () => useDeferredValue,
useEffect: () => useEffect,
useId: () => useId,
useImperativeHandle: () => useImperativeHandle,
useInsertionEffect: () => useInsertionEffect,
useLayoutEffect: () => useLayoutEffect,
useMemo: () => useMemo,
useReducer: () => useReducer,
useRef: () => useRef,
useState: () => useState,
useSyncExternalStore: () => useSyncExternalStore,
useTransition: () => useTransition,
useViewTransition: () => useViewTransition
});
module.exports = __toCommonJS(hooks_exports);
var import_constants = require("../constants");
var import_render = require("../dom/render");
const STASH_SATE = 0;
const STASH_EFFECT = 1;
const STASH_CALLBACK = 2;
const STASH_MEMO = 3;
const STASH_REF = 4;
const resolvedPromiseValueMap = /* @__PURE__ */ new WeakMap();
const isDepsChanged = (prevDeps, deps) => !prevDeps || !deps || prevDeps.length !== deps.length || deps.some((dep, i) => dep !== prevDeps[i]);
let viewTransitionState = void 0;
const documentStartViewTransition = (cb) => {
if (document?.startViewTransition) {
return document.startViewTransition(cb);
} else {
cb();
return { finished: Promise.resolve() };
}
};
let updateHook = void 0;
const viewTransitionHook = (context, node, cb) => {
const state = [true, false];
let lastVC = node.vC;
return documentStartViewTransition(() => {
if (lastVC === node.vC) {
viewTransitionState = state;
cb(context);
viewTransitionState = void 0;
lastVC = node.vC;
}
}).finished.then(() => {
if (state[1] && lastVC === node.vC) {
state[0] = false;
viewTransitionState = state;
cb(context);
viewTransitionState = void 0;
}
});
};
const startViewTransition = (callback) => {
updateHook = viewTransitionHook;
try {
callback();
} finally {
updateHook = void 0;
}
};
const useViewTransition = () => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return [false, () => {
}];
}
if (viewTransitionState) {
viewTransitionState[1] = true;
}
return [!!viewTransitionState?.[0], startViewTransition];
};
const pendingStack = [];
const runCallback = (type, callback) => {
let resolve;
const promise = new Promise((r) => resolve = r);
pendingStack.push([type, promise]);
try {
const res = callback();
if (res instanceof Promise) {
res.then(resolve, resolve);
} else {
resolve();
}
} finally {
pendingStack.pop();
}
};
const startTransition = (callback) => {
runCallback(1, callback);
};
const startTransitionHook = (callback) => {
runCallback(2, callback);
};
const useTransition = () => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return [false, () => {
}];
}
const [error, setError] = useState();
const [state, updateState] = useState();
if (error) {
throw error[0];
}
const startTransitionLocalHook = useCallback(
(callback) => {
startTransitionHook(() => {
updateState((state2) => !state2);
let res = callback();
if (res instanceof Promise) {
res = res.catch((e) => {
setError([e]);
});
}
return res;
});
},
[state]
);
const [context] = buildData;
return [context[0] === 2, startTransitionLocalHook];
};
const useDeferredValue = (value, ...rest) => {
const [values, setValues] = useState(
rest.length ? [rest[0], rest[0]] : [value, value]
);
if (Object.is(values[1], value)) {
return values[1];
}
pendingStack.push([3, Promise.resolve()]);
updateHook = async (context, _, cb) => {
cb(context);
values[0] = value;
};
setValues([values[0], value]);
updateHook = void 0;
pendingStack.pop();
return values[0];
};
const useState = (initialState) => {
const resolveInitialState = () => typeof initialState === "function" ? initialState() : initialState;
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return [resolveInitialState(), () => {
}];
}
const [, node] = buildData;
const stateArray = node[import_constants.DOM_STASH][1][STASH_SATE] ||= [];
const hookIndex = node[import_constants.DOM_STASH][0]++;
return stateArray[hookIndex] ||= [
resolveInitialState(),
(newState) => {
const localUpdateHook = updateHook;
const stateData = stateArray[hookIndex];
if (typeof newState === "function") {
newState = newState(stateData[0]);
}
if (!Object.is(newState, stateData[0])) {
stateData[0] = newState;
if (pendingStack.length) {
const [pendingType, pendingPromise] = pendingStack.at(-1);
Promise.all([
pendingType === 3 ? node : (0, import_render.update)([pendingType, false, localUpdateHook], node),
pendingPromise
]).then(([node2]) => {
if (!node2 || !(pendingType === 2 || pendingType === 3)) {
return;
}
const lastVC = node2.vC;
const addUpdateTask = () => {
setTimeout(() => {
if (lastVC !== node2.vC) {
return;
}
(0, import_render.update)([pendingType === 3 ? 1 : 0, false, localUpdateHook], node2);
});
};
requestAnimationFrame(addUpdateTask);
});
} else {
(0, import_render.update)([0, false, localUpdateHook], node);
}
}
}
];
};
const useReducer = (reducer, initialArg, init) => {
const [state, setState] = useState(() => init ? init(initialArg) : initialArg);
return [
state,
(action) => {
setState((state2) => reducer(state2, action));
}
];
};
const useEffectCommon = (index, effect, deps) => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return;
}
const [, node] = buildData;
const effectDepsArray = node[import_constants.DOM_STASH][1][STASH_EFFECT] ||= [];
const hookIndex = node[import_constants.DOM_STASH][0]++;
const [prevDeps, , prevCleanup] = effectDepsArray[hookIndex] ||= [];
if (isDepsChanged(prevDeps, deps)) {
if (prevCleanup) {
prevCleanup();
}
const runner = () => {
data[index] = void 0;
data[2] = effect();
};
const data = [deps, void 0, void 0, void 0, void 0];
data[index] = runner;
effectDepsArray[hookIndex] = data;
}
};
const useEffect = (effect, deps) => useEffectCommon(3, effect, deps);
const useLayoutEffect = (effect, deps) => useEffectCommon(1, effect, deps);
const useInsertionEffect = (effect, deps) => useEffectCommon(4, effect, deps);
const useCallback = (callback, deps) => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return callback;
}
const [, node] = buildData;
const callbackArray = node[import_constants.DOM_STASH][1][STASH_CALLBACK] ||= [];
const hookIndex = node[import_constants.DOM_STASH][0]++;
const prevDeps = callbackArray[hookIndex];
if (isDepsChanged(prevDeps?.[1], deps)) {
callbackArray[hookIndex] = [callback, deps];
} else {
callback = callbackArray[hookIndex][0];
}
return callback;
};
const useRef = (initialValue) => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return { current: initialValue };
}
const [, node] = buildData;
const refArray = node[import_constants.DOM_STASH][1][STASH_REF] ||= [];
const hookIndex = node[import_constants.DOM_STASH][0]++;
return refArray[hookIndex] ||= { current: initialValue };
};
const use = (promise) => {
const cachedRes = resolvedPromiseValueMap.get(promise);
if (cachedRes) {
if (cachedRes.length === 2) {
throw cachedRes[1];
}
return cachedRes[0];
}
promise.then(
(res) => resolvedPromiseValueMap.set(promise, [res]),
(e) => resolvedPromiseValueMap.set(promise, [void 0, e])
);
throw promise;
};
const useMemo = (factory, deps) => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
return factory();
}
const [, node] = buildData;
const memoArray = node[import_constants.DOM_STASH][1][STASH_MEMO] ||= [];
const hookIndex = node[import_constants.DOM_STASH][0]++;
const prevDeps = memoArray[hookIndex];
if (isDepsChanged(prevDeps?.[1], deps)) {
memoArray[hookIndex] = [factory(), deps];
}
return memoArray[hookIndex][0];
};
let idCounter = 0;
const useId = () => useMemo(() => `:r${(idCounter++).toString(32)}:`, []);
const useDebugValue = (_value, _formatter) => {
};
const createRef = () => {
return { current: null };
};
const forwardRef = (Component) => {
return (props) => {
const { ref, ...rest } = props;
return Component(rest, ref);
};
};
const useImperativeHandle = (ref, createHandle, deps) => {
useEffect(() => {
ref.current = createHandle();
return () => {
ref.current = null;
};
}, deps);
};
const useSyncExternalStore = (subscribe, getSnapshot, getServerSnapshot) => {
const buildData = import_render.buildDataStack.at(-1);
if (!buildData) {
if (!getServerSnapshot) {
throw new Error("getServerSnapshot is required for server side rendering");
}
return getServerSnapshot();
}
const [serverSnapshotIsUsed] = useState(!!(buildData[0][4] && getServerSnapshot));
const [state, setState] = useState(
() => serverSnapshotIsUsed ? getServerSnapshot() : getSnapshot()
);
useEffect(() => {
if (serverSnapshotIsUsed) {
setState(getSnapshot());
}
return subscribe(() => {
setState(getSnapshot());
});
}, []);
return state;
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
STASH_EFFECT,
createRef,
forwardRef,
startTransition,
startViewTransition,
use,
useCallback,
useDebugValue,
useDeferredValue,
useEffect,
useId,
useImperativeHandle,
useInsertionEffect,
useLayoutEffect,
useMemo,
useReducer,
useRef,
useState,
useSyncExternalStore,
useTransition,
useViewTransition
});
;