@lumjs/core 1.16.0 → 1.19.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/{types/console.js → console.js} +6 -6
- package/lib/index.js +14 -0
- package/lib/maps.js +67 -0
- package/lib/observable.js +52 -16
- package/lib/opt.js +350 -11
- package/lib/strings.js +28 -0
- package/lib/types/basics.js +110 -110
- package/lib/types/index.js +5 -2
- package/lib/types/needs.js +1 -1
- package/lib/types/owncount.js +50 -0
- package/package.json +3 -2
- package/debug/2023-06-08T19_55_05_247Z-debug-0.log +0 -107
package/lib/opt.js
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* @module @lumjs/core/opt
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const {U,F,S,needObj,needType} = require('./types');
|
|
6
|
+
const {U,F,S,N,B,isObj,isComplex,needObj,needType} = require('./types');
|
|
7
|
+
const {insert} = require('./arrays/add');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* See if a value is *set*, and if not, return a default value.
|
|
10
11
|
*
|
|
11
|
-
* @param {*}
|
|
12
|
+
* @param {*} optvalue - The value we are testing.
|
|
12
13
|
* @param {*} defvalue - The default value if opt was null or undefined.
|
|
13
14
|
*
|
|
14
15
|
* @param {boolean} [allowNull=false] If true, allow null to count as *set*.
|
|
@@ -17,22 +18,28 @@ const {U,F,S,needObj,needType} = require('./types');
|
|
|
17
18
|
* the default.
|
|
18
19
|
* @param {object} [lazyThis=null] If `isLazy` is true, this object will
|
|
19
20
|
* be used as `this` for the function.
|
|
21
|
+
* @param {Array} [lazyArgs] If `isLazy` is true, this may be used
|
|
22
|
+
* as a list of arguments to pass.
|
|
20
23
|
*
|
|
21
24
|
* @return {*} Either the specified `opt` value or the default value.
|
|
22
25
|
* @alias module:@lumjs/core/opt.val
|
|
23
26
|
*/
|
|
24
|
-
function val(
|
|
27
|
+
function val(optvalue, defvalue,
|
|
28
|
+
allowNull=false,
|
|
29
|
+
isLazy=false,
|
|
30
|
+
lazyThis=null,
|
|
31
|
+
lazyArgs=[])
|
|
25
32
|
{
|
|
26
|
-
if (typeof
|
|
33
|
+
if (typeof optvalue === U || (!allowNull && optvalue === null))
|
|
27
34
|
{ // The defined value was not "set" as per our rules.
|
|
28
35
|
if (isLazy && typeof defvalue === F)
|
|
29
36
|
{ // Get the default value from a passed in function.
|
|
30
|
-
return defvalue.
|
|
37
|
+
return defvalue.apply(lazyThis, lazyArgs);
|
|
31
38
|
}
|
|
32
39
|
return defvalue;
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
return
|
|
42
|
+
return optvalue;
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
exports.val = val;
|
|
@@ -48,18 +55,350 @@ exports.val = val;
|
|
|
48
55
|
* @param {string} optname - The property name we're checking for.
|
|
49
56
|
* @param {*} defvalue - The default value.
|
|
50
57
|
*
|
|
51
|
-
* @param {bool} [allowNull=true] Same as `val()`, but
|
|
58
|
+
* @param {bool} [allowNull=true] Same as `val()`, but default is `true`.
|
|
52
59
|
* @param {bool} [isLazy=false] Same as `val()`.
|
|
53
|
-
* @param {object} [lazyThis=opts] Same as `val()`.
|
|
60
|
+
* @param {object} [lazyThis=opts] Same as `val()`, but default is `obj`.
|
|
61
|
+
* @param {Array} [lazyArgs] Same as `val()`.
|
|
54
62
|
*
|
|
55
63
|
* @return {*} Either the property value, or the default value.
|
|
56
|
-
* module:@lumjs/core/opt.get
|
|
64
|
+
* @alias module:@lumjs/core/opt.get
|
|
57
65
|
*/
|
|
58
|
-
function get(obj, optname, defvalue,
|
|
66
|
+
function get(obj, optname, defvalue,
|
|
67
|
+
allowNull=true,
|
|
68
|
+
isLazy=false,
|
|
69
|
+
lazyThis=obj,
|
|
70
|
+
lazyArgs)
|
|
59
71
|
{
|
|
60
72
|
needObj(obj);
|
|
61
73
|
needType(S, optname);
|
|
62
|
-
return val(obj[optname], defvalue, allowNull, isLazy, lazyThis);
|
|
74
|
+
return val(obj[optname], defvalue, allowNull, isLazy, lazyThis, lazyArgs);
|
|
63
75
|
}
|
|
64
76
|
|
|
65
77
|
exports.get = get;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* A class for handling options with multiple sources.
|
|
81
|
+
* @alias module:@lumjs/core/opt.Opts
|
|
82
|
+
*/
|
|
83
|
+
class Opts
|
|
84
|
+
{
|
|
85
|
+
/**
|
|
86
|
+
* Build an Opts instance.
|
|
87
|
+
*
|
|
88
|
+
* @param {...object} sources - Initial sources of options.
|
|
89
|
+
*
|
|
90
|
+
* The order of sources matters, as the ones added later will override
|
|
91
|
+
* the ones added earlier. Keep that in mind when adding sources.
|
|
92
|
+
*/
|
|
93
|
+
constructor(...sources)
|
|
94
|
+
{
|
|
95
|
+
this.$sources = [];
|
|
96
|
+
this.$curPos = -1;
|
|
97
|
+
this.$curSrc = null;
|
|
98
|
+
|
|
99
|
+
this.$fatalErrors = false;
|
|
100
|
+
this.$strictProps = false;
|
|
101
|
+
|
|
102
|
+
this.add(...sources);
|
|
103
|
+
this._compile();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Compile current sources into a data object.
|
|
108
|
+
*
|
|
109
|
+
* @returns {object} `this`
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
_compile()
|
|
113
|
+
{
|
|
114
|
+
this.$data = Object.assign({}, ...this.$sources);
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Handle an error
|
|
120
|
+
*
|
|
121
|
+
* @param {string} msg - A summary of the error.
|
|
122
|
+
* @param {object} info - Debugging information for the logs.
|
|
123
|
+
* @param {function} [errClass=TypeError] Constructor for an `Error` class.
|
|
124
|
+
* Used if fatal errors are enabled.
|
|
125
|
+
*
|
|
126
|
+
* @returns {object} `this`
|
|
127
|
+
* @throws {Error} An error of `errClass` class, if fatal mode is enabled.
|
|
128
|
+
*/
|
|
129
|
+
_err(msg, info={}, errClass=TypeError)
|
|
130
|
+
{
|
|
131
|
+
const args = this.$fatalErrors ? [info] : [msg, info];
|
|
132
|
+
|
|
133
|
+
info.instance = this;
|
|
134
|
+
console.error(...args);
|
|
135
|
+
|
|
136
|
+
if (this.$fatalErrors)
|
|
137
|
+
{
|
|
138
|
+
throw new errClass(msg);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Set the fatal error handling setting.
|
|
144
|
+
*
|
|
145
|
+
* Default is `false`, so errors will be logged, but not thrown.
|
|
146
|
+
*
|
|
147
|
+
* @param {boolean} val - Should errors be fatal?
|
|
148
|
+
* @returns {object} `this`
|
|
149
|
+
*/
|
|
150
|
+
fatal(val)
|
|
151
|
+
{
|
|
152
|
+
if (typeof val === B)
|
|
153
|
+
{
|
|
154
|
+
this.$fatalErrors = val;
|
|
155
|
+
}
|
|
156
|
+
else
|
|
157
|
+
{
|
|
158
|
+
this._err('invalid fatal value', {val});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Set the strict property check setting.
|
|
166
|
+
*
|
|
167
|
+
* Default is `false`, we don't care about non-existent properties.
|
|
168
|
+
*
|
|
169
|
+
* @param {boolean} val - Should non-existant properties be an error?
|
|
170
|
+
* @returns {object} `this`
|
|
171
|
+
*/
|
|
172
|
+
strict(val)
|
|
173
|
+
{
|
|
174
|
+
if (typeof val === B)
|
|
175
|
+
{
|
|
176
|
+
this.$strictProps = val;
|
|
177
|
+
}
|
|
178
|
+
else
|
|
179
|
+
{
|
|
180
|
+
this._err('invalid strict value', {val});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Set the position/offset to add new sources at.
|
|
188
|
+
*
|
|
189
|
+
* This will affect subsequent calls to the `add()` method.
|
|
190
|
+
*
|
|
191
|
+
* @param {number} pos - The position/offset value.
|
|
192
|
+
*
|
|
193
|
+
* - A value of `-1` uses `Array#push(src))`; end of array.
|
|
194
|
+
* - A value of `0` uses `Array#unshift(src)`; start of array.
|
|
195
|
+
* - Any value `> 0` uses `Array#splice(pos, 0, src)`; offset from start.
|
|
196
|
+
* - Any value `< -1` uses `Array#splice(pos+1, 0, src)`; offset from end.
|
|
197
|
+
*
|
|
198
|
+
* The default value if none is specified is `-1`.
|
|
199
|
+
*
|
|
200
|
+
* @returns {object} `this`
|
|
201
|
+
* @throws {TypeError} An invalid value was passed while `fatal` was true.
|
|
202
|
+
*/
|
|
203
|
+
at(pos)
|
|
204
|
+
{
|
|
205
|
+
if (typeof pos === N)
|
|
206
|
+
{
|
|
207
|
+
this.$curPos = pos;
|
|
208
|
+
}
|
|
209
|
+
else
|
|
210
|
+
{
|
|
211
|
+
this._err("Invalid pos value", {pos});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Set the object to look for nested properties in.
|
|
219
|
+
*
|
|
220
|
+
* This will affect subsequent calls to the `add()` method.
|
|
221
|
+
*
|
|
222
|
+
* @param {(object|number|boolean)} source - Source definition
|
|
223
|
+
*
|
|
224
|
+
* - If this is an `object` it will be used as the object directly.
|
|
225
|
+
* - If this is a `number` it is the position of one of our data sources.
|
|
226
|
+
* Negative numbers count from the end of the list of sources.
|
|
227
|
+
* - If this is `true` then the compiled options data at the time of the
|
|
228
|
+
* call to this method will be used.
|
|
229
|
+
* - If this is `false` then the next time a `string` value is passed to
|
|
230
|
+
* `add()` the options will be compiled on demand, and that object will
|
|
231
|
+
* be used until the next call to `from()`.
|
|
232
|
+
*
|
|
233
|
+
* If this is not specified, then it defaults to `false`.
|
|
234
|
+
*
|
|
235
|
+
* @returns {object} `this`
|
|
236
|
+
* @throws {TypeError} An invalid value was passed while `fatal` was true.
|
|
237
|
+
*/
|
|
238
|
+
from(source)
|
|
239
|
+
{
|
|
240
|
+
if (source === true)
|
|
241
|
+
{ // Use existing data as the source.
|
|
242
|
+
this.$curSrc = this.$data;
|
|
243
|
+
}
|
|
244
|
+
else if (source === false)
|
|
245
|
+
{ // Auto-generate the source the next time.
|
|
246
|
+
this.$curSrc = null;
|
|
247
|
+
}
|
|
248
|
+
else if (typeof source === N)
|
|
249
|
+
{ // A number will be the position of an existing source.
|
|
250
|
+
const offset
|
|
251
|
+
= (source < 0)
|
|
252
|
+
? this.$sources.length + source
|
|
253
|
+
: source;
|
|
254
|
+
|
|
255
|
+
if (isObj(this.$sources[offset]))
|
|
256
|
+
{
|
|
257
|
+
this.$curSrc = this.$sources[offset];
|
|
258
|
+
}
|
|
259
|
+
else
|
|
260
|
+
{
|
|
261
|
+
this._err("Invalid source offset", {offset, source});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else if (isObj(source))
|
|
265
|
+
{ // An object or function will be used as the source.
|
|
266
|
+
this.$curSrc = source;
|
|
267
|
+
}
|
|
268
|
+
else
|
|
269
|
+
{
|
|
270
|
+
this._err("Invalid source", {source});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Add new sources of options.
|
|
278
|
+
*
|
|
279
|
+
* @param {...(object|string)} sources - Sources and positions.
|
|
280
|
+
*
|
|
281
|
+
* If this is an `object` then it's a source of options to add.
|
|
282
|
+
* This is the most common way of using this.
|
|
283
|
+
*
|
|
284
|
+
* If this is a `string` then it's assumed to be nested property
|
|
285
|
+
* of the current `from()` source, and if that property exists and
|
|
286
|
+
* is an object, it will be used as the source to add. If it does
|
|
287
|
+
* not exist, then the behaviour will depend on the values of the
|
|
288
|
+
* `strict()` and `fatal()` modifiers.
|
|
289
|
+
*
|
|
290
|
+
* @returns {object} `this`
|
|
291
|
+
*/
|
|
292
|
+
add(...sources)
|
|
293
|
+
{
|
|
294
|
+
let pos=-1;
|
|
295
|
+
|
|
296
|
+
for (let source of sources)
|
|
297
|
+
{
|
|
298
|
+
if (source === undefined || source === null)
|
|
299
|
+
{ // Skip undefined or null values.
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (typeof source === S)
|
|
304
|
+
{ // Try to find a nested property to include.
|
|
305
|
+
if (this.$curSrc === null)
|
|
306
|
+
{ // Has not been initialized, let's do that now.
|
|
307
|
+
this._compile();
|
|
308
|
+
this.$curSrc = this.$data;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (isObj(this.$curSrc[source]))
|
|
312
|
+
{ // Found a property, use it.
|
|
313
|
+
source = this.$curSrc[source];
|
|
314
|
+
}
|
|
315
|
+
else
|
|
316
|
+
{ // No such property.
|
|
317
|
+
if (this.$strictProps)
|
|
318
|
+
{
|
|
319
|
+
this._err('Property not found', {source});
|
|
320
|
+
}
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (isObj(source))
|
|
326
|
+
{ // It's a source to add.
|
|
327
|
+
insert(this.$sources, source, pos);
|
|
328
|
+
}
|
|
329
|
+
else
|
|
330
|
+
{ // That's not valid.
|
|
331
|
+
this._err('invalid source value', {source, sources});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return this._compile();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Remove existing sources of options.
|
|
340
|
+
*
|
|
341
|
+
* @param {...object} sources - Sources to remove.
|
|
342
|
+
*
|
|
343
|
+
* @returns {object} `this`
|
|
344
|
+
*/
|
|
345
|
+
remove(...sources)
|
|
346
|
+
{
|
|
347
|
+
for (const source of sources)
|
|
348
|
+
{
|
|
349
|
+
const index = this.$sources.indexOf(source);
|
|
350
|
+
if (index !== -1)
|
|
351
|
+
{
|
|
352
|
+
this.$sources.splice(index, 1);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return this._compile();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Remove all current sources. Resets compiled options data.
|
|
361
|
+
*
|
|
362
|
+
* @returns {object} `this`
|
|
363
|
+
*/
|
|
364
|
+
clear()
|
|
365
|
+
{
|
|
366
|
+
this.$sources = [];
|
|
367
|
+
return this._compile();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Get an option value from our compiled data sources.
|
|
372
|
+
*
|
|
373
|
+
* This uses the `get()` function, but instead of using positional
|
|
374
|
+
* arguments, it supports an object of named options instead.
|
|
375
|
+
*
|
|
376
|
+
* @param {string} opt - The name of the option to get.
|
|
377
|
+
* @param {object} [args] Optional arguments for `get()`.
|
|
378
|
+
* @param {*} [args.default] `defvalue` argument.
|
|
379
|
+
* @param {boolean} [args.null=true] `allowNull` argument.
|
|
380
|
+
* @param {boolean} [args.lazy=false] `isLazy` argument.
|
|
381
|
+
* @param {(object|function)} [args.lazyThis] `lazyThis` argument.
|
|
382
|
+
* If this is defined, `args.lazy` will be set to `true`.
|
|
383
|
+
* @param {Array} [args.lazyArgs] `lazyArgs` argument.
|
|
384
|
+
* If this is defined, `args.lazy` will be set to `true`.
|
|
385
|
+
*
|
|
386
|
+
* @returns {*} The output of the `get()` function.
|
|
387
|
+
*/
|
|
388
|
+
get(opt, args={})
|
|
389
|
+
{
|
|
390
|
+
if (isComplex(args.lazyThis) || Array.isArray(args.lazyArgs))
|
|
391
|
+
{
|
|
392
|
+
args.lazy = true;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return get(this.$data, opt,
|
|
396
|
+
args.default,
|
|
397
|
+
args.null,
|
|
398
|
+
args.lazy,
|
|
399
|
+
args.lazyThis,
|
|
400
|
+
args.lazyArgs);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
exports.Opts = Opts;
|
package/lib/strings.js
CHANGED
|
@@ -189,3 +189,31 @@ function replaceItems(string, replacements, useAll)
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
exports.replaceItems = replaceItems;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Replace values in a string via an async function.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} string - The input string.
|
|
197
|
+
*
|
|
198
|
+
* @param {(RegExp|string)} regexp - The pattern to find.
|
|
199
|
+
*
|
|
200
|
+
* If this is a `RegExp`, it *must* have the `g` flag set.
|
|
201
|
+
* If this is a `string` it will be converted into a `RegExp`,
|
|
202
|
+
* see the `String#matchAll` method for details.
|
|
203
|
+
*
|
|
204
|
+
* @param {function} replacerFunction - An `async` function.
|
|
205
|
+
*
|
|
206
|
+
* See `String#replace` for details on replacer functions.
|
|
207
|
+
*
|
|
208
|
+
* @returns {string}
|
|
209
|
+
*/
|
|
210
|
+
async function replaceAsync(string, regexp, replacerFunction)
|
|
211
|
+
{
|
|
212
|
+
const replacements = await Promise.all(
|
|
213
|
+
Array.from(string.matchAll(regexp),
|
|
214
|
+
match => replacerFunction(...match)));
|
|
215
|
+
let i = 0;
|
|
216
|
+
return string.replace(regexp, () => replacements[i++]);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
exports.replaceAsync = replaceAsync;
|
package/lib/types/basics.js
CHANGED
|
@@ -6,92 +6,92 @@ const {O, F, S, SY} = require('./js');
|
|
|
6
6
|
* @returns {boolean}
|
|
7
7
|
* @alias module:@lumjs/core/types.isObj
|
|
8
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
|
-
|
|
9
|
+
function isObj(v) { return (typeof v === O && v !== null); }
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* See if a value is *complex* (i.e. either `object` or `function`).
|
|
13
|
+
* Like `isObj()`, `null` does not count as an `object`.
|
|
14
|
+
* @param {*} v - The value we're testing.
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
* @alias module:@lumjs/core/types.isComplex
|
|
17
|
+
*/
|
|
18
|
+
function isComplex(v) { return (typeof v === F || isObj(v)); }
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* See if a value is *nil* (i.e. either `null` or `undefined`).
|
|
22
|
+
* @param {*} v - The value we're testing.
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
* @alias module:@lumjs/core/types.isNil
|
|
25
|
+
*/
|
|
26
|
+
function isNil(v) { return (v === undefined || v === null); }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* See if a value is not *nil* (i.e. neither `null` nor `undefined`).
|
|
30
|
+
* @param {*} v - The value we're testing.
|
|
31
|
+
* @returns {boolean}
|
|
32
|
+
* @alias module:@lumjs/core/types.notNil
|
|
33
|
+
*/
|
|
34
|
+
function notNil(v) { return (v !== undefined && v !== null); }
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* See if a value is a scalar.
|
|
38
|
+
* For the purposes of this, a scalar is any value which
|
|
39
|
+
* is neither *nil* nor *complex*.
|
|
40
|
+
* @param {*} v - The value we're testing.
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
* @alias module:@lumjs/core/types.isScalar
|
|
43
|
+
*/
|
|
44
|
+
function isScalar(v) { return (notNil(v) && !isComplex(v)); }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* See if a value is an `Array` object.
|
|
48
|
+
* This is literally just a copy of `Array.isArray`.
|
|
49
|
+
* @function
|
|
50
|
+
* @param {*} v - The value we're testing.
|
|
51
|
+
* @returns {boolean}
|
|
52
|
+
* @alias module:@lumjs/core/types.isArray
|
|
53
|
+
*/
|
|
54
|
+
const isArray = Array.isArray;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* See if a value is a `TypedArray` object.
|
|
58
|
+
* @param {*} v - The value we're testing.
|
|
59
|
+
* @returns {boolean}
|
|
60
|
+
* @alias module:@lumjs/core/types.isTypedArray
|
|
61
|
+
*/
|
|
62
|
+
function isTypedArray(v)
|
|
63
|
+
{
|
|
64
|
+
return (ArrayBuffer.isView(v) && !(v instanceof DataView));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* See if a value is a non-empty Array.
|
|
69
|
+
* @param {*} v - The value we're testing.
|
|
70
|
+
* @param {boolean} [typed=false] If `true` we want a `TypedArray`.
|
|
71
|
+
* If `false` (default) we want a regular `Array`.
|
|
72
|
+
* @returns {boolean}
|
|
73
|
+
* @alias module:@lumjs/core/types.nonEmptyArray
|
|
74
|
+
*/
|
|
75
|
+
function nonEmptyArray(v, typed=false)
|
|
76
|
+
{
|
|
77
|
+
if (typed)
|
|
78
|
+
return (isTypedArray(v) && v.length > 0);
|
|
79
|
+
else
|
|
80
|
+
return (isArray(v) && v.length > 0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* See if a value is an `arguments` object.
|
|
85
|
+
* @param {*} v - The value we're testing.
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
* @alias module:@lumjs/core/types.isArguments
|
|
88
|
+
*/
|
|
89
|
+
function isArguments(v)
|
|
90
|
+
{
|
|
91
|
+
return Object.prototype.toString.call(v) === '[object Arguments]';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
95
|
* See if a value is a Property name.
|
|
96
96
|
* @param {*} v - The value we're testing.
|
|
97
97
|
* @returns {boolean}
|
|
@@ -122,28 +122,28 @@ function isProperty(v)
|
|
|
122
122
|
* @returns {boolean} - Is the object a valid descriptor?
|
|
123
123
|
* @alias module:@lumjs/core/types.doesDescriptor
|
|
124
124
|
*/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
125
|
+
function doesDescriptor(obj)
|
|
126
|
+
{
|
|
127
|
+
if (isObj(obj))
|
|
128
|
+
{
|
|
129
|
+
const hasValue = (obj.value !== undefined);
|
|
130
|
+
const hasGetter = (typeof obj.get === F);
|
|
131
|
+
const hasSetter = (typeof obj.set === F);
|
|
132
|
+
const hasWritable = (obj.writable !== undefined);
|
|
133
|
+
|
|
134
|
+
if (hasValue && !hasGetter && !hasSetter)
|
|
135
|
+
{ // We have a value, and no getter or setter.
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
else if ((hasGetter || hasSetter) && !hasValue && !hasWritable)
|
|
139
|
+
{ // We have a getter or setter, and no value or writable properties.
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Nothing matched, not a valid descriptor rule.
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
149
|
* See if an object can be used as a valid *descriptor template*.
|
|
@@ -195,6 +195,6 @@ function doesDescriptorTemplate(obj, accessor=false, strict=true)
|
|
|
195
195
|
// Now export those.
|
|
196
196
|
module.exports =
|
|
197
197
|
{
|
|
198
|
-
isObj, isComplex, isNil, notNil, isScalar, isArray, isTypedArray,
|
|
199
|
-
nonEmptyArray, isArguments, isProperty, doesDescriptor, doesDescriptorTemplate,
|
|
198
|
+
isObj, isComplex, isNil, notNil, isScalar, isArray, isTypedArray,
|
|
199
|
+
nonEmptyArray, isArguments, isProperty, doesDescriptor, doesDescriptorTemplate,
|
|
200
200
|
}
|
package/lib/types/index.js
CHANGED
|
@@ -42,8 +42,10 @@ const def = require('./def');
|
|
|
42
42
|
const lazy = require('./lazy');
|
|
43
43
|
const TYPES = require('./typelist');
|
|
44
44
|
const stringify = require('./stringify');
|
|
45
|
+
const ownCount = require('./owncount');
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
// An alias for legacy reasons.
|
|
48
|
+
const console = require('../console');
|
|
47
49
|
|
|
48
50
|
// Okay, add all those to our exports.
|
|
49
51
|
// Further tests can be added by `TYPES.add()` later.
|
|
@@ -53,7 +55,8 @@ module.exports =
|
|
|
53
55
|
isObj, isComplex, isNil, notNil, isScalar, isArray, isTypedArray,
|
|
54
56
|
nonEmptyArray, isArguments, isProperty, doesDescriptor,
|
|
55
57
|
isInstance, isType, isa, needObj, needType, needs, stringify,
|
|
56
|
-
doesDescriptorTemplate,
|
|
58
|
+
doesDescriptorTemplate, ownCount,
|
|
59
|
+
console,
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
// Last but not least, this will be the module for TYPES.add()
|