forked from cerebral/overmind
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
90 lines (82 loc) · 2.38 KB
/
utils.ts
File metadata and controls
90 lines (82 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { EffectResult } from './types'
export const doNotProxy = Symbol('doNotProxy')
function isObject(value) {
return typeof value === 'object' && !Array.isArray(value) && value !== null
}
let hasWarnedConstructor = false
function createProxyGetHandler(
path: string,
cb: (effect: EffectResult) => void
): ProxyHandler<any>['get'] {
return (target, prop) => {
if (typeof target[prop] === 'function') {
const func = function(...args) {
const result = target[prop].apply(this, args)
if (result instanceof Promise) {
result.then((promisedResult) => {
// eslint-disable-next-line standard/no-callback-literal
cb({
name: path,
method: prop,
args,
result: promisedResult,
})
})
} else {
// eslint-disable-next-line standard/no-callback-literal
cb({
name: path,
method: prop,
args,
result,
})
}
return result
}
return new Proxy(func, {
construct(_, args) {
// eslint-disable-next-line
cb({
name: path,
method: prop,
args,
result: `[${prop.toString()}]`,
})
if (!hasWarnedConstructor) {
console.warn(
`EFFECTS - It is highly recommended to create a custom effect, exposing a method that deals with the instantiation of "${path}.${prop.toString()}". It improves readability and debugability of your app`
)
hasWarnedConstructor = true
}
return new target[prop](...args)
},
})
}
if (isObject(target[prop])) {
return new Proxy(target[prop], {
get: createProxyGetHandler(path + '.' + prop.toString(), cb),
})
}
return target[prop]
}
}
export function proxifyEffects<Effects>(
effects: Effects,
skipKeys: string[] = [],
cb: (effect: EffectResult) => void
): Effects {
return Object.keys(effects).reduce(
(currentEffects, key) => {
const effect = effects[key]
if (skipKeys.indexOf(key) === -1 && isObject(effect)) {
currentEffects[key] = new Proxy(effect, {
get: createProxyGetHandler(key, cb),
})
} else {
currentEffects[key] = effect
}
return currentEffects
},
{} as Effects
)
}