@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
@@ -4,6 +4,7 @@ import { Symkeys } from './classes/symkeys.js'
4
4
  import { JSONExtensions } from './json.extensions.js'
5
5
 
6
6
  const JSONToggle = new PatchToggle(JSONExtensions)
7
+ const symkeys = new Symkeys('nejs')
7
8
 
8
9
  /**
9
10
  * `SymbolExtensions` is a patch for the JavaScript built-in `Symbol` class. It
@@ -14,14 +15,159 @@ const JSONToggle = new PatchToggle(JSONExtensions)
14
15
  * utility functions.
15
16
  */
16
17
  export const SymbolExtensions = new Patch(Symbol, {
17
- add(named, associatedData = {}) {
18
- return this.keys.add(named, associatedData)
18
+ /**
19
+ * Adds a new symbol to the Symkeys instance with the given name and
20
+ * associated data.
21
+ *
22
+ * This method generates a unique symbol based on the provided name,
23
+ * optional domain, separator, and token. It also allows embedding
24
+ * additional data into the symbol's name.
25
+ *
26
+ * @param {string} named - The base name for the new symbol.
27
+ * @param {Object} options - Additional options for the symbol.
28
+ * @param {*} [options.associate={}] - Data to associate with the symbol.
29
+ * @param {Object} [options.embed] - Optional data to embed in the symbol.
30
+ * @param {string} [options.useDomain] - Optional domain to include in the
31
+ * symbol's name.
32
+ * @param {string} [options.useSeparator] - Optional separator to use in
33
+ * the symbol's name.
34
+ * @param {string} [options.useToken] - Optional token to use for the
35
+ * symbol. If not provided, a random token is generated.
36
+ * @returns {Symbol} The newly created symbol.
37
+ *
38
+ * @example
39
+ * // Add a symbol with associated data
40
+ * const mySymbol = SymbolExtensions.add('myIdentifier', {
41
+ * associate: { foo: 'bar' },
42
+ * embed: { baz: 'qux' },
43
+ * useDomain: 'exampleDomain',
44
+ * useSeparator: '-',
45
+ * useToken: 'customToken',
46
+ * })
47
+ * console.log(mySymbol)
48
+ * // Symbol(@exampleDomain-myIdentifier {"baz":"qux"} #customToken)
49
+ */
50
+ add(named, { associate = {}, embed, useToken, useDomain, useSeparator }) {
51
+ return this.keys.add(named, {
52
+ associate, embed, useToken, useDomain, useSeparator,
53
+ })
19
54
  },
20
55
 
56
+ /**
57
+ * Deletes the data associated with a given symbol from the Symkeys
58
+ * instance.
59
+ *
60
+ * This method allows removal of the data that has been associated with a
61
+ * particular symbol in the Symkeys instance. It is useful when you want
62
+ * to clean up or remove stored information associated with a symbol.
63
+ *
64
+ * @param {Symbol} forSymbol - The symbol whose associated data is to be
65
+ * deleted.
66
+ * @param {*} [replaceWith=undefined] - Optionally, if `replaceWith` is
67
+ * not `undefined`, a new value can be set after the original is deleted
68
+ * @returns {boolean} - Returns true if an element in the Symkeys existed
69
+ * and has been removed, or false if the element does not exist
70
+ *
71
+ * @example
72
+ * // Assuming 'mySymbol' is a symbol that has been added to the Symkeys
73
+ * // with associated data
74
+ * const isDeleted = Symbol.deleteData(mySymbol)
75
+ * console.log(isDeleted) // Output: true if data was deleted, false
76
+ *
77
+ * @example
78
+ * // Deleting data and replacing it with a new value
79
+ * const mySymbol = Symbol.for('mySymbol')
80
+ * Symbol.setData(mySymbol, { foo: 'bar' })
81
+ * Symbol.deleteData(mySymbol, { newFoo: 'newBar' })
82
+ * console.log(Symbol.keys.data(mySymbol)) // Output: { newFoo: 'newBar' }
83
+ */
21
84
  deleteData(forSymbol, replaceWith = undefined) {
22
85
  return this.keys.deleteData(forSymbol, replaceWith)
23
86
  },
24
87
 
88
+ /**
89
+ * Evaluates a key or value and generates a shared symbol key based on
90
+ * the provided object name and owner name.
91
+ *
92
+ * This method takes a key or value, an object name, and an object owner
93
+ * name as parameters. It determines the type of each parameter and
94
+ * constructs a token string by concatenating the owner name, object
95
+ * name, and key/value (if they are valid object keys).
96
+ *
97
+ * The token string is then used to create a shared symbol key using the
98
+ * `sharedKey` method of the current instance. The shared symbol key is
99
+ * returned along with the token as associated data.
100
+ *
101
+ * @param {string|Symbol} keyOrValue - The key or value to evaluate.
102
+ * @param {string|Symbol} objectName - The name of the object associated
103
+ * with the key or value.
104
+ * @param {string|Function|Object} objectOwnerName - The name of the
105
+ * owner of the object.
106
+ * @returns {Symbol} The shared symbol key generated based on the
107
+ * provided parameters.
108
+ *
109
+ * @example
110
+ * const symbolKey = SymbolExtensions.evalKey('myKey', 'myObject', 'myOwner')
111
+ * console.log(symbolKey)
112
+ * // Output: Symbol(@nejs.internal.refkey:myOwner.myObject.myKey)
113
+ *
114
+ * @example
115
+ * const symbolKey = SymbolExtensions.evalKey(
116
+ * 'myValue', () => {}, { [Symbol.toStringTag]: 'myOwner' }
117
+ * )
118
+ * console.log(symbolKey)
119
+ * // Output: Symbol(@nejs.internal.refkey:myOwner.myValue)
120
+ */
121
+ evalKey(keyOrValue, objectName, objectOwnerName) {
122
+ const is = {
123
+ string(v) { return typeof v === 'string' },
124
+ func(v) { return typeof v === 'function' },
125
+ object(v) { return typeof v === 'object' },
126
+ objKey(v) { return ['symbol', 'string'].some(k => typeof v === k) },
127
+ }
128
+ is.key = is.objKey(keyOrValue)
129
+
130
+ const ownerName = (
131
+ (is.string(objectOwnerName) && objectOwnerName) ||
132
+ (is.func(objectOwnerName) && objectOwnerName?.name) ||
133
+ (is.object(objectOwnerName) && objectOwnerName?.[Symbol.toStringTag]) ||
134
+ undefined
135
+ )
136
+
137
+ const token = [
138
+ ownerName && `${ownerName}.` || '',
139
+ is.objKey(objectName) && `${objectName}.` || '',
140
+ is.objKey(keyOrValue) && `${keyOrValue}`,
141
+ ].join('')
142
+
143
+ return this.sharedKey(`internal.refkey:${token}`, { token })
144
+ },
145
+
146
+ /**
147
+ * Checks if the Symkeys instance has data associated with a given
148
+ * symbol
149
+ *
150
+ * This method checks if the Symkeys instance has any data associated
151
+ * with the provided symbol. It is useful when you need to verify if
152
+ * data exists for a particular symbol before attempting to retrieve
153
+ * or manipulate it
154
+ *
155
+ * @param {Symbol} forSymbol - The symbol to check for associated data
156
+ * @returns {boolean} Returns true if data exists for the symbol,
157
+ * false otherwise
158
+ *
159
+ * @example
160
+ * // Assuming 'mySymbol' is a symbol that has been added to the
161
+ * // Symkeys with associated data
162
+ * const hasData = Symbol.hasData(mySymbol)
163
+ * console.log(hasData) // Output: true
164
+ *
165
+ * @example
166
+ * // Assuming 'nonExistentSymbol' is a symbol that has not been added
167
+ * // to the Symkeys
168
+ * const hasData = Symbol.hasData(nonExistentSymbol)
169
+ * console.log(hasData) // Output: false
170
+ */
25
171
  hasData(forSymbol) {
26
172
  return this.keys.hasData(forSymbol)
27
173
  },
@@ -109,12 +255,88 @@ export const SymbolExtensions = new Patch(Symbol, {
109
255
  * kOriginal.data.original = Object.prototype // ...and...
110
256
  * kOriginal.data = [Object.prototype, Array.prototype] // ...both work
111
257
  */
112
- keys: new Symkeys('nejs'),
258
+ get keys() { return symkeys },
113
259
 
260
+ /**
261
+ * Sets the data associated with a given symbol in the Symkeys
262
+ * instance.
263
+ *
264
+ * This method allows you to store data associated with a specific
265
+ * symbol in the Symkeys instance. It is useful when you want to
266
+ * attach additional information or metadata to a symbol for later
267
+ * retrieval.
268
+ *
269
+ * @param {Symbol} forSymbol - The symbol for which to set the
270
+ * associated data.
271
+ * @param {*} value - The data to be associated with the symbol.
272
+ *
273
+ * @example
274
+ * // Create a symbol
275
+ * const mySymbol = Symbol.for('mySymbol')
276
+ *
277
+ * // Set data for the symbol
278
+ * Symbol.setData(mySymbol, { foo: 'bar' })
279
+ *
280
+ * // Retrieve the data associated with the symbol
281
+ * const data = Symbol.keys.data(mySymbol)
282
+ * console.log(data) // Output: { foo: 'bar' }
283
+ */
114
284
  setData(forSymbol, value) {
115
285
  this.keys.setData(forSymbol, value)
116
286
  },
117
287
 
288
+ /**
289
+ * Creates or retrieves a shared symbol key with the given name and
290
+ * optional associated data.
291
+ *
292
+ * This method generates a shared symbol key using the provided name
293
+ * and optional parameters. If the symbol already exists in the
294
+ * Symkeys's internal map, it updates the associated data if provided.
295
+ * Otherwise, it creates a new symbol with the specified parameters.
296
+ *
297
+ * @param {string} named - The name to use for the shared symbol key.
298
+ * @param {Object} options - Optional parameters for the shared symbol key.
299
+ * @param {Object} [options.associate] - Data to associate with the symbol.
300
+ * @param {Object} [options.embed] - Data to embed in the symbol's name.
301
+ * @param {string} [options.useDomain] - Domain to include in the symbol's name.
302
+ * @param {string} [options.useSeparator] - Separator to use in the symbol's name.
303
+ * @returns {Symbol} The shared symbol key.
304
+ *
305
+ * @example
306
+ * // Create or retrieve a shared symbol key with associated data
307
+ * const sharedSymbol = Symbol.sharedKey('mySharedKey', {
308
+ * associate: { foo: 'bar' },
309
+ * embed: { baz: 'qux' },
310
+ * useDomain: 'exampleDomain',
311
+ * useSeparator: '-',
312
+ * })
313
+ * console.log(sharedSymbol)
314
+ * // Output: Symbol(@exampleDomain-mySharedKey {"baz":"qux"} #shared)
315
+ */
316
+ sharedKey(named, options) {
317
+ return this.keys.sharedKey(named, options)
318
+ },
319
+
320
+ /**
321
+ * A symbol used as the storage key for the single instance of a
322
+ * singleton.
323
+ *
324
+ * This getter returns a unique symbol created using `Symbol.for()`
325
+ * with the string 'singleton'. The symbol is used to store and
326
+ * retrieve the single instance of a singleton object.
327
+ *
328
+ * @type {symbol}
329
+ * @readonly
330
+ *
331
+ * @example
332
+ * const singletonKey = Symbol.singleton
333
+ * const singletonInstance = {}
334
+ * global[singletonKey] = singletonInstance
335
+ */
336
+ get singleton() {
337
+ return Symbol.for('singleton')
338
+ },
339
+
118
340
  /**
119
341
  * Creates a new Symbol with the given name and optional data. If data
120
342
  * is provided, it will be stringified and appended to the symbol's
@@ -270,9 +492,104 @@ export const SymbolPrototypeExtensions = new Patch(Symbol.prototype, {
270
492
  * Symkeys.getData(symWithData) // returns { name: 'Jane', age: 26 }
271
493
  */
272
494
  set data(value) {
273
- if (Symkeys.isSymkey(this) && Symkeys.hasData(this)) {
495
+ if (Symkeys.isSymkey(this)) {
274
496
  Symbol.keys.setData(this, value)
275
497
  }
498
+ else {
499
+ console.error(`The symbol ${this.description} is not a symkey`)
500
+ }
501
+ },
502
+
503
+ /**
504
+ * Retrieves the embedded JSON data from the symbol's description.
505
+ *
506
+ * This getter method checks if the symbol's description might contain
507
+ * JSON data. If the description contains JSON, it parses and returns
508
+ * the first JSON object found. If no JSON is found, it returns
509
+ * `undefined`.
510
+ *
511
+ * @returns {Object|undefined} - The parsed JSON object if found,
512
+ * otherwise `undefined`.
513
+ *
514
+ * @example
515
+ * const sym = Symbol.for('example {"name":"Brie"}')
516
+ * console.log(sym.embeddedJSON) // Output: { name: 'Brie' }
517
+ *
518
+ * @example
519
+ * const sym = Symbol('noJSON')
520
+ * console.log(sym.embeddedJSON) // Output: undefined
521
+ */
522
+ get embeddedJSON() {
523
+ return JSONToggle.perform((toggle, patch) => {
524
+ let [mightHave, index, parsed] = JSON.mightContain(
525
+ this.description, true
526
+ )
527
+
528
+ if (mightHave) {
529
+ return parsed?.[0]
530
+ }
531
+
532
+ return undefined
533
+ })
534
+ },
535
+
536
+ /**
537
+ * Parses the embedded JSON data from the symbol's description.
538
+ *
539
+ * This getter method first retrieves the embedded JSON data using the
540
+ * `embeddedJSON` getter. If JSON data is found, it attempts to parse
541
+ * the JSON string and return the resulting object. If parsing fails,
542
+ * an error is logged to the console.
543
+ *
544
+ * @returns {Object|undefined} - The parsed JSON object if parsing is
545
+ * successful, otherwise `undefined`.
546
+ *
547
+ * @example
548
+ * const sym = Symbol.for('example {"name":"Brie"}')
549
+ * console.log(sym.embeddedJSONParsed) // Output: { name: 'Brie' }
550
+ *
551
+ * @example
552
+ * const sym = Symbol('invalidJSON')
553
+ * console.log(sym.embeddedJSONParsed) // Output: undefined
554
+ */
555
+ get embeddedJSONParsed() {
556
+ const json = this.embeddedJSON
557
+
558
+ if (json) {
559
+ try {
560
+ return JSON.parse(json)
561
+ }
562
+ catch (error) {
563
+ console.error(`Failed to parse json: "${json}"`)
564
+ }
565
+ }
566
+
567
+ return undefined
568
+ },
569
+
570
+ /**
571
+ * Checks if the current symbol is a Symkey.
572
+ *
573
+ * This getter method determines whether the current symbol instance
574
+ * conforms to the Symkey pattern. A Symkey is a symbol that matches
575
+ * a specific pattern defined in the Symkeys class.
576
+ *
577
+ * @type {boolean}
578
+ * @readonly
579
+ *
580
+ * @returns {boolean} - Returns true if the symbol is a Symkey,
581
+ * otherwise false.
582
+ *
583
+ * @example
584
+ * const sym = Symbol('@nejs.prototype #rwiy2o905d')
585
+ * console.log(sym.isSymkey) // Output: true
586
+ *
587
+ * @example
588
+ * const sym = Symbol('regularSymbol')
589
+ * console.log(sym.isSymkey) // Output: false
590
+ */
591
+ get isSymkey() {
592
+ return Symkeys.isSymkey(this)
276
593
  },
277
594
 
278
595
  /**
@@ -294,39 +611,105 @@ export const SymbolPrototypeExtensions = new Patch(Symbol.prototype, {
294
611
  * console.log(sym.mightHaveEmbeddedJSON) // Output: false
295
612
  */
296
613
  get mightHaveEmbeddedJSON() {
297
- return mightContain(this.description)
614
+ return JSONToggle.perform((toggle, patch) => {
615
+ return JSON.mightContain(this.description)
616
+ })
298
617
  },
299
618
 
300
- get sgrString() {
301
- let revert = false
302
- let detail = undefined
303
-
304
- let { sgr } = String
305
- if (!sgr) { sgr = (string, ...args) => string }
619
+ /**
620
+ * Retrieves the reference object associated with the symbol.
621
+ *
622
+ * This getter method checks if the symbol's description matches a
623
+ * specific pattern using a regular expression. If a match is found,
624
+ * it extracts the token from the description and constructs a shared
625
+ * key using the token. It then retrieves the symbol associated with
626
+ * the shared key using the `sharedKey` method of the
627
+ * `SymbolExtensions.patches` object. Finally, it returns the data
628
+ * associated with the retrieved symbol.
629
+ *
630
+ * If no match is found or the retrieved symbol has no associated
631
+ * data, `undefined` is returned.
632
+ *
633
+ * @type {any}
634
+ * @readonly
635
+ *
636
+ * @example
637
+ * const sym = Symbol.for('@nejs.internal.refkey:example #shared')
638
+ * console.log(sym.refObject) // Output: the data associated with the
639
+ * // 'internal.refkey:example' shared key
640
+ *
641
+ * @example
642
+ * const sym = Symbol('no_match')
643
+ * console.log(sym.refObject) // Output: undefined
644
+ */
645
+ get refObject() {
646
+ const re = /@nejs.internal.refkey:(\S+) #shared/.exec(this.description)
647
+ if (re?.[1]) {
648
+ const [_match, token] = re
649
+ const shareKey = `internal.refkey:${token}`
650
+ const symbol = SymbolExtensions.patches.sharedKey(shareKey)
651
+ return symbol?.data
652
+ }
306
653
 
307
- if (!JSONExtensions.applied) { JSONToggle.start(); revert = true }
308
- if ((detail = JSON.mightContain(this.description, true))) {
309
- let jsonText = detail[2][0]
310
- let index = detail[1]
654
+ return undefined
655
+ },
311
656
 
312
- if (~index && jsonText && jsonText.length > 30) {
313
- let desc = this.description
314
- let newDescription = [
315
- sgr(`Symbol.for(${desc.slice(0, index)}`, 'green'),
316
- sgr(jsonText.slice(0, 10), 'di'),
317
- '...',
318
- sgr(jsonText.slice(-5), 'di'),
319
- sgr(`${desc.slice(index + jsonText.length + 1)})`, 'green'),
320
- ].join('')
657
+ /**
658
+ * Returns a formatted string representation of the symbol's
659
+ * description, highlighting any embedded JSON data.
660
+ *
661
+ * This getter method checks if the symbol's description contains
662
+ * JSON data and formats it for better readability. It uses the
663
+ * `sgr` function from the `String` object to apply color formatting
664
+ * to the output.
665
+ *
666
+ * If the symbol's description contains JSON data longer than 30
667
+ * characters, it truncates the JSON data and displays an ellipsis
668
+ * in the middle. The JSON data is highlighted using the 'di' color
669
+ * code.
670
+ *
671
+ * @type {string}
672
+ * @readonly
673
+ *
674
+ * @example
675
+ * const sym = Symbol.for('mySymbol {"name":"John Doe"}')
676
+ * console.log(sym.sgrString)
677
+ * // Output: Symbol.for(mySymbol {"name":"John ...hn Doe"})
678
+ *
679
+ * @example
680
+ * const sym = Symbol('mySymbol')
681
+ * console.log(sym.sgrString)
682
+ * // Output: mySymbol
683
+ */
684
+ get sgrString() {
685
+ let { sgr } = String
321
686
 
322
- if (revert) { JSONToggle.stop() }
323
- return `${newDescription}`
324
- }
687
+ if (!sgr) {
688
+ sgr = (string, ...args) => string
325
689
  }
326
690
 
327
- if (revert) { JSONToggle.stop() }
691
+ const response = JSONToggle.perform((toggle, patch) => {
692
+ let [mightContain, index, jsonResponse] =
693
+ JSON.mightContain(this.description, true)
694
+ let jsonText = jsonResponse?.[0]
695
+
696
+ if (mightContain) {
697
+ if (~index && jsonText && jsonText.length > 30) {
698
+ let desc = this.description
699
+ let newDescription = [
700
+ sgr(`Symbol.for(${desc.slice(0, index)}`, 'green'),
701
+ sgr(jsonText.slice(0, 10), 'di'),
702
+ '...',
703
+ sgr(jsonText.slice(-5), 'di'),
704
+ sgr(`${desc.slice(index + jsonText.length + 1)})`, 'green')
705
+ ].join('')
706
+
707
+ return `${newDescription}`
708
+ }
709
+ }
710
+ })
328
711
 
329
- return newDescription
712
+ return response ?? this.description
330
713
  },
331
714
 
332
715
  /**