CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-promise

Bare bones Promises/A+ implementation with essential extensions for readable, performant asynchronous operation handling.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

nodejs-integration.mddocs/

Node.js Integration

Utilities for bridging callback-based APIs with promises in Node.js environments, enabling seamless integration between traditional Node.js patterns and promise-based code.

Capabilities

Promise.denodeify

Converts Node.js-style callback functions to promise-returning functions.

/**
 * Converts callback-based function to promise-based function
 * @param {function} fn - Function expecting callback as last parameter
 * @param {number} [argumentCount] - Fixed number of arguments (optimization)
 * @returns {function} Function returning promise instead of using callback
 */
Promise.denodeify(fn, argumentCount);

Usage Examples:

const Promise = require('promise');
const fs = require('fs');

// Convert fs.readFile to promise-based
const readFile = Promise.denodeify(fs.readFile);

readFile('package.json', 'utf8')
  .then(contents => {
    console.log('File contents:', contents);
  })
  .catch(error => {
    console.error('Failed to read file:', error);
  });

// With argument count optimization
const readFileOptimized = Promise.denodeify(fs.readFile, 2);

// Convert multiple functions
const stat = Promise.denodeify(fs.stat);
const writeFile = Promise.denodeify(fs.writeFile);

// Chain converted functions
readFile('input.txt', 'utf8')
  .then(data => data.toUpperCase())
  .then(transformed => writeFile('output.txt', transformed))
  .then(() => console.log('File processed successfully'));

Promise.nodeify

Wraps a promise-returning function to optionally accept Node.js-style callbacks.

/**
 * Wraps promise function to support optional callback parameter
 * @param {function} fn - Function that returns a promise
 * @returns {function} Function that accepts optional callback as last parameter
 */
Promise.nodeify(fn);

Usage Examples:

const Promise = require('promise');

// Promise-based function
function fetchUserData(userId) {
  return Promise.resolve({ id: userId, name: 'John Doe' });
}

// Wrap to support both promises and callbacks
const fetchUser = Promise.nodeify(fetchUserData);

// Use as promise
fetchUser(123)
  .then(user => console.log('Promise:', user))
  .catch(error => console.error('Promise error:', error));

// Use with callback
fetchUser(123, (error, user) => {
  if (error) {
    console.error('Callback error:', error);
  } else {
    console.log('Callback:', user);
  }
});

// Hybrid API example
function createAPI() {
  const getUserData = Promise.nodeify((id) => {
    return fetch(`/api/users/${id}`).then(r => r.json());
  });
  
  return { getUserData };
}

Promise.prototype.nodeify

Calls a Node.js-style callback with the promise result.

/**
 * Calls Node.js callback with promise result
 * @param {function} [callback] - Callback function (error, result)
 * @param {*} [ctx] - Context (this) for callback invocation
 * @returns {Promise|void} Returns this promise if no callback, void otherwise
 */
Promise.prototype.nodeify(callback, ctx);

Usage Examples:

const Promise = require('promise');

// Convert promise to callback style
function getData(callback) {
  return fetchDataPromise()
    .nodeify(callback);
}

// Usage with callback
getData((error, result) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Result:', result);
  }
});

// Usage without callback (returns promise)
getData()
  .then(result => console.log('Promise result:', result))
  .catch(error => console.error('Promise error:', error));

// With context
const api = {
  name: 'MyAPI',
  handleResult(error, data) {
    console.log(`${this.name}:`, error || data);
  }
};

fetchDataPromise().nodeify(api.handleResult, api);

Common Patterns

Converting Entire Modules

const Promise = require('promise');
const fs = require('fs');

// Convert all fs functions to promise-based
const fsPromises = {
  readFile: Promise.denodeify(fs.readFile),
  writeFile: Promise.denodeify(fs.writeFile),
  stat: Promise.denodeify(fs.stat),
  readdir: Promise.denodeify(fs.readdir)
};

// Use promise-based file operations
async function processFiles() {
  const files = await fsPromises.readdir('./data');
  
  for (const file of files) {
    const stats = await fsPromises.stat(`./data/${file}`);
    if (stats.isFile()) {
      const content = await fsPromises.readFile(`./data/${file}`, 'utf8');
      // Process content...
    }
  }
}

Dual Promise/Callback APIs

const Promise = require('promise');

function createDualAPI(promiseFunction) {
  return Promise.nodeify(promiseFunction);
}

// Create API that supports both patterns
const api = {
  fetchUser: createDualAPI((id) => {
    return fetch(`/users/${id}`).then(r => r.json());
  }),
  
  createUser: createDualAPI((userData) => {
    return fetch('/users', {
      method: 'POST',
      body: JSON.stringify(userData)
    }).then(r => r.json());
  })
};

// Use as promises
await api.fetchUser(123);

// Use with callbacks  
api.fetchUser(123, (err, user) => {
  // Handle result
});

Error Handling

const Promise = require('promise');

// denodeify automatically handles callback errors
const readFile = Promise.denodeify(fs.readFile);

readFile('nonexistent.txt')
  .catch(error => {
    console.log(error.code); // 'ENOENT'
    console.log(error.path); // 'nonexistent.txt'
  });

// nodeify converts promise rejections to callback errors
Promise.reject(new Error('Something failed'))
  .nodeify((err, result) => {
    console.log(err.message); // 'Something failed'
    console.log(result);       // undefined
  });

Types

/**
 * Node.js-style callback signature
 * @callback NodeCallback
 * @param {Error|null} error - Error object or null for success
 * @param {*} [result] - Result value (present when error is null)
 */

/**
 * Function expecting Node.js-style callback as last parameter
 * @callback NodeFunction
 * @param {...*} args - Function arguments
 * @param {NodeCallback} callback - Node.js callback as last parameter
 */

Install with Tessl CLI

npx tessl i tessl/npm-promise

docs

core-promise.md

es6-static-methods.md

extension-methods.md

index.md

nodejs-integration.md

rejection-tracking.md

synchronous-inspection.md

tile.json