Skip to content

Commit

Permalink
Merge branch 'release/v0.23.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
holtwick committed Aug 5, 2024
2 parents 98492a8 + d5a205f commit c8b1b81
Show file tree
Hide file tree
Showing 32 changed files with 197 additions and 91 deletions.
2 changes: 1 addition & 1 deletion demos/tests/src/test-unit-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

export {}

async function handleCandidates(candidates: Record<string, Function>) {
async function handleCandidates(candidates: Record<string, any>) {
console.log('candidates', Object.keys(candidates))
for (const [name, fn] of Object.entries(candidates)) {
console.log('MODULE', name)
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zeed",
"type": "module",
"version": "0.22.10",
"version": "0.23.0",
"description": "🌱 Simple foundation library",
"author": {
"name": "Dirk Holtwick",
Expand Down Expand Up @@ -69,18 +69,18 @@
"watch": "nr build -- --watch src"
},
"devDependencies": {
"@antfu/eslint-config": "<2.22",
"@antfu/ni": "<0.22.0",
"@types/node": "^20.14.10",
"@vitejs/plugin-vue": "^5.0.5",
"@vitest/browser": "^2.0.2",
"@vitest/coverage-v8": "^2.0.2",
"@antfu/eslint-config": "^2.24",
"@antfu/ni": "^0.22.0",
"@types/node": "^22.1.0",
"@vitejs/plugin-vue": "^5.1.2",
"@vitest/browser": "^2.0.5",
"@vitest/coverage-v8": "^2.0.5",
"esbuild": "^0.23.0",
"eslint": "<9",
"playwright": "^1.45.1",
"tsup": "^8.1.0",
"typescript": "^5.5.3",
"vite": "^5.3.3",
"vitest": "^2.0.2"
"eslint": "^9",
"playwright": "^1.45.3",
"tsup": "^8.2.4",
"typescript": "^5.5.4",
"vite": "^5.3.5",
"vitest": "^2.0.5"
}
}
1 change: 1 addition & 0 deletions src/browser/log/log-colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function browserSupportsColors(): boolean {
|| (typeof navigator !== 'undefined'
&& navigator.userAgent
&& navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)
// eslint-disable-next-line regexp/no-legacy-features
&& Number.parseInt(RegExp.$1, 10) >= 31)
// Double check webkit in userAgent just in case we are in a worker
|| (typeof navigator !== 'undefined'
Expand Down
30 changes: 0 additions & 30 deletions src/common/crypto/xaes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ async function halfKey(index: number, key: CryptoKey, iv: Uint8Array, k1: Uint8A

/**
* Derives a 256-bit key and 96-bit nonce from the given 256-bit key and a 192-bit nonce.
*
* @param {CryptoKey} key
* @param {BufferSource} iv
* @returns {Promise<{key: CryptoKey, iv: Uint8Array}>}
*/
async function deriveKeyNonce(key: CryptoKey, iv: BufferSource): Promise<{ key: CryptoKey, iv: Uint8Array }> {
if (key.algorithm.name !== 'AES-CBC') {
Expand Down Expand Up @@ -90,13 +86,6 @@ async function deriveKeyNonce(key: CryptoKey, iv: BufferSource): Promise<{ key:
/**
* Encrypts data using XAES-256-GCM with the given key and iv.
* Key must be a 256-bit AES-CBC CryptoKey with 'encrypt' usage.
*
* @param {{iv: BufferSource, additionalData?: BufferSource}} params
* - encryption parameters, containing the 24-byte iv (nonce)
* and optional additional data to authenticate.
* @param {CryptoKey} key - 256-bit AES-CBC CryptoKey.
* @param {BufferSource} data - Data to encrypt.
* @returns {Promise<ArrayBuffer>} - Encrypted data.
*/
export async function encrypt(params: {
iv: BufferSource
Expand All @@ -118,13 +107,6 @@ export async function encrypt(params: {
/**
* Decrypts data using XAES-256-GCM with the given key and iv.
* Key must be a 256-bit AES-CBC CryptoKey with 'encrypt' and 'decrypt' usages.
*
* @param {{iv: BufferSource, additionalData?: BufferSource}} params
* - decryption parameters, containing the 24-byte iv (nonce)
* and optional additional data to authenticate.
* @param {CryptoKey} key - 256-bit AES-CBC CryptoKey.
* @param {BufferSource} data - Data to decrypt.
* @returns {Promise<ArrayBuffer>} - Decrypted data.
*/
export async function decrypt(params: {
iv: BufferSource
Expand All @@ -148,9 +130,6 @@ export async function decrypt(params: {
* The actual key is an AES-CBC CryptoKey with 256-bit length.
*
* This function is not necessary, as you can use crypto.subtle.generateKey with AES-CBC directly.
*
* @param {boolean} extractable
* @returns Promise<CryptoKey>
*/
export async function generateKey(extractable?: boolean): Promise<CryptoKey> {
return await crypto.subtle.generateKey(
Expand All @@ -169,11 +148,6 @@ export async function generateKey(extractable?: boolean): Promise<CryptoKey> {
* The actual key must be an AES-CBC CryptoKey with 256-bit length.
*
* This function is not necessary, as you can use crypto.subtle.importKey with AES-CBC directly.
*
* @param {"jwk" | "raw" | "pkcs8" | "spki"} format
* @param {BufferSource | JsonWebKey} keyData
* @param {boolean} extractable
* @returns {Promise<CryptoKey>}
*/
export async function importKey(format: 'jwk' | 'raw' | 'pkcs8' | 'spki', keyData: BufferSource | JsonWebKey, extractable?: boolean): Promise<CryptoKey> {
return await crypto.subtle.importKey( // @ts-expect-error-next-line
Expand All @@ -190,10 +164,6 @@ export async function importKey(format: 'jwk' | 'raw' | 'pkcs8' | 'spki', keyDat
* The resulting export will have AES-CBC algorithm specified.
*
* This function is not necessary, as you can use crypto.subtle.exportKey directly.
*
* @param {"jwk" | "pkcs8" | "raw" | "spki"} format
* @param {CryptoKey} key
* @returns {Promise<ArrayBuffer | JsonWebKey>}
*/
export async function exportKey(format: 'jwk' | 'pkcs8' | 'raw' | 'spki', key: CryptoKey): Promise<ArrayBuffer | JsonWebKey> {
return await crypto.subtle.exportKey(format, key)
Expand Down
3 changes: 2 additions & 1 deletion src/common/csv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export function csvParse(raw: string, opt: {
separator?: string
} = {}) {
// https://regex101.com/r/BCpKyV/1
let rxOneValueWithSeparator = /("((?:(?:[^"]*?)(?:"")?)*)"|([^,;\t\n]*))([,;\t]|\n|\r\n)/g
// eslint-disable-next-line regexp/no-unused-capturing-group, regexp/no-super-linear-backtracking, regexp/no-dupe-disjunctions, regexp/no-useless-non-capturing-group
let rxOneValueWithSeparator = /("((?:(?:[^"]*?)(?:"")?)*)"|([^,;\t\n]*))([,;\t\n]|\r\n)/g
if (opt.separator)
rxOneValueWithSeparator = new RegExp(rxOneValueWithSeparator.source.replaceAll(',;\\t', escapeRegExp(opt.separator)), rxOneValueWithSeparator.flags)

Expand Down
2 changes: 1 addition & 1 deletion src/common/data/basex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function _useBase(alphaOrBase: string | number): {
return new Uint8Array()

// Normalize
source = source.replace(/\s+/gi, '')
source = source.replace(/\s+/g, '')

let psz = 0
let length = 0
Expand Down
8 changes: 4 additions & 4 deletions src/common/data/camelcase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ PascalCase // I won't be using this here, but it's only one small step further i
export function toCamelCase(s: string) {
// if only capital letters, convert to lower case
if (s.length > 0) {
if (/^[A-Z0-9_\-\ ]*$/g.test(s))
if (/^[A-Z0-9_\- ]*$/.test(s))
s = s.toLowerCase()

s = s
// strip trailing non chars
.replace(/^[-_\ ]+/gi, '')
.replace(/[-_\ ]+$/gi, '')
.replace(/^[-_ ]+/g, '')
.replace(/[-_ ]+$/g, '')
// strip separators and upper case first char
.replace(/[-_\ ]+([a-z0-9])/gi, ($0, $1) => $1.toUpperCase())
.replace(/[-_ ]+([a-z0-9])/gi, ($0, $1) => $1.toUpperCase())
// lower case first char
s = s[0].toLowerCase() + s.substring(1)
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/day-legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Day {
}

static fromString(dateString: string): Day | undefined {
return Day.from(+dateString.replace(/[^0-9]/g, '').slice(0, 8))
return Day.from(+dateString.replace(/\D/g, '').slice(0, 8))
}

static fromDate(date: Date, utc = false): Day {
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/day.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export function dayFromParts(

export function dayFromString(value: string): DayValue | undefined {
const string = String(value)
.replace(/[^0-9]/g, '')
.replace(/\D/g, '')
.slice(0, 8)
if (string.length === 8)
return +string
Expand Down
4 changes: 2 additions & 2 deletions src/common/data/distributed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Distribute file, named by natural numbers, in a way that each folder only
* contains `maxEntriesPerFolder` subfolders or files. Returns a list of
* names, where the last one is the file name, all others are folder names.
*
* Example: `distributedFilePath(1003)` results in `['2', '1', '3']` which
*
* Example: `distributedFilePath(1003)` results in `['2', '1', '3']` which
* could be translated to the file path `2/1/3.json`.
*/
export function distributedFilePath(index: number, maxEntriesPerFolder: number = 1000): string[] {
Expand Down
1 change: 1 addition & 0 deletions src/common/data/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function isObject(obj: unknown): obj is object {
return obj != null && typeof obj === 'object'
}

// eslint-disable-next-line ts/no-unsafe-function-type
export function isFunction(obj: unknown): obj is Function {
return obj != null && typeof obj === 'function'
}
Expand Down
4 changes: 3 additions & 1 deletion src/common/data/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ function serializer(replacer?: EntryProcessor, cycleReplacer?: EntryProcessor) {
return function (this: EntryProcessor, key: string, value: any): any {
if (stack.length > 0) {
const thisPos = stack.indexOf(this)
// eslint-disable-next-line ts/no-unused-expressions
~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
// eslint-disable-next-line ts/no-unused-expressions
~thisPos ? keys.splice(thisPos, Number.POSITIVE_INFINITY, key) : keys.push(key)
if (~stack.indexOf(value))
value = cycleReplacer?.call(this, key, value)
Expand Down Expand Up @@ -87,7 +89,7 @@ export const jsonStringify = jsonStringifySafe
const suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/

const JsonSigRx = /^["{[]|^-?[0-9][0-9.]{0,14}$/
const JsonSigRx = /^["{[]|^-?\d[0-9.]{0,14}$/

function jsonParseTransform(key: string, value: any): any {
if (key === '__proto__' || key === 'constructor')
Expand Down
3 changes: 2 additions & 1 deletion src/common/data/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export function avg(array: number[]): number {
// https://www.noulakaz.net/2007/03/18/a-regular-expression-to-check-for-prime-numbers/
/** Fancy prime number check ;) */
export function isPrimeRX(value: number): boolean {
return !/^1?$|^(11+?)\1+$/.test('1'.repeat(value))
// eslint-disable-next-line regexp/no-super-linear-backtracking
return !/^1?$|^(1{2,}?)\1+$/.test('1'.repeat(value))
}

export function isPrime(value: number): boolean {
Expand Down
4 changes: 2 additions & 2 deletions src/common/data/object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ describe('objectPlain', () => {
inf: Number.POSITIVE_INFINITY,
err: new Error('err'),
set: new Set([1, { x: 1 }, 3]),
rx: /.*?.test/gim,
rx: /.+?test/gi,
map: new Map<any, any>([
['a', 1],
['b', 2],
Expand Down Expand Up @@ -282,7 +282,7 @@ describe('objectPlain', () => {
},
"rx": Object {
"__class": "RegExp",
"source": "/.*?.test/gim",
"source": "/.+?test/gi",
},
"set": Array [
1,
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const MAX_FILENAME_LENGTH = 100
// const reControlChars = /[\u0000-\u001F\u0080-\u009F]/g
const reRelativePath = /^\.+/
const reTrailingPeriods = /\.+$/
const reFilenameIllegal = /[<>:\"/\\|?*\u0000-\u001F\u0080-\u009F]+/gm // https://superuser.com/questions/358855/what-characters-are-safe-in-cross-platform-file-names-for-linux-windows-and-os/358861#358861
const reFilenameIllegal = /[<>:"/\\|?*\u0000-\u001F\u0080-\u009F]+/g // https://superuser.com/questions/358855/what-characters-are-safe-in-cross-platform-file-names-for-linux-windows-and-os/358861#358861

function filenameReservedRegex() {
return reFilenameIllegal // /[<>:"/\\|?*\u0000-\u001F]/g
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/regexp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rxEscape = /[\\\-\[\]\/{}()*+?.^$|]/g // Finds: \ - [ ] / { } ( ) * + ? . ^ $ |
const rxEscape = /[\\\-[\]/{}()*+?.^$|]/g // Finds: \ - [ ] / { } ( ) * + ? . ^ $ |

export function escapeRegExp(value: RegExp | string): string {
if (!value)
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/string-deburr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ const deburredLetters = {
let deburrLetter: any

/** Used to match Latin Unicode letters (excluding mathematical operators). */
const reLatin = /[\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u017F]/g
const reLatin = /[\xD8-\xF6\u0100-\u017F]/gi

/**
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { escapeHTML } from './html'

const findURL = /((?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00A1-\uFFFF][a-z0-9\u00A1-\uFFFF_-]{0,62})?[a-z0-9\u00A1-\uFFFF]\.)+(?:[a-z\u00A1-\uFFFF]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?)/gim
const findURL = /((?:(?:https?|ftp):)?\/\/(?:\S+@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4])|(?:(?:[a-z0-9\u00A1-\uFFFF][\w\u00A1-\uFFFF-]{0,62})?[a-z0-9\u00A1-\uFFFF]\.)+[a-z\u00A1-\uFFFF]{2,}\.?)(?::\d{2,5})?(?:[/?#]\S*)?)/gi

export function linkifyPlainText(text: string): string {
return text
Expand Down
10 changes: 6 additions & 4 deletions src/common/data/xrx.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/* eslint-disable no-cond-assign */

const RX_WHITESPACE = /\\\s|\s+|#[^\n]*\n?/gm
const RX_REAL_GROUPS = /\(\?P?<(\w[\w\d_]+)>|\((?!\?(:|\!|=|<=|<\!))/gm
const RX_WHITESPACE = /\\\s|\s+|#[^\n]*\n?/g
const RX_REAL_GROUPS = /\(\?P?<(\w{2,})>|\((?!\?([:!=]|<=|<!))/g
// eslint-disable-next-line regexp/no-unused-capturing-group
const RX_LOOK_BEHIND = /^((?:\(\?[\w$]+\))?)\(\?<([=!])([\s\S]*?)\)/gm

export function regExpString(rx: string | RegExp): string {
return typeof rx === 'string' ? rx : (rx.source || '')
}

export function regExpEscape(str: string): string {
return str.replace(/[-\[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}

export class XRX {
Expand Down Expand Up @@ -53,8 +54,9 @@ export class XRX {
name !== 'index'
&& name !== 'length'
&& !this.namedGroups[name]
)
) {
this.namedGroups[name] = index
}
// else
// log.error(`Unallowed or duplicate group name: ${name}`)

Expand Down
2 changes: 1 addition & 1 deletion src/common/dispose-defer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DefaultLogger } from './log'
import type { LoggerInterface } from './log/log-base'

export function polyfillUsing() {
try {
try {
// @ts-expect-error just a polyfill
Symbol.dispose ??= Symbol('Symbol.dispose')
// @ts-expect-error just a polyfill
Expand Down
11 changes: 4 additions & 7 deletions src/common/exec/throttle-debounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function throttle<F extends (...args: any[]) => any>(
} {
const { delay = 100, trailing = true, leading = true } = opt

let timeoutID: any = 0
let timeoutID: any
let checkpoint = 0
let visited = 0
let trailingExec: () => void | undefined
Expand Down Expand Up @@ -99,7 +99,7 @@ export function throttle<F extends (...args: any[]) => any>(
// Delay. We should not get here if timeout has not been reached before
timeoutID = setTimeout(() => {
// DEBUG && log('⏱ reached timeout', debugElapsed())
timeoutID = 0
clearExistingTimeout()
// Only execute on trailing or when visited again, but do not twice if leading
if (trailing && (!leading || visited > 0)) {
// DEBUG && log('🚀 trailing', debugElapsed())
Expand Down Expand Up @@ -149,16 +149,15 @@ export function debounce<F extends (...args: any[]) => any | Promise<any>>(
dispose: () => void
} {
const { delay = 100 } = opt
let timeoutID: any = 0

let timeoutID: any
let running = false
let lastArguments: any[] | undefined

function clearExistingTimeout() {
if (timeoutID) {
// log('clear')
clearTimeout(timeoutID)
timeoutID = 0
timeoutID = undefined
}
}

Expand All @@ -176,7 +175,6 @@ export function debounce<F extends (...args: any[]) => any | Promise<any>>(
if (lastArguments != null) {
clearExistingTimeout()
// log('exec trigger next')

timeoutID = setTimeout(exec, delay)
}
}
Expand All @@ -189,7 +187,6 @@ export function debounce<F extends (...args: any[]) => any | Promise<any>>(
clearExistingTimeout()
// log('trigger')
if (running === false)

timeoutID = setTimeout(exec, delay)
}

Expand Down
1 change: 1 addition & 0 deletions src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './network'
export * from './platform'
export * from './storage'
export * from './time'
export * from './timeout'
export * from './types'
export * from './utils'
export * from './uuid'
Loading

0 comments on commit c8b1b81

Please sign in to comment.