@lumjs/core 1.0.0-beta.2 → 1.0.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/obj/lock.js CHANGED
@@ -1,13 +1,12 @@
1
1
  // Import *most* required bits here.
2
2
  const {B, isObj, def} = require('../types');
3
- const {getDescriptor, DESC} = require('../descriptors');
4
3
 
5
4
  /**
6
5
  * Lock an object using Object.freeze()
7
6
  *
8
7
  * @param {object} obj - The object we want to lock.
9
- * @param {boolean} [clonable=true] Pass to {@link Lum._.addClone} first?
10
- * @param {object} [cloneOpts=null] Options for addClone.
8
+ * @param {boolean} [clonable=true] Pass to `addClone()` first?
9
+ * @param {object} [cloneOpts=null] Options for `addClone()`.
11
10
  * @param {boolean} [useSeal=false] Use Object.seal() instead of freeze.
12
11
  *
13
12
  * If cloneOpts is `null` then we will use the following:
@@ -15,8 +14,7 @@ const {getDescriptor, DESC} = require('../descriptors');
15
14
  * ```{mode: CLONE.DEF, addClone: true, addLock: true}```
16
15
  *
17
16
  * @return {object} The locked object.
18
- *
19
- * @method Lum._.lock
17
+ * @alias module:@lumjs/core/obj.lock
20
18
  */
21
19
  function lock(obj, clonable=true, cloneOpts=null, useSeal=false)
22
20
  {
@@ -38,23 +36,28 @@ const {getDescriptor, DESC} = require('../descriptors');
38
36
  /**
39
37
  * Add a lock() method to an object.
40
38
  *
41
- * Adds a wrapper version of {@link Lum._.lock} to the object as a method.
42
- *
43
- * @param {object} obj - The object we're adding lock() to.
44
- * @param {object} opts - Options (TODO: document this).
39
+ * Adds a wrapper version of `lock()` to the object as a method.
45
40
  *
46
- * @method Lum._.addLock
41
+ * @param {object} obj - The object we're adding `lock()` to.
42
+ * @param {object} [opts] - Options and defaults.
43
+ * In addition to options specific to this function, any options
44
+ * supported by `addClone()` may be specified here as well.
45
+ * @param {object} [opts.lockDesc] Descriptor rules the `lock()` method.
46
+ * @param {boolean} [opts.addClone=true] Default for `clonable` parameter.
47
+ * @param {object} [opts.useSeal=false] Default for `useSeal` parameter.
48
+ * @returns {object} `obj`
49
+ * @alias module:@lumjs/core/obj.addLock
47
50
  */
48
51
  function addLock(obj, opts)
49
52
  {
50
- const defDesc = getDescriptor(opts.lockDesc ?? DESC.CONF);
51
- defDesc.setValue(function(obj, cloneable, cloneOpts, useSeal)
53
+ const defDesc = opts.lockDesc ?? {};
54
+ defDesc.value = function(obj, cloneable, cloneOpts, useSeal)
52
55
  {
53
56
  if (typeof cloneable !== B) clonable = opts.addClone ?? true;
54
57
  if (!isObj(cloneOpts)) cloneOpts = opts; // Yup, just a raw copy.
55
58
  if (typeof useSeal !== B) useSeal = opts.useSeal ?? false;
56
59
  return lock(obj, cloneable, cloneOpts, useSeal);
57
- });
60
+ }
58
61
  return def(obj, 'lock', defDesc);
59
62
  }
60
63
 
package/lib/obj/merge.js CHANGED
@@ -20,6 +20,7 @@ const {B, isObj} = require('../types');
20
20
  * as the `opts` argument directly will set this option.
21
21
  *
22
22
  * @returns {object} The `target` object.
23
+ * @alias module:@lumjs/core/obj.mergeNested
23
24
  */
24
25
  function mergeNested(source, target, opts={})
25
26
  {
@@ -64,6 +65,7 @@ const {B, isObj} = require('../types');
64
65
  * @param {object} [opts2=opts1] Options for the second merge operation.
65
66
  * If this is not specified, `opts2` will be the same as `opts1`.
66
67
  *
68
+ * @alias module:@lumjs/core/obj.syncNested
67
69
  */
68
70
  function syncNested(obj1, obj2, opts1={}, opts2=opts1)
69
71
  {
package/lib/obj/ns.js CHANGED
@@ -5,13 +5,14 @@ const
5
5
  } = require('../types');
6
6
 
7
7
  /**
8
- * Internal: need a String or Array
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 + ' ' + this.message
14
- : this.message;
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
- * - TODO: document this.
174
- * - TODO: rewrite `ns.get` to use this behind the scenes.
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
- * - TODO: document this.
187
- * - TODO: rewrite `ns.add` to use this behind the scenes.
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/lib/objectid.js CHANGED
@@ -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
  {
package/lib/observable.js CHANGED
@@ -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 observable API.
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 an object appears to be observable.
276
+ * See if a value implements the *Observable* interface.
277
277
  *
278
- * @param {object} obj
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
- // And make it available as `types.doesObservable`
292
- require('./types').doesObservable = isObservable;
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/lib/opt.js CHANGED
@@ -1,4 +1,7 @@
1
- // Simple option handling.
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 CHANGED
@@ -1,4 +1,7 @@
1
- // String methods.
1
+ /**
2
+ * String and locale related functions.
3
+ * @module @lumjs/core/strings
4
+ */
2
5
  const {S,B,F,isObj,root,isArray,needType,needObj} = require('./types')
3
6
 
4
7
  /**
@@ -8,7 +11,8 @@ const {S,B,F,isObj,root,isArray,needType,needObj} = require('./types')
8
11
  * 2. If `Intl` exists it will be used.
9
12
  * 3. If neither of those exist, uses `'en-US'` as a default.
10
13
  *
11
- * @returns string - The locale/language string.
14
+ * @returns {string} - The locale/language string.
15
+ * @alias module:@lumjs/core/strings.getLocale
12
16
  */
13
17
  function getLocale()
14
18
  {
@@ -42,7 +46,8 @@ exports.getLocale = getLocale;
42
46
  * @param {boolean} [lcrest=false] Make the rest of the string lowercase?
43
47
  * @param {string} [locale=getLocale()] The locale/language of the string.
44
48
  *
45
- * @returns string - The output string.
49
+ * @returns {string} - The output string.
50
+ * @alias module:@lumjs/core/strings.ucfirst
46
51
  */
47
52
  function ucfirst ([ first, ...rest ], lcrest = false, locale = getLocale())
48
53
  {
@@ -61,11 +66,13 @@ exports.ucfirst = ucfirst;
61
66
  * Make the first character of each *word* in a string uppercase.
62
67
  *
63
68
  * @param {string} string - The input string.
64
- * @param {boolean} [unicode=false] Use Unicode words? (Only uses ASCII words otherwise)
69
+ * @param {boolean} [unicode=false] Use *Unicode* words?
70
+ * Only uses simple *PCRE-style* words (`\w`) otherwise.
65
71
  * @param {boolean} [lcrest=false] Make the rest of each word lowercase?
66
72
  * @param {string} [locale=getLocale()] The locale/language of the string.
67
73
  *
68
74
  * @returns {string} - The output string.
75
+ * @alias module:@lumjs/core/strings.ucwords
69
76
  */
70
77
  function ucwords(string, unicode = false, lcrest = false, locale = getLocale())
71
78
  {
@@ -77,6 +84,12 @@ exports.ucwords = ucwords;
77
84
 
78
85
  /**
79
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
80
93
  */
81
94
  function isSearch(value)
82
95
  {
@@ -87,6 +100,12 @@ exports.isSearch = isSearch;
87
100
 
88
101
  /**
89
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
90
109
  */
91
110
  function isReplacement(value)
92
111
  {
@@ -95,6 +114,26 @@ function isReplacement(value)
95
114
 
96
115
  exports.isReplacement = isReplacement;
97
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
+ */
98
137
  function replaceItems(string, replacements, useAll)
99
138
  {
100
139
  needType(S, string);
@@ -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
+