@lumjs/core 1.0.0-beta.1 → 1.0.0-beta.6
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/README.md +10 -2
- package/TODO.md +12 -4
- package/docs/changelogs/1.0-beta.md +99 -0
- package/{CHANGELOG.md → docs/changelogs/1.x.md} +7 -7
- package/jsdoc.json +33 -0
- package/lib/arrays.js +78 -0
- package/lib/context.js +86 -0
- package/{src → lib}/enum.js +30 -13
- package/{src → lib}/flags.js +6 -0
- package/lib/index.js +131 -0
- package/{src → lib}/lazy.js +33 -35
- package/{src → lib}/meta.js +38 -1
- package/lib/modules.js +113 -0
- package/lib/obj/clone.js +220 -0
- package/{src → lib}/obj/copyall.js +3 -0
- package/{src → lib}/obj/copyprops.js +1 -0
- package/lib/obj/index.js +23 -0
- package/{src → lib}/obj/lock.js +16 -13
- package/{src → lib}/obj/merge.js +2 -0
- package/{src → lib}/obj/ns.js +45 -8
- package/{src → lib}/objectid.js +2 -3
- package/{src → lib}/observable.js +23 -8
- package/{src → lib}/opt.js +6 -1
- package/lib/strings.js +192 -0
- package/lib/types/basics.js +154 -0
- package/lib/types/def.js +183 -0
- package/lib/types/index.js +55 -0
- package/lib/types/isa.js +186 -0
- package/lib/types/js.js +12 -0
- package/lib/types/needs.js +117 -0
- package/lib/types/root.js +92 -0
- package/lib/types/stringify.js +98 -0
- package/lib/types/typelist.js +168 -0
- package/package.json +26 -3
- package/test/arrays.js +19 -0
- package/test/meta.js +17 -0
- package/test/types.js +106 -23
- package/index.js +0 -64
- package/src/context.js +0 -47
- package/src/descriptors.js +0 -243
- package/src/obj/clone.js +0 -201
- package/src/obj/index.js +0 -18
- package/src/prop.js +0 -170
- package/src/strings.js +0 -76
- package/src/types.js +0 -545
package/{src → lib}/obj/ns.js
RENAMED
|
@@ -5,13 +5,14 @@ const
|
|
|
5
5
|
} = require('../types');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Need a String or Array
|
|
9
|
+
* @alias module:@lumjs/core/obj.SOA
|
|
9
10
|
*/
|
|
10
11
|
function SOA(name, err=true)
|
|
11
12
|
{
|
|
12
13
|
const msg = (typeof name === S)
|
|
13
|
-
? name + ' ' +
|
|
14
|
-
:
|
|
14
|
+
? name + ' ' + SOA.message
|
|
15
|
+
: SOA.message;
|
|
15
16
|
return err ? (new TypeError(msg)) : msg;
|
|
16
17
|
}
|
|
17
18
|
SOA.message = "must be a string or non-empty array";
|
|
@@ -19,6 +20,17 @@ def(SOA, 'toString', function() { return this.message; });
|
|
|
19
20
|
|
|
20
21
|
exports.SOA = SOA;
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Get a namespace path string.
|
|
25
|
+
*
|
|
26
|
+
* If it's already a string, return it as is.
|
|
27
|
+
* If it's an array of strings, join the elements with a `.` character.
|
|
28
|
+
*
|
|
29
|
+
* @param {(string|string[])} ns - A dotted string, or array of paths.
|
|
30
|
+
* @param {*} name - Name to use in the SOA error
|
|
31
|
+
* @returns {string}
|
|
32
|
+
* @alias module:@lumjs/core/obj.nsString
|
|
33
|
+
*/
|
|
22
34
|
function nsString(ns, name='Namespace')
|
|
23
35
|
{
|
|
24
36
|
if (nonEmptyArray(ns))
|
|
@@ -34,6 +46,17 @@ function nsString(ns, name='Namespace')
|
|
|
34
46
|
|
|
35
47
|
exports.nsString = nsString;
|
|
36
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Get a namespace path array.
|
|
51
|
+
*
|
|
52
|
+
* If it's already an array, return it as is.
|
|
53
|
+
* If it's a string, split it into an array, with the `.` delimiter.
|
|
54
|
+
*
|
|
55
|
+
* @param {(string|string[])} ns - A dotted string, or array of paths.
|
|
56
|
+
* @param {*} name - Name to use in the SOA error
|
|
57
|
+
* @returns {string[]}
|
|
58
|
+
* @alias module:@lumjs/core/obj.nsArray
|
|
59
|
+
*/
|
|
37
60
|
function nsArray(ns, name='Namespace')
|
|
38
61
|
{
|
|
39
62
|
if (typeof ns === S)
|
|
@@ -57,6 +80,7 @@ exports.nsArray = nsArray;
|
|
|
57
80
|
* Generally a string of dot (`.`) separated nested property names.
|
|
58
81
|
* @param {object} [opts] TBD.
|
|
59
82
|
* @return {*} The property if found, or `opts.default` if not.
|
|
83
|
+
* @alias module:@lumjs/core/obj.getObjectPath
|
|
60
84
|
*/
|
|
61
85
|
function getObjectPath(obj, proppath, opts={})
|
|
62
86
|
{
|
|
@@ -97,6 +121,7 @@ exports.getObjectPath = getObjectPath;
|
|
|
97
121
|
* @param {object} [opts] TBD.
|
|
98
122
|
* @return {*} Generally the last object in the nested path.
|
|
99
123
|
* However the output may vary depending on the options.
|
|
124
|
+
* @alias module:@lumjs/core/obj.setObjectPath
|
|
100
125
|
*/
|
|
101
126
|
function setObjectPath(obj, proppath, opts={})
|
|
102
127
|
{
|
|
@@ -169,9 +194,15 @@ exports.setObjectPath = setObjectPath;
|
|
|
169
194
|
|
|
170
195
|
/**
|
|
171
196
|
* Get a global namespace path if it exists.
|
|
197
|
+
*
|
|
198
|
+
* This literally just calls `getObjectPath()` on the `root` object.
|
|
172
199
|
*
|
|
173
|
-
* -
|
|
174
|
-
*
|
|
200
|
+
* @param {(string|Array)} proppath - Property path we're looking for.
|
|
201
|
+
* Generally a string of dot (`.`) separated nested property names.
|
|
202
|
+
* @param {object} [opts] See `getObjectPath()` for details.
|
|
203
|
+
* @return {*} The property if found, or `opts.default` if not.
|
|
204
|
+
* @alias module:@lumjs/core/obj.getNamespace
|
|
205
|
+
* @see module:@lumjs/core/obj.getObjectPath
|
|
175
206
|
*/
|
|
176
207
|
function getNamespace(namespaces, opts={})
|
|
177
208
|
{
|
|
@@ -183,12 +214,18 @@ exports.getNamespace = getNamespace;
|
|
|
183
214
|
/**
|
|
184
215
|
* Create a global namespace path if it does not exist.
|
|
185
216
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
217
|
+
* This literally just calls `setObjectPath()` on the `root` object.
|
|
218
|
+
*
|
|
219
|
+
* @param {(string|Array)} proppath - Property path to create.
|
|
220
|
+
* @param {object} [opts] See `setObjectPath()` for details.
|
|
221
|
+
* @return {*} Generally the last object in the nested path.
|
|
222
|
+
* However the output may vary depending on the options.
|
|
223
|
+
* @alias module:@lumjs/core/obj.setNamespace
|
|
224
|
+
* @see module:@lumjs/core/obj.setObjectPath
|
|
188
225
|
*/
|
|
189
226
|
function setNamespace(namespaces, opts={})
|
|
190
227
|
{
|
|
191
228
|
return setObjectPath(root, namespaces, opts);
|
|
192
229
|
}
|
|
193
230
|
|
|
194
|
-
exports.setNamespace = setNamespace;
|
|
231
|
+
exports.setNamespace = setNamespace;
|
package/{src → lib}/objectid.js
RENAMED
|
@@ -4,9 +4,8 @@ const {notNil,def,isNil} = require('./types');
|
|
|
4
4
|
/**
|
|
5
5
|
* Generate a large random number.
|
|
6
6
|
*
|
|
7
|
-
* Takes advantage of
|
|
8
|
-
*
|
|
9
7
|
* @returns {number}
|
|
8
|
+
* @alias module:@lumjs/core.randomNumber
|
|
10
9
|
*/
|
|
11
10
|
function randomNumber()
|
|
12
11
|
{
|
|
@@ -18,6 +17,7 @@ exports.randomNumber = randomNumber;
|
|
|
18
17
|
/**
|
|
19
18
|
* A class for creating unique identifier objects.
|
|
20
19
|
* Generally only used by my own inernal libraries, thus the name.
|
|
20
|
+
* @alias module:@lumjs/core.InternalObjectId
|
|
21
21
|
*/
|
|
22
22
|
class InternalObjectId
|
|
23
23
|
{
|
|
@@ -34,7 +34,6 @@ class InternalObjectId
|
|
|
34
34
|
* @param {boolean} [opts.useInstance=true] Store object or id value?
|
|
35
35
|
* If this is `true` (now the default), we store the instance itself.
|
|
36
36
|
* If this is `false` (the old default), we store just the `id` value.
|
|
37
|
-
*
|
|
38
37
|
*/
|
|
39
38
|
constructor(opts={})
|
|
40
39
|
{
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
// This library was original based on the observable library from riot.js,
|
|
2
|
-
// but has been refactored and expanded a lot since then.
|
|
3
1
|
|
|
4
|
-
const {B,F,S,def,isObj,isComplex} = require('./types');;
|
|
2
|
+
const {B,F,S,def,isObj,isComplex,TYPES} = require('./types');;
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
|
-
* Make an object support the
|
|
5
|
+
* Make an object support the *Observable* API.
|
|
8
6
|
*
|
|
9
7
|
* Adds `on()`, `off()`, `one()`, and `trigger()` methods.
|
|
10
8
|
*
|
|
@@ -38,6 +36,8 @@ const {B,F,S,def,isObj,isComplex} = require('./types');;
|
|
|
38
36
|
* In any other case it defaults to `null`.
|
|
39
37
|
*
|
|
40
38
|
* @returns {object} el
|
|
39
|
+
*
|
|
40
|
+
* @exports module:@lumjs/core/observable
|
|
41
41
|
*/
|
|
42
42
|
function observable (el={}, opts={})
|
|
43
43
|
{
|
|
@@ -273,9 +273,10 @@ function observable (el={}, opts={})
|
|
|
273
273
|
module.exports = observable;
|
|
274
274
|
|
|
275
275
|
/**
|
|
276
|
-
* See if
|
|
276
|
+
* See if a value implements the *Observable* interface.
|
|
277
277
|
*
|
|
278
|
-
* @
|
|
278
|
+
* @function module:@lumjs/core/observable.is
|
|
279
|
+
* @param {*} obj - The expected object/function to test.
|
|
279
280
|
* @returns {boolean}
|
|
280
281
|
*/
|
|
281
282
|
function isObservable(obj)
|
|
@@ -288,5 +289,19 @@ function isObservable(obj)
|
|
|
288
289
|
// Add an 'is()' method to `observable` itself.
|
|
289
290
|
def(observable, 'is', isObservable);
|
|
290
291
|
|
|
291
|
-
|
|
292
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Does a value implement the Observable interface?
|
|
294
|
+
* @name module:@lumjs/core/types.doesObservable
|
|
295
|
+
* @function
|
|
296
|
+
* @param {*} v - The expected object/function to test.
|
|
297
|
+
* @returns {boolean}
|
|
298
|
+
* @see module:@lumjs/core/observable.is
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Extension type for the {@link module:@lumjs/core/observable} interface.
|
|
303
|
+
* @memberof module:@lumjs/core/types.TYPES
|
|
304
|
+
* @member {string} OBSERV - Implements the *Observable* interface.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
TYPES.add('OBSERV', 'observable', isObservable, 'doesObservable');
|
package/{src → lib}/opt.js
RENAMED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Functions for working with options and default values.
|
|
3
|
+
* @module @lumjs/core/opt
|
|
4
|
+
*/
|
|
2
5
|
|
|
3
6
|
const {U,needObj,needType} = require('./types');
|
|
4
7
|
|
|
@@ -16,6 +19,7 @@ const {U,needObj,needType} = require('./types');
|
|
|
16
19
|
* be used as `this` for the function.
|
|
17
20
|
*
|
|
18
21
|
* @return {*} Either the specified `opt` value or the default value.
|
|
22
|
+
* @alias module:@lumjs/core/opt.val
|
|
19
23
|
*/
|
|
20
24
|
function val(opt, defvalue, allowNull=false, isLazy=false, lazyThis=null)
|
|
21
25
|
{
|
|
@@ -49,6 +53,7 @@ exports.val = val;
|
|
|
49
53
|
* @param {object} [lazyThis=opts] Same as `val()`.
|
|
50
54
|
*
|
|
51
55
|
* @return {*} Either the property value, or the default value.
|
|
56
|
+
* module:@lumjs/core/opt.get
|
|
52
57
|
*/
|
|
53
58
|
function get(obj, optname, defvalue, allowNull=true, isLazy=false, lazyThis=obj)
|
|
54
59
|
{
|
package/lib/strings.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String and locale related functions.
|
|
3
|
+
* @module @lumjs/core/strings
|
|
4
|
+
*/
|
|
5
|
+
const {S,B,F,isObj,root,isArray,needType,needObj} = require('./types')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get the locale/language string.
|
|
9
|
+
*
|
|
10
|
+
* 1. If `navigator.language` exists it will be used.
|
|
11
|
+
* 2. If `Intl` exists it will be used.
|
|
12
|
+
* 3. If neither of those exist, uses `'en-US'` as a default.
|
|
13
|
+
*
|
|
14
|
+
* @returns {string} - The locale/language string.
|
|
15
|
+
* @alias module:@lumjs/core/strings.getLocale
|
|
16
|
+
*/
|
|
17
|
+
function getLocale()
|
|
18
|
+
{
|
|
19
|
+
if (isObj(root.navigator) && typeof root.navigator.language === S)
|
|
20
|
+
{
|
|
21
|
+
return root.navigator.language;
|
|
22
|
+
}
|
|
23
|
+
else if (isObj(root.Intl))
|
|
24
|
+
{
|
|
25
|
+
try
|
|
26
|
+
{
|
|
27
|
+
const lang = root.Intl.DateTimeFormat().resolvedOptions().locale;
|
|
28
|
+
return lang;
|
|
29
|
+
}
|
|
30
|
+
catch (err)
|
|
31
|
+
{
|
|
32
|
+
console.warn("Attempt to get locale from Intl failed", err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// A last-ditch fallback.
|
|
37
|
+
return 'en-US';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
exports.getLocale = getLocale;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Make the first character of a string uppercase.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} string - The input string.
|
|
46
|
+
* @param {boolean} [lcrest=false] Make the rest of the string lowercase?
|
|
47
|
+
* @param {string} [locale=getLocale()] The locale/language of the string.
|
|
48
|
+
*
|
|
49
|
+
* @returns {string} - The output string.
|
|
50
|
+
* @alias module:@lumjs/core/strings.ucfirst
|
|
51
|
+
*/
|
|
52
|
+
function ucfirst ([ first, ...rest ], lcrest = false, locale = getLocale())
|
|
53
|
+
{
|
|
54
|
+
first = first.toLocaleUpperCase(locale);
|
|
55
|
+
rest = rest.join('');
|
|
56
|
+
if (lcrest)
|
|
57
|
+
{
|
|
58
|
+
rest = rest.toLocaleLowerCase(locale);
|
|
59
|
+
}
|
|
60
|
+
return first + rest;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
exports.ucfirst = ucfirst;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Make the first character of each *word* in a string uppercase.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} string - The input string.
|
|
69
|
+
* @param {boolean} [unicode=false] Use *Unicode* words?
|
|
70
|
+
* Only uses simple *PCRE-style* words (`\w`) otherwise.
|
|
71
|
+
* @param {boolean} [lcrest=false] Make the rest of each word lowercase?
|
|
72
|
+
* @param {string} [locale=getLocale()] The locale/language of the string.
|
|
73
|
+
*
|
|
74
|
+
* @returns {string} - The output string.
|
|
75
|
+
* @alias module:@lumjs/core/strings.ucwords
|
|
76
|
+
*/
|
|
77
|
+
function ucwords(string, unicode = false, lcrest = false, locale = getLocale())
|
|
78
|
+
{
|
|
79
|
+
const regex = unicode ? /[0-9\p{L}]+/ug : /\w+/g;
|
|
80
|
+
return string.replace(regex, word => ucfirst(word, lcrest, locale));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.ucwords = ucwords;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Is the passed in value a valid `String.replace` search value.
|
|
87
|
+
*
|
|
88
|
+
* Only strings and `RegExp` objects are valid.
|
|
89
|
+
*
|
|
90
|
+
* @param {*} v - Value to check.
|
|
91
|
+
* @returns {boolean}
|
|
92
|
+
* @alias module:@lumjs/core/strings.isSearch
|
|
93
|
+
*/
|
|
94
|
+
function isSearch(value)
|
|
95
|
+
{
|
|
96
|
+
return (typeof value === S || value instanceof RegExp);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
exports.isSearch = isSearch;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Is the passed in value a valid `String.replace` replacement value.
|
|
103
|
+
*
|
|
104
|
+
* Only strings and functions are valid.
|
|
105
|
+
*
|
|
106
|
+
* @param {*} v - Value to check.
|
|
107
|
+
* @returns {boolean}
|
|
108
|
+
* @alias module:@lumjs/core/strings.isReplacement
|
|
109
|
+
*/
|
|
110
|
+
function isReplacement(value)
|
|
111
|
+
{
|
|
112
|
+
return (typeof value === S || typeof value === F);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.isReplacement = isReplacement;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Apply multiple replacement rules to a string.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} string - The input string.
|
|
121
|
+
* @param {object} replacements - Replacement rules.
|
|
122
|
+
*
|
|
123
|
+
* If this is an `Array` then each item in the array can be:
|
|
124
|
+
* - Another array with two items, `[find, replace]`;
|
|
125
|
+
* - A `boolean`, will change the current `useAll` settting.
|
|
126
|
+
*
|
|
127
|
+
* If this is any other kind of `object` then the enumerable
|
|
128
|
+
* property *keys* will be used as `find` strings, and the
|
|
129
|
+
* associated *values* will be used as the `replacement` values.
|
|
130
|
+
*
|
|
131
|
+
* @param {boolean} [useAll] Which replacement method will be used.
|
|
132
|
+
* If `true` we use `replaceAll()`, if `false` we use `replace()`.
|
|
133
|
+
* The default is `false` if `value` is an `Array`, or `true` otherwise.
|
|
134
|
+
* @returns {string} The output string with all replacements performed.
|
|
135
|
+
* @alias module:@lumjs/core/strings.replaceItems
|
|
136
|
+
*/
|
|
137
|
+
function replaceItems(string, replacements, useAll)
|
|
138
|
+
{
|
|
139
|
+
needType(S, string);
|
|
140
|
+
needObj(replacements);
|
|
141
|
+
|
|
142
|
+
// This will call the appropriate method.
|
|
143
|
+
function replace()
|
|
144
|
+
{
|
|
145
|
+
if (useAll)
|
|
146
|
+
string = string.replaceAll(...arguments);
|
|
147
|
+
else
|
|
148
|
+
string = string.replace(...arguments);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (isArray(replacements))
|
|
152
|
+
{ // An array of arrays of replace/replaceAll parameters.
|
|
153
|
+
useAll = useAll ?? false; // Defaults to false here if it wasn't set.
|
|
154
|
+
for (const replacement of replacements)
|
|
155
|
+
{
|
|
156
|
+
if (isArray(replacement) && replacement.length == 2
|
|
157
|
+
&& isSearch(replacement[0]) && isReplacement(replacement[1]))
|
|
158
|
+
{ // A set of parameters for the function.
|
|
159
|
+
replace(...replacement);
|
|
160
|
+
}
|
|
161
|
+
else if (typeof replacement === B)
|
|
162
|
+
{ // A boolean will override the current useAll value.
|
|
163
|
+
useAll = replacement;
|
|
164
|
+
}
|
|
165
|
+
else
|
|
166
|
+
{ // That's not valid.
|
|
167
|
+
console.error("Invalid replacement value", replacement);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
{ // Any other object is a map of find strings to replacement values.
|
|
173
|
+
useAll = useAll ?? true; // Defaults to true here if it wasn't set.
|
|
174
|
+
for (const find in replacements)
|
|
175
|
+
{
|
|
176
|
+
const value = replacements[find];
|
|
177
|
+
if (isReplacement(value))
|
|
178
|
+
{
|
|
179
|
+
replace(find, value);
|
|
180
|
+
}
|
|
181
|
+
else
|
|
182
|
+
{
|
|
183
|
+
console.error("Invalid replacement value", value);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return string;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
exports.replaceItems = replaceItems;
|
|
192
|
+
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const {O, F, S, SY} = require('./js');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* See if a value is a non-null `object`.
|
|
5
|
+
* @param {*} v - The value we're testing.
|
|
6
|
+
* @returns {boolean}
|
|
7
|
+
* @alias module:@lumjs/core/types.isObj
|
|
8
|
+
*/
|
|
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
|
+
* See if a value is a Property name.
|
|
96
|
+
* @param {*} v - The value we're testing.
|
|
97
|
+
* @returns {boolean}
|
|
98
|
+
* @alias module:@lumjs/core/types.isProperty
|
|
99
|
+
*/
|
|
100
|
+
function isProperty(v)
|
|
101
|
+
{
|
|
102
|
+
const t = typeof v;
|
|
103
|
+
return (t === S || t === SY);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* See if an object can be used as a valid descriptor.
|
|
108
|
+
*
|
|
109
|
+
* Basically in order to be considered a valid descriptor,
|
|
110
|
+
* one of the the following sets of rules must be true:
|
|
111
|
+
*
|
|
112
|
+
* - A Data Descriptor:
|
|
113
|
+
* - Has a `value` property.
|
|
114
|
+
* - Does not have a `get` property.
|
|
115
|
+
* - Does not have a `set` property.
|
|
116
|
+
* - An Accessor Descriptor:
|
|
117
|
+
* - Has a `get` and/or `set` property.
|
|
118
|
+
* - Does not have a `value` property.
|
|
119
|
+
* - Does not have a `writable` property.
|
|
120
|
+
*
|
|
121
|
+
* @param {object} obj - The object we are testing.
|
|
122
|
+
* @returns {boolean} - Is the object a valid descriptor?
|
|
123
|
+
* @alias module:@lumjs/core/types.doesDescriptor
|
|
124
|
+
*/
|
|
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
|
+
|
|
148
|
+
// Now export those.
|
|
149
|
+
module.exports =
|
|
150
|
+
{
|
|
151
|
+
isObj, isComplex, isNil, notNil, isScalar, isArray, isTypedArray,
|
|
152
|
+
nonEmptyArray, isArguments, isProperty, doesDescriptor,
|
|
153
|
+
}
|
|
154
|
+
|