CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rsvp

A lightweight library that provides tools for organizing asynchronous code

Pending
Overview
Eval results
Files

object-utilities.mddocs/

Object Promise Utilities

Functions for working with objects containing promises, useful for handling named async operations and maintaining key-based result organization.

Capabilities

hash

Wait for all promises in an object to fulfill, or fail fast on first rejection.

/**
 * Wait for all object values to resolve, maintaining key structure
 * @param object - Object with promises or values as properties
 * @param label - Optional string for debugging/tooling
 * @returns Promise that fulfills with object containing resolved values
 */
function hash(object: Object, label?: string): Promise;

Usage Examples:

import { hash, resolve } from "rsvp";

// Basic usage with named promises
hash({
  user: fetchUser(123),
  posts: fetchUserPosts(123),
  settings: fetchUserSettings(123)
}).then(function(results) {
  console.log("User:", results.user);
  console.log("Posts:", results.posts);
  console.log("Settings:", results.settings);
}).catch(function(error) {
  console.error("At least one operation failed:", error);
});

// Mixed promises and immediate values
hash({
  immediate: "value",
  promised: resolve("async value"),
  fetched: fetchData()
}).then(function(results) {
  // results.immediate === "value"
  // results.promised === "async value"
  // results.fetched === result from fetchData()
});

// Nested object structure
hash({
  api: {
    users: fetchUsers(),
    posts: fetchPosts()
  },
  config: loadConfig(),
  permissions: checkPermissions()
}).then(function(results) {
  // Note: Only top-level values are processed
  // results.api will be the literal object, not processed
  console.log("Config:", results.config);
  console.log("Permissions:", results.permissions);
});

hashSettled

Wait for all promises in an object to settle (fulfill or reject), collecting all results with state information.

/**
 * Wait for all object values to settle regardless of outcome
 * @param object - Object with promises or values as properties
 * @param label - Optional string for debugging/tooling
 * @returns Promise with object containing {state, value/reason} for each key
 */
function hashSettled(object: Object, label?: string): Promise;

Usage Examples:

import { hashSettled, resolve, reject } from "rsvp";

hashSettled({
  success: resolve("worked"),
  failure: reject(new Error("failed")),
  immediate: 42
}).then(function(results) {
  // results.success === { state: 'fulfilled', value: 'worked' }
  // results.failure === { state: 'rejected', reason: Error }
  // results.immediate === { state: 'fulfilled', value: 42 }
  
  // Process results based on state
  Object.keys(results).forEach(key => {
    const result = results[key];
    if (result.state === 'fulfilled') {
      console.log(`${key} succeeded:`, result.value);
    } else {
      console.error(`${key} failed:`, result.reason);
    }
  });
});

// Practical example: Multiple API endpoints
hashSettled({
  users: fetch('/api/users').then(r => r.json()),
  posts: fetch('/api/posts').then(r => r.json()),
  comments: fetch('/api/comments').then(r => r.json())
}).then(function(results) {
  const successful = Object.keys(results)
    .filter(key => results[key].state === 'fulfilled')
    .reduce((acc, key) => {
      acc[key] = results[key].value;
      return acc;
    }, {});
  
  const failed = Object.keys(results)
    .filter(key => results[key].state === 'rejected')
    .map(key => ({ endpoint: key, error: results[key].reason }));
    
  console.log("Loaded data:", successful);
  if (failed.length > 0) {
    console.warn("Failed endpoints:", failed);
  }
});

Key Features and Limitations

Prototype Chain Handling

Both hash and hashSettled work only with own properties, not inherited properties:

import { hash, resolve } from "rsvp";

function MyConstructor() {
  this.example = resolve('Example');
}

MyConstructor.prototype = {
  protoProperty: resolve('Proto Property')
};

const myObject = new MyConstructor();

hash(myObject).then(function(result) {
  // result.example === 'Example' (own property)
  // result.protoProperty is undefined (inherited property ignored)
  console.log(result.hasOwnProperty('protoProperty')); // false
});

Type Validation

Both functions validate that the input is a proper object:

import { hash, hashSettled } from "rsvp";

// These will throw TypeError
hash(null).catch(error => console.error(error.message)); 
// "Promise.hash must be called with an object"

hashSettled("not an object").catch(error => console.error(error.message));
// "hashSettled must be called with an object"

// Valid inputs
hash({}); // Empty object - resolves immediately
hash({ key: "value" }); // Object with properties

Error Handling Patterns

import { hash, hashSettled } from "rsvp";

// hash - fail fast on first rejection
hash({
  good: resolve("success"),
  bad: reject(new Error("failure")),
  other: resolve("ignored") // Won't be processed due to early failure
}).catch(function(error) {
  console.error("First error encountered:", error);
});

// hashSettled - collect all results
hashSettled({
  good: resolve("success"),
  bad: reject(new Error("failure")),
  other: resolve("also processed")
}).then(function(results) {
  // All operations completed, check individual states
  const hasFailures = Object.values(results)
    .some(result => result.state === 'rejected');
});

Common Use Cases

API Data Loading

// Load related data sets
hash({
  profile: fetchUserProfile(userId),
  preferences: fetchUserPreferences(userId),
  notifications: fetchNotifications(userId)
}).then(function(data) {
  renderUserDashboard(data.profile, data.preferences, data.notifications);
});

Configuration Loading

// Load multiple config sources with fallback handling
hashSettled({
  userConfig: loadUserConfig(),
  defaultConfig: loadDefaultConfig(),
  envConfig: loadEnvironmentConfig()
}).then(function(configs) {
  const mergedConfig = Object.values(configs)
    .filter(c => c.state === 'fulfilled')
    .map(c => c.value)
    .reduce((merged, config) => ({ ...merged, ...config }), {});
});

Install with Tessl CLI

npx tessl i tessl/npm-rsvp

docs

array-utilities.md

configuration.md

index.md

node-integration.md

object-utilities.md

promise.md

utilities.md

tile.json