@lumjs/core 1.15.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/arrays/add.js +233 -0
- package/lib/arrays/index.js +21 -0
- package/lib/{arrays.js → arrays/list.js} +8 -43
- package/lib/arrays/util.js +38 -0
- package/lib/index.js +7 -0
- package/lib/maps.js +67 -0
- package/lib/obj/apply.js +52 -0
- package/lib/obj/copyall.js +1 -1
- package/lib/obj/copyprops.js +89 -11
- package/lib/obj/index.js +2 -1
- package/lib/observable.js +54 -18
- package/lib/opt.js +350 -11
- package/lib/strings.js +28 -0
- package/lib/types/console.js +119 -20
- package/lib/types/typelist.js +2 -0
- package/package.json +3 -2
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
|
|
2
|
+
const {N,def} = require('../types');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Functions for adding values to arrays in different ways.
|
|
6
|
+
* @alias module:@lumjs/core/arrays.add
|
|
7
|
+
*/
|
|
8
|
+
const ArrayAdd = module.exports = exports =
|
|
9
|
+
{
|
|
10
|
+
prepend, before, append, after, insert,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function _addWith(array, oldValue, newValue, ifMissing, fn)
|
|
14
|
+
{
|
|
15
|
+
let pos = array.indexOf(oldValue);
|
|
16
|
+
|
|
17
|
+
if (pos === -1)
|
|
18
|
+
{
|
|
19
|
+
if (typeof ifMissing === N)
|
|
20
|
+
{
|
|
21
|
+
pos = ifMissing;
|
|
22
|
+
}
|
|
23
|
+
else
|
|
24
|
+
{
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return fn(array, newValue, pos);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Prepend a value to an array.
|
|
34
|
+
*
|
|
35
|
+
* @param {Array} array - Array to add the value to.
|
|
36
|
+
* @param {*} value - Value to add to the array.
|
|
37
|
+
* @param {number} [pos=0] Position to prepend at.
|
|
38
|
+
*
|
|
39
|
+
* If `pos` is `0` then `array.unshift(value)` is used.
|
|
40
|
+
* Otherwise `array.splice(pos, 0, value)` is used.
|
|
41
|
+
*
|
|
42
|
+
* @returns {Array} `array`
|
|
43
|
+
* @alias module:@lumjs/core/arrays.add.prepend
|
|
44
|
+
*/
|
|
45
|
+
function prepend(array, value, pos=0)
|
|
46
|
+
{
|
|
47
|
+
if (pos === 0)
|
|
48
|
+
{
|
|
49
|
+
array.unshift(value);
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
{
|
|
53
|
+
array.splice(pos, 0, value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return array;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Append a value to an array.
|
|
61
|
+
*
|
|
62
|
+
* @param {Array} array - Array to add the value to.
|
|
63
|
+
* @param {*} value - Value to add to the array.
|
|
64
|
+
* @param {number} [pos=-1] Position to append at.
|
|
65
|
+
*
|
|
66
|
+
* If `pos` is `-1` then `array.push(value)` is used.
|
|
67
|
+
* Otherwise `array.splice(pos+1, 0, value)` is used.
|
|
68
|
+
*
|
|
69
|
+
* @returns {Array} `array`
|
|
70
|
+
* @alias module:@lumjs/core/arrays.add.append
|
|
71
|
+
*/
|
|
72
|
+
function append(array, value, pos=-1)
|
|
73
|
+
{
|
|
74
|
+
if (pos === -1)
|
|
75
|
+
{
|
|
76
|
+
array.push(value);
|
|
77
|
+
}
|
|
78
|
+
else
|
|
79
|
+
{
|
|
80
|
+
array.splice(pos+1, 0, value);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return array;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Add a value to an array _before_ an existing value.
|
|
88
|
+
*
|
|
89
|
+
* This uses `prepend()` to add the value.
|
|
90
|
+
*
|
|
91
|
+
* @param {Array} array - Array to add the value to.
|
|
92
|
+
* @param {*} oldValue - Existing value to find.
|
|
93
|
+
* @param {*} newValue - Value to add to the array.
|
|
94
|
+
* @param {(number|false)} [ifMissing=0] If `oldValue` is not found.
|
|
95
|
+
*
|
|
96
|
+
* If this is a `number` it will be used as the `pos` argument.
|
|
97
|
+
*
|
|
98
|
+
* If this is `false` the function will not add the value at all,
|
|
99
|
+
* but will return `false` instead.
|
|
100
|
+
*
|
|
101
|
+
* @returns {(Array|false)} Usually the input `array`; but will return
|
|
102
|
+
* `false` if `ifMissing` was `false` and the `oldValue` was not found.
|
|
103
|
+
*
|
|
104
|
+
* @alias module:@lumjs/core/arrays.add.before
|
|
105
|
+
*/
|
|
106
|
+
function before(array, oldValue, newValue, ifMissing=0)
|
|
107
|
+
{
|
|
108
|
+
return _addWith(array, oldValue, newValue, ifMissing, prepend);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Add a value to an array _after_ an existing value.
|
|
113
|
+
*
|
|
114
|
+
* This uses `append()` to add the value.
|
|
115
|
+
*
|
|
116
|
+
* @param {Array} array - Array to add the value to.
|
|
117
|
+
* @param {*} oldValue - Existing value to find.
|
|
118
|
+
* @param {*} newValue - Value to add to the array.
|
|
119
|
+
* @param {(number|false)} [ifMissing=-1] If `oldValue` is not found.
|
|
120
|
+
*
|
|
121
|
+
* If this is a `number` it will be used as the `pos` argument.
|
|
122
|
+
*
|
|
123
|
+
* If this is `false` the function will not add the value at all,
|
|
124
|
+
* but will return `false` instead.
|
|
125
|
+
*
|
|
126
|
+
* @returns {(Array|false)} Usually the input `array`; but will return
|
|
127
|
+
* `false` if `ifMissing` was `false` and the `oldValue` was not found.
|
|
128
|
+
*
|
|
129
|
+
* @alias module:@lumjs/core/arrays.add.after
|
|
130
|
+
*/
|
|
131
|
+
function after(array, oldValue, newValue, ifMissing=-1)
|
|
132
|
+
{
|
|
133
|
+
return _addWith(array, oldValue, newValue, ifMissing, append);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Insert a value to an array using special logic.
|
|
138
|
+
*
|
|
139
|
+
* See the `pos` argument for the positioning logic used.
|
|
140
|
+
*
|
|
141
|
+
* @param {Array} array - Array to add the value to.
|
|
142
|
+
* @param {*} value - Value to add to the array.
|
|
143
|
+
* @param {number} [pos=-1] Position to insert at.
|
|
144
|
+
*
|
|
145
|
+
* If `pos` is less than `0` this uses `append()`;
|
|
146
|
+
* Otherwise it uses `prepend()`.
|
|
147
|
+
*
|
|
148
|
+
* @returns {Array} `array`
|
|
149
|
+
* @alias module:@lumjs/core/arrays.add.insert
|
|
150
|
+
*/
|
|
151
|
+
function insert(array, value, pos=-1)
|
|
152
|
+
{
|
|
153
|
+
if (pos < 0)
|
|
154
|
+
{
|
|
155
|
+
return append(array, value, pos);
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{
|
|
159
|
+
return prepend(array, value, pos);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* A wrapper class to provide helper methods to Arrays.
|
|
165
|
+
*
|
|
166
|
+
* Provides wrapped versions of `prepend()`, `append()`,
|
|
167
|
+
* `before()`, `after()`, and `insert()`.
|
|
168
|
+
*
|
|
169
|
+
* The methods obviously pass the array argument, so remove it from
|
|
170
|
+
* the argument signature when using the wrapper method. Other than that,
|
|
171
|
+
* the rest of the arguments are the same as the wrapped functions.
|
|
172
|
+
*
|
|
173
|
+
* @alias module:@lumjs/core/arrays.add.At
|
|
174
|
+
*/
|
|
175
|
+
class ArrayAt
|
|
176
|
+
{
|
|
177
|
+
/**
|
|
178
|
+
* Build a wrapper around an array.
|
|
179
|
+
*
|
|
180
|
+
* @param {Array} array - Array to wrap.
|
|
181
|
+
*/
|
|
182
|
+
constructor(array)
|
|
183
|
+
{
|
|
184
|
+
this.array = array;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Add wrappers for the helper functions to the Array directly.
|
|
189
|
+
*
|
|
190
|
+
* WARNING: This is monkey patching the array object instance.
|
|
191
|
+
* If you're okay with that, cool.
|
|
192
|
+
*
|
|
193
|
+
* Otherwise, use a new `ArrayAt` object instance instead.
|
|
194
|
+
*
|
|
195
|
+
* @param {Array} array - Array to add methods to.
|
|
196
|
+
*
|
|
197
|
+
* @returns {Array} The input `array`
|
|
198
|
+
*/
|
|
199
|
+
static extend(array)
|
|
200
|
+
{
|
|
201
|
+
for (const methName in ArrayAdd)
|
|
202
|
+
{
|
|
203
|
+
const methFunc = ArrayAdd[methName];
|
|
204
|
+
def(array, methName, methFunc.bind(array, array));
|
|
205
|
+
}
|
|
206
|
+
return array;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* A static method that calls `new ArrayAt(array)`;
|
|
211
|
+
*
|
|
212
|
+
* @param {Array} array - Array to wrap
|
|
213
|
+
* @returns {module:@lumjs/core/arrays.ArrayAt} A new instance.
|
|
214
|
+
*/
|
|
215
|
+
static new(array)
|
|
216
|
+
{
|
|
217
|
+
return new this(array);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
} // ArrayAt class
|
|
221
|
+
|
|
222
|
+
// Set up ArrayAt methods, and export the functions.
|
|
223
|
+
for (const methName in ArrayAdd)
|
|
224
|
+
{
|
|
225
|
+
const methFunc = ArrayAdd[methName];
|
|
226
|
+
|
|
227
|
+
def(ArrayAt.prototype, methName, function()
|
|
228
|
+
{
|
|
229
|
+
methFunc(this.array, ...arguments);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
def(ArrayAdd, 'At', ArrayAt);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Array helper libraries
|
|
3
|
+
*
|
|
4
|
+
* @module @lumjs/core/arrays
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const {lazy} = require('../types');
|
|
8
|
+
const {powerset, random} = require('./util');
|
|
9
|
+
|
|
10
|
+
// Utils.
|
|
11
|
+
exports.powerset = powerset;
|
|
12
|
+
exports.random = random;
|
|
13
|
+
|
|
14
|
+
// List stuff.
|
|
15
|
+
lazy(exports, 'List', () => require('./list'));
|
|
16
|
+
lazy(exports, 'containsAny', () => exports.List.containsAny);
|
|
17
|
+
lazy(exports, 'containsAll', () => exports.List.containsAll);
|
|
18
|
+
lazy(exports, 'removeItems', () => exports.List.removeItems);
|
|
19
|
+
|
|
20
|
+
// Add functions and At class.
|
|
21
|
+
lazy(exports, 'add', () => require('./add'));
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @module @lumjs/core/arrays
|
|
4
|
-
*/
|
|
5
|
-
const {F,S} = require('./types/js');
|
|
1
|
+
|
|
2
|
+
const {F,S} = require('../types');
|
|
6
3
|
|
|
7
4
|
/**
|
|
8
5
|
* A wrapper class to abstract functionality of various kinds of lists.
|
|
@@ -278,6 +275,8 @@ function containsAny(list, ...items)
|
|
|
278
275
|
return List.for(list, CONTAINS_OPTS).containsAny(...items);
|
|
279
276
|
}
|
|
280
277
|
|
|
278
|
+
List.containsAny = containsAny;
|
|
279
|
+
|
|
281
280
|
/**
|
|
282
281
|
* See if a list contains *all* of the specified items.
|
|
283
282
|
*
|
|
@@ -291,6 +290,8 @@ function containsAll(list, ...items)
|
|
|
291
290
|
return List.for(list, CONTAINS_OPTS).containsAll(...items);
|
|
292
291
|
}
|
|
293
292
|
|
|
293
|
+
List.containsAll = containsAll;
|
|
294
|
+
|
|
294
295
|
const REMOVE_OPTS = {closures: ['remove']};
|
|
295
296
|
|
|
296
297
|
/**
|
|
@@ -309,42 +310,6 @@ function removeItems(list, ...items)
|
|
|
309
310
|
return List.for(list, REMOVE_OPTS).removeAll(...items);
|
|
310
311
|
}
|
|
311
312
|
|
|
312
|
-
|
|
313
|
-
* Return a Powerset of values in the array.
|
|
314
|
-
* @param {Array} array The array to make the powerset from.
|
|
315
|
-
* @returns {Array} The powerset.
|
|
316
|
-
* @alias module:@lumjs/core/arrays.powerset
|
|
317
|
-
*/
|
|
318
|
-
function powerset(array)
|
|
319
|
-
{
|
|
320
|
-
var ps = [[]];
|
|
321
|
-
for (var i=0; i < array.length; i++)
|
|
322
|
-
{
|
|
323
|
-
// we modify the ps array in the next loop,
|
|
324
|
-
// so can't use the ps.length property directly in the loop condition.
|
|
325
|
-
var current_length = ps.length;
|
|
326
|
-
for (var j = 0; j < current_length; j++)
|
|
327
|
-
{
|
|
328
|
-
ps.push(ps[j].concat(array[i]));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return ps;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Get a random element from an array.
|
|
336
|
-
* @param {Array} array The array to get an item from.
|
|
337
|
-
* @returns {mixed} The randomly selected item.
|
|
338
|
-
* @alias module:@lumjs/core/arrays.random
|
|
339
|
-
*/
|
|
340
|
-
function random(array)
|
|
341
|
-
{
|
|
342
|
-
return array[Math.floor(Math.random()*array.length)];
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
module.exports = exports =
|
|
346
|
-
{
|
|
347
|
-
List, containsAny, containsAll,
|
|
348
|
-
removeItems, powerset, random,
|
|
349
|
-
}
|
|
313
|
+
List.removeItems = removeItems;
|
|
350
314
|
|
|
315
|
+
module.exports = exports = List;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Return a Powerset of values in the array.
|
|
4
|
+
* @param {Array} array The array to make the powerset from.
|
|
5
|
+
* @returns {Array} The powerset.
|
|
6
|
+
* @alias module:@lumjs/core/arrays.powerset
|
|
7
|
+
*/
|
|
8
|
+
function powerset(array)
|
|
9
|
+
{
|
|
10
|
+
var ps = [[]];
|
|
11
|
+
for (var i=0; i < array.length; i++)
|
|
12
|
+
{
|
|
13
|
+
// we modify the ps array in the next loop,
|
|
14
|
+
// so can't use the ps.length property directly in the loop condition.
|
|
15
|
+
var current_length = ps.length;
|
|
16
|
+
for (var j = 0; j < current_length; j++)
|
|
17
|
+
{
|
|
18
|
+
ps.push(ps[j].concat(array[i]));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return ps;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get a random element from an array.
|
|
26
|
+
* @param {Array} array The array to get an item from.
|
|
27
|
+
* @returns {mixed} The randomly selected item.
|
|
28
|
+
* @alias module:@lumjs/core/arrays.random
|
|
29
|
+
*/
|
|
30
|
+
function random(array)
|
|
31
|
+
{
|
|
32
|
+
return array[Math.floor(Math.random()*array.length)];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = exports =
|
|
36
|
+
{
|
|
37
|
+
powerset, random,
|
|
38
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -44,6 +44,13 @@ def(exports, 'lazy', lazy);
|
|
|
44
44
|
*/
|
|
45
45
|
lazy(exports, 'arrays', () => require('./arrays'));
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Map utility functions «Lazy»
|
|
49
|
+
* @name module:@lumjs/core.maps
|
|
50
|
+
* @type {module:@lumjs/core/maps}
|
|
51
|
+
*/
|
|
52
|
+
lazy(exports, 'maps', () => require('./maps'));
|
|
53
|
+
|
|
47
54
|
/**
|
|
48
55
|
* Information about the JS context we're running in
|
|
49
56
|
* @name module:@lumjs/core.context
|
package/lib/maps.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map object helper functions.
|
|
3
|
+
* @module @lumjs/core/maps
|
|
4
|
+
*/
|
|
5
|
+
const {F,isObj} = require('./types/js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Build a `Map` instance out of various types of objects.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} input - An object to be converted into a `Map`.
|
|
11
|
+
*
|
|
12
|
+
* Supported object types:
|
|
13
|
+
*
|
|
14
|
+
* - `Array`, `Map`, or any other object with an `entries()` method.
|
|
15
|
+
* - Implements `Iterable` interface (`[Symbol.iterator]`).
|
|
16
|
+
* - Implements `Iterator` interface (`next()`).
|
|
17
|
+
* - Anything other object we'll use all enumerable properties.
|
|
18
|
+
*
|
|
19
|
+
* @returns {Map}
|
|
20
|
+
* @alias module:@lumjs/core/maps.mapOf
|
|
21
|
+
*/
|
|
22
|
+
function mapOf(input)
|
|
23
|
+
{
|
|
24
|
+
if (!isObj(input))
|
|
25
|
+
{
|
|
26
|
+
throw new TypeError('Non-object passed to mapOf');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof input.entries === F)
|
|
30
|
+
{ // Short-cut for Arrays, other Maps, etc.
|
|
31
|
+
return new Map(input.entries());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const map = new Map();
|
|
35
|
+
|
|
36
|
+
if (typeof input[Symbol.iterator] === F)
|
|
37
|
+
{ // Using the Iterable interface.
|
|
38
|
+
let i = 0;
|
|
39
|
+
for (const value of input)
|
|
40
|
+
{
|
|
41
|
+
map.set(i++, value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (typeof thing.next === F)
|
|
45
|
+
{ // Using the Iterator interface.
|
|
46
|
+
let i = 0, next;
|
|
47
|
+
|
|
48
|
+
while ((next = input.next()) && !next.done)
|
|
49
|
+
{
|
|
50
|
+
map.set(i++, next.value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
{ // A plain old object. Use enumerable properties.
|
|
55
|
+
for (const key in input)
|
|
56
|
+
{
|
|
57
|
+
map.set(key, input[key]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return map;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports =
|
|
65
|
+
{
|
|
66
|
+
mapOf,
|
|
67
|
+
}
|
package/lib/obj/apply.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const {F,isObj} = require('../types');
|
|
2
|
+
const copyProps = require('./copyprops');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Apply functions to an object
|
|
6
|
+
*
|
|
7
|
+
* In addition to the parameters passed, we'll also define:
|
|
8
|
+
*
|
|
9
|
+
* - `cp` will be a `CopyProps` instance via `copyProps.cache.into(obj)`;
|
|
10
|
+
* - `args` will be an array of `[obj, opts]`;
|
|
11
|
+
* - `opts` will be an object of `{obj, cp, args}`;
|
|
12
|
+
*
|
|
13
|
+
* @param {(object|function)} obj - The target we're applying to.
|
|
14
|
+
*
|
|
15
|
+
* @param {...(function|object)} fns - Values we are applying.
|
|
16
|
+
*
|
|
17
|
+
* For each value of `fns` as `fn`:
|
|
18
|
+
*
|
|
19
|
+
* - If a `function` we'll call `fn.apply(obj, args)`;
|
|
20
|
+
* - If an `object` we'll call `cp.from(fn)`.
|
|
21
|
+
*
|
|
22
|
+
* @returns {object} `obj`
|
|
23
|
+
* @throws {TypeError} If a `fns` value is not valid.
|
|
24
|
+
* @alias module:@lumjs/core/obj.apply
|
|
25
|
+
*/
|
|
26
|
+
function apply(obj, ...fns)
|
|
27
|
+
{
|
|
28
|
+
const cp = copyProps.cache.into(obj);
|
|
29
|
+
const opts = {obj, cp};
|
|
30
|
+
const args = [obj, opts];
|
|
31
|
+
opts.args = args;
|
|
32
|
+
|
|
33
|
+
for (const fn of fns)
|
|
34
|
+
{
|
|
35
|
+
if (typeof fn === F)
|
|
36
|
+
{
|
|
37
|
+
fn.apply(obj, args);
|
|
38
|
+
}
|
|
39
|
+
else if (isObj(fn))
|
|
40
|
+
{
|
|
41
|
+
cp.from(fn);
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
{
|
|
45
|
+
throw new TypeError("invalid parameter value");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return obj;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = apply;
|
package/lib/obj/copyall.js
CHANGED
|
@@ -39,7 +39,7 @@ exports.duplicateOne = copyAll.clone = obj => copyAll({}, obj);
|
|
|
39
39
|
*
|
|
40
40
|
* Use `copyProps.into({}).from(...sources)` for a more robust version.
|
|
41
41
|
*
|
|
42
|
-
* Alias: `copyAll.
|
|
42
|
+
* Alias: `copyAll.duplicate`
|
|
43
43
|
*
|
|
44
44
|
* @alias module:@lumjs/core/obj.duplicateOne
|
|
45
45
|
* @param {object} obj - The object to duplicate.
|
package/lib/obj/copyprops.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
// Get some constants
|
|
3
|
-
const {B,N,F,isObj,isArray,needObj,def,console} = require('../types');
|
|
4
|
-
const {duplicateOne: clone} = require('./copyall');
|
|
3
|
+
const {S,B,N,F,isObj,isArray,needObj,def,console} = require('../types');
|
|
4
|
+
const {copyAll, duplicateOne: clone} = require('./copyall');
|
|
5
5
|
|
|
6
6
|
const RECURSE_NONE = 0;
|
|
7
7
|
const RECURSE_ALL = -1;
|
|
@@ -233,22 +233,35 @@ def(copyProps, 'RECURSE_LIST', RECURSE_LIST);
|
|
|
233
233
|
* // Get a copy of the `copyProps` function.
|
|
234
234
|
* const cp = require('@lumjs/core').obj.copyProps;
|
|
235
235
|
*
|
|
236
|
-
* // Starting with the target:
|
|
236
|
+
* // Starting with the target(s):
|
|
237
237
|
* cp.into(targetObj).given({all: true}).from(source1, source2);
|
|
238
238
|
*
|
|
239
|
-
* // Starting with the
|
|
239
|
+
* // Starting with the source(s):
|
|
240
240
|
* cp.from(sourceObj).given({exclude: ['dontCopy']}).into(target1, target2);
|
|
241
241
|
*
|
|
242
242
|
* // Starting with the options:
|
|
243
243
|
* cp.given({recursive: cp.RECURSE_ALL}).from(source1, source2).into(target1, target2);
|
|
244
244
|
*
|
|
245
|
+
* // Call `cp.into()` and cache the instance in a `Map`.
|
|
246
|
+
* // Future calls with the same `targetObj` will return the cached instance.
|
|
247
|
+
* // Unlike `cp.into()`, only supports a single `targetObj`.
|
|
248
|
+
* cp.cache.into(targetObj);
|
|
249
|
+
*
|
|
250
|
+
* // Call `cp.from()` and cache the instance in a `Map`.
|
|
251
|
+
* // Future calls with the same `sourceObj` will return the cached instance.
|
|
252
|
+
* // Unlike `cp.from()`, only supports a single `sourceObj`.
|
|
253
|
+
* cp.cache.from(sourceObj);
|
|
245
254
|
*
|
|
255
|
+
* // Clear the `Map` instances for `cp.cache.into` and `cp.cache.from`
|
|
256
|
+
* cp.cache.clear();
|
|
257
|
+
*
|
|
246
258
|
* ```
|
|
247
259
|
*
|
|
248
260
|
* @alias module:@lumjs/core/obj~CopyProps
|
|
249
261
|
*/
|
|
250
262
|
class $CopyProps
|
|
251
263
|
{
|
|
264
|
+
// Constructor is private so we won't document it.
|
|
252
265
|
constructor(opts={})
|
|
253
266
|
{
|
|
254
267
|
this.opts = opts;
|
|
@@ -257,21 +270,42 @@ class $CopyProps
|
|
|
257
270
|
}
|
|
258
271
|
|
|
259
272
|
/**
|
|
260
|
-
* Set
|
|
261
|
-
*
|
|
262
|
-
* @param {
|
|
273
|
+
* Set options.
|
|
274
|
+
*
|
|
275
|
+
* @param {(string|object)} opt - Option(s) to set.
|
|
276
|
+
*
|
|
277
|
+
* If this is a `string` it's the name of an option to set.
|
|
278
|
+
* If this is an `object`, it's map of options to set with `copyAll`.
|
|
279
|
+
*
|
|
280
|
+
* @param {*} value - The option value.
|
|
281
|
+
*
|
|
282
|
+
* Only used if `option` is a `string`.
|
|
283
|
+
*
|
|
263
284
|
* @returns {object} `this`
|
|
264
285
|
*/
|
|
265
|
-
set(
|
|
286
|
+
set(opt, value)
|
|
266
287
|
{
|
|
267
|
-
|
|
288
|
+
//console.debug("CopyProps.set(", opt, value, ')');
|
|
289
|
+
if (typeof opt === S)
|
|
290
|
+
{ // Set a single option.
|
|
291
|
+
this.opts[opt] = value;
|
|
292
|
+
}
|
|
293
|
+
else if (isObj(opt))
|
|
294
|
+
{ // Set a bunch of options.
|
|
295
|
+
copyAll(this.opts, opt);
|
|
296
|
+
}
|
|
297
|
+
else
|
|
298
|
+
{ // That's not supported
|
|
299
|
+
console.error("invalid opt", {opt, value, cp: this});
|
|
300
|
+
}
|
|
301
|
+
//console.debug("CopyProps.set:after", this);
|
|
268
302
|
return this;
|
|
269
303
|
}
|
|
270
304
|
|
|
271
305
|
/**
|
|
272
|
-
* Set all
|
|
306
|
+
* Set all options.
|
|
273
307
|
*
|
|
274
|
-
* This replaces
|
|
308
|
+
* This replaces any existing options entirely.
|
|
275
309
|
*
|
|
276
310
|
* @param {object} opts - The options to set.
|
|
277
311
|
* @returns {object} `this`
|
|
@@ -372,4 +406,48 @@ copyProps.from = function(...sources)
|
|
|
372
406
|
return ((new $CopyProps()).from(...sources));
|
|
373
407
|
}
|
|
374
408
|
|
|
409
|
+
const CPC = copyProps.cache =
|
|
410
|
+
{
|
|
411
|
+
into(target)
|
|
412
|
+
{
|
|
413
|
+
if (this.intoCache === undefined)
|
|
414
|
+
this.intoCache = new Map();
|
|
415
|
+
const cache = this.intoCache;
|
|
416
|
+
if (cache.has(target))
|
|
417
|
+
{
|
|
418
|
+
return cache.get(target);
|
|
419
|
+
}
|
|
420
|
+
else
|
|
421
|
+
{
|
|
422
|
+
const cp = copyProps.into(target);
|
|
423
|
+
cache.set(target, cp);
|
|
424
|
+
return cp;
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
from(source)
|
|
428
|
+
{
|
|
429
|
+
if (this.fromCache === undefined)
|
|
430
|
+
this.fromCache = new Map();
|
|
431
|
+
const cache = this.fromCache;
|
|
432
|
+
if (cache.has(source))
|
|
433
|
+
{
|
|
434
|
+
return cache.get(source);
|
|
435
|
+
}
|
|
436
|
+
else
|
|
437
|
+
{
|
|
438
|
+
const cp = copyProps.from(source);
|
|
439
|
+
cache.set(source, cp);
|
|
440
|
+
return cp;
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
clear()
|
|
444
|
+
{
|
|
445
|
+
if (this.intoCache)
|
|
446
|
+
this.intoCache.clear();
|
|
447
|
+
if (this.fromCache)
|
|
448
|
+
this.fromCache.clear();
|
|
449
|
+
return this;
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
|
|
375
453
|
module.exports = copyProps;
|
package/lib/obj/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module @lumjs/core/obj
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
const apply = require('./apply');
|
|
6
7
|
const {copyAll,duplicateOne,duplicateAll} = require('./copyall');
|
|
7
8
|
const copyProps = require('./copyprops');
|
|
8
9
|
const {CLONE,clone,addClone,cloneIfLocked} = require('./clone');
|
|
@@ -23,5 +24,5 @@ module.exports =
|
|
|
23
24
|
mergeNested, syncNested, copyProps, copyAll, ns,
|
|
24
25
|
getObjectPath, setObjectPath, getNamespace, setNamespace,
|
|
25
26
|
getProperty, duplicateAll, duplicateOne, getMethods, signatureOf,
|
|
26
|
-
MethodFilter,
|
|
27
|
+
MethodFilter, apply,
|
|
27
28
|
}
|