From 6235c3f6bb9f571f8121292509d9619a1577fbf1 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Fri, 13 Dec 2024 15:11:48 -0800 Subject: [PATCH] Add more tsdoc comments --- packages/lib/src/Context.ts | 17 +++++++++++++++++ packages/lib/src/Deferred.ts | 11 +++++++++++ packages/lib/src/Emitter.ts | 9 +++++++++ packages/lib/src/LRUCache.ts | 16 ++++++++++++++++ packages/lib/src/Worker.ts | 26 ++++++++++++++++++++++++++ 5 files changed, 79 insertions(+) diff --git a/packages/lib/src/Context.ts b/packages/lib/src/Context.ts index 84dc4a9..604da2f 100644 --- a/packages/lib/src/Context.ts +++ b/packages/lib/src/Context.ts @@ -1,5 +1,22 @@ import type {Context} from '@welshman/lib' +/** + * A global context variable for configuring libraries and applications. + * + * In your application, you'll want to add something like the following to your types.d.ts: + * type MyContext = { + * x: number + * } + * + * declare module "@welshman/lib" { + * interface Context { + * net: MyContext + * } + * } + */ export const ctx: Context = {} +/** + * Adds data to ctx. + */ export const setContext = (newCtx: Context) => Object.assign(ctx, newCtx) diff --git a/packages/lib/src/Deferred.ts b/packages/lib/src/Deferred.ts index 7e37849..d21867d 100644 --- a/packages/lib/src/Deferred.ts +++ b/packages/lib/src/Deferred.ts @@ -1,7 +1,13 @@ +/** Promise type with strongly typed error */ export type CustomPromise = Promise & { __errorType: E } +/** + * Creates a Promise with strongly typed error + * @param executor - Promise executor function + * @returns Promise with typed error + */ export function makePromise( executor: ( resolve: (value: T | PromiseLike) => void, @@ -11,11 +17,16 @@ export function makePromise( return new Promise(executor) as CustomPromise } +/** Promise with exposed resolve/reject functions and typed error */ export type Deferred = CustomPromise & { resolve: (arg: T) => void reject: (arg: E) => void } +/** + * Creates a Deferred promise + * @returns Promise with resolve/reject methods exposed + */ export const defer = (): Deferred => { let resolve, reject const p = makePromise((resolve_, reject_) => { diff --git a/packages/lib/src/Emitter.ts b/packages/lib/src/Emitter.ts index 64470fe..fc0a46f 100644 --- a/packages/lib/src/Emitter.ts +++ b/packages/lib/src/Emitter.ts @@ -1,6 +1,15 @@ import {EventEmitter} from 'events' +/** + * Extended EventEmitter that also emits all events to '*' listeners + */ export class Emitter extends EventEmitter { + /** + * Emits an event to listeners and to '*' listeners + * @param type - Event type/name + * @param args - Arguments to pass to listeners + * @returns True if event had listeners + */ emit(type: string, ...args: any[]) { const a = super.emit(type, ...args) const b = super.emit('*', type, ...args) diff --git a/packages/lib/src/LRUCache.ts b/packages/lib/src/LRUCache.ts index 6546091..4f76fd6 100644 --- a/packages/lib/src/LRUCache.ts +++ b/packages/lib/src/LRUCache.ts @@ -1,3 +1,8 @@ +/** + * Least Recently Used (LRU) cache implementation + * @template T - Type of cache keys + * @template U - Type of cache values + */ export class LRUCache { map = new Map() keys: T[] = [] @@ -32,6 +37,12 @@ export class LRUCache { } } +/** + * Creates a memoized function with LRU caching + * @template T - Cache key type + * @template V - Cache value type + * @template Args - Function argument types + */ export function cached({ maxSize, getKey, @@ -60,6 +71,11 @@ export function cached({ return get } +/** + * Creates a simple memoized function with default settings + * @template V - Cache value type + * @template Args - Function argument types + */ export function simpleCache(getValue: (args: Args) => V) { return cached({maxSize: 10**5, getKey: xs => xs.join(':'), getValue}) } diff --git a/packages/lib/src/Worker.ts b/packages/lib/src/Worker.ts index 382bd06..a4c9777 100644 --- a/packages/lib/src/Worker.ts +++ b/packages/lib/src/Worker.ts @@ -1,12 +1,22 @@ +/** Symbol used to identify global handlers */ const ANY = Symbol("worker/ANY") +/** Configuration options for Worker */ export type WorkerOpts = { + /** Function to get key for message routing */ getKey?: (x: T) => any + /** Function to determine if message processing should be deferred */ shouldDefer?: (x: T) => boolean + /** Maximum number of messages to process in one batch */ chunkSize?: number + /** Milliseconds to wait between processing batches */ delay?: number } +/** + * Worker for processing messages in batches with throttling + * @template T - Type of messages to process + */ export class Worker { buffer: T[] = [] handlers: Map void>> = new Map() @@ -63,23 +73,38 @@ export class Worker { } } + /** + * Adds a message to the processing queue + * @param message - Message to process + */ push = (message: T) => { this.buffer.push(message) this.#enqueueWork() } + /** + * Adds a handler for messages with specific key + * @param k - Key to handle + * @param handler - Function to process matching messages + */ addHandler = (k: any, handler: (message: T) => void) => { this.handlers.set(k, (this.handlers.get(k) || []).concat(handler)) } + /** + * Adds a handler for all messages + * @param handler - Function to process all messages + */ addGlobalHandler = (handler: (message: T) => void) => { this.addHandler(ANY, handler) } + /** Removes all pending messages from the queue */ clear() { this.buffer = [] } + /** Pauses message processing */ pause() { clearTimeout(this.#timeout) @@ -87,6 +112,7 @@ export class Worker { this.#timeout = undefined } + /** Resumes message processing */ resume() { this.#paused = false this.#enqueueWork()