'use strict'; const { BIGINT, BOOLEAN, FUNCTION, NULL, NUMBER, OBJECT, STRING, SYMBOL, UNDEFINED } = require('./types.js'); const { isArray } = Array; exports.isArray = isArray; const invoke = value => /** @type {Function} */ (value)(); exports.invoke = invoke; /** * @template Value * @param {string} type * @param {Value} value * @returns {Value} */ const reviver = (type, value) => value; exports.reviver = reviver; /** * @template V * @typedef {[V]} Arr */ /** * @template V * @typedef {() => V} Ctx */ /** * @template T, V * @typedef {{t:T, v:V}} Obj */ /** * @template V * @typedef {V extends bigint ? BIGINT : V extends boolean ? BOOLEAN : V extends null ? NULL : V extends number ? NUMBER : V extends string ? STRING : V extends symbol ? SYMBOL : V extends undefined ? UNDEFINED : V extends object ? OBJECT : never} TypeOf */ /** * @template T, V * @param {T} t * @param {V} v * @returns {Obj} */ const obj = (t, v) => ({t, v}); exports.obj = obj; /** * @template V * @param {V} value * @returns {Ctx} */ const bound = value => Context.bind(value); exports.bound = bound; /** * @template V, T * @param {V} value * @returns {V extends Ctx ? ReturnType : V} */ const unbound = value => ( typeof value === FUNCTION ? invoke(value) : value ); exports.unbound = unbound; // This is needed to unlock *both* apply and construct // traps otherwise one of these might fail. // The 'use strict' directive is needed to allow // also primitive types to be bound. function Context() { 'use strict'; return this; } // TODO: is this really needed in here? // const { hasOwn } = Object; // const isConstructable = value => hasOwn(value, 'prototype'); // const isFunction = value => typeof value === FUNCTION;