UNPKG

5.3 kBJavaScriptView Raw
1export const sym = id => `@@redux-saga/${id}`
2
3export const TASK = sym('TASK')
4export const HELPER = sym('HELPER')
5export const MATCH = sym('MATCH')
6export const CANCEL = sym('CANCEL_PROMISE')
7export const SAGA_ACTION = sym('SAGA_ACTION')
8export const SELF_CANCELLATION = sym('SELF_CANCELLATION')
9export const konst = v => () => v
10export const kTrue = konst(true)
11export const kFalse = konst(false)
12export const noop = () => {}
13export const ident = v => v
14
15export function check(value, predicate, error) {
16 if (!predicate(value)) {
17 log('error', 'uncaught at check', error)
18 throw new Error(error)
19 }
20}
21
22const hasOwnProperty = Object.prototype.hasOwnProperty
23export function hasOwn(object, property) {
24 return is.notUndef(object) && hasOwnProperty.call(object, property)
25}
26
27export const is = {
28 undef: v => v === null || v === undefined,
29 notUndef: v => v !== null && v !== undefined,
30 func: f => typeof f === 'function',
31 number: n => typeof n === 'number',
32 string: s => typeof s === 'string',
33 array: Array.isArray,
34 object: obj => obj && !is.array(obj) && typeof obj === 'object',
35 promise: p => p && is.func(p.then),
36 iterator: it => it && is.func(it.next) && is.func(it.throw),
37 iterable: it => (it && is.func(Symbol) ? is.func(it[Symbol.iterator]) : is.array(it)),
38 task: t => t && t[TASK],
39 observable: ob => ob && is.func(ob.subscribe),
40 buffer: buf => buf && is.func(buf.isEmpty) && is.func(buf.take) && is.func(buf.put),
41 pattern: pat => pat && (is.string(pat) || typeof pat === 'symbol' || is.func(pat) || is.array(pat)),
42 channel: ch => ch && is.func(ch.take) && is.func(ch.close),
43 helper: it => it && it[HELPER],
44 stringableFunc: f => is.func(f) && hasOwn(f, 'toString'),
45}
46
47export const object = {
48 assign(target, source) {
49 for (let i in source) {
50 if (hasOwn(source, i)) {
51 target[i] = source[i]
52 }
53 }
54 },
55}
56
57export function remove(array, item) {
58 const index = array.indexOf(item)
59 if (index >= 0) {
60 array.splice(index, 1)
61 }
62}
63
64export const array = {
65 from(obj) {
66 const arr = Array(obj.length)
67 for (let i in obj) {
68 if (hasOwn(obj, i)) {
69 arr[i] = obj[i]
70 }
71 }
72 return arr
73 },
74}
75
76export function deferred(props = {}) {
77 let def = { ...props }
78 const promise = new Promise((resolve, reject) => {
79 def.resolve = resolve
80 def.reject = reject
81 })
82 def.promise = promise
83 return def
84}
85
86export function arrayOfDeffered(length) {
87 const arr = []
88 for (let i = 0; i < length; i++) {
89 arr.push(deferred())
90 }
91 return arr
92}
93
94export function delay(ms, val = true) {
95 let timeoutId
96 const promise = new Promise(resolve => {
97 timeoutId = setTimeout(() => resolve(val), ms)
98 })
99
100 promise[CANCEL] = () => clearTimeout(timeoutId)
101
102 return promise
103}
104
105export function createMockTask() {
106 let running = true
107 let result, error
108
109 return {
110 [TASK]: true,
111 isRunning: () => running,
112 result: () => result,
113 error: () => error,
114
115 setRunning: b => (running = b),
116 setResult: r => (result = r),
117 setError: e => (error = e),
118 }
119}
120
121export function autoInc(seed = 0) {
122 return () => ++seed
123}
124
125export const uid = autoInc()
126
127const kThrow = err => {
128 throw err
129}
130const kReturn = value => ({ value, done: true })
131export function makeIterator(next, thro = kThrow, name = '', isHelper) {
132 const iterator = { name, next, throw: thro, return: kReturn }
133
134 if (isHelper) {
135 iterator[HELPER] = true
136 }
137 if (typeof Symbol !== 'undefined') {
138 iterator[Symbol.iterator] = () => iterator
139 }
140 return iterator
141}
142
143/**
144 Print error in a useful way whether in a browser environment
145 (with expandable error stack traces), or in a node.js environment
146 (text-only log output)
147 **/
148export function log(level, message, error = '') {
149 /*eslint-disable no-console*/
150 if (typeof window === 'undefined') {
151 console.log(`redux-saga ${level}: ${message}\n${(error && error.stack) || error}`)
152 } else {
153 console[level](message, error)
154 }
155}
156
157export function deprecate(fn, deprecationWarning) {
158 return (...args) => {
159 if (process.env.NODE_ENV === 'development') log('warn', deprecationWarning)
160 return fn(...args)
161 }
162}
163
164export const updateIncentive = (deprecated, preferred) =>
165 `${deprecated} has been deprecated in favor of ${preferred}, please update your code`
166
167export const internalErr = err =>
168 new Error(
169 `
170 redux-saga: Error checking hooks detected an inconsistent state. This is likely a bug
171 in redux-saga code and not yours. Thanks for reporting this in the project's github repo.
172 Error: ${err}
173`,
174 )
175
176export const createSetContextWarning = (ctx, props) =>
177 `${ctx ? ctx + '.' : ''}setContext(props): argument ${props} is not a plain object`
178
179export const wrapSagaDispatch = dispatch => action =>
180 dispatch(Object.defineProperty(action, SAGA_ACTION, { value: true }))
181
182export const cloneableGenerator = generatorFunc => (...args) => {
183 const history = []
184 const gen = generatorFunc(...args)
185 return {
186 next: arg => {
187 history.push(arg)
188 return gen.next(arg)
189 },
190 clone: () => {
191 const clonedGen = cloneableGenerator(generatorFunc)(...args)
192 history.forEach(arg => clonedGen.next(arg))
193 return clonedGen
194 },
195 return: value => gen.return(value),
196 throw: exception => gen.throw(exception),
197 }
198}