@hkdigital/lib-sveltekit 0.1.4 → 0.1.6
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.
- package/README.md +127 -127
- package/dist/classes/data/IterableTree.js +243 -243
- package/dist/classes/data/Selector.js +190 -190
- package/dist/classes/data/index.js +2 -2
- package/dist/classes/index.js +3 -3
- package/dist/classes/promise/HkPromise.js +377 -377
- package/dist/classes/promise/index.js +1 -1
- package/dist/classes/stores/SubscribersCount.js +107 -107
- package/dist/classes/stores/index.js +1 -1
- package/dist/classes/streams/LogTransformStream.js +19 -19
- package/dist/classes/streams/ServerEventsStore.js +110 -110
- package/dist/classes/streams/TimeStampSource.js +26 -26
- package/dist/classes/streams/index.js +3 -3
- package/dist/classes/{svkit → svelte}/audio/AudioLoader.svelte.js +58 -58
- package/dist/classes/{svkit → svelte}/audio/AudioScene.svelte.js +282 -282
- package/dist/classes/{svkit → svelte}/audio/mocks.js +35 -35
- package/dist/classes/{svkit → svelte}/final-state-machine/FiniteStateMachine.svelte.js +133 -133
- package/dist/classes/{svkit → svelte}/final-state-machine/index.js +1 -1
- package/dist/classes/{svkit → svelte}/image/ImageLoader.svelte.js +47 -47
- package/dist/classes/{svkit → svelte}/image/ImageScene.svelte.js +253 -253
- package/dist/classes/{svkit → svelte}/image/ImageVariantsLoader.svelte.js +152 -152
- package/dist/classes/{svkit → svelte}/image/index.js +4 -4
- package/dist/classes/{svkit → svelte}/image/mocks.js +35 -35
- package/dist/classes/{svkit → svelte}/image/typedef.js +8 -8
- package/dist/classes/{svkit → svelte}/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
- package/dist/classes/{svkit → svelte}/loading-state-machine/constants.js +16 -16
- package/dist/classes/{svkit → svelte}/loading-state-machine/index.js +3 -3
- package/dist/classes/{svkit → svelte}/network-loader/NetworkLoader.svelte.js +331 -331
- package/dist/classes/{svkit → svelte}/network-loader/constants.js +3 -3
- package/dist/classes/{svkit → svelte}/network-loader/index.js +3 -3
- package/dist/classes/{svkit → svelte}/network-loader/mocks.js +30 -30
- package/dist/classes/{svkit → svelte}/network-loader/typedef.js +8 -8
- package/dist/components/area/HkArea.svelte +49 -49
- package/dist/components/area/HkArea.svelte.d.ts +0 -14
- package/dist/components/area/HkGridArea.svelte +77 -77
- package/dist/components/area/HkGridArea.svelte.d.ts +0 -22
- package/dist/components/area/index.js +2 -2
- package/dist/components/boxes/game-box/GameBox.svelte +112 -112
- package/dist/components/boxes/game-box/GameBox.svelte.d.ts +0 -15
- package/dist/components/boxes/game-box/gamebox.util.js +83 -83
- package/dist/components/boxes/index.js +2 -2
- package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte +199 -199
- package/dist/components/boxes/virtual-viewport/VirtualViewport.svelte.d.ts +0 -22
- package/dist/components/buttons/button/Button.svelte +75 -75
- package/dist/components/buttons/button/Button.svelte.d.ts +0 -21
- package/dist/components/buttons/button-text/TextButton.svelte +21 -21
- package/dist/components/buttons/button-text/TextButton.svelte.d.ts +0 -7
- package/dist/components/buttons/index.js +2 -2
- package/dist/components/hkdev/blocks/TextBlock.svelte +46 -46
- package/dist/components/hkdev/blocks/TextBlock.svelte.d.ts +0 -13
- package/dist/components/hkdev/buttons/CheckButton.svelte +62 -62
- package/dist/components/hkdev/buttons/CheckButton.svelte.d.ts +0 -18
- package/dist/components/icon/HkIcon.svelte +86 -86
- package/dist/components/icon/HkIcon.svelte.d.ts +0 -12
- package/dist/components/icon/HkTabIcon.svelte +116 -116
- package/dist/components/icon/HkTabIcon.svelte.d.ts +0 -21
- package/dist/components/icon/index.js +4 -4
- package/dist/components/icon/typedef.js +16 -16
- package/dist/components/image/ImageBox.svelte +208 -208
- package/dist/components/image/ImageBox.svelte.d.ts +2 -21
- package/dist/components/image/index.js +5 -5
- package/dist/components/image/typedef.js +32 -32
- package/dist/components/index.js +2 -2
- package/dist/components/inputs/index.js +1 -1
- package/dist/components/inputs/text-input/TestTextInput.svelte__ +102 -102
- package/dist/components/inputs/text-input/TextInput.svelte +226 -226
- package/dist/components/inputs/text-input/TextInput.svelte.d.ts +0 -28
- package/dist/components/inputs/text-input/TextInput.svelte___ +83 -83
- package/dist/components/inputs/text-input/assets/IconInvalid.svelte +14 -14
- package/dist/components/inputs/text-input/assets/IconValid.svelte +12 -12
- package/dist/components/layout/HkAppLayout.state.svelte.js +25 -25
- package/dist/components/layout/HkAppLayout.svelte +251 -251
- package/dist/components/layout/HkAppLayout.svelte.d.ts +0 -11
- package/dist/components/layout/HkGridLayers.svelte +82 -82
- package/dist/components/layout/HkGridLayers.svelte.d.ts +0 -23
- package/dist/components/layout/index.js +9 -9
- package/dist/components/panels/index.js +1 -1
- package/dist/components/panels/plain-panel/PlainPanel.svelte +33 -33
- package/dist/components/panels/plain-panel/PlainPanel.svelte.d.ts +0 -12
- package/dist/components/rows/index.js +3 -3
- package/dist/components/rows/panel-grid-row/PanelGridRow.svelte +104 -104
- package/dist/components/rows/panel-grid-row/PanelGridRow.svelte.d.ts +0 -14
- package/dist/components/rows/panel-row-2/PanelRow2.svelte +40 -40
- package/dist/components/rows/panel-row-2/PanelRow2.svelte.d.ts +0 -14
- package/dist/components/tab-bar/HkTabBar.state.svelte.js +149 -149
- package/dist/components/tab-bar/HkTabBar.svelte +74 -74
- package/dist/components/tab-bar/HkTabBar.svelte.d.ts +0 -18
- package/dist/components/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
- package/dist/components/tab-bar/HkTabBarSelector.svelte +49 -49
- package/dist/components/tab-bar/HkTabBarSelector.svelte.d.ts +0 -19
- package/dist/components/tab-bar/index.js +17 -17
- package/dist/components/tab-bar/typedef.js +8 -8
- package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte +179 -179
- package/dist/components/widgets/compare-left-right/CompareLeftRight.svelte.d.ts +0 -10
- package/dist/components/widgets/compare-left-right/index.js +1 -1
- package/dist/components/widgets/scale-control/index.js +1 -1
- package/dist/config/imagetools-config.js +189 -189
- package/dist/config/imagetools.d.ts +71 -71
- package/dist/config/typedef.js +8 -8
- package/dist/constants/errors/api.js +9 -9
- package/dist/constants/errors/generic.js +5 -5
- package/dist/constants/errors/index.js +3 -3
- package/dist/constants/errors/jwt.js +5 -5
- package/dist/constants/http/headers.js +6 -6
- package/dist/constants/http/index.js +2 -2
- package/dist/constants/http/methods.js +2 -2
- package/dist/constants/index.js +3 -3
- package/dist/constants/mime/application.js +5 -5
- package/dist/constants/mime/audio.js +13 -13
- package/dist/constants/mime/image.js +3 -3
- package/dist/constants/mime/index.js +4 -4
- package/dist/constants/mime/text.js +2 -2
- package/dist/constants/regexp/index.js +31 -31
- package/dist/constants/regexp/inspiratie.js__ +95 -95
- package/dist/constants/regexp/text.js +49 -49
- package/dist/constants/regexp/user.js +32 -32
- package/dist/constants/regexp/web.js +3 -3
- package/dist/constants/state-labels/input-states.js +11 -11
- package/dist/constants/state-labels/submit-states.js +4 -4
- package/dist/constants/time.js +28 -28
- package/dist/css/tw-prose.postcss__ +259 -259
- package/dist/css/utilities.postcss +43 -43
- package/dist/{design-system → design}/design-config.js +73 -73
- package/dist/{design-system → design}/tailwind-theme-extend.d.ts +4 -4
- package/dist/{design-system → design}/tailwind-theme-extend.js +151 -151
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/validate-url.js +180 -180
- package/dist/server/index.js +1 -1
- package/dist/server/logger.js +94 -94
- package/dist/states/index.js +1 -1
- package/dist/states/navigation.svelte.js +55 -55
- package/dist/stores/index.js +1 -1
- package/dist/stores/theme.js +80 -80
- package/dist/themes/hkdev/components/blocks/text-block.postcss +40 -40
- package/dist/themes/hkdev/components/boxes/game-box.postcss +13 -13
- package/dist/themes/hkdev/components/buttons/button-text.postcss +34 -34
- package/dist/themes/hkdev/components/buttons/button.postcss +138 -138
- package/dist/themes/hkdev/components/buttons/skip-button.postcss +8 -8
- package/dist/themes/hkdev/components/inputs/text-input.postcss +108 -108
- package/dist/themes/hkdev/components/panels/plain-panel.postcss +46 -46
- package/dist/themes/hkdev/components/panels/speech-bubble.postcss +52 -52
- package/dist/themes/hkdev/components/rows/panel-grid-row.postcss +7 -7
- package/dist/themes/hkdev/components/rows/panel-row-2.postcss +9 -9
- package/dist/themes/hkdev/components.postcss +55 -55
- package/dist/themes/hkdev/debug.postcss +1 -1
- package/dist/themes/hkdev/global/layout.postcss +39 -39
- package/dist/themes/hkdev/global/on-colors.postcss +53 -53
- package/dist/themes/hkdev/global/text.postcss__ +34 -34
- package/dist/themes/hkdev/global/vars.postcss__ +7 -7
- package/dist/themes/hkdev/globals.postcss +11 -11
- package/dist/themes/hkdev/responsive.postcss +12 -12
- package/dist/themes/hkdev/theme-ext.js +15 -15
- package/dist/themes/hkdev/theme.js +227 -227
- package/dist/themes/index.js +1 -1
- package/dist/util/array/index.js +455 -455
- package/dist/util/compare/index.js +247 -247
- package/dist/util/css/css-vars.js +83 -83
- package/dist/util/css/index.js +1 -1
- package/dist/util/design-system/components/states.js +22 -22
- package/dist/util/design-system/css/clamp.d.ts +2 -2
- package/dist/util/design-system/css/clamp.js +66 -66
- package/dist/util/design-system/css/root-design-vars.js +100 -100
- package/dist/util/design-system/index.js +5 -5
- package/dist/util/design-system/layout/scaling.js +97 -97
- package/dist/util/design-system/tailwind.js +289 -289
- package/dist/util/expect/arrays.js +47 -47
- package/dist/util/expect/index.js +259 -259
- package/dist/util/expect/primitives.js +55 -55
- package/dist/util/expect/url.js +60 -60
- package/dist/util/function/index.js +218 -218
- package/dist/util/http/errors.js +97 -97
- package/dist/util/http/headers.js +45 -45
- package/dist/util/http/http-request.js +273 -273
- package/dist/util/http/index.js +22 -22
- package/dist/util/http/json-request.js +143 -143
- package/dist/util/http/mocks.js +65 -65
- package/dist/util/http/response.js +228 -228
- package/dist/util/http/url.js +52 -52
- package/dist/util/image/index.js +86 -86
- package/dist/util/index.js +2 -2
- package/dist/util/is/index.js +140 -140
- package/dist/util/iterate/index.js +234 -234
- package/dist/util/object/index.js +1361 -1361
- package/dist/util/singleton/index.js +97 -97
- package/dist/util/string/index.js +184 -184
- package/dist/util/svelte/index.js +2 -2
- package/dist/util/svelte/observe/index.js +49 -49
- package/dist/util/svelte/state-context/index.js +83 -83
- package/dist/util/svelte/wait/index.js +38 -38
- package/dist/util/sveltekit/index.js +1 -1
- package/dist/util/sveltekit/route-folders/index.js +82 -82
- package/dist/util/time/index.js +339 -339
- package/dist/valibot/date.js__ +10 -10
- package/dist/valibot/index.js +9 -9
- package/dist/valibot/url.js +95 -95
- package/dist/valibot/user.js +23 -23
- package/dist/zod/all.js +33 -33
- package/dist/zod/generic.js +11 -11
- package/dist/zod/javascript.js +32 -32
- package/dist/zod/user.js +16 -16
- package/dist/zod/web.js +52 -52
- package/package.json +99 -99
- package/dist/themes/hkdev/components/buttons/button.postcss__ +0 -40
- package/dist/themes/hkdev/components/buttons/button.postcss___ +0 -91
- /package/dist/classes/{svkit → svelte}/audio/AudioLoader.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/audio/AudioScene.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/audio/mocks.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/final-state-machine/FiniteStateMachine.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/final-state-machine/index.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/ImageLoader.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/ImageScene.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/ImageVariantsLoader.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/index.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/mocks.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/image/typedef.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/loading-state-machine/LoadingStateMachine.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/loading-state-machine/constants.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/loading-state-machine/index.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/network-loader/NetworkLoader.svelte.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/network-loader/constants.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/network-loader/index.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/network-loader/mocks.d.ts +0 -0
- /package/dist/classes/{svkit → svelte}/network-loader/typedef.d.ts +0 -0
- /package/dist/{design-system → design}/design-config.d.ts +0 -0
package/dist/util/array/index.js
CHANGED
@@ -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
|
+
}
|