@nejs/basic-extensions 2.21.0 → 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 (270) hide show
  1. package/.idea/markdown.xml +8 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/ne-basic-extensions.iml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/CODE_STYLE.md +393 -0
  6. package/CODING_PHILOSOPHY.md +36 -0
  7. package/DOCUMENTATION_GUIDELINES.md +221 -0
  8. package/README.md +78 -4
  9. package/dist/@nejs/basic-extensions.bundle.2.22.6.js +25 -0
  10. package/dist/@nejs/basic-extensions.bundle.2.22.6.js.map +7 -0
  11. package/dist/cjs/classes/index.cjs +11129 -0
  12. package/dist/cjs/classes/index.cjs.map +7 -0
  13. package/dist/cjs/index.cjs +15191 -0
  14. package/dist/cjs/index.cjs.map +7 -0
  15. package/dist/cjs/utils/index.cjs +3954 -0
  16. package/dist/cjs/utils/index.cjs.map +7 -0
  17. package/dist/esm/basic-extensions.mjs +25 -0
  18. package/dist/esm/basic-extensions.mjs.map +7 -0
  19. package/package.json +16 -22
  20. package/repl.bootstrap.js +4 -7
  21. package/repl.history +30 -30
  22. package/src/big.int.extension.js +171 -45
  23. package/src/classes/enumeration.js +466 -0
  24. package/src/classes/index.js +5 -1
  25. package/src/index.js +5 -1
  26. package/src/math.extension.js +73 -0
  27. package/src/number.extension.js +18 -0
  28. package/src/regular.expression.extensions.js +0 -35
  29. package/src/utils/toolkit.js +699 -516
  30. package/tests/arrayextensions.test.js +3 -3
  31. package/tests/index.test.js +3 -1
  32. package/tests/newClasses/asyncIterable.test.js +3 -3
  33. package/tests/newClasses/deferred.test.js +3 -3
  34. package/tests/newClasses/descriptor.test.js +3 -3
  35. package/tests/newClasses/iterable.test.js +3 -3
  36. package/tests/newClasses/refmap.test.js +3 -3
  37. package/tests/newClasses/refset.test.js +3 -3
  38. package/tests/objectextensions.test.js +3 -3
  39. package/tests/setextensions.test.js +3 -3
  40. package/tests/stringextensions.test.js +3 -2
  41. package/tests/utils/descriptor.utils.test.js +1 -1
  42. package/tests/utils/toolkit.test.js +429 -163
  43. package/.esdoc.json +0 -9
  44. package/.vscode/settings.json +0 -5
  45. package/bin/build +0 -27
  46. package/bin/clean +0 -14
  47. package/bin/esbuild +0 -91
  48. package/bin/fixup +0 -13
  49. package/bin/repl.basics.js +0 -584
  50. package/bin/repl.signature.js +0 -63
  51. package/bin/version +0 -100
  52. package/dist/@nejs/basic-extensions.bundle.2.21.0.js +0 -25
  53. package/dist/@nejs/basic-extensions.bundle.2.21.0.js.map +0 -7
  54. package/dist/cjs/array.extensions.d.ts +0 -39
  55. package/dist/cjs/array.extensions.js +0 -477
  56. package/dist/cjs/array.extensions.js.map +0 -1
  57. package/dist/cjs/big.int.extension.d.ts +0 -31
  58. package/dist/cjs/big.int.extension.js +0 -165
  59. package/dist/cjs/big.int.extension.js.map +0 -1
  60. package/dist/cjs/classes/asyncIterable.d.ts +0 -126
  61. package/dist/cjs/classes/asyncIterable.js +0 -209
  62. package/dist/cjs/classes/asyncIterable.js.map +0 -1
  63. package/dist/cjs/classes/deferred.d.ts +0 -146
  64. package/dist/cjs/classes/deferred.js +0 -291
  65. package/dist/cjs/classes/deferred.js.map +0 -1
  66. package/dist/cjs/classes/descriptor.d.ts +0 -334
  67. package/dist/cjs/classes/descriptor.js +0 -537
  68. package/dist/cjs/classes/descriptor.js.map +0 -1
  69. package/dist/cjs/classes/enum.d.ts +0 -50
  70. package/dist/cjs/classes/enum.js +0 -405
  71. package/dist/cjs/classes/enum.js.map +0 -1
  72. package/dist/cjs/classes/index.d.ts +0 -15
  73. package/dist/cjs/classes/index.js +0 -63
  74. package/dist/cjs/classes/index.js.map +0 -1
  75. package/dist/cjs/classes/introspector.d.ts +0 -20
  76. package/dist/cjs/classes/introspector.js +0 -130
  77. package/dist/cjs/classes/introspector.js.map +0 -1
  78. package/dist/cjs/classes/iterable.d.ts +0 -169
  79. package/dist/cjs/classes/iterable.js +0 -268
  80. package/dist/cjs/classes/iterable.js.map +0 -1
  81. package/dist/cjs/classes/param.parser.d.ts +0 -221
  82. package/dist/cjs/classes/param.parser.js +0 -242
  83. package/dist/cjs/classes/param.parser.js.map +0 -1
  84. package/dist/cjs/classes/pluggable.proxy.d.ts +0 -153
  85. package/dist/cjs/classes/pluggable.proxy.js +0 -444
  86. package/dist/cjs/classes/pluggable.proxy.js.map +0 -1
  87. package/dist/cjs/classes/property.d.ts +0 -79
  88. package/dist/cjs/classes/property.js +0 -284
  89. package/dist/cjs/classes/property.js.map +0 -1
  90. package/dist/cjs/classes/refmap.d.ts +0 -238
  91. package/dist/cjs/classes/refmap.js +0 -421
  92. package/dist/cjs/classes/refmap.js.map +0 -1
  93. package/dist/cjs/classes/refset.d.ts +0 -186
  94. package/dist/cjs/classes/refset.js +0 -370
  95. package/dist/cjs/classes/refset.js.map +0 -1
  96. package/dist/cjs/classes/symkeys.d.ts +0 -349
  97. package/dist/cjs/classes/symkeys.js +0 -510
  98. package/dist/cjs/classes/symkeys.js.map +0 -1
  99. package/dist/cjs/classes/type.d.ts +0 -56
  100. package/dist/cjs/classes/type.js +0 -405
  101. package/dist/cjs/classes/type.js.map +0 -1
  102. package/dist/cjs/function.extensions.d.ts +0 -12
  103. package/dist/cjs/function.extensions.js +0 -758
  104. package/dist/cjs/function.extensions.js.map +0 -1
  105. package/dist/cjs/global.this.d.ts +0 -2
  106. package/dist/cjs/global.this.js +0 -300
  107. package/dist/cjs/global.this.js.map +0 -1
  108. package/dist/cjs/index.d.ts +0 -31
  109. package/dist/cjs/index.js +0 -226
  110. package/dist/cjs/index.js.map +0 -1
  111. package/dist/cjs/json.extensions.d.ts +0 -2
  112. package/dist/cjs/json.extensions.js +0 -109
  113. package/dist/cjs/json.extensions.js.map +0 -1
  114. package/dist/cjs/map.extensions.d.ts +0 -3
  115. package/dist/cjs/map.extensions.js +0 -143
  116. package/dist/cjs/map.extensions.js.map +0 -1
  117. package/dist/cjs/number.extension.d.ts +0 -44
  118. package/dist/cjs/number.extension.js +0 -261
  119. package/dist/cjs/number.extension.js.map +0 -1
  120. package/dist/cjs/object.extensions.d.ts +0 -33
  121. package/dist/cjs/object.extensions.js +0 -1091
  122. package/dist/cjs/object.extensions.js.map +0 -1
  123. package/dist/cjs/package.json +0 -3
  124. package/dist/cjs/proxy.extensions.d.ts +0 -2
  125. package/dist/cjs/proxy.extensions.js +0 -207
  126. package/dist/cjs/proxy.extensions.js.map +0 -1
  127. package/dist/cjs/reflect.extensions.d.ts +0 -14
  128. package/dist/cjs/reflect.extensions.js +0 -316
  129. package/dist/cjs/reflect.extensions.js.map +0 -1
  130. package/dist/cjs/regular.expression.extensions.d.ts +0 -2
  131. package/dist/cjs/regular.expression.extensions.js +0 -423
  132. package/dist/cjs/regular.expression.extensions.js.map +0 -1
  133. package/dist/cjs/set.extensions.d.ts +0 -40
  134. package/dist/cjs/set.extensions.js +0 -355
  135. package/dist/cjs/set.extensions.js.map +0 -1
  136. package/dist/cjs/string.extensions.d.ts +0 -23
  137. package/dist/cjs/string.extensions.js +0 -704
  138. package/dist/cjs/string.extensions.js.map +0 -1
  139. package/dist/cjs/symbol.extensions.d.ts +0 -11
  140. package/dist/cjs/symbol.extensions.js +0 -735
  141. package/dist/cjs/symbol.extensions.js.map +0 -1
  142. package/dist/cjs/utils/copy.object.d.ts +0 -408
  143. package/dist/cjs/utils/copy.object.js +0 -720
  144. package/dist/cjs/utils/copy.object.js.map +0 -1
  145. package/dist/cjs/utils/descriptor.utils.d.ts +0 -298
  146. package/dist/cjs/utils/descriptor.utils.js +0 -889
  147. package/dist/cjs/utils/descriptor.utils.js.map +0 -1
  148. package/dist/cjs/utils/index.d.ts +0 -75
  149. package/dist/cjs/utils/index.js +0 -61
  150. package/dist/cjs/utils/index.js.map +0 -1
  151. package/dist/cjs/utils/stdout.d.ts +0 -742
  152. package/dist/cjs/utils/stdout.js +0 -1042
  153. package/dist/cjs/utils/stdout.js.map +0 -1
  154. package/dist/cjs/utils/toolkit.d.ts +0 -1898
  155. package/dist/cjs/utils/toolkit.js +0 -1378
  156. package/dist/cjs/utils/toolkit.js.map +0 -1
  157. package/dist/cjs/weakref.extensions.d.ts +0 -2
  158. package/dist/cjs/weakref.extensions.js +0 -19
  159. package/dist/cjs/weakref.extensions.js.map +0 -1
  160. package/dist/mjs/array.extensions.d.ts +0 -39
  161. package/dist/mjs/array.extensions.js +0 -474
  162. package/dist/mjs/array.extensions.js.map +0 -1
  163. package/dist/mjs/big.int.extension.d.ts +0 -31
  164. package/dist/mjs/big.int.extension.js +0 -162
  165. package/dist/mjs/big.int.extension.js.map +0 -1
  166. package/dist/mjs/classes/asyncIterable.d.ts +0 -126
  167. package/dist/mjs/classes/asyncIterable.js +0 -204
  168. package/dist/mjs/classes/asyncIterable.js.map +0 -1
  169. package/dist/mjs/classes/deferred.d.ts +0 -146
  170. package/dist/mjs/classes/deferred.js +0 -287
  171. package/dist/mjs/classes/deferred.js.map +0 -1
  172. package/dist/mjs/classes/descriptor.d.ts +0 -334
  173. package/dist/mjs/classes/descriptor.js +0 -533
  174. package/dist/mjs/classes/descriptor.js.map +0 -1
  175. package/dist/mjs/classes/enum.d.ts +0 -50
  176. package/dist/mjs/classes/enum.js +0 -400
  177. package/dist/mjs/classes/enum.js.map +0 -1
  178. package/dist/mjs/classes/index.d.ts +0 -15
  179. package/dist/mjs/classes/index.js +0 -46
  180. package/dist/mjs/classes/index.js.map +0 -1
  181. package/dist/mjs/classes/introspector.d.ts +0 -20
  182. package/dist/mjs/classes/introspector.js +0 -126
  183. package/dist/mjs/classes/introspector.js.map +0 -1
  184. package/dist/mjs/classes/iterable.d.ts +0 -169
  185. package/dist/mjs/classes/iterable.js +0 -263
  186. package/dist/mjs/classes/iterable.js.map +0 -1
  187. package/dist/mjs/classes/param.parser.d.ts +0 -221
  188. package/dist/mjs/classes/param.parser.js +0 -238
  189. package/dist/mjs/classes/param.parser.js.map +0 -1
  190. package/dist/mjs/classes/pluggable.proxy.d.ts +0 -153
  191. package/dist/mjs/classes/pluggable.proxy.js +0 -438
  192. package/dist/mjs/classes/pluggable.proxy.js.map +0 -1
  193. package/dist/mjs/classes/property.d.ts +0 -79
  194. package/dist/mjs/classes/property.js +0 -280
  195. package/dist/mjs/classes/property.js.map +0 -1
  196. package/dist/mjs/classes/refmap.d.ts +0 -238
  197. package/dist/mjs/classes/refmap.js +0 -417
  198. package/dist/mjs/classes/refmap.js.map +0 -1
  199. package/dist/mjs/classes/refset.d.ts +0 -186
  200. package/dist/mjs/classes/refset.js +0 -366
  201. package/dist/mjs/classes/refset.js.map +0 -1
  202. package/dist/mjs/classes/symkeys.d.ts +0 -349
  203. package/dist/mjs/classes/symkeys.js +0 -506
  204. package/dist/mjs/classes/symkeys.js.map +0 -1
  205. package/dist/mjs/classes/type.d.ts +0 -56
  206. package/dist/mjs/classes/type.js +0 -401
  207. package/dist/mjs/classes/type.js.map +0 -1
  208. package/dist/mjs/function.extensions.d.ts +0 -12
  209. package/dist/mjs/function.extensions.js +0 -755
  210. package/dist/mjs/function.extensions.js.map +0 -1
  211. package/dist/mjs/global.this.d.ts +0 -2
  212. package/dist/mjs/global.this.js +0 -264
  213. package/dist/mjs/global.this.js.map +0 -1
  214. package/dist/mjs/index.d.ts +0 -31
  215. package/dist/mjs/index.js +0 -204
  216. package/dist/mjs/index.js.map +0 -1
  217. package/dist/mjs/json.extensions.d.ts +0 -2
  218. package/dist/mjs/json.extensions.js +0 -106
  219. package/dist/mjs/json.extensions.js.map +0 -1
  220. package/dist/mjs/map.extensions.d.ts +0 -3
  221. package/dist/mjs/map.extensions.js +0 -140
  222. package/dist/mjs/map.extensions.js.map +0 -1
  223. package/dist/mjs/number.extension.d.ts +0 -44
  224. package/dist/mjs/number.extension.js +0 -258
  225. package/dist/mjs/number.extension.js.map +0 -1
  226. package/dist/mjs/object.extensions.d.ts +0 -33
  227. package/dist/mjs/object.extensions.js +0 -1088
  228. package/dist/mjs/object.extensions.js.map +0 -1
  229. package/dist/mjs/package.json +0 -3
  230. package/dist/mjs/proxy.extensions.d.ts +0 -2
  231. package/dist/mjs/proxy.extensions.js +0 -204
  232. package/dist/mjs/proxy.extensions.js.map +0 -1
  233. package/dist/mjs/reflect.extensions.d.ts +0 -14
  234. package/dist/mjs/reflect.extensions.js +0 -313
  235. package/dist/mjs/reflect.extensions.js.map +0 -1
  236. package/dist/mjs/regular.expression.extensions.d.ts +0 -2
  237. package/dist/mjs/regular.expression.extensions.js +0 -420
  238. package/dist/mjs/regular.expression.extensions.js.map +0 -1
  239. package/dist/mjs/set.extensions.d.ts +0 -40
  240. package/dist/mjs/set.extensions.js +0 -352
  241. package/dist/mjs/set.extensions.js.map +0 -1
  242. package/dist/mjs/string.extensions.d.ts +0 -23
  243. package/dist/mjs/string.extensions.js +0 -701
  244. package/dist/mjs/string.extensions.js.map +0 -1
  245. package/dist/mjs/symbol.extensions.d.ts +0 -11
  246. package/dist/mjs/symbol.extensions.js +0 -732
  247. package/dist/mjs/symbol.extensions.js.map +0 -1
  248. package/dist/mjs/utils/copy.object.d.ts +0 -408
  249. package/dist/mjs/utils/copy.object.js +0 -702
  250. package/dist/mjs/utils/copy.object.js.map +0 -1
  251. package/dist/mjs/utils/descriptor.utils.d.ts +0 -298
  252. package/dist/mjs/utils/descriptor.utils.js +0 -875
  253. package/dist/mjs/utils/descriptor.utils.js.map +0 -1
  254. package/dist/mjs/utils/index.d.ts +0 -75
  255. package/dist/mjs/utils/index.js +0 -45
  256. package/dist/mjs/utils/index.js.map +0 -1
  257. package/dist/mjs/utils/stdout.d.ts +0 -742
  258. package/dist/mjs/utils/stdout.js +0 -1037
  259. package/dist/mjs/utils/stdout.js.map +0 -1
  260. package/dist/mjs/utils/toolkit.d.ts +0 -1898
  261. package/dist/mjs/utils/toolkit.js +0 -1373
  262. package/dist/mjs/utils/toolkit.js.map +0 -1
  263. package/dist/mjs/weakref.extensions.d.ts +0 -2
  264. package/dist/mjs/weakref.extensions.js +0 -16
  265. package/dist/mjs/weakref.extensions.js.map +0 -1
  266. package/jsdoc-config.json +0 -31
  267. package/tsconfig.base.json +0 -28
  268. package/tsconfig.cjs.json +0 -8
  269. package/tsconfig.esm.json +0 -8
  270. package/vitest.config.js +0 -7
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MarkdownSettings">
4
+ <option name="previewPanelProviderInfo">
5
+ <ProviderInfo name="Mermaid Studio (Chromium browser)" className="MermaidStudio_z.MermaidStudio_R.MermaidStudio_n.MermaidStudio_Q.MermaidStudio_U.MermaidStudio__.JCEFHtmlPanelProvider" />
6
+ </option>
7
+ </component>
8
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/ne-basic-extensions.iml" filepath="$PROJECT_DIR$/.idea/ne-basic-extensions.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/CODE_STYLE.md ADDED
@@ -0,0 +1,393 @@
1
+ # Code Style Guide
2
+
3
+ This document is written for AI assistants generating code in `@nejs` repositories. These are not aspirational conventions — they are patterns extracted from existing code. Follow them precisely so that generated code is indistinguishable from hand-written code.
4
+
5
+ ## Semicolons
6
+
7
+ Do not use semicolons. Rely on ASI (Automatic Semicolon Insertion). The one exception is class property definitions declared outside of any method or constructor — these get semicolons.
8
+
9
+ ```javascript
10
+ // no semicolons in statements, imports, returns, etc.
11
+ const name = 'Brie'
12
+ const items = [1, 2, 3]
13
+ return this.#settled
14
+ import { Patch } from '@nejs/extension'
15
+
16
+ // semicolons on class property definitions
17
+ export class Deferred extends Promise {
18
+ #promise = null;
19
+ #reject = null;
20
+ #resolve = null;
21
+
22
+ value = null;
23
+ reason = null;
24
+
25
+ #settled = false;
26
+
27
+ constructor(options) {
28
+ // no semicolons inside methods
29
+ const config = parseOptions(options)
30
+ let _resolve, _reject
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## Quotes
36
+
37
+ Use single quotes. Reserve double quotes for strings that contain single quotes. Use template literals when interpolating.
38
+
39
+ ```javascript
40
+ import { Patch } from '@nejs/extension'
41
+ const tag = 'EnumValue'
42
+ const msg = `${this.major}.${this.minor}.${this.patch}`
43
+ ```
44
+
45
+ ## Line Length
46
+
47
+ Aim for 80 columns or fewer. Wrap lines when it makes reading the code more pleasurable — in both code and JSDoc prose. Do not forcibly wrap to the detriment of legibility; a line that reads clearly at 85 columns is better than one awkwardly broken at 79. The goal is readability, not a hard ruler.
48
+
49
+ ## Indentation
50
+
51
+ 2 spaces. No tabs.
52
+
53
+ ## Variable Declarations
54
+
55
+ `const` by default. `let` only when reassignment is required. Never `var`.
56
+
57
+ ```javascript
58
+ const config = parseOptions(opts)
59
+ let _resolve, _reject
60
+ ```
61
+
62
+ ## Arrow Function Parameters
63
+
64
+ Always parenthesize, even with a single parameter.
65
+
66
+ ```javascript
67
+ values.forEach((value) => this.add(value))
68
+ this.some((element) => element === value)
69
+ ```
70
+
71
+ ## Arrow Functions vs `function`
72
+
73
+ Use arrow functions for callbacks, short lambdas, and closures that don't need their own `this`. Use `function` declarations or named function expressions when the function needs `this` binding, is a Symbol-keyed method, or benefits from a name for stack traces.
74
+
75
+ ```javascript
76
+ // arrow for callbacks
77
+ entries.filter((e) => Array.isArray(e) && e.length === 2)
78
+
79
+ // named function for Symbol-keyed methods that use `this`
80
+ [Symbol.for('compare')]: data(
81
+ function compareValue(to) {
82
+ const {real: lReal, value: lValue} = this
83
+ // ...
84
+ }, false, true, false
85
+ )
86
+ ```
87
+
88
+ ## Braces on Single-Statement Bodies
89
+
90
+ If the body of an `if`, `for`, or similar block is a single short statement, omit the braces. Brace everything else.
91
+
92
+ ```javascript
93
+ // unbraced — single short statement
94
+ if (!isLEnum || !isREnum)
95
+ return false
96
+
97
+ if (!Array.isArray(array))
98
+ return false
99
+
100
+ // braced — multi-line or complex body
101
+ if (config?.resolve && config?.reject) {
102
+ throw new TypeError(
103
+ 'resolve and reject options cannot be simultaneously provided'
104
+ )
105
+ }
106
+ ```
107
+
108
+ ## `else` and `else if` Placement
109
+
110
+ Drop `else` and `else if` to a new line. Do not cuddle them on the closing brace line.
111
+
112
+ ```javascript
113
+ if (config?.resolve) {
114
+ this.#resolve(config?.resolve)
115
+ }
116
+ else if (config?.reject) {
117
+ this.#reject(config?.reject)
118
+ }
119
+ ```
120
+
121
+ ```javascript
122
+ if (Descriptor.isDescriptor(object)) {
123
+ this._desc = object
124
+ }
125
+ else if (isObject(object) && isValidKey(key)) {
126
+ this._desc = Object.getOwnPropertyDescriptor(object, key)
127
+ }
128
+ ```
129
+
130
+ ## Ternary Formatting
131
+
132
+ Short ternaries stay on one line. Long ternaries break across lines with `?` and `:` indented, and the closing paren on its own line.
133
+
134
+ ```javascript
135
+ // short
136
+ const store = is.object(store) ? store : undefined
137
+
138
+ // long
139
+ const config = (options && typeof(options) === 'object'
140
+ ? options
141
+ : {}
142
+ )
143
+ ```
144
+
145
+ ## Multi-Line Boolean Expressions
146
+
147
+ Trailing `&&` or `||` at the end of each line. Subsequent conditions align under the first.
148
+
149
+ ```javascript
150
+ return this.major === otherVersion.major &&
151
+ this.minor === otherVersion.minor &&
152
+ this.patch === otherVersion.patch &&
153
+ this.prerelease === otherVersion.prerelease
154
+ ```
155
+
156
+ ## Parenthesized Multi-Line Returns
157
+
158
+ Wrap complex return expressions in parentheses. Opening paren on the `return` line.
159
+
160
+ ```javascript
161
+ return (
162
+ value instanceof Function &&
163
+ String(value).includes('=>') &&
164
+ !String(value).startsWith('bound') &&
165
+ !Reflect.has(value, 'prototype')
166
+ )
167
+ ```
168
+
169
+ ```javascript
170
+ return (array
171
+ .map((value) => (typeof value))
172
+ .some((value) => value === 'symbol')
173
+ )
174
+ ```
175
+
176
+ ## Destructuring
177
+
178
+ Destructure at point of use. Renaming during destructuring is common and encouraged when it clarifies intent or prevents collisions.
179
+
180
+ ```javascript
181
+ const { MAJOR, MINOR, PATCH } = SemVer
182
+ const {real: lReal, value: lValue, name: lName, type: lType} = this
183
+ const {real: rReal, value: rValue, name: rName, type: rType} = toObj
184
+ ```
185
+
186
+ ## Static Getter Constants
187
+
188
+ One-liner format when the body is a single return.
189
+
190
+ ```javascript
191
+ static get FULL() { return '*' }
192
+ static get MAJOR() { return 'major' }
193
+ static get MINOR() { return 'minor' }
194
+ ```
195
+
196
+ ## Short vs Expanded Getters
197
+
198
+ Short getters with trivial bodies can be one-liners. Anything beyond a simple return gets expanded.
199
+
200
+ ```javascript
201
+ // one-liner
202
+ get hasObject() { return isObject(this._object) }
203
+
204
+ // expanded
205
+ get settled() {
206
+ return this.#settled
207
+ }
208
+
209
+ get start() {
210
+ return typeof this.#start === 'function' ? this.#start() : this.#start
211
+ }
212
+ ```
213
+
214
+ ## Switch Statements
215
+
216
+ Compact case/return on the same line when cases are uniform and short. Use `break` or `return` — never fall through silently.
217
+
218
+ ```javascript
219
+ switch (part) {
220
+ case MAJOR: this[part] = parseInt(semverString); return
221
+ case MINOR: this[part] = parseInt(semverString); return
222
+ case PATCH: this[part] = parseInt(semverString); return
223
+ case PRERELEASE: this[part] = semverString; return
224
+ case METADATA: this[part] = semverString; return
225
+ default:
226
+ break
227
+ }
228
+ ```
229
+
230
+ For switches with longer case bodies, expand normally:
231
+
232
+ ```javascript
233
+ switch (hint) {
234
+ case 'number':
235
+ return parseFloat(`${this.major}.${this.minor}`)
236
+ case 'string':
237
+ return this.get()
238
+ default:
239
+ return null
240
+ }
241
+ ```
242
+
243
+ ## `typeof` With Parentheses
244
+
245
+ `typeof` is sometimes written with parentheses as though it were a function call. Both forms appear, but the parenthesized form is the more natural one in this codebase.
246
+
247
+ ```javascript
248
+ typeof(options) === 'object'
249
+ typeof(config?.executor) === 'function'
250
+ ```
251
+
252
+ ## Boolean Coercion and Bitwise Idioms
253
+
254
+ `!!` for explicit boolean coercion. `!!~` with `indexOf` for existence checks. These are deliberate, not accidental.
255
+
256
+ ```javascript
257
+ return !!this.find((entry) => entry === value)
258
+ return this.some((element) => !!~values.indexOf(element))
259
+ ```
260
+
261
+ ## Comparison Operators
262
+
263
+ Prefer strict equality (`===`). Loose equality (`==`) is acceptable when explicitly intended — it appears in methods like `oneIs` where the caller opts in via a parameter.
264
+
265
+ ```javascript
266
+ // default: strict
267
+ const _skip = this.value === Symbol.for('Enum.NonAssociatedValue')
268
+
269
+ // intentional loose equality controlled by parameter
270
+ doubleEqualsOkay ? element == value : element === value
271
+ ```
272
+
273
+ ## Optional Chaining and Nullish Coalescing
274
+
275
+ Use freely. These are idiomatic throughout the codebase.
276
+
277
+ ```javascript
278
+ this.inclusive = start?.inclusive ?? true
279
+ configurable: baseDescriptor?.configurable ?? true
280
+ const lineIndent = /^(\s+)/.exec(line)?.[1]?.length ?? 0
281
+ ```
282
+
283
+ ## Imports
284
+
285
+ External dependencies first, then internal modules, separated by a blank line. Named imports with destructuring.
286
+
287
+ ```javascript
288
+ import { Extension, Patch } from '@nejs/extension'
289
+
290
+ import { Deferred } from './async/deferred.js'
291
+ import { Callable } from './core/callable.js'
292
+ import { Range } from './core/range.js'
293
+ ```
294
+
295
+ ## Blank Lines
296
+
297
+ Use blank lines to separate logical sections within a function. One blank line between conceptual steps. Do not over-space — no double blank lines, no blank lines after opening braces or before closing braces.
298
+
299
+ ```javascript
300
+ constructor(options) {
301
+ const config = (options && typeof(options) === 'object'
302
+ ? options
303
+ : {}
304
+ )
305
+
306
+ if (config?.resolve && config?.reject) {
307
+ throw new TypeError(
308
+ 'resolve and reject options cannot be simultaneously provided'
309
+ )
310
+ }
311
+
312
+ let _resolve, _reject
313
+
314
+ super((resolve, reject) => {
315
+ _resolve = resolve
316
+ _reject = reject
317
+ })
318
+ ```
319
+
320
+ ## Class Structure
321
+
322
+ Order within a class body:
323
+
324
+ 1. `#` private fields (with defaults)
325
+ 2. Public instance fields (with defaults)
326
+ 3. `constructor`
327
+ 4. Instance getters/setters
328
+ 5. Instance methods
329
+ 6. `Symbol`-keyed methods and getters (`Symbol.toPrimitive`, `Symbol.iterator`, `Symbol.toStringTag`, `Symbol.species`)
330
+ 7. Static getters (constants)
331
+ 8. Static methods
332
+
333
+ ```javascript
334
+ export class Deferred extends Promise {
335
+ #promise = null
336
+ #reject = null
337
+ #resolve = null
338
+
339
+ value = null
340
+ reason = null
341
+
342
+ #settled = false
343
+
344
+ constructor(options) { ... }
345
+
346
+ get settled() { ... }
347
+ get promise() { ... }
348
+
349
+ resolve(value) { ... }
350
+ reject(reason) { ... }
351
+
352
+ static get [Symbol.species]() { ... }
353
+ }
354
+ ```
355
+
356
+ ## Symbols
357
+
358
+ Use `Symbol.for()` for shared/interoperable keys. Define symbol accessors as static getters with the `k` prefix convention.
359
+
360
+ ```javascript
361
+ static get kHandler() {
362
+ return Symbol.for('callable.handler')
363
+ }
364
+
365
+ static get kFunction() {
366
+ return Symbol.for('callable.function')
367
+ }
368
+ ```
369
+
370
+ ## String Concatenation
371
+
372
+ Template literals for interpolation. The `+` operator is acceptable for simple one-off concatenation (e.g., `key + '.associated'`).
373
+
374
+ ## Trailing Commas
375
+
376
+ Not enforced in either direction. Do not add them retroactively to existing code, do not remove them from existing code. When writing new multi-line object/array literals, trailing commas are acceptable.
377
+
378
+ ## Error Handling
379
+
380
+ Throw specific error types (`TypeError`, `Error`) with descriptive string messages. For invalid input in utility/library code, prefer branching and returning a safe default over throwing.
381
+
382
+ ```javascript
383
+ // throw for contract violations
384
+ throw new TypeError(
385
+ 'resolve and reject options cannot be simultaneously provided'
386
+ )
387
+
388
+ // branch for soft failures
389
+ if (!this.isObject(obj)) {
390
+ console.warn('Object.add() must receive an object for `toObject`')
391
+ return obj
392
+ }
393
+ ```
@@ -0,0 +1,36 @@
1
+ # Coding Philosophy & Architectural Preferences
2
+
3
+ Observations drawn from the `@nejs/foundation` and `@nejs/basic-extensions` codebases.
4
+
5
+ ## Core Beliefs
6
+
7
+ **JavaScript maximalism.** The language's built-in types are *incomplete*, not broken. Rather than avoiding prototype modification, the approach is to build a reversible patch infrastructure (`@nejs/extension`) to do it correctly. The `Controls` system with enable/disable is a disciplined concession to orthodoxy — `arr.first` should just *work*.
8
+
9
+ **Protocol-oriented thinking.** Heavy use of `Symbol.iterator`, `Symbol.species`, `Symbol.toPrimitive`, `Symbol.toStringTag`, and custom symbols throughout. Objects are participants in protocols. The `Callable` class is the clearest expression: a single entity that *is* both function and object, participating in both protocols simultaneously through comprehensive Proxy traps.
10
+
11
+ **Expressiveness as a core value.** The `if*` conditional pattern on every type checker, the `is`/`has`/`as`/`si` global toolkit, the Deferred exposing resolve/reject — these convert imperative control flow into expressions. `si.array(val, transform, fallback)` over an if/else block. Functional programming flavor without dogma.
12
+
13
+ **Descriptor-level awareness.** Properties are not key/value pairs — they are full descriptors with enumeration, configurability, and accessor semantics. Visibility handlers (`kMutablyHidden`, `kImmutablyVisible`), `Object.add()` with storage-backed accessors, and the `Descriptor` class form an entire vocabulary around `Object.defineProperty`.
14
+
15
+ ## Architecture Preferences
16
+
17
+ **Bottom-up, layered abstraction.** `@nejs/extension` (patch mechanism) → `@nejs/basic-extensions` (enriched primitives) → `@nejs/foundation` (higher-level patterns). Each layer assumes the one below. The goal is not an application framework — it is building the *language you wish you had*, then writing applications in that language.
18
+
19
+ **Enrich the base rather than wrap it.** Prefer extending built-in types with missing capabilities over creating parallel utility namespaces. Rich methods on every type (`set.map()`, `set.reduce()`, `arr.first`, `arr.last`) in the Ruby/Smalltalk tradition of making built-ins joyful to use.
20
+
21
+ **Convention applied uniformly.** Every `isX` gets a corresponding `ifX`. Every type gets the same treatment. Patterns are systematic, not ad-hoc.
22
+
23
+ ## Implementation Conventions
24
+
25
+ - `#` private fields over closures for encapsulation
26
+ - Custom symbols (prefixed `k`) for internal access keys (`kHandler`, `kFunction`, `kDescriptorStore`)
27
+ - Comprehensive JSDoc over TypeScript — types as documentation, not as a compilation step (tsc used as transpiler, not type checker)
28
+ - Well-known Symbols implemented wherever semantically appropriate (`Symbol.iterator`, `Symbol.species`, `Symbol.toPrimitive`, `Symbol.toStringTag`)
29
+ - Full Proxy trap coverage when proxying (not partial implementations)
30
+ - Method chaining where it fits naturally (e.g., SemVer increment/decrement)
31
+
32
+ ## Influences
33
+
34
+ - **Ruby/Smalltalk** — open classes, rich standard library methods on built-in types, ergonomic APIs
35
+ - **jQuery** — deferred pattern, the philosophy that APIs should be ergonomic first
36
+ - **JavaScript metaprogramming** — Proxy, Reflect, Symbol, and property descriptors are foundational tools, not curiosities
@@ -0,0 +1,221 @@
1
+ # Documentation & Style Guidelines
2
+
3
+ How documentation is written across `@nejs` projects. These aren't aspirational rules — they're patterns extracted from existing code. Follow them so that a reader who's seen three docs can predict the structure of the fourth.
4
+
5
+ ## Philosophy
6
+
7
+ Code alone never captures intent and circumstance. Documentation exists to explain *why* something exists in the world, what design pressures shaped it, and what the reader should expect when they use it. The JSDoc is the primary type system — not TypeScript, not Flow — and it serves double duty: human-readable narrative *and* IDE-consumable type information (WebStorm, VS Code, etc.).
8
+
9
+ TypeScript is avoided unless externally required. JSDoc `@param`, `@returns`, `@typedef`, and `@type` annotations carry the type information. This keeps the source as plain JavaScript while giving IDEs everything they need for autocomplete, hover docs, and type checking.
10
+
11
+ ## JSDoc Structure
12
+
13
+ A complete doc block follows this order. Not every section appears on every method — scale detail to complexity.
14
+
15
+ 1. **Opening narrative** — What it does and *why it exists*. For classes, include historical context or lineage where relevant. For methods, lead with the practical purpose.
16
+ 2. **`@typedef` / `@callback`** — For complex option objects or function signatures, define them inline or reference a shared typedef. Use TypeScript-style interface notation inside fenced code blocks when the shape is complex.
17
+ 3. **`@param`** — Every parameter documented. Include union types with `|`, defaults with `[param=default]`, conditional requirements ("Required if `start` is a number"), and constraints ("Must be non-zero").
18
+ 4. **`@returns`** — What comes back and under what conditions.
19
+ 5. **`@throws`** — When and why.
20
+ 6. **`@example`** — Concrete, runnable scenarios (see Examples section below).
21
+
22
+ ### Simple methods get simple docs
23
+
24
+ ```javascript
25
+ /**
26
+ * The `isString` method does exactly what one would expect. It returns
27
+ * true if the string matches typeof or instanceof as a string.
28
+ *
29
+ * @param {*} value checks to see if the `value` is a string
30
+ * @returns {boolean} `true` if it is a `String`, `false` otherwise
31
+ */
32
+ ```
33
+
34
+ Three lines of description, one param, one return. Done.
35
+
36
+ ### Complex methods get structured docs
37
+
38
+ For methods with multiple modes, option objects, or non-obvious behavior, use visual structure — tables, fenced code blocks for option lists, multiple examples showing different usage patterns:
39
+
40
+ ```javascript
41
+ /**
42
+ * Applies Select Graphic Rendition (SGR) parameters to a given message
43
+ * for styling in terminal environments. This function allows for the
44
+ * dynamic styling of text output using ANSI escape codes.
45
+ *
46
+ * Colors:
47
+ * ```
48
+ * 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
49
+ * ```
50
+ * Color Specifiers:
51
+ * ```
52
+ * 'fg' -> foreground | 'bg' -> background | 'bright' -> bright colors
53
+ * ```
54
+ *
55
+ * Modes:
56
+ * ```
57
+ * 'blink' or 'k' | 'conceal' or 'c' | 'italics' or 'i' | 'strike' or 's'
58
+ * 'bold' or 'b' | 'dim' or 'd' | 'negative' or 'n' | 'underline' or 'u'
59
+ * ```
60
+ *
61
+ * @param {string} message The message to be styled.
62
+ * @param {...string} useModes Styling modes — colors, specifiers, and
63
+ * decorations. Can be combined in a single comma-separated string or
64
+ * passed as separate arguments.
65
+ * @returns {string} The styled string wrapped in ANSI escape codes.
66
+ *
67
+ * @example
68
+ * sgr('Hello', 'red')
69
+ * sgr('World', 'green,bold')
70
+ * sgr('Example', 'bluebgbright')
71
+ *
72
+ * // Shorthand syntax
73
+ * sgr('hello', 'biu') // bold, italics, underline
74
+ * sgr('hello', 'bi,redfg') // bold, italics, red foreground
75
+ */
76
+ ```
77
+
78
+ ## Examples
79
+
80
+ Examples are stories, not syntax diagrams. Show a scenario the reader can inhabit.
81
+
82
+ ### Do this
83
+
84
+ ```javascript
85
+ /**
86
+ * @example
87
+ * // assume this pure function exists someplace
88
+ * const lastThenFirstThenMiddle = function() {
89
+ * let middle = ''
90
+ *
91
+ * if (this.middleName)
92
+ * middle = ` ${this.middleName}`
93
+ *
94
+ * return `${this.lastName}, ${this.firstName}${middle}`
95
+ * }
96
+ *
97
+ * let people = []
98
+ * for await (const model of await getSomePeople()) {
99
+ * let parseName = new Callable(model, lastThenFirstThenMiddle)
100
+ * people.push(parseName())
101
+ * }
102
+ *
103
+ * console.log(people)
104
+ * // Might look like ['Doe, Jane', 'Smith, Sally Joanne']
105
+ */
106
+ ```
107
+
108
+ This shows: the setup, the loop, the integration with async code, and what the output "might look like." The reader understands the *use case*, not just the constructor signature.
109
+
110
+ ### Teach through contrast
111
+
112
+ When a method's behavior has meaningful boundaries, show both sides:
113
+
114
+ ```javascript
115
+ /**
116
+ * @example
117
+ * // Note the differences between these
118
+ * const object = { get name() { return "Brie"; } };
119
+ * const descriptor = Object.getOwnPropertyDescriptor(object, 'name');
120
+ * is.callable(object); // false
121
+ * is.callable(descriptor); // true
122
+ */
123
+ ```
124
+
125
+ ## Types in JSDoc
126
+
127
+ JSDoc is the type system. Write types for the IDE, narrative for the human.
128
+
129
+ ### Primitives and unions
130
+
131
+ ```javascript
132
+ @param {string|number} value
133
+ @param {boolean} [inclusive=true]
134
+ @param {*} value
135
+ ```
136
+
137
+ ### Complex option objects
138
+
139
+ Use TypeScript-style interface notation inside the doc block when the shape warrants it:
140
+
141
+ ```javascript
142
+ /**
143
+ * The constructor takes an object called `options`. It can have the
144
+ * following properties:
145
+ *
146
+ * ```
147
+ * interface BaseDeferredOptions {
148
+ * // Deferreds store the value or reason. To turn this off, pass true
149
+ * doNotTrackAnswers?: boolean;
150
+ * }
151
+ *
152
+ * interface DeferredResolveOptions extends BaseDeferredOptions {
153
+ * resolve: any; // Auto-resolve with this value
154
+ * reject?: never;
155
+ * }
156
+ * ```
157
+ *
158
+ * @param {BaseDeferredOptions|DeferredResolveOptions} options
159
+ */
160
+ ```
161
+
162
+ This gives the reader a typed shape to reference while keeping the source as plain JavaScript.
163
+
164
+ ### Callback signatures
165
+
166
+ ```javascript
167
+ @param {function(number, number): boolean} compareFn
168
+ @callback StepFunction
169
+ @returns {number}
170
+ ```
171
+
172
+ ## Inline Comments
173
+
174
+ ### Explain decisions, not mechanics
175
+
176
+ ```javascript
177
+ // If the target function is a big arrow function, convert it to
178
+ // a bindable function. Note that big arrow functions will receive
179
+ // the handler as its first parameter; so account for that.
180
+ ```
181
+
182
+ This explains the *why* (arrow functions can't be bound) and the *consequence* (handler becomes first param). The code shows the *how*.
183
+
184
+ ### Be honest about shortcuts
185
+
186
+ ```javascript
187
+ // being lazy here, someone has defined we make an accessor but
188
+ // wants the default accessor behaviors with an associated store
189
+ // made by us.
190
+ ```
191
+
192
+ ### Leave breadcrumbs for future you
193
+
194
+ ```javascript
195
+ // NOTE to self; this is repeated here otherwise a circular reference from
196
+ // Object<->Function<->Global occurs. See original source in global.this.js
197
+ // {@see globalThis.isThenElse}
198
+ ```
199
+
200
+ ## Voice
201
+
202
+ The documentation voice is **knowledgeable but approachable**. It's a teacher explaining to a smart student, not a reference manual reciting signatures.
203
+
204
+ **Signature phrases** (use naturally, not mechanically):
205
+ - "This is useful for scenarios where..."
206
+ - "This allows..."
207
+ - "Returns `true` if... `false` otherwise"
208
+ - "If... is provided..."
209
+ - "Optionally..."
210
+
211
+ **Formatting conventions:**
212
+ - Backticks around all code references in prose: `undefined`, `handler`, `Array.prototype`
213
+ - `{@link ClassName}` for cross-references to other documented types
214
+ - Periods at end of `@param` and `@returns` descriptions
215
+ - Fenced code blocks inside JSDoc for visual structure (option tables, mode lists)
216
+
217
+ ## What Not to Document
218
+
219
+ - Don't over-document the obvious. If the method is `isString` and it checks if something is a string, three lines suffice.
220
+ - Don't repeat the function signature in prose. The params are already listed — the narrative should explain *intent*, not restate types.
221
+ - Don't write generic advice ("always validate inputs"). Document what *this specific code* does and why.