@webiny/app-admin 6.5.0-beta.0 → 6.5.0-beta.2
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/base/Admin.js +2 -0
- package/base/Admin.js.map +1 -1
- package/base/Base/FieldRenderers/AutoCompleteRenderer.js +1 -0
- package/base/Base/FieldRenderers/AutoCompleteRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/SelectRenderer.js +1 -0
- package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -1
- package/features/debugger/Debugger.d.ts +8 -0
- package/features/debugger/Debugger.js +25 -0
- package/features/debugger/Debugger.js.map +1 -0
- package/features/debugger/DebuggerIndicator.d.ts +16 -0
- package/features/debugger/DebuggerIndicator.js +31 -0
- package/features/debugger/DebuggerIndicator.js.map +1 -0
- package/features/debugger/DebuggerStore.d.ts +55 -0
- package/features/debugger/DebuggerStore.js +65 -0
- package/features/debugger/DebuggerStore.js.map +1 -0
- package/features/debugger/DebuggerView.d.ts +4 -0
- package/features/debugger/DebuggerView.js +49 -0
- package/features/debugger/DebuggerView.js.map +1 -0
- package/features/debugger/GraphQLExtensionsDebugHandler.d.ts +15 -0
- package/features/debugger/GraphQLExtensionsDebugHandler.js +15 -0
- package/features/debugger/GraphQLExtensionsDebugHandler.js.map +1 -0
- package/features/debugger/debuggerLink.d.ts +12 -0
- package/features/debugger/debuggerLink.js +10 -0
- package/features/debugger/debuggerLink.js.map +1 -0
- package/features/debugger/feature.d.ts +1 -0
- package/features/debugger/feature.js +18 -0
- package/features/debugger/feature.js.map +1 -0
- package/features/debugger/index.d.ts +7 -0
- package/features/debugger/index.js +7 -0
- package/features/debugger/permissions.d.ts +68 -0
- package/features/debugger/permissions.js +27 -0
- package/features/debugger/permissions.js.map +1 -0
- package/features/debugger/report.d.ts +7 -0
- package/features/debugger/report.js +22 -0
- package/features/debugger/report.js.map +1 -0
- package/features/debugger/routes.d.ts +4 -0
- package/features/debugger/routes.js +10 -0
- package/features/debugger/routes.js.map +1 -0
- package/features/formModel/createFieldRenderer.js +3 -4
- package/features/formModel/createFieldRenderer.js.map +1 -1
- package/hooks/useHotkeys.js +3 -1
- package/hooks/useHotkeys.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +3 -2
- package/package.json +19 -19
- package/presentation/listPresenter/FolderAwareDataSource.d.ts +5 -0
- package/presentation/listPresenter/FolderAwareDataSource.js +4 -3
- package/presentation/listPresenter/FolderAwareDataSource.js.map +1 -1
- package/presentation/listPresenter/QueryMatcher.d.ts +28 -5
- package/presentation/listPresenter/QueryMatcher.js +72 -2
- package/presentation/listPresenter/QueryMatcher.js.map +1 -1
- package/presentation/listPresenter/QueryMatcher.test.d.ts +1 -0
- package/presentation/listPresenter/QueryMatcher.test.js +345 -0
- package/presentation/listPresenter/QueryMatcher.test.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { QueryMatcher } from "./QueryMatcher.js";
|
|
3
|
+
const row = (id, savedOn, folderId = "root")=>({
|
|
4
|
+
id,
|
|
5
|
+
folderId,
|
|
6
|
+
savedOn
|
|
7
|
+
});
|
|
8
|
+
const createMatcher = (config = {})=>new QueryMatcher({
|
|
9
|
+
keyField: "id",
|
|
10
|
+
localFilters: {
|
|
11
|
+
folderId: (item, value)=>item.folderId === value
|
|
12
|
+
},
|
|
13
|
+
...config
|
|
14
|
+
});
|
|
15
|
+
const ids = (rows)=>rows.map((r)=>r.id);
|
|
16
|
+
describe("QueryMatcher.select", ()=>{
|
|
17
|
+
it("should only filter before the first query", ()=>{
|
|
18
|
+
const matcher = createMatcher();
|
|
19
|
+
expect(ids(matcher.select([
|
|
20
|
+
row("b", "2"),
|
|
21
|
+
row("a", "1")
|
|
22
|
+
]))).toEqual([
|
|
23
|
+
"b",
|
|
24
|
+
"a"
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
it("should sort by the applied sort, regardless of cache order", ()=>{
|
|
28
|
+
const matcher = createMatcher();
|
|
29
|
+
matcher.updateFromQuery({
|
|
30
|
+
sort: {
|
|
31
|
+
field: "savedOn",
|
|
32
|
+
direction: "DESC"
|
|
33
|
+
}
|
|
34
|
+
}, [
|
|
35
|
+
"c",
|
|
36
|
+
"b",
|
|
37
|
+
"a"
|
|
38
|
+
]);
|
|
39
|
+
const cached = [
|
|
40
|
+
row("a", "1"),
|
|
41
|
+
row("c", "3"),
|
|
42
|
+
row("b", "2")
|
|
43
|
+
];
|
|
44
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
45
|
+
"c",
|
|
46
|
+
"b",
|
|
47
|
+
"a"
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
it("should apply local filters", ()=>{
|
|
51
|
+
const matcher = createMatcher();
|
|
52
|
+
matcher.updateFromQuery({
|
|
53
|
+
filters: {
|
|
54
|
+
folderId: "root"
|
|
55
|
+
},
|
|
56
|
+
sort: {
|
|
57
|
+
field: "savedOn",
|
|
58
|
+
direction: "ASC"
|
|
59
|
+
}
|
|
60
|
+
}, [
|
|
61
|
+
"a",
|
|
62
|
+
"b"
|
|
63
|
+
]);
|
|
64
|
+
const cached = [
|
|
65
|
+
row("a", "1"),
|
|
66
|
+
row("x", "0", "other"),
|
|
67
|
+
row("b", "2")
|
|
68
|
+
];
|
|
69
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
70
|
+
"a",
|
|
71
|
+
"b"
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
it("should cut off items that sort past the last loaded item while more are available", ()=>{
|
|
75
|
+
const matcher = createMatcher();
|
|
76
|
+
matcher.updateFromQuery({
|
|
77
|
+
sort: {
|
|
78
|
+
field: "savedOn",
|
|
79
|
+
direction: "ASC"
|
|
80
|
+
}
|
|
81
|
+
}, [
|
|
82
|
+
"a",
|
|
83
|
+
"b"
|
|
84
|
+
], true);
|
|
85
|
+
const cached = [
|
|
86
|
+
row("z", "9"),
|
|
87
|
+
row("a", "1"),
|
|
88
|
+
row("b", "2")
|
|
89
|
+
];
|
|
90
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
91
|
+
"a",
|
|
92
|
+
"b"
|
|
93
|
+
]);
|
|
94
|
+
});
|
|
95
|
+
it("should include items past the last loaded item when nothing more is available", ()=>{
|
|
96
|
+
const matcher = createMatcher();
|
|
97
|
+
matcher.updateFromQuery({
|
|
98
|
+
sort: {
|
|
99
|
+
field: "savedOn",
|
|
100
|
+
direction: "ASC"
|
|
101
|
+
}
|
|
102
|
+
}, [
|
|
103
|
+
"a",
|
|
104
|
+
"b"
|
|
105
|
+
], false);
|
|
106
|
+
const cached = [
|
|
107
|
+
row("z", "9"),
|
|
108
|
+
row("a", "1"),
|
|
109
|
+
row("b", "2")
|
|
110
|
+
];
|
|
111
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
112
|
+
"a",
|
|
113
|
+
"b",
|
|
114
|
+
"z"
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
it("should extend the loaded window on appendResultKeys", ()=>{
|
|
118
|
+
const matcher = createMatcher();
|
|
119
|
+
matcher.updateFromQuery({
|
|
120
|
+
sort: {
|
|
121
|
+
field: "savedOn",
|
|
122
|
+
direction: "ASC"
|
|
123
|
+
}
|
|
124
|
+
}, [
|
|
125
|
+
"a"
|
|
126
|
+
], true);
|
|
127
|
+
matcher.appendResultKeys([
|
|
128
|
+
"b"
|
|
129
|
+
], true);
|
|
130
|
+
const cached = [
|
|
131
|
+
row("c", "3"),
|
|
132
|
+
row("b", "2"),
|
|
133
|
+
row("a", "1")
|
|
134
|
+
];
|
|
135
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
136
|
+
"a",
|
|
137
|
+
"b"
|
|
138
|
+
]);
|
|
139
|
+
});
|
|
140
|
+
it("should keep the server order for items with equal sort values", ()=>{
|
|
141
|
+
const matcher = createMatcher();
|
|
142
|
+
matcher.updateFromQuery({
|
|
143
|
+
sort: {
|
|
144
|
+
field: "savedOn",
|
|
145
|
+
direction: "DESC"
|
|
146
|
+
}
|
|
147
|
+
}, [
|
|
148
|
+
"b",
|
|
149
|
+
"a",
|
|
150
|
+
"c"
|
|
151
|
+
]);
|
|
152
|
+
const cached = [
|
|
153
|
+
row("a", "1"),
|
|
154
|
+
row("c", "1"),
|
|
155
|
+
row("b", "1")
|
|
156
|
+
];
|
|
157
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
158
|
+
"b",
|
|
159
|
+
"a",
|
|
160
|
+
"c"
|
|
161
|
+
]);
|
|
162
|
+
});
|
|
163
|
+
it("should sort empty values last in ascending order", ()=>{
|
|
164
|
+
const matcher = createMatcher();
|
|
165
|
+
matcher.updateFromQuery({
|
|
166
|
+
sort: {
|
|
167
|
+
field: "savedOn",
|
|
168
|
+
direction: "ASC"
|
|
169
|
+
}
|
|
170
|
+
}, [
|
|
171
|
+
"a",
|
|
172
|
+
"b"
|
|
173
|
+
]);
|
|
174
|
+
const cached = [
|
|
175
|
+
row("n"),
|
|
176
|
+
row("b", "2"),
|
|
177
|
+
row("u"),
|
|
178
|
+
row("a", "1")
|
|
179
|
+
];
|
|
180
|
+
cached[0].savedOn = null;
|
|
181
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
182
|
+
"a",
|
|
183
|
+
"b",
|
|
184
|
+
"n",
|
|
185
|
+
"u"
|
|
186
|
+
]);
|
|
187
|
+
});
|
|
188
|
+
it("should sort empty values first in descending order", ()=>{
|
|
189
|
+
const matcher = createMatcher();
|
|
190
|
+
matcher.updateFromQuery({
|
|
191
|
+
sort: {
|
|
192
|
+
field: "savedOn",
|
|
193
|
+
direction: "DESC"
|
|
194
|
+
}
|
|
195
|
+
}, [
|
|
196
|
+
"b",
|
|
197
|
+
"a"
|
|
198
|
+
]);
|
|
199
|
+
expect(ids(matcher.select([
|
|
200
|
+
row("a", "1"),
|
|
201
|
+
row("e"),
|
|
202
|
+
row("b", "2")
|
|
203
|
+
]))).toEqual([
|
|
204
|
+
"e",
|
|
205
|
+
"b",
|
|
206
|
+
"a"
|
|
207
|
+
]);
|
|
208
|
+
});
|
|
209
|
+
it("should sort an empty string as a regular string", ()=>{
|
|
210
|
+
const matcher = createMatcher();
|
|
211
|
+
matcher.updateFromQuery({
|
|
212
|
+
sort: {
|
|
213
|
+
field: "savedOn",
|
|
214
|
+
direction: "ASC"
|
|
215
|
+
}
|
|
216
|
+
}, [
|
|
217
|
+
"a",
|
|
218
|
+
"b"
|
|
219
|
+
]);
|
|
220
|
+
expect(ids(matcher.select([
|
|
221
|
+
row("b", "1"),
|
|
222
|
+
row("u"),
|
|
223
|
+
row("a", "")
|
|
224
|
+
]))).toEqual([
|
|
225
|
+
"a",
|
|
226
|
+
"b",
|
|
227
|
+
"u"
|
|
228
|
+
]);
|
|
229
|
+
});
|
|
230
|
+
it("should keep the server order while searching", ()=>{
|
|
231
|
+
const matcher = createMatcher();
|
|
232
|
+
matcher.updateFromQuery({
|
|
233
|
+
search: "hello",
|
|
234
|
+
sort: {
|
|
235
|
+
field: "savedOn",
|
|
236
|
+
direction: "ASC"
|
|
237
|
+
}
|
|
238
|
+
}, [
|
|
239
|
+
"c",
|
|
240
|
+
"a",
|
|
241
|
+
"b"
|
|
242
|
+
]);
|
|
243
|
+
const cached = [
|
|
244
|
+
row("a", "1"),
|
|
245
|
+
row("b", "2"),
|
|
246
|
+
row("c", "3"),
|
|
247
|
+
row("x", "0")
|
|
248
|
+
];
|
|
249
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
250
|
+
"c",
|
|
251
|
+
"a",
|
|
252
|
+
"b"
|
|
253
|
+
]);
|
|
254
|
+
});
|
|
255
|
+
it("should read nested sort fields by path", ()=>{
|
|
256
|
+
const matcher = createMatcher();
|
|
257
|
+
matcher.updateFromQuery({
|
|
258
|
+
sort: {
|
|
259
|
+
field: "values.title",
|
|
260
|
+
direction: "ASC"
|
|
261
|
+
}
|
|
262
|
+
}, [
|
|
263
|
+
"a",
|
|
264
|
+
"b"
|
|
265
|
+
]);
|
|
266
|
+
const cached = [
|
|
267
|
+
{
|
|
268
|
+
id: "b",
|
|
269
|
+
folderId: "root",
|
|
270
|
+
values: {
|
|
271
|
+
title: "Beta"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
id: "a",
|
|
276
|
+
folderId: "root",
|
|
277
|
+
values: {
|
|
278
|
+
title: "Alpha"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
];
|
|
282
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
283
|
+
"a",
|
|
284
|
+
"b"
|
|
285
|
+
]);
|
|
286
|
+
});
|
|
287
|
+
it("should use a custom sort value getter", ()=>{
|
|
288
|
+
const matcher = createMatcher({
|
|
289
|
+
getSortValue: (item, field)=>"title" === field ? item.values?.title : void 0
|
|
290
|
+
});
|
|
291
|
+
matcher.updateFromQuery({
|
|
292
|
+
sort: {
|
|
293
|
+
field: "title",
|
|
294
|
+
direction: "DESC"
|
|
295
|
+
}
|
|
296
|
+
}, [
|
|
297
|
+
"a",
|
|
298
|
+
"b"
|
|
299
|
+
]);
|
|
300
|
+
const cached = [
|
|
301
|
+
{
|
|
302
|
+
id: "a",
|
|
303
|
+
folderId: "root",
|
|
304
|
+
values: {
|
|
305
|
+
title: "Alpha"
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: "b",
|
|
310
|
+
folderId: "root",
|
|
311
|
+
values: {
|
|
312
|
+
title: "Beta"
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
];
|
|
316
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
317
|
+
"b",
|
|
318
|
+
"a"
|
|
319
|
+
]);
|
|
320
|
+
});
|
|
321
|
+
it("should put items the server did not return after the server's items among equal values", ()=>{
|
|
322
|
+
const matcher = createMatcher();
|
|
323
|
+
matcher.updateFromQuery({
|
|
324
|
+
sort: {
|
|
325
|
+
field: "savedOn",
|
|
326
|
+
direction: "DESC"
|
|
327
|
+
}
|
|
328
|
+
}, [
|
|
329
|
+
"b",
|
|
330
|
+
"a"
|
|
331
|
+
], true);
|
|
332
|
+
const cached = [
|
|
333
|
+
row("x", "1"),
|
|
334
|
+
row("a", "1"),
|
|
335
|
+
row("y", "1"),
|
|
336
|
+
row("b", "1")
|
|
337
|
+
];
|
|
338
|
+
expect(ids(matcher.select(cached))).toEqual([
|
|
339
|
+
"b",
|
|
340
|
+
"a"
|
|
341
|
+
]);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
//# sourceMappingURL=QueryMatcher.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/listPresenter/QueryMatcher.test.js","sources":["../../../src/presentation/listPresenter/QueryMatcher.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { QueryMatcher } from \"./QueryMatcher.js\";\n\ninterface Row {\n id: string;\n folderId: string;\n savedOn?: string;\n values?: { title?: string };\n}\n\nconst row = (id: string, savedOn?: string, folderId = \"root\"): Row => ({ id, folderId, savedOn });\n\nconst createMatcher = (config: Partial<ConstructorParameters<typeof QueryMatcher<Row>>[0]> = {}) =>\n new QueryMatcher<Row>({\n keyField: \"id\",\n localFilters: {\n folderId: (item, value) => item.folderId === value\n },\n ...config\n });\n\nconst ids = (rows: Row[]) => rows.map(r => r.id);\n\ndescribe(\"QueryMatcher.select\", () => {\n it(\"should only filter before the first query\", () => {\n const matcher = createMatcher();\n\n expect(ids(matcher.select([row(\"b\", \"2\"), row(\"a\", \"1\")]))).toEqual([\"b\", \"a\"]);\n });\n\n it(\"should sort by the applied sort, regardless of cache order\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"DESC\" } }, [\"c\", \"b\", \"a\"]);\n\n const cached = [row(\"a\", \"1\"), row(\"c\", \"3\"), row(\"b\", \"2\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"c\", \"b\", \"a\"]);\n });\n\n it(\"should apply local filters\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery(\n { filters: { folderId: \"root\" }, sort: { field: \"savedOn\", direction: \"ASC\" } },\n [\"a\", \"b\"]\n );\n\n const cached = [row(\"a\", \"1\"), row(\"x\", \"0\", \"other\"), row(\"b\", \"2\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\"]);\n });\n\n it(\"should cut off items that sort past the last loaded item while more are available\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"ASC\" } }, [\"a\", \"b\"], true);\n\n // \"z\" was cached by another view and sorts after the loaded window.\n const cached = [row(\"z\", \"9\"), row(\"a\", \"1\"), row(\"b\", \"2\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\"]);\n });\n\n it(\"should include items past the last loaded item when nothing more is available\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery(\n { sort: { field: \"savedOn\", direction: \"ASC\" } },\n [\"a\", \"b\"],\n false\n );\n\n const cached = [row(\"z\", \"9\"), row(\"a\", \"1\"), row(\"b\", \"2\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\", \"z\"]);\n });\n\n it(\"should extend the loaded window on appendResultKeys\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"ASC\" } }, [\"a\"], true);\n matcher.appendResultKeys([\"b\"], true);\n\n const cached = [row(\"c\", \"3\"), row(\"b\", \"2\"), row(\"a\", \"1\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\"]);\n });\n\n it(\"should keep the server order for items with equal sort values\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"DESC\" } }, [\"b\", \"a\", \"c\"]);\n\n const cached = [row(\"a\", \"1\"), row(\"c\", \"1\"), row(\"b\", \"1\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"b\", \"a\", \"c\"]);\n });\n\n // Empty values are ordered the same way as the DDB and SQL storage sort them.\n it(\"should sort empty values last in ascending order\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"ASC\" } }, [\"a\", \"b\"]);\n\n const cached = [row(\"n\"), row(\"b\", \"2\"), row(\"u\"), row(\"a\", \"1\")];\n cached[0].savedOn = null as unknown as string;\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\", \"n\", \"u\"]);\n });\n\n it(\"should sort empty values first in descending order\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"DESC\" } }, [\"b\", \"a\"]);\n\n expect(ids(matcher.select([row(\"a\", \"1\"), row(\"e\"), row(\"b\", \"2\")]))).toEqual([\n \"e\",\n \"b\",\n \"a\"\n ]);\n });\n\n it(\"should sort an empty string as a regular string\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"savedOn\", direction: \"ASC\" } }, [\"a\", \"b\"]);\n\n expect(ids(matcher.select([row(\"b\", \"1\"), row(\"u\"), row(\"a\", \"\")]))).toEqual([\n \"a\",\n \"b\",\n \"u\"\n ]);\n });\n\n it(\"should keep the server order while searching\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ search: \"hello\", sort: { field: \"savedOn\", direction: \"ASC\" } }, [\n \"c\",\n \"a\",\n \"b\"\n ]);\n\n const cached = [row(\"a\", \"1\"), row(\"b\", \"2\"), row(\"c\", \"3\"), row(\"x\", \"0\")];\n\n expect(ids(matcher.select(cached))).toEqual([\"c\", \"a\", \"b\"]);\n });\n\n it(\"should read nested sort fields by path\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery({ sort: { field: \"values.title\", direction: \"ASC\" } }, [\"a\", \"b\"]);\n\n const cached: Row[] = [\n { id: \"b\", folderId: \"root\", values: { title: \"Beta\" } },\n { id: \"a\", folderId: \"root\", values: { title: \"Alpha\" } }\n ];\n\n expect(ids(matcher.select(cached))).toEqual([\"a\", \"b\"]);\n });\n\n it(\"should use a custom sort value getter\", () => {\n const matcher = createMatcher({\n getSortValue: (item, field) => (field === \"title\" ? item.values?.title : undefined)\n });\n matcher.updateFromQuery({ sort: { field: \"title\", direction: \"DESC\" } }, [\"a\", \"b\"]);\n\n const cached: Row[] = [\n { id: \"a\", folderId: \"root\", values: { title: \"Alpha\" } },\n { id: \"b\", folderId: \"root\", values: { title: \"Beta\" } }\n ];\n\n expect(ids(matcher.select(cached))).toEqual([\"b\", \"a\"]);\n });\n\n it(\"should put items the server did not return after the server's items among equal values\", () => {\n const matcher = createMatcher();\n matcher.updateFromQuery(\n { sort: { field: \"savedOn\", direction: \"DESC\" } },\n [\"b\", \"a\"],\n true\n );\n\n // \"x\" and \"y\" were cached by another view and tie with the loaded items.\n const cached = [row(\"x\", \"1\"), row(\"a\", \"1\"), row(\"y\", \"1\"), row(\"b\", \"1\")];\n\n // Server items come first, in server order, and the tied leftovers are cut off\n // together with everything else past the last loaded item.\n expect(ids(matcher.select(cached))).toEqual([\"b\", \"a\"]);\n });\n});\n"],"names":["row","id","savedOn","folderId","createMatcher","config","QueryMatcher","item","value","ids","rows","r","describe","it","matcher","expect","cached","field","undefined"],"mappings":";;AAUA,MAAMA,MAAM,CAACC,IAAYC,SAAkBC,WAAW,MAAM,GAAW;QAAEF;QAAIE;QAAUD;IAAQ;AAE/F,MAAME,gBAAgB,CAACC,SAAsE,CAAC,CAAC,GAC3F,IAAIC,aAAkB;QAClB,UAAU;QACV,cAAc;YACV,UAAU,CAACC,MAAMC,QAAUD,KAAK,QAAQ,KAAKC;QACjD;QACA,GAAGH,MAAM;IACb;AAEJ,MAAMI,MAAM,CAACC,OAAgBA,KAAK,GAAG,CAACC,CAAAA,IAAKA,EAAE,EAAE;AAE/CC,SAAS,uBAAuB;IAC5BC,GAAG,6CAA6C;QAC5C,MAAMC,UAAUV;QAEhBW,OAAON,IAAIK,QAAQ,MAAM,CAAC;YAACd,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK,IAAI,OAAO,CAAC;YAAC;YAAK;SAAI;IAClF;IAEAa,GAAG,8DAA8D;QAC7D,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAO;QAAE,GAAG;YAAC;YAAK;YAAK;SAAI;QAE1F,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE5De,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;YAAK;SAAI;IAC/D;IAEAH,GAAG,8BAA8B;QAC7B,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CACnB;YAAE,SAAS;gBAAE,UAAU;YAAO;YAAG,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAC9E;YAAC;YAAK;SAAI;QAGd,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK,KAAK;YAAUA,IAAI,KAAK;SAAK;QAErEe,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;IAEAH,GAAG,qFAAqF;QACpF,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAAG;YAAC;YAAK;SAAI,EAAE;QAGtF,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE5De,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;IAEAH,GAAG,iFAAiF;QAChF,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CACnB;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAC/C;YAAC;YAAK;SAAI,EACV;QAGJ,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE5De,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;YAAK;SAAI;IAC/D;IAEAH,GAAG,uDAAuD;QACtD,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAAG;YAAC;SAAI,EAAE;QACjFA,QAAQ,gBAAgB,CAAC;YAAC;SAAI,EAAE;QAEhC,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE5De,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;IAEAH,GAAG,iEAAiE;QAChE,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAO;QAAE,GAAG;YAAC;YAAK;YAAK;SAAI;QAE1F,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE5De,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;YAAK;SAAI;IAC/D;IAGAH,GAAG,oDAAoD;QACnD,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAAG;YAAC;YAAK;SAAI;QAEpF,MAAME,SAAS;YAAChB,IAAI;YAAMA,IAAI,KAAK;YAAMA,IAAI;YAAMA,IAAI,KAAK;SAAK;QACjEgB,MAAM,CAAC,EAAE,CAAC,OAAO,GAAG;QAEpBD,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;YAAK;YAAK;SAAI;IACpE;IAEAH,GAAG,sDAAsD;QACrD,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAO;QAAE,GAAG;YAAC;YAAK;SAAI;QAErFC,OAAON,IAAIK,QAAQ,MAAM,CAAC;YAACd,IAAI,KAAK;YAAMA,IAAI;YAAMA,IAAI,KAAK;SAAK,IAAI,OAAO,CAAC;YAC1E;YACA;YACA;SACH;IACL;IAEAa,GAAG,mDAAmD;QAClD,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAAG;YAAC;YAAK;SAAI;QAEpFC,OAAON,IAAIK,QAAQ,MAAM,CAAC;YAACd,IAAI,KAAK;YAAMA,IAAI;YAAMA,IAAI,KAAK;SAAI,IAAI,OAAO,CAAC;YACzE;YACA;YACA;SACH;IACL;IAEAa,GAAG,gDAAgD;QAC/C,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,QAAQ;YAAS,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAM;QAAE,GAAG;YACvF;YACA;YACA;SACH;QAED,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAE3Ee,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;YAAK;SAAI;IAC/D;IAEAH,GAAG,0CAA0C;QACzC,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAgB,WAAW;YAAM;QAAE,GAAG;YAAC;YAAK;SAAI;QAEzF,MAAME,SAAgB;YAClB;gBAAE,IAAI;gBAAK,UAAU;gBAAQ,QAAQ;oBAAE,OAAO;gBAAO;YAAE;YACvD;gBAAE,IAAI;gBAAK,UAAU;gBAAQ,QAAQ;oBAAE,OAAO;gBAAQ;YAAE;SAC3D;QAEDD,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;IAEAH,GAAG,yCAAyC;QACxC,MAAMC,UAAUV,cAAc;YAC1B,cAAc,CAACG,MAAMU,QAAWA,AAAU,YAAVA,QAAoBV,KAAK,MAAM,EAAE,QAAQW;QAC7E;QACAJ,QAAQ,eAAe,CAAC;YAAE,MAAM;gBAAE,OAAO;gBAAS,WAAW;YAAO;QAAE,GAAG;YAAC;YAAK;SAAI;QAEnF,MAAME,SAAgB;YAClB;gBAAE,IAAI;gBAAK,UAAU;gBAAQ,QAAQ;oBAAE,OAAO;gBAAQ;YAAE;YACxD;gBAAE,IAAI;gBAAK,UAAU;gBAAQ,QAAQ;oBAAE,OAAO;gBAAO;YAAE;SAC1D;QAEDD,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;IAEAH,GAAG,0FAA0F;QACzF,MAAMC,UAAUV;QAChBU,QAAQ,eAAe,CACnB;YAAE,MAAM;gBAAE,OAAO;gBAAW,WAAW;YAAO;QAAE,GAChD;YAAC;YAAK;SAAI,EACV;QAIJ,MAAME,SAAS;YAAChB,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;YAAMA,IAAI,KAAK;SAAK;QAI3Ee,OAAON,IAAIK,QAAQ,MAAM,CAACE,UAAU,OAAO,CAAC;YAAC;YAAK;SAAI;IAC1D;AACJ"}
|