UNPKG

aveazul

Version:

Bluebird drop-in replacement built on native Promise

209 lines (162 loc) 7.25 kB
# AveAzul.js AveAzul ("Blue Bird" in Spanish) serves as a near drop-in replacement for Bluebird. It's built on native Promise, by extending it with the familiar utility methods from Bluebird. ## Purpose The primary goal is to help migrate legacy code, that uses Bluebird APIs extensively, to native Promises. While not a 100% drop-in replacement (some aspects of Bluebird simply can't be replicated), it offers a practical migration path with minimal changes for most cases. Further, if you like Bluebird's API but want to use native Promises, AveAzul gives you both - familiar Bluebird methods built on native Promise. ## Features - Built on native Promises - Implements most commonly used Bluebird methods - Comprehensive test suite ensuring compatibility ## Requirements - node.js version >= 12 ## Installation ```bash npm install aveazul ``` ## Usage ```javascript const AveAzul = require("aveazul"); // Basic Promise usage const promise = new AveAzul((resolve) => resolve(42)); promise.then((value) => console.log(value)); // 42 // Utility methods AveAzul.resolve([1, 2, 3]) .map((x) => x * 2) .filter((x) => x > 2) .then((result) => console.log(result)); // [4, 6] // Wait for at least 2 promises to be fulfilled const fetchUrls = [ fetch("https://api.example.com/data1"), fetch("https://api.example.com/data2"), fetch("https://api.example.com/data3"), fetch("https://api.example.com/data4"), ]; AveAzul.some(fetchUrls, 2).then((results) => console.log(`Got the first 2 successful results`) ); // Process items sequentially with mapSeries AveAzul.resolve([1, 2, 3]) .mapSeries(async (x) => { // Each item is processed only after the previous one completes await new Promise((resolve) => setTimeout(resolve, 100)); return x * 2; }) .then((result) => console.log(result)); // [2, 4, 6] // Promisify callback-style functions const fs = require("fs"); const readFile = AveAzul.promisify(fs.readFile); readFile("file.txt").then((content) => console.log(content)); // Properties from the original function are preserved console.log(readFile.length); // Original function's length property // Promisify all methods of an object const obj = { method(cb) { cb(null, "result"); }, }; AveAzul.promisifyAll(obj); obj.methodAsync().then((result) => console.log(result)); // 'result' // Resource management with disposer and using const getResource = () => { return AveAzul.resolve({ data: "important data", close: () => console.log("Resource closed!"), }).disposer((resource) => resource.close()); }; AveAzul.using(getResource(), (resource) => { console.log(resource.data); // "important data" return AveAzul.resolve("operation completed"); }).then((result) => { console.log(result); // "operation completed" // Resource is automatically closed here, even if an error occurred }); // Using spread to apply array results as arguments AveAzul.all([getUser(1), getPosts(1), getComments(1)]).spread( (user, posts, comments) => { // Instead of using .then(([user, posts, comments]) => {...}) console.log( `User ${user.name} has ${posts.length} posts and ${comments.length} comments` ); return { user, activity: { posts, comments } }; } ); ``` ## Migration from Bluebird For most applications, migrating from Bluebird to AveAzul should be as simple as: ```javascript // From const Promise = require("bluebird"); // To const Promise = require("aveazul"); ``` Key differences to be aware of: - Some advanced debugging features are not available - Performance characteristics may differ - A few very specialized methods not available ## API ### Instance Methods - `tap(fn)` - Execute side effects and return original value - `filter(fn)` - Filter array elements - `map(fn)` - Transform array elements - `mapSeries(fn)` - Transform array elements sequentially - `return(value)` - Inject a new value - `each(fn)` - Iterate over array elements - `delay(ms)` - Delay resolution - `timeout(ms, message?)` - Reject after specified time - `props(obj)` - Resolve object properties - `spread(fn)` - Apply array values as arguments to function - `tapCatch(fn)` - Execute side effects on rejection - `reduce(fn, initialValue?)` - Reduce array elements - `some(count)` - Resolves when a specified number of promises in the array have resolved - `throw(reason)` - Return rejected promise - `catchThrow(reason)` - Catch and throw new error - `catchReturn(value)` - Catch and return value - `get(propertyPath)` - Retrieve property value - `disposer(fn)` - Create a disposer for use with AveAzul.using() for resource cleanup - `any()` - Resolves when any promise in the iterable resolves, rejecting if all reject - `all()` - Like Promise.all(), resolves when all promises resolve, rejects if any reject - `call(propertyName, ...args)` - Call a method on the resolved value with the provided arguments - `asCallback(callback, options?)` - Register a Node-style callback that handles the resolution or rejection - `error(handler)` - Like catch(), but only catches operational errors, letting programmer errors bubble up ### Static Methods - `delay(ms, value?)` - Resolve after specified time - `map(value, fn)` - Transform array elements - `mapSeries(value, fn)` - Transform array elements one at a time in sequence - `try(fn)` - Wrap sync/async functions - `props(obj)` - Resolve object properties - `defer()` - Create a deferred promise - `promisify(fn, options?)` - Convert callback-style functions to promises (preserves original function properties) - `fromNode(fn, options?)` - Convert Node-style callback functions to promise-returning functions - `fromCallback(fn, options?)` - Alias for fromNode - `each(items, fn)` - Iterate over array elements - `reduce(array, fn, initialValue?)` - Reduce array elements - `some(promises, count)` - Wait for a specified number of promises to be fulfilled - `method(fn)` - Creates a method that returns a promise resolving to the value returned by the original function - `throw(reason)` - Return rejected promise - `promisifyAll(target, options?)` - Convert all methods of an object/class to promises - `using(resources, fn)` - Manage resources with automatic cleanup - `join(...values, handler?)` - Wait for multiple promises and pass their resolved values as separate arguments to the handler function. If no handler is provided, behaves like Promise.all ### Error Types - `AveAzul.OperationalError` - Error type for representing expected operational errors (network failures, validation errors, etc.) ### PromisifyAll Options - `suffix` (default: 'Async') - Suffix to append to promisified method names - `filter` - Filter function to determine which methods to promisify - `promisifier` - Custom function to handle promisification - `multiArgs` (default: false) - Whether to support multiple callback arguments ## Development ```bash # Install dependencies npm install # Run tests npm test npm run test:watch npm run test:coverage # Test against Bluebird for compatibility npm run jest:bluebird -- test/[name].test.js ``` ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## License Apache-2.0 ## Author Joel Chen, with assistant from Cursor Claude-3.7-sonnet