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

@productive-codebases/mobx-toolbox

v0.4.1

Published

MobX tooling for productive codebases.

Downloads

7

Readme

MobX Toolbox

A set of MobX helpers for productive codebases.

Installation

npm i @productive-codebases/mobx-toolbox --save

Summary

When working with MobX, it's advantageous to have multiple stores that manage specific parts of your application's state. Through store composition, you can structure your stores for each domain within your application, ensuring a clear separation of responsibilities.

By assembling these stores, you construct the complete state of the application and enhance the reusability of your stores.

MobX Toolbox offers essential base classes, type definitions, and utility functions to assist you in organizing this store composition in accordance with official MobX guidelines.

Getting started

The plan

  • Begin by establishing an Environment object, which enables the isolation of our stores from external dependencies.
  • Declare the record of stores
  • Create two stores as examples, each corresponding to different pages of our application.
  • Proceed to create the root store, which will encompass the Environment and handle the instantiation of the store record.

Implementation

  1. Create the environment
// Implement the different clients, configuration, storage that you are using into your application.
const appEnvironmentConfiguration = {
  configuration: /* ... */,
  fetchClient: /* ... */,
  openApiClients: /* ... */
  localStorage: /* ... */
}

// Instanciate the environment
const environment = new EnvironmentBase(appEnvironmentConfiguration)

// Expose a type for the root store
type Environment = typeof environment
  1. Declare the record of stores
// Expose all your stores, including the storeRoot in a single Record
interface IStoreRecord extends IStoreRecord<StoreRoot> {
  storeRoot: StoreRoot
  storeA: StoreA
  storeB: StoreB
}
  1. Implement some stores
// Each store extends StoreBase<TStoreRoot>
class StoreA extends StoreBase<StoreRoot> {
  fetchThings() {
    // Your store can access the the environment via the storeRoot
    return this.storeRoot.environment.configuration.fetchClient/* .get({ ... }) */
  }
}

// Optional options for some of your store, here for the "StoreB"
interface IStoreBOptions {
  featureFlags: {
    enableThing: boolean
  }
}

// Pass the option as the second parameter of the StoreBase type
class StoreB extends StoreBase<
  StoreRoot,
  IStoreBOptions
> {
  fetchOtherThings() {
    // You store can access to the internal options saved in the StoreBase`s constructor
    if (!this.options.featureFlags.enableThing) {
      return Promise.resolve(null)
    }

    return this.storeRoot.environment.configuration.fetchClient/* .get({ ... }) */
  }
}
  1. Create the root store.
// Implement the root store by extending StoreRootBase<TEnvironment, TStoreRecord>
class StoreRoot extends StoreRootBase<Environment, IStoreRecord> {
  _instanciateStores() {
    return {
      storeRoot: this,
      storeA: new StoreA(this, {}),
      storeB: new StoreB(this, {
        featureFlags: {
          enableThing: true
        }
      })
    }
  }
}

Usage

The root store is now your main entry point. From there, you can go anywhere:

// Access to the environment
storeRoot.environment.configuration.fetchClient/* .get({ ... }) */

// Access to any stores
storeRoot.stores.storeA.fetchThings()
storeRoot.stores.storeB.fetchOtherThings()

// You can even go around circles if you like!
// (It just demonstrate how objects are linked together)
storeRoot.stores.storeA.storeRoot.stores.storeB.storeRoot.environment.configuration.localStorage

Integration

MobX Toolbox preserves and doesn't alter MobX's reactivity system. The internal observation behavior remains pure MobX, so you can refer to MobX's documentation when constructing your store.

When it comes to making external parts of your application observable, such as components, you can consider different approaches depending on the UI framework you're using:

  • React: You can store the root store in a context, making it accessible throughout your app using a single hook. Additionally, consider utilizing the mobx-react-lite library to observe changes within your components.

  • Angular: Consider creating a service that manages the root store, allowing it to be injected into Angular's dependency injection system.

  • Vue: A hybrid approach is provided by https://github.com/mobxjs/mobx-vue.

Tooling

StoresViewser

The library exposes a StoresViewser and a MindmapRenderer allowing visualizing the architecture of your stores:

Integration example with React:

import { StoresViewer, MindmapRenderer } from '@productive-codebases/mobx-toolbox'

export default function ShowStoresViewer() {
  const ref = useRef<HTMLDivElement | null>(null)

  const { storeRoot } = useStores()

  useEffect(() => {
    if (!ref.current) {
      return
    }

    new MindmapRenderer(ref.current).initialize().then(renderer => {
      const storesViewer = new StoresViewer(renderer)
      storesViewer.fromStore(storeRoot).render()
    })
  }, [ref.current])

  return (
    <div ref={ref} />
  )
}

Output:

Example Image