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

@dhmk/hub

v0.0.1

Published

Action dispatching system with middleware and devtools support.

Downloads

8

Readme

@dhmk/hub

Action dispatching system with middleware and devtools support.

Allows you to dispatch and listen to custom actions, intercept and modify actions, and provides helpers to define action + handler pair as a regular method function.

Install: yarn add @dhmk/hub

Example

import hub, { logger, devTools } from "@dhmk/hub";

const example = hub({
  items: [] as any[],

  createItem: hub.action(() => {
    const id = Date.now() & 0xfff;

    const item = hub.withMeta({ id })(example, "item", {
      id,
      name: "item",

      setName: hub.action((name) => (item.name = name)),
    });

    example.items.push(item);

    hub.dispatch(example, "my_action", 1, 2, 3);
    // hub.dispatch(example, {type: 'my_action', args: [1, 2, 3]})

    return item;
  }),

  logger: hub("logger", {
    log: hub.action((...args) => {
      console.log("log", ...args);
      return 123;
    }),

    asyncLog: hub.action(function (x) {
      return setTimeout(this.log, 10, x);
    }),

    promiseLog: hub.action((x) => {
      console.log("promiseLog", x);
      return new Promise((res) => {
        setTimeout(res, 10, x);
      });
    }),
  }),

  [hub.defaultHandler]: (a) => {
    if (hub.shouldHandleAction(example, "item", a))
      return hub.handleAction(
        example.items.find((x) => x.id === a.meta.id),
        a
      );
  },
});

const root = hub.root("root", { example });
// root.add("example", example);

logger(root);
devTools(root);

export default class App extends React.Component {
  render() {
    return (
      <div>
        <h1>Test app</h1>
        <div>
          <button
            onClick={() =>
              example.logger.log({ id: 111, name: "test" }, "pizza", 10)
            }
          >
            Log
          </button>
          <button onClick={() => example.logger.asyncLog(222)}>
            Log async
          </button>
          <button onClick={() => example.logger.promiseLog(333)}>
            Log promise
          </button>
        </div>
        <button
          onClick={() => {
            example.createItem();
            this.forceUpdate();
          }}
        >
          Create
        </button>
        <hr />
        <ul>
          {example.items.map((x) => (
            <li key={x.id}>
              #{x.id} {x.name}{" "}
              <button
                onClick={() => {
                  x.setName(Math.random());
                  this.forceUpdate();
                }}
              >
                set name
              </button>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

API

  • hub(parentHub?: Hub, name?: string, conf: {}): Hub

    Copies all props from conf to a new object and replaces found own actions with methods.

  • hub.withMeta(meta: T | () => T)(parentHub?: Hub, name?: string, conf: {}): Hub

    All own actions will include meta data.

  • hub.defaultHandler: (action) => R

    Called when no own action handlers match current action.

  • hub.action(fn): fn

    Creates action + handler pair. When called, it will dispatch an action with provided arguments. When a hub will handle this action, it will call fn with provided arguments.

  • dispatch(hub, type, ...args)

    • dispatch(hub, {type, meta, args})

    Dispatches an action

  • handleAction(hub, action)

    Calls hub action handler performing side-effects

  • shouldHandleAction(hub, name?: string, action)

    Helper that checks if action type starts with hub path

  • root(name?: string, initialHubs: {}): Root

    Creates root hub which can add/remove other hubs and dispatch actions through them.

    Root methods:

    • add(name: string, hub)
    • remove(name: string)
    • replace(hubs: {})
    • dispatch(action)
    • intercept(filter: action => boolean, handler: (action, next) => R): DisposeFn
    • observe(filter: action => boolean, handler: (action) => void): DisposeFn
  • getPath(hub, name?: string): string

    Get full path of a hub, optionally with name suffix.

  • devTools(root): DisposeFn

    Attach devtools

  • logger(root): DisposeFn

    Simple action logger