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.
|
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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.
|
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
@@ -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
@@ -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"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user