kopia lustrzana https://github.com/Tldraw/Tldraw
98 wiersze
2.1 KiB
TypeScript
98 wiersze
2.1 KiB
TypeScript
import { isPlainObject } from 'is-plain-object'
|
|
import { nanoid } from 'nanoid'
|
|
|
|
/**
|
|
* Generate a unique id.
|
|
*
|
|
* @example
|
|
*
|
|
* ```ts
|
|
* const id = uniqueId()
|
|
* ```
|
|
*
|
|
* @public
|
|
*/
|
|
export function uniqueId() {
|
|
return nanoid()
|
|
}
|
|
|
|
const serializableTypes = new Set(['string', 'number', 'boolean', 'undefined'])
|
|
|
|
/**
|
|
* Get whether a value is serializable.
|
|
*
|
|
* @example
|
|
*
|
|
* ```ts
|
|
* const A = isSerializable(1) // true
|
|
* const B = isSerializable('a') // true
|
|
* const C = isSerializable(true) // true
|
|
* const D = isSerializable(undefined) // false
|
|
* ```
|
|
*
|
|
* @param value - The value to check.
|
|
* @public
|
|
*/
|
|
export function isSerializable(value: any): boolean {
|
|
if (serializableTypes.has(typeof value) || value === null) return true
|
|
if (Array.isArray(value)) return value.every(isSerializable)
|
|
if (isPlainObject(value)) return Object.values(value).every(isSerializable)
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Convert a file to base64.
|
|
*
|
|
* @example
|
|
*
|
|
* ```ts
|
|
* const A = fileToBase64('./test.png')
|
|
* ```
|
|
*
|
|
* @param value - The file as a blob.
|
|
* @public
|
|
*/
|
|
export function fileToBase64(file: Blob): Promise<string> {
|
|
return new Promise((resolve, reject) => {
|
|
if (file) {
|
|
const reader = new FileReader()
|
|
reader.readAsDataURL(file)
|
|
reader.onload = () => resolve(reader.result as string)
|
|
reader.onerror = (error) => reject(error)
|
|
reader.onabort = (error) => reject(error)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Get an incremented name (e.g. New page (2)) from a name (e.g. New page), based on an array of
|
|
* existing names.
|
|
*
|
|
* @param name - The name to increment.
|
|
* @param others - The array of existing names.
|
|
* @public
|
|
*/
|
|
export function getIncrementedName(name: string, others: string[]) {
|
|
let result = name
|
|
const set = new Set(others)
|
|
|
|
while (set.has(result)) {
|
|
result = /^.*(\d+)$/.exec(result)?.[1]
|
|
? result.replace(/(\d+)(?=\D?)$/, (m) => {
|
|
return (+m + 1).toString()
|
|
})
|
|
: `${result} 1`
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/** @public */
|
|
export const checkFlag = (flag: boolean | (() => boolean) | undefined) =>
|
|
typeof flag === 'boolean' ? flag : flag?.()
|
|
|
|
/** @public */
|
|
export function snapToGrid(n: number, gridSize: number) {
|
|
return Math.round(n / gridSize) * gridSize
|
|
}
|