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 🙏

© 2024 – Pkg Stats / Ryan Hefner

storyline

v1.0.0

Published

A scenario runner for node apps

Downloads

25

Readme

Storyline.js

Storyline is a scenario runner for Node JS projects. The goal is to help with cascading requirements for QA, Testing, and Demo purposes.

Let's say we needed to demo the onboarding process to new clients. To get this all setup in a dev environment, we might need to:

  • Migrate the database
  • Register an OAuth application
  • Create a dummy user
  • Create Seeded Data for the user
  • Create Seeded Data for the user's team

While a single scenario can be something that is memorizable, Storyline.js aims to make these kinds of app states faster and easier to recreate.

Installation

To install Storyline.js run:

npm install --save storyline

Setting Up a Storyline Instance

To get started using storyline, we will first need to create a new Storyline instance. Since Storyline is built to work with any framework or library, it takes in a Javascript arugment for the application being worked on. This could be anything from a POJO to a full application instance of our favorite JS framework. For this example, we'll pass in a POJO with a small KNEX instance to be able to run migrations:

const Storyline = require('storyline');
const pg = require('knex')({
  client: 'pg',
  connection: process.env.PG_CONNECTION_STRING,
  searchPath: 'knex,public',
});

const app = {db: pg};

const story = new Storyline(app);

Creating Plots/Scenarios

In Storyline.js the different scenarios that we want to run in sequence to set up an application state are called Plots. Each Plot is a ES2015 class consisting of two possible attributes:

  • requirements - a getter function returning an array of all the names of plots that need to be run before executing the current plot.
  • run - a function that will be run after all requirements have been fulfilled. This function will receive the application instance passed in when we created our Storyline instance.

Here, let's create a plot called CreateUser that will insert a row into the users table:

const Plot = require('storyline/plot');

class CreateUsers extends Plot {
  run(app) {
    return app.db('users').insert([
      {first_name: 'Tony', last_name: 'Stark'},
    ]);
  }
}

Registering Plots With Storyline

Now that we have our CreateUsers Plot, we need to register it with our Storyline instance. Here we will use the addPlot function to register our create-users plot to be run. Then to run a registered plot, we will use the run method on our Storyline and pass in the plot name that we want to run.

const Storyline = require('storyline');
const Plot = require('storyline/bin/plot');
const pg = require('knex')({
  client: 'pg',
  connection: process.env.PG_CONNECTION_STRING,
  searchPath: 'knex,public',
});

const app = {db: pg};

const story = new Storyline(app);

class CreateUsers extends Plot {
  run(app) {
    return app.db('users').insert([
      {first_name: 'Tony', last_name: 'Stark'},
    ]);
  }
}

story.addPlot('create-users', CreateUsers);
story.run('create-users');

Waiting on Other Plots

Now, what if we wanted to add something to our aliases table and set a foreign key to "Tony Stark"? We need to use the requirements option to specify that we must be sure that CreateUsers has already run.

const Storyline = require('storyline');
const Plot = require('storyline/bin/plot');
const pg = require('knex')(require('./knexfile').development);

const app = {db: pg};

const story = new Storyline(app);

class CreateUsers extends Plot {
  run(app) {
    return app.db('users').insert([
      {first_name: 'Tony', last_name: 'Stark'},
    ]);
  }
}

class CreateAliases extends Plot {
  run(app) {
    return app.db('users').where(
      {first_name: 'Tony', last_name: 'Stark'}
    ).select('id').then((users) => {
      const user_id = users[0].id;

      return app.db('aliases').insert({user_id, name: 'Iron Man'});
    });
  }
}

story.addPlot('create-users', CreateUsers);
story.addPlot('create-aliases', CreateAliases);
story.run('create-aliases').then(pg.destroy);