# Utilities > Utility functions for async operations and object manipulation. --- ## Overview This directory contains utility modules: - `asyncUtil.ts` - Promise-based async event handling - `objectUtil.ts` - Object manipulation helpers --- ## Async Utilities **File**: `/home/hechang27/Documents/sprt/noob-components/plugs/util/asyncUtil.ts` ### useAsyncEmits Creates a promise-based wrapper around Vue component emit functions. ```typescript export function useAsyncEmits>(emits: (evt: any, ...args: any[]) => void) { const emitsAsync = (evt: Evt, ...args: ExtractArgs) => new Promise>((resolve, reject) => { emits(evt, { resolve, reject }, ...args); }); return emitsAsync; } ``` #### Type Parameters | Parameter | Description | |-----------|-------------| | `Emits` | Record of event names to argument tuple types | #### Handler Type ```typescript export type AsyncHandler = { resolve: (t: T | PromiseLike) => void; reject: (err: any) => void; }; ``` #### Example Usage ```typescript // In parent component const emit = defineEmits<{ (e: 'save', handler: AsyncHandler, data: UserData): void; (e: 'delete', handler: AsyncHandler, id: string): void; }>(); // In child component or hook const emitsAsync = useAsyncEmits(emit); const saveResult = await emitsAsync('save', userData); const deleteResult = await emitsAsync('delete', userId); ``` ### handleAsync Wraps an async function to work with `AsyncHandler`. ```typescript export function handleAsync(handler: (...args: Args) => Promise) { return ({ resolve, reject }: AsyncHandler, ...args: Args) => handler(...args).then(resolve, reject); } ``` #### Example Usage ```typescript const handleSave = handleAsync(async (data: UserData) => { const response = await api.saveUser(data); return response.ok; }); emit('save', handleSave, userData); ``` --- ## Object Utilities **File**: `/home/hechang27/Documents/sprt/noob-components/plugs/util/objectUtil.ts` ### deepCopy Creates a deep clone of an object using lodash. ```typescript import { cloneDeep } from "lodash-es"; export function deepCopy(obj: T): T { return cloneDeep(obj); } ``` **Note**: Uses `lodash-es` for tree-shaking support. ### clearObject Removes all properties from an object. ```typescript export function clearObject(obj: Record) { for (const key in obj) { delete obj[key]; } } ``` ### clearAndAssign Clears target object and assigns all properties from source. ```typescript export function clearAndAssign(target: Record, source: Record) { clearObject(target); Object.assign(target, source); } ``` ### unnest Flattens a nested object property with a prefix. ```typescript export function unnest(obj: Record, key: string, prefix: string) { const { [key]: toFlatten, ...rest } = obj; const prefixed = Object.fromEntries(Object.entries(toFlatten).map(([k, v]) => [prefix.concat(k), v])); return { ...rest, ...prefixed }; } ``` #### Example ```typescript const obj = { name: 'John', metadata: { age: 30, city: 'NYC' } }; const result = unnest(obj, 'metadata', 'metadata.'); // result: { name: 'John', 'metadata.age': 30, 'metadata.city': 'NYC' } ``` --- ## Exports **File**: `/home/hechang27/Documents/sprt/noob-components/plugs/util/index.ts` ```typescript export * from "./asyncUtil"; export * from "./objectUtil"; ``` --- ## Anti-Patterns 1. **Do not use `clearObject` on objects with prototypes** - This only works on plain objects 2. **Do not use deepCopy on objects with circular references** - It will throw an error 3. **Do not forget to import from `lodash-es`** - The main `lodash` package does not support tree-shaking --- **Language**: English