@dooboostore/core
v1.0.31
Published
[](https://www.npmjs.com/package/@dooboostore/core) [
Core utilities for data manipulation and async operations.
| Module | Description | Key Exports |
|--------|-------------|------------|
| message | RxJS-like reactive system | Observable, Subject, BehaviorSubject, ReplaySubject |
| promise | Advanced async utilities | Promises, AbortablePromise |
| valid | Type guards & validation | ValidUtils (~20 type guards) |
| array | Array manipulation | ArrayUtils (chunk, flatten, compact, etc.) |
| object | Object introspection | ObjectUtils (keys, values, pick, merge, etc.) |
| string | String utilities | StringUtils (kebab, camel, pascal, trim, etc.) |
| date | Date/time operations | DateUtils (format, parse, diff, add, etc.) |
| math | Mathematical operations | MathUtil (Bezier, Pythagorean, angle calc) |
| convert | Type conversion | ConvertUtils (Map ↔ JSON, RGB, URL params) |
| random | Randomization | RandomUtils (randomInt, randomString, uuid) |
Tier 2: Data Structures & Network
Specialized tools for validation, HTTP, and geometry.
| Module | Description | Key Exports |
|--------|-------------|------------|
| validators | Form validation framework | Validator, FormValidator, 30+ validator implementations |
| fetch | HTTP client framework | HttpFetcher, HttpJsonFetcher, extensible plugin system |
| entity | 2D/3D geometry | Point2D, Point3D, Polygon, Rect, Ellipse, Vector |
| runs | Runnable pattern | Runnable<T, R> interface and implementations |
Tier 3: Coordination & Async Patterns
Advanced patterns for coordinating async operations.
| Module | Description | Key Exports |
|--------|-------------|------------|
| transaction | Transaction management | TransactionManager (coordinated error/cleanup) |
| schedule | Cron-based scheduling | ScheduleBase (standard cron format support) |
| store | Store loader pattern | StoreLoader (dynamic store initialization) |
Tier 4: Utilities & Helpers
General-purpose helpers and specialized tools.
| Module | Description | Key Features |
|--------|-------------|------------|
| url | URL utilities | UrlUtils (parse, build, getPath, getPort, getQuery) |
| parser | Parsing utilities | CssParser, ObjectPathParser |
| logger | Structured logging | Configurable log levels (DEBUG, INFO, WARN, ERROR) |
| storage | Storage abstraction | Storage, MemoryStorage, LocalStorageAdapter |
| reflect | Metadata reflection | ReflectUtils (getPropertyNames, getConstructorParams) |
| function | Function utilities | Dynamic function execution, function composition |
| optional | Optional/Maybe monad | Optional<T> (Haskell-like optional type) |
| iterators | Range iterators | Range (numeric and character ranges) |
| queues | Async queues | AsyncBlockingQueue<T> (FIFO async queue) |
| advice | AOP exception handling | Advice (exception handling patterns) |
| code | Code constants | ISO3166-1 country codes and classifications |
| image | Image utilities | Image manipulation and analysis |
| expression | Expression evaluation | Dynamic expression parsing and execution |
🎯 Core Modules Deep Dive
1️⃣ Message & Reactive System (Observable, Subject)
The reactive messaging system provides an RxJS-like API without the RxJS dependency.
Core Classes
// Base observable
Observable<T, E>
.pipe(...operators): Observable
.subscribe(observer | callbacks): Subscription
.toPromise(): Promise<T | undefined>
// Subject variants
Subject<T, E> // Multicast observable
BehaviorSubject<T, E> // With initial value
ReplaySubject<T, E> // Replays historical values
AsyncSubject<T, E> // Emits last value on complete30+ Operators
Transformation:
.map(fn) // Transform each value
.switchMap(fn) // Or switch to inner observable
.mergeMap(fn) // Or merge inner observables
.concatMap(fn) // Or concat inner observables
.reduce(fn, initial) // Accumulate values
.scan(fn, initial) // Running accumulation (like reduce but emits each step)Filtering:
.filter(predicate) // Keep only matching values
.distinct() // Skip duplicate consecutive values
.skipWhile(predicate) // Skip while predicate is true
.takeWhile(predicate) // Take while predicate is true
.first() // Take only first value
.last() // Take only last valueTime-based:
.debounceTime(ms) // Delay after last emission
.throttle(ms) // Allow one emission per interval
.delay(ms) // Delay all emissions
.bufferTime(ms) // Buffer values for interval
.timeout(ms) // Error if no emission in timeError Handling:
.catchError(handler) // Handle errors
.retry(count) // Retry on errorCombining:
.merge(other) // Combine with another observable
.concat(other) // Concatenate sequentiallyExample: Reactive Form Validation
import { Subject } from '@dooboostore/core/message';
import { debounceTime, map, switchMap } from '@dooboostore/core/message/operators';
// Create input change subject
const emailInput$ = new Subject<string>();
// Validation pipeline
const isValid$ = emailInput$.pipe(
debounceTime(300), // Wait 300ms after user stops typing
map(email => email.trim()), // Normalize input
switchMap(email => validateEmail(email)) // Check with server
);
// Subscribe to results
isValid$.subscribe({
next: (valid) => console.log('Valid:', valid),
error: (err) => console.error('Error:', err),
complete: () => console.log('Done')
});
// Emit values
emailInput$.next('[email protected]');2️⃣ Promise Utilities (Advanced Async)
Advanced patterns for Promise coordination and async control flow.
Key Functions
// Delay execution
Promises.sleep(ms: number): Promise<void>
Promises.sleepReject(ms: number): Promise<never> // Always rejects
Promises.delayExecute<T>(value: T, ms: number): Promise<T>
// Settlement & composition
Promises.settle<T>(promise: Promise<T>): Promise<SettledResult<T>>
// Returns { status: 'fulfilled' | 'rejected', value?, reason? }
Promises.settles<T>(...promises): Promise<SettledResult<T>[]>
// Settle multiple promises at once
// Recurring loops
Promises.loop(config: LoopConfig<T, R>): ObservableLoop<T, R>
// Executes promise repeatedly with delay/max attempts
// Error filtering
Promises.filterCatch<T>(promise, errorType): Promise<Error | undefined>
// Catches specific error type, rethrows others
// Abortable promises
Promises.abortable<T>(executor, signal?: AbortSignal): AbortablePromise<T>
// Promise that can be aborted via AbortSignalExample: Polling with Max Retries
import { Promises } from '@dooboostore/core/promise';
const loop = Promises.loop({
task: async () => {
const response = await fetch('/api/status');
if (!response.ok) throw new Error('Not ready');
return response.json();
},
delay: 2000, // Wait 2 seconds between attempts
maxAttempts: 5, // Max 5 attempts
onSuccess: (result) => console.log('Success:', result),
onError: (err) => console.error('Failed:', err)
});
// Manually check or cancel
console.log('Running:', loop.isRunning());
// loop.cancel();Example: Coordinated Settlement
import { Promises } from '@dooboostore/core/promise';
const results = await Promises.settles(
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} succeeded:`, result.value);
} else {
console.log(`Request ${index} failed:`, result.reason);
}
});3️⃣ Validation Framework (30+ Validators)
Enterprise-grade form validation with composable validators.
Core Classes
// Base validator
abstract class Validator<T> {
abstract validate(value: T): Promise<ValidationResult>;
}
// Form validator (combines multiple validators)
class FormValidator {
addValidator(field: string, validator: Validator): void
async validate(formData: Record<string, any>): Promise<ValidationErrors>
}
// Validation result
interface ValidationResult {
valid: boolean;
error?: string;
}30+ Built-in Validators
Text Validators:
new EmailValidator() // RFC 5322 email format
new PhoneValidator() // Phone numbers
new UrlValidator() // URL format
new PatternValidator(/regex/) // Custom regex pattern
new StringLengthValidator(1, 100) // Min/max length
new AlphanumericValidator() // Only letters & numbers
new CreditCardValidator() // Credit card formatNumber Validators:
new NumberRangeValidator(0, 100) // Min/max bounds
new IntegerValidator() // Whole numbers only
new PercentValidator() // 0-100 range
new PositiveValidator() // > 0Collection Validators:
new ArrayLengthValidator(1, 10) // Array size bounds
new ArrayItemValidator(itemValidator) // Each item
new RequiredValidator() // Not null/empty
new UniqueValidator() // No duplicatesDate/Time:
new DateValidator() // Valid date format
new DateRangeValidator(from, to) // Between dates
new FutureValidator() // Date in future
new PastValidator() // Date in pastLogic:
new CompositeValidator([v1, v2]) // All must pass (AND)
new AlternativeValidator([v1, v2])// Any must pass (OR)
new CustomValidator((val) => {...}) // Custom functionExample: Form Validation
import { FormValidator, EmailValidator, StringLengthValidator } from '@dooboostore/core/validators';
const validator = new FormValidator();
validator.addValidator('email', new EmailValidator());
validator.addValidator('password', new StringLengthValidator(8, 100));
validator.addValidator('username', new AlphanumericValidator());
const errors = await validator.validate({
email: '[email protected]',
password: 'secretpass123',
username: 'john_doe'
});
if (Object.keys(errors).length > 0) {
console.log('Validation errors:', errors);
} else {
console.log('Form is valid!');
}4️⃣ Geometry & Entity (2D/3D Operations)
Complete 2D/3D geometry system with collision detection.
Core Classes
// 2D Points
Point2D { x: number, y: number }
.distance(other: Point2D): number
.angle(other: Point2D): number
.rotate(angle: number, origin?: Point2D): Point2D
// 3D Points
Point3D { x: number, y: number, z: number }
.distance(other: Point3D): number
.cross(other: Point3D): Point3D
.dot(other: Point3D): number
// Polygons
Polygon { points: Point2D[] }
.contains(point: Point2D): boolean
.intersects(other: Polygon): boolean
.area(): number
.perimeter(): number
// Rectangles
Rect { x: number, y: number, width: number, height: number }
.contains(point: Point2D): boolean
.intersects(other: Rect): boolean
.overlaps(other: Rect): Rect | null
// Other shapes
Ellipse { centerX, centerY, radiusX, radiusY }
Vector { x, y }
Scalar { value }Example: Collision Detection
import { Rect, Point2D } from '@dooboostore/core/entity';
const playerRect = new Rect(100, 100, 50, 50);
const enemyRect = new Rect(130, 120, 40, 40);
const projectile = new Point2D(140, 110);
// Check collisions
if (playerRect.intersects(enemyRect)) {
console.log('Player hit enemy!');
}
if (enemyRect.contains(projectile)) {
console.log('Projectile hit enemy!');
}
// Get overlap area
const overlap = playerRect.overlaps(enemyRect);
console.log('Overlap:', overlap);5️⃣ HTTP Fetcher (Extensible Framework)
Flexible HTTP client with plugin architecture.
Core Classes
// Base fetcher
class HttpFetcher<T> {
fetch(url: string, options?: FetchOptions): Promise<T>
post(url: string, data: any, options?): Promise<T>
get(url: string, options?): Promise<T>
put(url: string, data: any, options?): Promise<T>
delete(url: string, options?): Promise<T>
patch(url: string, data: any, options?): Promise<T>
}
// JSON-specific
class HttpJsonFetcher extends HttpFetcher<any> {
// Automatic JSON parsing/serializing
}Plugin Hooks
interface FetcherOptions {
beforeRequest?: (request: Request) => Request | Promise<Request>
afterResponse?: (response: Response) => Response | Promise<Response>
onError?: (error: Error) => void
timeout?: number
retries?: number
headers?: Record<string, string>
}Example: API Client with Interceptors
import { HttpJsonFetcher } from '@dooboostore/core/fetch';
class ApiClient extends HttpJsonFetcher {
async beforeRequest(request: Request) {
// Add authorization token
request.headers.set('Authorization', `Bearer ${getToken()}`);
return request;
}
async afterResponse(response: Response) {
// Handle 401 - refresh token
if (response.status === 401) {
await refreshToken();
// Retry request...
}
return response;
}
async onError(error: Error) {
console.error('API Error:', error);
// Report to error tracking service
}
}
const client = new ApiClient({ timeout: 5000, retries: 3 });
const users = await client.get<User[]>('/api/users');6️⃣ Transaction Management
Coordinated async operations with centralized error/cleanup handling.
Core Classes
interface Transaction<I, T, C, F> {
try(data: I): Promise<T>
catch(error: any): Promise<C>
finally(): Promise<F>
}
class TransactionManager {
setTransaction(key: string, transaction: Transaction): void
getTransaction(key: string): Transaction | undefined
hasTransaction(key: string): boolean
deleteTransaction(key: string): void
async try(data?: any): Promise<void> // Run all try()
async catch(error: any): Promise<void> // Cascade to all catch()
async finally(): Promise<void> // Run all finally() for cleanup
}Example: Multi-Step Operation with Rollback
import { TransactionManager } from '@dooboostore/core/transaction';
class OrderTransaction {
try(order: Order) {
// Step 1: Create order in DB
// Step 2: Process payment
// Step 3: Send confirmation email
}
catch(error: any) {
// Rollback: Refund payment, delete order
}
finally() {
// Cleanup: Close connections, release locks
}
}
const manager = new TransactionManager();
manager.setTransaction('order', new OrderTransaction());
manager.setTransaction('inventory', new InventoryTransaction());
try {
await manager.try({ orderData: {...} });
} catch (error) {
await manager.catch(error); // Cascades to all transactions
} finally {
await manager.finally(); // Cleanup for all transactions
}7️⃣ Scheduling (Cron Format)
Schedule recurring tasks using standard cron format.
Cron Format Reference
* * * * * *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ └─ day of week (0-7, Sun-Sat)
│ │ │ │ └────── month (1-12)
│ │ │ └─────────── day (1-31)
│ │ └──────────────── hour (0-23)
│ └───────────────────── minute (0-59)
└────────────────────────── second (0-59, optional)
Examples:
"0 0 * * *" → Daily at midnight
"0 9 * * 1" → Every Monday at 9:00 AM
"*/15 * * * *" → Every 15 minutes
"0 0 1 * *" → First day of every month
"0 0 * * 0" → Every Sunday
"0 18 * * 1-5" → Weekdays at 6:00 PMExample: Scheduled Tasks
import { ScheduleBase } from '@dooboostore/core/schedule';
class BackupSchedule extends ScheduleBase<null, BackupResult> {
spec = "0 2 * * *"; // 2 AM daily
name = "Daily Database Backup";
async execute(): Promise<BackupResult> {
const backup = await performBackup();
return {
timestamp: new Date(),
filesBackedUp: backup.fileCount,
success: true
};
}
}
const schedule = new BackupSchedule();
await schedule.execute(); // Run manually8️⃣ Data Utilities
Common helpers for array, object, string, date operations.
ArrayUtils
ArrayUtils.chunk(arr, size) // Split into chunks
ArrayUtils.flatten(arr) // Flatten nested arrays
ArrayUtils.compact(arr) // Remove falsy values
ArrayUtils.uniq(arr) // Remove duplicates
ArrayUtils.shuffle(arr) // Randomize order
ArrayUtils.group(arr, keyFn) // Group by key function
ArrayUtils.range(start, end) // Create range array
ArrayUtils.zip(...arrays) // Combine arrays
ArrayUtils.transpose(matrix) // Transpose 2D arrayObjectUtils
ObjectUtils.keys(obj) // Get all keys
ObjectUtils.values(obj) // Get all values
ObjectUtils.entries(obj) // Get key-value pairs
ObjectUtils.pick(obj, keys) // Select specific keys
ObjectUtils.omit(obj, keys) // Remove specific keys
ObjectUtils.merge(...objects) // Deep merge objects
ObjectUtils.clone(obj) // Deep clone
ObjectUtils.assign(target, source) // Like Object.assign
ObjectUtils.freeze(obj) // Recursively freezeStringUtils
StringUtils.camelCase(str) // camelCase
StringUtils.kebabCase(str) // kebab-case
StringUtils.pascalCase(str) // PascalCase
StringUtils.snakeCase(str) // snake_case
StringUtils.trim(str) // Remove whitespace
StringUtils.capitalize(str) // Capitalize first letter
StringUtils.reverse(str) // Reverse string
StringUtils.truncate(str, length) // Truncate with ellipsis
StringUtils.repeat(str, count) // Repeat string
StringUtils.padStart(str, length, pad) // Pad startDateUtils
DateUtils.format(date, format) // Format date string
DateUtils.parse(dateStr) // Parse date string
DateUtils.add(date, amount, unit) // Add time
DateUtils.diff(date1, date2, unit) // Get difference
DateUtils.startOf(date, unit) // Start of period
DateUtils.endOf(date, unit) // End of period
DateUtils.isLeapYear(year) // Check leap year
DateUtils.getDaysInMonth(date) // Days in month
DateUtils.isBefore(date1, date2) // Date comparisonMathUtil
MathUtil.distance(p1, p2) // Euclidean distance
MathUtil.angle(p1, p2) // Angle between points
MathUtil.lerp(a, b, t) // Linear interpolation
MathUtil.clamp(value, min, max) // Clamp to range
MathUtil.normalize(value, min, max) // 0-1 normalization
MathUtil.degToRad(degrees) // Convert degrees to radians
MathUtil.radToDeg(radians) // Convert radians to degrees
MathUtil.bezier(t, ...points) // Bezier curve calculation📖 Usage Examples
Example 1: Real-time Search with Debounce
import { Subject } from '@dooboostore/core/message';
import { debounceTime, map, switchMap } from '@dooboostore/core/message/operators';
import { HttpJsonFetcher } from '@dooboostore/core/fetch';
const searchInput$ = new Subject<string>();
const fetcher = new HttpJsonFetcher();
searchInput$.pipe(
debounceTime(300),
map(query => query.trim()),
filter(query => query.length > 0),
switchMap(query => fetcher.get(`/api/search?q=${query}`))
).subscribe(
results => displayResults(results),
error => showError(error)
);
// Emit searches
searchInput$.next('typescript');
searchInput$.next('utilities');Example 2: Form Validation Pipeline
import { FormValidator, EmailValidator, StringLengthValidator } from '@dooboostore/core/validators';
import { Subject } from '@dooboostore/core/message';
import { debounceTime, switchMap } from '@dooboostore/core/message/operators';
const formData$ = new Subject<FormData>();
const validator = new FormValidator();
validator.addValidator('email', new EmailValidator());
validator.addValidator('password', new StringLengthValidator(8, 128));
formData$.pipe(
debounceTime(500),
switchMap(data => validator.validate(data))
).subscribe(
errors => {
if (Object.keys(errors).length === 0) {
enableSubmitButton();
} else {
showValidationErrors(errors);
}
}
);Example 3: Coordinated Async Operations
import { Promises } from '@dooboostore/core/promise';
import { HttpJsonFetcher } from '@dooboostore/core/fetch';
const fetcher = new HttpJsonFetcher({ timeout: 5000 });
const [users, posts, comments] = await Promise.all([
fetcher.get('/api/users'),
fetcher.get('/api/posts'),
fetcher.get('/api/comments')
]);
// Or with error handling
const results = await Promises.settles(
fetcher.get('/api/users'),
fetcher.get('/api/posts'),
fetcher.get('/api/comments')
);
results.forEach((result, idx) => {
if (result.status === 'fulfilled') {
console.log(`Request ${idx}:`, result.value);
} else {
console.log(`Request ${idx} failed:`, result.reason);
}
});Example 4: Geometry & Collision
import { Rect, Point2D, Polygon } from '@dooboostore/core/entity';
// Create game objects
const player = new Rect(100, 100, 50, 50);
const enemy = new Rect(200, 140, 40, 40);
const powerUp = new Point2D(150, 180);
// Check collisions
if (player.intersects(enemy)) {
console.log('Game Over!');
}
if (player.contains(powerUp)) {
console.log('Power Up Activated!');
}
// Complex shapes
const walls = new Polygon([
new Point2D(0, 0),
new Point2D(500, 0),
new Point2D(500, 500),
new Point2D(0, 500)
]);
if (walls.contains(player)) {
console.log('Player is inside walls');
}Example 5: Transaction with Rollback
import { TransactionManager } from '@dooboostore/core/transaction';
class PaymentTransaction {
async try(order: Order) {
// Charge the customer
await chargeCard(order.payment);
}
async catch(error: any) {
// Refund if something fails
console.log('Refunding due to:', error.message);
await refundCard(order.payment);
}
async finally() {
// Cleanup
await closePaymentConnection();
}
}
class InventoryTransaction {
async try(order: Order) {
await reduceInventory(order.items);
}
async catch(error: any) {
await restoreInventory(order.items);
}
async finally() {
await closeDatabase();
}
}
const manager = new TransactionManager();
manager.setTransaction('payment', new PaymentTransaction());
manager.setTransaction('inventory', new InventoryTransaction());
try {
await manager.try(order);
console.log('Order processed successfully');
} catch (error) {
await manager.catch(error); // All transactions rollback
console.log('Order failed and rolled back');
} finally {
await manager.finally(); // All cleanup
}🔗 Type Guard Utilities
Comprehensive type checking functions:
import { ValidUtils } from '@dooboostore/core/valid';
ValidUtils.isString(value) // Check if string
ValidUtils.isNumber(value) // Check if number
ValidUtils.isBoolean(value) // Check if boolean
ValidUtils.isArray(value) // Check if array
ValidUtils.isObject(value) // Check if object (not null/array)
ValidUtils.isNull(value) // Check if null
ValidUtils.isUndefined(value) // Check if undefined
ValidUtils.isFunction(value) // Check if function
ValidUtils.isDate(value) // Check if Date
ValidUtils.isRegExp(value) // Check if RegExp
ValidUtils.isEmpty(value) // Check if empty
ValidUtils.isAsync(value) // Check if Promise
ValidUtils.isIterable(value) // Check if iterable
ValidUtils.hasProperty(obj, prop) // Check if has property
ValidUtils.isPrimitive(value) // Check if primitive type🏗️ Architecture Overview
┌─────────────────────────────────────────────┐
│ @dooboostore/core Modules │
├─────────────────────────────────────────────┤
│ │
│ ┌─ TIER 1: Utilities ────────────────┐ │
│ │ • strings, arrays, objects │ │
│ │ • dates, math, convert │ │
│ │ • random, valid (type guards) │ │
│ └────────────────────────────────────┘ │
│ ↓ │
│ ┌─ TIER 1: Async Core ──────────────┐ │
│ │ • Observable/Subject (30+ ops) │ │
│ │ • Promises (sleep, settle, loop) │ │
│ └────────────────────────────────────┘ │
│ ↓ │
│ ┌─ TIER 2: Domain-Specific ────────┐ │
│ │ • Validators (30+ validators) │ │
│ │ • HttpFetcher (HTTP client) │ │
│ │ • Entity (2D/3D geometry) │ │
│ │ • Runs (Runnable pattern) │ │
│ └────────────────────────────────────┘ │
│ ↓ │
│ ┌─ TIER 3: Async Patterns ─────────┐ │
│ │ • Transaction (coordinated async) │ │
│ │ • Schedule (cron scheduling) │ │
│ │ • Store (dynamic loading) │ │
│ └────────────────────────────────────┘ │
│ ↓ │
│ ┌─ TIER 4: Specialized Utils ──────┐ │
│ │ • URL parsing, CSS parsing │ │
│ │ • Logger, Storage abstraction │ │
│ │ • Reflect, Function utilities │ │
│ │ • Optional monad, Iterators │ │
│ └────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘📊 Performance Characteristics
| Aspect | Characteristic | |--------|---| | Dependencies | 0 external dependencies | | Bundle Size | ~50KB gzipped (full library) | | Tree-Shaking | ✅ Fully supported | | Module Format | ESM, CJS, UMD | | TypeScript | Full native support | | Runtime | Node.js 12+, Browsers | | Observable Performance | Similar to RxJS for typical workloads | | Validation Speed | ~1ms for complex forms (100+ fields) | | HTTP Client | Native fetch-based, no extra overhead |
🎓 Best Practices
1. Use Type Guards for Runtime Safety
import { ValidUtils } from '@dooboostore/core/valid';
function processData(data: unknown) {
if (ValidUtils.isObject(data) && ValidUtils.hasProperty(data, 'id')) {
// Safe to access data.id
}
}2. Compose Validators for Complex Forms
import { CompositeValidator } from '@dooboostore/core/validators';
const passwordValidator = new CompositeValidator([
new StringLengthValidator(8, 128),
new PatternValidator(/[A-Z]/), // At least one uppercase
new PatternValidator(/[0-9]/) // At least one digit
]);3. Use Debounce for UI Events
searchInput$.pipe(
debounceTime(500), // Wait for user to finish typing
switchMap(query => searchApi(query))
).subscribe(results => updateUI(results));4. Manage Subscriptions Correctly
const subscription = observable.subscribe(...);
// Clean up when done
subscription.unsubscribe();5. Use Transactions for Multi-Step Operations
// Ensures all-or-nothing semantics
const manager = new TransactionManager();
manager.setTransaction('db', dbTransaction);
manager.setTransaction('api', apiTransaction);
// If any fails, all rollback🚀 Advanced Topics
Reactive Composition
const user$ = userIdInput$.pipe(
debounceTime(300),
switchMap(id => fetchUser(id)),
catchError(err => {
console.error('Failed to fetch user:', err);
return of(null);
})
);Error Boundaries with Transactions
const manager = new TransactionManager();
// Add multiple transactions
// try() → catch() → finally() flows automaticallyCustom Validators
class UniqueUsernameValidator extends Validator<string> {
async validate(username: string) {
const exists = await checkUsernameExists(username);
return {
valid: !exists,
error: exists ? 'Username already taken' : undefined
};
}
}📚 Learn More
The detailed API documentation, including all modules and usage examples, is available on our documentation website.
License
This package is licensed under the MIT License.
