@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
TypeScript
/** @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;
}