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

redux-baqend

v1.1.3

Published

baqend middleware for redux

Downloads

18

Readme

Redux Baqend Middleware

"Logo"

Installation

$ npm install redux-baqend --save

To use it add the baqendMiddleware and the baqendConnect enhancer to your redux store. You can add the optional baqendReducer as well if you like. Here is an example setup.

You can find examples at our react starters: React or React Native

store.js

import { applyMiddleware, combineReducers } from 'redux'
import { baqendReducer, createEnhancers } from 'redux-baqend'
import middlewares from '../middleware'
import reducers from '../reducers'

export default function configureStore(initialState = {}) {
  const reducer = combineReducers({
    baqend: baqendReducer,
    ...reducers
  })
  const middleware = applyMiddleware(
    ...middlewares
  )
  return createStoreWithBaqend(
    db.connect('app-starter'),
    reducer,
    initialState,
    middleware
  )
}

If you want to have a little bit more control over how your store is created you can add the baqend enhacers manually to the store creation

import { applyMiddleware, compose, createStore, combineReducers } from 'redux'
import { baqendReducer, createEnhancers } from 'redux-baqend'
import middlewares from '../middleware'
import reducers from '../reducers'

export default function configureStore(initialState = {}) {
  const { baqendConnect, baqendMiddleware } = createEnhancers(db.connect('app-starter'))
  const reducer = combineReducers({
    baqend: baqendReducer,
    ...reducers
  })
  const middleware = applyMiddleware(
    baqendMiddleware,
    ...middlewares
  )
  const enhancers = compose(
    baqendConnect,
    middleware
  )
  return createStore(reducer, initialState, enhancers)
}

app.js

const store = configureStore();

On calling this method two actions are dispatched from within the connect enhancer. The BAQEND_CONNECTING and BAQEND_CONNECTED actions. When the connection was successfull and the user is still logged it comes with the current user object, which you can use for auto login your user to your react app.

...
case BAQEND_CONNECTED:
  return { ...state, user: action.user, isLoggedIn: !!action.user }
...

Usage

Action Thunk

The Redux Baqend Middleware allows you to write action creators that return a function instead of an action as you know it from the Redux Thunk Middleware, but come with a baqend connection instance, which can be used to make request against you Baqend app from within asynchronous redux actions. In addition to that the payload of actions dispatched by the baqend middleware are serialized, before they are put into the store. The serialization depth can be set by an optional options parameter, which can be passed to the dispatch function as a second argument.

{
  'BAQEND': async ({ dispatch, getState, db }) => {
    const options = { depth: 0 }
    const items = await db.Items.find().resultList()
    dispatch({
      type: ITEMS_LOAD,
      payload: result,
    }, options)
    return items
  }
}

To convert the serialized baqend object back from JSON to a Baqend object you can either pass the jsons as arguments to the action array or do it manually by using the fromJSON method coming with the Javascript SDK.

{
  'BAQEND': [json, async ({ dispatch, getState, db }, item) => {
    const updated = await item.update()
    dispatch({
      type: ITEM_UPDATE,
      payload: updated
    })
    return updated
  }]
}

// or

{
  'BAQEND': async ({ dispatch, getState, db }) => {
    const item = db.Item.fromJSON(json)
    const updated = await item.update()
    dispatch({
      type: ITEM_UPDATE,
      payload: updated
    })
    return updated
  }
}

Action Objects

In React/Redux you should mostly work with serializable objects. Therefore you should convert the baqend objects to json before you pass them to your redux store and get and update your reference to the baqend object by using the fromJSON method coming with the js-sdk. You can either convert the objects manually or let the middleware do it automatically. Inside the payload methods of your actions you can work with baqend like you used to do.

A minimal baqend action:

{
  'BAQEND': {
    type: 'ITEMS_LOAD',
    payload: (db) => db.Items.find().resultList()
  }
}

When receiving this kind of action, baqendMiddleware will do the following:

  1. Wait for the db to be ready and connected to baqend

  2. Pass the db object to the payload method defined in your action and execute it

  3. Next the middleware will take the result of you query and check if it´s in json format already. If not it will take care of converting it to json and dispatch the following action and pass it to the next middleware

    {
      type: 'ITEMS_LOAD',
      payload: [
        { id: '/db/Item/1', value: 'value' },
        { id: '/db/Item/2', value: 'value' }
      ]
    }

Converting the Objects

The object are converted to jsons by the middleware before passing the them to the reducers. If you want to update an item from within your application you have to make a baqend object out of your updated json to be able to save it. By default they use a depth of 0, but you can pass in options to the actions with another depth.

let options = { depth: 1 }

return {
  'BAQEND': {
    type: 'ITEMS_LOAD',
    options: options,
    payload: (db) => {
      return db.Items.find().resultList(options)
    }
  }
}

// update object
return {
  'BAQEND': {
    type: 'ITEMS_LOAD',
    options: options,
    payload: [ item, (db, item) => {
      item.save(options)
    }]
  }
}

or doing it manually

return {
  'BAQEND': {
    type: 'ITEMS_LOAD',
    payload: (db) => {
      return db.Message.find().resultList({ depth: 1 }).then(results => {
        return results.map(item => item.toJSON({ depth: 1 }))
      })
    }
  }
}

// update object
return {
  'BAQEND': {
    type: 'ITEMS_LOAD',
    payload: (db) => {
      item = db.Item.fromJSON(item)
      return item.save({ depth: 1 }).then(item => {
        return item.toJSON({ depth: 1 })
      })
    }
  }
}

Dispatching multiple actions

Adding an types array will dispatch multiple actions for the initiation, the success and for the error of an dispatched action.

export function itemLoad(args) {
  return {
    'BAQEND': {
      types: [
        'ITEMS_LOAD_PENDING',
        'ITEMS_LOAD_SUCCESS',
        'ITEMS_LOAD_ERROR'
      ],
      payload: (db) => {
        return db.Message.find().resultList()
      }
    }
  }
}

Additional Fields

You can add additional fields to the dispatched actions by making objects out of the elements in the types array and add new properties to the result. You can either simply add a new property to the type or edit the payload response of the original payload method

export function itemLoad(params) {
  return {
    'BAQEND': {
      types: [
        {
          type: 'ITEMS_LOAD_PENDING',
          params: params
        },
        {
          type: 'ITEMS_LOAD_SUCCESS',
          payload: (items) => ({
            items: items,
            params: params
          })
        },
        'ITEMS_LOAD_ERROR'
      ],
      payload: (db) => {
        return db.Message.find().resultList()
      }
    }
  }
}

How Baqend fits your Backend requirements

Baqend is a fully managed Backend-as-a-Service platform with a strong focus on performance and scalability (click here for details). The JavaScript API gives you access to common backend features while the dashboard lets you define data models and access rules as well as business logic to execute on the server side.

Baqend's feature set includes:

  • Automated Browser and CDN Caching
  • Scalable Data Storage
  • Realtime Streaming Queries
  • Powerful Search and Query Language
  • Push Notifications
  • User Authentication and OAuth
  • File Storage and Hosting
  • Access Control on Object and Schema Level

#License

MIT