1 | export const sym = id => `@@redux-saga/${id}`
|
2 |
|
3 | export const TASK = sym('TASK')
|
4 | export const HELPER = sym('HELPER')
|
5 | export const MATCH = sym('MATCH')
|
6 | export const CANCEL = sym('CANCEL_PROMISE')
|
7 | export const SAGA_ACTION = sym('SAGA_ACTION')
|
8 | export const SELF_CANCELLATION = sym('SELF_CANCELLATION')
|
9 | export const konst = v => () => v
|
10 | export const kTrue = konst(true)
|
11 | export const kFalse = konst(false)
|
12 | export const noop = () => {}
|
13 | export const ident = v => v
|
14 |
|
15 | export function check(value, predicate, error) {
|
16 | if (!predicate(value)) {
|
17 | log('error', 'uncaught at check', error)
|
18 | throw new Error(error)
|
19 | }
|
20 | }
|
21 |
|
22 | const hasOwnProperty = Object.prototype.hasOwnProperty
|
23 | export function hasOwn(object, property) {
|
24 | return is.notUndef(object) && hasOwnProperty.call(object, property)
|
25 | }
|
26 |
|
27 | export 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 |
|
47 | export 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 |
|
57 | export function remove(array, item) {
|
58 | const index = array.indexOf(item)
|
59 | if (index >= 0) {
|
60 | array.splice(index, 1)
|
61 | }
|
62 | }
|
63 |
|
64 | export 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 |
|
76 | export 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 |
|
86 | export function arrayOfDeffered(length) {
|
87 | const arr = []
|
88 | for (let i = 0; i < length; i++) {
|
89 | arr.push(deferred())
|
90 | }
|
91 | return arr
|
92 | }
|
93 |
|
94 | export 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 |
|
105 | export 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 |
|
121 | export function autoInc(seed = 0) {
|
122 | return () => ++seed
|
123 | }
|
124 |
|
125 | export const uid = autoInc()
|
126 |
|
127 | const kThrow = err => {
|
128 | throw err
|
129 | }
|
130 | const kReturn = value => ({ value, done: true })
|
131 | export 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 |
|
145 |
|
146 |
|
147 |
|
148 | export function log(level, message, error = '') {
|
149 |
|
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 |
|
157 | export function deprecate(fn, deprecationWarning) {
|
158 | return (...args) => {
|
159 | if (process.env.NODE_ENV === 'development') log('warn', deprecationWarning)
|
160 | return fn(...args)
|
161 | }
|
162 | }
|
163 |
|
164 | export const updateIncentive = (deprecated, preferred) =>
|
165 | `${deprecated} has been deprecated in favor of ${preferred}, please update your code`
|
166 |
|
167 | export 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 |
|
176 | export const createSetContextWarning = (ctx, props) =>
|
177 | `${ctx ? ctx + '.' : ''}setContext(props): argument ${props} is not a plain object`
|
178 |
|
179 | export const wrapSagaDispatch = dispatch => action =>
|
180 | dispatch(Object.defineProperty(action, SAGA_ACTION, { value: true }))
|
181 |
|
182 | export 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 | }
|