@nejs/basic-extensions 1.6.0 → 1.7.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/.esdoc.json +9 -0
- package/README.md +2025 -11
- package/bin/clean +6 -0
- package/dist/@nejs/basic-extensions.bundle.1.6.1.js +4 -0
- package/dist/@nejs/basic-extensions.bundle.1.6.1.js.map +7 -0
- package/dist/cjs/arrayextensions.js +1 -0
- package/dist/cjs/arrayextensions.js.map +1 -0
- package/dist/cjs/functionextensions.js +1 -0
- package/dist/cjs/functionextensions.js.map +1 -0
- package/dist/cjs/globals.js +2 -1
- package/dist/cjs/globals.js.map +1 -0
- package/dist/cjs/index.d.ts +10 -19
- package/dist/cjs/index.js +69 -76
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/mapextensions.d.ts +2 -0
- package/dist/cjs/mapextensions.js +30 -0
- package/dist/cjs/mapextensions.js.map +1 -0
- package/dist/cjs/newClasses/asyncIterable.d.ts +123 -0
- package/dist/cjs/{asyncIterable.js → newClasses/asyncIterable.js} +7 -4
- package/dist/cjs/newClasses/asyncIterable.js.map +1 -0
- package/dist/cjs/newClasses/descriptor.d.ts +401 -0
- package/dist/cjs/{descriptor.js → newClasses/descriptor.js} +150 -80
- package/dist/cjs/newClasses/descriptor.js.map +1 -0
- package/dist/cjs/newClasses/iterable.d.ts +125 -0
- package/dist/cjs/{iterable.js → newClasses/iterable.js} +36 -10
- package/dist/cjs/newClasses/iterable.js.map +1 -0
- package/dist/cjs/newClasses/refmap.d.ts +238 -0
- package/dist/cjs/newClasses/refmap.js +433 -0
- package/dist/cjs/newClasses/refmap.js.map +1 -0
- package/dist/cjs/newClasses/refset.d.ts +186 -0
- package/dist/cjs/{refset.js → newClasses/refset.js} +18 -3
- package/dist/cjs/newClasses/refset.js.map +1 -0
- package/dist/cjs/objectextensions.d.ts +7 -6
- package/dist/cjs/objectextensions.js +85 -43
- package/dist/cjs/objectextensions.js.map +1 -0
- package/dist/cjs/reflectextensions.js +16 -12
- package/dist/cjs/reflectextensions.js.map +1 -0
- package/dist/cjs/stringextensions.js +1 -0
- package/dist/cjs/stringextensions.js.map +1 -0
- package/dist/cjs/symbolextensions.js +3 -1
- package/dist/cjs/symbolextensions.js.map +1 -0
- package/dist/cjs/weakrefextensions.js +1 -0
- package/dist/cjs/weakrefextensions.js.map +1 -0
- package/dist/mjs/arrayextensions.js +1 -0
- package/dist/mjs/arrayextensions.js.map +1 -0
- package/dist/mjs/functionextensions.js +1 -0
- package/dist/mjs/functionextensions.js.map +1 -0
- package/dist/mjs/globals.js +2 -1
- package/dist/mjs/globals.js.map +1 -0
- package/dist/mjs/index.d.ts +10 -19
- package/dist/mjs/index.js +67 -60
- package/dist/mjs/index.js.map +1 -0
- package/dist/mjs/mapextensions.d.ts +2 -0
- package/dist/mjs/mapextensions.js +27 -0
- package/dist/mjs/mapextensions.js.map +1 -0
- package/dist/mjs/newClasses/asyncIterable.d.ts +123 -0
- package/dist/mjs/{asyncIterable.js → newClasses/asyncIterable.js} +106 -105
- package/dist/mjs/newClasses/asyncIterable.js.map +1 -0
- package/dist/mjs/newClasses/descriptor.d.ts +401 -0
- package/dist/mjs/{descriptor.js → newClasses/descriptor.js} +129 -67
- package/dist/mjs/newClasses/descriptor.js.map +1 -0
- package/dist/mjs/newClasses/iterable.d.ts +125 -0
- package/dist/mjs/newClasses/iterable.js +199 -0
- package/dist/mjs/newClasses/iterable.js.map +1 -0
- package/dist/mjs/newClasses/refmap.d.ts +238 -0
- package/dist/mjs/newClasses/refmap.js +417 -0
- package/dist/mjs/newClasses/refmap.js.map +1 -0
- package/dist/mjs/newClasses/refset.d.ts +186 -0
- package/dist/mjs/{refset.js → newClasses/refset.js} +17 -3
- package/dist/mjs/newClasses/refset.js.map +1 -0
- package/dist/mjs/objectextensions.d.ts +7 -6
- package/dist/mjs/objectextensions.js +84 -42
- package/dist/mjs/objectextensions.js.map +1 -0
- package/dist/mjs/reflectextensions.js +16 -12
- package/dist/mjs/reflectextensions.js.map +1 -0
- package/dist/mjs/stringextensions.js +1 -0
- package/dist/mjs/stringextensions.js.map +1 -0
- package/dist/mjs/symbolextensions.js +3 -1
- package/dist/mjs/symbolextensions.js.map +1 -0
- package/dist/mjs/weakrefextensions.js +1 -0
- package/dist/mjs/weakrefextensions.js.map +1 -0
- package/docs/assets/anchor.js +350 -0
- package/docs/assets/bass-addons.css +12 -0
- package/docs/assets/bass.css +544 -0
- package/docs/assets/fonts/EOT/SourceCodePro-Bold.eot +0 -0
- package/docs/assets/fonts/EOT/SourceCodePro-Regular.eot +0 -0
- package/docs/assets/fonts/LICENSE.txt +93 -0
- package/docs/assets/fonts/OTF/SourceCodePro-Bold.otf +0 -0
- package/docs/assets/fonts/OTF/SourceCodePro-Regular.otf +0 -0
- package/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf +0 -0
- package/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf +0 -0
- package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff +0 -0
- package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff +0 -0
- package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff +0 -0
- package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff +0 -0
- package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 +0 -0
- package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 +0 -0
- package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 +0 -0
- package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 +0 -0
- package/docs/assets/fonts/source-code-pro.css +23 -0
- package/docs/assets/github.css +123 -0
- package/docs/assets/site.js +168 -0
- package/docs/assets/split.css +15 -0
- package/docs/assets/split.js +782 -0
- package/docs/assets/style.css +147 -0
- package/docs/index.html +13060 -0
- package/jsdoc-config.json +31 -0
- package/package.json +12 -3
- package/src/globals.js +1 -1
- package/src/index.js +75 -82
- package/src/mapextensions.js +30 -0
- package/src/{asyncIterable.js → newClasses/asyncIterable.js} +117 -117
- package/src/{descriptor.js → newClasses/descriptor.js} +137 -74
- package/src/newClasses/iterable.js +221 -0
- package/src/newClasses/refmap.js +483 -0
- package/src/{refset.js → newClasses/refset.js} +29 -16
- package/src/objectextensions.js +97 -46
- package/src/reflectextensions.js +16 -14
- package/src/symbolextensions.js +2 -1
- package/tests/index.test.js +1 -1
- package/tests/{asyncIterable.test.js → newClasses/asyncIterable.test.js} +3 -4
- package/tests/newClasses/descriptor.test.js +252 -0
- package/tests/{iterable.test.js → newClasses/iterable.test.js} +2 -4
- package/tests/newClasses/refmap.test.js +69 -0
- package/tests/{refset.test.js → newClasses/refset.test.js} +2 -4
- package/tests/objectextensions.test.js +128 -0
- package/tsconfig.base.json +2 -1
- package/dist/@nejs/basic-extensions.bundle.1.5.1.js +0 -2
- package/dist/@nejs/basic-extensions.bundle.1.5.1.js.map +0 -7
- package/dist/cjs/asyncIterable.d.ts +0 -3
- package/dist/cjs/descriptor.d.ts +0 -2
- package/dist/cjs/iterable.d.ts +0 -3
- package/dist/cjs/refset.d.ts +0 -2
- package/dist/mjs/asyncIterable.d.ts +0 -3
- package/dist/mjs/descriptor.d.ts +0 -2
- package/dist/mjs/iterable.d.ts +0 -3
- package/dist/mjs/iterable.js +0 -184
- package/dist/mjs/refset.d.ts +0 -2
- package/src/iterable.js +0 -203
package/src/objectextensions.js
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import { Patch } from '@nejs/extension';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* `ObjectExtensions` is a patch for the JavaScript built-in `Object` class.
|
|
5
|
-
* adds utility methods to the `Object` class without modifying the global
|
|
6
|
-
* directly. This patch includes methods for key validation, object
|
|
7
|
-
* and retrieving the string tag of an object. These methods
|
|
8
|
-
* enhancing the capabilities of the standard `Object` class
|
|
9
|
-
* utility functions.
|
|
4
|
+
* `ObjectExtensions` is a patch for the JavaScript built-in `Object` class.
|
|
5
|
+
* It adds utility methods to the `Object` class without modifying the global
|
|
6
|
+
* namespace directly. This patch includes methods for key validation, object
|
|
7
|
+
* type checking, and retrieving the string tag of an object. These methods
|
|
8
|
+
* are useful for enhancing the capabilities of the standard `Object` class
|
|
9
|
+
* with additional utility functions.
|
|
10
10
|
*/
|
|
11
11
|
export const ObjectExtensions = new Patch(Object, {
|
|
12
|
+
/**
|
|
13
|
+
* The function checks if a value is either `undefined` or `null`.
|
|
14
|
+
*
|
|
15
|
+
* @param {any} value - The parameter "value" is a variable that can hold
|
|
16
|
+
* any value.
|
|
17
|
+
* @returns {boolean} `true` if the value is either `undefined` or `null`,
|
|
18
|
+
* and `false` otherwise.
|
|
19
|
+
*/
|
|
20
|
+
isNullDefined(value) {
|
|
21
|
+
return value === undefined || value === null
|
|
22
|
+
},
|
|
23
|
+
|
|
12
24
|
/**
|
|
13
25
|
* Checks to see if the supplied `value` is both an object, and has the
|
|
14
26
|
* appropriate symbol defined.
|
|
@@ -22,19 +34,27 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
22
34
|
},
|
|
23
35
|
|
|
24
36
|
/**
|
|
25
|
-
* Retrieves the string tag of an object. The string tag is a representation
|
|
26
|
-
* the object's type, as defined by its `Object.prototype.toString`
|
|
27
|
-
* utility method is helpful for getting a more descriptive
|
|
28
|
-
* what is returned by the `typeof` operator,
|
|
37
|
+
* Retrieves the string tag of an object. The string tag is a representation
|
|
38
|
+
* of the object's type, as defined by its `Object.prototype.toString`
|
|
39
|
+
* method. This utility method is helpful for getting a more descriptive
|
|
40
|
+
* type of an object than what is returned by the `typeof` operator,
|
|
41
|
+
* especially for custom objects.
|
|
29
42
|
*
|
|
30
43
|
* @param {*} value - The object whose string tag is to be retrieved.
|
|
44
|
+
* @param {boolean} strict - if this is set to true, undefined will be
|
|
45
|
+
* returned whenever a supplied object does not have a
|
|
46
|
+
* `Symbol.toStringTag` defined, period. if false, the default,
|
|
31
47
|
* @returns {string} - The string tag of the object, indicating its type.
|
|
32
48
|
*/
|
|
33
|
-
getStringTag(value) {
|
|
49
|
+
getStringTag(value, strict = false) {
|
|
34
50
|
if (Object.hasStringTag(value)) {
|
|
35
51
|
return value[Symbol.toStringTag]
|
|
36
52
|
}
|
|
37
53
|
|
|
54
|
+
if (strict) {
|
|
55
|
+
return undefined
|
|
56
|
+
}
|
|
57
|
+
|
|
38
58
|
if (value && (typeof value === 'function')) {
|
|
39
59
|
return value.name
|
|
40
60
|
}
|
|
@@ -54,13 +74,13 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
54
74
|
*
|
|
55
75
|
* @param {any} value - The value whose type is to be determined.
|
|
56
76
|
* @param {object} [owner=globalThis] - The object in which to look up the
|
|
57
|
-
* constructor corresponding to the string tag. Defaults to `globalThis`,
|
|
58
|
-
* covers global constructors like `Array`, `Object`, etc.
|
|
59
|
-
* @returns {Function|object|null|undefined} - Returns the constructor or
|
|
60
|
-
* of the value based on its string tag. For 'Null' and 'Undefined',
|
|
61
|
-
* `null` and `undefined`, respectively. For other types, it
|
|
62
|
-
* corresponding constructor (e.g., `Array` for arrays) if
|
|
63
|
-
* `owner` object.
|
|
77
|
+
* constructor corresponding to the string tag. Defaults to `globalThis`,
|
|
78
|
+
* which covers global constructors like `Array`, `Object`, etc.
|
|
79
|
+
* @returns {Function|object|null|undefined} - Returns the constructor or
|
|
80
|
+
* type of the value based on its string tag. For 'Null' and 'Undefined',
|
|
81
|
+
* it returns `null` and `undefined`, respectively. For other types, it
|
|
82
|
+
* returns the corresponding constructor (e.g., `Array` for arrays) if
|
|
83
|
+
* available in the `owner` object.
|
|
64
84
|
*/
|
|
65
85
|
getType(value, owner = globalThis) {
|
|
66
86
|
const stringTag = Object.getStringTag(value)
|
|
@@ -74,13 +94,14 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
74
94
|
},
|
|
75
95
|
|
|
76
96
|
/**
|
|
77
|
-
* Determines if the provided value is an object. This method checks whether
|
|
78
|
-
* value is an instance of `Object` or if its type is 'object'. It's a
|
|
79
|
-
* method for type-checking, ensuring that a value is an object
|
|
80
|
-
* operations that are specific to objects.
|
|
97
|
+
* Determines if the provided value is an object. This method checks whether
|
|
98
|
+
* the value is an instance of `Object` or if its type is 'object'. It's a
|
|
99
|
+
* utility method for type-checking, ensuring that a value is an object
|
|
100
|
+
* before performing operations that are specific to objects.
|
|
81
101
|
*
|
|
82
102
|
* @param {*} value - The value to be checked.
|
|
83
|
-
* @returns {boolean} - Returns `true` if the value is an object,
|
|
103
|
+
* @returns {boolean} - Returns `true` if the value is an object,
|
|
104
|
+
* otherwise `false`.
|
|
84
105
|
*/
|
|
85
106
|
isObject(value) {
|
|
86
107
|
return value && (value instanceof Object || typeof value === 'object');
|
|
@@ -115,13 +136,14 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
115
136
|
},
|
|
116
137
|
|
|
117
138
|
/**
|
|
118
|
-
* Checks if the given value is a valid key for an object. In JavaScript, a
|
|
119
|
-
* key can be either a string or a symbol. This method is useful for
|
|
120
|
-
* object keys before using them in operations like setting or
|
|
139
|
+
* Checks if the given value is a valid key for an object. In JavaScript, a
|
|
140
|
+
* valid key can be either a string or a symbol. This method is useful for
|
|
141
|
+
* validating object keys before using them in operations like setting or
|
|
142
|
+
* getting object properties.
|
|
121
143
|
*
|
|
122
144
|
* @param {*} value - The value to be checked.
|
|
123
|
-
* @returns {boolean} - Returns `true` if the value is a valid object key
|
|
124
|
-
*
|
|
145
|
+
* @returns {boolean} - Returns `true` if the value is a valid object key
|
|
146
|
+
* (string or symbol), otherwise `false`.
|
|
125
147
|
*/
|
|
126
148
|
isValidKey(value) {
|
|
127
149
|
return (typeof value === 'string' || typeof value === 'symbol');
|
|
@@ -134,37 +156,66 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
134
156
|
* @param {object} object the object to pare down
|
|
135
157
|
* @param {Array<string|symbol>} keys the keys that should appear in the
|
|
136
158
|
* final reduced object
|
|
137
|
-
* @param {boolean} [bindAccessors = true] if this value is true
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* @returns {object} an object containing only the keys and symbols
|
|
142
|
-
* in the `keys` parameter.
|
|
159
|
+
* @param {boolean} [bindAccessors = true] if this value is true then any
|
|
160
|
+
* accessors from the source object will continue to have their `this`
|
|
161
|
+
* value bound to the source. If the getter or setter on that object is
|
|
162
|
+
* defined using an arrow function, this will not work as intended.
|
|
163
|
+
* @returns {object} an object containing only the keys and symbols
|
|
164
|
+
* specified in the `keys` parameter.
|
|
143
165
|
*/
|
|
144
166
|
stripTo(object, keys, bindAccessors = true) {
|
|
145
|
-
|
|
167
|
+
if (!object || typeof object !== 'object') {
|
|
168
|
+
throw new TypeError(
|
|
169
|
+
'Object.stripTo requires an object to strip. Received',
|
|
170
|
+
object
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const result = {};
|
|
146
175
|
|
|
147
176
|
if (!Array.isArray(keys)) {
|
|
148
|
-
return result
|
|
177
|
+
return result;
|
|
149
178
|
}
|
|
150
179
|
|
|
151
180
|
for (let key of keys) {
|
|
152
181
|
if (Reflect.has(object, key)) {
|
|
153
|
-
const
|
|
154
|
-
|
|
182
|
+
const originalDescriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
183
|
+
const descriptor = { ...originalDescriptor };
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
typeof descriptor.get === 'function' ||
|
|
187
|
+
typeof descriptor.set === 'function'
|
|
188
|
+
) {
|
|
155
189
|
if (bindAccessors) {
|
|
156
|
-
descriptor.get = descriptor
|
|
157
|
-
descriptor.set = descriptor
|
|
190
|
+
descriptor.get = descriptor.get?.bind(object);
|
|
191
|
+
descriptor.set = descriptor.set?.bind(object);
|
|
158
192
|
}
|
|
159
|
-
Object.defineProperty(result, descriptor)
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
Object.defineProperty(result, descriptor)
|
|
163
193
|
}
|
|
194
|
+
|
|
195
|
+
Object.defineProperty(result, key, descriptor);
|
|
164
196
|
}
|
|
165
197
|
}
|
|
166
198
|
|
|
167
|
-
return result
|
|
199
|
+
return result;
|
|
168
200
|
},
|
|
169
|
-
|
|
170
201
|
});
|
|
202
|
+
|
|
203
|
+
export const ObjectPrototypeExtensions = new Patch(Object.prototype, {
|
|
204
|
+
/**
|
|
205
|
+
* Strips an object down to only the keys specified. Optionally, any
|
|
206
|
+
* accessors can be made to retain their context on the source object.
|
|
207
|
+
* This is a passthrough to the static {@link Object.stripTo} function
|
|
208
|
+
*
|
|
209
|
+
* @param {Array<string|symbol>} keys the keys that should appear in the
|
|
210
|
+
* final reduced object
|
|
211
|
+
* @param {boolean} [bindAccessors = true] if this value is true then any
|
|
212
|
+
* accessors from the source object will continue to have their `this`
|
|
213
|
+
* value bound to the source. If the getter or setter on that object is
|
|
214
|
+
* defined using an arrow function, this will not work as intended.
|
|
215
|
+
* @returns {object} an object containing only the keys and symbols
|
|
216
|
+
* specified in the `keys` parameter.
|
|
217
|
+
*/
|
|
218
|
+
stripTo(keys, bindAccessors = true) {
|
|
219
|
+
return Object.stripTo(this, keys, bindAccessors)
|
|
220
|
+
}
|
|
221
|
+
})
|
package/src/reflectextensions.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Patch } from '@nejs/extension'
|
|
2
2
|
import { ObjectExtensions } from './objectextensions.js'
|
|
3
3
|
|
|
4
|
+
const { isObject } = ObjectExtensions.patches
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* The `ReflectExtensions` class is a patch applied to the built-in JavaScript
|
|
6
8
|
* `Reflect` object. It extends `Reflect` with additional utility methods that
|
|
@@ -31,20 +33,22 @@ export const ReflectExtensions = new Patch(Reflect, {
|
|
|
31
33
|
)
|
|
32
34
|
},
|
|
33
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Fetches all descriptors of an object, including those mapped to a
|
|
38
|
+
* symbol descriptor value.
|
|
39
|
+
*
|
|
40
|
+
* @param {object} object the object from whose descriptors need to be
|
|
41
|
+
* retrieved.
|
|
42
|
+
* @returns {object} with keys mapped to object descriptors
|
|
43
|
+
* @throws {TypeError} if the supplied `object` is null or not an object
|
|
44
|
+
* a TypeError exception will be thrown
|
|
45
|
+
*/
|
|
34
46
|
ownDescriptors(object) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
revertOnDone.doIt = false
|
|
38
|
-
|
|
39
|
-
if (!Object.isObject) {
|
|
40
|
-
revertOnDone.doIt = true
|
|
41
|
-
ObjectExtensions.apply()
|
|
47
|
+
if (!isObject(object)) {
|
|
48
|
+
throw new TypeError('The supplied object must be non-null and an object')
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
revertOnDone()
|
|
46
|
-
return {}
|
|
47
|
-
}
|
|
51
|
+
const result = {}
|
|
48
52
|
|
|
49
53
|
const keys = Reflect.ownKeys(object)
|
|
50
54
|
|
|
@@ -52,8 +56,6 @@ export const ReflectExtensions = new Patch(Reflect, {
|
|
|
52
56
|
result[key] = Object.getOwnPropertyDescriptor(key)
|
|
53
57
|
}
|
|
54
58
|
|
|
55
|
-
revertOnDone()
|
|
56
|
-
|
|
57
59
|
return result
|
|
58
60
|
},
|
|
59
61
|
|
|
@@ -69,7 +71,7 @@ export const ReflectExtensions = new Patch(Reflect, {
|
|
|
69
71
|
* at least one of the keys provided as arguments exists in the given object.
|
|
70
72
|
*/
|
|
71
73
|
hasSome(object, ...keys) {
|
|
72
|
-
return
|
|
74
|
+
return isObject(object) && (keys.flat(Infinity)
|
|
73
75
|
.map(key => Reflect.has(object, key))
|
|
74
76
|
.some(has => has)
|
|
75
77
|
)
|
package/src/symbolextensions.js
CHANGED
|
@@ -60,7 +60,8 @@ export const SymbolExtensions = new Patch(Symbol, {
|
|
|
60
60
|
* spec static symbols (`toStringTag`, `iterator`, etc...), and any symbols
|
|
61
61
|
* created by passing a value directly to the `Symbol` function, such as
|
|
62
62
|
* `Symbol('name')`
|
|
63
|
-
* @returns
|
|
63
|
+
* @returns true if the `value` in question is both a `symbol` and has
|
|
64
|
+
* returns `undefined` if passed to `Symbol.keyFor`
|
|
64
65
|
*/
|
|
65
66
|
isNonRegistered(value, allowOnlySymbols = false) {
|
|
66
67
|
return !Symbol.isRegistered(value, allowOnlySymbols)
|
package/tests/index.test.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Extensions } = require('../../dist/cjs/index.js')
|
|
2
|
+
const AsyncIterable = Extensions.AsyncIterable.class
|
|
3
|
+
const Iterable = Extensions.Iterable.class
|
|
2
4
|
|
|
3
5
|
describe('AsyncIterable', () => {
|
|
4
|
-
beforeAll(() => { enableAll() })
|
|
5
|
-
afterAll(() => { disableAll() })
|
|
6
|
-
|
|
7
6
|
test('should create an async iterable from an array of promises', async () => {
|
|
8
7
|
const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
|
|
9
8
|
const asyncIterable = new AsyncIterable(promises);
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
const { Extensions } = require('../../dist/cjs/index.js')
|
|
2
|
+
const Descriptor = Extensions.Descriptor.class
|
|
3
|
+
|
|
4
|
+
describe('Descriptor', () => {
|
|
5
|
+
describe('constructor', () => {
|
|
6
|
+
test('should create a Descriptor from a property descriptor', () => {
|
|
7
|
+
const obj = { a: 1 };
|
|
8
|
+
const desc = new Descriptor(Object.getOwnPropertyDescriptor(obj, 'a'));
|
|
9
|
+
expect(desc.isData).toBe(true);
|
|
10
|
+
expect(desc.value).toBe(1);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('should throw an error for invalid descriptors', () => {
|
|
14
|
+
expect(() => new Descriptor(5)).toThrow();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('isAccessor', () => {
|
|
19
|
+
test('should return true for accessor descriptors', () => {
|
|
20
|
+
const getter = () => {};
|
|
21
|
+
const setter = (value) => {};
|
|
22
|
+
const obj = {};
|
|
23
|
+
Object.defineProperty(obj, 'prop', { get: getter, set: setter });
|
|
24
|
+
const desc = new Descriptor(obj, 'prop');
|
|
25
|
+
expect(desc.isAccessor).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should return false for data descriptors', () => {
|
|
29
|
+
const obj = { a: 1 };
|
|
30
|
+
const desc = new Descriptor(obj, 'a');
|
|
31
|
+
expect(desc.isAccessor).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('isData', () => {
|
|
36
|
+
test('should return true for data descriptors', () => {
|
|
37
|
+
const obj = { a: 1 };
|
|
38
|
+
const desc = new Descriptor(obj, 'a');
|
|
39
|
+
expect(desc.isData).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should return false for accessor descriptors', () => {
|
|
43
|
+
const obj = {};
|
|
44
|
+
Object.defineProperty(obj, 'prop', {
|
|
45
|
+
get: () => {},
|
|
46
|
+
set: (value) => {}
|
|
47
|
+
});
|
|
48
|
+
const desc = new Descriptor(obj, 'prop');
|
|
49
|
+
expect(desc.isData).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('isDescriptor', () => {
|
|
54
|
+
test('should return true for valid descriptors', () => {
|
|
55
|
+
const desc = new Descriptor({ value: 10 });
|
|
56
|
+
expect(desc.isDescriptor).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('should throw an error for invalid descriptors', () => {
|
|
60
|
+
expect(() => new Descriptor({})).toThrow()
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('getters and setters', () => {
|
|
65
|
+
let desc;
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
desc = new Descriptor({ value: 10, writable: true, enumerable: true, configurable: true });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('configurable getter and setter', () => {
|
|
72
|
+
expect(desc.configurable).toBe(true);
|
|
73
|
+
desc.configurable = false;
|
|
74
|
+
expect(desc.configurable).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('enumerable getter and setter', () => {
|
|
78
|
+
expect(desc.enumerable).toBe(true);
|
|
79
|
+
desc.enumerable = false;
|
|
80
|
+
expect(desc.enumerable).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('writable getter and setter', () => {
|
|
84
|
+
expect(desc.writable).toBe(true);
|
|
85
|
+
desc.writable = false;
|
|
86
|
+
expect(desc.writable).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('value getter and setter', () => {
|
|
90
|
+
expect(desc.value).toBe(10);
|
|
91
|
+
desc.value = 20;
|
|
92
|
+
expect(desc.value).toBe(20);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('applyTo', () => {
|
|
97
|
+
test('should apply descriptor to an object', () => {
|
|
98
|
+
const obj = {};
|
|
99
|
+
const desc = new Descriptor({
|
|
100
|
+
configurable: true,
|
|
101
|
+
enumerable: true,
|
|
102
|
+
value: 10,
|
|
103
|
+
writable: true
|
|
104
|
+
});
|
|
105
|
+
desc.applyTo(obj, 'a');
|
|
106
|
+
expect(obj.a).toBe(10);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('should throw error for non-object or invalid key', () => {
|
|
110
|
+
const desc = new Descriptor({ value: 10 });
|
|
111
|
+
expect(() => desc.applyTo(123, 'a')).toThrow();
|
|
112
|
+
expect(() => desc.applyTo({}, null)).toThrow();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('static methods', () => {
|
|
117
|
+
describe('getData', () => {
|
|
118
|
+
test('should return the value of a data property', () => {
|
|
119
|
+
const obj = { a: 10 };
|
|
120
|
+
expect(Descriptor.getData(obj, 'a')).toBe(10);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('should return undefined for non-data properties', () => {
|
|
124
|
+
const obj = {};
|
|
125
|
+
Object.defineProperty(obj, 'prop', {
|
|
126
|
+
get: () => 20,
|
|
127
|
+
set: (value) => {}
|
|
128
|
+
});
|
|
129
|
+
expect(Descriptor.getData(obj, 'prop')).toBeNull();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('getAccessor', () => {
|
|
134
|
+
test('should return value of getter', () => {
|
|
135
|
+
const obj = {
|
|
136
|
+
get prop() { return 20 }
|
|
137
|
+
};
|
|
138
|
+
const accessedValue = Descriptor.getAccessor(obj, 'prop');
|
|
139
|
+
expect(accessedValue).toBe(20)
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('should return value getter when dependent on an adajcent value', () => {
|
|
143
|
+
const obj = {
|
|
144
|
+
age: 21,
|
|
145
|
+
get canDrink() { return this.age >= 21 }
|
|
146
|
+
};
|
|
147
|
+
const accessedValue = Descriptor.getAccessor(obj, 'canDrink');
|
|
148
|
+
expect(accessedValue).toBe(true)
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('should return null for non-accessor properties', () => {
|
|
152
|
+
const obj = { a: 10 };
|
|
153
|
+
expect(Descriptor.getAccessor(obj, 'a')).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('for', () => {
|
|
158
|
+
test('should return a descriptor for a given object property', () => {
|
|
159
|
+
const obj = { a: 10 };
|
|
160
|
+
const descriptor = Descriptor.for(obj, 'a');
|
|
161
|
+
expect(descriptor.value).toBe(10);
|
|
162
|
+
expect(descriptor.writable).toBe(true);
|
|
163
|
+
expect(descriptor.enumerable).toBe(true);
|
|
164
|
+
expect(descriptor.configurable).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('should return null for invalid inputs', () => {
|
|
168
|
+
expect(Descriptor.for(null, 'a')).toBeNull();
|
|
169
|
+
expect(Descriptor.for({}, Symbol())).toBeNull();
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe('accessor', () => {
|
|
174
|
+
test('should create an accessor descriptor', () => {
|
|
175
|
+
const getter = () => 'get';
|
|
176
|
+
const setter = (value) => { /* Do nothing */ };
|
|
177
|
+
const descriptor = Descriptor.accessor(getter, setter);
|
|
178
|
+
expect(descriptor.get).toBe(getter);
|
|
179
|
+
expect(descriptor.set).toBe(setter);
|
|
180
|
+
expect(descriptor.enumerable).toBe(false);
|
|
181
|
+
expect(descriptor.configurable).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Additional tests for variations in enumerable and configurable
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('data', () => {
|
|
188
|
+
test('should create a data descriptor', () => {
|
|
189
|
+
const value = 10;
|
|
190
|
+
const descriptor = Descriptor.data(value);
|
|
191
|
+
expect(descriptor.value).toBe(value);
|
|
192
|
+
expect(descriptor.writable).toBe(true);
|
|
193
|
+
expect(descriptor.enumerable).toBe(false);
|
|
194
|
+
expect(descriptor.configurable).toBe(false);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Additional tests for variations in writable, enumerable, and configurable
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
describe('Symbol methods', () => {
|
|
203
|
+
test('Symbol.for("nodejs.util.inspect.custom") should return custom inspect info', () => {
|
|
204
|
+
const desc = new Descriptor({ value: 10 });
|
|
205
|
+
expect(typeof desc[Symbol.for('nodejs.util.inspect.custom')]).toBe('function');
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test('Symbol.toPrimitive should handle different hints', () => {
|
|
209
|
+
const dataDesc = new Descriptor({ value: 10 });
|
|
210
|
+
const accessorDesc = new Descriptor({
|
|
211
|
+
age: 18,
|
|
212
|
+
get canDrink() { return this.age >= 21 },
|
|
213
|
+
set canDrink(value) {
|
|
214
|
+
if (value)
|
|
215
|
+
this.age = Math.max(21, this.age)
|
|
216
|
+
else
|
|
217
|
+
this.age = Math.min(20, this.age)
|
|
218
|
+
},
|
|
219
|
+
}, 'canDrink')
|
|
220
|
+
|
|
221
|
+
expect(dataDesc[Symbol.toPrimitive]('string')).toBe('Data (value)');
|
|
222
|
+
dataDesc.writable = true
|
|
223
|
+
expect(dataDesc[Symbol.toPrimitive]('string')).toBe('Data (value, writable)')
|
|
224
|
+
expect(isNaN(dataDesc[Symbol.toPrimitive]('number'))).toBe(true);
|
|
225
|
+
|
|
226
|
+
expect(accessorDesc[Symbol.toPrimitive]('string')).toBe(
|
|
227
|
+
'Accessor (getter, setter)'
|
|
228
|
+
)
|
|
229
|
+
expect(accessorDesc[Symbol.toPrimitive]('number')).toBe(NaN)
|
|
230
|
+
expect(accessorDesc.boundGet()).toBe(false)
|
|
231
|
+
expect(accessorDesc.hasObject).toBe(true)
|
|
232
|
+
expect(accessorDesc.set).toBeTruthy()
|
|
233
|
+
accessorDesc.boundSet?.(true)
|
|
234
|
+
expect(accessorDesc.boundGet()).toBe(true)
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('static properties', () => {
|
|
239
|
+
test('SHARED_KEYS should contain expected keys', () => {
|
|
240
|
+
expect(Descriptor.SHARED_KEYS).toEqual(['configurable', 'enumerable']);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test('ACCESSOR_KEYS should contain expected keys', () => {
|
|
244
|
+
expect(Descriptor.ACCESSOR_KEYS).toEqual(['get', 'set']);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test('DATA_KEYS should contain expected keys', () => {
|
|
248
|
+
expect(Descriptor.DATA_KEYS).toEqual(['value', 'writable']);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Extensions } = require('../../dist/cjs/index.js')
|
|
2
|
+
const Iterable = Extensions.Iterable.class
|
|
2
3
|
|
|
3
4
|
describe('Iterable', () => {
|
|
4
|
-
beforeAll(() => { enableAll() })
|
|
5
|
-
afterAll(() => { disableAll() })
|
|
6
|
-
|
|
7
5
|
test('should create an iterable from an array', () => {
|
|
8
6
|
const array = [1, 2, 3];
|
|
9
7
|
const iterable = new Iterable(array);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const { Extensions } = require('../../dist/cjs/index.js')
|
|
2
|
+
const RefMap = Extensions.RefMap.class
|
|
3
|
+
|
|
4
|
+
describe('RefMap', () => {
|
|
5
|
+
let refMap;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
refMap = new RefMap();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Test the constructor
|
|
12
|
+
test('should create an empty RefMap', () => {
|
|
13
|
+
expect(refMap.size).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Test objectifying behavior
|
|
17
|
+
test('should toggle objectify values', () => {
|
|
18
|
+
refMap.objectifying(true);
|
|
19
|
+
expect(refMap.objectifyValues).toBe(true);
|
|
20
|
+
refMap.objectifying(false);
|
|
21
|
+
expect(refMap.objectifyValues).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Test set and get methods
|
|
25
|
+
test('should set and get weakly referenced values', () => {
|
|
26
|
+
const obj = {};
|
|
27
|
+
refMap.set('key', obj);
|
|
28
|
+
expect(refMap.get('key')).toBe(obj);
|
|
29
|
+
expect(refMap.size).toBe(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Test handling of primitives
|
|
33
|
+
test('should handle primitives when objectifying is true', () => {
|
|
34
|
+
refMap.objectifying(true);
|
|
35
|
+
refMap.set('number', 123);
|
|
36
|
+
expect(typeof refMap.get('number')).toBe('object');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Test error handling
|
|
40
|
+
test('should throw error for invalid values in set', () => {
|
|
41
|
+
expect(() => refMap.set('key', undefined)).toThrow(TypeError);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Test asObject method
|
|
45
|
+
test('asObject should return a regular object', () => {
|
|
46
|
+
const obj = {};
|
|
47
|
+
refMap.set('key', obj);
|
|
48
|
+
const regularObject = refMap.asObject();
|
|
49
|
+
expect(typeof regularObject).toBe('object');
|
|
50
|
+
expect(regularObject.key).toBe(obj);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Test hasValue method
|
|
54
|
+
test('hasValue should correctly determine the presence of a value', () => {
|
|
55
|
+
const obj = {};
|
|
56
|
+
refMap.set('key', obj);
|
|
57
|
+
expect(refMap.hasValue(obj)).toBe(true);
|
|
58
|
+
expect(refMap.hasValue({})).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Test forEach method
|
|
62
|
+
test('forEach should iterate over values', () => {
|
|
63
|
+
const mockCallback = jest.fn();
|
|
64
|
+
const obj = {};
|
|
65
|
+
refMap.set('key', obj);
|
|
66
|
+
refMap.forEach(mockCallback);
|
|
67
|
+
expect(mockCallback.mock.calls.length).toBe(1);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Extensions } = require('../../dist/cjs/index.js')
|
|
2
|
+
const RefSet = Extensions.RefSet.class
|
|
2
3
|
|
|
3
4
|
describe('RefSet', () => {
|
|
4
|
-
beforeAll(() => { enableAll() })
|
|
5
|
-
afterAll(() => { disableAll() })
|
|
6
|
-
|
|
7
5
|
let refSet;
|
|
8
6
|
|
|
9
7
|
beforeEach(() => {
|