@hkdigital/lib-sveltekit 0.1.62 → 0.1.65

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 (209) hide show
  1. package/README.md +135 -135
  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 +243 -243
  5. package/dist/classes/data/Selector.js +190 -190
  6. package/dist/classes/data/index.js +2 -2
  7. package/dist/classes/index.js +4 -4
  8. package/dist/classes/promise/HkPromise.js +377 -377
  9. package/dist/classes/promise/index.js +1 -1
  10. package/dist/classes/stores/SubscribersCount.js +107 -107
  11. package/dist/classes/stores/index.js +1 -1
  12. package/dist/classes/streams/LogTransformStream.js +19 -19
  13. package/dist/classes/streams/ServerEventsStore.js +110 -110
  14. package/dist/classes/streams/TimeStampSource.js +26 -26
  15. package/dist/classes/streams/index.js +3 -3
  16. package/dist/classes/svelte/audio/AudioLoader.svelte.js +58 -58
  17. package/dist/classes/svelte/audio/AudioScene.svelte.js +295 -295
  18. package/dist/classes/svelte/audio/mocks.js +35 -35
  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/image/ImageLoader.svelte.js +47 -47
  22. package/dist/classes/svelte/image/ImageScene.svelte.js +253 -253
  23. package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +152 -152
  24. package/dist/classes/svelte/image/index.js +4 -4
  25. package/dist/classes/svelte/image/mocks.js +35 -35
  26. package/dist/classes/svelte/image/typedef.js +8 -8
  27. package/dist/classes/svelte/index.js +14 -14
  28. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
  29. package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
  30. package/dist/classes/svelte/loading-state-machine/index.js +3 -3
  31. package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +331 -331
  32. package/dist/classes/svelte/network-loader/constants.js +3 -3
  33. package/dist/classes/svelte/network-loader/index.js +3 -3
  34. package/dist/classes/svelte/network-loader/mocks.js +30 -30
  35. package/dist/classes/svelte/network-loader/typedef.js +8 -8
  36. package/dist/components/area/HkArea.svelte +49 -49
  37. package/dist/components/area/HkGridArea.svelte +77 -77
  38. package/dist/components/area/index.js +2 -2
  39. package/dist/components/buttons/button/Button.svelte +82 -82
  40. package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -30
  41. package/dist/components/buttons/button-text/TextButton.svelte +21 -21
  42. package/dist/components/buttons/index.js +3 -3
  43. package/dist/components/debug/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +146 -146
  44. package/dist/components/debug/index.js +1 -1
  45. package/dist/components/hkdev/blocks/TextBlock.svelte +46 -46
  46. package/dist/components/hkdev/buttons/CheckButton.svelte +62 -62
  47. package/dist/components/icons/HkIcon.svelte +86 -86
  48. package/dist/components/icons/HkTabIcon.svelte +116 -116
  49. package/dist/components/icons/SteezeIcon.svelte +97 -97
  50. package/dist/components/icons/index.js +6 -6
  51. package/dist/components/icons/typedef.js +16 -16
  52. package/dist/components/index.js +2 -2
  53. package/dist/components/inputs/index.js +1 -1
  54. package/dist/components/inputs/text-input/TestTextInput.svelte__ +102 -102
  55. package/dist/components/inputs/text-input/TextInput.svelte +223 -223
  56. package/dist/components/inputs/text-input/TextInput.svelte___ +83 -83
  57. package/dist/components/inputs/text-input/assets/IconInvalid.svelte +14 -14
  58. package/dist/components/inputs/text-input/assets/IconValid.svelte +12 -12
  59. package/dist/components/layout/grid-layers/GridLayers.svelte +167 -167
  60. package/dist/components/layout/index.js +1 -1
  61. package/dist/components/panels/index.js +1 -1
  62. package/dist/components/panels/panel/Panel.svelte +43 -43
  63. package/dist/components/rows/index.js +3 -3
  64. package/dist/components/rows/panel-grid-row/PanelGridRow.svelte +104 -104
  65. package/dist/components/rows/panel-row-2/PanelRow2.svelte +40 -40
  66. package/dist/components/tab-bar/HkTabBar.state.svelte.js +149 -149
  67. package/dist/components/tab-bar/HkTabBar.svelte +74 -74
  68. package/dist/components/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
  69. package/dist/components/tab-bar/HkTabBarSelector.svelte +49 -49
  70. package/dist/components/tab-bar/index.js +17 -17
  71. package/dist/components/tab-bar/typedef.js +8 -8
  72. package/dist/config/imagetools-config.js +189 -189
  73. package/dist/config/imagetools.d.ts +71 -71
  74. package/dist/config/typedef.js +8 -8
  75. package/dist/constants/bases.js +13 -13
  76. package/dist/constants/errors/api.js +9 -9
  77. package/dist/constants/errors/generic.js +5 -5
  78. package/dist/constants/errors/index.js +3 -3
  79. package/dist/constants/errors/jwt.js +5 -5
  80. package/dist/constants/http/headers.js +6 -6
  81. package/dist/constants/http/index.js +2 -2
  82. package/dist/constants/http/methods.js +2 -2
  83. package/dist/constants/index.js +3 -3
  84. package/dist/constants/mime/application.js +5 -5
  85. package/dist/constants/mime/audio.js +13 -13
  86. package/dist/constants/mime/image.js +3 -3
  87. package/dist/constants/mime/index.js +4 -4
  88. package/dist/constants/mime/text.js +2 -2
  89. package/dist/constants/regexp/index.js +31 -31
  90. package/dist/constants/regexp/inspiratie.js__ +95 -95
  91. package/dist/constants/regexp/text.js +49 -49
  92. package/dist/constants/regexp/user.js +32 -32
  93. package/dist/constants/regexp/web.js +3 -3
  94. package/dist/constants/state-labels/input-states.js +11 -11
  95. package/dist/constants/state-labels/submit-states.js +4 -4
  96. package/dist/constants/time.js +28 -28
  97. package/dist/css/utilities.css +43 -43
  98. package/dist/design/design-config.js +73 -73
  99. package/dist/design/tailwind-theme-extend.js +158 -158
  100. package/dist/schemas/index.js +1 -1
  101. package/dist/schemas/validate-url.js +180 -180
  102. package/dist/server/index.js +1 -1
  103. package/dist/server/logger.js +94 -94
  104. package/dist/states/index.js +1 -1
  105. package/dist/states/navigation.svelte.js +55 -55
  106. package/dist/stores/index.js +1 -1
  107. package/dist/stores/theme.js +80 -80
  108. package/dist/themes/hkdev/components/blocks/text-block.css +41 -41
  109. package/dist/themes/hkdev/components/boxes/game-box.css +12 -12
  110. package/dist/themes/hkdev/components/buttons/button-icon-steeze.css +22 -22
  111. package/dist/themes/hkdev/components/buttons/button-text.css +32 -32
  112. package/dist/themes/hkdev/components/buttons/button.css +142 -142
  113. package/dist/themes/hkdev/components/buttons/skip-button.css +6 -6
  114. package/dist/themes/hkdev/components/icons/icon-steeze.css +22 -22
  115. package/dist/themes/hkdev/components/inputs/text-input.css +104 -104
  116. package/dist/themes/hkdev/components/panels/panel.css +27 -27
  117. package/dist/themes/hkdev/components/rows/panel-grid-row.css +6 -6
  118. package/dist/themes/hkdev/components/rows/panel-row-2.css +7 -7
  119. package/dist/themes/hkdev/components.css +47 -47
  120. package/dist/themes/hkdev/debug.css +1 -1
  121. package/dist/themes/hkdev/global/layout.css +39 -39
  122. package/dist/themes/hkdev/global/on-colors.css +53 -53
  123. package/dist/themes/hkdev/globals.css +11 -11
  124. package/dist/themes/hkdev/responsive.css +12 -12
  125. package/dist/themes/hkdev/theme-ext.js +15 -15
  126. package/dist/themes/hkdev/theme.js +235 -235
  127. package/dist/themes/index.js +1 -1
  128. package/dist/util/array/index.js +455 -455
  129. package/dist/util/bases/base58.js +262 -262
  130. package/dist/util/bases/index.js +1 -1
  131. package/dist/util/compare/index.js +247 -247
  132. package/dist/util/css/css-vars.js +83 -83
  133. package/dist/util/css/index.js +1 -1
  134. package/dist/util/design-system/components/states.js +22 -22
  135. package/dist/util/design-system/css/clamp.js +66 -66
  136. package/dist/util/design-system/css/root-design-vars.js +100 -100
  137. package/dist/util/design-system/index.js +5 -5
  138. package/dist/util/design-system/layout/scaling.js +228 -228
  139. package/dist/util/design-system/skeleton.js +208 -208
  140. package/dist/util/design-system/tailwind.js +288 -288
  141. package/dist/util/expect/arrays.js +47 -47
  142. package/dist/util/expect/index.js +259 -259
  143. package/dist/util/expect/primitives.js +55 -55
  144. package/dist/util/expect/url.js +60 -60
  145. package/dist/util/function/index.js +218 -218
  146. package/dist/util/http/errors.js +97 -97
  147. package/dist/util/http/headers.js +45 -45
  148. package/dist/util/http/http-request.js +294 -294
  149. package/dist/util/http/index.js +22 -22
  150. package/dist/util/http/json-request.js +143 -143
  151. package/dist/util/http/mocks.js +65 -65
  152. package/dist/util/http/response.js +241 -241
  153. package/dist/util/http/test-data__/content-length-test-hkdigital-small.V4HfZyBQ.avif +0 -0
  154. package/dist/util/http/url.js +52 -52
  155. package/dist/util/image/index.js +86 -86
  156. package/dist/util/index.js +2 -2
  157. package/dist/util/is/index.js +140 -140
  158. package/dist/util/iterate/index.js +234 -234
  159. package/dist/util/object/index.js +1361 -1361
  160. package/dist/util/singleton/index.js +97 -97
  161. package/dist/util/string/array-path.js +75 -75
  162. package/dist/util/string/convert.js +54 -54
  163. package/dist/util/string/fs.js +226 -226
  164. package/dist/util/string/index.js +5 -5
  165. package/dist/util/string/interpolate.js +61 -61
  166. package/dist/util/string/pad.js +10 -10
  167. package/dist/util/svelte/index.js +4 -4
  168. package/dist/util/svelte/loading/loading-tracker.svelte.js +108 -108
  169. package/dist/util/svelte/observe/index.js +49 -49
  170. package/dist/util/svelte/state-context/index.js +83 -83
  171. package/dist/util/svelte/wait/index.js +38 -38
  172. package/dist/util/sveltekit/index.js +1 -1
  173. package/dist/util/sveltekit/route-folders/index.js +101 -101
  174. package/dist/util/time/index.js +323 -323
  175. package/dist/util/unique/index.js +249 -249
  176. package/dist/valibot/date.js__ +10 -10
  177. package/dist/valibot/index.js +9 -9
  178. package/dist/valibot/url.js +95 -95
  179. package/dist/valibot/user.js +23 -23
  180. package/dist/widgets/button-group/ButtonGroup.svelte +82 -94
  181. package/dist/widgets/button-group/ButtonGroup.svelte.d.ts +0 -2
  182. package/dist/widgets/button-group/typedef.js +10 -10
  183. package/dist/widgets/compare-left-right/CompareLeftRight.svelte +179 -179
  184. package/dist/widgets/compare-left-right/index.js +1 -1
  185. package/dist/widgets/game-box/GameBox.svelte +579 -186
  186. package/dist/widgets/game-box/GameBox.svelte.d.ts +64 -4
  187. package/dist/widgets/game-box/gamebox.util.js +83 -83
  188. package/dist/widgets/hk-app-layout/HkAppLayout.state.svelte.js +25 -25
  189. package/dist/widgets/hk-app-layout/HkAppLayout.svelte +251 -251
  190. package/dist/widgets/image-box/ImageBox.svelte +212 -212
  191. package/dist/widgets/image-box/index.js +5 -5
  192. package/dist/widgets/image-box/typedef.js +32 -32
  193. package/dist/widgets/index.js +23 -23
  194. package/dist/widgets/presenter/(broken) Presenter.state.svelte.js__ +613 -0
  195. package/dist/widgets/presenter/ImageSlide.svelte +64 -64
  196. package/dist/widgets/presenter/Presenter.state.svelte.js +636 -636
  197. package/dist/widgets/presenter/Presenter.svelte +140 -140
  198. package/dist/widgets/presenter/Presenter.svelte__ +125 -0
  199. package/dist/widgets/presenter/constants.js +7 -7
  200. package/dist/widgets/presenter/index.js +10 -10
  201. package/dist/widgets/presenter/typedef.js +106 -106
  202. package/dist/widgets/presenter/util.js +210 -210
  203. package/dist/widgets/virtual-viewport/VirtualViewport.svelte +196 -196
  204. package/dist/zod/all.js +33 -33
  205. package/dist/zod/generic.js +11 -11
  206. package/dist/zod/javascript.js +32 -32
  207. package/dist/zod/user.js +16 -16
  208. package/dist/zod/web.js +52 -52
  209. package/package.json +102 -102
@@ -1,455 +1,455 @@
1
- /* ------------------------------------------------------------------ Imports */
2
-
3
- import * as expect from '../expect/index.js';
4
-
5
- import { smallestFirst, largestFirst } from '../compare/index.js';
6
-
7
- import { objectGet, PATH_SEPARATOR } from '../object/index.js';
8
-
9
- import Selector from '../../classes/data/Selector.js';
10
-
11
- /* ---------------------------------------------------------------- Internals */
12
-
13
- const arraySlice = Array.prototype.slice;
14
- const arrayConcat = Array.prototype.concat;
15
-
16
- /* ------------------------------------------------------------------ Exports */
17
-
18
- export { PATH_SEPARATOR } from '../object/index.js';
19
-
20
- export { smallestFirst, largestFirst };
21
-
22
- export { arraySlice, arrayConcat };
23
-
24
- // -----------------------------------------------------------------------------
25
-
26
- /**
27
- * Convert a value to an array
28
- * - Converts an Arguments object to plain JS array
29
- * - If the value is undefined or null, an empty array is returned
30
- * - A primitive value is "wrapped" in an array
31
- *
32
- * @param {any} value - Item to convert
33
- *
34
- * @param {number} [start]
35
- * Index of the array to start extraction.
36
- * (the first element of the array is at index 0)
37
- *
38
- * @param {number} [end]
39
- * Index of the array where the extraction should end
40
- *
41
- * --
42
- *
43
- * @returns {Array} array
44
- *
45
- * --
46
- *
47
- * @example
48
- * toArray( [ 1, 2, 3, 4, 5 ], 2, 4 ) returns [ 3, 4 ]
49
- */
50
- export function toArray(value, start, end) {
51
- if (Array.isArray(value)) {
52
- //
53
- // Do not clone input value if it is already an array
54
- //
55
- // @note this behaviour differs from Array.from
56
- //
57
- if (undefined === start) {
58
- return value;
59
- }
60
-
61
- return value.slice(start, end);
62
- }
63
-
64
- if (undefined === value || null === value) {
65
- //
66
- // Return an empty array if value is undefined or null
67
- //
68
- // ==> this behaviour differs from Array.from() <==
69
- //
70
- return [];
71
- } else if (!(value instanceof Object)) {
72
- //
73
- // Wrap (non-object) in array (e.g. a string)
74
- //
75
- // @note this behaviour differs from Array.from
76
- //
77
- return [value];
78
- }
79
-
80
- if (undefined === start) {
81
- //
82
- // Construct a new array from the value
83
- //
84
- return Array.from(value);
85
- } else {
86
- return arraySlice(value, start, end);
87
- }
88
- }
89
-
90
- // -----------------------------------------------------------------------------
91
-
92
- /**
93
- * Convert an async iterator to an array
94
- * - If no async iterator is passed, the value will be processed by `from()`
95
- *
96
- * @param {AsyncIterator|mixed} value
97
- * Async iterator or value to convert to array
98
- *
99
- * @returns {Array} list of items returned by the iterator
100
- */
101
- export async function toArrayAsync(value) {
102
- if (value instanceof Object && typeof value[Symbol.asyncIterator] === 'function') {
103
- // value is an async iterator
104
-
105
- const arr = [];
106
-
107
- for await (const item of value) {
108
- arr.push(item);
109
- }
110
-
111
- return arr;
112
- } else {
113
- // value is not an async iterator
114
-
115
- return toArray(value);
116
- }
117
- }
118
-
119
- // -----------------------------------------------------------------------------
120
-
121
- /**
122
- * Convert a path string to an array path
123
- * - The path string will be spit at the `pathSeparator` token
124
- * - If the supplied path is already an array, the original array will
125
- * be returned
126
- *
127
- * @param {string|string[]} path
128
- * String or array path (e.g. "some.path.to")
129
- *
130
- * @param {string} [pathSeparator=PATH_SEPARATOR]
131
- * A custom path separator to use instead of the default "."
132
- *
133
- * @returns {string[]} array path (e.g. ["some", "path", "to"])
134
- */
135
- export function toArrayPath(path, pathSeparator = PATH_SEPARATOR) {
136
- if (typeof path === 'string') {
137
- return path.split(pathSeparator);
138
- } else if (Array.isArray(path)) {
139
- // path is already an array
140
- return path;
141
- } else {
142
- throw new Error('Missing or invalid parameter [path] (expected string or array)');
143
- }
144
- }
145
-
146
- // -----------------------------------------------------------------------------
147
-
148
- /**
149
- * Push a value to an array if it is not null, undefined or an empty string
150
- *
151
- * @template {arrray} T
152
- * @param {T} arr
153
- * @param {any} value
154
- *
155
- * @returns {T} arr
156
- */
157
- export function pushNotEmpty(arr, value) {
158
- expect.array(arr);
159
-
160
- if (value !== null && value !== undefined && value !== '') {
161
- arr.push(value);
162
- }
163
-
164
- return arr;
165
- }
166
-
167
- // -----------------------------------------------------------------------------
168
-
169
- /**
170
- * Loop over the supplied array and call the callback for every element
171
- * - The callback will receive the current element of the array as
172
- * first argument
173
- * - Via [additionalArguments], additional arguments may be supplied that
174
- * will be passed to the callback function
175
- *
176
- * @param {array} arr - The array to loop
177
- * @param {function} callback - Callback to call for every element
178
- * @param {array} additionalArguments The additional arguments
179
- */
180
- export function loop(arr, callback, additionalArguments) {
181
- expect.function(callback);
182
-
183
- if (!arr) {
184
- return;
185
- }
186
-
187
- expect.array(arr);
188
-
189
- if (!arr.length) {
190
- // Nothing to do
191
- return;
192
- }
193
-
194
- // >> CASE A: no additional arguments
195
-
196
- if (!additionalArguments) {
197
- for (let j = 0, n = arr.length; j < n; j = j + 1) {
198
- callback(arr[j]);
199
- }
200
-
201
- return;
202
- }
203
-
204
- // >> CASE B: additional arguments
205
-
206
- expect.arrayLike(additionalArguments);
207
-
208
- const args = [null, ...additionalArguments];
209
-
210
- for (let j = 0, n = arr.length; j < n; j = j + 1) {
211
- args[0] = arr[j];
212
- callback(...args);
213
- }
214
- }
215
-
216
- // -----------------------------------------------------------------------------
217
-
218
- /**
219
- * Get a list of all values from the items in the array at the
220
- * specified path
221
- *
222
- * @param {object[]} items
223
- *
224
- * @param {object} [options]
225
- *
226
- * @param {boolean} [options.outputAsSet=false]
227
- * Output a Set instead of an array
228
- *
229
- * @param {string} [options.pathSeparator=PATH_SEPARATOR]
230
- * A custom path separator to use instead of the default "."
231
- *
232
- *
233
- *
234
- * @returns {mixed[]} values
235
- */
236
- export function pathValues(items, path, options = {}) {
237
- // == Process parameters
238
-
239
- expect.array(items);
240
-
241
- const { outputAsSet = false, pathSeparator = PATH_SEPARATOR } = options;
242
-
243
- if (typeof path === 'string') {
244
- path = toArrayPath(path, pathSeparator);
245
- } else {
246
- expect.stringArray(path);
247
- }
248
-
249
- // >> CASE A: Output as plain Array
250
-
251
- if (!outputAsSet) {
252
- const values = [];
253
-
254
- for (let j = 0, n = items.length; j < n; j = j + 1) {
255
- const item = items[j];
256
-
257
- expect.object(item);
258
-
259
- values.push(objectGet(item, path));
260
- }
261
-
262
- return values;
263
- }
264
-
265
- // >> CASE B: Output as Set
266
-
267
- const values = new Set();
268
-
269
- for (let j = 0, n = items.length; j < n; j = j + 1) {
270
- const item = items[j];
271
-
272
- expect.object(item);
273
-
274
- values.add(objectGet(item, path));
275
- }
276
-
277
- return values;
278
- }
279
-
280
- // -----------------------------------------------------------------------------
281
-
282
- /**
283
- * Sort function that sorts a list of objects by values encountered at the
284
- * specified key values of the object.
285
- * - Sorts array inline (no new array is returned)
286
- * - This method is faster than `sortByPathValue` since the value lookup in the
287
- * items can be done faster
288
- *
289
- * @param {Object[]} items - List of items to sort
290
- *
291
- * @param {string} key
292
- * Object key to use for getting the values in the items to compare.
293
- *
294
- * @param {function} [compareFn=smallestFirst]
295
- * Function to use to compare values. See `compare.js`.
296
- */
297
- export function sortByKeyValue(items, key, compareFn = smallestFirst) {
298
- expect.function(compareFn);
299
-
300
- expect.array(items);
301
-
302
- expect.string(key);
303
-
304
- items.sort((itemA, itemB) => {
305
- return compareFn(itemA[key], itemB[key]);
306
- });
307
- }
308
-
309
- // -----------------------------------------------------------------------------
310
-
311
- /**
312
- * Sort function that sorts a list of objects by values encountered at the
313
- * specified key values of the object.
314
- * - Sorts array inline (no new array is returned)
315
- * - This method is faster than `sortByPathValue` since the value lookup in the
316
- * items can be done faster
317
- *
318
- * @param {Object[]} items - List of items to sort
319
- *
320
- * @param {string} key
321
- * Object key to use for getting the values in the items to compare.
322
- *
323
- * @param {function} [compareFn=smallestFirst]
324
- * Function to use to compare values. See `compare.js`.
325
- */
326
- export function sortByKeyValueReversed(items, key, compareFn = largestFirst) {
327
- expect.function(compareFn);
328
-
329
- expect.array(items);
330
-
331
- expect.string(key);
332
-
333
- items.sort((itemA, itemB) => {
334
- return compareFn(itemA[key], itemB[key]);
335
- });
336
- }
337
-
338
- // -----------------------------------------------------------------------------
339
-
340
- /**
341
- * Sort function that sorts a list of objects by values encountered at the
342
- * specified object path.
343
- * - Sorts array inline (no new array is returned)
344
- *
345
- * @param {Object[]} items - List of items to sort
346
- *
347
- * @param {string[]|string} path
348
- * Path to use for getting the values in the items to compare.
349
- * If a string path has been supplied, the default path separator
350
- * (PATH_SEPARATOR) is assumed. Use `toArrayPath` to convert paths with
351
- * custom path separators.
352
- *
353
- * @param {function} [compareFn=smallestFirst]
354
- * Function to use to compare values. See `compare.js`.
355
- */
356
- export function sortByPathValue(items, path, compareFn = smallestFirst) {
357
- expect.function(compareFn);
358
-
359
- expect.array(items);
360
-
361
- if (typeof path === 'string') {
362
- path = toArrayPath(path);
363
- } else {
364
- expect.stringArray(path);
365
- }
366
-
367
- const cache = new Map();
368
-
369
- items.sort((itemA, itemB) => {
370
- let valueA = cache.get(itemA);
371
-
372
- if (undefined === valueA) {
373
- valueA = objectGet(itemA, path);
374
-
375
- if (undefined !== valueA) {
376
- cache.set(itemA, valueA);
377
- }
378
- }
379
-
380
- let valueB = cache.get(itemB);
381
-
382
- if (undefined === valueB) {
383
- valueB = objectGet(itemB, path);
384
-
385
- if (undefined !== valueB) {
386
- cache.set(itemB, valueB);
387
- }
388
- }
389
-
390
- return compareFn(valueA, valueB);
391
- });
392
-
393
- cache.clear();
394
- }
395
-
396
- // -----------------------------------------------------------------------------
397
-
398
- /**
399
- * Find the first item in the list of objects that matches the selector
400
- * - All items in the supplied array must be objects
401
- *
402
- * @template {object} T
403
- * @param {T[]} arr
404
- * @param {object|null} selector
405
- *
406
- * @returns {T|null} first matched item
407
- */
408
- export function findFirst(arr, selector) {
409
- const selectorObj = new Selector(selector);
410
-
411
- return selectorObj.findFirst(arr);
412
- }
413
-
414
- // -----------------------------------------------------------------------------
415
-
416
- /**
417
- * Returns all items from the list of items that match the selector
418
- * - All items in the supplied array must be objects
419
- *
420
- * @template {object} T
421
- * @param {T[]} arr
422
- * @param {object|null} selector
423
- *
424
- * @returns {T[]} matching items
425
- */
426
- export function findAll(arr, selector) {
427
- const selectorObj = new Selector(selector);
428
-
429
- return selectorObj.findAll(arr);
430
- }
431
-
432
- // -----------------------------------------------------------------------------
433
-
434
- /**
435
- * Convert array to an object using a list of keys for each index
436
- *
437
- * @param {array} arr
438
- * @param {string[]} keys
439
- *
440
- * @returns {object}
441
- */
442
- export function arrayToObject(arr, keys) {
443
- expect.array(arr);
444
- expect.array(keys);
445
-
446
- const obj = {};
447
-
448
- const n = Math.min(arr.length, keys.length);
449
-
450
- for (let j = 0; j < n; j = j + 1) {
451
- obj[keys[j]] = arr[j];
452
- }
453
-
454
- return obj;
455
- }
1
+ /* ------------------------------------------------------------------ Imports */
2
+
3
+ import * as expect from '../expect/index.js';
4
+
5
+ import { smallestFirst, largestFirst } from '../compare/index.js';
6
+
7
+ import { objectGet, PATH_SEPARATOR } from '../object/index.js';
8
+
9
+ import Selector from '../../classes/data/Selector.js';
10
+
11
+ /* ---------------------------------------------------------------- Internals */
12
+
13
+ const arraySlice = Array.prototype.slice;
14
+ const arrayConcat = Array.prototype.concat;
15
+
16
+ /* ------------------------------------------------------------------ Exports */
17
+
18
+ export { PATH_SEPARATOR } from '../object/index.js';
19
+
20
+ export { smallestFirst, largestFirst };
21
+
22
+ export { arraySlice, arrayConcat };
23
+
24
+ // -----------------------------------------------------------------------------
25
+
26
+ /**
27
+ * Convert a value to an array
28
+ * - Converts an Arguments object to plain JS array
29
+ * - If the value is undefined or null, an empty array is returned
30
+ * - A primitive value is "wrapped" in an array
31
+ *
32
+ * @param {any} value - Item to convert
33
+ *
34
+ * @param {number} [start]
35
+ * Index of the array to start extraction.
36
+ * (the first element of the array is at index 0)
37
+ *
38
+ * @param {number} [end]
39
+ * Index of the array where the extraction should end
40
+ *
41
+ * --
42
+ *
43
+ * @returns {Array} array
44
+ *
45
+ * --
46
+ *
47
+ * @example
48
+ * toArray( [ 1, 2, 3, 4, 5 ], 2, 4 ) returns [ 3, 4 ]
49
+ */
50
+ export function toArray(value, start, end) {
51
+ if (Array.isArray(value)) {
52
+ //
53
+ // Do not clone input value if it is already an array
54
+ //
55
+ // @note this behaviour differs from Array.from
56
+ //
57
+ if (undefined === start) {
58
+ return value;
59
+ }
60
+
61
+ return value.slice(start, end);
62
+ }
63
+
64
+ if (undefined === value || null === value) {
65
+ //
66
+ // Return an empty array if value is undefined or null
67
+ //
68
+ // ==> this behaviour differs from Array.from() <==
69
+ //
70
+ return [];
71
+ } else if (!(value instanceof Object)) {
72
+ //
73
+ // Wrap (non-object) in array (e.g. a string)
74
+ //
75
+ // @note this behaviour differs from Array.from
76
+ //
77
+ return [value];
78
+ }
79
+
80
+ if (undefined === start) {
81
+ //
82
+ // Construct a new array from the value
83
+ //
84
+ return Array.from(value);
85
+ } else {
86
+ return arraySlice(value, start, end);
87
+ }
88
+ }
89
+
90
+ // -----------------------------------------------------------------------------
91
+
92
+ /**
93
+ * Convert an async iterator to an array
94
+ * - If no async iterator is passed, the value will be processed by `from()`
95
+ *
96
+ * @param {AsyncIterator|mixed} value
97
+ * Async iterator or value to convert to array
98
+ *
99
+ * @returns {Array} list of items returned by the iterator
100
+ */
101
+ export async function toArrayAsync(value) {
102
+ if (value instanceof Object && typeof value[Symbol.asyncIterator] === 'function') {
103
+ // value is an async iterator
104
+
105
+ const arr = [];
106
+
107
+ for await (const item of value) {
108
+ arr.push(item);
109
+ }
110
+
111
+ return arr;
112
+ } else {
113
+ // value is not an async iterator
114
+
115
+ return toArray(value);
116
+ }
117
+ }
118
+
119
+ // -----------------------------------------------------------------------------
120
+
121
+ /**
122
+ * Convert a path string to an array path
123
+ * - The path string will be spit at the `pathSeparator` token
124
+ * - If the supplied path is already an array, the original array will
125
+ * be returned
126
+ *
127
+ * @param {string|string[]} path
128
+ * String or array path (e.g. "some.path.to")
129
+ *
130
+ * @param {string} [pathSeparator=PATH_SEPARATOR]
131
+ * A custom path separator to use instead of the default "."
132
+ *
133
+ * @returns {string[]} array path (e.g. ["some", "path", "to"])
134
+ */
135
+ export function toArrayPath(path, pathSeparator = PATH_SEPARATOR) {
136
+ if (typeof path === 'string') {
137
+ return path.split(pathSeparator);
138
+ } else if (Array.isArray(path)) {
139
+ // path is already an array
140
+ return path;
141
+ } else {
142
+ throw new Error('Missing or invalid parameter [path] (expected string or array)');
143
+ }
144
+ }
145
+
146
+ // -----------------------------------------------------------------------------
147
+
148
+ /**
149
+ * Push a value to an array if it is not null, undefined or an empty string
150
+ *
151
+ * @template {arrray} T
152
+ * @param {T} arr
153
+ * @param {any} value
154
+ *
155
+ * @returns {T} arr
156
+ */
157
+ export function pushNotEmpty(arr, value) {
158
+ expect.array(arr);
159
+
160
+ if (value !== null && value !== undefined && value !== '') {
161
+ arr.push(value);
162
+ }
163
+
164
+ return arr;
165
+ }
166
+
167
+ // -----------------------------------------------------------------------------
168
+
169
+ /**
170
+ * Loop over the supplied array and call the callback for every element
171
+ * - The callback will receive the current element of the array as
172
+ * first argument
173
+ * - Via [additionalArguments], additional arguments may be supplied that
174
+ * will be passed to the callback function
175
+ *
176
+ * @param {array} arr - The array to loop
177
+ * @param {function} callback - Callback to call for every element
178
+ * @param {array} additionalArguments The additional arguments
179
+ */
180
+ export function loop(arr, callback, additionalArguments) {
181
+ expect.function(callback);
182
+
183
+ if (!arr) {
184
+ return;
185
+ }
186
+
187
+ expect.array(arr);
188
+
189
+ if (!arr.length) {
190
+ // Nothing to do
191
+ return;
192
+ }
193
+
194
+ // >> CASE A: no additional arguments
195
+
196
+ if (!additionalArguments) {
197
+ for (let j = 0, n = arr.length; j < n; j = j + 1) {
198
+ callback(arr[j]);
199
+ }
200
+
201
+ return;
202
+ }
203
+
204
+ // >> CASE B: additional arguments
205
+
206
+ expect.arrayLike(additionalArguments);
207
+
208
+ const args = [null, ...additionalArguments];
209
+
210
+ for (let j = 0, n = arr.length; j < n; j = j + 1) {
211
+ args[0] = arr[j];
212
+ callback(...args);
213
+ }
214
+ }
215
+
216
+ // -----------------------------------------------------------------------------
217
+
218
+ /**
219
+ * Get a list of all values from the items in the array at the
220
+ * specified path
221
+ *
222
+ * @param {object[]} items
223
+ *
224
+ * @param {object} [options]
225
+ *
226
+ * @param {boolean} [options.outputAsSet=false]
227
+ * Output a Set instead of an array
228
+ *
229
+ * @param {string} [options.pathSeparator=PATH_SEPARATOR]
230
+ * A custom path separator to use instead of the default "."
231
+ *
232
+ *
233
+ *
234
+ * @returns {mixed[]} values
235
+ */
236
+ export function pathValues(items, path, options = {}) {
237
+ // == Process parameters
238
+
239
+ expect.array(items);
240
+
241
+ const { outputAsSet = false, pathSeparator = PATH_SEPARATOR } = options;
242
+
243
+ if (typeof path === 'string') {
244
+ path = toArrayPath(path, pathSeparator);
245
+ } else {
246
+ expect.stringArray(path);
247
+ }
248
+
249
+ // >> CASE A: Output as plain Array
250
+
251
+ if (!outputAsSet) {
252
+ const values = [];
253
+
254
+ for (let j = 0, n = items.length; j < n; j = j + 1) {
255
+ const item = items[j];
256
+
257
+ expect.object(item);
258
+
259
+ values.push(objectGet(item, path));
260
+ }
261
+
262
+ return values;
263
+ }
264
+
265
+ // >> CASE B: Output as Set
266
+
267
+ const values = new Set();
268
+
269
+ for (let j = 0, n = items.length; j < n; j = j + 1) {
270
+ const item = items[j];
271
+
272
+ expect.object(item);
273
+
274
+ values.add(objectGet(item, path));
275
+ }
276
+
277
+ return values;
278
+ }
279
+
280
+ // -----------------------------------------------------------------------------
281
+
282
+ /**
283
+ * Sort function that sorts a list of objects by values encountered at the
284
+ * specified key values of the object.
285
+ * - Sorts array inline (no new array is returned)
286
+ * - This method is faster than `sortByPathValue` since the value lookup in the
287
+ * items can be done faster
288
+ *
289
+ * @param {Object[]} items - List of items to sort
290
+ *
291
+ * @param {string} key
292
+ * Object key to use for getting the values in the items to compare.
293
+ *
294
+ * @param {function} [compareFn=smallestFirst]
295
+ * Function to use to compare values. See `compare.js`.
296
+ */
297
+ export function sortByKeyValue(items, key, compareFn = smallestFirst) {
298
+ expect.function(compareFn);
299
+
300
+ expect.array(items);
301
+
302
+ expect.string(key);
303
+
304
+ items.sort((itemA, itemB) => {
305
+ return compareFn(itemA[key], itemB[key]);
306
+ });
307
+ }
308
+
309
+ // -----------------------------------------------------------------------------
310
+
311
+ /**
312
+ * Sort function that sorts a list of objects by values encountered at the
313
+ * specified key values of the object.
314
+ * - Sorts array inline (no new array is returned)
315
+ * - This method is faster than `sortByPathValue` since the value lookup in the
316
+ * items can be done faster
317
+ *
318
+ * @param {Object[]} items - List of items to sort
319
+ *
320
+ * @param {string} key
321
+ * Object key to use for getting the values in the items to compare.
322
+ *
323
+ * @param {function} [compareFn=smallestFirst]
324
+ * Function to use to compare values. See `compare.js`.
325
+ */
326
+ export function sortByKeyValueReversed(items, key, compareFn = largestFirst) {
327
+ expect.function(compareFn);
328
+
329
+ expect.array(items);
330
+
331
+ expect.string(key);
332
+
333
+ items.sort((itemA, itemB) => {
334
+ return compareFn(itemA[key], itemB[key]);
335
+ });
336
+ }
337
+
338
+ // -----------------------------------------------------------------------------
339
+
340
+ /**
341
+ * Sort function that sorts a list of objects by values encountered at the
342
+ * specified object path.
343
+ * - Sorts array inline (no new array is returned)
344
+ *
345
+ * @param {Object[]} items - List of items to sort
346
+ *
347
+ * @param {string[]|string} path
348
+ * Path to use for getting the values in the items to compare.
349
+ * If a string path has been supplied, the default path separator
350
+ * (PATH_SEPARATOR) is assumed. Use `toArrayPath` to convert paths with
351
+ * custom path separators.
352
+ *
353
+ * @param {function} [compareFn=smallestFirst]
354
+ * Function to use to compare values. See `compare.js`.
355
+ */
356
+ export function sortByPathValue(items, path, compareFn = smallestFirst) {
357
+ expect.function(compareFn);
358
+
359
+ expect.array(items);
360
+
361
+ if (typeof path === 'string') {
362
+ path = toArrayPath(path);
363
+ } else {
364
+ expect.stringArray(path);
365
+ }
366
+
367
+ const cache = new Map();
368
+
369
+ items.sort((itemA, itemB) => {
370
+ let valueA = cache.get(itemA);
371
+
372
+ if (undefined === valueA) {
373
+ valueA = objectGet(itemA, path);
374
+
375
+ if (undefined !== valueA) {
376
+ cache.set(itemA, valueA);
377
+ }
378
+ }
379
+
380
+ let valueB = cache.get(itemB);
381
+
382
+ if (undefined === valueB) {
383
+ valueB = objectGet(itemB, path);
384
+
385
+ if (undefined !== valueB) {
386
+ cache.set(itemB, valueB);
387
+ }
388
+ }
389
+
390
+ return compareFn(valueA, valueB);
391
+ });
392
+
393
+ cache.clear();
394
+ }
395
+
396
+ // -----------------------------------------------------------------------------
397
+
398
+ /**
399
+ * Find the first item in the list of objects that matches the selector
400
+ * - All items in the supplied array must be objects
401
+ *
402
+ * @template {object} T
403
+ * @param {T[]} arr
404
+ * @param {object|null} selector
405
+ *
406
+ * @returns {T|null} first matched item
407
+ */
408
+ export function findFirst(arr, selector) {
409
+ const selectorObj = new Selector(selector);
410
+
411
+ return selectorObj.findFirst(arr);
412
+ }
413
+
414
+ // -----------------------------------------------------------------------------
415
+
416
+ /**
417
+ * Returns all items from the list of items that match the selector
418
+ * - All items in the supplied array must be objects
419
+ *
420
+ * @template {object} T
421
+ * @param {T[]} arr
422
+ * @param {object|null} selector
423
+ *
424
+ * @returns {T[]} matching items
425
+ */
426
+ export function findAll(arr, selector) {
427
+ const selectorObj = new Selector(selector);
428
+
429
+ return selectorObj.findAll(arr);
430
+ }
431
+
432
+ // -----------------------------------------------------------------------------
433
+
434
+ /**
435
+ * Convert array to an object using a list of keys for each index
436
+ *
437
+ * @param {array} arr
438
+ * @param {string[]} keys
439
+ *
440
+ * @returns {object}
441
+ */
442
+ export function arrayToObject(arr, keys) {
443
+ expect.array(arr);
444
+ expect.array(keys);
445
+
446
+ const obj = {};
447
+
448
+ const n = Math.min(arr.length, keys.length);
449
+
450
+ for (let j = 0; j < n; j = j + 1) {
451
+ obj[keys[j]] = arr[j];
452
+ }
453
+
454
+ return obj;
455
+ }