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

vistate

v0.2.2

Published

Recordable state container. OOP style

Downloads

11

Readme

Vistate: smart actionable models instead of one big state container

state of project: not ready for use in production YET. But keep watching.

Assumptions

  1. Action dispatching is conceptually the same as method call
object.dispatch({type: 'increment', payload: 30});

is conceptually the same as:

object.increment(30);

We just have some object (e.g. model, store, entity etc.) and we send messages to it (It is nothing new, it's just the old school OOP.).

But method calling requires less boilerplate so the approach object.increment(30) is preffered to the first one.

  1. Sometimes we just need intelligent models which encapsulate both state and logic

  2. Sometimes we need whole hierarchy of models

    [  -------------------------- Todo application -------------------------- ]
       	[ TodoList ]           	[ TodoList ]              	[ TodoList ]
        |      |      |        |      |      |             |      |      |
     [Todo] [Todo] [Todo]    [Todo] [Todo] [Todo]        [Todo] [Todo] [Todo]
                                       ^
      					we like to send an action to this Todo

    And it should be possible to send action to the specific model and work on model level (not store or observable property level). In Vistate the most important thing is a model.

  3. Logic of dispatching the action and updating the state should be hidden from user. There is some kind of magic behind scene. When user calls

  counter.increment(30)

this could be dispatched in anyway possible. Action could be automatically recorded, previous state could be saved, subcribers could be notified. These things work automatically behind scenes, mainly in middleware systems. Systems are assigned to the models during creation.

  1. Projects should be easily debuggable and inspectable (there will be Dev Tools for Vistate soon...)

  2. Built-in solution for side-effects and asynchronicity (currently there are transactions for this purpose).

  3. Embracing inspiration

    Vistate takes inspiration from Redux, MVC, Smalltalk, SAM pattern, CQRS, event sourcing, DDD, Entity Component System, Vue, Vuex, Mobx, React, Django, Backbone, Rx, Redux Saga and many other things.

    This means that although there could be some similarities with many other libraries and approaches but Vistate is not bound to one philosophy but it's inspired by many.

  4. Immutability / mutability is an implementation detail.

    This framework started as being mutable. It promoted mutation of models directly in the action handlers:

    ....
    increment(state) {
      state.value += 1;
    }
    ....

    Now there is ongoing transition to use immutable data, but the API stays the same. In current implementation action handlers just don't receive real state but only proxy objects. When an action handler calls

    state.value += 1;

    This mutation is only recorded (not yet applied). This is the model that really applies these mutations. This is inspired by SAM pattern and its "proposed values". But the difference is that in Vistate there is a little bit syntax sugar to it. To achieve this a little library called transmutable was created. You can try it yourself.

for examples of use check test cases because they are most recent source of truth: https://github.com/hex13/enter-ghost/blob/master/packages/vistate/test/stateContainerSpec.js

API is not stable yet so there can be breaking changes.

Latest breaking changes:

  • no data() method in Transaction.
  • transaction methods return promise

Examples of use:


const assert = require('assert');
const { Model } = require('vistate');


class Example extends Model {
    $initialState() {
        return {value: 100};
    }
    inc(state, amount) {
        state.value += amount;
    }
}

const model = new Example();
model.$subscribe(() => {
    console.log("update your view here");
    console.log("current state:", model.state);
});

// notice that each call will trigger handler passed in `subscribe`
model.inc(100);
model.inc(200);
assert.equal(model.state.value, 400);
console.log("UNDO!");

// this uses event sourcing under the hood:
model.$undo();
assert.equal(model.state.value, 200);