/** * AD HOC FUNCTIONS ============================================================ * ============================================================================= */ /** * Create Case-Sensitive Short Auto Incrementing ID string derived from Timestamp in milliseconds * @Important: * - modifying this function may break existing database implementations. * - directory/file names in Linux are case-sensitive, but are not in macOS or Windows; * => it is better to only use lower case characters for this reason. * @Rationale: the primary use case is for generating globally unique Ids from frontend that can be used in backend. * * @Note: * - The ID is 10 characters long: * 1. URL safe - case-insensitive alphanumeric only characters (36 radix) * 2. Safe for use as HTML5 id attribute * 2. Sorts chronologically without conversion (replacing the need for database timestamp) * => Sorting will stop working after April 22, the year 5,188, because 36^9 limit padding is reached * -> The solution is to increment the padCount to 10, which will work until January 18, the year 117,829. * * - first 9 characters is Hex string of Timestamp * - Last 3 character is randomized using alphanumeric characters to avoid collision * - Collision probability is near zero in practice, because 3 random string suffix * a. using 36 (case-insensitive) characters have 36^3 = 46,656 possibilities, * b. using 62 (case-sensitive) characters have 62^3 = 238,328 possibilities, * => it is unlikely two people would create more than that possibilities in the same millisecond. * - Collision within the same instance is prevented by checking for suffix duplicates within each millisecond. * - This function is purposely slow with de-optimization to prevent generating too many Ids within one millisecond. * * @param {Number|String} [timestamp] - custom timestamp to generate ID for, defaults to Date.now() * @param {String} [alphabet] - custom characters to use for Id generation, default to alphaNumeric characters * @param {Boolean} [caseSensitive] - whether to use case-sensitive characters * @param {Number} [padCount] - if generated ID length is less than this, it's padded with the first character in the `alphabet` * @param {String} [suffix] - string to append to ID timestamp, default is random alphanumeric 3 characters string * @return {String} ID - example: 'mj8foo3ago' */ export function Id({ timestamp, caseSensitive, alphabet, padCount, suffix, }?: string | number | undefined): string; export namespace Id { const alphabet: string; const alphabetLower: string; const minLength: number; const pattern: RegExp; const history: {}; } /** * Check if given string is a valid Short Auto Incrementing ID derived from Timestamp in milliseconds * @param {*} value - to check * @return {Boolean} true - if valid, else false */ export function isId(value: any): boolean; /** * Check if value is of primitive type: string, number, boolean, bigint, symbol, null, undefined. * String, Number, etc. in object form are considered as primitive because they coerce the same way. * * @param {any} val - check * @returns {boolean} true - if it's considered of primitive value */ export function isPrimitive(val: any): boolean; /** * Check if given value is truthy. * A value is considered to be falsy, if it's one of these: * false, undefined, null, NaN, 0, 0.0, -0, +0, -0.0, +0.0, '', {}, [], * * @param {*} val - to evaluate for truthiness * @returns {boolean} */ export function isTruthy(val: any): boolean; /** * Get Timestamp in Milliseconds from Id string * @param {string} string - Id generated by the Id() function * @param {object} [options]: * {Boolean} [caseSensitive] - whether Id is case-sensitive * {String} [alphabet] - characters used to generate Id * @return {Number|Error} Timestamp - in Milliseconds, or throws error of Id is invalid */ export function timestampFromId(string: string, { caseSensitive, alphabet, }?: object | undefined): number | Error; export namespace timestampFromId { const padPattern: RegExp; } /** * Calculate Distance between two Geometry Points (with latitude and longitude) * * @note: this method is fast, but inaccurate (using Haversine formula); * for precise calculation - use https://www.npmjs.com/package/geolib * * @param {Object} point1 * @param {Object} point2 * @param {String<'km'|'m'|'mm'>} [unit] - of measurements, default is millimeter (length unit saved in database) * @returns {Number} distance - between given points in chosen unit */ export function distanceBetween(point1: any, point2: any, unit?: string | undefined): number; /** * Create a Dynamic Import Proxy map for code splitting, returning a new map object, * with values being default asset exports (or their Promises in frontend, and null in backend). * * @example: * // Setup once * const assetMap = dynamicImport({ * View: () => import(`./components/View.jsx`) * }) * * // Retrieving asset inside function or class Components * let { View = Component } = assetMap * if (View instanceof Promise) { * View.then(() => this.forceUpdate()) * View = null * } * if (View === null) View = () => // component is loading for the first time * else {...} // logic to render View * * @param {{[p: string]: function}} assetMap - map of the assets' dynamic import functions */ export function dynamicImport(assetMap: { [p: string]: Function; }): { [p: string]: Function; }; /** * Check if given password is good enough * @see: https://lowe.github.io/tryzxcvbn/ * minimum score of 3 is for safe password in security sensitive applications, 2 is usually enough * * @param {String} value - to check * @param {Number} strength - minimum strength * @returns {Boolean} true - if it is */ export function isGoodPassword(value: string, strength?: number): boolean; /** * Asynchronously load script with callback function once loaded * @note: only works if called before runtime! * @example: * asyncLoad('/static/js/file.js', () => {}) * * @param {String} src - file path * @param {Function} [callback] */ export function asyncLoad(src: string, callback?: Function | undefined): void; /** * Create HTML DOM