promidas 2.0.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 (295) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/dist/builder.d.ts +158 -0
  4. package/dist/builder.d.ts.map +1 -0
  5. package/dist/builder.js +255 -0
  6. package/dist/builder.js.map +1 -0
  7. package/dist/factory.d.ts +154 -0
  8. package/dist/factory.d.ts.map +1 -0
  9. package/dist/factory.js +243 -0
  10. package/dist/factory.js.map +1 -0
  11. package/dist/fetcher/client/config.d.ts +140 -0
  12. package/dist/fetcher/client/config.d.ts.map +1 -0
  13. package/dist/fetcher/client/config.js +2 -0
  14. package/dist/fetcher/client/config.js.map +1 -0
  15. package/dist/fetcher/client/fetch-with-progress.d.ts +156 -0
  16. package/dist/fetcher/client/fetch-with-progress.d.ts.map +1 -0
  17. package/dist/fetcher/client/fetch-with-progress.js +313 -0
  18. package/dist/fetcher/client/fetch-with-progress.js.map +1 -0
  19. package/dist/fetcher/client/fetch-with-timeout.d.ts +6 -0
  20. package/dist/fetcher/client/fetch-with-timeout.d.ts.map +1 -0
  21. package/dist/fetcher/client/fetch-with-timeout.js +48 -0
  22. package/dist/fetcher/client/fetch-with-timeout.js.map +1 -0
  23. package/dist/fetcher/client/protopedia-api-custom-client.d.ts +141 -0
  24. package/dist/fetcher/client/protopedia-api-custom-client.d.ts.map +1 -0
  25. package/dist/fetcher/client/protopedia-api-custom-client.js +268 -0
  26. package/dist/fetcher/client/protopedia-api-custom-client.js.map +1 -0
  27. package/dist/fetcher/client/select-custom-fetch.d.ts +58 -0
  28. package/dist/fetcher/client/select-custom-fetch.d.ts.map +1 -0
  29. package/dist/fetcher/client/select-custom-fetch.js +58 -0
  30. package/dist/fetcher/client/select-custom-fetch.js.map +1 -0
  31. package/dist/fetcher/errors/fetcher-error.d.ts +10 -0
  32. package/dist/fetcher/errors/fetcher-error.d.ts.map +1 -0
  33. package/dist/fetcher/errors/fetcher-error.js +15 -0
  34. package/dist/fetcher/errors/fetcher-error.js.map +1 -0
  35. package/dist/fetcher/index.d.ts +73 -0
  36. package/dist/fetcher/index.d.ts.map +1 -0
  37. package/dist/fetcher/index.js +70 -0
  38. package/dist/fetcher/index.js.map +1 -0
  39. package/dist/fetcher/types/index.d.ts +9 -0
  40. package/dist/fetcher/types/index.d.ts.map +1 -0
  41. package/dist/fetcher/types/index.js +7 -0
  42. package/dist/fetcher/types/index.js.map +1 -0
  43. package/dist/fetcher/types/progress-event.types.d.ts +221 -0
  44. package/dist/fetcher/types/progress-event.types.d.ts.map +1 -0
  45. package/dist/fetcher/types/progress-event.types.js +10 -0
  46. package/dist/fetcher/types/progress-event.types.js.map +1 -0
  47. package/dist/fetcher/types/prototype-api.types.d.ts +106 -0
  48. package/dist/fetcher/types/prototype-api.types.d.ts.map +1 -0
  49. package/dist/fetcher/types/prototype-api.types.js +2 -0
  50. package/dist/fetcher/types/prototype-api.types.js.map +1 -0
  51. package/dist/fetcher/types/result.types.d.ts +75 -0
  52. package/dist/fetcher/types/result.types.d.ts.map +1 -0
  53. package/dist/fetcher/types/result.types.js +2 -0
  54. package/dist/fetcher/types/result.types.js.map +1 -0
  55. package/dist/fetcher/utils/create-client-fetch.d.ts +63 -0
  56. package/dist/fetcher/utils/create-client-fetch.d.ts.map +1 -0
  57. package/dist/fetcher/utils/create-client-fetch.js +89 -0
  58. package/dist/fetcher/utils/create-client-fetch.js.map +1 -0
  59. package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts +6 -0
  60. package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts.map +1 -0
  61. package/dist/fetcher/utils/create-fetch-with-stripped-headers.js +40 -0
  62. package/dist/fetcher/utils/create-fetch-with-stripped-headers.js.map +1 -0
  63. package/dist/fetcher/utils/errors/handler.d.ts +58 -0
  64. package/dist/fetcher/utils/errors/handler.d.ts.map +1 -0
  65. package/dist/fetcher/utils/errors/handler.js +243 -0
  66. package/dist/fetcher/utils/errors/handler.js.map +1 -0
  67. package/dist/fetcher/utils/errors/messages.d.ts +75 -0
  68. package/dist/fetcher/utils/errors/messages.d.ts.map +1 -0
  69. package/dist/fetcher/utils/errors/messages.js +88 -0
  70. package/dist/fetcher/utils/errors/messages.js.map +1 -0
  71. package/dist/fetcher/utils/index.d.ts +13 -0
  72. package/dist/fetcher/utils/index.d.ts.map +1 -0
  73. package/dist/fetcher/utils/index.js +12 -0
  74. package/dist/fetcher/utils/index.js.map +1 -0
  75. package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts +10 -0
  76. package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts.map +1 -0
  77. package/dist/fetcher/utils/log-timestamp-normalization-warnings.js +32 -0
  78. package/dist/fetcher/utils/log-timestamp-normalization-warnings.js.map +1 -0
  79. package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts +59 -0
  80. package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts.map +1 -0
  81. package/dist/fetcher/utils/normalize-protopedia-timestamp.js +81 -0
  82. package/dist/fetcher/utils/normalize-protopedia-timestamp.js.map +1 -0
  83. package/dist/fetcher/utils/normalize-prototype.d.ts +56 -0
  84. package/dist/fetcher/utils/normalize-prototype.d.ts.map +1 -0
  85. package/dist/fetcher/utils/normalize-prototype.js +113 -0
  86. package/dist/fetcher/utils/normalize-prototype.js.map +1 -0
  87. package/dist/fetcher/utils/sanitize-options.d.ts +14 -0
  88. package/dist/fetcher/utils/sanitize-options.d.ts.map +1 -0
  89. package/dist/fetcher/utils/sanitize-options.js +16 -0
  90. package/dist/fetcher/utils/sanitize-options.js.map +1 -0
  91. package/dist/fetcher/utils/string-parsers.d.ts +45 -0
  92. package/dist/fetcher/utils/string-parsers.d.ts.map +1 -0
  93. package/dist/fetcher/utils/string-parsers.js +53 -0
  94. package/dist/fetcher/utils/string-parsers.js.map +1 -0
  95. package/dist/index.d.ts +66 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +70 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/logger/console-logger.d.ts +74 -0
  100. package/dist/logger/console-logger.d.ts.map +1 -0
  101. package/dist/logger/console-logger.js +113 -0
  102. package/dist/logger/console-logger.js.map +1 -0
  103. package/dist/logger/factory.d.ts +88 -0
  104. package/dist/logger/factory.d.ts.map +1 -0
  105. package/dist/logger/factory.js +94 -0
  106. package/dist/logger/factory.js.map +1 -0
  107. package/dist/logger/index.d.ts +42 -0
  108. package/dist/logger/index.d.ts.map +1 -0
  109. package/dist/logger/index.js +41 -0
  110. package/dist/logger/index.js.map +1 -0
  111. package/dist/logger/logger.types.d.ts +49 -0
  112. package/dist/logger/logger.types.d.ts.map +1 -0
  113. package/dist/logger/logger.types.js +2 -0
  114. package/dist/logger/logger.types.js.map +1 -0
  115. package/dist/repository/errors/validation-error.d.ts +24 -0
  116. package/dist/repository/errors/validation-error.d.ts.map +1 -0
  117. package/dist/repository/errors/validation-error.js +26 -0
  118. package/dist/repository/errors/validation-error.js.map +1 -0
  119. package/dist/repository/index.d.ts +122 -0
  120. package/dist/repository/index.d.ts.map +1 -0
  121. package/dist/repository/index.js +44 -0
  122. package/dist/repository/index.js.map +1 -0
  123. package/dist/repository/protopedia-in-memory-repository.d.ts +560 -0
  124. package/dist/repository/protopedia-in-memory-repository.d.ts.map +1 -0
  125. package/dist/repository/protopedia-in-memory-repository.js +929 -0
  126. package/dist/repository/protopedia-in-memory-repository.js.map +1 -0
  127. package/dist/repository/schemas/index.d.ts +9 -0
  128. package/dist/repository/schemas/index.d.ts.map +1 -0
  129. package/dist/repository/schemas/index.js +11 -0
  130. package/dist/repository/schemas/index.js.map +1 -0
  131. package/dist/repository/schemas/params.d.ts +44 -0
  132. package/dist/repository/schemas/params.d.ts.map +1 -0
  133. package/dist/repository/schemas/params.js +44 -0
  134. package/dist/repository/schemas/params.js.map +1 -0
  135. package/dist/repository/schemas/serializable-snapshot.d.ts +33 -0
  136. package/dist/repository/schemas/serializable-snapshot.d.ts.map +1 -0
  137. package/dist/repository/schemas/serializable-snapshot.js +45 -0
  138. package/dist/repository/schemas/serializable-snapshot.js.map +1 -0
  139. package/dist/repository/types/analysis.types.d.ts +89 -0
  140. package/dist/repository/types/analysis.types.d.ts.map +1 -0
  141. package/dist/repository/types/analysis.types.js +2 -0
  142. package/dist/repository/types/analysis.types.js.map +1 -0
  143. package/dist/repository/types/index.d.ts +12 -0
  144. package/dist/repository/types/index.d.ts.map +1 -0
  145. package/dist/repository/types/index.js +7 -0
  146. package/dist/repository/types/index.js.map +1 -0
  147. package/dist/repository/types/repository-events.types.d.ts +110 -0
  148. package/dist/repository/types/repository-events.types.d.ts.map +1 -0
  149. package/dist/repository/types/repository-events.types.js +2 -0
  150. package/dist/repository/types/repository-events.types.js.map +1 -0
  151. package/dist/repository/types/repository.types.d.ts +330 -0
  152. package/dist/repository/types/repository.types.d.ts.map +1 -0
  153. package/dist/repository/types/repository.types.js +2 -0
  154. package/dist/repository/types/repository.types.js.map +1 -0
  155. package/dist/repository/types/result.types.d.ts +55 -0
  156. package/dist/repository/types/result.types.d.ts.map +1 -0
  157. package/dist/repository/types/result.types.js +2 -0
  158. package/dist/repository/types/result.types.js.map +1 -0
  159. package/dist/repository/types/serialization.types.d.ts +61 -0
  160. package/dist/repository/types/serialization.types.d.ts.map +1 -0
  161. package/dist/repository/types/serialization.types.js +2 -0
  162. package/dist/repository/types/serialization.types.js.map +1 -0
  163. package/dist/repository/types/snapshot-operation.types.d.ts +140 -0
  164. package/dist/repository/types/snapshot-operation.types.d.ts.map +1 -0
  165. package/dist/repository/types/snapshot-operation.types.js +2 -0
  166. package/dist/repository/types/snapshot-operation.types.js.map +1 -0
  167. package/dist/repository/utils/convert-fetch-result.d.ts +46 -0
  168. package/dist/repository/utils/convert-fetch-result.d.ts.map +1 -0
  169. package/dist/repository/utils/convert-fetch-result.js +59 -0
  170. package/dist/repository/utils/convert-fetch-result.js.map +1 -0
  171. package/dist/repository/utils/convert-store-result.d.ts +36 -0
  172. package/dist/repository/utils/convert-store-result.d.ts.map +1 -0
  173. package/dist/repository/utils/convert-store-result.js +36 -0
  174. package/dist/repository/utils/convert-store-result.js.map +1 -0
  175. package/dist/repository/utils/emit-repository-event-safely.d.ts +5 -0
  176. package/dist/repository/utils/emit-repository-event-safely.d.ts.map +1 -0
  177. package/dist/repository/utils/emit-repository-event-safely.js +17 -0
  178. package/dist/repository/utils/emit-repository-event-safely.js.map +1 -0
  179. package/dist/repository/utils/index.d.ts +3 -0
  180. package/dist/repository/utils/index.d.ts.map +1 -0
  181. package/dist/repository/utils/index.js +3 -0
  182. package/dist/repository/utils/index.js.map +1 -0
  183. package/dist/repository/validation/index.d.ts +9 -0
  184. package/dist/repository/validation/index.d.ts.map +1 -0
  185. package/dist/repository/validation/index.js +10 -0
  186. package/dist/repository/validation/index.js.map +1 -0
  187. package/dist/repository/validation/params-validators.d.ts +46 -0
  188. package/dist/repository/validation/params-validators.d.ts.map +1 -0
  189. package/dist/repository/validation/params-validators.js +68 -0
  190. package/dist/repository/validation/params-validators.js.map +1 -0
  191. package/dist/repository/validation/serializable-snapshot.d.ts +47 -0
  192. package/dist/repository/validation/serializable-snapshot.d.ts.map +1 -0
  193. package/dist/repository/validation/serializable-snapshot.js +104 -0
  194. package/dist/repository/validation/serializable-snapshot.js.map +1 -0
  195. package/dist/schemas/index.d.ts +8 -0
  196. package/dist/schemas/index.d.ts.map +1 -0
  197. package/dist/schemas/index.js +8 -0
  198. package/dist/schemas/index.js.map +1 -0
  199. package/dist/schemas/normalized-prototype.d.ts +56 -0
  200. package/dist/schemas/normalized-prototype.d.ts.map +1 -0
  201. package/dist/schemas/normalized-prototype.js +123 -0
  202. package/dist/schemas/normalized-prototype.js.map +1 -0
  203. package/dist/store/errors/store-error.d.ts +148 -0
  204. package/dist/store/errors/store-error.d.ts.map +1 -0
  205. package/dist/store/errors/store-error.js +156 -0
  206. package/dist/store/errors/store-error.js.map +1 -0
  207. package/dist/store/index.d.ts +84 -0
  208. package/dist/store/index.d.ts.map +1 -0
  209. package/dist/store/index.js +83 -0
  210. package/dist/store/index.js.map +1 -0
  211. package/dist/store/store.d.ts +295 -0
  212. package/dist/store/store.d.ts.map +1 -0
  213. package/dist/store/store.js +411 -0
  214. package/dist/store/store.js.map +1 -0
  215. package/dist/store/types/index.d.ts +2 -0
  216. package/dist/store/types/index.d.ts.map +1 -0
  217. package/dist/store/types/index.js +2 -0
  218. package/dist/store/types/index.js.map +1 -0
  219. package/dist/store/types/result.types.d.ts +67 -0
  220. package/dist/store/types/result.types.d.ts.map +1 -0
  221. package/dist/store/types/result.types.js +2 -0
  222. package/dist/store/types/result.types.js.map +1 -0
  223. package/dist/types/codes.d.ts +44 -0
  224. package/dist/types/codes.d.ts.map +1 -0
  225. package/dist/types/codes.js +9 -0
  226. package/dist/types/codes.js.map +1 -0
  227. package/dist/types/index.d.ts +61 -0
  228. package/dist/types/index.d.ts.map +1 -0
  229. package/dist/types/index.js +60 -0
  230. package/dist/types/index.js.map +1 -0
  231. package/dist/types/normalized-prototype.d.ts +95 -0
  232. package/dist/types/normalized-prototype.d.ts.map +1 -0
  233. package/dist/types/normalized-prototype.js +2 -0
  234. package/dist/types/normalized-prototype.js.map +1 -0
  235. package/dist/utils/converters/index.d.ts +15 -0
  236. package/dist/utils/converters/index.d.ts.map +1 -0
  237. package/dist/utils/converters/index.js +15 -0
  238. package/dist/utils/converters/index.js.map +1 -0
  239. package/dist/utils/converters/license-type.d.ts +23 -0
  240. package/dist/utils/converters/license-type.d.ts.map +1 -0
  241. package/dist/utils/converters/license-type.js +38 -0
  242. package/dist/utils/converters/license-type.js.map +1 -0
  243. package/dist/utils/converters/release-flag.d.ts +24 -0
  244. package/dist/utils/converters/release-flag.d.ts.map +1 -0
  245. package/dist/utils/converters/release-flag.js +40 -0
  246. package/dist/utils/converters/release-flag.js.map +1 -0
  247. package/dist/utils/converters/status.d.ts +23 -0
  248. package/dist/utils/converters/status.d.ts.map +1 -0
  249. package/dist/utils/converters/status.js +40 -0
  250. package/dist/utils/converters/status.js.map +1 -0
  251. package/dist/utils/converters/thanks-flag.d.ts +25 -0
  252. package/dist/utils/converters/thanks-flag.d.ts.map +1 -0
  253. package/dist/utils/converters/thanks-flag.js +41 -0
  254. package/dist/utils/converters/thanks-flag.js.map +1 -0
  255. package/dist/utils/deep-merge.d.ts +38 -0
  256. package/dist/utils/deep-merge.d.ts.map +1 -0
  257. package/dist/utils/deep-merge.js +85 -0
  258. package/dist/utils/deep-merge.js.map +1 -0
  259. package/dist/utils/index.d.ts +80 -0
  260. package/dist/utils/index.d.ts.map +1 -0
  261. package/dist/utils/index.js +85 -0
  262. package/dist/utils/index.js.map +1 -0
  263. package/dist/utils/logger-utils.d.ts +100 -0
  264. package/dist/utils/logger-utils.d.ts.map +1 -0
  265. package/dist/utils/logger-utils.js +265 -0
  266. package/dist/utils/logger-utils.js.map +1 -0
  267. package/dist/utils/time/constants.d.ts +14 -0
  268. package/dist/utils/time/constants.d.ts.map +1 -0
  269. package/dist/utils/time/constants.js +14 -0
  270. package/dist/utils/time/constants.js.map +1 -0
  271. package/dist/utils/time/index.d.ts +28 -0
  272. package/dist/utils/time/index.d.ts.map +1 -0
  273. package/dist/utils/time/index.js +28 -0
  274. package/dist/utils/time/index.js.map +1 -0
  275. package/dist/utils/time/parser.d.ts +91 -0
  276. package/dist/utils/time/parser.d.ts.map +1 -0
  277. package/dist/utils/time/parser.js +143 -0
  278. package/dist/utils/time/parser.js.map +1 -0
  279. package/dist/utils/validation/index.d.ts +8 -0
  280. package/dist/utils/validation/index.d.ts.map +1 -0
  281. package/dist/utils/validation/index.js +7 -0
  282. package/dist/utils/validation/index.js.map +1 -0
  283. package/dist/utils/validation/normalized-prototype.d.ts +64 -0
  284. package/dist/utils/validation/normalized-prototype.d.ts.map +1 -0
  285. package/dist/utils/validation/normalized-prototype.js +97 -0
  286. package/dist/utils/validation/normalized-prototype.js.map +1 -0
  287. package/dist/utils/validation/types.d.ts +62 -0
  288. package/dist/utils/validation/types.d.ts.map +1 -0
  289. package/dist/utils/validation/types.js +8 -0
  290. package/dist/utils/validation/types.js.map +1 -0
  291. package/dist/version.d.ts +6 -0
  292. package/dist/version.d.ts.map +1 -0
  293. package/dist/version.js +6 -0
  294. package/dist/version.js.map +1 -0
  295. package/package.json +138 -0
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Custom fetch function factory with download progress tracking.
3
+ *
4
+ * This module provides a factory function that creates a custom fetch wrapper
5
+ * which monitors the complete request lifecycle and provides event-based
6
+ * progress tracking for UI updates and logging.
7
+ *
8
+ * @module
9
+ */
10
+ import type { Logger } from '../../logger/index.js';
11
+ import type { FetchProgressEvent } from '../types/progress-event.types.js';
12
+ /**
13
+ * Check if the logger should output progress logs based on its current level.
14
+ *
15
+ * This function is used to control direct stderr output (process.stderr.write)
16
+ * which bypasses the logger's internal level filtering. For logger.info() calls,
17
+ * the logger itself handles level filtering.
18
+ *
19
+ * @param logger - Logger instance to check
20
+ * @returns true if progress logs should be output, false otherwise
21
+ *
22
+ * @remarks
23
+ * - Used only for process.stderr.write() calls, not for logger.info()
24
+ * - If the logger has a 'level' property, checks if it's 'debug' or 'info'
25
+ * - If no 'level' property exists, assumes logging should be enabled
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const logger = new ConsoleLogger('warn');
30
+ * shouldProgressLog(logger); // false (warn > info)
31
+ *
32
+ * const debugLogger = new ConsoleLogger('debug');
33
+ * shouldProgressLog(debugLogger); // true (debug <= info)
34
+ * ```
35
+ */
36
+ export declare function shouldProgressLog(logger: Logger): boolean;
37
+ /**
38
+ * Configuration for creating a fetch function with progress tracking.
39
+ *
40
+ * @remarks
41
+ * This interface defines all options needed to create a custom fetch wrapper
42
+ * that monitors the complete request lifecycle through event callbacks.
43
+ *
44
+ * @example Basic usage with logging
45
+ * ```typescript
46
+ * const customFetch = createFetchWithProgress({
47
+ * logger: myLogger,
48
+ * enableProgressLog: true,
49
+ * });
50
+ * ```
51
+ *
52
+ * @example With event callback for UI updates
53
+ * ```typescript
54
+ * const customFetch = createFetchWithProgress({
55
+ * logger: myLogger,
56
+ * enableProgressLog: false,
57
+ * onProgressEvent: (event) => {
58
+ * if (event.type === 'download-progress') {
59
+ * updateProgressBar(event.percentage);
60
+ * }
61
+ * },
62
+ * });
63
+ * ```
64
+ */
65
+ export interface FetchWithProgressConfig {
66
+ /**
67
+ * Logger instance for progress output.
68
+ */
69
+ logger: Logger;
70
+ /**
71
+ * Whether to log progress to the logger.
72
+ */
73
+ enableProgressLog: boolean;
74
+ /**
75
+ * Base fetch function to wrap with progress tracking.
76
+ * If not provided, uses global fetch.
77
+ */
78
+ baseFetch?: typeof fetch;
79
+ /**
80
+ * Optional callback for progress events.
81
+ *
82
+ * Receives all lifecycle events:
83
+ * - request-start
84
+ * - response-received
85
+ * - download-progress (throttled to 500ms)
86
+ * - complete
87
+ *
88
+ * @param event - Progress event with type-specific data
89
+ */
90
+ onProgressEvent?: (event: FetchProgressEvent) => void;
91
+ }
92
+ /**
93
+ * Create a custom fetch function with complete lifecycle progress tracking.
94
+ *
95
+ * This factory function creates a fetch wrapper that monitors the entire request
96
+ * lifecycle and provides real-time feedback through event callbacks and/or logging.
97
+ * The returned function is compatible with the standard fetch API signature.
98
+ *
99
+ * @param config - Configuration object containing logger and callback options
100
+ * @returns A fetch-compatible function with progress tracking capabilities
101
+ *
102
+ * @remarks
103
+ * The returned fetch function:
104
+ * - Maintains the same signature as standard fetch
105
+ * - Fires events for all lifecycle phases: request-start, response-received, download-progress, complete
106
+ * - Wraps response body with a ReadableStream that tracks bytes received
107
+ * - Throttles progress updates to 500ms intervals to avoid overhead
108
+ * - Automatically estimates download size based on URL parameters (limit × 2670 bytes)
109
+ * - Works in both Node.js (using process.stderr for live updates) and browser environments
110
+ *
111
+ * Progress tracking behavior:
112
+ * - If `enableProgressLog` is true and logger level is 'debug' or 'info', logs progress messages
113
+ * - If `onProgressEvent` callback is provided, fires events regardless of log level
114
+ * - If neither logging nor callback are enabled, returns response without tracking overhead
115
+ *
116
+ * @example With progress logging
117
+ * ```typescript
118
+ * const customFetch = createFetchWithProgress({
119
+ * logger: myLogger,
120
+ * enableProgressLog: true,
121
+ * });
122
+ *
123
+ * // Use like standard fetch
124
+ * const response = await customFetch('https://api.example.com/data?limit=1000');
125
+ * const data = await response.json();
126
+ * ```
127
+ *
128
+ * @example With custom event handler
129
+ * ```typescript
130
+ * let progressBar: ProgressBar | null = null;
131
+ *
132
+ * const customFetch = createFetchWithProgress({
133
+ * logger: myLogger,
134
+ * enableProgressLog: false,
135
+ * onProgressEvent: (event) => {
136
+ * switch (event.type) {
137
+ * case 'request-start':
138
+ * console.log('Starting request...');
139
+ * break;
140
+ * case 'response-received':
141
+ * progressBar = new ProgressBar({ total: event.estimatedTotal });
142
+ * break;
143
+ * case 'download-progress':
144
+ * progressBar?.update(event.percentage);
145
+ * break;
146
+ * case 'complete':
147
+ * progressBar?.complete();
148
+ * console.log(`Downloaded ${event.received} bytes in ${event.totalTimeMs}ms`);
149
+ * break;
150
+ * }
151
+ * },
152
+ * });
153
+ * ```
154
+ */
155
+ export declare function createFetchWithProgress(config: FetchWithProgressConfig): typeof fetch;
156
+ //# sourceMappingURL=fetch-with-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-with-progress.d.ts","sourceRoot":"","sources":["../../../lib/fetcher/client/fetch-with-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAyCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,KAAK,CAgNd"}
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Custom fetch function factory with download progress tracking.
3
+ *
4
+ * This module provides a factory function that creates a custom fetch wrapper
5
+ * which monitors the complete request lifecycle and provides event-based
6
+ * progress tracking for UI updates and logging.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Check if the logger should output progress logs based on its current level.
12
+ *
13
+ * This function is used to control direct stderr output (process.stderr.write)
14
+ * which bypasses the logger's internal level filtering. For logger.info() calls,
15
+ * the logger itself handles level filtering.
16
+ *
17
+ * @param logger - Logger instance to check
18
+ * @returns true if progress logs should be output, false otherwise
19
+ *
20
+ * @remarks
21
+ * - Used only for process.stderr.write() calls, not for logger.info()
22
+ * - If the logger has a 'level' property, checks if it's 'debug' or 'info'
23
+ * - If no 'level' property exists, assumes logging should be enabled
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const logger = new ConsoleLogger('warn');
28
+ * shouldProgressLog(logger); // false (warn > info)
29
+ *
30
+ * const debugLogger = new ConsoleLogger('debug');
31
+ * shouldProgressLog(debugLogger); // true (debug <= info)
32
+ * ```
33
+ */
34
+ export function shouldProgressLog(logger) {
35
+ if ('level' in logger && typeof logger.level === 'string') {
36
+ const level = logger.level;
37
+ return level === 'debug' || level === 'info';
38
+ }
39
+ return true;
40
+ }
41
+ /**
42
+ * Estimate total response size from URL parameters.
43
+ *
44
+ * Uses empirical data to estimate the total download size based on the
45
+ * limit parameter in the query string.
46
+ *
47
+ * @param url - Request URL
48
+ * @returns Estimated size in bytes and item count (both 0 if cannot estimate)
49
+ */
50
+ function estimateTotalSize(url) {
51
+ try {
52
+ const urlObj = new URL(url);
53
+ const limitParam = urlObj.searchParams.get('limit');
54
+ if (!limitParam) {
55
+ return { estimatedSize: 0, itemCount: 0 };
56
+ }
57
+ const limit = parseInt(limitParam, 10);
58
+ if (isNaN(limit) || limit <= 0) {
59
+ return { estimatedSize: 0, itemCount: 0 };
60
+ }
61
+ // Average prototype size: approximately 2670 bytes per item
62
+ // Based on 5,000 sample data from ProtoPedia API (13,350,369 bytes / 5,000 items)
63
+ const AVERAGE_PROTOTYPE_SIZE = 2670;
64
+ return {
65
+ estimatedSize: limit * AVERAGE_PROTOTYPE_SIZE,
66
+ itemCount: limit,
67
+ };
68
+ }
69
+ catch (error) {
70
+ return { estimatedSize: 0, itemCount: 0 };
71
+ }
72
+ }
73
+ /**
74
+ * Create a custom fetch function with complete lifecycle progress tracking.
75
+ *
76
+ * This factory function creates a fetch wrapper that monitors the entire request
77
+ * lifecycle and provides real-time feedback through event callbacks and/or logging.
78
+ * The returned function is compatible with the standard fetch API signature.
79
+ *
80
+ * @param config - Configuration object containing logger and callback options
81
+ * @returns A fetch-compatible function with progress tracking capabilities
82
+ *
83
+ * @remarks
84
+ * The returned fetch function:
85
+ * - Maintains the same signature as standard fetch
86
+ * - Fires events for all lifecycle phases: request-start, response-received, download-progress, complete
87
+ * - Wraps response body with a ReadableStream that tracks bytes received
88
+ * - Throttles progress updates to 500ms intervals to avoid overhead
89
+ * - Automatically estimates download size based on URL parameters (limit × 2670 bytes)
90
+ * - Works in both Node.js (using process.stderr for live updates) and browser environments
91
+ *
92
+ * Progress tracking behavior:
93
+ * - If `enableProgressLog` is true and logger level is 'debug' or 'info', logs progress messages
94
+ * - If `onProgressEvent` callback is provided, fires events regardless of log level
95
+ * - If neither logging nor callback are enabled, returns response without tracking overhead
96
+ *
97
+ * @example With progress logging
98
+ * ```typescript
99
+ * const customFetch = createFetchWithProgress({
100
+ * logger: myLogger,
101
+ * enableProgressLog: true,
102
+ * });
103
+ *
104
+ * // Use like standard fetch
105
+ * const response = await customFetch('https://api.example.com/data?limit=1000');
106
+ * const data = await response.json();
107
+ * ```
108
+ *
109
+ * @example With custom event handler
110
+ * ```typescript
111
+ * let progressBar: ProgressBar | null = null;
112
+ *
113
+ * const customFetch = createFetchWithProgress({
114
+ * logger: myLogger,
115
+ * enableProgressLog: false,
116
+ * onProgressEvent: (event) => {
117
+ * switch (event.type) {
118
+ * case 'request-start':
119
+ * console.log('Starting request...');
120
+ * break;
121
+ * case 'response-received':
122
+ * progressBar = new ProgressBar({ total: event.estimatedTotal });
123
+ * break;
124
+ * case 'download-progress':
125
+ * progressBar?.update(event.percentage);
126
+ * break;
127
+ * case 'complete':
128
+ * progressBar?.complete();
129
+ * console.log(`Downloaded ${event.received} bytes in ${event.totalTimeMs}ms`);
130
+ * break;
131
+ * }
132
+ * },
133
+ * });
134
+ * ```
135
+ */
136
+ export function createFetchWithProgress(config) {
137
+ const { logger, enableProgressLog, baseFetch, onProgressEvent } = config;
138
+ return async (url, init) => {
139
+ // State for this request (reset for each request)
140
+ let lastLoggedPercentage = -1;
141
+ let lastLoggedReceived = 0;
142
+ let lastLoggedTime = 0;
143
+ let isEstimatedSize = false;
144
+ let estimatedItemCount = 0;
145
+ // Start timing before fetch call
146
+ const requestStartTime = Date.now();
147
+ // Fire request-start event
148
+ if (enableProgressLog && shouldProgressLog(logger)) {
149
+ logger.info('Request starting...');
150
+ }
151
+ onProgressEvent?.({ type: 'request-start' });
152
+ // Use provided baseFetch or globalThis.fetch (allows mocking in tests)
153
+ const fetchFn = baseFetch ?? globalThis.fetch;
154
+ const response = await fetchFn(url, init);
155
+ // Calculate preparation time (request + response headers)
156
+ const bodyStartTime = Date.now();
157
+ const prepareTimeMs = bodyStartTime - requestStartTime;
158
+ // Get Content-Length header to calculate progress
159
+ const contentLength = response.headers.get('Content-Length');
160
+ let total = contentLength ? parseInt(contentLength, 10) : 0;
161
+ if (isNaN(total)) {
162
+ total = 0;
163
+ }
164
+ // Estimate item count from URL parameters
165
+ const estimation = estimateTotalSize(url.toString());
166
+ estimatedItemCount = estimation.itemCount;
167
+ // If Content-Length is not available, use estimation for total
168
+ if (total === 0) {
169
+ total = estimation.estimatedSize;
170
+ isEstimatedSize = total > 0; // Mark as estimated if we got a value
171
+ }
172
+ // Fire response-received event
173
+ if (enableProgressLog && total > 0 && shouldProgressLog(logger)) {
174
+ const sizeNote = isEstimatedSize ? ' (estimated)' : '';
175
+ logger.info(`Response received (${prepareTimeMs}ms) - ${total} bytes${sizeNote}, limit=${estimatedItemCount}`);
176
+ }
177
+ onProgressEvent?.({
178
+ type: 'response-received',
179
+ prepareTimeMs,
180
+ estimatedTotal: total,
181
+ limit: estimatedItemCount,
182
+ });
183
+ // If no body, fire complete event and return response as-is
184
+ if (!response.body) {
185
+ const completionTime = Date.now();
186
+ const totalTimeMs = completionTime - requestStartTime;
187
+ if (enableProgressLog && shouldProgressLog(logger)) {
188
+ const message = isEstimatedSize
189
+ ? `Download complete: 0 bytes received (estimated ${total} bytes) in 0ms (total: ${totalTimeMs}ms)`
190
+ : `Download complete: 0 / ${total} bytes received in 0ms (total: ${totalTimeMs}ms)`;
191
+ if (typeof process !== 'undefined' && process.stderr?.write) {
192
+ process.stderr.write(`\r${message}\n`);
193
+ }
194
+ else {
195
+ logger.info(message);
196
+ }
197
+ }
198
+ onProgressEvent?.({
199
+ type: 'complete',
200
+ received: 0,
201
+ estimatedTotal: total,
202
+ downloadTimeMs: 0,
203
+ totalTimeMs,
204
+ });
205
+ return response;
206
+ }
207
+ // Create a new ReadableStream that monitors progress
208
+ const reader = response.body.getReader();
209
+ let received = 0;
210
+ const stream = new ReadableStream({
211
+ async start(controller) {
212
+ try {
213
+ while (true) {
214
+ const { done, value } = await reader.read();
215
+ if (done) {
216
+ // Finish progress logging
217
+ const completionTime = Date.now();
218
+ const totalElapsedMs = completionTime - requestStartTime;
219
+ const bodyElapsedMs = completionTime - bodyStartTime;
220
+ if (enableProgressLog && shouldProgressLog(logger)) {
221
+ // Show final progress (always output, regardless of time)
222
+ const message = isEstimatedSize
223
+ ? `Download complete: ${received} bytes received (estimated ${total} bytes) in ${bodyElapsedMs}ms (total: ${totalElapsedMs}ms)`
224
+ : `Download complete: ${received} / ${total} bytes received in ${bodyElapsedMs}ms (total: ${totalElapsedMs}ms)`;
225
+ // In Node.js, overwrite the progress line with \r; in browsers, use logger
226
+ if (typeof process !== 'undefined' && process.stderr?.write) {
227
+ process.stderr.write(`\r${message}\n`);
228
+ }
229
+ else {
230
+ logger.info(message);
231
+ }
232
+ }
233
+ // Fire complete event
234
+ onProgressEvent?.({
235
+ type: 'complete',
236
+ received,
237
+ estimatedTotal: total,
238
+ downloadTimeMs: bodyElapsedMs,
239
+ totalTimeMs: totalElapsedMs,
240
+ });
241
+ controller.close();
242
+ break;
243
+ }
244
+ received += value.length;
245
+ // Notify progress with time-based throttling (500ms)
246
+ const percentage = total > 0 ? (received / total) * 100 : 0;
247
+ const now = Date.now();
248
+ const timeElapsed = now - lastLoggedTime;
249
+ const isFirstLog = lastLoggedTime === 0;
250
+ if (isFirstLog || timeElapsed >= 500) {
251
+ // Log progress if enabled
252
+ if (enableProgressLog && shouldProgressLog(logger)) {
253
+ const delta = received - lastLoggedReceived;
254
+ const estimatedNote = isEstimatedSize && isFirstLog ? ' (estimated)' : '';
255
+ const message = `Download progress: ${percentage.toFixed(1)}%${estimatedNote} (${received} / ${total} bytes, +${delta})`;
256
+ // Write to stderr with \r to overwrite the same line (Node.js only)
257
+ if (typeof process !== 'undefined' && process.stderr?.write) {
258
+ process.stderr.write(`\r${message}`);
259
+ }
260
+ else {
261
+ logger.info(message);
262
+ }
263
+ }
264
+ // Fire download-progress event
265
+ onProgressEvent?.({
266
+ type: 'download-progress',
267
+ received,
268
+ total,
269
+ percentage,
270
+ });
271
+ lastLoggedPercentage = percentage;
272
+ lastLoggedReceived = received;
273
+ lastLoggedTime = now;
274
+ }
275
+ controller.enqueue(value);
276
+ }
277
+ }
278
+ catch (error) {
279
+ const completionTime = Date.now();
280
+ const totalElapsedMs = completionTime - requestStartTime;
281
+ const bodyElapsedMs = completionTime - bodyStartTime;
282
+ const errorMessage = error instanceof Error ? error.message : String(error);
283
+ if (enableProgressLog && shouldProgressLog(logger)) {
284
+ const message = `Download error: ${errorMessage} (${totalElapsedMs}ms)`;
285
+ if (typeof process !== 'undefined' && process.stderr?.write) {
286
+ process.stderr.write(`\r${message}\n`);
287
+ }
288
+ else {
289
+ logger.error(message);
290
+ }
291
+ }
292
+ // Fire error event
293
+ onProgressEvent?.({
294
+ type: 'error',
295
+ error: errorMessage,
296
+ received,
297
+ estimatedTotal: total,
298
+ downloadTimeMs: bodyElapsedMs,
299
+ totalTimeMs: totalElapsedMs,
300
+ });
301
+ controller.error(error);
302
+ }
303
+ },
304
+ });
305
+ // Create new response with monitored stream
306
+ return new Response(stream, {
307
+ status: response.status,
308
+ statusText: response.statusText,
309
+ headers: response.headers,
310
+ });
311
+ };
312
+ }
313
+ //# sourceMappingURL=fetch-with-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-with-progress.js","sourceRoot":"","sources":["../../../lib/fetcher/client/fetch-with-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface FetchWithTimeoutConfig {
2
+ timeoutMs: number;
3
+ baseFetch?: typeof fetch | undefined;
4
+ }
5
+ export declare function createFetchWithTimeout(config: FetchWithTimeoutConfig): typeof fetch;
6
+ //# sourceMappingURL=fetch-with-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-with-timeout.d.ts","sourceRoot":"","sources":["../../../lib/fetcher/client/fetch-with-timeout.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAC;CACtC;AAMD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,KAAK,CA+Cd"}
@@ -0,0 +1,48 @@
1
+ import { PromidasTimeoutError } from '../errors/fetcher-error.js';
2
+ function isAbortError(error) {
3
+ return error instanceof DOMException && error.name === 'AbortError';
4
+ }
5
+ export function createFetchWithTimeout(config) {
6
+ const { timeoutMs, baseFetch } = config;
7
+ return async (url, init) => {
8
+ const fetchFn = baseFetch ?? globalThis.fetch;
9
+ const controller = new AbortController();
10
+ const timeoutError = new PromidasTimeoutError(timeoutMs);
11
+ const abortFromCaller = () => {
12
+ // Preserve caller-provided abort reason when available
13
+ controller.abort(init?.signal?.reason);
14
+ };
15
+ if (init?.signal?.aborted) {
16
+ abortFromCaller();
17
+ }
18
+ else if (init?.signal) {
19
+ init.signal.addEventListener('abort', abortFromCaller, { once: true });
20
+ }
21
+ const timeoutId = setTimeout(() => {
22
+ controller.abort(timeoutError);
23
+ }, timeoutMs);
24
+ try {
25
+ return await fetchFn(url, {
26
+ ...init,
27
+ signal: controller.signal,
28
+ });
29
+ }
30
+ catch (error) {
31
+ // Some runtimes may reject with AbortError instead of the abort reason.
32
+ if (error === timeoutError) {
33
+ throw error;
34
+ }
35
+ if (isAbortError(error) && controller.signal.reason === timeoutError) {
36
+ throw timeoutError;
37
+ }
38
+ throw error;
39
+ }
40
+ finally {
41
+ clearTimeout(timeoutId);
42
+ if (init?.signal) {
43
+ init.signal.removeEventListener('abort', abortFromCaller);
44
+ }
45
+ }
46
+ };
47
+ }
48
+ //# sourceMappingURL=fetch-with-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-with-timeout.js","sourceRoot":"","sources":["../../../lib/fetcher/client/fetch-with-timeout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAOlE,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,MAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAExC,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,OAAO,GAAG,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;QAE9C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAEzD,MAAM,eAAe,GAAG,GAAG,EAAE;YAC3B,uDAAuD;YACvD,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC,CAAC;QAEF,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC1B,eAAe,EAAE,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,GAAG,EAAE;gBACxB,GAAG,IAAI;gBACP,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wEAAwE;YACxE,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;gBAC3B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACrE,MAAM,YAAY,CAAC;YACrB,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}