@nejs/basic-extensions 2.21.0 → 2.22.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/.idea/markdown.xml +8 -0
- package/.idea/modules.xml +8 -0
- package/.idea/ne-basic-extensions.iml +8 -0
- package/.idea/vcs.xml +6 -0
- package/CODE_STYLE.md +393 -0
- package/CODING_PHILOSOPHY.md +36 -0
- package/DOCUMENTATION_GUIDELINES.md +221 -0
- package/README.md +78 -4
- package/dist/@nejs/basic-extensions.bundle.2.22.6.js +25 -0
- package/dist/@nejs/basic-extensions.bundle.2.22.6.js.map +7 -0
- package/dist/cjs/classes/index.cjs +11129 -0
- package/dist/cjs/classes/index.cjs.map +7 -0
- package/dist/cjs/index.cjs +15191 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/utils/index.cjs +3954 -0
- package/dist/cjs/utils/index.cjs.map +7 -0
- package/dist/esm/basic-extensions.mjs +25 -0
- package/dist/esm/basic-extensions.mjs.map +7 -0
- package/package.json +16 -22
- package/repl.bootstrap.js +4 -7
- package/repl.history +30 -30
- package/src/big.int.extension.js +171 -45
- package/src/classes/enumeration.js +466 -0
- package/src/classes/index.js +5 -1
- package/src/index.js +5 -1
- package/src/math.extension.js +73 -0
- package/src/number.extension.js +18 -0
- package/src/regular.expression.extensions.js +0 -35
- package/src/utils/toolkit.js +699 -516
- package/tests/arrayextensions.test.js +3 -3
- package/tests/index.test.js +3 -1
- package/tests/newClasses/asyncIterable.test.js +3 -3
- package/tests/newClasses/deferred.test.js +3 -3
- package/tests/newClasses/descriptor.test.js +3 -3
- package/tests/newClasses/iterable.test.js +3 -3
- package/tests/newClasses/refmap.test.js +3 -3
- package/tests/newClasses/refset.test.js +3 -3
- package/tests/objectextensions.test.js +3 -3
- package/tests/setextensions.test.js +3 -3
- package/tests/stringextensions.test.js +3 -2
- package/tests/utils/descriptor.utils.test.js +1 -1
- package/tests/utils/toolkit.test.js +429 -163
- package/.esdoc.json +0 -9
- package/.vscode/settings.json +0 -5
- package/bin/build +0 -27
- package/bin/clean +0 -14
- package/bin/esbuild +0 -91
- package/bin/fixup +0 -13
- package/bin/repl.basics.js +0 -584
- package/bin/repl.signature.js +0 -63
- package/bin/version +0 -100
- package/dist/@nejs/basic-extensions.bundle.2.21.0.js +0 -25
- package/dist/@nejs/basic-extensions.bundle.2.21.0.js.map +0 -7
- package/dist/cjs/array.extensions.d.ts +0 -39
- package/dist/cjs/array.extensions.js +0 -477
- package/dist/cjs/array.extensions.js.map +0 -1
- package/dist/cjs/big.int.extension.d.ts +0 -31
- package/dist/cjs/big.int.extension.js +0 -165
- package/dist/cjs/big.int.extension.js.map +0 -1
- package/dist/cjs/classes/asyncIterable.d.ts +0 -126
- package/dist/cjs/classes/asyncIterable.js +0 -209
- package/dist/cjs/classes/asyncIterable.js.map +0 -1
- package/dist/cjs/classes/deferred.d.ts +0 -146
- package/dist/cjs/classes/deferred.js +0 -291
- package/dist/cjs/classes/deferred.js.map +0 -1
- package/dist/cjs/classes/descriptor.d.ts +0 -334
- package/dist/cjs/classes/descriptor.js +0 -537
- package/dist/cjs/classes/descriptor.js.map +0 -1
- package/dist/cjs/classes/enum.d.ts +0 -50
- package/dist/cjs/classes/enum.js +0 -405
- package/dist/cjs/classes/enum.js.map +0 -1
- package/dist/cjs/classes/index.d.ts +0 -15
- package/dist/cjs/classes/index.js +0 -63
- package/dist/cjs/classes/index.js.map +0 -1
- package/dist/cjs/classes/introspector.d.ts +0 -20
- package/dist/cjs/classes/introspector.js +0 -130
- package/dist/cjs/classes/introspector.js.map +0 -1
- package/dist/cjs/classes/iterable.d.ts +0 -169
- package/dist/cjs/classes/iterable.js +0 -268
- package/dist/cjs/classes/iterable.js.map +0 -1
- package/dist/cjs/classes/param.parser.d.ts +0 -221
- package/dist/cjs/classes/param.parser.js +0 -242
- package/dist/cjs/classes/param.parser.js.map +0 -1
- package/dist/cjs/classes/pluggable.proxy.d.ts +0 -153
- package/dist/cjs/classes/pluggable.proxy.js +0 -444
- package/dist/cjs/classes/pluggable.proxy.js.map +0 -1
- package/dist/cjs/classes/property.d.ts +0 -79
- package/dist/cjs/classes/property.js +0 -284
- package/dist/cjs/classes/property.js.map +0 -1
- package/dist/cjs/classes/refmap.d.ts +0 -238
- package/dist/cjs/classes/refmap.js +0 -421
- package/dist/cjs/classes/refmap.js.map +0 -1
- package/dist/cjs/classes/refset.d.ts +0 -186
- package/dist/cjs/classes/refset.js +0 -370
- package/dist/cjs/classes/refset.js.map +0 -1
- package/dist/cjs/classes/symkeys.d.ts +0 -349
- package/dist/cjs/classes/symkeys.js +0 -510
- package/dist/cjs/classes/symkeys.js.map +0 -1
- package/dist/cjs/classes/type.d.ts +0 -56
- package/dist/cjs/classes/type.js +0 -405
- package/dist/cjs/classes/type.js.map +0 -1
- package/dist/cjs/function.extensions.d.ts +0 -12
- package/dist/cjs/function.extensions.js +0 -758
- package/dist/cjs/function.extensions.js.map +0 -1
- package/dist/cjs/global.this.d.ts +0 -2
- package/dist/cjs/global.this.js +0 -300
- package/dist/cjs/global.this.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -31
- package/dist/cjs/index.js +0 -226
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/json.extensions.d.ts +0 -2
- package/dist/cjs/json.extensions.js +0 -109
- package/dist/cjs/json.extensions.js.map +0 -1
- package/dist/cjs/map.extensions.d.ts +0 -3
- package/dist/cjs/map.extensions.js +0 -143
- package/dist/cjs/map.extensions.js.map +0 -1
- package/dist/cjs/number.extension.d.ts +0 -44
- package/dist/cjs/number.extension.js +0 -261
- package/dist/cjs/number.extension.js.map +0 -1
- package/dist/cjs/object.extensions.d.ts +0 -33
- package/dist/cjs/object.extensions.js +0 -1091
- package/dist/cjs/object.extensions.js.map +0 -1
- package/dist/cjs/package.json +0 -3
- package/dist/cjs/proxy.extensions.d.ts +0 -2
- package/dist/cjs/proxy.extensions.js +0 -207
- package/dist/cjs/proxy.extensions.js.map +0 -1
- package/dist/cjs/reflect.extensions.d.ts +0 -14
- package/dist/cjs/reflect.extensions.js +0 -316
- package/dist/cjs/reflect.extensions.js.map +0 -1
- package/dist/cjs/regular.expression.extensions.d.ts +0 -2
- package/dist/cjs/regular.expression.extensions.js +0 -423
- package/dist/cjs/regular.expression.extensions.js.map +0 -1
- package/dist/cjs/set.extensions.d.ts +0 -40
- package/dist/cjs/set.extensions.js +0 -355
- package/dist/cjs/set.extensions.js.map +0 -1
- package/dist/cjs/string.extensions.d.ts +0 -23
- package/dist/cjs/string.extensions.js +0 -704
- package/dist/cjs/string.extensions.js.map +0 -1
- package/dist/cjs/symbol.extensions.d.ts +0 -11
- package/dist/cjs/symbol.extensions.js +0 -735
- package/dist/cjs/symbol.extensions.js.map +0 -1
- package/dist/cjs/utils/copy.object.d.ts +0 -408
- package/dist/cjs/utils/copy.object.js +0 -720
- package/dist/cjs/utils/copy.object.js.map +0 -1
- package/dist/cjs/utils/descriptor.utils.d.ts +0 -298
- package/dist/cjs/utils/descriptor.utils.js +0 -889
- package/dist/cjs/utils/descriptor.utils.js.map +0 -1
- package/dist/cjs/utils/index.d.ts +0 -75
- package/dist/cjs/utils/index.js +0 -61
- package/dist/cjs/utils/index.js.map +0 -1
- package/dist/cjs/utils/stdout.d.ts +0 -742
- package/dist/cjs/utils/stdout.js +0 -1042
- package/dist/cjs/utils/stdout.js.map +0 -1
- package/dist/cjs/utils/toolkit.d.ts +0 -1898
- package/dist/cjs/utils/toolkit.js +0 -1378
- package/dist/cjs/utils/toolkit.js.map +0 -1
- package/dist/cjs/weakref.extensions.d.ts +0 -2
- package/dist/cjs/weakref.extensions.js +0 -19
- package/dist/cjs/weakref.extensions.js.map +0 -1
- package/dist/mjs/array.extensions.d.ts +0 -39
- package/dist/mjs/array.extensions.js +0 -474
- package/dist/mjs/array.extensions.js.map +0 -1
- package/dist/mjs/big.int.extension.d.ts +0 -31
- package/dist/mjs/big.int.extension.js +0 -162
- package/dist/mjs/big.int.extension.js.map +0 -1
- package/dist/mjs/classes/asyncIterable.d.ts +0 -126
- package/dist/mjs/classes/asyncIterable.js +0 -204
- package/dist/mjs/classes/asyncIterable.js.map +0 -1
- package/dist/mjs/classes/deferred.d.ts +0 -146
- package/dist/mjs/classes/deferred.js +0 -287
- package/dist/mjs/classes/deferred.js.map +0 -1
- package/dist/mjs/classes/descriptor.d.ts +0 -334
- package/dist/mjs/classes/descriptor.js +0 -533
- package/dist/mjs/classes/descriptor.js.map +0 -1
- package/dist/mjs/classes/enum.d.ts +0 -50
- package/dist/mjs/classes/enum.js +0 -400
- package/dist/mjs/classes/enum.js.map +0 -1
- package/dist/mjs/classes/index.d.ts +0 -15
- package/dist/mjs/classes/index.js +0 -46
- package/dist/mjs/classes/index.js.map +0 -1
- package/dist/mjs/classes/introspector.d.ts +0 -20
- package/dist/mjs/classes/introspector.js +0 -126
- package/dist/mjs/classes/introspector.js.map +0 -1
- package/dist/mjs/classes/iterable.d.ts +0 -169
- package/dist/mjs/classes/iterable.js +0 -263
- package/dist/mjs/classes/iterable.js.map +0 -1
- package/dist/mjs/classes/param.parser.d.ts +0 -221
- package/dist/mjs/classes/param.parser.js +0 -238
- package/dist/mjs/classes/param.parser.js.map +0 -1
- package/dist/mjs/classes/pluggable.proxy.d.ts +0 -153
- package/dist/mjs/classes/pluggable.proxy.js +0 -438
- package/dist/mjs/classes/pluggable.proxy.js.map +0 -1
- package/dist/mjs/classes/property.d.ts +0 -79
- package/dist/mjs/classes/property.js +0 -280
- package/dist/mjs/classes/property.js.map +0 -1
- package/dist/mjs/classes/refmap.d.ts +0 -238
- package/dist/mjs/classes/refmap.js +0 -417
- package/dist/mjs/classes/refmap.js.map +0 -1
- package/dist/mjs/classes/refset.d.ts +0 -186
- package/dist/mjs/classes/refset.js +0 -366
- package/dist/mjs/classes/refset.js.map +0 -1
- package/dist/mjs/classes/symkeys.d.ts +0 -349
- package/dist/mjs/classes/symkeys.js +0 -506
- package/dist/mjs/classes/symkeys.js.map +0 -1
- package/dist/mjs/classes/type.d.ts +0 -56
- package/dist/mjs/classes/type.js +0 -401
- package/dist/mjs/classes/type.js.map +0 -1
- package/dist/mjs/function.extensions.d.ts +0 -12
- package/dist/mjs/function.extensions.js +0 -755
- package/dist/mjs/function.extensions.js.map +0 -1
- package/dist/mjs/global.this.d.ts +0 -2
- package/dist/mjs/global.this.js +0 -264
- package/dist/mjs/global.this.js.map +0 -1
- package/dist/mjs/index.d.ts +0 -31
- package/dist/mjs/index.js +0 -204
- package/dist/mjs/index.js.map +0 -1
- package/dist/mjs/json.extensions.d.ts +0 -2
- package/dist/mjs/json.extensions.js +0 -106
- package/dist/mjs/json.extensions.js.map +0 -1
- package/dist/mjs/map.extensions.d.ts +0 -3
- package/dist/mjs/map.extensions.js +0 -140
- package/dist/mjs/map.extensions.js.map +0 -1
- package/dist/mjs/number.extension.d.ts +0 -44
- package/dist/mjs/number.extension.js +0 -258
- package/dist/mjs/number.extension.js.map +0 -1
- package/dist/mjs/object.extensions.d.ts +0 -33
- package/dist/mjs/object.extensions.js +0 -1088
- package/dist/mjs/object.extensions.js.map +0 -1
- package/dist/mjs/package.json +0 -3
- package/dist/mjs/proxy.extensions.d.ts +0 -2
- package/dist/mjs/proxy.extensions.js +0 -204
- package/dist/mjs/proxy.extensions.js.map +0 -1
- package/dist/mjs/reflect.extensions.d.ts +0 -14
- package/dist/mjs/reflect.extensions.js +0 -313
- package/dist/mjs/reflect.extensions.js.map +0 -1
- package/dist/mjs/regular.expression.extensions.d.ts +0 -2
- package/dist/mjs/regular.expression.extensions.js +0 -420
- package/dist/mjs/regular.expression.extensions.js.map +0 -1
- package/dist/mjs/set.extensions.d.ts +0 -40
- package/dist/mjs/set.extensions.js +0 -352
- package/dist/mjs/set.extensions.js.map +0 -1
- package/dist/mjs/string.extensions.d.ts +0 -23
- package/dist/mjs/string.extensions.js +0 -701
- package/dist/mjs/string.extensions.js.map +0 -1
- package/dist/mjs/symbol.extensions.d.ts +0 -11
- package/dist/mjs/symbol.extensions.js +0 -732
- package/dist/mjs/symbol.extensions.js.map +0 -1
- package/dist/mjs/utils/copy.object.d.ts +0 -408
- package/dist/mjs/utils/copy.object.js +0 -702
- package/dist/mjs/utils/copy.object.js.map +0 -1
- package/dist/mjs/utils/descriptor.utils.d.ts +0 -298
- package/dist/mjs/utils/descriptor.utils.js +0 -875
- package/dist/mjs/utils/descriptor.utils.js.map +0 -1
- package/dist/mjs/utils/index.d.ts +0 -75
- package/dist/mjs/utils/index.js +0 -45
- package/dist/mjs/utils/index.js.map +0 -1
- package/dist/mjs/utils/stdout.d.ts +0 -742
- package/dist/mjs/utils/stdout.js +0 -1037
- package/dist/mjs/utils/stdout.js.map +0 -1
- package/dist/mjs/utils/toolkit.d.ts +0 -1898
- package/dist/mjs/utils/toolkit.js +0 -1373
- package/dist/mjs/utils/toolkit.js.map +0 -1
- package/dist/mjs/weakref.extensions.d.ts +0 -2
- package/dist/mjs/weakref.extensions.js +0 -16
- package/dist/mjs/weakref.extensions.js.map +0 -1
- package/jsdoc-config.json +0 -31
- package/tsconfig.base.json +0 -28
- package/tsconfig.cjs.json +0 -8
- package/tsconfig.esm.json +0 -8
- package/vitest.config.js +0 -7
|
@@ -1,720 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlexiblyHiddenHandler = exports.FlexiblyVisibleHandler = exports.ImmutablyHiddenHandler = exports.ImmutablyVisibleHandler = exports.MutablyHiddenHandler = exports.MutablyVisibleHandler = exports.VisibilityScopeHandler = exports.VisibilityKeys = exports.COPropertyHandler = void 0;
|
|
4
|
-
exports.tryIgnore = tryIgnore;
|
|
5
|
-
exports.transduceFrom = transduceFrom;
|
|
6
|
-
exports.transduceFromCOHandler = transduceFromCOHandler;
|
|
7
|
-
exports.makeTransducer = makeTransducer;
|
|
8
|
-
exports.kVisibilityKeys = kVisibilityKeys;
|
|
9
|
-
exports.copyObject = copyObject;
|
|
10
|
-
exports.customCopyObject = customCopyObject;
|
|
11
|
-
/**
|
|
12
|
-
* Transforms an array into an object using a provided transform
|
|
13
|
-
* function.
|
|
14
|
-
*
|
|
15
|
-
* @function transduceFrom
|
|
16
|
-
* @param {Array} array - The array to transform.
|
|
17
|
-
* @param {Function} transform - The function used to transform each
|
|
18
|
-
* element of the array. It should return an object with 'key' and
|
|
19
|
-
* 'value' properties.
|
|
20
|
-
* @param {Object} [into={}] - The object to transform the array into.
|
|
21
|
-
* @returns {Object} The transformed object.
|
|
22
|
-
* @example
|
|
23
|
-
* const array = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]
|
|
24
|
-
* const transform = (element) => ({ key: element.id, value: element.name })
|
|
25
|
-
* transduceFrom(array, transform)
|
|
26
|
-
* // => { 1: 'John', 2: 'Jane' }
|
|
27
|
-
*/
|
|
28
|
-
function tryIgnore(code) {
|
|
29
|
-
try {
|
|
30
|
-
return code();
|
|
31
|
-
}
|
|
32
|
-
catch (ignore) {
|
|
33
|
-
return undefined;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function transduceFrom(array, transform, into = {}) {
|
|
37
|
-
if (typeof transform !== 'function') {
|
|
38
|
-
return into;
|
|
39
|
-
}
|
|
40
|
-
return array.reduce((accumulator, element) => {
|
|
41
|
-
const { key, value } = (transform?.(element) ?? {});
|
|
42
|
-
if (key && value) {
|
|
43
|
-
accumulator[key] = value;
|
|
44
|
-
}
|
|
45
|
-
return accumulator;
|
|
46
|
-
}, into);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Transforms a COHandler instance into an object with 'key' and 'value'
|
|
50
|
-
* properties.
|
|
51
|
-
*
|
|
52
|
-
* @function transduceFromCOHandler
|
|
53
|
-
* @param {COHandler} element - The COHandler instance to transform.
|
|
54
|
-
* @returns {Object} An object with 'key' and 'value' properties, where
|
|
55
|
-
* 'key' is the 'property' of the COHandler instance and 'value' is
|
|
56
|
-
* the COHandler instance itself.
|
|
57
|
-
* @example
|
|
58
|
-
* const handler = new COHandler('foo')
|
|
59
|
-
* transduceFromCOHandler(handler)
|
|
60
|
-
* // => { key: 'foo', value: handler }
|
|
61
|
-
*/
|
|
62
|
-
function transduceFromCOHandler(element) {
|
|
63
|
-
const result = {};
|
|
64
|
-
if (element instanceof COPropertyHandler) {
|
|
65
|
-
result.key = element.property;
|
|
66
|
-
result.value = element;
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Creates a transducer function by partially applying the 'array' and
|
|
72
|
-
* 'transform' arguments to the 'transduceFrom' function.
|
|
73
|
-
*
|
|
74
|
-
* @function makeTransducer
|
|
75
|
-
* @param {Array} array - The array to transform.
|
|
76
|
-
* @param {Function} transform - The function used to transform each
|
|
77
|
-
* element of the array.
|
|
78
|
-
* @returns {Function} A transducer function that takes an 'into' object
|
|
79
|
-
* and returns the result of calling 'transduceFrom' with the provided
|
|
80
|
-
* 'array', 'transform', and 'into' arguments.
|
|
81
|
-
* @example
|
|
82
|
-
* const array = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]
|
|
83
|
-
* const transform = (element) => ({ key: element.id, value: element.name })
|
|
84
|
-
* const transducer = makeTransducer(array, transform)
|
|
85
|
-
* transducer({ 3: 'Jim' })
|
|
86
|
-
* // => { 1: 'John', 2: 'Jane', 3: 'Jim' }
|
|
87
|
-
*/
|
|
88
|
-
function makeTransducer(array, transform) {
|
|
89
|
-
return transduceFrom.bind(null, array, transform);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* A class for handling property descriptors during object copying.
|
|
93
|
-
* @class
|
|
94
|
-
* @example
|
|
95
|
-
* const handler = new COPropertyHandler('foo', (prop, descriptor) => {
|
|
96
|
-
* descriptor.enumerable = false
|
|
97
|
-
* return descriptor
|
|
98
|
-
* })
|
|
99
|
-
* handler.handle('foo', { value: 42, writable: true, enumerable: true })
|
|
100
|
-
* // => { value: 42, writable: true, enumerable: false }
|
|
101
|
-
*/
|
|
102
|
-
class COPropertyHandler {
|
|
103
|
-
/**
|
|
104
|
-
* The name of the property this handler is responsible for.
|
|
105
|
-
* @type {string|undefined}
|
|
106
|
-
*/
|
|
107
|
-
property = undefined;
|
|
108
|
-
/**
|
|
109
|
-
* The property handler. When provided and invoked, it will receive
|
|
110
|
-
* a the property name of the value being handled, the current
|
|
111
|
-
* descriptor to transform, and the object into which values are
|
|
112
|
-
* currently being copied into.
|
|
113
|
-
*
|
|
114
|
-
* The result must be a COPropertyHandler response type, which can
|
|
115
|
-
* be made with {@link COPropertyHandler.makeResponse} and which
|
|
116
|
-
* can be validated with {@link COPropertyHandler.isResponse}.
|
|
117
|
-
*
|
|
118
|
-
* The handler should have the following parameters
|
|
119
|
-
* - {string} property - The name of the property being handled.
|
|
120
|
-
* - {Object} curDescriptor - The property descriptor to handle.
|
|
121
|
-
* - {Object} destination - The destination object into which
|
|
122
|
-
* properties are being copied.
|
|
123
|
-
*
|
|
124
|
-
* An should return
|
|
125
|
-
* - {Object} a `COPropertyHandler.Response` type object which
|
|
126
|
-
* can be made with {@link COPropertyHandler.makeResponse}.
|
|
127
|
-
*
|
|
128
|
-
* @type {function|undefined}
|
|
129
|
-
*/
|
|
130
|
-
handler = undefined;
|
|
131
|
-
/**
|
|
132
|
-
* Creates a new COPropertyHandler instance.
|
|
133
|
-
* @param {string} [property] - The name of the property to handle.
|
|
134
|
-
* @param {function} [handler] - The function to handle the property
|
|
135
|
-
* descriptor.
|
|
136
|
-
*/
|
|
137
|
-
constructor(property, handler) {
|
|
138
|
-
Object.assign(this, { property, handler });
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Handles a property descriptor using the registered handler function.
|
|
142
|
-
* @param {string} property - The name of the property being handled.
|
|
143
|
-
* @param {Object} descriptor - The property descriptor to handle.
|
|
144
|
-
* @returns {Object} The resulting property descriptor after handling.
|
|
145
|
-
*/
|
|
146
|
-
handle(property, descriptor, destination) {
|
|
147
|
-
if (this.handler) {
|
|
148
|
-
return COPropertyHandler.defaultHandle(property, descriptor, this.handler);
|
|
149
|
-
}
|
|
150
|
-
return descriptor;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* The default property descriptor handler.
|
|
154
|
-
*
|
|
155
|
-
* @param {string} property - The name of the property being handled.
|
|
156
|
-
* @param {Object} curDescriptor - The property descriptor to handle.
|
|
157
|
-
* @param {Object} destination - The destination object into which
|
|
158
|
-
* properties are being copied.
|
|
159
|
-
* @param {function} handler - The function to handle the property
|
|
160
|
-
* descriptor.
|
|
161
|
-
* @returns {Object} a `COPropertyHandler.Response` type object which
|
|
162
|
-
* can be made with {@link COPropertyHandler.makeResponse}.
|
|
163
|
-
*/
|
|
164
|
-
static defaultHandle(property, curDescriptor, destination, handler) {
|
|
165
|
-
if (typeof handler === 'function') {
|
|
166
|
-
try {
|
|
167
|
-
const { descriptor, flow } = handler(property, curDescriptor, destination);
|
|
168
|
-
return this.makeResponse(descriptor, flow);
|
|
169
|
-
}
|
|
170
|
-
catch (ignore) { }
|
|
171
|
-
}
|
|
172
|
-
return this.makeResponse(curDescriptor);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Creates a COPropertyHandler response object.
|
|
176
|
-
*
|
|
177
|
-
* @param {Object} descriptor - The property descriptor.
|
|
178
|
-
* @param {string} [flow=COPropertyHandler.kNoChange] - The flow control
|
|
179
|
-
* directive. Must be one of the values from
|
|
180
|
-
* {@link COPropertyHandler.flowTypes} if provided.
|
|
181
|
-
* @returns {COPropertyHandler.Response} The response object.
|
|
182
|
-
* @example
|
|
183
|
-
* COPropertyHandler.makeResponse({ value: 42, writable: false })
|
|
184
|
-
* // => {
|
|
185
|
-
* // newDescriptor: { value: 42, writable: false },
|
|
186
|
-
* // flow: 'nochange'
|
|
187
|
-
* // }
|
|
188
|
-
*/
|
|
189
|
-
static makeResponse(descriptor, flow) {
|
|
190
|
-
return {
|
|
191
|
-
newDescriptor: descriptor,
|
|
192
|
-
flow: flow ?? this.kNoChange,
|
|
193
|
-
get [Symbol.toStringTag]() { return 'COPropertyHandler.Response'; }
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Checks if a value is a valid COPropertyHandler response object.
|
|
198
|
-
* @param {*} value - The value to check.
|
|
199
|
-
* @returns {boolean} `true` if the value is a response object, `false`
|
|
200
|
-
* otherwise.
|
|
201
|
-
* @example
|
|
202
|
-
* COPropertyHandler.isResponse({
|
|
203
|
-
* newDescriptor: { value: 42 },
|
|
204
|
-
* flow: 'nochange'
|
|
205
|
-
* })
|
|
206
|
-
* // => true
|
|
207
|
-
*/
|
|
208
|
-
static isResponse(value) {
|
|
209
|
-
return (value && typeof value === 'object' &&
|
|
210
|
-
value[Symbol.toStringTag] === 'COPropertyHandler.Response');
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* The flow control directive indicating no change in flow.
|
|
214
|
-
* @type {string}
|
|
215
|
-
*/
|
|
216
|
-
static get kNoChange() { return 'nochange'; }
|
|
217
|
-
/**
|
|
218
|
-
* The flow control directive indicating to continue the loop.
|
|
219
|
-
* @type {string}
|
|
220
|
-
*/
|
|
221
|
-
static get kContinue() { return 'continue'; }
|
|
222
|
-
/**
|
|
223
|
-
* The flow control directive indicating to break the loop.
|
|
224
|
-
* @type {string}
|
|
225
|
-
*/
|
|
226
|
-
static get kBreak() { return 'break'; }
|
|
227
|
-
/**
|
|
228
|
-
* An array of all valid flow control directive values.
|
|
229
|
-
* @type {string[]}
|
|
230
|
-
*/
|
|
231
|
-
static get flowTypes() {
|
|
232
|
-
return [this.kNoChange, this.kContinue, this.kBreak];
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* An object mapping flow control directive values to their
|
|
236
|
-
* corresponding string representations.
|
|
237
|
-
* @type {Object.<string, string>}
|
|
238
|
-
*/
|
|
239
|
-
static get flowEnum() {
|
|
240
|
-
return {
|
|
241
|
-
[this.kNoChange]: this.kNoChange,
|
|
242
|
-
[this.kContinue]: this.kContinue,
|
|
243
|
-
[this.kBreak]: this.kBreak,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
exports.COPropertyHandler = COPropertyHandler;
|
|
248
|
-
/**
|
|
249
|
-
* Returns an object containing getter functions that return Symbol
|
|
250
|
-
* values representing different visibility configurations for object
|
|
251
|
-
* properties.
|
|
252
|
-
*
|
|
253
|
-
* @function
|
|
254
|
-
* @name kVisibilityKeys
|
|
255
|
-
* @returns {Object} An object with the following properties:
|
|
256
|
-
* @property {symbol} mutablyHidden - Returns a Symbol representing a
|
|
257
|
-
* property that is not enumerable but is configurable.
|
|
258
|
-
* @property {symbol} mutablyVisible - Returns a Symbol representing a
|
|
259
|
-
* property that is both enumerable and configurable.
|
|
260
|
-
* @property {symbol} immutablyHidden - Returns a Symbol representing
|
|
261
|
-
* a property that is neither enumerable nor configurable.
|
|
262
|
-
* @property {symbol} immutablyVisible - Returns a Symbol representing
|
|
263
|
-
* a property that is enumerable but not configurable.
|
|
264
|
-
* @property {symbol} flexiblyHidden - Returns a Symbol representing a
|
|
265
|
-
* property that is not enumerable, writable and not configurable.
|
|
266
|
-
* @property {symbol} flexiblyVisible - Returns a Symbol representing
|
|
267
|
-
* a property that is both enumerable and writable, but not
|
|
268
|
-
* configurable.
|
|
269
|
-
* @property {Generator} keys - Returns a generator that yields the
|
|
270
|
-
* string keys of the visibility configurations.
|
|
271
|
-
* @property {Generator} symbols - Returns a generator that yields the
|
|
272
|
-
* Symbol values of the visibility configurations.
|
|
273
|
-
* @property {Generator} entries - Returns a generator that yields
|
|
274
|
-
* [key, Symbol] pairs for each visibility configuration.
|
|
275
|
-
* @property {Generator} descriptors - Returns a generator that yields
|
|
276
|
-
* [key, descriptor] pairs for each visibility configuration, where
|
|
277
|
-
* descriptor is the parsed JSON representation of the Symbol's
|
|
278
|
-
* description.
|
|
279
|
-
* @property {Generator} [Symbol.iterator] - Returns the same generator
|
|
280
|
-
* as the symbols property, allowing the object to be iterated over
|
|
281
|
-
* directly to access the Symbol values.
|
|
282
|
-
*
|
|
283
|
-
* @example
|
|
284
|
-
* const { mutablyHidden, mutablyVisible } = kVisibilityKeys()
|
|
285
|
-
*
|
|
286
|
-
* const obj = {
|
|
287
|
-
* [mutablyHidden]: 'hidden value',
|
|
288
|
-
* [mutablyVisible]: 'visible value',
|
|
289
|
-
* }
|
|
290
|
-
*
|
|
291
|
-
* console.log(obj) // { [Symbol()]: 'visible value' }
|
|
292
|
-
* console.log(obj[mutablyHidden]) // 'hidden value'
|
|
293
|
-
* console.log(obj[mutablyVisible]) // 'visible value'
|
|
294
|
-
*
|
|
295
|
-
* @example
|
|
296
|
-
* const visibilityKeys = kVisibilityKeys()
|
|
297
|
-
*
|
|
298
|
-
* for (const key of visibilityKeys.keys()) {
|
|
299
|
-
* console.log(key)
|
|
300
|
-
* }
|
|
301
|
-
* // Output:
|
|
302
|
-
* // 'mutablyHidden'
|
|
303
|
-
* // 'mutablyVisible'
|
|
304
|
-
* // 'immutablyHidden'
|
|
305
|
-
* // 'immutablyVisible'
|
|
306
|
-
* // 'flexiblyHidden'
|
|
307
|
-
* // 'flexiblyVisible'
|
|
308
|
-
*
|
|
309
|
-
* @example
|
|
310
|
-
* const visibilityKeys = kVisibilityKeys()
|
|
311
|
-
*
|
|
312
|
-
* for (const symbol of visibilityKeys) {
|
|
313
|
-
* console.log(symbol)
|
|
314
|
-
* }
|
|
315
|
-
* // Output:
|
|
316
|
-
* // Symbol({"enumerable":false,"configurable":true})
|
|
317
|
-
* // Symbol({"enumerable":true,"configurable":true})
|
|
318
|
-
* // Symbol({"enumerable":false,"configurable":false})
|
|
319
|
-
* // Symbol({"enumerable":true,"configurable":false})
|
|
320
|
-
* // Symbol({"enumerable":false,"writable":true})
|
|
321
|
-
* // Symbol({"enumerable":true,"writable":true})
|
|
322
|
-
*/
|
|
323
|
-
function kVisibilityKeys() {
|
|
324
|
-
const keys = {
|
|
325
|
-
get mutablyHidden() {
|
|
326
|
-
return Symbol.for(JSON.stringify({
|
|
327
|
-
enumerable: false,
|
|
328
|
-
configurable: true,
|
|
329
|
-
}));
|
|
330
|
-
},
|
|
331
|
-
get mutablyVisible() {
|
|
332
|
-
return Symbol.for(JSON.stringify({
|
|
333
|
-
enumerable: true,
|
|
334
|
-
configurable: true,
|
|
335
|
-
}));
|
|
336
|
-
},
|
|
337
|
-
get immutablyHidden() {
|
|
338
|
-
return Symbol.for(JSON.stringify({
|
|
339
|
-
enumerable: false,
|
|
340
|
-
configurable: false,
|
|
341
|
-
}));
|
|
342
|
-
},
|
|
343
|
-
get immutablyVisible() {
|
|
344
|
-
return Symbol.for(JSON.stringify({
|
|
345
|
-
enumerable: true,
|
|
346
|
-
configurable: false,
|
|
347
|
-
}));
|
|
348
|
-
},
|
|
349
|
-
get flexiblyHidden() {
|
|
350
|
-
return Symbol.for(JSON.stringify({
|
|
351
|
-
enumerable: false,
|
|
352
|
-
configurable: false,
|
|
353
|
-
writable: true,
|
|
354
|
-
}));
|
|
355
|
-
},
|
|
356
|
-
get flexiblyVisible() {
|
|
357
|
-
return Symbol.for(JSON.stringify({
|
|
358
|
-
enumerable: true,
|
|
359
|
-
configurable: false,
|
|
360
|
-
writable: true,
|
|
361
|
-
}));
|
|
362
|
-
},
|
|
363
|
-
};
|
|
364
|
-
const enumerated = {
|
|
365
|
-
mutablyHidden: keys.mutablyHidden,
|
|
366
|
-
mutablyVisible: keys.mutablyVisible,
|
|
367
|
-
immutablyHidden: keys.immutablyHidden,
|
|
368
|
-
immutablyVisible: keys.immutablyVisible,
|
|
369
|
-
flexiblyHidden: keys.flexiblyHidden,
|
|
370
|
-
flexiblyVisible: keys.flexiblyVisible,
|
|
371
|
-
};
|
|
372
|
-
function* keyGenerator() {
|
|
373
|
-
for (const key of Object.keys(enumerated)) {
|
|
374
|
-
yield key;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
function* symbolGenerator() {
|
|
378
|
-
for (const value of Object.values(enumerated)) {
|
|
379
|
-
yield value;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
function* entryGenerator() {
|
|
383
|
-
for (const entry of Object.entries(enumerated)) {
|
|
384
|
-
yield entry;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function* descriptorGenertor() {
|
|
388
|
-
for (const [key, value] of entryGenerator()) {
|
|
389
|
-
yield [key, JSON.parse(value.description)];
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
Object.defineProperties(keys, {
|
|
393
|
-
enumeration: { get() { return enumerated; }, enumerable: false },
|
|
394
|
-
keys: { get() { return keyGenerator(); }, enumerable: false },
|
|
395
|
-
symbols: { get() { return symbolGenerator(); }, enumerable: false },
|
|
396
|
-
entries: { get() { return entryGenerator(); }, enumerable: false },
|
|
397
|
-
descriptors: { get() { return descriptorGenertor(); }, enumerable: false },
|
|
398
|
-
descriptorFor: {
|
|
399
|
-
value(symbol) {
|
|
400
|
-
try {
|
|
401
|
-
return JSON.parse(symbol.description);
|
|
402
|
-
}
|
|
403
|
-
catch (ignored) { }
|
|
404
|
-
return undefined;
|
|
405
|
-
},
|
|
406
|
-
enumerable: false
|
|
407
|
-
},
|
|
408
|
-
[Symbol.iterator]: { get() { return symbolGenerator(); } },
|
|
409
|
-
});
|
|
410
|
-
return keys;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* An object containing Symbol values representing different visibility
|
|
414
|
-
* configurations for object properties.
|
|
415
|
-
*
|
|
416
|
-
* @constant {Object} VisibilityKeys
|
|
417
|
-
* @property {symbol} mutablyHidden - A Symbol representing a property
|
|
418
|
-
* that is not enumerable but is configurable.
|
|
419
|
-
* @property {symbol} mutablyVisible - A Symbol representing a property
|
|
420
|
-
* that is both enumerable and configurable.
|
|
421
|
-
* @property {symbol} immutablyHidden - A Symbol representing a property
|
|
422
|
-
* that is neither enumerable nor configurable.
|
|
423
|
-
* @property {symbol} immutablyVisible - A Symbol representing a property
|
|
424
|
-
* that is enumerable but not configurable.
|
|
425
|
-
* @property {symbol} flexiblyHidden - A Symbol representing a property
|
|
426
|
-
* that is not enumerable, writable and not configurable.
|
|
427
|
-
* @property {symbol} flexiblyVisible - A Symbol representing a property
|
|
428
|
-
* that is both enumerable and writable, but not configurable.
|
|
429
|
-
*/
|
|
430
|
-
exports.VisibilityKeys = kVisibilityKeys();
|
|
431
|
-
/**
|
|
432
|
-
* A class for handling property descriptors during object copying based
|
|
433
|
-
* on a specified visibility key.
|
|
434
|
-
*
|
|
435
|
-
* @class VisibilityScopeHandler
|
|
436
|
-
* @extends COPropertyHandler
|
|
437
|
-
* @param {symbol} visibilityKey - The visibility key to use for handling
|
|
438
|
-
* property descriptors.
|
|
439
|
-
* @example
|
|
440
|
-
* const handler = new VisibilityScopeHandler(VisibilityKeys.mutablyHidden)
|
|
441
|
-
* handler.handle('foo', { value: 42, writable: true, enumerable: true })
|
|
442
|
-
* // => { value: 42, writable: true, enumerable: false }
|
|
443
|
-
*/
|
|
444
|
-
class VisibilityScopeHandler extends COPropertyHandler {
|
|
445
|
-
overrides = undefined;
|
|
446
|
-
/**
|
|
447
|
-
* Creates a new VisibilityScopeHandler instance.
|
|
448
|
-
*
|
|
449
|
-
* @constructor
|
|
450
|
-
* @param {symbol} visibilityKey - The visibility key to use for handling
|
|
451
|
-
* property descriptors.
|
|
452
|
-
*/
|
|
453
|
-
constructor(visibilityKey) {
|
|
454
|
-
super(visibilityKey, (property, descriptor, dest, source) => {
|
|
455
|
-
let data = descriptor?.value;
|
|
456
|
-
if (!descriptor || typeof descriptor.value !== 'object') {
|
|
457
|
-
return COPropertyHandler.makeResponse(descriptor, 'nochange');
|
|
458
|
-
}
|
|
459
|
-
if (!data && (descriptor?.get || descriptor?.set)) {
|
|
460
|
-
const newDescriptor = this.applyOverridesTo(descriptor);
|
|
461
|
-
return COPropertyHandler.makeResponse(newDescriptor, 'nochange');
|
|
462
|
-
}
|
|
463
|
-
data = customCopyObject({ deep: false }, {}, data ?? {});
|
|
464
|
-
this.walkAndApply(data);
|
|
465
|
-
descriptor.value = data;
|
|
466
|
-
return COPropertyHandler.makeResponse(descriptor, 'continue');
|
|
467
|
-
});
|
|
468
|
-
tryIgnore(() => this.overrides = JSON.parse(property.description));
|
|
469
|
-
}
|
|
470
|
-
applyOverridesTo(existingDescriptor, overwrite = false) {
|
|
471
|
-
const allowed = ['value', 'get', 'set', 'writable', 'configurable', 'enumerable'];
|
|
472
|
-
const output = overwrite ? existingDescriptor : { ...existingDescriptor };
|
|
473
|
-
for (let [key, value] of Object.entries(this.overrides ?? {})) {
|
|
474
|
-
if (!~allowed.indexOf(key)) {
|
|
475
|
-
continue;
|
|
476
|
-
}
|
|
477
|
-
if (!(['get', 'set'].some(k => k === key) &&
|
|
478
|
-
['undefined', 'function'].some(t => typeof value === t))) {
|
|
479
|
-
continue;
|
|
480
|
-
}
|
|
481
|
-
if (!(['enumerable', 'configurable', 'writable'].some(k => k === key) &&
|
|
482
|
-
typeof value !== 'boolean')) {
|
|
483
|
-
value = !!value;
|
|
484
|
-
}
|
|
485
|
-
delete output[key];
|
|
486
|
-
output[key] = value;
|
|
487
|
-
}
|
|
488
|
-
return output;
|
|
489
|
-
}
|
|
490
|
-
walkAndApply(to) {
|
|
491
|
-
Reflect.ownKeys(to).forEach(key => {
|
|
492
|
-
tryIgnore(() => {
|
|
493
|
-
let result = Object.getOwnPropertyDescriptor(to, key);
|
|
494
|
-
this.applyOverridesTo(result, true);
|
|
495
|
-
Object.defineProperty(to, key, result);
|
|
496
|
-
});
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
exports.VisibilityScopeHandler = VisibilityScopeHandler;
|
|
501
|
-
/**
|
|
502
|
-
* A handler for mutably visible properties during object copying.
|
|
503
|
-
* @class
|
|
504
|
-
* @extends VisibilityScopeHandler
|
|
505
|
-
* @example
|
|
506
|
-
* const handler = new MutablyVisibleHandler()
|
|
507
|
-
* const sharedHandler = MutablyVisibleHandler.shared
|
|
508
|
-
*/
|
|
509
|
-
class MutablyVisibleHandler extends VisibilityScopeHandler {
|
|
510
|
-
constructor() { super(exports.VisibilityKeys.mutablyVisible); }
|
|
511
|
-
static get shared() {
|
|
512
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
513
|
-
}
|
|
514
|
-
static #singleton;
|
|
515
|
-
}
|
|
516
|
-
exports.MutablyVisibleHandler = MutablyVisibleHandler;
|
|
517
|
-
/**
|
|
518
|
-
* A handler for mutably hidden properties during object copying.
|
|
519
|
-
* @class
|
|
520
|
-
* @extends VisibilityScopeHandler
|
|
521
|
-
* @example
|
|
522
|
-
* const handler = new MutablyHiddenHandler()
|
|
523
|
-
* const sharedHandler = MutablyHiddenHandler.shared
|
|
524
|
-
*/
|
|
525
|
-
class MutablyHiddenHandler extends VisibilityScopeHandler {
|
|
526
|
-
constructor() { super(exports.VisibilityKeys.mutablyHidden); }
|
|
527
|
-
static get shared() {
|
|
528
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
529
|
-
}
|
|
530
|
-
static #singleton;
|
|
531
|
-
}
|
|
532
|
-
exports.MutablyHiddenHandler = MutablyHiddenHandler;
|
|
533
|
-
/**
|
|
534
|
-
* A handler for immutably visible properties during object copying.
|
|
535
|
-
* @class
|
|
536
|
-
* @extends VisibilityScopeHandler
|
|
537
|
-
* @example
|
|
538
|
-
* const handler = new ImmutablyVisibleHandler()
|
|
539
|
-
* const sharedHandler = ImmutablyVisibleHandler.shared
|
|
540
|
-
*/
|
|
541
|
-
class ImmutablyVisibleHandler extends VisibilityScopeHandler {
|
|
542
|
-
constructor() { super(exports.VisibilityKeys.immutablyVisible); }
|
|
543
|
-
static get shared() {
|
|
544
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
545
|
-
}
|
|
546
|
-
static #singleton;
|
|
547
|
-
}
|
|
548
|
-
exports.ImmutablyVisibleHandler = ImmutablyVisibleHandler;
|
|
549
|
-
/**
|
|
550
|
-
* A handler for immutably hidden properties during object copying.
|
|
551
|
-
* @class
|
|
552
|
-
* @extends VisibilityScopeHandler
|
|
553
|
-
* @example
|
|
554
|
-
* const handler = new ImmutablyHiddenHandler()
|
|
555
|
-
* const sharedHandler = ImmutablyHiddenHandler.shared
|
|
556
|
-
*/
|
|
557
|
-
class ImmutablyHiddenHandler extends VisibilityScopeHandler {
|
|
558
|
-
constructor() { super(exports.VisibilityKeys.immutablyHidden); }
|
|
559
|
-
static get shared() {
|
|
560
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
561
|
-
}
|
|
562
|
-
static #singleton;
|
|
563
|
-
}
|
|
564
|
-
exports.ImmutablyHiddenHandler = ImmutablyHiddenHandler;
|
|
565
|
-
/**
|
|
566
|
-
* A handler for flexibly visible properties during object copying.
|
|
567
|
-
* @class
|
|
568
|
-
* @extends VisibilityScopeHandler
|
|
569
|
-
* @example
|
|
570
|
-
* const handler = new FlexiblyVisibleHandler()
|
|
571
|
-
* const sharedHandler = FlexiblyVisibleHandler.shared
|
|
572
|
-
*/
|
|
573
|
-
class FlexiblyVisibleHandler extends VisibilityScopeHandler {
|
|
574
|
-
constructor() { super(exports.VisibilityKeys.flexiblyVisible); }
|
|
575
|
-
static get shared() {
|
|
576
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
577
|
-
}
|
|
578
|
-
static #singleton;
|
|
579
|
-
}
|
|
580
|
-
exports.FlexiblyVisibleHandler = FlexiblyVisibleHandler;
|
|
581
|
-
/**
|
|
582
|
-
* A handler for flexibly hidden properties during object copying.
|
|
583
|
-
* @class
|
|
584
|
-
* @extends VisibilityScopeHandler
|
|
585
|
-
* @example
|
|
586
|
-
* const handler = new FlexiblyHiddenHandler()
|
|
587
|
-
* const sharedHandler = FlexiblyHiddenHandler.shared
|
|
588
|
-
*/
|
|
589
|
-
class FlexiblyHiddenHandler extends VisibilityScopeHandler {
|
|
590
|
-
constructor() { super(exports.VisibilityKeys.flexiblyHidden); }
|
|
591
|
-
static get shared() {
|
|
592
|
-
return this.#singleton ?? (this.#singleton = new this);
|
|
593
|
-
}
|
|
594
|
-
static #singleton;
|
|
595
|
-
}
|
|
596
|
-
exports.FlexiblyHiddenHandler = FlexiblyHiddenHandler;
|
|
597
|
-
Object.defineProperties(COPropertyHandler, {
|
|
598
|
-
MutablyHiddenHandler: { get() { return MutablyHiddenHandler.shared; } },
|
|
599
|
-
MutablyVisibleHandler: { get() { return MutablyVisibleHandler.shared; } },
|
|
600
|
-
ImmutablyHiddenHandler: { get() { return ImmutablyHiddenHandler.shared; } },
|
|
601
|
-
ImmutablyVisibleHandler: { get() { return ImmutablyVisibleHandler.shared; } },
|
|
602
|
-
FlexiblyHiddenHandler: { get() { return FlexiblyHiddenHandler.shared; } },
|
|
603
|
-
FlexiblyVisibleHandler: { get() { return FlexiblyVisibleHandler.shared; } },
|
|
604
|
-
handlers: {
|
|
605
|
-
value: [
|
|
606
|
-
MutablyHiddenHandler, MutablyVisibleHandler, ImmutablyHiddenHandler,
|
|
607
|
-
ImmutablyVisibleHandler, FlexiblyHiddenHandler, FlexiblyVisibleHandler,
|
|
608
|
-
].map(klass => klass.shared),
|
|
609
|
-
configurable: true,
|
|
610
|
-
enumerable: true
|
|
611
|
-
},
|
|
612
|
-
});
|
|
613
|
-
/**
|
|
614
|
-
* Creates a deep or shallow copy of the provided source objects and merges
|
|
615
|
-
* them into the destination object. The function uses a Set to keep track
|
|
616
|
-
* of visited objects to avoid circular references.
|
|
617
|
-
*
|
|
618
|
-
* @function
|
|
619
|
-
* @name copyObject
|
|
620
|
-
* @param {boolean} deep - If true, performs a deep copy, otherwise performs
|
|
621
|
-
* a shallow copy.
|
|
622
|
-
* @param {object} destination - The object to which properties will be copied.
|
|
623
|
-
* @param {...object} sources - The source object(s) from which properties
|
|
624
|
-
* will be copied.
|
|
625
|
-
* @returns {object} The destination object with the copied properties.
|
|
626
|
-
*
|
|
627
|
-
* @example
|
|
628
|
-
* // Shallow copy
|
|
629
|
-
* const obj1 = { a: 1, b: { c: 2 } };
|
|
630
|
-
* const obj2 = { b: { d: 3 }, e: 4 };
|
|
631
|
-
* const result = copyObject(false, obj1, obj2);
|
|
632
|
-
* console.log(result); // Output: { a: 1, b: { d: 3 }, e: 4 }
|
|
633
|
-
*
|
|
634
|
-
* @example
|
|
635
|
-
* // Deep copy
|
|
636
|
-
* const obj1 = { a: 1, b: { c: 2 } };
|
|
637
|
-
* const obj2 = { b: { d: 3 }, e: 4 };
|
|
638
|
-
* const result = copyObject(true, obj1, obj2);
|
|
639
|
-
* console.log(result); // Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
640
|
-
*/
|
|
641
|
-
function copyObject(deep, destination, ...sources) {
|
|
642
|
-
const options = {
|
|
643
|
-
deep: deep || false,
|
|
644
|
-
propertyHandlers: COPropertyHandler?.handlers ?? [],
|
|
645
|
-
};
|
|
646
|
-
return customCopyObject(options, destination, ...sources);
|
|
647
|
-
}
|
|
648
|
-
function customCopyObject(_options, _destination, ..._sources) {
|
|
649
|
-
const visited = new Set();
|
|
650
|
-
const [options, destination, sources] = ccoParseArgs(_options, _destination, ..._sources);
|
|
651
|
-
let { deep } = options;
|
|
652
|
-
for (const source of sources) {
|
|
653
|
-
if (source === null || typeof source !== 'object' || visited.has(source)) {
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
visited.add(source);
|
|
657
|
-
const keys = Reflect.ownKeys(source);
|
|
658
|
-
for (let key of keys) {
|
|
659
|
-
let descriptor;
|
|
660
|
-
try {
|
|
661
|
-
descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
662
|
-
}
|
|
663
|
-
catch (err) {
|
|
664
|
-
console.warn(`Failed to get descriptor for key "${key}": ${err}`);
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
const isDataDesc = Reflect.has(descriptor, 'value');
|
|
668
|
-
const keyedValue = descriptor?.value;
|
|
669
|
-
const conditionsMet = [
|
|
670
|
-
isDataDesc,
|
|
671
|
-
keyedValue,
|
|
672
|
-
typeof keyedValue === 'object',
|
|
673
|
-
!visited.has(keyedValue)
|
|
674
|
-
].every(condition => condition);
|
|
675
|
-
if (conditionsMet) {
|
|
676
|
-
visited.add(keyedValue);
|
|
677
|
-
const prototype = Object.getPrototypeOf(keyedValue);
|
|
678
|
-
const descriptors = Object.getOwnPropertyDescriptors(keyedValue);
|
|
679
|
-
const replacement = Object.create(prototype, descriptors);
|
|
680
|
-
descriptor.value = deep
|
|
681
|
-
? customCopyObject(options, replacement, keyedValue)
|
|
682
|
-
: replacement;
|
|
683
|
-
}
|
|
684
|
-
try {
|
|
685
|
-
Object.defineProperty(destination, key, descriptor);
|
|
686
|
-
}
|
|
687
|
-
catch (err) {
|
|
688
|
-
console.error(`Failed to define property "${key}": ${err}`);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
return destination;
|
|
693
|
-
}
|
|
694
|
-
function ccoParseArgs(options, destination, ...sources) {
|
|
695
|
-
// Parse options
|
|
696
|
-
let { deep = true, propertyHandlers = [] } = options;
|
|
697
|
-
// Ensure boolean'ness
|
|
698
|
-
deep = !!deep;
|
|
699
|
-
// Ensure propertyHandlers are converted for our ease of use
|
|
700
|
-
// Transform 1: Ensure array of COPropertyHandlers at the
|
|
701
|
-
// cost of potentially having none
|
|
702
|
-
propertyHandlers = (Array.isArray(propertyHandlers)
|
|
703
|
-
? propertyHandlers
|
|
704
|
-
: [propertyHandlers]).filter(element => element instanceof COPropertyHandler);
|
|
705
|
-
// Transform 2: Convert array of handlers into an object keyed
|
|
706
|
-
// as { [handler.property]: handler }
|
|
707
|
-
const transducer = makeTransducer(propertyHandlers, transduceFromCOHandler);
|
|
708
|
-
propertyHandlers = transducer({});
|
|
709
|
-
// Rebuild options in the case that we recurse
|
|
710
|
-
options = { deep, propertyHandlers };
|
|
711
|
-
// Ensure sources have only objects
|
|
712
|
-
sources = sources.filter(source => source && typeof source === 'object');
|
|
713
|
-
// Ensure the destination is not null
|
|
714
|
-
if (!destination) {
|
|
715
|
-
destination = {};
|
|
716
|
-
}
|
|
717
|
-
return [options, destination, sources];
|
|
718
|
-
}
|
|
719
|
-
exports.default = copyObject;
|
|
720
|
-
//# sourceMappingURL=copy.object.js.map
|