declare module "bun" { type HMREventNames = | "beforeUpdate" | "afterUpdate" | "beforeFullReload" | "beforePrune" | "invalidate" | "error" | "ws:disconnect" | "ws:connect"; /** * The event names for the dev server */ type HMREvent = `bun:${HMREventNames}` | (string & {}); } interface ImportMeta { /** * Hot module replacement APIs. This value is `undefined` in production and * can be used in an `if` statement to check if HMR APIs are available * * ```ts * if (import.meta.hot) { * // HMR APIs are available * } * ``` * * However, this check is usually not needed as Bun will dead-code-eliminate * calls to all of the HMR APIs in production builds. * * https://bun.sh/docs/bundler/hmr */ hot: { /** * `import.meta.hot.data` maintains state between module instances during * hot replacement, enabling data transfer from previous to new versions. * When `import.meta.hot.data` is written to, Bun will mark this module as * capable of self-accepting (equivalent of calling `accept()`). * * @example * ```ts * const root = import.meta.hot.data.root ??= createRoot(elem); * root.render(); // re-use an existing root * ``` * * In production, `data` is inlined to be `{}`. This is handy because Bun * knows it can minify `{}.prop ??= value` into `value` in production. */ data: any; /** * Indicate that this module can be replaced simply by re-evaluating the * file. After a hot update, importers of this module will be * automatically patched. * * When `import.meta.hot.accept` is not used, the page will reload when * the file updates, and a console message shows which files were checked. * * @example * ```ts * import { getCount } from "./foo"; * * console.log("count is ", getCount()); * * import.meta.hot.accept(); * ``` */ accept(): void; /** * Indicate that this module can be replaced by evaluating the new module, * and then calling the callback with the new module. In this mode, the * importers do not get patched. This is to match Vite, which is unable * to patch their import statements. Prefer using `import.meta.hot.accept()` * without an argument as it usually makes your code easier to understand. * * When `import.meta.hot.accept` is not used, the page will reload when * the file updates, and a console message shows which files were checked. * * @example * ```ts * export const count = 0; * * import.meta.hot.accept((newModule) => { * if (newModule) { * // newModule is undefined when SyntaxError happened * console.log('updated: count is now ', newModule.count) * } * }); * ``` * * In production, calls to this are dead-code-eliminated. */ accept(cb: (newModule: any | undefined) => void): void; /** * Indicate that a dependency's module can be accepted. When the dependency * is updated, the callback will be called with the new module. * * When `import.meta.hot.accept` is not used, the page will reload when * the file updates, and a console message shows which files were checked. * * @example * ```ts * import.meta.hot.accept('./foo', (newModule) => { * if (newModule) { * // newModule is undefined when SyntaxError happened * console.log('updated: count is now ', newModule.count) * } * }); * ``` */ accept(specifier: string, callback: (newModule: any) => void): void; /** * Indicate that a dependency's module can be accepted. This variant * accepts an array of dependencies, where the callback will receive * the one updated module, and `undefined` for the rest. * * When `import.meta.hot.accept` is not used, the page will reload when * the file updates, and a console message shows which files were checked. */ accept(specifiers: string[], callback: (newModules: (any | undefined)[]) => void): void; /** * Attach an on-dispose callback. This is called: * - Just before the module is replaced with another copy (before the next is loaded) * - After the module is detached (removing all imports to this module) * * This callback is not called on route navigation or when the browser tab closes. * * Returning a promise will delay module replacement until the module is * disposed. All dispose callbacks are called in parallel. */ dispose(cb: (data: any) => void | Promise): void; /** * No-op * @deprecated */ decline(): void; // NOTE TO CONTRIBUTORS //////////////////////////////////////// // Callback is currently never called for `.prune()` // // so the types are commented out until we support it. // //////////////////////////////////////////////////////////////// // /** // * Attach a callback that is called when the module is removed from the module graph. // * // * This can be used to clean up resources that were created when the module was loaded. // * Unlike `import.meta.hot.dispose()`, this pairs much better with `accept` and `data` to manage stateful resources. // * // * @example // * ```ts // * export const ws = (import.meta.hot.data.ws ??= new WebSocket(location.origin)); // * // * import.meta.hot.prune(() => { // * ws.close(); // * }); // * ``` // */ // prune(callback: () => void): void; /** * Listen for an event from the dev server * * For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*. * * https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off * @param event The event to listen to * @param callback The callback to call when the event is emitted */ on(event: Bun.HMREvent, callback: () => void): void; /** * Stop listening for an event from the dev server * * For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*. * * https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off * @param event The event to stop listening to * @param callback The callback to stop listening to */ off(event: Bun.HMREvent, callback: () => void): void; }; }