UNPKG

@silver-zepp/sequence

Version:

Sequence - a JavaScript utility for managing complex chains of synchronous and asynchronous operations with timing control.

439 lines (438 loc) 14.2 kB
/** @about Sequence 1.0.0 @min_zeppos 2.0 @author: Silver, Zepp Health. @license: MIT */ /** * @class Sequence * @example * const seq = new Sequence() * .log("Starting sequence") * .delay(1000) * .call(() => sum = sum * 2) * .parallel([seq1, seq2, ...], { timeout: 5000 }) * .log("Parallel tasks completed") * .catch(error => console.log("Sequence error:", error)) * .finally(() => console.log("Sequence finished")) * .start(); */ export class Sequence { static "__#1@#all_sequences_arr": any[]; static "__#1@#task_delay": number; static "__#1@#task_log": number; static "__#1@#task_call": number; static "__#1@#task_parallel": number; static "__#1@#task_await": number; static "__#1@#delta_time": number; static "__#1@#time_scale": number; static "__#1@#last_frame_time": number; static "__#1@#global_logger": Console; /** @returns {number} Parallel mode where all tasks must complete. */ static get PARALLEL_MODE_ALL(): number; /** @returns {number} Parallel mode where the first task to complete ends execution. */ static get PARALLEL_MODE_RACE(): number; /** @returns {number} Parallel mode where any task completing is considered success. */ static get PARALLEL_MODE_ANY(): number; /** * Destroys all existing sequences. * @example * ```js * Sequence.DestroyAllSequences(); * ``` */ static DestroyAllSequences(): void; /** * Gets the current delta time, scaled by time scale. * @returns {number} The scaled delta time in seconds. * @example * ```js * const dt = Sequence.GetDeltaTime(); * console.log(`Time since last frame: ${dt} seconds`); * ``` */ static GetDeltaTime(): number; /** * Gets the current time scale. * @returns {number} The current time scale. * @example * ```js * const time_scale = Sequence.GetTimeScale(); * console.log(`Current time scale: ${time_scale}`); * ``` */ static GetTimeScale(): number; /** * Sets the time scale for all Sequence instances. * @param {number} scale - The new time scale (e.g., 0.5 for half speed, 2.0 for double speed). */ static SetTimeScale(scale: number): void; /** @private */ private static UpdateDeltaTime; /** * Sets a custom logger for all Sequence instances. * @param {Object} custom_logger - An object with a 'log' method. * @example * ```js * const my_logger = { log: (msg) => { ... } }; * Sequence.SetLogger(my_logger); * * // or if you're using VisLog * Sequence.SetLogger(vis); // .log("1") = vis.log("1") * ``` */ static SetLogger(custom_logger: any): void; /** * Creates a new Sequence instance. * @param {Object} [options={}] - Configuration options for the sequence. * @param {number} [options.tick_interval=50] - The interval between ticks in milliseconds (minimum 1ms). Default tick every 50ms. * @param {boolean} [options.autodestroy=true] - Whether to automatically destroy the sequence when it completes. * @example * ```js * const seq = new Sequence({ tick_interval: 100, autodestroy: false }); * ``` */ constructor(options?: { tick_interval?: number; autodestroy?: boolean; }); /** * Starts the sequence. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.start(); // starts the sequence * ``` */ start(): Sequence; /** * Stops the sequence. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.stop(); // stops the sequence * ``` */ stop(): Sequence; /** * Pauses the sequence if it's running. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.pause(); // pauses the sequence * ``` */ pause(): Sequence; /** * Resumes the sequence if it's paused. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.resume(); // resumes the sequence * ``` */ resume(): Sequence; /** * Adds a delay task to the sequence. * @param {number} ms - The delay duration in milliseconds. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.delay(1000); // adds a 1-second delay * ``` */ delay(ms: number): Sequence; /** * Adds a log task to the sequence. * @param {string} message - The message to log. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.log("Task complete"); * ``` */ log(...messages: any[]): Sequence; /** * Converts the sequence to a JSON object that represents its state. * @returns {Object} A JSON-serializable representation of the sequence's current state. * @example * ```js * const seq = new Sequence() * .delay(1000) * .log("Hello") * .loop(); * * seq.start(); * * console.log(JSON.stringify(seq, null, 2)); * // output: * { * "state": "running", * "cur_task_index": 0, * "task_count": 2, * "is_looping": true, * "autodestroy": false * } * * seq.destroy(); * console.log(JSON.stringify(seq)); * // output: {"destroyed":true} * ``` */ toJSON(): any; /** * Adds a function call task to the sequence. * @param {Function} fn - The function to call. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.call(() => console.log("Hello world.")); * ``` */ call(fn: Function): Sequence; /** * Adds an await task to the sequence. * @param {Function} fn - A function that takes a resolve callback as its first parameter, * and optionally receives the result of the previous await task as its last parameter. * @param {Object} [options] - Optional configuration. * @param {number} [options.timeout=5000] - Timeout in milliseconds. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.await( * (resolve, prev_result) => { * console.log('Previous result:', prev_result); * setTimeout(() => resolve('new result'), 2000); * }, * { timeout: 3000 } * ) * ``` */ await(fn: Function, options?: { timeout?: number; }): Sequence; /** * Restarts the sequence from the beginning. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.restart(); // restarts the sequence * ``` */ restart(): Sequence; /** * Clears all tasks from the sequence and stops it. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.clear(); // clears all tasks * ``` */ clear(): Sequence; /** * Repeats all tasks that came before it in the sequence. * If there are multiple repeats, each one creates a new "section" to repeat. * The sequence runs from the start (or the previous repeat) up to each repeat instruction. * * @param {number} times - How many times to repeat the section. * @returns {Sequence} The Sequence instance for chaining. * * @example * new Sequence() * .log("A") * .repeat(2) // section 1: repeats "A" twice * .log("B") * .repeat(3) // section 2: repeats "A" (twice) and "B" three times * .log("C") // runs once after all repeats are done * // result: A, A, B, A, A, B, A, A, B, C */ repeat(times: number): Sequence; /** * Sets the sequence to loop indefinitely. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.loop(); // sets the sequence to loop * ``` */ loop(): Sequence; /** * Disables auto-destruction of the sequence after completion. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq * .log("Hellow World") * .persist() * .start(); * * // later you rerun the sequence * seq.start() // logs "Hello World" again * ``` */ persist(): Sequence; /** * Removes a task from the sequence at the specified index. * @param {number} index - The index of the task to remove. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.removeTask(2); // removes the third task (0 index) * ``` */ removeTask(index: number): Sequence; /** * Adds parallel tasks to the sequence. * @param {Sequence[]} sequences - An array of Sequences to run in parallel. * @param {Object} [options] - Optional parameters. * @param {boolean} [options.wait_for_all=false] - Whether to wait for all sequences to complete. * @param {number} [options.timeout=5000] - Maximum time (in ms) to wait for sequences to complete. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * new Sequence() * .log("Starting parallel tasks") * .parallel([ * new Sequence().delay(1000).log("Task 1 done"), * new Sequence().delay(2000).log("Task 2 done") * ], { wait_for_all: true, timeout: 3000 }) * .log("All parallel tasks completed") * .start(); * ``` */ parallel(sequences: Sequence[], options?: { wait_for_all?: boolean; timeout?: number; }): Sequence; /** * Destroys the Sequence instance, stopping all tasks and clearing the sequence. * This method should be called when the Sequence is no longer needed to ensure proper cleanup. * * @returns {void} * @example * ```js * const seq = new Sequence() * .delay(1000) * .log("Task complete") * .start(); * * // ... later, when you're done with the sequence: * seq.destroy(); * ``` */ destroy(): void; /** * Stops all currently running tasks, including parallel tasks. * This method is called internally by destroy(), but can also be used independently * to halt all execution without clearing the task list. * * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * const seq = new Sequence() * .parallel([ * new Sequence().delay(5000).log("This won't run"), * new Sequence().delay(2000).log("This might run") * ]) * .log("Main sequence continues"); * * seq.start(); * * // stop all tasks after 3 seconds * setTimeout(() => { * seq.stopAllTasks(); * console.log("All tasks stopped"); * }, 3000); * ``` */ stopAllTasks(): Sequence; /** * Sets an error handler for the sequence. * This handler will be called if an error occurs during the execution of any task in the sequence. * @param {Function} handler - The error handling function to be called with the error as its argument. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.catch(error => console.log('Sequence error:', error)); * ``` */ catch(handler: Function): Sequence; /** * Adds a handler to be called when the Sequence completes, regardless of whether it succeeded or failed. * @param {Function} handler - The function to be called when the Sequence completes. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * new Sequence() * .log("Starting") * .delay(1000) * .log("Done") * .finally(() => console.log("Cleanup")) * .start(); * ``` */ finally(handler: Function): Sequence; /** * Gets the current task index. * @returns {number} The current task index. * @example * ```js * const cur_index = seq.getCurrentTaskIndex(); * ``` */ getCurrentTaskIndex(): number; /** * Gets the current state of the Sequence. * @returns {'idle' | 'running' | 'paused' | 'completed' | 'error'} The current state of the Sequence. * @example * ```js * const seq = new Sequence().delay(1000).log("Done"); * console.log(seq.getState()); // 'idle' * seq.start(); * console.log(seq.getState()); // 'running' * ``` */ getState(): "idle" | "running" | "paused" | "completed" | "error"; /** * Checks if the sequence is currently running. * @returns {boolean} True if the sequence is running, false otherwise. * @example * ```js * if (seq.isRunning()) console.log('Sequence is active'); * ``` */ isRunning(): boolean; /** * Checks if the sequence is set to loop. * @returns {boolean} True if the sequence is set to loop, false otherwise. * @example * ```js * if (seq.isLooping()) console.log('Sequence will loop'); * ``` */ isLooping(): boolean; /** * Checks if the sequence has been destroyed. * @returns {boolean} True if the sequence has been destroyed, false otherwise. * @example * ```js * if (seq.isDestroyed()) console.log('Sequence has been destroyed'); * ``` */ isDestroyed(): boolean; /** * Gets the total number of tasks in the sequence. * @returns {number} The number of tasks. * @example * ```js * const task_count = seq.getTaskCount(); * ``` */ getTaskCount(): number; /** * Sets the tick interval for the sequence (default tick every 50ms). * @param {number} interval - The new tick interval in milliseconds. * @returns {Sequence} The Sequence instance for chaining. * @example * ```js * seq.setTickInterval(10); // sets tick interval to 10ms * ``` */ setTickInterval(interval: number): Sequence; #private; }