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

@twist/core

v0.1.2

Published

[![Build Status](https://travis-ci.org/adobe/twist.svg?branch=master)](https://travis-ci.org/adobe/twist)

Downloads

8

Readme

Twist: Reactive State-Management for JavaScript Applications

Build Status

A web application is a lot like an iceberg - what you see on the surface is just a tiny fraction of the complexity that lies beneath the waves. To a casual observer, it's easy to get absorbed by beautiful designs, and be amazed by how a little CSS and JavaScript can give rise to such immersive experiences. But the more complex an application becomes, the more critically it depends on a solid foundation - the nuts and bolts of component hierarchies, state management, and caching layers that hold the whole thing together.

Twist is a library that arose in light of these problems, by focusing on application state, and how it gets bound to reusable UI components. Twist is not a UI framework in its own right, but it does provide a syntax for writing components that's compatible with other frameworks, such as React. It uses a structured reactive approach, so that you easily scale your application, while maintaining an easy way of binding to the view - you'll recognize concepts that were inspired by Mobx and Redux, which are both very popular state-management libraries for React.

To give you a feel for what Twist looks like, here's a small fragment of code, showing part of a model (a store), and part of a view (a component). Notice that stores can nest other stores (DOB and Address are also stores, but aren't shown):

@Store
class User {
    @State.byVal name;
    @State.byVal description;
    @State.byRef(DOB) birthday;
    @State.byRef(Address) address;

    @Action CHANGE_DESCRIPTION(newDescription) {
        this.description = newDescription;
    }
}

@Component
class ProfileView {
    @Attribute user;
    @Observable newDescription;

    constructor() {
        super();
        this.newDescription = this.user.description;
    }

    render() {
        return <g>
            <div>Hello { this.user.name }!</div>
            <if condition={ this.user.birthday.isToday() }>
                <div>Happy Birthday!!</div>
            </if>
            <div>About yourself: <input bind:value={ this.newDescription }/></div>
            <button onClick={ () => this.user.dispatch('CHANGE_DESCRIPTION', this.newDescription) }>Save</button>
        </g>;
    }
}

The Twist Documentation explains everything in great detail, but here's a preview of the main concepts:

  • Application state is placed in stores - these are serializable to/from JSON, and the @State.xxx decorators tell Twist how to serialize each property (which can itself be another store).
  • Stores are modified via actions - this ensures that all changes go through a single bottleneck (the "dispatcher"), so that you can reason about all the changes to your state. In particular, this means that Twist supports time-traveling debugging, using the Redux Devtools Extension.
  • Any state that can change is marked as observable, which allows Twist to know what to update when it changes (anything marked with @State.xxx is implicitly observable).
  • UI components have attributes as a means of passing in arguments, and a render function that declaratively shows how to render the component (this uses JSX syntax). When anything observable changes that the component depends on, the rendered view will be automatically updated.

While the state portion of Twist is framework-agnostic, the implementation of components depends on which UI framework is used. Right now, Twist only supports React, via React-Twist, but it's designed so that there can be other implementations in the future (and we encourage contributions if you're interested in helping with this!). This would allow the same component to work with multiple UI frameworks, which would be great for shared component libraries! Even today, React-Twist makes it really easy to use Twist stores with React, and also adds a bunch of features on top of React to make your life easier. See here for a complete description of the features.

Note: In case you're wondering, React-Twist components are React components - they just automatically optimize when to re-render, so you don't need to think about it. If you write a component in React-Twist, it can be used directly by a normal React application. Similarly, React-Twist components can use normal React components directly - everything is rendered via React and ReactDOM.

Using Twist

If you want to use both the state-management and component layers of Twist, you'll need to install the following (via NPM or Yarn):

  • @twist/core - This includes support for stores, data binding, and application state management.
  • @twist/react - The React implementation of Twist components.
  • @twist/react-webpack-plugin - A webpack plugin that compiles Twist files (Twist has its own Babel transform that runs before React's).

If you're not using webpack, you can also get hold of the Babel configuration directly, using @twist/configuration (this is done automatically by the webpack plugin).

After that, the only thing you need is a .twistrc file in the root of your project, that tells Twist which libraries to include (this is also used by the Twist ESLint plugin). There are a number of advanced options, but to get up and running, you just need to tell Twist that you're using React-Twist:

{
    "libraries": [
        "@twist/react"
    ]
}

In your webpack.conf.js you can now include the React Twist plugin - by default this will compile all files that end in .jsx with Twist and React:

const ReactTwistPlugin = require('@twist/react-webpack-plugin');

module.exports = {
    ...
    plugins: [
        new ReactTwistPlugin(),
        ...
    ],
    ...
};