UNPKG

defer-close

Version:

A lightweight utility for adding JavaScript's Disposable and AsyncDisposable interfaces to any object

127 lines (93 loc) 3.26 kB
# defer-close A lightweight utility for adding JavaScript's Disposable and AsyncDisposable interfaces to any object. This makes it easy to use automatic resource cleanup with `using` and `await using` statements. [![npm version](https://img.shields.io/npm/v/defer-close.svg)](https://www.npmjs.com/package/defer-close) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Installation ```bash # Using npm npm install defer-close # Using yarn yarn add defer-close # Using pnpm pnpm add defer-close # Using bun bun add defer-close ``` ## Usage ```typescript import deferClose from 'defer-close'; // Example with synchronous cleanup function openResource() { const resource = { data: 'important data' }; // Return a disposable version of the resource return deferClose(resource, (res) => { console.log('Resource closed:', res.data); // Cleanup logic here }); } // Using the "using" statement (ES2022+) { using resource = openResource(); // Use the resource... } // Resource automatically cleaned up here // Example with asynchronous cleanup function openAsyncResource() { const resource = { connection: 'db connection', cache: new Map() }; return deferClose(resource, async (res) => { console.log('Closing connection:', res.connection); await someAsyncCleanup(); res.cache.clear(); }); } // Using with "await using" statement async function example() { { await using dbResource = openAsyncResource(); // Use the resource... } // Resource automatically cleaned up here, even if an exception occurs } ``` ## Real-World Example Here's a practical example showing how to use `defer-close` with a POP3 email connection: ```typescript import deferClose from 'defer-close'; import { Pop3Command } from 'your-pop3-library'; // Helper function for required environment variables const DIE = (msg: string) => { throw new Error(msg); }; async function fetchEmails() { // Create a disposable POP3 connection await using pop3 = deferClose(new Pop3Command({ user: process.env.POP3_USER ?? DIE("missing POP3_USER"), password: process.env.POP3_PASS ?? DIE("missing POP3_PASS"), host: "pop.gmail.com", port: 995, tls: true, }), async (pop3) => { console.log('Closing connection...'); await pop3.QUIT(); }); // Use the POP3 connection to fetch emails const messageList = await pop3.LIST(); console.log(`Found ${messageList.length} messages`); // Process emails... return messageList; // Connection will be automatically closed when exiting this function // The QUIT command will be called automatically } ``` This example demonstrates how `defer-close` ensures proper resource cleanup even in complex scenarios like network connections. ## API ### deferClose<T>(obj: T, fn: (obj: T) => any): T & Disposable & AsyncDisposable Adds Disposable and AsyncDisposable interfaces to an object. - `obj`: The object to make disposable - `fn`: A function that will be called when the resource is disposed. Can be synchronous or asynchronous. Returns the original object enhanced with Disposable and AsyncDisposable interfaces. ## Testing ```bash bun test ``` ## License MIT © snomiao