@saulx/utils v6.7.0
utils
Saulx utils package
deepEqual
Compare objects
import { stringHash } from '@saulx/utils'
console.log(deepEqual({ a: { b: true } }, { a: { b: true } })) // truedeepCopy
Create a deepcopy of objects
import { deepCopy } from '@saulx/utils'
console.log(deepCopy({ x: true }))deepMerge
Merge an object into another object, arrays are treated as new values
import { deepMerge } from '@saulx/utils'
const a = { x: { a: { c: true, x: [1, 2] } } }
const b = { y: true }
const c = { x: { a: { b: true, x: ['bla'] } } }
console.log(deepMerge(a, b))
console.log(deepMerge(a, b, c))
/*
Logs
{
x: { a: { b: true, c: true, x: ['bla']}},
y: true
}
*/deepMergeArrays
Merge an object into another object, arrays are treated as objects
import { deepMergeArrays } from '@saulx/utils'
const a = { x: { a: { c: true, x: [1, 2, 3] } } }
const b = { y: true }
const c = { x: { a: { b: true, x: ['bla'] } } }
console.log(deepMergeArrays(a, b))
console.log(deepMergeArrays(a, b, c))
/*
Logs
{
x: { a: { b: true, c: true, x: ['bla', 2, 3]}},
y: true
}
*/isObject
Checks if a variable is an object and not an array
import { isObject } from '@saulx/utils'
console.log(isObject({ x: true })) // true
console.log(isObject([1, 2, 3])) // falsewait
Timeout in a promise, default is 100ms
import { wait } from '@saulx/utils'
const somethingAsync = async () => {
await wait() // 100ms
console.log('after 100ms')
await wait(1000)
console.log('after 1100ms')
}
somethingAsync()serializeQuery
Convert an object to a query string
import { serializeQuery } from '@saulx/utils'
const object = { bla: true, a: [1, 2, 3], b: { a: 1 }, c: ['a', 'b', 'c'] }
const queryString = serializeQuery(object)
console.log(queryString) // bla&a=[1,2,3]&b={"a":1}&c=a,b,cparseQuery
Convert a query string to an object
import { parseQuery } from '@saulx/utils'
const result = parseQuery('bla&a=[1,2,3]&b={"a":1}&c=a,b,c')
console.log(result) // { bla:true, a:[1,2,3], b:{a:1}, c:['a','b','c'] }readStream
Sink a read stream into a promise
import { readStream } from '@saulx/utils'
import fs from 'fs'
const aReadStream = fs.createReadStream('somefile')
const myResult = await readStream(aReadStream)toEnvVar
Convert a string to an env-variable safe name
import { toEnvVar } from '@saulx/utils'
const x = toEnvVar('@based/bla-bla-bla$_!')
console.log(x) // BASED_BLA_BLA_BLAstringToUtf8
Convert a string to a utf-8 Uint8 array
import { stringToUtf8 } from '@saulx/utils'
const utf8 = stringToUtf8('hello')
console.log(utf8) // [ 104, 101, 108, 108, 111 ]utf8ToString
Convert a utf8 Uint8 array to a string
import { utf8ToString } from '@saulx/utils'
// hello in utf-8
const utf8 = new Uint8Array([104, 101, 108, 108, 111])
const x = utf8ToString(utf8)
console.log(x) // helloencodeBase64
Convert utf-8 Uint8 array to a base64 string, allows converting 16byte chars. (vs btoa where its not supported)
import { encodeBase64 } from '@saulx/utils'
// hello in utf-8
const utf8 = new Uint8Array([104, 101, 108, 108, 111])
const b64 = encodeBase64(utf8)
console.log(b64) // aGVsbG8=decodeBase64
Decode a base64 string to a utf-8 Uint8 array (vs atob where its not supported)
import { decodeBase64 } from '@saulx/utils'
const utf8 = decodeBase64('aGVsbG8=)
console.log(b64) // [104, 101, 108, 108, 111]createEncoder
Create an encoder similair to encodeUri / decodeUri but with specific strings
Will use [a-z] and [0-9] as encoded variables
import { createEncoder } from '@saulx/utils'
const { encode, decode } = createEncoder(['🥹'], ['@'])
console.log(encode('hello 🥹')) // "hello @a"Can be used with larger strings
import { createEncoder } from '@saulx/utils'
const { encode, decode } = createEncoder(['hello'], ['@'])
console.log(encode('hello 🥹')) // "@a 🥹"padLeft
Add padding to a string
import { padLeft } from '@saulx/utils'
console.log(padLeft('a', 4, 'b')) // "bbba"
const y = padRight('a', 4, 'b')
t.is(y, 'abbb')padRight
Add padding to a string
import { padLeft } from '@saulx/utils'
console.log(padRight('a', 4, 'b')) // "abbb"queued
Pass any async function and queue it based on the arguments, also shares the function execution for the same args
Accepts 10 arguments maximum
import { queued, wait } from '@saulx/utils'
const myFn = queued(async (a: string) => {
await wait(1000)
return a + '!'
})
// will execute bla first then x
await Promise.all([
myFn('bla'),
myFn('x')
myFn('bla') // bla will be shared
])import { queued, wait } from '@saulx/utils'
const myFn = queued(async (a: string) => {
await wait(1000)
return a + '!'
}, {
dedup: (a) => {
// choose the value to use for dedup (to share results)
return a
},
concurrency: 10 // max concurrency of 10
})
// will execute all at the same time (scince concurrency is 10)
// will only execute 'bla' once since it has the same arguments used in id
await Promise.all([
myFn('bla'),
myFn('x')
myFn('bla') // bla will be shared
])getType
Returns a string with the operand/type of the javascrit primitive. Adds 'null' and 'array'.
getType('') // -> "string"
getType('this is a string') // -> "string"
getType(123) // -> "number"
getType(12.3) // -> "number"
getType(-12.3) // -> "number"
getType(-123) // -> "number"
getType(BigInt('1')) // -> "bigint"
getType(true) // -> "boolean"
getType(false) // -> "boolean"
getType(undefined) // -> "undefined"
getType({ a: 'wawa' }) // -> "object"
getType(() => {}) // -> "function"
getType([1, 2, 3]) // -> "array"
getType(null) // -> "null"walker
Generic structure walker. By default walks objects.
const result = []
await walk(objectToWalk, async (item, info) => {
result.push({
value: item,
name: info.name, // property name
path: info.path, // slash separated path in object
type: info.type, // operand type
})
}) // returns voidBy configuring the options you can walk any kind of structure
await walk(
objectToWalk, // starting target
itemFn, // function to run for each matched item
options: {
// check types for details
listFn, // function to list each path. Should return a list of items.
itemMatchFn, // function to choose which items to run itemFn on
recureseFn, // function to choose wchich items to recurse on
targetValidationFn, // function to validate starting path
previousPath, // prefix to add to paths
}
)nonRecursiveWalker
Generic object walker that does not use recursion.
const obj = {
a1: {
a1b1: {
a1b1c1: 'a1b1c1',
a1b1c2: {
a1b1c2d1: 'a1b1c2d1',
},
},
},
a2: 'a2',
a3: {
a3b1: 'a3b1',
},
}
nonRecursiveWalker(
obj, // Object to walk
(
target, // reference to matched property
path, // path as a string[]
type // 0 for property, 1 for object
) => {
if (path.join('.') === 'a1.a1b1') {
console.log('Object found type is 1')
}
if (path.join('.') === 'a2') {
console.log('Property found type is 0')
}
},
true // also match objects
)11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
12 months ago
11 months ago
10 months ago
11 months ago
10 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago