Comparing version 1.12.0 to 1.12.1
@@ -351,2 +351,6 @@ /** | ||
wrapperFn: any; | ||
barWrapFn: any; | ||
barProgWrapFn: any; | ||
barCurrentWrapFn: any; | ||
barEmptyWrapFn: any; | ||
showCount: boolean; | ||
@@ -359,4 +363,15 @@ showPercent: boolean; | ||
endChar: string; | ||
showCurrent: boolean; | ||
currentChar: string; | ||
} | ||
declare type ProgressBarOptions = Partial<ProgressBarOptionsFull>; | ||
interface ProgressBar { | ||
next: () => string; | ||
set: (newCurrent: number) => string; | ||
reset: () => string; | ||
update: () => string; | ||
start: () => string; | ||
finish: () => string; | ||
readonly max: number; | ||
} | ||
/** | ||
@@ -393,13 +408,7 @@ * Usage: | ||
*/ | ||
declare const getProgressBar: (max: number, options?: ProgressBarOptions) => { | ||
next: () => string; | ||
set: (newCurrent: number) => string; | ||
reset: () => string; | ||
update: () => string; | ||
start: () => string; | ||
finish: () => string; | ||
}; | ||
declare const getProgressBar: (max: number, options?: ProgressBarOptions) => ProgressBar; | ||
declare const progressBar_printLn: typeof printLn; | ||
type progressBar_ProgressBarOptions = ProgressBarOptions; | ||
type progressBar_ProgressBar = ProgressBar; | ||
declare const progressBar_getProgressBar: typeof getProgressBar; | ||
@@ -410,2 +419,3 @@ declare namespace progressBar { | ||
progressBar_ProgressBarOptions as ProgressBarOptions, | ||
progressBar_ProgressBar as ProgressBar, | ||
progressBar_getProgressBar as getProgressBar, | ||
@@ -686,3 +696,3 @@ }; | ||
*/ | ||
declare const range: (length?: number, multiplier?: number) => number[]; | ||
declare const range: (length?: number, multiplier?: number, offset?: number) => number[]; | ||
declare type UnwrapArray<T> = T extends Array<infer U> ? U : T; | ||
@@ -702,2 +712,3 @@ declare type UnwrapArrays<T extends [...any[]]> = T extends [infer Head, ...infer Tail] ? [UnwrapArray<Head>, ...UnwrapArrays<Tail>] : []; | ||
declare const zip: <T extends any[]>(...arrs: T) => UnwrapArrays<T>[]; | ||
declare const zipMax: <T extends any[]>(...arrs: T) => UnwrapArrays<T>[]; | ||
/** | ||
@@ -791,16 +802,17 @@ * Sort an array by a mapped form of the values, but returning the initial values | ||
*/ | ||
declare const sortNumberedText: (texts: string[]) => string[]; | ||
declare const sortNumberedText: (texts: string[], ignoreCase?: boolean) => string[]; | ||
declare const ArrayUtils: { | ||
range: (length?: number, multiplier?: number) => number[]; | ||
range: (length?: number, multiplier?: number, offset?: number) => number[]; | ||
zip: <T extends any[]>(...arrs: T) => UnwrapArrays<T>[]; | ||
sortByMapped: <T_1 = string, M = number>(arr: T_1[], mapFn: (value: T_1, index: number, array: T_1[]) => M, sortFn?: (a: M, b: M) => number) => T_1[]; | ||
randomise: <T_2 = string>(arr: T_2[]) => T_2[]; | ||
reverse: <T_3 = string>(arr: T_3[]) => T_3[]; | ||
entries: <T_4 = string>(arr: T_4[]) => [number, T_4][]; | ||
repeat: <T_5 = string>(maxLength: number, ...items: T_5[]) => T_5[]; | ||
roll: <T_6 extends unknown>(distance: number, arr: T_6[]) => T_6[]; | ||
sortNumberedText: (texts: string[]) => string[]; | ||
zipMax: <T_1 extends any[]>(...arrs: T_1) => UnwrapArrays<T_1>[]; | ||
sortByMapped: <T_2 = string, M = number>(arr: T_2[], mapFn: (value: T_2, index: number, array: T_2[]) => M, sortFn?: (a: M, b: M) => number) => T_2[]; | ||
randomise: <T_3 = string>(arr: T_3[]) => T_3[]; | ||
reverse: <T_4 = string>(arr: T_4[]) => T_4[]; | ||
entries: <T_5 = string>(arr: T_5[]) => [number, T_5][]; | ||
repeat: <T_6 = string>(maxLength: number, ...items: T_6[]) => T_6[]; | ||
roll: <T_7 extends unknown>(distance: number, arr: T_7[]) => T_7[]; | ||
sortNumberedText: (texts: string[], ignoreCase?: boolean) => string[]; | ||
utils: { | ||
isNumString: (text: string) => boolean; | ||
partitionNums: (name: string) => (string | number)[]; | ||
partitionNums: (ignoreCase: boolean) => (name: string) => (string | number)[]; | ||
}; | ||
@@ -815,2 +827,6 @@ }; | ||
declare const TimeUtils: { | ||
toReadableDuration: (duration: ms, longNames?: boolean, maxUnits?: number) => string; | ||
}; | ||
/** | ||
@@ -823,2 +839,3 @@ * symbols | ||
TAB: string; | ||
NBSP: string; | ||
TICK: string; | ||
@@ -835,4 +852,8 @@ CROSS: string; | ||
HOME: string; | ||
RADIO_EMPTY: string; | ||
RADIO_FULL: string; | ||
CURSOR: string; | ||
CHEV_LFT: string; | ||
CHEV_RGT: string; | ||
CHAIN: string; | ||
TRI_UPP: string; | ||
@@ -1433,2 +1454,3 @@ TRI_DWN: string; | ||
declare const toProp: <P = string, O = Object>(prop: string) => (item: O) => P; | ||
declare const toFixed: (precision: number) => (num: number) => number; | ||
declare const maps$1: { | ||
@@ -1439,2 +1461,3 @@ toString: <T = any>(item: T) => string; | ||
toProp: <P = string, O = Object>(prop: string) => (item: O) => P; | ||
toFixed: (precision: number) => (num: number) => number; | ||
}; | ||
@@ -1599,2 +1622,7 @@ /** | ||
}; | ||
declare const lerp: (progress: number, fromVal: number, toVal: number) => number; | ||
declare const lerpArray: (progress: number, fromArr: number[], toArr: number[]) => number[]; | ||
declare const lerpObj: <T extends object>(progress: number, fromObj: T, toObj: T) => T; | ||
declare const clamp: (value: number, a: number, b: number) => number; | ||
declare const capitalise: (str: string) => string; | ||
@@ -1619,2 +1647,3 @@ declare const fn_noop: typeof noop; | ||
declare const fn_toProp: typeof toProp; | ||
declare const fn_toFixed: typeof toFixed; | ||
declare const fn_asc: typeof asc; | ||
@@ -1634,2 +1663,7 @@ declare const fn_desc: typeof desc; | ||
declare const fn_round: typeof round; | ||
declare const fn_lerp: typeof lerp; | ||
declare const fn_lerpArray: typeof lerpArray; | ||
declare const fn_lerpObj: typeof lerpObj; | ||
declare const fn_clamp: typeof clamp; | ||
declare const fn_capitalise: typeof capitalise; | ||
declare namespace fn { | ||
@@ -1656,2 +1690,3 @@ export { | ||
fn_toProp as toProp, | ||
fn_toFixed as toFixed, | ||
maps$1 as maps, | ||
@@ -1675,2 +1710,7 @@ fn_asc as asc, | ||
fn_round as round, | ||
fn_lerp as lerp, | ||
fn_lerpArray as lerpArray, | ||
fn_lerpObj as lerpObj, | ||
fn_clamp as clamp, | ||
fn_capitalise as capitalise, | ||
}; | ||
@@ -1693,2 +1733,3 @@ } | ||
toProp: <P = string, O = Object>(prop: string) => (item: O) => P; | ||
toFixed: (precision: number) => (num: number) => number; | ||
}; | ||
@@ -1712,2 +1753,2 @@ declare const sorts: { | ||
export { ArrayUtils, CENTURY, ColourUtils, CustomEntryDict, DAY, DECADE, DeferredPromise, HOUR, ITimer, KeysOnly, MILLENNIUM, MILLISECOND, MINUTE, MONTH, Numbered, ObjOfType, ObjectUtils, OfType, Partial$1 as Partial, ProgressBarOptions, PromiseUtils, RemapOf, SECOND, WEEK, YEAR, all, allLimit, allLimitObj, allObj, centuries, century, day, days, decade, decades, each, eachLimit, entries, everys, filters, fn, getDeferred, getProgressBar, getTimer, hour, hours, interval, map, mapLimit, maps, millennium, millenniums, milliseconds, minute, minutes, month, months, ms, printLn, progressBar, randomise, range, reduces, repeat, retry, retryOr, reverse, roll, second, seconds, sortByMapped, sortNumberedText, sorts, stopInterval, superscript, symbols, timer, times, tryOr, wait, waitEvery, waitFor, waitUntil, waiters, week, weeks, year, years, zip }; | ||
export { ArrayUtils, CENTURY, ColourUtils, CustomEntryDict, DAY, DECADE, DeferredPromise, HOUR, ITimer, KeysOnly, MILLENNIUM, MILLISECOND, MINUTE, MONTH, Numbered, ObjOfType, ObjectUtils, OfType, Partial$1 as Partial, ProgressBar, ProgressBarOptions, PromiseUtils, RemapOf, SECOND, TimeUtils, WEEK, YEAR, all, allLimit, allLimitObj, allObj, centuries, century, day, days, decade, decades, each, eachLimit, entries, everys, filters, fn, getDeferred, getProgressBar, getTimer, hour, hours, interval, map, mapLimit, maps, millennium, millenniums, milliseconds, minute, minutes, month, months, ms, printLn, progressBar, randomise, range, reduces, repeat, retry, retryOr, reverse, roll, second, seconds, sortByMapped, sortNumberedText, sorts, stopInterval, superscript, symbols, timer, times, tryOr, wait, waitEvery, waitFor, waitUntil, waiters, week, weeks, year, years, zip, zipMax }; |
@@ -35,2 +35,3 @@ var __defProp = Object.defineProperty; | ||
SECOND: () => SECOND, | ||
TimeUtils: () => TimeUtils, | ||
WEEK: () => WEEK, | ||
@@ -90,3 +91,4 @@ YEAR: () => YEAR, | ||
years: () => years, | ||
zip: () => zip | ||
zip: () => zip, | ||
zipMax: () => zipMax | ||
}); | ||
@@ -195,19 +197,74 @@ module.exports = __toCommonJS(src_exports); | ||
// src/tools/timer.ts | ||
var formatDuration = (duration) => { | ||
const seconds2 = duration / SECOND; | ||
let extra = ""; | ||
let secsEx = Math.round(seconds2); | ||
let minsEx = Math.floor(secsEx / 60); | ||
if (minsEx >= 1) { | ||
secsEx %= 60; | ||
extra = `${minsEx}m ${secsEx}s`; | ||
let hoursEx = Math.floor(minsEx / 60); | ||
if (hoursEx >= 1) { | ||
minsEx %= 60; | ||
extra = `${hoursEx}h ${minsEx}m ${secsEx}s`; | ||
} | ||
// src/tools/TimeUtils.ts | ||
var units = [ | ||
{ | ||
value: MILLENNIUM, | ||
short: { singular: "mill", plural: "mills" }, | ||
long: { singular: " millennium", plural: " millenniums" } | ||
}, | ||
{ | ||
value: CENTURY, | ||
short: { singular: "cent", plural: "cents" }, | ||
long: { singular: " century", plural: " centuries" } | ||
}, | ||
{ | ||
value: YEAR, | ||
short: { singular: "y", plural: "y" }, | ||
long: { singular: " year", plural: " years" } | ||
}, | ||
{ | ||
value: MONTH, | ||
short: { singular: "mon", plural: "mons" }, | ||
long: { singular: " month", plural: " months" } | ||
}, | ||
{ | ||
value: DAY, | ||
short: { singular: "d", plural: "d" }, | ||
long: { singular: " day", plural: " days" } | ||
}, | ||
{ | ||
value: HOUR, | ||
short: { singular: "h", plural: "h" }, | ||
long: { singular: " hour", plural: " hours" } | ||
}, | ||
{ | ||
value: MINUTE, | ||
short: { singular: "m", plural: "m" }, | ||
long: { singular: " minute", plural: " minutes" } | ||
}, | ||
{ | ||
value: SECOND, | ||
short: { singular: "s", plural: "s" }, | ||
long: { singular: " second", plural: " seconds" } | ||
}, | ||
{ | ||
value: MILLISECOND, | ||
short: { singular: "ms", plural: "ms" }, | ||
long: { singular: " millisecond", plural: " milliseconds" } | ||
} | ||
return `${extra}${extra ? ` (${seconds2}s)` : `${seconds2}s`}`; | ||
]; | ||
var toReadableDuration = (duration, longNames = false, maxUnits = 3) => { | ||
if (duration === 0) | ||
return ""; | ||
const allUnitValues = units.map((unit, index) => { | ||
var _a; | ||
const previousUnitValue = ((_a = units[index - 1]) == null ? void 0 : _a.value) ?? Infinity; | ||
const amount = Math.floor(Math.abs(duration) % previousUnitValue / unit.value); | ||
return { amount, unit }; | ||
}).filter(({ amount }) => amount > 0); | ||
const results = allUnitValues.slice(0, maxUnits).map(({ amount, unit }) => { | ||
const labelObj = longNames ? unit.long : unit.short; | ||
const label = amount > 1 ? labelObj.plural : labelObj.singular; | ||
return `${amount}${label}`; | ||
}); | ||
if (longNames) { | ||
return [...results.slice(0, -1), "&&&&", ...results.slice(-1)].join(", ").replace("&&&&,", "&"); | ||
} | ||
return results.join(" "); | ||
}; | ||
var TimeUtils = { | ||
toReadableDuration | ||
}; | ||
// src/tools/timer.ts | ||
var getTimer = (name, verbose = false, wrapperFn = noWrap, chalk = noChalk, displayNames) => { | ||
@@ -227,3 +284,3 @@ let startTimes = {}; | ||
const lineStart = `${dispNames[label] || label}: `.padEnd(nameColLength + 1, " "); | ||
const lineEnd = `${formatDuration(duration)}`; | ||
const lineEnd = `${TimeUtils.toReadableDuration(duration, false, 4)}`; | ||
const line = chalk.bold(prefix + lineStart) + lineEnd; | ||
@@ -262,2 +319,6 @@ console.log(wrapperFn(line)); | ||
}; | ||
const logLine2 = (label, prefix2, nameColLength2, duration) => { | ||
lc++; | ||
return logLine(label, prefix2, nameColLength2, duration); | ||
}; | ||
const labels = Object.keys(startTimes); | ||
@@ -271,3 +332,3 @@ log(""); | ||
if (label !== "TOTAL") { | ||
longest = Math.max(longest, logLine(label, " ", nameColLength)); | ||
longest = Math.max(longest, logLine2(label, " ", nameColLength)); | ||
} | ||
@@ -285,7 +346,7 @@ } | ||
for (let { label, duration } of cEntries) { | ||
logLine(label, " ", nameColLength, duration); | ||
logLine2(label, " ", nameColLength, duration); | ||
} | ||
} | ||
log(wrapperFn(chalk.dim(" " + "\u23AF".repeat(longest)))); | ||
logLine("TOTAL", " ", nameColLength); | ||
logLine2("TOTAL", " ", nameColLength); | ||
log(""); | ||
@@ -319,3 +380,5 @@ return lc; | ||
byProp: () => byProp, | ||
capitalise: () => capitalise, | ||
ceilTo: () => ceilTo, | ||
clamp: () => clamp, | ||
combine: () => combine, | ||
@@ -337,2 +400,5 @@ combineProp: () => combineProp, | ||
isTruthy: () => isTruthy, | ||
lerp: () => lerp, | ||
lerpArray: () => lerpArray, | ||
lerpObj: () => lerpObj, | ||
maps: () => maps, | ||
@@ -350,2 +416,3 @@ nearestTo: () => nearestTo, | ||
toBool: () => toBool, | ||
toFixed: () => toFixed, | ||
toNumber: () => toNumber, | ||
@@ -355,2 +422,50 @@ toProp: () => toProp, | ||
}); | ||
// src/tools/ArrayUtils.ts | ||
var range = (length = 1, multiplier = 1, offset = 0) => new Array(Math.floor(length)).fill(1).map((v, i) => fixFloat(i * multiplier) + offset); | ||
var zipFn = (length, arrs) => range(length).map((i) => arrs.map((arr) => (arr || [])[i])); | ||
var zip = (...arrs) => zipFn(Math.min(...(arrs.length ? arrs : [[]]).map((arr) => (arr || []).length)), arrs); | ||
var zipMax = (...arrs) => zipFn(Math.max(...(arrs.length ? arrs : [[]]).map((arr) => (arr || []).length)), arrs); | ||
var sortByMapped = (arr, mapFn, sortFn = sorts.asc) => zip(arr, arr.map(mapFn)).sort((a, b) => sortFn(a[1], b[1])).map(([v]) => v); | ||
var randomise = (arr) => sortByMapped(arr, () => Math.random()); | ||
var reverse = (arr) => [...arr].reverse(); | ||
var entries = (arr) => zip(range(arr.length), arr); | ||
var repeat = (maxLength, ...items) => { | ||
const simple = new Array(maxLength).fill(items[0]); | ||
return items.length === 1 ? simple : simple.map((v, i) => items[i % items.length]); | ||
}; | ||
var roll = (distance, arr) => [ | ||
...arr.slice(distance % arr.length), | ||
...arr.slice(0, distance % arr.length) | ||
]; | ||
var isNumString = (text) => Boolean(text.match(/^[0-9]+$/)); | ||
var partitionNums = (ignoreCase) => (name) => (ignoreCase ? name.toLowerCase() : name).split(/([0-9]+)/).map((s) => isNumString(s) ? Number(s) : s); | ||
var sortNumberedText = (texts, ignoreCase = true) => { | ||
return sortByMapped(texts, partitionNums(ignoreCase), (a, b) => { | ||
for (let i in a) { | ||
const result2 = sorts.asc(a[i], b[i]); | ||
if (result2 !== 0) | ||
return result2; | ||
} | ||
return 0; | ||
}); | ||
}; | ||
var ArrayUtils = { | ||
range, | ||
zip, | ||
zipMax, | ||
sortByMapped, | ||
randomise, | ||
reverse, | ||
entries, | ||
repeat, | ||
roll, | ||
sortNumberedText, | ||
utils: { | ||
isNumString, | ||
partitionNums | ||
} | ||
}; | ||
// src/tools/fn.ts | ||
var noop = () => { | ||
@@ -384,2 +499,3 @@ }; | ||
var toProp = (prop) => (item) => item && item[prop]; | ||
var toFixed = (precision) => (num) => fixFloat(num, precision); | ||
var maps = { | ||
@@ -389,3 +505,4 @@ toString, | ||
toBool, | ||
toProp | ||
toProp, | ||
toFixed | ||
}; | ||
@@ -455,2 +572,11 @@ var asc = (a, b) => { | ||
}; | ||
var lerp = (progress, fromVal, toVal) => fromVal + (toVal - fromVal) * progress; | ||
var lerpArray = (progress, fromArr, toArr) => zip(fromArr, toArr).map(([fromVal, toVal]) => lerp(progress, fromVal, toVal)); | ||
var lerpObj = (progress, fromObj, toObj) => { | ||
const entries2 = Object.entries(fromObj); | ||
const lerped = entries2.map(([key, fromVal]) => typeof fromVal === "number" ? [key, lerp(progress, fromVal, toObj[key])] : [key, fromVal]); | ||
return Object.fromEntries(lerped); | ||
}; | ||
var clamp = (value, a, b) => Math.max(Math.min(a, b), Math.min(value, Math.max(a, b))); | ||
var capitalise = (str) => str.split(/\s/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); | ||
@@ -480,17 +606,23 @@ // src/tools/progressBar.ts | ||
}; | ||
var getCharWidth = (num, max, width) => Math.round(width * (Math.max(0, Math.min(num / max, 1)) / 1)); | ||
var getBarString = (current, max, width, opts) => { | ||
const { progChar, emptyChar, startChar, endChar } = opts; | ||
const numProgChars = Math.round(width * (Math.max(0, Math.min(current / max, 1)) / 1)); | ||
const numEmptyChars = width - numProgChars; | ||
const body = `${progChar.repeat(numProgChars)}${emptyChar.repeat(numEmptyChars)}`; | ||
const { progChar, emptyChar, startChar, endChar, showCurrent, currentChar } = opts; | ||
const numProgChars = getCharWidth(current, max, width); | ||
const numNextChars = getCharWidth(current + 1, max, width); | ||
const numCurrentChars = showCurrent ? numNextChars - numProgChars : 0; | ||
const numEmptyChars = width - numProgChars - numCurrentChars; | ||
const prog = opts.barProgWrapFn(progChar.repeat(numProgChars)); | ||
const curr = opts.barCurrentWrapFn(currentChar.repeat(numCurrentChars)); | ||
const empt = opts.barEmptyWrapFn(emptyChar.repeat(numEmptyChars)); | ||
const body = opts.barWrapFn(`${prog}${curr}${empt}`); | ||
return `${startChar}${body}${endChar}`; | ||
}; | ||
var getSuffix = (current, max, opts) => { | ||
var getSuffix = (current, maxNum, isMaxKnown, opts) => { | ||
let items = [""]; | ||
if (opts.showCount) { | ||
const pad = Math.max(max.toString().length, opts.countWidth); | ||
items.push(`[${current.toString().padStart(pad, " ")} / ${max.toString().padStart(pad, " ")}]`); | ||
const pad = Math.max(maxNum.toString().length, opts.countWidth); | ||
items.push(`[${current.toString().padStart(pad, " ")} / ${(isMaxKnown ? maxNum.toString() : "?").padStart(pad, " ")}]`); | ||
} | ||
if (opts.showPercent) { | ||
const percent = Math.round(current / max * 100); | ||
const percent = Math.round(current / maxNum * 100); | ||
items.push(`(${percent.toString().padStart("100".toString().length, " ")}%)`); | ||
@@ -508,2 +640,6 @@ } | ||
wrapperFn: noact, | ||
barWrapFn: noact, | ||
barProgWrapFn: noact, | ||
barCurrentWrapFn: noact, | ||
barEmptyWrapFn: noact, | ||
showCount: true, | ||
@@ -516,2 +652,4 @@ showPercent: false, | ||
endChar: "\u258F", | ||
showCurrent: false, | ||
currentChar: "\u259E", | ||
...opts | ||
@@ -525,8 +663,10 @@ }; | ||
let finished = false; | ||
const maxNum = typeof max === "number" ? max : 1; | ||
const isMaxKnown = typeof max === "number"; | ||
const update = () => { | ||
const suffix = getSuffix(current, max, opts); | ||
const suffix = getSuffix(current, maxNum, isMaxKnown, opts); | ||
const fullPrefix = prefix.padEnd(prefixWidth); | ||
const output = `${fullPrefix}${getBarString( | ||
current, | ||
max, | ||
maxNum, | ||
Math.max(0, maxWidth - [fullPrefix, suffix, startChar, endChar].join("").length), | ||
@@ -569,3 +709,4 @@ opts | ||
start, | ||
finish | ||
finish, | ||
max | ||
}; | ||
@@ -714,48 +855,2 @@ }; | ||
// src/tools/ArrayUtils.ts | ||
var range = (length = 1, multiplier = 1) => new Array(Math.floor(length)).fill(1).map((v, i) => i * multiplier); | ||
var zip = (...arrs) => { | ||
const length = Math.min(...arrs.map((arr) => (arr || []).length)); | ||
return range(length).map((i) => arrs.map((arr) => (arr || [])[i])); | ||
}; | ||
var sortByMapped = (arr, mapFn, sortFn = sorts.asc) => zip(arr, arr.map(mapFn)).sort((a, b) => sortFn(a[1], b[1])).map(([v]) => v); | ||
var randomise = (arr) => sortByMapped(arr, () => Math.random()); | ||
var reverse = (arr) => [...arr].reverse(); | ||
var entries = (arr) => zip(range(arr.length), arr); | ||
var repeat = (maxLength, ...items) => { | ||
const simple = new Array(maxLength).fill(items[0]); | ||
return items.length === 1 ? simple : simple.map((v, i) => items[i % items.length]); | ||
}; | ||
var roll = (distance, arr) => [ | ||
...arr.slice(distance % arr.length), | ||
...arr.slice(0, distance % arr.length) | ||
]; | ||
var isNumString = (text) => Boolean(text.match(/^[0-9]+$/)); | ||
var partitionNums = (name) => name.split(/([0-9]+)/).map((s) => isNumString(s) ? Number(s) : s); | ||
var sortNumberedText = (texts) => { | ||
return sortByMapped(texts, partitionNums, (a, b) => { | ||
for (let i in a) { | ||
const result2 = sorts.asc(a[i], b[i]); | ||
if (result2 !== 0) | ||
return result2; | ||
} | ||
return 0; | ||
}); | ||
}; | ||
var ArrayUtils = { | ||
range, | ||
zip, | ||
sortByMapped, | ||
randomise, | ||
reverse, | ||
entries, | ||
repeat, | ||
roll, | ||
sortNumberedText, | ||
utils: { | ||
isNumString, | ||
partitionNums | ||
} | ||
}; | ||
// src/tools/ObjectUtils.ts | ||
@@ -774,2 +869,3 @@ var map2 = (obj, func) => Object.fromEntries(Object.entries(obj).map(([key, value]) => func(key, value))); | ||
TAB: " ", | ||
NBSP: " ", | ||
TICK: "\u2714", | ||
@@ -786,4 +882,8 @@ CROSS: "\u2716", | ||
HOME: "~", | ||
RADIO_EMPTY: "\u25EF", | ||
RADIO_FULL: "\u25C9", | ||
CURSOR: "\u276F", | ||
CHEV_LFT: "\u2039", | ||
CHEV_RGT: "\u203A", | ||
CHAIN: "\u2AD8", | ||
TRI_UPP: "\u25B2", | ||
@@ -1126,6 +1226,6 @@ TRI_DWN: "\u25BC", | ||
var toHex = (colour) => { | ||
const hexs = colour.map((val) => val.toString(16).padStart(2, "0")); | ||
const hexs = colour.map((val) => (val ?? 0).toString(16).padStart(2, "0")); | ||
return `#${hexs.join("")}`; | ||
}; | ||
var getLuminance = ([r, g, b]) => fixFloat(0.299 * r + 0.587 * g + 0.114 * b); | ||
var getLuminance = ([r, g, b]) => fixFloat(0.299 * (r ?? 0) + 0.587 * (g ?? 0) + 0.114 * (b ?? 0)); | ||
var invertColour = ([r, g, b]) => [255 - r, 255 - g, 255 - b]; | ||
@@ -1153,2 +1253,3 @@ var white = [255, 255, 255]; | ||
SECOND, | ||
TimeUtils, | ||
WEEK, | ||
@@ -1208,3 +1309,4 @@ YEAR, | ||
years, | ||
zip | ||
zip, | ||
zipMax | ||
}); |
{ | ||
"name": "swiss-ak", | ||
"version": "1.12.0", | ||
"version": "1.12.1", | ||
"author": "Jack Cannon <jackc@annon.co.uk> (http://c.annon.co.uk/)", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -10,2 +10,3 @@ export * from './tools/types'; | ||
export * from './tools/ObjectUtils'; | ||
export * from './tools/TimeUtils'; | ||
export * from './tools/symbols'; | ||
@@ -12,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { sorts } from './fn'; | ||
import { sorts, fixFloat } from './fn'; | ||
@@ -17,3 +17,4 @@ /** | ||
*/ | ||
export const range = (length: number = 1, multiplier: number = 1): number[] => new Array(Math.floor(length)).fill(1).map((v, i) => i * multiplier); | ||
export const range = (length: number = 1, multiplier: number = 1, offset: number = 0): number[] => | ||
new Array(Math.floor(length)).fill(1).map((v, i) => fixFloat(i * multiplier) + offset); | ||
@@ -23,2 +24,5 @@ type UnwrapArray<T> = T extends Array<infer U> ? U : T; | ||
const zipFn = <T extends [...any[]]>(length: number, arrs: T): UnwrapArrays<T>[] => | ||
range(length).map((i) => arrs.map((arr) => (arr || [])[i])) as UnwrapArrays<T>[]; | ||
/** | ||
@@ -35,7 +39,9 @@ * Converts multiple arrays into an array of 'tuples' for each value at the corresponding indexes. | ||
*/ | ||
export const zip = <T extends [...any[]]>(...arrs: T): UnwrapArrays<T>[] => { | ||
const length = Math.min(...arrs.map((arr) => (arr || []).length)); | ||
return range(length).map((i) => arrs.map((arr) => (arr || [])[i])) as UnwrapArrays<T>[]; | ||
}; | ||
export const zip = <T extends [...any[]]>(...arrs: T): UnwrapArrays<T>[] => | ||
zipFn(Math.min(...(arrs.length ? arrs : [[]]).map((arr) => (arr || []).length)), arrs); | ||
// TODO docs | ||
export const zipMax = <T extends [...any[]]>(...arrs: T): UnwrapArrays<T>[] => | ||
zipFn(Math.max(...(arrs.length ? arrs : [[]]).map((arr) => (arr || []).length)), arrs); | ||
/** | ||
@@ -138,3 +144,4 @@ * Sort an array by a mapped form of the values, but returning the initial values | ||
const isNumString = (text: string) => Boolean(text.match(/^[0-9]+$/)); | ||
const partitionNums = (name: string) => name.split(/([0-9]+)/).map((s) => (isNumString(s) ? Number(s) : s)); | ||
const partitionNums = (ignoreCase: boolean) => (name: string) => | ||
(ignoreCase ? name.toLowerCase() : name).split(/([0-9]+)/).map((s) => (isNumString(s) ? Number(s) : s)); | ||
@@ -152,4 +159,4 @@ /** | ||
*/ | ||
export const sortNumberedText = (texts: string[]): string[] => { | ||
return sortByMapped(texts, partitionNums, (a, b) => { | ||
export const sortNumberedText = (texts: string[], ignoreCase: boolean = true): string[] => { | ||
return sortByMapped(texts, partitionNums(ignoreCase), (a, b) => { | ||
for (let i in a) { | ||
@@ -166,2 +173,3 @@ const result = sorts.asc(a[i], b[i]); | ||
zip, | ||
zipMax, | ||
sortByMapped, | ||
@@ -168,0 +176,0 @@ randomise, |
@@ -329,3 +329,3 @@ import * as fn from './fn'; | ||
export const toHex = (colour: ColourValues): string => { | ||
const hexs = colour.map((val) => val.toString(16).padStart(2, '0')); | ||
const hexs = colour.map((val) => (val ?? 0).toString(16).padStart(2, '0')); | ||
return `#${hexs.join('')}`; | ||
@@ -348,3 +348,3 @@ }; | ||
*/ | ||
export const getLuminance = ([r, g, b]: ColourValues): number => fn.fixFloat(0.299 * r + 0.587 * g + 0.114 * b); | ||
export const getLuminance = ([r, g, b]: ColourValues): number => fn.fixFloat(0.299 * (r ?? 0) + 0.587 * (g ?? 0) + 0.114 * (b ?? 0)); | ||
@@ -351,0 +351,0 @@ /** |
@@ -0,1 +1,3 @@ | ||
import { range, zip } from './ArrayUtils'; | ||
/** | ||
@@ -246,2 +248,8 @@ * fn.noop | ||
// todo docs | ||
export const toFixed = | ||
(precision: number) => | ||
(num: number): number => | ||
fixFloat(num, precision); | ||
export const maps = { | ||
@@ -251,3 +259,4 @@ toString, | ||
toBool, | ||
toProp | ||
toProp, | ||
toFixed | ||
}; | ||
@@ -471,1 +480,25 @@ | ||
}; | ||
// TODO docs | ||
export const lerp = (progress: number, fromVal: number, toVal: number): number => fromVal + (toVal - fromVal) * progress; | ||
export const lerpArray = (progress: number, fromArr: number[], toArr: number[]): number[] => | ||
zip(fromArr, toArr).map(([fromVal, toVal]) => lerp(progress, fromVal, toVal)); | ||
export const lerpObj = <T extends object>(progress: number, fromObj: T, toObj: T): T => { | ||
const entries = Object.entries(fromObj); | ||
const lerped = entries.map(([key, fromVal]) => (typeof fromVal === 'number' ? [key, lerp(progress, fromVal, toObj[key])] : [key, fromVal])); | ||
return Object.fromEntries(lerped) as T; | ||
}; | ||
// TODO docs | ||
// TODO move non high-level functions elsewhere (e.g. MathsUtils, StringUtils, etc) | ||
export const clamp = (value: number, a: number, b: number) => Math.max(Math.min(a, b), Math.min(value, Math.max(a, b))); | ||
// TODO docs | ||
export const capitalise = (str: string): string => | ||
str | ||
.split(/\s/) | ||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) | ||
.join(' '); |
@@ -48,19 +48,27 @@ import * as fn from './fn'; | ||
const getCharWidth = (num: number, max: number, width: number) => Math.round(width * (Math.max(0, Math.min(num / max, 1)) / 1)); | ||
const getBarString = (current: number, max: number, width: number, opts: ProgressBarOptionsFull) => { | ||
const { progChar, emptyChar, startChar, endChar } = opts; | ||
const numProgChars = Math.round(width * (Math.max(0, Math.min(current / max, 1)) / 1)); | ||
const numEmptyChars = width - numProgChars; | ||
const body = `${progChar.repeat(numProgChars)}${emptyChar.repeat(numEmptyChars)}`; | ||
const { progChar, emptyChar, startChar, endChar, showCurrent, currentChar } = opts; | ||
const numProgChars = getCharWidth(current, max, width); | ||
const numNextChars = getCharWidth(current + 1, max, width); | ||
const numCurrentChars = showCurrent ? numNextChars - numProgChars : 0; | ||
const numEmptyChars = width - numProgChars - numCurrentChars; | ||
const prog = opts.barProgWrapFn(progChar.repeat(numProgChars)); | ||
const curr = opts.barCurrentWrapFn(currentChar.repeat(numCurrentChars)); | ||
const empt = opts.barEmptyWrapFn(emptyChar.repeat(numEmptyChars)); | ||
const body = opts.barWrapFn(`${prog}${curr}${empt}`); | ||
return `${startChar}${body}${endChar}`; | ||
}; | ||
const getSuffix = (current: number, max: number, opts: ProgressBarOptionsFull) => { | ||
const getSuffix = (current: number, maxNum: number, isMaxKnown: boolean, opts: ProgressBarOptionsFull) => { | ||
let items = ['']; | ||
if (opts.showCount) { | ||
const pad = Math.max(max.toString().length, opts.countWidth); | ||
items.push(`[${current.toString().padStart(pad, ' ')} / ${max.toString().padStart(pad, ' ')}]`); | ||
const pad = Math.max(maxNum.toString().length, opts.countWidth); | ||
items.push(`[${current.toString().padStart(pad, ' ')} / ${(isMaxKnown ? maxNum.toString() : '?').padStart(pad, ' ')}]`); | ||
} | ||
if (opts.showPercent) { | ||
const percent = Math.round((current / max) * 100); | ||
const percent = Math.round((current / maxNum) * 100); | ||
items.push(`(${percent.toString().padStart('100'.toString().length, ' ')}%)`); | ||
@@ -77,2 +85,6 @@ } | ||
wrapperFn: any; | ||
barWrapFn: any; | ||
barProgWrapFn: any; | ||
barCurrentWrapFn: any; | ||
barEmptyWrapFn: any; | ||
showCount: boolean; | ||
@@ -85,2 +97,4 @@ showPercent: boolean; | ||
endChar: string; | ||
showCurrent: boolean; | ||
currentChar: string; | ||
} | ||
@@ -93,2 +107,6 @@ export type ProgressBarOptions = Partial<ProgressBarOptionsFull>; | ||
wrapperFn: fn.noact, | ||
barWrapFn: fn.noact, | ||
barProgWrapFn: fn.noact, | ||
barCurrentWrapFn: fn.noact, | ||
barEmptyWrapFn: fn.noact, | ||
showCount: true, | ||
@@ -101,5 +119,17 @@ showPercent: false, | ||
endChar: '▏', | ||
showCurrent: false, | ||
currentChar: '▞', | ||
...opts | ||
}); | ||
export interface ProgressBar { | ||
next: () => string; | ||
set: (newCurrent: number) => string; | ||
reset: () => string; | ||
update: () => string; | ||
start: () => string; | ||
finish: () => string; | ||
readonly max: number; | ||
} | ||
/** | ||
@@ -136,3 +166,3 @@ * Usage: | ||
*/ | ||
export const getProgressBar = (max: number, options: ProgressBarOptions = {}) => { | ||
export const getProgressBar = (max: number, options: ProgressBarOptions = {}): ProgressBar => { | ||
const opts = getFullOptions(options); | ||
@@ -143,8 +173,11 @@ const { prefix, prefixWidth, maxWidth, wrapperFn, startChar, endChar } = opts; | ||
const maxNum = typeof max === 'number' ? max : 1; | ||
const isMaxKnown = typeof max === 'number'; | ||
const update = () => { | ||
const suffix = getSuffix(current, max, opts); | ||
const suffix = getSuffix(current, maxNum, isMaxKnown, opts); | ||
const fullPrefix = prefix.padEnd(prefixWidth); | ||
const output = `${fullPrefix}${getBarString( | ||
current, | ||
max, | ||
maxNum, | ||
Math.max(0, maxWidth - [fullPrefix, suffix, startChar, endChar].join('').length), | ||
@@ -192,4 +225,5 @@ opts | ||
start, | ||
finish | ||
finish, | ||
max | ||
}; | ||
}; |
@@ -8,2 +8,4 @@ /** | ||
TAB: ' ', | ||
// NBSP: '\xa0', | ||
NBSP: ' ', | ||
@@ -22,5 +24,12 @@ TICK: '✔', | ||
RADIO_EMPTY: '◯', | ||
RADIO_FULL: '◉', | ||
CURSOR: '❯', | ||
CHEV_LFT: '‹', | ||
CHEV_RGT: '›', | ||
CHAIN: '⫘', | ||
TRI_UPP: '▲', | ||
@@ -77,3 +86,3 @@ TRI_DWN: '▼', | ||
o: '°', | ||
'*': '°', | ||
'*': '°' | ||
} | ||
@@ -80,0 +89,0 @@ }; |
@@ -1,26 +0,6 @@ | ||
import { ms, SECOND } from './times'; | ||
import { ms } from './times'; | ||
import { KeysOnly, Numbered } from './types'; | ||
import { noChalk, noWrap } from './fakeChalk'; | ||
import { TimeUtils } from './TimeUtils'; | ||
// Hacky little display function | ||
const formatDuration = (duration: ms) => { | ||
const seconds = duration / SECOND; | ||
let extra = ''; | ||
let secsEx = Math.round(seconds); | ||
let minsEx = Math.floor(secsEx / 60); | ||
if (minsEx >= 1) { | ||
secsEx %= 60; | ||
extra = `${minsEx}m ${secsEx}s`; | ||
let hoursEx = Math.floor(minsEx / 60); | ||
if (hoursEx >= 1) { | ||
minsEx %= 60; | ||
extra = `${hoursEx}h ${minsEx}m ${secsEx}s`; | ||
} | ||
} | ||
return `${extra}${extra ? ` (${seconds}s)` : `${seconds}s`}`; | ||
}; | ||
interface INames { | ||
@@ -113,3 +93,3 @@ [k: string]: string; | ||
const lineStart = `${dispNames[label] || label}: `.padEnd(nameColLength + 1, ' '); | ||
const lineEnd = `${formatDuration(duration)}`; | ||
const lineEnd = `${TimeUtils.toReadableDuration(duration, false, 4)}`; | ||
@@ -152,2 +132,6 @@ const line = chalk.bold(prefix + lineStart) + lineEnd; | ||
}; | ||
const logLine2 = (label: string, prefix?: string, nameColLength?: number, duration?: number) => { | ||
lc++; | ||
return logLine(label, prefix, nameColLength, duration); | ||
}; | ||
@@ -166,3 +150,3 @@ const labels = Object.keys(startTimes); | ||
if (label !== 'TOTAL') { | ||
longest = Math.max(longest, logLine(label, ' ', nameColLength)); | ||
longest = Math.max(longest, logLine2(label, ' ', nameColLength)); | ||
} | ||
@@ -186,3 +170,3 @@ } | ||
for (let { label, duration } of cEntries) { | ||
logLine(label, ' ', nameColLength, duration); | ||
logLine2(label, ' ', nameColLength, duration); | ||
} | ||
@@ -192,3 +176,3 @@ } | ||
log(wrapperFn(chalk.dim(' ' + '⎯'.repeat(longest)))); | ||
logLine('TOTAL', ' ', nameColLength); | ||
logLine2('TOTAL', ' ', nameColLength); | ||
@@ -195,0 +179,0 @@ log(''); |
Sorry, the diff of this file is not supported yet
223695
22
6567