@lumjs/core 1.38.4 → 1.38.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/lib/context.js +14 -12
- package/lib/env.js +937 -0
- package/lib/index.js +19 -25
- package/lib/meta.js +8 -14
- package/lib/node/index.js +14 -0
- package/lib/{modules.js → node/modules.js} +35 -6
- package/lib/node/package.js +107 -0
- package/lib/obj/apply.js +237 -29
- package/lib/obj/copyall.js +14 -20
- package/lib/obj/copyprops.js +6 -386
- package/lib/obj/cp.js +4 -1370
- package/lib/obj/cycle.js +182 -0
- package/lib/obj/cycle2.js +122 -0
- package/lib/obj/index.js +4 -4
- package/lib/obj/ns/formats.js +300 -0
- package/lib/obj/{ns.js → ns/index.js} +160 -37
- package/lib/objectid.js +236 -71
- package/lib/state.js +30 -45
- package/lib/types/index.js +1 -1
- package/package.json +9 -3
- /package/lib/{types → obj}/owncount.js +0 -0
package/lib/index.js
CHANGED
|
@@ -14,44 +14,38 @@
|
|
|
14
14
|
|
|
15
15
|
const types = require('./types');
|
|
16
16
|
const {df,lazy} = require('./obj/df');
|
|
17
|
+
const meta = require('./meta');
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
function from(submod)
|
|
19
|
+
exports = module.exports =
|
|
20
20
|
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
context: require('./context'),
|
|
22
|
+
def: types.def, // ← TODO: nix in 2.x
|
|
23
|
+
df,
|
|
24
|
+
Enum: require('./enum'),
|
|
25
|
+
env: require('./env'),
|
|
26
|
+
flags: require('./flags'),
|
|
27
|
+
lazy,
|
|
28
|
+
maps: require('./maps'),
|
|
29
|
+
meta,
|
|
30
|
+
...(meta), // ← TODO: nix in 2.x
|
|
31
|
+
...(require('./objectid')),
|
|
32
|
+
// obj: require('./obj'), // ← TODO: uncomment in 2.x
|
|
33
|
+
opt: require('./opt'),
|
|
34
|
+
state: require('./state'),
|
|
35
|
+
strings: require('./strings'),
|
|
36
|
+
types,
|
|
25
37
|
}
|
|
26
38
|
|
|
27
|
-
|
|
28
|
-
df(exports, 'def', types.def);
|
|
29
|
-
df(exports, 'df', df);
|
|
30
|
-
df(exports, 'lazy', lazy);
|
|
31
|
-
|
|
32
|
-
df(exports, 'context', require('./context'));
|
|
33
|
-
df(exports, 'state', {value: require('./state')});
|
|
39
|
+
// ↓ TODO: nix everything below here in 2.x
|
|
34
40
|
|
|
35
|
-
// ObjectID stuff is imported directly without registering a sub-module.
|
|
36
|
-
from(require('./objectid'));
|
|
37
|
-
|
|
38
|
-
// These are exported directly, but a meta sub-module also exists.
|
|
39
|
-
const meta = require('./meta');
|
|
40
|
-
from(meta);
|
|
41
|
-
df(exports, 'meta', meta);
|
|
42
41
|
df(exports, 'AbstractClass',
|
|
43
42
|
{
|
|
44
43
|
get() { return meta.AbstractClass; }
|
|
45
44
|
});
|
|
46
45
|
|
|
47
46
|
lazy(exports, 'arrays', () => require('./arrays'));
|
|
48
|
-
lazy(exports, 'maps', () => require('./maps'));
|
|
49
|
-
lazy(exports, 'strings', () => require('./strings'));
|
|
50
|
-
lazy(exports, 'flags', () => require('./flags'));
|
|
51
47
|
lazy(exports, 'obj', () => require('./obj'));
|
|
52
48
|
lazy(exports, 'console', () => require('./console'));
|
|
53
49
|
lazy(exports, 'traits', () => require('./traits'));
|
|
54
|
-
lazy(exports, 'opt', () => require('./opt'), {df:{autoDesc: false}});
|
|
55
|
-
lazy(exports, 'Enum', () => require('./enum'));
|
|
56
50
|
lazy(exports, 'observable', () => require('./observable'));
|
|
57
51
|
lazy(exports, 'events', () => require('./events'));
|
package/lib/meta.js
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
|
-
* Meta-programming helpers
|
|
4
|
-
*
|
|
5
|
-
* All of the function exported by this module are also available
|
|
6
|
-
* in the main {@link module:@lumjs/core core object} itself.
|
|
7
|
-
*
|
|
2
|
+
* Meta-programming helpers.
|
|
8
3
|
* @module @lumjs/core/meta
|
|
9
4
|
*/
|
|
10
|
-
|
|
11
|
-
const {F} = require('./types/js');
|
|
5
|
+
'use strict';
|
|
12
6
|
|
|
13
7
|
/**
|
|
14
|
-
* Get a stacktrace.
|
|
8
|
+
* Get a stacktrace.
|
|
15
9
|
*
|
|
16
10
|
* Uses the `stack` property of an `Error` object as the source.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
11
|
+
* Every runtime differs greatly in what is contained in the `stack` text,
|
|
12
|
+
* so this may not be particularly useful. For a more complete solution,
|
|
13
|
+
* try the `stacktrace-js` library.
|
|
20
14
|
*
|
|
21
15
|
* @param {string} [msg] - A message for the Error object.
|
|
22
16
|
*
|
|
@@ -186,9 +180,9 @@ exports.deprecated = deprecated;
|
|
|
186
180
|
*/
|
|
187
181
|
function wrapDepr(obj,prop,spec)
|
|
188
182
|
{
|
|
189
|
-
if (typeof spec ===
|
|
183
|
+
if (typeof spec === 'function')
|
|
190
184
|
spec = {get: spec};
|
|
191
|
-
if (typeof spec.get !==
|
|
185
|
+
if (typeof spec.get !== 'function')
|
|
192
186
|
throw new TypeError("invalid init");
|
|
193
187
|
|
|
194
188
|
return df(obj, prop,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A module namespace for NodeJS specific features.
|
|
3
|
+
*
|
|
4
|
+
* This is currently mostly a placeholder for future development.
|
|
5
|
+
*
|
|
6
|
+
* @module @lumjs/core/node
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
module.exports =
|
|
11
|
+
{
|
|
12
|
+
modules: require('./modules'),
|
|
13
|
+
Package: require('./package'),
|
|
14
|
+
}
|
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Module helpers.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* `@lumjs/core/modules` is a deprecated alias to this.
|
|
5
|
+
*
|
|
6
|
+
* @module @lumjs/core/node/modules
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
9
|
const path = require('path');
|
|
7
|
-
const {S,isObj} = require('
|
|
8
|
-
const replace = require('
|
|
10
|
+
const {S,isObj} = require('../types');
|
|
11
|
+
const replace = require('../strings').replaceItems;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Test if a passed value is a CommonJS `module` object.
|
|
15
|
+
* @param {*} mod - Value to test.
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
* @alias module:@lumjs/core/node/modules.isCJS
|
|
18
|
+
*/
|
|
19
|
+
const isCJS = (mod) => (isObj(mod)
|
|
20
|
+
&& typeof mod.id === 'string'
|
|
21
|
+
&& typeof mod.require === 'function'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Test if a passed value is an ES Module `import.meta` object.
|
|
26
|
+
* @param {*} mod - Value to test.
|
|
27
|
+
* @returns {boolean}
|
|
28
|
+
* @alias module:@lumjs/core/node/modules.isESM
|
|
29
|
+
*/
|
|
30
|
+
const isESM = (mod) => (isObj(mod)
|
|
31
|
+
&& typeof mod.url === 'string'
|
|
32
|
+
&& typeof mod.resolve === 'function'
|
|
33
|
+
);
|
|
9
34
|
|
|
10
35
|
/**
|
|
11
36
|
* Get the name of a module.
|
|
@@ -41,9 +66,13 @@ function name(module, opts={})
|
|
|
41
66
|
{ // Going to assume a string is the filename.
|
|
42
67
|
filename = module;
|
|
43
68
|
}
|
|
44
|
-
else if (
|
|
69
|
+
else if (isCJS(module))
|
|
45
70
|
{ // It's a CommonJS module context object.
|
|
46
|
-
filename = module.filename;
|
|
71
|
+
filename = module.filename ?? module.id;
|
|
72
|
+
}
|
|
73
|
+
else if (isESM(module))
|
|
74
|
+
{ // It's an ES Module metadata (import.meta) object.
|
|
75
|
+
filename = module.filename ?? path.basename(module.url);
|
|
47
76
|
}
|
|
48
77
|
else
|
|
49
78
|
{ // Sorry, we don't support that.
|
|
@@ -110,4 +139,4 @@ function name(module, opts={})
|
|
|
110
139
|
return filename;
|
|
111
140
|
}
|
|
112
141
|
|
|
113
|
-
exports
|
|
142
|
+
module.exports = { name, isCJS, isESM }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const semver = require('semver');
|
|
4
|
+
const PKGJSON = '/package.json';
|
|
5
|
+
|
|
6
|
+
function validate(pkgid, autoAppend)
|
|
7
|
+
{
|
|
8
|
+
if (typeof pkgid !== 'string')
|
|
9
|
+
{
|
|
10
|
+
throw new TypeError("package id must be a string");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (autoAppend && !pkgid.endsWith(PKGJSON))
|
|
14
|
+
{
|
|
15
|
+
pkgid += PKGJSON;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return pkgid;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A wrapper class around package.json data that provides some version
|
|
23
|
+
* related helper methods.
|
|
24
|
+
* @exports @lumjs/core/node.Package
|
|
25
|
+
*/
|
|
26
|
+
class Package
|
|
27
|
+
{
|
|
28
|
+
/**
|
|
29
|
+
* Build a Package instance.
|
|
30
|
+
*
|
|
31
|
+
* This requires that you've already loaded and parsed a package.json file.
|
|
32
|
+
* See the require() and import() static methods which take a package name,
|
|
33
|
+
* and expect that the package has a `/package.json` export defined.
|
|
34
|
+
*
|
|
35
|
+
* @param {object} pkginfo - Data parsed from a package.json file.
|
|
36
|
+
*/
|
|
37
|
+
constructor(pkginfo)
|
|
38
|
+
{
|
|
39
|
+
/**
|
|
40
|
+
* The package.json data.
|
|
41
|
+
* @type {object}
|
|
42
|
+
*/
|
|
43
|
+
this.info = pkginfo;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A `SemVer` instance (from the `semver` package) parsed from
|
|
47
|
+
* the `version` property of the package.json data.
|
|
48
|
+
* @type {object}
|
|
49
|
+
*/
|
|
50
|
+
this.version = semver.parse(this.info.version);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* See if the package version satisfies a range statement.
|
|
55
|
+
* @param {string} range - A semver range statement.
|
|
56
|
+
* @param {object} [options] Options; see semver documentation.
|
|
57
|
+
*/
|
|
58
|
+
satisfies(range, options)
|
|
59
|
+
{
|
|
60
|
+
return semver.satisfies(this.version, range, options);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Build a Package instance using require() to load a package.json file.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} pkgid - Package id.
|
|
67
|
+
*
|
|
68
|
+
* Assuming the package exports it's package.json as `/package.json` you
|
|
69
|
+
* can simply pass the plain package name here (e.g. `@lumjs/core`).
|
|
70
|
+
*
|
|
71
|
+
* @param {boolean} [autoAppend=true] Auto-append `/package.json` to pkgid?
|
|
72
|
+
*
|
|
73
|
+
* If this is true (it is by default) and `pkgid` does NOT end in
|
|
74
|
+
* `/package.json`, it will be automatically appended before passing
|
|
75
|
+
* to require(). If for whatever reason the actual sub-module breaks the
|
|
76
|
+
* expected naming convention, you'll need to pass the full sub-module
|
|
77
|
+
* path as the `pkgid` and set this argument to false.
|
|
78
|
+
*
|
|
79
|
+
* @returns {module:@lumjs/core/node.Package}
|
|
80
|
+
* @throws {TypeError} If `pkgid` is not a string.
|
|
81
|
+
* @throws {Error} If the package.json can not be loaded.
|
|
82
|
+
*/
|
|
83
|
+
static require(pkgid, autoAppend=true)
|
|
84
|
+
{
|
|
85
|
+
let pkginfo = require(validate(pkgid, autoAppend));
|
|
86
|
+
return new this(pkginfo);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Build a Package instance using import() to load a package.json file.
|
|
91
|
+
*
|
|
92
|
+
* All arguments are handled exactly the same as the require() method.
|
|
93
|
+
* The only difference is import() is asynchronous, so this will return
|
|
94
|
+
* a Promise that will resolve to the new Package instance.
|
|
95
|
+
*
|
|
96
|
+
* @param {string} pkgid
|
|
97
|
+
* @param {boolean} [autoAppend=true]
|
|
98
|
+
* @returns {Promise<module:@lumjs/core/node.Package>}
|
|
99
|
+
*/
|
|
100
|
+
static async import(pkgid, autoAppend=true)
|
|
101
|
+
{
|
|
102
|
+
let pkginfo = await import(validate(pkgid, autoAppend));
|
|
103
|
+
return new this(pkginfo);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = Package;
|
package/lib/obj/apply.js
CHANGED
|
@@ -1,52 +1,260 @@
|
|
|
1
|
-
const {F
|
|
2
|
-
const copyProps = require('./copyprops');
|
|
1
|
+
const {F} = require('../types');
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* In addition to the parameters passed, we'll also define:
|
|
4
|
+
* ApplyInfo objects will have a property with this Symbol
|
|
5
|
+
* as its key and boolean `true` as its value.
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
* - `args` will be an array of `[obj, opts]`;
|
|
11
|
-
* - `opts` will be an object of `{obj, cp, args}`;
|
|
7
|
+
* The `apply.Info` property is an alias to this.
|
|
12
8
|
*
|
|
13
|
-
* @
|
|
9
|
+
* @type {Symbol}
|
|
10
|
+
* @name module:@lumjs/core/obj.ApplyInfo
|
|
11
|
+
*/
|
|
12
|
+
const ApplyInfo = Symbol('@lumjs/core/obj.ApplyInfo');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ApplyOpts objects will have a property with this Symbol
|
|
16
|
+
* as its key and boolean `true` as its value.
|
|
14
17
|
*
|
|
15
|
-
*
|
|
18
|
+
* The `apply.Opts` property is an alias to this.
|
|
19
|
+
*
|
|
20
|
+
* @type {Symbol}
|
|
21
|
+
* @name module:@lumjs/core/obj.ApplyOpts
|
|
22
|
+
*/
|
|
23
|
+
const ApplyOpts = Symbol('@lumjs/core/obj.ApplyOpts');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Options for apply() functions and value handlers.
|
|
27
|
+
* @typedef {object} module:@lumjs/core/obj~ApplyOpts
|
|
28
|
+
* @prop {(object|function)} target - Target object.
|
|
29
|
+
* @prop {(object|function)} obj - DEPRECATED alias of `target`.
|
|
30
|
+
* @prop {(object|function)} ctx - Context (`this`) for functions.
|
|
31
|
+
* Set to `target` when opts are initially created.
|
|
32
|
+
* @prop {Set<module:@lumjs/core/obj~ApplyHandler>} handlers
|
|
33
|
+
* Registered value handlers.
|
|
34
|
+
* @prop {Array} args - Arguments passed to `function` values.
|
|
16
35
|
*
|
|
17
|
-
*
|
|
36
|
+
* In v1.x this defaults to `[target, opts]`.
|
|
37
|
+
* In v2.x this will default to `[opts]`.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Info for apply() value handlers.
|
|
42
|
+
* @typedef {object} module:@lumjs/core/obj~ApplyInfo
|
|
43
|
+
* @prop {mixed} value - The value that needs to be handled.
|
|
44
|
+
* @prop {object} opts - The current apply() options.
|
|
45
|
+
* @prop {boolean} ok - If a handler can handle `value` it must set
|
|
46
|
+
* this to `true` indicating the value has been handled.
|
|
47
|
+
* Otherwise apply() will throw a TypeError if every handler has
|
|
48
|
+
* been called and none can handle the value.
|
|
49
|
+
* @prop {boolean} done - If a handler has handled a value it may
|
|
50
|
+
* set this to `true` to indicate that no further handlers need
|
|
51
|
+
* to be called for that value. If this property is true then
|
|
52
|
+
* the `ok` property will automatically be considered true as well.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* An apply() value handler.
|
|
18
57
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
58
|
+
* In order to add a handler it must be added to `opts.handlers` using a
|
|
59
|
+
* registration function. You can make a handler that can register itself
|
|
60
|
+
* by checking the argument(s) for the `ApplyInfo` or `ApplyOpts` properties.
|
|
61
|
+
*
|
|
62
|
+
* An example for the upcoming v2.x default arguments:
|
|
63
|
+
*
|
|
64
|
+
* ```js
|
|
65
|
+
* const {apply} = require('@lumjs/core/obj');
|
|
66
|
+
* function myHandler(info)
|
|
67
|
+
* {
|
|
68
|
+
* if (info[apply.Opts])
|
|
69
|
+
* { // Registration (info is opts).
|
|
70
|
+
* info.handlers.add(myHandler);
|
|
71
|
+
* }
|
|
72
|
+
* else if (info[apply.Info])
|
|
73
|
+
* { // Handler call.
|
|
74
|
+
* if (someTest(info.value))
|
|
75
|
+
* { // Code to handle the value would be here.
|
|
76
|
+
* info.ok = true;
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* // Then to use the handler:
|
|
82
|
+
* apply(myObj, myHandler, ...valuesToApply);
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Support for the v1.x default arguments (or even custom arguments),
|
|
86
|
+
* and dealing with invalid arguments is left up to your imagination.
|
|
87
|
+
*
|
|
88
|
+
* @callback module:@lumjs/core/obj~ApplyHandler
|
|
89
|
+
* @param {module:@lumjs/core/obj~ApplyHandlerInfo} info
|
|
90
|
+
* @returns {void} No return value is required or used.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Some pre-defined value handlers and registration functions.
|
|
95
|
+
* @type {object}
|
|
96
|
+
* @alias module:@lumjs/core/obj.ApplyWith
|
|
97
|
+
*/
|
|
98
|
+
const ApplyWith =
|
|
99
|
+
{
|
|
100
|
+
/**
|
|
101
|
+
* A value handler for obj.apply() that uses `cp` to handle objects.
|
|
102
|
+
*
|
|
103
|
+
* This is a self-registering handler designed for @lumjs/core v2.x.
|
|
104
|
+
* Just pass it as a function value to apply() and it will add itself to
|
|
105
|
+
* `opts.handlers`, set `opts.cp` to `copyProps.cache.into(opts.target)`,
|
|
106
|
+
* and `opts.cp.applyDone` to `true`.
|
|
107
|
+
*
|
|
108
|
+
* This is automatically registered in v1.x. No need to manually add it.
|
|
109
|
+
*
|
|
110
|
+
* For any `object` value passed to apply() after registering this handler,
|
|
111
|
+
* it will call: `opts.cp.from(value)` to merge the value's properties into
|
|
112
|
+
* the target object. Finally it will set `info.ok` to `true` (fixed value),
|
|
113
|
+
* and `info.done` to `opts.cp.applyDone`.
|
|
114
|
+
*
|
|
115
|
+
* It does not handle anything other than `object` values.
|
|
116
|
+
*
|
|
117
|
+
* NOTE: As of v1.38.5 this is an alias to `@lumjs/cp/apply.Handler`
|
|
118
|
+
*
|
|
119
|
+
* @function module:@lumjs/obj.ApplyWith.cpHandler
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* A helper for registration functions that may have the `opts`
|
|
124
|
+
* passed in different argument positions.
|
|
125
|
+
* @param {Iterable} args - Arguments passed to function.
|
|
126
|
+
* @param {mixed} ctx - The value of `this` in the function.
|
|
127
|
+
* In case `opts.ctx`
|
|
128
|
+
* @returns {?module:@lumjs/core/obj~ApplyOpts}
|
|
129
|
+
* Will be null if no ApplyOpts object could be found in the arguments.
|
|
130
|
+
*/
|
|
131
|
+
getOpts(args)
|
|
132
|
+
{
|
|
133
|
+
for (let arg of args)
|
|
134
|
+
{
|
|
135
|
+
if (arg && arg[ApplyOpts]) return arg;
|
|
136
|
+
}
|
|
137
|
+
// No opts found.
|
|
138
|
+
return null;
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A registration function that sets `opts.args` to `[opts.target, opts]`
|
|
143
|
+
* which is the default arguments for @lumjs/core v1.x.
|
|
144
|
+
*/
|
|
145
|
+
v1Args()
|
|
146
|
+
{
|
|
147
|
+
let opts = ApplyInfo.getOpts(arguments);
|
|
148
|
+
if (opts)
|
|
149
|
+
{
|
|
150
|
+
opts.args = [opts.target, opts];
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A registration function that sets `opts.args` to `[opts]`
|
|
156
|
+
* which is the default arguments for @lumjs/core v2.x.
|
|
157
|
+
*/
|
|
158
|
+
v2Args()
|
|
159
|
+
{
|
|
160
|
+
let opts = ApplyInfo.getOpts(arguments);
|
|
161
|
+
if (opts)
|
|
162
|
+
{
|
|
163
|
+
opts.args = [opts];
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Apply functions (and other values) to an object.
|
|
170
|
+
*
|
|
171
|
+
* NOTE: For the duration of the v1.x releases, the `ApplyWith.cpHandler`
|
|
172
|
+
* function will be registered automatically. That will be removed in v2.x,
|
|
173
|
+
* and you'll have to add it manually from the `@lumjs/cp` package.
|
|
174
|
+
*
|
|
175
|
+
* @param {(object|function)} target - The target we're applying to.
|
|
176
|
+
* @param {...(function|object)} values - Values we are applying.
|
|
177
|
+
*
|
|
178
|
+
* For each `value` of the `values`:
|
|
179
|
+
*
|
|
180
|
+
* - If it's a `function` this will do `value.apply(obj, opts.args)`;
|
|
181
|
+
* - For any other kind of value:
|
|
182
|
+
* - Create an {@link module:@lumjs/core/obj~ApplyInfo} object.
|
|
183
|
+
* - For each handler in `opts.handlers` do `handler.call(obj, info)`;
|
|
184
|
+
* - If none of the handlers set `info.ok` or `info.done` to true,
|
|
185
|
+
* then a TypeError will be thrown, indicating an unhandled value.
|
|
21
186
|
*
|
|
22
187
|
* @returns {object} `obj`
|
|
23
|
-
* @throws {TypeError} If a
|
|
188
|
+
* @throws {TypeError} If a value could not be handled.
|
|
24
189
|
* @alias module:@lumjs/core/obj.apply
|
|
25
190
|
*/
|
|
26
|
-
function apply(
|
|
191
|
+
function apply(target, ...values)
|
|
27
192
|
{
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
193
|
+
const opts =
|
|
194
|
+
{
|
|
195
|
+
[ApplyOpts]: true,
|
|
196
|
+
target,
|
|
197
|
+
obj: target, // DEPRECATED: use target
|
|
198
|
+
copyProps: true, // Change to false in v2.x
|
|
199
|
+
ctx: target,
|
|
200
|
+
handlers: new Set(),
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// TODO: change this to `[opts]` in v2.x
|
|
204
|
+
opts.args = [target, opts];
|
|
32
205
|
|
|
33
|
-
|
|
206
|
+
// TODO: remove this line in v2.x
|
|
207
|
+
ApplyWith.cpHandler(opts);
|
|
208
|
+
|
|
209
|
+
for (let value of values)
|
|
34
210
|
{
|
|
35
|
-
if (typeof
|
|
211
|
+
if (typeof value === F)
|
|
36
212
|
{
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
else if (isObj(fn))
|
|
40
|
-
{
|
|
41
|
-
cp.from(fn);
|
|
213
|
+
value.apply(opts.ctx, opts.args);
|
|
42
214
|
}
|
|
43
215
|
else
|
|
44
216
|
{
|
|
45
|
-
|
|
217
|
+
let info =
|
|
218
|
+
{
|
|
219
|
+
[ApplyInfo]: true,
|
|
220
|
+
value,
|
|
221
|
+
opts,
|
|
222
|
+
ok: false,
|
|
223
|
+
done: false
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
for (let handler of opts.handlers)
|
|
227
|
+
{
|
|
228
|
+
handler.call(opts.ctx, info);
|
|
229
|
+
if (info.done)
|
|
230
|
+
{
|
|
231
|
+
info.ok = true;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (!info.ok)
|
|
237
|
+
{
|
|
238
|
+
throw new TypeError("invalid parameter value");
|
|
239
|
+
}
|
|
46
240
|
}
|
|
47
241
|
}
|
|
48
242
|
|
|
49
|
-
return
|
|
243
|
+
return target;
|
|
50
244
|
}
|
|
51
245
|
|
|
52
|
-
|
|
246
|
+
// Make aliases to the symbols.
|
|
247
|
+
Object.defineProperties(apply,
|
|
248
|
+
{
|
|
249
|
+
Info: { value: ApplyInfo },
|
|
250
|
+
Opts: { value: ApplyOpts },
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
module.exports = {apply, ApplyInfo, ApplyOpts, ApplyWith};
|
|
254
|
+
|
|
255
|
+
const cpApply = require('@lumjs/cp/apply');
|
|
256
|
+
Object.assign(ApplyWith,
|
|
257
|
+
{
|
|
258
|
+
cpInit: cpApply.init,
|
|
259
|
+
cpHandler: cpApply.Handler,
|
|
260
|
+
});
|
package/lib/obj/copyall.js
CHANGED
|
@@ -6,21 +6,11 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Use `copyProps`, or `mergeNested` for more robust versions.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* NOTE: As of v1.38.5 this is an alias of @lumjs/cp/fun.copyAll
|
|
10
|
+
*
|
|
11
|
+
* @name module:@lumjs/core/obj.copyAll
|
|
12
|
+
* @deprecated Moved to @lumjs/cp package.
|
|
11
13
|
*/
|
|
12
|
-
function copyAll(target, ...sources)
|
|
13
|
-
{
|
|
14
|
-
for (const source of sources)
|
|
15
|
-
{
|
|
16
|
-
for (const name in source)
|
|
17
|
-
{
|
|
18
|
-
target[name] = source[name];
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return target;
|
|
22
|
-
}
|
|
23
|
-
exports.copyAll = copyAll;
|
|
24
14
|
|
|
25
15
|
/**
|
|
26
16
|
* Make a (shallow) copy of a single object using `copyAll`.
|
|
@@ -29,12 +19,13 @@ exports.copyAll = copyAll;
|
|
|
29
19
|
*
|
|
30
20
|
* Alias: `copyAll.clone`
|
|
31
21
|
*
|
|
32
|
-
*
|
|
22
|
+
* NOTE: As of v1.38.5 this is an alias of @lumjs/cp/fun.duplicateOne
|
|
23
|
+
*
|
|
24
|
+
* @name module:@lumjs/core/obj.duplicateOne
|
|
33
25
|
* @param {object} obj - The object to duplicate.
|
|
34
26
|
* @returns {object} A clone of the object.
|
|
35
|
-
* @deprecated
|
|
27
|
+
* @deprecated Moved to @lumjs/cp package.
|
|
36
28
|
*/
|
|
37
|
-
exports.duplicateOne = copyAll.clone = obj => copyAll({}, obj);
|
|
38
29
|
|
|
39
30
|
/**
|
|
40
31
|
* Make a new object containing properties from other objects using `copyAll`.
|
|
@@ -43,9 +34,12 @@ exports.duplicateOne = copyAll.clone = obj => copyAll({}, obj);
|
|
|
43
34
|
*
|
|
44
35
|
* Alias: `copyAll.duplicate`
|
|
45
36
|
*
|
|
46
|
-
*
|
|
37
|
+
* NOTE: As of v1.38.5 this is an alias of @lumjs/cp/fun.duplicateAll
|
|
38
|
+
*
|
|
39
|
+
* @name module:@lumjs/core/obj.duplicateAll
|
|
47
40
|
* @param {object} obj - The object to duplicate.
|
|
48
41
|
* @returns {object} A clone of the object.
|
|
49
|
-
* @deprecated
|
|
42
|
+
* @deprecated Moved to @lumjs/cp package.
|
|
50
43
|
*/
|
|
51
|
-
|
|
44
|
+
|
|
45
|
+
module.exports = require('@lumjs/cp/fun');
|