import { nanoid } from 'nanoid'; export function uniqueId(): string { return 'gw_' + nanoid(4); } export type DeepPartial = T extends Array ? T : T extends object ? { [K in keyof T]?: DeepPartial; } : T; export type KVTuple = keyof T extends `${infer R}` ? (R extends keyof T ? [R, T[R]] : never) : never; export type AssertSameKey, T2 extends Record> = never; export type NestedKeyOf = { [Key in keyof T & (string | number)]: T[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf}` : `${Key}`; }[keyof T & (string | number)]; export type TypeOfPath = Path extends `${infer A}.${infer rest}` ? A extends keyof T ? TypeOfPath : never : Path extends keyof T ? T[Path] : never; export type ReplacePathOf = { [K in keyof T]: Path extends `${infer A}.${infer rest}` ? (A extends K ? ReplacePathOf : T[K]) : Path extends K ? U : T[K]; }; export const insert = (arr: T[], item: T, index: number) => index === arr.length ? arr.concat([item]) : arr.flatMap((x, i) => (i === index ? [item, x] : [x])); export const remove = (arr: T[], index: number) => arr.filter((_, i) => i !== index); export const replace = (arr: T[], index: number, f: (item: T) => T) => arr.map((x, i) => (i === index ? f(x) : x)); export function mutPath, U>(item: T, path: P, mut: (x: TypeOfPath) => U): ReplacePathOf { const mod = (d: any, path: string[], f: (x: any) => any) => { const [k, ...rest] = path; if (rest.length === 0) { return { ...d, [k]: f(d[k]), }; } return { ...d, [k]: mod(d[k], rest, f), }; }; return mod(item, path.split('.'), mut); }