@nejs/basic-extensions 2.6.0 → 2.8.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/.vscode/settings.json +5 -0
- package/README.md +6129 -1574
- package/dist/@nejs/basic-extensions.bundle.2.7.0.js +19 -0
- package/dist/@nejs/basic-extensions.bundle.2.7.0.js.map +7 -0
- package/dist/cjs/array.extensions.d.ts +39 -0
- package/dist/cjs/array.extensions.js +303 -0
- package/dist/cjs/array.extensions.js.map +1 -0
- package/dist/cjs/big.int.extension.d.ts +31 -0
- package/dist/cjs/big.int.extension.js +164 -0
- package/dist/cjs/big.int.extension.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/asyncIterable.js +32 -44
- package/dist/cjs/classes/asyncIterable.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/deferred.js +66 -138
- package/dist/cjs/classes/deferred.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/descriptor.js +56 -90
- package/dist/cjs/classes/descriptor.js.map +1 -0
- package/dist/cjs/classes/index.d.ts +13 -0
- package/dist/cjs/classes/index.js +57 -0
- package/dist/cjs/classes/index.js.map +1 -0
- package/dist/cjs/classes/introspector.d.ts +20 -0
- package/dist/cjs/classes/introspector.js +130 -0
- package/dist/cjs/classes/introspector.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/iterable.js +42 -63
- package/dist/cjs/classes/iterable.js.map +1 -0
- package/dist/cjs/classes/param.parser.d.ts +227 -0
- package/dist/cjs/classes/param.parser.js +242 -0
- package/dist/cjs/classes/param.parser.js.map +1 -0
- package/dist/cjs/classes/pluggable.proxy.d.ts +152 -0
- package/dist/cjs/classes/pluggable.proxy.js +444 -0
- package/dist/cjs/classes/pluggable.proxy.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/refmap.js +18 -30
- package/dist/cjs/classes/refmap.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/refset.js +28 -47
- package/dist/cjs/classes/refset.js.map +1 -0
- package/dist/cjs/classes/symkeys.d.ts +292 -0
- package/dist/cjs/classes/symkeys.js +424 -0
- package/dist/cjs/classes/symkeys.js.map +1 -0
- package/dist/cjs/classes/type.d.ts +56 -0
- package/dist/cjs/classes/type.js +405 -0
- package/dist/cjs/classes/type.js.map +1 -0
- package/dist/cjs/function.extensions.js +757 -0
- package/dist/cjs/function.extensions.js.map +1 -0
- package/dist/cjs/global.this.js +261 -0
- package/dist/cjs/global.this.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -3
- package/dist/cjs/index.js +62 -32
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/json.extensions.d.ts +2 -0
- package/dist/cjs/json.extensions.js +107 -0
- package/dist/cjs/json.extensions.js.map +1 -0
- package/dist/{mjs/mapextensions.d.ts → cjs/map.extensions.d.ts} +1 -0
- package/dist/cjs/map.extensions.js +142 -0
- package/dist/cjs/map.extensions.js.map +1 -0
- package/dist/cjs/number.extension.d.ts +44 -0
- package/dist/cjs/number.extension.js +260 -0
- package/dist/cjs/number.extension.js.map +1 -0
- package/dist/cjs/object.extensions.d.ts +62 -0
- package/dist/cjs/object.extensions.js +1116 -0
- package/dist/cjs/object.extensions.js.map +1 -0
- package/dist/cjs/proxy.extensions.d.ts +2 -0
- package/dist/cjs/proxy.extensions.js +207 -0
- package/dist/cjs/proxy.extensions.js.map +1 -0
- package/dist/cjs/reflect.extensions.js +316 -0
- package/dist/cjs/reflect.extensions.js.map +1 -0
- package/dist/cjs/regular.expression.extensions.d.ts +2 -0
- package/dist/cjs/regular.expression.extensions.js +423 -0
- package/dist/cjs/regular.expression.extensions.js.map +1 -0
- package/dist/cjs/set.extensions.d.ts +40 -0
- package/dist/cjs/{setextensions.js → set.extensions.js} +150 -2
- package/dist/cjs/set.extensions.js.map +1 -0
- package/dist/cjs/string.extensions.js +471 -0
- package/dist/cjs/string.extensions.js.map +1 -0
- package/dist/{mjs/symbolextensions.d.ts → cjs/symbol.extensions.d.ts} +1 -0
- package/dist/cjs/symbol.extensions.js +259 -0
- package/dist/cjs/symbol.extensions.js.map +1 -0
- package/dist/cjs/{weakrefextensions.js → weakref.extensions.js} +1 -1
- package/dist/cjs/weakref.extensions.js.map +1 -0
- package/dist/mjs/array.extensions.d.ts +39 -0
- package/dist/mjs/array.extensions.js +300 -0
- package/dist/mjs/array.extensions.js.map +1 -0
- package/dist/mjs/big.int.extension.d.ts +31 -0
- package/dist/mjs/big.int.extension.js +161 -0
- package/dist/mjs/big.int.extension.js.map +1 -0
- package/dist/mjs/classes/asyncIterable.js.map +1 -0
- package/dist/mjs/classes/deferred.js.map +1 -0
- package/dist/mjs/{newClasses → classes}/descriptor.js +7 -4
- package/dist/mjs/classes/descriptor.js.map +1 -0
- package/dist/mjs/classes/index.d.ts +13 -0
- package/dist/mjs/classes/index.js +40 -0
- package/dist/mjs/classes/index.js.map +1 -0
- package/dist/mjs/classes/introspector.d.ts +20 -0
- package/dist/mjs/classes/introspector.js +126 -0
- package/dist/mjs/classes/introspector.js.map +1 -0
- package/dist/mjs/classes/iterable.js.map +1 -0
- package/dist/mjs/classes/param.parser.d.ts +227 -0
- package/dist/mjs/classes/param.parser.js +238 -0
- package/dist/mjs/classes/param.parser.js.map +1 -0
- package/dist/mjs/classes/pluggable.proxy.d.ts +152 -0
- package/dist/mjs/classes/pluggable.proxy.js +438 -0
- package/dist/mjs/classes/pluggable.proxy.js.map +1 -0
- package/dist/mjs/{newClasses → classes}/refmap.js +3 -3
- package/dist/mjs/classes/refmap.js.map +1 -0
- package/dist/mjs/classes/refset.js.map +1 -0
- package/dist/mjs/classes/symkeys.d.ts +292 -0
- package/dist/mjs/classes/symkeys.js +420 -0
- package/dist/mjs/classes/symkeys.js.map +1 -0
- package/dist/mjs/classes/type.d.ts +56 -0
- package/dist/mjs/classes/type.js +401 -0
- package/dist/mjs/classes/type.js.map +1 -0
- package/dist/mjs/function.extensions.js +754 -0
- package/dist/mjs/function.extensions.js.map +1 -0
- package/dist/mjs/global.this.js +258 -0
- package/dist/mjs/global.this.js.map +1 -0
- package/dist/mjs/index.d.ts +4 -3
- package/dist/mjs/index.js +49 -19
- package/dist/mjs/index.js.map +1 -1
- package/dist/mjs/json.extensions.d.ts +2 -0
- package/dist/mjs/json.extensions.js +104 -0
- package/dist/mjs/json.extensions.js.map +1 -0
- package/dist/{cjs/mapextensions.d.ts → mjs/map.extensions.d.ts} +1 -0
- package/dist/mjs/map.extensions.js +139 -0
- package/dist/mjs/map.extensions.js.map +1 -0
- package/dist/mjs/number.extension.d.ts +44 -0
- package/dist/mjs/number.extension.js +257 -0
- package/dist/mjs/number.extension.js.map +1 -0
- package/dist/mjs/object.extensions.d.ts +62 -0
- package/dist/mjs/object.extensions.js +1112 -0
- package/dist/mjs/object.extensions.js.map +1 -0
- package/dist/mjs/proxy.extensions.d.ts +2 -0
- package/dist/mjs/proxy.extensions.js +204 -0
- package/dist/mjs/proxy.extensions.js.map +1 -0
- package/dist/mjs/reflect.extensions.js +313 -0
- package/dist/mjs/reflect.extensions.js.map +1 -0
- package/dist/mjs/regular.expression.extensions.d.ts +2 -0
- package/dist/mjs/regular.expression.extensions.js +420 -0
- package/dist/mjs/regular.expression.extensions.js.map +1 -0
- package/dist/mjs/set.extensions.d.ts +40 -0
- package/dist/mjs/{setextensions.js → set.extensions.js} +149 -1
- package/dist/mjs/set.extensions.js.map +1 -0
- package/dist/mjs/string.extensions.js +468 -0
- package/dist/mjs/string.extensions.js.map +1 -0
- package/dist/{cjs/symbolextensions.d.ts → mjs/symbol.extensions.d.ts} +1 -0
- package/dist/mjs/symbol.extensions.js +256 -0
- package/dist/mjs/symbol.extensions.js.map +1 -0
- package/dist/mjs/{weakrefextensions.js → weakref.extensions.js} +1 -1
- package/dist/mjs/weakref.extensions.js.map +1 -0
- package/docs/index.html +24045 -5805
- package/package.json +6 -4
- package/repl.bootstrap.js +21 -0
- package/src/array.extensions.js +322 -0
- package/src/big.int.extension.js +163 -0
- package/src/{newClasses → classes}/descriptor.js +16 -12
- package/src/classes/index.js +51 -0
- package/src/classes/introspector.js +167 -0
- package/src/classes/param.parser.js +253 -0
- package/src/classes/pluggable.proxy.js +485 -0
- package/src/{newClasses → classes}/refmap.js +5 -3
- package/src/classes/symkeys.js +464 -0
- package/src/classes/type.js +427 -0
- package/src/function.extensions.js +818 -0
- package/src/global.this.js +304 -0
- package/src/index.js +56 -23
- package/src/json.extensions.js +108 -0
- package/src/map.extensions.js +144 -0
- package/src/number.extension.js +273 -0
- package/src/object.extensions.js +1222 -0
- package/src/proxy.extensions.js +229 -0
- package/src/reflect.extensions.js +346 -0
- package/src/regular.expression.extensions.js +451 -0
- package/src/{setextensions.js → set.extensions.js} +151 -2
- package/src/string.extensions.js +515 -0
- package/src/symbol.extensions.js +268 -0
- package/tests/newClasses/refmap.test.js +3 -2
- package/tsconfig.base.json +5 -3
- package/tsconfig.cjs.json +2 -2
- package/tsconfig.esm.json +2 -2
- package/dist/@nejs/basic-extensions.bundle.2.5.0.js +0 -8
- package/dist/@nejs/basic-extensions.bundle.2.5.0.js.map +0 -7
- package/dist/cjs/arrayextensions.d.ts +0 -10
- package/dist/cjs/arrayextensions.js +0 -73
- package/dist/cjs/arrayextensions.js.map +0 -1
- package/dist/cjs/functionextensions.js +0 -202
- package/dist/cjs/functionextensions.js.map +0 -1
- package/dist/cjs/globals.js +0 -166
- package/dist/cjs/globals.js.map +0 -1
- package/dist/cjs/mapextensions.js +0 -32
- package/dist/cjs/mapextensions.js.map +0 -1
- package/dist/cjs/newClasses/asyncIterable.js.map +0 -1
- package/dist/cjs/newClasses/deferred.js.map +0 -1
- package/dist/cjs/newClasses/descriptor.js.map +0 -1
- package/dist/cjs/newClasses/iterable.js.map +0 -1
- package/dist/cjs/newClasses/refmap.js.map +0 -1
- package/dist/cjs/newClasses/refset.js.map +0 -1
- package/dist/cjs/objectextensions.d.ts +0 -11
- package/dist/cjs/objectextensions.js +0 -232
- package/dist/cjs/objectextensions.js.map +0 -1
- package/dist/cjs/reflectextensions.js +0 -111
- package/dist/cjs/reflectextensions.js.map +0 -1
- package/dist/cjs/setextensions.d.ts +0 -2
- package/dist/cjs/setextensions.js.map +0 -1
- package/dist/cjs/stringextensions.js +0 -158
- package/dist/cjs/stringextensions.js.map +0 -1
- package/dist/cjs/symbolextensions.js +0 -69
- package/dist/cjs/symbolextensions.js.map +0 -1
- package/dist/cjs/weakrefextensions.js.map +0 -1
- package/dist/mjs/arrayextensions.d.ts +0 -10
- package/dist/mjs/arrayextensions.js +0 -70
- package/dist/mjs/arrayextensions.js.map +0 -1
- package/dist/mjs/functionextensions.js +0 -199
- package/dist/mjs/functionextensions.js.map +0 -1
- package/dist/mjs/globals.js +0 -163
- package/dist/mjs/globals.js.map +0 -1
- package/dist/mjs/mapextensions.js +0 -29
- package/dist/mjs/mapextensions.js.map +0 -1
- package/dist/mjs/newClasses/asyncIterable.js.map +0 -1
- package/dist/mjs/newClasses/deferred.js.map +0 -1
- package/dist/mjs/newClasses/descriptor.js.map +0 -1
- package/dist/mjs/newClasses/iterable.js.map +0 -1
- package/dist/mjs/newClasses/refmap.js.map +0 -1
- package/dist/mjs/newClasses/refset.js.map +0 -1
- package/dist/mjs/objectextensions.d.ts +0 -11
- package/dist/mjs/objectextensions.js +0 -229
- package/dist/mjs/objectextensions.js.map +0 -1
- package/dist/mjs/reflectextensions.js +0 -108
- package/dist/mjs/reflectextensions.js.map +0 -1
- package/dist/mjs/setextensions.d.ts +0 -2
- package/dist/mjs/setextensions.js.map +0 -1
- package/dist/mjs/stringextensions.js +0 -155
- package/dist/mjs/stringextensions.js.map +0 -1
- package/dist/mjs/symbolextensions.js +0 -66
- package/dist/mjs/symbolextensions.js.map +0 -1
- package/dist/mjs/weakrefextensions.js.map +0 -1
- package/src/arrayextensions.js +0 -75
- package/src/functionextensions.js +0 -225
- package/src/globals.js +0 -196
- package/src/mapextensions.js +0 -32
- package/src/objectextensions.js +0 -256
- package/src/reflectextensions.js +0 -118
- package/src/stringextensions.js +0 -166
- package/src/symbolextensions.js +0 -69
- /package/dist/cjs/{newClasses → classes}/asyncIterable.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/deferred.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/descriptor.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/iterable.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/refmap.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/refset.d.ts +0 -0
- /package/dist/cjs/{functionextensions.d.ts → function.extensions.d.ts} +0 -0
- /package/dist/cjs/{globals.d.ts → global.this.d.ts} +0 -0
- /package/dist/cjs/{reflectextensions.d.ts → reflect.extensions.d.ts} +0 -0
- /package/dist/cjs/{stringextensions.d.ts → string.extensions.d.ts} +0 -0
- /package/dist/cjs/{weakrefextensions.d.ts → weakref.extensions.d.ts} +0 -0
- /package/dist/mjs/{newClasses → classes}/asyncIterable.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/asyncIterable.js +0 -0
- /package/dist/mjs/{newClasses → classes}/deferred.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/deferred.js +0 -0
- /package/dist/mjs/{newClasses → classes}/descriptor.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/iterable.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/iterable.js +0 -0
- /package/dist/mjs/{newClasses → classes}/refmap.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/refset.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/refset.js +0 -0
- /package/dist/mjs/{functionextensions.d.ts → function.extensions.d.ts} +0 -0
- /package/dist/mjs/{globals.d.ts → global.this.d.ts} +0 -0
- /package/dist/mjs/{reflectextensions.d.ts → reflect.extensions.d.ts} +0 -0
- /package/dist/mjs/{stringextensions.d.ts → string.extensions.d.ts} +0 -0
- /package/dist/mjs/{weakrefextensions.d.ts → weakref.extensions.d.ts} +0 -0
- /package/src/{newClasses → classes}/asyncIterable.js +0 -0
- /package/src/{newClasses → classes}/deferred.js +0 -0
- /package/src/{newClasses → classes}/iterable.js +0 -0
- /package/src/{newClasses → classes}/refset.js +0 -0
- /package/src/{weakrefextensions.js → weakref.extensions.js} +0 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { Patch } from '@nejs/extension'
|
|
2
|
+
import { FunctionExtensions } from './function.extensions.js'
|
|
3
|
+
|
|
4
|
+
const { isClass, isFunction } = FunctionExtensions.patches
|
|
5
|
+
const CustomInspect = Symbol.for('nodejs.util.inspect.custom')
|
|
6
|
+
|
|
7
|
+
export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
8
|
+
[Patch.kMutablyHidden]: {
|
|
9
|
+
/**
|
|
10
|
+
* The `isThenElse` function is a utility function that behaves like a
|
|
11
|
+
* ternary operator. It takes three arguments: `boolValue`, `thenValue`,
|
|
12
|
+
* and `elseValue`.
|
|
13
|
+
*
|
|
14
|
+
* It first checks the truthiness of `boolValue`.
|
|
15
|
+
*
|
|
16
|
+
* If `boolValue` is truthy, it returns `thenValue`; otherwise,
|
|
17
|
+
* it returns `elseValue`.
|
|
18
|
+
*
|
|
19
|
+
* If `thenValue` or `elseValue` is a function, it will be invoked with
|
|
20
|
+
* `boolValue` as an argument.
|
|
21
|
+
*
|
|
22
|
+
* If `elseValue` is not provided, it returns `boolValue` or `thenValue`
|
|
23
|
+
* depending on the truthiness of `boolValue`.
|
|
24
|
+
*
|
|
25
|
+
* If only `boolValue` is provided, it simply returns `boolValue`.
|
|
26
|
+
*
|
|
27
|
+
* @param {any} boolValue - Any object or value that is tested for
|
|
28
|
+
* truthiness.
|
|
29
|
+
* @param {function | any} [thenValue] - The value to return if `boolValue`
|
|
30
|
+
* is truthy. If a function, it's invoked with `boolValue`.
|
|
31
|
+
* @param {function | any} [elseValue] - The value to return if `boolValue`
|
|
32
|
+
* is falsy. If a function, it's invoked with `boolValue`.
|
|
33
|
+
* @returns {boolean | any} The result of the ternary operation.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Using values
|
|
37
|
+
* isThenElse(true, 'yes', 'no'); // Returns: 'yes'
|
|
38
|
+
* isThenElse(false, 'yes', 'no'); // Returns: 'no'
|
|
39
|
+
*
|
|
40
|
+
* // Using functions
|
|
41
|
+
* isThenElse(true, val => val ? 'yes' : 'no'); // Returns: 'yes'
|
|
42
|
+
* isThenElse(false, val => val ? 'yes' : 'no'); // Returns: 'no'
|
|
43
|
+
*/
|
|
44
|
+
isThenElse(boolValue, thenValue, elseValue) {
|
|
45
|
+
if (arguments.length > 1) {
|
|
46
|
+
const _then = isFunction(thenValue) ? thenValue(boolValue) : thenValue
|
|
47
|
+
|
|
48
|
+
if (arguments.length > 2) {
|
|
49
|
+
const _else = isFunction(elseValue) ? thenValue(boolValue) : elseValue
|
|
50
|
+
|
|
51
|
+
return boolValue ? _then : _else
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return boolValue || _then
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return boolValue
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Transforms an object to mimic a specified prototype, altering its type
|
|
62
|
+
* conversion and inspection behaviors. This function is especially useful
|
|
63
|
+
* for creating objects that need to behave like different primitive types
|
|
64
|
+
* under various operations.
|
|
65
|
+
*
|
|
66
|
+
* @param {Object} object - The object to be transformed.
|
|
67
|
+
* @param {Function|Object} [prototype=String.prototype] - The prototype or
|
|
68
|
+
* class to emulate. If a function is provided, its prototype is used.
|
|
69
|
+
* Defaults to String.prototype.
|
|
70
|
+
* @param {Function} [toPrimitive=(hint, val) => String(val)] - A function
|
|
71
|
+
* defining how the object should be converted to a primitive value. It
|
|
72
|
+
* receives a type hint ('number', 'string', or 'default') and the object,
|
|
73
|
+
* returning the primitive value.
|
|
74
|
+
* @returns {Object|null} The transformed object, or null if neither a class
|
|
75
|
+
* nor a prototype could be derived from the provided prototype parameter.
|
|
76
|
+
*/
|
|
77
|
+
maskAs(object, classPrototype, options) {
|
|
78
|
+
const {
|
|
79
|
+
prototype,
|
|
80
|
+
toPrimitive
|
|
81
|
+
} = GenericMask({...options, prototype: classPrototype})
|
|
82
|
+
|
|
83
|
+
const base = { configurable: true, enumerable: false }
|
|
84
|
+
const proto = isFunction(prototype) ? prototype.prototype : prototype
|
|
85
|
+
const klass = isClass(prototype) ? prototype : proto?.constructor
|
|
86
|
+
|
|
87
|
+
if (!klass && !proto) {
|
|
88
|
+
return null
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Object.setPrototypeOf(object, proto)
|
|
92
|
+
Object.defineProperties(object, {
|
|
93
|
+
valueOf: {
|
|
94
|
+
value() { return String(toPrimitive('default', object)) }, ...base },
|
|
95
|
+
|
|
96
|
+
[Symbol.toPrimitive]: {
|
|
97
|
+
value(hint) { return toPrimitive(hint, object) }, ...base
|
|
98
|
+
},
|
|
99
|
+
[Symbol.toStringTag]: { value: klass.name, ...base },
|
|
100
|
+
[Symbol.species]: { get() { return klass }, ...base },
|
|
101
|
+
[CustomInspect]: { ...base, value(depth, opts, inspect) {
|
|
102
|
+
return inspect(this[Symbol.toPrimitive](), { ...opts, depth })
|
|
103
|
+
}}
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
return object
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Masks an object as a string-like object by setting its prototype to
|
|
111
|
+
* String and defining how it converts to primitive types. This is
|
|
112
|
+
* particularly useful when an object needs to behave like a string in
|
|
113
|
+
* certain contexts, such as type coercion or logging.
|
|
114
|
+
*
|
|
115
|
+
* @param {Object} object - The object to be masked as a string.
|
|
116
|
+
* @param {string} [stringKey='value'] - The object property key used for
|
|
117
|
+
* the string representation. Defaults to 'value'.
|
|
118
|
+
* @param {Function} [toPrimitive] - Optional custom function for primitive
|
|
119
|
+
* conversion. If omitted, a default function handling various conversion
|
|
120
|
+
* hints is used.
|
|
121
|
+
* @returns {Object|null} The string-masked object, or null if the object
|
|
122
|
+
* doesn't have the specified stringKey property.
|
|
123
|
+
*/
|
|
124
|
+
maskAsString(
|
|
125
|
+
object,
|
|
126
|
+
stringKey,
|
|
127
|
+
toPrimitive
|
|
128
|
+
) {
|
|
129
|
+
if (object && Reflect.has(object, stringKey)) {
|
|
130
|
+
return maskAs(object, StringMask(stringKey ?? 'value', toPrimitive))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return null
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Masks an object as a number-like object. This allows the object to
|
|
138
|
+
* behave like a number in operations like arithmetic and type coercion.
|
|
139
|
+
* It sets the prototype to Number and defines custom conversion behavior.
|
|
140
|
+
*
|
|
141
|
+
* @param {Object} object - The object to be masked as a number
|
|
142
|
+
* representation. Defaults to 'value'.
|
|
143
|
+
* @param {Function} [toPrimitive] - Optional custom function for primitive
|
|
144
|
+
* conversion. If not provided, a default function handling different
|
|
145
|
+
* conversion hints is used.
|
|
146
|
+
* @returns {Object|null} The number-masked object, or null if the object
|
|
147
|
+
* doesn't have the specified numberKey property.
|
|
148
|
+
*/
|
|
149
|
+
maskAsNumber(
|
|
150
|
+
object,
|
|
151
|
+
numberKey,
|
|
152
|
+
toPrimitive
|
|
153
|
+
) {
|
|
154
|
+
if (object && Reflect.has(object, numberKey)) {
|
|
155
|
+
return maskAs(object, NumberMask(numberKey ?? 'value', toPrimitive))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return null
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Generates options for generic masking of an object, providing defaults for
|
|
163
|
+
* prototype and toPrimitive function if not specified.
|
|
164
|
+
*
|
|
165
|
+
* @param {Object} options - The options object including prototype,
|
|
166
|
+
* targetKey, and toPrimitive function.
|
|
167
|
+
* @returns {Object} The options object with defaults applied as necessary.
|
|
168
|
+
*/
|
|
169
|
+
GenericMask({ prototype, targetKey = 'value', toPrimitive }) {
|
|
170
|
+
const options = { targetKey, toPrimitive, prototype };
|
|
171
|
+
|
|
172
|
+
if (!isFunction(toPrimitive)) {
|
|
173
|
+
options.toPrimitive = (hint, object) => {
|
|
174
|
+
let property = object[targetKey];
|
|
175
|
+
let isNum = (
|
|
176
|
+
(typeof property === 'number' && Number.isFinite(property)) ||
|
|
177
|
+
(typeof property === 'string' &&
|
|
178
|
+
!isNaN(parseFloat(property)) && isFinite(property)
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
switch (hint) {
|
|
183
|
+
case 'string':
|
|
184
|
+
return isNum ? String(property) : (property ?? String(object));
|
|
185
|
+
case 'number':
|
|
186
|
+
return isNum ? Number(property) : NaN;
|
|
187
|
+
case 'default':
|
|
188
|
+
default:
|
|
189
|
+
return isNum ? Number(property) : property;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return options;
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Generates options for string masking of an object, providing a default
|
|
199
|
+
* toPrimitive function if not specified.
|
|
200
|
+
*
|
|
201
|
+
* @param {string} targetKey - The object property key for string
|
|
202
|
+
* representation.
|
|
203
|
+
* @param {Function} toPrimitive - Custom function for primitive conversion.
|
|
204
|
+
* @returns {Object} Options for string masking.
|
|
205
|
+
*/
|
|
206
|
+
StringMask(targetKey, toPrimitive) {
|
|
207
|
+
const options = { targetKey, toPrimitive, prototype: String.prototype }
|
|
208
|
+
|
|
209
|
+
if (!isFunction(toPrimitive)) {
|
|
210
|
+
options.toPrimitive = function toPrimitive(hint, object) {
|
|
211
|
+
switch (hint) {
|
|
212
|
+
case 'default': return object[targetKey]
|
|
213
|
+
case 'number': return parseInt(object[targetKey], 36)
|
|
214
|
+
case 'string': return String(object[targetKey])
|
|
215
|
+
default: return object
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return options
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Generates options for number masking of an object, providing a default
|
|
225
|
+
* toPrimitive function if not specified.
|
|
226
|
+
*
|
|
227
|
+
* @param {string} targetKey - The object property key for number
|
|
228
|
+
* representation.
|
|
229
|
+
* @param {Function} toPrimitive - Custom function for primitive conversion.
|
|
230
|
+
* @returns {Object} Options for number masking.
|
|
231
|
+
*/
|
|
232
|
+
NumberMask(targetKey, toPrimitive) {
|
|
233
|
+
const options = { targetKey, toPrimitive, prototype: Number.prototype }
|
|
234
|
+
|
|
235
|
+
if (!isFunction(toPrimitive)) {
|
|
236
|
+
options.toPrimitive = function toPrimitive(hint, object) {
|
|
237
|
+
switch (hint) {
|
|
238
|
+
case 'default': return object[targetKey]
|
|
239
|
+
case 'number': return Number(object[targetKey])
|
|
240
|
+
case 'string': return String(object[targetKey])
|
|
241
|
+
default: return object
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return options
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Blends the properties of multiple objects into a new object. This
|
|
251
|
+
* function creates a new object that inherits the prototype from the
|
|
252
|
+
* root object and the properties of the other objects and their parent
|
|
253
|
+
* prototypes.
|
|
254
|
+
*
|
|
255
|
+
* @param {Object} root - The root object to blend prototypes into.
|
|
256
|
+
* @param {...Object} objects - The objects whose prototypes to blend.
|
|
257
|
+
* @returns {Object} The new object with blended prototypes.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* // Define some objects with properties
|
|
261
|
+
* const obj1 = { prop1: 'value1' }
|
|
262
|
+
* const obj2 = { prop2: 'value2' }
|
|
263
|
+
* const obj3 = { prop3: 'value3' }
|
|
264
|
+
*
|
|
265
|
+
* // Blend the prototypes of obj2 and obj3 into obj1
|
|
266
|
+
* const blended = blendProtos(obj1, obj2, obj3)
|
|
267
|
+
*
|
|
268
|
+
* // Now blended has properties from obj1, obj2, and obj3
|
|
269
|
+
* console.log(blended.prop1) // Outputs: 'value1'
|
|
270
|
+
* console.log(blended.prop2) // Outputs: 'value2'
|
|
271
|
+
* console.log(blended.prop3) // Outputs: 'value3'
|
|
272
|
+
*/
|
|
273
|
+
blendProtos(root, ...objects) {
|
|
274
|
+
const descriptor = (o, k) => Object.getOwnPropertyDescriptor(o,k)
|
|
275
|
+
const parent = o => Object.getPrototypeOf(o)
|
|
276
|
+
const all = o => (Reflect
|
|
277
|
+
.ownKeys(o)
|
|
278
|
+
.reduce((a, k)=>({ ...a, [k]: descriptor(o,k) }), { })
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
const newRoot = Object.create(parent(root), objects.reduce)
|
|
282
|
+
const protos = objects.map(object => parent(object))
|
|
283
|
+
|
|
284
|
+
let descriptors = Object.create(null)
|
|
285
|
+
let uniques = new Set
|
|
286
|
+
|
|
287
|
+
for (let object of protos) {
|
|
288
|
+
let current = object
|
|
289
|
+
|
|
290
|
+
while (current) {
|
|
291
|
+
if (!uniques.has(current)) {
|
|
292
|
+
uniques.add(current)
|
|
293
|
+
descriptors = { ...descriptors, ...all(current) }
|
|
294
|
+
}
|
|
295
|
+
current = parent(current)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const blendedPrototype = Object.create(parent(root), descriptors)
|
|
300
|
+
|
|
301
|
+
return Object.setPrototypeOf(newRoot, blendedPrototype)
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
})
|
package/src/index.js
CHANGED
|
@@ -1,42 +1,62 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
1
|
+
import { ArrayExtensions, ArrayPrototypeExtensions } from './array.extensions.js'
|
|
2
|
+
import { BigIntExtensions, BigIntPrototypeExtensions } from './big.int.extension.js'
|
|
3
|
+
import { FunctionExtensions, FunctionPrototypeExtensions } from './function.extensions.js'
|
|
4
|
+
import { GlobalFunctionsAndProps } from './global.this.js'
|
|
5
|
+
import { JSONExtensions } from './json.extensions.js'
|
|
6
|
+
import { MapExtensions, MapPrototypeExtensions } from './map.extensions.js'
|
|
7
|
+
import { NumberExtensions, NumberPrototypeExtensions } from './number.extension.js'
|
|
8
|
+
import { ObjectExtensions, ObjectPrototypeExtensions } from './object.extensions.js'
|
|
9
|
+
import { ReflectExtensions } from './reflect.extensions.js'
|
|
10
|
+
import { RegExpExtensions } from './regular.expression.extensions.js'
|
|
11
|
+
import { SetExtensions, SetPrototypeExtensions } from './set.extensions.js'
|
|
12
|
+
import { StringExtensions, StringPrototypeExtensions } from './string.extensions.js'
|
|
13
|
+
import { SymbolExtensions, SymbolPrototypeExtensions } from './symbol.extensions.js'
|
|
14
|
+
|
|
15
|
+
import { DeferredExtension } from './classes/deferred.js'
|
|
16
|
+
import { DescriptorExtensions, Descriptor } from './classes/descriptor.js'
|
|
17
|
+
import { IntrospectorExtensions } from './classes/introspector.js'
|
|
18
|
+
import { IteratorExtensions, IterableExtensions } from './classes/iterable.js'
|
|
19
|
+
import { ParamParserExtensions } from './classes/param.parser.js'
|
|
20
|
+
import {
|
|
21
|
+
PluggableProxyExtensions,
|
|
22
|
+
ProxyHandlerExtensions,
|
|
23
|
+
PluggableProxyExtensionSet
|
|
24
|
+
} from './classes/pluggable.proxy.js'
|
|
25
|
+
import { RefMapExtensions } from './classes/refmap.js'
|
|
26
|
+
import { RefSetExtensions } from './classes/refset.js'
|
|
27
|
+
import { SymkeysExtension } from './classes/symkeys.js'
|
|
28
|
+
import { TypeExtensions } from './classes/type.js'
|
|
14
29
|
|
|
15
30
|
import {
|
|
16
31
|
AsyncIteratorExtensions,
|
|
17
32
|
AsyncIterableExtensions
|
|
18
|
-
} from './
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
IteratorExtensions,
|
|
22
|
-
IterableExtensions
|
|
23
|
-
} from './newClasses/iterable.js'
|
|
33
|
+
} from './classes/asyncIterable.js'
|
|
24
34
|
|
|
25
35
|
const StaticPatches = [
|
|
26
|
-
[
|
|
36
|
+
[Array, ArrayExtensions, Array.name],
|
|
37
|
+
[BigInt, BigIntExtensions, BigInt.name],
|
|
27
38
|
[Function, FunctionExtensions, Function.name],
|
|
39
|
+
[JSON, JSONExtensions, 'JSON'], // Missing a .name property
|
|
40
|
+
[Map, MapExtensions, Map.name],
|
|
41
|
+
[Number, NumberExtensions, Number.name],
|
|
42
|
+
[Object, ObjectExtensions, Object.name],
|
|
28
43
|
[Reflect, ReflectExtensions, 'Reflect'], // Missing a .name property
|
|
44
|
+
[RegExp, RegExpExtensions, RegExp.name],
|
|
45
|
+
[Set, SetExtensions, Set.name],
|
|
29
46
|
[String, StringExtensions, String.name],
|
|
30
47
|
[Symbol, SymbolExtensions, 'Symbol'], // Missing a .name property
|
|
31
48
|
]
|
|
32
49
|
|
|
33
50
|
const InstancePatches = [
|
|
34
|
-
[Object.prototype, ObjectPrototypeExtensions, Object.name],
|
|
35
|
-
[String.prototype, StringPrototypeExtensions, String.name],
|
|
36
|
-
[Function.prototype, FunctionPrototypeExtensions, Function.name],
|
|
37
51
|
[Array.prototype, ArrayPrototypeExtensions, Array.name],
|
|
52
|
+
[BigInt.prototype, BigIntPrototypeExtensions, BigInt.name],
|
|
53
|
+
[Function.prototype, FunctionPrototypeExtensions, Function.name],
|
|
38
54
|
[Map.prototype, MapPrototypeExtensions, Map.name],
|
|
55
|
+
[Number.prototype, NumberPrototypeExtensions, Number.name],
|
|
56
|
+
[Object.prototype, ObjectPrototypeExtensions, Object.name],
|
|
39
57
|
[Set.prototype, SetPrototypeExtensions, Set.name],
|
|
58
|
+
[String.prototype, StringPrototypeExtensions, String.name],
|
|
59
|
+
[Symbol.prototype, SymbolPrototypeExtensions, Symbol.name],
|
|
40
60
|
]
|
|
41
61
|
|
|
42
62
|
const Patches = new Map([
|
|
@@ -49,12 +69,25 @@ const Extensions = {
|
|
|
49
69
|
[AsyncIteratorExtensions.key]: AsyncIteratorExtensions,
|
|
50
70
|
[DeferredExtension.key]: DeferredExtension,
|
|
51
71
|
[DescriptorExtensions.key]: DescriptorExtensions,
|
|
72
|
+
[IntrospectorExtensions.key]: IntrospectorExtensions,
|
|
52
73
|
[IterableExtensions.key]: IterableExtensions,
|
|
53
74
|
[IteratorExtensions.key]: IteratorExtensions,
|
|
75
|
+
[ParamParserExtensions.key]: ParamParserExtensions,
|
|
76
|
+
[PluggableProxyExtensions.key]: PluggableProxyExtensions,
|
|
77
|
+
[ProxyHandlerExtensions.key]: ProxyHandlerExtensions,
|
|
54
78
|
[RefMapExtensions.key]: RefMapExtensions,
|
|
55
79
|
[RefSetExtensions.key]: RefSetExtensions,
|
|
80
|
+
[SymkeysExtension.key]: SymkeysExtension,
|
|
81
|
+
[TypeExtensions.key]: TypeExtensions,
|
|
56
82
|
}
|
|
57
83
|
|
|
84
|
+
export const Classes = {}
|
|
85
|
+
for (const extension of Object.values(Extensions)) {
|
|
86
|
+
const fnOrClass = extension.class || extension.function
|
|
87
|
+
Classes[fnOrClass.name] = fnOrClass
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
58
91
|
const Controls = {}
|
|
59
92
|
|
|
60
93
|
Object.assign(Controls, {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Patch } from '@nejs/extension'
|
|
2
|
+
|
|
3
|
+
export const JSONExtensions = new Patch(JSON, {
|
|
4
|
+
[Patch.kMutablyHidden]: {
|
|
5
|
+
/**
|
|
6
|
+
* The `extractFrom` method attempts to extract a JSON object from a string.
|
|
7
|
+
* It uses a regular expression to identify potential JSON objects in the
|
|
8
|
+
* string and attempts to parse them. If a valid JSON object is found, it is
|
|
9
|
+
* returned. If no valid JSON object is found, the method returns undefined.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: This method will only find JSON from an iterated upon start spot
|
|
12
|
+
* until the end of the string. So `'JSON follows {"count": 0}'` will
|
|
13
|
+
* return `{count: 0}` but `'JSON follows {"count": 0} and more'` will
|
|
14
|
+
* fail to locate any JSON in the String. You've been warned.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} string - The string from which to extract a JSON object.
|
|
17
|
+
* @returns {Object|undefined} - The first valid JSON object found in the
|
|
18
|
+
* string, or undefined if no valid JSON object is found.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Suppose we have a string with embedded JSON
|
|
22
|
+
* const str1 = 'Hello {"name":"John", "age":30} World'
|
|
23
|
+
* const str2 = 'Hello {"name": "John", "age": 30}'
|
|
24
|
+
*
|
|
25
|
+
* // Using `extractFrom`
|
|
26
|
+
* console.log(JSON.extractFrom(str1)) // Output: undefined
|
|
27
|
+
* console.log(JSON.extractFrom(str2)) // Output: {name: 'John', age: 30}
|
|
28
|
+
*/
|
|
29
|
+
extractFrom(string) {
|
|
30
|
+
const pattern = /([\w\{\[\"]+) ?/g
|
|
31
|
+
const decoder = part => {
|
|
32
|
+
try { return JSON.parse(part) } catch (_) { return undefined }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (
|
|
36
|
+
let part = pattern.exec(string);
|
|
37
|
+
part;
|
|
38
|
+
part = pattern.exec(string)
|
|
39
|
+
) {
|
|
40
|
+
if (part && part?.index) {
|
|
41
|
+
const decoded = decoder(string.substring(part.index))
|
|
42
|
+
if (decoded) {
|
|
43
|
+
return decoded
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return undefined
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The `mightContain` method checks if a string might contain a JSON object.
|
|
53
|
+
* It uses the `JSONStartPattern` regular expression to search for potential
|
|
54
|
+
* JSON objects in the string. If a potential JSON object is found, the method
|
|
55
|
+
* returns true. If no potential JSON object is found, the method returns false.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} string - The string to check for potential JSON objects.
|
|
58
|
+
* @returns {boolean} - Returns true if the string might contain a JSON object,
|
|
59
|
+
* false otherwise.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Suppose we have a string with embedded JSON
|
|
63
|
+
* const str = 'Hello {"name":"John", "age":30} World'
|
|
64
|
+
*
|
|
65
|
+
* // Using `mightContain`
|
|
66
|
+
* console.log(JSON.mightContain(str)) // Output: true
|
|
67
|
+
*/
|
|
68
|
+
mightContain(string) {
|
|
69
|
+
return !!this.JSONStartPattern.exec(string)
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Getter method for the JSONStartPattern.
|
|
74
|
+
*
|
|
75
|
+
* This method constructs a regular expression pattern that is used to
|
|
76
|
+
* identify potential JSON objects in a string. The pattern is designed
|
|
77
|
+
* to match various JSON data types including null, boolean, number,
|
|
78
|
+
* string, object, and array.
|
|
79
|
+
*
|
|
80
|
+
* The pattern is constructed using an array of strings, each representing
|
|
81
|
+
* a part of the pattern. The array is then joined into a single string
|
|
82
|
+
* and passed to the RegExp constructor to create the pattern.
|
|
83
|
+
*
|
|
84
|
+
* @returns {RegExp} - The constructed regular expression pattern.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // Using `JSONStartPattern`
|
|
88
|
+
* const pattern = JSONStartPattern;
|
|
89
|
+
* const str = 'Hello {"name":"John", "age":30} World';
|
|
90
|
+
* const match = pattern.exec(str);
|
|
91
|
+
* console.log(match[0]); // Output: '{"name":"John", "age":30}'
|
|
92
|
+
*/
|
|
93
|
+
get JSONStartPattern() {
|
|
94
|
+
const pattern = new RegExp([
|
|
95
|
+
'(?:', // Start with a non-capturing group and match
|
|
96
|
+
'(null)|', // ...a null
|
|
97
|
+
'(true|false)|', // ...a bool
|
|
98
|
+
'(\\d+\\.?\\d*)|', // ...a number (including floats)
|
|
99
|
+
'("[^\\"]*(?:[^:])")|', // ...a double quote (start of string)
|
|
100
|
+
'((?:\\{.*\\})+)|', // ...an open curly brace (object)
|
|
101
|
+
'((?:\\[.*\\]+))', // ...an open square bracket (array)
|
|
102
|
+
')+', // End of the groups
|
|
103
|
+
].join(''), 'gm')
|
|
104
|
+
|
|
105
|
+
return pattern
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
})
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Patch } from '@nejs/extension'
|
|
2
|
+
|
|
3
|
+
export const MapExtensions = new Patch(Map, {
|
|
4
|
+
[Patch.kMutablyHidden]: {
|
|
5
|
+
/**
|
|
6
|
+
* Determines if the supplied `value` is a `Map` object. This check
|
|
7
|
+
* is performed by first looking for the `Symbol.toStringTag` on the
|
|
8
|
+
* `value` and checking to see if it is equal to the string "Map".
|
|
9
|
+
* If that check fails, `instanceof` is used as a fallback to check
|
|
10
|
+
* the prototype chain.
|
|
11
|
+
*
|
|
12
|
+
* @param {any} value the value that needs to be checked to determine
|
|
13
|
+
* if it is a `Map` object or not
|
|
14
|
+
* @returns {boolean} `true` if the supplied `value` is a `Map`
|
|
15
|
+
* object, `false` otherwise
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const map = new Map()
|
|
19
|
+
* isMap(map) // true
|
|
20
|
+
* isMap(new Set()) // false
|
|
21
|
+
* isMap([]) // false
|
|
22
|
+
* isMap({}) // false
|
|
23
|
+
*/
|
|
24
|
+
isMap(value) {
|
|
25
|
+
return value?.[Symbol.toStringTag] === Map.name && value instanceof Map
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Conditionally returns a value based on whether the supplied
|
|
30
|
+
* `value` is a `Map` object or not. If the `value` is a `Map`
|
|
31
|
+
* object, the `thenValue` will be returned. If it is not a `Map`
|
|
32
|
+
* object, the `elseValue` will be returned instead.
|
|
33
|
+
*
|
|
34
|
+
* @param {any} value the value to check to determine if it is a
|
|
35
|
+
* `Map` object
|
|
36
|
+
* @param {any} thenValue the value to return if the supplied
|
|
37
|
+
* `value` is a `Map` object
|
|
38
|
+
* @param {any} elseValue the value to return if the supplied
|
|
39
|
+
* `value` is not a `Map` object
|
|
40
|
+
* @returns {any} either the `thenValue` or `elseValue` depending
|
|
41
|
+
* on if the supplied `value` is a `Map` object
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const map = new Map()
|
|
45
|
+
* const set = new Set()
|
|
46
|
+
* ifMap(map, 'is a map', 'not a map') // 'is a map'
|
|
47
|
+
* ifMap(set, 'is a map', 'not a map') // 'not a map'
|
|
48
|
+
*/
|
|
49
|
+
ifMap(value, thenValue, elseValue) {
|
|
50
|
+
return isThenElse(this.isMap(value), thenValue, elseValue)
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const { isMap: pIsMap, ifMap: pIfMap } = MapExtensions.patches
|
|
56
|
+
|
|
57
|
+
export const MapPrototypeExtensions = new Patch(Map.prototype, {
|
|
58
|
+
[Patch.kMutablyHidden]: {
|
|
59
|
+
/**
|
|
60
|
+
* Determines if the current object is a `Map` object
|
|
61
|
+
*
|
|
62
|
+
* This is a getter that uses the `isMap` function from the
|
|
63
|
+
* `MapExtensions` patch to check if the current object (`this`) is
|
|
64
|
+
* a `Map` object
|
|
65
|
+
*
|
|
66
|
+
* @type {boolean}
|
|
67
|
+
* @readonly
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* const map = new Map()
|
|
71
|
+
* console.log(map.isMap) // Output: true
|
|
72
|
+
*
|
|
73
|
+
* const notMap = {}
|
|
74
|
+
* console.log(notMap.isMap) // Output: false
|
|
75
|
+
*/
|
|
76
|
+
get isMap() {
|
|
77
|
+
return pIsMap(this)
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Conditionally returns a value based on whether the current
|
|
82
|
+
* object is a `Map` object or not
|
|
83
|
+
*
|
|
84
|
+
* If the current object is a `Map` object, the `thenValue` will
|
|
85
|
+
* be returned. If it is not a `Map` object, the `elseValue` will
|
|
86
|
+
* be returned instead.
|
|
87
|
+
*
|
|
88
|
+
* @param {any} thenValue the value to return if the current
|
|
89
|
+
* object is a `Map` object
|
|
90
|
+
* @param {any} elseValue the value to return if the current
|
|
91
|
+
* object is not a `Map` object
|
|
92
|
+
* @returns {any} either the `thenValue` or `elseValue` depending
|
|
93
|
+
* on if the current object is a `Map` object
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* const map = new Map()
|
|
97
|
+
* map.ifMap('is a map', 'not a map') // 'is a map'
|
|
98
|
+
*
|
|
99
|
+
* const notMap = {}
|
|
100
|
+
* notMap.ifMap('is a map', 'not a map') // 'not a map'
|
|
101
|
+
*/
|
|
102
|
+
ifMap(thenValue, elseValue) {
|
|
103
|
+
return pIfMap(this, thenValue, elseValue)
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The function `getKey` returns the key associated with a given value
|
|
108
|
+
* in a map.
|
|
109
|
+
*
|
|
110
|
+
* @param {any} value - The value parameter is the value that you want to
|
|
111
|
+
* find the corresponding key for in the map.
|
|
112
|
+
* @param [strict=true] - The "strict" parameter is a boolean value that
|
|
113
|
+
* determines whether strict equality (===) or loose equality (==) should
|
|
114
|
+
* be used when comparing the "value" parameter with the values in the
|
|
115
|
+
* entries of the object. If "strict" is set to true, strict equality will
|
|
116
|
+
* be used.
|
|
117
|
+
* @returns the key associated with the given value. If a matching key is
|
|
118
|
+
* found, it is returned. If no matching key is found, null is returned.
|
|
119
|
+
*/
|
|
120
|
+
getKey(value, strict = true) {
|
|
121
|
+
for (const [key, entryValue] of this) {
|
|
122
|
+
if (
|
|
123
|
+
(strict && value === entryValue) &&
|
|
124
|
+
(!strict && value == entryValue)
|
|
125
|
+
) {
|
|
126
|
+
return key
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
// NOTE to self; this is repeated here otherwise a circular reference from
|
|
136
|
+
// Object<->Function<->Global occurs. See original source in global.this.js
|
|
137
|
+
// {@see globalThis.isThenElse}
|
|
138
|
+
function isThenElse(bv, tv, ev) {
|
|
139
|
+
if (arguments.length > 1) {
|
|
140
|
+
var _then = isFunction(tv) ? tv(bv) : tv; if (arguments.length > 2) {
|
|
141
|
+
var _else = isFunction(ev) ? tv(bv) : ev; return bv ? _then : _else
|
|
142
|
+
} return bv || _then;
|
|
143
|
+
} return bv
|
|
144
|
+
}
|