New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@kaciras/utilities

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kaciras/utilities - npm Package Compare versions

Comparing version 0.6.3 to 0.6.4

435

dist/browser.js

@@ -41,3 +41,3 @@ const htmlEscapes = {

*
* <h1>Alternatives</h1>
* # Alternatives
* If you don't need serialization, use `URL.createObjectURL` for better performance.

@@ -158,219 +158,205 @@ */ function blobToBase64URL(blob) {

* - Division conversion: "90s" to "1.5m".
* - Modulo conversion: "90s" to "1m 30s".
* - Modulo conversion: "90s" to "1m 30s".
*
* The n2s and s2n means "number to string" and "string to number".
*
* All conversion functions take a unit argument, which is an array of
* length 2N containing the N units from smallest to largest, and
* the multiplier to the next unit.
* e.g.
* [
* "second", 60, // 60 seconds is a minute.
* "minute", 60, // 60 minute is a hour.
* "hour", Infinity, // No more units, the multiplier is infinity.
* ]
*/ function n2sDivision(units, value, uIndex) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
let v = Math.abs(value);
for(; uIndex < units.length; uIndex += 2){
if (v < units[uIndex + 1]) break;
v /= units[uIndex + 1];
}
if (value < 0) v = -v;
return `${Number(v.toFixed(2))} ${units[uIndex]}`;
}
*/ //@formatter:off
const SIZE_UNITS = [
"B",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB"
];
const SIZE_FRACTIONS_SI = [
1,
1e3,
1e6,
1e9,
1e12,
1e15,
1e18,
1e21,
1e24
];
const SIZE_FRACTIONS_IEC = [
1,
2 ** 10,
2 ** 20,
2 ** 30,
2 ** 40,
2 ** 50,
2 ** 60,
2 ** 70,
2 ** 80
];
const TIME_UNITS = [
"ns",
"us",
"ms",
"s",
"m",
"h",
"d"
];
const TIME_FRACTIONS = [
1,
1e3,
1e6,
1e9,
6e10,
36e11,
864e11
];
// @formatter:on
const divRE = /^([-+0-9.]+)\s*(\w+)$/;
function s2nDivision(name, units, value) {
const match = divRE.exec(value);
if (!match) {
throw new Error(`Can not convert "${value}" to ${name}`);
const groupRE = /\d+([a-z]+)\s*/gi;
class UnitConvertor {
constructor(name, units, fractions){
this.name = name;
this.units = units;
this.fractions = fractions;
}
const [, v, unit] = match;
let result = Number(v);
for(let i = 0; i < units.length; i += 2){
if (units[i] === unit) {
return result;
} else {
result *= units[i + 1];
/**
* Get the fraction of the unit, throw error if the unit is invalid.
*/ getFraction(unit) {
if (unit === undefined) {
return 1;
}
const { units , name , fractions } = this;
const i = units.indexOf(unit);
if (i !== -1) {
return fractions[i];
}
throw new Error(`Unknown ${name} unit: ${unit}`);
}
throw new Error(`Unknown ${name} unit: ${unit}`);
}
function n2sModulo(name, units, value, unit, parts = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
/**
* Find the index of the largest fraction that is less than the value.
*/ largest(value) {
const s = this.fractions;
let i = 0;
// When i outbound, (s[i] <= value) is false.
while(s[i] <= value)i++;
// (i = 0) when (value < 1), fallback to the minimum unit.
return Math.max(0, i - 1);
}
if (value < 0) {
throw new Error(`value (${value}) can not be negative`);
/**
* The result may lose precision and cannot be converted back.
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param precision The number of digits to appear after the decimal point.
*/ n2sDivision(value, unit, precision = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
const { units , fractions } = this;
let v = value * this.getFraction(unit);
const i = this.largest(Math.abs(v));
v /= fractions[i];
return `${Number(v.toFixed(precision))} ${units[i]}`;
}
let i = units.indexOf(unit);
let d = 1;
if (i === -1) {
throw new Error(`Unknown ${name} unit: ${unit}`);
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ s2nDivision(value, unit) {
const match = divRE.exec(value);
if (!match) {
throw new Error(`Can not convert "${value}" to ${this.name}`);
}
const [, v, u] = match;
return Number(v) * this.getFraction(u) / this.getFraction(unit);
}
// Find index of the largest unit.
for(;; i += 2){
const x = d * units[i + 1];
if (value < x) break;
else d = x;
}
const groups = [];
// Backtrace to calculate each group.
for(; // 1.16e-14 = 1/24/60/60/1000/1000/1000
i >= 0 && parts > 0 && value > 1.16e-14; i -= 2, parts -= 1){
const t = Math.floor(value / d);
// Avoid leading zeros.
if (groups.length || t !== 0) {
/**
* Formats a value and unit.
*
* The result may lose precision and cannot be converted back.
*
* @example
* durationConvertor.n2sModulo(0.1, "ns"); // "0ns"
* durationConvertor.n2sModulo(0, "s"); // "0s"
* durationConvertor.n2sModulo(10000, "d"); // "10000d"
* durationConvertor.n2sModulo(97215, "s", 4); // "1d 3h 0m 15s"
* durationConvertor.n2sModulo(0.522, "h"); // "31m 19s"
* durationConvertor.n2sModulo(0.522, "h", 1); // "31m"
* durationConvertor.n2sModulo(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/ n2sModulo(value, unit, parts = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
if (value < 0) {
throw new Error(`value (${value}) can not be negative`);
}
const { units , fractions } = this;
value *= this.getFraction(unit);
const groups = [];
let i = this.largest(value);
// Backtrace to calculate each group.
for(; i >= 0 && parts > 0; i--, parts -= 1){
const f = fractions[i];
// Avoid tailing zeros.
if (value * f < 1) break;
const t = Math.floor(value / f);
value %= f;
groups.push(`${t}${units[i]}`);
}
value %= d;
d /= units[i - 1];
return groups.length ? groups.join(" ") : `0${unit}`;
}
return groups.length ? groups.join(" ") : `0${unit}`;
}
const groupRE = /\d+([a-z]+)\s*/gi;
function s2nModulo(name, units, value, unit) {
const i = units.indexOf(unit);
if (i === -1) {
throw new Error(`Unknown ${name} unit: ${unit}`);
}
let k = units.length - 1;
let seen = 0;
let result = 0;
for (const [matched, u] of value.matchAll(groupRE)){
const j = units.lastIndexOf(u, k);
k = j - 2;
if (j === -1) {
throw new Error(units.includes(u) ? "Units must be ordered from largest to smallest" : `Unknown ${name} unit: ${u}`);
}
/*
* Similar performance compared to prebuilt table.
* See benchmark/format.js
*/ let n = parseFloat(matched);
if (j > i) {
for(let k = i; k < j; k += 2){
n *= units[k + 1];
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ s2nModulo(value, unit) {
const { name , units , fractions } = this;
let k = Infinity;
let seen = 0;
let result = 0;
for (const [matched, u] of value.matchAll(groupRE)){
const i = units.lastIndexOf(u, k);
k = i - 1;
if (i === -1) {
throw new Error(units.includes(u) ? "Units must be ordered from largest to smallest" : `Unknown ${name} unit: ${u}`);
}
} else {
for(let k = j; k < i; k += 2){
n /= units[k + 1];
}
seen += matched.length;
result += parseFloat(matched) * fractions[i];
}
result += n;
seen += matched.length;
if (seen === value.length && seen > 0) {
return result / this.getFraction(unit);
}
throw new Error(`Can not convert "${value}" to ${name}`);
}
if (seen === value.length && seen > 0) {
return result;
}
throw new Error(`Can not convert "${value}" to ${name}`);
}
const TIME_UNITS = [
"ns",
1000,
"us",
1000,
"ms",
1000,
"s",
60,
"m",
60,
"h",
24,
"d",
Infinity
];
/**
* Convert the given duration in to a human-readable format.
* Convert between duration and human-readable string.
* Support units from nanoseconds to days.
*
* @example
* formatDuration(0, "s"); // "0s"
* formatDuration(10000, "d"); // "10000d"
* formatDuration(97215, "s", 4); // "1d 3h 0m 15s"
* formatDuration(0.522, "h"); // "31m 19s"
* formatDuration(0.522, "h", 1); // "31m"
* formatDuration(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/ function formatDuration(value, unit, parts = 2) {
return n2sModulo("time", TIME_UNITS, value, unit, parts);
}
*/ const durationConvertor = new UnitConvertor("time", TIME_UNITS, TIME_FRACTIONS);
/**
* Convert duration string to number in specified unit.
*
* @example
* parseDuration("10000d", "d"); // 10000
* parseDuration("0h", "s"); // 0
* parseDuration("0.5m", "s"); // 30
* parseDuration("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ function parseDuration(value, unit) {
return s2nModulo("time", TIME_UNITS, value, unit);
}
const SIZE_UNITS_SI = [
"B",
1000,
"KB",
1000,
"MB",
1000,
"GB",
1000,
"TB",
1000,
"PB",
1000,
"EB",
1000,
"ZB",
1000,
"YB",
Infinity
];
const SIZE_UNITS_IEC = [
"B",
1024,
"KB",
1024,
"MB",
1024,
"GB",
1024,
"TB",
1024,
"PB",
1024,
"EB",
1024,
"ZB",
1024,
"YB",
Infinity
];
* Convert between bytes and human-readable string using SI prefixes.
*/ const dataSizeSI = new UnitConvertor("data size", SIZE_UNITS, SIZE_FRACTIONS_SI);
/**
* Convert bytes to a human-readable string.
*
* The result may lose precision and cannot be converted back.
*
* @param value The number to format.
* @param fraction 1000 for SI or 1024 for IEC.
*/ function formatSize(value, unit, fraction = 1024) {
return `${n2sDivision(fraction === 1024 ? SIZE_UNITS_IEC : SIZE_UNITS_SI, value, 0)}`;
}
* Convert between bytes and human-readable string using IEC prefixes.
*/ const dataSizeIEC = new UnitConvertor("data size", SIZE_UNITS, SIZE_FRACTIONS_IEC);
/**
* Parse size string to number of bytes.
*
* @param value The size string.
* @param fraction 1000 for SI or 1024 for IEC.
*/ function parseSize(value, fraction = 1024) {
return s2nDivision("data size", fraction === 1024 ? SIZE_UNITS_IEC : SIZE_UNITS_SI, value);
}
/**
* A simple string template engine, only support replace placeholders.

@@ -479,3 +465,5 @@ *

}
class FetchClientError extends Error {
/**
* The HTTP request was successful but failed the application layer checks.
*/ class FetchClientError extends Error {
constructor(response){

@@ -649,2 +637,9 @@ super(`Fetch failed with status: ${response.status}`);

/**
* Call a function silently. returns undefined if any error occurs.
*/ function silentCall(fn) {
try {
return fn();
} catch {}
}
/**
* Silence a Promise-like object. This is useful for avoiding non-harmful,

@@ -694,2 +689,19 @@ * but potentially confusing "uncaught play promise" rejection error messages.

}
/**
* Create a new instance with the `parent` as prototype and the `value` as child.
*
* # NOTES
* If the parent is a constructor, it will not be called and just use its `prototype`.
*
* Does not support override getter-only properties.
*
* This function does not use `Object.setPrototypeOf` because it has bad performance.
*
* @param parent Prototype of returned object.
* @param value Provide properties for returned object.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
*/ function inherit(parent, value) {
const proto = typeof parent === "function" ? parent.prototype : parent;
return Object.assign(Object.create(proto), value);
}

@@ -835,4 +847,25 @@ /**

const transferCache = new WeakMap();
function transfer(obj, transfers) {
/**
* Because RPC should keep the signature of the remote function, we cannot add a parameter
* for transfers to remote function.
*
* We track transferable values with a map. This brings a new problem that
* we cannot ensure that all the values added to the map are used.
*
* This has the potential for memory leaks, so use WeakMap instead of Map.
*/ const transferCache = new WeakMap();
/**
* By default, every function parameter, return value and object property value is copied,
* in the sense of structured cloning.
*
* If you want a value to be transferred rather than copied,
* you can wrap the value in a transfer() call and provide a list of transferable values:
*
* @example
* const data = new Uint8Array([1, 2, 3, 4, 5]);
* await client.someFunction(transfer(data, [data.buffer]));
*
* @param obj The object contains transferable values.
* @param transfers List of values to transfer.
*/ function transfer(obj, transfers) {
transferCache.set(obj, transfers);

@@ -1085,2 +1118,2 @@ return obj;

export { AbortError, Composite, FetchClient, FetchClientError, LRUCache, MultiEventEmitter, MultiMap, NeverAbort, rpc as RPC, ResponseFacade, SingleEventEmitter, base64url, blobToBase64URL, compositor, dragSortContext, escapeHTML, fetchFile, formatDuration, formatSize, identity, isPointerInside, noop, nthInChildren, parseDuration, parseSize, saveFile, selectFile, sha256, silencePromise, sleep, svgToUrl, swapElements, uniqueId };
export { AbortError, Composite, FetchClient, FetchClientError, LRUCache, MultiEventEmitter, MultiMap, NeverAbort, rpc as RPC, ResponseFacade, SingleEventEmitter, UnitConvertor, base64url, blobToBase64URL, compositor, dataSizeIEC, dataSizeSI, dragSortContext, durationConvertor, escapeHTML, fetchFile, identity, inherit, isPointerInside, noop, nthInChildren, saveFile, selectFile, sha256, silencePromise, silentCall, sleep, svgToUrl, swapElements, uniqueId };

@@ -24,3 +24,3 @@ /// <reference types="node" resolution-mode="require"/>

*
* <h1>Alternatives</h1>
* # Alternatives
* If you don't need serialization, use `URL.createObjectURL` for better performance.

@@ -27,0 +27,0 @@ */

@@ -8,2 +8,5 @@ /**

export declare function fetchFile(request: RequestInfo, init?: RequestInit): Promise<File>;
/**
* The HTTP request was successful but failed the application layer checks.
*/
export declare class FetchClientError extends Error {

@@ -10,0 +13,0 @@ private readonly response;

@@ -1,48 +0,81 @@

type TimeUnit = "ns" | "ms" | "s" | "m" | "h" | "d";
export declare class UnitConvertor<T extends readonly string[]> {
private readonly name;
private readonly units;
private readonly fractions;
constructor(name: string, units: T, fractions: number[]);
/**
* Get the fraction of the unit, throw error if the unit is invalid.
*/
private getFraction;
/**
* Find the index of the largest fraction that is less than the value.
*/
private largest;
/**
* The result may lose precision and cannot be converted back.
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param precision The number of digits to appear after the decimal point.
*/
n2sDivision(value: number, unit?: T[number], precision?: number): string;
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/
s2nDivision(value: string, unit?: T[number]): number;
/**
* Formats a value and unit.
*
* The result may lose precision and cannot be converted back.
*
* @example
* durationConvertor.n2sModulo(0.1, "ns"); // "0ns"
* durationConvertor.n2sModulo(0, "s"); // "0s"
* durationConvertor.n2sModulo(10000, "d"); // "10000d"
* durationConvertor.n2sModulo(97215, "s", 4); // "1d 3h 0m 15s"
* durationConvertor.n2sModulo(0.522, "h"); // "31m 19s"
* durationConvertor.n2sModulo(0.522, "h", 1); // "31m"
* durationConvertor.n2sModulo(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/
n2sModulo(value: number, unit?: T[number], parts?: number): string;
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/
s2nModulo(value: string, unit?: T[number]): number;
}
/**
* Convert the given duration in to a human-readable format.
* Convert between duration and human-readable string.
* Support units from nanoseconds to days.
*
* @example
* formatDuration(0, "s"); // "0s"
* formatDuration(10000, "d"); // "10000d"
* formatDuration(97215, "s", 4); // "1d 3h 0m 15s"
* formatDuration(0.522, "h"); // "31m 19s"
* formatDuration(0.522, "h", 1); // "31m"
* formatDuration(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/
export declare function formatDuration(value: number, unit: TimeUnit, parts?: number): string;
export declare const durationConvertor: UnitConvertor<readonly ["ns", "us", "ms", "s", "m", "h", "d"]>;
/**
* Convert duration string to number in specified unit.
*
* @example
* parseDuration("10000d", "d"); // 10000
* parseDuration("0h", "s"); // 0
* parseDuration("0.5m", "s"); // 30
* parseDuration("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
* Convert between bytes and human-readable string using SI prefixes.
*/
export declare function parseDuration(value: string, unit: TimeUnit): number;
export declare const dataSizeSI: UnitConvertor<readonly ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]>;
/**
* Convert bytes to a human-readable string.
*
* The result may lose precision and cannot be converted back.
*
* @param value The number to format.
* @param fraction 1000 for SI or 1024 for IEC.
* Convert between bytes and human-readable string using IEC prefixes.
*/
export declare function formatSize(value: number, unit: string, fraction?: 1024 | 1000): string;
/**
* Parse size string to number of bytes.
*
* @param value The size string.
* @param fraction 1000 for SI or 1024 for IEC.
*/
export declare function parseSize(value: string, fraction?: 1024 | 1000): number;
export declare const dataSizeIEC: UnitConvertor<readonly ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]>;
type Placeholders = Record<string, string | RegExp>;

@@ -49,0 +82,0 @@ /**

export type Awaitable<T> = T | Promise<T>;
export declare const noop: () => void;
export declare const identity: <T>(v: T) => T;
type Constructor<T> = Function & {
prototype: T;
};
/**

@@ -26,2 +29,6 @@ * An AbortSignal that never aborts.

/**
* Call a function silently. returns undefined if any error occurs.
*/
export declare function silentCall<T>(fn: () => T): T | undefined;
/**
* Silence a Promise-like object. This is useful for avoiding non-harmful,

@@ -43,1 +50,17 @@ * but potentially confusing "uncaught play promise" rejection error messages.

}
/**
* Create a new instance with the `parent` as prototype and the `value` as child.
*
* # NOTES
* If the parent is a constructor, it will not be called and just use its `prototype`.
*
* Does not support override getter-only properties.
*
* This function does not use `Object.setPrototypeOf` because it has bad performance.
*
* @param parent Prototype of returned object.
* @param value Provide properties for returned object.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
*/
export declare function inherit<P extends object | null, C>(parent: P | Constructor<P>, value: C): P extends null ? C : P & C;
export {};

@@ -45,3 +45,3 @@ import process from 'process';

*
* <h1>Alternatives</h1>
* # Alternatives
* If you don't need serialization, use `URL.createObjectURL` for better performance.

@@ -181,3 +181,5 @@ */ function blobToBase64URL(blob) {

}
class FetchClientError extends Error {
/**
* The HTTP request was successful but failed the application layer checks.
*/ class FetchClientError extends Error {
constructor(response){

@@ -310,219 +312,205 @@ super(`Fetch failed with status: ${response.status}`);

* - Division conversion: "90s" to "1.5m".
* - Modulo conversion: "90s" to "1m 30s".
* - Modulo conversion: "90s" to "1m 30s".
*
* The n2s and s2n means "number to string" and "string to number".
*
* All conversion functions take a unit argument, which is an array of
* length 2N containing the N units from smallest to largest, and
* the multiplier to the next unit.
* e.g.
* [
* "second", 60, // 60 seconds is a minute.
* "minute", 60, // 60 minute is a hour.
* "hour", Infinity, // No more units, the multiplier is infinity.
* ]
*/ function n2sDivision(units, value, uIndex) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
let v = Math.abs(value);
for(; uIndex < units.length; uIndex += 2){
if (v < units[uIndex + 1]) break;
v /= units[uIndex + 1];
}
if (value < 0) v = -v;
return `${Number(v.toFixed(2))} ${units[uIndex]}`;
}
*/ //@formatter:off
const SIZE_UNITS = [
"B",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB"
];
const SIZE_FRACTIONS_SI = [
1,
1e3,
1e6,
1e9,
1e12,
1e15,
1e18,
1e21,
1e24
];
const SIZE_FRACTIONS_IEC = [
1,
2 ** 10,
2 ** 20,
2 ** 30,
2 ** 40,
2 ** 50,
2 ** 60,
2 ** 70,
2 ** 80
];
const TIME_UNITS = [
"ns",
"us",
"ms",
"s",
"m",
"h",
"d"
];
const TIME_FRACTIONS = [
1,
1e3,
1e6,
1e9,
6e10,
36e11,
864e11
];
// @formatter:on
const divRE = /^([-+0-9.]+)\s*(\w+)$/;
function s2nDivision(name, units, value) {
const match = divRE.exec(value);
if (!match) {
throw new Error(`Can not convert "${value}" to ${name}`);
const groupRE = /\d+([a-z]+)\s*/gi;
class UnitConvertor {
constructor(name, units, fractions){
this.name = name;
this.units = units;
this.fractions = fractions;
}
const [, v, unit] = match;
let result = Number(v);
for(let i = 0; i < units.length; i += 2){
if (units[i] === unit) {
return result;
} else {
result *= units[i + 1];
/**
* Get the fraction of the unit, throw error if the unit is invalid.
*/ getFraction(unit) {
if (unit === undefined) {
return 1;
}
const { units , name , fractions } = this;
const i = units.indexOf(unit);
if (i !== -1) {
return fractions[i];
}
throw new Error(`Unknown ${name} unit: ${unit}`);
}
throw new Error(`Unknown ${name} unit: ${unit}`);
}
function n2sModulo(name, units, value, unit, parts = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
/**
* Find the index of the largest fraction that is less than the value.
*/ largest(value) {
const s = this.fractions;
let i = 0;
// When i outbound, (s[i] <= value) is false.
while(s[i] <= value)i++;
// (i = 0) when (value < 1), fallback to the minimum unit.
return Math.max(0, i - 1);
}
if (value < 0) {
throw new Error(`value (${value}) can not be negative`);
/**
* The result may lose precision and cannot be converted back.
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param precision The number of digits to appear after the decimal point.
*/ n2sDivision(value, unit, precision = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
const { units , fractions } = this;
let v = value * this.getFraction(unit);
const i = this.largest(Math.abs(v));
v /= fractions[i];
return `${Number(v.toFixed(precision))} ${units[i]}`;
}
let i = units.indexOf(unit);
let d = 1;
if (i === -1) {
throw new Error(`Unknown ${name} unit: ${unit}`);
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ s2nDivision(value, unit) {
const match = divRE.exec(value);
if (!match) {
throw new Error(`Can not convert "${value}" to ${this.name}`);
}
const [, v, u] = match;
return Number(v) * this.getFraction(u) / this.getFraction(unit);
}
// Find index of the largest unit.
for(;; i += 2){
const x = d * units[i + 1];
if (value < x) break;
else d = x;
}
const groups = [];
// Backtrace to calculate each group.
for(; // 1.16e-14 = 1/24/60/60/1000/1000/1000
i >= 0 && parts > 0 && value > 1.16e-14; i -= 2, parts -= 1){
const t = Math.floor(value / d);
// Avoid leading zeros.
if (groups.length || t !== 0) {
/**
* Formats a value and unit.
*
* The result may lose precision and cannot be converted back.
*
* @example
* durationConvertor.n2sModulo(0.1, "ns"); // "0ns"
* durationConvertor.n2sModulo(0, "s"); // "0s"
* durationConvertor.n2sModulo(10000, "d"); // "10000d"
* durationConvertor.n2sModulo(97215, "s", 4); // "1d 3h 0m 15s"
* durationConvertor.n2sModulo(0.522, "h"); // "31m 19s"
* durationConvertor.n2sModulo(0.522, "h", 1); // "31m"
* durationConvertor.n2sModulo(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/ n2sModulo(value, unit, parts = 2) {
if (!Number.isFinite(value)) {
throw new TypeError(`${value} is not a finite number`);
}
if (value < 0) {
throw new Error(`value (${value}) can not be negative`);
}
const { units , fractions } = this;
value *= this.getFraction(unit);
const groups = [];
let i = this.largest(value);
// Backtrace to calculate each group.
for(; i >= 0 && parts > 0; i--, parts -= 1){
const f = fractions[i];
// Avoid tailing zeros.
if (value * f < 1) break;
const t = Math.floor(value / f);
value %= f;
groups.push(`${t}${units[i]}`);
}
value %= d;
d /= units[i - 1];
return groups.length ? groups.join(" ") : `0${unit}`;
}
return groups.length ? groups.join(" ") : `0${unit}`;
}
const groupRE = /\d+([a-z]+)\s*/gi;
function s2nModulo(name, units, value, unit) {
const i = units.indexOf(unit);
if (i === -1) {
throw new Error(`Unknown ${name} unit: ${unit}`);
}
let k = units.length - 1;
let seen = 0;
let result = 0;
for (const [matched, u] of value.matchAll(groupRE)){
const j = units.lastIndexOf(u, k);
k = j - 2;
if (j === -1) {
throw new Error(units.includes(u) ? "Units must be ordered from largest to smallest" : `Unknown ${name} unit: ${u}`);
}
/*
* Similar performance compared to prebuilt table.
* See benchmark/format.js
*/ let n = parseFloat(matched);
if (j > i) {
for(let k = i; k < j; k += 2){
n *= units[k + 1];
/**
* Convert string to number in specified unit.
*
* @example
* durationConvertor.s2nModulo("10000d", "d"); // 10000
* durationConvertor.s2nModulo("0h", "s"); // 0
* durationConvertor.s2nModulo("0.5m", "s"); // 30
* durationConvertor.s2nModulo("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ s2nModulo(value, unit) {
const { name , units , fractions } = this;
let k = Infinity;
let seen = 0;
let result = 0;
for (const [matched, u] of value.matchAll(groupRE)){
const i = units.lastIndexOf(u, k);
k = i - 1;
if (i === -1) {
throw new Error(units.includes(u) ? "Units must be ordered from largest to smallest" : `Unknown ${name} unit: ${u}`);
}
} else {
for(let k = j; k < i; k += 2){
n /= units[k + 1];
}
seen += matched.length;
result += parseFloat(matched) * fractions[i];
}
result += n;
seen += matched.length;
if (seen === value.length && seen > 0) {
return result / this.getFraction(unit);
}
throw new Error(`Can not convert "${value}" to ${name}`);
}
if (seen === value.length && seen > 0) {
return result;
}
throw new Error(`Can not convert "${value}" to ${name}`);
}
const TIME_UNITS = [
"ns",
1000,
"us",
1000,
"ms",
1000,
"s",
60,
"m",
60,
"h",
24,
"d",
Infinity
];
/**
* Convert the given duration in to a human-readable format.
* Convert between duration and human-readable string.
* Support units from nanoseconds to days.
*
* @example
* formatDuration(0, "s"); // "0s"
* formatDuration(10000, "d"); // "10000d"
* formatDuration(97215, "s", 4); // "1d 3h 0m 15s"
* formatDuration(0.522, "h"); // "31m 19s"
* formatDuration(0.522, "h", 1); // "31m"
* formatDuration(0.522, "h", 999); // "31m 19s 200ms"
*
* @param value Numeric value to use.
* @param unit Unit ot the value.
* @param parts Maximum number of groups in result.
*/ function formatDuration(value, unit, parts = 2) {
return n2sModulo("time", TIME_UNITS, value, unit, parts);
}
*/ const durationConvertor = new UnitConvertor("time", TIME_UNITS, TIME_FRACTIONS);
/**
* Convert duration string to number in specified unit.
*
* @example
* parseDuration("10000d", "d"); // 10000
* parseDuration("0h", "s"); // 0
* parseDuration("0.5m", "s"); // 30
* parseDuration("1d 3h 0m 15s", "s"); // 97215
*
* @param value The string to parse.
* @param unit Target unit to converted to.
*/ function parseDuration(value, unit) {
return s2nModulo("time", TIME_UNITS, value, unit);
}
const SIZE_UNITS_SI = [
"B",
1000,
"KB",
1000,
"MB",
1000,
"GB",
1000,
"TB",
1000,
"PB",
1000,
"EB",
1000,
"ZB",
1000,
"YB",
Infinity
];
const SIZE_UNITS_IEC = [
"B",
1024,
"KB",
1024,
"MB",
1024,
"GB",
1024,
"TB",
1024,
"PB",
1024,
"EB",
1024,
"ZB",
1024,
"YB",
Infinity
];
* Convert between bytes and human-readable string using SI prefixes.
*/ const dataSizeSI = new UnitConvertor("data size", SIZE_UNITS, SIZE_FRACTIONS_SI);
/**
* Convert bytes to a human-readable string.
*
* The result may lose precision and cannot be converted back.
*
* @param value The number to format.
* @param fraction 1000 for SI or 1024 for IEC.
*/ function formatSize(value, unit, fraction = 1024) {
return `${n2sDivision(fraction === 1024 ? SIZE_UNITS_IEC : SIZE_UNITS_SI, value, 0)}`;
}
* Convert between bytes and human-readable string using IEC prefixes.
*/ const dataSizeIEC = new UnitConvertor("data size", SIZE_UNITS, SIZE_FRACTIONS_IEC);
/**
* Parse size string to number of bytes.
*
* @param value The size string.
* @param fraction 1000 for SI or 1024 for IEC.
*/ function parseSize(value, fraction = 1024) {
return s2nDivision("data size", fraction === 1024 ? SIZE_UNITS_IEC : SIZE_UNITS_SI, value);
}
/**
* A simple string template engine, only support replace placeholders.

@@ -655,2 +643,9 @@ *

/**
* Call a function silently. returns undefined if any error occurs.
*/ function silentCall(fn) {
try {
return fn();
} catch {}
}
/**
* Silence a Promise-like object. This is useful for avoiding non-harmful,

@@ -700,5 +695,43 @@ * but potentially confusing "uncaught play promise" rejection error messages.

}
/**
* Create a new instance with the `parent` as prototype and the `value` as child.
*
* # NOTES
* If the parent is a constructor, it will not be called and just use its `prototype`.
*
* Does not support override getter-only properties.
*
* This function does not use `Object.setPrototypeOf` because it has bad performance.
*
* @param parent Prototype of returned object.
* @param value Provide properties for returned object.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
*/ function inherit(parent, value) {
const proto = typeof parent === "function" ? parent.prototype : parent;
return Object.assign(Object.create(proto), value);
}
const transferCache = new WeakMap();
function transfer(obj, transfers) {
/**
* Because RPC should keep the signature of the remote function, we cannot add a parameter
* for transfers to remote function.
*
* We track transferable values with a map. This brings a new problem that
* we cannot ensure that all the values added to the map are used.
*
* This has the potential for memory leaks, so use WeakMap instead of Map.
*/ const transferCache = new WeakMap();
/**
* By default, every function parameter, return value and object property value is copied,
* in the sense of structured cloning.
*
* If you want a value to be transferred rather than copied,
* you can wrap the value in a transfer() call and provide a list of transferable values:
*
* @example
* const data = new Uint8Array([1, 2, 3, 4, 5]);
* await client.someFunction(transfer(data, [data.buffer]));
*
* @param obj The object contains transferable values.
* @param transfers List of values to transfer.
*/ function transfer(obj, transfers) {
transferCache.set(obj, transfers);

@@ -982,2 +1015,2 @@ return obj;

export { AbortError, Composite, FetchClient, FetchClientError, LRUCache, MultiEventEmitter, MultiMap, NeverAbort, rpc as RPC, ResponseFacade, SingleEventEmitter, base64url, blobToBase64URL, compositor, escapeHTML, fetchFile, formatDuration, formatSize, identity, noop, onExit, parseDuration, parseSize, sha256, silencePromise, sleep, svgToUrl, uniqueId };
export { AbortError, Composite, FetchClient, FetchClientError, LRUCache, MultiEventEmitter, MultiMap, NeverAbort, rpc as RPC, ResponseFacade, SingleEventEmitter, UnitConvertor, base64url, blobToBase64URL, compositor, dataSizeIEC, dataSizeSI, durationConvertor, escapeHTML, fetchFile, identity, inherit, noop, onExit, sha256, silencePromise, silentCall, sleep, svgToUrl, uniqueId };

@@ -14,2 +14,16 @@ export type Respond = (resp: ResponseMessage, transfer?: Transferable[]) => void;

}
/**
* By default, every function parameter, return value and object property value is copied,
* in the sense of structured cloning.
*
* If you want a value to be transferred rather than copied,
* you can wrap the value in a transfer() call and provide a list of transferable values:
*
* @example
* const data = new Uint8Array([1, 2, 3, 4, 5]);
* await client.someFunction(transfer(data, [data.buffer]));
*
* @param obj The object contains transferable values.
* @param transfers List of values to transfer.
*/
export declare function transfer<T>(obj: T, transfers: Transferable[]): T;

@@ -16,0 +30,0 @@ /**

{
"name": "@kaciras/utilities",
"version": "0.6.3",
"version": "0.6.4",
"license": "MIT",

@@ -22,3 +22,3 @@ "description": "A set of common JS functions for node and browser.",

"devDependencies": {
"@jest/globals": "^29.3.1",
"@jest/globals": "^29.4.1",
"@kaciras/eslint-config-core": "^2.5.0",

@@ -30,11 +30,11 @@ "@kaciras/eslint-config-jest": "^2.5.0",

"@stryker-mutator/jest-runner": "^6.3.1",
"@swc/core": "^1.3.26",
"@swc/core": "^1.3.32",
"@swc/jest": "^0.2.24",
"@types/node": "^18.11.18",
"eslint": "^8.32.0",
"is-builtin-module": "^3.2.0",
"jest": "^29.3.1",
"mockttp": "^3.6.2",
"rollup": "^3.10.0",
"typescript": "^4.9.4"
"eslint": "^8.33.0",
"is-builtin-module": "^3.2.1",
"jest": "^29.4.1",
"mockttp": "^3.6.3",
"rollup": "^3.12.1",
"typescript": "^4.9.5"
},

@@ -41,0 +41,0 @@ "scripts": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc