radashi
Version:
The modern, community-first TypeScript toolkit with all of the fast, readable, and minimal utility functions you need. Type-safe, dependency-free, tree-shakeable, fully tested.
1,851 lines (1,708 loc) • 46.9 kB
JavaScript
// src/array/alphabetical.ts
function alphabetical(array, getter, direction = "asc") {
if (!array) {
return [];
}
const asc = (a, b) => `${getter(a)}`.localeCompare(getter(b));
const dsc = (a, b) => `${getter(b)}`.localeCompare(getter(a));
return array.slice().sort(direction === "desc" ? dsc : asc);
}
// src/array/boil.ts
function boil(array, compareFunc) {
if (!array || (array.length ?? 0) === 0) {
return null;
}
return array.reduce(compareFunc);
}
// src/array/cartesianProduct.ts
function cartesianProduct(...arrays) {
let out = [[]];
for (const array of arrays) {
const result = [];
for (const currentArray of out) {
for (const item of array) {
const currentArrayCopy = currentArray.slice();
currentArrayCopy.push(item);
result.push(currentArrayCopy);
}
}
out = result;
}
return out;
}
// src/array/castArray.ts
function castArray(value) {
return Array.isArray(value) ? value.slice() : [value];
}
// src/array/castArrayIfExists.ts
function castArrayIfExists(value) {
return Array.isArray(value) ? value.slice() : value != null ? [value] : value;
}
// src/array/cluster.ts
function cluster(array, size = 2) {
const clusters = [];
if (size > 0) {
for (let i = 0; i < array.length; i += size) {
clusters.push(array.slice(i, i + size));
}
}
return clusters;
}
// src/array/concat.ts
function concat(...values) {
const result = [];
const append = (value) => value != null && result.push(value);
for (const value of values) {
if (Array.isArray(value)) {
value.forEach(append);
} else {
append(value);
}
}
return result;
}
// src/array/counting.ts
function counting(array, identity) {
if (!array) {
return {};
}
return array.reduce(
(acc, item) => {
const id = identity(item);
acc[id] = (acc[id] ?? 0) + 1;
return acc;
},
{}
);
}
// src/array/diff.ts
function diff(root, other, identity = (t) => t) {
if (!(root == null ? void 0 : root.length) && !(other == null ? void 0 : other.length)) {
return [];
}
if ((root == null ? void 0 : root.length) === void 0) {
return [...other];
}
if (!(other == null ? void 0 : other.length)) {
return [...root];
}
const bKeys = other.reduce(
(acc, item) => {
acc[identity(item)] = true;
return acc;
},
{}
);
return root.filter((a) => !bKeys[identity(a)]);
}
// src/array/first.ts
function first(array, defaultValue) {
return (array == null ? void 0 : array.length) > 0 ? array[0] : defaultValue;
}
// src/array/flat.ts
function flat(lists) {
return lists.reduce((acc, list2) => {
acc.push(...list2);
return acc;
}, []);
}
// src/array/fork.ts
function fork(array, condition) {
const forked = [[], []];
if (array) {
for (const item of array) {
forked[condition(item) ? 0 : 1].push(item);
}
}
return forked;
}
// src/array/group.ts
function group(array, getGroupId) {
return array.reduce(
(acc, item) => {
const groupId = getGroupId(item);
if (!acc[groupId]) {
acc[groupId] = [];
}
acc[groupId].push(item);
return acc;
},
{}
);
}
// src/array/intersects.ts
function intersects(listA, listB, identity) {
if (!listA || !listB) {
return false;
}
if (identity) {
const known = new Set(listA.map(identity));
return listB.some((item) => known.has(identity(item)));
}
return listB.some((item) => listA.includes(item));
}
// src/array/iterate.ts
function iterate(count, func, initValue) {
let value = initValue;
for (let i = 1; i <= count; i++) {
value = func(value, i);
}
return value;
}
// src/array/last.ts
function last(array, defaultValue) {
return (array == null ? void 0 : array.length) > 0 ? array[array.length - 1] : defaultValue;
}
// src/array/list.ts
function list(startOrLength, end, valueOrMapper, step) {
return Array.from(range(startOrLength, end, valueOrMapper, step));
}
// src/array/mapify.ts
function mapify(array, getKey, getValue = (item) => item) {
const map2 = /* @__PURE__ */ new Map();
for (const [index, item] of array.entries()) {
map2.set(getKey(item, index), getValue(item, index));
}
return map2;
}
// src/array/merge.ts
function merge(prev, array, toKey) {
if (!array && !prev) {
return [];
}
if (!array) {
return [...prev];
}
if (!prev) {
return [];
}
if (!toKey) {
return [...prev];
}
const keys2 = /* @__PURE__ */ new Map();
for (const item of array) {
keys2.set(toKey(item), item);
}
return prev.map((prevItem) => {
const key = toKey(prevItem);
return keys2.has(key) ? keys2.get(key) : prevItem;
});
}
// src/array/objectify.ts
function objectify(array, getKey, getValue = (item) => item) {
return array.reduce(
(acc, item) => {
acc[getKey(item)] = getValue(item);
return acc;
},
{}
);
}
// src/array/pluck.ts
function pluck(array, mappings) {
return array.map(
mappings ? (item) => mappings.map(
(mapping) => isFunction(mapping) ? mapping(item) : item[mapping]
) : Object.values
);
}
// src/array/remove.ts
function remove(array, predicate) {
return array.filter((item) => !predicate(item));
}
// src/array/replace.ts
function replace(array, newItem, match) {
if (!array) {
return [];
}
if (newItem === void 0) {
return [...array];
}
const out = array.slice();
for (let index = 0; index < array.length; index++) {
if (match(array[index], index)) {
out[index] = newItem;
break;
}
}
return out;
}
// src/array/replaceOrAppend.ts
function replaceOrAppend(array, newItem, match) {
if (!array && !newItem) {
return [];
}
if (!newItem) {
return [...array];
}
if (!array) {
return [newItem];
}
const out = array.slice();
for (let index = 0; index < array.length; index++) {
if (match(array[index], index)) {
out[index] = newItem;
return out;
}
}
out.push(newItem);
return out;
}
// src/array/select.ts
function select(array, mapper, condition) {
if (!array) {
return [];
}
let mapped;
return array.reduce((acc, item, index) => {
if (condition) {
condition(item, index) && acc.push(mapper(item, index));
} else if ((mapped = mapper(item, index)) != null) {
acc.push(mapped);
}
return acc;
}, []);
}
// src/array/selectFirst.ts
function selectFirst(array, mapper, condition) {
if (!array) {
return void 0;
}
let foundIndex = -1;
const found = array.find((item, index) => {
foundIndex = index;
return condition ? condition(item, index) : mapper(item, index) != null;
});
return found === void 0 ? void 0 : mapper(found, foundIndex);
}
// src/array/shift.ts
function shift(arr, n) {
if (arr.length === 0) {
return [...arr];
}
const shiftNumber = n % arr.length;
if (shiftNumber === 0) {
return [...arr];
}
return [...arr.slice(-shiftNumber, arr.length), ...arr.slice(0, -shiftNumber)];
}
// src/array/sift.ts
function sift(array) {
return (array == null ? void 0 : array.filter((x) => !!x)) ?? [];
}
// src/array/sort.ts
function sort(array, getter, desc = false) {
if (!array) {
return [];
}
const asc = (a, b) => getter(a) - getter(b);
const dsc = (a, b) => getter(b) - getter(a);
return array.slice().sort(desc === true ? dsc : asc);
}
// src/array/toggle.ts
function toggle(array, item, toKey, options) {
if (!array) {
return item !== void 0 ? [item] : [];
}
if (item === void 0) {
return [...array];
}
let matcher;
if (toKey) {
const key = toKey(item, -1);
matcher = (x, idx) => toKey(x, idx) === key;
} else {
matcher = (x) => x === item;
}
const existing = array.find(matcher);
if (existing !== void 0) {
return array.filter((x, idx) => !matcher(x, idx));
}
return (options == null ? void 0 : options.strategy) === "prepend" ? [item, ...array] : [...array, item];
}
// src/array/unique.ts
function unique(array, toKey) {
if (toKey) {
const keys2 = /* @__PURE__ */ new Set();
return array.reduce((acc, item) => {
const key = toKey(item);
if (!keys2.has(key)) {
keys2.add(key);
acc.push(item);
}
return acc;
}, []);
}
return [...new Set(array)];
}
// src/array/unzip.ts
function unzip(arrays) {
if (!arrays || !arrays.length) {
return [];
}
const out = new Array(
arrays.reduce((max2, arr) => Math.max(max2, arr.length), 0)
);
let index = 0;
const get2 = (array) => array[index];
for (; index < out.length; index++) {
out[index] = Array.from(arrays, get2);
}
return out;
}
// src/array/zip.ts
function zip(...arrays) {
return unzip(arrays);
}
// src/array/zipToObject.ts
function zipToObject(keys2, values) {
if (!keys2 || !keys2.length) {
return {};
}
const getValue = isFunction(values) ? values : isArray(values) ? (_k, i) => values[i] : (_k, _i) => values;
return keys2.reduce(
(acc, key, idx) => {
acc[key] = getValue(key, idx);
return acc;
},
{}
);
}
// src/async/AggregateError.ts
var AggregateErrorOrPolyfill = /* @__PURE__ */ (() => globalThis.AggregateError ?? class AggregateError extends Error {
constructor(errors = []) {
var _a, _b;
super();
const name = ((_a = errors.find((e) => e.name)) == null ? void 0 : _a.name) ?? "";
this.name = `AggregateError(${name}...)`;
this.message = `AggregateError with ${errors.length} errors`;
this.stack = ((_b = errors.find((e) => e.stack)) == null ? void 0 : _b.stack) ?? this.stack;
this.errors = errors;
}
})();
// src/async/all.ts
async function all(input) {
const errors = [];
const onError = (err) => {
errors.push(err);
};
let output;
if (isArray(input)) {
output = await Promise.all(
input.map((value) => Promise.resolve(value).catch(onError))
);
} else {
output = { ...input };
await Promise.all(
Object.keys(output).map(async (key) => {
output[key] = await Promise.resolve(output[key]).catch(onError);
})
);
}
if (errors.length > 0) {
throw new AggregateErrorOrPolyfill(errors);
}
return output;
}
// src/async/defer.ts
async function defer(func) {
const callbacks = [];
const register = (fn, options) => callbacks.push({
fn,
rethrow: (options == null ? void 0 : options.rethrow) ?? false
});
const [err, response] = await tryit(func)(register);
for (const { fn, rethrow } of callbacks) {
const [rethrown] = await tryit(fn)(err);
if (rethrown && rethrow) {
throw rethrown;
}
}
if (err) {
throw err;
}
return response;
}
// src/async/guard.ts
function guard(func, shouldGuard) {
const onError = (err) => {
if (shouldGuard && !shouldGuard(err)) {
throw err;
}
};
try {
const result = func();
return result instanceof Promise ? result.catch(onError) : result;
} catch (err) {
return onError(err);
}
}
// src/async/map.ts
async function map(array, asyncMapFunc) {
if (!array) {
return [];
}
const result = [];
let index = 0;
for (const value of array) {
const newValue = await asyncMapFunc(value, index++);
result.push(newValue);
}
return result;
}
// src/async/parallel.ts
async function parallel(options, array, func) {
if (!array.length) {
return [];
}
const work = array.map((item, index) => ({
index,
item
}));
let signal;
if (isNumber(options)) {
options = {
limit: options
};
} else {
signal = options.signal;
signal == null ? void 0 : signal.throwIfAborted();
}
const processor = async (resolve) => {
const results2 = [];
while (!(signal == null ? void 0 : signal.aborted)) {
const next = work.pop();
if (!next) {
break;
}
const [error, result] = await tryit(func)(next.item);
results2.push({
error,
result,
index: next.index
});
}
return resolve(results2);
};
const queues = Promise.all(
list(1, clamp(options.limit, 1, array.length)).map(
() => new Promise(processor)
)
);
let signalPromise;
if (signal) {
signalPromise = new Promise((_, reject) => {
const onAbort = () => reject(signal.reason);
signal.addEventListener("abort", onAbort);
queues.then(() => signal.removeEventListener("abort", onAbort));
});
}
const itemResults = await (signalPromise ? Promise.race([queues, signalPromise]) : queues);
const [errors, results] = fork(
sort(flat(itemResults), (r) => r.index),
(x) => !!x.error
);
if (errors.length > 0) {
throw new AggregateErrorOrPolyfill(errors.map((error) => error.error));
}
return results.map((r) => r.result);
}
// src/async/reduce.ts
async function reduce(array, reducer, initialValue) {
if (!array) {
array = [];
}
let index = 0;
let acc = initialValue;
if (acc === void 0 && arguments.length < 3) {
if (!array.length) {
throw new TypeError("Reduce of empty array with no initial value");
}
acc = array[index++];
}
while (index < array.length) {
acc = await reducer(acc, array[index], index++);
}
return acc;
}
// src/async/retry.ts
async function retry(options, func) {
const times = (options == null ? void 0 : options.times) ?? 3;
const delay = options == null ? void 0 : options.delay;
const backoff = (options == null ? void 0 : options.backoff) ?? null;
const signal = options == null ? void 0 : options.signal;
let i = 0;
while (true) {
const [err, result] = await tryit(func)((err2) => {
throw { _exited: err2 };
});
signal == null ? void 0 : signal.throwIfAborted();
if (!err) {
return result;
}
if (err._exited) {
throw err._exited;
}
if (++i >= times) {
throw err;
}
if (delay) {
await sleep(delay);
}
if (backoff) {
await sleep(backoff(i));
}
}
}
// src/async/sleep.ts
function sleep(milliseconds) {
return new Promise((res) => setTimeout(res, milliseconds));
}
// src/async/TimeoutError.ts
var TimeoutError = class extends Error {
constructor(message) {
super(message ?? "Operation timed out");
this.name = "TimeoutError";
}
};
// src/async/timeout.ts
function timeout(ms, error) {
return new Promise(
(_, reject) => setTimeout(
() => reject(isFunction(error) ? error() : new TimeoutError(error)),
ms
)
);
}
// src/async/toResult.ts
async function toResult(promise) {
try {
const result = await promise;
return [void 0, result];
} catch (error) {
if (isError(error)) {
return [error, void 0];
}
throw error;
}
}
// src/async/tryit.ts
function tryit(func) {
return (...args) => {
try {
const result = func(...args);
return isPromise(result) ? result.then(
(value) => [void 0, value],
(err) => [err, void 0]
) : [void 0, result];
} catch (err) {
return [err, void 0];
}
};
}
// src/async/withResolvers.ts
function withResolvers() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { resolve, reject, promise };
}
// src/curry/callable.ts
function callable(obj, fn) {
return new Proxy(Object.assign(fn.bind(null), obj), {
get: (target, key) => target[key],
set: (target, key, value) => {
target[key] = value;
return true;
},
apply: (target, _, args) => fn(Object.assign({}, target))(...args)
});
}
// src/curry/chain.ts
function chain(...funcs) {
return (...args) => {
return funcs.slice(1).reduce((acc, fn) => fn(acc), funcs[0](...args));
};
}
// src/curry/compose.ts
function compose(...funcs) {
return funcs.reverse().reduce((acc, fn) => fn(acc));
}
// src/curry/debounce.ts
function debounce({ delay, leading }, func) {
let timer = void 0;
let active = true;
const debounced = (...args) => {
if (active) {
clearTimeout(timer);
timer = setTimeout(() => {
active && func(...args);
timer = void 0;
}, delay);
if (leading) {
func(...args);
leading = false;
}
} else {
func(...args);
}
};
debounced.isPending = () => {
return timer !== void 0;
};
debounced.cancel = () => {
active = false;
};
debounced.flush = (...args) => func(...args);
return debounced;
}
// src/curry/flip.ts
function flip(fn) {
return (arg2, arg1, ...args) => fn(arg1, arg2, ...args);
}
// src/curry/memo.ts
function memoize(cache, func, keyFunc, ttl) {
return function callWithMemo(...args) {
const key = keyFunc ? keyFunc(...args) : JSON.stringify({ args });
const existing = cache[key];
if (existing !== void 0) {
if (!existing.exp) {
return existing.value;
}
if (existing.exp > (/* @__PURE__ */ new Date()).getTime()) {
return existing.value;
}
}
const result = func(...args);
cache[key] = {
exp: ttl ? (/* @__PURE__ */ new Date()).getTime() + ttl : null,
value: result
};
return result;
};
}
function memo(func, options = {}) {
return memoize({}, func, options.key ?? null, options.ttl ?? null);
}
// src/curry/memoLastCall.ts
function memoLastCall(fn) {
let lastArgs = null;
let lastResult = null;
return (...args) => {
if (lastArgs && lastArgs.length === args.length && lastArgs.every((arg, i) => Object.is(arg, args[i]))) {
return lastResult;
}
const result = fn(...args);
lastArgs = args;
lastResult = result;
return result;
};
}
// src/curry/once.ts
var once = /* @__PURE__ */ (() => {
const onceSymbol = /* @__PURE__ */ Symbol();
const once2 = (fn) => {
const onceFn = function(...args) {
if (onceFn[onceSymbol] === onceSymbol) {
onceFn[onceSymbol] = fn.apply(this, args);
}
return onceFn[onceSymbol];
};
onceFn[onceSymbol] = onceSymbol;
return onceFn;
};
once2.reset = (fn) => {
fn[onceSymbol] = onceSymbol;
};
return once2;
})();
// src/curry/partial.ts
function partial(fn, ...args) {
return (...rest) => fn(...[...args, ...rest]);
}
// src/curry/partob.ts
function partob(fn, argObj) {
return (restObj) => fn({ ...argObj, ...restObj });
}
// src/curry/proxied.ts
function proxied(handler) {
return new Proxy(
{},
{
get: (target, propertyName) => handler(propertyName)
}
);
}
// src/curry/throttle.ts
function throttle({ interval, trailing }, func) {
let timer;
let lastCalled = 0;
let trailingArgs;
const throttled = (...args) => {
if (!isThrottled()) {
trigger(...args);
} else if (trailing) {
trailingArgs = args;
}
};
const isThrottled = () => Date.now() - lastCalled < interval;
throttled.isThrottled = isThrottled;
const trigger = throttled.trigger = (...args) => {
func(...args);
lastCalled = Date.now();
if (trailing) {
trailingArgs = void 0;
clearTimeout(timer);
timer = setTimeout(
() => trailingArgs && trigger(...trailingArgs),
interval
);
}
};
return throttled;
}
// src/function/always.ts
function always(value) {
return () => value;
}
// src/function/castComparator.ts
function castComparator(mapping, compare, reverse) {
const map2 = isFunction(mapping) ? mapping : (obj) => obj[mapping];
const comparator = (left, right) => {
const mappedLeft = map2(left);
const mappedRight = map2(right);
if (compare) {
return compare(mappedLeft, mappedRight);
}
return mappedLeft > mappedRight ? 1 : mappedLeft < mappedRight ? -1 : 0;
};
return reverse ? flip(comparator) : comparator;
}
// src/function/castMapping.ts
function castMapping(mapping) {
return isFunction(mapping) ? mapping : mapping != null ? (input) => input[mapping] : (input) => input;
}
// src/function/noop.ts
function noop() {
}
// src/number/clamp.ts
function clamp(n, min2, max2) {
if (max2 != null && min2 != null && min2 > max2) {
throw new Error("invalid clamp range");
}
return max2 != null && n > max2 ? max2 : min2 != null && n < min2 ? min2 : n;
}
// src/number/inRange.ts
function inRange(number, start, end) {
const isTypeSafe = typeof number === "number" && typeof start === "number" && (typeof end === "undefined" || typeof end === "number");
if (!isTypeSafe) {
return false;
}
if (typeof end === "undefined") {
end = start;
start = 0;
}
return number >= Math.min(start, end) && number < Math.max(start, end);
}
// src/number/lerp.ts
function lerp(from, to, amount) {
return from + (to - from) * amount;
}
// src/number/max.ts
function max(array, getter) {
if (!array || (array.length ?? 0) === 0) {
return null;
}
const get2 = getter ?? ((v) => v);
return array.reduce((a, b) => get2(a) > get2(b) ? a : b);
}
// src/number/min.ts
function min(array, getter) {
if (!array || (array.length ?? 0) === 0) {
return null;
}
const get2 = getter ?? ((v) => v);
return array.reduce((a, b) => get2(a) < get2(b) ? a : b);
}
// src/number/range.ts
function* range(startOrLength, end, valueOrMapper = (i) => i, step = 1) {
const mapper = isFunction(valueOrMapper) ? valueOrMapper : () => valueOrMapper;
const start = end ? startOrLength : 0;
const final = end ?? startOrLength;
for (let i = start; i <= final; i += step) {
yield mapper(i);
}
}
// src/number/round.ts
function round(value, precision, toInteger = Math.round) {
if (precision) {
const p = precision > 0 ? Math.min(precision, 292) : Math.max(precision, -323);
let [q, e] = `${value}e`.split("e");
[q, e] = `${toInteger(+`${q}e${+e + p}`)}e`.split("e");
return +`${q}e${+e - p}`;
}
return toInteger(value);
}
// src/number/sum.ts
function sum(array, fn) {
return (array || []).reduce((acc, item) => acc + (fn ? fn(item) : item), 0);
}
// src/number/toFloat.ts
function toFloat(value, defaultValue) {
const parsedValue = isSymbol(value) ? Number.NaN : Number.parseFloat(value);
return Number.isNaN(parsedValue) ? defaultValue !== void 0 ? defaultValue : 0 : parsedValue;
}
// src/number/toInt.ts
function toInt(value, defaultValue) {
const parsedValue = isSymbol(value) ? Number.NaN : Number.parseInt(value);
return Number.isNaN(parsedValue) ? defaultValue !== void 0 ? defaultValue : 0 : parsedValue;
}
// src/object/assign.ts
function assign(initial, override) {
if (!initial || !override) {
return initial ?? override ?? {};
}
const proto = Object.getPrototypeOf(initial);
const merged = proto ? { ...initial } : Object.assign(Object.create(proto), initial);
for (const key of Object.keys(override)) {
merged[key] = isPlainObject(initial[key]) && isPlainObject(override[key]) ? assign(initial[key], override[key]) : override[key];
}
return merged;
}
// src/object/clone.ts
function clone(obj) {
if (isPrimitive(obj)) {
return obj;
}
if (typeof obj === "function") {
return obj.bind({});
}
const proto = Object.getPrototypeOf(obj);
const newObj = typeof (proto == null ? void 0 : proto.constructor) === "function" ? new proto.constructor() : Object.create(proto);
for (const key of Object.getOwnPropertyNames(obj)) {
newObj[key] = obj[key];
}
return newObj;
}
// src/object/cloneDeep.ts
var DefaultCloningStrategy = {
cloneMap(input, track, clone2) {
const output = track(/* @__PURE__ */ new Map());
for (const [key, value] of input) {
output.set(key, clone2(value));
}
return output;
},
cloneSet(input, track, clone2) {
const output = track(/* @__PURE__ */ new Set());
for (const value of input) {
output.add(clone2(value));
}
return output;
},
cloneArray(input, track, clone2) {
const output = track(new Array(input.length));
input.forEach((value, index) => {
output[index] = clone2(value);
});
return output;
},
cloneObject(input, track, clone2) {
const output = track(Object.create(Object.getPrototypeOf(input)));
for (const key of Reflect.ownKeys(input)) {
const descriptor = Object.getOwnPropertyDescriptor(input, key);
if ("value" in descriptor) {
descriptor.value = clone2(descriptor.value);
}
Object.defineProperty(output, key, descriptor);
}
return output;
},
cloneOther(input, track) {
return track(input);
}
};
var FastCloningStrategy = {
cloneObject: (input, track, clone2) => {
const output = track({ ...input });
for (const key of Object.keys(input)) {
output[key] = clone2(input[key]);
}
return output;
}
};
function cloneDeep(root, customStrategy) {
const strategy = { ...DefaultCloningStrategy, ...customStrategy };
const tracked = /* @__PURE__ */ new Map();
const track = (parent, newParent) => {
tracked.set(parent, newParent);
return newParent;
};
const clone2 = (value) => value && typeof value === "object" ? tracked.get(value) ?? cloneDeep2(value, strategy) : value;
const cloneDeep2 = (parent, strategy2) => {
const cloneParent = isObject(parent) ? strategy2.cloneObject : isArray(parent) ? strategy2.cloneArray : isMap(parent) ? strategy2.cloneMap : isSet(parent) ? strategy2.cloneSet : strategy2.cloneOther;
const newParent = cloneParent(parent, track.bind(null, parent), clone2);
if (!newParent) {
return cloneDeep2(parent, DefaultCloningStrategy);
}
tracked.set(parent, newParent);
return newParent;
};
return cloneDeep2(root, strategy);
}
// src/object/construct.ts
function construct(obj) {
if (!obj) {
return {};
}
return Object.keys(obj).reduce((acc, path) => {
return set(acc, path, obj[path]);
}, {});
}
// src/object/crush.ts
function crush(value) {
if (!value) {
return {};
}
return function crushReducer(crushed, value2, path) {
if (isObject(value2) || isArray(value2)) {
for (const [prop, propValue] of Object.entries(value2)) {
crushReducer(crushed, propValue, path ? `${path}.${prop}` : prop);
}
} else {
crushed[path] = value2;
}
return crushed;
}({}, value, "");
}
// src/object/filterKey.ts
function filterKey(obj, key, filter) {
return Object.prototype.hasOwnProperty.call(obj, key) && (filter == null || (isArray(filter) ? filter.includes(key) : filter(obj[key], key, obj)));
}
// src/object/get.ts
function get(value, path, defaultValue) {
const segments = path.split(/[\.\[\]]/g);
let current = value;
for (const key of segments) {
if (current === null) {
return defaultValue;
}
if (current === void 0) {
return defaultValue;
}
const unquotedKey = key.replace(/['"]/g, "");
if (unquotedKey.trim() === "") {
continue;
}
current = current[unquotedKey];
}
if (current === void 0) {
return defaultValue;
}
return current;
}
// src/object/invert.ts
function invert(obj) {
if (!obj) {
return {};
}
const keys2 = Object.keys(obj);
return keys2.reduce(
(acc, key) => {
acc[obj[key]] = key;
return acc;
},
{}
);
}
// src/object/isDangerousKey.ts
function isDangerousKey(key, object) {
return !(object && !Object.getPrototypeOf(object)) && (key === "__proto__" || key === "prototype" || key === "constructor");
}
// src/object/keys.ts
function keys(value) {
if (!value) {
return [];
}
const keys2 = [];
const keyPath = [];
const recurse = (value2) => {
if (isPlainObject(value2)) {
for (const [prop, propValue] of Object.entries(value2)) {
keyPath.push(prop);
recurse(propValue);
keyPath.pop();
}
} else if (isArray(value2)) {
value2.forEach((item, index) => {
keyPath.push(index);
recurse(item);
keyPath.pop();
});
} else {
keys2.push(keyPath.join("."));
}
};
recurse(value);
return keys2;
}
// src/object/listify.ts
function listify(obj, toItem) {
if (!obj) {
return [];
}
const entries = Object.entries(obj);
if (entries.length === 0) {
return [];
}
return entries.reduce((acc, entry) => {
acc.push(toItem(entry[0], entry[1]));
return acc;
}, []);
}
// src/object/lowerize.ts
function lowerize(obj) {
return mapKeys(obj, (k) => k.toLowerCase());
}
// src/object/mapEntries.ts
function mapEntries(obj, toEntry) {
if (!obj) {
return {};
}
return Object.entries(obj).reduce(
(acc, [key, value]) => {
const [newKey, newValue] = toEntry(key, value);
acc[newKey] = newValue;
return acc;
},
{}
);
}
// src/object/mapKeys.ts
function mapKeys(obj, mapFunc) {
const keys2 = Object.keys(obj);
return keys2.reduce(
(acc, key) => {
acc[mapFunc(key, obj[key])] = obj[key];
return acc;
},
{}
);
}
// src/object/mapValues.ts
function mapValues(obj, mapFunc) {
return Object.keys(obj).reduce(
(acc, key) => {
acc[key] = mapFunc(obj[key], key);
return acc;
},
{}
);
}
// src/object/omit.ts
function omit(obj, keys2) {
if (!obj) {
return {};
}
if (!keys2 || keys2.length === 0) {
return obj;
}
return keys2.reduce(
(acc, key) => {
delete acc[key];
return acc;
},
{ ...obj }
);
}
// src/object/pick.ts
function pick(obj, filter) {
if (!obj) {
return {};
}
let keys2 = filter;
if (isArray(filter)) {
filter = null;
} else {
keys2 = Reflect.ownKeys(obj);
}
return keys2.reduce((acc, key) => {
if (filterKey(obj, key, filter)) {
acc[key] = obj[key];
}
return acc;
}, {});
}
// src/object/set.ts
function set(initial, path, value) {
if (!initial) {
return {};
}
if (!path || value === void 0) {
return initial;
}
return function recurse(object, keys2, index) {
const key = keys2[index];
object ??= isIntString(key) ? [] : {};
if (isDangerousKey(key, object)) {
throw new Error("Unsafe key in path: " + key);
}
if (index < keys2.length - 1) {
value = recurse(object[key], keys2, index + 1);
}
if (!Object.is(object[key], value)) {
object = clone(object);
object[key] = value;
}
return object;
}(initial, path.match(/[^.[\]]+/g), 0);
}
// src/object/shake.ts
function shake(obj, filter = (value) => value === void 0) {
if (!obj) {
return {};
}
return Object.keys(obj).reduce((acc, key) => {
if (!filter(obj[key])) {
acc[key] = obj[key];
}
return acc;
}, {});
}
// src/object/traverse.ts
function traverse(root, visitor, options, outerContext) {
const context = outerContext ?? {
value: null,
key: null,
parent: null,
parents: [],
path: [],
skipped: /* @__PURE__ */ new Set(),
skip(obj) {
context.skipped.add(obj ?? context.value);
}
};
const { rootNeedsVisit } = options ??= {};
const ownKeys = options.ownKeys ?? Object.keys;
const nestedOptions = {
...options,
rootNeedsVisit: null
};
let ok = true;
const visit = (value, key) => {
if (context.parent.constructor === Map) {
[key, value] = value;
}
context.path.push(key);
const result = visitor(
context.value = value,
context.key = key,
context.parent,
context,
nestedOptions
);
if (result === false) {
return ok = false;
}
if (value !== null && typeof value === "object" && (isArray(value) || isPlainObject(value)) && !context.skipped.has(value) && !context.parents.includes(value)) {
traverse2(value, result);
}
context.path.pop();
return ok;
};
const traverse2 = (parent, parentResult) => {
context.parents.push(parent);
context.parent = parent;
if (rootNeedsVisit && parent === root) {
parentResult = visitor(
context.value = parent,
context.key = null,
context.parent,
context,
nestedOptions
);
if (parentResult === false) {
return ok;
}
}
if (isArray(parent)) {
parent.slice().forEach((value, index, values) => {
if (visit(value, index) === false) {
values.length = 0;
}
});
} else if (parent === root && isIterable(parent)) {
let index = 0;
for (const value of parent) {
if (visit(value, index) === false) {
return ok;
}
index++;
}
} else {
for (const key of ownKeys(parent)) {
if (visit(parent[key], key) === false) {
return ok;
}
}
}
context.parents.pop();
context.parent = last(context.parents);
if (ok && isFunction(parentResult)) {
ok = parentResult() !== false;
}
return ok;
};
if (outerContext) {
if (outerContext.skipped.has(root)) {
return true;
}
const { value, key } = context;
traverse2(root);
context.value = value;
context.key = key;
return ok;
}
return traverse2(root);
}
// src/object/upperize.ts
function upperize(obj) {
return mapKeys(obj, (k) => k.toUpperCase());
}
// src/random/draw.ts
function draw(array) {
const max2 = array.length;
if (max2 === 0) {
return null;
}
const index = random(0, max2 - 1);
return array[index];
}
// src/random/random.ts
function random(min2, max2) {
return Math.floor(Math.random() * (max2 - min2 + 1) + min2);
}
// src/random/shuffle.ts
function shuffle(array, random2 = random) {
const newArray = array.slice();
for (let idx = array.length - 1, randomIdx, item; idx > 0; idx--) {
randomIdx = random2(0, idx);
item = newArray[idx];
newArray[idx] = newArray[randomIdx];
newArray[randomIdx] = item;
}
return newArray;
}
// src/random/uid.ts
function uid(length, specials = "") {
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + specials;
return iterate(
length,
(acc) => {
return acc + characters.charAt(random(0, characters.length - 1));
},
""
);
}
// src/series/series.ts
var series = (items, toKey = (item) => `${item}`) => {
const indexesByKey = {};
const itemsByIndex = {};
for (const idx of range(items.length - 1)) {
const item = items[idx];
indexesByKey[toKey(item)] = idx;
itemsByIndex[idx] = item;
}
const first2 = () => itemsByIndex[0];
const last2 = () => itemsByIndex[items.length - 1];
const next = (current, defaultValue) => itemsByIndex[indexesByKey[toKey(current)] + 1] ?? defaultValue ?? first2();
const previous = (current, defaultValue) => itemsByIndex[indexesByKey[toKey(current)] - 1] ?? defaultValue ?? last2();
return {
/**
* Given two values in the series, returns the value that occurs
* earlier in the series.
*/
min(a, b) {
return indexesByKey[toKey(a)] < indexesByKey[toKey(b)] ? a : b;
},
/**
* Given two values in the series, returns the value that occurs
* later in the series.
*/
max(a, b) {
return indexesByKey[toKey(a)] > indexesByKey[toKey(b)] ? a : b;
},
first: first2,
last: last2,
next,
previous,
/**
* A more dynamic method than `next` and `previous` that lets you move
* many times in either direction.
*
* ```ts
* series(weekdays).spin('wednesday', 3) // => 'monday'
* series(weekdays).spin('wednesday', -3) // => 'friday'
* ```
*/
spin(current, num) {
if (num === 0) {
return current;
}
const abs = Math.abs(num);
const rel = abs > items.length ? abs % items.length : abs;
return list(0, rel - 1).reduce(
(acc) => num > 0 ? next(acc) : previous(acc),
current
);
}
};
};
// src/string/camel.ts
function camel(str) {
var _a;
const parts = ((_a = str == null ? void 0 : str.replace(/([A-Z])+/g, capitalize)) == null ? void 0 : _a.split(/(?=[A-Z])|[\.\-\s_]/).map((x) => x.toLowerCase())) ?? [];
if (parts.length === 0) {
return "";
}
if (parts.length === 1) {
return parts[0];
}
return parts.reduce((acc, part) => {
return `${acc}${part.charAt(0).toUpperCase()}${part.slice(1)}`;
});
}
// src/string/capitalize.ts
function capitalize(str) {
if (!str || str.length === 0) {
return "";
}
const lower = str.toLowerCase();
return lower.substring(0, 1).toUpperCase() + lower.substring(1, lower.length);
}
// src/string/dash.ts
function dash(str) {
var _a;
const parts = ((_a = str == null ? void 0 : str.replace(/([A-Z])+/g, capitalize)) == null ? void 0 : _a.split(/(?=[A-Z])|[\.\-\s_]/).map((x) => x.toLowerCase())) ?? [];
if (parts.length === 0) {
return "";
}
if (parts.length === 1) {
return parts[0];
}
return parts.reduce((acc, part) => {
return `${acc}-${part.toLowerCase()}`;
});
}
// src/string/dedent.ts
function dedent(text, ...values) {
var _a;
if (isArray(text)) {
if (values.length > 0) {
return dedent(
text.reduce((acc, input, i) => {
var _a2;
let value = String(values[i] ?? "");
const indent2 = value.includes("\n") && ((_a2 = input.match(/[ \t]*(?=[^\n]*$)/)) == null ? void 0 : _a2[0]);
if (indent2) {
value = value.replace(/\n(?=[^\n]*?\S)/g, "\n" + indent2);
}
return acc + input + value;
}, "")
);
}
text = text[0];
}
const indent = values[0] ?? ((_a = text.match(/^[ \t]*(?=\S)/m)) == null ? void 0 : _a[0]);
const output = indent ? text.replace(new RegExp(`^${indent}`, "gm"), "") : text;
return output.replace(/^[ \t]*\n|\n[ \t]*$/g, "");
}
// src/string/pascal.ts
function pascal(str) {
if (!str) {
return "";
}
const result = str.replace(
/(?:[^\w\d]|_|\s)+(\w)([A-Z]+)?/g,
(_, firstCharacter, capitalizedLetters) => {
if (capitalizedLetters) {
return firstCharacter.toUpperCase() + capitalizedLetters.toLowerCase();
}
return firstCharacter.toUpperCase();
}
);
return result[0].toUpperCase() + result.substring(1);
}
// src/string/similarity.ts
function similarity(str1, str2) {
if (str1 === str2) {
return 0;
}
let start = 0;
let end1 = str1.length - 1;
let end2 = str2.length - 1;
while (start <= end1 && start <= end2 && str1[start] === str2[start]) {
start++;
}
while (end1 >= start && end2 >= start && str1[end1] === str2[end2]) {
end1--;
end2--;
}
const length1 = end1 - start + 1;
const length2 = end2 - start + 1;
if (length1 === 0) {
return length2;
}
if (length2 === 0) {
return length1;
}
const numRows = length1 + 1;
const numColumns = length2 + 1;
const distances = new Array(numRows * numColumns).fill(0);
for (let x = 1; x < numColumns; x++) {
distances[x] = x;
}
for (let y = 1; y < numRows; y++) {
distances[y * numColumns] = y;
}
for (let x = 1; x < numColumns; x++) {
for (let y = 1; y < numRows; y++) {
const i = y * numColumns + x;
distances[i] = Math.min(
// Cost of a deletion.
distances[i - numColumns] + 1,
// Cost of an insertion.
distances[i - 1] + 1,
// Cost of a substitution.
distances[i - numColumns - 1] + (str1[start + y - 1] === str2[start + x - 1] ? 0 : 1)
);
}
}
return distances[length1 * numColumns + length2];
}
// src/string/snake.ts
function snake(str, options) {
const parts = (str == null ? void 0 : str.replace(/([A-Z])+/g, capitalize).split(/(?=[A-Z])|[\.\-\s_]/).map((x) => x.toLowerCase())) ?? [];
if (parts.length === 0) {
return "";
}
if (parts.length === 1) {
return parts[0];
}
const result = parts.reduce((acc, part) => {
return `${acc}_${part.toLowerCase()}`;
});
return (options == null ? void 0 : options.splitOnNumber) === false ? result : result.replace(/([A-Za-z]{1}[0-9]{1})/, (val) => `${val[0]}_${val[1]}`);
}
// src/string/template.ts
function template(str, data, regex = /\{\{(.+?)\}\}/g) {
let result = "";
let from = 0;
let match;
while (match = regex.exec(str)) {
result += str.slice(from, match.index) + data[match[1]];
from = regex.lastIndex;
}
return result + str.slice(from);
}
// src/string/title.ts
function title(str) {
if (!str) {
return "";
}
return str.split(/(?=[A-Z])|[\.\-\s_]/).map((s) => s.trim()).filter((s) => !!s).map((s) => capitalize(s.toLowerCase())).join(" ");
}
// src/string/trim.ts
function trim(str, charsToTrim = " ") {
if (!str) {
return "";
}
const toTrim = charsToTrim.replace(/[\W]{1}/g, "\\$&");
const regex = new RegExp(`^[${toTrim}]+|[${toTrim}]+$`, "g");
return str.replace(regex, "");
}
// src/typed/isArray.ts
var isArray = /* @__PURE__ */ (() => Array.isArray)();
// src/typed/isAsyncIterable.ts
var asyncIteratorSymbol = (
/* c8 ignore next */
Symbol.asyncIterator || /* @__PURE__ */ Symbol.for("Symbol.asyncIterator")
);
function isAsyncIterable(value) {
return !!value && typeof value === "object" && typeof value[asyncIteratorSymbol] === "function";
}
// src/typed/isBigInt.ts
function isBigInt(value) {
return typeof value === "bigint";
}
// src/typed/isBoolean.ts
function isBoolean(value) {
return typeof value === "boolean";
}
// src/typed/isClass.ts
function isClass(value) {
return isFunction(value) && Function.prototype.toString.call(value).startsWith("class ");
}
// src/typed/isDate.ts
function isDate(value) {
return isTagged(value, "[object Date]");
}
// src/typed/isEmpty.ts
function isEmpty(value) {
if (typeof value !== "object" || value === null) {
return !value || value === true;
}
if (isDate(value)) {
return Number.isNaN(value.getTime());
}
const length = value.length;
if (isNumber(length)) {
return length === 0;
}
const size = value.size;
if (isNumber(size)) {
return size === 0;
}
const keys2 = Object.keys(value).length;
return keys2 === 0;
}
// src/typed/isEqual.ts
function isEqual(x, y) {
if (Object.is(x, y)) {
return true;
}
if (x instanceof Date && y instanceof Date) {
return x.getTime() === y.getTime();
}
if (x instanceof RegExp && y instanceof RegExp) {
return x.toString() === y.toString();
}
if (typeof x !== "object" || x === null || typeof y !== "object" || y === null) {
return false;
}
const keysX = Reflect.ownKeys(x);
const keysY = Reflect.ownKeys(y);
if (keysX.length !== keysY.length) {
return false;
}
for (let i = 0; i < keysX.length; i++) {
if (!Reflect.has(y, keysX[i])) {
return false;
}
if (!isEqual(x[keysX[i]], y[keysX[i]])) {
return false;
}
}
return true;
}
// src/typed/isError.ts
function isError(value) {
return isTagged(value, "[object Error]");
}
// src/typed/isFloat.ts
function isFloat(value) {
return isNumber(value) && value % 1 !== 0;
}
// src/typed/isFunction.ts
function isFunction(value) {
return typeof value === "function";
}
// src/typed/isInt.ts
var isInt = /* @__PURE__ */ (() => Number.isInteger)();
// src/typed/isIntString.ts
function isIntString(value) {
if (!isString(value)) {
return false;
}
const num = +value;
return Number.isInteger(num) && `${num}` === value;
}
// src/typed/isIterable.ts
function isIterable(value) {
return typeof value === "object" && value !== null && Symbol.iterator in value;
}
// src/typed/isMap.ts
function isMap(value) {
return isTagged(value, "[object Map]");
}
// src/typed/isNullish.ts
function isNullish(value) {
return value === null || value === void 0;
}
// src/typed/isNumber.ts
function isNumber(value) {
return typeof value === "number" && !Number.isNaN(value);
}
// src/typed/isObject.ts
function isObject(value) {
return isTagged(value, "[object Object]");
}
// src/typed/isPlainObject.ts
function isPlainObject(value) {
if (typeof value !== "object" || value === null) {
return false;
}
const prototype = Object.getPrototypeOf(value);
return (
// Fast path for most common objects.
prototype === Object.prototype || // Support objects created without a prototype.
prototype === null || // Support plain objects from other realms.
Object.getPrototypeOf(prototype) === null
);
}
// src/typed/isPrimitive.ts
function isPrimitive(value) {
return value === void 0 || value === null || typeof value !== "object" && typeof value !== "function";
}
// src/typed/isPromise.ts
function isPromise(value) {
return !!value && isFunction(value.then);
}
// src/typed/isRegExp.ts
function isRegExp(value) {
return isTagged(value, "[object RegExp]");
}
// src/typed/isResult.ts
function isResult(value) {
return isArray(value) && value.length === 2 && (isError(value[0]) ? value[1] : value[0]) === void 0;
}
// src/typed/isResultErr.ts
function isResultErr(value) {
return isResult(value) && value[0] !== void 0;
}
// src/typed/isResultOk.ts
function isResultOk(value) {
return isResult(value) && value[0] === void 0;
}
// src/typed/isSet.ts
function isSet(value) {
return isTagged(value, "[object Set]");
}
// src/typed/isString.ts
function isString(value) {
return typeof value === "string";
}
// src/typed/isSymbol.ts
function isSymbol(value) {
return typeof value === "symbol";
}
// src/typed/isTagged.ts
function isTagged(value, tag) {
return Object.prototype.toString.call(value) === tag;
}
// src/typed/isUndefined.ts
function isUndefined(value) {
return typeof value === "undefined";
}
// src/typed/isWeakMap.ts
function isWeakMap(value) {
return isTagged(value, "[object WeakMap]");
}
// src/typed/isWeakSet.ts
function isWeakSet(value) {
return isTagged(value, "[object WeakSet]");
}
export { AggregateErrorOrPolyfill as AggregateError, DefaultCloningStrategy, FastCloningStrategy, TimeoutError, all, alphabetical, always, assign, boil, callable, camel, capitalize, cartesianProduct, castArray, castArrayIfExists, castComparator, castMapping, chain, clamp, clone, cloneDeep, cluster, compose, concat, construct, counting, crush, dash, debounce, dedent, defer, diff, draw, filterKey, first, flat, flip, fork, get, group, guard, inRange, intersects, invert, isArray, isAsyncIterable, isBigInt, isBoolean, isClass, isDangerousKey, isDate, isEmpty, isEqual, isError, isFloat, isFunction, isInt, isIntString, isIterable, isMap, isNullish, isNumber, isObject, isPlainObject, isPrimitive, isPromise, isRegExp, isResult, isResultErr, isResultOk, isSet, isString, isSymbol, isTagged, isUndefined, isWeakMap, isWeakSet, iterate, keys, last, lerp, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, mapify, max, memo, memoLastCall, merge, min, noop, objectify, omit, once, parallel, partial, partob, pascal, pick, pluck, proxied, random, range, reduce, remove, replace, replaceOrAppend, retry, round, select, selectFirst, series, set, shake, shift, shuffle, sift, similarity, sleep, snake, sort, sum, template, throttle, timeout, title, toFloat, toInt, toResult, toggle, traverse, trim, tryit as try, tryit, uid, unique, unzip, upperize, withResolvers, zip, zipToObject };