xypriss 9.6.97 → 9.7.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 (171) hide show
  1. package/README.md +55 -22
  2. package/dist/cjs/src/index.js +0 -19
  3. package/dist/cjs/src/index.js.map +1 -1
  4. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  5. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  6. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js +510 -0
  7. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  8. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  9. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  10. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js +413 -0
  11. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  12. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js +98 -0
  13. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  14. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js +52 -0
  15. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  16. package/dist/cjs/src/middleware/safe-json-middleware.js +0 -82
  17. package/dist/cjs/src/middleware/safe-json-middleware.js.map +1 -1
  18. package/dist/cjs/src/middleware/security-middleware.js +7 -4
  19. package/dist/cjs/src/middleware/security-middleware.js.map +1 -1
  20. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  21. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  22. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  23. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  24. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  25. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  26. package/dist/cjs/src/plugins/const/XyprissTempDir.js +72 -9
  27. package/dist/cjs/src/plugins/const/XyprissTempDir.js.map +1 -1
  28. package/dist/cjs/src/plugins/core/manager/PluginLoader.js +8 -0
  29. package/dist/cjs/src/plugins/core/manager/PluginLoader.js.map +1 -1
  30. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js +87 -0
  31. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  32. package/dist/cjs/src/server/FastServer/index.js +5 -0
  33. package/dist/cjs/src/server/FastServer/index.js.map +1 -1
  34. package/dist/cjs/src/server/ServerFactory.js +8 -13
  35. package/dist/cjs/src/server/ServerFactory.js.map +1 -1
  36. package/dist/cjs/src/server/components/fastapi/RedirectManager.js +8 -58
  37. package/dist/cjs/src/server/components/fastapi/RedirectManager.js.map +1 -1
  38. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  39. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  40. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js +9 -1
  41. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  42. package/dist/cjs/src/server/core/HttpServer.js +22 -0
  43. package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
  44. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js +33 -2
  45. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  46. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  47. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  48. package/dist/cjs/src/server/core/XyServerCreator.js +1 -0
  49. package/dist/cjs/src/server/core/XyServerCreator.js.map +1 -1
  50. package/dist/cjs/src/shared/logger/quickLogger.js +162 -0
  51. package/dist/cjs/src/shared/logger/quickLogger.js.map +1 -0
  52. package/dist/cjs/src/xhsc/PathApi.js +44 -3
  53. package/dist/cjs/src/xhsc/PathApi.js.map +1 -1
  54. package/dist/cjs/src/xhsc/System.js +2 -0
  55. package/dist/cjs/src/xhsc/System.js.map +1 -1
  56. package/dist/cjs/src/xhsc/UtilsApi.js +52 -0
  57. package/dist/cjs/src/xhsc/UtilsApi.js.map +1 -0
  58. package/dist/cjs/src/xhsc/XyPrissRunner.js +30 -2
  59. package/dist/cjs/src/xhsc/XyPrissRunner.js.map +1 -1
  60. package/dist/cjs/src/xhsc/fs/FSCore.js +148 -0
  61. package/dist/cjs/src/xhsc/fs/FSCore.js.map +1 -1
  62. package/dist/cjs/src/xhsc/fs/FileHandle.js +112 -0
  63. package/dist/cjs/src/xhsc/fs/FileHandle.js.map +1 -0
  64. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js +134 -0
  65. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  66. package/dist/cjs/src/xhsc/utils/ArrayUtils.js +67 -0
  67. package/dist/cjs/src/xhsc/utils/ArrayUtils.js.map +1 -0
  68. package/dist/cjs/src/xhsc/utils/AsyncUtils.js +582 -0
  69. package/dist/cjs/src/xhsc/utils/AsyncUtils.js.map +1 -0
  70. package/dist/cjs/src/xhsc/utils/DateUtils.js +959 -0
  71. package/dist/cjs/src/xhsc/utils/DateUtils.js.map +1 -0
  72. package/dist/cjs/src/xhsc/utils/FunctionUtils.js +29 -0
  73. package/dist/cjs/src/xhsc/utils/FunctionUtils.js.map +1 -0
  74. package/dist/cjs/src/xhsc/utils/IdUtils.js +22 -0
  75. package/dist/cjs/src/xhsc/utils/IdUtils.js.map +1 -0
  76. package/dist/cjs/src/xhsc/utils/NumberUtils.js +79 -0
  77. package/dist/cjs/src/xhsc/utils/NumberUtils.js.map +1 -0
  78. package/dist/cjs/src/xhsc/utils/ObjectUtils.js +141 -0
  79. package/dist/cjs/src/xhsc/utils/ObjectUtils.js.map +1 -0
  80. package/dist/cjs/src/xhsc/utils/StringUtils.js +145 -0
  81. package/dist/cjs/src/xhsc/utils/StringUtils.js.map +1 -0
  82. package/dist/cjs/src/xhsc/utils/ValidationUtils.js +49 -0
  83. package/dist/cjs/src/xhsc/utils/ValidationUtils.js.map +1 -0
  84. package/dist/cjs/src/xhsc.js +5 -3
  85. package/dist/cjs/src/xhsc.js.map +1 -1
  86. package/dist/esm/src/index.js +0 -2
  87. package/dist/esm/src/index.js.map +1 -1
  88. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  89. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  90. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js +508 -0
  91. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  92. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  93. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  94. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js +391 -0
  95. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  96. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js +96 -0
  97. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  98. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js +50 -0
  99. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  100. package/dist/esm/src/middleware/safe-json-middleware.js +1 -79
  101. package/dist/esm/src/middleware/safe-json-middleware.js.map +1 -1
  102. package/dist/esm/src/middleware/security-middleware.js +7 -4
  103. package/dist/esm/src/middleware/security-middleware.js.map +1 -1
  104. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  105. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  106. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  107. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  108. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  109. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  110. package/dist/esm/src/plugins/const/XyprissTempDir.js +70 -9
  111. package/dist/esm/src/plugins/const/XyprissTempDir.js.map +1 -1
  112. package/dist/esm/src/plugins/core/manager/PluginLoader.js +8 -0
  113. package/dist/esm/src/plugins/core/manager/PluginLoader.js.map +1 -1
  114. package/dist/esm/src/plugins/core/manager/PluginSecurity.js +87 -0
  115. package/dist/esm/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  116. package/dist/esm/src/server/FastServer/index.js +5 -0
  117. package/dist/esm/src/server/FastServer/index.js.map +1 -1
  118. package/dist/esm/src/server/ServerFactory.js +8 -1
  119. package/dist/esm/src/server/ServerFactory.js.map +1 -1
  120. package/dist/esm/src/server/components/fastapi/RedirectManager.js +8 -58
  121. package/dist/esm/src/server/components/fastapi/RedirectManager.js.map +1 -1
  122. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  123. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  124. package/dist/esm/src/server/components/multi-server/MultiServerManager.js +9 -1
  125. package/dist/esm/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  126. package/dist/esm/src/server/core/HttpServer.js +22 -0
  127. package/dist/esm/src/server/core/HttpServer.js.map +1 -1
  128. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js +33 -2
  129. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  130. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  131. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  132. package/dist/esm/src/server/core/XyServerCreator.js +1 -0
  133. package/dist/esm/src/server/core/XyServerCreator.js.map +1 -1
  134. package/dist/esm/src/shared/logger/quickLogger.js +160 -0
  135. package/dist/esm/src/shared/logger/quickLogger.js.map +1 -0
  136. package/dist/esm/src/xhsc/PathApi.js +44 -3
  137. package/dist/esm/src/xhsc/PathApi.js.map +1 -1
  138. package/dist/esm/src/xhsc/System.js +2 -0
  139. package/dist/esm/src/xhsc/System.js.map +1 -1
  140. package/dist/esm/src/xhsc/UtilsApi.js +50 -0
  141. package/dist/esm/src/xhsc/UtilsApi.js.map +1 -0
  142. package/dist/esm/src/xhsc/XyPrissRunner.js +30 -2
  143. package/dist/esm/src/xhsc/XyPrissRunner.js.map +1 -1
  144. package/dist/esm/src/xhsc/fs/FSCore.js +148 -0
  145. package/dist/esm/src/xhsc/fs/FSCore.js.map +1 -1
  146. package/dist/esm/src/xhsc/fs/FileHandle.js +110 -0
  147. package/dist/esm/src/xhsc/fs/FileHandle.js.map +1 -0
  148. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js +113 -0
  149. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  150. package/dist/esm/src/xhsc/utils/ArrayUtils.js +65 -0
  151. package/dist/esm/src/xhsc/utils/ArrayUtils.js.map +1 -0
  152. package/dist/esm/src/xhsc/utils/AsyncUtils.js +580 -0
  153. package/dist/esm/src/xhsc/utils/AsyncUtils.js.map +1 -0
  154. package/dist/esm/src/xhsc/utils/DateUtils.js +957 -0
  155. package/dist/esm/src/xhsc/utils/DateUtils.js.map +1 -0
  156. package/dist/esm/src/xhsc/utils/FunctionUtils.js +27 -0
  157. package/dist/esm/src/xhsc/utils/FunctionUtils.js.map +1 -0
  158. package/dist/esm/src/xhsc/utils/IdUtils.js +20 -0
  159. package/dist/esm/src/xhsc/utils/IdUtils.js.map +1 -0
  160. package/dist/esm/src/xhsc/utils/NumberUtils.js +77 -0
  161. package/dist/esm/src/xhsc/utils/NumberUtils.js.map +1 -0
  162. package/dist/esm/src/xhsc/utils/ObjectUtils.js +139 -0
  163. package/dist/esm/src/xhsc/utils/ObjectUtils.js.map +1 -0
  164. package/dist/esm/src/xhsc/utils/StringUtils.js +143 -0
  165. package/dist/esm/src/xhsc/utils/StringUtils.js.map +1 -0
  166. package/dist/esm/src/xhsc/utils/ValidationUtils.js +47 -0
  167. package/dist/esm/src/xhsc/utils/ValidationUtils.js.map +1 -0
  168. package/dist/esm/src/xhsc.js +6 -5
  169. package/dist/esm/src/xhsc.js.map +1 -1
  170. package/dist/index.d.ts +1872 -234
  171. package/package.json +119 -137
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Server, IncomingMessage, ServerResponse } from 'http';
2
2
  import { SecureCacheAdapter } from 'xypriss-security';
3
- export { XyPriStringify, fastStringify, safeStringify } from 'xypriss-security';
4
3
  import * as reliant_type from 'reliant-type';
5
4
  import { Readable, Writable } from 'node:stream';
6
5
 
@@ -1268,6 +1267,8 @@ interface SQLInjectionConfig {
1268
1267
  logAttempts?: boolean;
1269
1268
  /** False positive threshold (0-1) */
1270
1269
  falsePositiveThreshold?: number;
1270
+ /** Maximum allowed length for input strings before triggering 'Excessive length' detection */
1271
+ maxLength?: number;
1271
1272
  }
1272
1273
  /**
1273
1274
  * Path Traversal Protection Configuration
@@ -1843,6 +1844,20 @@ interface SecurityConfig {
1843
1844
  * ```
1844
1845
  */
1845
1846
  bruteForce?: boolean | RateLimitConfig;
1847
+ /**
1848
+ * Honeypot Tarpit Configuration (Bot & Scanner Neutralization)
1849
+ *
1850
+ * Instantly blocks vulnerability scanners by performing an ultra-fast O(1)
1851
+ * lookup on common malicious payload signatures (e.g., `/.env`, `/.git`).
1852
+ * Prevents wasted CPU cycles from regex ReDoS and framework routing.
1853
+ * By default, this is implicitly **TRUE**.
1854
+ *
1855
+ * @example Disable honeypot tarpit (Not recommended)
1856
+ * ```typescript
1857
+ * honeypotTarpit: false
1858
+ * ```
1859
+ */
1860
+ honeypotTarpit?: boolean;
1846
1861
  /**
1847
1862
  * Rate Limiting Configuration
1848
1863
  *
@@ -2845,13 +2860,13 @@ declare class XyPrissRunner {
2845
2860
  *
2846
2861
  * Serves as the foundational layer for all XyPriss domain-specific APIs.
2847
2862
  * It encapsulates the `XyPrissRunner` instance, ensuring that all subclasses
2848
- * have unified access to the underlying Rust bridge for high-performance system operations.
2863
+ * have unified access to the underlying XHSC bridge for high-performance system operations.
2849
2864
  */
2850
2865
  declare class BaseApi {
2851
2866
  protected runner: XyPrissRunner;
2852
2867
  /**
2853
2868
  * Initializes the Base API with a shared runner instance.
2854
- * @param runner The XyPrissRunner instance responsible for executing system commands.
2869
+ * @param runner - The XyPrissRunner used to invoke native XHSC binaries.
2855
2870
  */
2856
2871
  constructor(runner: XyPrissRunner);
2857
2872
  }
@@ -2860,7 +2875,7 @@ declare class BaseApi {
2860
2875
  *
2861
2876
  * The `PathApi` class provides a comprehensive suite of robust, platform-independent
2862
2877
  * utilities for working with file and directory paths. By bridging directly to
2863
- * the native engine's internal path module, it ensures rigorous adherence to filesystem standards
2878
+ * the XHSC native binary, it ensures rigorous adherence to filesystem standards
2864
2879
  * across Windows, macOS, and Linux environments.
2865
2880
  *
2866
2881
  * **Key Benefits:**
@@ -3082,10 +3097,41 @@ declare class PathApi extends BaseApi {
3082
3097
  * @returns {boolean} True if the path is absolute, false otherwise.
3083
3098
  */
3084
3099
  isAbsolute: (p: string) => boolean;
3100
+ /**
3101
+ * **Smart Path Correction**
3102
+ *
3103
+ * Attempts to fix path inconsistencies, such as doubled segments or redundant separators.
3104
+ * Prioritizes the high-performance XHSC implementation.
3105
+ *
3106
+ * @param p - Path to correct.
3107
+ * @param tentative - Maximum number of correction attempts.
3108
+ */
3109
+ correct(path: string, options?: {
3110
+ tentative?: number;
3111
+ verify?: boolean;
3112
+ }): string;
3085
3113
  /**
3086
3114
  * **Get System Temp Directory**
3087
3115
  */
3088
3116
  tempDir: () => string;
3117
+ /**
3118
+ * **User-Scoped Temp Directory**
3119
+ *
3120
+ * Resolves and ensures a unique, ephemeral temporary directory scoped
3121
+ * to the current user session under the XyPriss shared temp root
3122
+ * (`<os.tmpdir>/nehonix.xypriss.data/xuser/<hex4>`).
3123
+ *
3124
+ * Each access generates a fresh random sub-path — suited for
3125
+ * short-lived scratch space that must not collide across concurrent
3126
+ * processes or requests.
3127
+ *
3128
+ * @returns {string} Absolute path to the isolated user temp directory.
3129
+ *
3130
+ * @example
3131
+ * const scratch = __sys__.path.tmpUserDir;
3132
+ * __sys__.fs.writeFile(scratch + "/output.json", data);
3133
+ */
3134
+ get tmpUserDir(): string;
3089
3135
  /**
3090
3136
  * **Check Existence**
3091
3137
  */
@@ -3112,7 +3158,7 @@ declare class PathApi extends BaseApi {
3112
3158
  * **System Information Types**
3113
3159
  *
3114
3160
  * Standardized interfaces for the XyPriss System API.
3115
- * Maps directly to the underlying Rust structures.
3161
+ * Maps directly to the underlying native core structures.
3116
3162
  */
3117
3163
  interface SystemInfo {
3118
3164
  hostname: string;
@@ -3292,12 +3338,12 @@ interface FileStats {
3292
3338
  size: number;
3293
3339
  is_file: boolean;
3294
3340
  is_dir: boolean;
3295
- is_symlink: boolean;
3296
3341
  modified: number;
3297
- created: number;
3298
- accessed: number;
3299
- readonly: boolean;
3300
3342
  permissions: number;
3343
+ is_symlink?: boolean;
3344
+ created?: number;
3345
+ accessed?: number;
3346
+ readonly?: boolean;
3301
3347
  }
3302
3348
  interface DirUsage {
3303
3349
  path: string;
@@ -3336,6 +3382,45 @@ interface BatchRenameChange {
3336
3382
  old_path: string;
3337
3383
  new_path: string;
3338
3384
  }
3385
+ /**
3386
+ * **Filesystem Open Flags**
3387
+ *
3388
+ * Standardized flags for opening files, following Node.js conventions
3389
+ * and mapping to native XHSC `os` constants.
3390
+ *
3391
+ * ---
3392
+ *
3393
+ * ### Read flags
3394
+ * - `"r"` — Open for **reading only**. Fails if the file does not exist.
3395
+ * - `"r+"` — Open for **reading and writing**. Fails if the file does not exist.
3396
+ * - `"rs+"` — Open for **reading and writing in synchronous mode**. Instructs the OS
3397
+ * to bypass the local file system cache. Useful for NFS mounts or
3398
+ * scenarios where cache coherency is critical.
3399
+ *
3400
+ * ### Write flags
3401
+ * - `"w"` — Open for **writing only**. The file is **created** if it does not exist,
3402
+ * or **truncated to zero length** if it does.
3403
+ * - `"wx"` — Like `"w"`, but **fails if the file already exists** (exclusive create).
3404
+ * - `"w+"` — Open for **reading and writing**. The file is **created** if it does not
3405
+ * exist, or **truncated** if it does.
3406
+ * - `"wx+"` — Like `"w+"`, but **fails if the file already exists** (exclusive create).
3407
+ *
3408
+ * ### Append flags
3409
+ * - `"a"` — Open for **appending only**. The file is **created** if it does not exist.
3410
+ * The write position is always set to the end of the file.
3411
+ * - `"ax"` — Like `"a"`, but **fails if the file already exists** (exclusive create).
3412
+ * - `"a+"` — Open for **reading and appending**. The file is **created** if it does
3413
+ * not exist. Reading is allowed from any position; writes always go to EOF.
3414
+ * - `"ax+"` — Like `"a+"`, but **fails if the file already exists** (exclusive create).
3415
+ *
3416
+ * ---
3417
+ *
3418
+ * > **`x` suffix** — The exclusive flag (`x`) maps to `O_EXCL` at the OS level.
3419
+ * > It guarantees atomicity: the operation succeeds only if *this* call creates the file,
3420
+ * > preventing race conditions in concurrent environments.
3421
+ */
3422
+ type OpenFlag = "r" | "r+" | "rs+" | "w" | "wx" | "w+" | "wx+" | "a" | "ax" | "a+" | "ax+";
3423
+ type FileOpenFlags = OpenFlag | number;
3339
3424
 
3340
3425
  /**
3341
3426
  * **Operating System & Hardware API**
@@ -3420,6 +3505,45 @@ declare class FSBase extends PathApi {
3420
3505
  constructor(runner: XyPrissRunner);
3421
3506
  }
3422
3507
 
3508
+ /**
3509
+ * **High-Performance File Toolbox**
3510
+ * Exposed via __sys__.fs.open(path, callback)
3511
+ */
3512
+ declare class FileHandle {
3513
+ private id;
3514
+ private runner;
3515
+ private ipc;
3516
+ constructor(id: number, runner: any);
3517
+ /**
3518
+ * **Get Native Handle ID**
3519
+ */
3520
+ get nativeId(): number;
3521
+ /**
3522
+ * **Read from File**
3523
+ * @param length - Max bytes to read
3524
+ */
3525
+ read(length: number): Promise<Buffer>;
3526
+ /**
3527
+ * **Write to File**
3528
+ * @param data - Buffer or String
3529
+ */
3530
+ write(data: Buffer | string): Promise<number>;
3531
+ /**
3532
+ * **Seek within File**
3533
+ * @param offset - Position
3534
+ * @param whence - 0: Start, 1: Current, 2: End
3535
+ */
3536
+ seek(offset: number, whence?: number): Promise<number>;
3537
+ /**
3538
+ * **Get File Statistics**
3539
+ */
3540
+ stat(): Promise<FileStats>;
3541
+ /**
3542
+ * **Close Handle**
3543
+ */
3544
+ close(): Promise<void>;
3545
+ }
3546
+
3423
3547
  /**
3424
3548
  * **Core Filesystem Operations**
3425
3549
  */
@@ -3619,6 +3743,88 @@ declare class FSCore extends FSBase {
3619
3743
  * **Find Duplicates**
3620
3744
  */
3621
3745
  dedupe: (p: string) => DedupeGroup[];
3746
+ /**
3747
+ * **Open File**
3748
+ *
3749
+ * Opens a file and returns a numeric file descriptor (or runs a scoped callback).
3750
+ *
3751
+ * ---
3752
+ *
3753
+ * ### Modes via `flags`
3754
+ *
3755
+ * | Flag | Behavior |
3756
+ * |---------|-----------------------------------------------------------------|
3757
+ * | `"r"` | Read-only. Fails if the file does not exist. |
3758
+ * | `"r+"` | Read-write. Fails if the file does not exist. |
3759
+ * | `"rs+"` | Read-write, bypasses OS cache (useful for NFS / shared drives). |
3760
+ * | `"w"` | Write-only. Creates the file or truncates it if it exists. |
3761
+ * | `"wx"` | Write-only. Fails if the file already exists (atomic create). |
3762
+ * | `"w+"` | Read-write. Creates the file or truncates it if it exists. |
3763
+ * | `"wx+"` | Read-write. Fails if the file already exists (atomic create). |
3764
+ * | `"a"` | Append-only. Creates the file if missing. Writes go to EOF. |
3765
+ * | `"ax"` | Append-only. Fails if the file already exists (atomic create). |
3766
+ * | `"a+"` | Read-append. Creates the file if missing. Writes always at EOF. |
3767
+ * | `"ax+"` | Read-append. Fails if the file already exists (atomic create). |
3768
+ *
3769
+ * > **`x` suffix** — Maps to `O_EXCL` at the OS level: the call succeeds only if
3770
+ * > *this* invocation creates the file, preventing race conditions.
3771
+ *
3772
+ * ---
3773
+ *
3774
+ * ### Transport strategy
3775
+ *
3776
+ * The method resolves the file descriptor through two transports, in order:
3777
+ *
3778
+ * 1. **IPC** (`XYPRISS_IPC_PATH` set) — communicates with the XHSC daemon via a
3779
+ * Unix socket. File descriptors are **stateful and persistent** across calls.
3780
+ * 2. **Runner fallback** — used when IPC is unavailable or the environment variable
3781
+ * is not set. Descriptors are **not persistent** across multiple independent calls;
3782
+ * a warning is emitted to the console.
3783
+ *
3784
+ * ---
3785
+ *
3786
+ * ### Callback (scoped) mode
3787
+ *
3788
+ * When a `callback` is provided, the file is opened, passed as a {@link FileHandle}
3789
+ * toolbox to the callback, then **automatically closed** in a `finally` block —
3790
+ * even if the callback throws. In this mode the method returns `void`.
3791
+ *
3792
+ * When no callback is provided, the raw numeric file descriptor is returned and
3793
+ * **the caller is responsible for closing it**.
3794
+ *
3795
+ * ---
3796
+ *
3797
+ * @param p - Absolute or relative path to the target file.
3798
+ * @param flags - Open mode, as a string flag (default: `"r"`) or a numeric
3799
+ * `os` constant. See the flag table above.
3800
+ * @param callback - Optional scoped handler receiving a {@link FileHandle}.
3801
+ * When supplied, the handle is closed automatically on completion.
3802
+ *
3803
+ * @returns The numeric file descriptor when no callback is given; `void` otherwise.
3804
+ *
3805
+ * @example <caption>Scoped read (handle closed automatically)</caption>
3806
+ * ```typescript
3807
+ * await __sys__.fs.open("data.bin", "r", async (file) => {
3808
+ * const chunk = await file.read(1024);
3809
+ * console.log(chunk.toString());
3810
+ * });
3811
+ * ```
3812
+ *
3813
+ * @example <caption>Manual descriptor (caller must close)</caption>
3814
+ * ```typescript
3815
+ * const fd = await __sys__.fs.open("output.log", "a");
3816
+ * // ... write operations ...
3817
+ * await __sys__.fs.close(fd);
3818
+ * ```
3819
+ */
3820
+ open(p: string, flags?: FileOpenFlags, callback?: (handle: FileHandle) => Promise<void> | void): Promise<number | void>;
3821
+ /**
3822
+ * **Close File Handle**
3823
+ *
3824
+ * @param handle - The file handle to close.
3825
+ */
3826
+ close: (handle: number) => Promise<void>;
3827
+ private mapFlags;
3622
3828
  }
3623
3829
 
3624
3830
  /**
@@ -4416,233 +4622,1715 @@ declare class EnvApi implements IEnvApi {
4416
4622
  * const timeout = __sys__.__env__.get("REQUEST_TIMEOUT_MS", "5000");
4417
4623
  * const ms = parseInt(timeout, 10);
4418
4624
  *
4419
- * // Concise fallback with nullish coalescing
4420
- * const logLevel = __sys__.__env__.get("LOG_LEVEL") ?? "info";
4625
+ * // Concise fallback with nullish coalescing
4626
+ * const logLevel = __sys__.__env__.get("LOG_LEVEL") ?? "info";
4627
+ */
4628
+ get(key: string): string | undefined;
4629
+ get(key: string, defaultValue: string): string;
4630
+ /**
4631
+ * Reads a required variable from the secure internal store and throws if
4632
+ * it cannot be resolved.
4633
+ *
4634
+ * Use this method for every variable that is mandatory for application
4635
+ * correctness. It surfaces configuration errors at startup rather than
4636
+ * silently producing `undefined` at the point of use.
4637
+ *
4638
+ * @param key - Variable name to look up.
4639
+ * @param options - Optional validation settings.
4640
+ * @returns The stored value, guaranteed non-undefined.
4641
+ * @throws {EnvAccessError} When the variable is missing or empty.
4642
+ * @throws {EnvStoreError} When the store has not been initialised.
4643
+ *
4644
+ * @example
4645
+ * // Fail fast at boot if a critical variable is absent
4646
+ * const databaseUrl = __sys__.__env__.getStrict("DATABASE_URL");
4647
+ * const jwtSecret = __sys__.__env__.getStrict("JWT_SECRET", { rejectEmpty: true });
4648
+ * const smtpHost = __sys__.__env__.getStrict("SMTP_HOST");
4649
+ *
4650
+ * // Collect all required variables once at module initialisation
4651
+ * const config = {
4652
+ * db: __sys__.__env__.getStrict("DATABASE_URL"),
4653
+ * jwt: __sys__.__env__.getStrict("JWT_SECRET", { rejectEmpty: true }),
4654
+ * smtp: __sys__.__env__.getStrict("SMTP_HOST"),
4655
+ * };
4656
+ */
4657
+ getStrict(key: string, options?: EnvGetStrictOptions): string;
4658
+ /**
4659
+ * Returns `true` when the given key is present in the secure internal
4660
+ * store, regardless of its value (including empty strings).
4661
+ *
4662
+ * @param key - Variable name to test.
4663
+ * @throws {EnvStoreError} When the store has not been initialised.
4664
+ *
4665
+ * @example
4666
+ * if (__sys__.__env__.has("SENTRY_DSN")) {
4667
+ * Sentry.init({ dsn: __sys__.__env__.get("SENTRY_DSN") });
4668
+ * }
4669
+ *
4670
+ * const betaEnabled = __sys__.__env__.has("ENABLE_BETA_UI");
4671
+ */
4672
+ has(key: string): boolean;
4673
+ /**
4674
+ * Returns a frozen, point-in-time snapshot of stored variables.
4675
+ *
4676
+ * The object is frozen at the moment of the call; subsequent `set` or
4677
+ * `delete` calls do not affect it.
4678
+ *
4679
+ * Providing `options.keys` is strongly recommended in production code.
4680
+ * Returning the full store risks inadvertently capturing secrets in log
4681
+ * statements or JSON serialisations.
4682
+ *
4683
+ * @param options - Optional filter configuration.
4684
+ * @returns A frozen {@link EnvSnapshot}.
4685
+ * @throws {EnvStoreError} When the store has not been initialised.
4686
+ *
4687
+ * @example
4688
+ * // Filtered snapshot — preferred in all production code paths
4689
+ * const dbConfig = __sys__.__env__.all({
4690
+ * keys: ["DATABASE_URL", "DATABASE_POOL_SIZE", "DATABASE_TIMEOUT_MS"],
4691
+ * });
4692
+ *
4693
+ * // Full snapshot — use only for diagnostics / startup validation
4694
+ * const full = __sys__.__env__.all();
4695
+ * logger.debug("Env snapshot", { count: Object.keys(full).length });
4696
+ */
4697
+ all(options?: EnvAllOptions): EnvSnapshot;
4698
+ /**
4699
+ * Returns `true` when the execution mode is `"production"`.
4700
+ *
4701
+ * @example
4702
+ * const logger = createLogger({
4703
+ * level: __sys__.__env__.isProduction() ? "error" : "debug",
4704
+ * });
4705
+ */
4706
+ isProduction(): boolean;
4707
+ /**
4708
+ * Returns `true` when the execution mode is `"development"`.
4709
+ *
4710
+ * @example
4711
+ * if (__sys__.__env__.isDevelopment()) {
4712
+ * app.use(requestLogger({ colorize: true }));
4713
+ * }
4714
+ */
4715
+ isDevelopment(): boolean;
4716
+ /**
4717
+ * Returns `true` when the execution mode is `"staging"`.
4718
+ *
4719
+ * @example
4720
+ * if (__sys__.__env__.isStaging()) {
4721
+ * payment.useSandbox();
4722
+ * }
4723
+ */
4724
+ isStaging(): boolean;
4725
+ /**
4726
+ * Returns `true` when the execution mode is `"test"`.
4727
+ *
4728
+ * @example
4729
+ * const dbUrl = __sys__.__env__.isTest()
4730
+ * ? __sys__.__env__.getStrict("TEST_DATABASE_URL")
4731
+ * : __sys__.__env__.getStrict("DATABASE_URL");
4732
+ */
4733
+ isTest(): boolean;
4734
+ /**
4735
+ * Returns `true` when the execution mode exactly matches `envName`
4736
+ * (case-sensitive).
4737
+ *
4738
+ * @param envName - Mode name to compare against.
4739
+ *
4740
+ * @example
4741
+ * if (__sys__.__env__.is("canary")) {
4742
+ * featureFlags.enableAll();
4743
+ * }
4744
+ */
4745
+ is(envName: string): boolean;
4746
+ /**
4747
+ * Retrieves the OS-level username of the current process owner by invoking
4748
+ * the XHSC native Go binary.
4749
+ *
4750
+ * This method is synchronous and blocks until the native call completes.
4751
+ * Do not call it in request hot paths. Returns `""` on failure so callers
4752
+ * can safely use the result without null checks.
4753
+ *
4754
+ * @returns The current OS username, or `""` on failure.
4755
+ *
4756
+ * @example
4757
+ * const actor = __sys__.__env__.user() || "<unknown>";
4758
+ * auditLog.write({ actor, action: "deploy" });
4759
+ */
4760
+ user(): string;
4761
+ /**
4762
+ * Returns the internal store, throwing {@link EnvStoreError} if it has not
4763
+ * yet been initialised.
4764
+ *
4765
+ * SECURITY: This is the single point of store access. Every read and write
4766
+ * method must go through here — never access `globalThis[XY_ENV_STORE_KEY]`
4767
+ * directly outside this method.
4768
+ *
4769
+ * Eliminating the `?? process.env` fallback is intentional. A silent
4770
+ * fallback to `process.env` during the bootstrap race window would bypass
4771
+ * the Shield and leak values without any warning. A thrown error is
4772
+ * immediately visible during development and integration testing.
4773
+ *
4774
+ * @internal
4775
+ * @throws {EnvStoreError}
4776
+ */
4777
+ private requireStoreMap;
4778
+ private getStoreForCaller;
4779
+ /**
4780
+ * Asserts that `key` is a valid environment variable name.
4781
+ *
4782
+ * @internal
4783
+ * @throws {EnvKeyError}
4784
+ */
4785
+ private validateKey;
4786
+ /**
4787
+ * Asserts that `value` does not contain characters that can corrupt
4788
+ * downstream parsers, log sinks, or HTTP serialisers.
4789
+ *
4790
+ * Rejected characters:
4791
+ * - CR (`\r`) and LF (`\n`) — break line-oriented `.env` parsers and
4792
+ * enable log injection attacks.
4793
+ * - NUL (`\0`) — truncates strings in C-based runtimes and can bypass
4794
+ * suffix-based extension checks in some file path handling code.
4795
+ *
4796
+ * @internal
4797
+ * @throws {EnvKeyError}
4798
+ */
4799
+ private validateValue;
4800
+ /**
4801
+ * **Environment Security Shield**
4802
+ *
4803
+ * Replaces the `process.env` object with a hardened Proxy that enforces
4804
+ * the following policies on every property access:
4805
+ *
4806
+ * **Read trap**
4807
+ * - Whitelisted keys (see {@link EnvApi.whitelistedFields}) and keys
4808
+ * matching the prefixes `XY_`, `XYPRISS_`, `ENC_`, `DOTENV_`, or `__`
4809
+ * pass through to the real value.
4810
+ * - All other reads return `undefined`. A one-time per-key warning is
4811
+ * written to `process.stderr` (suppressed when
4812
+ * `XYPRISS_ENV_SHIELD=silent`).
4813
+ *
4814
+ * **`ownKeys` and `has` traps**
4815
+ * - Restrict the apparent key set to the whitelist. This prevents
4816
+ * third-party code from enumerating the real store through
4817
+ * `Object.keys(process.env)`, `JSON.stringify(process.env)`, or spread
4818
+ * operators — all of which bypass the `get` trap.
4819
+ *
4820
+ * The descriptor is applied with `writable: false` to prevent replacement
4821
+ * by application code, and `configurable: true` to allow test teardown.
4822
+ *
4823
+ * @internal
4824
+ */
4825
+ /**
4826
+ * **Environment Security Shield**
4827
+ *
4828
+ * Replaces the `process.env` object with a hardened Proxy that enforces
4829
+ * the following policies on every property access:
4830
+ *
4831
+ * **Read trap**
4832
+ * - Whitelisted keys (see {@link EnvApi.whitelistedFields}) and keys
4833
+ * matching the prefixes `XY_`, `XYPRISS_`, `ENC_`, `DOTENV_`, or `__`
4834
+ * pass through to the real value.
4835
+ * - All other reads return `undefined`. A one-time per-key warning is
4836
+ * written to `process.stderr` (suppressed when
4837
+ * `XYPRISS_ENV_SHIELD=silent`).
4838
+ *
4839
+ * **`ownKeys` and `has` traps**
4840
+ * - Restrict the apparent key set to the whitelist. This prevents
4841
+ * third-party code from enumerating the real store through
4842
+ * `Object.keys(process.env)`, `JSON.stringify(process.env)`, or spread
4843
+ * operators — all of which bypass the `get` trap.
4844
+ *
4845
+ * The descriptor is applied with `writable: false` to prevent replacement
4846
+ * by application code, and `configurable: true` to allow test teardown.
4847
+ *
4848
+ * @internal
4849
+ */
4850
+ private applyShield;
4851
+ private isCallerProjectCode;
4852
+ }
4853
+
4854
+ /**
4855
+ * **StringUtils — XyPriss String Utilities**
4856
+ */
4857
+ declare class StringUtils {
4858
+ /**
4859
+ * **Generate a Random String**
4860
+ *
4861
+ * Generates a pseudo-random character sequence of a specified length.
4862
+ * Uses alphanumeric characters (A-Z, a-z, 0-9).
4863
+ *
4864
+ * @param length - The desired length of the string (default: `10`).
4865
+ * @returns A random alphanumeric string.
4866
+ *
4867
+ * @example
4868
+ * ```ts
4869
+ * utils.randomString(8); // "a7B2k9Xz"
4870
+ * ```
4871
+ */
4872
+ randomString(length?: number): string;
4873
+ /**
4874
+ * **Slugify a String**
4875
+ *
4876
+ * Converts a string into a URL-friendly "slug" by lowering case,
4877
+ * removing non-alphanumeric characters, and replacing spaces with hyphens.
4878
+ *
4879
+ * @param text - The string to slugify.
4880
+ * @returns The URL-friendly slug.
4881
+ *
4882
+ * @example
4883
+ * ```ts
4884
+ * utils.slugify("Hello World!"); // "hello-world"
4885
+ * ```
4886
+ */
4887
+ slugify(text: string): string;
4888
+ /**
4889
+ * **Truncate a String**
4890
+ *
4891
+ * Shortens a string to a specified length and appends a suffix (default: `...`)
4892
+ * if the original string was longer than the limit.
4893
+ *
4894
+ * @param text - The string to truncate.
4895
+ * @param maxLength - Maximum length including the suffix.
4896
+ * @param suffix - The string to append (default: `"..."`).
4897
+ * @returns The truncated string.
4898
+ *
4899
+ * @example
4900
+ * ```ts
4901
+ * utils.truncate("Very long sentence", 10); // "Very lo..."
4902
+ * ```
4903
+ */
4904
+ truncate(text: string, maxLength: number, suffix?: string): string;
4905
+ /**
4906
+ * **Capitalize a String**
4907
+ *
4908
+ * Uppercases the first character of the string.
4909
+ *
4910
+ * @param text - The string to capitalize.
4911
+ * @returns The capitalized string.
4912
+ */
4913
+ capitalize(text: string): string;
4914
+ /**
4915
+ * **Convert to camelCase**
4916
+ *
4917
+ * Converts hyphen-separated, underscore-separated, or space-separated
4918
+ * strings into camelCase.
4919
+ *
4920
+ * @param text - The string to convert.
4921
+ * @returns The camelCase string.
4922
+ */
4923
+ toCamelCase(text: string): string;
4924
+ /**
4925
+ * **Pad a String**
4926
+ *
4927
+ * Adds padding characters to the start or end of a string until it
4928
+ * reaches the target length.
4929
+ *
4930
+ * @param text - The source string.
4931
+ * @param length - Target length.
4932
+ * @param char - Padding character (default: `" "`).
4933
+ * @param position - Whether to pad at `"start"` or `"end"`.
4934
+ * @returns The padded string.
4935
+ */
4936
+ pad(text: string, length: number, char?: string, position?: "start" | "end"): string;
4937
+ /**
4938
+ * **Count Word/Substring Occurrences**
4939
+ *
4940
+ * Returns the number of times a specific word or substring appears.
4941
+ *
4942
+ * @param text - The body of text to search.
4943
+ * @param word - The substring to look for.
4944
+ * @param caseSensitive - Whether to respect case (default: `false`).
4945
+ * @returns The number of occurrences.
4946
+ */
4947
+ countOccurrences(text: string, word: string, caseSensitive?: boolean): number;
4948
+ /**
4949
+ * **toQueryString**
4950
+ *
4951
+ * Serializes a flat record into a URL-encoded query string format.
4952
+ *
4953
+ * @param params The object to serialize.
4954
+ * @returns The query string.
4955
+ */
4956
+ toQueryString(params: Record<string, unknown>): string;
4957
+ }
4958
+
4959
+ /**
4960
+ * **NumberUtils — XyPriss Number & Math Utilities**
4961
+ */
4962
+ declare class NumberUtils {
4963
+ /**
4964
+ * **Clamp a Value**
4965
+ *
4966
+ * Restricts a numeric value to a defined range [min, max].
4967
+ *
4968
+ * @param value - The value to clamp.
4969
+ * @param min - The lower bound.
4970
+ * @param max - The upper bound.
4971
+ * @returns The clamped value.
4972
+ */
4973
+ clamp(value: number, min: number, max: number): number;
4974
+ /**
4975
+ * **Linear Interpolation (LERP)**
4976
+ *
4977
+ * Returns the linear interpolation between `start` and `end` for a factor `t`.
4978
+ *
4979
+ * @param start - The start value.
4980
+ * @param end - The end value.
4981
+ * @param t - The interpolation factor (0.0 to 1.0).
4982
+ * @returns The interpolated value.
4983
+ */
4984
+ lerp(start: number, end: number, t: number): number;
4985
+ /**
4986
+ * **Get a Random Integer**
4987
+ *
4988
+ * Returns a random integer between min (inclusive) and max (inclusive).
4989
+ *
4990
+ * @param min - Minimum value.
4991
+ * @param max - Maximum value.
4992
+ * @returns A random integer.
4993
+ */
4994
+ randomInt(min: number, max: number): number;
4995
+ /**
4996
+ * **Format Number**
4997
+ *
4998
+ * Locale-aware number formatting.
4999
+ *
5000
+ * @param value - The number to format.
5001
+ * @param locale - Optional locale (default: `en-US`).
5002
+ * @param options - Intl.NumberFormatOptions.
5003
+ * @returns A localized string.
5004
+ */
5005
+ formatNumber(value: number, locale?: string, options?: Intl.NumberFormatOptions): string;
5006
+ /**
5007
+ * **Format Bytes**
5008
+ *
5009
+ * Converts raw bytes into a human-readable size string (KB, MB, GB, etc.).
5010
+ *
5011
+ * @param bytes - The number of bytes.
5012
+ * @param decimals - Decimal precision.
5013
+ * @returns A human-readable size string.
5014
+ */
5015
+ formatBytes(bytes: number, decimals?: number): string;
5016
+ }
5017
+
5018
+ /**
5019
+ * @file DateUtils.ts
5020
+ * @description XyPriss Date & Time Utilities — A comprehensive, zero-dependency
5021
+ * date/time utility class built on the native `Date` object and the `Intl` API.
5022
+ *
5023
+ * @remarks
5024
+ * All methods are pure and side-effect-free unless otherwise noted.
5025
+ * Timestamps can be provided in either **seconds** (Unix) or **milliseconds**
5026
+ * (JavaScript). The class auto-detects the unit using the heuristic:
5027
+ * values below `1e11` are treated as seconds; values at or above `1e11` are
5028
+ * treated as milliseconds. This heuristic is valid until **November 2286**.
5029
+ *
5030
+ * @example
5031
+ * ```ts
5032
+ * const du = new DateUtils();
5033
+ *
5034
+ * du.format(Date.now()); // "Apr 15, 2026"
5035
+ * du.timeAgo(Date.now() - 90_000); // "2 minutes ago"
5036
+ * du.formatDuration(3_661_000); // "1h 1m 1s"
5037
+ * du.startOf("month"); // 2026-04-01T00:00:00.000Z
5038
+ * ```
5039
+ */
5040
+ declare class DateUtils {
5041
+ /**
5042
+ * Converts any supported input value to a `Date` object.
5043
+ *
5044
+ * Supported inputs:
5045
+ * - `Date` — returned as-is (not cloned).
5046
+ * - `number` — auto-detected as Unix seconds (`< 1e11`) or milliseconds.
5047
+ * - `string` — parsed via `new Date(string)` (ISO 8601 recommended).
5048
+ *
5049
+ * @param date - The value to convert.
5050
+ * @returns The corresponding `Date` object.
5051
+ * @throws {RangeError} If the resulting `Date` is invalid.
5052
+ *
5053
+ * @internal
5054
+ */
5055
+ private toDate;
5056
+ /**
5057
+ * Converts any supported input value to a millisecond timestamp.
5058
+ *
5059
+ * @param date - The value to convert.
5060
+ * @returns Milliseconds since the Unix epoch.
5061
+ *
5062
+ * @internal
5063
+ */
5064
+ private toMs;
5065
+ /**
5066
+ * Returns the current Unix timestamp in **seconds**.
5067
+ *
5068
+ * @returns The current time as a Unix timestamp (integer seconds).
5069
+ *
5070
+ * @example
5071
+ * ```ts
5072
+ * du.now(); // e.g. 1776287197
5073
+ * ```
5074
+ */
5075
+ now(): number;
5076
+ /**
5077
+ * Returns the current time as a JavaScript timestamp in **milliseconds**.
5078
+ *
5079
+ * Equivalent to `Date.now()`.
5080
+ *
5081
+ * @returns The current time in milliseconds since the Unix epoch.
5082
+ *
5083
+ * @example
5084
+ * ```ts
5085
+ * du.nowMs(); // e.g. 1776287197000
5086
+ * ```
5087
+ */
5088
+ nowMs(): number;
5089
+ /**
5090
+ * Returns the current time as a `Date` object.
5091
+ *
5092
+ * @returns A new `Date` representing the current instant.
5093
+ *
5094
+ * @example
5095
+ * ```ts
5096
+ * du.today(); // Date { ... }
5097
+ * ```
5098
+ */
5099
+ today(): Date;
5100
+ /**
5101
+ * Serializes a date value into a localized string using `Intl.DateTimeFormat`.
5102
+ *
5103
+ * Automatically handles Unix timestamps (seconds) and JavaScript timestamps
5104
+ * (milliseconds) via the `< 1e11` heuristic.
5105
+ *
5106
+ * @param date - The input to format: `Date`, number (timestamp), or ISO string.
5107
+ * @param locale - BCP 47 locale tag (default: `"en-US"`).
5108
+ * @param options - `Intl.DateTimeFormatOptions` to customize the output.
5109
+ * @returns A localized date string.
5110
+ *
5111
+ * @example
5112
+ * ```ts
5113
+ * du.format(1776287197);
5114
+ * // → "Apr 15, 2026"
5115
+ *
5116
+ * du.format(new Date(), "fr-FR", { dateStyle: "full" });
5117
+ * // → "mercredi 15 avril 2026"
5118
+ *
5119
+ * du.format("2026-04-15T12:00:00Z", "en-GB", { timeStyle: "short" });
5120
+ * // → "12:00"
5121
+ * ```
5122
+ */
5123
+ format(date: Date | number | string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
5124
+ /**
5125
+ * Formats a date as an ISO 8601 string (`YYYY-MM-DDTHH:mm:ss.sssZ`).
5126
+ *
5127
+ * This is the format recommended for data interchange and storage.
5128
+ *
5129
+ * @param date - The date to format (default: current time).
5130
+ * @returns An ISO 8601 UTC string.
5131
+ *
5132
+ * @example
5133
+ * ```ts
5134
+ * du.toISO();
5135
+ * // → "2026-04-15T10:30:00.000Z"
5136
+ *
5137
+ * du.toISO(1776287197);
5138
+ * // → "2026-04-15T..."
5139
+ * ```
5140
+ */
5141
+ toISO(date?: Date | number | string): string;
5142
+ /**
5143
+ * Formats a date as a plain date string: `YYYY-MM-DD`.
5144
+ *
5145
+ * The date is rendered in **local time** unless a UTC flag is set.
5146
+ *
5147
+ * @param date - The date to format (default: current time).
5148
+ * @param utc - If `true`, use UTC date components instead of local time (default: `false`).
5149
+ * @returns A date-only string in `YYYY-MM-DD` format.
5150
+ *
5151
+ * @example
5152
+ * ```ts
5153
+ * du.toDateString();
5154
+ * // → "2026-04-15"
5155
+ *
5156
+ * du.toDateString(new Date("2026-12-31T23:59:00Z"), true);
5157
+ * // → "2026-12-31"
5158
+ * ```
5159
+ */
5160
+ toDateString(date?: Date | number | string, utc?: boolean): string;
5161
+ /**
5162
+ * Formats a date as a time string: `HH:mm:ss`.
5163
+ *
5164
+ * The time is rendered in **local time** unless the UTC flag is set.
5165
+ *
5166
+ * @param date - The date to format (default: current time).
5167
+ * @param utc - If `true`, use UTC time components (default: `false`).
5168
+ * @returns A time-only string in `HH:mm:ss` format.
5169
+ *
5170
+ * @example
5171
+ * ```ts
5172
+ * du.toTimeString(new Date("2026-04-15T08:05:03Z"), true);
5173
+ * // → "08:05:03"
5174
+ * ```
5175
+ */
5176
+ toTimeString(date?: Date | number | string, utc?: boolean): string;
5177
+ /**
5178
+ * Converts a duration into a human-readable string (e.g., `"1d 2h 30m 5s"`).
5179
+ *
5180
+ * Components are omitted when their value is zero, except for seconds which
5181
+ * always appear when the total duration is less than one minute.
5182
+ *
5183
+ * @param value - The duration to format.
5184
+ * @param unit - The unit of `value`: `"ms"` (milliseconds, default) or `"s"` (seconds).
5185
+ * @returns A compact, space-separated duration string.
5186
+ *
5187
+ * @example
5188
+ * ```ts
5189
+ * du.formatDuration(3_661_000); // → "1h 1m 1s"
5190
+ * du.formatDuration(90, "s"); // → "1m 30s"
5191
+ * du.formatDuration(0); // → "0s"
5192
+ * du.formatDuration(86_400_000); // → "1d"
5193
+ * ```
5194
+ */
5195
+ formatDuration(value: number, unit?: "ms" | "s"): string;
5196
+ /**
5197
+ * Returns a relative time string (e.g., `"5 minutes ago"`, `"in 2 hours"`).
5198
+ *
5199
+ * Uses `Intl.RelativeTimeFormat` for locale-aware output. Automatically
5200
+ * selects the most appropriate unit (second → minute → hour → day → month → year).
5201
+ *
5202
+ * @param date - The reference date, in the past or future.
5203
+ * @param locale - BCP 47 locale tag (default: `"en-US"`).
5204
+ * @returns A localized relative time string.
5205
+ *
5206
+ * @example
5207
+ * ```ts
5208
+ * du.timeAgo(Date.now() - 90_000); // → "2 minutes ago"
5209
+ * du.timeAgo(Date.now() + 3_600_000); // → "in 1 hour"
5210
+ * du.timeAgo(Date.now() - 90_000, "fr"); // → "il y a 2 minutes"
5211
+ * ```
5212
+ */
5213
+ timeAgo(date: Date | number | string, locale?: string): string;
5214
+ /**
5215
+ * Adds a given amount of time to a date and returns a new `Date`.
5216
+ *
5217
+ * Supported units: `"ms"`, `"s"` (seconds), `"m"` (minutes), `"h"` (hours),
5218
+ * `"d"` (days), `"w"` (weeks), `"mo"` (months), `"y"` (years).
5219
+ *
5220
+ * Month and year arithmetic is handled using `setMonth` / `setFullYear`,
5221
+ * which correctly accounts for varying month lengths (e.g., adding 1 month
5222
+ * to January 31 yields February 28/29).
5223
+ *
5224
+ * @param date - The starting date.
5225
+ * @param value - The amount to add (can be negative to subtract).
5226
+ * @param unit - The time unit.
5227
+ * @returns A new `Date` offset by the specified amount.
5228
+ *
5229
+ * @example
5230
+ * ```ts
5231
+ * du.add(new Date("2026-01-31"), 1, "mo");
5232
+ * // → Date("2026-02-28") — accounts for shorter February
5233
+ *
5234
+ * du.add(new Date("2026-04-15"), -7, "d");
5235
+ * // → Date("2026-04-08")
5236
+ *
5237
+ * du.add(Date.now(), 2, "h");
5238
+ * // → Date 2 hours from now
5239
+ * ```
5240
+ */
5241
+ add(date: Date | number | string, value: number, unit: "ms" | "s" | "m" | "h" | "d" | "w" | "mo" | "y"): Date;
5242
+ /**
5243
+ * Subtracts a given amount of time from a date and returns a new `Date`.
5244
+ *
5245
+ * This is a convenience wrapper around {@link add} with a negated `value`.
5246
+ *
5247
+ * @param date - The starting date.
5248
+ * @param value - The amount to subtract (must be positive).
5249
+ * @param unit - The time unit (same options as {@link add}).
5250
+ * @returns A new `Date` shifted back by the specified amount.
5251
+ *
5252
+ * @example
5253
+ * ```ts
5254
+ * du.subtract(new Date("2026-03-01"), 1, "mo");
5255
+ * // → Date("2026-02-01")
5256
+ * ```
5257
+ */
5258
+ subtract(date: Date | number | string, value: number, unit: "ms" | "s" | "m" | "h" | "d" | "w" | "mo" | "y"): Date;
5259
+ /**
5260
+ * Returns the difference between two dates in the specified unit.
5261
+ *
5262
+ * The result is the **signed** difference `(dateA - dateB)` truncated
5263
+ * toward zero. A positive value means `dateA` is later than `dateB`.
5264
+ *
5265
+ * Supported units: `"ms"`, `"s"`, `"m"`, `"h"`, `"d"`, `"w"`.
5266
+ * Month and year differences are intentionally excluded because their
5267
+ * variable length makes a lossless inverse impossible; use {@link add}
5268
+ * and calendar-aware logic for those cases.
5269
+ *
5270
+ * @param dateA - The first date.
5271
+ * @param dateB - The second date.
5272
+ * @param unit - The unit for the result (default: `"ms"`).
5273
+ * @returns The signed integer difference in the requested unit.
5274
+ *
5275
+ * @example
5276
+ * ```ts
5277
+ * du.diff("2026-04-20", "2026-04-15", "d"); // → 5
5278
+ * du.diff("2026-04-10", "2026-04-15", "d"); // → -5
5279
+ * du.diff(Date.now(), Date.now() - 3600_000, "h"); // → 1
5280
+ * ```
5281
+ */
5282
+ diff(dateA: Date | number | string, dateB: Date | number | string, unit?: "ms" | "s" | "m" | "h" | "d" | "w"): number;
5283
+ /**
5284
+ * Returns `true` if `dateA` is strictly before `dateB`.
5285
+ *
5286
+ * @param dateA - The first date.
5287
+ * @param dateB - The second date.
5288
+ * @returns `true` if `dateA < dateB`.
5289
+ *
5290
+ * @example
5291
+ * ```ts
5292
+ * du.isBefore("2026-01-01", "2026-06-01"); // → true
5293
+ * ```
5294
+ */
5295
+ isBefore(dateA: Date | number | string, dateB: Date | number | string): boolean;
5296
+ /**
5297
+ * Returns `true` if `dateA` is strictly after `dateB`.
5298
+ *
5299
+ * @param dateA - The first date.
5300
+ * @param dateB - The second date.
5301
+ * @returns `true` if `dateA > dateB`.
5302
+ *
5303
+ * @example
5304
+ * ```ts
5305
+ * du.isAfter("2026-12-31", "2026-06-01"); // → true
5306
+ * ```
5307
+ */
5308
+ isAfter(dateA: Date | number | string, dateB: Date | number | string): boolean;
5309
+ /**
5310
+ * Returns `true` if two dates represent the same instant in time.
5311
+ *
5312
+ * Comparison is performed at millisecond precision.
5313
+ *
5314
+ * @param dateA - The first date.
5315
+ * @param dateB - The second date.
5316
+ * @returns `true` if both dates resolve to the same millisecond.
5317
+ *
5318
+ * @example
5319
+ * ```ts
5320
+ * du.isSame(new Date("2026-04-15"), 1776268800000); // → true (if same instant)
5321
+ * ```
5322
+ */
5323
+ isSame(dateA: Date | number | string, dateB: Date | number | string): boolean;
5324
+ /**
5325
+ * Returns `true` if `date` falls within the range `[start, end]` (inclusive).
5326
+ *
5327
+ * @param date - The date to test.
5328
+ * @param start - The start of the range.
5329
+ * @param end - The end of the range.
5330
+ * @returns `true` if `start ≤ date ≤ end`.
5331
+ *
5332
+ * @example
5333
+ * ```ts
5334
+ * du.isBetween("2026-04-15", "2026-01-01", "2026-12-31"); // → true
5335
+ * du.isBetween("2025-12-31", "2026-01-01", "2026-12-31"); // → false
5336
+ * ```
5337
+ */
5338
+ isBetween(date: Date | number | string, start: Date | number | string, end: Date | number | string): boolean;
5339
+ /**
5340
+ * Returns a new `Date` set to the **start** of the specified unit
5341
+ * (i.e., all smaller components zeroed out).
5342
+ *
5343
+ * Supported units: `"day"`, `"week"` (Monday = start), `"month"`, `"year"`.
5344
+ *
5345
+ * @param unit - The boundary unit.
5346
+ * @param date - The reference date (default: current time).
5347
+ * @returns A new `Date` at the beginning of the unit.
5348
+ *
5349
+ * @example
5350
+ * ```ts
5351
+ * du.startOf("day");
5352
+ * // → 2026-04-15T00:00:00.000 (local)
5353
+ *
5354
+ * du.startOf("month", new Date("2026-04-15"));
5355
+ * // → 2026-04-01T00:00:00.000
5356
+ *
5357
+ * du.startOf("year", "2026-06-15");
5358
+ * // → 2026-01-01T00:00:00.000
5359
+ * ```
5360
+ */
5361
+ startOf(unit: "day" | "week" | "month" | "year", date?: Date | number | string): Date;
5362
+ /**
5363
+ * Returns a new `Date` set to the **end** of the specified unit
5364
+ * (i.e., the last millisecond of that unit).
5365
+ *
5366
+ * Supported units: `"day"`, `"week"` (Sunday = end), `"month"`, `"year"`.
5367
+ *
5368
+ * @param unit - The boundary unit.
5369
+ * @param date - The reference date (default: current time).
5370
+ * @returns A new `Date` at the very last millisecond of the unit.
5371
+ *
5372
+ * @example
5373
+ * ```ts
5374
+ * du.endOf("month", new Date("2026-02-01"));
5375
+ * // → 2026-02-28T23:59:59.999
5376
+ *
5377
+ * du.endOf("year", "2026-01-01");
5378
+ * // → 2026-12-31T23:59:59.999
5379
+ * ```
5380
+ */
5381
+ endOf(unit: "day" | "week" | "month" | "year", date?: Date | number | string): Date;
5382
+ /**
5383
+ * Returns `true` if the given year is a leap year.
5384
+ *
5385
+ * A year is a leap year if it is divisible by 4, except for century years,
5386
+ * which must also be divisible by 400.
5387
+ *
5388
+ * @param year - The four-digit year to test (default: current year).
5389
+ * @returns `true` if the year is a leap year.
5390
+ *
5391
+ * @example
5392
+ * ```ts
5393
+ * du.isLeapYear(2024); // → true
5394
+ * du.isLeapYear(2100); // → false
5395
+ * du.isLeapYear(2000); // → true
5396
+ * ```
5397
+ */
5398
+ isLeapYear(year?: number): boolean;
5399
+ /**
5400
+ * Returns the number of days in a given month of a given year.
5401
+ *
5402
+ * Correctly accounts for leap years when querying February.
5403
+ *
5404
+ * @param month - The 1-based month index (1 = January, 12 = December).
5405
+ * @param year - The four-digit year (default: current year).
5406
+ * @returns The number of days in the specified month (28–31).
5407
+ *
5408
+ * @example
5409
+ * ```ts
5410
+ * du.daysInMonth(2, 2024); // → 29 (leap year)
5411
+ * du.daysInMonth(2, 2023); // → 28
5412
+ * du.daysInMonth(1, 2026); // → 31
5413
+ * ```
5414
+ */
5415
+ daysInMonth(month: number, year?: number): number;
5416
+ /**
5417
+ * Returns the ISO 8601 week number (1–53) for a given date.
5418
+ *
5419
+ * ISO 8601 defines Week 1 as the week containing the year's first Thursday.
5420
+ * Weeks run Monday–Sunday. A date in early January may belong to the
5421
+ * final week of the previous year (e.g., January 1, 2016 → Week 53 of 2015).
5422
+ *
5423
+ * @param date - The reference date (default: current time).
5424
+ * @returns The ISO week number.
5425
+ *
5426
+ * @example
5427
+ * ```ts
5428
+ * du.weekNumber(new Date("2026-01-01")); // → 1
5429
+ * du.weekNumber(new Date("2016-01-03")); // → 53 (belongs to 2015)
5430
+ * ```
5431
+ */
5432
+ weekNumber(date?: Date | number | string): number;
5433
+ /**
5434
+ * Returns the day of the year (1–366) for a given date.
5435
+ *
5436
+ * @param date - The reference date (default: current time).
5437
+ * @returns An integer from 1 to 366.
5438
+ *
5439
+ * @example
5440
+ * ```ts
5441
+ * du.dayOfYear(new Date("2026-02-01")); // → 32
5442
+ * du.dayOfYear(new Date("2026-12-31")); // → 365
5443
+ * ```
5444
+ */
5445
+ dayOfYear(date?: Date | number | string): number;
5446
+ /**
5447
+ * Returns the ISO 8601 quarter (1–4) in which the given date falls.
5448
+ *
5449
+ * @param date - The reference date (default: current time).
5450
+ * @returns A quarter number: `1`, `2`, `3`, or `4`.
5451
+ *
5452
+ * @example
5453
+ * ```ts
5454
+ * du.quarter(new Date("2026-04-15")); // → 2 (Apr–Jun)
5455
+ * du.quarter(new Date("2026-11-01")); // → 4 (Oct–Dec)
5456
+ * ```
5457
+ */
5458
+ quarter(date?: Date | number | string): 1 | 2 | 3 | 4;
5459
+ /**
5460
+ * Returns `true` if the given date falls on a weekend (Saturday or Sunday).
5461
+ *
5462
+ * The check uses **local time**.
5463
+ *
5464
+ * @param date - The date to check (default: current time).
5465
+ * @returns `true` if the date is a Saturday or Sunday.
5466
+ *
5467
+ * @example
5468
+ * ```ts
5469
+ * du.isWeekend(new Date("2026-04-18")); // → true (Saturday)
5470
+ * du.isWeekend(new Date("2026-04-15")); // → false (Wednesday)
5471
+ * ```
5472
+ */
5473
+ isWeekend(date?: Date | number | string): boolean;
5474
+ /**
5475
+ * Returns `true` if the given date falls on a weekday (Monday–Friday).
5476
+ *
5477
+ * @param date - The date to check (default: current time).
5478
+ * @returns `true` if the date is Monday through Friday.
5479
+ *
5480
+ * @example
5481
+ * ```ts
5482
+ * du.isWeekday(new Date("2026-04-15")); // → true
5483
+ * du.isWeekday(new Date("2026-04-19")); // → false (Sunday)
5484
+ * ```
5485
+ */
5486
+ isWeekday(date?: Date | number | string): boolean;
5487
+ /**
5488
+ * Returns `true` if two dates fall on the same calendar day (in local time).
5489
+ *
5490
+ * Only the year, month, and date components are compared; time is ignored.
5491
+ *
5492
+ * @param dateA - The first date.
5493
+ * @param dateB - The second date.
5494
+ * @returns `true` if both dates share the same year, month, and day.
5495
+ *
5496
+ * @example
5497
+ * ```ts
5498
+ * du.isSameDay("2026-04-15T08:00:00", "2026-04-15T22:00:00"); // → true
5499
+ * du.isSameDay("2026-04-15", "2026-04-16"); // → false
5500
+ * ```
5501
+ */
5502
+ isSameDay(dateA: Date | number | string, dateB: Date | number | string): boolean;
5503
+ /**
5504
+ * Returns `true` if the given date is today (in local time).
5505
+ *
5506
+ * @param date - The date to test.
5507
+ * @returns `true` if `date` falls on the current calendar day.
5508
+ *
5509
+ * @example
5510
+ * ```ts
5511
+ * du.isToday(new Date()); // → true
5512
+ * du.isToday("2020-01-01"); // → false
5513
+ * ```
5514
+ */
5515
+ isToday(date: Date | number | string): boolean;
5516
+ /**
5517
+ * Returns `true` if the given date is in the past (before the current instant).
5518
+ *
5519
+ * @param date - The date to check.
5520
+ * @returns `true` if `date` is strictly before `Date.now()`.
5521
+ *
5522
+ * @example
5523
+ * ```ts
5524
+ * du.isPast("2020-01-01"); // → true
5525
+ * du.isPast(Date.now() + 1000); // → false
5526
+ * ```
5527
+ */
5528
+ isPast(date: Date | number | string): boolean;
5529
+ /**
5530
+ * Returns `true` if the given date is in the future (after the current instant).
5531
+ *
5532
+ * @param date - The date to check.
5533
+ * @returns `true` if `date` is strictly after `Date.now()`.
5534
+ *
5535
+ * @example
5536
+ * ```ts
5537
+ * du.isFuture(Date.now() + 5000); // → true
5538
+ * du.isFuture("2020-01-01"); // → false
5539
+ * ```
5540
+ */
5541
+ isFuture(date: Date | number | string): boolean;
5542
+ /**
5543
+ * Clamps a date to a `[min, max]` range.
5544
+ *
5545
+ * If `date` is before `min`, `min` is returned.
5546
+ * If `date` is after `max`, `max` is returned.
5547
+ * Otherwise, `date` is returned unchanged (as a new `Date`).
5548
+ *
5549
+ * @param date - The date to clamp.
5550
+ * @param min - The lower bound.
5551
+ * @param max - The upper bound.
5552
+ * @returns A new `Date` clamped within `[min, max]`.
5553
+ *
5554
+ * @example
5555
+ * ```ts
5556
+ * du.clamp("2025-01-01", "2026-01-01", "2026-12-31");
5557
+ * // → Date("2026-01-01") — clamped to min
5558
+ *
5559
+ * du.clamp("2026-06-15", "2026-01-01", "2026-12-31");
5560
+ * // → Date("2026-06-15") — within range, unchanged
5561
+ * ```
5562
+ */
5563
+ clamp(date: Date | number | string, min: Date | number | string, max: Date | number | string): Date;
5564
+ /**
5565
+ * Generates an array of `Date` objects representing each day in the range
5566
+ * `[start, end]`, inclusive.
5567
+ *
5568
+ * The range is capped at **3 650 days** (~10 years) to prevent accidental
5569
+ * allocation of enormous arrays.
5570
+ *
5571
+ * @param start - The first day of the range.
5572
+ * @param end - The last day of the range.
5573
+ * @returns An ordered array of `Date` objects, one per day.
5574
+ * @throws {RangeError} If the range exceeds 3 650 days.
5575
+ *
5576
+ * @example
5577
+ * ```ts
5578
+ * du.dateRange("2026-04-13", "2026-04-15");
5579
+ * // → [Date("2026-04-13"), Date("2026-04-14"), Date("2026-04-15")]
5580
+ * ```
5581
+ */
5582
+ dateRange(start: Date | number | string, end: Date | number | string): Date[];
5583
+ /**
5584
+ * Returns `true` if the given value can be successfully interpreted
5585
+ * as a valid, finite date.
5586
+ *
5587
+ * Accepts `Date`, `number`, and `string` inputs. A `Date` whose
5588
+ * `getTime()` returns `NaN` is considered invalid.
5589
+ *
5590
+ * @param value - The value to validate.
5591
+ * @returns `true` if the value represents a valid date.
5592
+ *
5593
+ * @example
5594
+ * ```ts
5595
+ * du.isValid(new Date()); // → true
5596
+ * du.isValid("2026-04-15"); // → true
5597
+ * du.isValid("not-a-date"); // → false
5598
+ * du.isValid(new Date("invalid")); // → false
5599
+ * du.isValid(NaN); // → false
5600
+ * ```
5601
+ */
5602
+ isValid(value: unknown): boolean;
5603
+ /**
5604
+ * Parses a date string using an ordered list of format patterns and returns
5605
+ * the first successfully parsed `Date`, or `null` if none match.
5606
+ *
5607
+ * Supported format tokens:
5608
+ * - `YYYY` — 4-digit year
5609
+ * - `MM` — 2-digit month (01–12)
5610
+ * - `DD` — 2-digit day (01–31)
5611
+ * - `HH` — 2-digit hours (00–23)
5612
+ * - `mm` — 2-digit minutes (00–59)
5613
+ * - `ss` — 2-digit seconds (00–59)
5614
+ *
5615
+ * @param value - The date string to parse.
5616
+ * @param formats - An ordered list of format strings to attempt.
5617
+ * @returns The first successfully parsed `Date`, or `null`.
5618
+ *
5619
+ * @example
5620
+ * ```ts
5621
+ * du.parse("15/04/2026", ["DD/MM/YYYY"]);
5622
+ * // → Date("2026-04-15")
5623
+ *
5624
+ * du.parse("2026-04-15 08:30:00", ["YYYY-MM-DD HH:mm:ss"]);
5625
+ * // → Date("2026-04-15T08:30:00")
5626
+ *
5627
+ * du.parse("bad-input", ["YYYY-MM-DD"]);
5628
+ * // → null
5629
+ * ```
5630
+ */
5631
+ parse(value: string, formats: string[]): Date | null;
5632
+ /**
5633
+ * Returns the UTC offset of the local environment in minutes.
5634
+ *
5635
+ * Positive values indicate zones **behind** UTC (e.g., UTC-5 → `300`),
5636
+ * mirroring the behaviour of `Date.prototype.getTimezoneOffset()`.
5637
+ *
5638
+ * @returns The UTC offset in minutes.
5639
+ *
5640
+ * @example
5641
+ * ```ts
5642
+ * du.timezoneOffset(); // → -120 for UTC+2, 300 for UTC-5
5643
+ * ```
5644
+ */
5645
+ timezoneOffset(): number;
5646
+ /**
5647
+ * Formats a date in a specific IANA timezone using `Intl.DateTimeFormat`.
5648
+ *
5649
+ * Requires the runtime to support the `timeZone` option (all modern
5650
+ * environments do).
5651
+ *
5652
+ * @param date - The date to format.
5653
+ * @param timeZone - A valid IANA timezone identifier (e.g., `"America/New_York"`).
5654
+ * @param locale - BCP 47 locale tag (default: `"en-US"`).
5655
+ * @param options - Additional `Intl.DateTimeFormatOptions`.
5656
+ * @returns A localized date string in the given timezone.
5657
+ *
5658
+ * @example
5659
+ * ```ts
5660
+ * du.formatInTimezone(Date.now(), "Asia/Tokyo", "ja-JP", { dateStyle: "full", timeStyle: "short" });
5661
+ * // → "2026年4月15日水曜日 19:00"
5662
+ * ```
5663
+ */
5664
+ formatInTimezone(date: Date | number | string, timeZone: string, locale?: string, options?: Omit<Intl.DateTimeFormatOptions, "timeZone">): string;
5665
+ }
5666
+
5667
+ /**
5668
+ * **ObjectUtils — XyPriss Object Utilities**
5669
+ */
5670
+ declare class ObjectUtils {
5671
+ /**
5672
+ * **Deep Clone an Object**
5673
+ *
5674
+ * Creates a deep copy of `obj` using `XStringify` for serialization,
5675
+ * which handles cyclic references and offers better performance
5676
+ * than the native `JSON.stringify` in complex object graphs.
5677
+ *
5678
+ * @param obj - The object to clone. Must be serializable.
5679
+ * @returns A completely independent deep copy of the input object.
5680
+ *
5681
+ * @example
5682
+ * ```ts
5683
+ * const original = { a: 1, nested: { b: 2 } };
5684
+ * const clone = utils.deepClone(original);
5685
+ * clone.nested.b = 99;
5686
+ * // original.nested.b is still 2
5687
+ * ```
5688
+ */
5689
+ deepClone<T>(obj: T): T;
5690
+ /**
5691
+ * **Pick Specific Keys from an Object**
5692
+ *
5693
+ * Returns a new object containing only the key-value pairs whose
5694
+ * keys appear in the `keys` array. Non-existent keys are silently ignored.
5695
+ *
5696
+ * @param obj - The source object.
5697
+ * @param keys - Array of keys to extract.
5698
+ * @returns A new object with only the specified keys.
5699
+ *
5700
+ * @example
5701
+ * ```ts
5702
+ * utils.pick({ a: 1, b: 2, c: 3 }, ["a", "c"]); // { a: 1, c: 3 }
5703
+ * ```
5704
+ */
5705
+ pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
5706
+ /**
5707
+ * **Omit Specific Keys from an Object**
5708
+ *
5709
+ * Returns a new object that is a shallow copy of `obj` with the
5710
+ * specified keys removed.
5711
+ *
5712
+ * @param obj - The source object.
5713
+ * @param keys - Array of keys to exclude.
5714
+ * @returns A new object without the specified keys.
5715
+ *
5716
+ * @example
5717
+ * ```ts
5718
+ * utils.omit({ a: 1, b: 2, c: 3 }, ["b"]); // { a: 1, c: 3 }
5719
+ * ```
5720
+ */
5721
+ omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
5722
+ /**
5723
+ * **Check if an Object is Empty**
5724
+ *
5725
+ * Returns `true` if the object has no own enumerable keys.
5726
+ * Works correctly with objects created via `Object.create(null)`.
5727
+ *
5728
+ * @param obj - The object to inspect.
5729
+ * @returns `true` if the object has no own keys, `false` otherwise.
5730
+ *
5731
+ * @example
5732
+ * ```ts
5733
+ * utils.isEmpty({}); // true
5734
+ * utils.isEmpty({ a: 1 }); // false
5735
+ * utils.isEmpty(Object.create(null)); // true
5736
+ * ```
5737
+ */
5738
+ isEmpty(obj: object): boolean;
5739
+ /**
5740
+ * **flattenObject**
5741
+ *
5742
+ * Collapses nested objects into flat dot-notation (or custom) keys.
5743
+ * Useful for configuration mapping or CSV generation.
5744
+ *
5745
+ * @param obj - The object to flatten.
5746
+ * @param separator - Optional path separator (default: `"."`).
5747
+ * @returns A shallow object with path-based keys.
5748
+ */
5749
+ flattenObject(obj: Record<string, unknown>, separator?: string): Record<string, unknown>;
5750
+ /**
5751
+ * **parse**
5752
+ *
5753
+ * Safely parses a JSON string. If the parsing fails, the provided fallback
5754
+ * value is returned instead of throwing an exception.
5755
+ *
5756
+ * @param json The JSON string to parse.
5757
+ * @param fallback The fallback value to return on failure.
5758
+ * @returns The parsed object or the fallback value.
5759
+ */
5760
+ parse<T>(json: string, fallback?: T | null): T | null;
5761
+ }
5762
+
5763
+ /**
5764
+ * **ArrayUtils — XyPriss Array Utilities**
5765
+ */
5766
+ declare class ArrayUtils {
5767
+ /**
5768
+ * **Chunk an Array**
5769
+ *
5770
+ * Splits an array into sub-arrays of a fixed maximum size.
5771
+ */
5772
+ chunk<T>(arr: T[], size: number): T[][];
5773
+ /**
5774
+ * **Unique Elements**
5775
+ *
5776
+ * Returns a new array with all duplicates removed.
5777
+ */
5778
+ unique<T>(arr: T[]): T[];
5779
+ /**
5780
+ * **Shuffle Elements**
5781
+ *
5782
+ * Randomly reorders an array using the Fisher-Yates algorithm.
5783
+ */
5784
+ shuffle<T>(arr: T[]): T[];
5785
+ /**
5786
+ * **Group Elements**
5787
+ *
5788
+ * Groups array elements into an object based on a key-mapping function.
5789
+ */
5790
+ groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]>;
5791
+ /**
5792
+ * **Pick Random Sample**
5793
+ */
5794
+ sample<T>(arr: T[]): T | undefined;
5795
+ /**
5796
+ * **Flatten One Level**
5797
+ */
5798
+ flatten<T>(arr: T[][]): T[];
5799
+ }
5800
+
5801
+ /**
5802
+ * # AsyncUtils — XyPriss Async Control Flow
5803
+ *
5804
+ * A comprehensive library of asynchronous control flow primitives for TypeScript.
5805
+ * Each method is designed to be safe, performant, and composable.
5806
+ *
5807
+ * @example
5808
+ * ```ts
5809
+ * const async = new AsyncUtils();
5810
+ *
5811
+ * // Auto-retry + debounce + performance measurement in a few lines
5812
+ * const save = async.debounce(async (data: string) => {
5813
+ * const { result, durationMs } = await async.measure(() =>
5814
+ * async.retry(() => api.save(data), { maxAttempts: 3, delay: 1000 })
5815
+ * );
5816
+ * console.log(`Saved in ${durationMs.toFixed(1)}ms`, result);
5817
+ * }, 500);
5818
+ * ```
5819
+ *
5820
+ * @module AsyncUtils
5821
+ */
5822
+ /** Advanced options for {@link AsyncUtils.retry}. */
5823
+ interface RetryOptions {
5824
+ /** Maximum number of attempts. @default 3 */
5825
+ maxAttempts?: number;
5826
+ /** Initial delay between attempts (ms). @default 500 */
5827
+ delay?: number;
5828
+ /** Multiplicative factor for the delay at each attempt (exponential backoff). @default 1 */
5829
+ backoffFactor?: number;
5830
+ /** Maximum delay regardless of backoff (ms). @default Infinity */
5831
+ maxDelay?: number;
5832
+ /** Abort signal allowing to interrupt attempts at any time. */
5833
+ signal?: AbortSignal;
5834
+ /**
5835
+ * Optional predicate — returns `true` if the error is "retryable".
5836
+ * Useful for not retrying a 400 or 401 error that won't change.
5837
+ *
5838
+ * @example
5839
+ * ```ts
5840
+ * retryIf: (err) => err instanceof NetworkError
5841
+ * ```
5842
+ */
5843
+ retryIf?: (error: unknown, attempt: number) => boolean;
5844
+ /**
5845
+ * Callback called at each failed attempt (ideal for telemetry).
5846
+ *
5847
+ * @example
5848
+ * ```ts
5849
+ * onRetry: (err, attempt) => logger.warn(`Attempt ${attempt} failed`, err)
5850
+ * ```
5851
+ */
5852
+ onRetry?: (error: unknown, attempt: number) => void;
5853
+ }
5854
+ /** Options for {@link AsyncUtils.timeout}. */
5855
+ interface TimeoutOptions {
5856
+ /** Message of the error thrown in case of timeout. @default "Operation timed out" */
5857
+ message?: string;
5858
+ /** External signal allowing to cancel the promise before timeout. */
5859
+ signal?: AbortSignal;
5860
+ }
5861
+ /** Result of an execution via {@link AsyncUtils.measure}. */
5862
+ interface MeasureResult<T> {
5863
+ result: T;
5864
+ /** Operation duration in milliseconds (µs precision via `performance.now()`). */
5865
+ durationMs: number;
5866
+ }
5867
+ /** Result of an execution via {@link AsyncUtils.attempt}. */
5868
+ type AttemptResult<T> = {
5869
+ ok: true;
5870
+ value: T;
5871
+ error?: never;
5872
+ } | {
5873
+ ok: false;
5874
+ error: unknown;
5875
+ value?: never;
5876
+ };
5877
+ declare class AsyncUtils {
5878
+ /**
5879
+ * ## Asynchronous Pause
5880
+ *
5881
+ * Suspends execution for a given duration.
5882
+ * Compatible with `AbortSignal`: sleep will be interrupted cleanly
5883
+ * if the signal is triggered (the promise **resolves** without error in this case).
5884
+ *
5885
+ * @param ms - Pause duration in milliseconds.
5886
+ * @param signal - Optional cancellation signal (AbortController).
5887
+ * @returns A promise that resolves after `ms` ms (or earlier if signal triggered).
5888
+ *
5889
+ * @example Simple pause
5890
+ * ```ts
5891
+ * await utils.sleep(2000); // waits 2 seconds
5892
+ * ```
5893
+ *
5894
+ * @example Cancellation via AbortController
5895
+ * ```ts
5896
+ * const controller = new AbortController();
5897
+ * setTimeout(() => controller.abort(), 500);
5898
+ *
5899
+ * await utils.sleep(5000, controller.signal); // resolves after ~500ms
5900
+ * ```
5901
+ */
5902
+ sleep(ms: number, signal?: AbortSignal): Promise<void>;
5903
+ /**
5904
+ * ## Asynchronous Pause (alias of `sleep`)
5905
+ *
5906
+ * @alias sleep
5907
+ * @see {@link sleep}
5908
+ */
5909
+ wait(ms: number, signal?: AbortSignal): Promise<void>;
5910
+ /**
5911
+ * ## Retry with Exponential Backoff
5912
+ *
5913
+ * Retries an asynchronous operation up to `maxAttempts` times.
5914
+ * Supports exponential backoff, maximum delay, filter predicate,
5915
+ * and `AbortSignal` to interrupt the retry cycle.
5916
+ *
5917
+ * Delay formula: `min(delay × backoffFactor^attempt, maxDelay)`.
5918
+ *
5919
+ * @param fn - The asynchronous function to execute.
5920
+ * @param options - Retry options (see {@link RetryOptions}).
5921
+ * @returns Resolved value of `fn` on the first successful attempt.
5922
+ * @throws Last error if all attempts fail.
5923
+ *
5924
+ * @example Basic retry (3 attempts, 500ms between each)
5925
+ * ```ts
5926
+ * const data = await utils.retry(() => fetch("/api/data").then(r => r.json()));
5927
+ * ```
5928
+ *
5929
+ * @example Exponential backoff: 200ms → 400ms → 800ms → max 1000ms
5930
+ * ```ts
5931
+ * const result = await utils.retry(() => unstableApi(), {
5932
+ * maxAttempts: 4,
5933
+ * delay: 200,
5934
+ * backoffFactor: 2,
5935
+ * maxDelay: 1000,
5936
+ * onRetry: (err, n) => console.warn(`Retry #${n}`, err),
5937
+ * });
5938
+ * ```
5939
+ *
5940
+ * @example Do not retry auth errors
5941
+ * ```ts
5942
+ * await utils.retry(() => api.call(), {
5943
+ * retryIf: (err) => !(err instanceof AuthError),
5944
+ * });
5945
+ * ```
5946
+ */
5947
+ retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
5948
+ /**
5949
+ * ## Promise Timeout
5950
+ *
5951
+ * Wraps a promise with a maximum duration. If the promise does not
5952
+ * resolve within the given time, an `Error` is thrown.
5953
+ *
5954
+ * Automatically handles internal timer cleanup to prevent memory leaks.
5955
+ *
5956
+ * @param fn - Function returning the promise to monitor.
5957
+ * @param ms - Maximum delay in milliseconds before rejecting.
5958
+ * @param options - Additional options (error message, cancellation signal).
5959
+ * @returns Resolved value if the promise succeeds within delay.
5960
+ * @throws `Error` with `options.message` if timeout is reached.
5961
+ *
5962
+ * @example
5963
+ * ```ts
5964
+ * const result = await utils.timeout(
5965
+ * () => fetch("/slow-api").then(r => r.json()),
5966
+ * 3000,
5967
+ * { message: "API took too long to respond" }
5968
+ * );
5969
+ * ```
5970
+ */
5971
+ timeout<T>(fn: () => Promise<T>, ms: number, options?: TimeoutOptions): Promise<T>;
5972
+ /**
5973
+ * ## Safe Execution (Never Throws)
5974
+ *
5975
+ * Executes an asynchronous function and always captures the result as a
5976
+ * discriminated object `{ ok, value }` or `{ ok, error }`.
5977
+ * **Never throws exceptions**, simplifying control flow.
5978
+ *
5979
+ * Ideal for API calls, parsing, or any operation where failure is a normal outcome
5980
+ * and must be handled explicitly.
5981
+ *
5982
+ * @param fn - Asynchronous function to execute safely.
5983
+ * @returns Discriminated object indicating success or failure.
5984
+ *
5985
+ * @example Without `attempt` (verbose)
5986
+ * ```ts
5987
+ * let user;
5988
+ * try { user = await fetchUser(id); }
5989
+ * catch (e) { console.error(e); return; }
5990
+ * ```
5991
+ *
5992
+ * @example With `attempt` (concise)
5993
+ * ```ts
5994
+ * const { ok, value: user, error } = await utils.attempt(() => fetchUser(id));
5995
+ * if (!ok) { console.error(error); return; }
5996
+ * // `user` is guaranteed defined here
5997
+ * ```
5998
+ *
5999
+ * @example Combined with `retry`
6000
+ * ```ts
6001
+ * const { ok, value } = await utils.attempt(() =>
6002
+ * utils.retry(() => api.getData(), { maxAttempts: 5 })
6003
+ * );
6004
+ * ```
6005
+ */
6006
+ attempt<T>(fn: () => Promise<T>): Promise<AttemptResult<T>>;
6007
+ /**
6008
+ * ## Debounce
6009
+ *
6010
+ * Delays execution of `fn` until `wait` ms have elapsed since the last call.
6011
+ * If a new call arrives before the delay ends, the previous one is cancelled
6012
+ * and the timer restarts from zero.
6013
+ *
6014
+ * Typical use cases: search fields (prevents one request per keystroke),
6015
+ * resize listeners, auto-save.
6016
+ *
6017
+ * The returned version exposes a `.cancel()` method to manually cancel the
6018
+ * pending timer, and `.flush()` to trigger execution immediately.
6019
+ *
6020
+ * @param fn - Function to debounce.
6021
+ * @param wait - Quiet period required before execution (ms). @default 300
6022
+ * @returns Debounced version of `fn` with `.cancel()` and `.flush()` methods.
6023
+ *
6024
+ * @example Real-time search
6025
+ * ```ts
6026
+ * const search = utils.debounce((query: string) => {
6027
+ * fetch(`/api/search?q=${query}`);
6028
+ * }, 400);
6029
+ *
6030
+ * input.addEventListener("input", (e) => search(e.target.value));
6031
+ * ```
6032
+ *
6033
+ * @example Explicit cancellation (e.g., on component unmount)
6034
+ * ```ts
6035
+ * const save = utils.debounce(saveToServer, 1000);
6036
+ * onUnmount(() => save.cancel());
6037
+ * ```
6038
+ *
6039
+ * @example Immediate flush (e.g., before navigation)
6040
+ * ```ts
6041
+ * window.addEventListener("beforeunload", () => save.flush());
6042
+ * ```
4421
6043
  */
4422
- get(key: string): string | undefined;
4423
- get(key: string, defaultValue: string): string;
6044
+ debounce<T extends (...args: any[]) => any>(fn: T, wait?: number): ((...args: Parameters<T>) => void) & {
6045
+ cancel: () => void;
6046
+ flush: (...args: Parameters<T>) => void;
6047
+ };
4424
6048
  /**
4425
- * Reads a required variable from the secure internal store and throws if
4426
- * it cannot be resolved.
6049
+ * ## Throttle
4427
6050
  *
4428
- * Use this method for every variable that is mandatory for application
4429
- * correctness. It surfaces configuration errors at startup rather than
4430
- * silently producing `undefined` at the point of use.
6051
+ * Guarantees that `fn` executes no more than once per `limit` ms window,
6052
+ * regardless of how many calls are received.
4431
6053
  *
4432
- * @param key - Variable name to look up.
4433
- * @param options - Optional validation settings.
4434
- * @returns The stored value, guaranteed non-undefined.
4435
- * @throws {EnvAccessError} When the variable is missing or empty.
4436
- * @throws {EnvStoreError} When the store has not been initialised.
6054
+ * Unlike debounce, throttle executes `fn` **immediately** on the first call,
6055
+ * then ignores subsequent calls until the window ends.
4437
6056
  *
4438
- * @example
4439
- * // Fail fast at boot if a critical variable is absent
4440
- * const databaseUrl = __sys__.__env__.getStrict("DATABASE_URL");
4441
- * const jwtSecret = __sys__.__env__.getStrict("JWT_SECRET", { rejectEmpty: true });
4442
- * const smtpHost = __sys__.__env__.getStrict("SMTP_HOST");
6057
+ * Typical use cases: scroll handlers, mousemove, drag-and-drop, gamepads.
4443
6058
  *
4444
- * // Collect all required variables once at module initialisation
4445
- * const config = {
4446
- * db: __sys__.__env__.getStrict("DATABASE_URL"),
4447
- * jwt: __sys__.__env__.getStrict("JWT_SECRET", { rejectEmpty: true }),
4448
- * smtp: __sys__.__env__.getStrict("SMTP_HOST"),
4449
- * };
6059
+ * The returned version exposes a `.cancel()` method to manually reset the
6060
+ * throttle window.
6061
+ *
6062
+ * @param fn - Function to throttle.
6063
+ * @param limit - Minimum duration between two executions (ms). @default 300
6064
+ * @returns Throttled version of `fn` with `.cancel()` method.
6065
+ *
6066
+ * @example Scroll handler limited to 60fps (~16ms)
6067
+ * ```ts
6068
+ * const onScroll = utils.throttle(() => {
6069
+ * updateScrollIndicator();
6070
+ * }, 16);
6071
+ *
6072
+ * window.addEventListener("scroll", onScroll);
6073
+ * ```
4450
6074
  */
4451
- getStrict(key: string, options?: EnvGetStrictOptions): string;
6075
+ throttle<T extends (...args: any[]) => any>(fn: T, limit?: number): ((...args: Parameters<T>) => void) & {
6076
+ cancel: () => void;
6077
+ };
4452
6078
  /**
4453
- * Returns `true` when the given key is present in the secure internal
4454
- * store, regardless of its value (including empty strings).
6079
+ * ## High-Precision Execution Time Measurement
4455
6080
  *
4456
- * @param key - Variable name to test.
4457
- * @throws {EnvStoreError} When the store has not been initialised.
6081
+ * Wraps a synchronous or asynchronous function and returns its result
6082
+ * along with its execution time in milliseconds (microsecond precision via `performance.now()`).
4458
6083
  *
4459
- * @example
4460
- * if (__sys__.__env__.has("SENTRY_DSN")) {
4461
- * Sentry.init({ dsn: __sys__.__env__.get("SENTRY_DSN") });
4462
- * }
6084
+ * @param fn - Function to measure (sync or async).
6085
+ * @returns An object `{ result, durationMs }`.
4463
6086
  *
4464
- * const betaEnabled = __sys__.__env__.has("ENABLE_BETA_UI");
6087
+ * @example Measuring an API call
6088
+ * ```ts
6089
+ * const { result, durationMs } = await utils.measure(() =>
6090
+ * fetch("/api/heavy").then(r => r.json())
6091
+ * );
6092
+ * console.log(`Response received in ${durationMs.toFixed(2)}ms:`, result);
6093
+ * ```
4465
6094
  */
4466
- has(key: string): boolean;
6095
+ measure<T>(fn: () => T | Promise<T>): Promise<MeasureResult<T>>;
4467
6096
  /**
4468
- * Returns a frozen, point-in-time snapshot of stored variables.
6097
+ * ## High-Precision Drift-Corrected Interval
4469
6098
  *
4470
- * The object is frozen at the moment of the call; subsequent `set` or
4471
- * `delete` calls do not affect it.
6099
+ * Repeatedly executes `fn` with automatic compensation for accumulated
6100
+ * clock drift. Unlike `setInterval`, this implementation adjusts each delay
6101
+ * based on actual elapsed time.
4472
6102
  *
4473
- * Providing `options.keys` is strongly recommended in production code.
4474
- * Returning the full store risks inadvertently capturing secrets in log
4475
- * statements or JSON serialisations.
6103
+ * The current tick count is passed as a parameter to `fn`, enabling
6104
+ * animations or progression counting.
4476
6105
  *
4477
- * @param options - Optional filter configuration.
4478
- * @returns A frozen {@link EnvSnapshot}.
4479
- * @throws {EnvStoreError} When the store has not been initialised.
6106
+ * Execution stops cleanly when `signal` is aborted.
4480
6107
  *
4481
- * @example
4482
- * // Filtered snapshot preferred in all production code paths
4483
- * const dbConfig = __sys__.__env__.all({
4484
- * keys: ["DATABASE_URL", "DATABASE_POOL_SIZE", "DATABASE_TIMEOUT_MS"],
4485
- * });
6108
+ * @param fn - Callback called at each tick, receiving the tick index (0-indexed).
6109
+ * @param ms - Target interval in milliseconds.
6110
+ * @param signal - `AbortSignal` to stop the loop.
6111
+ * @returns A promise that resolves when the signal is aborted.
4486
6112
  *
4487
- * // Full snapshot use only for diagnostics / startup validation
4488
- * const full = __sys__.__env__.all();
4489
- * logger.debug("Env snapshot", { count: Object.keys(full).length });
4490
- */
4491
- all(options?: EnvAllOptions): EnvSnapshot;
4492
- /**
4493
- * Returns `true` when the execution mode is `"production"`.
6113
+ * @example Counter update every second
6114
+ * ```ts
6115
+ * const controller = new AbortController();
4494
6116
  *
4495
- * @example
4496
- * const logger = createLogger({
4497
- * level: __sys__.__env__.isProduction() ? "error" : "debug",
4498
- * });
4499
- */
4500
- isProduction(): boolean;
4501
- /**
4502
- * Returns `true` when the execution mode is `"development"`.
6117
+ * utils.repeat((tick) => {
6118
+ * console.log(`Tick ${tick} ${new Date().toLocaleTimeString()}`);
6119
+ * }, 1000, controller.signal);
4503
6120
  *
4504
- * @example
4505
- * if (__sys__.__env__.isDevelopment()) {
4506
- * app.use(requestLogger({ colorize: true }));
4507
- * }
6121
+ * // Stop after 5 seconds
6122
+ * setTimeout(() => controller.abort(), 5000);
6123
+ * ```
4508
6124
  */
4509
- isDevelopment(): boolean;
6125
+ repeat(fn: (tick: number) => void | Promise<void>, ms: number, signal?: AbortSignal): Promise<void>;
4510
6126
  /**
4511
- * Returns `true` when the execution mode is `"staging"`.
6127
+ * ## Parallel Execution with Limited Concurrency
4512
6128
  *
4513
- * @example
4514
- * if (__sys__.__env__.isStaging()) {
4515
- * payment.useSandbox();
4516
- * }
6129
+ * Processes an array of values in parallel via `fn`, limiting the number
6130
+ * of active promises simultaneously to `concurrency`. Results are returned
6131
+ * in the same order as inputs.
6132
+ *
6133
+ * Ideal for scenarios where you want to avoid saturating a server or database
6134
+ * with thousands of simultaneous requests.
6135
+ *
6136
+ * @param items - Array of items to process.
6137
+ * @param fn - Asynchronous function applied to each element.
6138
+ * @param concurrency - Maximum number of active parallel promises. @default 5
6139
+ * @returns Array of results in the same order as `items`.
6140
+ *
6141
+ * @example Batch file import (max 3 at a time)
6142
+ * ```ts
6143
+ * const files = ["f1.csv", "f2.csv", "f3.csv", "f4.csv"];
6144
+ * const results = await utils.pool(files, f => importFile(f), 3);
6145
+ * ```
4517
6146
  */
4518
- isStaging(): boolean;
6147
+ pool<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>, concurrency?: number): Promise<R[]>;
4519
6148
  /**
4520
- * Returns `true` when the execution mode is `"test"`.
6149
+ * ## Race with Built-in Timeout
4521
6150
  *
4522
- * @example
4523
- * const dbUrl = __sys__.__env__.isTest()
4524
- * ? __sys__.__env__.getStrict("TEST_DATABASE_URL")
4525
- * : __sys__.__env__.getStrict("DATABASE_URL");
6151
+ * Launches multiple promises in parallel and returns the first one to resolve.
6152
+ * If none resolve within `timeoutMs`, an error is thrown.
6153
+ *
6154
+ * Similar to `Promise.race`, but with an integrated temporal safety net.
6155
+ *
6156
+ * @param fns - Array of functions returning promises.
6157
+ * @param timeoutMs - Maximum delay in milliseconds. @default Infinity
6158
+ * @returns Value of the first resolved promise.
6159
+ * @throws `Error("Race timed out")` if timeout is reached.
4526
6160
  */
4527
- isTest(): boolean;
6161
+ race<T>(fns: Array<() => Promise<T>>, timeoutMs?: number): Promise<T>;
4528
6162
  /**
4529
- * Returns `true` when the execution mode exactly matches `envName`
4530
- * (case-sensitive).
6163
+ * ## Async Memoization with TTL
4531
6164
  *
4532
- * @param envName - Mode name to compare against.
6165
+ * Returns a memoized version of `fn`: results are cached for `ttlMs` milliseconds.
6166
+ * After this delay, the next call triggers a fresh execution.
4533
6167
  *
4534
- * @example
4535
- * if (__sys__.__env__.is("canary")) {
4536
- * featureFlags.enableAll();
4537
- * }
6168
+ * If multiple identical calls arrive simultaneously (while the promise is pending),
6169
+ * they share the same promise — avoiding "thundering herd" on cold caches.
6170
+ *
6171
+ * @param fn - Asynchronous function to memoize.
6172
+ * @param ttlMs - Cache entry TTL (ms). `0` = no expiration.
6173
+ * @param keyFn - Serialization function for arguments into cache keys.
6174
+ * @default `JSON.stringify`
6175
+ * @returns Memoized version of `fn` with `.clear()` method.
4538
6176
  */
4539
- is(envName: string): boolean;
6177
+ memoize<TArgs extends any[], TResult>(fn: (...args: TArgs) => Promise<TResult>, ttlMs?: number, keyFn?: (...args: TArgs) => string): ((...args: TArgs) => Promise<TResult>) & {
6178
+ clear: () => void;
6179
+ };
4540
6180
  /**
4541
- * Retrieves the OS-level username of the current process owner by invoking
4542
- * the XHSC native Go binary.
6181
+ * ## Sequential Queue
4543
6182
  *
4544
- * This method is synchronous and blocks until the native call completes.
4545
- * Do not call it in request hot paths. Returns `""` on failure so callers
4546
- * can safely use the result without null checks.
6183
+ * Guarantees that tasks are executed **one by one, in the order they were added**.
6184
+ * Tasks submitted while another is pending are queued and executed sequentially.
4547
6185
  *
4548
- * @returns The current OS username, or `""` on failure.
6186
+ * Unlike `pool(items, fn, 1)`, `queue` allows adding tasks dynamically over time.
4549
6187
  *
4550
- * @example
4551
- * const actor = __sys__.__env__.user() || "<unknown>";
4552
- * auditLog.write({ actor, action: "deploy" });
6188
+ * @returns An object `{ add, size }`:
6189
+ * - `add(fn)` Enqueues a task and returns a promise for its result.
6190
+ * - `size` Getter for the current number of pending tasks.
6191
+ *
6192
+ * @example Critical Database Mutation
6193
+ * ```ts
6194
+ * const db = utils.queue();
6195
+ *
6196
+ * async function transfer(from: string, to: string, amount: number) {
6197
+ * return db.add(async () => {
6198
+ * const balance = await getBalance(from);
6199
+ * if (balance < amount) throw new Error("Insufficient funds");
6200
+ * await debit(from, amount);
6201
+ * await credit(to, amount);
6202
+ * });
6203
+ * }
6204
+ * ```
4553
6205
  */
4554
- user(): string;
6206
+ queue(): {
6207
+ add: <T>(fn: () => Promise<T>) => Promise<T>;
6208
+ readonly size: number;
6209
+ };
4555
6210
  /**
4556
- * Returns the internal store, throwing {@link EnvStoreError} if it has not
4557
- * yet been initialised.
6211
+ * ## Once Guaranteed Single Execution
4558
6212
  *
4559
- * SECURITY: This is the single point of store access. Every read and write
4560
- * method must go through here never access `globalThis[XY_ENV_STORE_KEY]`
4561
- * directly outside this method.
6213
+ * Returns a version of `fn` that executes only **once**, regardless of how
6214
+ * many calls are made. Subsequent calls receive the cached promise or value
6215
+ * without re-executing `fn`.
4562
6216
  *
4563
- * Eliminating the `?? process.env` fallback is intentional. A silent
4564
- * fallback to `process.env` during the bootstrap race window would bypass
4565
- * the Shield and leak values without any warning. A thrown error is
4566
- * immediately visible during development and integration testing.
6217
+ * Particularly useful for expensive initializations (DB connections, config loading).
4567
6218
  *
4568
- * @internal
4569
- * @throws {EnvStoreError}
6219
+ * @param fn - The function to execute exactly once.
6220
+ * @returns A function that always returns the same resolved promise.
4570
6221
  */
4571
- private requireStoreMap;
4572
- private getStoreForCaller;
6222
+ once<TArgs extends any[], TResult>(fn: (...args: TArgs) => Promise<TResult>): (...args: TArgs) => Promise<TResult>;
4573
6223
  /**
4574
- * Asserts that `key` is a valid environment variable name.
6224
+ * ## Conditional Polling
4575
6225
  *
4576
- * @internal
4577
- * @throws {EnvKeyError}
6226
+ * Repeatedly polls `fn` until `predicate` returns `true` or a signal is aborted.
6227
+ *
6228
+ * @param fn - Asynchronous function returning value to test.
6229
+ * @param predicate - Success condition for the returned value.
6230
+ * @param interval - Delay between attempts (ms). @default 1000
6231
+ * @param signal - `AbortSignal` to stop polling.
6232
+ * @returns The value for which `predicate` returned `true`.
6233
+ * @throws `DOMException("AbortError")` if signal is aborted before success.
4578
6234
  */
4579
- private validateKey;
6235
+ poll<T>(fn: () => Promise<T>, predicate: (value: T) => boolean, interval?: number, signal?: AbortSignal): Promise<T>;
6236
+ }
6237
+
6238
+ /**
6239
+ * **ValidationUtils — XyPriss Validation Utilities**
6240
+ */
6241
+ declare class ValidationUtils {
4580
6242
  /**
4581
- * Asserts that `value` does not contain characters that can corrupt
4582
- * downstream parsers, log sinks, or HTTP serialisers.
6243
+ * **email**
4583
6244
  *
4584
- * Rejected characters:
4585
- * - CR (`\r`) and LF (`\n`) — break line-oriented `.env` parsers and
4586
- * enable log injection attacks.
4587
- * - NUL (`\0`) — truncates strings in C-based runtimes and can bypass
4588
- * suffix-based extension checks in some file path handling code.
6245
+ * Performs semantic validation on an email address string.
4589
6246
  *
4590
- * @internal
4591
- * @throws {EnvKeyError}
6247
+ * @param email The email string to validate.
6248
+ * @returns `true` if valid, `false` otherwise.
4592
6249
  */
4593
- private validateValue;
6250
+ email(email: string): boolean;
4594
6251
  /**
4595
- * **Environment Security Shield**
6252
+ * **url**
4596
6253
  *
4597
- * Replaces the `process.env` object with a hardened Proxy that enforces
4598
- * the following policies on every property access:
4599
- *
4600
- * **Read trap**
4601
- * - Whitelisted keys (see {@link EnvApi.whitelistedFields}) and keys
4602
- * matching the prefixes `XY_`, `XYPRISS_`, `ENC_`, `DOTENV_`, or `__`
4603
- * pass through to the real value.
4604
- * - All other reads return `undefined`. A one-time per-key warning is
4605
- * written to `process.stderr` (suppressed when
4606
- * `XYPRISS_ENV_SHIELD=silent`).
6254
+ * Validates a URL string using the `strulink` RFC-compliant URI parser.
4607
6255
  *
4608
- * **`ownKeys` and `has` traps**
4609
- * - Restrict the apparent key set to the whitelist. This prevents
4610
- * third-party code from enumerating the real store through
4611
- * `Object.keys(process.env)`, `JSON.stringify(process.env)`, or spread
4612
- * operators — all of which bypass the `get` trap.
6256
+ * @param url The URL string to validate.
6257
+ * @returns `true` if valid, `false` otherwise.
6258
+ */
6259
+ url(url: string | URL): boolean;
6260
+ /**
6261
+ * **nullish**
4613
6262
  *
4614
- * The descriptor is applied with `writable: false` to prevent replacement
4615
- * by application code, and `configurable: true` to allow test teardown.
6263
+ * A type guard that determines if a value is either `null` or `undefined`.
4616
6264
  *
4617
- * @internal
6265
+ * @param value The value to check.
6266
+ * @returns `true` if null or undefined.
4618
6267
  */
6268
+ nullish(value: unknown): value is null | undefined;
6269
+ }
6270
+
6271
+ /**
6272
+ * **IdUtils — Identity Primitives**
6273
+ */
6274
+ declare class IdUtils {
4619
6275
  /**
4620
- * **Environment Security Shield**
4621
- *
4622
- * Replaces the `process.env` object with a hardened Proxy that enforces
4623
- * the following policies on every property access:
6276
+ * **uuid**
4624
6277
  *
4625
- * **Read trap**
4626
- * - Whitelisted keys (see {@link EnvApi.whitelistedFields}) and keys
4627
- * matching the prefixes `XY_`, `XYPRISS_`, `ENC_`, `DOTENV_`, or `__`
4628
- * pass through to the real value.
4629
- * - All other reads return `undefined`. A one-time per-key warning is
4630
- * written to `process.stderr` (suppressed when
4631
- * `XYPRISS_ENV_SHIELD=silent`).
6278
+ * Generates a RFC-compliant UUID v4 using the `nehoid` engine.
4632
6279
  *
4633
- * **`ownKeys` and `has` traps**
4634
- * - Restrict the apparent key set to the whitelist. This prevents
4635
- * third-party code from enumerating the real store through
4636
- * `Object.keys(process.env)`, `JSON.stringify(process.env)`, or spread
4637
- * operators — all of which bypass the `get` trap.
6280
+ * @returns A random UUID string.
6281
+ */
6282
+ uuid(): string;
6283
+ }
6284
+
6285
+ /**
6286
+ * **FunctionUtils — Functional Programming Helpers**
6287
+ */
6288
+ declare class FunctionUtils {
6289
+ /**
6290
+ * **memo**
4638
6291
  *
4639
- * The descriptor is applied with `writable: false` to prevent replacement
4640
- * by application code, and `configurable: true` to allow test teardown.
6292
+ * Returns a memoized version of a function that caches its results based on input parameters.
4641
6293
  *
4642
- * @internal
6294
+ * @param fn The function to memoize.
6295
+ * @returns The memoized function.
4643
6296
  */
4644
- private applyShield;
4645
- private isCallerProjectCode;
6297
+ memo<T extends (...args: any[]) => any>(fn: T): T;
6298
+ }
6299
+
6300
+ /**
6301
+ * **UtilsApi — XyPriss System Utility Module**
6302
+ *
6303
+ * A comprehensive, high-performance utility class for application development.
6304
+ * Utilities are grouped into specialized categories for better modularity.
6305
+ *
6306
+ * Exposed via `__sys__.utils`.
6307
+ *
6308
+ * @example
6309
+ * ```ts
6310
+ * __sys__.utils.num.formatBytes(1048576); // "1 MB"
6311
+ * __sys__.utils.is.email("test@example.com"); // true
6312
+ * __sys__.utils.id.uuid(); // "550e8400-e29b-41d4-a716-446655440000"
6313
+ * ```
6314
+ */
6315
+ declare class UtilsApi {
6316
+ /** **String Utilities** (`slugify`, `truncate`, `randomString`, etc.) */
6317
+ readonly str: StringUtils;
6318
+ /** **Number & Math Utilities** (`clamp`, `lerp`, `formatBytes`, etc.) */
6319
+ readonly num: NumberUtils;
6320
+ /** **Date & Time Utilities** (`formatDuration`, `timeAgo`, etc.) */
6321
+ readonly date: DateUtils;
6322
+ /** **Object Utilities** (`deepClone`, `parse`, `pick`, etc.) */
6323
+ readonly obj: ObjectUtils;
6324
+ /** **Array Utilities** (`chunk`, `unique`, `groupBy`, etc.) */
6325
+ readonly arr: ArrayUtils;
6326
+ /** **Async & Control Flow Utilities** (`sleep`, `retry`, `debounce`, etc.) */
6327
+ readonly async: AsyncUtils;
6328
+ /** **Validation Utilities** (`email`, `url`, `nullish`) */
6329
+ readonly is: ValidationUtils;
6330
+ /** **Identity Utilities** (`uuid`) */
6331
+ readonly id: IdUtils;
6332
+ /** **Functional Utilities** (`memo`) */
6333
+ readonly fn: FunctionUtils;
4646
6334
  }
4647
6335
 
4648
6336
  /**
@@ -4669,6 +6357,7 @@ declare class XyPrissFS {
4669
6357
  fs: FSApi;
4670
6358
  path: PathApi;
4671
6359
  os: OSApi;
6360
+ utils: UtilsApi;
4672
6361
  protected _internalRoot: string;
4673
6362
  /**
4674
6363
  * **Project Root Path**
@@ -7321,6 +9010,12 @@ declare class XemsRunner {
7321
9010
  /**
7322
9011
  * Enables hardware-bound persistent storage for XEMS.
7323
9012
  */
9013
+ private static runnersByPath;
9014
+ /**
9015
+ * Internal factory for getting or creating a runner for a specific path.
9016
+ * This ensures only one process exists for a given file in the entire process.
9017
+ */
9018
+ static getInstance(pathStr: string, options?: XemsOptions): XemsRunner;
7324
9019
  enablePersistence(pathStr: string, secret: string, resources?: {
7325
9020
  cacheSize?: number;
7326
9021
  }): void;
@@ -8217,63 +9912,6 @@ declare class MultiServerApp implements XyPrissApp {
8217
9912
  getOptimizerStats(): any;
8218
9913
  }
8219
9914
 
8220
- /**
8221
- * Safe JSON Middleware for Express
8222
- * Automatically handles circular references in JSON responses
8223
- */
8224
-
8225
- interface SafeJsonOptions {
8226
- /**
8227
- * Enable safe JSON serialization for all responses
8228
- * @default true
8229
- */
8230
- enabled?: boolean;
8231
- /**
8232
- * Maximum depth for object serialization
8233
- * @default 10
8234
- */
8235
- maxDepth?: number;
8236
- /**
8237
- * Maximum string length before truncation
8238
- * @default 1000
8239
- */
8240
- truncateStrings?: number;
8241
- /**
8242
- * Include non-enumerable properties
8243
- * @default false
8244
- */
8245
- includeNonEnumerable?: boolean;
8246
- /**
8247
- * Log when circular references are detected
8248
- * @default false
8249
- */
8250
- logCircularRefs?: boolean;
8251
- /**
8252
- * Custom replacer function for additional handling
8253
- */
8254
- customReplacer?: (key: string, value: any) => any;
8255
- }
8256
- /**
8257
- * Creates middleware that safely handles JSON serialization
8258
- */
8259
- declare function createSafeJsonMiddleware(options?: SafeJsonOptions): (req: XyPrisRequest, res: XyPrisResponse, next: NextFunction) => void;
8260
- /**
8261
- * Quick setup function for common use cases
8262
- */
8263
- declare function setupSafeJson(app: any, options?: SafeJsonOptions): void;
8264
- /**
8265
- * Utility function to safely stringify any object
8266
- */
8267
- declare function safeJsonStringify(obj: any, options?: SafeJsonOptions): string;
8268
- /**
8269
- * Enhanced res.json replacement that can be used manually
8270
- */
8271
- declare function sendSafeJson(res: XyPrisResponse, obj: any, options?: SafeJsonOptions): void;
8272
- /**
8273
- * Middleware specifically for debugging circular references
8274
- */
8275
- declare function createCircularRefDebugger(): (req: XyPrisRequest, res: XyPrisResponse, next: NextFunction) => void;
8276
-
8277
9915
  /***************************************************************************
8278
9916
  * XyPrissJS - Fast And Secure
8279
9917
  *
@@ -8978,5 +10616,5 @@ declare const getMimes: (extensions?: string | string[]) => string[];
8978
10616
  */
8979
10617
  declare function Router(): XyPrissRouter;
8980
10618
 
8981
- export { ConfigurationManager as CM, ConfigurationManager as Configs, FileUploadAPI as FLA, FileUploadAPI, Plugin, PluginHookIds, Router, SecurityMiddleware, Upload, XJsonResponseHandler, XyGuard, MultiServerApp as XyPMS, XyPrissRouter, XyPrissXHSC, __cfg__, __const__, __sys__, createCircularRefDebugger, createOptimalCache, createSafeJsonMiddleware, createServer, getCallerProjectRoot, getIp, getMime, getMimes, identifyProjectRoot, initializeFileUpload, mergeWithDefaults, mergeWithDefaults as mwdef, quickServer, safeJsonStringify, sendSafeJson, setupSafeJson, uploadAny, uploadArray, uploadFields, uploadSingle, xems };
10619
+ export { ConfigurationManager as CM, ConfigurationManager as Configs, FileUploadAPI as FLA, FileUploadAPI, Plugin, PluginHookIds, Router, SecurityMiddleware, Upload, XJsonResponseHandler, XyGuard, MultiServerApp as XyPMS, XyPrissRouter, XyPrissXHSC, __cfg__, __const__, __sys__, createOptimalCache, createServer, getCallerProjectRoot, getIp, getMime, getMimes, identifyProjectRoot, initializeFileUpload, mergeWithDefaults, mergeWithDefaults as mwdef, quickServer, uploadAny, uploadArray, uploadFields, uploadSingle, xems };
8982
10620
  export type { ArchiveOptions, BatchRenameChange, CacheConfig, FileUploadConfig as FiUpConfig, FileUploadConfig, GetIpResult, IpSource, MonitorSnapshot, MultiServerConfig, NetworkStats, NextFunction, PerformanceConfig, PluginCreator, ProcessInfo, ProcessMonitorSnapshot, XyPrisRequest as Request, RequestHandler, XyPrisResponse as Response, RoutRateLimit, RouteConfig, RouteGuard, RouteMeta, RouteOptions, ParamType as RouteParamType, SecurityConfig, ServerOptions$1 as ServerOptions, XyPrisRequest$1 as XRequest, XyPrisResponse$1 as XResponse, XemsTypes, XyPrisRequest$1 as XyPrisRequest, XyPrisResponse$1 as XyPrisResponse, XyPrissApp, XyPrissPlugin };