CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web3-utils

Collection of utility functions used in web3.js for Ethereum dApp development

Pending
Overview
Eval results
Files

promises.mddocs/

Promise Utilities

Advanced promise helpers including timeout handling, polling mechanisms, and deferred promise implementation with state tracking. These utilities provide sophisticated asynchronous programming capabilities for Web3 applications.

Capabilities

Promise Detection

/**
 * Checks if object is a Promise
 * @param object - Object to check
 * @returns true if object is a Promise
 */
function isPromise(object: unknown): boolean;

Timeout Utilities

Wait with Timeout

/**
 * Waits for promise with timeout (overloaded function)
 * @param awaitable - Promise or async function to wait for
 * @param timeout - Timeout in milliseconds
 * @param error - Optional error to throw on timeout
 * @returns Promise that resolves with result or undefined on timeout
 */
function waitWithTimeout<T>(
  awaitable: Promise<T> | AsyncFunction<T>, 
  timeout: number, 
  error?: Error
): Promise<T | undefined>;

Timeout Rejection

/**
 * Creates timeout promise that rejects
 * @param timeout - Timeout in milliseconds
 * @param error - Error to reject with
 * @returns Tuple of timer and rejection promise
 */
function rejectIfTimeout(timeout: number, error: Error): [Timer, Promise<never>];

Polling Utilities

Polling with Interval ID

/**
 * Polls function until result is defined, returns interval ID
 * @param func - Async function to poll
 * @param interval - Polling interval in milliseconds
 * @returns Tuple of promise and timer for cleanup
 */
function pollTillDefinedAndReturnIntervalId<T>(
  func: AsyncFunction<T>, 
  interval: number
): [Promise<Exclude<T, undefined>>, Timer];

Simple Polling (Deprecated)

/**
 * Polls function until result is defined
 * @deprecated Use pollTillDefinedAndReturnIntervalId instead
 * @param func - Async function to poll
 * @param interval - Polling interval in milliseconds
 * @returns Promise that resolves when result is defined
 */
function pollTillDefined<T>(
  func: AsyncFunction<T>, 
  interval: number
): Promise<Exclude<T, undefined>>;

Conditional Rejection

/**
 * Rejects if condition met at intervals
 * @param cond - Async condition function
 * @param interval - Check interval in milliseconds
 * @returns Tuple of timer and rejection promise
 */
function rejectIfConditionAtInterval<T>(
  cond: AsyncFunction<T | undefined>, 
  interval: number
): [Timer, Promise<never>];

Deferred Promise

Advanced promise implementation with manual control and state tracking.

/**
 * Deferred promise with state tracking and timeout support
 * Implements Promise interface and additional Web3DeferredPromiseInterface
 */
class Web3DeferredPromise<T> implements Promise<T>, Web3DeferredPromiseInterface<T> {
  /**
   * Promise string tag for debugging
   */
  readonly [Symbol.toStringTag]: 'Promise';

  /**
   * Current state of the promise
   */
  readonly state: 'pending' | 'fulfilled' | 'rejected';

  /**
   * Creates a new deferred promise
   * @param options - Configuration options
   * @param options.timeout - Timeout in milliseconds
   * @param options.eagerStart - Whether to start timer immediately
   * @param options.timeoutMessage - Custom timeout error message
   */
  constructor(options?: {
    timeout?: number;
    eagerStart?: boolean;
    timeoutMessage?: string;
  });

  /**
   * Promise then method
   * @param onfulfilled - Success callback
   * @param onrejected - Error callback
   * @returns New promise
   */
  then<TResult1 = T, TResult2 = never>(
    onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
  ): Promise<TResult1 | TResult2>;

  /**
   * Promise catch method
   * @param onrejected - Error callback
   * @returns New promise
   */
  catch<TResult = never>(
    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
  ): Promise<T | TResult>;

  /**
   * Promise finally method
   * @param onfinally - Finally callback
   * @returns New promise
   */
  finally(onfinally?: (() => void) | null): Promise<T>;

  /**
   * Manually resolve the promise
   * @param value - Value or promise to resolve with
   */
  resolve(value: T | PromiseLike<T>): void;

  /**
   * Manually reject the promise
   * @param reason - Rejection reason
   */
  reject(reason?: unknown): void;

  /**
   * Start the timeout timer
   */
  startTimer(): void;
}

Usage Examples

Basic Promise Utilities

import { 
  isPromise, waitWithTimeout, pollTillDefinedAndReturnIntervalId 
} from "web3-utils";

// Check if object is promise
const maybePromise = fetch('/api/data');
if (isPromise(maybePromise)) {
  const result = await maybePromise;
}

// Wait with timeout
try {
  const result = await waitWithTimeout(
    fetch('/api/slow-endpoint'),
    5000, // 5 second timeout
    new Error('Request timed out')
  );
  
  if (result === undefined) {
    console.log('Operation timed out');
  } else {
    console.log('Got result:', result);
  }
} catch (error) {
  console.error('Error or timeout:', error);
}

Polling Examples

import { pollTillDefinedAndReturnIntervalId } from "web3-utils";

// Poll for transaction receipt
async function waitForTransactionReceipt(txHash: string) {
  const [receiptPromise, intervalId] = pollTillDefinedAndReturnIntervalId(
    async () => {
      try {
        const receipt = await web3.eth.getTransactionReceipt(txHash);
        return receipt; // Returns undefined if not mined yet
      } catch (error) {
        return undefined; // Continue polling on error
      }
    },
    1000 // Poll every second
  );

  try {
    const receipt = await receiptPromise;
    console.log('Transaction mined:', receipt);
    return receipt;
  } finally {
    clearInterval(intervalId); // Clean up interval
  }
}

// Poll for account balance changes
async function watchBalance(address: string, expectedAmount: string) {
  const [balancePromise, intervalId] = pollTillDefinedAndReturnIntervalId(
    async () => {
      const balance = await web3.eth.getBalance(address);
      return balance >= expectedAmount ? balance : undefined;
    },
    2000 // Poll every 2 seconds
  );

  return balancePromise.finally(() => clearInterval(intervalId));
}

Deferred Promise Examples

import { Web3DeferredPromise } from "web3-utils";

// Basic deferred promise
const deferred = new Web3DeferredPromise<string>();

// Check state
console.log(deferred.state); // "pending"

// Resolve manually
setTimeout(() => {
  deferred.resolve("Hello World");
}, 1000);

const result = await deferred;
console.log(result); // "Hello World"
console.log(deferred.state); // "fulfilled"

// Deferred promise with timeout
const deferredWithTimeout = new Web3DeferredPromise<number>({
  timeout: 5000,
  eagerStart: true,
  timeoutMessage: "Operation timed out after 5 seconds"
});

// Will automatically reject after 5 seconds if not resolved
try {
  // Simulate slow operation
  setTimeout(() => {
    deferredWithTimeout.resolve(42);
  }, 3000);

  const result = await deferredWithTimeout;
  console.log('Result:', result); // 42
} catch (error) {
  console.error('Timeout error:', error);
}

Advanced Usage Patterns

import { 
  Web3DeferredPromise, rejectIfTimeout, rejectIfConditionAtInterval 
} from "web3-utils";

// Custom timeout with cleanup
async function fetchWithCustomTimeout<T>(
  operation: Promise<T>, 
  timeoutMs: number
): Promise<T> {
  const [timeoutTimer, timeoutPromise] = rejectIfTimeout(
    timeoutMs, 
    new Error(`Operation timed out after ${timeoutMs}ms`)
  );

  try {
    return await Promise.race([operation, timeoutPromise]);
  } finally {
    clearTimeout(timeoutTimer);
  }
}

// Conditional timeout based on external condition
async function fetchWithConditionalTimeout<T>(
  operation: Promise<T>,
  shouldCancel: () => Promise<boolean>
): Promise<T> {
  const [conditionTimer, conditionPromise] = rejectIfConditionAtInterval(
    shouldCancel,
    1000 // Check every second
  );

  try {
    return await Promise.race([operation, conditionPromise]);
  } finally {
    clearInterval(conditionTimer);
  }
}

// Usage
let cancelled = false;
const result = await fetchWithConditionalTimeout(
  longRunningOperation(),
  async () => cancelled
);

// Cancel after 10 seconds
setTimeout(() => { cancelled = true; }, 10000);

Types

// Type definitions for promise utilities
type AsyncFunction<T, K = unknown> = (...args: K[]) => Promise<T>;
type Timer = ReturnType<typeof setInterval>;
type Timeout = ReturnType<typeof setTimeout>;

interface Web3DeferredPromiseInterface<T> {
  readonly state: 'pending' | 'fulfilled' | 'rejected';
  resolve(value: T | PromiseLike<T>): void;
  reject(reason?: unknown): void;
  startTimer(): void;
}

Install with Tessl CLI

npx tessl i tessl/npm-web3-utils

docs

conversion.md

data-manipulation.md

events.md

hashing.md

index.md

json-rpc.md

promises.md

providers.md

random-validation.md

tile.json