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

nuclear-reactor

v0.4.15

Published

-

Downloads

10

Readme

Nuclear Reactor

Build Status

Deal breaker for React/Preact state management. If you heard about Flux - nuclear-reactor is like next form of it. Simple, yet powerful.

Installation

  npm i nuclear-reactor --save

Examples

Examples of usage you can find in this repository https://github.com/idchlife/nuclear-reactor-examples

Usage

You will have reactors - basically singletons of classes. Like stores in flux (in terms of exporting default instance of class). And components. Which will listen to reactors or reactors properties.

Reactor

  • Instance of class.
  • Reactor = store + actions. At the same time it's just an object! You're not registering it anywhere, you just export instance of it and choose when to notify components that something has changed.
  • It can be charged with some handy decorators (or functions, for our friends without decorators)

Reactor has state in it. State lives in it's properties. It also has actions in it. Any method of reactor can be action. Public ones. Well, in typescript or flow public ones.

Here is code, so you can see simplicity for yourself. Also I will cover most of the functionality in comments

Code with comments

// Your reactors/CounterReactor.ts
import { notify } from "nuclear-reactor";

class CounterReactor {
  // this little guy here basically says: any component aware of this
  // reactor or it's properties will be notified after this property will be changed
  @notify
  count: number = 0;
}

export default new CounterReactor();
// Your components/Counter.tsx
import { Component, h } from "preact";
import { AwareOf } from "nuclear-reactor";
import CounterReactor from "../reactors/CounterReactor";
// or react equivalent

interface State {
  count: number;
}

@AwareOf(
  CounterReactor, // before passing properties you should tell, which
  // reactor has these properties
  "count" // Means that this component's state will be populated with
  // count property of the reactor and nothing more
)
export default class Counter extends Component<any, State> {
  render(props, state: State) {
    return (
      <div>
        <div>{state.count}</div>
        <div><button onClick={() => CounterReactor.count++}>Increment</button></div>
        <div><button onClick={() => CounterReactor.count--}>Decrement</button></div>
      </div>
    )
  }
}

The thing is. Every time property .count of the CounterReactor will be set - reactor will notify all it's listeners about changes. Like store in flux, if you know what I am talking about - it will "emitChange" (not exactly reactor, but hub inside this library will notify about this reactor changes, but for simplicity of understanding we pretend that "reactor notifies listeners")

@notify decorator/function

(or function if you will be using without decorators)

notify can be used as @notify for properties of your reactor. Like in code above - it will detect that value of this property was set and notify reactor listeners.

Also notify can be used as function in methods, like this:

import { notify } from "nuclear-reactor";

class DateReactor {
  stringDate: string;

  refreshDate() {
    this.stringDate = "some-new-date";

    notify(this);
  }
}

Also, notify function can be used even without argument! One condition, though: it should be called exactly inside reactor method. Not in some function outside, not in promise callback. And if you will follow this condition - it will do it's job. It will know where it was called and notify listeners of only reactor where it was used. Like this:

import { notify } from "nuclear-reactor";

class DateReactor {
  stringDate: string;

  refreshDate() {
    this.stringDate = "some-new-date";

    notify();
  }
}

Neat, don't you think?

AwareOf decorator

AwareOf used for what it was called. Component's state will be aware of reactor properties.

Used like this:

  import { AwareOf } from "nuclear-reactor";
  import AuthReactor from "../reactors/AuthReactor";
  import ProfileReactor from "../reactors/ProfileReactor";

  interface State {
    profile: any
  }

  @AwareOf(
     AuthReactor,
     ProfileReactor,
     "profile"
   )
export default class Page extends Component<any, typeof AuthReactor & State> {
// omitting, because you for sure know how to write components

As you can see, we can pass reactor without properties. It means that component's state will be populated with all of reactor's properties. Sometimes it's handy. Basically arguments for @AwareOf look like this: @AwareOf(...args: Array<Reactor | string>) First you specify Reactor, and then you specify or not it's properties. Multiple reactors and multiple properties can be passed. Your component can listen to numerous reactors and their properties! And all of them will populate components state.

Listening to reactor without component

If you want to attach some outside listener for reactor, like custom service, or manager, you can extend your reactor class with StoreLikeReactor. StoreLikeReactor will add methods for adding and removing listeners. Be careful, it's your responsibility to add and (!) remove listeners. Without removing them in time you can easily provoke memory leak with many duplicate listeners!

import { StoreLikeReactor } from "nuclear-reactor";

class YourReactor extends StoreLikeReactor {

}

export default new YourReactor();
import YourReactor from "./reactors/YourReactor";

function yourListener() {
  console.log("Whelp reactor changed");
}
reactor.addChangeListener(yourListener);
reactor.removeChangeListener(yourListener);

Usage without decorators

Of course you can use this library without TypeScript and decorators. If you're comfortable with your favorite babel-react stack, you can use AwareOf like this: https://github.com/idchlife/nuclear-reactor-examples/blob/master/todo-js-react/components/TodoApp.js#L16

notify function for properties change awareness can be used without decorators like this

// your reactor constructor
constructor() {
  notify(this, "price");
  notify(this, "product");
}

Contributing

  1. Fork it ( https://github.com/idchlife/nuclear-reactor/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

LICENSE

MIT

Here is a nice picture of Cherenkov radiation: image