UNPKG

@apoyo/std

Version:
1,023 lines (1,004 loc) 27.1 kB
// src/types.ts var isNumber = (value) => typeof value === "number"; var isNaN2 = (value) => Number.isNaN(value); var isNull = (value) => value === null; var isUndefined = (value) => value === void 0; var isObject = (input) => typeof input === "object" && input !== null; var isFunction = (input) => typeof input === "function"; // src/pipe.ts function pipe(a, ...fns) { return fns.reduce((value, fn) => fn(value), a); } // src/flow.ts function flow(...fns) { return (a) => fns.reduce((value, fn) => fn(value), a); } // src/function.ts function fcurry2(fn) { return function(...args) { return args.length === 1 ? (x) => fn(x, args[0]) : fn(args[0], args[1]); }; } var identity = (a) => a; var constant = (a) => () => a; var cast = (a) => a; function not(predicate) { return (value, indexOrKey) => !predicate(value, indexOrKey); } var tuple = (...t) => t; var tupled = (f) => (a) => f(...a); var untupled = (f) => (...a) => f(a); function throwError(err) { throw err; } var first = (a, _b) => a; var last = (_a, b) => b; var add = fcurry2((a, b) => a + b); function or(...fns) { return (value, indexOrKey) => fns.some((fn) => fn(value, indexOrKey)); } function and(...fns) { return (value, indexOrKey) => fns.every((fn) => fn(value, indexOrKey)); } var once = (fn) => { let result; let done = false; return (...args) => { if (!done) { result = fn(...args); done = true; } return result; }; }; var run = (fn) => fn(); // src/Option.ts var isSome = (value) => value !== void 0; var isNone = (value) => value === void 0; var fromNullable = (value) => value === null ? void 0 : value; var fromFalsy = (value) => !value ? void 0 : value; var fromString = (value) => value === "" ? void 0 : value; var fromNumber = (value) => isNaN(value) ? void 0 : value; var fromDate = (value) => isNaN(value.getTime()) ? void 0 : value; var map = (fn) => (value) => isSome(value) ? fn(value) : void 0; function filter(fn) { return (value) => isSome(value) && fn(value) ? value : void 0; } function reject(fn) { return filter(not(fn)); } function get(valueOrFn) { return (value) => isSome(value) ? value : typeof valueOrFn === "function" ? valueOrFn() : valueOrFn; } function throwError2(errOrFn) { return (value) => isSome(value) ? value : typeof errOrFn === "function" ? throwError(errOrFn()) : throwError(errOrFn); } var Option = { isSome, isNone, map, filter, reject, get, throwError: throwError2, fromNullable, fromFalsy, fromString, fromNumber, fromDate }; // src/Dict.ts var isDict = (input) => typeof input === "object" && input !== null; var isEmpty2 = (dict) => pipe(dict, keys, isEmpty); var set = (key, value) => (dict) => (dict[key] = value, dict); var lookup = (key) => (dict) => dict[key]; var get2 = lookup; var reduce = (fn, initial) => (dict) => { let result = initial; const props = Object.keys(dict); const len = props.length; for (let i = 0; i < len; ++i) { const key = props[i]; const value = dict[key]; result = fn(result, value, key); } return result; }; var mapIndexed = (fn) => (dict) => pipe(dict, reduce((acc, value, key) => pipe(acc, set(key, fn(value, key))), {})); var map2 = (fn) => mapIndexed((v) => fn(v)); function filter2(fn) { return (arr) => pipe(arr, reduce((acc, value, key) => fn(value, key) ? pipe(acc, set(key, value)) : acc, {})); } function reject2(fn) { return filter2(not(fn)); } var filterMap = (fn) => (dict) => pipe(dict, reduce((acc, value, key) => pipe(fn(value, key), (value2) => isSome(value2) ? pipe(acc, set(key, value2)) : acc), {})); var compact = (value) => pipe(value, filterMap(identity)); var collect = (fn) => (dict) => pipe(dict, reduce((acc, value, key) => (acc.push(fn(value, key)), acc), [])); function omit(props) { const propsSet = new Set(props); return Dict.reject((_, key) => propsSet.has(key)); } function pick(props) { const propsSet = new Set(props); return Dict.filter((_, key) => propsSet.has(key)); } var values = (dict) => pipe(dict, collect(identity)); var keys = (dict) => Object.keys(dict); var fromPairs = (pairs) => { const dict = {}; for (let i = 0; i < pairs.length; ++i) { const [key, value] = pairs[i]; dict[key] = value; } return dict; }; var toPairs = (dict) => pipe(dict, collect((value, key) => [key, value])); var concat = (member) => (dict) => Object.assign({}, dict, member); var union = (member) => (dict) => Object.assign({}, member, dict); var intersect = (member) => (dict) => pipe(dict, filterMap((value, key) => isSome(member[key]) ? value : void 0)); var difference = (member) => (dict) => pipe(dict, filterMap((value, key) => isSome(member[key]) ? void 0 : value)); var Dict = { isEmpty: isEmpty2, lookup, get: get2, set, map: map2, mapIndexed, filter: filter2, reject: reject2, filterMap, compact, reduce, collect, isDict, keys, values, fromPairs, toPairs, concat, union, intersect, difference, omit, pick }; // src/Ord.ts var Ordering = /* @__PURE__ */ ((Ordering2) => { Ordering2[Ordering2["UP"] = 1] = "UP"; Ordering2[Ordering2["DOWN"] = -1] = "DOWN"; Ordering2[Ordering2["EQ"] = 0] = "EQ"; return Ordering2; })(Ordering || {}); var string = (a, b) => a > b ? 1 : a === b ? 0 : -1; var number = (a, b) => a > b ? 1 : a === b ? 0 : -1; var boolean = (a, b) => a > b ? 1 : a === b ? 0 : -1; var date = (a, b) => number(a.valueOf(), b.valueOf()); var contramap = (fn) => (ord) => (a, b) => ord(fn(a), fn(b)); var inverse = (ord) => (a, b) => ord(b, a); var optional = (ord) => (a, b) => a === b ? 0 : isSome(a) ? isSome(b) ? ord(a, b) : -1 : 1; var nullable = (ord) => (a, b) => a === b ? 0 : a !== null ? b !== null ? ord(a, b) : -1 : 1; function concat2(...ords) { return (a, b) => { for (let i = 0; i < ords.length; ++i) { const ord = ords[i]; const result = ord(a, b); if (result !== 0) { return result; } } return 0; }; } function eq(ord) { return fcurry2((x, y) => ord(x, y) === 0 /* EQ */); } function lt(ord) { return fcurry2((x, y) => ord(x, y) < 0 /* EQ */); } function lte(ord) { return fcurry2((x, y) => ord(x, y) <= 0 /* EQ */); } function gt(ord) { return fcurry2((x, y) => ord(x, y) > 0 /* EQ */); } function gte(ord) { return fcurry2((x, y) => ord(x, y) >= 0 /* EQ */); } function min(ord) { return fcurry2((x, y) => ord(x, y) <= 0 /* EQ */ ? x : y); } function max(ord) { return min(inverse(ord)); } var Ord = { string, number, boolean, date, contramap, inverse, optional, nullable, concat: concat2, eq, lt, lte, gt, gte, min, max }; // src/NonEmptyArray.ts var of = (value) => [value]; function fromArray(arr) { return isNonEmpty(arr) ? arr : void 0; } var head = (arr) => arr[0]; var last2 = (arr) => arr[arr.length - 1]; var mapIndexed2 = (fn) => (arr) => { const res = [fn(arr[0], 0)]; for (let i = 1; i < arr.length; ++i) { res.push(fn(arr[i], i)); } return res; }; var map3 = (fn) => (arr) => pipe(arr, mapIndexed2((value) => fn(value))); var min2 = (ord) => (arr) => arr.reduce(min(ord), arr[0]); var max2 = (ord) => min2(inverse(ord)); var sort2 = (ord) => sort(ord); var NonEmptyArray = { of, fromArray, head, last: last2, map: map3, mapIndexed: mapIndexed2, min: min2, max: max2, sort: sort2 }; // src/Result.ts var ok = (value) => ({ _tag: "Result.Ok" /* Ok */, ok: value }); var ko = (value) => ({ _tag: "Result.Ko" /* Ko */, ko: value }); var fromOption = (onNone) => (option) => isSome(option) ? ok(option) : ko(onNone()); var isOk = (result) => result._tag === "Result.Ok" /* Ok */; var isKo = (result) => result._tag === "Result.Ko" /* Ko */; var isResult = (result) => isObject(result) && (result._tag === "Result.Ok" /* Ok */ || result._tag === "Result.Ko" /* Ko */); var get3 = (result) => isOk(result) ? result.ok : throwError(result.ko); var tuple2 = (result) => isOk(result) ? [result.ok, void 0] : [void 0, result.ko]; var map5 = (fn) => (result) => isOk(result) ? ok(fn(result.ok)) : result; var mapError = (fn) => (result) => isKo(result) ? ko(fn(result.ko)) : result; var join = (result) => pipe(result, chain(identity)); var chain = (fn) => (result) => isOk(result) ? fn(result.ok) : result; var catchError = (fn) => (result) => isKo(result) ? fn(result.ko) : result; var fold = (onOk, onKo) => (result) => { return isOk(result) ? onOk(result.ok) : onKo(result.ko); }; var swap = (result) => pipe(result, fold((value) => ko(value), (err) => ok(err))); var tryCatch = (fn) => { try { return ok(fn()); } catch (err) { return ko(err); } }; var tryCatchFn = (fun) => (...args) => tryCatch(() => fun(...args)); var unionBy = (fn) => (members) => { const errors = []; for (let i = 0; i < members.length; ++i) { const result = fn(members[i], i); if (Result.isOk(result)) { return result; } errors.push(result.ko); } return Result.ko(errors); }; var union2 = (members) => pipe(members, unionBy(identity)); var structBy = (fn) => (props) => { const [success, errors] = pipe(toPairs(props), map4(([key, prop]) => pipe(fn(prop, key), Result.map((value) => [key, value]))), separate); return errors.length > 0 ? Result.ko(errors) : Result.ok(fromPairs(success)); }; var struct = structBy(identity); var Result = { ok, ko, isOk, isKo, isResult, fromOption, get: get3, tuple: tuple2, map: map5, mapError, join, chain, catchError, fold, swap, tryCatch, tryCatchFn, unionBy, union: union2, structBy, struct }; // src/Array.ts var isArray = (arr) => Array.isArray(arr); var isEmpty = (arr) => arr.length === 0; var length = (arr) => arr.length; var of2 = (value) => [value]; var from = (value) => Array.from(value); var head2 = (arr) => arr.length > 0 ? arr[0] : void 0; var last3 = (arr) => arr.length > 0 ? arr[arr.length - 1] : void 0; var mapIndexed3 = (fn) => (arr) => arr.map(fn); var map4 = (fn) => (arr) => arr.map((value) => fn(value)); var filterMap2 = (fn) => (arr) => { const out = []; for (let i = 0; i < arr.length; ++i) { const result = fn(arr[i]); if (isSome(result)) { out.push(result); } } return out; }; var compact2 = (arr) => pipe(arr, filterMap2(identity)); var concat3 = (value) => (arr) => arr.concat(value); var flatten = (arr) => [].concat.apply([], arr); var chain2 = (fn) => (arr) => pipe(arr, map4(fn), flatten); var chainIndexed = (fn) => (arr) => pipe(arr, mapIndexed3(fn), flatten); var some = (fn) => (arr) => arr.some(fn); var every = (fn) => (arr) => arr.every(fn); var join2 = (sep) => (arr) => arr.join(sep); function filter3(fn) { return (arr) => arr.filter(fn); } function reject3(fn) { return (arr) => arr.filter(not(fn)); } var reduce2 = (fn, initial) => (arr) => arr.reduce(fn, initial); var slice = (start, end) => (arr) => arr.slice(start, end); var take = (nb) => slice(0, nb); var skip = (nb) => slice(nb); var sort = (ord) => (arr) => arr.map(of2).sort(pipe(ord, contramap(head))).map(head); var reverse = (arr) => arr.slice().reverse(); var toDict = (fn, reducer, initial) => (arr) => { const res = {}; for (let i = 0; i < arr.length; ++i) { const value = arr[i]; const key = fn(value, i); const curr = res[key]; res[key] = isSome(curr) ? reducer(curr, value) : initial(value); } return res; }; var groupBy = (fn) => toDict(fn, (arr, value) => (arr.push(value), arr), of2); var indexBy = (fn, strategy = last) => toDict(fn, strategy, identity); var countBy = (fn) => toDict(fn, add(1), constant(1)); var chunksOf = (size) => (arr) => { const count = Math.ceil(arr.length / size); const chunks = Array(count); for (let i = 0; i < count; ++i) { const start = i * size; const end = Math.min(start + size, arr.length); chunks[i] = arr.slice(start, end); } return chunks; }; function uniq(arr) { return from(new Set(arr)); } var uniqBy = (fn) => (arr) => pipe(arr, indexBy(fn, first), values); var union3 = (fn, member) => (arr) => pipe(arr, indexBy(fn, first), union(pipe(member, indexBy(fn, first))), values); var intersect2 = (fn, member) => (arr) => pipe(arr, indexBy(fn, first), intersect(pipe(member, indexBy(fn, first))), values); var difference2 = (fn, member) => (arr) => pipe(arr, indexBy(fn, first), difference(pipe(member, indexBy(fn, first))), values); var pluck = (key) => (arr) => arr.map((v) => v[key]); function partition(fn) { return partitionMap((value) => fn(value) ? ok(value) : ko(value)); } var partitionMap = (fn) => (arr) => { const ok2 = []; const ko2 = []; for (let i = 0; i < arr.length; ++i) { const value = arr[i]; const res = fn(value); if (isOk(res)) { ok2.push(res.ok); } else { ko2.push(res.ko); } } return [ok2, ko2]; }; var separate = (arr) => pipe(arr, partitionMap(identity)); var isNonEmpty = (arr) => arr.length > 0; var min3 = (ord) => (arr) => isNonEmpty(arr) ? pipe(arr, min2(ord)) : void 0; var max3 = (ord) => min3(inverse(ord)); var find = (fn) => (arr) => arr.find(fn); var includes = (fn) => (arr) => isSome(arr.find(fn)); var empty = () => []; var sum = (arr) => arr.reduce(add, 0); var sumBy = (fn) => (arr) => arr.reduce((a, b) => a + fn(b), 0); var push = fcurry2((arr, value) => (arr.push(value), arr)); var Arr = { of: of2, from, length, isArray, isEmpty, isNonEmpty, head: head2, last: last3, map: map4, mapIndexed: mapIndexed3, chain: chain2, chainIndexed, some, every, join: join2, reduce: reduce2, reject: reject3, filter: filter3, filterMap: filterMap2, compact: compact2, concat: concat3, flatten, slice, take, skip, sort, chunksOf, groupBy, countBy, indexBy, uniq, uniqBy, union: union3, intersect: intersect2, difference: difference2, pluck, partition, partitionMap, separate, min: min3, max: max3, reverse, find, includes, empty, sum, sumBy, push }; // src/List.ts var init = () => ({ length: 0 }); var map6 = (fn) => (list) => { const lb = init(); let elem = list.head; while (elem) { push2(lb, fn(elem.value)); elem = elem.next; } return lb; }; var unshift = (queue, value) => { const head3 = queue.head; const item = { next: head3, prev: void 0, value }; if (head3) { head3.prev = item; } if (!queue.last) { queue.last = item; } queue.head = item; queue.length++; }; var push2 = (queue, value) => { const last4 = queue.last; const item = { next: void 0, prev: last4, value }; if (last4) { last4.next = item; } if (!queue.head) { queue.head = item; } queue.last = item; queue.length++; }; var shift = (queue) => { const head3 = queue.head; if (head3) { queue.head = head3.next; queue.length--; } if (queue.last === head3) { queue.last = void 0; } return head3 && head3.value; }; var pop = (queue) => { const last4 = queue.last; if (last4) { queue.last = last4.prev; queue.length--; } if (queue.head === last4) { queue.head = void 0; } return last4 && last4.value; }; var fromArray2 = (arr) => { const queue = init(); for (let i = 0; i < arr.length; ++i) { push2(queue, arr[i]); } return queue; }; var toArray = (list) => { const arr = []; let elem = list.head; while (elem) { arr.push(elem.value); elem = elem.next; } return arr; }; var List = { init, map: map6, fromArray: fromArray2, toArray, unshift, shift, push: push2, pop }; // src/Task.ts var thunk = (fn) => ({ _tag: "Task", then: (onResolve, onReject) => Promise.resolve().then(fn).then(onResolve, onReject) }); var from2 = (promise) => thunk(() => promise); var isTask = (value) => value._tag === "Task"; function of4(value = void 0) { return thunk(() => of3(value)); } var resolve = of4; var reject5 = (value) => thunk(() => reject4(value)); var run2 = (task) => new Promise(task.then); var map7 = (fn) => (task) => thunk(() => task.then(fn)); var mapError2 = (fn) => (task) => thunk(() => task.then(identity, (err) => reject4(fn(err)))); var chain3 = (fn) => (task) => thunk(() => task.then((v) => fn(v))); var catchError2 = (fn) => (task) => thunk(() => task.then(identity, (err) => fn(err))); var tap2 = (fn) => (task) => thunk(() => pipe(task, tap(fn))); var tapError2 = (fn) => (task) => thunk(() => pipe(task, tapError(fn))); var sleep2 = (ms) => thunk(() => sleep(ms)); var delay2 = (ms) => (task) => thunk(() => pipe(task, delay(ms))); var all2 = (tasks) => thunk(() => all(tasks)); var sequence = (tasks) => thunk(async () => { const res = []; for (let i = 0; i < tasks.length; ++i) { const task = tasks[i]; res.push(await task); } return res; }); var concurrent = (concurrency) => (tasks) => thunk(async () => { if (concurrency < 1) { throw new Error(`Concurrency should be above 1 or above`); } if (concurrency === Number.POSITIVE_INFINITY || concurrency > tasks.length) { concurrency = tasks.length; } const results = Array(tasks.length); const queue = fromArray2(tasks.map((task, index) => ({ index, task }))); const loop = async () => { let item = shift(queue); while (item) { const { index, task } = item; results[index] = await task; item = shift(queue); } }; const p = []; for (let i = 0; i < concurrency; ++i) { p.push(loop()); } await all(p); return results; }); var tryCatch3 = (task) => thunk(() => tryCatch2(task)); var taskify = (fn) => (...args) => thunk(() => fn(...args)); var timeout2 = (ms, fn) => (task) => thunk(() => pipe(task, timeout(ms, fn))); var struct2 = fcurry2((obj, strategy) => { const toPairs3 = ([key, task]) => pipe(task, map7((v) => [key, v])); return pipe(toPairs(obj), map4(toPairs3), strategy, map7(fromPairs)); }); var retry = (strategy) => (task) => { const run3 = (attempt) => pipe(task, catchError2((err) => pipe(thunk(() => strategy(err, attempt)), chain3(() => run3(attempt + 1))))); return run3(1); }; var retryBy = (options) => { const delay3 = options.delay || 0; const when = options.when; return retry((err, attempt) => { if (attempt >= options.attempts) { return Task.reject(err); } const next = when ? when(err) : true; if (next) { const timeout3 = typeof delay3 === "number" ? delay3 : delay3(attempt); return sleep2(timeout3); } return Task.reject(err); }); }; var Task = { isTask, of: of4, resolve, reject: reject5, run: run2, sleep: sleep2, delay: delay2, map: map7, mapError: mapError2, chain: chain3, catchError: catchError2, tap: tap2, tapError: tapError2, all: all2, sequence, concurrent, tryCatch: tryCatch3, thunk, from: from2, struct: struct2, timeout: timeout2, taskify, retry, retryBy }; // src/Promise.ts var thunk2 = (fn) => Promise.resolve().then(fn); var of3 = (value) => Promise.resolve(value); var resolve2 = of3; var reject4 = (value) => Promise.reject(value); var map8 = (fn) => then(fn); var mapError3 = (fn) => (promise) => thunk2(() => promise.then(identity, (err) => reject4(fn(err)))); var chain4 = (fn) => then(fn); var catchError3 = (fn) => (promise) => thunk2(() => promise.then(identity, (err) => fn(err))); var then = (fn) => (promise) => thunk2(() => promise.then(fn)); var tap = (fn) => then((value) => thunk2(() => fn(value)).then(() => value)); var tapError = (fn) => (promise) => pipe(promise, catchError3((value) => thunk2(() => fn(value)).then(() => reject4(value)))); var sleep = (ms) => new Promise((r) => setTimeout(r, ms)); var delay = (ms) => (prom) => pipe(prom, tap(() => sleep(ms))); var all = (promises) => Promise.all(promises); var tryCatch2 = (promise) => thunk2(() => promise.then(ok, ko)); var timeout = (ms, fn) => (promise) => Promise.race([promise, pipe(Prom.sleep(ms), Prom.then(fn))]); function struct3(obj) { return pipe(obj, map2(from2), struct2(all2), run2); } var Prom = { of: of3, resolve: resolve2, reject: reject4, thunk: thunk2, sleep, delay, map: map8, mapError: mapError3, chain: chain4, catchError: catchError3, then, tap, tapError, all, tryCatch: tryCatch2, struct: struct3, timeout }; // src/Exception.ts var Exception = class extends Error { constructor(message, cause) { super(message); const proto = new.target.prototype; if (Object.setPrototypeOf) { Object.setPrototypeOf(this, proto); } else { this.__proto__ = proto; } Object.defineProperty(this, "name", { configurable: true, enumerable: false, value: this.constructor.name, writable: true }); Object.defineProperty(this, "cause", { configurable: true, enumerable: false, value: cause, writable: true }); } }; // src/String.ts var DOUBLE_BRACE_REGEXP = /{{(\d+|[a-z$_][a-z\d$_]*?(?:\.[a-z\d$_]*?)*?)}}/gi; var BRACE_REGEXP = /{(\d+|[a-z$_][a-z\d$_]*?(?:\.[a-z\d$_]*?)*?)}/gi; var of5 = (value) => String(value); var length2 = (str) => str.length; var isEmpty3 = (str) => str.length === 0; function oneOf(arr) { const set2 = new Set(arr); return (str) => set2.has(str); } var concat4 = (append) => (str) => str + append; var split = (sep) => (str) => str.split(sep); var lower = (str) => str.toLowerCase(); var upper = (str) => str.toUpperCase(); var capitalize = (str) => str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase(); var truncate = (maxLength, suffix = "...") => (str) => str.length > maxLength ? str.slice(0, maxLength) + suffix : str; var replace = (regexp, replacer) => (str) => str.replace(regexp, replacer); var replaceAll = (regexp, replacer) => replace(new RegExp(regexp, "g"), replacer); var regexpEscape = flow(replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"), replace(/-/g, "\\x2d")); var htmlEscape = flow(replace(/&/g, "&amp;"), replace(/"/g, "&quot;"), replace(/'/g, "&#39;"), replace(/`/g, "&#x60;"), replace(/</g, "&lt;"), replace(/>/g, "&gt;")); var htmlUnescape = flow(replace(/&gt;/g, ">"), replace(/&lt;/g, "<"), replace(/&#x60;/g, "`"), replace(/&#0?39;/g, "'"), replace(/&quot;/g, '"'), replace(/&amp;/g, "&")); var template = (info2) => flow(replace(DOUBLE_BRACE_REGEXP, (_, key) => pipe(info2, property(key), of5, htmlEscape)), replace(BRACE_REGEXP, (_, key) => pipe(info2, property(key), of5))); var eq2 = pipe(string, eq); var WHITESPACE_CHARS = [ " ", "\f", "\n", "\r", " ", "\v", "\xA0", "\u1680", "\u2000", "\u200A", "\u2028", "\u2029", "\u202F", "\u205F", "\u3000", "\uFEFF" ]; var trimWhile = (fn) => { return (str) => { let start = 0; let end = str.length; while (start < end && fn(str[start])) ++start; while (end > start && fn(str[end - 1])) --end; return start > 0 || end < str.length ? str.substring(start, end) : str; }; }; var isWhitespace = oneOf(WHITESPACE_CHARS); var trim = trimWhile(isWhitespace); var Str = { of: of5, length: length2, isEmpty: isEmpty3, oneOf, concat: concat4, lower, upper, capitalize, truncate, split, replace, replaceAll, template, regexpEscape, htmlEscape, htmlUnescape, eq: eq2, isWhitespace, trimWhile, trim }; // src/Object.ts var copy = (member) => Object.assign({}, member); function merge(...members) { return Object.assign({}, ...members); } var property = (path) => (obj) => pipe(path, split("."), reduce2((obj2, prop) => obj2 ? obj2[prop] : void 0, obj)); var omit2 = omit; var pick2 = pick; var compact3 = (obj) => { const out = { ...obj }; for (const key in out) { if (key === void 0) { delete out[key]; } } return out; }; var Obj = { copy, merge, property, omit: omit2, pick: pick2, compact: compact3 }; // src/Err.ts var INFO_RESERVED = /* @__PURE__ */ new Set(["message", "stack", "cause"]); var isNotReserved = (_, key) => !INFO_RESERVED.has(key); var info = (err) => { return pipe(merge(toError(err)), filter2(isNotReserved)); }; var fullInfo = (err) => { const infos = pipe(err, toError, toArray2, filterMap2(info), reverse); return merge(...infos); }; var fullStack = (err) => pipe(err, toError, toArray2, filterMap2((err2) => err2.stack), join2(` caused by: `)); var of6 = (msg, info2 = {}, cause, constructorOpt) => { const data = pipe(info2, filter2(isNotReserved)); const message = pipe(msg, template(data)); const e = new Exception(message, cause); Object.assign(e, data); Error.captureStackTrace(e, constructorOpt || of6); return e; }; var toError = (err) => err instanceof Error ? err : of6(String(err)); var toArray2 = (err) => { const errors = []; let cur = toError(err); while (cur) { errors.push(cur); cur = cur.cause; } return errors; }; function wrap(msg, info2) { return function _wrap(e) { const err = toError(e); return of6(msg, info2, err, _wrap); }; } function chain5(msg, info2) { return function _chain(e) { const err = toError(e); return of6(`${msg}: ${err.message}`, info2, err, _chain); }; } var find2 = (fn) => (source) => { let cur = toError(source); while (cur) { const found = fn(cur); if (found) { return cur; } cur = cur.cause; } return void 0; }; var has = (fn) => (source) => pipe(source, find2(fn), (value) => value ? true : false); var hasName = (name) => has((info2) => info2.name === name); var format = (e) => { const err = toError(e); const stack = fullStack(err); const i = fullInfo(err); return { name: i.name ? String(i.name) : err.name, message: err.message, stack, info: i }; }; var omitStack = omit2(["stack"]); var Err = { of: of6, toError, wrap, chain: chain5, find: find2, has, hasName, format, omitStack }; // src/Tree.ts var of7 = (value, forest = []) => ({ value, forest }); var draw = (tree) => tree.value + drawForest("\n", tree.forest); var drawForest = (indentation, forest) => { let r = ""; const len = forest.length; let tree; for (let i = 0; i < len; i++) { tree = forest[i]; const isLast = i === len - 1; r += indentation + (isLast ? "\u2514" : "\u251C") + "\u2500 " + tree.value; r += drawForest(indentation + (len > 1 && !isLast ? "\u2502 " : " "), tree.forest); } return r; }; var Tree = { of: of7, draw }; // src/Enum.ts var keys2 = (enumType) => Object.keys(enumType).filter((key) => isNaN(Number(key))); function values2(enumType) { return keys2(enumType).map((key) => enumType[key]); } var toPairs2 = (enumType) => keys2(enumType).map((key) => [key, enumType[key]]); var isEnum = (enumType) => { const set2 = new Set(values2(enumType)); return (input) => set2.has(input); }; var Enum = { keys: keys2, values: values2, toPairs: toPairs2, isEnum }; export { Arr, Dict, Enum, Err, Exception, List, NonEmptyArray, Obj, Option, Ord, Ordering, Prom, Result, Str, Task, Tree, add, and, cast, constant, fcurry2, first, flow, identity, isFunction, isNaN2 as isNaN, isNull, isNumber, isObject, isUndefined, last, not, once, or, pipe, run, throwError, tuple, tupled, untupled };