@nejs/basic-extensions 2.9.0 → 2.10.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.
Files changed (167) hide show
  1. package/dist/@nejs/basic-extensions.bundle.2.10.0.js +19 -0
  2. package/dist/@nejs/basic-extensions.bundle.2.10.0.js.map +7 -0
  3. package/dist/cjs/array.extensions.js +174 -0
  4. package/dist/cjs/array.extensions.js.map +1 -1
  5. package/dist/cjs/big.int.extension.js +1 -0
  6. package/dist/cjs/big.int.extension.js.map +1 -1
  7. package/dist/cjs/classes/descriptor.js +1 -1
  8. package/dist/cjs/classes/descriptor.js.map +1 -1
  9. package/dist/cjs/classes/index.d.ts +1 -0
  10. package/dist/cjs/classes/index.js +3 -0
  11. package/dist/cjs/classes/index.js.map +1 -1
  12. package/dist/cjs/classes/iterable.d.ts +44 -0
  13. package/dist/cjs/classes/iterable.js +64 -0
  14. package/dist/cjs/classes/iterable.js.map +1 -1
  15. package/dist/cjs/classes/param.parser.d.ts +10 -10
  16. package/dist/cjs/classes/property.d.ts +86 -0
  17. package/dist/cjs/classes/property.js +284 -0
  18. package/dist/cjs/classes/property.js.map +1 -0
  19. package/dist/cjs/classes/symkeys.d.ts +68 -11
  20. package/dist/cjs/classes/symkeys.js +103 -17
  21. package/dist/cjs/classes/symkeys.js.map +1 -1
  22. package/dist/cjs/classes/type.d.ts +4 -4
  23. package/dist/cjs/function.extensions.js +1 -0
  24. package/dist/cjs/function.extensions.js.map +1 -1
  25. package/dist/cjs/global.this.js +29 -0
  26. package/dist/cjs/global.this.js.map +1 -1
  27. package/dist/cjs/index.d.ts +2 -0
  28. package/dist/cjs/index.js +18 -0
  29. package/dist/cjs/index.js.map +1 -1
  30. package/dist/cjs/json.extensions.js +19 -18
  31. package/dist/cjs/json.extensions.js.map +1 -1
  32. package/dist/cjs/map.extensions.js +1 -0
  33. package/dist/cjs/map.extensions.js.map +1 -1
  34. package/dist/cjs/number.extension.js +1 -0
  35. package/dist/cjs/number.extension.js.map +1 -1
  36. package/dist/cjs/object.extensions.d.ts +0 -29
  37. package/dist/cjs/object.extensions.js +218 -255
  38. package/dist/cjs/object.extensions.js.map +1 -1
  39. package/dist/cjs/set.extensions.js +1 -0
  40. package/dist/cjs/set.extensions.js.map +1 -1
  41. package/dist/cjs/string.extensions.js +474 -469
  42. package/dist/cjs/string.extensions.js.map +1 -1
  43. package/dist/cjs/symbol.extensions.js +386 -31
  44. package/dist/cjs/symbol.extensions.js.map +1 -1
  45. package/dist/cjs/utils/copy.object.d.ts +408 -0
  46. package/dist/cjs/utils/copy.object.js +720 -0
  47. package/dist/cjs/utils/copy.object.js.map +1 -0
  48. package/dist/cjs/utils/index.d.ts +1 -0
  49. package/dist/cjs/utils/index.js +19 -0
  50. package/dist/cjs/utils/index.js.map +1 -0
  51. package/dist/cjs/utils/toolkit.d.ts +1897 -0
  52. package/dist/cjs/utils/toolkit.js +1377 -0
  53. package/dist/cjs/utils/toolkit.js.map +1 -0
  54. package/dist/mjs/array.extensions.js +174 -0
  55. package/dist/mjs/array.extensions.js.map +1 -1
  56. package/dist/mjs/big.int.extension.js +1 -0
  57. package/dist/mjs/big.int.extension.js.map +1 -1
  58. package/dist/mjs/classes/descriptor.js +1 -1
  59. package/dist/mjs/classes/descriptor.js.map +1 -1
  60. package/dist/mjs/classes/index.d.ts +1 -0
  61. package/dist/mjs/classes/index.js +3 -0
  62. package/dist/mjs/classes/index.js.map +1 -1
  63. package/dist/mjs/classes/iterable.d.ts +44 -0
  64. package/dist/mjs/classes/iterable.js +64 -0
  65. package/dist/mjs/classes/iterable.js.map +1 -1
  66. package/dist/mjs/classes/param.parser.d.ts +10 -10
  67. package/dist/mjs/classes/property.d.ts +86 -0
  68. package/dist/mjs/classes/property.js +280 -0
  69. package/dist/mjs/classes/property.js.map +1 -0
  70. package/dist/mjs/classes/symkeys.d.ts +68 -11
  71. package/dist/mjs/classes/symkeys.js +103 -17
  72. package/dist/mjs/classes/symkeys.js.map +1 -1
  73. package/dist/mjs/classes/type.d.ts +4 -4
  74. package/dist/mjs/function.extensions.js +1 -0
  75. package/dist/mjs/function.extensions.js.map +1 -1
  76. package/dist/mjs/global.this.js +6 -0
  77. package/dist/mjs/global.this.js.map +1 -1
  78. package/dist/mjs/index.d.ts +2 -0
  79. package/dist/mjs/index.js +4 -0
  80. package/dist/mjs/index.js.map +1 -1
  81. package/dist/mjs/json.extensions.js +19 -18
  82. package/dist/mjs/json.extensions.js.map +1 -1
  83. package/dist/mjs/map.extensions.js +1 -0
  84. package/dist/mjs/map.extensions.js.map +1 -1
  85. package/dist/mjs/number.extension.js +1 -0
  86. package/dist/mjs/number.extension.js.map +1 -1
  87. package/dist/mjs/object.extensions.d.ts +0 -29
  88. package/dist/mjs/object.extensions.js +215 -251
  89. package/dist/mjs/object.extensions.js.map +1 -1
  90. package/dist/mjs/set.extensions.js +1 -0
  91. package/dist/mjs/set.extensions.js.map +1 -1
  92. package/dist/mjs/string.extensions.js +474 -469
  93. package/dist/mjs/string.extensions.js.map +1 -1
  94. package/dist/mjs/symbol.extensions.js +386 -31
  95. package/dist/mjs/symbol.extensions.js.map +1 -1
  96. package/dist/mjs/utils/copy.object.d.ts +408 -0
  97. package/dist/mjs/utils/copy.object.js +702 -0
  98. package/dist/mjs/utils/copy.object.js.map +1 -0
  99. package/dist/mjs/utils/index.d.ts +1 -0
  100. package/dist/mjs/utils/index.js +3 -0
  101. package/dist/mjs/utils/index.js.map +1 -0
  102. package/dist/mjs/utils/toolkit.d.ts +1897 -0
  103. package/dist/mjs/utils/toolkit.js +1372 -0
  104. package/dist/mjs/utils/toolkit.js.map +1 -0
  105. package/package.json +29 -37
  106. package/repl.bootstrap.js +12 -1
  107. package/src/array.extensions.js +191 -1
  108. package/src/big.int.extension.js +3 -1
  109. package/src/classes/descriptor.js +1 -1
  110. package/src/classes/index.js +4 -0
  111. package/src/classes/iterable.js +74 -0
  112. package/src/classes/property.js +333 -0
  113. package/src/classes/symkeys.js +120 -19
  114. package/src/function.extensions.js +2 -0
  115. package/src/global.this.js +8 -0
  116. package/src/index.js +5 -0
  117. package/src/json.extensions.js +18 -19
  118. package/src/map.extensions.js +3 -1
  119. package/src/number.extension.js +3 -1
  120. package/src/object.extensions.js +240 -277
  121. package/src/set.extensions.js +3 -1
  122. package/src/string.extensions.js +512 -506
  123. package/src/symbol.extensions.js +412 -29
  124. package/src/utils/copy.object.js +780 -0
  125. package/src/utils/index.js +2 -0
  126. package/src/utils/toolkit.js +1471 -0
  127. package/tests/arrayextensions.test.js +2 -0
  128. package/tests/index.test.js +1 -0
  129. package/tests/newClasses/asyncIterable.test.js +2 -0
  130. package/tests/newClasses/deferred.test.js +5 -3
  131. package/tests/newClasses/descriptor.test.js +2 -0
  132. package/tests/newClasses/iterable.test.js +2 -0
  133. package/tests/newClasses/refmap.test.js +2 -1
  134. package/tests/newClasses/refset.test.js +2 -0
  135. package/tests/objectextensions.test.js +2 -0
  136. package/tests/setextensions.test.js +2 -0
  137. package/tests/stringextensions.test.js +1 -0
  138. package/tests/utils/toolkit.test.js +223 -0
  139. package/tsconfig.base.json +1 -1
  140. package/vitest.config.js +7 -0
  141. package/dist/@nejs/basic-extensions.bundle.2.8.0.js +0 -19
  142. package/dist/@nejs/basic-extensions.bundle.2.8.0.js.map +0 -7
  143. package/docs/assets/anchor.js +0 -350
  144. package/docs/assets/bass-addons.css +0 -12
  145. package/docs/assets/bass.css +0 -544
  146. package/docs/assets/fonts/EOT/SourceCodePro-Bold.eot +0 -0
  147. package/docs/assets/fonts/EOT/SourceCodePro-Regular.eot +0 -0
  148. package/docs/assets/fonts/LICENSE.txt +0 -93
  149. package/docs/assets/fonts/OTF/SourceCodePro-Bold.otf +0 -0
  150. package/docs/assets/fonts/OTF/SourceCodePro-Regular.otf +0 -0
  151. package/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf +0 -0
  152. package/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf +0 -0
  153. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff +0 -0
  154. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff +0 -0
  155. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff +0 -0
  156. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff +0 -0
  157. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 +0 -0
  158. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 +0 -0
  159. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 +0 -0
  160. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 +0 -0
  161. package/docs/assets/fonts/source-code-pro.css +0 -23
  162. package/docs/assets/github.css +0 -123
  163. package/docs/assets/site.js +0 -168
  164. package/docs/assets/split.css +0 -15
  165. package/docs/assets/split.js +0 -782
  166. package/docs/assets/style.css +0 -147
  167. package/docs/index.html +0 -35485
@@ -2,17 +2,12 @@ import { Patch } from '@nejs/extension'
2
2
 
3
3
  import { SymbolExtensions } from './symbol.extensions.js';
4
4
  import { Descriptor } from './classes/descriptor.js';
5
+ import { Property } from './classes/property.js';
5
6
 
6
- const { keys: symkeys } = SymbolExtensions.patches
7
+ import { as, has, is, si } from './utils/toolkit.js';
8
+ import { copyObject } from './utils/copy.object.js';
7
9
 
8
- // Avoid circular dependencies; rewrite here for brevity
9
- const isFn = o => typeof o === 'function' || o instanceof Function
10
- const isStr = o => typeof o === 'string' || o instanceof String
11
- const isBool = o => typeof o === 'boolean'
12
- const isTrue = o => isBool(o) && o === true
13
- const isTruthy = o => isTrue(!!o)
14
- const isFalse = o => isBool(o) && o === false
15
- const isFalsy = o => isFalse(!!o)
10
+ const { keys: symkeys } = SymbolExtensions.patches
16
11
 
17
12
  /**
18
13
  * `ObjectExtensions` is a constant that applies a patch to the global
@@ -28,6 +23,128 @@ const isFalsy = o => isFalse(!!o)
28
23
  */
29
24
  export const ObjectExtensions = new Patch(Object, {
30
25
  [Patch.kMutablyHidden]: {
26
+ add(...args) {
27
+ const { isDescriptor } = Descriptor
28
+ const { isObject: isObj } = this
29
+ const { kDescriptorStore } = this
30
+
31
+ let obj, key, value, _get, _set, storage, storageKey
32
+ let _type, _flag, _desc
33
+
34
+ // Check to see if we received multiple arguments or an object
35
+ if (args.length && isObj(args[0])) {
36
+ ({
37
+ to: obj,
38
+ key,
39
+ value,
40
+ get: _get,
41
+ set: _set,
42
+ storage,
43
+ storageKey,
44
+ type: _type = ['accessor', 'data'][1],
45
+ flag: _flag = undefined,
46
+ descriptorBase: _desc = undefined,
47
+ } = args[0])
48
+ }
49
+ else if (args.length > 1) {
50
+ ([
51
+ to,
52
+ _type,
53
+ key,
54
+ getOrValue,
55
+ _set,
56
+ storage,
57
+ storageKey,
58
+ _flag,
59
+ _desc,
60
+ ] = args)
61
+
62
+ obj = to
63
+ _type = (
64
+ ['accessor', 'data'].includes(_type.toLowerCase())
65
+ ? _type.toLowerCase() : 'data'
66
+ )
67
+ _get = _type === 'accessor' ? getOrValue : undefined
68
+ _value = _type === 'data' ? getOrValue : undefined
69
+ }
70
+
71
+ if (!this.isObject(obj)) {
72
+ console.warn('Object.add() must receive an object for `toObject`')
73
+ return obj;
74
+ }
75
+
76
+ const more = isDescriptor(_desc) ? _desc : {}
77
+ const flag = _flag || Object.definitionType.mutablyVisible
78
+ const props = { ...Patch.getDescriptorOverridesFromSymbol(flag), ...more }
79
+ const type = (['accessor', 'data'].includes(_type)
80
+ ? String(_type).toLowerCase() : 'data'
81
+ )
82
+
83
+ switch (type) {
84
+ case 'accessor':
85
+ let store = storage;
86
+ let storeKey = storageKey || key
87
+ let makeStore = false
88
+ let get = _get;
89
+ let set = _set;
90
+
91
+ if (!is.truthy(get) && !is.function(get)) { get = undefined }
92
+ if (!is.truthy(set) && !is.function(set)) { set = undefined }
93
+
94
+ if (isObj(store) ||is.true(store) || is.function(store)) {
95
+ makeStore =is.true(store)
96
+ store = is.fn(store) ? store() : store
97
+ store = is.object(store) ? store : (makeStore && {} || undefined)
98
+ }
99
+ // store should be defined by here: object or undefined
100
+
101
+ if ((!get && !set) && makeStore) {
102
+ // being lazy here, someone has defined we make an accessor but
103
+ // wants the default accessor behaviors with an associated store
104
+ // made by us.
105
+ Object.defineProperty(obj, kDescriptorStore, {
106
+ value: symkeys.add('descriptor.store', store),
107
+ configurable: true,
108
+ enumerable: false,
109
+ writable: true,
110
+ })
111
+
112
+ get = () => this[kDescriptorStore]?.data?.[storeKey]
113
+ set = (value) => { this[kDescriptorStore].data[storeKey] = value }
114
+ }
115
+
116
+ else if (get?.length && set?.length > 1 && store) {
117
+ // if we received a get or set that takes more arguments than
118
+ // expected, assume the last argument should be the store variable
119
+ // so we execute the supplied function with the storage and its
120
+ // results or byproducts are the result to the get/set we define
121
+ const innerGet = get
122
+ const innerSet = set
123
+ get = () => innerGet(store)
124
+ set = (value) => innerSet(value, store)
125
+ }
126
+ // get and set should be in their final state by here
127
+
128
+ Object.defineProperty(obj, key, { ...props, get, set })
129
+ break
130
+
131
+ case 'data':
132
+ Object.defineProperty(obj, key, { ...props, value })
133
+ break
134
+ }
135
+
136
+ return obj
137
+ },
138
+
139
+ addAccessor(to, key, getter, setter, storage) {
140
+ const store = storage ?? (!getter && !setter) ? true : undefined;
141
+ return this.add({ to, key, get: getter, set: setter, storage: store })
142
+ },
143
+
144
+ addData(to, key, value) {
145
+ return this.add({ to, key, value })
146
+ },
147
+
31
148
  /**
32
149
  * Creates a shallow copy of the provided object(s).
33
150
  *
@@ -85,6 +202,34 @@ export const ObjectExtensions = new Patch(Object, {
85
202
  return copyObject(true, destination, ...sources)
86
203
  },
87
204
 
205
+ /**
206
+ * Defines a new property on an object with a specified value and
207
+ * visibility/mutability flag. The flag determines the visibility and
208
+ * mutability of the property. By default, the property is defined as
209
+ * mutably hidden.
210
+ *
211
+ * @param {object} object - The object on which to define the property.
212
+ * @param {string} key - The name of the property to be defined.
213
+ * @param {any} value - The value of the property to be defined.
214
+ * @param {symbol} [flag=Object.definitionType.mutablyHidden] - The
215
+ * visibility/mutability flag for the property. This should be one of the
216
+ * symbols available in `ObjectExtensions.definitionType`.
217
+ * @returns {object} The object with the newly defined property.
218
+ *
219
+ * @example
220
+ * // Define a new mutably hidden property on an object
221
+ * const myObject = {};
222
+ * const myValue = 'Hello, world!';
223
+ * const hiddenSymbol = Object.definitionType.mutablyHidden;
224
+ * Object.define(myObject, 'myProperty', myValue, hiddenSymbol);
225
+ * // myObject now has a mutably hidden property 'myProperty' with value
226
+ * // 'Hello, world!'
227
+ */
228
+ define(object, key, value, flag = Object.definitionType.mutablyHidden) {
229
+ const properties = Patch.getDescriptorOverridesFromSymbol(flag)
230
+ return Object.defineProperty(object, key, { ...properties, value })
231
+ },
232
+
88
233
  /**
89
234
  * A getter property that provides access to the definition types used
90
235
  * for object property definitions. These types are used to control the
@@ -117,34 +262,6 @@ export const ObjectExtensions = new Patch(Object, {
117
262
  }
118
263
  },
119
264
 
120
- /**
121
- * Defines a new property on an object with a specified value and
122
- * visibility/mutability flag. The flag determines the visibility and
123
- * mutability of the property. By default, the property is defined as
124
- * mutably hidden.
125
- *
126
- * @param {object} object - The object on which to define the property.
127
- * @param {string} key - The name of the property to be defined.
128
- * @param {any} value - The value of the property to be defined.
129
- * @param {symbol} [flag=Object.definitionType.mutablyHidden] - The
130
- * visibility/mutability flag for the property. This should be one of the
131
- * symbols available in `ObjectExtensions.definitionType`.
132
- * @returns {object} The object with the newly defined property.
133
- *
134
- * @example
135
- * // Define a new mutably hidden property on an object
136
- * const myObject = {};
137
- * const myValue = 'Hello, world!';
138
- * const hiddenSymbol = Object.definitionType.mutablyHidden;
139
- * Object.define(myObject, 'myProperty', myValue, hiddenSymbol);
140
- * // myObject now has a mutably hidden property 'myProperty' with value
141
- * // 'Hello, world!'
142
- */
143
- define(object, key, value, flag = Object.definitionType.mutablyHidden) {
144
- const properties = Patch.getDescriptorOverridesFromSymbol(flag)
145
- return Object.defineProperty(object, key, { ...properties, value })
146
- },
147
-
148
265
  /**
149
266
  * Defines a new accessor property on an object with specified getter and
150
267
  * setter functions and a visibility/mutability flag. The flag determines
@@ -181,128 +298,6 @@ export const ObjectExtensions = new Patch(Object, {
181
298
  return Object.defineProperty(object, key, { ...properties, get, set })
182
299
  },
183
300
 
184
- addAccessor(to, key, getter, setter, storage) {
185
- const store = storage ?? (!getter && !setter) ? true : undefined;
186
- return this.add({ to, key, get: getter, set: setter, storage: store })
187
- },
188
-
189
- addData(to, key, value) {
190
- return this.add({ to, key, value })
191
- },
192
-
193
- add(...args) {
194
- const { isDescriptor } = Descriptor
195
- const { isObject: isObj } = this
196
- const { kDescriptorStore } = this
197
-
198
- let obj, key, value, _get, _set, storage, storageKey
199
- let _type, _flag, _desc
200
-
201
- // Check to see if we received multiple arguments or an object
202
- if (args.length && isObj(args[0])) {
203
- ({
204
- to: obj,
205
- key,
206
- value,
207
- get: _get,
208
- set: _set,
209
- storage,
210
- storageKey,
211
- type: _type = ['accessor', 'data'][1],
212
- flag: _flag = undefined,
213
- descriptorBase: _desc = undefined,
214
- } = args[0])
215
- }
216
- else if (args.length > 1) {
217
- ([
218
- to,
219
- _type,
220
- key,
221
- getOrValue,
222
- _set,
223
- storage,
224
- storageKey,
225
- _flag,
226
- _desc,
227
- ] = args)
228
-
229
- obj = to
230
- _type = (
231
- ['accessor', 'data'].includes(_type.toLowerCase())
232
- ? _type.toLowerCase() : 'data'
233
- )
234
- _get = _type === 'accessor' ? getOrValue : undefined
235
- _value = _type === 'data' ? getOrValue : undefined
236
- }
237
-
238
- if (!this.isObject(obj)) {
239
- console.warn('Object.add() must receive an object for `toObject`')
240
- return obj;
241
- }
242
-
243
- const more = isDescriptor(_desc) ? _desc : {}
244
- const flag = _flag || Object.definitionType.mutablyVisible
245
- const props = { ...Patch.getDescriptorOverridesFromSymbol(flag), ...more }
246
- const type = (['accessor', 'data'].includes(_type)
247
- ? String(_type).toLowerCase() : 'data'
248
- )
249
-
250
- switch (type) {
251
- case 'accessor':
252
- let store = storage;
253
- let storeKey = storageKey || key
254
- let makeStore = false
255
- let get = _get;
256
- let set = _set;
257
-
258
- if (!isTruthy(get) && !isFn(get)) { get = undefined }
259
- if (!isTruthy(set) && !isFn(set)) { set = undefined }
260
-
261
- if (isObj(store) || isTrue(store) || isFn(store)) {
262
- makeStore = isTrue(store)
263
- store = isFn(store) ? store() : store
264
- store = isObj(store) ? store : (makeStore && {} || undefined)
265
- }
266
- // store should be defined by here: object or undefined
267
-
268
- if ((!get && !set) && makeStore) {
269
- // being lazy here, someone has defined we make an accessor but
270
- // wants the default accessor behaviors with an associated store
271
- // made by us.
272
- Object.defineProperty(obj, kDescriptorStore, {
273
- value: symkeys.add('descriptor.store', store),
274
- configurable: true,
275
- enumerable: false,
276
- writable: true,
277
- })
278
-
279
- get = () => this[kDescriptorStore]?.data?.[storeKey]
280
- set = (value) => { this[kDescriptorStore].data[storeKey] = value }
281
- }
282
-
283
- else if (get?.length && set?.length > 1 && store) {
284
- // if we received a get or set that takes more arguments than
285
- // expected, assume the last argument should be the store variable
286
- // so we execute the supplied function with the storage and its
287
- // results or byproducts are the result to the get/set we define
288
- const innerGet = get
289
- const innerSet = set
290
- get = () => innerGet(store)
291
- set = (value) => innerSet(value, store)
292
- }
293
- // get and set should be in their final state by here
294
-
295
- Object.defineProperty(obj, key, { ...props, get, set })
296
- break
297
-
298
- case 'data':
299
- Object.defineProperty(obj, key, { ...props, value })
300
- break
301
- }
302
-
303
- return obj
304
- },
305
-
306
301
  /**
307
302
  * Creates a new object from an array of key-value pairs (entries), with an
308
303
  * optional prototype and reducer function. If no prototype is provided,
@@ -337,12 +332,12 @@ export const ObjectExtensions = new Patch(Object, {
337
332
  * // with prototype { foo: 'bar' }
338
333
  */
339
334
  fromEntriesUsing(entries, prototype = Object.prototype, reducer = undefined) {
340
- if (!Array.isArray(entries)) {
335
+ if (!is.array(entries)) {
341
336
  return undefined;
342
337
  }
343
338
 
344
339
  const entriesToUse = entries.filter(
345
- entry => Array.isArray(entry) && entry.length >= 2
340
+ entry => is.array(entry) && entry.length >= 2
346
341
  );
347
342
 
348
343
  if (!entriesToUse.length) {
@@ -414,7 +409,7 @@ export const ObjectExtensions = new Patch(Object, {
414
409
  * @returns {string} - The string tag of the object, indicating its type.
415
410
  */
416
411
  getStringTag(value, strict = false) {
417
- if (Object.hasStringTag(value)) {
412
+ if (has.stringTag(value)) {
418
413
  return value[Symbol.toStringTag]
419
414
  }
420
415
 
@@ -469,7 +464,7 @@ export const ObjectExtensions = new Patch(Object, {
469
464
  * @returns true if the symbol is defined, false otherwise
470
465
  */
471
466
  hasStringTag(value) {
472
- return Object.isObject(value) && Reflect.has(value, Symbol.toStringTag)
467
+ return has.stringTag(value)
473
468
  },
474
469
 
475
470
  /**
@@ -481,7 +476,7 @@ export const ObjectExtensions = new Patch(Object, {
481
476
  * and `false` otherwise.
482
477
  */
483
478
  isNullDefined(value) {
484
- return value === undefined || value === null
479
+ return is.nullish(value)
485
480
  },
486
481
 
487
482
  /**
@@ -517,7 +512,7 @@ export const ObjectExtensions = new Patch(Object, {
517
512
  * );
518
513
  */
519
514
  ifNullDefined(value, thenValue, elseValue) {
520
- return isThenElse(this.isNullDefined(value), thenValue, elseValue);
515
+ return isThenElse(is.nullish(value), thenValue, elseValue);
521
516
  },
522
517
 
523
518
  /**
@@ -542,21 +537,31 @@ export const ObjectExtensions = new Patch(Object, {
542
537
  * console.log(isObject(null)); // Output: false
543
538
  */
544
539
  isObject(value) {
545
- return value instanceof Object || value && typeof value === 'object'
540
+ return is.object(value)
546
541
  },
547
542
 
548
543
  /**
549
- * Determines if the provided value is an object. This method checks whether
550
- * the value is an instance of `Object` or if its type is 'object'. It's a
551
- * utility method for type-checking, ensuring that a value is an object
552
- * before performing operations that are specific to objects.
544
+ * Executes a conditional function based on whether the provided value
545
+ * is an object or not. This method first checks if the value is an
546
+ * object using the `is.object` method from the toolkit. If it is, it
547
+ * returns the `thenValue`, otherwise it returns the `elseValue`.
553
548
  *
554
- * @param {*} value - The value to be checked.
555
- * @returns {boolean} - Returns `true` if the value is an object,
556
- * otherwise `false`.
557
- },
558
- isObject(value) {
559
- return value && (value instanceof Object || typeof value === 'object');
549
+ * @param {any} value - The value to be checked.
550
+ * @param {function | any} thenValue - The value to return if `value`
551
+ * is an object.
552
+ * @param {function | any} elseValue - The value to return if `value`
553
+ * is not an object.
554
+ * @returns {*} - Returns `thenValue` if the value is an object,
555
+ * otherwise `elseValue`.
556
+ *
557
+ * @example
558
+ * // returns 'Is Object'
559
+ * ifObject({}, 'Is Object', 'Not Object')
560
+ * // returns 'Not Object'
561
+ * ifObject(42, 'Is Object', 'Not Object')
562
+ */
563
+ ifObject(value, thenValue, elseValue) {
564
+ return isThenElse(is.object(value), thenValue, elseValue)
560
565
  },
561
566
 
562
567
  /**
@@ -567,24 +572,7 @@ export const ObjectExtensions = new Patch(Object, {
567
572
  * false otherwise.
568
573
  */
569
574
  isPrimitive(value) {
570
- // Check for null as a special case because typeof null
571
- // is 'object'
572
- if (value === null) {
573
- return true;
574
- }
575
-
576
- // Check for other primitives
577
- switch (typeof value) {
578
- case 'string':
579
- case 'number':
580
- case 'bigint':
581
- case 'boolean':
582
- case 'undefined':
583
- case 'symbol':
584
- return true;
585
- default:
586
- return false;
587
- }
575
+ return is.primitive(value)
588
576
  },
589
577
 
590
578
  /**
@@ -608,7 +596,7 @@ export const ObjectExtensions = new Patch(Object, {
608
596
  * ifPrimitive({a: 'hello'}, 1, 2)
609
597
  */
610
598
  ifPrimitive(value, thenValue, elseValue) {
611
- return isThenElse(this.isPrimitive(value), thenValue, elseValue)
599
+ return isThenElse(is.primitive(value), thenValue, elseValue)
612
600
  },
613
601
 
614
602
  /**
@@ -814,6 +802,61 @@ export const ObjectExtensions = new Patch(Object, {
814
802
 
815
803
  return result;
816
804
  },
805
+
806
+ withProperties(prototype, ...properties) {
807
+ const props = properties.filter(p => p instanceof Property);
808
+ const possible = properties.filter(p => Array.isArray(p))
809
+
810
+ if (possible.length) {
811
+ for (const [key, descriptorOrDataOrAccessorArgs, ...rest] of possible) {
812
+ // if arg[1] is a descriptor
813
+ if (Property.is.descriptor(descriptorOrDataOrAccessorArgs)) {
814
+ props.push(new Property(key, descriptorOrDataOrAccessorArgs))
815
+ }
816
+ else {
817
+ const { get, set } = descriptorOrDataOrAccessorArgs;
818
+ const args = [key, descriptorOrDataOrAccessorArgs, ...rest];
819
+ if (get || set) {
820
+ props.push(Property.accessor(...args))
821
+ }
822
+ else {
823
+ props.push(Property.data(...args))
824
+ }
825
+ }
826
+ }
827
+ }
828
+
829
+ const object = Object.create(prototype ?? Object.prototype);
830
+ const sorted = props.toSorted(
831
+ (a,b) => a.key < b.key ? -1 : (a.key > b.key ? 1 : 0)
832
+ );
833
+ for (const property of sorted) {
834
+ property.apply(object);
835
+ }
836
+
837
+ Property.data(Symbol.for('properties'), sorted).apply(object);
838
+ return object;
839
+ },
840
+
841
+ /**
842
+ * Retrieves a toolkit object containing various utility functions
843
+ * for type checking and introspection.
844
+ *
845
+ * The toolkit includes many functions. It was designed to read as
846
+ * though the toolkit were assigned to the variable `it`.
847
+ *
848
+ * @example
849
+ * const is = ObjectExtensions.patches.toolkit
850
+ * console.log(is.object({})) // Output: true
851
+ * console.log(is.string('hello')) // Output: true
852
+ * console.log(is.number(42)) // Output: true
853
+ *
854
+ * @returns {object} The toolkit object containing various utility
855
+ * functions for type checking and introspection.
856
+ */
857
+ get toolkit() {
858
+ return { as, has, is, si }
859
+ },
817
860
  },
818
861
  });
819
862
 
@@ -1149,89 +1192,9 @@ export const ObjectPrototypeExtensions = new Patch(Object.prototype, {
1149
1192
  // {@see globalThis.isThenElse}
1150
1193
  function isThenElse(bv, tv, ev) {
1151
1194
  if (arguments.length > 1) {
1152
- var _then = isFunction(tv) ? tv(bv) : tv; if (arguments.length > 2) {
1153
- var _else = isFunction(ev) ? tv(bv) : ev; return bv ? _then : _else
1195
+ var _then = is.function(tv) ? tv(bv) : tv; if (arguments.length > 2) {
1196
+ var _else = is.function(ev) ? tv(bv) : ev; return bv ? _then : _else
1154
1197
  } return bv || _then;
1155
1198
  } return bv
1156
1199
  }
1157
1200
 
1158
- /**
1159
- * Creates a deep or shallow copy of the provided source objects and merges
1160
- * them into the destination object. The function uses a Set to keep track
1161
- * of visited objects to avoid circular references.
1162
- *
1163
- * @function
1164
- * @name copyObject
1165
- * @param {boolean} deep - If true, performs a deep copy, otherwise performs
1166
- * a shallow copy.
1167
- * @param {object} destination - The object to which properties will be copied.
1168
- * @param {...object} sources - The source object(s) from which properties
1169
- * will be copied.
1170
- * @returns {object} The destination object with the copied properties.
1171
- *
1172
- * @example
1173
- * // Shallow copy
1174
- * const obj1 = { a: 1, b: { c: 2 } };
1175
- * const obj2 = { b: { d: 3 }, e: 4 };
1176
- * const result = copyObject(false, obj1, obj2);
1177
- * console.log(result); // Output: { a: 1, b: { d: 3 }, e: 4 }
1178
- *
1179
- * @example
1180
- * // Deep copy
1181
- * const obj1 = { a: 1, b: { c: 2 } };
1182
- * const obj2 = { b: { d: 3 }, e: 4 };
1183
- * const result = copyObject(true, obj1, obj2);
1184
- * console.log(result); // Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }
1185
- */
1186
- export function copyObject(deep, destination, ...sources) {
1187
- const visited = new Set()
1188
-
1189
- for (const source of sources) {
1190
- if (source === null || typeof source !== 'object' || visited.has(source)) {
1191
- continue
1192
- }
1193
-
1194
- visited.add(source)
1195
-
1196
- const keys = Reflect.ownKeys(source)
1197
- for (const key of keys) {
1198
- let descriptor
1199
- try {
1200
- descriptor = Object.getOwnPropertyDescriptor(source, key)
1201
- } catch (err) {
1202
- console.warn(`Failed to get descriptor for key "${key}": ${err}`)
1203
- continue
1204
- }
1205
-
1206
- const isDataDesc = Reflect.has(descriptor, 'value')
1207
- const keyedValue = descriptor?.value
1208
-
1209
- const conditionsMet = [
1210
- isDataDesc,
1211
- keyedValue,
1212
- typeof keyedValue === 'object',
1213
- !visited.has(keyedValue)
1214
- ].every(condition => condition)
1215
-
1216
- if (conditionsMet) {
1217
- visited.add(keyedValue)
1218
-
1219
- const prototype = Object.getPrototypeOf(keyedValue)
1220
- const descriptors = Object.getOwnPropertyDescriptors(keyedValue)
1221
- const replacement = Object.create(prototype, descriptors)
1222
-
1223
- descriptor.value = deep
1224
- ? copyObject(deep, replacement, keyedValue)
1225
- : replacement
1226
- }
1227
-
1228
- try {
1229
- Object.defineProperty(destination, key, descriptor)
1230
- } catch (err) {
1231
- console.error(`Failed to define property "${key}": ${err}`)
1232
- }
1233
- }
1234
- }
1235
-
1236
- return destination
1237
- }
@@ -385,9 +385,11 @@ export const SetPrototypeExtensions = new Patch(Set.prototype, {
385
385
  // Object<->Function<->Global occurs. See original source in global.this.js
386
386
  // {@see globalThis.isThenElse}
387
387
  function isThenElse(bv, tv, ev) {
388
+ function isFunction(value) { typeof value === 'function' }
389
+
388
390
  if (arguments.length > 1) {
389
391
  var _then = isFunction(tv) ? tv(bv) : tv; if (arguments.length > 2) {
390
392
  var _else = isFunction(ev) ? tv(bv) : ev; return bv ? _then : _else
391
393
  } return bv || _then;
392
394
  } return bv
393
- }
395
+ }