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

@art-suite/art-flux

v2.1.5

Published

Art.Flux is a simple, elegant solution to the following design constraints:

Downloads

27

Readme

Art-Flux

Art.Flux is a simple, elegant solution to the following design constraints:

  • Components can subscribe to remote or shared data
  • Subscribing Components' states are automatically updated:
    • if the status of the initial request changes
    • as the initial request makes progress
    • whenever the data changes
  • if the data is available immediately upon component instantiation, the component’s first render will reflect that data
  • data is addressed by model-name and key-string
    • non-string keys are supported via custom toFluxKey methods
  • model and subscription definitions are simple and lean

If you are familiar with the Flux design pattern, see: [[Art.Flux-vs-Other-Fluxes]]

See

How It Works

There are three main parts to Art.Flux: FluxModels, FluxComponents and the FluxStore:

Using Art.Flux consists of registering one or more FluxModels and creating FluxComponents that subscribe to data provided by those models.

Behind the scenes, the FluxStore, a singleton class, manages all component subscriptions and provides epoch state updates. Epoch state updates queue all state changes in Flux turing a time unit, usually one animation frame, and applies them atomically to the FluxStore's internal state. Immediately after the internal state update, FluxStore notifies all subscribers of changes.

New subscriptions to data not currently in the FluxStore indirectly cause loads to be invoked on the appropriate models. FluxModels are responsible for updating the FluxStore on the progress of those loads and the final result. FluxModels can later update the FluxStore if that data is updated locally or remotely.

When all subscribers to a particular piece of data go away, the FluxStore releases the data. In this way the FluxStore only keeps in memory what is actually being used by active FluxComponents.

The diagram above shows typical method invocations that cause data to flow around the Flux loop. Only the myModel.myMutator needs to be invoked in your application code. FluxComponent state is automatically updated, and standard FluxModels take care of updating the FluxStore for you.

Example

To use Art.Flux, create your a custom model and custom FluxComponent with a subscription to the model:

# models/nav_state.coffee
{ApplicationState} = require 'art-flux'

module.exports = class NavState extends ApplicationState
  @stateFields currentTab: "home"

  nextTab: ->
    @currentTab = switch @currentTab
      when "home" then "search"
      else "home"

  @register()
# components/my_component.coffee
{TextElement} = require 'art-react'
{createFluxComponentFactory} = require 'art-flux'

module.exports = createFluxComponentFactory
  @subscriptions ”navState.currentTab”

  nextTab: -> @models.navState.nextTab()

  render: ->
    TextElement
      text: @state.currentTab
      on: pointerClick: @nextTab

Subscription Declarations

@subscriptions takes an object as input with each entry describing one subscription.

A subscription consists of 3 parts:

  • stateField: the field in @state which will be set with the subscribed-to data
  • model: the subscribed-to model (from the ModelRegistry)
  • key: key for the specific, subscribed-to data in the model

There are many different ways to define the subscription, shown below.

Subscription Declarations, Object Forms

Fully Explicit

  @subscriptions
    stateField:
      model: "modelName", model-instance or (props) -> "modelName"
      key:   "key",       key-object     or (props) -> "key" or key-object

Model-name == StateField-name with Explicit, Constant Key

@subscriptions
  stateField: constantKey

is equivalent to:

@subscriptions
  stateField:
    model:  'stateField'
    key:    constantKey

Model-name == StateField-name with Key-Function

@subscriptions
  stateField: (props) -> # return key

is equivalent to:

@subscriptions
  stateField:
    model:  'stateField'
    key:    (props) -> # return key

Example:

@subscriptions
  user: (props) -> props.userId

# Or, using coffeescript shorthand:
@subscriptions
  user: ({userId}) -> userId

Subscription Declarations, String Forms

In addition to declaring subscriptions with object-notation, you can also use a simple string for common subscription-types. A subscription-string can contain one or more subscription declarations separated by spaces or commas.

Model Form

This form is useful for subscribing to a single record from a table. This pattern works best if you follow the [[Flux Conventions]].

@subscriptions "myField"

is equivalent to:

@subscriptions
  myField:
    model:  'myField'
    key:    ({myField, myFieldId}) -> myField?.id || myFieldId

Example:

@subscriptions "post"

#is short for:
@subscriptions
  post:
    model:  "post"
    key:    ({post, postId}) -> post?.id || postId

Model.Key form

This form is useful for subscribing to a specific, known key. In particularly, this works well with ApplicationState models.

@subscriptions "modelName.fieldName"

is equivalent to:

@subscriptions
  fieldName:
    key: fieldName
    model: modelName

Model-By form

Key functions

If the key or model is a function, the function:

  • is executed without @ set
  • inputs: (props) - the component
  • outputs: key or modelName respectively
###
IN: props is the component instance's @props
@/THIS: not set
OUT: key
###
(props) -> key

Key-functions are called initially during getInitialState to set up initial subscriptions.

If the key-function returns null, all dependent state fields will be set to null. No other action will be taken.

Whenever @props changes (e.g. when componentWillReceiveProps is called), these key-functions are re-evaluated. If the return value changes, subscriptions are updated and new data is requested where needed.

FluxComponent Subscriptions

Declaring a subscription on a FluxComponent has a few important effects. For a given subscription with a state-field name 'myStatefield':

  • defines the getter: @myStatefield
  • sets multiple fields on @state:
    • @state.myStateField - the current value from the subscription or null if no value has been fetched
    • @state.myStateFieldStatus - (string) the current status of fetching the value for the subscription (see Art.Founcation.ConnectionStatus)
    • @state.myStateFieldProgress - (number between 0 and 1) the current progress fetching the value for the subscription

Example

class UserView extends FluxComponent
  @subscriptions "user"

  render: ->
    TextElement
      text: @user?.name || @state.userStatus

Flux Conventions

  • model-names which represent tables of records should be singular. Examples:
    • user
    • post
    • comment
  • Keys for records are called "ids." When passing an id as a prop to a component, name it the model-name plus 'Id'. Examples:
    • userId
    • postId
    • commentId

If you follow these patterns, your subscription declarations are nice and concise. Example:

class UserView extends FluxComponent
  @subscriptions "user post"

Equivalant to

class UserView extends FluxComponent
 @subscriptions
   user: ({user, userId}) -> user?.id || userId
   post: ({post, postId}) -> post?.id || postId