@blake.regalia/belt
Advanced tools
Comparing version 0.31.1 to 0.32.0
@@ -1,2 +0,2 @@ | ||
import type { Dict, JsonObject } from './types'; | ||
import type { InsteadOfAny, JsonObject, KeyValuable, KeysOf, Promisable, TypedArray, ValuesOf } from './types'; | ||
/** | ||
@@ -24,18 +24,50 @@ * Utility nil buffer constant | ||
/** | ||
* The seldomnly-used "identity" function | ||
* The "identity" function | ||
*/ | ||
export declare const F_IDENTITY: (w: any) => any; | ||
export declare const F_IDENTITY: <w_type>(w: w_type) => w_type; | ||
/** | ||
* Creates a proper-case string | ||
* Casts the given argument to a specific type. | ||
* @param w_value - value to cast | ||
* @returns the value casted to the target type | ||
*/ | ||
export declare const cast: <w_to>(w_value: any) => w_to; | ||
/** | ||
* Forces TypeScript to perform type narrowing on the given value by asserting its type | ||
* @param w_value - value to narrow | ||
* @returns `true` always | ||
*/ | ||
export declare const narrow: <w_to>(w_value: any) => w_value is w_to; | ||
/** | ||
* Equivalent to testing `'undefined' === typeof thing` | ||
*/ | ||
export declare const proper: (s_input: string) => string; | ||
export declare const is_undefined: (z: unknown) => z is undefined; | ||
/** | ||
* Converts given identifier to "snake_case" | ||
* Equivalent to testing `'boolean' === typeof thing` | ||
*/ | ||
export declare const snake: (s_ident: string) => string; | ||
export declare const is_boolean: (z: unknown) => z is boolean; | ||
/** | ||
* Converts given identifier to "PascalCase" | ||
* Equivalent to testing `'number' === typeof thing` | ||
*/ | ||
export declare const pascal: (s_ident: string) => string; | ||
export declare const is_number: (z: unknown) => z is number; | ||
/** | ||
* Equivalent to testing `'bigint' === typeof thing` | ||
*/ | ||
export declare const is_bigint: (z: unknown) => z is bigint; | ||
/** | ||
* Equivalent to testing `'string' === typeof thing` | ||
*/ | ||
export declare const is_string: (z: unknown) => z is string; | ||
/** | ||
* Equivalent to testing `'symbol' === typeof thing` | ||
*/ | ||
export declare const is_symbol: (z: unknown) => z is symbol; | ||
/** | ||
* Equivalent to testing `'object' === typeof thing` | ||
*/ | ||
export declare const is_object: (z: unknown) => z is object; | ||
/** | ||
* Equivalent to testing `'function' === typeof thing` | ||
*/ | ||
export declare const is_function: (z: unknown) => z is Function; | ||
/** | ||
* Simple test for whether a value is a Uint8Array or not | ||
@@ -51,106 +83,200 @@ */ | ||
*/ | ||
export declare const is_dict: (z: unknown) => z is JsonObject<never>; | ||
export declare const is_dict: (z: unknown) => z is JsonObject; | ||
/** | ||
* Strict test for whether an ES object is a plain object (dict) or not | ||
*/ | ||
export declare const is_dict_es: (z: unknown) => z is JsonObject<never>; | ||
export declare const is_dict_es: (z: unknown) => z is JsonObject; | ||
/** | ||
* Fold array into an object | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export declare const fold: <w_out, w_value>(a_in: Iterable<w_value>, f_fold: (z_value: w_value, i_each: number) => Dict<w_out>) => Dict<w_out>; | ||
export declare const is_iterable: <w_type = unknown>(z: unknown) => z is Iterable<w_type>; | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export declare const interjoin: <w_item extends unknown, w_insert extends unknown>(a_input: w_item[], w_insert: w_insert) => (w_item | w_insert)[]; | ||
export declare const is_error: <h_extend extends object>(z: unknown) => z is Error & h_extend; | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence. | ||
* @param z_identify - if specified and a string, identifies the key of each item to use as an identifier | ||
* if specified and a function, used as a callback to produce the comparison key | ||
* if omitted, compares items using full equality `===` | ||
* Typed alias to `Array.from` | ||
*/ | ||
export declare const deduplicate: <z_item extends unknown, s_key extends keyof z_item = keyof z_item>(a_items: z_item[], z_identify?: s_key | ((z_item: z_item) => any) | undefined) => z_item[]; | ||
export declare const array: <w_value>(a_in: Iterable<w_value>) => w_value[]; | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
* Typed alias to `Object.create` | ||
*/ | ||
export declare const escape_regex: (s_input: string) => string; | ||
export declare const create: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.create` | ||
* @deprecated Use {@link create} instead | ||
*/ | ||
export declare const oc: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
export declare const odc: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
export declare const oda: <h_object extends {}, h_extend extends {}>(h_object: h_object, h_extend: h_extend) => h_object & h_extend; | ||
export declare const assign: <h_object extends {}, h_extend extends {}>(h_object: h_object, h_extend: h_extend) => h_object & h_extend; | ||
/** | ||
* @deprecated Use {@link assign} instead | ||
*/ | ||
export declare const oda: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
export declare const odk: <si_key extends string, w_value extends any>(h_object: Record<si_key, w_value>) => si_key[]; | ||
export declare const keys: <w_src extends KeyValuable>(w_src: w_src) => KeysOf<w_src>[]; | ||
/** | ||
* @deprecated Use {@link keys} instead | ||
*/ | ||
export declare const odk: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
export declare const odv: <w_value extends any>(h_object: Record<any, w_value>) => w_value[]; | ||
export declare const values: <w_src extends KeyValuable, z_values = ValuesOf<w_src>>(w_src: w_src) => z_values[]; | ||
/** | ||
* Typed alias to `Object.entries` | ||
* @deprecated Use {@link values} instead | ||
*/ | ||
export declare const ode: <si_key extends string, w_value extends any>(h_object: Record<si_key, w_value>) => [si_key, w_value][]; | ||
export declare const odv: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.fromEntries` | ||
* Typed alias of `Object.entries` | ||
*/ | ||
export declare const ofe: <as_keys extends string, w_values extends any>(a_entries: Iterable<[as_keys, w_values]>) => Record<as_keys, w_values>; | ||
export declare const entries: <w_src extends KeyValuable, z_keys extends PropertyKey = KeysOf<w_src>, z_values = ValuesOf<w_src>>(w_src: w_src) => [z_keys, z_values][]; | ||
/** | ||
* Map object entries | ||
* @deprecated Use {@link entries} instead | ||
*/ | ||
export declare const odem: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_object: Record<si_key, w_value>, f_map: (g_entry: [si_key, w_value], i_index: number, a_all: [si_key, w_value][]) => w_out) => w_out[]; | ||
export declare const ode: <w_src extends KeyValuable, z_keys extends PropertyKey = KeysOf<w_src>, z_values = ValuesOf<w_src>>(w_src: w_src) => [z_keys, z_values][]; | ||
/** | ||
* Reduce object entries to an arbitrary type | ||
* Typed alias of `Object.fromEntries` | ||
*/ | ||
export declare const oder: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_reduce: (w_prev: w_out, g_entry: [si_key, w_value], i_index: number, a_all: [si_key, w_value][]) => w_out, w_init: w_out) => w_out; | ||
export declare const from_entries: <as_keys extends PropertyKey, w_values extends any>(a_entries: Iterable<readonly [as_keys, w_values]>) => Record<as_keys, w_values>; | ||
/** | ||
* Reduce object entries to an array via concatenation (with filtering) | ||
* @deprecated Use {@link from_entries} instead | ||
*/ | ||
export declare const oderac: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_concat: (si_key: si_key, w_value: w_value, i_entry: number) => w_out, b_add_undefs?: boolean) => w_out[]; | ||
export declare const ofe: <as_keys extends PropertyKey, w_values extends unknown>(a_entries: Iterable<readonly [as_keys, w_values]>) => Record<as_keys, w_values>; | ||
/** | ||
* Reduce object entries to an array via flattening | ||
* Map object entries. Alias of: | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).map(f_map) | ||
* ``` | ||
*/ | ||
export declare const oderaf: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_concat: (si_key: si_key, w_value: w_value, i_entry: number) => w_out[]) => w_out[]; | ||
export declare const map_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_map: (a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out) => w_out[]; | ||
/** | ||
* Reduce object entries to an object via merging | ||
* @deprecated Use {@link map_entries} instead | ||
*/ | ||
export declare const oderom: <w_value_out extends unknown, si_key_in extends string, w_value_in extends unknown, si_key_out extends string>(h_thing: Record<si_key_in, w_value_in>, f_merge: (si_key: si_key_in, w_value: w_value_in, i_index: number) => Record<si_key_in, w_value_out>) => Record<si_key_out, w_value_out>; | ||
export declare const odem: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_map: (a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out) => w_out[]; | ||
/** | ||
* Reduce object entries to an object via transforming value function | ||
* Reduce an object to an arbitrary type by its entries. Alias of | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).reduce(f_reduce) | ||
* ``` | ||
*/ | ||
export declare const fodemtv: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_transform: (w_value: w_value, si_key: si_key, i_entry: number) => w_out) => { [si_key_out in keyof Record<si_key, w_value>]: w_out; }; | ||
export declare const reduce_object: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_reduce: (w_prev: w_out, a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out, w_init: w_out) => w_out; | ||
/** | ||
* Promise-based version of `setTimeout()` | ||
* @deprecated Use {@link reduce_object} instead | ||
*/ | ||
export declare const timeout: (xt_wait: number) => Promise<void>; | ||
export declare const timeout_exec: <w_return extends unknown = any>(xt_wait: number, f_attempt?: (() => Promise<w_return>) | undefined) => Promise<[w_return | undefined, 0 | 1]>; | ||
export interface WithTimeoutConfig<w_value extends any> { | ||
duration: number; | ||
trip: () => void; | ||
run: () => Promise<w_value>; | ||
} | ||
export declare const with_timeout: <w_value extends unknown>(g_with: WithTimeoutConfig<w_value>) => Promise<w_value>; | ||
export declare const oder: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_reduce: (w_prev: w_out, a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out, w_init: w_out) => w_out; | ||
/** | ||
* A Promise that never fulfills nor rejects | ||
* Reduce an object's entries to an array via concatenation (with filtering) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => item` | ||
* @param b_keep_undefs - by default, `undefined` items will be ommitted from return array unless this is truthy | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export declare const forever: <w_type = void>(w_type?: w_type | undefined) => Promise<w_type>; | ||
export declare const concat_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => w_out, b_keep_undefs?: 0 | 1 | boolean | undefined, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Promse-based version of `queueMicrotask()` | ||
* @deprecated Use {@link concat_entries} instead | ||
*/ | ||
export declare const microtask: () => Promise<void>; | ||
export declare const defer: <w_return extends unknown = any>() => [Promise<w_return>, (w_return: w_return, e_reject?: Error) => void]; | ||
export declare const defer_many: <h_input extends Dict<unknown>>(h_input: h_input) => { | ||
promises: { [si_each in keyof h_input]: Promise<h_input[si_each]>; }; | ||
resolve(h_resolves: { [si_each_1 in keyof h_input]?: h_input[si_each_1]; }): void; | ||
reject(h_rejects: { [si_each_2 in keyof h_input]?: Error; }): void; | ||
}; | ||
export declare const oderac: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => w_out, b_keep_undefs?: 0 | 1 | boolean | undefined, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Cryptographically strong random number | ||
* Reduce object entries to an array via flattening (i.e., callback return value will be spread into array) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => Iterable<item>` | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export declare const crypto_random: () => number; | ||
export declare const flatten_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => Iterable<w_out>, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* @deprecated Use {@link flatten_entries} instead | ||
*/ | ||
export declare const oderaf: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => Iterable<w_out>, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Transform an object to an object by its entries via merging (i.e., callback return value will be spread into object) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_merge - callback having signature `(key, value, index) => object` | ||
* @param h_out - optionally specifies the output object to merge properties into | ||
* @returns all `item` values returned by {@link f_merge} merged into a single object | ||
*/ | ||
export declare const transform_object: <h_out extends object, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_merge: (si_key: z_keys, w_value: z_values, i_index: number) => h_out, h_out?: h_out) => h_out; | ||
/** | ||
* @deprecated Use {@link transform_object} instead | ||
*/ | ||
export declare const oderom: <h_out extends object, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_merge: (si_key: z_keys, w_value: z_values, i_index: number) => h_out, h_out?: h_out) => h_out; | ||
/** | ||
* Transforms an object by applying the given callback to each of its values, returning a new object | ||
* with the same keys as the original object | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_transform - callback having signature `(value, key, index) => new_value` | ||
* @returns the new object | ||
*/ | ||
export declare const transform_values: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_transform: (w_value: z_values, si_key: z_keys, i_entry: number) => w_out) => { [si_key_out in z_keys]: w_out; }; | ||
/** | ||
* @deprecated Use {@link transform_values} instead | ||
*/ | ||
export declare const fodemtv: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_transform: (w_value: z_values, si_key: z_keys, i_entry: number) => w_out) => { [si_key_out in z_keys]: w_out; }; | ||
/** | ||
* Fold an array into an object via reduction, i.e., by transforming each value into an object and merging it into a single output. | ||
* | ||
* Useful when the number of output entries per input entry can vary. For 1:1 multiplicity see also {@link collapse}. | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* fold(['a', 'b', 'c'], (value, index) => ({[value]: index})) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_fold - transforming callback function with signature | ||
* ```ts | ||
* type f_fold = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @param h_out - optionally specify the output object, an existing object to merge properties into | ||
* @returns the merged output object | ||
*/ | ||
export declare const fold: <w_value, z_keys extends PropertyKey = string, w_out = any, h_output extends Record<z_keys, w_out> | undefined = Record<z_keys, w_out> | undefined, h_returned extends Record<z_keys, w_out> = Record<z_keys, w_out>, h_dest = undefined extends h_output ? h_returned : h_output>(w_in: Iterable<w_value>, f_fold: (z_value: w_value, i_each: number) => h_returned, h_out?: h_output) => h_dest; | ||
/** | ||
* Collapse an array into an object by mapping its items into entries | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* collapse(['a', 'b', 'c'], (value, index) => [value, index]) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_collapse - transforming callback function with signature | ||
* ```ts | ||
* type f_collapse = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @returns the merged output object | ||
*/ | ||
export declare const collapse: <w_value, z_keys extends PropertyKey = string, z_values = any>(w_in: Iterable<w_value>, f_collapse: (z_value: w_value, i_each: number) => [z_keys, z_values]) => Record<z_keys, z_values>; | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
*/ | ||
export declare const interjoin: <w_item extends unknown, w_insert extends unknown>(a_input: w_item[], w_insert: w_insert) => (w_item | w_insert)[]; | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence of each value. Optionally accepts | ||
* an identity argument for deduplicating lists of objects using a key or callback function. | ||
* @param a_items - the items to deduplicate | ||
* @param z_identify - defines how to identify items in the list | ||
* - if given a string, specifes the key of each item whose value should be used to identify it | ||
* - if given a function, used as a callback to produce the comparison key | ||
* - if omitted, compares items using strict equality | ||
*/ | ||
export declare const deduplicate: <z_item extends unknown, s_key extends keyof z_item = keyof z_item>(a_items: z_item[], z_identify?: s_key | ((z_item: z_item) => any) | undefined) => z_item[]; | ||
/** | ||
* Generate a random int within a given range | ||
@@ -160,7 +286,2 @@ */ | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export declare const crypto_random_int: (x_a: number, x_b?: number) => number; | ||
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; | ||
/** | ||
* Shuffles an array | ||
@@ -182,2 +303,17 @@ */ | ||
export declare const die: (s_msg: string, w_data?: unknown) => never; | ||
export {}; | ||
/** | ||
* Synchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - synchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export declare const try_sync: <w_return, w_error>(f_try: (_?: void | undefined) => w_return) => [w_return, 0] | [undefined, InsteadOfAny<w_error, unknown>]; | ||
/** | ||
* Asynchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - asynchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the awaited value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export declare const try_async: <w_error, w_return>(f_try: () => Promisable<w_return>) => Promise<[w_return, 0] | [undefined, w_error]>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.die = exports.remove = exports.shuffle = exports.crypto_random_int = exports.random_int = exports.crypto_random = exports.defer_many = exports.defer = exports.microtask = exports.forever = exports.with_timeout = exports.timeout_exec = exports.timeout = exports.fodemtv = exports.oderom = exports.oderaf = exports.oderac = exports.oder = exports.odem = exports.ofe = exports.ode = exports.odv = exports.odk = exports.oda = exports.oc = exports.escape_regex = exports.deduplicate = exports.interjoin = exports.fold = exports.is_dict_es = exports.is_dict = exports.is_array = exports.is_bytes = exports.pascal = exports.snake = exports.proper = exports.F_IDENTITY = exports.F_NOOP = exports.XG_32 = exports.XG_16 = exports.XG_8 = exports.__UNDEFINED = exports.ATU8_NIL = void 0; | ||
exports.collapse = exports.fold = exports.fodemtv = exports.transform_values = exports.oderom = exports.transform_object = exports.oderaf = exports.flatten_entries = exports.oderac = exports.concat_entries = exports.oder = exports.reduce_object = exports.odem = exports.map_entries = exports.ofe = exports.from_entries = exports.ode = exports.entries = exports.odv = exports.values = exports.odk = exports.keys = exports.oda = exports.assign = exports.odc = exports.create = exports.array = exports.is_error = exports.is_iterable = exports.is_dict_es = exports.is_dict = exports.is_array = exports.is_bytes = exports.is_function = exports.is_object = exports.is_symbol = exports.is_string = exports.is_bigint = exports.is_number = exports.is_boolean = exports.is_undefined = exports.narrow = exports.cast = exports.F_IDENTITY = exports.F_NOOP = exports.XG_32 = exports.XG_16 = exports.XG_8 = exports.__UNDEFINED = exports.ATU8_NIL = void 0; | ||
exports.try_async = exports.try_sync = exports.die = exports.remove = exports.shuffle = exports.random_int = exports.deduplicate = exports.interjoin = void 0; | ||
/** | ||
@@ -29,3 +30,3 @@ * Utility nil buffer constant | ||
/** | ||
* The seldomnly-used "identity" function | ||
* The "identity" function | ||
*/ | ||
@@ -35,23 +36,57 @@ const F_IDENTITY = (w) => w; // eslint-disable-line | ||
/** | ||
* Creates a proper-case string | ||
* Casts the given argument to a specific type. | ||
* @param w_value - value to cast | ||
* @returns the value casted to the target type | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types | ||
exports.cast = exports.F_IDENTITY; | ||
/** | ||
* Forces TypeScript to perform type narrowing on the given value by asserting its type | ||
* @param w_value - value to narrow | ||
* @returns `true` always | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types | ||
const narrow = (w_value) => !0; | ||
exports.narrow = narrow; | ||
/** | ||
* Equivalent to testing `'undefined' === typeof thing` | ||
*/ | ||
const proper = (s_input) => s_input ? s_input.split(/[\s_]+/g).map(s => s[0].toUpperCase() + s.slice(1)).join(' ') : s_input; | ||
exports.proper = proper; | ||
const is_undefined = (z) => (typeof z)[0] > 't'; | ||
exports.is_undefined = is_undefined; | ||
/** | ||
* Converts given identifier to "snake_case" | ||
* Equivalent to testing `'boolean' === typeof thing` | ||
*/ | ||
const snake = (s_ident) => s_ident.toUpperCase() === s_ident | ||
// depending on upper or mixed case | ||
? s_ident.toLowerCase().replace(/[^a-z0-9$]+/g, '_') | ||
: s_ident.replace(/(?<!^)(?:[^a-zA-Z0-9$]*([A-Z])|[^a-zA-Z0-9$]+)/g, (s_ignore, s_cap) => '_' + (s_cap || '')).toLowerCase(); | ||
exports.snake = snake; | ||
const is_boolean = (z) => (typeof z)[3] > 'k'; | ||
exports.is_boolean = is_boolean; | ||
/** | ||
* Converts given identifier to "PascalCase" | ||
* Equivalent to testing `'number' === typeof thing` | ||
*/ | ||
// if all uppercase; make lower | ||
const pascal = (s_ident) => (s_ident.toUpperCase() === s_ident ? (0, exports.pascal)(s_ident.toLowerCase()) : s_ident) | ||
// convert to pascal | ||
.replace(/(?:^|[^A-Za-z0-9$])([\w0-9$])/g, (s_ignore, s_letter) => s_letter.toUpperCase()); | ||
exports.pascal = pascal; | ||
const is_number = (z) => 'n' === (typeof z)[0]; | ||
exports.is_number = is_number; | ||
/** | ||
* Equivalent to testing `'bigint' === typeof thing` | ||
*/ | ||
const is_bigint = (z) => 'i' === (typeof z)[1]; | ||
exports.is_bigint = is_bigint; | ||
/** | ||
* Equivalent to testing `'string' === typeof thing` | ||
*/ | ||
const is_string = (z) => (typeof z)[2] > 'q'; | ||
exports.is_string = is_string; | ||
/** | ||
* Equivalent to testing `'symbol' === typeof thing` | ||
*/ | ||
const is_symbol = (z) => (typeof z)[1] > 'x'; | ||
exports.is_symbol = is_symbol; | ||
/** | ||
* Equivalent to testing `'object' === typeof thing` | ||
*/ | ||
const is_object = (z) => (typeof z)[1] < 'c'; | ||
exports.is_object = is_object; | ||
/** | ||
* Equivalent to testing `'function' === typeof thing` | ||
*/ | ||
const is_function = (z) => (typeof z)[4] > 's'; | ||
exports.is_function = is_function; | ||
/** | ||
* Simple test for whether a value is a Uint8Array or not | ||
@@ -69,3 +104,3 @@ */ | ||
*/ | ||
const is_dict = (z) => z ? 'object' === typeof z && !(0, exports.is_array)(z) : false; | ||
const is_dict = (z) => z ? (0, exports.is_object)(z) && !(0, exports.is_array)(z) : false; | ||
exports.is_dict = is_dict; | ||
@@ -78,14 +113,203 @@ /** | ||
/** | ||
* Fold array into an object | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
const fold = (a_in, f_fold) => { | ||
const h_out = {}; | ||
let i_each = 0; | ||
for (const z_each of a_in) { | ||
Object.assign(h_out, f_fold(z_each, i_each++)); | ||
} | ||
return h_out; | ||
}; | ||
const is_iterable = (z) => !!z?.[Symbol.iterator]; | ||
exports.is_iterable = is_iterable; | ||
/** | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
const is_error = (z) => z instanceof Error; | ||
exports.is_error = is_error; | ||
/** | ||
* Typed alias to `Array.from` | ||
*/ | ||
exports.array = Array.from; | ||
/** | ||
* Typed alias to `Object.create` | ||
*/ | ||
exports.create = Object.create; | ||
/** | ||
* @deprecated Use {@link create} instead | ||
*/ | ||
exports.odc = exports.create; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
exports.assign = Object.assign; | ||
/** | ||
* @deprecated Use {@link assign} instead | ||
*/ | ||
exports.oda = exports.create; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
exports.keys = Object.keys; | ||
/** | ||
* @deprecated Use {@link keys} instead | ||
*/ | ||
exports.odk = exports.create; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
exports.values = Object.values; | ||
/** | ||
* @deprecated Use {@link values} instead | ||
*/ | ||
exports.odv = exports.create; | ||
/** | ||
* Typed alias of `Object.entries` | ||
*/ | ||
exports.entries = Object.entries; | ||
/** | ||
* @deprecated Use {@link entries} instead | ||
*/ | ||
exports.ode = exports.entries; | ||
/** | ||
* Typed alias of `Object.fromEntries` | ||
*/ | ||
exports.from_entries = Object.fromEntries; | ||
/** | ||
* @deprecated Use {@link from_entries} instead | ||
*/ | ||
exports.ofe = exports.from_entries; | ||
/** | ||
* Map object entries. Alias of: | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).map(f_map) | ||
* ``` | ||
*/ | ||
const map_entries = (w_src, f_map) => (0, exports.entries)(w_src).map(f_map); | ||
exports.map_entries = map_entries; | ||
/** | ||
* @deprecated Use {@link map_entries} instead | ||
*/ | ||
exports.odem = exports.map_entries; | ||
/** | ||
* Reduce an object to an arbitrary type by its entries. Alias of | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).reduce(f_reduce) | ||
* ``` | ||
*/ | ||
const reduce_object = (w_src, f_reduce, w_init) => (0, exports.entries)(w_src).reduce(f_reduce, w_init); | ||
exports.reduce_object = reduce_object; | ||
/** | ||
* @deprecated Use {@link reduce_object} instead | ||
*/ | ||
exports.oder = exports.reduce_object; | ||
/** | ||
* Reduce an object's entries to an array via concatenation (with filtering) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => item` | ||
* @param b_keep_undefs - by default, `undefined` items will be ommitted from return array unless this is truthy | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
const concat_entries = (w_src, f_concat, b_keep_undefs = 0, a_out = []) => (0, exports.reduce_object)(w_src, (a_acc, [si_key, w_value], i_entry) => { | ||
// invoke callback and capture return value | ||
const w_add = f_concat(si_key, w_value, i_entry); | ||
// add result to array iff not undefined or if undefined values are explictly allowed | ||
if (exports.__UNDEFINED !== w_add || b_keep_undefs) | ||
a_acc.push(w_add); | ||
return a_acc; | ||
}, a_out); | ||
exports.concat_entries = concat_entries; | ||
/** | ||
* @deprecated Use {@link concat_entries} instead | ||
*/ | ||
exports.oderac = exports.concat_entries; | ||
/** | ||
* Reduce object entries to an array via flattening (i.e., callback return value will be spread into array) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => Iterable<item>` | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
const flatten_entries = (w_src, f_concat, a_out = []) => (0, exports.reduce_object)(w_src, (a_acc, [si_key, w_value], i_entry) => [ | ||
...a_acc, | ||
...f_concat(si_key, w_value, i_entry), | ||
], a_out); | ||
exports.flatten_entries = flatten_entries; | ||
/** | ||
* @deprecated Use {@link flatten_entries} instead | ||
*/ | ||
exports.oderaf = exports.flatten_entries; | ||
/** | ||
* Transform an object to an object by its entries via merging (i.e., callback return value will be spread into object) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_merge - callback having signature `(key, value, index) => object` | ||
* @param h_out - optionally specifies the output object to merge properties into | ||
* @returns all `item` values returned by {@link f_merge} merged into a single object | ||
*/ | ||
const transform_object = (w_src, f_merge, h_out = {}) => (0, exports.reduce_object)(w_src, (h_acc, [si_key, w_value], i_index) => ({ | ||
...h_acc, | ||
...f_merge(si_key, w_value, i_index), | ||
}), h_out); | ||
exports.transform_object = transform_object; | ||
/** | ||
* @deprecated Use {@link transform_object} instead | ||
*/ | ||
exports.oderom = exports.transform_object; | ||
/** | ||
* Transforms an object by applying the given callback to each of its values, returning a new object | ||
* with the same keys as the original object | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_transform - callback having signature `(value, key, index) => new_value` | ||
* @returns the new object | ||
*/ | ||
const transform_values = (w_src, f_transform) => (0, exports.from_entries)((0, exports.map_entries)(w_src, ([si_key, w_value], i_entry) => [si_key, f_transform(w_value, si_key, i_entry)])); | ||
exports.transform_values = transform_values; | ||
/** | ||
* @deprecated Use {@link transform_values} instead | ||
*/ | ||
exports.fodemtv = exports.transform_values; | ||
/** | ||
* Fold an array into an object via reduction, i.e., by transforming each value into an object and merging it into a single output. | ||
* | ||
* Useful when the number of output entries per input entry can vary. For 1:1 multiplicity see also {@link collapse}. | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* fold(['a', 'b', 'c'], (value, index) => ({[value]: index})) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_fold - transforming callback function with signature | ||
* ```ts | ||
* type f_fold = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @param h_out - optionally specify the output object, an existing object to merge properties into | ||
* @returns the merged output object | ||
*/ | ||
const fold = (w_in, f_fold, h_out = {}) => (0, exports.array)(w_in).reduce((h_acc, z_each, i_each) => (0, exports.assign)(h_acc, f_fold(z_each, i_each)), h_out); | ||
exports.fold = fold; | ||
/** | ||
* Collapse an array into an object by mapping its items into entries | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* collapse(['a', 'b', 'c'], (value, index) => [value, index]) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_collapse - transforming callback function with signature | ||
* ```ts | ||
* type f_collapse = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @returns the merged output object | ||
*/ | ||
const collapse = (w_in, f_collapse) => (0, exports.from_entries)((0, exports.array)(w_in).map(f_collapse)); | ||
exports.collapse = collapse; | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
@@ -99,2 +323,3 @@ */ | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
if (a_input.length) | ||
@@ -106,6 +331,9 @@ a_output.push(a_input.at(-1)); | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence. | ||
* @param z_identify - if specified and a string, identifies the key of each item to use as an identifier | ||
* if specified and a function, used as a callback to produce the comparison key | ||
* if omitted, compares items using full equality `===` | ||
* Removes duplicates from an array, keeping only the first occurrence of each value. Optionally accepts | ||
* an identity argument for deduplicating lists of objects using a key or callback function. | ||
* @param a_items - the items to deduplicate | ||
* @param z_identify - defines how to identify items in the list | ||
* - if given a string, specifes the key of each item whose value should be used to identify it | ||
* - if given a function, used as a callback to produce the comparison key | ||
* - if omitted, compares items using strict equality | ||
*/ | ||
@@ -118,7 +346,7 @@ const deduplicate = (a_items, z_identify) => { | ||
// use object property | ||
if ('string' === typeof z_identify) { | ||
if ((0, exports.is_string)(z_identify)) { | ||
a_keys = a_items.map(w => w[z_identify]); | ||
} | ||
// use identity function | ||
else if ('function' === typeof z_identify) { | ||
else if ((0, exports.is_function)(z_identify)) { | ||
a_keys = a_items.map(z_identify); | ||
@@ -149,193 +377,2 @@ } | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
const escape_regex = (s_input) => s_input.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
exports.escape_regex = escape_regex; | ||
/** | ||
* Typed alias to `Object.create` | ||
*/ | ||
exports.oc = Object.create; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
exports.oda = Object.assign; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
exports.odk = Object.keys; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
exports.odv = Object.values; | ||
/** | ||
* Typed alias to `Object.entries` | ||
*/ | ||
exports.ode = Object.entries; | ||
/** | ||
* Typed alias to `Object.fromEntries` | ||
*/ | ||
exports.ofe = Object.fromEntries; | ||
/** | ||
* Map object entries | ||
*/ | ||
const odem = (h_object, f_map) => (0, exports.ode)(h_object).map(f_map); | ||
exports.odem = odem; | ||
/** | ||
* Reduce object entries to an arbitrary type | ||
*/ | ||
const oder = (h_thing, f_reduce, w_init) => (0, exports.ode)(h_thing).reduce(f_reduce, w_init); | ||
exports.oder = oder; | ||
/** | ||
* Reduce object entries to an array via concatenation (with filtering) | ||
*/ | ||
const oderac = (h_thing, f_concat, b_add_undefs = false) => (0, exports.oder)(h_thing, (a_out, [si_key, w_value], i_entry) => { | ||
// invoke callback and capture return value | ||
const w_add = f_concat(si_key, w_value, i_entry); | ||
// add result to array iff not undefined or if undefined values are explictly allowed | ||
if (exports.__UNDEFINED !== w_add || b_add_undefs) | ||
a_out.push(w_add); | ||
return a_out; | ||
}, []); | ||
exports.oderac = oderac; | ||
/** | ||
* Reduce object entries to an array via flattening | ||
*/ | ||
const oderaf = (h_thing, f_concat) => (0, exports.oder)(h_thing, (a_out, [si_key, w_value], i_entry) => [ | ||
...a_out, | ||
...f_concat(si_key, w_value, i_entry), | ||
], []); | ||
exports.oderaf = oderaf; | ||
/** | ||
* Reduce object entries to an object via merging | ||
*/ | ||
const oderom = (h_thing, f_merge) => (0, exports.oder)(h_thing, (h_out, [si_key, w_value], i_index) => ({ | ||
...h_out, | ||
...f_merge(si_key, w_value, i_index), | ||
}), {}); | ||
exports.oderom = oderom; | ||
/** | ||
* Reduce object entries to an object via transforming value function | ||
*/ | ||
const fodemtv = (h_thing, f_transform) => (0, exports.ofe)((0, exports.odem)(h_thing, ([si_key, w_value], i_entry) => [si_key, f_transform(w_value, si_key, i_entry)])); | ||
exports.fodemtv = fodemtv; | ||
/** | ||
* Promise-based version of `setTimeout()` | ||
*/ | ||
const timeout = (xt_wait) => new Promise((fk_resolve) => { | ||
setTimeout(() => { | ||
fk_resolve(exports.__UNDEFINED); | ||
}, xt_wait); | ||
}); | ||
exports.timeout = timeout; | ||
const timeout_exec = (xt_wait, f_attempt) => new Promise((fk_resolve, fe_reject) => { | ||
// infinite | ||
if (!Number.isFinite(xt_wait)) { | ||
void f_attempt?.().then(w => fk_resolve([w, 0])).catch(e => fe_reject(e)); | ||
return; | ||
} | ||
let b_timed_out = false; | ||
// attempt callback | ||
f_attempt?.() | ||
.then((w_return) => { | ||
// already timed out | ||
if (b_timed_out) | ||
return; | ||
// cancel pending timer | ||
clearTimeout(i_pending); | ||
// resolve promise | ||
fk_resolve([w_return, 0]); | ||
}) | ||
.catch((e_attempt) => { | ||
fe_reject(e_attempt); | ||
}); | ||
// start waiting | ||
const i_pending = setTimeout(() => { | ||
// mark as timed out | ||
b_timed_out = true; | ||
// resolve promise | ||
fk_resolve([exports.__UNDEFINED, 1]); | ||
}, xt_wait); | ||
}); | ||
exports.timeout_exec = timeout_exec; | ||
const with_timeout = (g_with) => new Promise((fk_resolve, fe_reject) => { | ||
// state of completion | ||
let b_complete = false; | ||
// timer | ||
setTimeout(() => { | ||
// already completed | ||
if (b_complete) | ||
return; | ||
// now complete | ||
b_complete = true; | ||
// reject | ||
fe_reject(g_with.trip()); | ||
}, g_with.duration); | ||
// run task | ||
g_with.run().then((w_value) => { | ||
// already failed | ||
if (b_complete) | ||
return; | ||
// now complete | ||
b_complete = true; | ||
// resolve | ||
fk_resolve(w_value); | ||
}).catch(fe_reject); | ||
}); | ||
exports.with_timeout = with_timeout; | ||
/** | ||
* A Promise that never fulfills nor rejects | ||
*/ | ||
const forever = (w_type) => new Promise(exports.F_NOOP); | ||
exports.forever = forever; | ||
/** | ||
* Promse-based version of `queueMicrotask()` | ||
*/ | ||
const microtask = () => new Promise((fk_resolve) => { | ||
queueMicrotask(() => { | ||
fk_resolve(exports.__UNDEFINED); | ||
}); | ||
}); | ||
exports.microtask = microtask; | ||
const defer = () => { | ||
let fk_resolve; | ||
let fe_reject; | ||
const dp_promise = new Promise((fk, fe) => { | ||
fk_resolve = fk; | ||
fe_reject = fe; | ||
}); | ||
return [dp_promise, (w_return, e_reject) => { | ||
if (e_reject) { | ||
fe_reject(e_reject); | ||
} | ||
else { | ||
fk_resolve(w_return); | ||
} | ||
}]; | ||
}; | ||
exports.defer = defer; | ||
const defer_many = (h_input) => { | ||
const h_mapped = (0, exports.fodemtv)(h_input, () => (0, exports.defer)()); | ||
return { | ||
promises: (0, exports.fodemtv)(h_mapped, a_defer => a_defer[0]), | ||
resolve(h_resolves) { | ||
for (const si_key in h_resolves) { | ||
h_mapped[si_key]?.[1](h_resolves[si_key]); | ||
} | ||
}, | ||
reject(h_rejects) { | ||
for (const si_key in h_rejects) { | ||
h_mapped[si_key]?.[1](exports.__UNDEFINED, h_rejects[si_key]); | ||
} | ||
}, | ||
}; | ||
}; | ||
exports.defer_many = defer_many; | ||
/** | ||
* Cryptographically strong random number | ||
*/ | ||
const crypto_random = () => crypto.getRandomValues(new Uint32Array(1))[0] / (2 ** 32); | ||
exports.crypto_random = crypto_random; | ||
/** | ||
* Generate a random int within a given range | ||
@@ -351,12 +388,2 @@ */ | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
const crypto_random_int = (x_a, x_b = 0) => { | ||
const x_min = Math.floor(Math.min(x_a, x_b)); | ||
const x_max = Math.ceil(Math.max(x_a, x_b)); | ||
// confine to range | ||
return Math.floor((0, exports.crypto_random)() * (x_max - x_min)) + x_min; | ||
}; | ||
exports.crypto_random_int = crypto_random_int; | ||
/** | ||
* Shuffles an array | ||
@@ -394,5 +421,37 @@ */ | ||
const die = (s_msg, w_data) => { | ||
throw (0, exports.oda)(Error(s_msg), { data: w_data }); | ||
throw (0, exports.assign)(Error(s_msg), { data: w_data }); | ||
}; | ||
exports.die = die; | ||
/** | ||
* Synchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - synchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
const try_sync = (f_try) => { | ||
try { | ||
return [f_try(), 0]; | ||
} | ||
catch (e_fail) { | ||
return [exports.__UNDEFINED, e_fail]; | ||
} | ||
}; | ||
exports.try_sync = try_sync; | ||
/** | ||
* Asynchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - asynchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the awaited value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
const try_async = async (f_try) => { | ||
try { | ||
return [await f_try(), 0]; | ||
} | ||
catch (e_fail) { | ||
return [exports.__UNDEFINED, e_fail]; | ||
} | ||
}; | ||
exports.try_async = try_async; | ||
//# sourceMappingURL=belt.js.map |
@@ -68,5 +68,5 @@ "use strict"; | ||
// unsigned bigint | ||
(_) => (0, data_js_1.bytes_to_bigint_be)(f_bytes()), | ||
(_) => (0, data_js_1.bytes_to_biguint_be)(f_bytes()), | ||
// negative bigint | ||
(_) => -(0, data_js_1.bytes_to_bigint_be)(f_bytes()) - 1n, | ||
(_) => -(0, data_js_1.bytes_to_biguint_be)(f_bytes()) - 1n, | ||
][xc_additional](), | ||
@@ -73,0 +73,0 @@ // major type 7 |
import type { NaiveBase58, NaiveBase64, NaiveBase93, NaiveHexLower } from './strings'; | ||
import type { JsonValue } from './types'; | ||
import type { JsonValue, NaiveJsonString } from './types'; | ||
export declare const uuid_v4: () => string; | ||
type Uint8ArrayConstructorParams = [] | [length: number] | [array: ArrayLike<number> | ArrayBufferLike] | [buffer: ArrayBufferLike, byteOffset?: number, length?: number]; | ||
/** | ||
* Typed alias to `JSON.stringify` | ||
*/ | ||
export declare const stringify_json: <w_string extends string = NaiveJsonString>(w_json: JsonValue, f_replacer?: Parameters<typeof JSON.stringify>[1], z_space?: Parameters<typeof JSON.stringify>[2]) => w_string; | ||
/** | ||
* Typed alias to `JSON.parse` | ||
*/ | ||
export declare const parse_json: <w_value extends JsonValue<void | undefined> = JsonValue>(sx_json: string, f_reviver?: Parameters<typeof JSON.parse>[1]) => w_value; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export declare const parse_json_safe: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* @deprecated Use {@link parse_json_safe} instead. | ||
*/ | ||
export declare const safe_json: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles | ||
* and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted | ||
* since order matters. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
*/ | ||
export declare const canonicalize_json: <w_json extends JsonValue>(w_json: w_json) => w_json; | ||
/** | ||
* Helps reduce codesize | ||
@@ -91,3 +117,3 @@ * @param a_args | ||
/** | ||
* Encodes the given 32-bit integer in big-endian format to a new buffer. | ||
* Encodes the given 32-bit unsigned integer in big-endian format to a new buffer. | ||
* @param xg_uint | ||
@@ -98,3 +124,3 @@ * @returns | ||
/** | ||
* Decodes a 32-bit integer in big-endian format from a buffer (optionally at the given position). | ||
* Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position). | ||
* @param n_uint | ||
@@ -105,3 +131,3 @@ * @returns | ||
/** | ||
* Encodes the given bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* @param xg_value - the value to encode | ||
@@ -111,22 +137,18 @@ * @param nb_size - size of the buffer to create | ||
*/ | ||
export declare const biguint_to_bytes_be: (xg_value: bigint, nb_size?: number) => Uint8Array; | ||
/** | ||
* @deprecated Use {@link biguint_to_bytes_be} instead. | ||
*/ | ||
export declare const bigint_to_bytes_be: (xg_value: bigint, nb_size?: number) => Uint8Array; | ||
/** | ||
* Decodes a bigint in big-endian format from a buffer | ||
* Decodes an unsigned bigint in big-endian format from a buffer | ||
* @param atu8_bytes | ||
* @returns | ||
*/ | ||
export declare const bytes_to_bigint_be: (atu8_bytes: Uint8Array) => bigint; | ||
export declare const bytes_to_biguint_be: (atu8_bytes: Uint8Array) => bigint; | ||
/** | ||
* Converts a JSON object into its canonical form. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
* @deprecated Use {@link bytes_to_biguint_be} instead. | ||
*/ | ||
export declare const canonicalize_json: <w_json extends JsonValue>(w_json: w_json) => w_json; | ||
export declare const bytes_to_bigint_be: (atu8_bytes: Uint8Array) => bigint; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export declare const safe_json: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* Concatenate a sequence of Uint8Arrays. | ||
@@ -200,2 +222,10 @@ * @param a_buffers the data to concatenate in order | ||
export declare const base58_to_bytes: (sb58_buffer: string) => Uint8Array; | ||
/** | ||
* Cryptographically strong random number in the range [0, 1) | ||
*/ | ||
export declare const crypto_random: () => number; | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export declare const crypto_random_int: (x_a: number, x_b?: number) => number; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.base58_to_bytes = exports.bytes_to_base58 = exports.base93_to_bytes = exports.bytes_to_base93 = exports.string8_to_bytes = exports.base64_to_bytes = exports.bytes_to_base64 = exports.base64_to_bytes_slim = exports.bytes_to_base64_slim = exports.hex_to_bytes = exports.bytes_to_hex = exports.concat2 = exports.concat = exports.safe_json = exports.canonicalize_json = exports.bytes_to_bigint_be = exports.bigint_to_bytes_be = exports.bytes_to_uint32_be = exports.uint32_to_bytes_be = exports.bytes_to_json = exports.json_to_bytes = exports.text_to_base64 = exports.base64_to_text = exports.bytes_to_text = exports.text_to_bytes = exports.decode_length_prefix_u16 = exports.encode_length_prefix_u16 = exports.zero_out = exports.hmac = exports.sha512 = exports.sha384 = exports.sha256d = exports.sha256 = exports.dataview = exports.bytes = exports.uuid_v4 = void 0; | ||
exports.crypto_random_int = exports.crypto_random = exports.base58_to_bytes = exports.bytes_to_base58 = exports.base93_to_bytes = exports.bytes_to_base93 = exports.string8_to_bytes = exports.base64_to_bytes = exports.bytes_to_base64 = exports.base64_to_bytes_slim = exports.bytes_to_base64_slim = exports.hex_to_bytes = exports.bytes_to_hex = exports.concat2 = exports.concat = exports.bytes_to_bigint_be = exports.bytes_to_biguint_be = exports.bigint_to_bytes_be = exports.biguint_to_bytes_be = exports.bytes_to_uint32_be = exports.uint32_to_bytes_be = exports.bytes_to_json = exports.json_to_bytes = exports.text_to_base64 = exports.base64_to_text = exports.bytes_to_text = exports.text_to_bytes = exports.decode_length_prefix_u16 = exports.encode_length_prefix_u16 = exports.zero_out = exports.hmac = exports.sha512 = exports.sha384 = exports.sha256d = exports.sha256 = exports.dataview = exports.bytes = exports.canonicalize_json = exports.safe_json = exports.parse_json_safe = exports.parse_json = exports.stringify_json = exports.uuid_v4 = void 0; | ||
const belt_js_1 = require("./belt.js"); | ||
@@ -21,2 +21,47 @@ // eslint-disable-next-line @typescript-eslint/naming-convention | ||
/** | ||
* Typed alias to `JSON.stringify` | ||
*/ | ||
exports.stringify_json = JSON.stringify; | ||
/** | ||
* Typed alias to `JSON.parse` | ||
*/ | ||
exports.parse_json = JSON.parse; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
const parse_json_safe = (sx_json) => (0, belt_js_1.try_sync)(_ => (0, exports.parse_json)(sx_json))[0]; | ||
exports.parse_json_safe = parse_json_safe; | ||
/** | ||
* @deprecated Use {@link parse_json_safe} instead. | ||
*/ | ||
exports.safe_json = exports.parse_json_safe; | ||
/** | ||
* Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles | ||
* and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted | ||
* since order matters. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
*/ | ||
const canonicalize_json = (w_json) => { | ||
// JSON object | ||
if ((0, belt_js_1.is_dict_es)(w_json)) { | ||
// sort all keys | ||
const h_sorted = (0, belt_js_1.from_entries)((0, belt_js_1.entries)(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1)); | ||
// traverse on children | ||
for (const si_key in h_sorted) { | ||
h_sorted[si_key] = (0, exports.canonicalize_json)(h_sorted[si_key]); | ||
} | ||
w_json = h_sorted; | ||
} | ||
// JSON array | ||
else if ((0, belt_js_1.is_array)(w_json)) { | ||
w_json = w_json.map(w_item => (0, exports.canonicalize_json)(w_item)); | ||
} | ||
// boolean, number, string, or null | ||
return w_json; | ||
}; | ||
exports.canonicalize_json = canonicalize_json; | ||
/** | ||
* Helps reduce codesize | ||
@@ -93,3 +138,3 @@ * @param a_args | ||
if (0 !== atu8_data.reduce((c_sum, x_value) => c_sum + x_value, 0)) | ||
throw new Error('Failed to zero out sensitive memory region'); | ||
(0, belt_js_1.die)('Failed to zero out sensitive memory region'); | ||
}; | ||
@@ -149,3 +194,3 @@ exports.zero_out = zero_out; | ||
*/ | ||
const json_to_bytes = (w_json) => (0, exports.text_to_bytes)(JSON.stringify(w_json)); | ||
const json_to_bytes = (w_json) => (0, exports.text_to_bytes)((0, exports.stringify_json)(w_json)); | ||
exports.json_to_bytes = json_to_bytes; | ||
@@ -157,6 +202,6 @@ /** | ||
*/ | ||
const bytes_to_json = (atu8_json) => JSON.parse((0, exports.bytes_to_text)(atu8_json)); | ||
const bytes_to_json = (atu8_json) => (0, exports.parse_json)((0, exports.bytes_to_text)(atu8_json)); | ||
exports.bytes_to_json = bytes_to_json; | ||
/** | ||
* Encodes the given 32-bit integer in big-endian format to a new buffer. | ||
* Encodes the given 32-bit unsigned integer in big-endian format to a new buffer. | ||
* @param xg_uint | ||
@@ -175,3 +220,3 @@ * @returns | ||
/** | ||
* Decodes a 32-bit integer in big-endian format from a buffer (optionally at the given position). | ||
* Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position). | ||
* @param n_uint | ||
@@ -183,3 +228,3 @@ * @returns | ||
/** | ||
* Encodes the given bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* @param xg_value - the value to encode | ||
@@ -189,3 +234,3 @@ * @param nb_size - size of the buffer to create | ||
*/ | ||
const bigint_to_bytes_be = (xg_value, nb_size = 32) => { | ||
const biguint_to_bytes_be = (xg_value, nb_size = 32) => { | ||
// prep buffer of the appropriate size | ||
@@ -200,44 +245,19 @@ let atu8_out = (0, exports.bytes)(nb_size); | ||
}; | ||
exports.bigint_to_bytes_be = bigint_to_bytes_be; | ||
exports.biguint_to_bytes_be = biguint_to_bytes_be; | ||
/** | ||
* Decodes a bigint in big-endian format from a buffer | ||
* @deprecated Use {@link biguint_to_bytes_be} instead. | ||
*/ | ||
exports.bigint_to_bytes_be = exports.biguint_to_bytes_be; | ||
/** | ||
* Decodes an unsigned bigint in big-endian format from a buffer | ||
* @param atu8_bytes | ||
* @returns | ||
*/ | ||
const bytes_to_bigint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << belt_js_1.XG_8) | BigInt(xb_value), 0n); | ||
exports.bytes_to_bigint_be = bytes_to_bigint_be; | ||
const bytes_to_biguint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << belt_js_1.XG_8) | BigInt(xb_value), 0n); | ||
exports.bytes_to_biguint_be = bytes_to_biguint_be; | ||
/** | ||
* Converts a JSON object into its canonical form. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
* @deprecated Use {@link bytes_to_biguint_be} instead. | ||
*/ | ||
const canonicalize_json = (w_json) => { | ||
if ((0, belt_js_1.is_dict_es)(w_json)) { | ||
// sort all keys | ||
const h_sorted = (0, belt_js_1.ofe)((0, belt_js_1.ode)(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1)); | ||
// traverse on children | ||
for (const si_key in h_sorted) { | ||
h_sorted[si_key] = (0, exports.canonicalize_json)(h_sorted[si_key]); | ||
} | ||
w_json = h_sorted; | ||
} | ||
else if ((0, belt_js_1.is_array)(w_json)) { | ||
w_json = w_json.map(w_item => (0, exports.canonicalize_json)(w_item)); | ||
} | ||
return w_json; | ||
}; | ||
exports.canonicalize_json = canonicalize_json; | ||
exports.bytes_to_bigint_be = exports.bytes_to_biguint_be; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
const safe_json = (sx_json) => { | ||
try { | ||
return JSON.parse(sx_json); | ||
} | ||
catch (e_parse) { } | ||
}; | ||
exports.safe_json = safe_json; | ||
/** | ||
* Concatenate a sequence of Uint8Arrays. | ||
@@ -366,3 +386,3 @@ * @param a_buffers the data to concatenate in order | ||
if (-1 === xb_char) | ||
throw new Error('Invalid base64 string'); | ||
(0, belt_js_1.die)('Invalid base64 string'); | ||
// add 6 bits from index to buffer | ||
@@ -385,3 +405,3 @@ xb_work = (xb_work << 6) | xb_char; | ||
} | ||
return new Uint8Array(a_out); | ||
return (0, exports.bytes)(a_out); | ||
}; | ||
@@ -456,3 +476,3 @@ exports.base64_to_bytes = base64_to_bytes; | ||
if (-1 === xb_char) | ||
throw new Error('Invalid base93 string'); | ||
(0, belt_js_1.die)('Invalid base93 string'); | ||
if (-1 === xb_work) { | ||
@@ -517,8 +537,8 @@ xb_work = xb_char; | ||
const base58_to_bytes = (sb58_buffer) => { | ||
if (!sb58_buffer || 'string' !== typeof sb58_buffer) { | ||
throw new Error(`Expected base58 string but got “${sb58_buffer}”`); | ||
if (!sb58_buffer || !(0, belt_js_1.is_string)(sb58_buffer)) { | ||
(0, belt_js_1.die)(`Expected base58 string but got “${sb58_buffer}”`); | ||
} | ||
const m_invalid = sb58_buffer.match(/[IOl0]/gmu); | ||
if (m_invalid) { | ||
throw new Error(`Invalid base58 character “${String(m_invalid)}”`); | ||
(0, belt_js_1.die)(`Invalid base58 character “${String(m_invalid)}”`); | ||
} | ||
@@ -543,2 +563,17 @@ const m_lz = sb58_buffer.match(/^1+/gmu); | ||
exports.base58_to_bytes = base58_to_bytes; | ||
/** | ||
* Cryptographically strong random number in the range [0, 1) | ||
*/ | ||
const crypto_random = () => crypto.getRandomValues((0, exports.bytes)(1))[0] / (2 ** 32); | ||
exports.crypto_random = crypto_random; | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
const crypto_random_int = (x_a, x_b = 0) => { | ||
const x_min = Math.floor(Math.min(x_a, x_b)); | ||
const x_max = Math.ceil(Math.max(x_a, x_b)); | ||
// confine to range | ||
return Math.floor((0, exports.crypto_random)() * (x_max - x_min)) + x_min; | ||
}; | ||
exports.crypto_random_int = crypto_random_int; | ||
//# sourceMappingURL=data.js.map |
@@ -0,1 +1,2 @@ | ||
import type { NoInfer } from 'ts-toolbelt/out/Function/_api'; | ||
import type { Subtype } from './types'; | ||
@@ -46,2 +47,26 @@ /** | ||
export type NaiveHexMixed<s_subtype extends string = string> = Subtype<HexMethods & s_subtype, 'hex-lower' | 'hex-upper'>; | ||
/** | ||
* Creates a proper-case string, returning `undefined` if given `undefined | ||
* @param s_input - any text to transform | ||
* @returns the transformed text in "Proper case" | ||
*/ | ||
export declare const proper: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_input: s_input) => NoInfer<z_output>; | ||
/** | ||
* Converts given identifier to "snake_case", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "snake_case" | ||
*/ | ||
export declare const snake: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_ident: s_input) => NoInfer<z_output>; | ||
/** | ||
* Converts given identifier to "PascalCase", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "PascalCase" | ||
*/ | ||
export declare const pascal: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_ident: s_input) => NoInfer<z_output>; | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
export declare const escape_regex: (s_input: string) => string; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.escape_regex = exports.pascal = exports.snake = exports.proper = void 0; | ||
/** | ||
* Creates a proper-case string, returning `undefined` if given `undefined | ||
* @param s_input - any text to transform | ||
* @returns the transformed text in "Proper case" | ||
*/ | ||
const proper = (s_input) => s_input?.split(/[\s_]+/g).map(s => s ? s[0].toUpperCase() + s.slice(1) : '').join(' '); | ||
exports.proper = proper; | ||
/** | ||
* Converts given identifier to "snake_case", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "snake_case" | ||
*/ | ||
const snake = (s_ident) => (s_ident | ||
? s_ident.toUpperCase() === s_ident | ||
// depending on upper or mixed case | ||
? s_ident.toLowerCase().replace(/[^a-z0-9$]+/g, '_') | ||
: s_ident.replace(/(?<!^)(?:[^a-zA-Z0-9$]*([A-Z])|[^a-zA-Z0-9$]+)/g, (s_ignore, s_cap) => '_' + (s_cap || '')).toLowerCase() | ||
: s_ident); | ||
exports.snake = snake; | ||
/** | ||
* Converts given identifier to "PascalCase", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "PascalCase" | ||
*/ | ||
const pascal = (s_ident) => (s_ident | ||
// if all uppercase; make lower | ||
? (/^([^A-Za-z]*[A-Z]+)+([^A-Za-z])?$/.test(s_ident) ? (0, exports.pascal)(s_ident.toLowerCase()) : s_ident) | ||
// convert to pascal | ||
.replace(/(?:^|[^A-Za-z0-9$])([\w0-9$]|$)/g, (s_ignore, s_letter) => s_letter.toUpperCase()).trim() | ||
: s_ident); | ||
exports.pascal = pascal; | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
const escape_regex = (s_input) => s_input.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
exports.escape_regex = escape_regex; | ||
//# sourceMappingURL=strings.js.map |
@@ -5,2 +5,10 @@ import type { A, U } from 'ts-toolbelt'; | ||
/** | ||
* Test whether a given type value is the `any` type. Returns `1` if true, `0` otherwise | ||
*/ | ||
export type IsLiteralAny<w_test> = 0 extends (1 & w_test) ? 1 : 0; | ||
/** | ||
* If the given type value is the `any` type, use the given substitute type instead | ||
*/ | ||
export type InsteadOfAny<w_test, w_instead> = 0 extends (1 & w_test) ? w_instead : w_test; | ||
/** | ||
* Create subtype on any type using intersection. Can be removed later using {@link Unsubtype} | ||
@@ -56,2 +64,18 @@ */ | ||
/** | ||
* Types that can be accessed via index operator, and that work with `Object.entries()` | ||
*/ | ||
export type KeyValuable = Record<any, any> | ArrayLike<any>; | ||
/** | ||
* Returns the keys of the given type, returning`${bigint}` for Array since its keys satisfy `${bigint}` | ||
*/ | ||
export type KeysOf<w_type> = w_type extends ArrayLike<any> ? `${bigint}` : w_type extends JsonObject ? string : w_type extends Record<infer s_key, any> ? s_key : never; | ||
/** | ||
* Returns the values of the given type, extracting the values of an Array, or the properties of an Object. | ||
*/ | ||
export type ValuesOf<w_type> = w_type extends ArrayLike<infer w_value> ? w_value : w_type[keyof w_type]; | ||
/** | ||
* Union of all TypedArray types | ||
*/ | ||
export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; | ||
/** | ||
* JSON string | ||
@@ -63,5 +87,5 @@ */ | ||
*/ | ||
export interface JsonObject<w_inject extends any = never> { | ||
export type JsonObject<w_inject extends any = never> = { | ||
[k: string]: JsonValue<w_inject>; | ||
} | ||
}; | ||
/** | ||
@@ -68,0 +92,0 @@ * Union of "valuable", primitive JSON value types |
@@ -6,6 +6,2 @@ "use strict"; | ||
exports.ES_TYPE = Symbol('es-type'); | ||
/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars */ | ||
{ | ||
const test = {}; | ||
} | ||
//# sourceMappingURL=types.js.map |
@@ -1,2 +0,2 @@ | ||
import type { Dict, JsonObject } from './types'; | ||
import type { InsteadOfAny, JsonObject, KeyValuable, KeysOf, Promisable, TypedArray, ValuesOf } from './types'; | ||
/** | ||
@@ -24,18 +24,50 @@ * Utility nil buffer constant | ||
/** | ||
* The seldomnly-used "identity" function | ||
* The "identity" function | ||
*/ | ||
export declare const F_IDENTITY: (w: any) => any; | ||
export declare const F_IDENTITY: <w_type>(w: w_type) => w_type; | ||
/** | ||
* Creates a proper-case string | ||
* Casts the given argument to a specific type. | ||
* @param w_value - value to cast | ||
* @returns the value casted to the target type | ||
*/ | ||
export declare const cast: <w_to>(w_value: any) => w_to; | ||
/** | ||
* Forces TypeScript to perform type narrowing on the given value by asserting its type | ||
* @param w_value - value to narrow | ||
* @returns `true` always | ||
*/ | ||
export declare const narrow: <w_to>(w_value: any) => w_value is w_to; | ||
/** | ||
* Equivalent to testing `'undefined' === typeof thing` | ||
*/ | ||
export declare const proper: (s_input: string) => string; | ||
export declare const is_undefined: (z: unknown) => z is undefined; | ||
/** | ||
* Converts given identifier to "snake_case" | ||
* Equivalent to testing `'boolean' === typeof thing` | ||
*/ | ||
export declare const snake: (s_ident: string) => string; | ||
export declare const is_boolean: (z: unknown) => z is boolean; | ||
/** | ||
* Converts given identifier to "PascalCase" | ||
* Equivalent to testing `'number' === typeof thing` | ||
*/ | ||
export declare const pascal: (s_ident: string) => string; | ||
export declare const is_number: (z: unknown) => z is number; | ||
/** | ||
* Equivalent to testing `'bigint' === typeof thing` | ||
*/ | ||
export declare const is_bigint: (z: unknown) => z is bigint; | ||
/** | ||
* Equivalent to testing `'string' === typeof thing` | ||
*/ | ||
export declare const is_string: (z: unknown) => z is string; | ||
/** | ||
* Equivalent to testing `'symbol' === typeof thing` | ||
*/ | ||
export declare const is_symbol: (z: unknown) => z is symbol; | ||
/** | ||
* Equivalent to testing `'object' === typeof thing` | ||
*/ | ||
export declare const is_object: (z: unknown) => z is object; | ||
/** | ||
* Equivalent to testing `'function' === typeof thing` | ||
*/ | ||
export declare const is_function: (z: unknown) => z is Function; | ||
/** | ||
* Simple test for whether a value is a Uint8Array or not | ||
@@ -51,106 +83,200 @@ */ | ||
*/ | ||
export declare const is_dict: (z: unknown) => z is JsonObject<never>; | ||
export declare const is_dict: (z: unknown) => z is JsonObject; | ||
/** | ||
* Strict test for whether an ES object is a plain object (dict) or not | ||
*/ | ||
export declare const is_dict_es: (z: unknown) => z is JsonObject<never>; | ||
export declare const is_dict_es: (z: unknown) => z is JsonObject; | ||
/** | ||
* Fold array into an object | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export declare const fold: <w_out, w_value>(a_in: Iterable<w_value>, f_fold: (z_value: w_value, i_each: number) => Dict<w_out>) => Dict<w_out>; | ||
export declare const is_iterable: <w_type = unknown>(z: unknown) => z is Iterable<w_type>; | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export declare const interjoin: <w_item extends unknown, w_insert extends unknown>(a_input: w_item[], w_insert: w_insert) => (w_item | w_insert)[]; | ||
export declare const is_error: <h_extend extends object>(z: unknown) => z is Error & h_extend; | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence. | ||
* @param z_identify - if specified and a string, identifies the key of each item to use as an identifier | ||
* if specified and a function, used as a callback to produce the comparison key | ||
* if omitted, compares items using full equality `===` | ||
* Typed alias to `Array.from` | ||
*/ | ||
export declare const deduplicate: <z_item extends unknown, s_key extends keyof z_item = keyof z_item>(a_items: z_item[], z_identify?: s_key | ((z_item: z_item) => any) | undefined) => z_item[]; | ||
export declare const array: <w_value>(a_in: Iterable<w_value>) => w_value[]; | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
* Typed alias to `Object.create` | ||
*/ | ||
export declare const escape_regex: (s_input: string) => string; | ||
export declare const create: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.create` | ||
* @deprecated Use {@link create} instead | ||
*/ | ||
export declare const oc: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
export declare const odc: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
export declare const oda: <h_object extends {}, h_extend extends {}>(h_object: h_object, h_extend: h_extend) => h_object & h_extend; | ||
export declare const assign: <h_object extends {}, h_extend extends {}>(h_object: h_object, h_extend: h_extend) => h_object & h_extend; | ||
/** | ||
* @deprecated Use {@link assign} instead | ||
*/ | ||
export declare const oda: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
export declare const odk: <si_key extends string, w_value extends any>(h_object: Record<si_key, w_value>) => si_key[]; | ||
export declare const keys: <w_src extends KeyValuable>(w_src: w_src) => KeysOf<w_src>[]; | ||
/** | ||
* @deprecated Use {@link keys} instead | ||
*/ | ||
export declare const odk: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
export declare const odv: <w_value extends any>(h_object: Record<any, w_value>) => w_value[]; | ||
export declare const values: <w_src extends KeyValuable, z_values = ValuesOf<w_src>>(w_src: w_src) => z_values[]; | ||
/** | ||
* Typed alias to `Object.entries` | ||
* @deprecated Use {@link values} instead | ||
*/ | ||
export declare const ode: <si_key extends string, w_value extends any>(h_object: Record<si_key, w_value>) => [si_key, w_value][]; | ||
export declare const odv: <h_source extends object | null>(h_object: h_source, gc_props?: PropertyDescriptorMap) => object; | ||
/** | ||
* Typed alias to `Object.fromEntries` | ||
* Typed alias of `Object.entries` | ||
*/ | ||
export declare const ofe: <as_keys extends string, w_values extends any>(a_entries: Iterable<[as_keys, w_values]>) => Record<as_keys, w_values>; | ||
export declare const entries: <w_src extends KeyValuable, z_keys extends PropertyKey = KeysOf<w_src>, z_values = ValuesOf<w_src>>(w_src: w_src) => [z_keys, z_values][]; | ||
/** | ||
* Map object entries | ||
* @deprecated Use {@link entries} instead | ||
*/ | ||
export declare const odem: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_object: Record<si_key, w_value>, f_map: (g_entry: [si_key, w_value], i_index: number, a_all: [si_key, w_value][]) => w_out) => w_out[]; | ||
export declare const ode: <w_src extends KeyValuable, z_keys extends PropertyKey = KeysOf<w_src>, z_values = ValuesOf<w_src>>(w_src: w_src) => [z_keys, z_values][]; | ||
/** | ||
* Reduce object entries to an arbitrary type | ||
* Typed alias of `Object.fromEntries` | ||
*/ | ||
export declare const oder: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_reduce: (w_prev: w_out, g_entry: [si_key, w_value], i_index: number, a_all: [si_key, w_value][]) => w_out, w_init: w_out) => w_out; | ||
export declare const from_entries: <as_keys extends PropertyKey, w_values extends any>(a_entries: Iterable<readonly [as_keys, w_values]>) => Record<as_keys, w_values>; | ||
/** | ||
* Reduce object entries to an array via concatenation (with filtering) | ||
* @deprecated Use {@link from_entries} instead | ||
*/ | ||
export declare const oderac: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_concat: (si_key: si_key, w_value: w_value, i_entry: number) => w_out, b_add_undefs?: boolean) => w_out[]; | ||
export declare const ofe: <as_keys extends PropertyKey, w_values extends unknown>(a_entries: Iterable<readonly [as_keys, w_values]>) => Record<as_keys, w_values>; | ||
/** | ||
* Reduce object entries to an array via flattening | ||
* Map object entries. Alias of: | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).map(f_map) | ||
* ``` | ||
*/ | ||
export declare const oderaf: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_concat: (si_key: si_key, w_value: w_value, i_entry: number) => w_out[]) => w_out[]; | ||
export declare const map_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_map: (a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out) => w_out[]; | ||
/** | ||
* Reduce object entries to an object via merging | ||
* @deprecated Use {@link map_entries} instead | ||
*/ | ||
export declare const oderom: <w_value_out extends unknown, si_key_in extends string, w_value_in extends unknown, si_key_out extends string>(h_thing: Record<si_key_in, w_value_in>, f_merge: (si_key: si_key_in, w_value: w_value_in, i_index: number) => Record<si_key_in, w_value_out>) => Record<si_key_out, w_value_out>; | ||
export declare const odem: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_map: (a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out) => w_out[]; | ||
/** | ||
* Reduce object entries to an object via transforming value function | ||
* Reduce an object to an arbitrary type by its entries. Alias of | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).reduce(f_reduce) | ||
* ``` | ||
*/ | ||
export declare const fodemtv: <w_out extends unknown, si_key extends string, w_value extends unknown>(h_thing: Record<si_key, w_value>, f_transform: (w_value: w_value, si_key: si_key, i_entry: number) => w_out) => { [si_key_out in keyof Record<si_key, w_value>]: w_out; }; | ||
export declare const reduce_object: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_reduce: (w_prev: w_out, a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out, w_init: w_out) => w_out; | ||
/** | ||
* Promise-based version of `setTimeout()` | ||
* @deprecated Use {@link reduce_object} instead | ||
*/ | ||
export declare const timeout: (xt_wait: number) => Promise<void>; | ||
export declare const timeout_exec: <w_return extends unknown = any>(xt_wait: number, f_attempt?: (() => Promise<w_return>) | undefined) => Promise<[w_return | undefined, 0 | 1]>; | ||
export interface WithTimeoutConfig<w_value extends any> { | ||
duration: number; | ||
trip: () => void; | ||
run: () => Promise<w_value>; | ||
} | ||
export declare const with_timeout: <w_value extends unknown>(g_with: WithTimeoutConfig<w_value>) => Promise<w_value>; | ||
export declare const oder: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_reduce: (w_prev: w_out, a_entry: [z_keys, z_values], i_index: number, a_all: [z_keys, z_values][]) => w_out, w_init: w_out) => w_out; | ||
/** | ||
* A Promise that never fulfills nor rejects | ||
* Reduce an object's entries to an array via concatenation (with filtering) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => item` | ||
* @param b_keep_undefs - by default, `undefined` items will be ommitted from return array unless this is truthy | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export declare const forever: <w_type = void>(w_type?: w_type | undefined) => Promise<w_type>; | ||
export declare const concat_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => w_out, b_keep_undefs?: 0 | 1 | boolean | undefined, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Promse-based version of `queueMicrotask()` | ||
* @deprecated Use {@link concat_entries} instead | ||
*/ | ||
export declare const microtask: () => Promise<void>; | ||
export declare const defer: <w_return extends unknown = any>() => [Promise<w_return>, (w_return: w_return, e_reject?: Error) => void]; | ||
export declare const defer_many: <h_input extends Dict<unknown>>(h_input: h_input) => { | ||
promises: { [si_each in keyof h_input]: Promise<h_input[si_each]>; }; | ||
resolve(h_resolves: { [si_each_1 in keyof h_input]?: h_input[si_each_1]; }): void; | ||
reject(h_rejects: { [si_each_2 in keyof h_input]?: Error; }): void; | ||
}; | ||
export declare const oderac: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => w_out, b_keep_undefs?: 0 | 1 | boolean | undefined, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Cryptographically strong random number | ||
* Reduce object entries to an array via flattening (i.e., callback return value will be spread into array) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => Iterable<item>` | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export declare const crypto_random: () => number; | ||
export declare const flatten_entries: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => Iterable<w_out>, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* @deprecated Use {@link flatten_entries} instead | ||
*/ | ||
export declare const oderaf: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_concat: (si_key: z_keys, w_value: z_values, i_entry: number) => Iterable<w_out>, a_out?: w_out[]) => w_out[]; | ||
/** | ||
* Transform an object to an object by its entries via merging (i.e., callback return value will be spread into object) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_merge - callback having signature `(key, value, index) => object` | ||
* @param h_out - optionally specifies the output object to merge properties into | ||
* @returns all `item` values returned by {@link f_merge} merged into a single object | ||
*/ | ||
export declare const transform_object: <h_out extends object, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_merge: (si_key: z_keys, w_value: z_values, i_index: number) => h_out, h_out?: h_out) => h_out; | ||
/** | ||
* @deprecated Use {@link transform_object} instead | ||
*/ | ||
export declare const oderom: <h_out extends object, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_merge: (si_key: z_keys, w_value: z_values, i_index: number) => h_out, h_out?: h_out) => h_out; | ||
/** | ||
* Transforms an object by applying the given callback to each of its values, returning a new object | ||
* with the same keys as the original object | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_transform - callback having signature `(value, key, index) => new_value` | ||
* @returns the new object | ||
*/ | ||
export declare const transform_values: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_transform: (w_value: z_values, si_key: z_keys, i_entry: number) => w_out) => { [si_key_out in z_keys]: w_out; }; | ||
/** | ||
* @deprecated Use {@link transform_values} instead | ||
*/ | ||
export declare const fodemtv: <w_out extends unknown, w_src extends KeyValuable = KeyValuable, z_keys extends KeysOf<w_src> = KeysOf<w_src>, z_values extends ValuesOf<w_src> = ValuesOf<w_src>>(w_src: w_src, f_transform: (w_value: z_values, si_key: z_keys, i_entry: number) => w_out) => { [si_key_out in z_keys]: w_out; }; | ||
/** | ||
* Fold an array into an object via reduction, i.e., by transforming each value into an object and merging it into a single output. | ||
* | ||
* Useful when the number of output entries per input entry can vary. For 1:1 multiplicity see also {@link collapse}. | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* fold(['a', 'b', 'c'], (value, index) => ({[value]: index})) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_fold - transforming callback function with signature | ||
* ```ts | ||
* type f_fold = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @param h_out - optionally specify the output object, an existing object to merge properties into | ||
* @returns the merged output object | ||
*/ | ||
export declare const fold: <w_value, z_keys extends PropertyKey = string, w_out = any, h_output extends Record<z_keys, w_out> | undefined = Record<z_keys, w_out> | undefined, h_returned extends Record<z_keys, w_out> = Record<z_keys, w_out>, h_dest = undefined extends h_output ? h_returned : h_output>(w_in: Iterable<w_value>, f_fold: (z_value: w_value, i_each: number) => h_returned, h_out?: h_output) => h_dest; | ||
/** | ||
* Collapse an array into an object by mapping its items into entries | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* collapse(['a', 'b', 'c'], (value, index) => [value, index]) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_collapse - transforming callback function with signature | ||
* ```ts | ||
* type f_collapse = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @returns the merged output object | ||
*/ | ||
export declare const collapse: <w_value, z_keys extends PropertyKey = string, z_values = any>(w_in: Iterable<w_value>, f_collapse: (z_value: w_value, i_each: number) => [z_keys, z_values]) => Record<z_keys, z_values>; | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
*/ | ||
export declare const interjoin: <w_item extends unknown, w_insert extends unknown>(a_input: w_item[], w_insert: w_insert) => (w_item | w_insert)[]; | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence of each value. Optionally accepts | ||
* an identity argument for deduplicating lists of objects using a key or callback function. | ||
* @param a_items - the items to deduplicate | ||
* @param z_identify - defines how to identify items in the list | ||
* - if given a string, specifes the key of each item whose value should be used to identify it | ||
* - if given a function, used as a callback to produce the comparison key | ||
* - if omitted, compares items using strict equality | ||
*/ | ||
export declare const deduplicate: <z_item extends unknown, s_key extends keyof z_item = keyof z_item>(a_items: z_item[], z_identify?: s_key | ((z_item: z_item) => any) | undefined) => z_item[]; | ||
/** | ||
* Generate a random int within a given range | ||
@@ -160,7 +286,2 @@ */ | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export declare const crypto_random_int: (x_a: number, x_b?: number) => number; | ||
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; | ||
/** | ||
* Shuffles an array | ||
@@ -182,2 +303,17 @@ */ | ||
export declare const die: (s_msg: string, w_data?: unknown) => never; | ||
export {}; | ||
/** | ||
* Synchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - synchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export declare const try_sync: <w_return, w_error>(f_try: (_?: void | undefined) => w_return) => [w_return, 0] | [undefined, InsteadOfAny<w_error, unknown>]; | ||
/** | ||
* Asynchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - asynchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the awaited value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export declare const try_async: <w_error, w_return>(f_try: () => Promisable<w_return>) => Promise<[w_return, 0] | [undefined, w_error]>; |
@@ -1,2 +0,1 @@ | ||
import { ok } from 'assert'; | ||
/** | ||
@@ -26,24 +25,52 @@ * Utility nil buffer constant | ||
/** | ||
* The seldomnly-used "identity" function | ||
* The "identity" function | ||
*/ | ||
export const F_IDENTITY = (w) => w; // eslint-disable-line | ||
/** | ||
* Creates a proper-case string | ||
* Casts the given argument to a specific type. | ||
* @param w_value - value to cast | ||
* @returns the value casted to the target type | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types | ||
export const cast = F_IDENTITY; | ||
/** | ||
* Forces TypeScript to perform type narrowing on the given value by asserting its type | ||
* @param w_value - value to narrow | ||
* @returns `true` always | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types | ||
export const narrow = (w_value) => !0; | ||
/** | ||
* Equivalent to testing `'undefined' === typeof thing` | ||
*/ | ||
export const proper = (s_input) => s_input ? s_input.split(/[\s_]+/g).map(s => s[0].toUpperCase() + s.slice(1)).join(' ') : s_input; | ||
export const is_undefined = (z) => (typeof z)[0] > 't'; | ||
/** | ||
* Converts given identifier to "snake_case" | ||
* Equivalent to testing `'boolean' === typeof thing` | ||
*/ | ||
export const snake = (s_ident) => s_ident.toUpperCase() === s_ident | ||
// depending on upper or mixed case | ||
? s_ident.toLowerCase().replace(/[^a-z0-9$]+/g, '_') | ||
: s_ident.replace(/(?<!^)(?:[^a-zA-Z0-9$]*([A-Z])|[^a-zA-Z0-9$]+)/g, (s_ignore, s_cap) => '_' + (s_cap || '')).toLowerCase(); | ||
export const is_boolean = (z) => (typeof z)[3] > 'k'; | ||
/** | ||
* Converts given identifier to "PascalCase" | ||
* Equivalent to testing `'number' === typeof thing` | ||
*/ | ||
// if all uppercase; make lower | ||
export const pascal = (s_ident) => (s_ident.toUpperCase() === s_ident ? pascal(s_ident.toLowerCase()) : s_ident) | ||
// convert to pascal | ||
.replace(/(?:^|[^A-Za-z0-9$])([\w0-9$])/g, (s_ignore, s_letter) => s_letter.toUpperCase()); | ||
export const is_number = (z) => 'n' === (typeof z)[0]; | ||
/** | ||
* Equivalent to testing `'bigint' === typeof thing` | ||
*/ | ||
export const is_bigint = (z) => 'i' === (typeof z)[1]; | ||
/** | ||
* Equivalent to testing `'string' === typeof thing` | ||
*/ | ||
export const is_string = (z) => (typeof z)[2] > 'q'; | ||
/** | ||
* Equivalent to testing `'symbol' === typeof thing` | ||
*/ | ||
export const is_symbol = (z) => (typeof z)[1] > 'x'; | ||
/** | ||
* Equivalent to testing `'object' === typeof thing` | ||
*/ | ||
export const is_object = (z) => (typeof z)[1] < 'c'; | ||
/** | ||
* Equivalent to testing `'function' === typeof thing` | ||
*/ | ||
export const is_function = (z) => (typeof z)[4] > 's'; | ||
/** | ||
* Simple test for whether a value is a Uint8Array or not | ||
@@ -59,3 +86,3 @@ */ | ||
*/ | ||
export const is_dict = (z) => z ? 'object' === typeof z && !is_array(z) : false; | ||
export const is_dict = (z) => z ? is_object(z) && !is_array(z) : false; | ||
/** | ||
@@ -66,13 +93,193 @@ * Strict test for whether an ES object is a plain object (dict) or not | ||
/** | ||
* Fold array into an object | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export const fold = (a_in, f_fold) => { | ||
const h_out = {}; | ||
let i_each = 0; | ||
for (const z_each of a_in) { | ||
Object.assign(h_out, f_fold(z_each, i_each++)); | ||
} | ||
return h_out; | ||
}; | ||
export const is_iterable = (z) => !!z?.[Symbol.iterator]; | ||
/** | ||
* Simple test for whether a value is iterable or not | ||
*/ | ||
export const is_error = (z) => z instanceof Error; | ||
/** | ||
* Typed alias to `Array.from` | ||
*/ | ||
export const array = Array.from; | ||
/** | ||
* Typed alias to `Object.create` | ||
*/ | ||
export const create = Object.create; | ||
/** | ||
* @deprecated Use {@link create} instead | ||
*/ | ||
export const odc = create; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
export const assign = Object.assign; | ||
/** | ||
* @deprecated Use {@link assign} instead | ||
*/ | ||
export const oda = create; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
export const keys = Object.keys; | ||
/** | ||
* @deprecated Use {@link keys} instead | ||
*/ | ||
export const odk = create; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
export const values = Object.values; | ||
/** | ||
* @deprecated Use {@link values} instead | ||
*/ | ||
export const odv = create; | ||
/** | ||
* Typed alias of `Object.entries` | ||
*/ | ||
export const entries = Object.entries; | ||
/** | ||
* @deprecated Use {@link entries} instead | ||
*/ | ||
export const ode = entries; | ||
/** | ||
* Typed alias of `Object.fromEntries` | ||
*/ | ||
export const from_entries = Object.fromEntries; | ||
/** | ||
* @deprecated Use {@link from_entries} instead | ||
*/ | ||
export const ofe = from_entries; | ||
/** | ||
* Map object entries. Alias of: | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).map(f_map) | ||
* ``` | ||
*/ | ||
export const map_entries = (w_src, f_map) => entries(w_src).map(f_map); | ||
/** | ||
* @deprecated Use {@link map_entries} instead | ||
*/ | ||
export const odem = map_entries; | ||
/** | ||
* Reduce an object to an arbitrary type by its entries. Alias of | ||
* ```ts | ||
* w_obj => Object.entries(w_obj).reduce(f_reduce) | ||
* ``` | ||
*/ | ||
export const reduce_object = (w_src, f_reduce, w_init) => entries(w_src).reduce(f_reduce, w_init); | ||
/** | ||
* @deprecated Use {@link reduce_object} instead | ||
*/ | ||
export const oder = reduce_object; | ||
/** | ||
* Reduce an object's entries to an array via concatenation (with filtering) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => item` | ||
* @param b_keep_undefs - by default, `undefined` items will be ommitted from return array unless this is truthy | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export const concat_entries = (w_src, f_concat, b_keep_undefs = 0, a_out = []) => reduce_object(w_src, (a_acc, [si_key, w_value], i_entry) => { | ||
// invoke callback and capture return value | ||
const w_add = f_concat(si_key, w_value, i_entry); | ||
// add result to array iff not undefined or if undefined values are explictly allowed | ||
if (__UNDEFINED !== w_add || b_keep_undefs) | ||
a_acc.push(w_add); | ||
return a_acc; | ||
}, a_out); | ||
/** | ||
* @deprecated Use {@link concat_entries} instead | ||
*/ | ||
export const oderac = concat_entries; | ||
/** | ||
* Reduce object entries to an array via flattening (i.e., callback return value will be spread into array) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_concat - callback having signature `(key, value, index) => Iterable<item>` | ||
* @param a_out - optionally specifies the output array to merge items into | ||
* @returns an array of the `item` returned by {@link f_concat} | ||
*/ | ||
export const flatten_entries = (w_src, f_concat, a_out = []) => reduce_object(w_src, (a_acc, [si_key, w_value], i_entry) => [ | ||
...a_acc, | ||
...f_concat(si_key, w_value, i_entry), | ||
], a_out); | ||
/** | ||
* @deprecated Use {@link flatten_entries} instead | ||
*/ | ||
export const oderaf = flatten_entries; | ||
/** | ||
* Transform an object to an object by its entries via merging (i.e., callback return value will be spread into object) | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_merge - callback having signature `(key, value, index) => object` | ||
* @param h_out - optionally specifies the output object to merge properties into | ||
* @returns all `item` values returned by {@link f_merge} merged into a single object | ||
*/ | ||
export const transform_object = (w_src, f_merge, h_out = {}) => reduce_object(w_src, (h_acc, [si_key, w_value], i_index) => ({ | ||
...h_acc, | ||
...f_merge(si_key, w_value, i_index), | ||
}), h_out); | ||
/** | ||
* @deprecated Use {@link transform_object} instead | ||
*/ | ||
export const oderom = transform_object; | ||
/** | ||
* Transforms an object by applying the given callback to each of its values, returning a new object | ||
* with the same keys as the original object | ||
* @param w_src - value that will get passed to `Object.entries` | ||
* @param f_transform - callback having signature `(value, key, index) => new_value` | ||
* @returns the new object | ||
*/ | ||
export const transform_values = (w_src, f_transform) => from_entries(map_entries(w_src, ([si_key, w_value], i_entry) => [si_key, f_transform(w_value, si_key, i_entry)])); | ||
/** | ||
* @deprecated Use {@link transform_values} instead | ||
*/ | ||
export const fodemtv = transform_values; | ||
/** | ||
* Fold an array into an object via reduction, i.e., by transforming each value into an object and merging it into a single output. | ||
* | ||
* Useful when the number of output entries per input entry can vary. For 1:1 multiplicity see also {@link collapse}. | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* fold(['a', 'b', 'c'], (value, index) => ({[value]: index})) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_fold - transforming callback function with signature | ||
* ```ts | ||
* type f_fold = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @param h_out - optionally specify the output object, an existing object to merge properties into | ||
* @returns the merged output object | ||
*/ | ||
export const fold = (w_in, f_fold, h_out = {}) => array(w_in).reduce((h_acc, z_each, i_each) => assign(h_acc, f_fold(z_each, i_each)), h_out); | ||
/** | ||
* Collapse an array into an object by mapping its items into entries | ||
* | ||
* Example: | ||
* ```ts | ||
* // turn a list of strings into a dict | ||
* collapse(['a', 'b', 'c'], (value, index) => [value, index]) | ||
* // output: {a:0, b:1, c:2} | ||
* ``` | ||
* | ||
* The return type is dynamically constructed with the following precedence: | ||
* - 1. from explicit type arguments if given `fold<IterableItemValue, OutputKey, OutputValue>(...)` | ||
* - 2. from the type of the {@link h_out} argument if it was defined | ||
* - 3. from the return type of the {@link f_fold} callback | ||
* @param w_in - the {@link Iterable} input | ||
* @param f_collapse - transforming callback function with signature | ||
* ```ts | ||
* type f_collapse = (z_value: w_value, i_each: number) => Record<z_keys, w_value> | ||
* ``` | ||
* @returns the merged output object | ||
*/ | ||
export const collapse = (w_in, f_collapse) => from_entries(array(w_in).map(f_collapse)); | ||
/** | ||
* Creates a new array by inserting an item in between every existing item | ||
@@ -86,2 +293,3 @@ */ | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
if (a_input.length) | ||
@@ -92,6 +300,9 @@ a_output.push(a_input.at(-1)); | ||
/** | ||
* Removes duplicates from an array, keeping only the first occurrence. | ||
* @param z_identify - if specified and a string, identifies the key of each item to use as an identifier | ||
* if specified and a function, used as a callback to produce the comparison key | ||
* if omitted, compares items using full equality `===` | ||
* Removes duplicates from an array, keeping only the first occurrence of each value. Optionally accepts | ||
* an identity argument for deduplicating lists of objects using a key or callback function. | ||
* @param a_items - the items to deduplicate | ||
* @param z_identify - defines how to identify items in the list | ||
* - if given a string, specifes the key of each item whose value should be used to identify it | ||
* - if given a function, used as a callback to produce the comparison key | ||
* - if omitted, compares items using strict equality | ||
*/ | ||
@@ -104,7 +315,7 @@ export const deduplicate = (a_items, z_identify) => { | ||
// use object property | ||
if ('string' === typeof z_identify) { | ||
if (is_string(z_identify)) { | ||
a_keys = a_items.map(w => w[z_identify]); | ||
} | ||
// use identity function | ||
else if ('function' === typeof z_identify) { | ||
else if (is_function(z_identify)) { | ||
a_keys = a_items.map(z_identify); | ||
@@ -134,178 +345,2 @@ } | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
export const escape_regex = (s_input) => s_input.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
/** | ||
* Typed alias to `Object.create` | ||
*/ | ||
export const oc = Object.create; | ||
/** | ||
* Typed alias to `Object.assign` | ||
*/ | ||
export const oda = Object.assign; | ||
/** | ||
* Typed alias to `Object.keys` | ||
*/ | ||
export const odk = Object.keys; | ||
/** | ||
* Typed alias to `Object.values` | ||
*/ | ||
export const odv = Object.values; | ||
/** | ||
* Typed alias to `Object.entries` | ||
*/ | ||
export const ode = Object.entries; | ||
/** | ||
* Typed alias to `Object.fromEntries` | ||
*/ | ||
export const ofe = Object.fromEntries; | ||
/** | ||
* Map object entries | ||
*/ | ||
export const odem = (h_object, f_map) => ode(h_object).map(f_map); | ||
/** | ||
* Reduce object entries to an arbitrary type | ||
*/ | ||
export const oder = (h_thing, f_reduce, w_init) => ode(h_thing).reduce(f_reduce, w_init); | ||
/** | ||
* Reduce object entries to an array via concatenation (with filtering) | ||
*/ | ||
export const oderac = (h_thing, f_concat, b_add_undefs = false) => oder(h_thing, (a_out, [si_key, w_value], i_entry) => { | ||
// invoke callback and capture return value | ||
const w_add = f_concat(si_key, w_value, i_entry); | ||
// add result to array iff not undefined or if undefined values are explictly allowed | ||
if (__UNDEFINED !== w_add || b_add_undefs) | ||
a_out.push(w_add); | ||
return a_out; | ||
}, []); | ||
/** | ||
* Reduce object entries to an array via flattening | ||
*/ | ||
export const oderaf = (h_thing, f_concat) => oder(h_thing, (a_out, [si_key, w_value], i_entry) => [ | ||
...a_out, | ||
...f_concat(si_key, w_value, i_entry), | ||
], []); | ||
/** | ||
* Reduce object entries to an object via merging | ||
*/ | ||
export const oderom = (h_thing, f_merge) => oder(h_thing, (h_out, [si_key, w_value], i_index) => ({ | ||
...h_out, | ||
...f_merge(si_key, w_value, i_index), | ||
}), {}); | ||
/** | ||
* Reduce object entries to an object via transforming value function | ||
*/ | ||
export const fodemtv = (h_thing, f_transform) => ofe(odem(h_thing, ([si_key, w_value], i_entry) => [si_key, f_transform(w_value, si_key, i_entry)])); | ||
/** | ||
* Promise-based version of `setTimeout()` | ||
*/ | ||
export const timeout = (xt_wait) => new Promise((fk_resolve) => { | ||
setTimeout(() => { | ||
fk_resolve(__UNDEFINED); | ||
}, xt_wait); | ||
}); | ||
export const timeout_exec = (xt_wait, f_attempt) => new Promise((fk_resolve, fe_reject) => { | ||
// infinite | ||
if (!Number.isFinite(xt_wait)) { | ||
void f_attempt?.().then(w => fk_resolve([w, 0])).catch(e => fe_reject(e)); | ||
return; | ||
} | ||
let b_timed_out = false; | ||
// attempt callback | ||
f_attempt?.() | ||
.then((w_return) => { | ||
// already timed out | ||
if (b_timed_out) | ||
return; | ||
// cancel pending timer | ||
clearTimeout(i_pending); | ||
// resolve promise | ||
fk_resolve([w_return, 0]); | ||
}) | ||
.catch((e_attempt) => { | ||
fe_reject(e_attempt); | ||
}); | ||
// start waiting | ||
const i_pending = setTimeout(() => { | ||
// mark as timed out | ||
b_timed_out = true; | ||
// resolve promise | ||
fk_resolve([__UNDEFINED, 1]); | ||
}, xt_wait); | ||
}); | ||
export const with_timeout = (g_with) => new Promise((fk_resolve, fe_reject) => { | ||
// state of completion | ||
let b_complete = false; | ||
// timer | ||
setTimeout(() => { | ||
// already completed | ||
if (b_complete) | ||
return; | ||
// now complete | ||
b_complete = true; | ||
// reject | ||
fe_reject(g_with.trip()); | ||
}, g_with.duration); | ||
// run task | ||
g_with.run().then((w_value) => { | ||
// already failed | ||
if (b_complete) | ||
return; | ||
// now complete | ||
b_complete = true; | ||
// resolve | ||
fk_resolve(w_value); | ||
}).catch(fe_reject); | ||
}); | ||
/** | ||
* A Promise that never fulfills nor rejects | ||
*/ | ||
export const forever = (w_type) => new Promise(F_NOOP); | ||
/** | ||
* Promse-based version of `queueMicrotask()` | ||
*/ | ||
export const microtask = () => new Promise((fk_resolve) => { | ||
queueMicrotask(() => { | ||
fk_resolve(__UNDEFINED); | ||
}); | ||
}); | ||
export const defer = () => { | ||
let fk_resolve; | ||
let fe_reject; | ||
const dp_promise = new Promise((fk, fe) => { | ||
fk_resolve = fk; | ||
fe_reject = fe; | ||
}); | ||
return [dp_promise, (w_return, e_reject) => { | ||
if (e_reject) { | ||
fe_reject(e_reject); | ||
} | ||
else { | ||
fk_resolve(w_return); | ||
} | ||
}]; | ||
}; | ||
export const defer_many = (h_input) => { | ||
const h_mapped = fodemtv(h_input, () => defer()); | ||
return { | ||
promises: fodemtv(h_mapped, a_defer => a_defer[0]), | ||
resolve(h_resolves) { | ||
for (const si_key in h_resolves) { | ||
h_mapped[si_key]?.[1](h_resolves[si_key]); | ||
} | ||
}, | ||
reject(h_rejects) { | ||
for (const si_key in h_rejects) { | ||
h_mapped[si_key]?.[1](__UNDEFINED, h_rejects[si_key]); | ||
} | ||
}, | ||
}; | ||
}; | ||
/** | ||
* Cryptographically strong random number | ||
*/ | ||
export const crypto_random = () => crypto.getRandomValues(new Uint32Array(1))[0] / (2 ** 32); | ||
/** | ||
* Generate a random int within a given range | ||
@@ -320,11 +355,2 @@ */ | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export const crypto_random_int = (x_a, x_b = 0) => { | ||
const x_min = Math.floor(Math.min(x_a, x_b)); | ||
const x_max = Math.ceil(Math.max(x_a, x_b)); | ||
// confine to range | ||
return Math.floor(crypto_random() * (x_max - x_min)) + x_min; | ||
}; | ||
/** | ||
* Shuffles an array | ||
@@ -360,4 +386,34 @@ */ | ||
export const die = (s_msg, w_data) => { | ||
throw oda(Error(s_msg), { data: w_data }); | ||
throw assign(Error(s_msg), { data: w_data }); | ||
}; | ||
/** | ||
* Synchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - synchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export const try_sync = (f_try) => { | ||
try { | ||
return [f_try(), 0]; | ||
} | ||
catch (e_fail) { | ||
return [__UNDEFINED, e_fail]; | ||
} | ||
}; | ||
/** | ||
* Asynchronously try the given callback, returning a tuple of the result or error | ||
* @param f_try - asynchronous callback function | ||
* @returns a tuple where: | ||
* - 0: the awaited value returned by callback function if it did not throw, otherwise `undefined` | ||
* - 1: the error thrown by the callback function, if any, otherwise `undefined` | ||
*/ | ||
export const try_async = async (f_try) => { | ||
try { | ||
return [await f_try(), 0]; | ||
} | ||
catch (e_fail) { | ||
return [__UNDEFINED, e_fail]; | ||
} | ||
}; | ||
//# sourceMappingURL=belt.js.map |
/* eslint-disable prefer-const, no-sequences, @typescript-eslint/naming-convention */ | ||
import { __UNDEFINED } from './belt.js'; | ||
import { bytes_to_bigint_be, bytes_to_text, dataview } from './data.js'; | ||
import { bytes_to_biguint_be, bytes_to_text, dataview } from './data.js'; | ||
/** | ||
@@ -65,5 +65,5 @@ * Decodes a CBOR buffer into its ES equivalent. It does not support floating point numbers. | ||
// unsigned bigint | ||
(_) => bytes_to_bigint_be(f_bytes()), | ||
(_) => bytes_to_biguint_be(f_bytes()), | ||
// negative bigint | ||
(_) => -bytes_to_bigint_be(f_bytes()) - 1n, | ||
(_) => -bytes_to_biguint_be(f_bytes()) - 1n, | ||
][xc_additional](), | ||
@@ -70,0 +70,0 @@ // major type 7 |
import type { NaiveBase58, NaiveBase64, NaiveBase93, NaiveHexLower } from './strings'; | ||
import type { JsonValue } from './types'; | ||
import type { JsonValue, NaiveJsonString } from './types'; | ||
export declare const uuid_v4: () => string; | ||
type Uint8ArrayConstructorParams = [] | [length: number] | [array: ArrayLike<number> | ArrayBufferLike] | [buffer: ArrayBufferLike, byteOffset?: number, length?: number]; | ||
/** | ||
* Typed alias to `JSON.stringify` | ||
*/ | ||
export declare const stringify_json: <w_string extends string = NaiveJsonString>(w_json: JsonValue, f_replacer?: Parameters<typeof JSON.stringify>[1], z_space?: Parameters<typeof JSON.stringify>[2]) => w_string; | ||
/** | ||
* Typed alias to `JSON.parse` | ||
*/ | ||
export declare const parse_json: <w_value extends JsonValue<void | undefined> = JsonValue>(sx_json: string, f_reviver?: Parameters<typeof JSON.parse>[1]) => w_value; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export declare const parse_json_safe: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* @deprecated Use {@link parse_json_safe} instead. | ||
*/ | ||
export declare const safe_json: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles | ||
* and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted | ||
* since order matters. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
*/ | ||
export declare const canonicalize_json: <w_json extends JsonValue>(w_json: w_json) => w_json; | ||
/** | ||
* Helps reduce codesize | ||
@@ -91,3 +117,3 @@ * @param a_args | ||
/** | ||
* Encodes the given 32-bit integer in big-endian format to a new buffer. | ||
* Encodes the given 32-bit unsigned integer in big-endian format to a new buffer. | ||
* @param xg_uint | ||
@@ -98,3 +124,3 @@ * @returns | ||
/** | ||
* Decodes a 32-bit integer in big-endian format from a buffer (optionally at the given position). | ||
* Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position). | ||
* @param n_uint | ||
@@ -105,3 +131,3 @@ * @returns | ||
/** | ||
* Encodes the given bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* @param xg_value - the value to encode | ||
@@ -111,22 +137,18 @@ * @param nb_size - size of the buffer to create | ||
*/ | ||
export declare const biguint_to_bytes_be: (xg_value: bigint, nb_size?: number) => Uint8Array; | ||
/** | ||
* @deprecated Use {@link biguint_to_bytes_be} instead. | ||
*/ | ||
export declare const bigint_to_bytes_be: (xg_value: bigint, nb_size?: number) => Uint8Array; | ||
/** | ||
* Decodes a bigint in big-endian format from a buffer | ||
* Decodes an unsigned bigint in big-endian format from a buffer | ||
* @param atu8_bytes | ||
* @returns | ||
*/ | ||
export declare const bytes_to_bigint_be: (atu8_bytes: Uint8Array) => bigint; | ||
export declare const bytes_to_biguint_be: (atu8_bytes: Uint8Array) => bigint; | ||
/** | ||
* Converts a JSON object into its canonical form. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
* @deprecated Use {@link bytes_to_biguint_be} instead. | ||
*/ | ||
export declare const canonicalize_json: <w_json extends JsonValue>(w_json: w_json) => w_json; | ||
export declare const bytes_to_bigint_be: (atu8_bytes: Uint8Array) => bigint; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export declare const safe_json: <w_out extends JsonValue<void | undefined> = JsonValue>(sx_json: string) => w_out | undefined; | ||
/** | ||
* Concatenate a sequence of Uint8Arrays. | ||
@@ -200,2 +222,10 @@ * @param a_buffers the data to concatenate in order | ||
export declare const base58_to_bytes: (sb58_buffer: string) => Uint8Array; | ||
/** | ||
* Cryptographically strong random number in the range [0, 1) | ||
*/ | ||
export declare const crypto_random: () => number; | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export declare const crypto_random_int: (x_a: number, x_b?: number) => number; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
import { XG_8, is_array, is_dict_es, ode, ofe } from './belt.js'; | ||
import { XG_8, is_array, is_dict_es, is_string, entries, from_entries, transform_values, die, try_sync } from './belt.js'; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
@@ -18,2 +18,45 @@ const S_UUID_V4 = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'; | ||
/** | ||
* Typed alias to `JSON.stringify` | ||
*/ | ||
export const stringify_json = JSON.stringify; | ||
/** | ||
* Typed alias to `JSON.parse` | ||
*/ | ||
export const parse_json = JSON.parse; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export const parse_json_safe = (sx_json) => try_sync(_ => parse_json(sx_json))[0]; | ||
/** | ||
* @deprecated Use {@link parse_json_safe} instead. | ||
*/ | ||
export const safe_json = parse_json_safe; | ||
/** | ||
* Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles | ||
* and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted | ||
* since order matters. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
*/ | ||
export const canonicalize_json = (w_json) => { | ||
// JSON object | ||
if (is_dict_es(w_json)) { | ||
// sort all keys | ||
const h_sorted = from_entries(entries(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1)); | ||
// traverse on children | ||
for (const si_key in h_sorted) { | ||
h_sorted[si_key] = canonicalize_json(h_sorted[si_key]); | ||
} | ||
w_json = h_sorted; | ||
} | ||
// JSON array | ||
else if (is_array(w_json)) { | ||
w_json = w_json.map(w_item => canonicalize_json(w_item)); | ||
} | ||
// boolean, number, string, or null | ||
return w_json; | ||
}; | ||
/** | ||
* Helps reduce codesize | ||
@@ -83,3 +126,3 @@ * @param a_args | ||
if (0 !== atu8_data.reduce((c_sum, x_value) => c_sum + x_value, 0)) | ||
throw new Error('Failed to zero out sensitive memory region'); | ||
die('Failed to zero out sensitive memory region'); | ||
}; | ||
@@ -132,3 +175,3 @@ export const encode_length_prefix_u16 = (atu8_data) => { | ||
*/ | ||
export const json_to_bytes = (w_json) => text_to_bytes(JSON.stringify(w_json)); | ||
export const json_to_bytes = (w_json) => text_to_bytes(stringify_json(w_json)); | ||
/** | ||
@@ -139,5 +182,5 @@ * UTF-8 decodes the given Uint8Array and subsequently attempts to JSON parse it. | ||
*/ | ||
export const bytes_to_json = (atu8_json) => JSON.parse(bytes_to_text(atu8_json)); | ||
export const bytes_to_json = (atu8_json) => parse_json(bytes_to_text(atu8_json)); | ||
/** | ||
* Encodes the given 32-bit integer in big-endian format to a new buffer. | ||
* Encodes the given 32-bit unsigned integer in big-endian format to a new buffer. | ||
* @param xg_uint | ||
@@ -155,3 +198,3 @@ * @returns | ||
/** | ||
* Decodes a 32-bit integer in big-endian format from a buffer (optionally at the given position). | ||
* Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position). | ||
* @param n_uint | ||
@@ -162,3 +205,3 @@ * @returns | ||
/** | ||
* Encodes the given bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given. | ||
* @param xg_value - the value to encode | ||
@@ -168,3 +211,3 @@ * @param nb_size - size of the buffer to create | ||
*/ | ||
export const bigint_to_bytes_be = (xg_value, nb_size = 32) => { | ||
export const biguint_to_bytes_be = (xg_value, nb_size = 32) => { | ||
// prep buffer of the appropriate size | ||
@@ -180,39 +223,16 @@ let atu8_out = bytes(nb_size); | ||
/** | ||
* Decodes a bigint in big-endian format from a buffer | ||
* @deprecated Use {@link biguint_to_bytes_be} instead. | ||
*/ | ||
export const bigint_to_bytes_be = biguint_to_bytes_be; | ||
/** | ||
* Decodes an unsigned bigint in big-endian format from a buffer | ||
* @param atu8_bytes | ||
* @returns | ||
*/ | ||
export const bytes_to_bigint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << XG_8) | BigInt(xb_value), 0n); | ||
export const bytes_to_biguint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << XG_8) | BigInt(xb_value), 0n); | ||
/** | ||
* Converts a JSON object into its canonical form. | ||
* @param w_json JSON-compatible value to canonicalize | ||
* @returns canonicalized JSON value | ||
* @deprecated Use {@link bytes_to_biguint_be} instead. | ||
*/ | ||
export const canonicalize_json = (w_json) => { | ||
if (is_dict_es(w_json)) { | ||
// sort all keys | ||
const h_sorted = ofe(ode(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1)); | ||
// traverse on children | ||
for (const si_key in h_sorted) { | ||
h_sorted[si_key] = canonicalize_json(h_sorted[si_key]); | ||
} | ||
w_json = h_sorted; | ||
} | ||
else if (is_array(w_json)) { | ||
w_json = w_json.map(w_item => canonicalize_json(w_item)); | ||
} | ||
return w_json; | ||
}; | ||
export const bytes_to_bigint_be = bytes_to_biguint_be; | ||
/** | ||
* Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing | ||
* @param sx_json | ||
* @returns | ||
*/ | ||
export const safe_json = (sx_json) => { | ||
try { | ||
return JSON.parse(sx_json); | ||
} | ||
catch (e_parse) { } | ||
}; | ||
/** | ||
* Concatenate a sequence of Uint8Arrays. | ||
@@ -334,3 +354,3 @@ * @param a_buffers the data to concatenate in order | ||
if (-1 === xb_char) | ||
throw new Error('Invalid base64 string'); | ||
die('Invalid base64 string'); | ||
// add 6 bits from index to buffer | ||
@@ -353,3 +373,3 @@ xb_work = (xb_work << 6) | xb_char; | ||
} | ||
return new Uint8Array(a_out); | ||
return bytes(a_out); | ||
}; | ||
@@ -421,3 +441,3 @@ /** | ||
if (-1 === xb_char) | ||
throw new Error('Invalid base93 string'); | ||
die('Invalid base93 string'); | ||
if (-1 === xb_work) { | ||
@@ -480,8 +500,8 @@ xb_work = xb_char; | ||
export const base58_to_bytes = (sb58_buffer) => { | ||
if (!sb58_buffer || 'string' !== typeof sb58_buffer) { | ||
throw new Error(`Expected base58 string but got “${sb58_buffer}”`); | ||
if (!sb58_buffer || !is_string(sb58_buffer)) { | ||
die(`Expected base58 string but got “${sb58_buffer}”`); | ||
} | ||
const m_invalid = sb58_buffer.match(/[IOl0]/gmu); | ||
if (m_invalid) { | ||
throw new Error(`Invalid base58 character “${String(m_invalid)}”`); | ||
die(`Invalid base58 character “${String(m_invalid)}”`); | ||
} | ||
@@ -505,2 +525,15 @@ const m_lz = sb58_buffer.match(/^1+/gmu); | ||
}; | ||
/** | ||
* Cryptographically strong random number in the range [0, 1) | ||
*/ | ||
export const crypto_random = () => crypto.getRandomValues(bytes(1))[0] / (2 ** 32); | ||
/** | ||
* Generate a cryptographically strong random int within a given range | ||
*/ | ||
export const crypto_random_int = (x_a, x_b = 0) => { | ||
const x_min = Math.floor(Math.min(x_a, x_b)); | ||
const x_max = Math.ceil(Math.max(x_a, x_b)); | ||
// confine to range | ||
return Math.floor(crypto_random() * (x_max - x_min)) + x_min; | ||
}; | ||
//# sourceMappingURL=data.js.map |
@@ -0,1 +1,2 @@ | ||
import type { NoInfer } from 'ts-toolbelt/out/Function/_api'; | ||
import type { Subtype } from './types'; | ||
@@ -46,2 +47,26 @@ /** | ||
export type NaiveHexMixed<s_subtype extends string = string> = Subtype<HexMethods & s_subtype, 'hex-lower' | 'hex-upper'>; | ||
/** | ||
* Creates a proper-case string, returning `undefined` if given `undefined | ||
* @param s_input - any text to transform | ||
* @returns the transformed text in "Proper case" | ||
*/ | ||
export declare const proper: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_input: s_input) => NoInfer<z_output>; | ||
/** | ||
* Converts given identifier to "snake_case", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "snake_case" | ||
*/ | ||
export declare const snake: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_ident: s_input) => NoInfer<z_output>; | ||
/** | ||
* Converts given identifier to "PascalCase", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "PascalCase" | ||
*/ | ||
export declare const pascal: <s_input extends string | undefined, z_output = s_input extends undefined ? undefined : string>(s_ident: s_input) => NoInfer<z_output>; | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
export declare const escape_regex: (s_input: string) => string; | ||
export {}; |
@@ -1,2 +0,35 @@ | ||
export {}; | ||
/** | ||
* Creates a proper-case string, returning `undefined` if given `undefined | ||
* @param s_input - any text to transform | ||
* @returns the transformed text in "Proper case" | ||
*/ | ||
export const proper = (s_input) => s_input?.split(/[\s_]+/g).map(s => s ? s[0].toUpperCase() + s.slice(1) : '').join(' '); | ||
/** | ||
* Converts given identifier to "snake_case", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "snake_case" | ||
*/ | ||
export const snake = (s_ident) => (s_ident | ||
? s_ident.toUpperCase() === s_ident | ||
// depending on upper or mixed case | ||
? s_ident.toLowerCase().replace(/[^a-z0-9$]+/g, '_') | ||
: s_ident.replace(/(?<!^)(?:[^a-zA-Z0-9$]*([A-Z])|[^a-zA-Z0-9$]+)/g, (s_ignore, s_cap) => '_' + (s_cap || '')).toLowerCase() | ||
: s_ident); | ||
/** | ||
* Converts given identifier to "PascalCase", returning {@link s_ident} if given a falsy value | ||
* @param s_ident - an identifier to transform | ||
* @returns the transformed identifier in "PascalCase" | ||
*/ | ||
export const pascal = (s_ident) => (s_ident | ||
// if all uppercase; make lower | ||
? (/^([^A-Za-z]*[A-Z]+)+([^A-Za-z])?$/.test(s_ident) ? pascal(s_ident.toLowerCase()) : s_ident) | ||
// convert to pascal | ||
.replace(/(?:^|[^A-Za-z0-9$])([\w0-9$]|$)/g, (s_ignore, s_letter) => s_letter.toUpperCase()).trim() | ||
: s_ident); | ||
/** | ||
* Escape all special regex characters to turn a string into a verbatim match pattern | ||
* @param s_input input string | ||
* @returns escaped string ready for RegExp constructor | ||
*/ | ||
export const escape_regex = (s_input) => s_input.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
//# sourceMappingURL=strings.js.map |
@@ -5,2 +5,10 @@ import type { A, U } from 'ts-toolbelt'; | ||
/** | ||
* Test whether a given type value is the `any` type. Returns `1` if true, `0` otherwise | ||
*/ | ||
export type IsLiteralAny<w_test> = 0 extends (1 & w_test) ? 1 : 0; | ||
/** | ||
* If the given type value is the `any` type, use the given substitute type instead | ||
*/ | ||
export type InsteadOfAny<w_test, w_instead> = 0 extends (1 & w_test) ? w_instead : w_test; | ||
/** | ||
* Create subtype on any type using intersection. Can be removed later using {@link Unsubtype} | ||
@@ -56,2 +64,18 @@ */ | ||
/** | ||
* Types that can be accessed via index operator, and that work with `Object.entries()` | ||
*/ | ||
export type KeyValuable = Record<any, any> | ArrayLike<any>; | ||
/** | ||
* Returns the keys of the given type, returning`${bigint}` for Array since its keys satisfy `${bigint}` | ||
*/ | ||
export type KeysOf<w_type> = w_type extends ArrayLike<any> ? `${bigint}` : w_type extends JsonObject ? string : w_type extends Record<infer s_key, any> ? s_key : never; | ||
/** | ||
* Returns the values of the given type, extracting the values of an Array, or the properties of an Object. | ||
*/ | ||
export type ValuesOf<w_type> = w_type extends ArrayLike<infer w_value> ? w_value : w_type[keyof w_type]; | ||
/** | ||
* Union of all TypedArray types | ||
*/ | ||
export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; | ||
/** | ||
* JSON string | ||
@@ -63,5 +87,5 @@ */ | ||
*/ | ||
export interface JsonObject<w_inject extends any = never> { | ||
export type JsonObject<w_inject extends any = never> = { | ||
[k: string]: JsonValue<w_inject>; | ||
} | ||
}; | ||
/** | ||
@@ -68,0 +92,0 @@ * Union of "valuable", primitive JSON value types |
export const TYPE_ID = Symbol('type-id'); | ||
export const ES_TYPE = Symbol('es-type'); | ||
/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars */ | ||
{ | ||
const test = {}; | ||
} | ||
//# sourceMappingURL=types.js.map |
{ | ||
"name": "@blake.regalia/belt", | ||
"version": "0.31.1", | ||
"version": "0.32.0", | ||
"repository": "github:blake-regalia/belt", | ||
@@ -25,13 +25,18 @@ "license": "ISC", | ||
"build": "yarn build:mjs && yarn build:cjs", | ||
"bundle": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript" | ||
"bundle": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript", | ||
"test": "yarn build && bun test ./test/*.ts" | ||
}, | ||
"devDependencies": { | ||
"@blake.regalia/eslint-config-elite": "^0.4.0", | ||
"@blake.regalia/eslint-config-elite": "^0.4.4", | ||
"@blake.regalia/tsconfig": "^0.2.0", | ||
"@rollup/plugin-typescript": "^11.1.5", | ||
"@types/node": "^20.10.4", | ||
"@types/web": "^0.0.127", | ||
"@typescript-eslint/parser": "^6.14.0", | ||
"eslint": "^8.55.0", | ||
"rollup": "^4.9.0", | ||
"@jest/globals": "^29.7.0", | ||
"@rollup/plugin-typescript": "^11.1.6", | ||
"@types/node": "^20.11.24", | ||
"@types/web": "^0.0.140", | ||
"@typescript-eslint/parser": "^7.1.0", | ||
"bun": "^1.0.29", | ||
"bun-types": "^1.0.29", | ||
"eslint": "^8.57.0", | ||
"jest": "^29.7.0", | ||
"rollup": "^4.12.0", | ||
"ts-node": "^10.9.2", | ||
@@ -38,0 +43,0 @@ "ts-toolbelt": "^9.6.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
267884
48
5161
15