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

deflux

v1.0.17

Published

A declarative FLUX architecture for React

Downloads

22

Readme

deflux

A declarative FLUX architecture for React

Features

  1. Flux architecture
  2. Support multiple stores
  3. Support declarative syntax
  4. Support pure function for action / render / component / reducer
  5. Support linked props
  6. Support computed props
  7. Support wired actions for store
  8. Support many prop sources: Store, Own Props, State, Promise, Literal
  9. Update store props/reducers/middleware on demand
  10. Compatible with Redux store/reducer/middleware
  11. Compatible with Rxjs

Samples

https://codesandbox.io/s/j30rxwnww9

References

create(factory, ...describers)

Create an object which is built by factory method and describers

update(target, ...describers)

store(initialState)

Create store factory with initialState

component(renderMethodOrComponentClass)

Create component factory. create() will return HOC instead Component if no renderMethodOrComponentClass specified

Store: withProp(stateProp, fromStore(parentStore), parentProp)

Declare linked store prop which is linked to a specific prop of parent store. Once parent store updated, all linked props of child stores will update as well. Remark: When You update linked props of child stores, parent store's props will update as well. This is 2 ways binding. It is helpful to create an action can update multiple stores. For sample: Imaging you have 2 stores, one for todo ids, other for todo texts. You want to update both stores with an action

const IdStore = create(store([]));
const TextStore = create(store({}));
const TodoStore = create(
  store(),
  // link ids to IdStore, it holds id list
  withProp("ids", fromStore(IdStore)),
  // link texts to TextStore, it holds text list
  withProp("texts", fromStore(TextStore))
);
const AddTodoAction = text => state => {
  const id = new Date().getTime();
  return {
    ...state,
    // append id to id list
    ids: [...state.ids, id],
    // set new text to texts hash
    texts: {
      ...state.texts,
      [id]: text
    }
  };
};
TodoStore.dispatch(AddTodoAction, "Test Todo");

Store: withProp(stateProp, fromProp(...propNames), computer)

Declare computed store prop which can be computed from one or many props.

create(
  store({ width: 5, height: 2 }),
  // compute area from with & height
  withProp(
    "area",
    fromProp("width", "height"),
    (width, height) => width * height
  )
);

Store: withReducer(...reducers)

Declare reducer for the store. Reducer is function, it retrieves (state, action, payload) => newState. Reducer will be called if there is any action creator called. There are two kinds of action. One can modify state and other only create action payload only.

const MyActionCreator = text => text;
// when an action returns a function, it will retrieve state as an argument and it becomes state modifier.
// No reducer can handle this action type
const MyStateModifierAction = text => state => ({ text });
const MyReducer = (state, action, payload) => {
  if (action === MyActionCreator) {
    // do something and return new state
    return { ...state, text: payload };
  }
  return state;
};
MyStore.dispatch(MyActionCreator, "Hello World");

Store: withMiddleware(...middleware)

Declare middleware for the store. Middleware is a curry function, it retrieves store => next => (action, payload) => newState

Component: withProp(name, propSource, map)

Declare component prop, there are two prop sources: fromStore and fromProp (owned props). You can specific the prop retrieves value from one or more Stores

withProp(
  "name",
  fromStore(store1, store2, store3),
  // map all store states to prop value
  (store1State, store2State, store3State) => finalValue
);

You can specific the prop retrieves value from one or more owned props.

withProp(
  "name",
  fromProp("prop1", "prop2", "prop3"),
  // map all owned prop value to new prop value
  (prop1Value, prop2Value, prop3Value) => finalValue
);

You also specific multiple props at once.

withProp("*", fromStore(store), state => ({
  prop1: state.value1,
  prop2: state.value2
}));

Component: withAction(name, store, action, payloadFactory)

Declare wired action as component prop.

const MyStore = create(store({ name: "Peter" }));
const MyAction = () => state => {
  alert(state.name);
  // no change
  return state;
};
const Component = create(
  component(props => <div onClick={props.click} />),
  withAction("click", MyStore, MyAction)
);

You can pass payloadFactory to produce new payload from calling context and input args. Calling context has some props: ownProps (the original props retrieved from parent component), mappedProps (the props that component will be used to render) payloadFactory has prototype: (arg1, arg2, ...) => payload. (arg1, arg2, ...) => callingContext => payload.

withAction(
  "propName",
  MyStore,
  MyAction,
  (arg1, arg2, arg3) => callingContext =>
    arg1 + arg3 + callingContext.ownProps.name
);

Connect Redux store to component

const ReduxIncreaseActionType = 1;
const ReduxDecreaseActionType = 2;
const ReduxIncreaseActionCreator = () => ({ type: ReduxIncreaseActionType });
const ReduxDecreaseActionCreator = () => ({ type: ReduxDecreaseActionType });
const ReduxReducer = (state = 100, action) => {
  if (action.type === ReduxIncreaseActionType) return state + 1;
  if (action.type === ReduxDecreaseActionType) return state - 1;
  return state;
};

const ReduxStore = createStore(ReduxReducer);

const ReduxComponent = create(
  component(props => (
    <div>
      <div>{props.counter}</div>
      <button onClick={() => props.increase()}>Increase</button>
      <button onClick={() => props.decrease()}>Decrease</button>
    </div>
  )),
  withProp("counter", fromStore(ReduxStore)),
  withAction("increase", ReduxStore, false, ReduxIncreaseActionCreator),
  withAction("decrease", ReduxStore, false, ReduxDecreaseActionCreator)
);

Map observable value to component prop

import { fromEvent } from "rxjs";
const source = fromEvent(document, "click");

const MouseInfo = create(
  component(props => (
    <div>
      Mouse Info:
      {props.mouseEvent
        ? `clientX: ${props.mouseEvent.clientX}, ${props.mouseEvent.clientY}`
        : "Not clicked yet"}
    </div>
  )),
  withProp("mouseEvent", fromObservable(source))
);