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