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

@duckness/pool

v1.0.0

Published

Duckness Pool - @duckness/duck + Redux

Downloads

491

Readme

@duckness/pool

@duckness/duck + Redux

NPM License Libraries.io dependency status for latest release, scoped npm package GitHub issues vulnerabilities npm bundle size

Example

import Pool from '@duckness/pool'
import CounterDuck from './ducks/CounterDuck'

const CounterPool = Pool({
  buildStore: ({ initialCounter = 0 } = {}) => {
    return { counter: initialCounter }
  }
})
CounterPool.addDuck(CounterDuck)

CounterPool.build({initialCounter: 0})
CounterPool.store
// => [redux store]

Table of Contents

API

Create Pool

const myPool = Pool({
  ?poolName: String, // pool name, default is 'pool'
  ?ducks: Array<Duck>, // array of pool ducks
  ?middlewares: Array<Middleware>, // additional middlewares for Redux store
  ?streams: Array<PoolStream>, // pool plugins
  ?buildStore: (props, { refProps, refDucks, refErrorReporter }) => storeState, // build initial store state
  ?buildRootReducer: ({ refDucks, refErrorReporter }) => rootReducer // build custom root reducer from ducks instead of default root reducer
})

buildStore

Optional function to build init store state (props, { refProps, refDucks, refReducers, refErrorReporter }) => storeState

  • props are passed to pool when pool.build(props) are called.
  • refProps.current - props passed to pool.build(props) function
  • refDucks.current - current array of ducks.
  • refReducers.root - pool root reducer
  • refReducers.pre - pool pre reducer
  • refReducers.post - pool post reducer
  • refErrorReporter.current - current error reporter function.

default buildStore

If not specified store state will be set to {}.

buildRootReducer

Optional function for custom root reducer (ducks, { refProps, refDucks, refReducers, refErrorReporter }) => rootReducer

  • ducks - array of ducks
  • refProps.current - props passed to pool.build(props) function
  • refDucks.current - current array of ducks.
  • refReducers.pre - pool pre reducer
  • refReducers.post - pool post reducer
  • refErrorReporter.current - current error reporter function.

default buildRootReducer

Default root reducer will combine all duck root reducers via

ducks.reduce((state, duck) => {
  return duck(state, action)
}, state)

with every duck root reducer wrapped in try/catch returning unmodified state in case of exception inside duck root reducer.

.addDuck(duck)

Add duck to pool.

MyPool.addDuck(myDuck)

.preReducer(reducer)

Add pool pre reducer. Pre reducers will run BEFORE duck reducers and will receive all actions. Will replace previously set pre reducer.

MyPool.preReducer(function globalPreReducer(state, action) {/* ... */} )

.postReducer(reducer)

Add pool post reducer. Post reducers will run AFTER duck reducers and will receive all actions. Will replace previously set post reducer.

MyPool.postReducer(function globalPostReducer(state, action) {/* ... */} )

.build(props)

Build pool state from some props. props will be passed to buildStore function.

MyPool.build({ initialCounter: 0 })

.store

Reference to built redux store.

MyPool.store.subscribe(/* ... */)

.dispatch(...)

  1. Dispatches an action (action is a plain object).
const action = { type: 'actionType', payload: {} }
MyPool.dispatch(action)
  1. Dispatches and action from 'poolName/duckName' duck. This will first look for a duck by 'duckName' and current 'poolName', then duck's action creator by 'actionName' and call it with 'actionParams' to build action to dispatch.
MyPool.dispatch('duckName', 'actionName', ...actionParams)

Example:

const MyDuck = Duck('myDuck', 'myPool')
MyDuck.action('someAction')

const MyPool = Pool({ poolName: 'myPool' })
MyPool.addDuck(MyDuck)
MyPool.dispatch('myDuck', 'someAction', ...actionParams)

// equal to
MyPool.dispatch(MyDuck.action.someAction(...actionParams))
  1. Dispatches and action from 'customPoolName/duckName' duck. This will first look for a duck by 'duckName' and 'poolName', then duck's action creator by 'actionName' and call it with 'actionParams' to build action to dispatch.
MyPool.dispatch(['customPoolName', 'duckName'], 'actionName', ...actionParams)

.reduce([state,] action)

Reduce state with action. Does not change pool's store. Can be used to look ahead what the state will be after dispatching an action.

MyPool.reduce(action) // reduce pool's store state
MyPool.reduce(state, action) // reduce custom state

.select(?selector)

Select something from store. Returns store state if selector undefined.

MyPool.select(MyDuck.select.something)
// => selected value
MyPool.select()
// => current store state

.fetch(selector, ?resolver)

Returns Promise

function resolver(selected, resolve, prevSelected)

Fetch value from the store:

  • first selector is called to produce selected value
  • if resolver is defined: selected value is passed to resolver with previous selected value (undefined for the first run) and resolve function that can be used to resolve this fetch
  • if resolver is not defined: selected value will be resolved if it is not undefined
  • if nothing was resolved: repeat when store is updated (after next action dispatch).

fetch will subscribe to store updates (if it was not resolved after first select) and unsubscribe when it is resolved.

// resolves with items when items are loaded into store or are already present
const items = await ListPool.fetch(ItemsDuck.select.items)

// resolves when counter is reset, returning counter value before reset
const counterResetFrom = await MyPool.fetch(
  state => state.counter,
  (selected, resolve, prevSelected) => {
    if (null != prevSelected && 0 !== prevSelected && 0 === selected) {
      resolve(selected)
    }
  }
)

.trigger(selector, callback, ?resolver)

Returns clear trigger function.

function callback(selected)

function resolver(selected, resolve, prevSelected)

Trigger callback every time:

  • selected value changes (resolver is undefined)
  • or resolver calls resolve

trigger calls resolver first time trigger is set and later on store updates.

To unsubscribe call clear trigger function.

// console.log value for 10 seconds
const clearTrigger = MyPool.trigger(
    MyDuck.select.someValue,
    console.log
  )
setTimeout(clearTrigger, 10000)

.setErrorReporter(reporterFn)

Set exception reporter function. Will also overwrite errorReporters set in ducks.

MyPool.setErrorReporter(error => {
  window.Sentry.captureException(error)
})

.reportError(error)

Call assigned error reporter

MyPool.reportError(new Error('Clean pool!'))

.addMiddleware(middleware)

Add custom Redux middleware (applied on .build)

Pool Streams - Pool plugins

Pool Stream is a Pool plugin that can add middlewares to Redux store. One example is @duckness/pool-saga-stream that adds @duckness/saga support to Pool (ducks can have Redux Sagas).

.addStream(poolStream)

Adds Pool Stream to Pool

PoolStream API

{
  // array of middlewares for Redux store
  middlewares({ refDucks, refProps, refReducers, refErrorReporter }) {
    // refDucks.current - current array of ducks
    // refProps.current - props passed to build function
    // refReducers.root - root reducer function
    // refReducers.pre - pool pre reducer function
    // refReducers.post - pool post reducer function
    // refErrorReporter.current - current error reporter function
    // ...
    return [...streamMiddlewares] 
  },
  // called before redux store is built
  beforeBuild({ refDucks, refProps, refReducers, refErrorReporter }) {
    // refDucks.current - current array of ducks
    // refProps.current - props passed to build function
    // refReducers.root - root reducer function
    // refReducers.pre - pool pre reducer function
    // refReducers.post - pool post reducer function
    // refErrorReporter.current - current error reporter function
    // ...
  },
  // called after redux store is built
  afterBuild({ refStore, refDucks, refProps, refReducers, refErrorReporter }) {
    // refStore.current - current Redux store
    // refDucks.current - current array of ducks
    // refProps.current - props passed to build function
    // refReducers.root - root reducer function
    // refReducers.pre - pool pre reducer function
    // refReducers.post - pool post reducer function
    // refErrorReporter.current - current error reporter function
    // ...
  }
}

.ducks

Array of added ducks (read only)

.getDuckByName(duckPath)

Find added duck by it's path. Returns null if duck is not found.

duckPath:

  • Array: [poolName, duckName]
  • String: duckName (use current poolName)

.middlewares

Array of added middlewares (read only)

.streams

Array of added streams (read only)

.props

Props used to build pool (read only)

Examples

https://github.com/hitosu/duckness/tree/master/stories

@Duckness packages: