@nejs/basic-extensions 1.4.1 → 1.5.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/dist/@nejs/basic-extensions.bundle.1.4.1.js +2 -0
- package/dist/@nejs/basic-extensions.bundle.1.4.1.js.map +7 -0
- package/dist/cjs/asyncIterable.d.ts +3 -0
- package/dist/cjs/asyncIterable.js +203 -0
- package/dist/cjs/descriptor.d.ts +1 -1
- package/dist/cjs/descriptor.js +16 -3
- package/dist/cjs/globals.js +55 -67
- package/dist/cjs/index.d.ts +9 -2
- package/dist/cjs/index.js +27 -10
- package/dist/cjs/iterable.d.ts +3 -0
- package/dist/cjs/iterable.js +199 -0
- package/dist/cjs/objectextensions.js +9 -0
- package/dist/cjs/refset.d.ts +2 -0
- package/dist/cjs/refset.js +374 -0
- package/dist/cjs/symbolextensions.js +43 -0
- package/dist/cjs/weakrefextensions.d.ts +2 -0
- package/dist/cjs/weakrefextensions.js +18 -0
- package/dist/mjs/asyncIterable.d.ts +3 -0
- package/dist/mjs/asyncIterable.js +188 -0
- package/dist/mjs/descriptor.d.ts +1 -1
- package/dist/mjs/descriptor.js +14 -1
- package/dist/mjs/globals.js +55 -67
- package/dist/mjs/index.d.ts +9 -2
- package/dist/mjs/index.js +20 -10
- package/dist/mjs/iterable.d.ts +3 -0
- package/dist/mjs/iterable.js +184 -0
- package/dist/mjs/objectextensions.js +9 -0
- package/dist/mjs/refset.d.ts +2 -0
- package/dist/mjs/refset.js +352 -0
- package/dist/mjs/symbolextensions.js +43 -0
- package/dist/mjs/weakrefextensions.d.ts +2 -0
- package/dist/mjs/weakrefextensions.js +15 -0
- package/package.json +2 -2
- package/src/asyncIterable.js +208 -0
- package/src/descriptor.js +16 -1
- package/src/globals.js +58 -78
- package/src/index.js +35 -10
- package/src/iterable.js +203 -0
- package/src/objectextensions.js +12 -0
- package/src/refset.js +414 -0
- package/src/symbolextensions.js +46 -0
- package/src/weakrefextensions.js +18 -0
- package/tests/asyncIterable.test.js +44 -0
- package/tests/iterable.test.js +45 -0
- package/tests/refset.test.js +58 -0
- package/dist/@nejs/basic-extensions.bundle.1.4.0.js +0 -2
- package/dist/@nejs/basic-extensions.bundle.1.4.0.js.map +0 -7
package/src/globals.js
CHANGED
|
@@ -5,51 +5,22 @@ const { isClass, isFunction } = FunctionExtensions.patchEntries.isClass.computed
|
|
|
5
5
|
const CustomInspect = Symbol.for('nodejs.util.inspect.custom')
|
|
6
6
|
|
|
7
7
|
export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
8
|
-
asBigIntObject(
|
|
9
|
-
bigIntPrimitive
|
|
10
|
-
) {
|
|
11
|
-
const base = { configurable: true, enumerable: false }
|
|
12
|
-
const object = { value: bigIntPrimitive }
|
|
13
|
-
|
|
14
|
-
Object.defineProperties(object, {
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
[Symbol.toPrimitive]: { value: function() { return bigIntPrimitive }, ...base },
|
|
17
|
-
[Symbol.toStringTag]: { value: BigInt.name, ...base },
|
|
18
|
-
[Symbol.species]: { get() { return BigInt }, ...base },
|
|
19
|
-
[CustomInspect]: { ...base, value(depth, opts, inspect) {
|
|
20
|
-
return inspect(this[Symbol.toPrimitive](), { ...opts, depth })
|
|
21
|
-
}}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
Object.setPrototypeOf(object, BigInt.prototype)
|
|
25
|
-
|
|
26
|
-
Reflect.ownKeys(BigInt.prototype).forEach(key => {
|
|
27
|
-
if (typeof object[key] !== 'function') {
|
|
28
|
-
return
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
object[key] = (function (...args) {
|
|
32
|
-
return BigInt.prototype[key].apply(this, args)
|
|
33
|
-
}).bind(object.value)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
return object
|
|
37
|
-
},
|
|
38
|
-
|
|
39
8
|
/**
|
|
40
|
-
* Transforms an object to mimic a specified prototype, altering its type
|
|
41
|
-
* and inspection behaviors. This function is especially useful
|
|
42
|
-
* that need to behave like different primitive types
|
|
9
|
+
* Transforms an object to mimic a specified prototype, altering its type
|
|
10
|
+
* conversion and inspection behaviors. This function is especially useful
|
|
11
|
+
* for creating objects that need to behave like different primitive types
|
|
12
|
+
* under various operations.
|
|
43
13
|
*
|
|
44
14
|
* @param {Object} object - The object to be transformed.
|
|
45
|
-
* @param {Function|Object} [prototype=String.prototype] - The prototype or
|
|
46
|
-
* emulate. If a function is provided, its prototype is used.
|
|
47
|
-
* String.prototype.
|
|
48
|
-
* @param {Function} [toPrimitive=(hint, val) => String(val)] - A function
|
|
49
|
-
* the object should be converted to a primitive value. It
|
|
50
|
-
* ('number', 'string', or 'default') and the object,
|
|
51
|
-
*
|
|
52
|
-
*
|
|
15
|
+
* @param {Function|Object} [prototype=String.prototype] - The prototype or
|
|
16
|
+
* class to emulate. If a function is provided, its prototype is used.
|
|
17
|
+
* Defaults to String.prototype.
|
|
18
|
+
* @param {Function} [toPrimitive=(hint, val) => String(val)] - A function
|
|
19
|
+
* defining how the object should be converted to a primitive value. It
|
|
20
|
+
* receives a type hint ('number', 'string', or 'default') and the object,
|
|
21
|
+
* returning the primitive value.
|
|
22
|
+
* @returns {Object|null} The transformed object, or null if neither a class
|
|
23
|
+
* nor a prototype could be derived from the provided prototype parameter.
|
|
53
24
|
*/
|
|
54
25
|
maskAs(object, classPrototype, options) {
|
|
55
26
|
const {
|
|
@@ -67,9 +38,12 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
67
38
|
|
|
68
39
|
Object.setPrototypeOf(object, proto)
|
|
69
40
|
Object.defineProperties(object, {
|
|
70
|
-
valueOf: {
|
|
41
|
+
valueOf: {
|
|
42
|
+
value() { return String(toPrimitive('default', object)) }, ...base },
|
|
71
43
|
|
|
72
|
-
[Symbol.toPrimitive]: {
|
|
44
|
+
[Symbol.toPrimitive]: {
|
|
45
|
+
value(hint) { return toPrimitive(hint, object) }, ...base
|
|
46
|
+
},
|
|
73
47
|
[Symbol.toStringTag]: { value: klass.name, ...base },
|
|
74
48
|
[Symbol.species]: { get() { return klass }, ...base },
|
|
75
49
|
[CustomInspect]: { ...base, value(depth, opts, inspect) {
|
|
@@ -81,18 +55,19 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
81
55
|
},
|
|
82
56
|
|
|
83
57
|
/**
|
|
84
|
-
* Masks an object as a string-like object by setting its prototype to
|
|
85
|
-
* defining how it converts to primitive types. This is
|
|
86
|
-
* object needs to behave like a string in
|
|
87
|
-
* logging.
|
|
58
|
+
* Masks an object as a string-like object by setting its prototype to
|
|
59
|
+
* String and defining how it converts to primitive types. This is
|
|
60
|
+
* particularly useful when an object needs to behave like a string in
|
|
61
|
+
* certain contexts, such as type coercion or logging.
|
|
88
62
|
*
|
|
89
63
|
* @param {Object} object - The object to be masked as a string.
|
|
90
|
-
* @param {string} [stringKey='value'] - The object property key used for
|
|
91
|
-
* representation. Defaults to 'value'.
|
|
92
|
-
* @param {Function} [toPrimitive] - Optional custom function for primitive
|
|
93
|
-
* If omitted, a default function handling various conversion
|
|
94
|
-
*
|
|
95
|
-
*
|
|
64
|
+
* @param {string} [stringKey='value'] - The object property key used for
|
|
65
|
+
* the string representation. Defaults to 'value'.
|
|
66
|
+
* @param {Function} [toPrimitive] - Optional custom function for primitive
|
|
67
|
+
* conversion. If omitted, a default function handling various conversion
|
|
68
|
+
* hints is used.
|
|
69
|
+
* @returns {Object|null} The string-masked object, or null if the object
|
|
70
|
+
* doesn't have the specified stringKey property.
|
|
96
71
|
*/
|
|
97
72
|
maskAsString(
|
|
98
73
|
object,
|
|
@@ -107,17 +82,17 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
107
82
|
},
|
|
108
83
|
|
|
109
84
|
/**
|
|
110
|
-
* Masks an object as a number-like object. This allows the object to
|
|
111
|
-
* number in operations like arithmetic and type coercion.
|
|
112
|
-
* Number and defines custom conversion behavior.
|
|
85
|
+
* Masks an object as a number-like object. This allows the object to
|
|
86
|
+
* behave like a number in operations like arithmetic and type coercion.
|
|
87
|
+
* It sets the prototype to Number and defines custom conversion behavior.
|
|
113
88
|
*
|
|
114
|
-
* @param {Object} object - The object to be masked as a number
|
|
115
|
-
* Defaults to 'value'.
|
|
89
|
+
* @param {Object} object - The object to be masked as a number
|
|
90
|
+
* representation. Defaults to 'value'.
|
|
116
91
|
* @param {Function} [toPrimitive] - Optional custom function for primitive
|
|
117
|
-
* conversion. If not provided, a default function handling different
|
|
118
|
-
* hints is used.
|
|
119
|
-
* @returns {Object|null} The number-masked object, or null if the object
|
|
120
|
-
* have the specified numberKey property.
|
|
92
|
+
* conversion. If not provided, a default function handling different
|
|
93
|
+
* conversion hints is used.
|
|
94
|
+
* @returns {Object|null} The number-masked object, or null if the object
|
|
95
|
+
* doesn't have the specified numberKey property.
|
|
121
96
|
*/
|
|
122
97
|
maskAsNumber(
|
|
123
98
|
object,
|
|
@@ -135,8 +110,8 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
135
110
|
* Generates options for generic masking of an object, providing defaults for
|
|
136
111
|
* prototype and toPrimitive function if not specified.
|
|
137
112
|
*
|
|
138
|
-
* @param {Object} options - The options object including prototype,
|
|
139
|
-
* and toPrimitive function.
|
|
113
|
+
* @param {Object} options - The options object including prototype,
|
|
114
|
+
* targetKey, and toPrimitive function.
|
|
140
115
|
* @returns {Object} The options object with defaults applied as necessary.
|
|
141
116
|
*/
|
|
142
117
|
GenericMask({ prototype, targetKey = 'value', toPrimitive }) {
|
|
@@ -145,14 +120,18 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
145
120
|
if (!isFunction(toPrimitive)) {
|
|
146
121
|
options.toPrimitive = (hint, object) => {
|
|
147
122
|
let property = object[targetKey];
|
|
148
|
-
let isNum = (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
123
|
+
let isNum = (
|
|
124
|
+
(typeof property === 'number' && Number.isFinite(property)) ||
|
|
125
|
+
(typeof property === 'string' &&
|
|
126
|
+
!isNaN(parseFloat(property)) && isFinite(property)
|
|
127
|
+
)
|
|
128
|
+
);
|
|
152
129
|
|
|
153
130
|
switch (hint) {
|
|
154
|
-
case 'string':
|
|
155
|
-
|
|
131
|
+
case 'string':
|
|
132
|
+
return isNum ? String(property) : (property ?? String(object));
|
|
133
|
+
case 'number':
|
|
134
|
+
return isNum ? Number(property) : NaN;
|
|
156
135
|
case 'default':
|
|
157
136
|
default:
|
|
158
137
|
return isNum ? Number(property) : property;
|
|
@@ -164,10 +143,11 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
164
143
|
},
|
|
165
144
|
|
|
166
145
|
/**
|
|
167
|
-
* Generates options for string masking of an object, providing a default
|
|
168
|
-
* function if not specified.
|
|
146
|
+
* Generates options for string masking of an object, providing a default
|
|
147
|
+
* toPrimitive function if not specified.
|
|
169
148
|
*
|
|
170
|
-
* @param {string} targetKey - The object property key for string
|
|
149
|
+
* @param {string} targetKey - The object property key for string
|
|
150
|
+
* representation.
|
|
171
151
|
* @param {Function} toPrimitive - Custom function for primitive conversion.
|
|
172
152
|
* @returns {Object} Options for string masking.
|
|
173
153
|
*/
|
|
@@ -189,10 +169,11 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
189
169
|
},
|
|
190
170
|
|
|
191
171
|
/**
|
|
192
|
-
* Generates options for number masking of an object, providing a default
|
|
193
|
-
* function if not specified.
|
|
172
|
+
* Generates options for number masking of an object, providing a default
|
|
173
|
+
* toPrimitive function if not specified.
|
|
194
174
|
*
|
|
195
|
-
* @param {string} targetKey - The object property key for number
|
|
175
|
+
* @param {string} targetKey - The object property key for number
|
|
176
|
+
* representation.
|
|
196
177
|
* @param {Function} toPrimitive - Custom function for primitive conversion.
|
|
197
178
|
* @returns {Object} Options for number masking.
|
|
198
179
|
*/
|
|
@@ -212,5 +193,4 @@ export const GlobalFunctionsAndProps = new Patch(globalThis, {
|
|
|
212
193
|
|
|
213
194
|
return options
|
|
214
195
|
},
|
|
215
|
-
|
|
216
196
|
})
|
package/src/index.js
CHANGED
|
@@ -4,8 +4,19 @@ import { ReflectExtensions } from './reflectextensions.js'
|
|
|
4
4
|
import { StringExtensions } from './stringextensions.js'
|
|
5
5
|
import { SymbolExtensions } from './symbolextensions.js'
|
|
6
6
|
import { ArrayPrototypeExtensions } from './arrayextensions.js'
|
|
7
|
-
import {
|
|
7
|
+
import { DescriptorExtensions } from './descriptor.js'
|
|
8
8
|
import { GlobalFunctionsAndProps } from './globals.js'
|
|
9
|
+
import { RefSetExtensions } from './refset.js'
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
AsyncIteratorExtensions,
|
|
13
|
+
AsyncIterableExtensions
|
|
14
|
+
} from './asyncIterable.js'
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
IteratorExtensions,
|
|
18
|
+
IterableExtensions
|
|
19
|
+
} from './iterable.js'
|
|
9
20
|
|
|
10
21
|
import { Patch } from '@nejs/extension'
|
|
11
22
|
|
|
@@ -21,7 +32,12 @@ const Owners = [
|
|
|
21
32
|
|
|
22
33
|
const NetNew = [
|
|
23
34
|
GlobalFunctionsAndProps,
|
|
24
|
-
|
|
35
|
+
DescriptorExtensions,
|
|
36
|
+
AsyncIterableExtensions,
|
|
37
|
+
AsyncIteratorExtensions,
|
|
38
|
+
IterableExtensions,
|
|
39
|
+
IteratorExtensions,
|
|
40
|
+
RefSetExtensions,
|
|
25
41
|
]
|
|
26
42
|
|
|
27
43
|
export function enableAll(owners) {
|
|
@@ -35,9 +51,11 @@ export function enableAll(owners) {
|
|
|
35
51
|
Patch.enableFor(owner)
|
|
36
52
|
})
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
enableNetNew()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function enableNetNew() {
|
|
58
|
+
NetNew.forEach(extension => { extension.apply() })
|
|
41
59
|
}
|
|
42
60
|
|
|
43
61
|
export function disableAll(owners) {
|
|
@@ -51,9 +69,11 @@ export function disableAll(owners) {
|
|
|
51
69
|
Patch.disableFor(owner)
|
|
52
70
|
})
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
disableNetNew()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function disableNetNew() {
|
|
76
|
+
NetNew.forEach(extension => { extension.revert() })
|
|
57
77
|
}
|
|
58
78
|
|
|
59
79
|
export const all = (() => {
|
|
@@ -66,7 +86,7 @@ export const all = (() => {
|
|
|
66
86
|
ArrayPrototypeExtensions,
|
|
67
87
|
|
|
68
88
|
GlobalFunctionsAndProps,
|
|
69
|
-
|
|
89
|
+
DescriptorExtensions,
|
|
70
90
|
]
|
|
71
91
|
|
|
72
92
|
const dest = extensions.reduce((accumulator, extension) => {
|
|
@@ -91,5 +111,10 @@ export {
|
|
|
91
111
|
ArrayPrototypeExtensions,
|
|
92
112
|
|
|
93
113
|
GlobalFunctionsAndProps,
|
|
94
|
-
|
|
114
|
+
DescriptorExtensions,
|
|
115
|
+
AsyncIterableExtensions,
|
|
116
|
+
AsyncIteratorExtensions,
|
|
117
|
+
IterableExtensions,
|
|
118
|
+
IteratorExtensions,
|
|
119
|
+
RefSetExtensions,
|
|
95
120
|
}
|
package/src/iterable.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { Extension } from '@nejs/extension'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The Iterable class is designed to provide a convenient way to create synchronous
|
|
5
|
+
* iterable objects. It can be initialized with either an array or individual elements.
|
|
6
|
+
* This class implements the iterable protocol, allowing instances to be used with
|
|
7
|
+
* `for...of` loops and other standard JavaScript iteration mechanisms.
|
|
8
|
+
*/
|
|
9
|
+
class Iterable {
|
|
10
|
+
/**
|
|
11
|
+
* Private field to store the elements of the iterable.
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
#elements = [];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Constructs an instance of Iterable. It can be initialized with either an
|
|
18
|
+
* iterable object (such as an array, Set, Map, string, or any object
|
|
19
|
+
* implementing the iterable protocol) or individual elements. If the first
|
|
20
|
+
* argument is an iterable, the class instance is initialized with the
|
|
21
|
+
* elements from the iterable, followed by any additional arguments. If the
|
|
22
|
+
* first argument is not an iterable, all arguments are treated as individual
|
|
23
|
+
* elements.
|
|
24
|
+
*
|
|
25
|
+
* @param {Iterable|*} elementsOrFirstElement - An iterable object or the
|
|
26
|
+
* first element.
|
|
27
|
+
* @param {...*} moreElements - Additional elements if the first argument is
|
|
28
|
+
* not an iterable.
|
|
29
|
+
*/
|
|
30
|
+
constructor(elementsOrFirstElement, ...moreElements) {
|
|
31
|
+
if (
|
|
32
|
+
elementsOrFirstElement != null &&
|
|
33
|
+
typeof elementsOrFirstElement[Symbol.iterator] === 'function'
|
|
34
|
+
) {
|
|
35
|
+
this.#elements = [...elementsOrFirstElement, ...moreElements];
|
|
36
|
+
} else {
|
|
37
|
+
this.#elements = [elementsOrFirstElement, ...moreElements];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Implements the iterable protocol. When an instance of Iterable is used
|
|
43
|
+
* in a `for...of` loop or spread syntax, this generator function is invoked
|
|
44
|
+
* to yield the elements one by one in a synchronous manner.
|
|
45
|
+
*
|
|
46
|
+
* @returns {Generator} A generator that yields each element of the iterable.
|
|
47
|
+
*/
|
|
48
|
+
*[Symbol.iterator]() {
|
|
49
|
+
for (const element of this.#elements) {
|
|
50
|
+
yield element;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Provides access to the elements as a standard array. Useful for scenarios
|
|
56
|
+
* where array methods and behaviors are needed.
|
|
57
|
+
*
|
|
58
|
+
* @returns {Array} An array containing all the elements of the iterable.
|
|
59
|
+
*/
|
|
60
|
+
get asArray() {
|
|
61
|
+
return this.#elements;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Ensures that the constructor of this object instance's name
|
|
66
|
+
* is returned if the string tag for this instance is queried
|
|
67
|
+
*
|
|
68
|
+
* @returns {string} the name of the class
|
|
69
|
+
*/
|
|
70
|
+
get [Symbol.toStringTag]() {
|
|
71
|
+
return this.constructor.name
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Being able to create a compliant `Iterator` around any type of iterable
|
|
76
|
+
* object. This can be wrapped around any type of object that has a
|
|
77
|
+
* `[Symbol.iterator]` property assigned to a generator function.
|
|
78
|
+
*/
|
|
79
|
+
static Iterator = class Iterator {
|
|
80
|
+
/**
|
|
81
|
+
* Creates a new `Iterator` object instance.
|
|
82
|
+
*
|
|
83
|
+
* @param {object} iterable any object that has a `[Symbol.iterator]`
|
|
84
|
+
* property assigned to a generator function.
|
|
85
|
+
*/
|
|
86
|
+
constructor(iterable) {
|
|
87
|
+
if (!iterable || !Reflect.has(iterable, Symbol.iterator)) {
|
|
88
|
+
throw new TypeError(
|
|
89
|
+
'Value used to instantiate Iterator is not iterable'
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.#iterable = iterable;
|
|
94
|
+
this.#iterator = iterable[Symbol.iterator]();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Returns a new `Array` derived from the iterable this object
|
|
99
|
+
* wraps.
|
|
100
|
+
*
|
|
101
|
+
* @returns {array} a new `Array` generated from the wrapped
|
|
102
|
+
* iterable. The method is generated from `Array.from()`
|
|
103
|
+
*/
|
|
104
|
+
get asArray() {
|
|
105
|
+
return Array.from(this.#iterable)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Returns the actual iterable object passed to the constructor that
|
|
110
|
+
* created this instance.
|
|
111
|
+
*
|
|
112
|
+
* @returns {object} the object containing the `[Symbol.iterator]`
|
|
113
|
+
*/
|
|
114
|
+
get iterable() {
|
|
115
|
+
return this.#iterable
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The function retrieves the next value in the iterator. If the
|
|
120
|
+
* the iterator has run its course, `reset()` can be invoked to
|
|
121
|
+
* reset the pointer to the beginning of the iteration.
|
|
122
|
+
*
|
|
123
|
+
* @returns {any} the next value
|
|
124
|
+
*/
|
|
125
|
+
next() {
|
|
126
|
+
const result = this.#iterator.next();
|
|
127
|
+
if (result.done) {
|
|
128
|
+
return { value: undefined, done: true };
|
|
129
|
+
} else {
|
|
130
|
+
return { value: result.value, done: false };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Resets the iterator to the beginning allowing it to be
|
|
136
|
+
* iterated over again.
|
|
137
|
+
*/
|
|
138
|
+
reset() {
|
|
139
|
+
this.#iterator = this.#iterable[Symbol.iterator]();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The existence of this symbol on the object instances, indicates that
|
|
144
|
+
* it can be used in `for(.. of ..)` loops and its values can be
|
|
145
|
+
* extracted from calls to `Array.from()`
|
|
146
|
+
*
|
|
147
|
+
* @returns {Iterator} this is returned since this object is already
|
|
148
|
+
* conforming to the expected JavaScript Iterator interface
|
|
149
|
+
*/
|
|
150
|
+
[Symbol.iterator]() {
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Ensures that the constructor of this object instance's name
|
|
156
|
+
* is returned if the string tag for this instance is queried
|
|
157
|
+
*
|
|
158
|
+
* @returns {string} the name of the class
|
|
159
|
+
*/
|
|
160
|
+
get [Symbol.toStringTag]() {
|
|
161
|
+
return this.constructor.name
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The object from which its iterator functionality is derived.
|
|
166
|
+
*
|
|
167
|
+
* @type {object}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
#iterable = null;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The results of a call to the iterable's `[Symbol.iterator]`
|
|
174
|
+
* generator function.
|
|
175
|
+
*
|
|
176
|
+
* @type {object}
|
|
177
|
+
* @private
|
|
178
|
+
*/
|
|
179
|
+
#iterator = null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Checks if a given value is an iterable. This method determines if the
|
|
184
|
+
* provided value has a `Symbol.iterator` property that is a generator
|
|
185
|
+
* function. It's a precise way to identify if the value conforms to the
|
|
186
|
+
* iterable protocol using a generator function.
|
|
187
|
+
*
|
|
188
|
+
* Note: This method specifically checks for generator functions. Some
|
|
189
|
+
* iterables might use regular functions that return an iterator, which
|
|
190
|
+
* this method won't identify.
|
|
191
|
+
*
|
|
192
|
+
* @param {*} value - The value to be checked for iterability.
|
|
193
|
+
* @returns {boolean} - Returns true if the value is an iterable implemented
|
|
194
|
+
* using a generator function, false otherwise.
|
|
195
|
+
*/
|
|
196
|
+
static isIterable(value) {
|
|
197
|
+
const type = Object.prototype.toString.call(value?.[Symbol.iterator]);
|
|
198
|
+
return type === '[object GeneratorFunction]';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export const IterableExtensions = new Extension(Iterable)
|
|
203
|
+
export const IteratorExtensions = new Extension(Iterable.Iterator)
|
package/src/objectextensions.js
CHANGED
|
@@ -9,6 +9,10 @@ import { Patch } from '@nejs/extension';
|
|
|
9
9
|
* utility functions.
|
|
10
10
|
*/
|
|
11
11
|
export const ObjectExtensions = new Patch(Object, {
|
|
12
|
+
hasStringTag(value) {
|
|
13
|
+
return Object.isObject(value) && Reflect.has(value, Symbol.toStringTag)
|
|
14
|
+
},
|
|
15
|
+
|
|
12
16
|
/**
|
|
13
17
|
* Retrieves the string tag of an object. The string tag is a representation of
|
|
14
18
|
* the object's type, as defined by its `Object.prototype.toString` method. This
|
|
@@ -19,6 +23,14 @@ export const ObjectExtensions = new Patch(Object, {
|
|
|
19
23
|
* @returns {string} - The string tag of the object, indicating its type.
|
|
20
24
|
*/
|
|
21
25
|
getStringTag(value) {
|
|
26
|
+
if (Object.hasStringTag(value)) {
|
|
27
|
+
return value[Symbol.toStringTag]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (value && (typeof value === 'function')) {
|
|
31
|
+
return value.name
|
|
32
|
+
}
|
|
33
|
+
|
|
22
34
|
return /\s(.+)]/.exec(Object.prototype.toString.call(value))[1];
|
|
23
35
|
},
|
|
24
36
|
|