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

packs-framework

v2.0.10

Published

The packs framework provides state management and a React-based container for loading [packs](https://gitlab.com/wiagl/packs) survey components. The framework takes in a list of components, declarative JSON "modules" (one for each survey screen), an initi

Downloads

28

Readme

Packs Framework ✌️

The packs framework provides state management and a React-based container for loading packs survey components. The framework takes in a list of components, declarative JSON "modules" (one for each survey screen), an initial state object, a "wrapper" component for wrapping components across all screens, and a recorder function to store responses. It's recommended to use the packs cli tool for generating and managing surveys, instead of directly using the framework.

Packs components

Packs components are the building blocks of a packs app. Each component returns response data that advances the survey to the next screen, or survey "module", using the push function exposed from the framework.

Here is a simplified example of a component that asks for a binary response, 'A' or 'B' using radio buttons:

({ name='qux', options=['A', 'B'], push }) => (
  <div>
  {
    options.map((option, i) => (
      <label
        key={i}
        onClick={() => push({ [name]: option })}
      >
        {option}
        <input type="radio" />
      </label>
    ))
  }
  </div>
)

Each component can access variables from the global state / response object using a special $ syntax in its props, which is explained further below.

JSON modules

Each survey screen is defined by a declarative JSON object that references a specific component and provides parameters as props to the component. The following example references a component similar to the example component above, in the npm package "your-components". This component will return the response to the global state / response object under the variable "indent_preference" which can later be referenced inside props using the syntax "$indent_preference" or, embedded in a string, as "Really? You prefer ${indent_preference}??".

Example component:

{
  "component": "your-components/ChooseOne",
  "name": "indent_preference",
  "text": "Which do you prefer?",
  "options": [
    "Tabs",
    "Spaces"
  ]
}

Later example:

{
  "component": "your-components/Message",
  "text": "Really? You prefer ${indent_preference}??"
}

State management

The framework maintains an atomic state object that components can write to, in order to unmount, and read from during mounting. This works because surveys are generally a linear process. The StateList state manager also handles browser history between survey modules automatically. It also provides a temporary screenState object that modules can write to during instantiation through the exposed set function, which will temporarily overwrite the global state object. For example, a component with a text input could update itself through the set function:

const component = ({ value, set }) => (
  <input
    type="text"
    value={value}
    onChange={e => set({ v: e.target.value })}
  />
)

component.defaultProps = {
  value: '$v'
}

Afterwards the framework will reset the screenState object for the next module.

Recorder function

The framework uses a recorder function for storing response data which you can customize and pass in. The recorder function is initialized on page load and called after each push call. Here is a simplified example:

const recorder = (endpoint, responseObject, index) => {
  // you must initialize a session "key" so that the framework doesn't keep trying to initialize
  sessionStorage.setItem("key", "INITIALIZED");

  return new Promise((reject, resolve) => {
    // handle the responseObject
    resolve();
  });
}

A response object looks like:

{
  data: [{
    module_0_component: 'your-components/ChooseOne',
    module_0_t: 1508503142793,
    indent_preference: 'Spaces'
  }],
  screenState: [
    {
      indent_preference: 'Tabs',
      timestamp: 1508503141700
    },
    {
      indent_preference: 'Spaces',
      timestamp: 1508503142100
    }
  ],
  silent: false
}

The data field is an array in case the user goes back and changes their answer.

Silent components

Silent components are renderless components that simply process data, for example randomizing two states:

{
  "component": "packs-components/Randomize",
  "states": [
    { "coin": true },
    { "coin": false }
  ]
}

These components must pass a silent flag, by passing true as the second argument when calling push to ensure that StateList doesn't create a new history entry (or else going back wouldn't work since the component instantly returns). For example:

push({ coin: Math.random() > 0.5 }, true);

Wrapper component

A wrapper component is a special container component to style and house a survey. It can access the survey state and display a progress bar or other useful information.

Advanced

pack function

The pack function is a higher-order function that takes in a set of components and returns a special function that takes an initial state object, modules, element id where to mount, wrapper component and recorder function. It's recommended to use the packs cli tool instead of using this function directly.

Simplified example:

import { pack } from 'packs-framework'
import components from 'my-components'
import wrapper from 'my-wrapper'
import recorder from 'my-recorder'

const run = pack(components)

const initialState = {
  start: Date.now()
}

const modules = [
  {
    "component": "Markdown",
    "source": "### Instructions\nPlease be honest"
  },
  {
    "component": "ChooseOne",
    "name": "indent_preference",
    "text": "Which do you prefer?",
    "options": [
      "Tabs",
      "Spaces"
    ]
  },
  {
    "component": "NumberInput",
    "text": "How many spaces?",
    "condition": {
      "==": ["$indent_preference", "Spaces"]
    }
  }
]

const elementId = 'root' // id of div to mount app

run(initialState, modules, elementId, wrapper, recorder)

Browser support

Packwrap currently targets IE10+ and evergreen browsers. Compatibility table coming soon...

Thanks to BrowserStack for providing cross-browser testing for this project. They are an excellent service for testing your surveys across many browsers and devices and support open-source projects. browserstack

Version history

2.0.10

  • queueUrl may not exist (undefined).

2.0.9

  • Adding config.

2.0.8

  • Adding queueUrl.

2.0.7

  • update yarn

2.0.6

  • save module name

2.0.5

  • Remove lib from git, use eslint.

2.0.4

  • lib/stateList.js was in camelcase for some reason, change to lib/StateList.js as it should be.

2.0.3

  • Undo the changes in 2.0.2 which were done by accident.

2.0.2

  • Move various Babel dependencies from dev-dependencies, because they are needed when packing surveys.

2.0.1

Last Robbie version