UNPKG

doddle

Version:

Tiny yet feature-packed (async) iteration toolkit.

140 lines 4.2 kB
import { pull } from "./doddle/index.js"; export function _iter(input) { return input[Symbol.iterator](); } export function _aiter(input) { return input[Symbol.asyncIterator](); } export function _xiter(input) { return isAsyncIterable(input) ? _aiter(input) : _iter(input); } export function isObject(value) { return typeof value === "object" && value != null; } export function isFunction(value) { return typeof value === "function"; } export function isArrayLike(value) { return isObject(value) && isInt(value.length); } export function isIterable(value) { return isObject(value) && isFunction(value[Symbol.iterator]); } export const orderedStages = [undefined, "before", "after", "both"]; export const isInt = Number.isSafeInteger; export const isBool = (value) => !!value === value; export const isPair = (value) => Array.isArray(value) && value.length === 2; export const isPosInt = (value) => isInt(value) && value > 0; export function isAsyncIterable(value) { return isObject(value) && isFunction(value[Symbol.asyncIterator]); } export function isReadableStream(value) { return isObject(value) && isFunction(value.getReader); } export function isNextable(value) { // Checks if value is an iterator return isObject(value) && isFunction(value.next); } export function getClassName(something) { if (something === null) { return "null"; } if (!isObject(something)) { return typeof something; } const ctorName = something.constructor?.name ?? something?.[Symbol.toStringTag] ?? "Object"; return ctorName; } export function getValueDesc(object) { if (object == null) { return `${object}`; } if (isFunction(object)) { return `function ${object.name || "<anonymous>"}`; } if (typeof object === "bigint") { return `${object}n`; } if (typeof object === "symbol") { return object.description; } if (typeof object === "string") { if (object.length > 30) { object = object.slice(0, 30) + "⋯"; } return `"${object}"`; } if (isObject(object)) { if (isDoddle(object)) { return object.toString(); } if (isNextable(object)) { return `iterator ${getClassName(object)}`; } else if (isIterable(object)) { return `iterable ${getClassName(object)}`; } else if (isAsyncIterable(object)) { return `async iterable ${getClassName(object)}`; } else if (isDoddle(object)) { return object.toString(); } else if (isThenable(object)) { return `a Promise`; } else { return `object ${getClassName(object)}`; } } return `${object}`; } /** * Checks if the given value is a thenable. * * @param what The value to check. */ export function isThenable(what) { return isObject(what) && isFunction(what.then); } export function isDoddle(value) { return isObject(value) && isFunction(value.pull); } export function returnKvp(input, key, value) { key = pull(key); if (isAsyncIterable(input) && isThenable(key)) { return key.then(key => [pull(key), value]); } return [key, value]; } export function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } export function createCompare(desc) { const baseCompare = (a, b) => (desc ? -1 : 1) * (a < b ? -1 : a > b ? 1 : 0); return (a, b) => { if (Array.isArray(a) && Array.isArray(b)) { for (let i = 0; i < a.length; i++) { const result = baseCompare(a[i], b[i]); if (result !== 0) { return result; } } return 0; } return baseCompare(a, b); }; } export function createCompareKey(desc) { const compare = createCompare(desc); return (a, b) => { return compare(a[0], b[0]); }; } //# sourceMappingURL=utils.js.map