From 95eae509ccd28dbdff3bf47e3b325ae346ea05d3 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Wed, 4 Jun 2025 14:13:45 -0700 Subject: [PATCH] Add more lib docs --- docs/lib/deferred.md | 147 ++++++-------------------------------- docs/lib/emitter.md | 37 ++++++++++ docs/lib/lru.md | 139 ++++++++++------------------------- docs/lib/normalize-url.md | 24 +++---- docs/lib/task-queue.md | 82 ++++++++++----------- 5 files changed, 147 insertions(+), 282 deletions(-) create mode 100644 docs/lib/emitter.md diff --git a/docs/lib/deferred.md b/docs/lib/deferred.md index 8706e89..f3e684a 100644 --- a/docs/lib/deferred.md +++ b/docs/lib/deferred.md @@ -2,140 +2,39 @@ The `Deferred` module provides utilities for creating promises with exposed resolve/reject functions and typed error handling. This is particularly useful for managing asynchronous operations where you need external control over promise resolution. -## Types +## API -### CustomPromise ```typescript -type CustomPromise = Promise & { - __errorType: E -} -``` -A Promise type with strongly typed error information. +// Creates a Deferred promise +export declare const defer: () => Deferred; -### Deferred -```typescript -type Deferred = CustomPromise & { - resolve: (arg: T) => void - reject: (arg: E) => void -} -``` -A Promise with exposed resolve/reject functions and typed error handling. +// Promise with exposed resolve/reject functions and typed error +export type Deferred = CustomPromise & { + resolve: (arg: T) => void; + reject: (arg: E) => void; +}; -## Core Functions - -### makePromise -```typescript -function makePromise( - executor: ( - resolve: (value: T | PromiseLike) => void, - reject: (reason: E) => void - ) => void -): CustomPromise +// Creates a Promise with strongly typed error +export declare function makePromise( + executor: (resolve: (value: T | PromiseLike) => void, reject: (reason: E) => void) => void, +): CustomPromise; ``` -Creates a Promise with strongly typed error information. - -### defer -```typescript -function defer(): Deferred -``` - -Creates a Deferred promise with resolve/reject methods exposed. - -## Usage Examples - -### Basic Usage +## Example ```typescript +import { defer } from '@welshman/lib'; + // Create a deferred promise -const deferred = defer() +const deferred = defer(); -// Resolve later +// Resolve it externally setTimeout(() => { - deferred.resolve('Success!') -}, 1000) + deferred.resolve('Hello, world!'); +}, 1000); -// Use like a regular promise -await deferred // => 'Success!' -``` - -### With Typed Errors - -```typescript -interface ApiError { - code: number - message: string -} - -const request = defer() - -try { - const response = await fetch('/api') - request.resolve(response) -} catch (error) { - request.reject({ - code: 500, - message: error.message - }) -} -``` - -### External Promise Control - -```typescript -class AsyncOperation { - private ready = defer() - - initialize() { - // Setup async operation - this.ready.resolve(true) - } - - async waitUntilReady() { - return this.ready - } -} -``` - -### With Timeout - -```typescript -function withTimeout(promise: Promise, ms: number): Promise { - const timeout = defer() - - setTimeout(() => { - timeout.reject(new Error('Timeout')) - }, ms) - - return Promise.race([promise, timeout]) -} - -// Usage -try { - const result = await withTimeout(slowOperation(), 5000) -} catch (error) { - console.log('Operation timed out') -} -``` - -### Event to Promise - -```typescript -function eventToPromise( - emitter: EventEmitter, - successEvent: string, - errorEvent: string -): Deferred { - const deferred = defer() - - emitter.once(successEvent, (data: T) => { - deferred.resolve(data) - }) - - emitter.once(errorEvent, (error: Error) => { - deferred.reject(error) - }) - - return deferred -} +// Use it like a regular promise +deferred.then(value => { + console.log(value); // "Hello, world!" +}); ``` diff --git a/docs/lib/emitter.md b/docs/lib/emitter.md new file mode 100644 index 0000000..8709b74 --- /dev/null +++ b/docs/lib/emitter.md @@ -0,0 +1,37 @@ +# Event Emitter + +The `Emitter` class extends Node.js EventEmitter to automatically emit all events to `'*'` listeners in addition to specific event listeners. + +## API + +```typescript +// Extended EventEmitter that also emits all events to '*' listeners +export declare class Emitter extends EventEmitter { + // Emits an event to listeners and to '*' listeners + emit(type: string, ...args: any[]): boolean; +} +``` + +## Example + +```typescript +import { Emitter } from '@welshman/lib'; + +const emitter = new Emitter(); + +// Listen for specific events +emitter.on('message', (data) => { + console.log('Message:', data); +}); + +// Listen for all events with '*' +emitter.on('*', (eventType, ...args) => { + console.log('Event:', eventType, args); +}); + +// Emit an event - triggers both listeners +emitter.emit('message', 'Hello world'); +// Output: +// Event: message ['Hello world'] +// Message: Hello world +``` \ No newline at end of file diff --git a/docs/lib/lru.md b/docs/lib/lru.md index f3aab9b..75ee2f3 100644 --- a/docs/lib/lru.md +++ b/docs/lib/lru.md @@ -2,108 +2,47 @@ A LRU (Least Recently Used) Cache implementation provides efficient caching with automatic eviction of least recently used items when the cache reaches its maximum size. -## Basic Usage +## API ```typescript -// Create cache with max size -const cache = new LRUCache(3) - -// Add items -cache.set('a', 1) -cache.set('b', 2) -cache.set('c', 3) - -// Access items -cache.get('a') // => 1 - -// Check if key exists -cache.has('b') // => true - -// Adding beyond max size evicts least recently used -cache.set('d', 4) // Evicts oldest item -``` - -## API Reference - -### Constructor - -```typescript -constructor(maxSize: number = Infinity) -``` - -Creates a new LRU cache with specified maximum size. - -### Methods - -#### set(key: T, value: U) -```typescript -set(key: T, value: U): void -``` -Adds or updates an item in the cache. If cache is at maximum size, evicts least recently used item. - -#### get(key: T) -```typescript -get(key: T): U | undefined -``` -Retrieves item from cache. Also marks item as recently used. - -#### has(key: T) -```typescript -has(key: T): boolean -``` -Checks if key exists in cache without affecting usage tracking. - -## Cache Decorator - -The package also provides a convenient decorator function for creating memoized functions with LRU caching: - -```typescript -function cached({ - maxSize, - getKey, - getValue, -}: { - maxSize: number - getKey: (args: Args) => T - getValue: (args: Args) => V -}): (...args: Args) => V -``` - -### Usage Example - -```typescript -// Create cached function -const getUser = cached({ - maxSize: 1000, - getKey: (args) => args[0], // Use first argument as cache key - getValue: async (args) => { - const [id] = args - return await fetchUser(id) - } -}) - -// Use cached function -const user1 = await getUser(123) -const user2 = await getUser(123) // Returns cached result -``` - -### Simple Cache Helper - -For basic caching needs, there's also a simplified cache creator: - -```typescript -function simpleCache( - getValue: (args: Args) => V -) { - return cached({ - maxSize: 100000, - getKey: xs => xs.join(':'), - getValue - }) +// LRU cache implementation +export declare class LRUCache { + constructor(maxSize?: number); + has(k: T): boolean; + get(k: T): U | undefined; + set(k: T, v: U): void; + pop(k: T): U | undefined; } -// Usage -const cachedFn = simpleCache(async (id: string) => { - return await expensiveOperation(id) -}) +// Creates a memoized function with LRU caching +export declare function cached(options: { + maxSize: number; + getKey: (args: Args) => T; + getValue: (args: Args) => V; +}): ((...args: Args) => V) & { cache: LRUCache; pop: (...args: Args) => V }; + +// Creates a simple memoized function with default settings +export declare function simpleCache(getValue: (args: Args) => V): (...args: Args) => V; +``` + +## Example + +```typescript +import { LRUCache } from '@welshman/lib'; + +// Create cache with max size of 3 +const cache = new LRUCache(3); + +// Add items +cache.set('a', 1); +cache.set('b', 2); +cache.set('c', 3); + +console.log(cache.get('a')); // 1 + +// Adding 'd' will evict 'b' (least recently used) +cache.set('d', 4); + +console.log(cache.has('b')); // false +console.log(cache.has('a')); // true (recently accessed) ``` diff --git a/docs/lib/normalize-url.md b/docs/lib/normalize-url.md index c8b437d..729391b 100644 --- a/docs/lib/normalize-url.md +++ b/docs/lib/normalize-url.md @@ -2,19 +2,7 @@ A `normalizeUrl` function borrowed from [sindresorhus/normalize-url](https://github.com/sindresorhus/normalize-url) is included for convenience. -## Basic Usage - -```typescript -normalizeUrl('example') -//=> 'http://example' - -normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true}); -//=> 'http://sindresorhus.com/about.html' -``` - -## API Reference - -### Configuration +## API ```typescript export type Options = { @@ -67,3 +55,13 @@ export type Options = { readonly sortQueryParameters?: boolean } ``` + +## Example + +```typescript +normalizeUrl('example') +//=> 'http://example' + +normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true}); +//=> 'http://sindresorhus.com/about.html' +``` diff --git a/docs/lib/task-queue.md b/docs/lib/task-queue.md index 398b5e8..958fb69 100644 --- a/docs/lib/task-queue.md +++ b/docs/lib/task-queue.md @@ -2,58 +2,50 @@ The `TaskQueue` class provides a simple queue processing system with batched operations and throttling. It's designed to handle asynchronous operations efficiently while maintaining control over processing rates and resource usage. -## Basic Usage +## API ```typescript -// Create queue for processing messages -const queue = new TaskQueue({ - chunkSize: 10, - processItem: (n: number) => console.log(n) -}) +// Task queue options +export type TaskQueueOptions = { + batchSize: number; + processItem: (item: Item) => unknown; +}; -// Add and remove items to/from queue -worker.push(10) -worker.push(21) -worker.remove(10) -worker.push(57) -``` - -## Control Methods - -Control message processing: - -```typescript -// Pause processing -worker.stop() - -// Resume processing -worker.start() - -// Clear queue -worker.clear() -``` - -## API Reference - -### Constructor - -```typescript -class TaskQueue { - constructor(readonly options: TaskQueueOptions) {} +// Task queue implementation +export declare class TaskQueue { + constructor(options: TaskQueueOptions); + push(item: Item): void; + remove(item: Item): void; + subscribe(subscriber: (item: Item) => void): () => void; + process(): Promise; + stop(): void; + start(): void; + clear(): void; } ``` -The TaskQueue class accepts messages of type `Item` and processes them. - -### Configuration +## Example ```typescript -type TaskQueueOptions = { - // How many items to process at a time - batchSize: number +import { TaskQueue } from '@welshman/lib'; - // A function for processing items. Any promises returned will be awaited - processItem: (item: Item) => unknown -} +// Create a task queue that processes 3 items at a time +const queue = new TaskQueue({ + batchSize: 3, + processItem: async (message: string) => { + console.log('Processing:', message); + // Simulate async work + await new Promise(resolve => setTimeout(resolve, 100)); + } +}); + +// Add items to the queue +queue.push('Message 1'); +queue.push('Message 2'); +queue.push('Message 3'); +queue.push('Message 4'); + +// Items will be processed in batches of 3 +// Output: "Processing: Message 1", "Processing: Message 2", "Processing: Message 3" +// Then: "Processing: Message 4" ``` -