@lumjs/core 1.38.7 → 1.39.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/index.js +23 -11
- package/lib/arrays/util.js +83 -1
- package/lib/context.js +3 -3
- package/lib/enum.js +9 -5
- package/lib/env.js +28 -12
- package/lib/index.js +7 -2
- package/lib/meta.js +259 -57
- package/lib/obj/apply.js +1 -3
- package/lib/obj/basics.js +12 -0
- package/lib/obj/cp.js +1 -1
- package/lib/obj/df.js +9 -9
- package/lib/obj/getproperty.js +1 -1
- package/lib/obj/index.js +18 -14
- package/lib/obj/keys.js +55 -0
- package/lib/obj/lock.js +2 -68
- package/lib/obj/unlocked.js +8 -10
- package/lib/proxy.js +417 -0
- package/lib/state.js +35 -4
- package/lib/types/js.js +3 -0
- package/lib/types/root.js +1 -0
- package/package.json +5 -2
- package/lib/arrays/add.js +0 -233
- package/lib/arrays/list.js +0 -314
- package/lib/arrays/typed.js +0 -139
- package/lib/obj/clone.js +0 -378
- package/lib/obj/copyall.js +0 -45
- package/lib/obj/copyprops.js +0 -73
- package/lib/obj/merge.js +0 -84
package/lib/meta.js
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const { getOwnKeys, keyName } = require('./obj/keys');
|
|
8
|
+
const { isIterable, isObj } = require('./types/basics');
|
|
9
|
+
|
|
10
|
+
const cp = Object.assign;
|
|
11
|
+
const dp = Object.defineProperty;
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* Get a stacktrace.
|
|
9
15
|
*
|
|
@@ -17,13 +23,10 @@
|
|
|
17
23
|
* @returns {string[]} An array of stack strings.
|
|
18
24
|
* @alias module:@lumjs/core/meta.stacktrace
|
|
19
25
|
*/
|
|
20
|
-
function stacktrace(msg)
|
|
21
|
-
{
|
|
26
|
+
function stacktrace(msg) {
|
|
22
27
|
return (new Error(msg)).stack.split("\n");
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
exports.stacktrace = stacktrace;
|
|
26
|
-
|
|
27
30
|
/**
|
|
28
31
|
* An Error that can be thrown from abstract methods.
|
|
29
32
|
*
|
|
@@ -54,8 +57,7 @@ exports.stacktrace = stacktrace;
|
|
|
54
57
|
*
|
|
55
58
|
* @alias module:@lumjs/core/meta.AbstractError
|
|
56
59
|
*/
|
|
57
|
-
class AbstractError extends Error
|
|
58
|
-
{
|
|
60
|
+
class AbstractError extends Error {
|
|
59
61
|
/**
|
|
60
62
|
* Construct an AbstractError
|
|
61
63
|
*
|
|
@@ -69,8 +71,7 @@ class AbstractError extends Error
|
|
|
69
71
|
* error message to use 'getter' instead of 'method'.
|
|
70
72
|
*
|
|
71
73
|
*/
|
|
72
|
-
constructor(name, getter=false)
|
|
73
|
-
{
|
|
74
|
+
constructor(name, getter = false) {
|
|
74
75
|
let msg = "Abstract ";
|
|
75
76
|
msg += (getter ? 'getter ' : 'method ');
|
|
76
77
|
if (name) msg += `'${name}' `;
|
|
@@ -80,8 +81,6 @@ class AbstractError extends Error
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
exports.AbstractError = AbstractError;
|
|
84
|
-
|
|
85
84
|
/**
|
|
86
85
|
* Function prototypes for async, generator, and async generator functions.
|
|
87
86
|
* @alias module:@lumjs/core/meta.Functions
|
|
@@ -91,22 +90,20 @@ const Functions =
|
|
|
91
90
|
/**
|
|
92
91
|
* Constructor for dynamic generator functions.
|
|
93
92
|
*/
|
|
94
|
-
Generator: Object.getPrototypeOf(function*(){}).constructor,
|
|
93
|
+
Generator: Object.getPrototypeOf(function* () { }).constructor,
|
|
95
94
|
|
|
96
95
|
/**
|
|
97
96
|
* Constructor for dynamic async functions.
|
|
98
97
|
*/
|
|
99
|
-
Async: Object.getPrototypeOf(async function(){}).constructor,
|
|
98
|
+
Async: Object.getPrototypeOf(async function () { }).constructor,
|
|
100
99
|
|
|
101
100
|
/**
|
|
102
101
|
* Constructor for dynamic async generator functions.
|
|
103
102
|
*/
|
|
104
|
-
AsyncGenerator: Object.getPrototypeOf(async function*(){}).constructor,
|
|
103
|
+
AsyncGenerator: Object.getPrototypeOf(async function* () { }).constructor,
|
|
105
104
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
exports.Functions = Functions;
|
|
109
|
-
|
|
110
107
|
/**
|
|
111
108
|
* A placeholder function for when something is not implemented.
|
|
112
109
|
*
|
|
@@ -117,54 +114,134 @@ exports.Functions = Functions;
|
|
|
117
114
|
* @returns {void}
|
|
118
115
|
* @alias module:@lumjs/core/meta.NYI
|
|
119
116
|
*/
|
|
120
|
-
function NYI(fatal=true, prefix='')
|
|
121
|
-
|
|
122
|
-
const msg = prefix+"« NOT YET IMPLEMENTED »";
|
|
117
|
+
function NYI(fatal = true, prefix = '') {
|
|
118
|
+
const msg = prefix + "« NOT YET IMPLEMENTED »";
|
|
123
119
|
if (fatal)
|
|
124
120
|
throw new Error(msg);
|
|
125
121
|
else
|
|
126
122
|
console.error(msg);
|
|
127
123
|
}
|
|
128
124
|
|
|
129
|
-
|
|
125
|
+
function defaultDeprecateItemHandler(item) {
|
|
126
|
+
let { depVar } = this.opts;
|
|
127
|
+
if (depVar && typeof item === 'string') {
|
|
128
|
+
return item.trim().replaceAll(depVar, this.dep);
|
|
129
|
+
}
|
|
130
|
+
else if (this.setOpts && isObj(item)) {
|
|
131
|
+
cp(this.opts, item);
|
|
132
|
+
return this.next = true;
|
|
133
|
+
}
|
|
134
|
+
return item;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const DEP_OPTS =
|
|
138
|
+
{
|
|
139
|
+
depVar: '{DEP}',
|
|
140
|
+
handle: defaultDeprecateItemHandler,
|
|
141
|
+
preDep: '[DEPRECATED]:',
|
|
142
|
+
}
|
|
130
143
|
|
|
131
144
|
/**
|
|
132
|
-
* Send a deprecation message to the console.
|
|
145
|
+
* Send a deprecation message to the console (low-level).
|
|
133
146
|
*
|
|
134
|
-
* Will default to using `console.warn()` to send the message,
|
|
135
|
-
*
|
|
136
|
-
*
|
|
147
|
+
* Will default to using `console.warn()` to send the message, however
|
|
148
|
+
* it can be made to use `console.trace()` instead if one of the following
|
|
149
|
+
* evaluates to a true value:
|
|
150
|
+
* - `core.env.get('LUM_TRACE_DEPRECATED')`
|
|
151
|
+
* - `core.state.get('core.traceDeprecated')`
|
|
152
|
+
* As the state module is deprecated, as of 2.x only the env.get() test
|
|
153
|
+
* will continue to work.
|
|
137
154
|
*
|
|
138
|
-
* @param {string} dep - Name of what is deprecated
|
|
139
|
-
* @param {
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
155
|
+
* @param {string} dep - Name of what is deprecated.
|
|
156
|
+
* @param {...mixed} [info] Additional information.
|
|
157
|
+
*
|
|
158
|
+
* This may be used to suggest replacements, or whatever other
|
|
159
|
+
* information you want to include in the logs.
|
|
160
|
+
*
|
|
161
|
+
* TODO: document how functions are handled.
|
|
143
162
|
*/
|
|
144
|
-
function
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
163
|
+
function deprecate(dep, ...info) {
|
|
164
|
+
|
|
165
|
+
let stateLib = require('./state');
|
|
166
|
+
let fn = stateLib.eors('LUM_TRACE_DEPRECATED', 'core.traceDeprecated')
|
|
167
|
+
? 'trace'
|
|
148
168
|
: 'warn';
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
|
|
170
|
+
let ctx = {
|
|
171
|
+
add: true,
|
|
172
|
+
dep,
|
|
173
|
+
done: false,
|
|
174
|
+
info,
|
|
175
|
+
logs: [],
|
|
176
|
+
next: false,
|
|
177
|
+
opts: cp({showDep: dep}, DEP_OPTS),
|
|
178
|
+
setOpts: true,
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (let item of info) {
|
|
182
|
+
if (typeof item === 'function') {
|
|
183
|
+
item.call(ctx, ctx);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
if (typeof ctx.opts.handle === 'function') {
|
|
187
|
+
ctx.next = false;
|
|
188
|
+
item = ctx.opts.handle.call(ctx, item, ctx);
|
|
189
|
+
if (ctx.next) continue; // Move on.
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (ctx.add) {
|
|
193
|
+
if (ctx.logs.length === 0 && ctx.opts.preDep) {
|
|
194
|
+
ctx.logs.push(ctx.opts.preDep);
|
|
195
|
+
}
|
|
196
|
+
ctx.logs.push(ctx.opts.showDep || ctx.dep || dep);
|
|
197
|
+
ctx.add = false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (item) {
|
|
201
|
+
ctx.logs.push(item);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (ctx.done) break; // No more items, we're done.
|
|
153
205
|
}
|
|
154
|
-
|
|
155
|
-
|
|
206
|
+
|
|
207
|
+
console[fn](...ctx.logs);
|
|
208
|
+
return ctx.return ?? ctx.opts.return;
|
|
156
209
|
}
|
|
157
210
|
|
|
158
|
-
|
|
211
|
+
const DED_OPTS =
|
|
212
|
+
{
|
|
213
|
+
preRep: 'replace with',
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Send a deprecation message to the console (simple).
|
|
218
|
+
*
|
|
219
|
+
* This is now a frontend to the newer `deprecate()` function,
|
|
220
|
+
* which may replace it entirely one day.
|
|
221
|
+
*
|
|
222
|
+
* @param {string} dep - Name of what is deprecated.
|
|
223
|
+
* @param {?(string|string[])} [rep] Replacement suggestion(s).
|
|
224
|
+
* @param {mixed} [ret] Value to return
|
|
225
|
+
* @param {object} [opts] Formatting options.
|
|
226
|
+
*
|
|
227
|
+
* @returns {mixed} `ret`
|
|
228
|
+
* @alias module:@lumjs/core/meta.deprecated
|
|
229
|
+
*/
|
|
230
|
+
function deprecated(dep, rep, ret, opts) {
|
|
231
|
+
opts = cp({}, DED_OPTS, opts);
|
|
232
|
+
rep = Array.isArray(rep) ? rep.slice(0) : [rep];
|
|
233
|
+
if (opts.preRep) rep.unshift(opts.preRep);
|
|
234
|
+
return deprecate(dep, opts, ...rep);
|
|
235
|
+
}
|
|
159
236
|
|
|
160
237
|
/**
|
|
161
238
|
* Assign a getter property that when accessed will
|
|
162
239
|
* show a deprecation message via `deprecated()` function
|
|
163
240
|
* before returning the deprecated property value.
|
|
164
241
|
*
|
|
165
|
-
* @param {object} obj - Target to assign property on
|
|
166
|
-
* @param {string} prop - Property to assign
|
|
167
|
-
* @param {(object|function)} spec - Specification
|
|
242
|
+
* @param {(object|function)} obj - Target to assign property on.
|
|
243
|
+
* @param {(string|symbol)} prop - Property to assign.
|
|
244
|
+
* @param {(object|function)} spec - Specification.
|
|
168
245
|
*
|
|
169
246
|
* If this is a `function` it will be used as the `spec.get` value.
|
|
170
247
|
*
|
|
@@ -172,29 +249,154 @@ exports.deprecated = deprecated;
|
|
|
172
249
|
* @param {string} [spec.dep=prop] Name of what is deprecated;
|
|
173
250
|
* defaults to `prop` if omitted.
|
|
174
251
|
* @param {(string|string[])} [spec.rep] Replacement suggestion(s).
|
|
175
|
-
* @param {object} [spec.opts] Options for `def()` to add getter with.
|
|
176
|
-
*
|
|
177
252
|
* @returns {object} `obj`
|
|
178
253
|
*
|
|
179
254
|
* @alias module:@lumjs/core/meta.wrapDepr
|
|
180
255
|
*/
|
|
181
|
-
function wrapDepr(obj,prop,spec)
|
|
182
|
-
{
|
|
256
|
+
function wrapDepr(obj, prop, spec) {
|
|
183
257
|
if (typeof spec === 'function')
|
|
184
|
-
spec = {get: spec};
|
|
185
|
-
if (typeof spec.get !== 'function')
|
|
258
|
+
spec = { get: spec };
|
|
259
|
+
if (typeof spec.get !== 'function')
|
|
186
260
|
throw new TypeError("invalid init");
|
|
187
261
|
|
|
188
|
-
|
|
189
|
-
{
|
|
190
|
-
|
|
191
|
-
deprecated(spec.dep??prop, spec.rep, spec.get())
|
|
192
|
-
}
|
|
262
|
+
let getter;
|
|
263
|
+
if (spec.rep) { // Original style using deprecated() function.
|
|
264
|
+
getter = () =>
|
|
265
|
+
deprecated(spec.dep ?? prop, spec.rep, spec.get(), spec)
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
getter = () => {
|
|
269
|
+
let info = Array.isArray(spec.info) ? spec.info.slice(0) : [];
|
|
270
|
+
return deprecate(spec.dep ?? prop, {return: spec.get()}, spec, ...info);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return dp(obj, prop, {
|
|
275
|
+
configurable: true,
|
|
276
|
+
get: getter,
|
|
277
|
+
});
|
|
193
278
|
}
|
|
194
279
|
|
|
195
|
-
exports
|
|
280
|
+
wrapDepr(exports, 'AbstractClass', () => require('./old/abstractclass'));
|
|
196
281
|
|
|
197
|
-
|
|
198
|
-
const
|
|
282
|
+
const FUN_RESERVED = new Set(['prototype', 'length', 'name']);
|
|
283
|
+
const FUN_FILTER = (key) => !FUN_RESERVED.has(key);
|
|
199
284
|
|
|
200
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Deprecate an entire module.
|
|
287
|
+
*
|
|
288
|
+
* This will use `getOwnKeys()` to get a list of properties in a module,
|
|
289
|
+
* and will create a wrapped version that will use `wrapDepr()` for each
|
|
290
|
+
* of the properties.
|
|
291
|
+
*
|
|
292
|
+
* @param {(object|function)} src - The exported module.
|
|
293
|
+
*
|
|
294
|
+
* If this is a function, a wrapped version that calls deprecated()
|
|
295
|
+
* before passing all arguments will be created. It will also use
|
|
296
|
+
* the name of the function as a default `basespec.dep` value.
|
|
297
|
+
*
|
|
298
|
+
* @param {(object|string)} [basespec] Base specification.
|
|
299
|
+
*
|
|
300
|
+
* If this is a string it will be used as the `basespec.dep` option.
|
|
301
|
+
*
|
|
302
|
+
* Properties in this will be used as the defaults for the `spec` for each
|
|
303
|
+
* property in the `src` when calling the `wrapDepr()` function, with the
|
|
304
|
+
* exception of `dep` (see below for how it is handled), and `get` which
|
|
305
|
+
* is generated automatically for each property.
|
|
306
|
+
*
|
|
307
|
+
* @param {string} [basespec.dep] The name of the module being deprecated.
|
|
308
|
+
*
|
|
309
|
+
* If this is specified as a non-empty string then the spec for each property
|
|
310
|
+
* will use `{dep: basespec.dep+sep+key}`; otherwise it will use `key` alone.
|
|
311
|
+
*
|
|
312
|
+
* @param {function} [basespec.filter] Filter the properties.
|
|
313
|
+
*
|
|
314
|
+
* If this is specified it will be passed to `keys.filter()` to filter
|
|
315
|
+
* the keys that will actually be created in the destination object.
|
|
316
|
+
*
|
|
317
|
+
* If `src` is a *function*, and this is NOT specified, then a *default*
|
|
318
|
+
* will be used that excludes `[prototype, length, name]` from the keys.
|
|
319
|
+
*
|
|
320
|
+
* There is NO default when `src` is an *object*.
|
|
321
|
+
*
|
|
322
|
+
* @param {string} [basespec.sep] Value to use as `sep` (see `basespec.dep`).
|
|
323
|
+
*
|
|
324
|
+
* The default is a single dot (`.`) character.
|
|
325
|
+
*
|
|
326
|
+
* @param {object} [dest] Object to add wrapped properties to.
|
|
327
|
+
*
|
|
328
|
+
* This is only applicable if `src` is an *object*.
|
|
329
|
+
* It will NOT be used when `src` is a *function*.
|
|
330
|
+
* If not specified, an empty object will be created.
|
|
331
|
+
*
|
|
332
|
+
* @returns {(object|function)} Return value depends on the type of `src`.
|
|
333
|
+
*/
|
|
334
|
+
function deprecateAll(src, basespec, dest = {}) {
|
|
335
|
+
if (typeof basespec === 'string') {
|
|
336
|
+
basespec = cp({ dep: basespec }, DED_OPTS);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
basespec = cp({}, DED_OPTS, basespec);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
let hasName = () =>
|
|
343
|
+
(typeof basespec.dep === 'string' && basespec.dep.trim() !== '');
|
|
344
|
+
|
|
345
|
+
let getInfo = (spec) => {
|
|
346
|
+
let info = Array.isArray(spec.info)
|
|
347
|
+
? spec.info.slice(0)
|
|
348
|
+
: [];
|
|
349
|
+
if (spec.rep) {
|
|
350
|
+
info.push(spec.rep);
|
|
351
|
+
delete spec.rep;
|
|
352
|
+
}
|
|
353
|
+
return info;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
let keys = getOwnKeys(src);
|
|
357
|
+
let sep = basespec.sep ?? '.';
|
|
358
|
+
|
|
359
|
+
if (typeof src === 'function') {
|
|
360
|
+
if (!hasName()) basespec.dep = src.name;
|
|
361
|
+
if (!basespec.filter) basespec.filter = FUN_FILTER;
|
|
362
|
+
|
|
363
|
+
dest = function () {
|
|
364
|
+
let fun = {src, arguments};
|
|
365
|
+
let spec = cp({}, basespec, {fun});
|
|
366
|
+
let info = getInfo(spec);
|
|
367
|
+
deprecate(spec.dep, spec, ...info);
|
|
368
|
+
return src.apply(this, arguments);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (typeof basespec.filter === 'function') {
|
|
373
|
+
keys = keys.filter(basespec.filter);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
hasName = hasName(); // finalise
|
|
377
|
+
|
|
378
|
+
for (let key of keys) {
|
|
379
|
+
//let dep = hasName ? basespec.dep + sep + keyName(key) : key;
|
|
380
|
+
let spec = cp({}, basespec, {
|
|
381
|
+
dep: key,
|
|
382
|
+
get: () => src[key],
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
if (hasName) {
|
|
386
|
+
spec.info = getInfo(spec);
|
|
387
|
+
if (basespec.preRep) spec.info.unshift(basespec.preRep);
|
|
388
|
+
spec.showDep = basespec.dep + sep + keyName(key);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
wrapDepr(dest, key, spec);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return dest;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
cp(deprecateAll, {FUN_FILTER, FUN_RESERVED});
|
|
398
|
+
|
|
399
|
+
exports = module.exports = {
|
|
400
|
+
AbstractError, deprecate, deprecated, deprecateAll, Functions,
|
|
401
|
+
NYI, stacktrace, wrapDepr,
|
|
402
|
+
}
|
package/lib/obj/apply.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const {F} = require('../types');
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* ApplyInfo objects will have a property with this Symbol
|
|
5
3
|
* as its key and boolean `true` as its value.
|
|
@@ -208,7 +206,7 @@ function apply(target, ...values)
|
|
|
208
206
|
|
|
209
207
|
for (let value of values)
|
|
210
208
|
{
|
|
211
|
-
if (typeof value ===
|
|
209
|
+
if (typeof value === 'function')
|
|
212
210
|
{
|
|
213
211
|
value.apply(opts.ctx, opts.args);
|
|
214
212
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const getProperty = require('./getproperty.js');
|
|
4
|
+
const getPrototypeOf = require('./getprotos.js');
|
|
5
|
+
const { getOwnKeys, isEmptyObject, keyName } = require('./keys.js');
|
|
6
|
+
const ownCount = require('./owncount.js');
|
|
7
|
+
const unlocked = require('./unlocked.js');
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
getOwnKeys, getProperty, getPrototypeOf, keyName, isEmptyObject,
|
|
11
|
+
ownCount, unlocked,
|
|
12
|
+
}
|
package/lib/obj/cp.js
CHANGED
package/lib/obj/df.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {doesDescriptor} = require('../types/basics');
|
|
4
4
|
const {needObj,needType} = require('../types/needs');
|
|
5
5
|
const TYPES = require('../types/typelist');
|
|
6
6
|
|
|
@@ -67,8 +67,8 @@ function descriptor(desc, opts)
|
|
|
67
67
|
|
|
68
68
|
for (const dp of dps)
|
|
69
69
|
{
|
|
70
|
-
if (typeof opts[dp] ===
|
|
71
|
-
&& (force.includes(dp) || typeof desc[dp] !==
|
|
70
|
+
if (typeof opts[dp] === 'boolean'
|
|
71
|
+
&& (force.includes(dp) || typeof desc[dp] !== 'boolean'))
|
|
72
72
|
{
|
|
73
73
|
desc[dp] = opts[dp];
|
|
74
74
|
}
|
|
@@ -122,11 +122,11 @@ function df(obj, name, value, opts={})
|
|
|
122
122
|
needObj(obj, {log, fun: true});
|
|
123
123
|
needType(TYPES.PROP, name, {log});
|
|
124
124
|
|
|
125
|
-
if (typeof opts ===
|
|
125
|
+
if (typeof opts === 'boolean')
|
|
126
126
|
{
|
|
127
127
|
opts = {useDesc: opts};
|
|
128
128
|
}
|
|
129
|
-
else if (typeof opts ===
|
|
129
|
+
else if (typeof opts === 'function' && typeof value === 'function')
|
|
130
130
|
{
|
|
131
131
|
value = {get: value, set: opts};
|
|
132
132
|
opts = {useDesc: true};
|
|
@@ -220,7 +220,7 @@ function dfor(obj, opts={}, prev=null)
|
|
|
220
220
|
{
|
|
221
221
|
const fnOne = function (name, value, setter)
|
|
222
222
|
{
|
|
223
|
-
if (typeof setter ===
|
|
223
|
+
if (typeof setter === 'function' && typeof value === 'function')
|
|
224
224
|
{
|
|
225
225
|
value = {get: value, set: setter}
|
|
226
226
|
opts = clone(opts, {useDesc: true});
|
|
@@ -334,7 +334,7 @@ function lazy(target, name, initfunc, opts={})
|
|
|
334
334
|
let log = {target, name, initfunc, opts};
|
|
335
335
|
needObj(target, {log, fun: true});
|
|
336
336
|
needType(TYPES.PROP, name, {log});
|
|
337
|
-
needType(
|
|
337
|
+
needType('function', initfunc, {log});
|
|
338
338
|
needObj(opts, {log});
|
|
339
339
|
|
|
340
340
|
// The `this` object for the functions.
|
|
@@ -367,7 +367,7 @@ function lazy(target, name, initfunc, opts={})
|
|
|
367
367
|
}
|
|
368
368
|
else if (doesDescriptor(value))
|
|
369
369
|
{ // A descriptor was returned, extract the real value.
|
|
370
|
-
if (typeof value.get ===
|
|
370
|
+
if (typeof value.get === 'function')
|
|
371
371
|
{
|
|
372
372
|
return value.get();
|
|
373
373
|
}
|
|
@@ -387,7 +387,7 @@ function lazy(target, name, initfunc, opts={})
|
|
|
387
387
|
return defval(initfunc.call(ctx,ctx));
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
-
if (typeof opts.set ===
|
|
390
|
+
if (typeof opts.set === 'function')
|
|
391
391
|
{ // We want to assign a lazy setter as well.
|
|
392
392
|
desc.set = function(value)
|
|
393
393
|
{
|
package/lib/obj/getproperty.js
CHANGED
package/lib/obj/index.js
CHANGED
|
@@ -5,20 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
const {apply,ApplyInfo,ApplyOpts,ApplyWith} = require('./apply');
|
|
7
7
|
const assignd = require('./assignd');
|
|
8
|
-
const {copyAll,duplicateOne,duplicateAll} = require('./copyall');
|
|
9
|
-
const copyProps = require('./copyprops');
|
|
10
|
-
const {CLONE,clone,addClone,cloneIfLocked} = require('./clone');
|
|
11
8
|
const {df,dfa,dfor,lazy} = require('./df');
|
|
12
9
|
const {flip, flipKeyVal, flipMap} = require('./flip');
|
|
13
10
|
const {getMethods,signatureOf,MethodFilter} = require('./getmethods');
|
|
14
11
|
const getProperty = require('./getproperty');
|
|
15
12
|
const getPrototypesOf = require('./getprotos');
|
|
16
|
-
const {lock,addLock} = require('./lock');
|
|
17
|
-
const {mergeNested,syncNested} = require('./merge');
|
|
18
13
|
const ns = require('./ns');
|
|
19
|
-
const cp = require('./cp');
|
|
20
14
|
const unlocked = require('./unlocked');
|
|
21
15
|
const ownCount = require('./owncount');
|
|
16
|
+
const {getOwnKeys,isEmptyObject} = require('./keys');
|
|
22
17
|
|
|
23
18
|
const
|
|
24
19
|
{
|
|
@@ -26,6 +21,11 @@ const
|
|
|
26
21
|
getNamespace,setNamespace,nsFactory,
|
|
27
22
|
} = ns;
|
|
28
23
|
|
|
24
|
+
// Deprecated functions; TODO: remove in 2.0
|
|
25
|
+
const NSO = '@lumjs/core/obj';
|
|
26
|
+
const { deprecateAll } = require('../meta');
|
|
27
|
+
const cp = deprecateAll(require('./cp'), NSO+'/cp');
|
|
28
|
+
|
|
29
29
|
/**
|
|
30
30
|
* Create a new object with a `null` prototype.
|
|
31
31
|
*
|
|
@@ -43,13 +43,17 @@ const
|
|
|
43
43
|
const discrete = (props) => Object.create(null, props);
|
|
44
44
|
|
|
45
45
|
// TODO: reorder the following alphabetically, for sanity sake...
|
|
46
|
-
module.exports =
|
|
46
|
+
exports = module.exports =
|
|
47
47
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
cp, // TODO: remove this line in 2.0
|
|
49
|
+
|
|
50
|
+
apply, ApplyInfo, ApplyOpts, ApplyWith, assignd,
|
|
51
|
+
delObjectPath, df, dfa, dfor, discrete, flip, flipKeyVal, flipMap,
|
|
52
|
+
getMethods, getNamespace, getObjectPath, getOwnKeys, getProperty,
|
|
53
|
+
getPrototypesOf, isEmptyObject, lazy, MethodFilter, ns, nsFactory,
|
|
54
|
+
ownCount, setNamespace, setObjectPath, signatureOf, unlocked,
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
// Deprecated collections; TODO: remove in 2.0
|
|
58
|
+
deprecateAll(require('@lumjs/cp/fun'), NSO, exports);
|
|
59
|
+
deprecateAll(require('@lumjs/cp/util'), NSO, exports);
|
package/lib/obj/keys.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get both string and symbol keys from an object.
|
|
5
|
+
* @param {object} obj - Target object.
|
|
6
|
+
* @returns {(string|symbol)[]}
|
|
7
|
+
*/
|
|
8
|
+
const getOwnKeys = obj => [
|
|
9
|
+
...(Object.getOwnPropertyNames(obj)),
|
|
10
|
+
...(Object.getOwnPropertySymbols(obj)),
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* See if an object has its own properties.
|
|
15
|
+
*/
|
|
16
|
+
const isEmptyObject = obj => getOwnKeys(obj).length === 0;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get the name of a property key.
|
|
20
|
+
* @param {(string|symbol)} key - Property key.
|
|
21
|
+
*
|
|
22
|
+
* If this is a string it will be returned as-is.
|
|
23
|
+
* If this is a symbol then how it is formatted depends
|
|
24
|
+
* on the options specified.
|
|
25
|
+
*
|
|
26
|
+
* @param {object} [opts] Options for handling symbol property keys.
|
|
27
|
+
* @param {string} [opts.prefix] Prefix character; default: `[`.
|
|
28
|
+
* @param {string} [opts.suffix] Suffix character; default: `]`.
|
|
29
|
+
* @param {boolean} [opts.toStr=false] Use toString method?
|
|
30
|
+
*
|
|
31
|
+
* If this is false (default), then the return value will be the
|
|
32
|
+
* `key.description` value with the prefix and suffix values applied.
|
|
33
|
+
*
|
|
34
|
+
* If this is true then the prefix/suffix options are ignored,
|
|
35
|
+
* and `key.toString()` will be used as the return value.
|
|
36
|
+
*
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function keyName(key, opts={}) {
|
|
40
|
+
if (typeof key === 'string') return key;
|
|
41
|
+
if (typeof key === 'symbol') {
|
|
42
|
+
if (opts.toStr) {
|
|
43
|
+
return key.toString();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let pf = opts.prefix ?? '[';
|
|
47
|
+
let sf = opts.suffix ?? ']';
|
|
48
|
+
return pf+key.description+sf;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.error({key, opts});
|
|
52
|
+
throw new TypeError('Invalid key');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = {getOwnKeys, isEmptyObject, keyName}
|