functional.js
Advanced tools
+855
| 'use strict'; | ||
| // src/typeChecks.ts | ||
| function isFunction(obj) { | ||
| return !!(obj && obj.constructor && obj.call && obj.apply); | ||
| } | ||
| function isObject(obj) { | ||
| return isFunction(obj) || !!obj && typeof obj === "object"; | ||
| } | ||
| function isArray(obj) { | ||
| return Array.isArray(obj); | ||
| } | ||
| function isArguments(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Arguments]"; | ||
| } | ||
| function isDate(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Date]"; | ||
| } | ||
| function isNumber(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Number]"; | ||
| } | ||
| function isRegExp(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object RegExp]"; | ||
| } | ||
| function isString(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object String]"; | ||
| } | ||
| function exists(obj) { | ||
| return obj != null; | ||
| } | ||
| function truthy(obj) { | ||
| return exists(obj) && obj !== false; | ||
| } | ||
| function falsy(obj) { | ||
| return !truthy(obj); | ||
| } | ||
| // src/curry.ts | ||
| function curry(func) { | ||
| if (!isFunction(func)) { | ||
| throw new Error("fjs Error: Invalid function"); | ||
| } | ||
| if (func.length === 2) { | ||
| const curried2 = function(a, b, ...rest2) { | ||
| if (arguments.length >= 2) { | ||
| if (rest2.length === 0) { | ||
| return func(a, b); | ||
| } | ||
| let accumulated = func(a, b); | ||
| for (let i = 0; i < rest2.length; i++) { | ||
| accumulated = func(accumulated, rest2[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (next, ...more) => curried2(a, next, ...more); | ||
| }; | ||
| return curried2; | ||
| } | ||
| if (func.length === 3) { | ||
| const curried3 = function(a, b, c, ...rest2) { | ||
| if (arguments.length >= 3) { | ||
| if (rest2.length === 0) { | ||
| return func(a, b, c); | ||
| } | ||
| let accumulated = func(a, b, c); | ||
| for (let i = 0; i < rest2.length; i++) { | ||
| accumulated = func(accumulated, rest2[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next, ...more) => curried3(a, b, next, ...more); | ||
| } | ||
| return function(nextB, nextC, ...more) { | ||
| if (arguments.length >= 2) { | ||
| return curried3(a, nextB, nextC, ...more); | ||
| } | ||
| return (next, ...moreNext) => curried3(a, nextB, next, ...moreNext); | ||
| }; | ||
| }; | ||
| return curried3; | ||
| } | ||
| function curried(...args) { | ||
| if (args.length === 0) { | ||
| return curried; | ||
| } | ||
| if (args.length >= func.length) { | ||
| if (args.length === func.length) { | ||
| return func(...args); | ||
| } | ||
| let accumulated = func(...args.slice(0, func.length)); | ||
| const remaining = args.slice(func.length); | ||
| for (let i = 0; i < remaining.length; i++) { | ||
| accumulated = func(accumulated, remaining[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (...nextArgs) => curried(...args, ...nextArgs); | ||
| } | ||
| return curried; | ||
| } | ||
| // src/array.ts | ||
| var HARD_RETURN = /* @__PURE__ */ Symbol("hardReturn"); | ||
| var eachArray = (iterator, items) => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| if (iterator(items[i], i) === HARD_RETURN) { | ||
| return; | ||
| } | ||
| } | ||
| }; | ||
| var mapArray = (iterator, items) => { | ||
| const length = items.length; | ||
| const mapped = new Array(length); | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i], i); | ||
| } | ||
| return mapped; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i], i); | ||
| } | ||
| return mapped; | ||
| }; | ||
| var foldArray = (iterator, cumulate, items) => { | ||
| let acc = cumulate; | ||
| if (items.length > 0 && typeof items[0] === "number" && typeof acc === "number") { | ||
| let numberAcc = acc; | ||
| for (let i = 0; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc, items[i], i); | ||
| } | ||
| return numberAcc; | ||
| } | ||
| for (let i = 0; i < items.length; i++) { | ||
| acc = iterator(acc, items[i], i); | ||
| } | ||
| return acc; | ||
| }; | ||
| var reduceArray = (iterator, items) => { | ||
| let acc = items[0]; | ||
| if (items.length > 1 && typeof acc === "number" && typeof items[1] === "number") { | ||
| let numberAcc = acc; | ||
| for (let i = 1; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc, items[i], i - 1); | ||
| } | ||
| return numberAcc; | ||
| } | ||
| for (let i = 1; i < items.length; i++) { | ||
| acc = iterator(acc, items[i], i - 1); | ||
| } | ||
| return acc; | ||
| }; | ||
| var filterArray = (iterator, items) => { | ||
| const filtered = []; | ||
| const length = items.length; | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| if (fn.length >= 2) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| }; | ||
| function each(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => each(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return; | ||
| } | ||
| eachArray(iterator, items); | ||
| } | ||
| function map(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => map(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return mapArray(iterator, items); | ||
| } | ||
| function fold(iterator, cumulate, items) { | ||
| if (arguments.length >= 3) { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return cumulate; | ||
| } | ||
| return foldArray(iterator, cumulate, items); | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next) => fold(iterator, cumulate, next); | ||
| } | ||
| return function(nextCumulate, nextItems) { | ||
| if (arguments.length >= 2) { | ||
| return fold(iterator, nextCumulate, nextItems); | ||
| } | ||
| return (next) => fold(iterator, nextCumulate, next); | ||
| }; | ||
| } | ||
| var foldl = fold; | ||
| function reduce(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => reduce(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items) || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| return reduceArray(iterator, items); | ||
| } | ||
| var reducel = reduce; | ||
| var foldll = reduce; | ||
| function clone(items) { | ||
| const input = items ?? []; | ||
| const result = new Array(input.length); | ||
| for (let i = 0; i < input.length; i++) { | ||
| result[i] = input[i]; | ||
| } | ||
| return result; | ||
| } | ||
| function first(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => first(iterator, next); | ||
| } | ||
| let result; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| result = item; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return result; | ||
| } | ||
| var head = first; | ||
| var take = first; | ||
| function rest(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => rest(iterator, next); | ||
| } | ||
| const result = select(iterator, items); | ||
| result.shift(); | ||
| return result; | ||
| } | ||
| var tail = rest; | ||
| var drop = rest; | ||
| function last(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => last(iterator, next); | ||
| } | ||
| const itemsClone = clone(items); | ||
| return first(iterator, itemsClone.reverse()); | ||
| } | ||
| function every(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => every(iterator, next); | ||
| } | ||
| let isEvery = true; | ||
| each((item, index) => { | ||
| if (!iterator(item, index)) { | ||
| isEvery = false; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return isEvery; | ||
| } | ||
| var all = every; | ||
| function any(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => any(iterator, next); | ||
| } | ||
| let isAny = false; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| isAny = true; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return isAny; | ||
| } | ||
| var contains = any; | ||
| function select(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => select(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return filterArray(iterator, items); | ||
| } | ||
| var filter = select; | ||
| function best(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => best(iterator, next); | ||
| } | ||
| const compare = (arg1, arg2) => { | ||
| return iterator(arg1, arg2) ? arg1 : arg2; | ||
| }; | ||
| return reduce(compare, items); | ||
| } | ||
| function whilst(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => whilst(iterator, next); | ||
| } | ||
| const result = []; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| result.push(item); | ||
| } else { | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return result; | ||
| } | ||
| function partition(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => partition(iterator, next); | ||
| } | ||
| const truthy2 = []; | ||
| const falsy2 = []; | ||
| each((item, index) => { | ||
| (iterator(item, index) ? truthy2 : falsy2).push(item); | ||
| }, items); | ||
| return [truthy2, falsy2]; | ||
| } | ||
| function group(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => group(iterator, next); | ||
| } | ||
| const result = {}; | ||
| each((item) => { | ||
| const key = iterator(item); | ||
| const existing = result[key]; | ||
| if (existing) { | ||
| existing.push(item); | ||
| return; | ||
| } | ||
| result[key] = [item]; | ||
| }, items); | ||
| return result; | ||
| } | ||
| function shuffle(items) { | ||
| const result = clone(items); | ||
| for (let i = 0; i < result.length; i++) { | ||
| const j = Math.floor(Math.random() * (i + 1)); | ||
| const t = result[i]; | ||
| result[i] = result[j]; | ||
| result[j] = t; | ||
| } | ||
| return result; | ||
| } | ||
| var strictEquals = (a, b) => a === b; | ||
| function nub(comparator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => nub(comparator, next); | ||
| } | ||
| const input = items; | ||
| if (comparator === strictEquals) { | ||
| return Array.from(new Set(input)); | ||
| } | ||
| const unique2 = input.length > 0 ? [input[0]] : []; | ||
| each((item) => { | ||
| if (!any((value) => comparator(item, value), unique2)) { | ||
| unique2.push(item); | ||
| } | ||
| }, input); | ||
| return unique2; | ||
| } | ||
| var unique = nub; | ||
| var distinct = nub; | ||
| // src/composition.ts | ||
| function compose(...funcs) { | ||
| const anyInvalid = any((func) => !isFunction(func)); | ||
| const total = funcs.length; | ||
| if (anyInvalid(funcs)) { | ||
| throw new Error("fjs Error: Invalid function to compose"); | ||
| } | ||
| return function(...args) { | ||
| let result = funcs[total - 1].apply(this, args); | ||
| for (let i = total - 2; i >= 0; i--) { | ||
| result = funcs[i].call(this, result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| // src/object.ts | ||
| function toArray(obj) { | ||
| return map((key) => [key, obj[key]], Object.keys(obj)); | ||
| } | ||
| var apply = curry((func, items) => { | ||
| let method; | ||
| let args = []; | ||
| if (isArray(func)) { | ||
| [method, ...args] = func; | ||
| } else { | ||
| method = func; | ||
| } | ||
| return map((item) => { | ||
| const fn = item[method]; | ||
| if (typeof fn === "function") { | ||
| return fn.apply(item, args); | ||
| } | ||
| return fn; | ||
| }, items); | ||
| }); | ||
| var assign = curry((obj1, obj2) => { | ||
| return { ...obj2, ...obj1 }; | ||
| }); | ||
| var extend = assign; | ||
| function prop(property) { | ||
| return function(obj) { | ||
| return obj[property]; | ||
| }; | ||
| } | ||
| var pluck = curry((property, items) => { | ||
| return map(prop(property), items); | ||
| }); | ||
| // src/utilities.ts | ||
| function identity(value) { | ||
| return value; | ||
| } | ||
| function constant(value) { | ||
| return () => value; | ||
| } | ||
| function tap(fn) { | ||
| return (value) => { | ||
| fn(value); | ||
| return value; | ||
| }; | ||
| } | ||
| // src/pipe.ts | ||
| function pipe(value, ...fns) { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i](result); | ||
| } | ||
| return result; | ||
| } | ||
| function flow(...fns) { | ||
| return (value) => { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i](result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| // src/objectOps.ts | ||
| var pick = curry((keys, obj) => { | ||
| const result = {}; | ||
| keys.forEach((key) => { | ||
| if (key in obj) { | ||
| result[key] = obj[key]; | ||
| } | ||
| }); | ||
| return result; | ||
| }); | ||
| var omit = curry((keys, obj) => { | ||
| const result = { ...obj }; | ||
| keys.forEach((key) => { | ||
| delete result[key]; | ||
| }); | ||
| return result; | ||
| }); | ||
| var path = curry((pathArray, obj) => { | ||
| let current = obj; | ||
| for (const key of pathArray) { | ||
| if (current == null) { | ||
| return void 0; | ||
| } | ||
| current = current[key]; | ||
| } | ||
| return current; | ||
| }); | ||
| var assoc = curry((key, value, obj) => { | ||
| return { ...obj, [key]: value }; | ||
| }); | ||
| var dissoc = curry((key, obj) => { | ||
| const result = { ...obj }; | ||
| delete result[key]; | ||
| return result; | ||
| }); | ||
| // src/arrayOps.ts | ||
| var flatMap = curry((fn, items) => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const length = input.length; | ||
| const result = []; | ||
| const mapper = fn; | ||
| for (let i = 0; i < length; i++) { | ||
| const mapped = mapper(input[i], i); | ||
| if (!exists(mapped) || !isArray(mapped)) { | ||
| continue; | ||
| } | ||
| const mappedItems = mapped; | ||
| for (let j = 0; j < mappedItems.length; j++) { | ||
| result.push(mappedItems[j]); | ||
| } | ||
| } | ||
| return result; | ||
| }); | ||
| var chain = flatMap; | ||
| var flatten = (items) => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const result = []; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const subArray = input[i]; | ||
| if (!exists(subArray) || !isArray(subArray)) { | ||
| continue; | ||
| } | ||
| for (let j = 0; j < subArray.length; j++) { | ||
| result.push(subArray[j]); | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| var zip = curry((arr1, arr2) => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result = []; | ||
| for (let i = 0; i < length; i++) { | ||
| result.push([arr1[i], arr2[i]]); | ||
| } | ||
| return result; | ||
| }); | ||
| var zipWith = curry((fn, arr1, arr2) => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| result[i] = fn(arr1[i], arr2[i]); | ||
| } | ||
| return result; | ||
| }); | ||
| var uniq = (items) => { | ||
| return Array.from(new Set(items)); | ||
| }; | ||
| var uniqBy = curry((fn, items) => { | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const result = []; | ||
| each((item) => { | ||
| const key = fn(item); | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| result.push(item); | ||
| } | ||
| }, items); | ||
| return result; | ||
| }); | ||
| // src/async.ts | ||
| var mapAsync = curry(async (fn, items) => { | ||
| const length = items.length; | ||
| const promises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = fn(items[i], i); | ||
| } | ||
| return Promise.all(promises); | ||
| }); | ||
| var filterAsync = curry(async (predicate, items) => { | ||
| const length = items.length; | ||
| const promises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = predicate(items[i], i); | ||
| } | ||
| const results = await Promise.all(promises); | ||
| const filtered = []; | ||
| for (let i = 0; i < length; i++) { | ||
| if (results[i]) { | ||
| filtered.push(items[i]); | ||
| } | ||
| } | ||
| return filtered; | ||
| }); | ||
| var reduceAsync = curry(async (fn, items) => { | ||
| if (!items || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| let accumulator = items[0]; | ||
| for (let i = 1; i < items.length; i++) { | ||
| accumulator = await fn(accumulator, items[i], i); | ||
| } | ||
| return accumulator; | ||
| }); | ||
| var foldAsync = curry(async (fn, initial, items) => { | ||
| let accumulator = initial; | ||
| for (let i = 0; i < items.length; i++) { | ||
| accumulator = await fn(accumulator, items[i], i); | ||
| } | ||
| return accumulator; | ||
| }); | ||
| function mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, items) { | ||
| if (arguments.length < 5) { | ||
| return (next) => mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items; | ||
| let accumulator = initial; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const mapped = await mapFn(input[i], i); | ||
| const keep = await filterFn(mapped, i); | ||
| if (keep) { | ||
| accumulator = await reduceFn(accumulator, mapped, i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| function mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, items) { | ||
| if (arguments.length < 5) { | ||
| return (next) => mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items; | ||
| const length = input.length; | ||
| const mappedPromises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| mappedPromises[i] = Promise.resolve(mapFn(input[i], i)); | ||
| } | ||
| const mapped = await Promise.all(mappedPromises); | ||
| const filterPromises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| filterPromises[i] = Promise.resolve(filterFn(mapped[i], i)); | ||
| } | ||
| const keep = await Promise.all(filterPromises); | ||
| let accumulator = initial; | ||
| for (let i = 0; i < length; i++) { | ||
| if (keep[i]) { | ||
| accumulator = await reduceFn(accumulator, mapped[i], i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| var eachAsync = curry(async (fn, items) => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| await fn(items[i], i); | ||
| } | ||
| }); | ||
| async function pipeAsync(value, ...fns) { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| } | ||
| function flowAsync(...fns) { | ||
| return async (value) => { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| var composeAsync = (...fns) => { | ||
| return async (value) => { | ||
| let result = value; | ||
| for (let i = fns.length - 1; i >= 0; i--) { | ||
| result = await fns[i](result); | ||
| } | ||
| return result; | ||
| }; | ||
| }; | ||
| // src/index.ts | ||
| var fjs = { | ||
| curry, | ||
| each, | ||
| map, | ||
| fold, | ||
| foldl, | ||
| reduce, | ||
| reducel, | ||
| foldll, | ||
| clone, | ||
| first, | ||
| head, | ||
| take, | ||
| rest, | ||
| tail, | ||
| drop, | ||
| last, | ||
| every, | ||
| all, | ||
| any, | ||
| contains, | ||
| select, | ||
| filter, | ||
| best, | ||
| whilst, | ||
| partition, | ||
| group, | ||
| shuffle, | ||
| nub, | ||
| strictEquals, | ||
| unique, | ||
| distinct, | ||
| compose, | ||
| toArray, | ||
| apply, | ||
| assign, | ||
| extend, | ||
| prop, | ||
| pluck, | ||
| isFunction, | ||
| isObject, | ||
| isArray, | ||
| isArguments, | ||
| isDate, | ||
| isNumber, | ||
| isRegExp, | ||
| isString, | ||
| exists, | ||
| truthy, | ||
| falsy, | ||
| identity, | ||
| constant, | ||
| tap, | ||
| pipe, | ||
| flow, | ||
| pick, | ||
| omit, | ||
| path, | ||
| assoc, | ||
| dissoc, | ||
| flatMap, | ||
| chain, | ||
| flatten, | ||
| zip, | ||
| zipWith, | ||
| uniq, | ||
| uniqBy, | ||
| mapAsync, | ||
| filterAsync, | ||
| reduceAsync, | ||
| foldAsync, | ||
| eachAsync, | ||
| pipeAsync, | ||
| flowAsync, | ||
| composeAsync, | ||
| mapFilterReduceAsync, | ||
| mapFilterReduceAsyncParallel | ||
| }; | ||
| exports.all = all; | ||
| exports.any = any; | ||
| exports.apply = apply; | ||
| exports.assign = assign; | ||
| exports.assoc = assoc; | ||
| exports.best = best; | ||
| exports.chain = chain; | ||
| exports.clone = clone; | ||
| exports.compose = compose; | ||
| exports.composeAsync = composeAsync; | ||
| exports.constant = constant; | ||
| exports.contains = contains; | ||
| exports.curry = curry; | ||
| exports.dissoc = dissoc; | ||
| exports.distinct = distinct; | ||
| exports.drop = drop; | ||
| exports.each = each; | ||
| exports.eachAsync = eachAsync; | ||
| exports.every = every; | ||
| exports.exists = exists; | ||
| exports.extend = extend; | ||
| exports.falsy = falsy; | ||
| exports.filter = filter; | ||
| exports.filterAsync = filterAsync; | ||
| exports.first = first; | ||
| exports.fjs = fjs; | ||
| exports.flatMap = flatMap; | ||
| exports.flatten = flatten; | ||
| exports.flow = flow; | ||
| exports.flowAsync = flowAsync; | ||
| exports.fold = fold; | ||
| exports.foldAsync = foldAsync; | ||
| exports.foldl = foldl; | ||
| exports.foldll = foldll; | ||
| exports.group = group; | ||
| exports.head = head; | ||
| exports.identity = identity; | ||
| exports.isArguments = isArguments; | ||
| exports.isArray = isArray; | ||
| exports.isDate = isDate; | ||
| exports.isFunction = isFunction; | ||
| exports.isNumber = isNumber; | ||
| exports.isObject = isObject; | ||
| exports.isRegExp = isRegExp; | ||
| exports.isString = isString; | ||
| exports.last = last; | ||
| exports.map = map; | ||
| exports.mapAsync = mapAsync; | ||
| exports.mapFilterReduceAsync = mapFilterReduceAsync; | ||
| exports.mapFilterReduceAsyncParallel = mapFilterReduceAsyncParallel; | ||
| exports.nub = nub; | ||
| exports.omit = omit; | ||
| exports.partition = partition; | ||
| exports.path = path; | ||
| exports.pick = pick; | ||
| exports.pipe = pipe; | ||
| exports.pipeAsync = pipeAsync; | ||
| exports.pluck = pluck; | ||
| exports.prop = prop; | ||
| exports.reduce = reduce; | ||
| exports.reduceAsync = reduceAsync; | ||
| exports.reducel = reducel; | ||
| exports.rest = rest; | ||
| exports.select = select; | ||
| exports.shuffle = shuffle; | ||
| exports.strictEquals = strictEquals; | ||
| exports.tail = tail; | ||
| exports.take = take; | ||
| exports.tap = tap; | ||
| exports.toArray = toArray; | ||
| exports.truthy = truthy; | ||
| exports.uniq = uniq; | ||
| exports.uniqBy = uniqBy; | ||
| exports.unique = unique; | ||
| exports.whilst = whilst; | ||
| exports.zip = zip; | ||
| exports.zipWith = zipWith; | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"sources":["../src/typeChecks.ts","../src/curry.ts","../src/array.ts","../src/composition.ts","../src/object.ts","../src/utilities.ts","../src/pipe.ts","../src/objectOps.ts","../src/arrayOps.ts","../src/async.ts","../src/index.ts"],"names":["rest","truthy","falsy","unique"],"mappings":"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","file":"index.cjs","sourcesContent":["export function isFunction(obj: unknown): obj is (...args: any[]) => unknown {\n return !!(obj && (obj as any).constructor && (obj as any).call && (obj as any).apply);\n}\n\nexport function isObject(obj: unknown): obj is object {\n return isFunction(obj) || (!!obj && typeof obj === \"object\");\n}\n\nexport function isArray<T = unknown>(obj: unknown): obj is T[] {\n return Array.isArray(obj);\n}\n\nexport function isArguments(obj: unknown): obj is IArguments {\n return Object.prototype.toString.call(obj) === \"[object Arguments]\";\n}\n\nexport function isDate(obj: unknown): obj is Date {\n return Object.prototype.toString.call(obj) === \"[object Date]\";\n}\n\nexport function isNumber(obj: unknown): obj is number {\n return Object.prototype.toString.call(obj) === \"[object Number]\";\n}\n\nexport function isRegExp(obj: unknown): obj is RegExp {\n return Object.prototype.toString.call(obj) === \"[object RegExp]\";\n}\n\nexport function isString(obj: unknown): obj is string {\n return Object.prototype.toString.call(obj) === \"[object String]\";\n}\n\nexport function exists<T>(obj: T | null | undefined): obj is T {\n return obj != null;\n}\n\nexport function truthy<T>(obj: T | null | undefined | false): obj is T {\n return exists(obj) && obj !== false;\n}\n\nexport function falsy(obj: unknown): obj is null | undefined | false {\n return !truthy(obj);\n}\n","import type { AnyFunction, CurriedFunction } from \"./types\";\nimport { isFunction } from \"./typeChecks\";\n\nexport function curry<T extends AnyFunction>(func: T): CurriedFunction<T> {\n if (!isFunction(func)) {\n throw new Error(\"fjs Error: Invalid function\");\n }\n\n if (func.length === 2) {\n const curried2 = function (a: any, b?: any, ...rest: any[]): any {\n if (arguments.length >= 2) {\n if (rest.length === 0) {\n return func(a, b);\n }\n let accumulated = func(a, b);\n for (let i = 0; i < rest.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, rest[i], i);\n }\n return accumulated;\n }\n return (next: any, ...more: any[]) => curried2(a, next, ...more);\n };\n return curried2 as CurriedFunction<T>;\n }\n\n if (func.length === 3) {\n const curried3 = function (a: any, b?: any, c?: any, ...rest: any[]): any {\n if (arguments.length >= 3) {\n if (rest.length === 0) {\n return func(a, b, c);\n }\n let accumulated = func(a, b, c);\n for (let i = 0; i < rest.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, rest[i], i);\n }\n return accumulated;\n }\n if (arguments.length === 2) {\n return (next: any, ...more: any[]) => curried3(a, b, next, ...more);\n }\n return function (nextB: any, nextC?: any, ...more: any[]): any {\n if (arguments.length >= 2) {\n return curried3(a, nextB, nextC, ...more);\n }\n return (next: any, ...moreNext: any[]) => curried3(a, nextB, next, ...moreNext);\n };\n };\n return curried3 as CurriedFunction<T>;\n }\n\n function curried(...args: any[]): any {\n if (args.length === 0) {\n return curried;\n }\n\n if (args.length >= func.length) {\n if (args.length === func.length) {\n return func(...args);\n }\n\n let accumulated = func(...args.slice(0, func.length));\n const remaining = args.slice(func.length);\n\n for (let i = 0; i < remaining.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, remaining[i], i);\n }\n\n return accumulated;\n }\n\n return (...nextArgs: any[]) => curried(...args, ...nextArgs);\n }\n\n return curried as CurriedFunction<T>;\n}\n","import type { Mapper, Predicate, Reducer, Comparator } from \"./types\";\nimport { isArray, exists } from \"./typeChecks\";\n\nconst HARD_RETURN = Symbol(\"hardReturn\");\n\nconst eachArray = <T>(iterator: (value: T, index: number) => any, items: T[]): void => {\n for (let i = 0; i < items.length; i++) {\n if (iterator(items[i]!, i) === HARD_RETURN) {\n return;\n }\n }\n};\n\nconst mapArray = <T, U>(iterator: Mapper<T, U>, items: T[]): U[] => {\n const length = items.length;\n const mapped = new Array<U>(length);\n const fn = iterator;\n if (length > 0 && typeof items[0] === \"number\" && fn.length === 1) {\n for (let i = 0; i < length; i++) {\n mapped[i] = fn(items[i]!, i);\n }\n return mapped;\n }\n for (let i = 0; i < length; i++) {\n mapped[i] = fn(items[i]!, i);\n }\n return mapped;\n};\n\nconst foldArray = <T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U => {\n let acc = cumulate;\n if (items.length > 0 && typeof items[0] === \"number\" && typeof acc === \"number\") {\n let numberAcc = acc as unknown as number;\n for (let i = 0; i < items.length; i++) {\n numberAcc = iterator(numberAcc as unknown as U, items[i]!, i) as unknown as number;\n }\n return numberAcc as unknown as U;\n }\n for (let i = 0; i < items.length; i++) {\n acc = iterator(acc, items[i]!, i);\n }\n return acc;\n};\n\nconst reduceArray = <T>(iterator: Reducer<T, T>, items: T[]): T => {\n let acc = items[0];\n if (items.length > 1 && typeof acc === \"number\" && typeof items[1] === \"number\") {\n let numberAcc = acc as unknown as number;\n for (let i = 1; i < items.length; i++) {\n numberAcc = iterator(numberAcc as unknown as T, items[i]!, i - 1) as unknown as number;\n }\n return numberAcc as unknown as T;\n }\n for (let i = 1; i < items.length; i++) {\n acc = iterator(acc as T, items[i]!, i - 1);\n }\n return acc as T;\n};\n\nconst filterArray = <T>(iterator: Predicate<T>, items: T[]): T[] => {\n const filtered: T[] = [];\n const length = items.length;\n const fn = iterator;\n if (length > 0 && typeof items[0] === \"number\" && fn.length === 1) {\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n }\n if (fn.length >= 2) {\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n }\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n};\n\nexport function each<T>(iterator: (value: T, index: number) => any, items: T[]): void;\nexport function each<T>(iterator: (value: T, index: number) => any): (items: T[]) => void;\nexport function each<T>(iterator: (value: T, index: number) => any, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => each(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return;\n }\n eachArray(iterator, items);\n}\n\nexport function map<T, U>(iterator: Mapper<T, U>, items: T[]): U[];\nexport function map<T, U>(iterator: Mapper<T, U>): (items: T[]) => U[];\nexport function map<T, U>(iterator: Mapper<T, U>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => map(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n return mapArray(iterator, items);\n}\n\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U;\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate: U): (items: T[]) => U;\nexport function fold<T, U>(\n iterator: Reducer<T, U>\n): {\n (cumulate: U, items: T[]): U;\n (cumulate: U): (items: T[]) => U;\n};\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate?: U, items?: T[]): any {\n if (arguments.length >= 3) {\n if (!exists(items) || !isArray(items)) {\n return cumulate as U;\n }\n return foldArray(iterator, cumulate as U, items);\n }\n if (arguments.length === 2) {\n return (next: T[]) => fold(iterator, cumulate as U, next);\n }\n return function (nextCumulate: U, nextItems?: T[]): any {\n if (arguments.length >= 2) {\n return fold(iterator, nextCumulate, nextItems as T[]);\n }\n return (next: T[]) => fold(iterator, nextCumulate, next);\n };\n}\n\nexport const foldl = fold;\n\nexport function reduce<T>(iterator: Reducer<T, T>, items: T[]): T;\nexport function reduce<T>(iterator: Reducer<T, T>): (items: T[]) => T;\nexport function reduce<T>(iterator: Reducer<T, T>, items?: T[]): T | ((items: T[]) => T) {\n if (arguments.length < 2) {\n return (next: T[]) => reduce(iterator, next);\n }\n if (!exists(items) || !isArray(items) || items.length === 0) {\n throw new Error(\"fjs Error: Cannot reduce empty array without initial value\");\n }\n return reduceArray(iterator, items);\n}\n\nexport const reducel = reduce;\nexport const foldll = reduce;\n\nexport function clone<T>(items: T[]): T[] {\n const input = items ?? [];\n const result = new Array<T>(input.length);\n for (let i = 0; i < input.length; i++) {\n result[i] = input[i]!;\n }\n return result;\n}\n\nexport function first<T>(iterator: Predicate<T>, items: T[]): T | undefined;\nexport function first<T>(iterator: Predicate<T>): (items: T[]) => T | undefined;\nexport function first<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => first(iterator, next);\n }\n let result: T | undefined;\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n result = item;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return result;\n}\n\nexport const head = first;\nexport const take = first;\n\nexport function rest<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function rest<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function rest<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => rest(iterator, next);\n }\n const result = select(iterator, items as T[]);\n result.shift();\n return result;\n}\n\nexport const tail = rest;\nexport const drop = rest;\n\nexport function last<T>(iterator: Predicate<T>, items: T[]): T | undefined;\nexport function last<T>(iterator: Predicate<T>): (items: T[]) => T | undefined;\nexport function last<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => last(iterator, next);\n }\n const itemsClone = clone(items as T[]);\n return first(iterator, itemsClone.reverse());\n}\n\nexport function every<T>(iterator: Predicate<T>, items: T[]): boolean;\nexport function every<T>(iterator: Predicate<T>): (items: T[]) => boolean;\nexport function every<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => every(iterator, next);\n }\n let isEvery = true;\n each((item: T, index: number) => {\n if (!iterator(item, index)) {\n isEvery = false;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return isEvery;\n}\n\nexport const all = every;\n\nexport function any<T>(iterator: Predicate<T>, items: T[]): boolean;\nexport function any<T>(iterator: Predicate<T>): (items: T[]) => boolean;\nexport function any<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => any(iterator, next);\n }\n let isAny = false;\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n isAny = true;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return isAny;\n}\n\nexport const contains = any;\n\nexport function select<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function select<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function select<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => select(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n return filterArray(iterator, items);\n}\n\nexport const filter = select;\n\nexport function best<T>(iterator: Comparator<T>, items: T[]): T | undefined;\nexport function best<T>(iterator: Comparator<T>): (items: T[]) => T | undefined;\nexport function best<T>(iterator: Comparator<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => best(iterator, next);\n }\n const compare = (arg1: T, arg2: T): T => {\n return iterator(arg1, arg2) ? arg1 : arg2;\n };\n return reduce(compare, items as T[]);\n}\n\nexport function whilst<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function whilst<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function whilst<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => whilst(iterator, next);\n }\n const result: T[] = [];\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n result.push(item);\n } else {\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return result;\n}\n\nexport function partition<T>(iterator: Predicate<T>, items: T[]): [T[], T[]];\nexport function partition<T>(iterator: Predicate<T>): (items: T[]) => [T[], T[]];\nexport function partition<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => partition(iterator, next);\n }\n const truthy: T[] = [];\n const falsy: T[] = [];\n each((item: T, index: number) => {\n (iterator(item, index) ? truthy : falsy).push(item);\n }, items as T[]);\n return [truthy, falsy];\n}\n\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K,\n items: T[]\n): Record<K, T[]>;\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K\n): (items: T[]) => Record<K, T[]>;\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K,\n items?: T[]\n): any {\n if (arguments.length < 2) {\n return (next: T[]) => group(iterator, next);\n }\n const result = {} as Record<K, T[]>;\n each((item: T) => {\n const key = iterator(item);\n const existing = result[key];\n if (existing) {\n existing.push(item);\n return;\n }\n result[key] = [item];\n }, items as T[]);\n return result;\n}\n\nexport function shuffle<T>(items: T[]): T[] {\n const result = clone(items);\n for (let i = 0; i < result.length; i++) {\n const j = Math.floor(Math.random() * (i + 1));\n const t = result[i]!;\n result[i] = result[j]!;\n result[j] = t;\n }\n return result;\n}\n\nexport const strictEquals = <T>(a: T, b: T): boolean => a === b;\n\nexport function nub<T>(comparator: Comparator<T>, items: T[]): T[];\nexport function nub<T>(comparator: Comparator<T>): (items: T[]) => T[];\nexport function nub<T>(comparator: Comparator<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => nub(comparator, next);\n }\n const input = items as T[];\n if (comparator === strictEquals) {\n return Array.from(new Set(input));\n }\n const unique: T[] = input.length > 0 ? [input[0]!] : [];\n each((item: T) => {\n if (!any((value: T) => comparator(item, value), unique)) {\n unique.push(item);\n }\n }, input);\n return unique;\n}\n\nexport const unique = nub;\nexport const distinct = nub;\n","import type { UnaryFn, AnyFunction } from \"./types\";\nimport { isFunction } from \"./typeChecks\";\nimport { any } from \"./array\";\n\nexport function compose<A>(f: UnaryFn<A, A>): UnaryFn<A, A>;\nexport function compose<A, B>(f: UnaryFn<B, A>, g: UnaryFn<A, B>): UnaryFn<A, A>;\nexport function compose<A, B, C>(\n f: UnaryFn<C, A>,\n g: UnaryFn<B, C>,\n h: UnaryFn<A, B>\n): UnaryFn<A, A>;\nexport function compose<A, B, C, D>(\n f: UnaryFn<D, A>,\n g: UnaryFn<C, D>,\n h: UnaryFn<B, C>,\n i: UnaryFn<A, B>\n): UnaryFn<A, A>;\nexport function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any>;\nexport function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any> {\n const anyInvalid = any((func: unknown) => !isFunction(func));\n const total = funcs.length;\n\n if (anyInvalid(funcs)) {\n throw new Error(\"fjs Error: Invalid function to compose\");\n }\n\n return function (this: any, ...args: any[]) {\n let result: any = (funcs[total - 1] as AnyFunction).apply(this, args);\n for (let i = total - 2; i >= 0; i--) {\n result = (funcs[i] as AnyFunction).call(this, result);\n }\n return result;\n };\n}\n","import type { Curried2 } from \"./types\";\nimport { curry } from \"./curry\";\nimport { map } from \"./array\";\nimport { isArray } from \"./typeChecks\";\n\nexport function toArray<T extends Record<string, any>>(obj: T): Array<[keyof T, T[keyof T]]> {\n return map((key: keyof T) => [key, obj[key]], Object.keys(obj) as Array<keyof T>);\n}\n\nexport const apply = curry(<T extends Record<string, any>, K extends keyof T>(\n func: K | [K, ...any[]],\n items: T[]\n): any[] => {\n let method: K;\n let args: any[] = [];\n\n if (isArray(func)) {\n [method, ...args] = func as [K, ...any[]];\n } else {\n method = func;\n }\n\n return map((item: T) => {\n const fn = item[method];\n if (typeof fn === \"function\") {\n return fn.apply(item, args);\n }\n return fn;\n }, items);\n}) as unknown as Curried2<any, any[], any[]>;\n\nexport const assign = curry(<T extends Record<string, any>, U extends Record<string, any>>(\n obj1: T,\n obj2: U\n): U & T => {\n return { ...obj2, ...obj1 };\n}) as unknown as Curried2<Record<string, any>, Record<string, any>, Record<string, any>>;\n\nexport const extend = assign;\n\nexport function prop<K extends string | number | symbol>(property: K) {\n return function <T extends Record<K, any>>(obj: T): T[K] {\n return obj[property];\n };\n}\n\nexport const pluck = curry(<T, K extends keyof T>(property: K, items: T[]): Array<T[K]> => {\n return map(prop(property), items);\n}) as unknown as Curried2<any, any[], any[]>;\n","export function identity<T>(value: T): T {\n return value;\n}\n\nexport function constant<T>(value: T): () => T {\n return () => value;\n}\n\nexport function tap<T>(fn: (value: T) => void) {\n return (value: T): T => {\n fn(value);\n return value;\n };\n}\n","import type { UnaryFn } from \"./types\";\n\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, fn1: UnaryFn<A, B>): B;\nexport function pipe<A, B, C>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): C;\nexport function pipe<A, B, C, D>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>\n): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>,\n fn5: UnaryFn<E, F>\n): F;\nexport function pipe(value: any, ...fns: UnaryFn<any, any>[]): any {\n let result = value;\n for (let i = 0; i < fns.length; i++) {\n result = fns[i]!(result);\n }\n return result;\n}\n\nexport function flow<A, B>(fn1: UnaryFn<A, B>): UnaryFn<A, B>;\nexport function flow<A, B, C>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): UnaryFn<A, C>;\nexport function flow<A, B, C, D>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>\n): UnaryFn<A, D>;\nexport function flow<A, B, C, D, E>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>\n): UnaryFn<A, E>;\nexport function flow<A, B, C, D, E, F>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>,\n fn5: UnaryFn<E, F>\n): UnaryFn<A, F>;\nexport function flow(...fns: UnaryFn<any, any>[]): UnaryFn<any, any> {\n return (value: any) => {\n let result = value;\n for (let i = 0; i < fns.length; i++) {\n result = fns[i]!(result);\n }\n return result;\n };\n}\n","import type { Curried2, Curried3 } from \"./types\";\nimport { curry } from \"./curry\";\n\nexport const pick = curry(<T extends object, K extends keyof T>(\n keys: K[],\n obj: T\n): Pick<T, K> => {\n const result = {} as Pick<T, K>;\n keys.forEach((key) => {\n if (key in obj) {\n result[key] = obj[key];\n }\n });\n return result;\n}) as unknown as Curried2<string[], any, any>;\n\nexport const omit = curry(<T extends object, K extends keyof T>(\n keys: K[],\n obj: T\n): Omit<T, K> => {\n const result = { ...obj } as any;\n keys.forEach((key) => {\n delete result[key];\n });\n return result as Omit<T, K>;\n}) as unknown as Curried2<string[], any, any>;\n\nexport const path = curry(<T = any>(pathArray: Array<string | number>, obj: any): T | undefined => {\n let current = obj;\n for (const key of pathArray) {\n if (current == null) {\n return undefined;\n }\n current = current[key];\n }\n return current as T;\n}) as unknown as Curried2<Array<string | number>, any, any>;\n\nexport const assoc = curry(<T extends object, K extends keyof T>(\n key: K,\n value: T[K],\n obj: T\n): T => {\n return { ...obj, [key]: value };\n}) as unknown as Curried3<string, any, any, any>;\n\nexport const dissoc = curry(<T extends object, K extends keyof T>(key: K, obj: T): Omit<T, K> => {\n const result = { ...obj } as any;\n delete result[key];\n return result as Omit<T, K>;\n}) as unknown as Curried2<string, any, any>;\n","import type { Curried2, Curried3 } from \"./types\";\nimport { curry } from \"./curry\";\nimport { each } from \"./array\";\nimport { exists, isArray } from \"./typeChecks\";\n\nexport const flatMap = curry(<T, U>(fn: (value: T, index: number) => U[], items: T[]): U[] => {\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n const input = items;\n const length = input.length;\n const result: U[] = [];\n const mapper = fn;\n for (let i = 0; i < length; i++) {\n const mapped = mapper(input[i]!, i);\n if (!exists(mapped) || !isArray(mapped)) {\n continue;\n }\n const mappedItems = mapped;\n for (let j = 0; j < mappedItems.length; j++) {\n result.push(mappedItems[j]!);\n }\n }\n return result;\n}) as unknown as Curried2<(value: any, index: number) => any[], any[], any[]>;\n\nexport const chain = flatMap;\n\nexport const flatten = <T>(items: T[][]): T[] => {\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n const input = items;\n const result: T[] = [];\n for (let i = 0; i < input.length; i++) {\n const subArray = input[i]!;\n if (!exists(subArray) || !isArray(subArray)) {\n continue;\n }\n for (let j = 0; j < subArray.length; j++) {\n result.push(subArray[j]!);\n }\n }\n return result;\n};\n\nexport const zip = curry(<T, U>(arr1: T[], arr2: U[]): Array<[T, U]> => {\n const length = Math.min(arr1.length, arr2.length);\n const result: Array<[T, U]> = [];\n for (let i = 0; i < length; i++) {\n result.push([arr1[i]!, arr2[i]!]);\n }\n return result;\n}) as unknown as Curried2<any[], any[], Array<[any, any]>>;\n\nexport const zipWith = curry(<T, U, R>(\n fn: (a: T, b: U) => R,\n arr1: T[],\n arr2: U[]\n): R[] => {\n const length = Math.min(arr1.length, arr2.length);\n const result = new Array<R>(length);\n for (let i = 0; i < length; i++) {\n result[i] = fn(arr1[i]!, arr2[i]!);\n }\n return result;\n}) as unknown as Curried3<(a: any, b: any) => any, any[], any[], any[]>;\n\nexport const uniq = <T>(items: T[]): T[] => {\n return Array.from(new Set(items));\n};\n\nexport const uniqBy = curry(<T, K>(fn: (value: T) => K, items: T[]): T[] => {\n const seen = new Set<K>();\n const result: T[] = [];\n each((item: T) => {\n const key = fn(item);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(item);\n }\n }, items);\n return result;\n}) as unknown as Curried2<(value: any) => any, any[], any[]>;\n","import type { Curried2, Curried3, UnaryFn } from \"./types\";\nimport { curry } from \"./curry\";\n\nexport const mapAsync = curry(async <T, U>(\n fn: (value: T, index: number) => Promise<U>,\n items: T[]\n): Promise<U[]> => {\n const length = items.length;\n const promises = new Array<Promise<U>>(length);\n for (let i = 0; i < length; i++) {\n promises[i] = fn(items[i]!, i);\n }\n return Promise.all(promises);\n}) as unknown as Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>;\n\nexport const filterAsync = curry(async <T>(\n predicate: (value: T, index: number) => Promise<boolean>,\n items: T[]\n): Promise<T[]> => {\n const length = items.length;\n const promises = new Array<Promise<boolean>>(length);\n for (let i = 0; i < length; i++) {\n promises[i] = predicate(items[i]!, i);\n }\n const results = await Promise.all(promises);\n const filtered: T[] = [];\n for (let i = 0; i < length; i++) {\n if (results[i]) {\n filtered.push(items[i]!);\n }\n }\n return filtered;\n}) as unknown as Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>;\n\nexport const reduceAsync = curry(async <T>(\n fn: (accumulator: T, value: T, index: number) => Promise<T>,\n items: T[]\n): Promise<T> => {\n if (!items || items.length === 0) {\n throw new Error(\"fjs Error: Cannot reduce empty array without initial value\");\n }\n let accumulator: any = items[0]!;\n for (let i = 1; i < items.length; i++) {\n accumulator = (await fn(accumulator, items[i]!, i)) as T;\n }\n return accumulator;\n}) as unknown as Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>;\n\nexport const foldAsync = curry(async <T, U>(\n fn: (accumulator: U, value: T, index: number) => Promise<U>,\n initial: U,\n items: T[]\n): Promise<U> => {\n let accumulator = initial;\n for (let i = 0; i < items.length; i++) {\n accumulator = await fn(accumulator, items[i]!, i);\n }\n return accumulator;\n}) as unknown as Curried3<\n (accumulator: any, value: any, index: number) => Promise<any>,\n any,\n any[],\n Promise<any>\n>;\n\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items: T[]\n): Promise<R>;\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R\n): (items: T[]) => Promise<R>;\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items?: T[]\n): Promise<R> | ((items: T[]) => Promise<R>) {\n if (arguments.length < 5) {\n return (next: T[]) => mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, next);\n }\n return (async () => {\n const input = items as T[];\n let accumulator = initial;\n for (let i = 0; i < input.length; i++) {\n const mapped = await mapFn(input[i]!, i);\n const keep = await filterFn(mapped, i);\n if (keep) {\n accumulator = await reduceFn(accumulator, mapped, i);\n }\n }\n return accumulator;\n })();\n}\n\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items: T[]\n): Promise<R>;\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R\n): (items: T[]) => Promise<R>;\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items?: T[]\n): Promise<R> | ((items: T[]) => Promise<R>) {\n if (arguments.length < 5) {\n return (next: T[]) => mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, next);\n }\n return (async () => {\n const input = items as T[];\n const length = input.length;\n const mappedPromises = new Array<Promise<U>>(length);\n for (let i = 0; i < length; i++) {\n mappedPromises[i] = Promise.resolve(mapFn(input[i]!, i));\n }\n const mapped = await Promise.all(mappedPromises);\n const filterPromises = new Array<Promise<boolean>>(length);\n for (let i = 0; i < length; i++) {\n filterPromises[i] = Promise.resolve(filterFn(mapped[i]!, i));\n }\n const keep = await Promise.all(filterPromises);\n let accumulator = initial;\n for (let i = 0; i < length; i++) {\n if (keep[i]) {\n accumulator = await reduceFn(accumulator, mapped[i]!, i);\n }\n }\n return accumulator;\n })();\n}\n\nexport const eachAsync = curry(async <T>(\n fn: (value: T, index: number) => Promise<void>,\n items: T[]\n): Promise<void> => {\n for (let i = 0; i < items.length; i++) {\n await fn(items[i]!, i);\n }\n}) as unknown as Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>;\n\nexport async function pipeAsync<A>(value: A): Promise<A>;\nexport async function pipeAsync<A, B>(value: A, fn1: UnaryFn<A, Promise<B>>): Promise<B>;\nexport async function pipeAsync<A, B, C>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>\n): Promise<C>;\nexport async function pipeAsync<A, B, C, D>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>\n): Promise<D>;\nexport async function pipeAsync<A, B, C, D, E>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>,\n fn4: UnaryFn<D, Promise<E>>\n): Promise<E>;\nexport async function pipeAsync(value: any, ...fns: UnaryFn<any, Promise<any>>[]): Promise<any> {\n let result = value;\n for (const fn of fns) {\n result = await fn(result);\n }\n return result;\n}\n\nexport function flowAsync<A, B>(fn1: UnaryFn<A, Promise<B>>): UnaryFn<A, Promise<B>>;\nexport function flowAsync<A, B, C>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>\n): UnaryFn<A, Promise<C>>;\nexport function flowAsync<A, B, C, D>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>\n): UnaryFn<A, Promise<D>>;\nexport function flowAsync<A, B, C, D, E>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>,\n fn4: UnaryFn<D, Promise<E>>\n): UnaryFn<A, Promise<E>>;\nexport function flowAsync(...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> {\n return async (value: any) => {\n let result = value;\n for (const fn of fns) {\n result = await fn(result);\n }\n return result;\n };\n}\n\nexport const composeAsync = (...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> => {\n return async (value: any) => {\n let result = value;\n for (let i = fns.length - 1; i >= 0; i--) {\n result = await fns[i]!(result);\n }\n return result;\n };\n};\n","import { curry } from \"./curry\";\nimport {\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct\n} from \"./array\";\nimport { compose } from \"./composition\";\nimport { toArray, apply, assign, extend, prop, pluck } from \"./object\";\nimport {\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy\n} from \"./typeChecks\";\nimport { identity, constant, tap } from \"./utilities\";\nimport { pipe, flow } from \"./pipe\";\nimport { pick, omit, path, assoc, dissoc } from \"./objectOps\";\nimport { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from \"./arrayOps\";\nimport {\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n} from \"./async\";\n\nexport { curry } from \"./curry\";\n\nexport {\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct\n} from \"./array\";\n\nexport { compose } from \"./composition\";\n\nexport { toArray, apply, assign, extend, prop, pluck } from \"./object\";\n\nexport {\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy\n} from \"./typeChecks\";\n\nexport { identity, constant, tap } from \"./utilities\";\n\nexport { pipe, flow } from \"./pipe\";\n\nexport { pick, omit, path, assoc, dissoc } from \"./objectOps\";\n\nexport { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from \"./arrayOps\";\n\nexport {\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n} from \"./async\";\n\nexport type {\n Predicate,\n Comparator,\n Mapper,\n Reducer,\n UnaryFn,\n Curried2,\n Curried3,\n Curried4,\n AnyFunction,\n CurriedFunction\n} from \"./types\";\n\nexport const fjs = {\n curry,\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct,\n compose,\n toArray,\n apply,\n assign,\n extend,\n prop,\n pluck,\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy,\n identity,\n constant,\n tap,\n pipe,\n flow,\n pick,\n omit,\n path,\n assoc,\n dissoc,\n flatMap,\n chain,\n flatten,\n zip,\n zipWith,\n uniq,\n uniqBy,\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n};\n"]} |
+235
| type Predicate<T> = { | ||
| bivarianceHack(value: T, index: number): boolean; | ||
| }["bivarianceHack"]; | ||
| type Comparator<T> = (a: T, b: T) => boolean; | ||
| type Mapper<T, U> = (value: T, index: number) => U; | ||
| type Reducer<T, U> = (accumulator: U, value: T, index: number) => U; | ||
| type UnaryFn<T, U> = (arg: T) => U; | ||
| type Curried2<A, B, R> = { | ||
| (): Curried2<A, B, R>; | ||
| (a: A): (b: B, ...rest: any[]) => R; | ||
| (a: A, b: B, ...rest: any[]): R; | ||
| }; | ||
| type Curried3<A, B, C, R> = { | ||
| (): Curried3<A, B, C, R>; | ||
| (a: A): Curried2<B, C, R>; | ||
| (a: A, b: B): (c: C, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, ...rest: any[]): R; | ||
| }; | ||
| type Curried4<A, B, C, D, R> = { | ||
| (): Curried4<A, B, C, D, R>; | ||
| (a: A): Curried3<B, C, D, R>; | ||
| (a: A, b: B): Curried2<C, D, R>; | ||
| (a: A, b: B, c: C): (d: D, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, d: D, ...rest: any[]): R; | ||
| }; | ||
| type AnyFunction = (...args: any[]) => any; | ||
| type CurriedFunction<T extends AnyFunction> = T extends (a: infer A, b: infer B, c: infer C, d: infer D) => infer R ? Curried4<A, B, C, D, R> : T extends (a: infer A, b: infer B, c: infer C) => infer R ? Curried3<A, B, C, R> : T extends (a: infer A, b: infer B) => infer R ? Curried2<A, B, R> : T; | ||
| declare function curry<T extends AnyFunction>(func: T): CurriedFunction<T>; | ||
| declare function each<T>(iterator: (value: T, index: number) => any, items: T[]): void; | ||
| declare function each<T>(iterator: (value: T, index: number) => any): (items: T[]) => void; | ||
| declare function map<T, U>(iterator: Mapper<T, U>, items: T[]): U[]; | ||
| declare function map<T, U>(iterator: Mapper<T, U>): (items: T[]) => U[]; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>, cumulate: U): (items: T[]) => U; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>): { | ||
| (cumulate: U, items: T[]): U; | ||
| (cumulate: U): (items: T[]) => U; | ||
| }; | ||
| declare const foldl: typeof fold; | ||
| declare function reduce<T>(iterator: Reducer<T, T>, items: T[]): T; | ||
| declare function reduce<T>(iterator: Reducer<T, T>): (items: T[]) => T; | ||
| declare const reducel: typeof reduce; | ||
| declare const foldll: typeof reduce; | ||
| declare function clone<T>(items: T[]): T[]; | ||
| declare function first<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| declare function first<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| declare const head: typeof first; | ||
| declare const take: typeof first; | ||
| declare function rest<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function rest<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare const tail: typeof rest; | ||
| declare const drop: typeof rest; | ||
| declare function last<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| declare function last<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| declare function every<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| declare function every<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| declare const all: typeof every; | ||
| declare function any<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| declare function any<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| declare const contains: typeof any; | ||
| declare function select<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function select<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare const filter: typeof select; | ||
| declare function best<T>(iterator: Comparator<T>, items: T[]): T | undefined; | ||
| declare function best<T>(iterator: Comparator<T>): (items: T[]) => T | undefined; | ||
| declare function whilst<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function whilst<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare function partition<T>(iterator: Predicate<T>, items: T[]): [T[], T[]]; | ||
| declare function partition<T>(iterator: Predicate<T>): (items: T[]) => [T[], T[]]; | ||
| declare function group<T, K extends string | number | symbol>(iterator: (value: T) => K, items: T[]): Record<K, T[]>; | ||
| declare function group<T, K extends string | number | symbol>(iterator: (value: T) => K): (items: T[]) => Record<K, T[]>; | ||
| declare function shuffle<T>(items: T[]): T[]; | ||
| declare const strictEquals: <T>(a: T, b: T) => boolean; | ||
| declare function nub<T>(comparator: Comparator<T>, items: T[]): T[]; | ||
| declare function nub<T>(comparator: Comparator<T>): (items: T[]) => T[]; | ||
| declare const unique: typeof nub; | ||
| declare const distinct: typeof nub; | ||
| declare function compose<A>(f: UnaryFn<A, A>): UnaryFn<A, A>; | ||
| declare function compose<A, B>(f: UnaryFn<B, A>, g: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose<A, B, C>(f: UnaryFn<C, A>, g: UnaryFn<B, C>, h: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose<A, B, C, D>(f: UnaryFn<D, A>, g: UnaryFn<C, D>, h: UnaryFn<B, C>, i: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any>; | ||
| declare function toArray<T extends Record<string, any>>(obj: T): Array<[keyof T, T[keyof T]]>; | ||
| declare const apply: Curried2<any, any[], any[]>; | ||
| declare const assign: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| declare const extend: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| declare function prop<K extends string | number | symbol>(property: K): <T extends Record<K, any>>(obj: T) => T[K]; | ||
| declare const pluck: Curried2<any, any[], any[]>; | ||
| declare function isFunction(obj: unknown): obj is (...args: any[]) => unknown; | ||
| declare function isObject(obj: unknown): obj is object; | ||
| declare function isArray<T = unknown>(obj: unknown): obj is T[]; | ||
| declare function isArguments(obj: unknown): obj is IArguments; | ||
| declare function isDate(obj: unknown): obj is Date; | ||
| declare function isNumber(obj: unknown): obj is number; | ||
| declare function isRegExp(obj: unknown): obj is RegExp; | ||
| declare function isString(obj: unknown): obj is string; | ||
| declare function exists<T>(obj: T | null | undefined): obj is T; | ||
| declare function truthy<T>(obj: T | null | undefined | false): obj is T; | ||
| declare function falsy(obj: unknown): obj is null | undefined | false; | ||
| declare function identity<T>(value: T): T; | ||
| declare function constant<T>(value: T): () => T; | ||
| declare function tap<T>(fn: (value: T) => void): (value: T) => T; | ||
| declare function pipe<A>(value: A): A; | ||
| declare function pipe<A, B>(value: A, fn1: UnaryFn<A, B>): B; | ||
| declare function pipe<A, B, C>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): C; | ||
| declare function pipe<A, B, C, D>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>): D; | ||
| declare function pipe<A, B, C, D, E>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>): E; | ||
| declare function pipe<A, B, C, D, E, F>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>, fn5: UnaryFn<E, F>): F; | ||
| declare function flow<A, B>(fn1: UnaryFn<A, B>): UnaryFn<A, B>; | ||
| declare function flow<A, B, C>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): UnaryFn<A, C>; | ||
| declare function flow<A, B, C, D>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>): UnaryFn<A, D>; | ||
| declare function flow<A, B, C, D, E>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>): UnaryFn<A, E>; | ||
| declare function flow<A, B, C, D, E, F>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>, fn5: UnaryFn<E, F>): UnaryFn<A, F>; | ||
| declare const mapAsync: Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>; | ||
| declare const filterAsync: Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>; | ||
| declare const reduceAsync: Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>; | ||
| declare const foldAsync: Curried3<(accumulator: any, value: any, index: number) => Promise<any>, any, any[], Promise<any>>; | ||
| declare function mapFilterReduceAsync<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R, items: T[]): Promise<R>; | ||
| declare function mapFilterReduceAsync<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R): (items: T[]) => Promise<R>; | ||
| declare function mapFilterReduceAsyncParallel<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R, items: T[]): Promise<R>; | ||
| declare function mapFilterReduceAsyncParallel<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R): (items: T[]) => Promise<R>; | ||
| declare const eachAsync: Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>; | ||
| declare function pipeAsync<A>(value: A): Promise<A>; | ||
| declare function pipeAsync<A, B>(value: A, fn1: UnaryFn<A, Promise<B>>): Promise<B>; | ||
| declare function pipeAsync<A, B, C>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>): Promise<C>; | ||
| declare function pipeAsync<A, B, C, D>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>): Promise<D>; | ||
| declare function pipeAsync<A, B, C, D, E>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>, fn4: UnaryFn<D, Promise<E>>): Promise<E>; | ||
| declare function flowAsync<A, B>(fn1: UnaryFn<A, Promise<B>>): UnaryFn<A, Promise<B>>; | ||
| declare function flowAsync<A, B, C>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>): UnaryFn<A, Promise<C>>; | ||
| declare function flowAsync<A, B, C, D>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>): UnaryFn<A, Promise<D>>; | ||
| declare function flowAsync<A, B, C, D, E>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>, fn4: UnaryFn<D, Promise<E>>): UnaryFn<A, Promise<E>>; | ||
| declare const composeAsync: (...fns: UnaryFn<any, Promise<any>>[]) => UnaryFn<any, Promise<any>>; | ||
| declare const pick: Curried2<string[], any, any>; | ||
| declare const omit: Curried2<string[], any, any>; | ||
| declare const path: Curried2<Array<string | number>, any, any>; | ||
| declare const assoc: Curried3<string, any, any, any>; | ||
| declare const dissoc: Curried2<string, any, any>; | ||
| declare const flatMap: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| declare const chain: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| declare const flatten: <T>(items: T[][]) => T[]; | ||
| declare const zip: Curried2<any[], any[], Array<[any, any]>>; | ||
| declare const zipWith: Curried3<(a: any, b: any) => any, any[], any[], any[]>; | ||
| declare const uniq: <T>(items: T[]) => T[]; | ||
| declare const uniqBy: Curried2<(value: any) => any, any[], any[]>; | ||
| declare const fjs: { | ||
| curry: typeof curry; | ||
| each: typeof each; | ||
| map: typeof map; | ||
| fold: typeof fold; | ||
| foldl: typeof fold; | ||
| reduce: typeof reduce; | ||
| reducel: typeof reduce; | ||
| foldll: typeof reduce; | ||
| clone: typeof clone; | ||
| first: typeof first; | ||
| head: typeof first; | ||
| take: typeof first; | ||
| rest: typeof rest; | ||
| tail: typeof rest; | ||
| drop: typeof rest; | ||
| last: typeof last; | ||
| every: typeof every; | ||
| all: typeof every; | ||
| any: typeof any; | ||
| contains: typeof any; | ||
| select: typeof select; | ||
| filter: typeof select; | ||
| best: typeof best; | ||
| whilst: typeof whilst; | ||
| partition: typeof partition; | ||
| group: typeof group; | ||
| shuffle: typeof shuffle; | ||
| nub: typeof nub; | ||
| strictEquals: <T>(a: T, b: T) => boolean; | ||
| unique: typeof nub; | ||
| distinct: typeof nub; | ||
| compose: typeof compose; | ||
| toArray: typeof toArray; | ||
| apply: Curried2<any, any[], any[]>; | ||
| assign: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| extend: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| prop: typeof prop; | ||
| pluck: Curried2<any, any[], any[]>; | ||
| isFunction: typeof isFunction; | ||
| isObject: typeof isObject; | ||
| isArray: typeof isArray; | ||
| isArguments: typeof isArguments; | ||
| isDate: typeof isDate; | ||
| isNumber: typeof isNumber; | ||
| isRegExp: typeof isRegExp; | ||
| isString: typeof isString; | ||
| exists: typeof exists; | ||
| truthy: typeof truthy; | ||
| falsy: typeof falsy; | ||
| identity: typeof identity; | ||
| constant: typeof constant; | ||
| tap: typeof tap; | ||
| pipe: typeof pipe; | ||
| flow: typeof flow; | ||
| pick: Curried2<string[], any, any>; | ||
| omit: Curried2<string[], any, any>; | ||
| path: Curried2<(string | number)[], any, any>; | ||
| assoc: Curried3<string, any, any, any>; | ||
| dissoc: Curried2<string, any, any>; | ||
| flatMap: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| chain: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| flatten: <T>(items: T[][]) => T[]; | ||
| zip: Curried2<any[], any[], [any, any][]>; | ||
| zipWith: Curried3<(a: any, b: any) => any, any[], any[], any[]>; | ||
| uniq: <T>(items: T[]) => T[]; | ||
| uniqBy: Curried2<(value: any) => any, any[], any[]>; | ||
| mapAsync: Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>; | ||
| filterAsync: Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>; | ||
| reduceAsync: Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>; | ||
| foldAsync: Curried3<(accumulator: any, value: any, index: number) => Promise<any>, any, any[], Promise<any>>; | ||
| eachAsync: Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>; | ||
| pipeAsync: typeof pipeAsync; | ||
| flowAsync: typeof flowAsync; | ||
| composeAsync: (...fns: UnaryFn<any, Promise<any>>[]) => UnaryFn<any, Promise<any>>; | ||
| mapFilterReduceAsync: typeof mapFilterReduceAsync; | ||
| mapFilterReduceAsyncParallel: typeof mapFilterReduceAsyncParallel; | ||
| }; | ||
| export { type AnyFunction, type Comparator, type Curried2, type Curried3, type Curried4, type CurriedFunction, type Mapper, type Predicate, type Reducer, type UnaryFn, all, any, apply, assign, assoc, best, chain, clone, compose, composeAsync, constant, contains, curry, dissoc, distinct, drop, each, eachAsync, every, exists, extend, falsy, filter, filterAsync, first, fjs, flatMap, flatten, flow, flowAsync, fold, foldAsync, foldl, foldll, group, head, identity, isArguments, isArray, isDate, isFunction, isNumber, isObject, isRegExp, isString, last, map, mapAsync, mapFilterReduceAsync, mapFilterReduceAsyncParallel, nub, omit, partition, path, pick, pipe, pipeAsync, pluck, prop, reduce, reduceAsync, reducel, rest, select, shuffle, strictEquals, tail, take, tap, toArray, truthy, uniq, uniqBy, unique, whilst, zip, zipWith }; |
+235
| type Predicate<T> = { | ||
| bivarianceHack(value: T, index: number): boolean; | ||
| }["bivarianceHack"]; | ||
| type Comparator<T> = (a: T, b: T) => boolean; | ||
| type Mapper<T, U> = (value: T, index: number) => U; | ||
| type Reducer<T, U> = (accumulator: U, value: T, index: number) => U; | ||
| type UnaryFn<T, U> = (arg: T) => U; | ||
| type Curried2<A, B, R> = { | ||
| (): Curried2<A, B, R>; | ||
| (a: A): (b: B, ...rest: any[]) => R; | ||
| (a: A, b: B, ...rest: any[]): R; | ||
| }; | ||
| type Curried3<A, B, C, R> = { | ||
| (): Curried3<A, B, C, R>; | ||
| (a: A): Curried2<B, C, R>; | ||
| (a: A, b: B): (c: C, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, ...rest: any[]): R; | ||
| }; | ||
| type Curried4<A, B, C, D, R> = { | ||
| (): Curried4<A, B, C, D, R>; | ||
| (a: A): Curried3<B, C, D, R>; | ||
| (a: A, b: B): Curried2<C, D, R>; | ||
| (a: A, b: B, c: C): (d: D, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, d: D, ...rest: any[]): R; | ||
| }; | ||
| type AnyFunction = (...args: any[]) => any; | ||
| type CurriedFunction<T extends AnyFunction> = T extends (a: infer A, b: infer B, c: infer C, d: infer D) => infer R ? Curried4<A, B, C, D, R> : T extends (a: infer A, b: infer B, c: infer C) => infer R ? Curried3<A, B, C, R> : T extends (a: infer A, b: infer B) => infer R ? Curried2<A, B, R> : T; | ||
| declare function curry<T extends AnyFunction>(func: T): CurriedFunction<T>; | ||
| declare function each<T>(iterator: (value: T, index: number) => any, items: T[]): void; | ||
| declare function each<T>(iterator: (value: T, index: number) => any): (items: T[]) => void; | ||
| declare function map<T, U>(iterator: Mapper<T, U>, items: T[]): U[]; | ||
| declare function map<T, U>(iterator: Mapper<T, U>): (items: T[]) => U[]; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>, cumulate: U): (items: T[]) => U; | ||
| declare function fold<T, U>(iterator: Reducer<T, U>): { | ||
| (cumulate: U, items: T[]): U; | ||
| (cumulate: U): (items: T[]) => U; | ||
| }; | ||
| declare const foldl: typeof fold; | ||
| declare function reduce<T>(iterator: Reducer<T, T>, items: T[]): T; | ||
| declare function reduce<T>(iterator: Reducer<T, T>): (items: T[]) => T; | ||
| declare const reducel: typeof reduce; | ||
| declare const foldll: typeof reduce; | ||
| declare function clone<T>(items: T[]): T[]; | ||
| declare function first<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| declare function first<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| declare const head: typeof first; | ||
| declare const take: typeof first; | ||
| declare function rest<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function rest<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare const tail: typeof rest; | ||
| declare const drop: typeof rest; | ||
| declare function last<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| declare function last<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| declare function every<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| declare function every<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| declare const all: typeof every; | ||
| declare function any<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| declare function any<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| declare const contains: typeof any; | ||
| declare function select<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function select<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare const filter: typeof select; | ||
| declare function best<T>(iterator: Comparator<T>, items: T[]): T | undefined; | ||
| declare function best<T>(iterator: Comparator<T>): (items: T[]) => T | undefined; | ||
| declare function whilst<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| declare function whilst<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| declare function partition<T>(iterator: Predicate<T>, items: T[]): [T[], T[]]; | ||
| declare function partition<T>(iterator: Predicate<T>): (items: T[]) => [T[], T[]]; | ||
| declare function group<T, K extends string | number | symbol>(iterator: (value: T) => K, items: T[]): Record<K, T[]>; | ||
| declare function group<T, K extends string | number | symbol>(iterator: (value: T) => K): (items: T[]) => Record<K, T[]>; | ||
| declare function shuffle<T>(items: T[]): T[]; | ||
| declare const strictEquals: <T>(a: T, b: T) => boolean; | ||
| declare function nub<T>(comparator: Comparator<T>, items: T[]): T[]; | ||
| declare function nub<T>(comparator: Comparator<T>): (items: T[]) => T[]; | ||
| declare const unique: typeof nub; | ||
| declare const distinct: typeof nub; | ||
| declare function compose<A>(f: UnaryFn<A, A>): UnaryFn<A, A>; | ||
| declare function compose<A, B>(f: UnaryFn<B, A>, g: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose<A, B, C>(f: UnaryFn<C, A>, g: UnaryFn<B, C>, h: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose<A, B, C, D>(f: UnaryFn<D, A>, g: UnaryFn<C, D>, h: UnaryFn<B, C>, i: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| declare function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any>; | ||
| declare function toArray<T extends Record<string, any>>(obj: T): Array<[keyof T, T[keyof T]]>; | ||
| declare const apply: Curried2<any, any[], any[]>; | ||
| declare const assign: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| declare const extend: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| declare function prop<K extends string | number | symbol>(property: K): <T extends Record<K, any>>(obj: T) => T[K]; | ||
| declare const pluck: Curried2<any, any[], any[]>; | ||
| declare function isFunction(obj: unknown): obj is (...args: any[]) => unknown; | ||
| declare function isObject(obj: unknown): obj is object; | ||
| declare function isArray<T = unknown>(obj: unknown): obj is T[]; | ||
| declare function isArguments(obj: unknown): obj is IArguments; | ||
| declare function isDate(obj: unknown): obj is Date; | ||
| declare function isNumber(obj: unknown): obj is number; | ||
| declare function isRegExp(obj: unknown): obj is RegExp; | ||
| declare function isString(obj: unknown): obj is string; | ||
| declare function exists<T>(obj: T | null | undefined): obj is T; | ||
| declare function truthy<T>(obj: T | null | undefined | false): obj is T; | ||
| declare function falsy(obj: unknown): obj is null | undefined | false; | ||
| declare function identity<T>(value: T): T; | ||
| declare function constant<T>(value: T): () => T; | ||
| declare function tap<T>(fn: (value: T) => void): (value: T) => T; | ||
| declare function pipe<A>(value: A): A; | ||
| declare function pipe<A, B>(value: A, fn1: UnaryFn<A, B>): B; | ||
| declare function pipe<A, B, C>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): C; | ||
| declare function pipe<A, B, C, D>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>): D; | ||
| declare function pipe<A, B, C, D, E>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>): E; | ||
| declare function pipe<A, B, C, D, E, F>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>, fn5: UnaryFn<E, F>): F; | ||
| declare function flow<A, B>(fn1: UnaryFn<A, B>): UnaryFn<A, B>; | ||
| declare function flow<A, B, C>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): UnaryFn<A, C>; | ||
| declare function flow<A, B, C, D>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>): UnaryFn<A, D>; | ||
| declare function flow<A, B, C, D, E>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>): UnaryFn<A, E>; | ||
| declare function flow<A, B, C, D, E, F>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>, fn3: UnaryFn<C, D>, fn4: UnaryFn<D, E>, fn5: UnaryFn<E, F>): UnaryFn<A, F>; | ||
| declare const mapAsync: Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>; | ||
| declare const filterAsync: Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>; | ||
| declare const reduceAsync: Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>; | ||
| declare const foldAsync: Curried3<(accumulator: any, value: any, index: number) => Promise<any>, any, any[], Promise<any>>; | ||
| declare function mapFilterReduceAsync<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R, items: T[]): Promise<R>; | ||
| declare function mapFilterReduceAsync<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R): (items: T[]) => Promise<R>; | ||
| declare function mapFilterReduceAsyncParallel<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R, items: T[]): Promise<R>; | ||
| declare function mapFilterReduceAsyncParallel<T, U, R>(mapFn: (value: T, index: number) => Promise<U> | U, filterFn: (value: U, index: number) => Promise<boolean> | boolean, reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, initial: R): (items: T[]) => Promise<R>; | ||
| declare const eachAsync: Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>; | ||
| declare function pipeAsync<A>(value: A): Promise<A>; | ||
| declare function pipeAsync<A, B>(value: A, fn1: UnaryFn<A, Promise<B>>): Promise<B>; | ||
| declare function pipeAsync<A, B, C>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>): Promise<C>; | ||
| declare function pipeAsync<A, B, C, D>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>): Promise<D>; | ||
| declare function pipeAsync<A, B, C, D, E>(value: A, fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>, fn4: UnaryFn<D, Promise<E>>): Promise<E>; | ||
| declare function flowAsync<A, B>(fn1: UnaryFn<A, Promise<B>>): UnaryFn<A, Promise<B>>; | ||
| declare function flowAsync<A, B, C>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>): UnaryFn<A, Promise<C>>; | ||
| declare function flowAsync<A, B, C, D>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>): UnaryFn<A, Promise<D>>; | ||
| declare function flowAsync<A, B, C, D, E>(fn1: UnaryFn<A, Promise<B>>, fn2: UnaryFn<B, Promise<C>>, fn3: UnaryFn<C, Promise<D>>, fn4: UnaryFn<D, Promise<E>>): UnaryFn<A, Promise<E>>; | ||
| declare const composeAsync: (...fns: UnaryFn<any, Promise<any>>[]) => UnaryFn<any, Promise<any>>; | ||
| declare const pick: Curried2<string[], any, any>; | ||
| declare const omit: Curried2<string[], any, any>; | ||
| declare const path: Curried2<Array<string | number>, any, any>; | ||
| declare const assoc: Curried3<string, any, any, any>; | ||
| declare const dissoc: Curried2<string, any, any>; | ||
| declare const flatMap: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| declare const chain: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| declare const flatten: <T>(items: T[][]) => T[]; | ||
| declare const zip: Curried2<any[], any[], Array<[any, any]>>; | ||
| declare const zipWith: Curried3<(a: any, b: any) => any, any[], any[], any[]>; | ||
| declare const uniq: <T>(items: T[]) => T[]; | ||
| declare const uniqBy: Curried2<(value: any) => any, any[], any[]>; | ||
| declare const fjs: { | ||
| curry: typeof curry; | ||
| each: typeof each; | ||
| map: typeof map; | ||
| fold: typeof fold; | ||
| foldl: typeof fold; | ||
| reduce: typeof reduce; | ||
| reducel: typeof reduce; | ||
| foldll: typeof reduce; | ||
| clone: typeof clone; | ||
| first: typeof first; | ||
| head: typeof first; | ||
| take: typeof first; | ||
| rest: typeof rest; | ||
| tail: typeof rest; | ||
| drop: typeof rest; | ||
| last: typeof last; | ||
| every: typeof every; | ||
| all: typeof every; | ||
| any: typeof any; | ||
| contains: typeof any; | ||
| select: typeof select; | ||
| filter: typeof select; | ||
| best: typeof best; | ||
| whilst: typeof whilst; | ||
| partition: typeof partition; | ||
| group: typeof group; | ||
| shuffle: typeof shuffle; | ||
| nub: typeof nub; | ||
| strictEquals: <T>(a: T, b: T) => boolean; | ||
| unique: typeof nub; | ||
| distinct: typeof nub; | ||
| compose: typeof compose; | ||
| toArray: typeof toArray; | ||
| apply: Curried2<any, any[], any[]>; | ||
| assign: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| extend: Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| prop: typeof prop; | ||
| pluck: Curried2<any, any[], any[]>; | ||
| isFunction: typeof isFunction; | ||
| isObject: typeof isObject; | ||
| isArray: typeof isArray; | ||
| isArguments: typeof isArguments; | ||
| isDate: typeof isDate; | ||
| isNumber: typeof isNumber; | ||
| isRegExp: typeof isRegExp; | ||
| isString: typeof isString; | ||
| exists: typeof exists; | ||
| truthy: typeof truthy; | ||
| falsy: typeof falsy; | ||
| identity: typeof identity; | ||
| constant: typeof constant; | ||
| tap: typeof tap; | ||
| pipe: typeof pipe; | ||
| flow: typeof flow; | ||
| pick: Curried2<string[], any, any>; | ||
| omit: Curried2<string[], any, any>; | ||
| path: Curried2<(string | number)[], any, any>; | ||
| assoc: Curried3<string, any, any, any>; | ||
| dissoc: Curried2<string, any, any>; | ||
| flatMap: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| chain: Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| flatten: <T>(items: T[][]) => T[]; | ||
| zip: Curried2<any[], any[], [any, any][]>; | ||
| zipWith: Curried3<(a: any, b: any) => any, any[], any[], any[]>; | ||
| uniq: <T>(items: T[]) => T[]; | ||
| uniqBy: Curried2<(value: any) => any, any[], any[]>; | ||
| mapAsync: Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>; | ||
| filterAsync: Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>; | ||
| reduceAsync: Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>; | ||
| foldAsync: Curried3<(accumulator: any, value: any, index: number) => Promise<any>, any, any[], Promise<any>>; | ||
| eachAsync: Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>; | ||
| pipeAsync: typeof pipeAsync; | ||
| flowAsync: typeof flowAsync; | ||
| composeAsync: (...fns: UnaryFn<any, Promise<any>>[]) => UnaryFn<any, Promise<any>>; | ||
| mapFilterReduceAsync: typeof mapFilterReduceAsync; | ||
| mapFilterReduceAsyncParallel: typeof mapFilterReduceAsyncParallel; | ||
| }; | ||
| export { type AnyFunction, type Comparator, type Curried2, type Curried3, type Curried4, type CurriedFunction, type Mapper, type Predicate, type Reducer, type UnaryFn, all, any, apply, assign, assoc, best, chain, clone, compose, composeAsync, constant, contains, curry, dissoc, distinct, drop, each, eachAsync, every, exists, extend, falsy, filter, filterAsync, first, fjs, flatMap, flatten, flow, flowAsync, fold, foldAsync, foldl, foldll, group, head, identity, isArguments, isArray, isDate, isFunction, isNumber, isObject, isRegExp, isString, last, map, mapAsync, mapFilterReduceAsync, mapFilterReduceAsyncParallel, nub, omit, partition, path, pick, pipe, pipeAsync, pluck, prop, reduce, reduceAsync, reducel, rest, select, shuffle, strictEquals, tail, take, tap, toArray, truthy, uniq, uniqBy, unique, whilst, zip, zipWith }; |
+777
| // src/typeChecks.ts | ||
| function isFunction(obj) { | ||
| return !!(obj && obj.constructor && obj.call && obj.apply); | ||
| } | ||
| function isObject(obj) { | ||
| return isFunction(obj) || !!obj && typeof obj === "object"; | ||
| } | ||
| function isArray(obj) { | ||
| return Array.isArray(obj); | ||
| } | ||
| function isArguments(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Arguments]"; | ||
| } | ||
| function isDate(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Date]"; | ||
| } | ||
| function isNumber(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Number]"; | ||
| } | ||
| function isRegExp(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object RegExp]"; | ||
| } | ||
| function isString(obj) { | ||
| return Object.prototype.toString.call(obj) === "[object String]"; | ||
| } | ||
| function exists(obj) { | ||
| return obj != null; | ||
| } | ||
| function truthy(obj) { | ||
| return exists(obj) && obj !== false; | ||
| } | ||
| function falsy(obj) { | ||
| return !truthy(obj); | ||
| } | ||
| // src/curry.ts | ||
| function curry(func) { | ||
| if (!isFunction(func)) { | ||
| throw new Error("fjs Error: Invalid function"); | ||
| } | ||
| if (func.length === 2) { | ||
| const curried2 = function(a, b, ...rest2) { | ||
| if (arguments.length >= 2) { | ||
| if (rest2.length === 0) { | ||
| return func(a, b); | ||
| } | ||
| let accumulated = func(a, b); | ||
| for (let i = 0; i < rest2.length; i++) { | ||
| accumulated = func(accumulated, rest2[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (next, ...more) => curried2(a, next, ...more); | ||
| }; | ||
| return curried2; | ||
| } | ||
| if (func.length === 3) { | ||
| const curried3 = function(a, b, c, ...rest2) { | ||
| if (arguments.length >= 3) { | ||
| if (rest2.length === 0) { | ||
| return func(a, b, c); | ||
| } | ||
| let accumulated = func(a, b, c); | ||
| for (let i = 0; i < rest2.length; i++) { | ||
| accumulated = func(accumulated, rest2[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next, ...more) => curried3(a, b, next, ...more); | ||
| } | ||
| return function(nextB, nextC, ...more) { | ||
| if (arguments.length >= 2) { | ||
| return curried3(a, nextB, nextC, ...more); | ||
| } | ||
| return (next, ...moreNext) => curried3(a, nextB, next, ...moreNext); | ||
| }; | ||
| }; | ||
| return curried3; | ||
| } | ||
| function curried(...args) { | ||
| if (args.length === 0) { | ||
| return curried; | ||
| } | ||
| if (args.length >= func.length) { | ||
| if (args.length === func.length) { | ||
| return func(...args); | ||
| } | ||
| let accumulated = func(...args.slice(0, func.length)); | ||
| const remaining = args.slice(func.length); | ||
| for (let i = 0; i < remaining.length; i++) { | ||
| accumulated = func(accumulated, remaining[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (...nextArgs) => curried(...args, ...nextArgs); | ||
| } | ||
| return curried; | ||
| } | ||
| // src/array.ts | ||
| var HARD_RETURN = /* @__PURE__ */ Symbol("hardReturn"); | ||
| var eachArray = (iterator, items) => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| if (iterator(items[i], i) === HARD_RETURN) { | ||
| return; | ||
| } | ||
| } | ||
| }; | ||
| var mapArray = (iterator, items) => { | ||
| const length = items.length; | ||
| const mapped = new Array(length); | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i], i); | ||
| } | ||
| return mapped; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i], i); | ||
| } | ||
| return mapped; | ||
| }; | ||
| var foldArray = (iterator, cumulate, items) => { | ||
| let acc = cumulate; | ||
| if (items.length > 0 && typeof items[0] === "number" && typeof acc === "number") { | ||
| let numberAcc = acc; | ||
| for (let i = 0; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc, items[i], i); | ||
| } | ||
| return numberAcc; | ||
| } | ||
| for (let i = 0; i < items.length; i++) { | ||
| acc = iterator(acc, items[i], i); | ||
| } | ||
| return acc; | ||
| }; | ||
| var reduceArray = (iterator, items) => { | ||
| let acc = items[0]; | ||
| if (items.length > 1 && typeof acc === "number" && typeof items[1] === "number") { | ||
| let numberAcc = acc; | ||
| for (let i = 1; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc, items[i], i - 1); | ||
| } | ||
| return numberAcc; | ||
| } | ||
| for (let i = 1; i < items.length; i++) { | ||
| acc = iterator(acc, items[i], i - 1); | ||
| } | ||
| return acc; | ||
| }; | ||
| var filterArray = (iterator, items) => { | ||
| const filtered = []; | ||
| const length = items.length; | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| if (fn.length >= 2) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| }; | ||
| function each(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => each(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return; | ||
| } | ||
| eachArray(iterator, items); | ||
| } | ||
| function map(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => map(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return mapArray(iterator, items); | ||
| } | ||
| function fold(iterator, cumulate, items) { | ||
| if (arguments.length >= 3) { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return cumulate; | ||
| } | ||
| return foldArray(iterator, cumulate, items); | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next) => fold(iterator, cumulate, next); | ||
| } | ||
| return function(nextCumulate, nextItems) { | ||
| if (arguments.length >= 2) { | ||
| return fold(iterator, nextCumulate, nextItems); | ||
| } | ||
| return (next) => fold(iterator, nextCumulate, next); | ||
| }; | ||
| } | ||
| var foldl = fold; | ||
| function reduce(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => reduce(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items) || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| return reduceArray(iterator, items); | ||
| } | ||
| var reducel = reduce; | ||
| var foldll = reduce; | ||
| function clone(items) { | ||
| const input = items ?? []; | ||
| const result = new Array(input.length); | ||
| for (let i = 0; i < input.length; i++) { | ||
| result[i] = input[i]; | ||
| } | ||
| return result; | ||
| } | ||
| function first(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => first(iterator, next); | ||
| } | ||
| let result; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| result = item; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return result; | ||
| } | ||
| var head = first; | ||
| var take = first; | ||
| function rest(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => rest(iterator, next); | ||
| } | ||
| const result = select(iterator, items); | ||
| result.shift(); | ||
| return result; | ||
| } | ||
| var tail = rest; | ||
| var drop = rest; | ||
| function last(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => last(iterator, next); | ||
| } | ||
| const itemsClone = clone(items); | ||
| return first(iterator, itemsClone.reverse()); | ||
| } | ||
| function every(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => every(iterator, next); | ||
| } | ||
| let isEvery = true; | ||
| each((item, index) => { | ||
| if (!iterator(item, index)) { | ||
| isEvery = false; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return isEvery; | ||
| } | ||
| var all = every; | ||
| function any(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => any(iterator, next); | ||
| } | ||
| let isAny = false; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| isAny = true; | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return isAny; | ||
| } | ||
| var contains = any; | ||
| function select(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => select(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return filterArray(iterator, items); | ||
| } | ||
| var filter = select; | ||
| function best(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => best(iterator, next); | ||
| } | ||
| const compare = (arg1, arg2) => { | ||
| return iterator(arg1, arg2) ? arg1 : arg2; | ||
| }; | ||
| return reduce(compare, items); | ||
| } | ||
| function whilst(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => whilst(iterator, next); | ||
| } | ||
| const result = []; | ||
| each((item, index) => { | ||
| if (iterator(item, index)) { | ||
| result.push(item); | ||
| } else { | ||
| return HARD_RETURN; | ||
| } | ||
| return void 0; | ||
| }, items); | ||
| return result; | ||
| } | ||
| function partition(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => partition(iterator, next); | ||
| } | ||
| const truthy2 = []; | ||
| const falsy2 = []; | ||
| each((item, index) => { | ||
| (iterator(item, index) ? truthy2 : falsy2).push(item); | ||
| }, items); | ||
| return [truthy2, falsy2]; | ||
| } | ||
| function group(iterator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => group(iterator, next); | ||
| } | ||
| const result = {}; | ||
| each((item) => { | ||
| const key = iterator(item); | ||
| const existing = result[key]; | ||
| if (existing) { | ||
| existing.push(item); | ||
| return; | ||
| } | ||
| result[key] = [item]; | ||
| }, items); | ||
| return result; | ||
| } | ||
| function shuffle(items) { | ||
| const result = clone(items); | ||
| for (let i = 0; i < result.length; i++) { | ||
| const j = Math.floor(Math.random() * (i + 1)); | ||
| const t = result[i]; | ||
| result[i] = result[j]; | ||
| result[j] = t; | ||
| } | ||
| return result; | ||
| } | ||
| var strictEquals = (a, b) => a === b; | ||
| function nub(comparator, items) { | ||
| if (arguments.length < 2) { | ||
| return (next) => nub(comparator, next); | ||
| } | ||
| const input = items; | ||
| if (comparator === strictEquals) { | ||
| return Array.from(new Set(input)); | ||
| } | ||
| const unique2 = input.length > 0 ? [input[0]] : []; | ||
| each((item) => { | ||
| if (!any((value) => comparator(item, value), unique2)) { | ||
| unique2.push(item); | ||
| } | ||
| }, input); | ||
| return unique2; | ||
| } | ||
| var unique = nub; | ||
| var distinct = nub; | ||
| // src/composition.ts | ||
| function compose(...funcs) { | ||
| const anyInvalid = any((func) => !isFunction(func)); | ||
| const total = funcs.length; | ||
| if (anyInvalid(funcs)) { | ||
| throw new Error("fjs Error: Invalid function to compose"); | ||
| } | ||
| return function(...args) { | ||
| let result = funcs[total - 1].apply(this, args); | ||
| for (let i = total - 2; i >= 0; i--) { | ||
| result = funcs[i].call(this, result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| // src/object.ts | ||
| function toArray(obj) { | ||
| return map((key) => [key, obj[key]], Object.keys(obj)); | ||
| } | ||
| var apply = curry((func, items) => { | ||
| let method; | ||
| let args = []; | ||
| if (isArray(func)) { | ||
| [method, ...args] = func; | ||
| } else { | ||
| method = func; | ||
| } | ||
| return map((item) => { | ||
| const fn = item[method]; | ||
| if (typeof fn === "function") { | ||
| return fn.apply(item, args); | ||
| } | ||
| return fn; | ||
| }, items); | ||
| }); | ||
| var assign = curry((obj1, obj2) => { | ||
| return { ...obj2, ...obj1 }; | ||
| }); | ||
| var extend = assign; | ||
| function prop(property) { | ||
| return function(obj) { | ||
| return obj[property]; | ||
| }; | ||
| } | ||
| var pluck = curry((property, items) => { | ||
| return map(prop(property), items); | ||
| }); | ||
| // src/utilities.ts | ||
| function identity(value) { | ||
| return value; | ||
| } | ||
| function constant(value) { | ||
| return () => value; | ||
| } | ||
| function tap(fn) { | ||
| return (value) => { | ||
| fn(value); | ||
| return value; | ||
| }; | ||
| } | ||
| // src/pipe.ts | ||
| function pipe(value, ...fns) { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i](result); | ||
| } | ||
| return result; | ||
| } | ||
| function flow(...fns) { | ||
| return (value) => { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i](result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| // src/objectOps.ts | ||
| var pick = curry((keys, obj) => { | ||
| const result = {}; | ||
| keys.forEach((key) => { | ||
| if (key in obj) { | ||
| result[key] = obj[key]; | ||
| } | ||
| }); | ||
| return result; | ||
| }); | ||
| var omit = curry((keys, obj) => { | ||
| const result = { ...obj }; | ||
| keys.forEach((key) => { | ||
| delete result[key]; | ||
| }); | ||
| return result; | ||
| }); | ||
| var path = curry((pathArray, obj) => { | ||
| let current = obj; | ||
| for (const key of pathArray) { | ||
| if (current == null) { | ||
| return void 0; | ||
| } | ||
| current = current[key]; | ||
| } | ||
| return current; | ||
| }); | ||
| var assoc = curry((key, value, obj) => { | ||
| return { ...obj, [key]: value }; | ||
| }); | ||
| var dissoc = curry((key, obj) => { | ||
| const result = { ...obj }; | ||
| delete result[key]; | ||
| return result; | ||
| }); | ||
| // src/arrayOps.ts | ||
| var flatMap = curry((fn, items) => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const length = input.length; | ||
| const result = []; | ||
| const mapper = fn; | ||
| for (let i = 0; i < length; i++) { | ||
| const mapped = mapper(input[i], i); | ||
| if (!exists(mapped) || !isArray(mapped)) { | ||
| continue; | ||
| } | ||
| const mappedItems = mapped; | ||
| for (let j = 0; j < mappedItems.length; j++) { | ||
| result.push(mappedItems[j]); | ||
| } | ||
| } | ||
| return result; | ||
| }); | ||
| var chain = flatMap; | ||
| var flatten = (items) => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const result = []; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const subArray = input[i]; | ||
| if (!exists(subArray) || !isArray(subArray)) { | ||
| continue; | ||
| } | ||
| for (let j = 0; j < subArray.length; j++) { | ||
| result.push(subArray[j]); | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| var zip = curry((arr1, arr2) => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result = []; | ||
| for (let i = 0; i < length; i++) { | ||
| result.push([arr1[i], arr2[i]]); | ||
| } | ||
| return result; | ||
| }); | ||
| var zipWith = curry((fn, arr1, arr2) => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| result[i] = fn(arr1[i], arr2[i]); | ||
| } | ||
| return result; | ||
| }); | ||
| var uniq = (items) => { | ||
| return Array.from(new Set(items)); | ||
| }; | ||
| var uniqBy = curry((fn, items) => { | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const result = []; | ||
| each((item) => { | ||
| const key = fn(item); | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| result.push(item); | ||
| } | ||
| }, items); | ||
| return result; | ||
| }); | ||
| // src/async.ts | ||
| var mapAsync = curry(async (fn, items) => { | ||
| const length = items.length; | ||
| const promises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = fn(items[i], i); | ||
| } | ||
| return Promise.all(promises); | ||
| }); | ||
| var filterAsync = curry(async (predicate, items) => { | ||
| const length = items.length; | ||
| const promises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = predicate(items[i], i); | ||
| } | ||
| const results = await Promise.all(promises); | ||
| const filtered = []; | ||
| for (let i = 0; i < length; i++) { | ||
| if (results[i]) { | ||
| filtered.push(items[i]); | ||
| } | ||
| } | ||
| return filtered; | ||
| }); | ||
| var reduceAsync = curry(async (fn, items) => { | ||
| if (!items || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| let accumulator = items[0]; | ||
| for (let i = 1; i < items.length; i++) { | ||
| accumulator = await fn(accumulator, items[i], i); | ||
| } | ||
| return accumulator; | ||
| }); | ||
| var foldAsync = curry(async (fn, initial, items) => { | ||
| let accumulator = initial; | ||
| for (let i = 0; i < items.length; i++) { | ||
| accumulator = await fn(accumulator, items[i], i); | ||
| } | ||
| return accumulator; | ||
| }); | ||
| function mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, items) { | ||
| if (arguments.length < 5) { | ||
| return (next) => mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items; | ||
| let accumulator = initial; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const mapped = await mapFn(input[i], i); | ||
| const keep = await filterFn(mapped, i); | ||
| if (keep) { | ||
| accumulator = await reduceFn(accumulator, mapped, i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| function mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, items) { | ||
| if (arguments.length < 5) { | ||
| return (next) => mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items; | ||
| const length = input.length; | ||
| const mappedPromises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| mappedPromises[i] = Promise.resolve(mapFn(input[i], i)); | ||
| } | ||
| const mapped = await Promise.all(mappedPromises); | ||
| const filterPromises = new Array(length); | ||
| for (let i = 0; i < length; i++) { | ||
| filterPromises[i] = Promise.resolve(filterFn(mapped[i], i)); | ||
| } | ||
| const keep = await Promise.all(filterPromises); | ||
| let accumulator = initial; | ||
| for (let i = 0; i < length; i++) { | ||
| if (keep[i]) { | ||
| accumulator = await reduceFn(accumulator, mapped[i], i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| var eachAsync = curry(async (fn, items) => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| await fn(items[i], i); | ||
| } | ||
| }); | ||
| async function pipeAsync(value, ...fns) { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| } | ||
| function flowAsync(...fns) { | ||
| return async (value) => { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| var composeAsync = (...fns) => { | ||
| return async (value) => { | ||
| let result = value; | ||
| for (let i = fns.length - 1; i >= 0; i--) { | ||
| result = await fns[i](result); | ||
| } | ||
| return result; | ||
| }; | ||
| }; | ||
| // src/index.ts | ||
| var fjs = { | ||
| curry, | ||
| each, | ||
| map, | ||
| fold, | ||
| foldl, | ||
| reduce, | ||
| reducel, | ||
| foldll, | ||
| clone, | ||
| first, | ||
| head, | ||
| take, | ||
| rest, | ||
| tail, | ||
| drop, | ||
| last, | ||
| every, | ||
| all, | ||
| any, | ||
| contains, | ||
| select, | ||
| filter, | ||
| best, | ||
| whilst, | ||
| partition, | ||
| group, | ||
| shuffle, | ||
| nub, | ||
| strictEquals, | ||
| unique, | ||
| distinct, | ||
| compose, | ||
| toArray, | ||
| apply, | ||
| assign, | ||
| extend, | ||
| prop, | ||
| pluck, | ||
| isFunction, | ||
| isObject, | ||
| isArray, | ||
| isArguments, | ||
| isDate, | ||
| isNumber, | ||
| isRegExp, | ||
| isString, | ||
| exists, | ||
| truthy, | ||
| falsy, | ||
| identity, | ||
| constant, | ||
| tap, | ||
| pipe, | ||
| flow, | ||
| pick, | ||
| omit, | ||
| path, | ||
| assoc, | ||
| dissoc, | ||
| flatMap, | ||
| chain, | ||
| flatten, | ||
| zip, | ||
| zipWith, | ||
| uniq, | ||
| uniqBy, | ||
| mapAsync, | ||
| filterAsync, | ||
| reduceAsync, | ||
| foldAsync, | ||
| eachAsync, | ||
| pipeAsync, | ||
| flowAsync, | ||
| composeAsync, | ||
| mapFilterReduceAsync, | ||
| mapFilterReduceAsyncParallel | ||
| }; | ||
| export { all, any, apply, assign, assoc, best, chain, clone, compose, composeAsync, constant, contains, curry, dissoc, distinct, drop, each, eachAsync, every, exists, extend, falsy, filter, filterAsync, first, fjs, flatMap, flatten, flow, flowAsync, fold, foldAsync, foldl, foldll, group, head, identity, isArguments, isArray, isDate, isFunction, isNumber, isObject, isRegExp, isString, last, map, mapAsync, mapFilterReduceAsync, mapFilterReduceAsyncParallel, nub, omit, partition, path, pick, pipe, pipeAsync, pluck, prop, reduce, reduceAsync, reducel, rest, select, shuffle, strictEquals, tail, take, tap, toArray, truthy, uniq, uniqBy, unique, whilst, zip, zipWith }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"sources":["../src/typeChecks.ts","../src/curry.ts","../src/array.ts","../src/composition.ts","../src/object.ts","../src/utilities.ts","../src/pipe.ts","../src/objectOps.ts","../src/arrayOps.ts","../src/async.ts","../src/index.ts"],"names":["rest","truthy","falsy","unique"],"mappings":"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","file":"index.js","sourcesContent":["export function isFunction(obj: unknown): obj is (...args: any[]) => unknown {\n return !!(obj && (obj as any).constructor && (obj as any).call && (obj as any).apply);\n}\n\nexport function isObject(obj: unknown): obj is object {\n return isFunction(obj) || (!!obj && typeof obj === \"object\");\n}\n\nexport function isArray<T = unknown>(obj: unknown): obj is T[] {\n return Array.isArray(obj);\n}\n\nexport function isArguments(obj: unknown): obj is IArguments {\n return Object.prototype.toString.call(obj) === \"[object Arguments]\";\n}\n\nexport function isDate(obj: unknown): obj is Date {\n return Object.prototype.toString.call(obj) === \"[object Date]\";\n}\n\nexport function isNumber(obj: unknown): obj is number {\n return Object.prototype.toString.call(obj) === \"[object Number]\";\n}\n\nexport function isRegExp(obj: unknown): obj is RegExp {\n return Object.prototype.toString.call(obj) === \"[object RegExp]\";\n}\n\nexport function isString(obj: unknown): obj is string {\n return Object.prototype.toString.call(obj) === \"[object String]\";\n}\n\nexport function exists<T>(obj: T | null | undefined): obj is T {\n return obj != null;\n}\n\nexport function truthy<T>(obj: T | null | undefined | false): obj is T {\n return exists(obj) && obj !== false;\n}\n\nexport function falsy(obj: unknown): obj is null | undefined | false {\n return !truthy(obj);\n}\n","import type { AnyFunction, CurriedFunction } from \"./types\";\nimport { isFunction } from \"./typeChecks\";\n\nexport function curry<T extends AnyFunction>(func: T): CurriedFunction<T> {\n if (!isFunction(func)) {\n throw new Error(\"fjs Error: Invalid function\");\n }\n\n if (func.length === 2) {\n const curried2 = function (a: any, b?: any, ...rest: any[]): any {\n if (arguments.length >= 2) {\n if (rest.length === 0) {\n return func(a, b);\n }\n let accumulated = func(a, b);\n for (let i = 0; i < rest.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, rest[i], i);\n }\n return accumulated;\n }\n return (next: any, ...more: any[]) => curried2(a, next, ...more);\n };\n return curried2 as CurriedFunction<T>;\n }\n\n if (func.length === 3) {\n const curried3 = function (a: any, b?: any, c?: any, ...rest: any[]): any {\n if (arguments.length >= 3) {\n if (rest.length === 0) {\n return func(a, b, c);\n }\n let accumulated = func(a, b, c);\n for (let i = 0; i < rest.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, rest[i], i);\n }\n return accumulated;\n }\n if (arguments.length === 2) {\n return (next: any, ...more: any[]) => curried3(a, b, next, ...more);\n }\n return function (nextB: any, nextC?: any, ...more: any[]): any {\n if (arguments.length >= 2) {\n return curried3(a, nextB, nextC, ...more);\n }\n return (next: any, ...moreNext: any[]) => curried3(a, nextB, next, ...moreNext);\n };\n };\n return curried3 as CurriedFunction<T>;\n }\n\n function curried(...args: any[]): any {\n if (args.length === 0) {\n return curried;\n }\n\n if (args.length >= func.length) {\n if (args.length === func.length) {\n return func(...args);\n }\n\n let accumulated = func(...args.slice(0, func.length));\n const remaining = args.slice(func.length);\n\n for (let i = 0; i < remaining.length; i++) {\n accumulated = (func as AnyFunction)(accumulated, remaining[i], i);\n }\n\n return accumulated;\n }\n\n return (...nextArgs: any[]) => curried(...args, ...nextArgs);\n }\n\n return curried as CurriedFunction<T>;\n}\n","import type { Mapper, Predicate, Reducer, Comparator } from \"./types\";\nimport { isArray, exists } from \"./typeChecks\";\n\nconst HARD_RETURN = Symbol(\"hardReturn\");\n\nconst eachArray = <T>(iterator: (value: T, index: number) => any, items: T[]): void => {\n for (let i = 0; i < items.length; i++) {\n if (iterator(items[i]!, i) === HARD_RETURN) {\n return;\n }\n }\n};\n\nconst mapArray = <T, U>(iterator: Mapper<T, U>, items: T[]): U[] => {\n const length = items.length;\n const mapped = new Array<U>(length);\n const fn = iterator;\n if (length > 0 && typeof items[0] === \"number\" && fn.length === 1) {\n for (let i = 0; i < length; i++) {\n mapped[i] = fn(items[i]!, i);\n }\n return mapped;\n }\n for (let i = 0; i < length; i++) {\n mapped[i] = fn(items[i]!, i);\n }\n return mapped;\n};\n\nconst foldArray = <T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U => {\n let acc = cumulate;\n if (items.length > 0 && typeof items[0] === \"number\" && typeof acc === \"number\") {\n let numberAcc = acc as unknown as number;\n for (let i = 0; i < items.length; i++) {\n numberAcc = iterator(numberAcc as unknown as U, items[i]!, i) as unknown as number;\n }\n return numberAcc as unknown as U;\n }\n for (let i = 0; i < items.length; i++) {\n acc = iterator(acc, items[i]!, i);\n }\n return acc;\n};\n\nconst reduceArray = <T>(iterator: Reducer<T, T>, items: T[]): T => {\n let acc = items[0];\n if (items.length > 1 && typeof acc === \"number\" && typeof items[1] === \"number\") {\n let numberAcc = acc as unknown as number;\n for (let i = 1; i < items.length; i++) {\n numberAcc = iterator(numberAcc as unknown as T, items[i]!, i - 1) as unknown as number;\n }\n return numberAcc as unknown as T;\n }\n for (let i = 1; i < items.length; i++) {\n acc = iterator(acc as T, items[i]!, i - 1);\n }\n return acc as T;\n};\n\nconst filterArray = <T>(iterator: Predicate<T>, items: T[]): T[] => {\n const filtered: T[] = [];\n const length = items.length;\n const fn = iterator;\n if (length > 0 && typeof items[0] === \"number\" && fn.length === 1) {\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n }\n if (fn.length >= 2) {\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n }\n for (let i = 0; i < length; i++) {\n const value = items[i]!;\n if (fn(value, i)) {\n filtered.push(value);\n }\n }\n return filtered;\n};\n\nexport function each<T>(iterator: (value: T, index: number) => any, items: T[]): void;\nexport function each<T>(iterator: (value: T, index: number) => any): (items: T[]) => void;\nexport function each<T>(iterator: (value: T, index: number) => any, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => each(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return;\n }\n eachArray(iterator, items);\n}\n\nexport function map<T, U>(iterator: Mapper<T, U>, items: T[]): U[];\nexport function map<T, U>(iterator: Mapper<T, U>): (items: T[]) => U[];\nexport function map<T, U>(iterator: Mapper<T, U>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => map(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n return mapArray(iterator, items);\n}\n\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U;\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate: U): (items: T[]) => U;\nexport function fold<T, U>(\n iterator: Reducer<T, U>\n): {\n (cumulate: U, items: T[]): U;\n (cumulate: U): (items: T[]) => U;\n};\nexport function fold<T, U>(iterator: Reducer<T, U>, cumulate?: U, items?: T[]): any {\n if (arguments.length >= 3) {\n if (!exists(items) || !isArray(items)) {\n return cumulate as U;\n }\n return foldArray(iterator, cumulate as U, items);\n }\n if (arguments.length === 2) {\n return (next: T[]) => fold(iterator, cumulate as U, next);\n }\n return function (nextCumulate: U, nextItems?: T[]): any {\n if (arguments.length >= 2) {\n return fold(iterator, nextCumulate, nextItems as T[]);\n }\n return (next: T[]) => fold(iterator, nextCumulate, next);\n };\n}\n\nexport const foldl = fold;\n\nexport function reduce<T>(iterator: Reducer<T, T>, items: T[]): T;\nexport function reduce<T>(iterator: Reducer<T, T>): (items: T[]) => T;\nexport function reduce<T>(iterator: Reducer<T, T>, items?: T[]): T | ((items: T[]) => T) {\n if (arguments.length < 2) {\n return (next: T[]) => reduce(iterator, next);\n }\n if (!exists(items) || !isArray(items) || items.length === 0) {\n throw new Error(\"fjs Error: Cannot reduce empty array without initial value\");\n }\n return reduceArray(iterator, items);\n}\n\nexport const reducel = reduce;\nexport const foldll = reduce;\n\nexport function clone<T>(items: T[]): T[] {\n const input = items ?? [];\n const result = new Array<T>(input.length);\n for (let i = 0; i < input.length; i++) {\n result[i] = input[i]!;\n }\n return result;\n}\n\nexport function first<T>(iterator: Predicate<T>, items: T[]): T | undefined;\nexport function first<T>(iterator: Predicate<T>): (items: T[]) => T | undefined;\nexport function first<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => first(iterator, next);\n }\n let result: T | undefined;\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n result = item;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return result;\n}\n\nexport const head = first;\nexport const take = first;\n\nexport function rest<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function rest<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function rest<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => rest(iterator, next);\n }\n const result = select(iterator, items as T[]);\n result.shift();\n return result;\n}\n\nexport const tail = rest;\nexport const drop = rest;\n\nexport function last<T>(iterator: Predicate<T>, items: T[]): T | undefined;\nexport function last<T>(iterator: Predicate<T>): (items: T[]) => T | undefined;\nexport function last<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => last(iterator, next);\n }\n const itemsClone = clone(items as T[]);\n return first(iterator, itemsClone.reverse());\n}\n\nexport function every<T>(iterator: Predicate<T>, items: T[]): boolean;\nexport function every<T>(iterator: Predicate<T>): (items: T[]) => boolean;\nexport function every<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => every(iterator, next);\n }\n let isEvery = true;\n each((item: T, index: number) => {\n if (!iterator(item, index)) {\n isEvery = false;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return isEvery;\n}\n\nexport const all = every;\n\nexport function any<T>(iterator: Predicate<T>, items: T[]): boolean;\nexport function any<T>(iterator: Predicate<T>): (items: T[]) => boolean;\nexport function any<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => any(iterator, next);\n }\n let isAny = false;\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n isAny = true;\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return isAny;\n}\n\nexport const contains = any;\n\nexport function select<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function select<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function select<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => select(iterator, next);\n }\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n return filterArray(iterator, items);\n}\n\nexport const filter = select;\n\nexport function best<T>(iterator: Comparator<T>, items: T[]): T | undefined;\nexport function best<T>(iterator: Comparator<T>): (items: T[]) => T | undefined;\nexport function best<T>(iterator: Comparator<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => best(iterator, next);\n }\n const compare = (arg1: T, arg2: T): T => {\n return iterator(arg1, arg2) ? arg1 : arg2;\n };\n return reduce(compare, items as T[]);\n}\n\nexport function whilst<T>(iterator: Predicate<T>, items: T[]): T[];\nexport function whilst<T>(iterator: Predicate<T>): (items: T[]) => T[];\nexport function whilst<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => whilst(iterator, next);\n }\n const result: T[] = [];\n each((item: T, index: number) => {\n if (iterator(item, index)) {\n result.push(item);\n } else {\n return HARD_RETURN;\n }\n return undefined;\n }, items as T[]);\n return result;\n}\n\nexport function partition<T>(iterator: Predicate<T>, items: T[]): [T[], T[]];\nexport function partition<T>(iterator: Predicate<T>): (items: T[]) => [T[], T[]];\nexport function partition<T>(iterator: Predicate<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => partition(iterator, next);\n }\n const truthy: T[] = [];\n const falsy: T[] = [];\n each((item: T, index: number) => {\n (iterator(item, index) ? truthy : falsy).push(item);\n }, items as T[]);\n return [truthy, falsy];\n}\n\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K,\n items: T[]\n): Record<K, T[]>;\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K\n): (items: T[]) => Record<K, T[]>;\nexport function group<T, K extends string | number | symbol>(\n iterator: (value: T) => K,\n items?: T[]\n): any {\n if (arguments.length < 2) {\n return (next: T[]) => group(iterator, next);\n }\n const result = {} as Record<K, T[]>;\n each((item: T) => {\n const key = iterator(item);\n const existing = result[key];\n if (existing) {\n existing.push(item);\n return;\n }\n result[key] = [item];\n }, items as T[]);\n return result;\n}\n\nexport function shuffle<T>(items: T[]): T[] {\n const result = clone(items);\n for (let i = 0; i < result.length; i++) {\n const j = Math.floor(Math.random() * (i + 1));\n const t = result[i]!;\n result[i] = result[j]!;\n result[j] = t;\n }\n return result;\n}\n\nexport const strictEquals = <T>(a: T, b: T): boolean => a === b;\n\nexport function nub<T>(comparator: Comparator<T>, items: T[]): T[];\nexport function nub<T>(comparator: Comparator<T>): (items: T[]) => T[];\nexport function nub<T>(comparator: Comparator<T>, items?: T[]): any {\n if (arguments.length < 2) {\n return (next: T[]) => nub(comparator, next);\n }\n const input = items as T[];\n if (comparator === strictEquals) {\n return Array.from(new Set(input));\n }\n const unique: T[] = input.length > 0 ? [input[0]!] : [];\n each((item: T) => {\n if (!any((value: T) => comparator(item, value), unique)) {\n unique.push(item);\n }\n }, input);\n return unique;\n}\n\nexport const unique = nub;\nexport const distinct = nub;\n","import type { UnaryFn, AnyFunction } from \"./types\";\nimport { isFunction } from \"./typeChecks\";\nimport { any } from \"./array\";\n\nexport function compose<A>(f: UnaryFn<A, A>): UnaryFn<A, A>;\nexport function compose<A, B>(f: UnaryFn<B, A>, g: UnaryFn<A, B>): UnaryFn<A, A>;\nexport function compose<A, B, C>(\n f: UnaryFn<C, A>,\n g: UnaryFn<B, C>,\n h: UnaryFn<A, B>\n): UnaryFn<A, A>;\nexport function compose<A, B, C, D>(\n f: UnaryFn<D, A>,\n g: UnaryFn<C, D>,\n h: UnaryFn<B, C>,\n i: UnaryFn<A, B>\n): UnaryFn<A, A>;\nexport function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any>;\nexport function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any> {\n const anyInvalid = any((func: unknown) => !isFunction(func));\n const total = funcs.length;\n\n if (anyInvalid(funcs)) {\n throw new Error(\"fjs Error: Invalid function to compose\");\n }\n\n return function (this: any, ...args: any[]) {\n let result: any = (funcs[total - 1] as AnyFunction).apply(this, args);\n for (let i = total - 2; i >= 0; i--) {\n result = (funcs[i] as AnyFunction).call(this, result);\n }\n return result;\n };\n}\n","import type { Curried2 } from \"./types\";\nimport { curry } from \"./curry\";\nimport { map } from \"./array\";\nimport { isArray } from \"./typeChecks\";\n\nexport function toArray<T extends Record<string, any>>(obj: T): Array<[keyof T, T[keyof T]]> {\n return map((key: keyof T) => [key, obj[key]], Object.keys(obj) as Array<keyof T>);\n}\n\nexport const apply = curry(<T extends Record<string, any>, K extends keyof T>(\n func: K | [K, ...any[]],\n items: T[]\n): any[] => {\n let method: K;\n let args: any[] = [];\n\n if (isArray(func)) {\n [method, ...args] = func as [K, ...any[]];\n } else {\n method = func;\n }\n\n return map((item: T) => {\n const fn = item[method];\n if (typeof fn === \"function\") {\n return fn.apply(item, args);\n }\n return fn;\n }, items);\n}) as unknown as Curried2<any, any[], any[]>;\n\nexport const assign = curry(<T extends Record<string, any>, U extends Record<string, any>>(\n obj1: T,\n obj2: U\n): U & T => {\n return { ...obj2, ...obj1 };\n}) as unknown as Curried2<Record<string, any>, Record<string, any>, Record<string, any>>;\n\nexport const extend = assign;\n\nexport function prop<K extends string | number | symbol>(property: K) {\n return function <T extends Record<K, any>>(obj: T): T[K] {\n return obj[property];\n };\n}\n\nexport const pluck = curry(<T, K extends keyof T>(property: K, items: T[]): Array<T[K]> => {\n return map(prop(property), items);\n}) as unknown as Curried2<any, any[], any[]>;\n","export function identity<T>(value: T): T {\n return value;\n}\n\nexport function constant<T>(value: T): () => T {\n return () => value;\n}\n\nexport function tap<T>(fn: (value: T) => void) {\n return (value: T): T => {\n fn(value);\n return value;\n };\n}\n","import type { UnaryFn } from \"./types\";\n\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, fn1: UnaryFn<A, B>): B;\nexport function pipe<A, B, C>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): C;\nexport function pipe<A, B, C, D>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>\n): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>,\n fn5: UnaryFn<E, F>\n): F;\nexport function pipe(value: any, ...fns: UnaryFn<any, any>[]): any {\n let result = value;\n for (let i = 0; i < fns.length; i++) {\n result = fns[i]!(result);\n }\n return result;\n}\n\nexport function flow<A, B>(fn1: UnaryFn<A, B>): UnaryFn<A, B>;\nexport function flow<A, B, C>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): UnaryFn<A, C>;\nexport function flow<A, B, C, D>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>\n): UnaryFn<A, D>;\nexport function flow<A, B, C, D, E>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>\n): UnaryFn<A, E>;\nexport function flow<A, B, C, D, E, F>(\n fn1: UnaryFn<A, B>,\n fn2: UnaryFn<B, C>,\n fn3: UnaryFn<C, D>,\n fn4: UnaryFn<D, E>,\n fn5: UnaryFn<E, F>\n): UnaryFn<A, F>;\nexport function flow(...fns: UnaryFn<any, any>[]): UnaryFn<any, any> {\n return (value: any) => {\n let result = value;\n for (let i = 0; i < fns.length; i++) {\n result = fns[i]!(result);\n }\n return result;\n };\n}\n","import type { Curried2, Curried3 } from \"./types\";\nimport { curry } from \"./curry\";\n\nexport const pick = curry(<T extends object, K extends keyof T>(\n keys: K[],\n obj: T\n): Pick<T, K> => {\n const result = {} as Pick<T, K>;\n keys.forEach((key) => {\n if (key in obj) {\n result[key] = obj[key];\n }\n });\n return result;\n}) as unknown as Curried2<string[], any, any>;\n\nexport const omit = curry(<T extends object, K extends keyof T>(\n keys: K[],\n obj: T\n): Omit<T, K> => {\n const result = { ...obj } as any;\n keys.forEach((key) => {\n delete result[key];\n });\n return result as Omit<T, K>;\n}) as unknown as Curried2<string[], any, any>;\n\nexport const path = curry(<T = any>(pathArray: Array<string | number>, obj: any): T | undefined => {\n let current = obj;\n for (const key of pathArray) {\n if (current == null) {\n return undefined;\n }\n current = current[key];\n }\n return current as T;\n}) as unknown as Curried2<Array<string | number>, any, any>;\n\nexport const assoc = curry(<T extends object, K extends keyof T>(\n key: K,\n value: T[K],\n obj: T\n): T => {\n return { ...obj, [key]: value };\n}) as unknown as Curried3<string, any, any, any>;\n\nexport const dissoc = curry(<T extends object, K extends keyof T>(key: K, obj: T): Omit<T, K> => {\n const result = { ...obj } as any;\n delete result[key];\n return result as Omit<T, K>;\n}) as unknown as Curried2<string, any, any>;\n","import type { Curried2, Curried3 } from \"./types\";\nimport { curry } from \"./curry\";\nimport { each } from \"./array\";\nimport { exists, isArray } from \"./typeChecks\";\n\nexport const flatMap = curry(<T, U>(fn: (value: T, index: number) => U[], items: T[]): U[] => {\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n const input = items;\n const length = input.length;\n const result: U[] = [];\n const mapper = fn;\n for (let i = 0; i < length; i++) {\n const mapped = mapper(input[i]!, i);\n if (!exists(mapped) || !isArray(mapped)) {\n continue;\n }\n const mappedItems = mapped;\n for (let j = 0; j < mappedItems.length; j++) {\n result.push(mappedItems[j]!);\n }\n }\n return result;\n}) as unknown as Curried2<(value: any, index: number) => any[], any[], any[]>;\n\nexport const chain = flatMap;\n\nexport const flatten = <T>(items: T[][]): T[] => {\n if (!exists(items) || !isArray(items)) {\n return [];\n }\n const input = items;\n const result: T[] = [];\n for (let i = 0; i < input.length; i++) {\n const subArray = input[i]!;\n if (!exists(subArray) || !isArray(subArray)) {\n continue;\n }\n for (let j = 0; j < subArray.length; j++) {\n result.push(subArray[j]!);\n }\n }\n return result;\n};\n\nexport const zip = curry(<T, U>(arr1: T[], arr2: U[]): Array<[T, U]> => {\n const length = Math.min(arr1.length, arr2.length);\n const result: Array<[T, U]> = [];\n for (let i = 0; i < length; i++) {\n result.push([arr1[i]!, arr2[i]!]);\n }\n return result;\n}) as unknown as Curried2<any[], any[], Array<[any, any]>>;\n\nexport const zipWith = curry(<T, U, R>(\n fn: (a: T, b: U) => R,\n arr1: T[],\n arr2: U[]\n): R[] => {\n const length = Math.min(arr1.length, arr2.length);\n const result = new Array<R>(length);\n for (let i = 0; i < length; i++) {\n result[i] = fn(arr1[i]!, arr2[i]!);\n }\n return result;\n}) as unknown as Curried3<(a: any, b: any) => any, any[], any[], any[]>;\n\nexport const uniq = <T>(items: T[]): T[] => {\n return Array.from(new Set(items));\n};\n\nexport const uniqBy = curry(<T, K>(fn: (value: T) => K, items: T[]): T[] => {\n const seen = new Set<K>();\n const result: T[] = [];\n each((item: T) => {\n const key = fn(item);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(item);\n }\n }, items);\n return result;\n}) as unknown as Curried2<(value: any) => any, any[], any[]>;\n","import type { Curried2, Curried3, UnaryFn } from \"./types\";\nimport { curry } from \"./curry\";\n\nexport const mapAsync = curry(async <T, U>(\n fn: (value: T, index: number) => Promise<U>,\n items: T[]\n): Promise<U[]> => {\n const length = items.length;\n const promises = new Array<Promise<U>>(length);\n for (let i = 0; i < length; i++) {\n promises[i] = fn(items[i]!, i);\n }\n return Promise.all(promises);\n}) as unknown as Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>;\n\nexport const filterAsync = curry(async <T>(\n predicate: (value: T, index: number) => Promise<boolean>,\n items: T[]\n): Promise<T[]> => {\n const length = items.length;\n const promises = new Array<Promise<boolean>>(length);\n for (let i = 0; i < length; i++) {\n promises[i] = predicate(items[i]!, i);\n }\n const results = await Promise.all(promises);\n const filtered: T[] = [];\n for (let i = 0; i < length; i++) {\n if (results[i]) {\n filtered.push(items[i]!);\n }\n }\n return filtered;\n}) as unknown as Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>;\n\nexport const reduceAsync = curry(async <T>(\n fn: (accumulator: T, value: T, index: number) => Promise<T>,\n items: T[]\n): Promise<T> => {\n if (!items || items.length === 0) {\n throw new Error(\"fjs Error: Cannot reduce empty array without initial value\");\n }\n let accumulator: any = items[0]!;\n for (let i = 1; i < items.length; i++) {\n accumulator = (await fn(accumulator, items[i]!, i)) as T;\n }\n return accumulator;\n}) as unknown as Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>;\n\nexport const foldAsync = curry(async <T, U>(\n fn: (accumulator: U, value: T, index: number) => Promise<U>,\n initial: U,\n items: T[]\n): Promise<U> => {\n let accumulator = initial;\n for (let i = 0; i < items.length; i++) {\n accumulator = await fn(accumulator, items[i]!, i);\n }\n return accumulator;\n}) as unknown as Curried3<\n (accumulator: any, value: any, index: number) => Promise<any>,\n any,\n any[],\n Promise<any>\n>;\n\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items: T[]\n): Promise<R>;\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R\n): (items: T[]) => Promise<R>;\nexport function mapFilterReduceAsync<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items?: T[]\n): Promise<R> | ((items: T[]) => Promise<R>) {\n if (arguments.length < 5) {\n return (next: T[]) => mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, next);\n }\n return (async () => {\n const input = items as T[];\n let accumulator = initial;\n for (let i = 0; i < input.length; i++) {\n const mapped = await mapFn(input[i]!, i);\n const keep = await filterFn(mapped, i);\n if (keep) {\n accumulator = await reduceFn(accumulator, mapped, i);\n }\n }\n return accumulator;\n })();\n}\n\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items: T[]\n): Promise<R>;\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R\n): (items: T[]) => Promise<R>;\nexport function mapFilterReduceAsyncParallel<T, U, R>(\n mapFn: (value: T, index: number) => Promise<U> | U,\n filterFn: (value: U, index: number) => Promise<boolean> | boolean,\n reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R,\n initial: R,\n items?: T[]\n): Promise<R> | ((items: T[]) => Promise<R>) {\n if (arguments.length < 5) {\n return (next: T[]) => mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, next);\n }\n return (async () => {\n const input = items as T[];\n const length = input.length;\n const mappedPromises = new Array<Promise<U>>(length);\n for (let i = 0; i < length; i++) {\n mappedPromises[i] = Promise.resolve(mapFn(input[i]!, i));\n }\n const mapped = await Promise.all(mappedPromises);\n const filterPromises = new Array<Promise<boolean>>(length);\n for (let i = 0; i < length; i++) {\n filterPromises[i] = Promise.resolve(filterFn(mapped[i]!, i));\n }\n const keep = await Promise.all(filterPromises);\n let accumulator = initial;\n for (let i = 0; i < length; i++) {\n if (keep[i]) {\n accumulator = await reduceFn(accumulator, mapped[i]!, i);\n }\n }\n return accumulator;\n })();\n}\n\nexport const eachAsync = curry(async <T>(\n fn: (value: T, index: number) => Promise<void>,\n items: T[]\n): Promise<void> => {\n for (let i = 0; i < items.length; i++) {\n await fn(items[i]!, i);\n }\n}) as unknown as Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>;\n\nexport async function pipeAsync<A>(value: A): Promise<A>;\nexport async function pipeAsync<A, B>(value: A, fn1: UnaryFn<A, Promise<B>>): Promise<B>;\nexport async function pipeAsync<A, B, C>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>\n): Promise<C>;\nexport async function pipeAsync<A, B, C, D>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>\n): Promise<D>;\nexport async function pipeAsync<A, B, C, D, E>(\n value: A,\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>,\n fn4: UnaryFn<D, Promise<E>>\n): Promise<E>;\nexport async function pipeAsync(value: any, ...fns: UnaryFn<any, Promise<any>>[]): Promise<any> {\n let result = value;\n for (const fn of fns) {\n result = await fn(result);\n }\n return result;\n}\n\nexport function flowAsync<A, B>(fn1: UnaryFn<A, Promise<B>>): UnaryFn<A, Promise<B>>;\nexport function flowAsync<A, B, C>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>\n): UnaryFn<A, Promise<C>>;\nexport function flowAsync<A, B, C, D>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>\n): UnaryFn<A, Promise<D>>;\nexport function flowAsync<A, B, C, D, E>(\n fn1: UnaryFn<A, Promise<B>>,\n fn2: UnaryFn<B, Promise<C>>,\n fn3: UnaryFn<C, Promise<D>>,\n fn4: UnaryFn<D, Promise<E>>\n): UnaryFn<A, Promise<E>>;\nexport function flowAsync(...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> {\n return async (value: any) => {\n let result = value;\n for (const fn of fns) {\n result = await fn(result);\n }\n return result;\n };\n}\n\nexport const composeAsync = (...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> => {\n return async (value: any) => {\n let result = value;\n for (let i = fns.length - 1; i >= 0; i--) {\n result = await fns[i]!(result);\n }\n return result;\n };\n};\n","import { curry } from \"./curry\";\nimport {\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct\n} from \"./array\";\nimport { compose } from \"./composition\";\nimport { toArray, apply, assign, extend, prop, pluck } from \"./object\";\nimport {\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy\n} from \"./typeChecks\";\nimport { identity, constant, tap } from \"./utilities\";\nimport { pipe, flow } from \"./pipe\";\nimport { pick, omit, path, assoc, dissoc } from \"./objectOps\";\nimport { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from \"./arrayOps\";\nimport {\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n} from \"./async\";\n\nexport { curry } from \"./curry\";\n\nexport {\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct\n} from \"./array\";\n\nexport { compose } from \"./composition\";\n\nexport { toArray, apply, assign, extend, prop, pluck } from \"./object\";\n\nexport {\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy\n} from \"./typeChecks\";\n\nexport { identity, constant, tap } from \"./utilities\";\n\nexport { pipe, flow } from \"./pipe\";\n\nexport { pick, omit, path, assoc, dissoc } from \"./objectOps\";\n\nexport { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from \"./arrayOps\";\n\nexport {\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n} from \"./async\";\n\nexport type {\n Predicate,\n Comparator,\n Mapper,\n Reducer,\n UnaryFn,\n Curried2,\n Curried3,\n Curried4,\n AnyFunction,\n CurriedFunction\n} from \"./types\";\n\nexport const fjs = {\n curry,\n each,\n map,\n fold,\n foldl,\n reduce,\n reducel,\n foldll,\n clone,\n first,\n head,\n take,\n rest,\n tail,\n drop,\n last,\n every,\n all,\n any,\n contains,\n select,\n filter,\n best,\n whilst,\n partition,\n group,\n shuffle,\n nub,\n strictEquals,\n unique,\n distinct,\n compose,\n toArray,\n apply,\n assign,\n extend,\n prop,\n pluck,\n isFunction,\n isObject,\n isArray,\n isArguments,\n isDate,\n isNumber,\n isRegExp,\n isString,\n exists,\n truthy,\n falsy,\n identity,\n constant,\n tap,\n pipe,\n flow,\n pick,\n omit,\n path,\n assoc,\n dissoc,\n flatMap,\n chain,\n flatten,\n zip,\n zipWith,\n uniq,\n uniqBy,\n mapAsync,\n filterAsync,\n reduceAsync,\n foldAsync,\n eachAsync,\n pipeAsync,\n flowAsync,\n composeAsync,\n mapFilterReduceAsync,\n mapFilterReduceAsyncParallel\n};\n"]} |
| function m(n){return !!(n&&n.constructor&&n.call&&n.apply)}function N(n){return m(n)||!!n&&typeof n=="object"}function y(n){return Array.isArray(n)}function W(n){return Object.prototype.toString.call(n)==="[object Arguments]"}function H(n){return Object.prototype.toString.call(n)==="[object Date]"}function _(n){return Object.prototype.toString.call(n)==="[object Number]"}function G(n){return Object.prototype.toString.call(n)==="[object RegExp]"}function J(n){return Object.prototype.toString.call(n)==="[object String]"}function f(n){return n!=null}function v(n){return f(n)&&n!==false}function L(n){return !v(n)}function s(n){if(!m(n))throw new Error("fjs Error: Invalid function");if(n.length===2){let e=function(r,o,...a){if(arguments.length>=2){if(a.length===0)return n(r,o);let i=n(r,o);for(let u=0;u<a.length;u++)i=n(i,a[u],u);return i}return (i,...u)=>e(r,i,...u)};return e}if(n.length===3){let e=function(r,o,a,...i){if(arguments.length>=3){if(i.length===0)return n(r,o,a);let u=n(r,o,a);for(let c=0;c<i.length;c++)u=n(u,i[c],c);return u}return arguments.length===2?(u,...c)=>e(r,o,u,...c):function(u,c,...T){return arguments.length>=2?e(r,u,c,...T):(I,...b)=>e(r,u,I,...b)}};return e}function t(...e){if(e.length===0)return t;if(e.length>=n.length){if(e.length===n.length)return n(...e);let r=n(...e.slice(0,n.length)),o=e.slice(n.length);for(let a=0;a<o.length;a++)r=n(r,o[a],a);return r}return (...r)=>t(...e,...r)}return t}var C=Symbol("hardReturn"),On=(n,t)=>{for(let e=0;e<t.length;e++)if(n(t[e],e)===C)return},Sn=(n,t)=>{let e=t.length,r=new Array(e),o=n;if(e>0&&typeof t[0]=="number"&&o.length===1){for(let a=0;a<e;a++)r[a]=o(t[a],a);return r}for(let a=0;a<e;a++)r[a]=o(t[a],a);return r},zn=(n,t,e)=>{let r=t;if(e.length>0&&typeof e[0]=="number"&&typeof r=="number"){let o=r;for(let a=0;a<e.length;a++)o=n(o,e[a],a);return o}for(let o=0;o<e.length;o++)r=n(r,e[o],o);return r},In=(n,t)=>{let e=t[0];if(t.length>1&&typeof e=="number"&&typeof t[1]=="number"){let r=e;for(let o=1;o<t.length;o++)r=n(r,t[o],o-1);return r}for(let r=1;r<t.length;r++)e=n(e,t[r],r-1);return e},Nn=(n,t)=>{let e=[],r=t.length,o=n;if(r>0&&typeof t[0]=="number"&&o.length===1){for(let a=0;a<r;a++){let i=t[a];o(i,a)&&e.push(i);}return e}if(o.length>=2){for(let a=0;a<r;a++){let i=t[a];o(i,a)&&e.push(i);}return e}for(let a=0;a<r;a++){let i=t[a];o(i,a)&&e.push(i);}return e};function p(n,t){if(arguments.length<2)return e=>p(n,e);!f(t)||!y(t)||On(n,t);}function d(n,t){return arguments.length<2?e=>d(n,e):!f(t)||!y(t)?[]:Sn(n,t)}function U(n,t,e){return arguments.length>=3?!f(e)||!y(e)?t:zn(n,t,e):arguments.length===2?r=>U(n,t,r):function(r,o){return arguments.length>=2?U(n,r,o):a=>U(n,r,a)}}var Q=U;function A(n,t){if(arguments.length<2)return e=>A(n,e);if(!f(t)||!y(t)||t.length===0)throw new Error("fjs Error: Cannot reduce empty array without initial value");return In(n,t)}var V=A,X=A;function w(n){let t=n??[],e=new Array(t.length);for(let r=0;r<t.length;r++)e[r]=t[r];return e}function g(n,t){if(arguments.length<2)return r=>g(n,r);let e;return p((r,o)=>{if(n(r,o))return e=r,C},t),e}var Y=g,Z=g;function h(n,t){if(arguments.length<2)return r=>h(n,r);let e=F(n,t);return e.shift(),e}var $=h,nn=h;function B(n,t){if(arguments.length<2)return r=>B(n,r);let e=w(t);return g(n,e.reverse())}function R(n,t){if(arguments.length<2)return r=>R(n,r);let e=true;return p((r,o)=>{if(!n(r,o))return e=false,C},t),e}var en=R;function x(n,t){if(arguments.length<2)return r=>x(n,r);let e=false;return p((r,o)=>{if(n(r,o))return e=true,C},t),e}var rn=x;function F(n,t){return arguments.length<2?e=>F(n,e):!f(t)||!y(t)?[]:Nn(n,t)}var tn=F;function k(n,t){return arguments.length<2?r=>k(n,r):A((r,o)=>n(r,o)?r:o,t)}function D(n,t){if(arguments.length<2)return r=>D(n,r);let e=[];return p((r,o)=>{if(n(r,o))e.push(r);else return C},t),e}function K(n,t){if(arguments.length<2)return o=>K(n,o);let e=[],r=[];return p((o,a)=>{(n(o,a)?e:r).push(o);},t),[e,r]}function E(n,t){if(arguments.length<2)return r=>E(n,r);let e={};return p(r=>{let o=n(r),a=e[o];if(a){a.push(r);return}e[o]=[r];},t),e}function on(n){let t=w(n);for(let e=0;e<t.length;e++){let r=Math.floor(Math.random()*(e+1)),o=t[e];t[e]=t[r],t[r]=o;}return t}var j=(n,t)=>n===t;function P(n,t){if(arguments.length<2)return o=>P(n,o);let e=t;if(n===j)return Array.from(new Set(e));let r=e.length>0?[e[0]]:[];return p(o=>{x(a=>n(o,a),r)||r.push(o);},e),r}var an=P,un=P;function sn(...n){let t=x(r=>!m(r)),e=n.length;if(t(n))throw new Error("fjs Error: Invalid function to compose");return function(...r){let o=n[e-1].apply(this,r);for(let a=e-2;a>=0;a--)o=n[a].call(this,o);return o}}function cn(n){return d(t=>[t,n[t]],Object.keys(n))}var ln=s((n,t)=>{let e,r=[];return y(n)?[e,...r]=n:e=n,d(o=>{let a=o[e];return typeof a=="function"?a.apply(o,r):a},t)}),q=s((n,t)=>({...t,...n})),yn=q;function M(n){return function(t){return t[n]}}var fn=s((n,t)=>d(M(n),t));function pn(n){return n}function Tn(n){return ()=>n}function mn(n){return t=>(n(t),t)}function dn(n,...t){let e=n;for(let r=0;r<t.length;r++)e=t[r](e);return e}function xn(...n){return t=>{let e=t;for(let r=0;r<n.length;r++)e=n[r](e);return e}}var Un=s((n,t)=>{let e={};return n.forEach(r=>{r in t&&(e[r]=t[r]);}),e}),An=s((n,t)=>{let e={...t};return n.forEach(r=>{delete e[r];}),e}),gn=s((n,t)=>{let e=t;for(let r of n){if(e==null)return;e=e[r];}return e}),hn=s((n,t,e)=>({...e,[n]:t})),Fn=s((n,t)=>{let e={...t};return delete e[n],e});var O=s((n,t)=>{if(!f(t)||!y(t))return [];let e=t,r=e.length,o=[],a=n;for(let i=0;i<r;i++){let u=a(e[i],i);if(!f(u)||!y(u))continue;let c=u;for(let T=0;T<c.length;T++)o.push(c[T]);}return o}),Pn=O,bn=n=>{if(!f(n)||!y(n))return [];let t=n,e=[];for(let r=0;r<t.length;r++){let o=t[r];if(!(!f(o)||!y(o)))for(let a=0;a<o.length;a++)e.push(o[a]);}return e},Cn=s((n,t)=>{let e=Math.min(n.length,t.length),r=[];for(let o=0;o<e;o++)r.push([n[o],t[o]]);return r}),wn=s((n,t,e)=>{let r=Math.min(t.length,e.length),o=new Array(r);for(let a=0;a<r;a++)o[a]=n(t[a],e[a]);return o}),Rn=n=>Array.from(new Set(n)),vn=s((n,t)=>{let e=new Set,r=[];return p(o=>{let a=n(o);e.has(a)||(e.add(a),r.push(o));},t),r});var Bn=s(async(n,t)=>{let e=t.length,r=new Array(e);for(let o=0;o<e;o++)r[o]=n(t[o],o);return Promise.all(r)}),kn=s(async(n,t)=>{let e=t.length,r=new Array(e);for(let i=0;i<e;i++)r[i]=n(t[i],i);let o=await Promise.all(r),a=[];for(let i=0;i<e;i++)o[i]&&a.push(t[i]);return a}),Dn=s(async(n,t)=>{if(!t||t.length===0)throw new Error("fjs Error: Cannot reduce empty array without initial value");let e=t[0];for(let r=1;r<t.length;r++)e=await n(e,t[r],r);return e}),Kn=s(async(n,t,e)=>{let r=t;for(let o=0;o<e.length;o++)r=await n(r,e[o],o);return r});function S(n,t,e,r,o){return arguments.length<5?a=>S(n,t,e,r,a):(async()=>{let a=o,i=r;for(let u=0;u<a.length;u++){let c=await n(a[u],u);await t(c,u)&&(i=await e(i,c,u));}return i})()}function z(n,t,e,r,o){return arguments.length<5?a=>z(n,t,e,r,a):(async()=>{let a=o,i=a.length,u=new Array(i);for(let l=0;l<i;l++)u[l]=Promise.resolve(n(a[l],l));let c=await Promise.all(u),T=new Array(i);for(let l=0;l<i;l++)T[l]=Promise.resolve(t(c[l],l));let I=await Promise.all(T),b=r;for(let l=0;l<i;l++)I[l]&&(b=await e(b,c[l],l));return b})()}var En=s(async(n,t)=>{for(let e=0;e<t.length;e++)await n(t[e],e);});async function jn(n,...t){let e=n;for(let r of t)e=await r(e);return e}function qn(...n){return async t=>{let e=t;for(let r of n)e=await r(e);return e}}var Mn=(...n)=>async t=>{let e=t;for(let r=n.length-1;r>=0;r--)e=await n[r](e);return e};var ge={curry:s,each:p,map:d,fold:U,foldl:Q,reduce:A,reducel:V,foldll:X,clone:w,first:g,head:Y,take:Z,rest:h,tail:$,drop:nn,last:B,every:R,all:en,any:x,contains:rn,select:F,filter:tn,best:k,whilst:D,partition:K,group:E,shuffle:on,nub:P,strictEquals:j,unique:an,distinct:un,compose:sn,toArray:cn,apply:ln,assign:q,extend:yn,prop:M,pluck:fn,isFunction:m,isObject:N,isArray:y,isArguments:W,isDate:H,isNumber:_,isRegExp:G,isString:J,exists:f,truthy:v,falsy:L,identity:pn,constant:Tn,tap:mn,pipe:dn,flow:xn,pick:Un,omit:An,path:gn,assoc:hn,dissoc:Fn,flatMap:O,chain:Pn,flatten:bn,zip:Cn,zipWith:wn,uniq:Rn,uniqBy:vn,mapAsync:Bn,filterAsync:kn,reduceAsync:Dn,foldAsync:Kn,eachAsync:En,pipeAsync:jn,flowAsync:qn,composeAsync:Mn,mapFilterReduceAsync:S,mapFilterReduceAsyncParallel:z};export{en as all,x as any,ln as apply,q as assign,hn as assoc,k as best,Pn as chain,w as clone,sn as compose,Mn as composeAsync,Tn as constant,rn as contains,s as curry,Fn as dissoc,un as distinct,nn as drop,p as each,En as eachAsync,R as every,f as exists,yn as extend,L as falsy,tn as filter,kn as filterAsync,g as first,ge as fjs,O as flatMap,bn as flatten,xn as flow,qn as flowAsync,U as fold,Kn as foldAsync,Q as foldl,X as foldll,E as group,Y as head,pn as identity,W as isArguments,y as isArray,H as isDate,m as isFunction,_ as isNumber,N as isObject,G as isRegExp,J as isString,B as last,d as map,Bn as mapAsync,S as mapFilterReduceAsync,z as mapFilterReduceAsyncParallel,P as nub,An as omit,K as partition,gn as path,Un as pick,dn as pipe,jn as pipeAsync,fn as pluck,M as prop,A as reduce,Dn as reduceAsync,V as reducel,h as rest,F as select,on as shuffle,j as strictEquals,$ as tail,Z as take,mn as tap,cn as toArray,v as truthy,Rn as uniq,vn as uniqBy,an as unique,D as whilst,Cn as zip,wn as zipWith}; |
+21
| MIT License | ||
| Copyright (c) 2026 Lee Crossley | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
+351
| # functional.js | ||
| Lightweight, TypeScript-first functional programming library. Data-last design, auto-curried utilities, tree-shakeable ESM + CJS, zero dependencies. | ||
| ## Core Philosophy | ||
| - Data-last design for composition | ||
| - Auto-curried by default | ||
| - <6KB gzipped, zero dependencies | ||
| - Pure, immutable-by-default utilities | ||
| ## Positioning | ||
| - Simpler than fp-ts, better inference than Ramda | ||
| - More consistent TypeScript than lodash/fp | ||
| - Designed for modern build tooling | ||
| ## Imports | ||
| ```typescript | ||
| import { pipe, flow, map, filter, reduce } from "functional.js"; | ||
| ``` | ||
| Named exports only. A `fjs` namespace export is available when needed. | ||
| ## Quick Reference | ||
| All functions with TypeScript signatures. | ||
| ### Core Composition | ||
| - `curry(fn: (...args: any[]) => any): CurriedFunction` | ||
| - `compose(...fns: Array<(arg: any) => any>): (arg: any) => any` | ||
| - `pipe(value: T, ...fns: Array<(arg: any) => any>): any` | ||
| - `flow(...fns: Array<(arg: any) => any>): (arg: any) => any` | ||
| ### Arrays | ||
| All are data-last and auto-curried where applicable. | ||
| - `each(fn: (value: T, index: number) => any, items: T[]): void` | ||
| - `map(fn: (value: T, index: number) => U, items: T[]): U[]` | ||
| - `fold(fn: (acc: U, value: T, index: number) => U, initial: U, items: T[]): U` | ||
| - `reduce(fn: (acc: T, value: T, index: number) => T, items: T[]): T` | ||
| - `clone(items: T[]): T[]` | ||
| - `first(fn: (value: T, index: number) => boolean, items: T[]): T | undefined` | ||
| - `rest(fn: (value: T, index: number) => boolean, items: T[]): T[]` | ||
| - `last(fn: (value: T, index: number) => boolean, items: T[]): T | undefined` | ||
| - `every(fn: (value: T, index: number) => boolean, items: T[]): boolean` | ||
| - `any(fn: (value: T, index: number) => boolean, items: T[]): boolean` | ||
| - `select(fn: (value: T, index: number) => boolean, items: T[]): T[]` | ||
| - `best(fn: (a: T, b: T) => boolean, items: T[]): T | undefined` | ||
| - `whilst(fn: (value: T, index: number) => boolean, items: T[]): T[]` | ||
| - `partition(fn: (value: T, index: number) => boolean, items: T[]): [T[], T[]]` | ||
| - `group(fn: (value: T) => K, items: T[]): Record<K, T[]>` | ||
| - `shuffle(items: T[]): T[]` | ||
| - `nub(fn: (a: T, b: T) => boolean, items: T[]): T[]` | ||
| - `strictEquals(a: T, b: T): boolean` | ||
| Aliases: | ||
| - `foldl` → `fold` | ||
| - `reducel` → `reduce` | ||
| - `foldll` → `reduce` | ||
| - `head` → `first` | ||
| - `take` → `first` | ||
| - `tail` → `rest` | ||
| - `drop` → `rest` | ||
| - `all` → `every` | ||
| - `contains` → `any` | ||
| - `filter` → `select` | ||
| - `unique` → `nub` | ||
| - `distinct` → `nub` | ||
| ### Array Ops | ||
| - `flatMap(fn: (value: T, index: number) => U[], items: T[]): U[]` | ||
| - `chain` → `flatMap` | ||
| - `flatten(items: T[][]): T[]` | ||
| - `zip(arr1: T[], arr2: U[]): Array<[T, U]>` | ||
| - `zipWith(fn: (a: T, b: U) => R, arr1: T[], arr2: U[]): R[]` | ||
| - `uniq(items: T[]): T[]` | ||
| - `uniqBy(fn: (value: T) => K, items: T[]): T[]` | ||
| ### Objects | ||
| - `toArray(obj: Record<string, any>): Array<[key, value]>` | ||
| - `apply(methodOrTuple: K | [K, ...args], items: T[]): any[]` | ||
| - `assign(obj1: T, obj2: U): U & T` | ||
| - `extend` → `assign` | ||
| - `prop(key: K): (obj: Record<K, any>) => any` | ||
| - `pluck(key: K, items: T[]): Array<T[K]>` | ||
| - `pick(keys: K[], obj: T): Pick<T, K>` | ||
| - `omit(keys: K[], obj: T): Omit<T, K>` | ||
| - `path(pathArray: Array<string | number>, obj: any): T | undefined` | ||
| - `assoc(key: K, value: T[K], obj: T): T` | ||
| - `dissoc(key: K, obj: T): Omit<T, K>` | ||
| ### Utilities | ||
| - `identity(value: T): T` | ||
| - `constant(value: T): () => T` | ||
| - `tap(fn: (value: T) => void): (value: T) => T` | ||
| ### Async | ||
| - `mapAsync(fn: (value: T, index: number) => Promise<U>, items: T[]): Promise<U[]>` | ||
| - `filterAsync(fn: (value: T, index: number) => Promise<boolean>, items: T[]): Promise<T[]>` | ||
| - `reduceAsync(fn: (acc: T, value: T, index: number) => Promise<T>, items: T[]): Promise<T>` | ||
| - `foldAsync(fn: (acc: U, value: T, index: number) => Promise<U>, initial: U, items: T[]): Promise<U>` | ||
| - `eachAsync(fn: (value: T, index: number) => Promise<void>, items: T[]): Promise<void>` | ||
| - `pipeAsync(value: T, ...fns: Array<(arg: any) => Promise<any>>): Promise<any>` | ||
| - `flowAsync(...fns: Array<(arg: any) => Promise<any>>): (arg: any) => Promise<any>` | ||
| - `composeAsync(...fns: Array<(arg: any) => Promise<any>>): (arg: any) => Promise<any>` | ||
| ### Type Checks | ||
| - `isFunction`, `isObject`, `isArray`, `isArguments` | ||
| - `isDate`, `isNumber`, `isRegExp`, `isString` | ||
| - `exists`, `truthy`, `falsy` | ||
| ### Types | ||
| - `Predicate<T>`, `Comparator<T>`, `Mapper<T, U>`, `Reducer<T, U>` | ||
| - `UnaryFn<T, U>`, `AnyFunction` | ||
| - `Curried2`, `Curried3`, `Curried4`, `CurriedFunction` | ||
| ## Common Patterns | ||
| ### Data pipeline | ||
| ```typescript | ||
| import { pipe, map, filter, reduce } from "functional.js"; | ||
| const result = pipe( | ||
| data, | ||
| filter((x) => x.active), | ||
| map((x) => x.name), | ||
| reduce((acc, name) => acc + name) | ||
| ); | ||
| ``` | ||
| ### Reusable flow | ||
| ```typescript | ||
| import { flow, filter, map } from "functional.js"; | ||
| const getNames = flow( | ||
| filter((x) => x.active), | ||
| map((x) => x.name) | ||
| ); | ||
| ``` | ||
| ### Currying for reuse | ||
| ```typescript | ||
| import { curry, map } from "functional.js"; | ||
| const discount = curry((percentage: number, price: number) => price * (1 - percentage / 100)); | ||
| const apply10 = discount(10); | ||
| const discounted = map(apply10, prices); | ||
| ``` | ||
| ## Common Use Cases | ||
| ### Transforming and filtering data | ||
| ```typescript | ||
| import { pipe, filter, map } from "functional.js"; | ||
| const names = pipe( | ||
| users, | ||
| filter((u) => u.active), | ||
| map((u) => u.name) | ||
| ); | ||
| ``` | ||
| ### Shaping objects | ||
| ```typescript | ||
| import { pipe, pick, assoc, path } from "functional.js"; | ||
| const summary = pipe( | ||
| profile, | ||
| pick(["id", "name"]), | ||
| assoc("city", path(["details", "city"], profile)) | ||
| ); | ||
| ``` | ||
| ### Async pipelines | ||
| ```typescript | ||
| import { pipeAsync, mapAsync, filterAsync } from "functional.js"; | ||
| const run = async (ids: number[]) => { | ||
| const passingIds = await pipeAsync( | ||
| ids, | ||
| mapAsync((id) => fetchScore(id)), | ||
| filterAsync((score) => score >= 50) | ||
| ); | ||
| return passingIds; | ||
| }; | ||
| ``` | ||
| ## Migration Guides | ||
| ### From Ramda | ||
| - `R.pipe` → `pipe` | ||
| - `R.compose` → `compose` | ||
| - `R.map` → `map` | ||
| - `R.filter` → `filter` | ||
| - `R.reduce` → `reduce` | ||
| - `R.groupBy` → `group` | ||
| - `R.uniq` → `uniq` | ||
| - `R.prop` → `prop` | ||
| ```typescript | ||
| import { pipe, map, filter } from "functional.js"; | ||
| const result = pipe( | ||
| items, | ||
| filter((item) => item.ready), | ||
| map((item) => item.id) | ||
| ); | ||
| ``` | ||
| ### From lodash/fp | ||
| - `fp.flow` → `flow` | ||
| - `fp.compose` → `compose` | ||
| - `fp.map` → `map` | ||
| - `fp.filter` → `filter` | ||
| - `fp.reduce` → `reduce` | ||
| - `fp.get` → `path` | ||
| - `fp.pick` → `pick` | ||
| - `fp.omit` → `omit` | ||
| ```typescript | ||
| import { flow, filter, map } from "functional.js"; | ||
| const getReadyIds = flow( | ||
| filter((item) => item.ready), | ||
| map((item) => item.id) | ||
| ); | ||
| ``` | ||
| ## Performance Characteristics | ||
| - Small bundle size and tree-shakeable named exports | ||
| - Data-last API enables partial application without allocations | ||
| - Async utilities avoid intermediate arrays when chained in `pipeAsync` | ||
| ## TypeScript Best Practices | ||
| - Rely on inference for callbacks in `map`, `filter`, `reduce` | ||
| - Add generics only when inference needs help | ||
| - Prefer `flow` for reusable pipelines and `pipe` for inline usage | ||
| - Avoid explicit types for intermediate values unless required | ||
| ## Type System Guide | ||
| ### When to Add Types | ||
| Prefer inference for callbacks, especially with `map`, `filter`, and `reduce`: | ||
| ```typescript | ||
| const numbers = [1, 2, 3, 4, 5]; | ||
| const doubled = map((x) => x * 2, numbers); | ||
| ``` | ||
| Add generics only when inference is insufficient: | ||
| ```typescript | ||
| const getActiveNames = flow( | ||
| filter<User>((u) => u.active), | ||
| map((u) => u.name) | ||
| ); | ||
| ``` | ||
| Use `flow` when you want a reusable typed pipeline that can be called multiple times. | ||
| ## Composition Guide | ||
| ### Using pipe | ||
| Use `pipe` when you have the data already and want to run a pipeline immediately: | ||
| ```typescript | ||
| import { pipe, filter, map } from "functional.js"; | ||
| const result = pipe( | ||
| users, | ||
| filter((u) => u.active), | ||
| map((u) => u.name) | ||
| ); | ||
| ``` | ||
| ### Using flow | ||
| Use `flow` when you want a reusable function: | ||
| ```typescript | ||
| import { flow, filter, map } from "functional.js"; | ||
| const getActiveNames = flow( | ||
| filter((u) => u.active), | ||
| map((u) => u.name) | ||
| ); | ||
| const names1 = getActiveNames(users); | ||
| const names2 = getActiveNames(otherUsers); | ||
| ``` | ||
| ### Using compose | ||
| Use `compose` for right-to-left composition (less common): | ||
| ```typescript | ||
| import { compose, map, filter } from "functional.js"; | ||
| const getActiveNames = compose( | ||
| map((u) => u.name), | ||
| filter((u) => u.active) | ||
| ); | ||
| ``` | ||
| ## Common Gotchas | ||
| - `reduce` throws on empty arrays without an initial value (use `fold` with an initial value instead) | ||
| - Most functions are curried and data-last, so partial application is expected | ||
| - `filter` is an alias of `select`, and `head` is an alias of `first` | ||
| - `assign` and `shuffle` are immutable and return new values (do not mutate inputs) | ||
| - Data comes LAST, not first (e.g., `map(fn, array)` not `map(array, fn)`) | ||
| ## Comparison Matrix | ||
| | Library | Bundle Size | TypeScript | Auto-Curry | Learning Curve | | ||
| | ------------- | ----------- | ---------- | ---------- | -------------- | | ||
| | functional.js | ~6KB | Strong | Yes | Low | | ||
| | Ramda | ~50KB | Medium | Yes | Medium | | ||
| | lodash/fp | ~24KB | Medium | Yes | Low | | ||
| | fp-ts | ~15KB | Strong | No | High | | ||
| ## Notes | ||
| - `reduce` throws on empty arrays without an initial value | ||
| - Most functions are curried and data-last, enabling partial application | ||
| - Prefer `pipe` for immediate evaluation and `flow` for reusable pipelines |
+367
| import type { Mapper, Predicate, Reducer, Comparator } from "./types"; | ||
| import { isArray, exists } from "./typeChecks"; | ||
| const HARD_RETURN = Symbol("hardReturn"); | ||
| const eachArray = <T>(iterator: (value: T, index: number) => any, items: T[]): void => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| if (iterator(items[i]!, i) === HARD_RETURN) { | ||
| return; | ||
| } | ||
| } | ||
| }; | ||
| const mapArray = <T, U>(iterator: Mapper<T, U>, items: T[]): U[] => { | ||
| const length = items.length; | ||
| const mapped = new Array<U>(length); | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i]!, i); | ||
| } | ||
| return mapped; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| mapped[i] = fn(items[i]!, i); | ||
| } | ||
| return mapped; | ||
| }; | ||
| const foldArray = <T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U => { | ||
| let acc = cumulate; | ||
| if (items.length > 0 && typeof items[0] === "number" && typeof acc === "number") { | ||
| let numberAcc = acc as unknown as number; | ||
| for (let i = 0; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc as unknown as U, items[i]!, i) as unknown as number; | ||
| } | ||
| return numberAcc as unknown as U; | ||
| } | ||
| for (let i = 0; i < items.length; i++) { | ||
| acc = iterator(acc, items[i]!, i); | ||
| } | ||
| return acc; | ||
| }; | ||
| const reduceArray = <T>(iterator: Reducer<T, T>, items: T[]): T => { | ||
| let acc = items[0]; | ||
| if (items.length > 1 && typeof acc === "number" && typeof items[1] === "number") { | ||
| let numberAcc = acc as unknown as number; | ||
| for (let i = 1; i < items.length; i++) { | ||
| numberAcc = iterator(numberAcc as unknown as T, items[i]!, i - 1) as unknown as number; | ||
| } | ||
| return numberAcc as unknown as T; | ||
| } | ||
| for (let i = 1; i < items.length; i++) { | ||
| acc = iterator(acc as T, items[i]!, i - 1); | ||
| } | ||
| return acc as T; | ||
| }; | ||
| const filterArray = <T>(iterator: Predicate<T>, items: T[]): T[] => { | ||
| const filtered: T[] = []; | ||
| const length = items.length; | ||
| const fn = iterator; | ||
| if (length > 0 && typeof items[0] === "number" && fn.length === 1) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]!; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| if (fn.length >= 2) { | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]!; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| } | ||
| for (let i = 0; i < length; i++) { | ||
| const value = items[i]!; | ||
| if (fn(value, i)) { | ||
| filtered.push(value); | ||
| } | ||
| } | ||
| return filtered; | ||
| }; | ||
| export function each<T>(iterator: (value: T, index: number) => any, items: T[]): void; | ||
| export function each<T>(iterator: (value: T, index: number) => any): (items: T[]) => void; | ||
| export function each<T>(iterator: (value: T, index: number) => any, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => each(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return; | ||
| } | ||
| eachArray(iterator, items); | ||
| } | ||
| export function map<T, U>(iterator: Mapper<T, U>, items: T[]): U[]; | ||
| export function map<T, U>(iterator: Mapper<T, U>): (items: T[]) => U[]; | ||
| export function map<T, U>(iterator: Mapper<T, U>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => map(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return mapArray(iterator, items); | ||
| } | ||
| export function fold<T, U>(iterator: Reducer<T, U>, cumulate: U, items: T[]): U; | ||
| export function fold<T, U>(iterator: Reducer<T, U>, cumulate: U): (items: T[]) => U; | ||
| export function fold<T, U>( | ||
| iterator: Reducer<T, U> | ||
| ): { | ||
| (cumulate: U, items: T[]): U; | ||
| (cumulate: U): (items: T[]) => U; | ||
| }; | ||
| export function fold<T, U>(iterator: Reducer<T, U>, cumulate?: U, items?: T[]): any { | ||
| if (arguments.length >= 3) { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return cumulate as U; | ||
| } | ||
| return foldArray(iterator, cumulate as U, items); | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next: T[]) => fold(iterator, cumulate as U, next); | ||
| } | ||
| return function (nextCumulate: U, nextItems?: T[]): any { | ||
| if (arguments.length >= 2) { | ||
| return fold(iterator, nextCumulate, nextItems as T[]); | ||
| } | ||
| return (next: T[]) => fold(iterator, nextCumulate, next); | ||
| }; | ||
| } | ||
| export const foldl = fold; | ||
| export function reduce<T>(iterator: Reducer<T, T>, items: T[]): T; | ||
| export function reduce<T>(iterator: Reducer<T, T>): (items: T[]) => T; | ||
| export function reduce<T>(iterator: Reducer<T, T>, items?: T[]): T | ((items: T[]) => T) { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => reduce(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items) || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| return reduceArray(iterator, items); | ||
| } | ||
| export const reducel = reduce; | ||
| export const foldll = reduce; | ||
| export function clone<T>(items: T[]): T[] { | ||
| const input = items ?? []; | ||
| const result = new Array<T>(input.length); | ||
| for (let i = 0; i < input.length; i++) { | ||
| result[i] = input[i]!; | ||
| } | ||
| return result; | ||
| } | ||
| export function first<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| export function first<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| export function first<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => first(iterator, next); | ||
| } | ||
| let result: T | undefined; | ||
| each((item: T, index: number) => { | ||
| if (iterator(item, index)) { | ||
| result = item; | ||
| return HARD_RETURN; | ||
| } | ||
| return undefined; | ||
| }, items as T[]); | ||
| return result; | ||
| } | ||
| export const head = first; | ||
| export const take = first; | ||
| export function rest<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| export function rest<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| export function rest<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => rest(iterator, next); | ||
| } | ||
| const result = select(iterator, items as T[]); | ||
| result.shift(); | ||
| return result; | ||
| } | ||
| export const tail = rest; | ||
| export const drop = rest; | ||
| export function last<T>(iterator: Predicate<T>, items: T[]): T | undefined; | ||
| export function last<T>(iterator: Predicate<T>): (items: T[]) => T | undefined; | ||
| export function last<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => last(iterator, next); | ||
| } | ||
| const itemsClone = clone(items as T[]); | ||
| return first(iterator, itemsClone.reverse()); | ||
| } | ||
| export function every<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| export function every<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| export function every<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => every(iterator, next); | ||
| } | ||
| let isEvery = true; | ||
| each((item: T, index: number) => { | ||
| if (!iterator(item, index)) { | ||
| isEvery = false; | ||
| return HARD_RETURN; | ||
| } | ||
| return undefined; | ||
| }, items as T[]); | ||
| return isEvery; | ||
| } | ||
| export const all = every; | ||
| export function any<T>(iterator: Predicate<T>, items: T[]): boolean; | ||
| export function any<T>(iterator: Predicate<T>): (items: T[]) => boolean; | ||
| export function any<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => any(iterator, next); | ||
| } | ||
| let isAny = false; | ||
| each((item: T, index: number) => { | ||
| if (iterator(item, index)) { | ||
| isAny = true; | ||
| return HARD_RETURN; | ||
| } | ||
| return undefined; | ||
| }, items as T[]); | ||
| return isAny; | ||
| } | ||
| export const contains = any; | ||
| export function select<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| export function select<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| export function select<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => select(iterator, next); | ||
| } | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| return filterArray(iterator, items); | ||
| } | ||
| export const filter = select; | ||
| export function best<T>(iterator: Comparator<T>, items: T[]): T | undefined; | ||
| export function best<T>(iterator: Comparator<T>): (items: T[]) => T | undefined; | ||
| export function best<T>(iterator: Comparator<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => best(iterator, next); | ||
| } | ||
| const compare = (arg1: T, arg2: T): T => { | ||
| return iterator(arg1, arg2) ? arg1 : arg2; | ||
| }; | ||
| return reduce(compare, items as T[]); | ||
| } | ||
| export function whilst<T>(iterator: Predicate<T>, items: T[]): T[]; | ||
| export function whilst<T>(iterator: Predicate<T>): (items: T[]) => T[]; | ||
| export function whilst<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => whilst(iterator, next); | ||
| } | ||
| const result: T[] = []; | ||
| each((item: T, index: number) => { | ||
| if (iterator(item, index)) { | ||
| result.push(item); | ||
| } else { | ||
| return HARD_RETURN; | ||
| } | ||
| return undefined; | ||
| }, items as T[]); | ||
| return result; | ||
| } | ||
| export function partition<T>(iterator: Predicate<T>, items: T[]): [T[], T[]]; | ||
| export function partition<T>(iterator: Predicate<T>): (items: T[]) => [T[], T[]]; | ||
| export function partition<T>(iterator: Predicate<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => partition(iterator, next); | ||
| } | ||
| const truthy: T[] = []; | ||
| const falsy: T[] = []; | ||
| each((item: T, index: number) => { | ||
| (iterator(item, index) ? truthy : falsy).push(item); | ||
| }, items as T[]); | ||
| return [truthy, falsy]; | ||
| } | ||
| export function group<T, K extends string | number | symbol>( | ||
| iterator: (value: T) => K, | ||
| items: T[] | ||
| ): Record<K, T[]>; | ||
| export function group<T, K extends string | number | symbol>( | ||
| iterator: (value: T) => K | ||
| ): (items: T[]) => Record<K, T[]>; | ||
| export function group<T, K extends string | number | symbol>( | ||
| iterator: (value: T) => K, | ||
| items?: T[] | ||
| ): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => group(iterator, next); | ||
| } | ||
| const result = {} as Record<K, T[]>; | ||
| each((item: T) => { | ||
| const key = iterator(item); | ||
| const existing = result[key]; | ||
| if (existing) { | ||
| existing.push(item); | ||
| return; | ||
| } | ||
| result[key] = [item]; | ||
| }, items as T[]); | ||
| return result; | ||
| } | ||
| export function shuffle<T>(items: T[]): T[] { | ||
| const result = clone(items); | ||
| for (let i = 0; i < result.length; i++) { | ||
| const j = Math.floor(Math.random() * (i + 1)); | ||
| const t = result[i]!; | ||
| result[i] = result[j]!; | ||
| result[j] = t; | ||
| } | ||
| return result; | ||
| } | ||
| export const strictEquals = <T>(a: T, b: T): boolean => a === b; | ||
| export function nub<T>(comparator: Comparator<T>, items: T[]): T[]; | ||
| export function nub<T>(comparator: Comparator<T>): (items: T[]) => T[]; | ||
| export function nub<T>(comparator: Comparator<T>, items?: T[]): any { | ||
| if (arguments.length < 2) { | ||
| return (next: T[]) => nub(comparator, next); | ||
| } | ||
| const input = items as T[]; | ||
| if (comparator === strictEquals) { | ||
| return Array.from(new Set(input)); | ||
| } | ||
| const unique: T[] = input.length > 0 ? [input[0]!] : []; | ||
| each((item: T) => { | ||
| if (!any((value: T) => comparator(item, value), unique)) { | ||
| unique.push(item); | ||
| } | ||
| }, input); | ||
| return unique; | ||
| } | ||
| export const unique = nub; | ||
| export const distinct = nub; |
| import type { Curried2, Curried3 } from "./types"; | ||
| import { curry } from "./curry"; | ||
| import { each } from "./array"; | ||
| import { exists, isArray } from "./typeChecks"; | ||
| export const flatMap = curry(<T, U>(fn: (value: T, index: number) => U[], items: T[]): U[] => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const length = input.length; | ||
| const result: U[] = []; | ||
| const mapper = fn; | ||
| for (let i = 0; i < length; i++) { | ||
| const mapped = mapper(input[i]!, i); | ||
| if (!exists(mapped) || !isArray(mapped)) { | ||
| continue; | ||
| } | ||
| const mappedItems = mapped; | ||
| for (let j = 0; j < mappedItems.length; j++) { | ||
| result.push(mappedItems[j]!); | ||
| } | ||
| } | ||
| return result; | ||
| }) as unknown as Curried2<(value: any, index: number) => any[], any[], any[]>; | ||
| export const chain = flatMap; | ||
| export const flatten = <T>(items: T[][]): T[] => { | ||
| if (!exists(items) || !isArray(items)) { | ||
| return []; | ||
| } | ||
| const input = items; | ||
| const result: T[] = []; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const subArray = input[i]!; | ||
| if (!exists(subArray) || !isArray(subArray)) { | ||
| continue; | ||
| } | ||
| for (let j = 0; j < subArray.length; j++) { | ||
| result.push(subArray[j]!); | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| export const zip = curry(<T, U>(arr1: T[], arr2: U[]): Array<[T, U]> => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result: Array<[T, U]> = []; | ||
| for (let i = 0; i < length; i++) { | ||
| result.push([arr1[i]!, arr2[i]!]); | ||
| } | ||
| return result; | ||
| }) as unknown as Curried2<any[], any[], Array<[any, any]>>; | ||
| export const zipWith = curry(<T, U, R>( | ||
| fn: (a: T, b: U) => R, | ||
| arr1: T[], | ||
| arr2: U[] | ||
| ): R[] => { | ||
| const length = Math.min(arr1.length, arr2.length); | ||
| const result = new Array<R>(length); | ||
| for (let i = 0; i < length; i++) { | ||
| result[i] = fn(arr1[i]!, arr2[i]!); | ||
| } | ||
| return result; | ||
| }) as unknown as Curried3<(a: any, b: any) => any, any[], any[], any[]>; | ||
| export const uniq = <T>(items: T[]): T[] => { | ||
| return Array.from(new Set(items)); | ||
| }; | ||
| export const uniqBy = curry(<T, K>(fn: (value: T) => K, items: T[]): T[] => { | ||
| const seen = new Set<K>(); | ||
| const result: T[] = []; | ||
| each((item: T) => { | ||
| const key = fn(item); | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| result.push(item); | ||
| } | ||
| }, items); | ||
| return result; | ||
| }) as unknown as Curried2<(value: any) => any, any[], any[]>; |
+220
| import type { Curried2, Curried3, UnaryFn } from "./types"; | ||
| import { curry } from "./curry"; | ||
| export const mapAsync = curry(async <T, U>( | ||
| fn: (value: T, index: number) => Promise<U>, | ||
| items: T[] | ||
| ): Promise<U[]> => { | ||
| const length = items.length; | ||
| const promises = new Array<Promise<U>>(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = fn(items[i]!, i); | ||
| } | ||
| return Promise.all(promises); | ||
| }) as unknown as Curried2<(value: any, index: number) => Promise<any>, any[], Promise<any[]>>; | ||
| export const filterAsync = curry(async <T>( | ||
| predicate: (value: T, index: number) => Promise<boolean>, | ||
| items: T[] | ||
| ): Promise<T[]> => { | ||
| const length = items.length; | ||
| const promises = new Array<Promise<boolean>>(length); | ||
| for (let i = 0; i < length; i++) { | ||
| promises[i] = predicate(items[i]!, i); | ||
| } | ||
| const results = await Promise.all(promises); | ||
| const filtered: T[] = []; | ||
| for (let i = 0; i < length; i++) { | ||
| if (results[i]) { | ||
| filtered.push(items[i]!); | ||
| } | ||
| } | ||
| return filtered; | ||
| }) as unknown as Curried2<(value: any, index: number) => Promise<boolean>, any[], Promise<any[]>>; | ||
| export const reduceAsync = curry(async <T>( | ||
| fn: (accumulator: T, value: T, index: number) => Promise<T>, | ||
| items: T[] | ||
| ): Promise<T> => { | ||
| if (!items || items.length === 0) { | ||
| throw new Error("fjs Error: Cannot reduce empty array without initial value"); | ||
| } | ||
| let accumulator: any = items[0]!; | ||
| for (let i = 1; i < items.length; i++) { | ||
| accumulator = (await fn(accumulator, items[i]!, i)) as T; | ||
| } | ||
| return accumulator; | ||
| }) as unknown as Curried2<(accumulator: any, value: any, index: number) => Promise<any>, any[], Promise<any>>; | ||
| export const foldAsync = curry(async <T, U>( | ||
| fn: (accumulator: U, value: T, index: number) => Promise<U>, | ||
| initial: U, | ||
| items: T[] | ||
| ): Promise<U> => { | ||
| let accumulator = initial; | ||
| for (let i = 0; i < items.length; i++) { | ||
| accumulator = await fn(accumulator, items[i]!, i); | ||
| } | ||
| return accumulator; | ||
| }) as unknown as Curried3< | ||
| (accumulator: any, value: any, index: number) => Promise<any>, | ||
| any, | ||
| any[], | ||
| Promise<any> | ||
| >; | ||
| export function mapFilterReduceAsync<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R, | ||
| items: T[] | ||
| ): Promise<R>; | ||
| export function mapFilterReduceAsync<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R | ||
| ): (items: T[]) => Promise<R>; | ||
| export function mapFilterReduceAsync<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R, | ||
| items?: T[] | ||
| ): Promise<R> | ((items: T[]) => Promise<R>) { | ||
| if (arguments.length < 5) { | ||
| return (next: T[]) => mapFilterReduceAsync(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items as T[]; | ||
| let accumulator = initial; | ||
| for (let i = 0; i < input.length; i++) { | ||
| const mapped = await mapFn(input[i]!, i); | ||
| const keep = await filterFn(mapped, i); | ||
| if (keep) { | ||
| accumulator = await reduceFn(accumulator, mapped, i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| export function mapFilterReduceAsyncParallel<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R, | ||
| items: T[] | ||
| ): Promise<R>; | ||
| export function mapFilterReduceAsyncParallel<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R | ||
| ): (items: T[]) => Promise<R>; | ||
| export function mapFilterReduceAsyncParallel<T, U, R>( | ||
| mapFn: (value: T, index: number) => Promise<U> | U, | ||
| filterFn: (value: U, index: number) => Promise<boolean> | boolean, | ||
| reduceFn: (accumulator: R, value: U, index: number) => Promise<R> | R, | ||
| initial: R, | ||
| items?: T[] | ||
| ): Promise<R> | ((items: T[]) => Promise<R>) { | ||
| if (arguments.length < 5) { | ||
| return (next: T[]) => mapFilterReduceAsyncParallel(mapFn, filterFn, reduceFn, initial, next); | ||
| } | ||
| return (async () => { | ||
| const input = items as T[]; | ||
| const length = input.length; | ||
| const mappedPromises = new Array<Promise<U>>(length); | ||
| for (let i = 0; i < length; i++) { | ||
| mappedPromises[i] = Promise.resolve(mapFn(input[i]!, i)); | ||
| } | ||
| const mapped = await Promise.all(mappedPromises); | ||
| const filterPromises = new Array<Promise<boolean>>(length); | ||
| for (let i = 0; i < length; i++) { | ||
| filterPromises[i] = Promise.resolve(filterFn(mapped[i]!, i)); | ||
| } | ||
| const keep = await Promise.all(filterPromises); | ||
| let accumulator = initial; | ||
| for (let i = 0; i < length; i++) { | ||
| if (keep[i]) { | ||
| accumulator = await reduceFn(accumulator, mapped[i]!, i); | ||
| } | ||
| } | ||
| return accumulator; | ||
| })(); | ||
| } | ||
| export const eachAsync = curry(async <T>( | ||
| fn: (value: T, index: number) => Promise<void>, | ||
| items: T[] | ||
| ): Promise<void> => { | ||
| for (let i = 0; i < items.length; i++) { | ||
| await fn(items[i]!, i); | ||
| } | ||
| }) as unknown as Curried2<(value: any, index: number) => Promise<void>, any[], Promise<void>>; | ||
| export async function pipeAsync<A>(value: A): Promise<A>; | ||
| export async function pipeAsync<A, B>(value: A, fn1: UnaryFn<A, Promise<B>>): Promise<B>; | ||
| export async function pipeAsync<A, B, C>( | ||
| value: A, | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>> | ||
| ): Promise<C>; | ||
| export async function pipeAsync<A, B, C, D>( | ||
| value: A, | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>>, | ||
| fn3: UnaryFn<C, Promise<D>> | ||
| ): Promise<D>; | ||
| export async function pipeAsync<A, B, C, D, E>( | ||
| value: A, | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>>, | ||
| fn3: UnaryFn<C, Promise<D>>, | ||
| fn4: UnaryFn<D, Promise<E>> | ||
| ): Promise<E>; | ||
| export async function pipeAsync(value: any, ...fns: UnaryFn<any, Promise<any>>[]): Promise<any> { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| } | ||
| export function flowAsync<A, B>(fn1: UnaryFn<A, Promise<B>>): UnaryFn<A, Promise<B>>; | ||
| export function flowAsync<A, B, C>( | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>> | ||
| ): UnaryFn<A, Promise<C>>; | ||
| export function flowAsync<A, B, C, D>( | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>>, | ||
| fn3: UnaryFn<C, Promise<D>> | ||
| ): UnaryFn<A, Promise<D>>; | ||
| export function flowAsync<A, B, C, D, E>( | ||
| fn1: UnaryFn<A, Promise<B>>, | ||
| fn2: UnaryFn<B, Promise<C>>, | ||
| fn3: UnaryFn<C, Promise<D>>, | ||
| fn4: UnaryFn<D, Promise<E>> | ||
| ): UnaryFn<A, Promise<E>>; | ||
| export function flowAsync(...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> { | ||
| return async (value: any) => { | ||
| let result = value; | ||
| for (const fn of fns) { | ||
| result = await fn(result); | ||
| } | ||
| return result; | ||
| }; | ||
| } | ||
| export const composeAsync = (...fns: UnaryFn<any, Promise<any>>[]): UnaryFn<any, Promise<any>> => { | ||
| return async (value: any) => { | ||
| let result = value; | ||
| for (let i = fns.length - 1; i >= 0; i--) { | ||
| result = await fns[i]!(result); | ||
| } | ||
| return result; | ||
| }; | ||
| }; |
| import type { UnaryFn, AnyFunction } from "./types"; | ||
| import { isFunction } from "./typeChecks"; | ||
| import { any } from "./array"; | ||
| export function compose<A>(f: UnaryFn<A, A>): UnaryFn<A, A>; | ||
| export function compose<A, B>(f: UnaryFn<B, A>, g: UnaryFn<A, B>): UnaryFn<A, A>; | ||
| export function compose<A, B, C>( | ||
| f: UnaryFn<C, A>, | ||
| g: UnaryFn<B, C>, | ||
| h: UnaryFn<A, B> | ||
| ): UnaryFn<A, A>; | ||
| export function compose<A, B, C, D>( | ||
| f: UnaryFn<D, A>, | ||
| g: UnaryFn<C, D>, | ||
| h: UnaryFn<B, C>, | ||
| i: UnaryFn<A, B> | ||
| ): UnaryFn<A, A>; | ||
| export function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any>; | ||
| export function compose(...funcs: UnaryFn<any, any>[]): UnaryFn<any, any> { | ||
| const anyInvalid = any((func: unknown) => !isFunction(func)); | ||
| const total = funcs.length; | ||
| if (anyInvalid(funcs)) { | ||
| throw new Error("fjs Error: Invalid function to compose"); | ||
| } | ||
| return function (this: any, ...args: any[]) { | ||
| let result: any = (funcs[total - 1] as AnyFunction).apply(this, args); | ||
| for (let i = total - 2; i >= 0; i--) { | ||
| result = (funcs[i] as AnyFunction).call(this, result); | ||
| } | ||
| return result; | ||
| }; | ||
| } |
+75
| import type { AnyFunction, CurriedFunction } from "./types"; | ||
| import { isFunction } from "./typeChecks"; | ||
| export function curry<T extends AnyFunction>(func: T): CurriedFunction<T> { | ||
| if (!isFunction(func)) { | ||
| throw new Error("fjs Error: Invalid function"); | ||
| } | ||
| if (func.length === 2) { | ||
| const curried2 = function (a: any, b?: any, ...rest: any[]): any { | ||
| if (arguments.length >= 2) { | ||
| if (rest.length === 0) { | ||
| return func(a, b); | ||
| } | ||
| let accumulated = func(a, b); | ||
| for (let i = 0; i < rest.length; i++) { | ||
| accumulated = (func as AnyFunction)(accumulated, rest[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (next: any, ...more: any[]) => curried2(a, next, ...more); | ||
| }; | ||
| return curried2 as CurriedFunction<T>; | ||
| } | ||
| if (func.length === 3) { | ||
| const curried3 = function (a: any, b?: any, c?: any, ...rest: any[]): any { | ||
| if (arguments.length >= 3) { | ||
| if (rest.length === 0) { | ||
| return func(a, b, c); | ||
| } | ||
| let accumulated = func(a, b, c); | ||
| for (let i = 0; i < rest.length; i++) { | ||
| accumulated = (func as AnyFunction)(accumulated, rest[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| if (arguments.length === 2) { | ||
| return (next: any, ...more: any[]) => curried3(a, b, next, ...more); | ||
| } | ||
| return function (nextB: any, nextC?: any, ...more: any[]): any { | ||
| if (arguments.length >= 2) { | ||
| return curried3(a, nextB, nextC, ...more); | ||
| } | ||
| return (next: any, ...moreNext: any[]) => curried3(a, nextB, next, ...moreNext); | ||
| }; | ||
| }; | ||
| return curried3 as CurriedFunction<T>; | ||
| } | ||
| function curried(...args: any[]): any { | ||
| if (args.length === 0) { | ||
| return curried; | ||
| } | ||
| if (args.length >= func.length) { | ||
| if (args.length === func.length) { | ||
| return func(...args); | ||
| } | ||
| let accumulated = func(...args.slice(0, func.length)); | ||
| const remaining = args.slice(func.length); | ||
| for (let i = 0; i < remaining.length; i++) { | ||
| accumulated = (func as AnyFunction)(accumulated, remaining[i], i); | ||
| } | ||
| return accumulated; | ||
| } | ||
| return (...nextArgs: any[]) => curried(...args, ...nextArgs); | ||
| } | ||
| return curried as CurriedFunction<T>; | ||
| } |
+1015
| import { describe, it, expect } from "vitest"; | ||
| import * as fjs from "./index"; | ||
| describe("functional-js", () => { | ||
| it("should export all functions", () => { | ||
| expect(fjs).toBeDefined(); | ||
| expect(fjs.curry).toBeDefined(); | ||
| expect(fjs.compose).toBeDefined(); | ||
| expect(fjs.map).toBeDefined(); | ||
| }); | ||
| describe("curry", () => { | ||
| it("should throw an error with non-function input", () => { | ||
| expect(() => fjs.curry(undefined as any)).toThrow("fjs Error: Invalid function"); | ||
| expect(() => fjs.curry(1 as any)).toThrow("fjs Error: Invalid function"); | ||
| }); | ||
| it("should curry a string concatenation function", () => { | ||
| const concatenate = fjs.curry((word1: string, word2: string) => word1 + " " + word2); | ||
| const concatenateHello = concatenate("Hello"); | ||
| const result = concatenateHello("World"); | ||
| expect(result).toEqual("Hello World"); | ||
| }); | ||
| it("should curry an addition function with multiple args", () => { | ||
| const add = fjs.curry((arg1: number, arg2: number, arg3: number) => arg1 + arg2 + arg3); | ||
| const add3 = add(3); | ||
| const add5 = add3(2); | ||
| expect(add(3)(2)(1)).toEqual(6); | ||
| expect(add3(2, 1)).toEqual(6); | ||
| expect(add3(2)(1)).toEqual(6); | ||
| expect(add5(1)).toEqual(6); | ||
| }); | ||
| it("should extend the arity using curry", () => { | ||
| const add = fjs.curry((arg1: number, arg2: number) => arg1 + arg2); | ||
| const add3 = add(3); | ||
| expect(add(1, 2, 3)).toEqual(6); | ||
| expect(add3(1, 2, 3, 4, 5)).toEqual(18); | ||
| }); | ||
| it("should extend arity for 2-arg curry", () => { | ||
| const add2 = fjs.curry((a: number, b: number) => a + b); | ||
| expect(add2(1, 2, 3)).toEqual(6); | ||
| expect(add2(1)(2, 3)).toEqual(6); | ||
| expect(add2(1, 2, 3, 4)).toEqual(10); | ||
| }); | ||
| it("should extend arity for 3-arg curry", () => { | ||
| const add3 = fjs.curry((a: number, b: number, c: number) => a + b + c); | ||
| expect(add3(1, 2, 3, 4)).toEqual(10); | ||
| expect(add3(1)(2, 3, 4)).toEqual(10); | ||
| expect(add3(1)(2)(3, 4)).toEqual(10); | ||
| expect(add3(1, 2, 3, 4, 5)).toEqual(16); | ||
| }); | ||
| it("should curry 3-arg with partial two args", () => { | ||
| const add3 = fjs.curry((a: number, b: number, c: number) => a + b + c); | ||
| const add3Partial = add3(1, 2); | ||
| expect(add3Partial(3)).toEqual(6); | ||
| }); | ||
| it("should curry 4-arg with generic path", () => { | ||
| const add4 = fjs.curry((a: number, b: number, c: number, d: number) => a + b + c + (d || 0)); | ||
| expect(add4(1, 2, 3, 4)).toEqual(10); | ||
| expect(add4(1, 2, 3, 4, 5)).toEqual(15); | ||
| expect(add4(1)(2)(3)(4)).toEqual(10); | ||
| }); | ||
| it("should return function for zero-arg call in generic path", () => { | ||
| const add4 = fjs.curry((a: number, b: number, c: number, d: number) => a + b + c + d); | ||
| const result = add4(); | ||
| expect(fjs.isFunction(result)).toBeTruthy(); | ||
| }); | ||
| it("should return curried function when called with no args", () => { | ||
| const add = fjs.curry((a: number, b: number) => a + b); | ||
| const result = add(); | ||
| expect(fjs.isFunction(result)).toBeTruthy(); | ||
| }); | ||
| }); | ||
| describe("each", () => { | ||
| it("should iterate over array items", () => { | ||
| const result: string[] = []; | ||
| const items = ["f", "u", "n", "c"]; | ||
| const addTo = (item: string) => result.push(item); | ||
| fjs.each(addTo, items); | ||
| expect(result).toEqual(items); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const result: string[] = []; | ||
| const items = ["f", "u", "n", "c"]; | ||
| const addTo = (item: string) => result.push(item); | ||
| const addToResult = fjs.each(addTo); | ||
| expect(fjs.isFunction(addToResult)).toBeTruthy(); | ||
| addToResult(items); | ||
| expect(result).toEqual(["f", "u", "n", "c"]); | ||
| }); | ||
| it("should handle null param", () => { | ||
| const nothing = (item: any) => item; | ||
| const doNothing = fjs.each(nothing); | ||
| expect(() => doNothing(null as any)).not.toThrow(); | ||
| }); | ||
| it("should pass the current index", () => { | ||
| const result: number[] = []; | ||
| const items = ["f", "u", "n", "c"]; | ||
| fjs.each((_item, i) => result.push(i), items); | ||
| expect(result).toEqual([0, 1, 2, 3]); | ||
| }); | ||
| }); | ||
| describe("map", () => { | ||
| it("should double numbers in an array", () => { | ||
| const items = [1, 2, 3]; | ||
| const doubleUp = (number: number) => number * 2; | ||
| const result = fjs.map(doubleUp, items); | ||
| expect(result).toEqual([2, 4, 6]); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [1, 2, 3]; | ||
| const doubleUp = (number: number) => number * 2; | ||
| const doubleMap = fjs.map(doubleUp); | ||
| expect(fjs.isFunction(doubleMap)).toBeTruthy(); | ||
| const result = doubleMap(items); | ||
| expect(result).toEqual([2, 4, 6]); | ||
| }); | ||
| it("should use current index", () => { | ||
| const items = [1, 2, 3]; | ||
| const timesIndex = (number: number, i: number) => number * i; | ||
| const result = fjs.map(timesIndex, items); | ||
| expect(result).toEqual([0, 2, 6]); | ||
| }); | ||
| it("should handle non-array input", () => { | ||
| const result = fjs.map((x: number) => x * 2, null as any); | ||
| expect(result).toEqual([]); | ||
| }); | ||
| }); | ||
| describe("reduce", () => { | ||
| it("should have aliases", () => { | ||
| expect(fjs.reduce).toEqual(fjs.reducel); | ||
| expect(fjs.reduce).toEqual(fjs.foldll); | ||
| }); | ||
| it("should cumulate an array of numbers", () => { | ||
| const items = [1, 2, 3]; | ||
| const add = (arg1: number, arg2: number) => arg1 + arg2; | ||
| const result = fjs.reduce(add, items); | ||
| expect(result).toEqual(6); | ||
| }); | ||
| it("should cumulate an array of strings", () => { | ||
| const items = ["f", "u", "n", "c"]; | ||
| const concatenate = (arg1: string, arg2: string) => arg1 + arg2; | ||
| const result = fjs.reduce(concatenate, items); | ||
| expect(result).toEqual("func"); | ||
| }); | ||
| it("should use current index", () => { | ||
| const items = [1, 2, 3, 4]; | ||
| const add = (arg1: number, arg2: number, i: number) => arg1 + arg2 + i; | ||
| const result = fjs.reduce(add, items); | ||
| expect(result).toEqual(13); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [1, 2, 3]; | ||
| const multiply = (arg1: number, arg2: number) => arg1 * arg2; | ||
| const multiplyReduce = fjs.reduce(multiply); | ||
| expect(fjs.isFunction(multiplyReduce)).toBeTruthy(); | ||
| const result = multiplyReduce(items); | ||
| expect(result).toEqual(6); | ||
| }); | ||
| }); | ||
| describe("fold", () => { | ||
| it("should have alias", () => { | ||
| expect(fjs.fold).toEqual(fjs.foldl); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [1, 2, 3]; | ||
| const multiply = (arg1: number, arg2: number) => arg1 * arg2; | ||
| const multiplyFoldFrom10 = fjs.fold(multiply, 10); | ||
| expect(fjs.isFunction(multiplyFoldFrom10)).toBeTruthy(); | ||
| const result = multiplyFoldFrom10(items); | ||
| expect(result).toEqual(60); | ||
| }); | ||
| it("should return initial value for non-array input", () => { | ||
| const result = fjs.fold((acc: number, x: number) => acc + x, 10, null as any); | ||
| expect(result).toEqual(10); | ||
| }); | ||
| it("should allow curried two-step invocation", () => { | ||
| const sum = (acc: number, x: number) => acc + x; | ||
| const withInitial = fjs.fold(sum)(10); | ||
| const result = withInitial([1, 2, 3]); | ||
| expect(result).toEqual(16); | ||
| }); | ||
| it("should allow curried direct invocation", () => { | ||
| const sum = (acc: number, x: number) => acc + x; | ||
| const result = fjs.fold(sum)(10, [1, 2, 3]); | ||
| expect(result).toEqual(16); | ||
| }); | ||
| }); | ||
| describe("best", () => { | ||
| it("should be curryable", () => { | ||
| const items = [1, -4, 2, 3]; | ||
| const biggest = (arg1: number, arg2: number) => arg1 > arg2; | ||
| const smallest = (arg1: number, arg2: number) => arg1 < arg2; | ||
| const biggestAndBest = fjs.best(biggest); | ||
| const bestSmallest = fjs.best(smallest); | ||
| expect(fjs.isFunction(biggestAndBest)).toBeTruthy(); | ||
| expect(fjs.isFunction(bestSmallest)).toBeTruthy(); | ||
| expect(biggestAndBest(items)).toEqual(3); | ||
| expect(bestSmallest(items)).toEqual(-4); | ||
| }); | ||
| it("should get the longest word", () => { | ||
| const words = ["simply", "the", "best"]; | ||
| const longest = fjs.best((arg1: string, arg2: string) => arg1.length > arg2.length); | ||
| expect(fjs.isFunction(longest)).toBeTruthy(); | ||
| expect(longest(words)).toEqual("simply"); | ||
| }); | ||
| }); | ||
| describe("whilst", () => { | ||
| it("should get even numbers until odd", () => { | ||
| const even = (item: number) => item % 2 === 0; | ||
| const whileEven = fjs.whilst(even); | ||
| expect(whileEven([2])).toEqual([2]); | ||
| expect(whileEven([2, 4, 5, 6])).toEqual([2, 4]); | ||
| expect(whileEven([1, 4, 6, 8])).toEqual([]); | ||
| }); | ||
| }); | ||
| describe("any", () => { | ||
| it("should have alias", () => { | ||
| expect(fjs.any).toEqual(fjs.contains); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items1 = [1, 2, 3]; | ||
| const items2 = [1, 3, 5]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const anyEven = fjs.any(even); | ||
| const containsEven = fjs.contains(even); | ||
| expect(anyEven(items1)).toBeTruthy(); | ||
| expect(containsEven(items1)).toBeTruthy(); | ||
| expect(anyEven(items2)).not.toBeTruthy(); | ||
| expect(containsEven(items2)).not.toBeTruthy(); | ||
| }); | ||
| }); | ||
| describe("select/filter", () => { | ||
| it("should be curryable", () => { | ||
| const items = [1, 2, 3, 4, 5]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const odd = (item: number) => item % 2 !== 0; | ||
| const selectEven = fjs.select(even); | ||
| const selectOdd = fjs.select(odd); | ||
| expect(selectEven(items)).toEqual([2, 4]); | ||
| expect(selectOdd(items)).toEqual([1, 3, 5]); | ||
| }); | ||
| it("should handle non-array input", () => { | ||
| const result = fjs.filter((x: number) => x > 0, undefined as any); | ||
| expect(result).toEqual([]); | ||
| }); | ||
| it("should use predicate with index", () => { | ||
| const result = fjs.filter((value: number, index: number) => value + index > 3, [ | ||
| 1, | ||
| 2, | ||
| 3 | ||
| ]); | ||
| expect(result).toEqual([3]); | ||
| }); | ||
| }); | ||
| describe("clone", () => { | ||
| it("should clone an array and keep independence", () => { | ||
| const items = [5, 4, 3, 2, 1]; | ||
| const clonedItems = fjs.clone(items); | ||
| expect(clonedItems).toEqual(items); | ||
| items.length = 0; | ||
| expect(clonedItems).not.toEqual(items); | ||
| }); | ||
| it("should handle undefined input", () => { | ||
| const result = fjs.clone(undefined as any); | ||
| expect(result).toEqual([]); | ||
| }); | ||
| }); | ||
| describe("first/head/take", () => { | ||
| it("should have aliases", () => { | ||
| expect(fjs.first).toEqual(fjs.head); | ||
| expect(fjs.first).toEqual(fjs.take); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [5, 4, 3, 2, 1]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const odd = (item: number) => item % 2 !== 0; | ||
| const firstEven = fjs.first(even); | ||
| const firstOdd = fjs.first(odd); | ||
| expect(firstEven(items)).toEqual(4); | ||
| expect(firstOdd(items)).toEqual(5); | ||
| }); | ||
| }); | ||
| describe("rest/tail/drop", () => { | ||
| it("should have aliases", () => { | ||
| expect(fjs.rest).toEqual(fjs.tail); | ||
| expect(fjs.rest).toEqual(fjs.drop); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [5, 4, 3, 2, 1]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const odd = (item: number) => item % 2 !== 0; | ||
| const restEven = fjs.rest(even); | ||
| const restOdd = fjs.rest(odd); | ||
| expect(restEven(items)).toEqual([2]); | ||
| expect(restOdd(items)).toEqual([3, 1]); | ||
| }); | ||
| }); | ||
| describe("last", () => { | ||
| it("should be curryable", () => { | ||
| const items = [5, 4, 3, 2, 1]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const odd = (item: number) => item % 2 !== 0; | ||
| const lastEven = fjs.last(even); | ||
| const lastOdd = fjs.last(odd); | ||
| expect(lastEven(items)).toEqual(2); | ||
| expect(lastOdd(items)).toEqual(1); | ||
| }); | ||
| }); | ||
| describe("every/all", () => { | ||
| it("should have alias", () => { | ||
| expect(fjs.every).toEqual(fjs.all); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [2, 4, 6, 8]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const odd = (item: number) => item % 2 !== 0; | ||
| const everyEven = fjs.every(even); | ||
| const everyOdd = fjs.every(odd); | ||
| expect(everyEven(items)).toEqual(true); | ||
| expect(everyOdd(items)).toEqual(false); | ||
| }); | ||
| }); | ||
| describe("compose", () => { | ||
| it("should throw an error with non-function", () => { | ||
| const f = (a: string) => "hello " + a; | ||
| const g = 1; | ||
| expect(() => fjs.compose(f as any, g as any)).toThrow( | ||
| "fjs Error: Invalid function to compose" | ||
| ); | ||
| }); | ||
| it("should compose two functions", () => { | ||
| const f = (a: number) => "hello " + a; | ||
| const g = (a: number) => a + 1; | ||
| const composed = fjs.compose(f, g); | ||
| expect(composed(1)).toEqual("hello 2"); | ||
| }); | ||
| it("should compose multiple functions", () => { | ||
| const e = (a: number) => "hello " + a; | ||
| const f = (a: number) => a + 1; | ||
| const g = (a: number) => a * 100; | ||
| const composed = fjs.compose(e, f, g); | ||
| expect(composed(2)).toEqual("hello 201"); | ||
| }); | ||
| it("should return the same value when called with same argument", () => { | ||
| const f = (a: number) => "hello " + a; | ||
| const g = (a: number) => a + 1; | ||
| const composed = fjs.compose(f, g); | ||
| expect(composed(1)).toEqual(composed(1)); | ||
| }); | ||
| }); | ||
| describe("partition", () => { | ||
| it("should partition odd and even numbers", () => { | ||
| const items = [1, 2, 3, 4, 5, 6, 7]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const result = fjs.partition(even, items); | ||
| expect(result).toEqual([ | ||
| [2, 4, 6], | ||
| [1, 3, 5, 7] | ||
| ]); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const items = [7, 6, 5, 4, 3, 2, 1]; | ||
| const even = (item: number) => item % 2 === 0; | ||
| const partitionEven = fjs.partition(even); | ||
| const result = partitionEven(items); | ||
| expect(result).toEqual([ | ||
| [6, 4, 2], | ||
| [7, 5, 3, 1] | ||
| ]); | ||
| }); | ||
| }); | ||
| describe("group", () => { | ||
| it("should be curryable", () => { | ||
| const items = ["Lee", "Ryan", "Leona", "Sarah", "Rob", "Liam"]; | ||
| const firstLetter = (item: string) => item.charAt(0); | ||
| const groupFirstLetter = fjs.group(firstLetter); | ||
| const result = groupFirstLetter(items); | ||
| expect(result).toEqual({ | ||
| L: ["Lee", "Leona", "Liam"], | ||
| R: ["Ryan", "Rob"], | ||
| S: ["Sarah"] | ||
| }); | ||
| }); | ||
| }); | ||
| describe("pluck", () => { | ||
| it("should be curryable", () => { | ||
| const items = [ | ||
| { p1: "abc", p2: false, p3: 123 }, | ||
| { p1: "cab", p2: true, p3: 312 }, | ||
| { p1: "bca", p2: false, p3: 231 } | ||
| ]; | ||
| const pluck1 = fjs.pluck("p1"); | ||
| const result1 = pluck1(items); | ||
| const pluck2 = fjs.pluck("p2"); | ||
| const result2 = pluck2(items); | ||
| expect(result1).toEqual(["abc", "cab", "bca"]); | ||
| expect(result2).toEqual([false, true, false]); | ||
| }); | ||
| }); | ||
| describe("toArray", () => { | ||
| it("should convert object to array", () => { | ||
| const obj = { p1: "abc", p2: false, p3: null }; | ||
| const result = fjs.toArray(obj); | ||
| expect(result).toEqual([ | ||
| ["p1", "abc"], | ||
| ["p2", false], | ||
| ["p3", null] | ||
| ]); | ||
| expect(fjs.isArray(obj)).toBeFalsy(); | ||
| expect(fjs.isArray(result)).toBeTruthy(); | ||
| }); | ||
| }); | ||
| describe("apply", () => { | ||
| it("should be curryable", () => { | ||
| const items = ["Hello", "World"]; | ||
| const applyCase = fjs.apply("toUpperCase"); | ||
| const result = applyCase(items); | ||
| expect(result).toEqual(["HELLO", "WORLD"]); | ||
| }); | ||
| it("should work with additional argument", () => { | ||
| const items = ["Hello", "World"]; | ||
| const applyIndexOf = fjs.apply(["indexOf", "o"]); | ||
| const result = applyIndexOf(items); | ||
| expect(result).toEqual([4, 1]); | ||
| }); | ||
| it("should work with multiple arguments", () => { | ||
| const items = ["Hello", "World"]; | ||
| const applyIndexOf = fjs.apply(["substring", "1", "4"]); | ||
| const result = applyIndexOf(items); | ||
| expect(result).toEqual(["ell", "orl"]); | ||
| }); | ||
| it("should return property value when not a function", () => { | ||
| const items = ["Hello", "World"]; | ||
| const applyLength = fjs.apply("length"); | ||
| const result = applyLength(items); | ||
| expect(result).toEqual([5, 5]); | ||
| }); | ||
| }); | ||
| describe("assign/extend", () => { | ||
| it("should have alias", () => { | ||
| expect(fjs.assign).toEqual(fjs.extend); | ||
| }); | ||
| it("should do basic assign", () => { | ||
| const obj1 = { prop1: "obj1prop1", prop2: "obj1prop2" }; | ||
| const obj2 = { prop2: "obj2prop2", prop3: "obj2prop3" }; | ||
| const result = fjs.assign(obj1, obj2); | ||
| expect(result).toEqual({ | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2", | ||
| prop3: "obj2prop3" | ||
| }); | ||
| }); | ||
| it("should be curryable and extend arity", () => { | ||
| const obj1 = { prop1: "obj1prop1", prop2: "obj1prop2" }; | ||
| const obj2 = { prop2: "obj2prop2", prop3: "obj2prop3", prop4: "obj2prop4" }; | ||
| const obj3 = { prop4: "obj3prop4", prop5: "obj3prop5" }; | ||
| const assignToObj1 = fjs.assign(obj1); | ||
| const result1 = assignToObj1(obj2, obj3); | ||
| const result2 = fjs.assign(obj1, obj2, obj3); | ||
| expect(result1).toEqual({ | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2", | ||
| prop3: "obj2prop3", | ||
| prop4: "obj2prop4", | ||
| prop5: "obj3prop5" | ||
| }); | ||
| expect(result1).toEqual(result2); | ||
| }); | ||
| }); | ||
| describe("nub/unique/distinct", () => { | ||
| it("should have aliases", () => { | ||
| expect(fjs.nub).toEqual(fjs.unique); | ||
| expect(fjs.nub).toEqual(fjs.distinct); | ||
| }); | ||
| it("should remove duplicate elements", () => { | ||
| const base = ["John", "Jane", "Jane", "Jane", "Joe", "John", "Joe"]; | ||
| const expected = ["John", "Jane", "Joe"]; | ||
| const actual = fjs.nub((arg1: string, arg2: string) => arg1 === arg2, base); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should return one item for list of one", () => { | ||
| const base = [1]; | ||
| const actual = fjs.nub((arg1: number, arg2: number) => arg1 === arg2, base); | ||
| expect(actual).toEqual(base); | ||
| }); | ||
| it("should return empty for empty list", () => { | ||
| const empty: number[] = []; | ||
| const actual = fjs.nub((arg1: number, arg2: number) => arg1 === arg2, empty); | ||
| expect(actual).toEqual(empty); | ||
| }); | ||
| it("should be curryable", () => { | ||
| const base = [1, 2, 4, 5, 5, 5, 6, 7, 8, 8]; | ||
| const expected = [1, 2, 4, 5, 6, 7, 8]; | ||
| const nubByEquality = fjs.nub((arg1: number, arg2: number) => arg1 === arg2); | ||
| const actual = nubByEquality(base); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should work with complex comparator", () => { | ||
| const base = [ | ||
| { value1: 1, value2: 2 }, | ||
| { value1: 9, value2: 2 }, | ||
| { value1: 3, value2: 1 }, | ||
| { value1: 1, value2: 4 }, | ||
| { value1: 44, value2: 4 } | ||
| ]; | ||
| const expected = [ | ||
| { value1: 1, value2: 2 }, | ||
| { value1: 3, value2: 1 }, | ||
| { value1: 1, value2: 4 } | ||
| ]; | ||
| const actual = fjs.nub( | ||
| (arg1: any, arg2: any) => arg1.value2 === arg2.value2, | ||
| base | ||
| ); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should use strictEquals for fast path", () => { | ||
| const base = [1, 2, 2, 3, 3]; | ||
| const actual = fjs.nub(fjs.strictEquals, base); | ||
| expect(actual).toEqual([1, 2, 3]); | ||
| }); | ||
| }); | ||
| describe("type checks", () => { | ||
| describe("exists", () => { | ||
| it("should have correct return values", () => { | ||
| expect(fjs.exists(undefined)).toBeFalsy(); | ||
| expect(fjs.exists(null)).toBeFalsy(); | ||
| expect(fjs.exists(1)).toBeTruthy(); | ||
| expect(fjs.exists(-1)).toBeTruthy(); | ||
| expect(fjs.exists(0)).toBeTruthy(); | ||
| expect(fjs.exists("abc")).toBeTruthy(); | ||
| expect(fjs.exists("")).toBeTruthy(); | ||
| expect(fjs.exists(true)).toBeTruthy(); | ||
| expect(fjs.exists(false)).toBeTruthy(); | ||
| expect(fjs.exists([])).toBeTruthy(); | ||
| expect(fjs.exists({})).toBeTruthy(); | ||
| expect(fjs.exists(() => {})).toBeTruthy(); | ||
| }); | ||
| }); | ||
| describe("truthy", () => { | ||
| it("should have correct return values", () => { | ||
| expect(fjs.truthy(undefined)).toBeFalsy(); | ||
| expect(fjs.truthy(null)).toBeFalsy(); | ||
| expect(fjs.truthy(false)).toBeFalsy(); | ||
| expect(fjs.truthy(1)).toBeTruthy(); | ||
| expect(fjs.truthy(0)).toBeTruthy(); | ||
| expect(fjs.truthy("abc")).toBeTruthy(); | ||
| expect(fjs.truthy("")).toBeTruthy(); | ||
| expect(fjs.truthy(true)).toBeTruthy(); | ||
| expect(fjs.truthy([])).toBeTruthy(); | ||
| expect(fjs.truthy({})).toBeTruthy(); | ||
| expect(fjs.truthy(() => {})).toBeTruthy(); | ||
| }); | ||
| }); | ||
| describe("falsy", () => { | ||
| it("should have correct return values", () => { | ||
| expect(fjs.falsy(undefined)).toBeTruthy(); | ||
| expect(fjs.falsy(null)).toBeTruthy(); | ||
| expect(fjs.falsy(false)).toBeTruthy(); | ||
| expect(fjs.falsy(1)).toBeFalsy(); | ||
| expect(fjs.falsy(0)).toBeFalsy(); | ||
| expect(fjs.falsy("abc")).toBeFalsy(); | ||
| expect(fjs.falsy("")).toBeFalsy(); | ||
| expect(fjs.falsy(true)).toBeFalsy(); | ||
| expect(fjs.falsy([])).toBeFalsy(); | ||
| expect(fjs.falsy({})).toBeFalsy(); | ||
| expect(fjs.falsy(() => {})).toBeFalsy(); | ||
| }); | ||
| }); | ||
| }); | ||
| describe("reduce edge cases", () => { | ||
| it("should throw on empty array without initial value", () => { | ||
| expect(() => fjs.reduce((a: number, b: number) => a + b, [])).toThrow( | ||
| "fjs Error: Cannot reduce empty array without initial value" | ||
| ); | ||
| }); | ||
| }); | ||
| describe("filter/select uncurried usage", () => { | ||
| it("should work with uncurried filter", () => { | ||
| const isEven = (x: number) => x % 2 === 0; | ||
| const result = fjs.filter(isEven, [1, 2, 3, 4, 5]); | ||
| expect(result).toEqual([2, 4]); | ||
| }); | ||
| it("should work with single-param filter on non-numeric arrays", () => { | ||
| const isLong = (s: string) => s.length > 3; | ||
| const result = fjs.filter(isLong, ["hi", "hello", "hey", "world"]); | ||
| expect(result).toEqual(["hello", "world"]); | ||
| }); | ||
| }); | ||
| describe("shuffle", () => { | ||
| it("should return a new array", () => { | ||
| const items = [1, 2, 3, 4]; | ||
| const result = fjs.shuffle(items); | ||
| expect(result).toEqual(expect.arrayContaining(items)); | ||
| expect(result).not.toBe(items); | ||
| }); | ||
| }); | ||
| describe("utilities", () => { | ||
| it("should return identity", () => { | ||
| expect(fjs.identity(5)).toEqual(5); | ||
| }); | ||
| it("should return constant function", () => { | ||
| const alwaysTrue = fjs.constant(true); | ||
| expect(alwaysTrue()).toEqual(true); | ||
| }); | ||
| it("should tap and return input", () => { | ||
| let count = 0; | ||
| const result = fjs.tap((value: number) => { | ||
| count = value; | ||
| })(10); | ||
| expect(result).toEqual(10); | ||
| expect(count).toEqual(10); | ||
| }); | ||
| }); | ||
| describe("pipe and flow", () => { | ||
| it("should pipe values left-to-right", () => { | ||
| const result = fjs.pipe( | ||
| 2, | ||
| (x: number) => x + 1, | ||
| (x: number) => x * 3 | ||
| ); | ||
| expect(result).toEqual(9); | ||
| }); | ||
| it("should flow functions left-to-right", () => { | ||
| const fn = fjs.flow( | ||
| (x: number) => x + 1, | ||
| (x: number) => x * 3 | ||
| ); | ||
| expect(fn(2)).toEqual(9); | ||
| }); | ||
| }); | ||
| describe("array ops", () => { | ||
| it("should flatMap and chain", () => { | ||
| const result = fjs.flatMap((x: number) => [x, x * 2], [1, 2, 3]); | ||
| const chainResult = fjs.chain((x: number) => [x, x * 2], [1, 2]); | ||
| expect(result).toEqual([1, 2, 2, 4, 3, 6]); | ||
| expect(chainResult).toEqual([1, 2, 2, 4]); | ||
| }); | ||
| it("should flatten nested arrays", () => { | ||
| expect(fjs.flatten([[1, 2], [3], [4, 5]])).toEqual([1, 2, 3, 4, 5]); | ||
| }); | ||
| it("should zip and zipWith arrays", () => { | ||
| expect(fjs.zip([1, 2], ["a", "b", "c"])).toEqual([ | ||
| [1, "a"], | ||
| [2, "b"] | ||
| ]); | ||
| const result = fjs.zipWith( | ||
| (a: number, b: number) => a + b, | ||
| [1, 2], | ||
| [10, 20, 30] | ||
| ); | ||
| expect(result).toEqual([11, 22]); | ||
| }); | ||
| it("should uniq and uniqBy", () => { | ||
| expect(fjs.uniq([1, 2, 2, 3, 3])).toEqual([1, 2, 3]); | ||
| const result = fjs.uniqBy((x: { id: number }) => x.id, [ | ||
| { id: 1, name: "a" }, | ||
| { id: 1, name: "b" }, | ||
| { id: 2, name: "c" } | ||
| ]); | ||
| expect(result).toEqual([ | ||
| { id: 1, name: "a" }, | ||
| { id: 2, name: "c" } | ||
| ]); | ||
| }); | ||
| it("should handle edge cases in flatMap", () => { | ||
| const result = fjs.flatMap((x: number) => { | ||
| if (x === 2) return null as any; | ||
| if (x === 3) return undefined as any; | ||
| if (x === 4) return 42 as any; | ||
| return [x, x * 2]; | ||
| }, [1, 2, 3, 4, 5]); | ||
| expect(result).toEqual([1, 2, 5, 10]); | ||
| expect(fjs.flatMap((x: number) => [x], null as any)).toEqual([]); | ||
| expect(fjs.flatMap((x: number) => [x], undefined as any)).toEqual([]); | ||
| }); | ||
| it("should handle edge cases in flatten", () => { | ||
| const result = fjs.flatten([ | ||
| [1, 2], | ||
| null as any, | ||
| undefined as any, | ||
| 42 as any, | ||
| [3, 4] | ||
| ]); | ||
| expect(result).toEqual([1, 2, 3, 4]); | ||
| expect(fjs.flatten(null as any)).toEqual([]); | ||
| expect(fjs.flatten(undefined as any)).toEqual([]); | ||
| }); | ||
| }); | ||
| describe("object ops", () => { | ||
| it("should pick and omit keys", () => { | ||
| const obj = { a: 1, b: 2, c: 3 }; | ||
| expect(fjs.pick(["a", "c"], obj)).toEqual({ a: 1, c: 3 }); | ||
| expect(fjs.omit(["b"], obj)).toEqual({ a: 1, c: 3 }); | ||
| }); | ||
| it("should get path and assoc/dissoc", () => { | ||
| const nested = { user: { name: "Alice", age: 30 } }; | ||
| expect(fjs.path(["user", "name"], nested)).toEqual("Alice"); | ||
| expect(fjs.path(["user", "missing"], nested)).toBeUndefined(); | ||
| expect(fjs.path(["user"], null as any)).toBeUndefined(); | ||
| const updated = fjs.assoc("age", 31, nested.user); | ||
| expect(updated).toEqual({ name: "Alice", age: 31 }); | ||
| expect(fjs.dissoc("age", updated)).toEqual({ name: "Alice" }); | ||
| }); | ||
| }); | ||
| describe("async utilities", () => { | ||
| it("should map, filter, reduce, fold, and each asynchronously", async () => { | ||
| const data = [1, 2, 3]; | ||
| const mapped = await fjs.mapAsync(async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 2; | ||
| }, data); | ||
| expect(mapped).toEqual([2, 4, 6]); | ||
| const filtered = await fjs.filterAsync(async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x > 1; | ||
| }, data); | ||
| expect(filtered).toEqual([2, 3]); | ||
| const reduced = await fjs.reduceAsync(async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, data); | ||
| expect(reduced).toEqual(6); | ||
| const folded = await fjs.foldAsync( | ||
| async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, | ||
| 10, | ||
| data | ||
| ); | ||
| expect(folded).toEqual(16); | ||
| let total = 0; | ||
| await fjs.eachAsync(async (x: number) => { | ||
| await Promise.resolve(); | ||
| total += x; | ||
| }, data); | ||
| expect(total).toEqual(6); | ||
| }); | ||
| it("should map, filter, and reduce in a single async pipeline", async () => { | ||
| const data = [1, 2, 3, 4]; | ||
| const result = await fjs.mapFilterReduceAsync( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 2; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x > 4; | ||
| }, | ||
| async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, | ||
| 0, | ||
| data | ||
| ); | ||
| expect(result).toEqual(14); | ||
| const pipeline = fjs.mapFilterReduceAsync( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 2; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x > 4; | ||
| }, | ||
| async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, | ||
| 0 | ||
| ); | ||
| expect(await pipeline(data)).toEqual(14); | ||
| }); | ||
| it("should map, filter, and reduce with parallel async pipeline", async () => { | ||
| const data = [1, 2, 3, 4]; | ||
| const result = await fjs.mapFilterReduceAsyncParallel( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 2; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x > 4; | ||
| }, | ||
| async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, | ||
| 0, | ||
| data | ||
| ); | ||
| expect(result).toEqual(14); | ||
| const pipeline = fjs.mapFilterReduceAsyncParallel( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 2; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x > 4; | ||
| }, | ||
| async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, | ||
| 0 | ||
| ); | ||
| expect(await pipeline(data)).toEqual(14); | ||
| }); | ||
| it("should pipe and flow async functions", async () => { | ||
| const result = await fjs.pipeAsync( | ||
| 2, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x + 1; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 3; | ||
| } | ||
| ); | ||
| expect(result).toEqual(9); | ||
| const fn = fjs.flowAsync( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x + 1; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 3; | ||
| } | ||
| ); | ||
| expect(await fn(2)).toEqual(9); | ||
| const composed = fjs.composeAsync( | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x + 1; | ||
| }, | ||
| async (x: number) => { | ||
| await Promise.resolve(); | ||
| return x * 3; | ||
| } | ||
| ); | ||
| expect(await composed(2)).toEqual(7); | ||
| }); | ||
| it("should throw on reduceAsync with empty array", async () => { | ||
| await expect( | ||
| fjs.reduceAsync(async (acc: number, x: number) => { | ||
| await Promise.resolve(); | ||
| return acc + x; | ||
| }, []) | ||
| ).rejects.toThrow("fjs Error: Cannot reduce empty array without initial value"); | ||
| }); | ||
| }); | ||
| describe("additional type checks", () => { | ||
| it("should detect arguments and built-in types", () => { | ||
| const isArgs = (function () { | ||
| return fjs.isArguments(arguments); | ||
| })(); | ||
| expect(isArgs).toBeTruthy(); | ||
| expect(fjs.isDate(new Date())).toBeTruthy(); | ||
| expect(fjs.isNumber(123)).toBeTruthy(); | ||
| expect(fjs.isRegExp(/a/)).toBeTruthy(); | ||
| expect(fjs.isString("abc")).toBeTruthy(); | ||
| }); | ||
| it("should detect objects and functions", () => { | ||
| const fn = () => {}; | ||
| expect(fjs.isObject({})).toBeTruthy(); | ||
| expect(fjs.isObject(fn)).toBeTruthy(); | ||
| }); | ||
| }); | ||
| }); |
+230
| import { curry } from "./curry"; | ||
| import { | ||
| each, | ||
| map, | ||
| fold, | ||
| foldl, | ||
| reduce, | ||
| reducel, | ||
| foldll, | ||
| clone, | ||
| first, | ||
| head, | ||
| take, | ||
| rest, | ||
| tail, | ||
| drop, | ||
| last, | ||
| every, | ||
| all, | ||
| any, | ||
| contains, | ||
| select, | ||
| filter, | ||
| best, | ||
| whilst, | ||
| partition, | ||
| group, | ||
| shuffle, | ||
| nub, | ||
| strictEquals, | ||
| unique, | ||
| distinct | ||
| } from "./array"; | ||
| import { compose } from "./composition"; | ||
| import { toArray, apply, assign, extend, prop, pluck } from "./object"; | ||
| import { | ||
| isFunction, | ||
| isObject, | ||
| isArray, | ||
| isArguments, | ||
| isDate, | ||
| isNumber, | ||
| isRegExp, | ||
| isString, | ||
| exists, | ||
| truthy, | ||
| falsy | ||
| } from "./typeChecks"; | ||
| import { identity, constant, tap } from "./utilities"; | ||
| import { pipe, flow } from "./pipe"; | ||
| import { pick, omit, path, assoc, dissoc } from "./objectOps"; | ||
| import { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from "./arrayOps"; | ||
| import { | ||
| mapAsync, | ||
| filterAsync, | ||
| reduceAsync, | ||
| foldAsync, | ||
| eachAsync, | ||
| pipeAsync, | ||
| flowAsync, | ||
| composeAsync, | ||
| mapFilterReduceAsync, | ||
| mapFilterReduceAsyncParallel | ||
| } from "./async"; | ||
| export { curry } from "./curry"; | ||
| export { | ||
| each, | ||
| map, | ||
| fold, | ||
| foldl, | ||
| reduce, | ||
| reducel, | ||
| foldll, | ||
| clone, | ||
| first, | ||
| head, | ||
| take, | ||
| rest, | ||
| tail, | ||
| drop, | ||
| last, | ||
| every, | ||
| all, | ||
| any, | ||
| contains, | ||
| select, | ||
| filter, | ||
| best, | ||
| whilst, | ||
| partition, | ||
| group, | ||
| shuffle, | ||
| nub, | ||
| strictEquals, | ||
| unique, | ||
| distinct | ||
| } from "./array"; | ||
| export { compose } from "./composition"; | ||
| export { toArray, apply, assign, extend, prop, pluck } from "./object"; | ||
| export { | ||
| isFunction, | ||
| isObject, | ||
| isArray, | ||
| isArguments, | ||
| isDate, | ||
| isNumber, | ||
| isRegExp, | ||
| isString, | ||
| exists, | ||
| truthy, | ||
| falsy | ||
| } from "./typeChecks"; | ||
| export { identity, constant, tap } from "./utilities"; | ||
| export { pipe, flow } from "./pipe"; | ||
| export { pick, omit, path, assoc, dissoc } from "./objectOps"; | ||
| export { flatMap, chain, flatten, zip, zipWith, uniq, uniqBy } from "./arrayOps"; | ||
| export { | ||
| mapAsync, | ||
| filterAsync, | ||
| reduceAsync, | ||
| foldAsync, | ||
| eachAsync, | ||
| pipeAsync, | ||
| flowAsync, | ||
| composeAsync, | ||
| mapFilterReduceAsync, | ||
| mapFilterReduceAsyncParallel | ||
| } from "./async"; | ||
| export type { | ||
| Predicate, | ||
| Comparator, | ||
| Mapper, | ||
| Reducer, | ||
| UnaryFn, | ||
| Curried2, | ||
| Curried3, | ||
| Curried4, | ||
| AnyFunction, | ||
| CurriedFunction | ||
| } from "./types"; | ||
| export const fjs = { | ||
| curry, | ||
| each, | ||
| map, | ||
| fold, | ||
| foldl, | ||
| reduce, | ||
| reducel, | ||
| foldll, | ||
| clone, | ||
| first, | ||
| head, | ||
| take, | ||
| rest, | ||
| tail, | ||
| drop, | ||
| last, | ||
| every, | ||
| all, | ||
| any, | ||
| contains, | ||
| select, | ||
| filter, | ||
| best, | ||
| whilst, | ||
| partition, | ||
| group, | ||
| shuffle, | ||
| nub, | ||
| strictEquals, | ||
| unique, | ||
| distinct, | ||
| compose, | ||
| toArray, | ||
| apply, | ||
| assign, | ||
| extend, | ||
| prop, | ||
| pluck, | ||
| isFunction, | ||
| isObject, | ||
| isArray, | ||
| isArguments, | ||
| isDate, | ||
| isNumber, | ||
| isRegExp, | ||
| isString, | ||
| exists, | ||
| truthy, | ||
| falsy, | ||
| identity, | ||
| constant, | ||
| tap, | ||
| pipe, | ||
| flow, | ||
| pick, | ||
| omit, | ||
| path, | ||
| assoc, | ||
| dissoc, | ||
| flatMap, | ||
| chain, | ||
| flatten, | ||
| zip, | ||
| zipWith, | ||
| uniq, | ||
| uniqBy, | ||
| mapAsync, | ||
| filterAsync, | ||
| reduceAsync, | ||
| foldAsync, | ||
| eachAsync, | ||
| pipeAsync, | ||
| flowAsync, | ||
| composeAsync, | ||
| mapFilterReduceAsync, | ||
| mapFilterReduceAsyncParallel | ||
| }; |
| import type { Curried2 } from "./types"; | ||
| import { curry } from "./curry"; | ||
| import { map } from "./array"; | ||
| import { isArray } from "./typeChecks"; | ||
| export function toArray<T extends Record<string, any>>(obj: T): Array<[keyof T, T[keyof T]]> { | ||
| return map((key: keyof T) => [key, obj[key]], Object.keys(obj) as Array<keyof T>); | ||
| } | ||
| export const apply = curry(<T extends Record<string, any>, K extends keyof T>( | ||
| func: K | [K, ...any[]], | ||
| items: T[] | ||
| ): any[] => { | ||
| let method: K; | ||
| let args: any[] = []; | ||
| if (isArray(func)) { | ||
| [method, ...args] = func as [K, ...any[]]; | ||
| } else { | ||
| method = func; | ||
| } | ||
| return map((item: T) => { | ||
| const fn = item[method]; | ||
| if (typeof fn === "function") { | ||
| return fn.apply(item, args); | ||
| } | ||
| return fn; | ||
| }, items); | ||
| }) as unknown as Curried2<any, any[], any[]>; | ||
| export const assign = curry(<T extends Record<string, any>, U extends Record<string, any>>( | ||
| obj1: T, | ||
| obj2: U | ||
| ): U & T => { | ||
| return { ...obj2, ...obj1 }; | ||
| }) as unknown as Curried2<Record<string, any>, Record<string, any>, Record<string, any>>; | ||
| export const extend = assign; | ||
| export function prop<K extends string | number | symbol>(property: K) { | ||
| return function <T extends Record<K, any>>(obj: T): T[K] { | ||
| return obj[property]; | ||
| }; | ||
| } | ||
| export const pluck = curry(<T, K extends keyof T>(property: K, items: T[]): Array<T[K]> => { | ||
| return map(prop(property), items); | ||
| }) as unknown as Curried2<any, any[], any[]>; |
| import type { Curried2, Curried3 } from "./types"; | ||
| import { curry } from "./curry"; | ||
| export const pick = curry(<T extends object, K extends keyof T>( | ||
| keys: K[], | ||
| obj: T | ||
| ): Pick<T, K> => { | ||
| const result = {} as Pick<T, K>; | ||
| keys.forEach((key) => { | ||
| if (key in obj) { | ||
| result[key] = obj[key]; | ||
| } | ||
| }); | ||
| return result; | ||
| }) as unknown as Curried2<string[], any, any>; | ||
| export const omit = curry(<T extends object, K extends keyof T>( | ||
| keys: K[], | ||
| obj: T | ||
| ): Omit<T, K> => { | ||
| const result = { ...obj } as any; | ||
| keys.forEach((key) => { | ||
| delete result[key]; | ||
| }); | ||
| return result as Omit<T, K>; | ||
| }) as unknown as Curried2<string[], any, any>; | ||
| export const path = curry(<T = any>(pathArray: Array<string | number>, obj: any): T | undefined => { | ||
| let current = obj; | ||
| for (const key of pathArray) { | ||
| if (current == null) { | ||
| return undefined; | ||
| } | ||
| current = current[key]; | ||
| } | ||
| return current as T; | ||
| }) as unknown as Curried2<Array<string | number>, any, any>; | ||
| export const assoc = curry(<T extends object, K extends keyof T>( | ||
| key: K, | ||
| value: T[K], | ||
| obj: T | ||
| ): T => { | ||
| return { ...obj, [key]: value }; | ||
| }) as unknown as Curried3<string, any, any, any>; | ||
| export const dissoc = curry(<T extends object, K extends keyof T>(key: K, obj: T): Omit<T, K> => { | ||
| const result = { ...obj } as any; | ||
| delete result[key]; | ||
| return result as Omit<T, K>; | ||
| }) as unknown as Curried2<string, any, any>; |
+63
| import type { UnaryFn } from "./types"; | ||
| export function pipe<A>(value: A): A; | ||
| export function pipe<A, B>(value: A, fn1: UnaryFn<A, B>): B; | ||
| export function pipe<A, B, C>(value: A, fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): C; | ||
| export function pipe<A, B, C, D>( | ||
| value: A, | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D> | ||
| ): D; | ||
| export function pipe<A, B, C, D, E>( | ||
| value: A, | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D>, | ||
| fn4: UnaryFn<D, E> | ||
| ): E; | ||
| export function pipe<A, B, C, D, E, F>( | ||
| value: A, | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D>, | ||
| fn4: UnaryFn<D, E>, | ||
| fn5: UnaryFn<E, F> | ||
| ): F; | ||
| export function pipe(value: any, ...fns: UnaryFn<any, any>[]): any { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i]!(result); | ||
| } | ||
| return result; | ||
| } | ||
| export function flow<A, B>(fn1: UnaryFn<A, B>): UnaryFn<A, B>; | ||
| export function flow<A, B, C>(fn1: UnaryFn<A, B>, fn2: UnaryFn<B, C>): UnaryFn<A, C>; | ||
| export function flow<A, B, C, D>( | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D> | ||
| ): UnaryFn<A, D>; | ||
| export function flow<A, B, C, D, E>( | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D>, | ||
| fn4: UnaryFn<D, E> | ||
| ): UnaryFn<A, E>; | ||
| export function flow<A, B, C, D, E, F>( | ||
| fn1: UnaryFn<A, B>, | ||
| fn2: UnaryFn<B, C>, | ||
| fn3: UnaryFn<C, D>, | ||
| fn4: UnaryFn<D, E>, | ||
| fn5: UnaryFn<E, F> | ||
| ): UnaryFn<A, F>; | ||
| export function flow(...fns: UnaryFn<any, any>[]): UnaryFn<any, any> { | ||
| return (value: any) => { | ||
| let result = value; | ||
| for (let i = 0; i < fns.length; i++) { | ||
| result = fns[i]!(result); | ||
| } | ||
| return result; | ||
| }; | ||
| } |
| export function isFunction(obj: unknown): obj is (...args: any[]) => unknown { | ||
| return !!(obj && (obj as any).constructor && (obj as any).call && (obj as any).apply); | ||
| } | ||
| export function isObject(obj: unknown): obj is object { | ||
| return isFunction(obj) || (!!obj && typeof obj === "object"); | ||
| } | ||
| export function isArray<T = unknown>(obj: unknown): obj is T[] { | ||
| return Array.isArray(obj); | ||
| } | ||
| export function isArguments(obj: unknown): obj is IArguments { | ||
| return Object.prototype.toString.call(obj) === "[object Arguments]"; | ||
| } | ||
| export function isDate(obj: unknown): obj is Date { | ||
| return Object.prototype.toString.call(obj) === "[object Date]"; | ||
| } | ||
| export function isNumber(obj: unknown): obj is number { | ||
| return Object.prototype.toString.call(obj) === "[object Number]"; | ||
| } | ||
| export function isRegExp(obj: unknown): obj is RegExp { | ||
| return Object.prototype.toString.call(obj) === "[object RegExp]"; | ||
| } | ||
| export function isString(obj: unknown): obj is string { | ||
| return Object.prototype.toString.call(obj) === "[object String]"; | ||
| } | ||
| export function exists<T>(obj: T | null | undefined): obj is T { | ||
| return obj != null; | ||
| } | ||
| export function truthy<T>(obj: T | null | undefined | false): obj is T { | ||
| return exists(obj) && obj !== false; | ||
| } | ||
| export function falsy(obj: unknown): obj is null | undefined | false { | ||
| return !truthy(obj); | ||
| } |
| import { describe, it } from "vitest"; | ||
| import { expectTypeOf } from "expect-type"; | ||
| import { curry, map, filter, compose, fold } from "./index"; | ||
| describe("Type tests", () => { | ||
| it("curry should preserve function signature", () => { | ||
| const add = curry((a: number, b: number) => a + b); | ||
| expectTypeOf(add).toBeCallableWith(1, 2); | ||
| expectTypeOf(add(1)).toBeFunction(); | ||
| expectTypeOf(add(1)(2)).toBeNumber(); | ||
| }); | ||
| it("map should infer correct types", () => { | ||
| const double = (x: number) => x * 2; | ||
| const result = map(double, [1, 2, 3]); | ||
| expectTypeOf(result).toEqualTypeOf<number[]>(); | ||
| const curriedMap = map(double); | ||
| expectTypeOf(curriedMap).toBeFunction(); | ||
| expectTypeOf(curriedMap([1, 2, 3])).toEqualTypeOf<number[]>(); | ||
| }); | ||
| it("filter should preserve array type", () => { | ||
| const isEven = (x: number) => x % 2 === 0; | ||
| const result = filter(isEven, [1, 2, 3, 4]); | ||
| expectTypeOf(result).toEqualTypeOf<number[]>(); | ||
| }); | ||
| it("compose should infer return type", () => { | ||
| const addOne = (x: number) => x + 1; | ||
| const double = (x: number) => x * 2; | ||
| const toString = (x: number) => String(x); | ||
| const composed = compose(toString, double, addOne); | ||
| expectTypeOf(composed).toBeFunction(); | ||
| expectTypeOf(composed).returns.toBeString(); | ||
| }); | ||
| it("fold should infer accumulator type", () => { | ||
| const sum = (acc: number, x: number) => acc + x; | ||
| const result = fold(sum, 0, [1, 2, 3]); | ||
| expectTypeOf(result).toBeNumber(); | ||
| const concat = (acc: string, x: string) => acc + x; | ||
| const stringResult = fold(concat, "", ["a", "b", "c"]); | ||
| expectTypeOf(stringResult).toBeString(); | ||
| }); | ||
| }); |
+47
| export type Predicate<T> = { | ||
| bivarianceHack(value: T, index: number): boolean; | ||
| }["bivarianceHack"]; | ||
| export type Comparator<T> = (a: T, b: T) => boolean; | ||
| export type Mapper<T, U> = (value: T, index: number) => U; | ||
| export type Reducer<T, U> = (accumulator: U, value: T, index: number) => U; | ||
| export type UnaryFn<T, U> = (arg: T) => U; | ||
| export type Curried2<A, B, R> = { | ||
| (): Curried2<A, B, R>; | ||
| (a: A): (b: B, ...rest: any[]) => R; | ||
| (a: A, b: B, ...rest: any[]): R; | ||
| }; | ||
| export type Curried3<A, B, C, R> = { | ||
| (): Curried3<A, B, C, R>; | ||
| (a: A): Curried2<B, C, R>; | ||
| (a: A, b: B): (c: C, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, ...rest: any[]): R; | ||
| }; | ||
| export type Curried4<A, B, C, D, R> = { | ||
| (): Curried4<A, B, C, D, R>; | ||
| (a: A): Curried3<B, C, D, R>; | ||
| (a: A, b: B): Curried2<C, D, R>; | ||
| (a: A, b: B, c: C): (d: D, ...rest: any[]) => R; | ||
| (a: A, b: B, c: C, d: D, ...rest: any[]): R; | ||
| }; | ||
| export type AnyFunction = (...args: any[]) => any; | ||
| export type CurriedFunction<T extends AnyFunction> = T extends ( | ||
| a: infer A, | ||
| b: infer B, | ||
| c: infer C, | ||
| d: infer D | ||
| ) => infer R | ||
| ? Curried4<A, B, C, D, R> | ||
| : T extends (a: infer A, b: infer B, c: infer C) => infer R | ||
| ? Curried3<A, B, C, R> | ||
| : T extends (a: infer A, b: infer B) => infer R | ||
| ? Curried2<A, B, R> | ||
| : T; |
| export function identity<T>(value: T): T { | ||
| return value; | ||
| } | ||
| export function constant<T>(value: T): () => T { | ||
| return () => value; | ||
| } | ||
| export function tap<T>(fn: (value: T) => void) { | ||
| return (value: T): T => { | ||
| fn(value); | ||
| return value; | ||
| }; | ||
| } |
+91
-41
| { | ||
| "name": "functional.js", | ||
| "author": "Lee Crossley <leee@hotmail.co.uk> (http://ilee.co.uk/)", | ||
| "description": "A functional JavaScript library that facilitates currying and point-free programming, with optional lambda expressions.", | ||
| "homepage": "http://functionaljs.com", | ||
| "version": "0.8.0", | ||
| "main": "functional.js", | ||
| "keywords": [ | ||
| "functional", | ||
| "curry", | ||
| "arity", | ||
| "compose", | ||
| "iterator", | ||
| "lambda", | ||
| "underscore" | ||
| ], | ||
| "contributors": [ | ||
| { | ||
| "name": "Lee Crossley", | ||
| "email": "leee@hotmail.co.uk" | ||
| "name": "functional.js", | ||
| "version": "1.0.0", | ||
| "author": "Lee Crossley <leee@hotmail.co.uk> (http://ilee.co.uk/)", | ||
| "description": "A lightweight, TypeScript-first functional programming library with excellent type inference", | ||
| "homepage": "http://functionaljs.com", | ||
| "type": "module", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/index.d.ts", | ||
| "production": "./dist/index.min.js", | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| { | ||
| "name": "Ryan Roberts", | ||
| "email": "ryansroberts@gmail.com" | ||
| } | ||
| ], | ||
| "scripts": { | ||
| "test": "gulp test" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git@github.com:functionaljs/functional-js.git" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.8.x" | ||
| }, | ||
| "devDependencies": { | ||
| "gulp": "^3.9.0", | ||
| "gulp-jasmine": "^2.1.0", | ||
| "gulp-jshint": "^2.0.0", | ||
| "gulp-rename": "^1.2.2", | ||
| "jshint": "^2.8.0" | ||
| } | ||
| "files": [ | ||
| "dist", | ||
| "src", | ||
| "README.md", | ||
| "LICENSE", | ||
| "llms.txt" | ||
| ], | ||
| "keywords": [ | ||
| "functional", | ||
| "fp", | ||
| "typescript", | ||
| "curry", | ||
| "currying", | ||
| "compose", | ||
| "composition", | ||
| "pipe", | ||
| "immutable", | ||
| "point-free", | ||
| "data-last", | ||
| "ramda", | ||
| "lodash-fp", | ||
| "functional-programming", | ||
| "ai", | ||
| "ai-friendly", | ||
| "llm", | ||
| "llm-documented", | ||
| "llms-txt" | ||
| ], | ||
| "contributors": [ | ||
| { | ||
| "name": "Lee Crossley", | ||
| "email": "leee@hotmail.co.uk" | ||
| }, | ||
| { | ||
| "name": "Ryan Roberts", | ||
| "email": "ryansroberts@gmail.com" | ||
| } | ||
| ], | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "dev": "tsup --watch", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "test:coverage": "vitest run --coverage", | ||
| "type-check": "tsc --noEmit", | ||
| "lint": "eslint src --ext .ts", | ||
| "format": "prettier --write \"src/**/*.ts\"", | ||
| "format:check": "prettier --check \"src/**/*.ts\"", | ||
| "changeset": "changeset", | ||
| "version": "changeset version", | ||
| "release": "pnpm build && changeset publish", | ||
| "benchmark": "pnpm --dir local/benchmarks install && pnpm build && node local/benchmarks/run.mjs" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git@github.com:functionaljs/functional-js.git" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@changesets/cli": "^2.27.1", | ||
| "@types/node": "^20.11.5", | ||
| "@typescript-eslint/eslint-plugin": "^6.19.1", | ||
| "@typescript-eslint/parser": "^6.19.1", | ||
| "@vitest/coverage-v8": "^1.2.1", | ||
| "eslint": "^8.56.0", | ||
| "expect-type": "^0.17.3", | ||
| "prettier": "^3.2.4", | ||
| "tsup": "^8.0.1", | ||
| "typescript": "^5.3.3", | ||
| "vitest": "^1.2.1" | ||
| }, | ||
| "packageManager": "pnpm@8.15.1" | ||
| } |
+188
-37
@@ -1,65 +0,216 @@ | ||
| # functional.js (fjs) [](https://travis-ci.org/functionaljs/functional-js) [](https://npmjs.org/package/functional.js) [](https://david-dm.org/functionaljs/functional-js#info=devDependencies) | ||
| # functional.js | ||
| <img align="right" src="http://functionaljs.com/css/images/logo@2x.png"> | ||
| <p align="center"> | ||
| <strong>A lightweight, TypeScript-first functional programming library</strong> | ||
| </p> | ||
| **functional.js is a functional JavaScript library.** | ||
| <p align="center"> | ||
| <a href="https://www.npmjs.com/package/functional.js"><img src="https://img.shields.io/npm/v/functional.js.svg" alt="npm version"></a> | ||
| <a href="https://github.com/functionaljs/functional-js/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a> | ||
| </p> | ||
| It facilitates [currying](http://en.wikipedia.org/wiki/Currying) and [point-free / tacit](http://en.wikipedia.org/wiki/Tacit_programming) programming, with optional lambda expressions. | ||
| ## Features | ||
| ### Documentation | ||
| - **TypeScript-first** with excellent type inference | ||
| - **Lightweight** (~3KB gzipped) with strong tree-shaking | ||
| - **Auto-curried** functions for point-free programming | ||
| - **Zero dependencies** | ||
| - **Modern ESM + CJS** dual package | ||
| - **Full test coverage** (100%) | ||
| Visit [functionaljs.com](http://functionaljs.com/) for the full documentation including curry, each, map, reduce, fold, apply, every, any, select, pluck, toArray, first, last, best, partition, group, while and more. | ||
| ## Install | ||
| ### Curry function example | ||
| ```bash | ||
| npm install functional.js # or | ||
| pnpm add functional.js # or | ||
| yarn add functional.js | ||
| ``` | ||
| ```javascript | ||
| var add = fjs.curry(function(a, b) { | ||
| return a + b; | ||
| }); | ||
| ## Quick Start | ||
| var add3 = add(3); | ||
| ```typescript | ||
| import { pipe, map, filter, reduce } from "functional.js"; | ||
| add(1, 2, 3); // => 6 | ||
| add3(1, 2, 3, 4, 5); // => 18 | ||
| const data = [1, 2, 3, 4, 5, 6]; | ||
| const result = pipe( | ||
| data, | ||
| filter((x) => x % 2 === 0), | ||
| map((x) => x * 2), | ||
| reduce((acc, x) => acc + x) | ||
| ); | ||
| console.log(result); | ||
| ``` | ||
| ### Curry expression example | ||
| ### Using Curry | ||
| ```javascript | ||
| var add = fjs.curry("a, b => a + b"); | ||
| ```typescript | ||
| import { curry } from "functional.js"; | ||
| var add3 = add(3); | ||
| const add = curry((a: number, b: number) => a + b); | ||
| add(1, 2, 3); // => 6 | ||
| add3(1, 2, 3, 4, 5); // => 18 | ||
| add(1, 2); | ||
| add(1)(2); | ||
| const add5 = add(5); | ||
| add5(10); | ||
| ``` | ||
| ### Curry ES6 example | ||
| ### Point-Free Style | ||
| ```javascript | ||
| const add = fjs.curry((a, b) => a + b); | ||
| ```typescript | ||
| import { flow, map, filter, pluck } from "functional.js"; | ||
| const add3 = add(3); | ||
| interface User { | ||
| name: string; | ||
| age: number; | ||
| active: boolean; | ||
| } | ||
| add(1, 2, 3); // => 6 | ||
| add3(1, 2, 3, 4, 5); // => 18 | ||
| const getActiveUserNames = flow( | ||
| filter<User>((u) => u.active), | ||
| map((u) => u.name.toUpperCase()) | ||
| ); | ||
| const users: User[] = [ | ||
| { name: "Alice", age: 30, active: true }, | ||
| { name: "Bob", age: 25, active: false }, | ||
| { name: "Charlie", age: 35, active: true } | ||
| ]; | ||
| console.log(getActiveUserNames(users)); | ||
| ``` | ||
| ### Real world example | ||
| ## Core Functions | ||
| ```javascript | ||
| var converter = fjs.curry(function(rate, symbol, input) { | ||
| var output = input * rate; | ||
| return symbol + output.toFixed(2); | ||
| }); | ||
| ### Function Composition | ||
| var poundsToUSD = converter(1.52, "$"); | ||
| var poundsToEUR = converter(1.27, "€"); | ||
| - `curry(fn)` — Auto-curry any function | ||
| - `compose(...fns)` — Right-to-left function composition | ||
| - `pipe(value, ...fns)` — Left-to-right data pipeline | ||
| - `flow(...fns)` — Left-to-right function composition | ||
| poundsToUSD(100); // => "€63.50" | ||
| poundsToEUR(50); // => "$152.00" | ||
| ### Array Operations | ||
| - `map(fn, array)` — Transform array elements | ||
| - `filter(fn, array)` — Filter array by predicate | ||
| - `reduce(fn, array)` — Reduce array (no initial value) | ||
| - `fold(fn, initial, array)` — Fold array with initial value | ||
| - `flatMap(fn, array)` — Map and flatten | ||
| - `each(fn, array)` — Iterate over array | ||
| - `partition(fn, array)` — Split array by predicate | ||
| - `group(fn, array)` — Group array by key function | ||
| - `zip(arr1, arr2)` — Zip two arrays together | ||
| - `zipWith(fn, arr1, arr2)` — Zip with a combining function | ||
| - `uniq(array)` — Remove duplicates | ||
| - `uniqBy(fn, array)` — Remove duplicates by key function | ||
| ### Array Queries | ||
| - `first(fn, array)` — Find first matching element | ||
| - `last(fn, array)` — Find last matching element | ||
| - `every(fn, array)` — Check if all elements match | ||
| - `any(fn, array)` — Check if any element matches | ||
| - `best(comparator, array)` — Find best element by comparator | ||
| ### Object Operations | ||
| - `prop(key)` — Create property accessor | ||
| - `pluck(key, array)` — Extract property from array of objects | ||
| - `pick(keys, obj)` — Select properties from object | ||
| - `omit(keys, obj)` — Remove properties from object | ||
| - `path(pathArray, obj)` — Get nested property value | ||
| - `assoc(key, value, obj)` — Set property immutably | ||
| - `dissoc(key, obj)` — Remove property immutably | ||
| - `assign(obj1, obj2)` — Merge objects | ||
| ### Utilities | ||
| - `identity(x)` — Return input unchanged | ||
| - `constant(x)` — Create constant function | ||
| - `tap(fn)` — Execute side effect and return input | ||
| ### Type Checks | ||
| - `isFunction`, `isObject`, `isArray` | ||
| - `isString`, `isNumber`, `isDate`, `isRegExp` | ||
| - `exists`, `truthy`, `falsy` | ||
| ## TypeScript Support | ||
| All functions have full TypeScript support with proper type inference: | ||
| ```typescript | ||
| import { pipe, map, filter } from "functional.js"; | ||
| const numbers = [1, 2, 3, 4, 5]; | ||
| const result = pipe( | ||
| numbers, | ||
| filter((x) => x > 2), | ||
| map((x) => x.toString()) | ||
| ); | ||
| ``` | ||
| ## Comparison | ||
| | Library | Bundle Size | TypeScript | Auto-Curry | Notes | | ||
| | ------------- | ----------- | ---------- | ---------- | ----- | | ||
| | functional.js | ~3KB | Strong | Yes | Data-last, zero dependencies | | ||
| | Ramda | ~50KB | Limited | Yes | Data-last, large API | | ||
| | lodash/fp | ~24KB | Good | Yes | Data-last wrappers over lodash | | ||
| | underscore | ~17KB | Limited | No | Data-first utilities | | ||
| | fp-ts | ~15KB | Strong | No | Types-first, higher learning curve | | ||
| ## Performance | ||
| Benchmarks run on Node.js 24.13.0 (macOS), using small/medium/large scenarios with isolated processes, warmups, and median results. | ||
| Highlights from the latest run: | ||
| - functional.js wins 31 of 45 ops/sec metrics | ||
| - functional.js is fastest cold start at 0.81 ms | ||
| - functional.js leads 4 of 9 memory benchmarks (lowest heap delta) | ||
| - functional.js is up to 3.86x faster than the runner-up when it leads (1.57x average) | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
| ## Using AI Assistants | ||
| Use these prompts with AI assistants (ChatGPT, Claude, Cursor, etc.) to get accurate functional.js help: | ||
| ### For learning | ||
| - "Show me how to use pipe in functional.js with TypeScript" | ||
| - "Compare functional.js pipe with Ramda pipe" | ||
| - "Explain when to use flow versus compose in functional.js" | ||
| - "Give me a functional.js example for transforming an array of users" | ||
| ### For migration | ||
| - "Convert this Ramda code to functional.js: [paste code]" | ||
| - "Migrate lodash/fp chain to functional.js pipe: [paste code]" | ||
| - "Replace compose with flow using functional.js: [paste code]" | ||
| ### For problem-solving | ||
| - "How do I transform an array of users with functional.js" | ||
| - "Show me point-free style with functional.js" | ||
| - "Build a reusable pipeline with flow and use it on data" | ||
| ### For debugging | ||
| - "Why does reduce throw on this input in functional.js: [paste code]" | ||
| - "My curried function returns another function, what did I do wrong in functional.js: [paste code]" | ||
| ## License | ||
| [MIT License](http://ilee.mit-license.org) | ||
| [MIT License](./LICENSE) © Lee Crossley | ||
| ## Acknowledgments | ||
| Inspired by Ramda, lodash/fp, and fp-ts. Built for modern TypeScript development. |
-69
| { | ||
| "bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.). | ||
| "curly" : true, // Require {} for every new block or scope. | ||
| "eqeqeq" : true, // Require triple equals i.e. `===`. | ||
| "forin" : true, // Tolerate `for in` loops without `hasOwnPrototype`. | ||
| "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` | ||
| "latedef" : true, // Prohibit variable use before definition. | ||
| "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. | ||
| "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. | ||
| "noempty" : true, // Prohibit use of empty blocks. | ||
| "nonew" : true, // Prohibit use of constructors for side-effects. | ||
| "plusplus" : true, // Prohibit use of `++` & `--`. | ||
| "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions. | ||
| "undef" : true, // Require all non-global variables be declared before they are used. | ||
| "strict" : false, // Require `use strict` pragma in every file. | ||
| "trailing" : true, // Prohibit trailing whitespaces. | ||
| "asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons). | ||
| "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. | ||
| "debug" : false, // Allow debugger statements e.g. browser breakpoints. | ||
| "eqnull" : false, // Tolerate use of `== null`. | ||
| "es5" : true, // Allow EcmaScript 5 syntax. | ||
| "esnext" : false, // Allow ES.next specific features such as `const` and `let`. | ||
| "evil" : false, // Tolerate use of `eval`. | ||
| "expr" : false, // Tolerate `ExpressionStatement` as Programs. | ||
| "funcscope" : false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside. | ||
| "globalstrict" : false, // Allow global "use strict" (also enables 'strict'). | ||
| "iterator" : false, // Allow usage of __iterator__ property. | ||
| "lastsemic" : false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block. | ||
| "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. | ||
| "laxcomma" : false, // Suppress warnings about comma-first coding style. | ||
| "loopfunc" : false, // Allow functions to be defined within loops. | ||
| "multistr" : false, // Tolerate multi-line strings. | ||
| "onecase" : false, // Tolerate switches with just one case. | ||
| "proto" : false, // Tolerate __proto__ property. This property is deprecated. | ||
| "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. | ||
| "scripturl" : false, // Tolerate script-targeted URLs. | ||
| "smarttabs" : false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only. | ||
| "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. | ||
| "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. | ||
| "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. | ||
| "validthis" : false, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function. | ||
| "browser" : true, // Standard browser globals e.g. `window`, `document`. | ||
| "couch" : false, // Enable globals exposed by CouchDB. | ||
| "devel" : true, // Allow development statements e.g. `console.log();`. | ||
| "dojo" : false, // Enable globals exposed by Dojo Toolkit. | ||
| "jquery" : false, // Enable globals exposed by jQuery JavaScript library. | ||
| "mootools" : false, // Enable globals exposed by MooTools JavaScript framework. | ||
| "node" : true, // Enable globals available when code is running inside of the NodeJS runtime environment. | ||
| "nonstandard" : false, // Define non-standard but widely adopted globals such as escape and unescape. | ||
| "prototypejs" : false, // Enable globals exposed by Prototype JavaScript framework. | ||
| "rhino" : false, // Enable globals available when your code is running inside of the Rhino runtime environment. | ||
| "wsh" : false, // Enable globals available when your code is running as a script for the Windows Script Host. | ||
| "nomen" : false, // Prohibit use of initial or trailing underbars in names. | ||
| "onevar" : false, // Allow only one `var` statement per function. | ||
| "passfail" : false, // Stop on first error. | ||
| "white" : false, // Check against strict whitespace and indentation rules. | ||
| "maxerr" : 100, // Maximum errors before stopping. | ||
| "predef" : [ // Extra globals. | ||
| "describe", | ||
| "it", | ||
| "before", | ||
| "expect" | ||
| ], | ||
| "indent" : 4 // Specify indentation spacing | ||
| } |
Sorry, the diff of this file is not supported yet
| language: node_js | ||
| sudo: false | ||
| node_js: | ||
| - "4.1" | ||
| before_script: | ||
| - npm install -g gulp |
-26
| { | ||
| "name": "functional.js", | ||
| "author": "Lee Crossley <leee@hotmail.co.uk> (http://ilee.co.uk/)", | ||
| "description": "A functional JavaScript library that facilitates currying and point-free programming", | ||
| "homepage": "http://functionaljs.com", | ||
| "version": "0.8.0", | ||
| "keywords": [ | ||
| "functional", | ||
| "curry", | ||
| "arity", | ||
| "compose", | ||
| "iterator", | ||
| "lambda", | ||
| "underscore" | ||
| ], | ||
| "main": "functional.js", | ||
| "ignore" : [ | ||
| ".gitignore", | ||
| ".jshintrc", | ||
| ".travis.yml", | ||
| "component.json", | ||
| "gulpfile.js", | ||
| "README.md", | ||
| "spec.js" | ||
| ] | ||
| } |
| { | ||
| "name": "functional.js", | ||
| "author": "Lee Crossley <leee@hotmail.co.uk> (http://ilee.co.uk/)", | ||
| "description": "A functional JavaScript library that facilitates currying and point-free programming", | ||
| "homepage": "http://functionaljs.com", | ||
| "version": "0.8.0", | ||
| "keywords": [ | ||
| "functional", | ||
| "curry", | ||
| "arity", | ||
| "compose", | ||
| "iterator", | ||
| "lambda", | ||
| "underscore" | ||
| ], | ||
| "repo": "leecrossley/functional-js", | ||
| "main": "functional.js", | ||
| "scripts": [ | ||
| "functional.js" | ||
| ] | ||
| } |
-315
| var fjs = (function () { | ||
| "use strict"; | ||
| var fjs = {}, hardReturn = "hardReturn;"; | ||
| var lambda = function (exp) { | ||
| if (!fjs.isString(exp)) { | ||
| return; | ||
| } | ||
| var parts = exp.match(/(.*)\s*[=-]>\s*(.*)/); | ||
| parts.shift(); | ||
| var params = parts.shift() | ||
| .replace(/^\s*|\s(?=\s)|\s*$|,/g, "").split(" "); | ||
| var body = parts.shift(); | ||
| parts = ((!/\s*return\s+/.test(body)) ? "return " : "" ) + body; | ||
| params.push(parts); | ||
| return Function.apply({}, params); | ||
| }; | ||
| var sliceArgs = function (args) { | ||
| return args.length > 0 ? [].slice.call(args, 0) : []; | ||
| }; | ||
| fjs.isFunction = function (obj) { | ||
| return !!(obj && obj.constructor && obj.call && obj.apply); | ||
| }; | ||
| fjs.isObject = function (obj) { | ||
| return fjs.isFunction(obj) || (!!obj && typeof (obj) === "object"); | ||
| }; | ||
| fjs.isArray = function (obj) { | ||
| return Object.prototype.toString.call(obj) === "[object Array]"; | ||
| }; | ||
| var checkFunction = function (func) { | ||
| if (!fjs.isFunction(func)) { | ||
| func = lambda(func); | ||
| if (!fjs.isFunction(func)) { | ||
| throw "fjs Error: Invalid function"; | ||
| } | ||
| } | ||
| return func; | ||
| }; | ||
| fjs.curry = function (func) { | ||
| func = checkFunction(func); | ||
| return function inner() { | ||
| var _args = sliceArgs(arguments); | ||
| if (_args.length === func.length) { | ||
| return func.apply(null, _args); | ||
| } else if (_args.length > func.length) { | ||
| var initial = func.apply(null, _args); | ||
| return fjs.fold(func, initial, _args.slice(func.length)); | ||
| } else { | ||
| return function() { | ||
| var args = sliceArgs(arguments); | ||
| return inner.apply(null, _args.concat(args)); | ||
| }; | ||
| } | ||
| }; | ||
| }; | ||
| fjs.each = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| if (!fjs.exists(items) || !fjs.isArray(items)) { | ||
| return; | ||
| } | ||
| for (var i = 0, j = items.length; i < j; i += 1) { | ||
| if (iterator.call(null, items[i], i) === hardReturn) { | ||
| return; | ||
| } | ||
| } | ||
| }); | ||
| fjs.map = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var mapped = []; | ||
| fjs.each(function () { | ||
| mapped.push(iterator.apply(null, arguments)); | ||
| }, items); | ||
| return mapped; | ||
| }); | ||
| fjs.fold = fjs.foldl = fjs.curry(function (iterator, cumulate, items) { | ||
| iterator = checkFunction(iterator); | ||
| fjs.each(function (item, i) { | ||
| cumulate = iterator.call(null, cumulate, item, i); | ||
| }, items); | ||
| return cumulate; | ||
| }); | ||
| fjs.reduce = fjs.reducel = fjs.foldll = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var cumulate = items[0]; | ||
| items.shift(); | ||
| return fjs.fold(iterator, cumulate, items); | ||
| }); | ||
| fjs.clone = function (items) { | ||
| var clone = []; | ||
| fjs.each(function (item) { | ||
| clone.push(item); | ||
| }, items); | ||
| return clone; | ||
| }; | ||
| fjs.first = fjs.head = fjs.take = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var first; | ||
| fjs.each(function (item) { | ||
| if (iterator.call(null, item)) { | ||
| first = item; | ||
| return hardReturn; | ||
| } | ||
| }, items); | ||
| return first; | ||
| }); | ||
| fjs.rest = fjs.tail = fjs.drop = fjs.curry(function (iterator, items) { | ||
| var result = fjs.select(iterator, items); | ||
| result.shift(); | ||
| return result; | ||
| }); | ||
| fjs.last = fjs.curry(function (iterator, items) { | ||
| var itemsClone = fjs.clone(items); | ||
| return fjs.first(iterator, itemsClone.reverse()); | ||
| }); | ||
| fjs.every = fjs.all = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var isEvery = true; | ||
| fjs.each(function (item) { | ||
| if (!iterator.call(null, item)) { | ||
| isEvery = false; | ||
| return hardReturn; | ||
| } | ||
| }, items); | ||
| return isEvery; | ||
| }); | ||
| fjs.any = fjs.contains = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var isAny = false; | ||
| fjs.each(function (item) { | ||
| if (iterator.call(null, item)) { | ||
| isAny = true; | ||
| return hardReturn; | ||
| } | ||
| }, items); | ||
| return isAny; | ||
| }); | ||
| fjs.select = fjs.filter = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var filtered = []; | ||
| fjs.each(function (item) { | ||
| if (iterator.call(null, item)) { | ||
| filtered.push(item); | ||
| } | ||
| }, items); | ||
| return filtered; | ||
| }); | ||
| fjs.best = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var compare = function (arg1, arg2) { | ||
| return iterator.call(this, arg1, arg2) ? | ||
| arg1 : arg2; | ||
| }; | ||
| return fjs.reduce(compare, items); | ||
| }); | ||
| fjs.while = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var result = []; | ||
| fjs.each(function (item) { | ||
| if (iterator.call(null, item)) { | ||
| result.push(item); | ||
| } else { | ||
| return hardReturn; | ||
| } | ||
| }, items); | ||
| return result; | ||
| }); | ||
| fjs.compose = function (funcs) { | ||
| var anyInvalid = fjs.any(function (func) { | ||
| return !fjs.isFunction(func); | ||
| }); | ||
| funcs = sliceArgs(arguments).reverse(); | ||
| if (anyInvalid(funcs)) { | ||
| throw "fjs Error: Invalid function to compose"; | ||
| } | ||
| return function() { | ||
| var args = arguments; | ||
| var applyEach = fjs.each(function (func) { | ||
| args = [func.apply(null, args)]; | ||
| }); | ||
| applyEach(funcs); | ||
| return args[0]; | ||
| }; | ||
| }; | ||
| fjs.partition = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var truthy = [], | ||
| falsy = []; | ||
| fjs.each(function (item) { | ||
| (iterator.call(null, item) ? truthy : falsy).push(item); | ||
| }, items); | ||
| return [truthy, falsy]; | ||
| }); | ||
| fjs.group = fjs.curry(function (iterator, items) { | ||
| iterator = checkFunction(iterator); | ||
| var result = {}; | ||
| var group; | ||
| fjs.each(function (item) { | ||
| group = iterator.call(null, item); | ||
| result[group] = result[group] || []; | ||
| result[group].push(item); | ||
| }, items); | ||
| return result; | ||
| }); | ||
| fjs.shuffle = function (items) { | ||
| var j, t; | ||
| fjs.each(function(item, i) { | ||
| j = Math.floor(Math.random() * (i + 1)); | ||
| t = items[i]; | ||
| items[i] = items[j]; | ||
| items[j] = t; | ||
| }, items); | ||
| return items; | ||
| }; | ||
| fjs.toArray = function (obj) { | ||
| return fjs.map(function (key) { | ||
| return [key, obj[key]]; | ||
| }, Object.keys(obj)); | ||
| }; | ||
| fjs.apply = fjs.curry(function (func, items) { | ||
| var args = []; | ||
| if (fjs.isArray(func)) { | ||
| args = [].slice.call(func, 1); | ||
| func = func[0]; | ||
| } | ||
| return fjs.map(function (item) { | ||
| return item[func].apply(item, args); | ||
| }, items); | ||
| }); | ||
| fjs.assign = fjs.extend = fjs.curry(function (obj1, obj2) { | ||
| fjs.each(function (key) { | ||
| obj2[key] = obj1[key]; | ||
| }, Object.keys(obj1)); | ||
| return obj2; | ||
| }); | ||
| fjs.prop = function (prop) { | ||
| return function (obj) { | ||
| return obj[prop]; | ||
| }; | ||
| }; | ||
| fjs.pluck = fjs.curry(function (prop, items) { | ||
| return fjs.map(fjs.prop(prop), items); | ||
| }); | ||
| fjs.nub = fjs.unique = fjs.distinct = fjs.curry(function (comparator, items) { | ||
| var unique = items.length > 0 ? [items[0]] : []; | ||
| fjs.each(function (item) { | ||
| if (!fjs.any(fjs.curry(comparator)(item), unique)) { | ||
| unique[unique.length] = item; | ||
| } | ||
| }, items); | ||
| return unique; | ||
| }); | ||
| fjs.exists = function (obj) { | ||
| return obj != null; // jshint ignore:line | ||
| }; | ||
| fjs.truthy = function (obj) { | ||
| return fjs.exists(obj) && obj !== false; | ||
| }; | ||
| fjs.falsy = function (obj) { | ||
| return !fjs.truthy(obj); | ||
| }; | ||
| fjs.each(function(type) { | ||
| fjs["is" + type] = function (obj) { | ||
| return Object.prototype.toString.call(obj) === "[object " + type + "]"; | ||
| }; | ||
| }, ["Arguments", "Date", "Number", "RegExp", "String"]); | ||
| return fjs; | ||
| })(); | ||
| if (typeof (exports) !== "undefined") { | ||
| if (typeof (module) !== "undefined" && module.exports) { | ||
| exports = module.exports = fjs; | ||
| } | ||
| exports.fjs = fjs; | ||
| } |
-19
| var gulp = require("gulp"); | ||
| var jshint = require("gulp-jshint"); | ||
| var jasmine = require("gulp-jasmine"); | ||
| var pkg = require("./package.json"); | ||
| gulp.task("jshint", function () { | ||
| return gulp | ||
| .src("*.js") | ||
| .pipe(jshint()) | ||
| .pipe(jshint.reporter("default")); | ||
| }); | ||
| gulp.task("jasmine", function () { | ||
| return gulp.src("spec.js") | ||
| .pipe(jasmine()); | ||
| }); | ||
| gulp.task("test", ["jshint", "jasmine"]); |
-921
| var fjs = require("./functional.js"); | ||
| describe("functional", function() { | ||
| it("should have a global fjs object", function() { | ||
| expect(fjs).toBeDefined(); | ||
| }); | ||
| it("should throw an error calling fjs.curry with non function or expression", function() { | ||
| var result1 = function () { | ||
| fjs.curry(); | ||
| }; | ||
| var result2 = function () { | ||
| fjs.curry(1); | ||
| }; | ||
| expect(result1).toThrow("fjs Error: Invalid function"); | ||
| expect(result2).toThrow("fjs Error: Invalid function"); | ||
| }); | ||
| it("should fjs.curry a string concatenation function", function() { | ||
| var concatenate = fjs.curry(function(word1, word2) { | ||
| return word1 + " " + word2; | ||
| }); | ||
| var concatenateHello = concatenate("Hello"); | ||
| var result = concatenateHello("World"); | ||
| expect(result).toEqual("Hello World"); | ||
| }); | ||
| it("should fjs.curry a string concatenation expression", function() { | ||
| var concatenate = fjs.curry("a, b => a + b"); | ||
| var concatenateHello = concatenate("Hello"); | ||
| var result = concatenateHello("World"); | ||
| expect(result).toEqual("HelloWorld"); | ||
| }); | ||
| it("should fjs.curry an addition function with multiple args and fjs.curry the fjs.curry", function() { | ||
| var add = fjs.curry(function(arg1, arg2, arg3) { | ||
| return arg1 + arg2 + arg3; | ||
| }); | ||
| var add3 = add(3), | ||
| add5 = add3(2); | ||
| expect(add(3)(2)(1)).toEqual(6); | ||
| expect(add3(2, 1)).toEqual(6); | ||
| expect(add3(2)(1)).toEqual(6); | ||
| expect(add5(1)).toEqual(6); | ||
| }); | ||
| it("should extend the arity using fjs.curry", function() { | ||
| var add = fjs.curry(function(arg1, arg2) { | ||
| return arg1 + arg2; | ||
| }); | ||
| var add3 = add(3); | ||
| expect(add(1, 2, 3)).toEqual(6); | ||
| expect(add3(1, 2, 3, 4, 5)).toEqual(18); | ||
| }); | ||
| it("should extend the arity using expression", function() { | ||
| var add = fjs.curry("a, b => a + b"); | ||
| var add3 = add(3); | ||
| expect(add(1, 2, 3)).toEqual(6); | ||
| expect(add3(1, 2, 3, 4, 5)).toEqual(18); | ||
| }); | ||
| it("should be able to add items to an array using fjs.each", function() { | ||
| var result = [], | ||
| items = ["f", "u", "n", "c"]; | ||
| var addTo = function (item) { | ||
| return result.push(item); | ||
| }; | ||
| fjs.each(addTo, items); | ||
| expect(result).toEqual(items); | ||
| }); | ||
| it("should be able to fjs.curry fjs.each", function() { | ||
| var result = [], | ||
| items = ["f", "u", "n", "c"]; | ||
| var addTo = function (item) { | ||
| return result.push(item); | ||
| }; | ||
| var addToResult = fjs.each(addTo); | ||
| expect(fjs.isFunction(addToResult)).toBeTruthy(); | ||
| addToResult(items); | ||
| expect(result).toEqual(["f", "u", "n", "c"]); | ||
| }); | ||
| it("should handle null param to fjs.each", function() { | ||
| var nothing = function (item) { | ||
| return item; | ||
| }; | ||
| var doNothing = fjs.each(nothing); | ||
| var result = function () { | ||
| doNothing(null); | ||
| }; | ||
| expect(result).not.toThrow(); | ||
| }); | ||
| it("should pass the current index when using fjs.each", function() { | ||
| var result = [], | ||
| items = ["f", "u", "n", "c"]; | ||
| fjs.each(function (item, i) { | ||
| return result.push(i); | ||
| }, items); | ||
| expect(result).toEqual([0, 1, 2, 3]); | ||
| }); | ||
| it("should allow bind using fjs.each", function() { | ||
| var result = [], | ||
| items = ["f", "u", "n", "c"]; | ||
| var iterator = function (val, item, i) { | ||
| return result.push(val + item + i); | ||
| }; | ||
| fjs.each(iterator.bind(this, "val"), items); | ||
| expect(result).toEqual(["valf0", "valu1", "valn2", "valc3"]); | ||
| }); | ||
| it("should be able to double numbers in an array using fjs.map", function() { | ||
| var items = [1, 2, 3]; | ||
| var doubleUp = function (number) { | ||
| return number * 2; | ||
| }; | ||
| var result = fjs.map(doubleUp, items); | ||
| expect(result).toEqual([2, 4, 6]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.map", function() { | ||
| var items = [1, 2, 3]; | ||
| var doubleUp = function (number) { | ||
| return number * 2; | ||
| }; | ||
| var doubleMap = fjs.map(doubleUp); | ||
| expect(fjs.isFunction(doubleMap)).toBeTruthy(); | ||
| var result = doubleMap(items); | ||
| expect(result).toEqual([2, 4, 6]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.map expression", function() { | ||
| var items = [1, 2, 3]; | ||
| var doubleMap = fjs.map("n => n * 2"); | ||
| var result = doubleMap(items); | ||
| expect(result).toEqual([2, 4, 6]); | ||
| }); | ||
| it("should be able to use current index with fjs.map", function() { | ||
| var items = [1, 2, 3]; | ||
| var timesIndex = function (number, i) { | ||
| return number * i; | ||
| }; | ||
| var result = fjs.map(timesIndex, items); | ||
| expect(result).toEqual([0, 2, 6]); | ||
| }); | ||
| it("should be able to use fjs.reduce, fjs.reducel or fjs.foldll", function() { | ||
| expect(fjs.reduce).toEqual(fjs.reducel); | ||
| expect(fjs.reduce).toEqual(fjs.foldll); | ||
| }); | ||
| it("should be able to cumulate an array of numbers using fjs.reduce", function() { | ||
| var items = [1, 2, 3]; | ||
| var add = function (arg1, arg2) { | ||
| return arg1 + arg2; | ||
| }; | ||
| var result = fjs.reduce(add, items); | ||
| expect(result).toEqual(6); | ||
| }); | ||
| it("should be able to cumulate an array of strings using fjs.reduce", function() { | ||
| var items = ["f", "u", "n", "c"]; | ||
| var concatenate = function (arg1, arg2) { | ||
| return arg1 + arg2; | ||
| }; | ||
| var result = fjs.reduce(concatenate, items); | ||
| expect(result).toEqual("func"); | ||
| }); | ||
| it("should be able use current index with fjs.reduce", function() { | ||
| var items = [1, 2, 3, 4]; | ||
| var add = function (arg1, arg2, i) { | ||
| return arg1 + arg2 + i; | ||
| }; | ||
| var result = fjs.reduce(add, items); | ||
| expect(result).toEqual(13); | ||
| }); | ||
| it("should be able to fjs.curry fjs.reduce", function() { | ||
| var items = [1, 2, 3]; | ||
| var multiply = function (arg1, arg2) { | ||
| return arg1 * arg2; | ||
| }; | ||
| var multiplyReduce = fjs.reduce(multiply); | ||
| expect(fjs.isFunction(multiplyReduce)).toBeTruthy(); | ||
| var result = multiplyReduce(items); | ||
| expect(result).toEqual(6); | ||
| }); | ||
| it("should be able to fjs.curry fjs.reduce expression", function() { | ||
| var items = [1, 2, 3]; | ||
| var multiply = function (arg1, arg2) { | ||
| return arg1 * arg2; | ||
| }; | ||
| var multiplyReduce = fjs.reduce("a, b => a * b"); | ||
| var result = multiplyReduce(items); | ||
| expect(result).toEqual(6); | ||
| }); | ||
| it("should be able to use fjs.fold or fjs.foldl", function() { | ||
| expect(fjs.fold).toEqual(fjs.foldl); | ||
| }); | ||
| it("should be able to fjs.curry fjs.fold", function() { | ||
| var items = [1, 2, 3]; | ||
| var multiply = function (arg1, arg2) { | ||
| return arg1 * arg2; | ||
| }; | ||
| var multiplyFoldFrom10 = fjs.fold(multiply, 10); | ||
| expect(fjs.isFunction(multiplyFoldFrom10)).toBeTruthy(); | ||
| var result = multiplyFoldFrom10(items); | ||
| expect(result).toEqual(60); | ||
| }); | ||
| it("should be able to fjs.curry fjs.fold expression", function() { | ||
| var items = [1, 2, 3]; | ||
| var multiplyFoldFrom10 = fjs.fold("a, b => a * b", 10); | ||
| var result = multiplyFoldFrom10(items); | ||
| expect(result).toEqual(60); | ||
| }); | ||
| it("should be able to fjs.curry fjs.best", function() { | ||
| var items = [1, -4, 2, 3]; | ||
| var biggest = function (arg1, arg2) { | ||
| return arg1 > arg2; | ||
| }; | ||
| var smallest = function (arg1, arg2) { | ||
| return arg1 < arg2; | ||
| }; | ||
| var biggestAndBest = fjs.best(biggest); | ||
| var bestSmallest = fjs.best(smallest); | ||
| expect(fjs.isFunction(biggestAndBest)).toBeTruthy(); | ||
| expect(fjs.isFunction(bestSmallest)).toBeTruthy(); | ||
| expect(biggestAndBest(items)).toEqual(3); | ||
| expect(bestSmallest(items)).toEqual(-4); | ||
| }); | ||
| it("should be able to fjs.curry fjs.best to get the longest word", function() { | ||
| var words = ["simply", "the", "best"]; | ||
| var longest = fjs.best(function (arg1, arg2) { | ||
| return arg1.length > arg2.length; | ||
| }); | ||
| expect(fjs.isFunction(longest)).toBeTruthy(); | ||
| expect(longest(words)).toEqual("simply"); | ||
| }); | ||
| it("should be able to fjs.curry fjs.best expression", function() { | ||
| var words = ["simply", "the", "best"]; | ||
| var longest = fjs.best("a, b => a.length > b.length"); | ||
| expect(longest(words)).toEqual("simply"); | ||
| }); | ||
| it("should be able to fjs.curry fjs.while to get even numbers until odd", function() { | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var whileEven = fjs.while(even); | ||
| expect(whileEven([2])).toEqual([2]); | ||
| expect(whileEven([2, 4, 5, 6])).toEqual([2, 4]); | ||
| expect(whileEven([1, 4, 6, 8])).toEqual([]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.while expression", function() { | ||
| var whileEven = fjs.while("n => n % 2 === 0"); | ||
| expect(whileEven([2])).toEqual([2]); | ||
| expect(whileEven([2, 4, 5, 6])).toEqual([2, 4]); | ||
| expect(whileEven([1, 4, 6, 8])).toEqual([]); | ||
| }); | ||
| it("should be able to use fjs.any or fjs.contains", function() { | ||
| expect(fjs.any).toEqual(fjs.contains); | ||
| }); | ||
| it("should be able to fjs.curry fjs.any", function() { | ||
| var items1 = [1, 2, 3], | ||
| items2 = [1, 3, 5]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var anyEven = fjs.any(even); | ||
| var containsEven = fjs.contains(even); | ||
| expect(anyEven(items1)).toBeTruthy(); | ||
| expect(containsEven(items1)).toBeTruthy(); | ||
| expect(anyEven(items2)).not.toBeTruthy(); | ||
| expect(containsEven(items2)).not.toBeTruthy(); | ||
| }); | ||
| it("should be able to fjs.curry fjs.any or fjs.contains expression", function() { | ||
| var items1 = [1, 2, 3], | ||
| items2 = [1, 3, 5]; | ||
| var anyEven = fjs.any("n => n % 2 === 0"); | ||
| var containsEven = fjs.contains("n => n % 2 === 0"); | ||
| expect(anyEven(items1)).toBeTruthy(); | ||
| expect(containsEven(items1)).toBeTruthy(); | ||
| expect(anyEven(items2)).not.toBeTruthy(); | ||
| expect(containsEven(items2)).not.toBeTruthy(); | ||
| }); | ||
| it("should be able to fjs.curry fjs.select", function() { | ||
| var items = [1, 2, 3, 4, 5]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var odd = function (item) { | ||
| return item % 2 !== 0; | ||
| }; | ||
| var selectEven = fjs.select(even); | ||
| var selectOdd = fjs.select(odd); | ||
| expect(selectEven(items)).toEqual([2, 4]); | ||
| expect(selectOdd(items)).toEqual([1, 3, 5]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.select expression", function() { | ||
| var items = [1, 2, 3, 4, 5]; | ||
| var selectEven = fjs.select("n => n % 2 === 0"); | ||
| var selectOdd = fjs.select("n => n % 2 !== 0"); | ||
| expect(selectEven(items)).toEqual([2, 4]); | ||
| expect(selectOdd(items)).toEqual([1, 3, 5]); | ||
| }); | ||
| it("should be able to fjs.clone an array and keep independence", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var clonedItems = fjs.clone(items); | ||
| expect(clonedItems).toEqual(items); | ||
| items = []; | ||
| expect(clonedItems).not.toEqual(items); | ||
| }); | ||
| it("should be able to use fjs.first, fjs.head or fjs.take", function() { | ||
| expect(fjs.first).toEqual(fjs.head); | ||
| expect(fjs.first).toEqual(fjs.take); | ||
| }); | ||
| it("should be able to fjs.curry fjs.first", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var odd = function (item) { | ||
| return item % 2 !== 0; | ||
| }; | ||
| var firstEven = fjs.first(even); | ||
| var firstOdd = fjs.first(odd); | ||
| expect(firstEven(items)).toEqual(4); | ||
| expect(firstOdd(items)).toEqual(5); | ||
| }); | ||
| it("should be able to fjs.curry fjs.first expression", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var firstEven = fjs.first("n => n % 2 === 0"); | ||
| var firstOdd = fjs.first("n => n % 2 !== 0"); | ||
| var first = fjs.first("n => n"); | ||
| expect(firstEven(items)).toEqual(4); | ||
| expect(firstOdd(items)).toEqual(5); | ||
| expect(first(items)).toEqual(5); | ||
| }); | ||
| it("should be able to use fjs.rest, fjs.tail or fjs.drop", function() { | ||
| expect(fjs.rest).toEqual(fjs.tail); | ||
| expect(fjs.rest).toEqual(fjs.drop); | ||
| }); | ||
| it("should be able to fjs.curry fjs.rest", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var odd = function (item) { | ||
| return item % 2 !== 0; | ||
| }; | ||
| var restEven = fjs.rest(even); | ||
| var restOdd = fjs.rest(odd); | ||
| expect(restEven(items)).toEqual([2]); | ||
| expect(restOdd(items)).toEqual([3, 1]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.rest expression", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var restEven = fjs.rest("n => n % 2 === 0"); | ||
| var restOdd = fjs.rest("n => n % 2 !== 0"); | ||
| var rest = fjs.rest("n => n"); | ||
| expect(restEven(items)).toEqual([2]); | ||
| expect(restOdd(items)).toEqual([3, 1]); | ||
| expect(rest(items)).toEqual([4, 3, 2, 1]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.last", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var odd = function (item) { | ||
| return item % 2 !== 0; | ||
| }; | ||
| var lastEven = fjs.last(even); | ||
| var lastOdd = fjs.last(odd); | ||
| expect(lastEven(items)).toEqual(2); | ||
| expect(lastOdd(items)).toEqual(1); | ||
| }); | ||
| it("should be able to fjs.curry fjs.last expression", function() { | ||
| var items = [5, 4, 3, 2, 1]; | ||
| var lastEven = fjs.last("n => n % 2 === 0"); | ||
| var lastOdd = fjs.last("n => n % 2 !== 0"); | ||
| var last = fjs.last("n => n"); | ||
| expect(lastEven(items)).toEqual(2); | ||
| expect(lastOdd(items)).toEqual(1); | ||
| expect(last(items)).toEqual(1); | ||
| }); | ||
| it("should be able to fjs.curry fjs.every", function() { | ||
| var items = [2, 4, 6, 8]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var odd = function (item) { | ||
| return item % 2 !== 0; | ||
| }; | ||
| var everyEven = fjs.every(even); | ||
| var everyOdd = fjs.every(odd); | ||
| expect(everyEven(items)).toEqual(true); | ||
| expect(everyOdd(items)).toEqual(false); | ||
| }); | ||
| it("should be able to fjs.curry fjs.every expression", function() { | ||
| var items = [2, 4, 6, 8]; | ||
| var everyEven = fjs.every("n => n % 2 === 0"); | ||
| var everyOdd = fjs.every("n => n % 2 !== 0"); | ||
| expect(everyEven(items)).toEqual(true); | ||
| expect(everyOdd(items)).toEqual(false); | ||
| }); | ||
| it("should be able to use fjs.every or fjs.all", function() { | ||
| expect(fjs.every).toEqual(fjs.all); | ||
| }); | ||
| it("should throw an error attempting to fjs.compose anything that isn't a function", function() { | ||
| var f = function (a) { | ||
| return "hello " + a; | ||
| }; | ||
| var g = 1; | ||
| var result = function () { | ||
| fjs.compose(f, g); | ||
| }; | ||
| expect(result).toThrow("fjs Error: Invalid function to compose"); | ||
| }); | ||
| it("should be able to fjs.compose two functions", function() { | ||
| var f = function (a) { | ||
| return "hello " + a; | ||
| }; | ||
| var g = function (a) { | ||
| return a + 1; | ||
| }; | ||
| var composed = fjs.compose(f, g); | ||
| expect(composed(1)).toEqual("hello 2"); | ||
| }); | ||
| it("should be able to fjs.compose multiple functions", function() { | ||
| var e = function (a) { | ||
| return "hello " + a; | ||
| }; | ||
| var f = function (a) { | ||
| return a + 1; | ||
| }; | ||
| var g = function (a) { | ||
| return a * 100; | ||
| }; | ||
| var composed = fjs.compose(e, f, g); | ||
| expect(composed(2)).toEqual("hello 201"); | ||
| }); | ||
| it("fjs.compose should return the same value when called with the same argument", function() { | ||
| var f = function (a) { | ||
| return "hello " + a; | ||
| }; | ||
| var g = function (a) { | ||
| return a + 1; | ||
| }; | ||
| var composed = fjs.compose(f, g); | ||
| expect(composed(1)).toEqual(composed(1)); | ||
| }); | ||
| it("should be able to fjs.partition an array of odd and even numbers", function() { | ||
| var items = [1, 2, 3, 4, 5, 6, 7]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var result = fjs.partition(even, items); | ||
| expect(result).toEqual([[2, 4, 6], [1, 3, 5, 7]]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.partition", function() { | ||
| var items = [7, 6, 5, 4, 3, 2, 1]; | ||
| var even = function (item) { | ||
| return item % 2 === 0; | ||
| }; | ||
| var partitionEven = fjs.partition(even); | ||
| var result = partitionEven(items); | ||
| expect(result).toEqual([[6, 4, 2], [7, 5, 3, 1]]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.partition expression", function() { | ||
| var items = [7, 6, 5, 4, 3, 2, 1]; | ||
| var partitionEven = fjs.partition("n => n % 2 === 0"); | ||
| var result = partitionEven(items); | ||
| expect(result).toEqual([[6, 4, 2], [7, 5, 3, 1]]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.group", function() { | ||
| var items = ["Lee", "Ryan", "Leona", "Sarah", "Rob", "Liam"]; | ||
| var firstLetter = function (item) { | ||
| return item.charAt(0); | ||
| }; | ||
| var groupFirstLetter = fjs.group(firstLetter); | ||
| var result = groupFirstLetter(items); | ||
| expect(result).toEqual({"L": [ "Lee", "Leona", "Liam" ], | ||
| "R": [ "Ryan", "Rob" ], "S": [ "Sarah" ]}); | ||
| }); | ||
| it("should be able to fjs.curry fjs.group", function() { | ||
| var items = ["Lee", "Ryan", "Leona", "Sarah", "Rob", "Liam"]; | ||
| var groupFirstLetter = fjs.group("a => a.charAt(0)"); | ||
| var result = groupFirstLetter(items); | ||
| expect(result).toEqual({"L": [ "Lee", "Leona", "Liam" ], | ||
| "R": [ "Ryan", "Rob" ], "S": [ "Sarah" ]}); | ||
| }); | ||
| it("should be able to fjs.curry fjs.pluck", function() { | ||
| var items = [{ | ||
| "p1": "abc", | ||
| "p2": false, | ||
| "p3": 123 | ||
| }, { | ||
| "p1": "cab", | ||
| "p2": true, | ||
| "p3": 312 | ||
| },{ | ||
| "p1": "bca", | ||
| "p2": false, | ||
| "p3": 231 | ||
| }]; | ||
| var pluck1 = fjs.pluck("p1"); | ||
| var result1 = pluck1(items); | ||
| var pluck2 = fjs.pluck("p2"); | ||
| var result2 = pluck2(items); | ||
| expect(result1).toEqual(["abc", "cab", "bca"]); | ||
| expect(result2).toEqual([false, true, false]); | ||
| }); | ||
| it("should convert an object to an array", function() { | ||
| var obj = { | ||
| "p1": "abc", | ||
| "p2": false, | ||
| "p3": null | ||
| }; | ||
| var result = fjs.toArray(obj); | ||
| expect(result).toEqual([["p1", "abc"], ["p2", false], ["p3", null]]); | ||
| expect(fjs.isArray(obj)).toBeFalsy(); | ||
| expect(fjs.isArray(result)).toBeTruthy(); | ||
| }); | ||
| it("should be able to fjs.curry fjs.apply", function() { | ||
| var items = ["Hello", "World"]; | ||
| var applyCase = fjs.apply("toUpperCase"); | ||
| var result = applyCase(items); | ||
| expect(result).toEqual(["HELLO", "WORLD"]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.apply with additional argument", function() { | ||
| var items = ["Hello", "World"]; | ||
| var applyIndexOf = fjs.apply(["indexOf", "o"]); | ||
| var result = applyIndexOf(items); | ||
| expect(result).toEqual([4, 1]); | ||
| }); | ||
| it("should be able to fjs.curry fjs.apply with multiple arguments", function() { | ||
| var items = ["Hello", "World"]; | ||
| var applyIndexOf = fjs.apply(["substring", "1", "4"]); | ||
| var result = applyIndexOf(items); | ||
| expect(result).toEqual(["ell", "orl"]); | ||
| }); | ||
| it("should be able to use fjs.assign or fjs.extend", function() { | ||
| expect(fjs.assign).toEqual(fjs.extend); | ||
| }); | ||
| it("should be able to do a basic fjs.assign", function() { | ||
| var obj1 = { | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2" | ||
| }; | ||
| var obj2 = { | ||
| prop2: "obj2prop2", | ||
| prop3: "obj2prop3" | ||
| }; | ||
| var result = fjs.assign(obj1, obj2); | ||
| expect(result).toEqual({ | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2", | ||
| prop3: "obj2prop3" | ||
| }); | ||
| }); | ||
| it("should be able to fjs.curry fjs.assign and extend the arity", function() { | ||
| var obj1 = { | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2" | ||
| }; | ||
| var obj2 = { | ||
| prop2: "obj2prop2", | ||
| prop3: "obj2prop3", | ||
| prop4: "obj2prop4" | ||
| }; | ||
| var obj3 = { | ||
| prop4: "obj3prop4", | ||
| prop5: "obj3prop5" | ||
| }; | ||
| var assignToObj1 = fjs.assign(obj1); | ||
| var result1 = assignToObj1(obj2, obj3); | ||
| var result2 = fjs.assign(obj1, obj2, obj3); | ||
| expect(result1).toEqual({ | ||
| prop1: "obj1prop1", | ||
| prop2: "obj1prop2", | ||
| prop3: "obj2prop3", | ||
| prop4: "obj2prop4", | ||
| prop5: "obj3prop5" | ||
| }); | ||
| expect(result1).toEqual(result2); | ||
| }); | ||
| it("should be able to use fjs.nub, fjs.unique or fjs.distinct", function() { | ||
| expect(fjs.nub).toEqual(fjs.unique); | ||
| expect(fjs.nub).toEqual(fjs.distinct); | ||
| }); | ||
| it("should remove duplicate elements from a list with fjs.nub", function() { | ||
| var base = ["John", "Jane", "Jane", "Jane", "Joe", "John", "Joe"]; | ||
| var expected = ["John", "Jane", "Joe"]; | ||
| var actual = fjs.nub(function (arg1, arg2) { | ||
| return arg1 === arg2; | ||
| }, base); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should return one item when fjs.nub list of one", function() { | ||
| var base = [1]; | ||
| var actual = fjs.nub(function (arg1, arg2) { | ||
| return arg1 === arg2; | ||
| }, base); | ||
| expect(actual).toEqual(base); | ||
| }); | ||
| it("should return empty when fjs.nub of empty list", function() { | ||
| var empty = []; | ||
| var actual = fjs.nub(function (arg1, arg2) { | ||
| return arg1 === arg2; | ||
| }, empty); | ||
| expect(actual).toEqual(empty); | ||
| }); | ||
| it("should be able to fjs.curry fjs.nub expression", function() { | ||
| var base = [1,2,4,5,5,5,6,7,8,8]; | ||
| var expected = [1,2,4,5,6,7,8]; | ||
| var nubByEquality = fjs.nub(function (arg1, arg2) { | ||
| return arg1 === arg2; | ||
| }); | ||
| var actual = nubByEquality(base); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should be able to fjs.nub with a complex comparator", function() { | ||
| var base = [{value1: 1, value2: 2},{value1: 9, value2: 2}, | ||
| {value1: 3, value2: 1},{value1: 1, value2: 4},{value1: 44, value2: 4}]; | ||
| var expected = [{value1: 1, value2: 2},{value1: 3, value2: 1},{value1: 1, value2: 4},]; | ||
| var actual = fjs.nub(function (arg1, arg2) { | ||
| return arg1.value2 === arg2.value2; | ||
| }, base); | ||
| expect(actual).toEqual(expected); | ||
| }); | ||
| it("should have correct return values for fjs.exists", function() { | ||
| expect(fjs.exists(undefined)).toBeFalsy(); | ||
| expect(fjs.exists(null)).toBeFalsy(); | ||
| expect(fjs.exists(1)).toBeTruthy(); | ||
| expect(fjs.exists(-1)).toBeTruthy(); | ||
| expect(fjs.exists(0)).toBeTruthy(); | ||
| expect(fjs.exists("abc")).toBeTruthy(); | ||
| expect(fjs.exists("")).toBeTruthy(); | ||
| expect(fjs.exists(Number.MAX_VALUE)).toBeTruthy(); | ||
| expect(fjs.exists(Number.MIN_VALUE)).toBeTruthy(); | ||
| expect(fjs.exists(NaN)).toBeTruthy(); | ||
| expect(fjs.exists(0144)).toBeTruthy(); | ||
| expect(fjs.exists(0xFF)).toBeTruthy(); | ||
| expect(fjs.exists(0.1)).toBeTruthy(); | ||
| expect(fjs.exists(-0.1)).toBeTruthy(); | ||
| expect(fjs.exists(3e5)).toBeTruthy(); | ||
| expect(fjs.exists(true)).toBeTruthy(); | ||
| expect(fjs.exists(false)).toBeTruthy(); | ||
| expect(fjs.exists(Infinity)).toBeTruthy(); | ||
| expect(fjs.exists(Number.POSITIVE_INFINITY)).toBeTruthy(); | ||
| expect(fjs.exists(Number.NEGATIVE_INFINITY)).toBeTruthy(); | ||
| expect(fjs.exists(new Date())).toBeTruthy(); | ||
| expect(fjs.exists([])).toBeTruthy(); | ||
| expect(fjs.exists({})).toBeTruthy(); | ||
| expect(fjs.exists(function() { })).toBeTruthy(); | ||
| }); | ||
| it("should have correct return values for fjs.truthy", function() { | ||
| expect(fjs.truthy(undefined)).toBeFalsy(); | ||
| expect(fjs.truthy(null)).toBeFalsy(); | ||
| expect(fjs.truthy(false)).toBeFalsy(); | ||
| expect(fjs.truthy(1)).toBeTruthy(); | ||
| expect(fjs.truthy(-1)).toBeTruthy(); | ||
| expect(fjs.truthy(0)).toBeTruthy(); | ||
| expect(fjs.truthy("abc")).toBeTruthy(); | ||
| expect(fjs.truthy("")).toBeTruthy(); | ||
| expect(fjs.truthy(Number.MAX_VALUE)).toBeTruthy(); | ||
| expect(fjs.truthy(Number.MIN_VALUE)).toBeTruthy(); | ||
| expect(fjs.truthy(NaN)).toBeTruthy(); | ||
| expect(fjs.truthy(0144)).toBeTruthy(); | ||
| expect(fjs.truthy(0xFF)).toBeTruthy(); | ||
| expect(fjs.truthy(0.1)).toBeTruthy(); | ||
| expect(fjs.truthy(-0.1)).toBeTruthy(); | ||
| expect(fjs.truthy(3e5)).toBeTruthy(); | ||
| expect(fjs.truthy(true)).toBeTruthy(); | ||
| expect(fjs.truthy(Infinity)).toBeTruthy(); | ||
| expect(fjs.truthy(Number.POSITIVE_INFINITY)).toBeTruthy(); | ||
| expect(fjs.truthy(Number.NEGATIVE_INFINITY)).toBeTruthy(); | ||
| expect(fjs.truthy(new Date())).toBeTruthy(); | ||
| expect(fjs.truthy([])).toBeTruthy(); | ||
| expect(fjs.truthy({})).toBeTruthy(); | ||
| expect(fjs.truthy(function() { })).toBeTruthy(); | ||
| }); | ||
| it("should have correct return values for fjs.falsy", function() { | ||
| expect(fjs.falsy(undefined)).toBeTruthy(); | ||
| expect(fjs.falsy(null)).toBeTruthy(); | ||
| expect(fjs.falsy(false)).toBeTruthy(); | ||
| expect(fjs.falsy(1)).toBeFalsy(); | ||
| expect(fjs.falsy(-1)).toBeFalsy(); | ||
| expect(fjs.falsy(0)).toBeFalsy(); | ||
| expect(fjs.falsy("abc")).toBeFalsy(); | ||
| expect(fjs.falsy("")).toBeFalsy(); | ||
| expect(fjs.falsy(Number.MAX_VALUE)).toBeFalsy(); | ||
| expect(fjs.falsy(Number.MIN_VALUE)).toBeFalsy(); | ||
| expect(fjs.falsy(NaN)).toBeFalsy(); | ||
| expect(fjs.falsy(0144)).toBeFalsy(); | ||
| expect(fjs.falsy(0xFF)).toBeFalsy(); | ||
| expect(fjs.falsy(0.1)).toBeFalsy(); | ||
| expect(fjs.falsy(-0.1)).toBeFalsy(); | ||
| expect(fjs.falsy(3e5)).toBeFalsy(); | ||
| expect(fjs.falsy(true)).toBeFalsy(); | ||
| expect(fjs.falsy(Infinity)).toBeFalsy(); | ||
| expect(fjs.falsy(Number.POSITIVE_INFINITY)).toBeFalsy(); | ||
| expect(fjs.falsy(Number.NEGATIVE_INFINITY)).toBeFalsy(); | ||
| expect(fjs.falsy(new Date())).toBeFalsy(); | ||
| expect(fjs.falsy([])).toBeFalsy(); | ||
| expect(fjs.falsy({})).toBeFalsy(); | ||
| expect(fjs.falsy(function() { })).toBeFalsy(); | ||
| }); | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
298428
528.88%25
150%3913
281.01%217
228.79%0
-100%Yes
NaN11
120%1
Infinity%