-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathassign.js
98 lines (95 loc) · 2.92 KB
/
assign.js
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
91
92
93
94
95
96
97
98
const isPromise = require('./_internal/isPromise')
const objectAssign = require('./_internal/objectAssign')
const __ = require('./_internal/placeholder')
const curry2 = require('./_internal/curry2')
const curry3 = require('./_internal/curry3')
const functionObjectAll = require('./_internal/functionObjectAll')
// _assign(object Object, funcs Object<function>) -> Promise|Object
const _assign = function (object, funcs) {
const result = functionObjectAll(funcs, [object])
return isPromise(result)
? result.then(curry3(objectAssign, {}, object, __))
: ({ ...object, ...result })
}
/**
* @name assign
*
* @synopsis
* ```coffeescript [specscript]
* assign(
* o Promise|Object,
* resolversOrValues Object<function|Promise|any>
* ) -> result Promise|Object
*
* assign(
* resolversOrValues Object<function|Promise|any>
* )(o Object) -> result Promise|Object
* ```
*
* @description
* Function executor and composer. Accepts an object of resolver functions or values and an object `o`. Creates a result object from the argument object, evaluates each resolver with the argument object, and assigns to the result object the evaluations at the corresponding resolver keys.
*
* ```javascript [playground]
* const assignSquaredAndCubed = assign({
* squared: ({ number }) => number ** 2,
* cubed: ({ number }) => number ** 3,
* })
*
* console.log(assignSquaredAndCubed({ number: 2 }))
* // { number: 2, squared: 4, cubed: 8 }
*
* console.log(assignSquaredAndCubed({ number: 3 }))
* // { number: 3, squared: 9, cubed: 27 }
* ```
*
* Any of the resolvers may be asynchronous and return Promises.
*
* ```javascript [playground]
* const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
*
* const asyncAssignTotal = assign({
* async total({ numbers }) {
* await sleep(500)
* return numbers.reduce((a, b) => a + b)
* },
* })
*
* asyncAssignTotal({ numbers: [1, 2, 3, 4, 5] }).then(console.log)
* // { numbers: [1, 2, 3, 4, 5], total: 15 }
* ```
*
* Values passed in resolver position are set on the result object directly. If any of these values are promises, they are resolved for their values before being set on the result object.
*
* ```javascript [playground]
* assign({}, {
* a: 1,
* b: Promise.resolve(2),
* c: () => 3,
* d: async o => Object.keys(o).length,
* }).then(console.log) // { a: 1, b: 2, c: 3, d: 0 }
* ```
*
* Any promises passed in argument position are resolved for their values before further execution. This only applies to the eager version of the API.
*
* ```javascript [playground]
* assign(Promise.resolve({}), {
* a() {
* return 1
* },
* b() {
* return 2
* },
* }).then(console.log)
* ```
*
* @execution concurrent
*/
const assign = function (arg0, arg1) {
if (arg1 == null) {
return curry2(_assign, __, arg0)
}
return isPromise(arg0)
? arg0.then(curry2(_assign, __, arg1))
: _assign(arg0, arg1)
}
module.exports = assign