import { ARRAY, FUNCTION, NULL, OBJECT } from './types.js'; import { isArray, reviver, obj } from './utils.js'; export { bound, unbound } from './utils.js'; /** * @template V * @typedef {import("./utils.js").Arr} Arr */ /** * @template T, V * @typedef {import("./utils.js").Obj} Obj */ /** * @template V * @typedef {import("./utils.js").TypeOf} TypeOf */ /** * @template W, T, V * @typedef {W extends Function ? W : W extends Arr ? W[0] : W extends Obj ? W["v"] : never} ValueOf */ /** * @template {string} T * @template V * @param {T} type * @param {V} value * @returns {T extends typeof ARRAY ? Arr : Obj} */ export const target = (type, value) => // @see https://github.com/microsoft/TypeScript/issues/33014 // @ts-ignore ( type === ARRAY ? (/** @type {Arr} */ ([value])) : obj(type, value) ); /** * @template W, T, V * @param {W} wrap * @param {typeof reviver} [revive] * @returns */ export const unwrap = (wrap, revive = reviver) => { /** @type {string} */ let type = typeof wrap, value = wrap; if (type === OBJECT) { if (isArray(wrap)) { type = ARRAY; value = wrap.at(0); } else ({ t: type, v: value } = /** @type {Obj} */ (wrap)); } return revive(type, /** @type {ValueOf} */ (value)); }; const resolver = (type, value) => ( type === FUNCTION ? value : target(type, value) ); /** * @template V * @param {V} value * @param {Function} [resolve] * @returns {V extends Function ? V : V extends Array ? Arr : Obj, V>} */ export const wrap = (value, resolve = resolver) => { const type = value === null ? NULL : typeof value; return resolve(type === OBJECT && isArray(value) ? ARRAY : type, value); };