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

fluxomorph

v1.0.2

Published

Minimal Isomorphic Flux Implementation

Downloads

2

Readme

Fluxomorph

Build Status npm version Dependency Status devDependency Status

Introduction:

Minimal Isomorphic Flux Implementation. Still WIP. Made both out of need and for educational purposes. Full example of usage can be seen in fluxity-starter-auth.

Install:

npm install fluxomorph --save

Usage:

  • Create a flux instance with actions and stores using only the constructor.
var Flux = require('fluxomorph');

var myFlux = Flux({
  Stores: {
    myStore: {
      getInitialState: function() {
        return {
          hello: 'world',
          age: 28
        };
      },
      handlers: {
        'MY_ACTION_EVENT': function(context, payload) {
          this.setState(payload);
        },
        'MY_OTHER_ACTION_EVENT': function(context, payload) {
          this.replaceState(payload);
        }
      }
    }
  },
  Actions: {
    myAction: function(context, payload, done) {
      context.Dispatcher.emit('MY_ACTION_EVENT', payload);
    },
    myOtherAction: function(context, payload, done) {
      context.Dispatcher.emit('MY_OTHER_ACTION_EVENT', payload);
    }
  }
});
  • Create a flux instance with actions and stores using the constructor and register methods.
var Flux = require('fluxomorph');

var myFlux = Flux();

myFlux.registerStore('myStore', {
  getInitialState: function() {
    return {
      hello: 'world',
      age: 28
    };
  },
  handlers: {
    'MY_ACTION_EVENT': function(context, payload) {
      this.setState(payload);
    },
    'MY_OTHER_ACTION_EVENT': function(context, payload) {
      this.replaceState(payload);
    }
  }
});

myFlux.registerAction('myAction', function(context, payload, done) {
  context.Dispatcher.emit('MY_ACTION_EVENT', payload);
});

myFlux.registerAction('myOtherAction', function(context, payload, done) {
  context.Dispatcher.emit('MY_OTHER_ACTION_EVENT', payload);
});
  • Using custom setState, replaceState and getState methods for stores. This enables you to use your favorite immutable data structures.
var Flux = require('fluxomorph');

var myFlux = Flux();

myFlux.registerStore('myStore', {
  getInitialState: function() {
    return {
      hello: 'world',
      age: 28
    };
  },
  setState: function(emitUpdate, newState) {
    this.state = assign(this.state, newState);
    emitUpdate();
  },
  replaceState: function(emitUpdate, newState) {
    this.state = assign({}, newState);
    emitUpdate();
  },
  getState: function() {
    return assign(Array.isArray(this.state) ? [] : {}, this.state);
  },
  handlers: {
    'MY_ACTION_EVENT': function(context, payload) {
      this.setState(payload);
    },
    'MY_OTHER_ACTION_EVENT': function(context, payload) {
      this.replaceState(payload);
    }
  }
});
  • Adding stuff to the context, making it available to the actions.
var Flux = require('fluxomorph');

var myFlux = Flux();

myFlux.registerStore('myStore', {
  getInitialState: function() {
    return {
      hello: 'world',
      age: 28
    };
  },
  setState: function(emitUpdate, newState) {
    this.state = assign(this.state, newState);
    emitUpdate();
  },
  replaceState: function(emitUpdate, newState) {
    this.state = assign({}, newState);
    emitUpdate();
  },
  getState: function() {
    return assign(Array.isArray(this.state) ? [] : {}, this.state);
  },
  handlers: {
    'MY_ACTION_EVENT': function(context, payload) {
      this.setState(payload);
    },
    'MY_OTHER_ACTION_EVENT': function(context, payload) {
      this.replaceState(payload);
    }
  }
});

myFlux.addToContext('api', {
  signIn: function() {}
});

myFlux.addToContext('router', {
  redirect: function() {}
});

// inside action handlers you now have context.api and context.router
  • Listening for updates in stores
myFlux.Stores.myStore.on('change', function() {
  console.log('updated state:', myFlux.Stores.myStore.getState());
});

var currentState = myFlux.Stores.myStore.getState();
console.log('initial state:', currentState);

myFlux.Actions.myAction({
  age: 50
});
  • Dehydration / rehydration (pull all state out of the stores in your instance for serialization / initialization)
var Flux = require('fluxomorph');

var filledStoreDefinitions = {
  myStore: {
    getInitialState: function() {
      return {
        hello: 'world',
        age: 28
      };
    }
  },
  myOtherStore: {
    getInitialState: function() {
      return [
        'hello',
        'goodbye'
      ];
    }
  }
};

var emptyStoreDefinitions = {
  myStore: {
    getInitialState: function() {
      return {};
    }
  },
  myOtherStore: {
    getInitialState: function() {
      return [];
    }
  }
};

var myFlux = Flux({
  Stores: filledStoreDefinitions
});

var filledAppState = myFlux.dehydrate();
console.log(filledAppState);
/*
{
  myStore: {
    hello: 'world',
    age: 28
  },
  myOtherStore: [
    'hello',
    goodbye
  ]
}
*/

var myOtherFlux = Flux({
  Stores: emptyStoreDefinitions
});

var emptyAppState = myOtherFlux.dehydrate();
console.log(emptyAppState);
/*
{
  myStore: {},
  myOtherStore: []
}
*/

myOtherFlux.rehydrate(filledAppState);

var rehydratedAppState = myOtherFlux.dehydrate();
console.log(rehydratedAppState);
/*
{
  myStore: {
    hello: 'world',
    age: 28
  },
  myOtherStore: [
    'hello',
    goodbye
  ]
}
*/
  • Attach handlers to eventEmitters/sockets (wip - there is still some work to be done here to have proper cleanup)
// socket in this case might be a socket.io/ws connection or just an any event emitter
// following the eventEmitter.on('eventName', function handler() {...}) pattern

myFlux.registerSocketActor(socket, 'some-event', function(context, payload) {
  // call an action
  context.Actions.myAction(payload);
  // or alternatively dispatch a message to a store directly
  // context.Dispatcher.emit('MY_ACTION_EVENT', payload);
});

myFlux.registerSocketActor(socket, 'some-other-event', function(context, payload) {
  // call an action
  context.Actions.myOtherAction(payload);
  // or alternatively dispatch a message to a store directly
  // context.Dispatcher.emit('MY_OTHER_ACTION_EVENT', payload);
});
  • Getting the context of your flux instance (which you might want to pass to another mechanism - e.g your router)
var context = myFlux.getContext();

// now you have access to context.Stores, context.Actions and context.Dispatcher
  • React state mixin (example using react-router and child context).
'use strict';

var React = require('react');
var Router = require('react-router');
var RouteHandler = Router.RouteHandler;
var Flux = require('fluxomorph');

var storeDefinitions = require('../store-defs');
var actionDefinitions = require('../action-defs');

var App = React.createClass({
  mixins: [Flux.StateMixin('flux')],

  childContextTypes: {
    flux: React.PropTypes.object.isRequired,
    routerState: React.PropTypes.object.isRequired
  },

  propTypes: {
    flux: React.PropTypes.any,
    routerState: React.PropTypes.object
  },

  getChildContext: function() {
    return {
      flux: this.props.flux,
      routerState: this.props.routerState
    };
  },

  render: function() {
    return (
      <RouteHandler
        state={this.state}
      />
    );
  }
});

var router = Router.create({...});

var flux = Flux({
  Stores: storeDefinitions,
  Actions: actionDefinitions
})

flux.addToContext('router', router);

router.run(function(Handler, routerState) {
  React.render(
    <Handler
      flux={flux.getContext()}
      routerState={routerState}
    />,
    document.body
  );
});

/*
this.state in the react component will have the form:

{
  Stores: {
    myStore: {...},
    myOtherStore: {...}
  }
}

 */