@hkdigital/lib-sveltekit 0.1.6 → 0.1.7

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 (215) hide show
  1. package/README.md +127 -127
  2. package/dist/classes/data/IterableTree.js +243 -243
  3. package/dist/classes/data/Selector.js +190 -190
  4. package/dist/classes/data/index.js +2 -2
  5. package/dist/classes/index.js +3 -3
  6. package/dist/classes/promise/HkPromise.js +377 -377
  7. package/dist/classes/promise/index.js +1 -1
  8. package/dist/classes/stores/SubscribersCount.js +107 -107
  9. package/dist/classes/stores/index.js +1 -1
  10. package/dist/classes/streams/LogTransformStream.js +19 -19
  11. package/dist/classes/streams/ServerEventsStore.js +110 -110
  12. package/dist/classes/streams/TimeStampSource.js +26 -26
  13. package/dist/classes/streams/index.js +3 -3
  14. package/dist/classes/svelte/audio/AudioLoader.svelte.js +58 -58
  15. package/dist/classes/svelte/audio/AudioScene.svelte.js +282 -282
  16. package/dist/classes/svelte/audio/mocks.js +35 -35
  17. package/dist/classes/svelte/final-state-machine/FiniteStateMachine.svelte.js +133 -133
  18. package/dist/classes/svelte/final-state-machine/index.js +1 -1
  19. package/dist/classes/svelte/image/ImageLoader.svelte.js +47 -47
  20. package/dist/classes/svelte/image/ImageScene.svelte.js +253 -253
  21. package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +152 -152
  22. package/dist/classes/svelte/image/index.js +4 -4
  23. package/dist/classes/svelte/image/mocks.js +35 -35
  24. package/dist/classes/svelte/image/typedef.js +8 -8
  25. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
  26. package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
  27. package/dist/classes/svelte/loading-state-machine/index.js +3 -3
  28. package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +331 -331
  29. package/dist/classes/svelte/network-loader/constants.js +3 -3
  30. package/dist/classes/svelte/network-loader/index.js +3 -3
  31. package/dist/classes/svelte/network-loader/mocks.js +30 -30
  32. package/dist/classes/svelte/network-loader/typedef.js +8 -8
  33. package/dist/components/area/HkArea.svelte +49 -49
  34. package/dist/components/area/HkArea.svelte.d.ts +14 -0
  35. package/dist/components/area/HkGridArea.svelte +77 -77
  36. package/dist/components/area/HkGridArea.svelte.d.ts +22 -0
  37. package/dist/components/area/index.js +2 -2
  38. package/dist/components/boxes/game-box/GameBox.svelte +112 -112
  39. package/dist/components/boxes/game-box/GameBox.svelte.d.ts +15 -0
  40. package/dist/components/boxes/game-box/gamebox.util.js +83 -83
  41. package/dist/components/boxes/index.js +2 -2
  42. package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte +199 -199
  43. package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte.d.ts +22 -0
  44. package/dist/components/buttons/button/Button.svelte +76 -75
  45. package/dist/components/buttons/button/Button.svelte.d.ts +21 -0
  46. package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -0
  47. package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte.d.ts +16 -0
  48. package/dist/components/buttons/button-text/TextButton.svelte +21 -21
  49. package/dist/components/buttons/button-text/TextButton.svelte.d.ts +7 -0
  50. package/dist/components/buttons/index.d.ts +1 -0
  51. package/dist/components/buttons/index.js +3 -2
  52. package/dist/components/hkdev/blocks/TextBlock.svelte +46 -46
  53. package/dist/components/hkdev/blocks/TextBlock.svelte.d.ts +13 -0
  54. package/dist/components/hkdev/buttons/CheckButton.svelte +62 -62
  55. package/dist/components/hkdev/buttons/CheckButton.svelte.d.ts +18 -0
  56. package/dist/components/{icon → icons}/HkIcon.svelte +86 -86
  57. package/dist/components/icons/HkIcon.svelte.d.ts +22 -0
  58. package/dist/components/{icon → icons}/HkTabIcon.svelte +116 -116
  59. package/dist/components/icons/HkTabIcon.svelte.d.ts +40 -0
  60. package/dist/components/icons/SteezeIcon.svelte +96 -0
  61. package/dist/components/icons/SteezeIcon.svelte.d.ts +22 -0
  62. package/dist/components/{icon → icons}/index.d.ts +1 -0
  63. package/dist/components/{icon → icons}/index.js +6 -4
  64. package/dist/components/{icon → icons}/typedef.js +16 -16
  65. package/dist/components/image/ImageBox.svelte +208 -208
  66. package/dist/components/image/ImageBox.svelte.d.ts +19 -0
  67. package/dist/components/image/index.js +5 -5
  68. package/dist/components/image/typedef.js +32 -32
  69. package/dist/components/index.js +2 -2
  70. package/dist/components/inputs/index.js +1 -1
  71. package/dist/components/inputs/text-input/TestTextInput.svelte__ +102 -102
  72. package/dist/components/inputs/text-input/TextInput.svelte +226 -226
  73. package/dist/components/inputs/text-input/TextInput.svelte.d.ts +28 -0
  74. package/dist/components/inputs/text-input/TextInput.svelte___ +83 -83
  75. package/dist/components/inputs/text-input/assets/IconInvalid.svelte +14 -14
  76. package/dist/components/inputs/text-input/assets/IconValid.svelte +12 -12
  77. package/dist/components/layout/HkAppLayout.state.svelte.js +25 -25
  78. package/dist/components/layout/HkAppLayout.svelte +251 -251
  79. package/dist/components/layout/HkAppLayout.svelte.d.ts +11 -0
  80. package/dist/components/layout/HkGridLayers.svelte +82 -82
  81. package/dist/components/layout/HkGridLayers.svelte.d.ts +23 -0
  82. package/dist/components/layout/index.js +9 -9
  83. package/dist/components/panels/index.js +1 -1
  84. package/dist/components/panels/plain-panel/PlainPanel.svelte +33 -33
  85. package/dist/components/panels/plain-panel/PlainPanel.svelte.d.ts +12 -0
  86. package/dist/components/rows/index.js +3 -3
  87. package/dist/components/rows/panel-grid-row/PanelGridRow.svelte +104 -104
  88. package/dist/components/rows/panel-grid-row/PanelGridRow.svelte.d.ts +14 -0
  89. package/dist/components/rows/panel-row-2/PanelRow2.svelte +40 -40
  90. package/dist/components/rows/panel-row-2/PanelRow2.svelte.d.ts +14 -0
  91. package/dist/components/tab-bar/HkTabBar.state.svelte.js +149 -149
  92. package/dist/components/tab-bar/HkTabBar.svelte +74 -74
  93. package/dist/components/tab-bar/HkTabBar.svelte.d.ts +18 -0
  94. package/dist/components/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
  95. package/dist/components/tab-bar/HkTabBarSelector.svelte +49 -49
  96. package/dist/components/tab-bar/HkTabBarSelector.svelte.d.ts +19 -0
  97. package/dist/components/tab-bar/index.js +17 -17
  98. package/dist/components/tab-bar/typedef.d.ts +1 -1
  99. package/dist/components/tab-bar/typedef.js +8 -8
  100. package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte +179 -179
  101. package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte.d.ts +10 -0
  102. package/dist/components/widgets/compare-left-right/index.js +1 -1
  103. package/dist/components/widgets/scale-control/index.js +1 -1
  104. package/dist/config/imagetools-config.js +189 -189
  105. package/dist/config/imagetools.d.ts +71 -71
  106. package/dist/config/typedef.js +8 -8
  107. package/dist/constants/errors/api.js +9 -9
  108. package/dist/constants/errors/generic.js +5 -5
  109. package/dist/constants/errors/index.js +3 -3
  110. package/dist/constants/errors/jwt.js +5 -5
  111. package/dist/constants/http/headers.js +6 -6
  112. package/dist/constants/http/index.js +2 -2
  113. package/dist/constants/http/methods.js +2 -2
  114. package/dist/constants/index.js +3 -3
  115. package/dist/constants/mime/application.js +5 -5
  116. package/dist/constants/mime/audio.js +13 -13
  117. package/dist/constants/mime/image.js +3 -3
  118. package/dist/constants/mime/index.js +4 -4
  119. package/dist/constants/mime/text.js +2 -2
  120. package/dist/constants/regexp/index.js +31 -31
  121. package/dist/constants/regexp/inspiratie.js__ +95 -95
  122. package/dist/constants/regexp/text.js +49 -49
  123. package/dist/constants/regexp/user.js +32 -32
  124. package/dist/constants/regexp/web.js +3 -3
  125. package/dist/constants/state-labels/input-states.js +11 -11
  126. package/dist/constants/state-labels/submit-states.js +4 -4
  127. package/dist/constants/time.js +28 -28
  128. package/dist/css/tw-prose.postcss__ +259 -259
  129. package/dist/css/utilities.postcss +43 -43
  130. package/dist/design/design-config.js +73 -73
  131. package/dist/design/tailwind-theme-extend.d.ts +4 -4
  132. package/dist/design/tailwind-theme-extend.js +160 -151
  133. package/dist/schemas/index.js +1 -1
  134. package/dist/schemas/validate-url.js +180 -180
  135. package/dist/server/index.js +1 -1
  136. package/dist/server/logger.js +94 -94
  137. package/dist/states/index.js +1 -1
  138. package/dist/states/navigation.svelte.js +55 -55
  139. package/dist/stores/index.js +1 -1
  140. package/dist/stores/theme.js +80 -80
  141. package/dist/themes/hkdev/components/blocks/text-block.postcss +40 -40
  142. package/dist/themes/hkdev/components/boxes/game-box.postcss +13 -13
  143. package/dist/themes/hkdev/components/buttons/button-icon-steeze.postcss +22 -0
  144. package/dist/themes/hkdev/components/buttons/button-text.postcss +34 -34
  145. package/dist/themes/hkdev/components/buttons/button.postcss +138 -138
  146. package/dist/themes/hkdev/components/buttons/button.postcss__ +40 -0
  147. package/dist/themes/hkdev/components/buttons/button.postcss___ +91 -0
  148. package/dist/themes/hkdev/components/buttons/skip-button.postcss +8 -8
  149. package/dist/themes/hkdev/components/icons/icon-steeze.postcss +22 -0
  150. package/dist/themes/hkdev/components/inputs/text-input.postcss +108 -108
  151. package/dist/themes/hkdev/components/panels/plain-panel.postcss +46 -46
  152. package/dist/themes/hkdev/components/panels/speech-bubble.postcss +52 -52
  153. package/dist/themes/hkdev/components/rows/panel-grid-row.postcss +7 -7
  154. package/dist/themes/hkdev/components/rows/panel-row-2.postcss +9 -9
  155. package/dist/themes/hkdev/components.postcss +61 -55
  156. package/dist/themes/hkdev/debug.postcss +1 -1
  157. package/dist/themes/hkdev/global/layout.postcss +39 -39
  158. package/dist/themes/hkdev/global/on-colors.postcss +53 -53
  159. package/dist/themes/hkdev/global/text.postcss__ +34 -34
  160. package/dist/themes/hkdev/global/vars.postcss__ +7 -7
  161. package/dist/themes/hkdev/globals.postcss +11 -11
  162. package/dist/themes/hkdev/responsive.postcss +12 -12
  163. package/dist/themes/hkdev/theme-ext.js +15 -15
  164. package/dist/themes/hkdev/theme.js +227 -227
  165. package/dist/themes/index.js +1 -1
  166. package/dist/util/array/index.js +455 -455
  167. package/dist/util/compare/index.js +247 -247
  168. package/dist/util/css/css-vars.js +83 -83
  169. package/dist/util/css/index.js +1 -1
  170. package/dist/util/design-system/components/states.js +22 -22
  171. package/dist/util/design-system/css/clamp.js +66 -66
  172. package/dist/util/design-system/css/root-design-vars.js +100 -100
  173. package/dist/util/design-system/index.js +5 -5
  174. package/dist/util/design-system/layout/scaling.js +97 -97
  175. package/dist/util/design-system/tailwind.js +289 -289
  176. package/dist/util/expect/arrays.js +47 -47
  177. package/dist/util/expect/index.js +259 -259
  178. package/dist/util/expect/primitives.js +55 -55
  179. package/dist/util/expect/url.js +60 -60
  180. package/dist/util/function/index.js +218 -218
  181. package/dist/util/http/errors.js +97 -97
  182. package/dist/util/http/headers.js +45 -45
  183. package/dist/util/http/http-request.js +273 -273
  184. package/dist/util/http/index.js +22 -22
  185. package/dist/util/http/json-request.js +143 -143
  186. package/dist/util/http/mocks.js +65 -65
  187. package/dist/util/http/response.js +228 -228
  188. package/dist/util/http/url.js +52 -52
  189. package/dist/util/image/index.js +86 -86
  190. package/dist/util/index.js +2 -2
  191. package/dist/util/is/index.js +140 -140
  192. package/dist/util/iterate/index.js +234 -234
  193. package/dist/util/object/index.js +1361 -1361
  194. package/dist/util/singleton/index.js +97 -97
  195. package/dist/util/string/index.js +184 -184
  196. package/dist/util/svelte/index.js +2 -2
  197. package/dist/util/svelte/observe/index.js +49 -49
  198. package/dist/util/svelte/state-context/index.js +83 -83
  199. package/dist/util/svelte/wait/index.js +38 -38
  200. package/dist/util/sveltekit/index.js +1 -1
  201. package/dist/util/sveltekit/route-folders/index.js +82 -82
  202. package/dist/util/time/index.js +339 -339
  203. package/dist/valibot/date.js__ +10 -10
  204. package/dist/valibot/index.js +9 -9
  205. package/dist/valibot/url.js +95 -95
  206. package/dist/valibot/user.js +23 -23
  207. package/dist/zod/all.js +33 -33
  208. package/dist/zod/generic.js +11 -11
  209. package/dist/zod/javascript.js +32 -32
  210. package/dist/zod/user.js +16 -16
  211. package/dist/zod/web.js +52 -52
  212. package/package.json +99 -99
  213. package/dist/components/icon/HkIcon.svelte.d.ts +0 -10
  214. package/dist/components/icon/HkTabIcon.svelte.d.ts +0 -19
  215. /package/dist/components/{icon → icons}/typedef.d.ts +0 -0
@@ -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
+ }