/** * Stabilize a possibly-changing callback so that consumers get a referentially * stable function. In Solid, components don't re-render, so "stability" only * matters when a consumer captures the current callback into something with * its own identity (e.g. a directive, a long-lived subscription). This helper * returns a trampoline whose identity never changes; internally, it dispatches * to whatever `callback` is pointed at when invoked. * * Semantically equivalent to Base UI React's `useStableCallback`, adapted for * Solid's non-rerendering model: instead of keeping a ref synced inside a * layout effect, we mutate the stored callback on every call site so the * latest closure wins at invocation time. * * Important: only call the returned trampoline from event handlers, effects, * or other non-render code. Calling it synchronously during component setup * before the callback it wraps has been assigned is a bug. */ /** * Structural supertype of every function shape users might stabilize. We * lean on `any` here because `unknown[]` wouldn't admit callbacks with * highly specific parameter signatures as subtypes, which would defeat the * purpose of this primitive. */ // biome-ignore-start lint/suspicious/noExplicitAny: see type comment above. export type AnyCallback = (...args: any[]) => any; // biome-ignore-end lint/suspicious/noExplicitAny: see type comment above. export function createStableCallback( getCallback: () => T | undefined, ): T { const trampoline = ((...args: unknown[]) => { const current = getCallback(); return current?.(...args); }) as T; return trampoline; }