Tldraw/apps/docs/utils/debounce.ts

55 wiersze
1.1 KiB
TypeScript

/**
* Debounce a function.
*
* @example
*
* ```ts
* const A = debounce(myFunction, 1000)
* ```
*
* @public
* @see source - https://gist.github.com/ca0v/73a31f57b397606c9813472f7493a940
*/
export function debounce<T extends unknown[], U>(
callback: (...args: T) => PromiseLike<U> | U,
wait: number
) {
let state:
| undefined
| {
timeout: ReturnType<typeof setTimeout>
promise: Promise<U>
Move from function properties to methods (#4288) Things left to do - [x] Update docs (things like the [tools page](https://tldraw-docs-fqnvru1os-tldraw.vercel.app/docs/tools), possibly more) - [x] Write a list of breaking changes and how to upgrade. - [x] Do another pass and check if we can update any lines that have `@typescript-eslint/method-signature-style` and `local/prefer-class-methods` disabled - [x] Thinks about what to do with `TLEventHandlers`. Edit: Feels like keeping them is the best way to go. - [x] Remove `override` keyword where it's not needed. Not sure if it's worth the effort. Edit: decided not to spend time here. - [ ] What about possible detached / destructured uses? Fixes https://github.com/tldraw/tldraw/issues/2799 ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [x] `api` - [ ] `other` ### Test plan 1. Create a shape... 2. - [ ] Unit tests - [ ] End to end tests ### Release notes - Adds eslint rules for enforcing the use of methods instead of function properties and fixes / disables all the resulting errors. # Breaking changes This change affects the syntax of how the event handlers for shape tools and utils are defined. ## Shape utils **Before** ```ts export class CustomShapeUtil extends ShapeUtil<CustomShape> { // Defining flags override canEdit = () => true // Defining event handlers override onResize: TLOnResizeHandler<CustomShape> = (shape, info) => { ... } } ``` **After** ```ts export class CustomShapeUtil extends ShapeUtil<CustomShape> { // Defining flags override canEdit() { return true } // Defining event handlers override onResize(shape: CustomShape, info: TLResizeInfo<CustomShape>) { ... } } ``` ## Tools **Before** ```ts export class CustomShapeTool extends StateNode { // Defining child states static override children = (): TLStateNodeConstructor[] => [Idle, Pointing] // Defining event handlers override onKeyDown: TLEventHandlers['onKeyDown'] = (info) => { ... } } ``` **After** ```ts export class CustomShapeTool extends StateNode { // Defining child states static override children(): TLStateNodeConstructor[] { return [Idle, Pointing] } // Defining event handlers override onKeyDown(info: TLKeyboardEventInfo) { ... } } ``` --------- Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com> Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-07-29 13:40:18 +00:00
resolve(value: U | PromiseLike<U>): void
reject(value: any): void
latestArgs: T
} = undefined
const fn = (...args: T): Promise<U> => {
if (!state) {
state = {} as any
state!.promise = new Promise((resolve, reject) => {
state!.resolve = resolve
state!.reject = reject
})
}
clearTimeout(state!.timeout)
state!.latestArgs = args
state!.timeout = setTimeout(() => {
const s = state!
state = undefined
try {
s.resolve(callback(...s.latestArgs))
} catch (e) {
s.reject(e)
}
}, wait)
return state!.promise
}
fn.cancel = () => {
if (!state) return
clearTimeout(state.timeout)
}
return fn
}