12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import invariant from 'invariant'
- import isEmpty from 'lodash/isEmpty'
- import isFunction from 'lodash/isFunction'
- import isString from 'lodash/isString'
- import conformsTo from 'lodash/conformsTo'
- import checkStore from './checkStore'
- import { DAEMON, ONCE_TILL_UNMOUNT, RESTART_ON_REMOUNT } from './constants'
- const allowedModes = [RESTART_ON_REMOUNT, DAEMON, ONCE_TILL_UNMOUNT]
- const checkKey = (key) =>
- invariant(
- isString(key) && !isEmpty(key),
- '(app/utils...) injectSaga: Expected `key` to be a non empty string'
- )
- const checkDescriptor = (descriptor) => {
- const shape = {
- saga: isFunction,
- mode: (mode) => isString(mode) && allowedModes.includes(mode)
- }
- invariant(
- conformsTo(descriptor, shape),
- '(app/utils...) injectSaga: Expected a valid saga descriptor'
- )
- }
- export function injectSagaFactory (store, isValid) {
- return function injectSaga (key, descriptor: { saga?: any, mode?: string } = {}, args?: any) {
- if (!isValid) { checkStore(store) }
- const newDescriptor = {
- ...descriptor,
- mode: descriptor.mode || DAEMON
- }
- const { saga, mode } = newDescriptor
- checkKey(key)
- checkDescriptor(newDescriptor)
- let hasSaga = Reflect.has(store.injectedSagas, key)
- if (process.env.NODE_ENV !== 'production') {
- const oldDescriptor = store.injectedSagas[key]
- // enable hot reloading of daemon and once-till-unmount sagas
- if (hasSaga && oldDescriptor.saga !== saga) {
- oldDescriptor.task.cancel()
- hasSaga = false
- }
- }
- if (
- !hasSaga ||
- (hasSaga && mode !== DAEMON && mode !== ONCE_TILL_UNMOUNT)
- ) {
- /* eslint-disable no-param-reassign */
- store.injectedSagas[key] = {
- ...newDescriptor,
- task: store.runSaga(saga, args)
- }
- /* eslint-enable no-param-reassign */
- }
- }
- }
- export function ejectSagaFactory (store, isValid) {
- return function ejectSaga (key) {
- if (!isValid) { checkStore(store) }
- checkKey(key)
- if (Reflect.has(store.injectedSagas, key)) {
- const descriptor = store.injectedSagas[key]
- if (descriptor.mode && descriptor.mode !== DAEMON) {
- descriptor.task.cancel()
- // Clean up in production in development we need `descriptor.saga` for hot reloading
- if (process.env.NODE_ENV === 'production') {
- // Need some value to be able to detect `ONCE_TILL_UNMOUNT` sagas in `injectSaga`
- store.injectedSagas[key] = 'done' // eslint-disable-line no-param-reassign
- }
- }
- }
- }
- }
- export default function getInjectors (store) {
- checkStore(store)
- return {
- injectSaga: injectSagaFactory(store, true),
- ejectSaga: ejectSagaFactory(store, true)
- }
- }
|