import type { Fn } from '../../@aileron/declare/index.js'; /** * Schedules a callback function to execute in the next macrotask cycle with optimized MessageChannel-based timing. * * Automatically selects the most appropriate macrotask scheduling mechanism based on the runtime * environment. In Node.js, uses native `setImmediate` for true macrotask semantics that execute after * I/O events. In browsers and other environments, uses a custom MessageChannelScheduler-based * `setImmediate` implementation that provides immediate macro task execution with automatic batching * optimization, significantly outperforming traditional `setTimeout(0)` approaches. * * @param callback - Function to execute in the next macrotask cycle * @returns Numeric ID that can be used with `cancelMacrotask` to cancel execution * * @example * Basic macrotask scheduling: * ```typescript * import { scheduleMacrotask } from '@winglet/common-utils'; * * console.log('1: Synchronous code'); * * // Schedule macrotask * const taskId = scheduleMacrotask(() => { * console.log('4: Macrotask executed'); * }); * * // Schedule microtask for comparison * Promise.resolve().then(() => { * console.log('3: Microtask executed'); * }); * * console.log('2: More synchronous code'); * * // Output order: * // 1: Synchronous code * // 2: More synchronous code * // 3: Microtask executed * // 4: Macrotask executed * ``` * * @example * Automatic batching demonstration: * ```typescript * // These tasks will be automatically batched by MessageChannelScheduler * const task1 = scheduleMacrotask(() => { * console.log('Task 1 - batched execution'); * }); * * const task2 = scheduleMacrotask(() => { * console.log('Task 2 - batched execution'); * }); * * const task3 = scheduleMacrotask(() => { * console.log('Task 3 - batched execution'); * }); * * // All three tasks execute together in single macro task cycle * // More efficient than individual setTimeout calls * ``` * * @example * Performance comparison with traditional approaches: * ```typescript * // MessageChannelScheduler-based (preferred) * const startTime = performance.now(); * scheduleMacrotask(() => { * const endTime = performance.now(); * console.log(`MessageChannel delay: ${endTime - startTime}ms`); * // Typically ~0.1-1ms in browsers * }); * * // Traditional setTimeout (slower) * const startTime2 = performance.now(); * setTimeout(() => { * const endTime2 = performance.now(); * console.log(`setTimeout delay: ${endTime2 - startTime2}ms`); * // Typically ~4-10ms in browsers due to minimum delay * }, 0); * ``` * * @example * UI updates and rendering coordination: * ```typescript * // Defer heavy computation to avoid blocking UI * function processLargeDataset(data: any[], callback: (result: any) => void) { * const batchSize = 1000; * let index = 0; * const results: any[] = []; * * function processBatch() { * const end = Math.min(index + batchSize, data.length); * * // Process batch synchronously * for (let i = index; i < end; i++) { * results.push(processItem(data[i])); * } * * index = end; * * if (index < data.length) { * // Schedule next batch with optimal timing * scheduleMacrotask(processBatch); * } else { * callback(results); * } * } * * scheduleMacrotask(processBatch); * } * * // DOM manipulation coordination * function updateUIAfterDataChange(newData: any) { * // Update data model (synchronous) * updateModel(newData); * * // Schedule DOM updates for next macrotask * scheduleMacrotask(() => { * updateDOM(); * * // Schedule analytics after DOM is updated * scheduleMacrotask(() => { * trackUserInteraction('data-updated'); * }); * }); * } * ``` * * @example * Event loop execution order with MessageChannel optimization: * ```typescript * const executionOrder: string[] = []; * * // Synchronous execution * executionOrder.push('sync-1'); * * // Macrotask (runs after microtasks, with batching) * scheduleMacrotask(() => { * executionOrder.push('macrotask-1'); * * // Nested microtask (runs before next macrotask) * queueMicrotask(() => { * executionOrder.push('nested-microtask'); * }); * * // Nested macrotask (runs in subsequent cycle) * scheduleMacrotask(() => { * executionOrder.push('nested-macrotask'); * }); * }); * * // Microtask (runs before macro tasks) * queueMicrotask(() => { * executionOrder.push('microtask-1'); * }); * * // Another macrotask (batched with first if scheduled synchronously) * scheduleMacrotask(() => { * executionOrder.push('macrotask-2'); * }); * * executionOrder.push('sync-2'); * * // Final order: ['sync-1', 'sync-2', 'microtask-1', 'macrotask-1', 'macrotask-2', 'nested-microtask', 'nested-macrotask'] * ``` * * @remarks * **Event Loop Integration:** * - **Execution Timing**: Runs after all microtasks but before next I/O polling * - **Priority**: Lower than microtasks, higher than I/O callbacks * - **Concurrency**: Non-blocking, allows other work between scheduled tasks * - **Rendering**: Occurs before browser rendering in most implementations * - **Batching**: MessageChannelScheduler automatically groups synchronous schedules * * **Platform Behavior:** * - **Node.js (native setImmediate)**: Executes after I/O events, true macrotask semantics * - **Browsers (MessageChannelScheduler)**: Immediate execution without 4ms minimum delay * - **Web Workers**: Consistent MessageChannelScheduler behavior across all environments * - **Electron**: Node.js behavior in main process, MessageChannelScheduler in renderers * * **Performance Characteristics:** * - **Time Complexity**: O(1) for scheduling operation * - **Space Complexity**: O(1) per scheduled task * - **Scheduling Overhead**: ~0.001ms in Node.js, ~0.01ms with MessageChannelScheduler * - **Memory Usage**: Minimal, automatic cleanup after execution * - **Batching Efficiency**: Automatic optimization for synchronously scheduled tasks * * **Comparison with Alternatives:** * - **setTimeout(0)**: MessageChannelScheduler is 4-10x faster, no minimum delay * - **Promise.resolve().then()**: Executes earlier (microtask queue) * - **requestAnimationFrame**: Tied to browser rendering, different timing * - **Native MessageChannel**: More complex setup, similar timing characteristics * * **MessageChannelScheduler Advantages:** * - **No Minimum Delay**: Executes immediately after microtasks * - **Automatic Batching**: Groups synchronously scheduled tasks for efficiency * - **Memory Efficient**: Optimized task management and cleanup * - **Error Isolation**: Task errors don't affect other tasks in batch * - **Consistent Timing**: Predictable execution across environments */ export declare const scheduleMacrotask: Fn<[callback: Fn<[], void>], number>; /** * Cancels a previously scheduled macrotask using its numeric identifier. * * Provides reliable cancellation of pending macrotask execution across different JavaScript * environments. Automatically uses the appropriate cancellation method (native `clearImmediate` in * Node.js, MessageChannelScheduler's `clearImmediate` in browsers) based on the scheduling * mechanism. Safe to call multiple times with the same ID or with invalid IDs. * * @param id - Numeric identifier returned by `scheduleMacrotask` * * @example * Basic task cancellation: * ```typescript * import { scheduleMacrotask, cancelMacrotask } from '@winglet/common-utils'; * * // Schedule a task * const taskId = scheduleMacrotask(() => { * console.log('This will not execute'); * }); * * // Cancel before execution * cancelMacrotask(taskId); * * // Task is safely cancelled, no output * ``` * * @example * Batch cancellation with MessageChannelScheduler: * ```typescript * // Schedule multiple tasks that will be batched * const task1 = scheduleMacrotask(() => console.log('Task 1')); * const task2 = scheduleMacrotask(() => console.log('Task 2')); * const task3 = scheduleMacrotask(() => console.log('Task 3')); * * // Cancel individual task from batch * cancelMacrotask(task2); * * // Only task1 and task3 will execute * // MessageChannelScheduler handles partial batch cancellation efficiently * ``` * * @example * Conditional cancellation patterns: * ```typescript * // Timeout-based cancellation * function scheduleWithTimeout( * task: () => T, * timeoutMs: number * ): Promise { * return new Promise((resolve, reject) => { * let completed = false; * * // Schedule main task with MessageChannelScheduler optimization * const taskId = scheduleMacrotask(() => { * if (!completed) { * completed = true; * try { * resolve(task()); * } catch (error) { * reject(error); * } * } * }); * * // Schedule timeout cancellation * setTimeout(() => { * if (!completed) { * completed = true; * cancelMacrotask(taskId); * reject(new Error('Task timeout')); * } * }, timeoutMs); * }); * } * ``` * * @example * Resource management with efficient cancellation: * ```typescript * // MessageChannelScheduler-optimized batch processor * class OptimizedBatchProcessor { * private taskIds: Set = new Set(); * private cancelled = false; * * processBatches(data: any[], batchSize: number) { * for (let i = 0; i < data.length; i += batchSize) { * const batch = data.slice(i, i + batchSize); * * // Tasks scheduled synchronously will be automatically batched * const taskId = scheduleMacrotask(() => { * if (!this.cancelled) { * this.processBatch(batch); * this.taskIds.delete(taskId); * } * }); * * this.taskIds.add(taskId); * } * } * * cancel() { * this.cancelled = true; * // Efficient O(1) cancellation per task * this.taskIds.forEach(id => cancelMacrotask(id)); * this.taskIds.clear(); * } * * private processBatch(batch: any[]) { * // Process batch logic * } * } * ``` * * @remarks * **Cancellation Guarantees:** * - **Timing**: Safe to cancel at any point before task execution * - **Memory**: Automatic cleanup of cancelled tasks * - **Safety**: No errors thrown for invalid or already-executed IDs * - **Atomicity**: Cancellation is immediate and irreversible * - **Batch Support**: Efficient individual task cancellation from batched groups * * **Platform Behavior:** * - **Node.js**: Uses native `clearImmediate` for tasks scheduled with `setImmediate` * - **Browsers**: Uses MessageChannelScheduler's `clearImmediate` with O(1) performance * - **Cross-platform**: Consistent API regardless of underlying implementation * - **Error Handling**: Silent failure for invalid IDs (matches native behavior) * * **Performance Characteristics:** * - **Time Complexity**: O(1) for cancellation operation * - **Space Complexity**: O(1) per cancelled task * - **Overhead**: Negligible cancellation cost * - **Memory**: Immediate cleanup of cancelled task references * - **Batch Efficiency**: Individual cancellation doesn't affect batch performance * * **MessageChannelScheduler Cancellation Features:** * - **Precise Control**: Cancel individual tasks from batched groups * - **Memory Efficiency**: Immediate cleanup of cancelled task references * - **No Side Effects**: Cancellation doesn't affect other tasks in queue * - **Consistent Behavior**: Same cancellation semantics as native implementations */ export declare const cancelMacrotask: Fn<[id: number], void>; /** * Creates a cancellable macrotask with a fluent API that returns a cancellation function. * * Schedules a callback for execution in the next macrotask cycle using MessageChannelScheduler * optimization and returns a cancellation function that can prevent execution. Uses a two-layer * cancellation strategy: immediate task cancellation via the platform API and a boolean flag * to prevent execution if the task has already been queued but not yet cancelled. Leverages * MessageChannelScheduler's automatic batching for optimal performance. * * @param callback - Function to execute in the next macrotask cycle * @returns Cancellation function that prevents execution when called * * @example * Basic cancellable task with MessageChannelScheduler: * ```typescript * import { scheduleCancelableMacrotask } from '@winglet/common-utils'; * * // Schedule a task and get cancellation function * const cancelTask = scheduleCancelableMacrotask(() => { * console.log('This may or may not execute'); * }); * * // Cancel the task before execution * cancelTask(); * // No output - task was cancelled * * // Alternative: let it execute naturally with batching optimization * const cancelTask2 = scheduleCancelableMacrotask(() => { * console.log('This will execute in optimized batch'); * }); * // Don't call cancelTask2() - output: "This will execute in optimized batch" * ``` * * @example * Batch processing with individual cancellation: * ```typescript * // Schedule multiple tasks that benefit from automatic batching * const cancellations: (() => void)[] = []; * * for (let i = 0; i < 10; i++) { * const cancel = scheduleCancelableMacrotask(() => { * console.log(`Processing item ${i}`); * }); * cancellations.push(cancel); * } * * // Cancel specific items (e.g., items 3, 5, 7) * [3, 5, 7].forEach(index => { * if (cancellations[index]) { * cancellations[index](); * } * }); * * // Remaining tasks execute in batched manner for optimal performance * ``` * * @example * Real-time data processing with cancellation: * ```typescript * // MessageChannelScheduler-optimized data processor * class RealTimeProcessor { * private pendingCancellations = new Set<() => void>(); * * processDataStream(dataItems: any[]) { * // Clear previous processing * this.cancelAll(); * * // Schedule processing for each item (will be automatically batched) * dataItems.forEach((item, index) => { * const cancel = scheduleCancelableMacrotask(() => { * this.processItem(item); * this.pendingCancellations.delete(cancel); * }); * * this.pendingCancellations.add(cancel); * }); * } * * cancelItem(predicate: (item: any) => boolean) { * // Selective cancellation based on business logic * // MessageChannelScheduler handles efficient individual cancellation * } * * cancelAll() { * this.pendingCancellations.forEach(cancel => cancel()); * this.pendingCancellations.clear(); * } * * private processItem(item: any) { * // Item processing logic * } * } * ``` * * @example * UI interaction with optimized scheduling: * ```typescript * // User interaction handler with batched updates * class InteractiveUI { * private pendingUpdates = new Map void>(); * * scheduleUpdate(componentId: string, updateFn: () => void) { * // Cancel existing update for this component * const existingCancel = this.pendingUpdates.get(componentId); * if (existingCancel) { * existingCancel(); * } * * // Schedule new update (benefits from MessageChannelScheduler batching) * const cancel = scheduleCancelableMacrotask(() => { * updateFn(); * this.pendingUpdates.delete(componentId); * }); * * this.pendingUpdates.set(componentId, cancel); * return cancel; * } * * cancelUpdate(componentId: string): boolean { * const cancel = this.pendingUpdates.get(componentId); * if (cancel) { * cancel(); * this.pendingUpdates.delete(componentId); * return true; * } * return false; * } * * destroy() { * // Cancel all pending updates efficiently * this.pendingUpdates.forEach(cancel => cancel()); * this.pendingUpdates.clear(); * } * } * ``` * * @remarks * **Cancellation Strategy:** * - **Two-Layer Protection**: MessageChannelScheduler cancellation + execution guard boolean * - **Race Condition Safe**: Handles cancellation before and during execution * - **Memory Efficient**: Automatic cleanup of cancelled tasks * - **Idempotent**: Safe to call cancellation function multiple times * - **Batch Aware**: Individual cancellation doesn't affect batch performance * * **MessageChannelScheduler Integration:** * - **Automatic Batching**: Multiple synchronous schedules are automatically optimized * - **Immediate Execution**: No artificial delays like setTimeout(0) * - **Error Isolation**: Task errors don't affect other tasks in the batch * - **Memory Optimization**: Efficient task management and cleanup * - **Consistent Timing**: Predictable execution timing across environments * * **Performance Characteristics:** * - **Time Complexity**: O(1) for scheduling and cancellation * - **Space Complexity**: O(1) per scheduled task * - **Memory Overhead**: ~40 bytes per task (closure + boolean flag) * - **Cancellation Speed**: Immediate (no async overhead) * - **Batch Efficiency**: Optimal performance for multiple synchronous schedules * * **Comparison with Alternatives:** * - **setTimeout-based**: 4-10x faster execution, automatic batching * - **AbortController**: More complex API, larger memory footprint * - **Promise cancellation**: Requires additional promise infrastructure * - **Manual ID tracking**: More error-prone, requires external state management * * **Event Loop Integration:** * - **Execution Timing**: After microtasks, optimized macro task execution * - **Cancellation Timing**: Immediate, no event loop involvement * - **Platform Behavior**: Inherits MessageChannelScheduler optimizations * - **Nested Scheduling**: Full support for task scheduling within tasks with batching */ export declare const scheduleCancelableMacrotask: (callback: Fn) => Fn;