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

react-agent

v0.1.5

Published

React Agent is a JavaScript library for your client store, server querying, and database management. It can be included in any React project without conflict with other state management tools or REST APIs.

Downloads

13

Readme

React Agent

React Agent is a JavaScript library for your client store, server querying, and database management. It can be included in any React project without conflict with other state management tools or REST APIs.

React Agent is easy to learn.

Here's the basic idea: the client runs 'actions' that are defined on the server-side.

// client.js
run(‘setMessage’, { message: ‘Hello World’ })

// server.js
setMessage: {
    action: ‘INSERT INTO messages(text) VALUES(:message)’
}

These actions can be as powerful as you want -- i.e. CRUD operations, API calls, and authentication. Moreover, clients can subscribe to server-side actions so that they receive live updates.

React Agent includes offline-support to render optimistic updates and then synchronization on reestablished network connection. It also features time travel debugging.

Why use React Agent?

The popular conceptualization of state management stores state in two places: data on the client-side and data on the server-side.

To connect these, front-end and back-end developers usually write a lot of code such as HTTP requests, controllers, and routes. It can get complicated. previous

In contrast, React Agent serves as a communication channel between the client and the server. It abstracts state transfer to make it super easy to interact between the client and server. now

Below is a client-side guide. Here's our full documentation.

Getting Started

This guide is focused on client-side usage of React Agent, although it includes necessary details to know about server-side usage. See React Agent Server for more information about server-side set-up.

Installing

Install the package:

npm install react-agent --save

How to use

First, import React Agent into your highest level React component.

import { Agent } from 'react-agent'

Then, wrap your main component with <Agent> to start React Agent when your app loads.

render(
 <Agent>
   <App />
 </Agent>
 , document.querySelector('#root'))

Optionally, you can 1) set an initial state for React Agent with store={ initialStore }. As we’ll see, the state set with React Agent is accessible from any component. And, 2) log in the console what's happening under the hood by including logger={true}.

const initialStore = {
 first: true,
 second: false,
 third: 'ok'
}

render(
 <Agent store={ initialStore } logger={true}>
   <App />
 </Agent>
 , document.querySelector('#root'))

Let’s get started on the fun part. Import React Agent into a React component.

import { get, set, run, emit, on, unsubscribe } from 'react-agent'

There's six methods that make sense to learn. The first two are set and get, which manipulate state on the client-side, but don't interact with the server. The last four are run, emit, on, and unsubscribe, which are used for exchanging client and server-side state. To start, let’s use set to write to the React Agent store and get to return the values.

set and get

The set method takes a property/value pair as its parameters by comma seperation or as an object.

set('username', 'Billy')
set({ username: 'Billy' })

Multiple property/values pairs can be set by including them in consecutive order.

set('age', 28, 'active', true)
set({ age: 28, active: true })

The get method takes a property and returns the associated value.

get(‘username’) // returns ‘Billy’

It is also possible to manipulate client-side state in a more complex way using set and get in conjunction. For example, let's say we want to add a new value to an array in React Agent's store. The array is stored as the value of the property allUsers.

allUsers = get('allUsers')
set('allUsers', [...allUsers, { user: Billy }])

First, we use get to assign the current value of allUsers to a variable. Then, we take advantage of the ES6 spread operator ... to easily add { user: Billy } to allUsers.

Since React Agent’s methods can be imported into any component, React Agent's store is now accessible from any component without ‘passing-down’ props. Under the hood, React Agent uses React’s virtual DOM for efficient rendering.

Note: while React Agent can be used as a store for state, it can also be used without conflict alongside other state management tools such as Redux or React component state.

run

Now, let's examine the four methods that communicate with the server. Since these methods interact with the server, but do not affect React Agent's store, they are often used in conjunction with get and set to update client state.

run can perform any action on the server-side. For example, it might execute a CRUD operation on a SQL database, or it might execute an API call.

run takes a key as its first argument, which corresponds to a matching key on the server-side. When a client calls run on a key, the server executes the action labeled by the matching key.

As its optional second argument, run takes an object to pass to the server's action.

run('addUser', { user: Billy })

Here, we run the action addUser, which executes the action addUser on the server-side. That's all we need to do to add a user!

After the action is completed on the server, the promise returned by run either resolves or rejects. Then, the client can handle returned data, or catch an error.

run('getAllUsers')
  .then(data => {
    set('allUsers', data.users)
  })
  .catch(err => {
    console.log(err)
  })

emit, on, and unsubscribe

In addition to run, three other methods interact with the server: emit, on, and unsubscribe.

emit sends a state update to all clients who have subscribed to a key. Optionally, it takes an object as a second argument to pass to the server.

emit('updateMessages', { cookieID: 937985713 })

on subscribes a client to a key. That is, if emit is called with the corresponding key, the server pushes state updates to all subscribed clients.

on('updateMessages', data => {
  set('allMessages', data.messages)
})

unsubscribe removes a client's subscription to a key so that they no longer receive state updates.

unsubscribe('updateMessages')

Now, let's bring it together in one big example.

// The server will push any updates of 'getAllStudents' to the client.
on('getAllStudents', data => {
  set('allStudents', data.students)
})

// If a user adds Billy as a student, we optimistically update the client's store.
currentUsers = get('allStudents')
set('allStudents', [...currentStudents, { name: Billy }])

// Run the action 'addStudent' to update the server's database.
// If successful, emit an action to all subscribers of 'getAllStudents.'
// If error, revert the client's state to former value before optimistic update.
run('addStudent', { name: Billy })
  .then(() => {
    emit('getAllStudents')
  })
  .catch( err => {
    set('addStudents', currentUsers)
  })

Additional Methods and Features

Time Travel Debugging

React Agent uses Redux under the hood for time travel debugging. To enable this feature, pass devTools={true} to the <Agent> wrapper. Then, use Redux DevTools Chrome extension to travel through time.

render( 
 <Agent devTools={true}>
   <App />
 </Agent>
, document.querySelector('#root'))

destroy

destroy is used to delete a property and its values from React Agent's store. You can pass in multiple properties to delete.

destroy('messages')
destroy('users', 'comments', 'messages')

getStore

getStore returns an object containing the current state of React Agent's entire store. Alternatively, call get with no arguments for the same result.

currentState = getStore()
currentState = get()

isOfflineCacheEmpty

isOfflineCacheEmpty returns a boolean indicating whether any actions sent to the server have not yet been sent back as a response to the client. This method can be useful to determine whether the client has unsaved changes. For example, say the network connection drops, but a user continues interacting with the site because of optimistic rendering. If isOfflineCacheEmpty is then called, it would return false.

isOfflineCacheEmpty() // returns true or false

In fact, React Agent can alert a user that they have unsaved changes -- this feature is turned-off by default. If a user tries to navigate away from the site, it provides a pop-up warning. It uses isOfflineCacheEmpty under the hood. To turn on this feature, pass offlinePopUp={true} to the <Agent> wrapper.

render(
 <Agent offlinePopUp={true}>
   <App />
 </Agent>
 , document.querySelector('#root'))

run

run also accepts multiple keys as arguments in the form of an array. As its optional second argument, it takes an object which is passed to every action included in the array. In this configuration, run returns a promise, which resolves to an object containing the key of each action and its respective response from the server.

run(['addUser', 'addMessage'], { user: 'Billy', message: 'trapped in a simulation.' })
// returns { addUser: { id: 2956739 }, addMessage: { time: 2018-01-19T01:10:47 }}

Contributors

Authors

License

This project is licensed under the MIT License - see the LICENSE.txt file for details.