@nejs/basic-extensions 2.21.5 → 2.22.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +78 -4
  2. package/dist/@nejs/basic-extensions.bundle.2.22.6.js +25 -0
  3. package/dist/@nejs/basic-extensions.bundle.2.22.6.js.map +7 -0
  4. package/dist/cjs/classes/index.cjs +11129 -0
  5. package/dist/cjs/classes/index.cjs.map +7 -0
  6. package/dist/cjs/index.cjs +15191 -0
  7. package/dist/cjs/index.cjs.map +7 -0
  8. package/dist/cjs/utils/index.cjs +3954 -0
  9. package/dist/cjs/utils/index.cjs.map +7 -0
  10. package/dist/esm/basic-extensions.mjs +25 -0
  11. package/dist/esm/basic-extensions.mjs.map +7 -0
  12. package/package.json +16 -22
  13. package/repl.bootstrap.js +4 -7
  14. package/repl.history +26 -26
  15. package/src/classes/enumeration.js +466 -0
  16. package/src/classes/index.js +5 -1
  17. package/src/index.js +3 -1
  18. package/src/regular.expression.extensions.js +0 -35
  19. package/src/utils/toolkit.js +699 -516
  20. package/tests/arrayextensions.test.js +3 -3
  21. package/tests/index.test.js +3 -1
  22. package/tests/newClasses/asyncIterable.test.js +3 -3
  23. package/tests/newClasses/deferred.test.js +3 -3
  24. package/tests/newClasses/descriptor.test.js +3 -3
  25. package/tests/newClasses/iterable.test.js +3 -3
  26. package/tests/newClasses/refmap.test.js +3 -3
  27. package/tests/newClasses/refset.test.js +3 -3
  28. package/tests/objectextensions.test.js +3 -3
  29. package/tests/setextensions.test.js +3 -3
  30. package/tests/stringextensions.test.js +3 -2
  31. package/tests/utils/descriptor.utils.test.js +1 -1
  32. package/tests/utils/toolkit.test.js +429 -163
  33. package/.esdoc.json +0 -9
  34. package/.vscode/settings.json +0 -5
  35. package/bin/build +0 -27
  36. package/bin/clean +0 -14
  37. package/bin/esbuild +0 -91
  38. package/bin/fixup +0 -13
  39. package/bin/repl.basics.js +0 -584
  40. package/bin/repl.signature.js +0 -63
  41. package/bin/version +0 -100
  42. package/dist/@nejs/basic-extensions.bundle.2.21.5.js +0 -25
  43. package/dist/@nejs/basic-extensions.bundle.2.21.5.js.map +0 -7
  44. package/dist/cjs/array.extensions.d.ts +0 -39
  45. package/dist/cjs/array.extensions.js +0 -477
  46. package/dist/cjs/array.extensions.js.map +0 -1
  47. package/dist/cjs/big.int.extension.d.ts +0 -31
  48. package/dist/cjs/big.int.extension.js +0 -273
  49. package/dist/cjs/big.int.extension.js.map +0 -1
  50. package/dist/cjs/classes/asyncIterable.d.ts +0 -126
  51. package/dist/cjs/classes/asyncIterable.js +0 -209
  52. package/dist/cjs/classes/asyncIterable.js.map +0 -1
  53. package/dist/cjs/classes/deferred.d.ts +0 -146
  54. package/dist/cjs/classes/deferred.js +0 -291
  55. package/dist/cjs/classes/deferred.js.map +0 -1
  56. package/dist/cjs/classes/descriptor.d.ts +0 -334
  57. package/dist/cjs/classes/descriptor.js +0 -537
  58. package/dist/cjs/classes/descriptor.js.map +0 -1
  59. package/dist/cjs/classes/enum.d.ts +0 -50
  60. package/dist/cjs/classes/enum.js +0 -405
  61. package/dist/cjs/classes/enum.js.map +0 -1
  62. package/dist/cjs/classes/index.d.ts +0 -15
  63. package/dist/cjs/classes/index.js +0 -63
  64. package/dist/cjs/classes/index.js.map +0 -1
  65. package/dist/cjs/classes/introspector.d.ts +0 -20
  66. package/dist/cjs/classes/introspector.js +0 -130
  67. package/dist/cjs/classes/introspector.js.map +0 -1
  68. package/dist/cjs/classes/iterable.d.ts +0 -169
  69. package/dist/cjs/classes/iterable.js +0 -268
  70. package/dist/cjs/classes/iterable.js.map +0 -1
  71. package/dist/cjs/classes/param.parser.d.ts +0 -221
  72. package/dist/cjs/classes/param.parser.js +0 -242
  73. package/dist/cjs/classes/param.parser.js.map +0 -1
  74. package/dist/cjs/classes/pluggable.proxy.d.ts +0 -153
  75. package/dist/cjs/classes/pluggable.proxy.js +0 -444
  76. package/dist/cjs/classes/pluggable.proxy.js.map +0 -1
  77. package/dist/cjs/classes/property.d.ts +0 -79
  78. package/dist/cjs/classes/property.js +0 -284
  79. package/dist/cjs/classes/property.js.map +0 -1
  80. package/dist/cjs/classes/refmap.d.ts +0 -238
  81. package/dist/cjs/classes/refmap.js +0 -421
  82. package/dist/cjs/classes/refmap.js.map +0 -1
  83. package/dist/cjs/classes/refset.d.ts +0 -186
  84. package/dist/cjs/classes/refset.js +0 -370
  85. package/dist/cjs/classes/refset.js.map +0 -1
  86. package/dist/cjs/classes/symkeys.d.ts +0 -349
  87. package/dist/cjs/classes/symkeys.js +0 -510
  88. package/dist/cjs/classes/symkeys.js.map +0 -1
  89. package/dist/cjs/classes/type.d.ts +0 -56
  90. package/dist/cjs/classes/type.js +0 -405
  91. package/dist/cjs/classes/type.js.map +0 -1
  92. package/dist/cjs/function.extensions.d.ts +0 -12
  93. package/dist/cjs/function.extensions.js +0 -758
  94. package/dist/cjs/function.extensions.js.map +0 -1
  95. package/dist/cjs/global.this.d.ts +0 -2
  96. package/dist/cjs/global.this.js +0 -300
  97. package/dist/cjs/global.this.js.map +0 -1
  98. package/dist/cjs/index.d.ts +0 -31
  99. package/dist/cjs/index.js +0 -228
  100. package/dist/cjs/index.js.map +0 -1
  101. package/dist/cjs/json.extensions.d.ts +0 -2
  102. package/dist/cjs/json.extensions.js +0 -109
  103. package/dist/cjs/json.extensions.js.map +0 -1
  104. package/dist/cjs/map.extensions.d.ts +0 -3
  105. package/dist/cjs/map.extensions.js +0 -143
  106. package/dist/cjs/map.extensions.js.map +0 -1
  107. package/dist/cjs/math.extension.d.ts +0 -14
  108. package/dist/cjs/math.extension.js +0 -71
  109. package/dist/cjs/math.extension.js.map +0 -1
  110. package/dist/cjs/number.extension.d.ts +0 -44
  111. package/dist/cjs/number.extension.js +0 -278
  112. package/dist/cjs/number.extension.js.map +0 -1
  113. package/dist/cjs/object.extensions.d.ts +0 -33
  114. package/dist/cjs/object.extensions.js +0 -1091
  115. package/dist/cjs/object.extensions.js.map +0 -1
  116. package/dist/cjs/package.json +0 -3
  117. package/dist/cjs/proxy.extensions.d.ts +0 -2
  118. package/dist/cjs/proxy.extensions.js +0 -207
  119. package/dist/cjs/proxy.extensions.js.map +0 -1
  120. package/dist/cjs/reflect.extensions.d.ts +0 -14
  121. package/dist/cjs/reflect.extensions.js +0 -316
  122. package/dist/cjs/reflect.extensions.js.map +0 -1
  123. package/dist/cjs/regular.expression.extensions.d.ts +0 -2
  124. package/dist/cjs/regular.expression.extensions.js +0 -423
  125. package/dist/cjs/regular.expression.extensions.js.map +0 -1
  126. package/dist/cjs/set.extensions.d.ts +0 -40
  127. package/dist/cjs/set.extensions.js +0 -355
  128. package/dist/cjs/set.extensions.js.map +0 -1
  129. package/dist/cjs/string.extensions.d.ts +0 -23
  130. package/dist/cjs/string.extensions.js +0 -704
  131. package/dist/cjs/string.extensions.js.map +0 -1
  132. package/dist/cjs/symbol.extensions.d.ts +0 -11
  133. package/dist/cjs/symbol.extensions.js +0 -735
  134. package/dist/cjs/symbol.extensions.js.map +0 -1
  135. package/dist/cjs/utils/copy.object.d.ts +0 -408
  136. package/dist/cjs/utils/copy.object.js +0 -720
  137. package/dist/cjs/utils/copy.object.js.map +0 -1
  138. package/dist/cjs/utils/descriptor.utils.d.ts +0 -298
  139. package/dist/cjs/utils/descriptor.utils.js +0 -889
  140. package/dist/cjs/utils/descriptor.utils.js.map +0 -1
  141. package/dist/cjs/utils/index.d.ts +0 -75
  142. package/dist/cjs/utils/index.js +0 -61
  143. package/dist/cjs/utils/index.js.map +0 -1
  144. package/dist/cjs/utils/stdout.d.ts +0 -742
  145. package/dist/cjs/utils/stdout.js +0 -1042
  146. package/dist/cjs/utils/stdout.js.map +0 -1
  147. package/dist/cjs/utils/toolkit.d.ts +0 -1898
  148. package/dist/cjs/utils/toolkit.js +0 -1378
  149. package/dist/cjs/utils/toolkit.js.map +0 -1
  150. package/dist/cjs/weakref.extensions.d.ts +0 -2
  151. package/dist/cjs/weakref.extensions.js +0 -19
  152. package/dist/cjs/weakref.extensions.js.map +0 -1
  153. package/dist/mjs/array.extensions.d.ts +0 -39
  154. package/dist/mjs/array.extensions.js +0 -474
  155. package/dist/mjs/array.extensions.js.map +0 -1
  156. package/dist/mjs/big.int.extension.d.ts +0 -31
  157. package/dist/mjs/big.int.extension.js +0 -270
  158. package/dist/mjs/big.int.extension.js.map +0 -1
  159. package/dist/mjs/classes/asyncIterable.d.ts +0 -126
  160. package/dist/mjs/classes/asyncIterable.js +0 -204
  161. package/dist/mjs/classes/asyncIterable.js.map +0 -1
  162. package/dist/mjs/classes/deferred.d.ts +0 -146
  163. package/dist/mjs/classes/deferred.js +0 -287
  164. package/dist/mjs/classes/deferred.js.map +0 -1
  165. package/dist/mjs/classes/descriptor.d.ts +0 -334
  166. package/dist/mjs/classes/descriptor.js +0 -533
  167. package/dist/mjs/classes/descriptor.js.map +0 -1
  168. package/dist/mjs/classes/enum.d.ts +0 -50
  169. package/dist/mjs/classes/enum.js +0 -400
  170. package/dist/mjs/classes/enum.js.map +0 -1
  171. package/dist/mjs/classes/index.d.ts +0 -15
  172. package/dist/mjs/classes/index.js +0 -46
  173. package/dist/mjs/classes/index.js.map +0 -1
  174. package/dist/mjs/classes/introspector.d.ts +0 -20
  175. package/dist/mjs/classes/introspector.js +0 -126
  176. package/dist/mjs/classes/introspector.js.map +0 -1
  177. package/dist/mjs/classes/iterable.d.ts +0 -169
  178. package/dist/mjs/classes/iterable.js +0 -263
  179. package/dist/mjs/classes/iterable.js.map +0 -1
  180. package/dist/mjs/classes/param.parser.d.ts +0 -221
  181. package/dist/mjs/classes/param.parser.js +0 -238
  182. package/dist/mjs/classes/param.parser.js.map +0 -1
  183. package/dist/mjs/classes/pluggable.proxy.d.ts +0 -153
  184. package/dist/mjs/classes/pluggable.proxy.js +0 -438
  185. package/dist/mjs/classes/pluggable.proxy.js.map +0 -1
  186. package/dist/mjs/classes/property.d.ts +0 -79
  187. package/dist/mjs/classes/property.js +0 -280
  188. package/dist/mjs/classes/property.js.map +0 -1
  189. package/dist/mjs/classes/refmap.d.ts +0 -238
  190. package/dist/mjs/classes/refmap.js +0 -417
  191. package/dist/mjs/classes/refmap.js.map +0 -1
  192. package/dist/mjs/classes/refset.d.ts +0 -186
  193. package/dist/mjs/classes/refset.js +0 -366
  194. package/dist/mjs/classes/refset.js.map +0 -1
  195. package/dist/mjs/classes/symkeys.d.ts +0 -349
  196. package/dist/mjs/classes/symkeys.js +0 -506
  197. package/dist/mjs/classes/symkeys.js.map +0 -1
  198. package/dist/mjs/classes/type.d.ts +0 -56
  199. package/dist/mjs/classes/type.js +0 -401
  200. package/dist/mjs/classes/type.js.map +0 -1
  201. package/dist/mjs/function.extensions.d.ts +0 -12
  202. package/dist/mjs/function.extensions.js +0 -755
  203. package/dist/mjs/function.extensions.js.map +0 -1
  204. package/dist/mjs/global.this.d.ts +0 -2
  205. package/dist/mjs/global.this.js +0 -264
  206. package/dist/mjs/global.this.js.map +0 -1
  207. package/dist/mjs/index.d.ts +0 -31
  208. package/dist/mjs/index.js +0 -206
  209. package/dist/mjs/index.js.map +0 -1
  210. package/dist/mjs/json.extensions.d.ts +0 -2
  211. package/dist/mjs/json.extensions.js +0 -106
  212. package/dist/mjs/json.extensions.js.map +0 -1
  213. package/dist/mjs/map.extensions.d.ts +0 -3
  214. package/dist/mjs/map.extensions.js +0 -140
  215. package/dist/mjs/map.extensions.js.map +0 -1
  216. package/dist/mjs/math.extension.d.ts +0 -14
  217. package/dist/mjs/math.extension.js +0 -68
  218. package/dist/mjs/math.extension.js.map +0 -1
  219. package/dist/mjs/number.extension.d.ts +0 -44
  220. package/dist/mjs/number.extension.js +0 -275
  221. package/dist/mjs/number.extension.js.map +0 -1
  222. package/dist/mjs/object.extensions.d.ts +0 -33
  223. package/dist/mjs/object.extensions.js +0 -1088
  224. package/dist/mjs/object.extensions.js.map +0 -1
  225. package/dist/mjs/package.json +0 -3
  226. package/dist/mjs/proxy.extensions.d.ts +0 -2
  227. package/dist/mjs/proxy.extensions.js +0 -204
  228. package/dist/mjs/proxy.extensions.js.map +0 -1
  229. package/dist/mjs/reflect.extensions.d.ts +0 -14
  230. package/dist/mjs/reflect.extensions.js +0 -313
  231. package/dist/mjs/reflect.extensions.js.map +0 -1
  232. package/dist/mjs/regular.expression.extensions.d.ts +0 -2
  233. package/dist/mjs/regular.expression.extensions.js +0 -420
  234. package/dist/mjs/regular.expression.extensions.js.map +0 -1
  235. package/dist/mjs/set.extensions.d.ts +0 -40
  236. package/dist/mjs/set.extensions.js +0 -352
  237. package/dist/mjs/set.extensions.js.map +0 -1
  238. package/dist/mjs/string.extensions.d.ts +0 -23
  239. package/dist/mjs/string.extensions.js +0 -701
  240. package/dist/mjs/string.extensions.js.map +0 -1
  241. package/dist/mjs/symbol.extensions.d.ts +0 -11
  242. package/dist/mjs/symbol.extensions.js +0 -732
  243. package/dist/mjs/symbol.extensions.js.map +0 -1
  244. package/dist/mjs/utils/copy.object.d.ts +0 -408
  245. package/dist/mjs/utils/copy.object.js +0 -702
  246. package/dist/mjs/utils/copy.object.js.map +0 -1
  247. package/dist/mjs/utils/descriptor.utils.d.ts +0 -298
  248. package/dist/mjs/utils/descriptor.utils.js +0 -875
  249. package/dist/mjs/utils/descriptor.utils.js.map +0 -1
  250. package/dist/mjs/utils/index.d.ts +0 -75
  251. package/dist/mjs/utils/index.js +0 -45
  252. package/dist/mjs/utils/index.js.map +0 -1
  253. package/dist/mjs/utils/stdout.d.ts +0 -742
  254. package/dist/mjs/utils/stdout.js +0 -1037
  255. package/dist/mjs/utils/stdout.js.map +0 -1
  256. package/dist/mjs/utils/toolkit.d.ts +0 -1898
  257. package/dist/mjs/utils/toolkit.js +0 -1373
  258. package/dist/mjs/utils/toolkit.js.map +0 -1
  259. package/dist/mjs/weakref.extensions.d.ts +0 -2
  260. package/dist/mjs/weakref.extensions.js +0 -16
  261. package/dist/mjs/weakref.extensions.js.map +0 -1
  262. package/jsdoc-config.json +0 -31
  263. package/tsconfig.base.json +0 -28
  264. package/tsconfig.cjs.json +0 -8
  265. package/tsconfig.esm.json +0 -8
  266. package/vitest.config.js +0 -7
@@ -1,755 +0,0 @@
1
- import { Patch } from '@nejs/extension';
2
- /**
3
- * The `FunctionExtensions` class is a patch applied to the built-in JavaScript
4
- * `Function` constructor. It extends `Function` with additional utility methods
5
- * for determining the specific type or nature of function-like objects. These
6
- * methods allow developers to distinguish between classes, regular functions,
7
- * async functions, and arrow functions in a more intuitive and straightforward
8
- * manner. This class is part of the `@nejs/extension` library and enhances the
9
- * capabilities of function handling and introspection in JavaScript.
10
- */
11
- export const FunctionExtensions = new Patch(Function, {
12
- [Patch.kMutablyHidden]: {
13
- /**
14
- * Retrieves the properties of a function and its prototype.
15
- *
16
- * This method uses the `Reflect.ownKeys` function to get all the keys
17
- * (including non-enumerable and symbol keys) of the function and its
18
- * prototype. It then uses `Object.getOwnPropertyDescriptor` to get the
19
- * property descriptors for each key. The descriptors include information
20
- * about the property's value, writability, enumerability, and
21
- * configurability.
22
- *
23
- * @param {Function} fn - The function whose properties are to be retrieved.
24
- * @returns {Array} An array containing the function itself, its property
25
- * descriptors, its prototype, and the prototype's property descriptors.
26
- *
27
- * @example
28
- * function MyFunction() {}
29
- * MyFunction.myProp = 'hello';
30
- * MyFunction.prototype.myProtoProp = 'world';
31
- *
32
- * const result = getClassProperties(MyFunction);
33
- * console.log(result);
34
- * // Output: [MyFunction, { myProp: { value: 'hello', writable: true,
35
- * // enumerable: true, configurable: true } }, MyFunction.prototype,
36
- * // { myProtoProp: { value: 'world', writable: true, enumerable: true,
37
- * // configurable: true } }]
38
- */
39
- getClassProperties(fn) {
40
- const descriptors = Reflect.ownKeys(fn).reduce((acc, key) => {
41
- acc[key] = Object.getOwnPropertyDescriptor(fn, key);
42
- return acc;
43
- }, {});
44
- const prototypeDescriptors = Reflect.ownKeys(fn.prototype).reduce((acc, key) => {
45
- acc[key] = Object.getOwnPropertyDescriptor(fn.prototype, key);
46
- return acc;
47
- }, {});
48
- return [fn, descriptors, fn.prototype, prototypeDescriptors];
49
- },
50
- /**
51
- * Determines if a given value is an asynchronous function. It checks if the
52
- * value is an instance of `Function` and if its string representation
53
- * includes the keyword 'Async'. This method is particularly useful for
54
- * identifying async functions.
55
- *
56
- * @param {*} value - The value to be checked.
57
- * @returns {boolean} Returns `true` if the value is an async function,
58
- * otherwise `false`.
59
- */
60
- isAsync(value) {
61
- const stringTag = /(\w+)]/g.exec(Object.prototype.toString.call(value))[1];
62
- return (value instanceof Function &&
63
- stringTag.includes('Async'));
64
- },
65
- /**
66
- * The `ifAsync` function checks if a given value is an async function and
67
- * returns one of two provided values based on the result. This function is
68
- * a convenience method for performing conditional operations based on the
69
- * type of a value.
70
- *
71
- * @param {*} value - The value to be checked. If this is an async function,
72
- * `thenValue` is returned, otherwise `elseValue` is returned.
73
- * @param {*} thenValue - The value to be returned if `value` is an async
74
- * function.
75
- * @param {*} elseValue - The value to be returned if `value` is not an
76
- * async function.
77
- * @returns {*} Returns `thenValue` if `value` is an async function,
78
- * otherwise returns `elseValue`.
79
- * @see {@link isThenElse}
80
- *
81
- * @example
82
- * // Suppose we have an async function and a regular function
83
- * async function asyncFunc() { return 'I am async'; }
84
- * function regularFunc() { return 'I am regular'; }
85
- *
86
- * // Using ifAsync
87
- * console.log(Function.ifAsync(asyncFunc, 'Async', 'Not Async'));
88
- * // Output: 'Async'
89
- * console.log(Function.ifAsync(regularFunc, 'Async', 'Not Async'));
90
- * // Output: 'Not Async'
91
- */
92
- ifAsync(value, thenValue, elseValue) {
93
- return isThenElse(this.isAsync(value), thenValue, elseValue);
94
- },
95
- /**
96
- * The function checks if a given value is an async generator function
97
- *
98
- * @param {any} value - The `value` parameter is the value that we want to
99
- * check if it is a generator function.
100
- * @returns {boolean} `true` if the value is an instance of a function and
101
- * its string tag is 'AsyncGeneratorFunction', otherwise it returns `false`.
102
- */
103
- isAsyncGenerator(value) {
104
- const stringTag = getStringTag(value);
105
- return (value instanceof Function &&
106
- stringTag == 'AsyncGeneratorFunction');
107
- },
108
- /**
109
- * The `ifAsyncGenerator` function checks if a given value is an async
110
- * generator function and returns one of two provided values based on the
111
- * result. This function is a convenience method for performing conditional
112
- * operations based on the type of a value.
113
- *
114
- * @param {*} value - The value to be checked. If this is an async
115
- * generator function, `thenValue` is returned, otherwise `elseValue` is
116
- * returned.
117
- * @param {*} thenValue - The value to be returned if `value` is an async
118
- * generator function.
119
- * @param {*} elseValue - The value to be returned if `value` is not an
120
- * async generator function.
121
- * @returns {*} Returns `thenValue` if `value` is an async generator
122
- * function, otherwise returns `elseValue`.
123
- *
124
- * @example
125
- * // Suppose we have an async generator function and a regular function
126
- * async function* asyncGenFunc() { yield 'I am async'; }
127
- * function regularFunc() { return 'I am regular'; }
128
- *
129
- * // Using ifAsyncGenerator
130
- * console.log(Function.ifAsyncGenerator(asyncGenFunc, 'Async', 'Not Async'));
131
- * // Output: 'Async'
132
- * console.log(Function.ifAsyncGenerator(regularFunc, 'Async', 'Not Async'));
133
- * // Output: 'Not Async'
134
- */
135
- ifAsyncGenerator(value, thenValue, elseValue) {
136
- return isThenElse(this.isAsyncGenerator(value), thenValue, elseValue);
137
- },
138
- /**
139
- * Checks if a given value is an arrow function. It verifies if the value is
140
- * an instance of `Function`, if its string representation includes the '=>'
141
- * symbol, and if it lacks a prototype, which is a characteristic of arrow
142
- * functions in JavaScript.
143
- *
144
- * @param {*} value - The value to be checked.
145
- * @returns {boolean} Returns `true` if the value is an arrow function,
146
- * otherwise `false`.
147
- */
148
- isBigArrow(value) {
149
- return (value instanceof Function &&
150
- String(value).includes('=>') &&
151
- !String(value).startsWith('bound') &&
152
- !Reflect.has(value, 'prototype'));
153
- },
154
- /**
155
- * The `ifBigArrow` function checks if a given value is an arrow function
156
- * and returns one of two provided values based on the result. This function
157
- * is a convenience method for performing conditional operations based on
158
- * the type of a value.
159
- *
160
- * @param {*} value - The value to be checked. If this is an arrow function,
161
- * `thenValue` is returned, otherwise `elseValue` is returned.
162
- * @param {*} thenValue - The value to be returned if `value` is an arrow
163
- * function.
164
- * @param {*} elseValue - The value to be returned if `value` is not an
165
- * arrow function.
166
- * @returns {*} Returns `thenValue` if `value` is an arrow function,
167
- * otherwise returns `elseValue`.
168
- *
169
- * @example
170
- * // Suppose we have an arrow function and a regular function
171
- * const arrowFunc = () => 'I am an arrow function';
172
- * function regularFunc() { return 'I am a regular function'; }
173
- *
174
- * // Using ifBigArrow
175
- * console.log(Function.ifBigArrow(arrowFunc, 'Arrow', 'Not Arrow'));
176
- * // Output: 'Arrow'
177
- * console.log(Function.ifBigArrow(regularFunc, 'Arrow', 'Not Arrow'));
178
- * // Output: 'Not Arrow'
179
- */
180
- ifBigArrow(value, thenValue, elseValue) {
181
- return isThenElse(this.isBigArrow(value), thenValue, elseValue);
182
- },
183
- /**
184
- * Determines if a given value is a bound function. Bound functions are
185
- * created using the `Function.prototype.bind` method, which allows setting
186
- * the `this` value at the time of binding. This method checks if the value
187
- * is an instance of `Function`, if its string representation starts with
188
- * 'bound', and if it lacks a `prototype` property. These characteristics
189
- * are indicative of bound functions in JavaScript.
190
- *
191
- * @param {*} value - The value to be checked, typically a function.
192
- * @returns {boolean} Returns `true` if the value is a bound function,
193
- * otherwise `false`. Bound functions have a specific format in their
194
- * string representation and do not have their own `prototype` property.
195
- */
196
- isBound(value) {
197
- return (value instanceof Function &&
198
- String(value).startsWith('bound') &&
199
- !Reflect.has(value, 'prototype'));
200
- },
201
- /**
202
- * The `ifBound` function checks if a given value is a bound function and
203
- * returns one of two provided values based on the result. This function
204
- * is a convenience method for performing conditional operations based on
205
- * the type of a value.
206
- *
207
- * @param {*} value - The value to be checked. If this is a bound function,
208
- * `thenValue` is returned, otherwise `elseValue` is returned.
209
- * @param {*} thenValue - The value to be returned if `value` is a bound
210
- * function.
211
- * @param {*} elseValue - The value to be returned if `value` is not a
212
- * bound function.
213
- * @returns {*} Returns `thenValue` if `value` is a bound function,
214
- * otherwise returns `elseValue`.
215
- *
216
- * @example
217
- * // Suppose we have a bound function and a regular function
218
- * const boundFunc = function() { return this.x }.bind({x: 'I am bound'});
219
- * function regularFunc() { return 'I am a regular function'; }
220
- *
221
- * // Using ifBound
222
- * console.log(Function.ifBound(boundFunc, 'Bound', 'Not Bound'));
223
- * // Output: 'Bound'
224
- * console.log(Function.ifBound(regularFunc, 'Bound', 'Not Bound'));
225
- * // Output: 'Not Bound'
226
- */
227
- ifBound(value, thenValue, elseValue) {
228
- return isThenElse(this.isBound(value), thenValue, elseValue);
229
- },
230
- /**
231
- * Determines if a given value is a class. It checks if the value is an
232
- * instance of `Function` and if its string representation includes the
233
- * keyword 'class'. This method is useful for distinguishing classes from
234
- * other function types in JavaScript.
235
- *
236
- * @param {*} value - The value to be checked.
237
- * @returns {boolean} Returns `true` if the value is a class, otherwise
238
- * `false`.
239
- */
240
- isClass(value) {
241
- return value instanceof Function && !!/^class\s/.exec(String(value));
242
- },
243
- /**
244
- * The `ifClass` function checks if a given value is a class and returns
245
- * one of two provided values based on the result. This function is a
246
- * convenience method for performing conditional operations based on the
247
- * type of a value.
248
- *
249
- * @param {*} value - The value to be checked. If this is a class,
250
- * `thenValue` is returned, otherwise `elseValue` is returned.
251
- * @param {*} thenValue - The value to be returned if `value` is a class.
252
- * @param {*} elseValue - The value to be returned if `value` is not a
253
- * class.
254
- * @returns {*} Returns `thenValue` if `value` is a class, otherwise returns
255
- * `elseValue`.
256
- *
257
- * @example
258
- * // Suppose we have a class and a regular function
259
- * class MyClass {}
260
- * function myFunction() {}
261
- *
262
- * // Using ifClass
263
- * console.log(Function.ifClass(MyClass, 'Class', 'Not Class'));
264
- * // Output: 'Class'
265
- * console.log(Function.ifClass(myFunction, 'Class', 'Not Class'));
266
- * // Output: 'Not Class'
267
- */
268
- ifClass(value, thenValue, elseValue) {
269
- return isThenElse(this.isClass(value), thenValue, elseValue);
270
- },
271
- /**
272
- * Checks if a given value is a regular function. This method verifies if
273
- * the value is an instance of `Function`, which includes regular functions,
274
- * classes, and async functions but excludes arrow functions.
275
- *
276
- * @param {*} value - The value to be checked.
277
- * @returns {boolean} Returns `true` if the value is a regular function,
278
- * otherwise `false`.
279
- */
280
- isFunction(value) {
281
- return value instanceof Function && !Function.isClass(value);
282
- },
283
- /**
284
- * The `ifFunction` method checks if a given value is a regular function
285
- * and returns one of two provided values based on the result. This method
286
- * is a convenience for performing conditional operations based on the
287
- * type of a value.
288
- *
289
- * @param {*} value - The value to be checked. If this is a function,
290
- * `thenValue` is returned, otherwise `elseValue` is returned.
291
- * @param {*} thenValue - The value to be returned if `value` is a function.
292
- * @param {*} elseValue - The value to be returned if `value` is not a
293
- * function.
294
- * @returns {*} Returns `thenValue` if `value` is a function, otherwise
295
- * returns `elseValue`.
296
- *
297
- * @example
298
- * // Suppose we have a function and a non-function value
299
- * function myFunction() {}
300
- * let notFunction = "I'm not a function";
301
- *
302
- * // Using ifFunction
303
- * console.log(Function.ifFunction(myFunction, 'Function', 'Not Function'));
304
- * // Output: 'Function'
305
- * console.log(Function.ifFunction(notFunction, 'Function', 'Not Function'));
306
- * // Output: 'Not Function'
307
- */
308
- ifFunction(value, thenValue, elseValue) {
309
- return isThenElse(this.isFunction(value), thenValue, elseValue);
310
- },
311
- /**
312
- * The function checks if a given value is a generator function
313
- *
314
- * @param {any} value - The `value` parameter is the value that we want to
315
- * check if it is a generator function.
316
- * @returns {boolean} `true` if the value is an instance of a function and
317
- * its string tag is 'GeneratorFunction', otherwise it returns `false`.
318
- */
319
- isGenerator(value) {
320
- const stringTag = getStringTag(value);
321
- return (value instanceof Function &&
322
- stringTag == 'GeneratorFunction');
323
- },
324
- /**
325
- * The `ifGenerator` method checks if a given value is a generator function
326
- * and returns one of two provided values based on the result. This method
327
- * is a convenience for performing conditional operations based on the
328
- * type of a value.
329
- *
330
- * @param {*} value - The value to be checked. If this is a generator
331
- * function, `thenValue` is returned, otherwise `elseValue` is returned.
332
- * @param {*} thenValue - The value to be returned if `value` is a generator
333
- * function.
334
- * @param {*} elseValue - The value to be returned if `value` is not a
335
- * generator function.
336
- * @returns {*} Returns `thenValue` if `value` is a generator function,
337
- * otherwise returns `elseValue`.
338
- *
339
- * @example
340
- * // Suppose we have a generator function and a non-generator function
341
- * function* myGenerator() {}
342
- * function myFunction() {}
343
- *
344
- * // Using ifGenerator
345
- * console.log(Function.ifGenerator(myGenerator, 'Generator', 'Not Generator'));
346
- * // Output: 'Generator'
347
- * console.log(Function.ifGenerator(myFunction, 'Generator', 'Not Generator'));
348
- * // Output: 'Not Generator'
349
- */
350
- ifGenerator(value, thenValue, elseValue) {
351
- return isThenElse(this.isGenerator(value), thenValue, elseValue);
352
- },
353
- /**
354
- * This method modifies the behavior of the `instanceof` operator for a
355
- * given class. It does this by defining a custom `Symbol.hasInstance`
356
- * method on the class. The custom method checks if the string tag of the
357
- * instance matches the name of the class or if the instance is part of
358
- * the prototype chain of the class.
359
- *
360
- * @param {Function} Class - The class for which to modify the behavior
361
- * of the `instanceof` operator.
362
- *
363
- * @example
364
- * // Suppose we have a class `MyClass`
365
- * class MyClass {}
366
- *
367
- * // And an instance of the class
368
- * const myInstance = new MyClass();
369
- *
370
- * // Before applying `StringTagHasInstance`, `instanceof` works as usual
371
- * console.log(myInstance instanceof MyClass); // Output: true
372
- *
373
- * // Now we apply `StringTagHasInstance` to `MyClass`
374
- * FunctionExtensions.patches.StringTagHasInstance(MyClass);
375
- *
376
- * // `instanceof` now checks the string tag and the prototype chain
377
- * console.log(myInstance instanceof MyClass); // Output: true
378
- */
379
- StringTagHasInstance(Class) {
380
- Object.defineProperty(Class, Symbol.hasInstance, {
381
- value: function stringTagAwareHasInstance(fn) {
382
- const protoChain = getPrototypeChainEntries(fn);
383
- return (fn[Symbol.toStringTag] === this.name ||
384
- fn instanceof this);
385
- }
386
- });
387
- },
388
- },
389
- });
390
- const { isAsyncGenerator: pIsAsyncGenerator, ifAsyncGenerator: pIfAsyncGenerator, isAsync: pIsAsync, ifAsync: pIfAsync, isBigArrow: pIsBigArrow, ifBigArrow: pIfBigArrow, isBound: pIsBound, ifBound: pIfBound, isClass: pIsClass, ifClass: pIfClass, isFunction: pIsFunction, ifFunction: pIfFunction, isGenerator: pIsGenerator, ifGenerator: pIfGenerator, } = FunctionExtensions.patches;
391
- export const FunctionPrototypeExtensions = new Patch(Function.prototype, {
392
- [Patch.kMutablyHidden]: {
393
- /**
394
- * Determines if a given value is an asynchronous function. It checks if the
395
- * value is an instance of `Function` and if its string representation
396
- * includes the keyword 'Async'. This method is particularly useful for
397
- * identifying async functions.
398
- *
399
- * @returns {boolean} Returns `true` if the value is an async function,
400
- * otherwise `false`.
401
- */
402
- get isAsync() {
403
- return pIsAsync(this);
404
- },
405
- /**
406
- * The `ifAsync` method checks if the current function is asynchronous and
407
- * returns one of two provided values based on the result. This method is
408
- * a convenience for performing conditional operations based on the
409
- * type of a function.
410
- *
411
- * @param {*} thenValue - The value to be returned if the function is
412
- * asynchronous.
413
- * @param {*} elseValue - The value to be returned if the function is not
414
- * asynchronous.
415
- * @returns {*} Returns `thenValue` if the function is asynchronous,
416
- * otherwise returns `elseValue`.
417
- * @see {@link Function.ifAsync}
418
- *
419
- * @example
420
- * // Suppose we have an async function and a non-async function
421
- * async function myAsyncFunction() {}
422
- * function myFunction() {}
423
- *
424
- * // Using ifAsync
425
- * console.log(myAsyncFunction.ifAsync('Async', 'Not Async'));
426
- * // Output: 'Async'
427
- * console.log(myFunction.ifAsync('Async', 'Not Async'));
428
- * // Output: 'Not Async'
429
- */
430
- ifAsync(thenValue, elseValue) {
431
- return pIfAsync(this, thenValue, elseValue);
432
- },
433
- /**
434
- * The function checks if a given value is an async generator function
435
- *
436
- * @returns {boolean} `true` if the value is an instance of a function and
437
- * its string tag is 'AsyncGeneratorFunction', otherwise it returns `false`.
438
- */
439
- get isAsyncGenerator() {
440
- return pIsAsyncGenerator(this);
441
- },
442
- /**
443
- * The `ifAsyncGenerator` method checks if the current function is an
444
- * asynchronous generator and returns one of two provided values based on
445
- * the result. This method is a convenience for performing conditional
446
- * operations based on the type of a function.
447
- *
448
- * @param {*} thenValue - The value to be returned if the function is an
449
- * asynchronous generator.
450
- * @param {*} elseValue - The value to be returned if the function is not
451
- * an asynchronous generator.
452
- * @returns {*} Returns `thenValue` if the function is an asynchronous
453
- * generator, otherwise returns `elseValue`.
454
- * @see {@link Function.ifAsyncGenerator}
455
- *
456
- * @example
457
- * // Suppose we have an async generator function and a non-async function
458
- * async function* myAsyncGeneratorFunction() {}
459
- * function myFunction() {}
460
- *
461
- * // Using ifAsyncGenerator
462
- * console.log(myAsyncGeneratorFunction.ifAsyncGenerator(
463
- * 'Async Generator', 'Not Async Generator'
464
- * ));
465
- * // Output: 'Async Generator'
466
- * console.log(myFunction.ifAsyncGenerator(
467
- * 'Async Generator', 'Not Async Generator'
468
- * ));
469
- * // Output: 'Not Async Generator'
470
- */
471
- ifAsyncGenerator(thenValue, elseValue) {
472
- return pIfAsyncGenerator(this, thenValue, elseValue);
473
- },
474
- /**
475
- * Checks if a given value is an arrow function. It verifies if the value is
476
- * an instance of `Function`, if its string representation includes the '=>'
477
- * symbol, and if it lacks a prototype, which is a characteristic of arrow
478
- * functions in JavaScript.
479
- *
480
- * @returns {boolean} Returns `true` if the value is an arrow function,
481
- * otherwise `false`.
482
- */
483
- get isBigArrow() {
484
- return pIsBigArrow(this);
485
- },
486
- /**
487
- * Checks if the current function is a "big arrow" function and
488
- * returns one of two provided values based on the result.
489
- *
490
- * A "big arrow" function is an arrow function that is not bound
491
- * to a specific context and does not have its own `this` value.
492
- *
493
- * @param {*} thenValue - The value to be returned if the function
494
- * is a "big arrow" function.
495
- * @param {*} elseValue - The value to be returned if the function
496
- * is not a "big arrow" function.
497
- * @returns {*} Returns `thenValue` if the function is a "big arrow"
498
- * function, otherwise returns `elseValue`.
499
- *
500
- * @example
501
- * // Suppose we have a "big arrow" function and a regular function
502
- * const bigArrowFn = () => {}
503
- * function regularFn() {}
504
- *
505
- * // Using ifBigArrow
506
- * console.log(bigArrowFn.ifBigArrow('Big Arrow', 'Not Big Arrow'))
507
- * // Output: 'Big Arrow'
508
- * console.log(regularFn.ifBigArrow('Big Arrow', 'Not Big Arrow'))
509
- * // Output: 'Not Big Arrow'
510
- */
511
- ifBigArrow(thenValue, elseValue) {
512
- return pIfBigArrow(this, thenValue, elseValue);
513
- },
514
- /**
515
- * Determines if a given value is a bound function. Bound functions are
516
- * created using the `Function.prototype.bind` method, which allows setting
517
- * the `this` value at the time of binding. This method checks if the value
518
- * is an instance of `Function`, if its string representation starts with
519
- * 'bound', and if it lacks a `prototype` property. These characteristics
520
- * are indicative of bound functions in JavaScript.
521
- *
522
- * @returns {boolean} Returns `true` if the value is a bound function,
523
- * otherwise `false`. Bound functions have a specific format in their
524
- * string representation and do not have their own `prototype` property.
525
- */
526
- get isBound() {
527
- return pIsBound(this);
528
- },
529
- /**
530
- * Checks if the current function is bound and returns one of two
531
- * provided values based on the result.
532
- *
533
- * A bound function is a function that has a fixed `this` value and
534
- * may have preset arguments. It is created using the
535
- * `Function.prototype.bind` method.
536
- *
537
- * @param {*} thenValue - The value to be returned if the function
538
- * is bound.
539
- * @param {*} elseValue - The value to be returned if the function
540
- * is not bound.
541
- * @returns {*} Returns `thenValue` if the function is bound,
542
- * otherwise returns `elseValue`.
543
- *
544
- * @example
545
- * // Suppose we have a bound function and a regular function
546
- * const boundFn = function() {}.bind(null)
547
- * function regularFn() {}
548
- *
549
- * // Using ifBound
550
- * console.log(boundFn.ifBound('Bound', 'Not Bound'))
551
- * // Output: 'Bound'
552
- * console.log(regularFn.ifBound('Bound', 'Not Bound'))
553
- * // Output: 'Not Bound'
554
- */
555
- ifBound(thenValue, elseValue) {
556
- return pIfBound(this, thenValue, elseValue);
557
- },
558
- /**
559
- * Determines if a given value is a class. It checks if the value is an
560
- * instance of `Function` and if its string representation includes the
561
- * keyword 'class'. This method is useful for distinguishing classes from
562
- * other function types in JavaScript.
563
- *
564
- * @returns {boolean} Returns `true` if the value is a class, otherwise
565
- * `false`.
566
- */
567
- get isClass() {
568
- return pIsClass(this);
569
- },
570
- /**
571
- * Checks if the current function is a class and returns one of two
572
- * provided values based on the result.
573
- *
574
- * A class is a special type of function in JavaScript that is
575
- * defined using the `class` keyword. It serves as a blueprint for
576
- * creating objects and encapsulates data and behavior.
577
- *
578
- * @param {any} thenValue - The value to be returned if the function
579
- * is a class.
580
- * @param {any} elseValue - The value to be returned if the function
581
- * is not a class.
582
- * @returns {any} Returns `thenValue` if the function is a class,
583
- * otherwise returns `elseValue`.
584
- *
585
- * @example
586
- * // Suppose we have a class and a regular function
587
- * class MyClass {}
588
- * function myFunction() {}
589
- *
590
- * // Using ifClass
591
- * console.log(MyClass.ifClass('Class', 'Not Class'))
592
- * // Output: 'Class'
593
- * console.log(myFunction.ifClass('Class', 'Not Class'))
594
- * // Output: 'Not Class'
595
- */
596
- ifClass(thenValue, elseValue) {
597
- return pIfClass(this, thenValue, elseValue);
598
- },
599
- /**
600
- * Checks if a given value is a regular function. This method verifies if
601
- * the value is an instance of `Function`, which includes regular functions,
602
- * classes, and async functions but excludes arrow functions.
603
- *
604
- * @returns {boolean} Returns `true` if the value is a regular function,
605
- * otherwise `false`.
606
- */
607
- get isFunction() {
608
- return pIsFunction(this);
609
- },
610
- /**
611
- * Checks if the current function is a regular function and returns
612
- * one of two provided values based on the result.
613
- *
614
- * A regular function is an instance of `Function`, which includes
615
- * regular functions, classes, and async functions but excludes
616
- * arrow functions.
617
- *
618
- * @param {any} thenValue - The value to be returned if the function
619
- * is a regular function.
620
- * @param {any} elseValue - The value to be returned if the function
621
- * is not a regular function.
622
- * @returns {any} Returns `thenValue` if the function is a regular
623
- * function, otherwise returns `elseValue`.
624
- *
625
- * @example
626
- * // Suppose we have a regular function and an arrow function
627
- * function regularFunction() {}
628
- * const arrowFunction = () => {}
629
- *
630
- * // Using ifFunction
631
- * console.log(regularFunction.ifFunction('Regular', 'Not Regular'))
632
- * // Output: 'Regular'
633
- * console.log(arrowFunction.ifFunction('Regular', 'Not Regular'))
634
- * // Output: 'Not Regular'
635
- */
636
- ifFunction(thenValue, elseValue) {
637
- return pIfFunction(this, thenValue, elseValue);
638
- },
639
- /**
640
- * The function checks if a given value is a generator function
641
- *
642
- * @returns {boolean} `true` if the value is an instance of a function and
643
- * its string tag is 'GeneratorFunction', otherwise it returns `false`.
644
- */
645
- get isGenerator() {
646
- return pIsGenerator(this);
647
- },
648
- /**
649
- * Checks if the current function is a generator function and
650
- * returns one of two provided values based on the result.
651
- *
652
- * A generator function is a special type of function that can be
653
- * paused and resumed, allowing it to yield multiple values over
654
- * time rather than returning a single value.
655
- *
656
- * @param {any} thenValue - The value to be returned if the
657
- * function is a generator function.
658
- * @param {any} elseValue - The value to be returned if the
659
- * function is not a generator function.
660
- * @returns {any} Returns `thenValue` if the function is a
661
- * generator function, otherwise returns `elseValue`.
662
- *
663
- * @example
664
- * // Suppose we have a generator function and a regular function
665
- * function* generatorFunction() {
666
- * yield 1
667
- * yield 2
668
- * yield 3
669
- * }
670
- * function regularFunction() {}
671
- *
672
- * // Using ifGenerator
673
- * console.log(generatorFunction.ifGenerator('Generator', 'Regular'))
674
- * // Output: 'Generator'
675
- * console.log(regularFunction.ifGenerator('Generator', 'Regular'))
676
- * // Output: 'Regular'
677
- */
678
- ifGenerator(thenValue, elseValue) {
679
- return pIfGenerator(this, thenValue, elseValue);
680
- },
681
- /**
682
- * Retrieves the properties of the current function and its prototype.
683
- *
684
- * This method uses the `getClassProperties` function from the
685
- * `FunctionExtensions.patches` object to get all the properties of the
686
- * current function and its prototype. The properties include both
687
- * enumerable and non-enumerable properties, as well as properties
688
- * defined with symbols.
689
- *
690
- * @returns {Array} An array containing the function itself, its property
691
- * descriptors, its prototype, and the prototype's property descriptors.
692
- *
693
- * @example
694
- * // Suppose we have a function with a property and a prototype property
695
- * function MyFunction() {}
696
- * MyFunction.myProp = 'hello';
697
- * MyFunction.prototype.myProtoProp = 'world';
698
- *
699
- * // Using getClassProperties
700
- * const result = MyFunction.getClassProperties();
701
- * console.log(result);
702
- * // Output: [MyFunction, { myProp: { value: 'hello', writable: true,
703
- * // enumerable: true, configurable: true } }, MyFunction.prototype,
704
- * // { myProtoProp: { value: 'world', writable: true, enumerable: true,
705
- * // configurable: true } }]
706
- */
707
- getClassProperties() {
708
- return FunctionExtensions.patches.getClassProperties(this);
709
- },
710
- },
711
- });
712
- // NOTE to self; this is repeated here otherwise a circular reference from
713
- // Object<->Function<->Global occurs. See original source in global.this.js
714
- // {@see globalThis.isThenElse}
715
- function isThenElse(bv, tv, ev) {
716
- function isFunction(value) { typeof value === 'function'; }
717
- if (arguments.length > 1) {
718
- var _then = isFunction(tv) ? tv(bv) : tv;
719
- if (arguments.length > 2) {
720
- var _else = isFunction(ev) ? tv(bv) : ev;
721
- return bv ? _then : _else;
722
- }
723
- return bv || _then;
724
- }
725
- return bv;
726
- }
727
- function hasStringTag(value) {
728
- return Object.isObject(value) && Reflect.has(value, Symbol.toStringTag);
729
- }
730
- function getStringTag(value, strict = false) {
731
- if (Object.hasStringTag(value)) {
732
- return value[Symbol.toStringTag];
733
- }
734
- if (strict) {
735
- return undefined;
736
- }
737
- if (value && (typeof value === 'function')) {
738
- return value.name;
739
- }
740
- return /\s(.+)]/.exec(Object.prototype.toString.call(value))[1];
741
- }
742
- function getPrototypeChainEntries(object) {
743
- const entries = [];
744
- let prototype = Object.getPrototypeOf(object);
745
- while (prototype) {
746
- const descriptors = Reflect.ownKeys(prototype).reduce((acc, key) => {
747
- acc[key] = Object.getOwnPropertyDescriptor(prototype, key);
748
- return acc;
749
- }, {});
750
- entries.push([prototype, descriptors]);
751
- prototype = Object.getPrototypeOf(prototype);
752
- }
753
- return entries;
754
- }
755
- //# sourceMappingURL=function.extensions.js.map