Add more lib docs
This commit is contained in:
+23
-124
@@ -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<T, E> = Promise<T> & {
|
||||
__errorType: E
|
||||
}
|
||||
```
|
||||
A Promise type with strongly typed error information.
|
||||
// Creates a Deferred promise
|
||||
export declare const defer: <T, E = T>() => Deferred<T, E>;
|
||||
|
||||
### Deferred
|
||||
```typescript
|
||||
type Deferred<T, E = T> = CustomPromise<T, E> & {
|
||||
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<T, E = T> = CustomPromise<T, E> & {
|
||||
resolve: (arg: T) => void;
|
||||
reject: (arg: E) => void;
|
||||
};
|
||||
|
||||
## Core Functions
|
||||
|
||||
### makePromise
|
||||
```typescript
|
||||
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
|
||||
export declare 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.
|
||||
|
||||
### defer
|
||||
```typescript
|
||||
function defer<T, E = T>(): Deferred<T, E>
|
||||
```
|
||||
|
||||
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<string, Error>()
|
||||
const deferred = defer<string>();
|
||||
|
||||
// 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<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
|
||||
}
|
||||
// Use it like a regular promise
|
||||
deferred.then(value => {
|
||||
console.log(value); // "Hello, world!"
|
||||
});
|
||||
```
|
||||
|
||||
@@ -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
@@ -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<string, number>(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<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
|
||||
})
|
||||
// LRU cache implementation
|
||||
export declare class LRUCache<T, U> {
|
||||
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<T, V, Args extends any[]>(options: {
|
||||
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
@@ -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'
|
||||
```
|
||||
|
||||
+37
-45
@@ -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<number>({
|
||||
chunkSize: 10,
|
||||
processItem: (n: number) => console.log(n)
|
||||
})
|
||||
// Task queue options
|
||||
export type TaskQueueOptions<Item> = {
|
||||
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<Item> {
|
||||
constructor(readonly options: TaskQueueOptions<Item>) {}
|
||||
// Task queue implementation
|
||||
export declare class TaskQueue<Item> {
|
||||
constructor(options: TaskQueueOptions<Item>);
|
||||
push(item: Item): void;
|
||||
remove(item: Item): void;
|
||||
subscribe(subscriber: (item: Item) => void): () => void;
|
||||
process(): Promise<void>;
|
||||
stop(): void;
|
||||
start(): void;
|
||||
clear(): void;
|
||||
}
|
||||
```
|
||||
|
||||
The TaskQueue class accepts messages of type `Item` and processes them.
|
||||
|
||||
### Configuration
|
||||
## Example
|
||||
|
||||
```typescript
|
||||
type TaskQueueOptions<Item> = {
|
||||
// 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"
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user