npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@silver-zepp/sequence

v1.0.3

Published

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

Readme

Sequence

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

Key Features

  • Linear Readability: Define sequences of operations in a clear, Arduino-like linear fashion.
  • Timing Control: Control over delays and execution timing.
  • Async/Sync Mixing: Combine synchronous and asynchronous tasks.
  • Flow Control: Pause, resume, and loop functionality for flexible execution.
  • Parallel Execution: Run tasks in parallel with timeout control.
  • Error Handling: Built-in error with .catch() and cleanup with .finally(); try/catch out of the box.
  • State Management: Track sequence state (idle, running, paused, completed, error).
  • Composability: Easily compose and reuse sequences.

Use Cases

  • Animation sequencing (move a box from A to B, wait a second, move it to C)
  • Game development (cutscenes, scripted events)
  • API call orchestration (if this then that)
  • Any scenario requiring precise timing and sequencing of operations
  • Complex UI interactions

Examples

// install -> npm i @silver-zepp/sequence
import { Sequence } from '@silver-zepp/sequence';

// Example #0: Print Hello World after 1 second
new Sequence()
	.delay(1000)          // wait for 1000ms
	.log("Hello World")   // print a message
	.start()              // autostart this sequence

// Example #1: A little bit more complex Arduino-like execution chain
const seq = new Sequence()
  .log("1. Waiting 500 ms")
  .delay(500)
  .log("2. Waiting 1000 ms")
  .delay(1000)
  .log("3. Waiting 2000 ms")
  .delay(2000)
  .call(() => console.log("===> Custom function called"))
  .log("4. Starting parallel tasks")
  .parallel([
    new Sequence().delay(1000).call(() => console.log("===> task [ 1 ] done")),
    new Sequence().delay(2000).call(() => console.log("===> task [ 2 ] done"))
  ], { wait_for_all: true, timeout: 3000 }) // wait for all parallel tasks to finish? this is done async
  .log("5. All parallel tasks completed or timed out")
  .log("6. All done")
  .loop()
  .start()

// Example #2: async + context passing
function asyncBlockA(resolve) {
  console.log('dummy async op...');
  setTimeout(() => {
    console.log('dummy async op DONE after 2 seconds');
    resolve({ ok: true, data: 'dummy data' });
  }, 2000);
}

function blockB(data) {
  console.log(JSON.stringify(data));
}

const seq = new Sequence()
  .log('Starting blocks A & B sequentially')
  .await(asyncBlockA, { timeout: 3000 }) // timeout of 3s (default 5s)
  .log('Block A executed waiting for 1s before going next')
  .delay(1000)
  .call((result) => blockB(result)) // using `result` from .await() method
  .log('All sequential tasks completed')
  .start();

// Example #3: Animate some things
const seq = new Sequence()
  .log("Starting animation")
  .call(() => circle.add("fade-in")) // call arbitrary function
  .delay(500)
  .call(() => circle.add("move-up"))
  .delay(1000)
  .parallel([ // call multile functions at the same time in async manner
    new Sequence().call(() => circle.add("rotate")),
    new Sequence().call(() => updateText("Animation complete!"))
  ])
  .log("Animation sequence finished")
  .start();

// Example #4: Operate with variables outside the sequence
let check_count = 0;
let is_destroyed = false;
const checker = new Sequence()
  .call(() => {
    check_count++;
    is_destroyed = seq.isDestroyed();
    if (is_destroyed) {
      console.log("Seq state:", JSON.stringify(seq));
      checker.stop();
    } else {
      console.log("Checker CHECKS:", check_count);
    }
  })
  .delay(1000)
  .loop()
  .start()


// Example #5: Basic parallelism
new Sequence()
  .log("Starting parallel tasks")
  .parallel([
    new Sequence().delay(2000).log("Task 1 done (2 sec)"),
    new Sequence().delay(1000).log("Task 2 done (1 sec)"),
    new Sequence().delay(4000).log("..."), // This task will timeout
  ], { mode: Sequence.PARALLEL_MODE_ALL, timeout: 3000 }) // note the mode selector
  .log("All parallel tasks completed")
  .start();

// Example #6: Timescale manipulation
// aka make things slow down or speed up
// 1.0 is the default speed; 
// at 0.5 the sequence will take twice the time
// delay(1000) = 1s but delay(1000) at timescale 0.5 is equal to 2000 (!)
Sequence.SetTimeScale(1.0);  

let count = 0;
let delay_start_time = 0;
const seq = new Sequence({ tick_interval: 50 })
  .call(() => count++)
  .repeat(5) // this will loop the above code, making count = 5
  .log("1. Count:", () => `${count} (index: ${seq.getCurrentTaskIndex()})`)
  .call(() => delay_start_time = Date.now())
  .delay(1000)
  .log("2. After 1s delay")
  .log("Actual delay time:", () => `${Date.now() - delay_start_time}ms`)
  .log("TS:", Sequence.GetTimeScale, "DT:" , Sequence.GetDeltaTime)
  .log("3. Count:", () => `${count} (index: ${seq.getCurrentTaskIndex()})`)
  .repeat(5) // this will loop the whole code from above so the end count will be 5 * 5 = 25
  .log("4. Execution finished")
  .call(()=> setTimeout(after, 300)) // execute external function that will check if the seq is destroyed
  .start();

function after(){
  console.log(seq.isDestroyed())
}

// Example #0 (again): Same old example but with a little bit more explanation
new Sequence()
	.delay(1000)          // wait for 1000ms
	.log("Hello World")   // print a message
	.start()              // autostart this sequence
// Note: the sequence will autodestroy itself after execution
// if you want to rerun it in the future, create the seq with autodestroy flag set to false
const seq = new Sequence({ autodestroy: false })
	.delay(1000)
	.log("Hello World")
// this way you can start the sequence whenever you need and as many times as needed
seq.start();
// ...
seq.start();