@internetarchive/collection-browser 1.14.17-alpha.2 → 1.14.17-alpha.21

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 (87) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/app-root.d.ts +1 -0
  4. package/dist/src/app-root.js +38 -0
  5. package/dist/src/app-root.js.map +1 -1
  6. package/dist/src/collection-browser.d.ts +2 -15
  7. package/dist/src/collection-browser.js +22 -29
  8. package/dist/src/collection-browser.js.map +1 -1
  9. package/dist/src/data-source/collection-browser-data-source.d.ts +55 -32
  10. package/dist/src/data-source/collection-browser-data-source.js +155 -162
  11. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  12. package/dist/src/data-source/models.d.ts +6 -3
  13. package/dist/src/data-source/models.js.map +1 -1
  14. package/dist/src/manage/manage-bar.d.ts +1 -1
  15. package/dist/src/manage/manage-bar.js.map +1 -1
  16. package/dist/src/models.d.ts +20 -4
  17. package/dist/src/models.js +105 -0
  18. package/dist/src/models.js.map +1 -1
  19. package/dist/src/sort-filter-bar/sort-filter-bar.js +25 -16
  20. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  21. package/dist/src/tiles/grid/item-tile.d.ts +1 -0
  22. package/dist/src/tiles/grid/item-tile.js +28 -1
  23. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  24. package/dist/src/tiles/grid/tile-stats.js +13 -8
  25. package/dist/src/tiles/grid/tile-stats.js.map +1 -1
  26. package/dist/src/tiles/list/tile-list-compact.js +1 -1
  27. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  28. package/dist/src/tiles/list/tile-list.d.ts +1 -0
  29. package/dist/src/tiles/list/tile-list.js +32 -1
  30. package/dist/src/tiles/list/tile-list.js.map +1 -1
  31. package/dist/src/tiles/tile-dispatcher.js +3 -2
  32. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  33. package/dist/src/tiles/tile-display-value-provider.d.ts +6 -2
  34. package/dist/src/tiles/tile-display-value-provider.js +15 -1
  35. package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
  36. package/dist/src/utils/collapse-repeated-quotes.d.ts +11 -0
  37. package/dist/src/utils/collapse-repeated-quotes.js +14 -0
  38. package/dist/src/utils/collapse-repeated-quotes.js.map +1 -0
  39. package/dist/src/utils/resolve-mediatype.d.ts +8 -0
  40. package/dist/src/utils/resolve-mediatype.js +24 -0
  41. package/dist/src/utils/resolve-mediatype.js.map +1 -0
  42. package/dist/test/collection-browser.test.js +39 -19
  43. package/dist/test/collection-browser.test.js.map +1 -1
  44. package/dist/test/collection-facets/more-facets-content.test.js +2 -2
  45. package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
  46. package/dist/test/collection-facets.test.js +5 -0
  47. package/dist/test/collection-facets.test.js.map +1 -1
  48. package/dist/test/item-image.test.js +33 -34
  49. package/dist/test/item-image.test.js.map +1 -1
  50. package/dist/test/mocks/mock-search-responses.d.ts +1 -0
  51. package/dist/test/mocks/mock-search-responses.js +62 -0
  52. package/dist/test/mocks/mock-search-responses.js.map +1 -1
  53. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +41 -4
  54. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
  55. package/dist/test/tiles/hover/hover-pane-controller.test.js +18 -17
  56. package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -1
  57. package/package.json +2 -2
  58. package/src/app-root.ts +39 -0
  59. package/src/collection-browser.ts +24 -40
  60. package/src/data-source/collection-browser-data-source.ts +160 -132
  61. package/src/data-source/models.ts +6 -2
  62. package/src/manage/manage-bar.ts +1 -1
  63. package/src/models.ts +154 -3
  64. package/src/sort-filter-bar/sort-filter-bar.ts +26 -16
  65. package/src/tiles/grid/item-tile.ts +36 -1
  66. package/src/tiles/grid/tile-stats.ts +12 -7
  67. package/src/tiles/list/tile-list-compact.ts +1 -1
  68. package/src/tiles/list/tile-list.ts +43 -5
  69. package/src/tiles/tile-dispatcher.ts +2 -1
  70. package/src/tiles/tile-display-value-provider.ts +20 -2
  71. package/src/utils/collapse-repeated-quotes.ts +13 -0
  72. package/src/utils/resolve-mediatype.ts +26 -0
  73. package/test/collection-browser.test.ts +74 -19
  74. package/test/collection-facets/more-facets-content.test.ts +4 -2
  75. package/test/collection-facets.test.ts +5 -0
  76. package/test/item-image.test.ts +34 -36
  77. package/test/mocks/mock-search-responses.ts +66 -0
  78. package/test/sort-filter-bar/sort-filter-bar.test.ts +50 -4
  79. package/test/tiles/hover/hover-pane-controller.test.ts +19 -17
  80. package/dist/src/data-source/data-source-fetch-provider.d.ts +0 -13
  81. package/dist/src/data-source/data-source-fetch-provider.js +0 -61
  82. package/dist/src/data-source/data-source-fetch-provider.js.map +0 -1
  83. package/dist/src/selected-facets.d.ts +0 -67
  84. package/dist/src/selected-facets.js +0 -149
  85. package/dist/src/selected-facets.js.map +0 -1
  86. package/src/data-source/data-source-fetch-provider.ts +0 -79
  87. package/src/selected-facets.ts +0 -216
@@ -1,8 +1,7 @@
1
1
  import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
2
  import { AccountExtraInfo, Aggregation, CollectionExtraInfo, FilterMap, PageElementMap, SearchParams } from '@internetarchive/search-service';
3
- import { type PrefixFilterType, type TileModel, PrefixFilterCounts } from '../models';
3
+ import { type PrefixFilterType, TileModel, PrefixFilterCounts, RequestKind } from '../models';
4
4
  import type { CollectionBrowserSearchInterface, CollectionTitles, PageSpecifierParams } from './models';
5
- declare type RequestKind = 'full' | 'hits' | 'aggregations';
6
5
  export interface CollectionBrowserDataSourceInterface extends ReactiveController {
7
6
  /**
8
7
  * How many tile models are present in this data source
@@ -15,6 +14,11 @@ export interface CollectionBrowserDataSourceInterface extends ReactiveController
15
14
  * for MDS but not FTS.
16
15
  */
17
16
  readonly canPerformSearch: boolean;
17
+ /**
18
+ * Whether the end of the set of results for the current query state has been
19
+ * encountered (i.e., the last page of results).
20
+ */
21
+ readonly endOfDataReached: boolean;
18
22
  /**
19
23
  * A string key compactly representing the current full search state, which can
20
24
  * be used to determine, e.g., when a new search is required or whether an arriving
@@ -83,6 +87,18 @@ export interface CollectionBrowserDataSourceInterface extends ReactiveController
83
87
  * An array of all the tile models whose management checkboxes are unchecked
84
88
  */
85
89
  readonly uncheckedTileModels: TileModel[];
90
+ /**
91
+ * A Promise which, after each query change, resolves once the fetches for the initial
92
+ * search have completed. Waits for *both* the hits and aggregations fetches to finish.
93
+ *
94
+ * Ensure you await this component's `updateComplete` promise before awaiting this
95
+ * one, to ensure you do not await an obsolete promise from the previous update.
96
+ */
97
+ readonly initialSearchComplete: Promise<boolean>;
98
+ /**
99
+ * Resets the data source to its empty state, with no result pages, aggregations, etc.
100
+ */
101
+ reset(): void;
86
102
  /**
87
103
  * Adds the given page of tile models to the data source.
88
104
  * If the given page number already exists, that page will be overwritten.
@@ -137,10 +153,6 @@ export interface CollectionBrowserDataSourceInterface extends ReactiveController
137
153
  * @param pageSize
138
154
  */
139
155
  setPageSize(pageSize: number): void;
140
- /**
141
- * Resets the data source to its empty state, with no result pages, aggregations, etc.
142
- */
143
- reset(): void;
144
156
  /**
145
157
  * Notifies the data source that a query change has occurred, which may trigger a data
146
158
  * reset & new fetches.
@@ -178,7 +190,19 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
178
190
  * Maps the full query key to the pages being fetched for that query
179
191
  */
180
192
  private pageFetchesInProgress;
193
+ /**
194
+ * A record of the query key used for the last search.
195
+ * If this changes, we need to load new results.
196
+ */
197
+ private previousQueryKey;
198
+ private id;
199
+ /**
200
+ * @inheritdoc
201
+ */
181
202
  totalResults: number;
203
+ /**
204
+ * @inheritdoc
205
+ */
182
206
  endOfDataReached: boolean;
183
207
  /**
184
208
  * @inheritdoc
@@ -212,15 +236,33 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
212
236
  * @inheritdoc
213
237
  */
214
238
  prefixFilterCountMap: Partial<Record<PrefixFilterType, PrefixFilterCounts>>;
239
+ /**
240
+ * Internal property to store the `resolve` function for the most recent
241
+ * `initialSearchComplete` promise, allowing us to resolve it at the appropriate time.
242
+ */
243
+ private _initialSearchCompleteResolver;
244
+ /**
245
+ * Internal property to store the private value backing the `initialSearchComplete` getter.
246
+ */
247
+ private _initialSearchCompletePromise;
248
+ /**
249
+ * @inheritdoc
250
+ */
251
+ get initialSearchComplete(): Promise<boolean>;
215
252
  constructor(
216
253
  /** The host element to which this controller should attach listeners */
217
254
  host: ReactiveControllerHost & CollectionBrowserSearchInterface,
218
255
  /** Default size of result pages */
219
256
  pageSize: number);
257
+ hostUpdate(): void;
220
258
  /**
221
259
  * @inheritdoc
222
260
  */
223
261
  get size(): number;
262
+ /**
263
+ * @inheritdoc
264
+ */
265
+ reset(): void;
224
266
  /**
225
267
  * @inheritdoc
226
268
  */
@@ -241,15 +283,14 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
241
283
  * @inheritdoc
242
284
  */
243
285
  getTileModelAt(index: number): TileModel | undefined;
244
- indexOf(tile: TileModel): number;
245
286
  /**
246
287
  * @inheritdoc
247
288
  */
248
- setPageSize(pageSize: number): void;
289
+ indexOf(tile: TileModel): number;
249
290
  /**
250
291
  * @inheritdoc
251
292
  */
252
- reset(): void;
293
+ setPageSize(pageSize: number): void;
253
294
  /**
254
295
  * @inheritdoc
255
296
  */
@@ -261,15 +302,15 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
261
302
  /**
262
303
  * @inheritdoc
263
304
  */
264
- checkAllTiles(): void;
305
+ checkAllTiles: () => void;
265
306
  /**
266
307
  * @inheritdoc
267
308
  */
268
- uncheckAllTiles(): void;
309
+ uncheckAllTiles: () => void;
269
310
  /**
270
311
  * @inheritdoc
271
312
  */
272
- removeCheckedTiles(): void;
313
+ removeCheckedTiles: () => void;
273
314
  /**
274
315
  * @inheritdoc
275
316
  */
@@ -301,8 +342,8 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
301
342
  * - Any currently-applied prefix filters
302
343
  * - The current sort options
303
344
  *
304
- * This lets us keep track of queries so we don't persist data that's
305
- * no longer relevant.
345
+ * This lets us internally keep track of queries so we don't persist data that's
346
+ * no longer relevant. Not meant to be human-readable.
306
347
  */
307
348
  get pageFetchQueryKey(): string;
308
349
  /**
@@ -402,23 +443,6 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
402
443
  * @param results
403
444
  */
404
445
  private addTilesToDataSource;
405
- /**
406
- * Returns the mediatype string for the given search result, taking into account
407
- * the special `favorited_search` hit type.
408
- * @param result The search result to extract a mediatype from
409
- */
410
- private getMediatype;
411
- /**
412
- * Returns the input string, but removing one set of quotes from all instances of
413
- * ""clauses wrapped in two sets of quotes"". This assumes the quotes are already
414
- * URL-encoded.
415
- *
416
- * This should be a temporary measure to address the fact that the __href__ field
417
- * sometimes acquires extra quotation marks during query rewriting. Once there is a
418
- * full Lucene parser in place that handles quoted queries correctly, this can likely
419
- * be removed.
420
- */
421
- private collapseRepeatedQuotes;
422
446
  /**
423
447
  * Fetches the aggregation buckets for the given prefix filter type.
424
448
  */
@@ -428,4 +452,3 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
428
452
  */
429
453
  updatePrefixFilterCounts(filterType: PrefixFilterType): Promise<void>;
430
454
  }
431
- export {};
@@ -1,5 +1,5 @@
1
1
  import { FilterConstraint, FilterMapBuilder, SearchType, } from '@internetarchive/search-service';
2
- import { prefixFilterAggregationKeys, } from '../models';
2
+ import { prefixFilterAggregationKeys, TileModel, } from '../models';
3
3
  import { sha1 } from '../utils/sha1';
4
4
  export class CollectionBrowserDataSource {
5
5
  constructor(
@@ -16,7 +16,19 @@ export class CollectionBrowserDataSource {
16
16
  * Maps the full query key to the pages being fetched for that query
17
17
  */
18
18
  this.pageFetchesInProgress = {};
19
+ /**
20
+ * A record of the query key used for the last search.
21
+ * If this changes, we need to load new results.
22
+ */
23
+ this.previousQueryKey = '';
24
+ this.id = Math.random();
25
+ /**
26
+ * @inheritdoc
27
+ */
19
28
  this.totalResults = 0;
29
+ /**
30
+ * @inheritdoc
31
+ */
20
32
  this.endOfDataReached = false;
21
33
  /**
22
34
  * @inheritdoc
@@ -30,14 +42,126 @@ export class CollectionBrowserDataSource {
30
42
  * @inheritdoc
31
43
  */
32
44
  this.prefixFilterCountMap = {};
45
+ /**
46
+ * Internal property to store the private value backing the `initialSearchComplete` getter.
47
+ */
48
+ this._initialSearchCompletePromise = new Promise(res => {
49
+ this._initialSearchCompleteResolver = res;
50
+ });
51
+ /**
52
+ * @inheritdoc
53
+ */
54
+ this.checkAllTiles = () => {
55
+ this.map(model => {
56
+ const cloned = model.clone();
57
+ cloned.checked = true;
58
+ return cloned;
59
+ });
60
+ };
61
+ /**
62
+ * @inheritdoc
63
+ */
64
+ this.uncheckAllTiles = () => {
65
+ this.map(model => {
66
+ const cloned = model.clone();
67
+ cloned.checked = false;
68
+ return cloned;
69
+ });
70
+ };
71
+ /**
72
+ * @inheritdoc
73
+ */
74
+ this.removeCheckedTiles = () => {
75
+ // To make sure our data source remains page-aligned, we will offset our data source by
76
+ // the number of removed tiles, so that we can just add the offset when the infinite
77
+ // scroller queries for cell contents.
78
+ // This only matters while we're still viewing the same set of results. If the user changes
79
+ // their query/filters/sort, then the data source is overwritten and the offset cleared.
80
+ const { checkedTileModels, uncheckedTileModels } = this;
81
+ const numChecked = checkedTileModels.length;
82
+ if (numChecked === 0)
83
+ return;
84
+ this.offset += numChecked;
85
+ const newPages = {};
86
+ // Which page the remaining tile models start on, post-offset
87
+ let offsetPageNumber = Math.floor(this.offset / this.pageSize) + 1;
88
+ let indexOnPage = this.offset % this.pageSize;
89
+ // Fill the pages up to that point with empty models
90
+ for (let page = 1; page <= offsetPageNumber; page += 1) {
91
+ const remainingHidden = this.offset - this.pageSize * (page - 1);
92
+ const offsetCellsOnPage = Math.min(this.pageSize, remainingHidden);
93
+ newPages[page] = Array(offsetCellsOnPage).fill(undefined);
94
+ }
95
+ // Shift all the remaining tiles into their new positions in the data source
96
+ for (const model of uncheckedTileModels) {
97
+ if (!newPages[offsetPageNumber])
98
+ newPages[offsetPageNumber] = [];
99
+ newPages[offsetPageNumber].push(model);
100
+ indexOnPage += 1;
101
+ if (indexOnPage >= this.pageSize) {
102
+ offsetPageNumber += 1;
103
+ indexOnPage = 0;
104
+ }
105
+ }
106
+ // Swap in the new pages
107
+ this.pages = newPages;
108
+ this.numTileModels -= numChecked;
109
+ this.host.requestUpdate();
110
+ this.host.refreshVisibleResults();
111
+ };
33
112
  this.host.addController(this);
34
113
  }
114
+ /**
115
+ * @inheritdoc
116
+ */
117
+ get initialSearchComplete() {
118
+ return this._initialSearchCompletePromise;
119
+ }
120
+ hostUpdate() {
121
+ // This reactive controller hook is run whenever the host component (collection-browser) performs an update.
122
+ // We check whether the host's state has changed in a way which should trigger a reset & new results fetch.
123
+ // Only the currently-installed data source should react to the update
124
+ if (this.host.dataSource !== this)
125
+ return;
126
+ // Can't perform searches without a search service
127
+ if (!this.host.searchService)
128
+ return;
129
+ // We should only reset if part of the full query state has changed
130
+ const queryKeyChanged = this.pageFetchQueryKey !== this.previousQueryKey;
131
+ console.log('query keys', this.pageFetchQueryKey, this.previousQueryKey);
132
+ if (!queryKeyChanged)
133
+ return;
134
+ // We should only reset if either:
135
+ // (a) our state permits a valid search, or
136
+ // (b) we have a blank query that we want to show empty results for
137
+ const shouldShowEmptyQueryResults = this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';
138
+ if (!(this.canPerformSearch || shouldShowEmptyQueryResults))
139
+ return;
140
+ this.handleQueryChange();
141
+ }
35
142
  /**
36
143
  * @inheritdoc
37
144
  */
38
145
  get size() {
39
146
  return this.numTileModels;
40
147
  }
148
+ /**
149
+ * @inheritdoc
150
+ */
151
+ reset() {
152
+ this.pages = {};
153
+ this.aggregations = {};
154
+ this.yearHistogramAggregation = undefined;
155
+ this.pageFetchesInProgress = {};
156
+ this.pageElements = undefined;
157
+ this.parentCollections = [];
158
+ this.prefixFilterCountMap = {};
159
+ this.offset = 0;
160
+ this.numTileModels = 0;
161
+ this.totalResults = 0;
162
+ this.endOfDataReached = false;
163
+ this.host.requestUpdate();
164
+ }
41
165
  /**
42
166
  * @inheritdoc
43
167
  */
@@ -73,6 +197,9 @@ export class CollectionBrowserDataSource {
73
197
  const indexOnPage = index % this.pageSize;
74
198
  return (_a = this.pages[pageNum]) === null || _a === void 0 ? void 0 : _a[indexOnPage];
75
199
  }
200
+ /**
201
+ * @inheritdoc
202
+ */
76
203
  indexOf(tile) {
77
204
  return Object.values(this.pages).flat().indexOf(tile);
78
205
  }
@@ -83,32 +210,22 @@ export class CollectionBrowserDataSource {
83
210
  this.reset();
84
211
  this.pageSize = pageSize;
85
212
  }
86
- /**
87
- * @inheritdoc
88
- */
89
- reset() {
90
- this.pages = {};
91
- this.aggregations = {};
92
- this.yearHistogramAggregation = undefined;
93
- this.pageFetchesInProgress = {};
94
- this.pageElements = undefined;
95
- this.parentCollections = [];
96
- this.prefixFilterCountMap = {};
97
- this.offset = 0;
98
- this.numTileModels = 0;
99
- this.totalResults = 0;
100
- this.endOfDataReached = false;
101
- this.host.requestUpdate();
102
- }
103
213
  /**
104
214
  * @inheritdoc
105
215
  */
106
216
  async handleQueryChange() {
107
217
  this.reset();
218
+ // Reset the `initialSearchComplete` promise with a new value for the imminent search
219
+ this._initialSearchCompletePromise = new Promise(res => {
220
+ this._initialSearchCompleteResolver = res;
221
+ });
222
+ // Fire the initial page & facet requests
108
223
  await Promise.all([
109
224
  this.doInitialPageFetch(),
110
225
  this.host.suppressFacets ? null : this.fetchFacets(),
111
226
  ]);
227
+ // Resolve the `initialSearchComplete` promise for this search
228
+ this._initialSearchCompleteResolver(true);
112
229
  }
113
230
  /**
114
231
  * @inheritdoc
@@ -119,58 +236,7 @@ export class CollectionBrowserDataSource {
119
236
  tileModels.map((model, index, array) => model ? callback(model, index, array) : model),
120
237
  ]));
121
238
  this.host.requestUpdate();
122
- }
123
- /**
124
- * @inheritdoc
125
- */
126
- checkAllTiles() {
127
- this.map(model => ({ ...model, checked: true }));
128
- }
129
- /**
130
- * @inheritdoc
131
- */
132
- uncheckAllTiles() {
133
- this.map(model => ({ ...model, checked: false }));
134
- }
135
- /**
136
- * @inheritdoc
137
- */
138
- removeCheckedTiles() {
139
- // To make sure our data source remains page-aligned, we will offset our data source by
140
- // the number of removed tiles, so that we can just add the offset when the infinite
141
- // scroller queries for cell contents.
142
- // This only matters while we're still viewing the same set of results. If the user changes
143
- // their query/filters/sort, then the data source is overwritten and the offset cleared.
144
- const { checkedTileModels, uncheckedTileModels } = this;
145
- const numChecked = checkedTileModels.length;
146
- if (numChecked === 0)
147
- return;
148
- this.offset += numChecked;
149
- const newPages = {};
150
- // Which page the remaining tile models start on, post-offset
151
- let offsetPageNumber = Math.floor(this.offset / this.pageSize) + 1;
152
- let indexOnPage = this.offset % this.pageSize;
153
- // Fill the pages up to that point with empty models
154
- for (let page = 1; page <= offsetPageNumber; page += 1) {
155
- const remainingHidden = this.offset - this.pageSize * (page - 1);
156
- const offsetCellsOnPage = Math.min(this.pageSize, remainingHidden);
157
- newPages[page] = Array(offsetCellsOnPage).fill(undefined);
158
- }
159
- // Shift all the remaining tiles into their new positions in the data source
160
- for (const model of uncheckedTileModels) {
161
- if (!newPages[offsetPageNumber])
162
- newPages[offsetPageNumber] = [];
163
- newPages[offsetPageNumber].push(model);
164
- indexOnPage += 1;
165
- if (indexOnPage >= this.pageSize) {
166
- offsetPageNumber += 1;
167
- indexOnPage = 0;
168
- }
169
- }
170
- // Swap in the new pages
171
- this.pages = newPages;
172
- this.numTileModels -= numChecked;
173
- this.host.requestUpdate();
239
+ this.host.refreshVisibleResults();
174
240
  }
175
241
  /**
176
242
  * @inheritdoc
@@ -227,16 +293,16 @@ export class CollectionBrowserDataSource {
227
293
  * - Any currently-applied prefix filters
228
294
  * - The current sort options
229
295
  *
230
- * This lets us keep track of queries so we don't persist data that's
231
- * no longer relevant.
296
+ * This lets us internally keep track of queries so we don't persist data that's
297
+ * no longer relevant. Not meant to be human-readable.
232
298
  */
233
299
  get pageFetchQueryKey() {
234
300
  var _a, _b, _c, _d, _e;
235
- const profileKey = `${this.host.withinProfile}--${this.host.profileElement}`;
301
+ const profileKey = `pf;${this.host.withinProfile}--pe;${this.host.profileElement}`;
236
302
  const pageTarget = (_a = this.host.withinCollection) !== null && _a !== void 0 ? _a : profileKey;
237
303
  const sortField = (_c = (_b = this.host.sortParam) === null || _b === void 0 ? void 0 : _b.field) !== null && _c !== void 0 ? _c : 'none';
238
304
  const sortDirection = (_e = (_d = this.host.sortParam) === null || _d === void 0 ? void 0 : _d.direction) !== null && _e !== void 0 ? _e : 'none';
239
- return `${this.fullQuery}-${pageTarget}-${this.host.searchType}-${sortField}-${sortDirection}`;
305
+ return `fq:${this.fullQuery}-pt:${pageTarget}-st:${this.host.searchType}-sf:${sortField}-sd:${sortDirection}`;
240
306
  }
241
307
  /**
242
308
  * Similar to `pageFetchQueryKey` above, but excludes sort fields since they
@@ -458,9 +524,11 @@ export class CollectionBrowserDataSource {
458
524
  */
459
525
  async fetchFacets() {
460
526
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
527
+ console.log('fetchFacets', this.id, this.host.profileElement);
461
528
  const trimmedQuery = (_a = this.host.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
462
529
  if (!this.canPerformSearch)
463
530
  return;
531
+ console.log('will actually fetch facets');
464
532
  const { facetFetchQueryKey } = this;
465
533
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
466
534
  const params = {
@@ -481,8 +549,10 @@ export class CollectionBrowserDataSource {
481
549
  // If so, we just want to discard this set of aggregations because they are
482
550
  // likely no longer valid for the newer query.
483
551
  const queryChangedSinceFetch = facetFetchQueryKey !== this.facetFetchQueryKey;
484
- if (queryChangedSinceFetch)
552
+ if (queryChangedSinceFetch) {
553
+ console.log('facet query has changed since fetch, returning. new/old:', this.facetFetchQueryKey, facetFetchQueryKey);
485
554
  return;
555
+ }
486
556
  if (!success) {
487
557
  const errorMsg = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _c === void 0 ? void 0 : _c.message;
488
558
  const detailMsg = (_e = (_d = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _d === void 0 ? void 0 : _d.details) === null || _e === void 0 ? void 0 : _e.message;
@@ -490,6 +560,7 @@ export class CollectionBrowserDataSource {
490
560
  // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
491
561
  (_g = (_f = window === null || window === void 0 ? void 0 : window.Sentry) === null || _f === void 0 ? void 0 : _f.captureMessage) === null || _g === void 0 ? void 0 : _g.call(_f, 'Missing or malformed facet response from backend', 'error');
492
562
  }
563
+ this.host.setFacetsLoading(false);
493
564
  return;
494
565
  }
495
566
  const { aggregations, collectionTitles } = success.response;
@@ -523,7 +594,7 @@ export class CollectionBrowserDataSource {
523
594
  */
524
595
  async fetchPage(pageNumber, numInitialPages = 1) {
525
596
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
526
- console.log(`fetchPage(${pageNumber})`, this.canPerformSearch, this.hasPage(pageNumber), this.endOfDataReached, this.host.baseQuery, JSON.stringify(this.host.selectedFacets));
597
+ console.log(`fetchPage(${pageNumber})`, this.id, this.canPerformSearch, this.hasPage(pageNumber), this.endOfDataReached, this.host.baseQuery, JSON.stringify(this.host.selectedFacets), this.pageFetchQueryKey);
527
598
  const trimmedQuery = (_a = this.host.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
528
599
  if (!this.canPerformSearch)
529
600
  return;
@@ -547,6 +618,7 @@ export class CollectionBrowserDataSource {
547
618
  pageFetches.add(pageNumber + i);
548
619
  }
549
620
  this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
621
+ this.previousQueryKey = pageFetchQueryKey;
550
622
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
551
623
  const params = {
552
624
  ...this.pageSpecifierParams,
@@ -592,6 +664,7 @@ export class CollectionBrowserDataSource {
592
664
  this.host.emitEmptyResults();
593
665
  }
594
666
  if (this.host.withinCollection) {
667
+ console.log('host is within collection, setting collection info:', success.response.collectionExtraInfo);
595
668
  this.collectionExtraInfo = success.response.collectionExtraInfo;
596
669
  // For collections, we want the UI to respect the default sort option
597
670
  // which can be specified in metadata, or otherwise assumed to be week:desc
@@ -601,10 +674,13 @@ export class CollectionBrowserDataSource {
601
674
  }
602
675
  }
603
676
  else if (this.host.withinProfile) {
604
- console.log('host is within profile, setting acct info:', success.response.accountExtraInfo);
677
+ console.log('host is within profile, setting acct info:', success.response.accountExtraInfo, success.response.pageElements);
605
678
  this.accountExtraInfo = success.response.accountExtraInfo;
606
679
  this.pageElements = success.response.pageElements;
607
680
  }
681
+ else {
682
+ console.log('not within profile/collxn', this.host.withinCollection, this.host.withinProfile);
683
+ }
608
684
  const { results, collectionTitles } = success.response;
609
685
  if (results && results.length > 0) {
610
686
  // Load any collection titles present on the response into the cache,
@@ -625,6 +701,7 @@ export class CollectionBrowserDataSource {
625
701
  // temporary estimates based on pages rendered so far).
626
702
  const resultCountDiscrepancy = numRows - results.length;
627
703
  if (resultCountDiscrepancy > 0) {
704
+ console.log('End of data reached');
628
705
  this.endOfDataReached = true;
629
706
  this.host.setTileCount(this.totalResults);
630
707
  }
@@ -646,57 +723,9 @@ export class CollectionBrowserDataSource {
646
723
  // const datasource = { ...this.dataSource };
647
724
  const tiles = [];
648
725
  results === null || results === void 0 ? void 0 : results.forEach(result => {
649
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13;
650
726
  if (!result.identifier)
651
727
  return;
652
- let loginRequired = false;
653
- let contentWarning = false;
654
- // Check if item and item in "modifying" collection, setting above flags
655
- if (((_a = result.collection) === null || _a === void 0 ? void 0 : _a.values.length) &&
656
- ((_b = result.mediatype) === null || _b === void 0 ? void 0 : _b.value) !== 'collection') {
657
- for (const collection of (_d = (_c = result.collection) === null || _c === void 0 ? void 0 : _c.values) !== null && _d !== void 0 ? _d : []) {
658
- if (collection === 'loggedin') {
659
- loginRequired = true;
660
- if (contentWarning)
661
- break;
662
- }
663
- if (collection === 'no-preview') {
664
- contentWarning = true;
665
- if (loginRequired)
666
- break;
667
- }
668
- }
669
- }
670
- tiles.push({
671
- averageRating: (_e = result.avg_rating) === null || _e === void 0 ? void 0 : _e.value,
672
- checked: false,
673
- collections: (_g = (_f = result.collection) === null || _f === void 0 ? void 0 : _f.values) !== null && _g !== void 0 ? _g : [],
674
- collectionFilesCount: (_j = (_h = result.collection_files_count) === null || _h === void 0 ? void 0 : _h.value) !== null && _j !== void 0 ? _j : 0,
675
- collectionSize: (_l = (_k = result.collection_size) === null || _k === void 0 ? void 0 : _k.value) !== null && _l !== void 0 ? _l : 0,
676
- commentCount: (_o = (_m = result.num_reviews) === null || _m === void 0 ? void 0 : _m.value) !== null && _o !== void 0 ? _o : 0,
677
- creator: (_p = result.creator) === null || _p === void 0 ? void 0 : _p.value,
678
- creators: (_r = (_q = result.creator) === null || _q === void 0 ? void 0 : _q.values) !== null && _r !== void 0 ? _r : [],
679
- dateAdded: (_s = result.addeddate) === null || _s === void 0 ? void 0 : _s.value,
680
- dateArchived: (_t = result.publicdate) === null || _t === void 0 ? void 0 : _t.value,
681
- datePublished: (_u = result.date) === null || _u === void 0 ? void 0 : _u.value,
682
- dateReviewed: (_v = result.reviewdate) === null || _v === void 0 ? void 0 : _v.value,
683
- description: (_w = result.description) === null || _w === void 0 ? void 0 : _w.values.join('\n'),
684
- favCount: (_y = (_x = result.num_favorites) === null || _x === void 0 ? void 0 : _x.value) !== null && _y !== void 0 ? _y : 0,
685
- href: this.collapseRepeatedQuotes((_z = result.__href__) === null || _z === void 0 ? void 0 : _z.value),
686
- identifier: result.identifier,
687
- issue: (_0 = result.issue) === null || _0 === void 0 ? void 0 : _0.value,
688
- itemCount: (_2 = (_1 = result.item_count) === null || _1 === void 0 ? void 0 : _1.value) !== null && _2 !== void 0 ? _2 : 0,
689
- mediatype: this.getMediatype(result),
690
- snippets: (_4 = (_3 = result.highlight) === null || _3 === void 0 ? void 0 : _3.values) !== null && _4 !== void 0 ? _4 : [],
691
- source: (_5 = result.source) === null || _5 === void 0 ? void 0 : _5.value,
692
- subjects: (_7 = (_6 = result.subject) === null || _6 === void 0 ? void 0 : _6.values) !== null && _7 !== void 0 ? _7 : [],
693
- title: (_9 = (_8 = result.title) === null || _8 === void 0 ? void 0 : _8.value) !== null && _9 !== void 0 ? _9 : '',
694
- volume: (_10 = result.volume) === null || _10 === void 0 ? void 0 : _10.value,
695
- viewCount: (_12 = (_11 = result.downloads) === null || _11 === void 0 ? void 0 : _11.value) !== null && _12 !== void 0 ? _12 : 0,
696
- weeklyViewCount: (_13 = result.week) === null || _13 === void 0 ? void 0 : _13.value,
697
- loginRequired,
698
- contentWarning,
699
- });
728
+ tiles.push(new TileModel(result));
700
729
  });
701
730
  this.addPage(pageNumber, tiles);
702
731
  const visiblePages = this.host.currentVisiblePageNumbers;
@@ -705,42 +734,6 @@ export class CollectionBrowserDataSource {
705
734
  this.host.refreshVisibleResults();
706
735
  }
707
736
  }
708
- /**
709
- * Returns the mediatype string for the given search result, taking into account
710
- * the special `favorited_search` hit type.
711
- * @param result The search result to extract a mediatype from
712
- */
713
- getMediatype(result) {
714
- var _a, _b, _c;
715
- /**
716
- * hit_type == 'favorited_search' is basically a new hit_type
717
- * - we are getting from PPS.
718
- * - which gives response for fav- collection
719
- * - having favorited items like account/collection/item etc..
720
- * - as user can also favorite a search result (a search page)
721
- * - so we need to have response (having fav- items and fav- search results)
722
- *
723
- * if backend hit_type == 'favorited_search'
724
- * - let's assume a "search" as new mediatype
725
- */
726
- if (((_a = result === null || result === void 0 ? void 0 : result.rawMetadata) === null || _a === void 0 ? void 0 : _a.hit_type) === 'favorited_search') {
727
- return 'search';
728
- }
729
- return (_c = (_b = result.mediatype) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 'data';
730
- }
731
- /**
732
- * Returns the input string, but removing one set of quotes from all instances of
733
- * ""clauses wrapped in two sets of quotes"". This assumes the quotes are already
734
- * URL-encoded.
735
- *
736
- * This should be a temporary measure to address the fact that the __href__ field
737
- * sometimes acquires extra quotation marks during query rewriting. Once there is a
738
- * full Lucene parser in place that handles quoted queries correctly, this can likely
739
- * be removed.
740
- */
741
- collapseRepeatedQuotes(str) {
742
- return str === null || str === void 0 ? void 0 : str.replace(/%22%22(?!%22%22)(.+?)%22%22/g, '%22$1%22');
743
- }
744
737
  /**
745
738
  * Fetches the aggregation buckets for the given prefix filter type.
746
739
  */