Add more lib docs

This commit is contained in:
Jon Staab
2025-06-04 14:13:45 -07:00
parent d2d0b208ed
commit 95eae509cc
5 changed files with 147 additions and 282 deletions
+23 -124
View File
@@ -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. 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 ```typescript
type CustomPromise<T, E> = Promise<T> & { // Creates a Deferred promise
__errorType: E export declare const defer: <T, E = T>() => Deferred<T, E>;
}
```
A Promise type with strongly typed error information.
### Deferred // Promise with exposed resolve/reject functions and typed error
```typescript export type Deferred<T, E = T> = CustomPromise<T, E> & {
type Deferred<T, E = T> = CustomPromise<T, E> & { resolve: (arg: T) => void;
resolve: (arg: T) => void reject: (arg: E) => void;
reject: (arg: E) => void };
}
```
A Promise with exposed resolve/reject functions and typed error handling.
## Core Functions // Creates a Promise with strongly typed error
export declare function makePromise<T, E>(
### makePromise executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: E) => void) => void,
```typescript ): CustomPromise<T, E>;
function makePromise<T, E>(
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason: E) => void
) => void
): CustomPromise<T, E>
``` ```
Creates a Promise with strongly typed error information. ## Example
### defer
```typescript
function defer<T, E = T>(): Deferred<T, E>
```
Creates a Deferred promise with resolve/reject methods exposed.
## Usage Examples
### Basic Usage
```typescript ```typescript
import { defer } from '@welshman/lib';
// Create a deferred promise // Create a deferred promise
const deferred = defer<string, Error>() const deferred = defer<string>();
// Resolve later // Resolve it externally
setTimeout(() => { setTimeout(() => {
deferred.resolve('Success!') deferred.resolve('Hello, world!');
}, 1000) }, 1000);
// Use like a regular promise // Use it like a regular promise
await deferred // => 'Success!' deferred.then(value => {
``` console.log(value); // "Hello, world!"
});
### With Typed Errors
```typescript
interface ApiError {
code: number
message: string
}
const request = defer<Response, ApiError>()
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<boolean>()
initialize() {
// Setup async operation
this.ready.resolve(true)
}
async waitUntilReady() {
return this.ready
}
}
```
### With Timeout
```typescript
function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
const timeout = defer<T>()
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<T>(
emitter: EventEmitter,
successEvent: string,
errorEvent: string
): Deferred<T, Error> {
const deferred = defer<T, Error>()
emitter.once(successEvent, (data: T) => {
deferred.resolve(data)
})
emitter.once(errorEvent, (error: Error) => {
deferred.reject(error)
})
return deferred
}
``` ```
+37
View File
@@ -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
```
+39 -100
View File
@@ -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. 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 ```typescript
// Create cache with max size // LRU cache implementation
const cache = new LRUCache<string, number>(3) export declare class LRUCache<T, U> {
constructor(maxSize?: number);
// Add items has(k: T): boolean;
cache.set('a', 1) get(k: T): U | undefined;
cache.set('b', 2) set(k: T, v: U): void;
cache.set('c', 3) pop(k: T): U | undefined;
// 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<T, V, Args extends any[]>({
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<V, Args extends any[]>(
getValue: (args: Args) => V
) {
return cached({
maxSize: 100000,
getKey: xs => xs.join(':'),
getValue
})
} }
// Usage // Creates a memoized function with LRU caching
const cachedFn = simpleCache(async (id: string) => { export declare function cached<T, V, Args extends any[]>(options: {
return await expensiveOperation(id) maxSize: number;
}) getKey: (args: Args) => T;
getValue: (args: Args) => V;
}): ((...args: Args) => V) & { cache: LRUCache<T, V>; pop: (...args: Args) => V };
// Creates a simple memoized function with default settings
export declare function simpleCache<V, Args extends any[]>(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<string, number>(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)
``` ```
+11 -13
View File
@@ -2,19 +2,7 @@
A `normalizeUrl` function borrowed from [sindresorhus/normalize-url](https://github.com/sindresorhus/normalize-url) is included for convenience. A `normalizeUrl` function borrowed from [sindresorhus/normalize-url](https://github.com/sindresorhus/normalize-url) is included for convenience.
## Basic Usage ## API
```typescript
normalizeUrl('example')
//=> 'http://example'
normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true});
//=> 'http://sindresorhus.com/about.html'
```
## API Reference
### Configuration
```typescript ```typescript
export type Options = { export type Options = {
@@ -67,3 +55,13 @@ export type Options = {
readonly sortQueryParameters?: boolean readonly sortQueryParameters?: boolean
} }
``` ```
## Example
```typescript
normalizeUrl('example')
//=> 'http://example'
normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true});
//=> 'http://sindresorhus.com/about.html'
```
+37 -45
View File
@@ -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. 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 ```typescript
// Create queue for processing messages // Task queue options
const queue = new TaskQueue<number>({ export type TaskQueueOptions<Item> = {
chunkSize: 10, batchSize: number;
processItem: (n: number) => console.log(n) processItem: (item: Item) => unknown;
}) };
// Add and remove items to/from queue // Task queue implementation
worker.push(10) export declare class TaskQueue<Item> {
worker.push(21) constructor(options: TaskQueueOptions<Item>);
worker.remove(10) push(item: Item): void;
worker.push(57) remove(item: Item): void;
``` subscribe(subscriber: (item: Item) => void): () => void;
process(): Promise<void>;
## Control Methods stop(): void;
start(): void;
Control message processing: clear(): void;
```typescript
// Pause processing
worker.stop()
// Resume processing
worker.start()
// Clear queue
worker.clear()
```
## API Reference
### Constructor
```typescript
class TaskQueue<Item> {
constructor(readonly options: TaskQueueOptions<Item>) {}
} }
``` ```
The TaskQueue class accepts messages of type `Item` and processes them. ## Example
### Configuration
```typescript ```typescript
type TaskQueueOptions<Item> = { import { TaskQueue } from '@welshman/lib';
// How many items to process at a time
batchSize: number
// A function for processing items. Any promises returned will be awaited // Create a task queue that processes 3 items at a time
processItem: (item: Item) => unknown 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"
``` ```