@hkdigital/lib-core 0.3.11 → 0.3.13

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 (293) hide show
  1. package/README.md +173 -149
  2. package/dist/assets/autospuiten/car-paint-picker.js +41 -41
  3. package/dist/assets/autospuiten/labels.js +7 -7
  4. package/dist/classes/data/IterableTree.js +242 -242
  5. package/dist/classes/data/Selector.js +190 -190
  6. package/dist/classes/data/index.js +2 -2
  7. package/dist/classes/data/typedef.js +9 -9
  8. package/dist/classes/event-emitter/EventEmitter.js +273 -273
  9. package/dist/classes/event-emitter/index.js +2 -2
  10. package/dist/classes/index.js +4 -4
  11. package/dist/classes/promise/HkPromise.js +384 -384
  12. package/dist/classes/promise/index.js +1 -1
  13. package/dist/classes/stores/SubscribersCount.js +107 -107
  14. package/dist/classes/stores/index.js +1 -1
  15. package/dist/classes/streams/LogTransformStream.js +19 -19
  16. package/dist/classes/streams/ServerEventsStore.js +111 -111
  17. package/dist/classes/streams/TimeStampSource.js +26 -26
  18. package/dist/classes/streams/index.js +3 -3
  19. package/dist/classes/svelte/finite-state-machine/FiniteStateMachine.svelte.js +133 -133
  20. package/dist/classes/svelte/finite-state-machine/index.js +1 -1
  21. package/dist/classes/svelte/index.js +1 -11
  22. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
  23. package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
  24. package/dist/classes/svelte/loading-state-machine/index.js +3 -3
  25. package/dist/config/README.md +197 -196
  26. package/dist/config/generators/imagetools.js +189 -189
  27. package/dist/config/generators/vite.js +148 -142
  28. package/dist/config/imagetools.d.ts +72 -72
  29. package/dist/config/vite.js +4 -4
  30. package/dist/constants/bases/index.js +13 -13
  31. package/dist/constants/http/headers.js +6 -6
  32. package/dist/constants/http/index.js +2 -2
  33. package/dist/constants/http/methods.js +14 -14
  34. package/dist/constants/index.js +6 -6
  35. package/dist/constants/mime/application.js +5 -5
  36. package/dist/constants/mime/audio.js +13 -13
  37. package/dist/constants/mime/image.js +3 -3
  38. package/dist/constants/mime/index.js +4 -4
  39. package/dist/constants/mime/text.js +2 -2
  40. package/dist/constants/regexp/README.md +96 -95
  41. package/dist/constants/regexp/index.js +31 -31
  42. package/dist/constants/regexp/inspiratie.js__ +95 -95
  43. package/dist/constants/regexp/text.d.ts +4 -4
  44. package/dist/constants/regexp/text.js +49 -49
  45. package/dist/constants/regexp/url.js +3 -3
  46. package/dist/constants/regexp/user.js +29 -29
  47. package/dist/constants/states/drag.js +6 -6
  48. package/dist/constants/states/drop.js +6 -6
  49. package/dist/constants/states/index.js +4 -4
  50. package/dist/constants/states/input.js +11 -11
  51. package/dist/constants/states/submit.js +4 -4
  52. package/dist/constants/time/index.js +28 -28
  53. package/dist/css/utilities.css +43 -43
  54. package/dist/design/README.md +405 -405
  55. package/dist/design/config/design-config.js +73 -73
  56. package/dist/design/generators/index.js +288 -288
  57. package/dist/design/index.js +96 -96
  58. package/dist/design/plugins/skeleton.js +208 -208
  59. package/dist/design/tailwind-theme-extend.js +158 -158
  60. package/dist/design/themes/README.md +102 -102
  61. package/dist/design/themes/hkdev/components/blocks/text-block.css +34 -34
  62. package/dist/design/themes/hkdev/components/boxes/game-box.css +11 -11
  63. package/dist/design/themes/hkdev/components/buttons/button-icon-steeze.css +22 -22
  64. package/dist/design/themes/hkdev/components/buttons/button-text.css +32 -32
  65. package/dist/design/themes/hkdev/components/buttons/button.css +146 -146
  66. package/dist/design/themes/hkdev/components/buttons/skip-button.css +5 -5
  67. package/dist/design/themes/hkdev/components/drag-drop/draggable.css +73 -73
  68. package/dist/design/themes/hkdev/components/drag-drop/drop-zone.css +58 -58
  69. package/dist/design/themes/hkdev/components/icons/icon-steeze.css +15 -15
  70. package/dist/design/themes/hkdev/components/inputs/text-input.css +102 -102
  71. package/dist/design/themes/hkdev/components/panels/panel.css +25 -25
  72. package/dist/design/themes/hkdev/components/rows/panel-grid-row.css +4 -4
  73. package/dist/design/themes/hkdev/components/rows/panel-row-2.css +5 -5
  74. package/dist/design/themes/hkdev/components.css +29 -29
  75. package/dist/design/themes/hkdev/debug.css +1 -1
  76. package/dist/design/themes/hkdev/global/layout.css +32 -32
  77. package/dist/design/themes/hkdev/global/on-colors.css +32 -32
  78. package/dist/design/themes/hkdev/globals.css +3 -3
  79. package/dist/design/themes/hkdev/responsive.css +12 -12
  80. package/dist/design/themes/hkdev/theme-ext.js +12 -12
  81. package/dist/design/themes/hkdev/theme.css +218 -218
  82. package/dist/design/utils/clamp.js +66 -66
  83. package/dist/design/utils/root-vars.js +102 -102
  84. package/dist/design/utils/scaling.js +228 -228
  85. package/dist/design/utils/states.js +22 -22
  86. package/dist/errors/api.js +9 -9
  87. package/dist/errors/generic.js +20 -20
  88. package/dist/errors/http.js +16 -16
  89. package/dist/errors/index.js +5 -5
  90. package/dist/errors/jwt.js +5 -5
  91. package/dist/errors/promise.js +25 -25
  92. package/dist/logging/README.md +158 -0
  93. package/dist/logging/index.d.ts +3 -1
  94. package/dist/logging/index.js +11 -7
  95. package/dist/logging/internal/adapters/console.js +114 -114
  96. package/dist/logging/internal/adapters/index.js +2 -2
  97. package/dist/logging/internal/adapters/pino.js +160 -142
  98. package/dist/logging/internal/adapters/typedef.js +10 -10
  99. package/dist/logging/internal/{unified-logger/constants.js → constants.js} +22 -22
  100. package/dist/logging/internal/factories/client.d.ts +1 -1
  101. package/dist/logging/internal/factories/client.js +21 -21
  102. package/dist/logging/internal/factories/server.d.ts +1 -1
  103. package/dist/logging/internal/factories/server.js +22 -22
  104. package/dist/logging/internal/factories/universal.d.ts +2 -2
  105. package/dist/logging/internal/factories/universal.js +22 -22
  106. package/dist/logging/internal/{unified-logger → logger}/Logger.d.ts +2 -2
  107. package/dist/logging/internal/{unified-logger → logger}/Logger.js +217 -217
  108. package/dist/logging/internal/logger/index.d.ts +1 -0
  109. package/dist/logging/internal/logger/index.js +1 -0
  110. package/dist/logging/internal/{unified-logger/typedef.d.ts → typedef.d.ts} +2 -1
  111. package/dist/logging/internal/{unified-logger/typedef.js → typedef.js} +21 -17
  112. package/dist/network/README.md +172 -172
  113. package/dist/network/cache/IndexedDbCache.js +1407 -1407
  114. package/dist/network/cache/MemoryResponseCache.js +138 -138
  115. package/dist/network/cache/index.js +5 -5
  116. package/dist/network/cache/typedef.js +41 -41
  117. package/dist/network/cache.js +3 -3
  118. package/dist/network/http/caching.js +261 -261
  119. package/dist/network/http/errors.js +97 -97
  120. package/dist/network/http/headers.js +75 -75
  121. package/dist/network/http/http-request.js +578 -578
  122. package/dist/network/http/index.js +22 -22
  123. package/dist/network/http/json-request.js +224 -224
  124. package/dist/network/http/mocks.js +65 -65
  125. package/dist/network/http/response.js +318 -318
  126. package/dist/network/http/test-data__/content-length-test-hkdigital-small.V4HfZyBQ.avif +0 -0
  127. package/dist/network/http/typedef.js +93 -93
  128. package/dist/network/http/url.js +52 -52
  129. package/dist/network/http.js +5 -5
  130. package/dist/network/loaders/README.md +254 -254
  131. package/dist/network/loaders/audio/AudioLoader.svelte.js +58 -58
  132. package/dist/network/loaders/audio/AudioScene.svelte.js +324 -324
  133. package/dist/network/loaders/audio/mocks.js +35 -35
  134. package/dist/network/loaders/audio.js +1 -1
  135. package/dist/network/loaders/image/ImageLoader.svelte.js +44 -44
  136. package/dist/network/loaders/image/ImageScene.svelte.js +248 -248
  137. package/dist/network/loaders/image/ImageVariantsLoader.svelte.js +150 -150
  138. package/dist/network/loaders/image/index.js +4 -4
  139. package/dist/network/loaders/image/mocks.js +35 -35
  140. package/dist/network/loaders/image/typedef.js +8 -8
  141. package/dist/network/loaders/image/utils/index.js +86 -86
  142. package/dist/network/loaders/image.js +7 -7
  143. package/dist/network/loaders/typedef.js +38 -38
  144. package/dist/network/loaders.js +2 -2
  145. package/dist/network/states/NetworkLoader.svelte.js +338 -338
  146. package/dist/network/states/constants.js +3 -3
  147. package/dist/network/states/index.js +3 -3
  148. package/dist/network/states/mocks.js +30 -30
  149. package/dist/network/states/typedef.js +8 -8
  150. package/dist/network/typedef.js +9 -9
  151. package/dist/services/README.md +200 -0
  152. package/dist/services/index.d.ts +6 -1
  153. package/dist/services/index.js +8 -1
  154. package/dist/services/{internal/service-base → service-base}/ServiceBase.d.ts +2 -2
  155. package/dist/services/{internal/service-base → service-base}/ServiceBase.js +462 -462
  156. package/dist/services/{internal/service-base → service-base}/constants.d.ts +0 -12
  157. package/dist/services/{internal/service-base → service-base}/constants.js +98 -110
  158. package/dist/services/{internal/service-base → service-base}/index.js +3 -3
  159. package/dist/services/{internal/service-base → service-base}/typedef.d.ts +1 -1
  160. package/dist/services/{internal/service-base → service-base}/typedef.js +101 -101
  161. package/dist/services/{internal/service-manager → service-manager}/ServiceManager.d.ts +2 -2
  162. package/dist/services/{internal/service-manager → service-manager}/ServiceManager.js +608 -608
  163. package/dist/services/{internal/service-manager → service-manager}/constants.js +6 -6
  164. package/dist/services/{internal/service-manager → service-manager}/typedef.js +90 -90
  165. package/dist/states/index.js +1 -1
  166. package/dist/states/navigation.svelte.js +55 -55
  167. package/dist/stores/index.js +1 -1
  168. package/dist/stores/theme.js +80 -80
  169. package/dist/typedef/context.js +6 -6
  170. package/dist/typedef/drag.js +25 -25
  171. package/dist/typedef/drop.js +12 -12
  172. package/dist/typedef/index.d.ts +1 -0
  173. package/dist/typedef/index.js +4 -4
  174. package/dist/ui/components/button-group/ButtonGroup.svelte +82 -82
  175. package/dist/ui/components/button-group/typedef.js +10 -10
  176. package/dist/ui/components/compare-left-right/CompareLeftRight.svelte +179 -179
  177. package/dist/ui/components/compare-left-right/index.js +1 -1
  178. package/dist/ui/components/game-box/GameBox.svelte +577 -577
  179. package/dist/ui/components/game-box/gamebox.util.js +83 -83
  180. package/dist/ui/components/hk-app-layout/HkAppLayout.state.svelte.js +25 -25
  181. package/dist/ui/components/hk-app-layout/HkAppLayout.svelte +251 -251
  182. package/dist/ui/components/image-box/ImageBox.svelte +210 -210
  183. package/dist/ui/components/image-box/index.js +5 -5
  184. package/dist/ui/components/image-box/typedef.js +32 -32
  185. package/dist/ui/components/index.js +23 -23
  186. package/dist/ui/components/presenter/ImageSlide.svelte +64 -64
  187. package/dist/ui/components/presenter/Presenter.state.svelte.js +638 -638
  188. package/dist/ui/components/presenter/Presenter.svelte +142 -142
  189. package/dist/ui/components/presenter/constants.js +7 -7
  190. package/dist/ui/components/presenter/index.js +10 -10
  191. package/dist/ui/components/presenter/typedef.js +106 -106
  192. package/dist/ui/components/presenter/util.js +210 -210
  193. package/dist/ui/components/virtual-viewport/VirtualViewport.svelte +196 -196
  194. package/dist/ui/primitives/area/HkArea.svelte +49 -49
  195. package/dist/ui/primitives/area/HkGridArea.svelte +77 -77
  196. package/dist/ui/primitives/area/index.js +2 -2
  197. package/dist/ui/primitives/buttons/button/Button.svelte +82 -82
  198. package/dist/ui/primitives/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -30
  199. package/dist/ui/primitives/buttons/button-text/TextButton.svelte +21 -21
  200. package/dist/ui/primitives/buttons/index.js +3 -3
  201. package/dist/ui/primitives/debug/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +146 -146
  202. package/dist/ui/primitives/debug/index.js +1 -1
  203. package/dist/ui/primitives/drag-drop/DragController.js +44 -44
  204. package/dist/ui/primitives/drag-drop/DragDropContext.svelte +111 -111
  205. package/dist/ui/primitives/drag-drop/Draggable.svelte +519 -519
  206. package/dist/ui/primitives/drag-drop/DropZone.svelte +258 -258
  207. package/dist/ui/primitives/drag-drop/DropZoneArea.svelte +119 -119
  208. package/dist/ui/primitives/drag-drop/DropZoneList.svelte +125 -125
  209. package/dist/ui/primitives/drag-drop/actions.js +26 -26
  210. package/dist/ui/primitives/drag-drop/drag-state.svelte.js +322 -322
  211. package/dist/ui/primitives/drag-drop/index.js +7 -7
  212. package/dist/ui/primitives/drag-drop/util.js +85 -85
  213. package/dist/ui/primitives/hkdev/blocks/TextBlock.svelte +46 -46
  214. package/dist/ui/primitives/hkdev/buttons/CheckButton.svelte +62 -62
  215. package/dist/ui/primitives/icons/HkIcon.svelte +86 -86
  216. package/dist/ui/primitives/icons/HkTabIcon.svelte +116 -116
  217. package/dist/ui/primitives/icons/SteezeIcon.svelte +97 -97
  218. package/dist/ui/primitives/icons/index.js +6 -6
  219. package/dist/ui/primitives/icons/typedef.js +16 -16
  220. package/dist/ui/primitives/index.js +2 -2
  221. package/dist/ui/primitives/inputs/index.js +1 -1
  222. package/dist/ui/primitives/inputs/text-input/TestTextInput.svelte__ +102 -0
  223. package/dist/ui/primitives/inputs/text-input/TextInput.svelte +223 -223
  224. package/dist/ui/primitives/inputs/text-input/TextInput.svelte___ +83 -0
  225. package/dist/ui/primitives/inputs/text-input/assets/IconInvalid.svelte +14 -14
  226. package/dist/ui/primitives/inputs/text-input/assets/IconValid.svelte +12 -12
  227. package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte +63 -63
  228. package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte__heightFrom__ +372 -0
  229. package/dist/ui/primitives/layout/grid-layers/util.js +74 -74
  230. package/dist/ui/primitives/layout/index.js +1 -1
  231. package/dist/ui/primitives/panels/index.js +1 -1
  232. package/dist/ui/primitives/panels/panel/Panel.svelte +43 -43
  233. package/dist/ui/primitives/rows/index.js +3 -3
  234. package/dist/ui/primitives/rows/panel-grid-row/PanelGridRow.svelte +104 -104
  235. package/dist/ui/primitives/rows/panel-row-2/PanelRow2.svelte +40 -40
  236. package/dist/ui/primitives/tab-bar/HkTabBar.state.svelte.js +149 -149
  237. package/dist/ui/primitives/tab-bar/HkTabBar.svelte +74 -74
  238. package/dist/ui/primitives/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
  239. package/dist/ui/primitives/tab-bar/HkTabBarSelector.svelte +49 -49
  240. package/dist/ui/primitives/tab-bar/index.js +17 -17
  241. package/dist/ui/primitives/tab-bar/typedef.js +11 -11
  242. package/dist/util/array/index.js +436 -436
  243. package/dist/util/bases/base58.js +262 -262
  244. package/dist/util/bases/index.js +1 -1
  245. package/dist/util/compare/index.js +247 -247
  246. package/dist/util/css/css-vars.js +83 -83
  247. package/dist/util/css/index.js +1 -1
  248. package/dist/util/env/index.js +9 -9
  249. package/dist/util/exceptions/index.d.ts +4 -3
  250. package/dist/util/exceptions/index.js +26 -23
  251. package/dist/util/expect/arrays.js +47 -47
  252. package/dist/util/expect/index.js +259 -259
  253. package/dist/util/expect/primitives.js +55 -55
  254. package/dist/util/expect/url.js +60 -60
  255. package/dist/util/function/index.js +218 -218
  256. package/dist/util/geo/index.js +26 -26
  257. package/dist/util/index.js +7 -7
  258. package/dist/util/is/index.js +147 -147
  259. package/dist/util/iterate/index.js +204 -204
  260. package/dist/util/object/index.js +1345 -1345
  261. package/dist/util/singleton/index.js +97 -97
  262. package/dist/util/string/array-path.js +75 -75
  263. package/dist/util/string/convert.js +54 -54
  264. package/dist/util/string/fs.js +226 -226
  265. package/dist/util/string/index.js +5 -5
  266. package/dist/util/string/interpolate.js +61 -61
  267. package/dist/util/string/pad.js +10 -10
  268. package/dist/util/svelte/index.js +4 -4
  269. package/dist/util/svelte/loading/loading-tracker.svelte.js +108 -108
  270. package/dist/util/svelte/observe/index.js +49 -49
  271. package/dist/util/svelte/state-context/index.js +117 -117
  272. package/dist/util/svelte/wait/index.js +38 -38
  273. package/dist/util/sveltekit/index.js +1 -1
  274. package/dist/util/sveltekit/route-folders/index.js +101 -101
  275. package/dist/util/time/index.js +328 -328
  276. package/dist/util/unique/index.js +231 -231
  277. package/dist/valibot/README.md +61 -50
  278. package/dist/valibot/index.js +8 -8
  279. package/dist/valibot/parsers/date.js__ +10 -0
  280. package/dist/valibot/parsers/email.d.ts +12 -0
  281. package/dist/valibot/parsers/email.js +34 -0
  282. package/dist/valibot/parsers/url.js +110 -110
  283. package/dist/valibot/parsers/user.js +23 -23
  284. package/dist/valibot/parsers.js +3 -3
  285. package/package.json +131 -131
  286. package/dist/logging/internal/unified-logger/index.d.ts +0 -3
  287. package/dist/logging/internal/unified-logger/index.js +0 -6
  288. package/dist/services/internal/index.d.ts +0 -6
  289. package/dist/services/internal/index.js +0 -8
  290. /package/dist/logging/internal/{unified-logger/constants.d.ts → constants.d.ts} +0 -0
  291. /package/dist/services/{internal/service-base → service-base}/index.d.ts +0 -0
  292. /package/dist/services/{internal/service-manager → service-manager}/constants.d.ts +0 -0
  293. /package/dist/services/{internal/service-manager → service-manager}/typedef.d.ts +0 -0
@@ -1,318 +1,318 @@
1
- import { ResponseError, HttpError } from '../../errors/index.js';
2
- import * as expect from '../../util/expect/index.js';
3
- import { toURL } from './url.js';
4
-
5
- import {
6
- WWW_AUTHENTICATE,
7
- CONTENT_LENGTH
8
- } from '../../constants/http/headers.js';
9
-
10
- import { href } from './url.js';
11
-
12
- import { getErrorFromResponse } from './errors.js';
13
-
14
- // > Types
15
-
16
- /**
17
- * Callback function that reports progress of data loading
18
- *
19
- * @callback progressCallback
20
- *
21
- * @param {object} _
22
- * @param {number} _.bytesLoaded - Number of bytes loaded so far
23
- * @param {number} _.size - Total size of the response in bytes (0 if unknown)
24
- */
25
-
26
- // > Exports
27
-
28
- /**
29
- * Check if the response status is ok (in 200-299 range)
30
- * This function examines HTTP status codes and throws appropriate errors for
31
- * non-successful responses, with special handling for 401 Unauthorized.
32
- *
33
- * @param {object} response - Fetch Response object to check
34
- *
35
- * @param {string} url - The URL used for the request (for error messages)
36
- *
37
- * @throws {Error} When response has 401 status with authorization details
38
- * @throws {ResponseError} When response has other non-successful status codes
39
- *
40
- * @example
41
- * // Check if response was successful
42
- * try {
43
- * await expectResponseOk(response, 'https://api.example.com/data');
44
- * // Process successful response here
45
- * } catch (error) {
46
- * // Handle specific error types
47
- * if (error.message.includes('401')) {
48
- * // Handle unauthorized error
49
- * }
50
- * }
51
- */
52
- export async function expectResponseOk(response, url) {
53
- expect.object(response);
54
-
55
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200
56
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
57
-
58
- if (200 === response.status || 201 === response.status) {
59
- if (!response.ok) {
60
- throw new ResponseError(
61
- `Server returned - ${response.status} ${response.statusText} ` +
62
- `[response.ok=false] [url=${href(url)}]`
63
- );
64
- }
65
-
66
- // All ok
67
- return;
68
- }
69
-
70
- // > Handle 401 Unauthorized
71
-
72
- if (401 === response.status) {
73
- let errorMessage = 'Server returned [401] Unauthorized';
74
-
75
- const authValue = response.headers.get(WWW_AUTHENTICATE);
76
-
77
- if (authValue) {
78
- // Add WWW_AUTHENTICATE response to error message
79
- errorMessage += ` (${authValue})`;
80
- }
81
-
82
- errorMessage += ` [url=${href(url)}]`;
83
-
84
- throw new Error(errorMessage);
85
- }
86
-
87
- // > Handle all other error responses
88
-
89
- const error = await getErrorFromResponse(response);
90
-
91
- throw new ResponseError(
92
- `Server returned - ${response.status} ${response.statusText} ` +
93
- `[url=${href(url)}]`,
94
- { cause: error }
95
- );
96
- }
97
-
98
- /**
99
- * Get the response size from the content-length response header
100
- *
101
- * @param {Response} response - Fetch Response object
102
- *
103
- * @returns {number} Response size in bytes, or 0 if content-length is not set
104
- *
105
- * @example
106
- * const response = await fetch('https://example.com/large-file.zip');
107
- * const size = getResponseSize(response);
108
- * console.log(`Download size: ${size} bytes`);
109
- */
110
- export function getResponseSize(response) {
111
- const sizeStr = response.headers.get(CONTENT_LENGTH);
112
-
113
- if (!sizeStr) {
114
- return 0;
115
- }
116
-
117
- return parseInt(sizeStr, 10);
118
- }
119
-
120
- /**
121
- * Wait for a response and check if the response is ok
122
- * This function awaits a response promise and performs error checking,
123
- * wrapping network errors in a standardized ResponseError format.
124
- *
125
- * @param {Promise<Response>} responsePromise - Promise that resolves to a Response
126
- *
127
- * @param {string|URL} url - URL used for the request (for error messages)
128
- *
129
- * @throws {ResponseError} When a network error occurs or response is not ok
130
- *
131
- * @returns {Promise<Response>} The response if successful
132
- *
133
- * @example
134
- * // Handle a fetch promise with proper error handling
135
- * const responsePromise = fetch('https://api.example.com/data');
136
- * try {
137
- * const response = await waitForAndCheckResponse(
138
- * responsePromise,
139
- * 'https://api.example.com/data'
140
- * );
141
- * // Process response
142
- * } catch (error) {
143
- * // Handle standardized ResponseError
144
- * console.error(error.message);
145
- * }
146
- */
147
- export async function waitForAndCheckResponse(responsePromise, url) {
148
- expect.promise(responsePromise);
149
-
150
- url = toURL(url);
151
-
152
- let response;
153
-
154
- try {
155
- response = await responsePromise;
156
-
157
- if (response && false === response.ok) {
158
- // Check if this is a network error (status 0) vs HTTP error
159
- if (response.status === 0) {
160
- // Network error - treat as before
161
- throw new Error(`Response failed [response.ok=false]`);
162
- }
163
-
164
- // HTTP error - get response body for detailed error information
165
- const responseBody = await response.text();
166
- let errorDetails;
167
-
168
- try {
169
- // Try to parse as JSON (common for API errors)
170
- errorDetails = JSON.parse(responseBody);
171
- } catch {
172
- // Fallback to plain text
173
- errorDetails = responseBody;
174
- }
175
-
176
- throw new HttpError(
177
- response.status,
178
- `HTTP ${response.status}: ${response.statusText}`,
179
- errorDetails
180
- );
181
- }
182
- } catch (e) {
183
- if (e instanceof HttpError) {
184
- // Re-throw HttpError as-is
185
- throw e;
186
- } else if (e instanceof TypeError || response?.ok === false) {
187
- throw new ResponseError(
188
- `A network error occurred for request [${href(url)}]`,
189
- {
190
- cause: e
191
- }
192
- );
193
- } else {
194
- throw e;
195
- }
196
- }
197
-
198
- return response;
199
- }
200
-
201
- /**
202
- * Load response body as ArrayBuffer with progress monitoring and abort capability
203
- *
204
- * This function reads a response body stream chunk by chunk, with optional
205
- * progress reporting. It provides an abort mechanism to cancel an in-progress
206
- * download.
207
- *
208
- * @param {Response} response - Fetch Response object to read
209
- *
210
- * @param {progressCallback} [onProgress] - Optional callback for progress updates
211
- *
212
- * @returns {{
213
- * bufferPromise: Promise<ArrayBuffer>,
214
- * abort: () => void
215
- * }} Object containing the buffer promise and abort function
216
- *
217
- * @example
218
- * // Download a file with progress monitoring and abort capability
219
- * const response = await fetch('https://example.com/large-file.zip');
220
- *
221
- * const { bufferPromise, abort } = loadResponseBuffer(
222
- * response,
223
- * ({ bytesLoaded, size }) => {
224
- * // Update progress UI
225
- * const percent = size ? Math.round((bytesLoaded / size) * 100) : 0;
226
- * console.log(`Downloaded ${bytesLoaded} bytes (${percent}%)`);
227
- * }
228
- * );
229
- *
230
- * // To abort the download:
231
- * // abort();
232
- *
233
- * try {
234
- * const buffer = await bufferPromise;
235
- * // Process the complete buffer
236
- * } catch (error) {
237
- * console.error('Download failed or was aborted', error);
238
- * }
239
- */
240
- export function loadResponseBuffer(response, onProgress) {
241
- // @note size might be 0
242
- // @note might not be send by server in dev mode
243
- const size = getResponseSize(response);
244
-
245
- let bytesLoaded = 0;
246
-
247
- if (onProgress /*&& size*/) {
248
- onProgress({ bytesLoaded, size });
249
- }
250
-
251
- if (!response.body) {
252
- throw new Error('Missing [response.body]');
253
- }
254
-
255
- let reader;
256
- let aborted = false;
257
-
258
- /**
259
- * Read chunks from response body using reader
260
- *
261
- * @returns {Promise<ArrayBuffer>}
262
- */
263
- async function read() {
264
- reader = response.body.getReader();
265
- let chunks = [];
266
-
267
- for (;;) {
268
- const { done, value } = await reader.read();
269
-
270
- if (value) {
271
- // @note value is an ArrayBuffer
272
- bytesLoaded += value.byteLength;
273
-
274
- chunks.push(value);
275
-
276
- if (onProgress /*&& size*/) {
277
- onProgress({ bytesLoaded, size });
278
- }
279
- }
280
-
281
- if (done || aborted) {
282
- // Loading complete or aborted by user
283
- break;
284
- }
285
- } // end for
286
-
287
- if (size && bytesLoaded !== size) {
288
- console.error(`Received [${bytesLoaded}], but expected [${size}] bytes`);
289
- }
290
-
291
- // Concat the chunks into a single array
292
- let buffer = new ArrayBuffer(bytesLoaded);
293
- let body = new Uint8Array(buffer);
294
-
295
- let offset = 0;
296
-
297
- // Place the chunks in the buffer
298
- for (let chunk of chunks) {
299
- body.set(chunk, offset);
300
- offset += chunk.byteLength;
301
- } // end for
302
-
303
- return buffer;
304
- }
305
-
306
- const bufferPromise = read();
307
-
308
- return {
309
- bufferPromise,
310
- abort: () => {
311
- aborted = true;
312
-
313
- if (reader) {
314
- reader.cancel('Aborted by user');
315
- }
316
- }
317
- };
318
- } // end fn
1
+ import { ResponseError, HttpError } from '../../errors/index.js';
2
+ import * as expect from '../../util/expect/index.js';
3
+ import { toURL } from './url.js';
4
+
5
+ import {
6
+ WWW_AUTHENTICATE,
7
+ CONTENT_LENGTH
8
+ } from '../../constants/http/headers.js';
9
+
10
+ import { href } from './url.js';
11
+
12
+ import { getErrorFromResponse } from './errors.js';
13
+
14
+ // > Types
15
+
16
+ /**
17
+ * Callback function that reports progress of data loading
18
+ *
19
+ * @callback progressCallback
20
+ *
21
+ * @param {object} _
22
+ * @param {number} _.bytesLoaded - Number of bytes loaded so far
23
+ * @param {number} _.size - Total size of the response in bytes (0 if unknown)
24
+ */
25
+
26
+ // > Exports
27
+
28
+ /**
29
+ * Check if the response status is ok (in 200-299 range)
30
+ * This function examines HTTP status codes and throws appropriate errors for
31
+ * non-successful responses, with special handling for 401 Unauthorized.
32
+ *
33
+ * @param {object} response - Fetch Response object to check
34
+ *
35
+ * @param {string} url - The URL used for the request (for error messages)
36
+ *
37
+ * @throws {Error} When response has 401 status with authorization details
38
+ * @throws {ResponseError} When response has other non-successful status codes
39
+ *
40
+ * @example
41
+ * // Check if response was successful
42
+ * try {
43
+ * await expectResponseOk(response, 'https://api.example.com/data');
44
+ * // Process successful response here
45
+ * } catch (error) {
46
+ * // Handle specific error types
47
+ * if (error.message.includes('401')) {
48
+ * // Handle unauthorized error
49
+ * }
50
+ * }
51
+ */
52
+ export async function expectResponseOk(response, url) {
53
+ expect.object(response);
54
+
55
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200
56
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
57
+
58
+ if (200 === response.status || 201 === response.status) {
59
+ if (!response.ok) {
60
+ throw new ResponseError(
61
+ `Server returned - ${response.status} ${response.statusText} ` +
62
+ `[response.ok=false] [url=${href(url)}]`
63
+ );
64
+ }
65
+
66
+ // All ok
67
+ return;
68
+ }
69
+
70
+ // > Handle 401 Unauthorized
71
+
72
+ if (401 === response.status) {
73
+ let errorMessage = 'Server returned [401] Unauthorized';
74
+
75
+ const authValue = response.headers.get(WWW_AUTHENTICATE);
76
+
77
+ if (authValue) {
78
+ // Add WWW_AUTHENTICATE response to error message
79
+ errorMessage += ` (${authValue})`;
80
+ }
81
+
82
+ errorMessage += ` [url=${href(url)}]`;
83
+
84
+ throw new Error(errorMessage);
85
+ }
86
+
87
+ // > Handle all other error responses
88
+
89
+ const error = await getErrorFromResponse(response);
90
+
91
+ throw new ResponseError(
92
+ `Server returned - ${response.status} ${response.statusText} ` +
93
+ `[url=${href(url)}]`,
94
+ { cause: error }
95
+ );
96
+ }
97
+
98
+ /**
99
+ * Get the response size from the content-length response header
100
+ *
101
+ * @param {Response} response - Fetch Response object
102
+ *
103
+ * @returns {number} Response size in bytes, or 0 if content-length is not set
104
+ *
105
+ * @example
106
+ * const response = await fetch('https://example.com/large-file.zip');
107
+ * const size = getResponseSize(response);
108
+ * console.log(`Download size: ${size} bytes`);
109
+ */
110
+ export function getResponseSize(response) {
111
+ const sizeStr = response.headers.get(CONTENT_LENGTH);
112
+
113
+ if (!sizeStr) {
114
+ return 0;
115
+ }
116
+
117
+ return parseInt(sizeStr, 10);
118
+ }
119
+
120
+ /**
121
+ * Wait for a response and check if the response is ok
122
+ * This function awaits a response promise and performs error checking,
123
+ * wrapping network errors in a standardized ResponseError format.
124
+ *
125
+ * @param {Promise<Response>} responsePromise - Promise that resolves to a Response
126
+ *
127
+ * @param {string|URL} url - URL used for the request (for error messages)
128
+ *
129
+ * @throws {ResponseError} When a network error occurs or response is not ok
130
+ *
131
+ * @returns {Promise<Response>} The response if successful
132
+ *
133
+ * @example
134
+ * // Handle a fetch promise with proper error handling
135
+ * const responsePromise = fetch('https://api.example.com/data');
136
+ * try {
137
+ * const response = await waitForAndCheckResponse(
138
+ * responsePromise,
139
+ * 'https://api.example.com/data'
140
+ * );
141
+ * // Process response
142
+ * } catch (error) {
143
+ * // Handle standardized ResponseError
144
+ * console.error(error.message);
145
+ * }
146
+ */
147
+ export async function waitForAndCheckResponse(responsePromise, url) {
148
+ expect.promise(responsePromise);
149
+
150
+ url = toURL(url);
151
+
152
+ let response;
153
+
154
+ try {
155
+ response = await responsePromise;
156
+
157
+ if (response && false === response.ok) {
158
+ // Check if this is a network error (status 0) vs HTTP error
159
+ if (response.status === 0) {
160
+ // Network error - treat as before
161
+ throw new Error(`Response failed [response.ok=false]`);
162
+ }
163
+
164
+ // HTTP error - get response body for detailed error information
165
+ const responseBody = await response.text();
166
+ let errorDetails;
167
+
168
+ try {
169
+ // Try to parse as JSON (common for API errors)
170
+ errorDetails = JSON.parse(responseBody);
171
+ } catch {
172
+ // Fallback to plain text
173
+ errorDetails = responseBody;
174
+ }
175
+
176
+ throw new HttpError(
177
+ response.status,
178
+ `HTTP ${response.status}: ${response.statusText}`,
179
+ errorDetails
180
+ );
181
+ }
182
+ } catch (e) {
183
+ if (e instanceof HttpError) {
184
+ // Re-throw HttpError as-is
185
+ throw e;
186
+ } else if (e instanceof TypeError || response?.ok === false) {
187
+ throw new ResponseError(
188
+ `A network error occurred for request [${href(url)}]`,
189
+ {
190
+ cause: e
191
+ }
192
+ );
193
+ } else {
194
+ throw e;
195
+ }
196
+ }
197
+
198
+ return response;
199
+ }
200
+
201
+ /**
202
+ * Load response body as ArrayBuffer with progress monitoring and abort capability
203
+ *
204
+ * This function reads a response body stream chunk by chunk, with optional
205
+ * progress reporting. It provides an abort mechanism to cancel an in-progress
206
+ * download.
207
+ *
208
+ * @param {Response} response - Fetch Response object to read
209
+ *
210
+ * @param {progressCallback} [onProgress] - Optional callback for progress updates
211
+ *
212
+ * @returns {{
213
+ * bufferPromise: Promise<ArrayBuffer>,
214
+ * abort: () => void
215
+ * }} Object containing the buffer promise and abort function
216
+ *
217
+ * @example
218
+ * // Download a file with progress monitoring and abort capability
219
+ * const response = await fetch('https://example.com/large-file.zip');
220
+ *
221
+ * const { bufferPromise, abort } = loadResponseBuffer(
222
+ * response,
223
+ * ({ bytesLoaded, size }) => {
224
+ * // Update progress UI
225
+ * const percent = size ? Math.round((bytesLoaded / size) * 100) : 0;
226
+ * console.log(`Downloaded ${bytesLoaded} bytes (${percent}%)`);
227
+ * }
228
+ * );
229
+ *
230
+ * // To abort the download:
231
+ * // abort();
232
+ *
233
+ * try {
234
+ * const buffer = await bufferPromise;
235
+ * // Process the complete buffer
236
+ * } catch (error) {
237
+ * console.error('Download failed or was aborted', error);
238
+ * }
239
+ */
240
+ export function loadResponseBuffer(response, onProgress) {
241
+ // @note size might be 0
242
+ // @note might not be send by server in dev mode
243
+ const size = getResponseSize(response);
244
+
245
+ let bytesLoaded = 0;
246
+
247
+ if (onProgress /*&& size*/) {
248
+ onProgress({ bytesLoaded, size });
249
+ }
250
+
251
+ if (!response.body) {
252
+ throw new Error('Missing [response.body]');
253
+ }
254
+
255
+ let reader;
256
+ let aborted = false;
257
+
258
+ /**
259
+ * Read chunks from response body using reader
260
+ *
261
+ * @returns {Promise<ArrayBuffer>}
262
+ */
263
+ async function read() {
264
+ reader = response.body.getReader();
265
+ let chunks = [];
266
+
267
+ for (;;) {
268
+ const { done, value } = await reader.read();
269
+
270
+ if (value) {
271
+ // @note value is an ArrayBuffer
272
+ bytesLoaded += value.byteLength;
273
+
274
+ chunks.push(value);
275
+
276
+ if (onProgress /*&& size*/) {
277
+ onProgress({ bytesLoaded, size });
278
+ }
279
+ }
280
+
281
+ if (done || aborted) {
282
+ // Loading complete or aborted by user
283
+ break;
284
+ }
285
+ } // end for
286
+
287
+ if (size && bytesLoaded !== size) {
288
+ console.error(`Received [${bytesLoaded}], but expected [${size}] bytes`);
289
+ }
290
+
291
+ // Concat the chunks into a single array
292
+ let buffer = new ArrayBuffer(bytesLoaded);
293
+ let body = new Uint8Array(buffer);
294
+
295
+ let offset = 0;
296
+
297
+ // Place the chunks in the buffer
298
+ for (let chunk of chunks) {
299
+ body.set(chunk, offset);
300
+ offset += chunk.byteLength;
301
+ } // end for
302
+
303
+ return buffer;
304
+ }
305
+
306
+ const bufferPromise = read();
307
+
308
+ return {
309
+ bufferPromise,
310
+ abort: () => {
311
+ aborted = true;
312
+
313
+ if (reader) {
314
+ reader.cancel('Aborted by user');
315
+ }
316
+ }
317
+ };
318
+ } // end fn