CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lumino--coreutils

Essential utility functions and classes for TypeScript/JavaScript applications including JSON handling, MIME data management, promise delegation, secure tokens, and cross-platform random number generation.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

promise-delegation.mddocs/

Promise Delegation

Promise wrapper that separates promise creation from resolution logic, enabling flexible asynchronous workflows where the resolution logic cannot be defined at the point of promise creation.

Capabilities

PromiseDelegate Class

A class which wraps a promise into a delegate object, allowing external resolution or rejection of the promise.

/**
 * A class which wraps a promise into a delegate object.
 * 
 * Notes:
 * This class is useful when the logic to resolve or reject a promise
 * cannot be defined at the point where the promise is created.
 */
class PromiseDelegate<T> {
  /**
   * Construct a new promise delegate
   */
  constructor();

  /**
   * The promise wrapped by the delegate
   */
  readonly promise: Promise<T>;

  /**
   * Resolve the wrapped promise with the given value
   * @param value - The value to use for resolving the promise
   */
  resolve(value: T | PromiseLike<T>): void;

  /**
   * Reject the wrapped promise with the given value
   * @param reason - The reason for rejecting the promise
   */
  reject(reason: any): void;
}

Usage Examples:

import { PromiseDelegate } from "@lumino/coreutils";

// Basic usage - create a delegate and resolve it later
const delegate = new PromiseDelegate<string>();

// The promise can be awaited or chained
delegate.promise.then(value => {
  console.log("Resolved with:", value);
}).catch(error => {
  console.log("Rejected with:", error);
});

// Later, resolve the promise from elsewhere
setTimeout(() => {
  delegate.resolve("Hello, World!");
}, 1000);

// Or reject it
// delegate.reject(new Error("Something went wrong"));

Common Use Cases

Async Event Handling:

import { PromiseDelegate } from "@lumino/coreutils";

class EventEmitter {
  private listeners = new Map<string, PromiseDelegate<any>[]>();

  // Wait for a specific event to occur
  waitForEvent<T>(eventName: string): Promise<T> {
    const delegate = new PromiseDelegate<T>();
    
    if (!this.listeners.has(eventName)) {
      this.listeners.set(eventName, []);
    }
    this.listeners.get(eventName)!.push(delegate);
    
    return delegate.promise;
  }

  // Emit an event, resolving all waiting promises
  emit<T>(eventName: string, data: T): void {
    const delegates = this.listeners.get(eventName) || [];
    delegates.forEach(delegate => delegate.resolve(data));
    this.listeners.set(eventName, []);
  }
}

// Usage
const emitter = new EventEmitter();
const dataPromise = emitter.waitForEvent<{id: number, name: string}>("user-loaded");

dataPromise.then(userData => {
  console.log("User loaded:", userData.name);
});

// Later, in another part of the application
emitter.emit("user-loaded", { id: 123, name: "Alice" });

Resource Loading:

import { PromiseDelegate } from "@lumino/coreutils";

class ResourceLoader {
  private loadingPromises = new Map<string, PromiseDelegate<any>>();

  loadResource<T>(url: string): Promise<T> {
    // Return existing promise if already loading
    if (this.loadingPromises.has(url)) {
      return this.loadingPromises.get(url)!.promise;
    }

    // Create new delegate for this resource
    const delegate = new PromiseDelegate<T>();
    this.loadingPromises.set(url, delegate);

    // Start loading (could be HTTP request, file read, etc.)
    this.startLoading(url, delegate);

    return delegate.promise;
  }

  private startLoading<T>(url: string, delegate: PromiseDelegate<T>): void {
    // Simulate async loading
    fetch(url)
      .then(response => response.json())
      .then(data => {
        delegate.resolve(data);
        this.loadingPromises.delete(url);
      })
      .catch(error => {
        delegate.reject(error);
        this.loadingPromises.delete(url);
      });
  }
}

// Usage
const loader = new ResourceLoader();
const userPromise = loader.loadResource<{name: string, email: string}>("/api/user/123");
const configPromise = loader.loadResource<{theme: string, locale: string}>("/api/config");

Promise.all([userPromise, configPromise]).then(([user, config]) => {
  console.log(`Hello ${user.name}, your theme is ${config.theme}`);
});

Conditional Resolution:

import { PromiseDelegate } from "@lumino/coreutils";

class ConditionalTask<T> {
  private delegate = new PromiseDelegate<T>();
  private conditions: (() => boolean)[] = [];

  constructor() {}

  get promise(): Promise<T> {
    return this.delegate.promise;
  }

  addCondition(condition: () => boolean): this {
    this.conditions.push(condition);
    this.checkConditions();
    return this;
  }

  setResult(result: T): void {
    this.result = result;
    this.checkConditions();
  }

  setError(error: any): void {
    this.delegate.reject(error);
  }

  private result?: T;

  private checkConditions(): void {
    if (this.result !== undefined && this.conditions.every(cond => cond())) {
      this.delegate.resolve(this.result);
    }
  }
}

// Usage
const task = new ConditionalTask<string>();

let userLoggedIn = false;
let dataLoaded = false;

task
  .addCondition(() => userLoggedIn)
  .addCondition(() => dataLoaded);

task.promise.then(result => {
  console.log("All conditions met:", result);
});

// Simulate conditions being met
setTimeout(() => {
  userLoggedIn = true;
  task.setResult("Task completed!");
}, 1000);

setTimeout(() => {
  dataLoaded = true;
}, 1500);

Timeout with Cleanup:

import { PromiseDelegate } from "@lumino/coreutils";

function withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {
  const delegate = new PromiseDelegate<T>();
  let timeoutId: number;

  // Race between the original promise and timeout
  promise.then(
    value => {
      clearTimeout(timeoutId);
      delegate.resolve(value);
    },
    error => {
      clearTimeout(timeoutId);
      delegate.reject(error);
    }
  );

  timeoutId = setTimeout(() => {
    delegate.reject(new Error(`Operation timed out after ${timeoutMs}ms`));
  }, timeoutMs);

  return delegate.promise;
}

// Usage
const slowOperation = new Promise(resolve => {
  setTimeout(() => resolve("Done!"), 5000);
});

const fastTimeout = withTimeout(slowOperation, 2000);

fastTimeout.catch(error => {
  console.log(error.message); // "Operation timed out after 2000ms"
});

docs

index.md

json-utilities.md

mime-data.md

promise-delegation.md

random-generation.md

token-system.md

uuid-generation.md

tile.json