@internetarchive/collection-browser 1.14.17-alpha.37 → 1.14.17-alpha.38

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.
@@ -13,9 +13,9 @@ export declare class CollectionBrowserDataSource implements CollectionBrowserDat
13
13
  private offset;
14
14
  private numTileModels;
15
15
  /**
16
- * Maps the full query key to the pages being fetched for that query
16
+ * A set of fetch IDs that are valid for the current query state
17
17
  */
18
- private pageFetchesInProgress;
18
+ private fetchesInProgress;
19
19
  /**
20
20
  * A record of the query key used for the last search.
21
21
  * If this changes, we need to load new results.
@@ -2,6 +2,7 @@ import { FilterConstraint, FilterMapBuilder, SearchType, } from '@internetarchiv
2
2
  import { prefixFilterAggregationKeys, TileModel, } from '../models';
3
3
  import { sha1 } from '../utils/sha1';
4
4
  export class CollectionBrowserDataSource {
5
+ // eslint-disable-next-line no-useless-constructor
5
6
  constructor(
6
7
  /** The host element to which this controller should attach listeners */
7
8
  host,
@@ -13,9 +14,9 @@ export class CollectionBrowserDataSource {
13
14
  this.offset = 0;
14
15
  this.numTileModels = 0;
15
16
  /**
16
- * Maps the full query key to the pages being fetched for that query
17
+ * A set of fetch IDs that are valid for the current query state
17
18
  */
18
- this.pageFetchesInProgress = {};
19
+ this.fetchesInProgress = new Set();
19
20
  /**
20
21
  * A record of the query key used for the last search.
21
22
  * If this changes, we need to load new results.
@@ -116,7 +117,7 @@ export class CollectionBrowserDataSource {
116
117
  this.requestHostUpdate();
117
118
  this.refreshVisibleResults();
118
119
  };
119
- //this.host.addController(this);
120
+ // Just setting some property values
120
121
  }
121
122
  /**
122
123
  * @inheritdoc
@@ -171,7 +172,6 @@ export class CollectionBrowserDataSource {
171
172
  this.pages = {};
172
173
  this.aggregations = {};
173
174
  this.yearHistogramAggregation = undefined;
174
- this.pageFetchesInProgress = {};
175
175
  this.pageElements = undefined;
176
176
  this.parentCollections = [];
177
177
  this.prefixFilterCountMap = {};
@@ -181,6 +181,8 @@ export class CollectionBrowserDataSource {
181
181
  this.totalResults = 0;
182
182
  this.endOfDataReached = false;
183
183
  this.queryInitialized = false;
184
+ // Invalidate any fetches in progress
185
+ this.fetchesInProgress.clear();
184
186
  if (this.activeOnHost)
185
187
  this.host.setTotalResultCount(0);
186
188
  this.requestHostUpdate();
@@ -590,6 +592,9 @@ export class CollectionBrowserDataSource {
590
592
  return;
591
593
  console.log('will actually fetch facets');
592
594
  const { facetFetchQueryKey } = this;
595
+ if (this.fetchesInProgress.has(facetFetchQueryKey))
596
+ return;
597
+ this.fetchesInProgress.add(facetFetchQueryKey);
593
598
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
594
599
  const params = {
595
600
  ...this.pageSpecifierParams,
@@ -608,7 +613,8 @@ export class CollectionBrowserDataSource {
608
613
  // This is checking to see if the query has changed since the data was fetched.
609
614
  // If so, we just want to discard this set of aggregations because they are
610
615
  // likely no longer valid for the newer query.
611
- const queryChangedSinceFetch = facetFetchQueryKey !== this.facetFetchQueryKey;
616
+ const queryChangedSinceFetch = this.fetchesInProgress.has(facetFetchQueryKey);
617
+ this.fetchesInProgress.delete(facetFetchQueryKey);
612
618
  if (queryChangedSinceFetch) {
613
619
  console.log('facet query has changed since fetch, returning. new/old:', this.facetFetchQueryKey, facetFetchQueryKey);
614
620
  return;
@@ -653,7 +659,7 @@ export class CollectionBrowserDataSource {
653
659
  * if `pageNumber != 1`, defaulting to a single page.
654
660
  */
655
661
  async fetchPage(pageNumber, numInitialPages = 1) {
656
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
662
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
657
663
  const trimmedQuery = (_a = this.host.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
658
664
  if (!this.canPerformSearch)
659
665
  return;
@@ -668,14 +674,16 @@ export class CollectionBrowserDataSource {
668
674
  const numRows = this.pageSize * numPages;
669
675
  // if a fetch is already in progress for this query and page, don't fetch again
670
676
  const { pageFetchQueryKey } = this;
671
- const pageFetches = (_b = this.pageFetchesInProgress[pageFetchQueryKey]) !== null && _b !== void 0 ? _b : new Set();
672
- if (pageFetches.has(pageNumber))
677
+ const currentPageKey = `${pageFetchQueryKey}-p:${pageNumber}`;
678
+ if (this.fetchesInProgress.has(currentPageKey))
673
679
  return;
680
+ // const pageFetches =
681
+ // this.fetchesInProgress[pageFetchQueryKey] ?? new Set();
682
+ // if (pageFetches.has(pageNumber)) return;
674
683
  for (let i = 0; i < numPages; i += 1) {
675
- pageFetches.add(pageNumber + i);
684
+ this.fetchesInProgress.add(`${pageFetchQueryKey}-p:${pageNumber + i}`);
676
685
  }
677
686
  console.log(`fetchPage(${pageNumber})`, this.id, this.canPerformSearch, this.hasPage(pageNumber), this.endOfDataReached, this.host.baseQuery, JSON.stringify(this.host.selectedFacets), this.pageFetchQueryKey);
678
- this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
679
687
  this.previousQueryKey = pageFetchQueryKey;
680
688
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
681
689
  const params = {
@@ -689,26 +697,24 @@ export class CollectionBrowserDataSource {
689
697
  };
690
698
  params.uid = await this.requestUID(params, 'hits');
691
699
  console.log('=== FIRING PAGE REQUEST ===');
692
- const searchResponse = await ((_c = this.host.searchService) === null || _c === void 0 ? void 0 : _c.search(params, this.host.searchType));
700
+ const searchResponse = await ((_b = this.host.searchService) === null || _b === void 0 ? void 0 : _b.search(params, this.host.searchType));
693
701
  console.log('=== RECEIVED PAGE RESPONSE IN CB === ');
694
702
  const success = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success;
695
- // This is checking to see if the query has changed since the data was fetched.
696
- // If so, we just want to discard the data since there should be a new query
697
- // right behind it.
698
- const queryChangedSinceFetch = pageFetchQueryKey !== this.pageFetchQueryKey;
699
- if (queryChangedSinceFetch)
703
+ // This is checking to see if the fetch has been invalidated since it was fired off.
704
+ // If so, we just want to discard the response since it is for an obsolete query state.
705
+ if (!this.fetchesInProgress.has(currentPageKey))
700
706
  return;
707
+ for (let i = 0; i < numPages; i += 1) {
708
+ this.fetchesInProgress.delete(`${pageFetchQueryKey}-p:${pageNumber + i}`);
709
+ }
701
710
  if (!success) {
702
- const errorMsg = (_d = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _d === void 0 ? void 0 : _d.message;
703
- const detailMsg = (_f = (_e = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _e === void 0 ? void 0 : _e.details) === null || _f === void 0 ? void 0 : _f.message;
711
+ const errorMsg = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _c === void 0 ? void 0 : _c.message;
712
+ 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;
704
713
  this.queryErrorMessage = `${errorMsg !== null && errorMsg !== void 0 ? errorMsg : ''}${detailMsg ? `; ${detailMsg}` : ''}`;
705
714
  if (!this.queryErrorMessage) {
706
715
  this.queryErrorMessage = 'Missing or malformed response from backend';
707
716
  // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
708
- (_h = (_g = window === null || window === void 0 ? void 0 : window.Sentry) === null || _g === void 0 ? void 0 : _g.captureMessage) === null || _h === void 0 ? void 0 : _h.call(_g, this.queryErrorMessage, 'error');
709
- }
710
- for (let i = 0; i < numPages; i += 1) {
711
- (_j = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _j === void 0 ? void 0 : _j.delete(pageNumber + i);
717
+ (_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, this.queryErrorMessage, 'error');
712
718
  }
713
719
  this.setSearchResultsLoading(false);
714
720
  this.requestHostUpdate();
@@ -729,7 +735,7 @@ export class CollectionBrowserDataSource {
729
735
  // which can be specified in metadata, or otherwise assumed to be week:desc
730
736
  this.host.applyDefaultCollectionSort(this.collectionExtraInfo);
731
737
  if (this.collectionExtraInfo) {
732
- this.parentCollections = [].concat((_l = (_k = this.collectionExtraInfo.public_metadata) === null || _k === void 0 ? void 0 : _k.collection) !== null && _l !== void 0 ? _l : []);
738
+ this.parentCollections = [].concat((_j = (_h = this.collectionExtraInfo.public_metadata) === null || _h === void 0 ? void 0 : _h.collection) !== null && _j !== void 0 ? _j : []);
733
739
  }
734
740
  }
735
741
  else if (this.host.withinProfile) {
@@ -765,9 +771,6 @@ export class CollectionBrowserDataSource {
765
771
  if (this.activeOnHost)
766
772
  this.host.setTileCount(this.totalResults);
767
773
  }
768
- for (let i = 0; i < numPages; i += 1) {
769
- (_m = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _m === void 0 ? void 0 : _m.delete(pageNumber + i);
770
- }
771
774
  this.requestHostUpdate();
772
775
  }
773
776
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"collection-browser-data-source.js","sourceRoot":"","sources":["../../../src/data-source/collection-browser-data-source.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveControllerHost } from 'lit';\nimport {\n AccountExtraInfo,\n Aggregation,\n Bucket,\n CollectionExtraInfo,\n FilterConstraint,\n FilterMap,\n FilterMapBuilder,\n PageElementMap,\n SearchParams,\n SearchResult,\n SearchType,\n} from '@internetarchive/search-service';\nimport {\n prefixFilterAggregationKeys,\n type FacetBucket,\n type PrefixFilterType,\n TileModel,\n PrefixFilterCounts,\n RequestKind,\n} from '../models';\nimport type { PageSpecifierParams } from './models';\nimport type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';\nimport type { CollectionBrowserSearchInterface } from './collection-browser-query-state';\nimport { sha1 } from '../utils/sha1';\n\nexport class CollectionBrowserDataSource\n implements CollectionBrowserDataSourceInterface\n{\n private pages: Record<string, TileModel[]> = {};\n\n private offset = 0;\n\n private numTileModels = 0;\n\n /**\n * Maps the full query key to the pages being fetched for that query\n */\n private pageFetchesInProgress: Record<string, Set<number>> = {};\n\n /**\n * A record of the query key used for the last search.\n * If this changes, we need to load new results.\n */\n private previousQueryKey: string = '';\n\n private searchResultsLoading = false;\n\n private facetsLoading = false;\n\n // TEMP for ease of debugging\n private id = Math.random();\n\n /**\n * @inheritdoc\n */\n totalResults = 0;\n\n /**\n * @inheritdoc\n */\n endOfDataReached = false;\n\n /**\n * @inheritdoc\n */\n queryInitialized = false;\n\n /**\n * @inheritdoc\n */\n aggregations?: Record<string, Aggregation>;\n\n /**\n * @inheritdoc\n */\n yearHistogramAggregation?: Aggregation;\n\n /**\n * @inheritdoc\n */\n collectionTitles = new Map<string, string>();\n\n /**\n * @inheritdoc\n */\n collectionExtraInfo?: CollectionExtraInfo;\n\n /**\n * @inheritdoc\n */\n accountExtraInfo?: AccountExtraInfo;\n\n /**\n * @inheritdoc\n */\n pageElements?: PageElementMap;\n\n /**\n * @inheritdoc\n */\n parentCollections?: string[] = [];\n\n /**\n * @inheritdoc\n */\n prefixFilterCountMap: Partial<Record<PrefixFilterType, PrefixFilterCounts>> =\n {};\n\n /**\n * @inheritdoc\n */\n queryErrorMessage?: string;\n\n /**\n * Internal property to store the `resolve` function for the most recent\n * `initialSearchComplete` promise, allowing us to resolve it at the appropriate time.\n */\n private _initialSearchCompleteResolver!: (val: boolean) => void;\n\n /**\n * Internal property to store the private value backing the `initialSearchComplete` getter.\n */\n private _initialSearchCompletePromise: Promise<boolean> = new Promise(res => {\n this._initialSearchCompleteResolver = res;\n });\n\n /**\n * @inheritdoc\n */\n get initialSearchComplete(): Promise<boolean> {\n return this._initialSearchCompletePromise;\n }\n\n constructor(\n /** The host element to which this controller should attach listeners */\n private readonly host: ReactiveControllerHost &\n CollectionBrowserSearchInterface,\n /** Default size of result pages */\n private pageSize: number\n ) {\n //this.host.addController(this);\n }\n\n hostUpdate(): void {\n console.log(\n 'hostUpdate',\n this.id,\n this.previousQueryKey,\n this.pageFetchQueryKey\n );\n // This reactive controller hook is run whenever the host component (collection-browser) performs an update.\n // We check whether the host's state has changed in a way which should trigger a reset & new results fetch.\n\n // Only the currently-installed data source should react to the update\n if (!this.activeOnHost) return;\n\n // Copy loading states onto the host\n this.setSearchResultsLoading(this.searchResultsLoading);\n this.setFacetsLoading(this.facetsLoading);\n\n // Can't perform searches without a search service\n if (!this.host.searchService) return;\n\n // We should only reset if part of the full query state has changed\n const queryKeyChanged = this.pageFetchQueryKey !== this.previousQueryKey;\n console.log('query keys', this.pageFetchQueryKey, this.previousQueryKey);\n if (!queryKeyChanged) return;\n\n // We should only reset if either:\n // (a) our state permits a valid search, or\n // (b) we have a blank query that we want to show empty results for\n const shouldShowEmptyQueryResults =\n this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';\n if (!(this.canPerformSearch || shouldShowEmptyQueryResults)) return;\n\n if (this.activeOnHost) this.host.emitQueryStateChanged();\n this.handleQueryChange();\n }\n\n /**\n * Returns whether this data source is the one currently installed on the host component.\n */\n private get activeOnHost(): boolean {\n return this.host.dataSource === this;\n }\n\n /**\n * @inheritdoc\n */\n get size(): number {\n return this.numTileModels;\n }\n\n /**\n * @inheritdoc\n */\n reset(): void {\n this.pages = {};\n this.aggregations = {};\n this.yearHistogramAggregation = undefined;\n this.pageFetchesInProgress = {};\n this.pageElements = undefined;\n this.parentCollections = [];\n this.prefixFilterCountMap = {};\n this.queryErrorMessage = undefined;\n\n this.offset = 0;\n this.numTileModels = 0;\n this.totalResults = 0;\n this.endOfDataReached = false;\n this.queryInitialized = false;\n\n if (this.activeOnHost) this.host.setTotalResultCount(0);\n this.requestHostUpdate();\n }\n\n /**\n * @inheritdoc\n */\n addPage(pageNum: number, pageTiles: TileModel[]): void {\n this.pages[pageNum] = pageTiles;\n this.numTileModels += pageTiles.length;\n this.requestHostUpdate();\n }\n\n /**\n * @inheritdoc\n */\n getPage(pageNum: number): TileModel[] {\n return this.pages[pageNum];\n }\n\n /**\n * @inheritdoc\n */\n getAllPages(): Record<string, TileModel[]> {\n return this.pages;\n }\n\n /**\n * @inheritdoc\n */\n hasPage(pageNum: number): boolean {\n return !!this.pages[pageNum];\n }\n\n /**\n * @inheritdoc\n */\n getTileModelAt(index: number): TileModel | undefined {\n const pageNum = Math.floor(index / this.pageSize) + 1;\n const indexOnPage = index % this.pageSize;\n return this.pages[pageNum]?.[indexOnPage];\n }\n\n /**\n * @inheritdoc\n */\n indexOf(tile: TileModel): number {\n return Object.values(this.pages).flat().indexOf(tile);\n }\n\n /**\n * @inheritdoc\n */\n setPageSize(pageSize: number): void {\n this.reset();\n this.pageSize = pageSize;\n }\n\n /**\n * @inheritdoc\n */\n async handleQueryChange(): Promise<void> {\n this.reset();\n\n // Reset the `initialSearchComplete` promise with a new value for the imminent search\n this._initialSearchCompletePromise = new Promise(res => {\n this._initialSearchCompleteResolver = res;\n });\n\n // Fire the initial page & facet requests\n this.queryInitialized = true;\n await Promise.all([\n this.doInitialPageFetch(),\n this.host.suppressFacets ? null : this.fetchFacets(),\n ]);\n\n // Resolve the `initialSearchComplete` promise for this search\n this._initialSearchCompleteResolver(true);\n }\n\n /**\n * @inheritdoc\n */\n map(\n callback: (model: TileModel, index: number, array: TileModel[]) => TileModel\n ): void {\n this.pages = Object.fromEntries(\n Object.entries(this.pages).map(([page, tileModels]) => [\n page,\n tileModels.map((model, index, array) =>\n model ? callback(model, index, array) : model\n ),\n ])\n );\n this.requestHostUpdate();\n this.refreshVisibleResults();\n }\n\n /**\n * @inheritdoc\n */\n checkAllTiles = (): void => {\n this.map(model => {\n const cloned = model.clone();\n cloned.checked = true;\n return cloned;\n });\n };\n\n /**\n * @inheritdoc\n */\n uncheckAllTiles = (): void => {\n this.map(model => {\n const cloned = model.clone();\n cloned.checked = false;\n return cloned;\n });\n };\n\n /**\n * @inheritdoc\n */\n removeCheckedTiles = (): void => {\n // To make sure our data source remains page-aligned, we will offset our data source by\n // the number of removed tiles, so that we can just add the offset when the infinite\n // scroller queries for cell contents.\n // This only matters while we're still viewing the same set of results. If the user changes\n // their query/filters/sort, then the data source is overwritten and the offset cleared.\n const { checkedTileModels, uncheckedTileModels } = this;\n const numChecked = checkedTileModels.length;\n if (numChecked === 0) return;\n this.offset += numChecked;\n const newPages: typeof this.pages = {};\n\n // Which page the remaining tile models start on, post-offset\n let offsetPageNumber = Math.floor(this.offset / this.pageSize) + 1;\n let indexOnPage = this.offset % this.pageSize;\n\n // Fill the pages up to that point with empty models\n for (let page = 1; page <= offsetPageNumber; page += 1) {\n const remainingHidden = this.offset - this.pageSize * (page - 1);\n const offsetCellsOnPage = Math.min(this.pageSize, remainingHidden);\n newPages[page] = Array(offsetCellsOnPage).fill(undefined);\n }\n\n // Shift all the remaining tiles into their new positions in the data source\n for (const model of uncheckedTileModels) {\n if (!newPages[offsetPageNumber]) newPages[offsetPageNumber] = [];\n newPages[offsetPageNumber].push(model);\n indexOnPage += 1;\n if (indexOnPage >= this.pageSize) {\n offsetPageNumber += 1;\n indexOnPage = 0;\n }\n }\n\n // Swap in the new pages\n this.pages = newPages;\n this.numTileModels -= numChecked;\n this.requestHostUpdate();\n this.refreshVisibleResults();\n };\n\n /**\n * @inheritdoc\n */\n get checkedTileModels(): TileModel[] {\n return this.getFilteredTileModels(model => model.checked);\n }\n\n /**\n * @inheritdoc\n */\n get uncheckedTileModels(): TileModel[] {\n return this.getFilteredTileModels(model => !model.checked);\n }\n\n /**\n * Returns a flattened, filtered array of all the tile models in the data source\n * for which the given predicate returns a truthy value.\n *\n * @param predicate A callback function to apply on each tile model, as with Array.filter\n * @returns A filtered array of tile models satisfying the predicate\n */\n private getFilteredTileModels(\n predicate: (model: TileModel, index: number, array: TileModel[]) => unknown\n ): TileModel[] {\n return Object.values(this.pages)\n .flat()\n .filter((model, index, array) =>\n model ? predicate(model, index, array) : false\n );\n }\n\n /**\n * @inheritdoc\n */\n get canPerformSearch(): boolean {\n if (!this.host.searchService) return false;\n\n const trimmedQuery = this.host.baseQuery?.trim();\n const hasNonEmptyQuery = !!trimmedQuery;\n const isCollectionSearch = !!this.host.withinCollection;\n const isProfileSearch = !!this.host.withinProfile;\n const hasProfileElement = !!this.host.profileElement;\n const isMetadataSearch = this.host.searchType === SearchType.METADATA;\n\n // Metadata searches within a collection/profile are allowed to have no query.\n // Otherwise, a non-empty query must be set.\n return (\n hasNonEmptyQuery ||\n (isCollectionSearch && isMetadataSearch) ||\n (isProfileSearch && hasProfileElement && isMetadataSearch)\n );\n }\n\n /**\n * Sets the state for whether the initial set of search results for the\n * current query is loading\n */\n private setSearchResultsLoading(loading: boolean): void {\n this.searchResultsLoading = loading;\n if (this.activeOnHost) {\n this.host.setSearchResultsLoading(loading);\n }\n }\n\n /**\n * Sets the state for whether the facets for a query is loading\n */\n private setFacetsLoading(loading: boolean): void {\n this.facetsLoading = loading;\n if (this.activeOnHost) {\n this.host.setFacetsLoading(loading);\n }\n }\n\n /**\n * Requests that the host perform an update, provided this data\n * source is actively installed on it.\n */\n private requestHostUpdate(): void {\n if (this.activeOnHost) {\n this.host.requestUpdate();\n }\n }\n\n /**\n * Requests that the host refresh its visible tiles, provided this\n * data source is actively installed on it.\n */\n private refreshVisibleResults(): void {\n if (this.activeOnHost) {\n this.host.refreshVisibleResults();\n }\n }\n\n /**\n * The query key is a string that uniquely identifies the current search.\n * It consists of:\n * - The current base query\n * - The current collection/profile target & page element\n * - The current search type\n * - Any currently-applied facets\n * - Any currently-applied date range\n * - Any currently-applied prefix filters\n * - The current sort options\n *\n * This lets us internally keep track of queries so we don't persist data that's\n * no longer relevant. Not meant to be human-readable.\n */\n get pageFetchQueryKey(): string {\n const profileKey = `pf;${this.host.withinProfile}--pe;${this.host.profileElement}`;\n const pageTarget = this.host.withinCollection ?? profileKey;\n const sortField = this.host.sortParam?.field ?? 'none';\n const sortDirection = this.host.sortParam?.direction ?? 'none';\n return `fq:${this.fullQuery}-pt:${pageTarget}-st:${this.host.searchType}-sf:${sortField}-sd:${sortDirection}`;\n }\n\n /**\n * Similar to `pageFetchQueryKey` above, but excludes sort fields since they\n * are not relevant in determining aggregation queries.\n */\n get facetFetchQueryKey(): string {\n const profileKey = `${this.host.withinProfile}--${this.host.profileElement}`;\n const pageTarget = this.host.withinCollection ?? profileKey;\n return `${this.fullQuery}-${pageTarget}-${this.host.searchType}`;\n }\n\n /**\n * Constructs a search service FilterMap object from the combination of\n * all the currently-applied filters. This includes any facets, letter\n * filters, and date range.\n */\n get filterMap(): FilterMap {\n const builder = new FilterMapBuilder();\n\n // Add the date range, if applicable\n if (this.host.minSelectedDate) {\n builder.addFilter(\n 'year',\n this.host.minSelectedDate,\n FilterConstraint.GREATER_OR_EQUAL\n );\n }\n if (this.host.maxSelectedDate) {\n builder.addFilter(\n 'year',\n this.host.maxSelectedDate,\n FilterConstraint.LESS_OR_EQUAL\n );\n }\n\n // Add any selected facets\n if (this.host.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n this.host.selectedFacets\n )) {\n const { name, values } = this.prepareFacetForFetch(\n facetName,\n facetValues\n );\n for (const [value, bucket] of Object.entries(values)) {\n let constraint;\n if (bucket.state === 'selected') {\n constraint = FilterConstraint.INCLUDE;\n } else if (bucket.state === 'hidden') {\n constraint = FilterConstraint.EXCLUDE;\n }\n\n if (constraint) {\n builder.addFilter(name, value, constraint);\n }\n }\n }\n }\n\n // Add any letter filters\n if (this.host.selectedTitleFilter) {\n builder.addFilter(\n 'firstTitle',\n this.host.selectedTitleFilter,\n FilterConstraint.INCLUDE\n );\n }\n if (this.host.selectedCreatorFilter) {\n builder.addFilter(\n 'firstCreator',\n this.host.selectedCreatorFilter,\n FilterConstraint.INCLUDE\n );\n }\n\n const filterMap = builder.build();\n return filterMap;\n }\n\n /**\n * Produces a compact unique ID for a search request that can help with debugging\n * on the backend by making related requests easier to trace through different services.\n * (e.g., tying the hits/aggregations requests for the same page back to a single hash).\n *\n * @param params The search service parameters for the request\n * @param kind The kind of request (hits-only, aggregations-only, or both)\n * @returns A Promise resolving to the uid to apply to the request\n */\n async requestUID(params: SearchParams, kind: RequestKind): Promise<string> {\n const paramsToHash = JSON.stringify({\n pageType: params.pageType,\n pageTarget: params.pageTarget,\n query: params.query,\n fields: params.fields,\n filters: params.filters,\n sort: params.sort,\n searchType: this.host.searchType,\n });\n\n const fullQueryHash = (await sha1(paramsToHash)).slice(0, 20); // First 80 bits of SHA-1 are plenty for this\n const sessionId = (await this.host.getSessionId()).slice(0, 20); // Likewise\n const page = params.page ?? 0;\n const kindPrefix = kind.charAt(0); // f = full, h = hits, a = aggregations\n const currentTime = Date.now();\n\n return `R:${fullQueryHash}-S:${sessionId}-P:${page}-K:${kindPrefix}-T:${currentTime}`;\n }\n\n /**\n * @inheritdoc\n */\n get pageSpecifierParams(): PageSpecifierParams | null {\n if (this.host.withinCollection) {\n return {\n pageType: 'collection_details',\n pageTarget: this.host.withinCollection,\n };\n }\n if (this.host.withinProfile) {\n return {\n pageType: 'account_details',\n pageTarget: this.host.withinProfile,\n pageElements: this.host.profileElement\n ? [this.host.profileElement]\n : [],\n };\n }\n return null;\n }\n\n /**\n * The full query, including year facets and date range clauses\n */\n private get fullQuery(): string | undefined {\n let fullQuery = this.host.baseQuery?.trim() ?? '';\n\n const { facetQuery, dateRangeQueryClause, sortFilterQueries } = this;\n\n if (facetQuery) {\n fullQuery += ` AND ${facetQuery}`;\n }\n if (dateRangeQueryClause) {\n fullQuery += ` AND ${dateRangeQueryClause}`;\n }\n if (sortFilterQueries) {\n fullQuery += ` AND ${sortFilterQueries}`;\n }\n return fullQuery.trim();\n }\n\n /**\n * Generates a query string representing the current set of applied facets\n *\n * Example: `mediatype:(\"collection\" OR \"audio\" OR -\"etree\") AND year:(\"2000\" OR \"2001\")`\n */\n private get facetQuery(): string | undefined {\n if (!this.host.selectedFacets) return undefined;\n const facetClauses = [];\n for (const [facetName, facetValues] of Object.entries(\n this.host.selectedFacets\n )) {\n facetClauses.push(this.buildFacetClause(facetName, facetValues));\n }\n return this.joinFacetClauses(facetClauses)?.trim();\n }\n\n private get dateRangeQueryClause(): string | undefined {\n if (!this.host.minSelectedDate || !this.host.maxSelectedDate) {\n return undefined;\n }\n\n return `year:[${this.host.minSelectedDate} TO ${this.host.maxSelectedDate}]`;\n }\n\n private get sortFilterQueries(): string {\n const queries = [this.titleQuery, this.creatorQuery];\n return queries.filter(q => q).join(' AND ');\n }\n\n /**\n * Returns a query clause identifying the currently selected title filter,\n * e.g., `firstTitle:X`.\n */\n private get titleQuery(): string | undefined {\n return this.host.selectedTitleFilter\n ? `firstTitle:${this.host.selectedTitleFilter}`\n : undefined;\n }\n\n /**\n * Returns a query clause identifying the currently selected creator filter,\n * e.g., `firstCreator:X`.\n */\n private get creatorQuery(): string | undefined {\n return this.host.selectedCreatorFilter\n ? `firstCreator:${this.host.selectedCreatorFilter}`\n : undefined;\n }\n\n /**\n * Builds an OR-joined facet clause for the given facet name and values.\n *\n * E.g., for name `subject` and values\n * `{ foo: { state: 'selected' }, bar: { state: 'hidden' } }`\n * this will produce the clause\n * `subject:(\"foo\" OR -\"bar\")`.\n *\n * @param facetName The facet type (e.g., 'collection')\n * @param facetValues The facet buckets, mapped by their keys\n */\n private buildFacetClause(\n facetName: string,\n facetValues: Record<string, FacetBucket>\n ): string {\n const { name: facetQueryName, values } = this.prepareFacetForFetch(\n facetName,\n facetValues\n );\n const facetEntries = Object.entries(values);\n if (facetEntries.length === 0) return '';\n\n const facetValuesArray: string[] = [];\n for (const [key, facetData] of facetEntries) {\n const plusMinusPrefix = facetData.state === 'hidden' ? '-' : '';\n facetValuesArray.push(`${plusMinusPrefix}\"${key}\"`);\n }\n\n const valueQuery = facetValuesArray.join(` OR `);\n return `${facetQueryName}:(${valueQuery})`;\n }\n\n /**\n * Handles some special pre-request normalization steps for certain facet types\n * that require them.\n *\n * @param facetName The name of the facet type (e.g., 'language')\n * @param facetValues An array of values for that facet type\n */\n private prepareFacetForFetch(\n facetName: string,\n facetValues: Record<string, FacetBucket>\n ): { name: string; values: Record<string, FacetBucket> } {\n // eslint-disable-next-line prefer-const\n let [normalizedName, normalizedValues] = [facetName, facetValues];\n\n // The full \"search engine\" name of the lending field is \"lending___status\"\n if (facetName === 'lending') {\n normalizedName = 'lending___status';\n }\n\n return {\n name: normalizedName,\n values: normalizedValues,\n };\n }\n\n /**\n * Takes an array of facet clauses, and combines them into a\n * full AND-joined facet query string. Empty clauses are ignored.\n */\n private joinFacetClauses(facetClauses: string[]): string | undefined {\n const nonEmptyFacetClauses = facetClauses.filter(\n clause => clause.length > 0\n );\n return nonEmptyFacetClauses.length > 0\n ? `(${nonEmptyFacetClauses.join(' AND ')})`\n : undefined;\n }\n\n /**\n * Fires a backend request to fetch a set of aggregations (representing UI facets) for\n * the current search state.\n */\n private async fetchFacets(): Promise<void> {\n console.log('fetchFacets', this.id, this.host.profileElement);\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return;\n console.log('will actually fetch facets');\n\n const { facetFetchQueryKey } = this;\n\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n rows: 0,\n filters: this.filterMap,\n // Fetch a few extra buckets beyond the 6 we show, in case some get suppressed\n aggregationsSize: 10,\n // Note: we don't need an aggregations param to fetch the default aggregations from the PPS.\n // The default aggregations for the search_results page type should be what we need here.\n };\n params.uid = await this.requestUID(\n { ...params, sort: sortParams },\n 'aggregations'\n );\n\n this.setFacetsLoading(true);\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n const success = searchResponse?.success;\n\n // This is checking to see if the query has changed since the data was fetched.\n // If so, we just want to discard this set of aggregations because they are\n // likely no longer valid for the newer query.\n const queryChangedSinceFetch =\n facetFetchQueryKey !== this.facetFetchQueryKey;\n if (queryChangedSinceFetch) {\n console.log(\n 'facet query has changed since fetch, returning. new/old:',\n this.facetFetchQueryKey,\n facetFetchQueryKey\n );\n return;\n }\n\n if (!success) {\n const errorMsg = searchResponse?.error?.message;\n const detailMsg = searchResponse?.error?.details?.message;\n\n if (!errorMsg && !detailMsg) {\n // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'\n window?.Sentry?.captureMessage?.(\n 'Missing or malformed facet response from backend',\n 'error'\n );\n }\n\n this.setFacetsLoading(false);\n return;\n }\n\n const { aggregations, collectionTitles } = success.response;\n this.aggregations = aggregations;\n\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles.set(id, title);\n }\n }\n\n this.yearHistogramAggregation =\n success?.response?.aggregations?.year_histogram;\n\n this.setFacetsLoading(false);\n this.requestHostUpdate();\n }\n\n /**\n * Performs the initial page fetch(es) for the current search state.\n */\n private async doInitialPageFetch(): Promise<void> {\n this.setSearchResultsLoading(true);\n // Try to batch 2 initial page requests when possible\n await this.fetchPage(this.host.initialPageNumber, 2);\n this.setSearchResultsLoading(false);\n }\n\n /**\n * Fetches one or more pages of results and updates the data source.\n *\n * @param pageNumber The page number to fetch\n * @param numInitialPages If this is an initial page fetch (`pageNumber = 1`),\n * specifies how many pages to batch together in one request. Ignored\n * if `pageNumber != 1`, defaulting to a single page.\n */\n async fetchPage(pageNumber: number, numInitialPages = 1): Promise<void> {\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return;\n\n // if we already have data, don't fetch again\n if (this.hasPage(pageNumber)) return;\n\n if (this.endOfDataReached) return;\n\n // Batch multiple initial page requests together if needed (e.g., can request\n // pages 1 and 2 together in a single request).\n const numPages = pageNumber === 1 ? numInitialPages : 1;\n const numRows = this.pageSize * numPages;\n\n // if a fetch is already in progress for this query and page, don't fetch again\n const { pageFetchQueryKey } = this;\n const pageFetches =\n this.pageFetchesInProgress[pageFetchQueryKey] ?? new Set();\n if (pageFetches.has(pageNumber)) return;\n\n for (let i = 0; i < numPages; i += 1) {\n pageFetches.add(pageNumber + i);\n }\n console.log(\n `fetchPage(${pageNumber})`,\n this.id,\n this.canPerformSearch,\n this.hasPage(pageNumber),\n this.endOfDataReached,\n this.host.baseQuery,\n JSON.stringify(this.host.selectedFacets),\n this.pageFetchQueryKey\n );\n this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;\n this.previousQueryKey = pageFetchQueryKey;\n\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n page: pageNumber,\n rows: numRows,\n sort: sortParams,\n filters: this.filterMap,\n aggregations: { omit: true },\n };\n params.uid = await this.requestUID(params, 'hits');\n\n console.log('=== FIRING PAGE REQUEST ===');\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n console.log('=== RECEIVED PAGE RESPONSE IN CB === ');\n const success = searchResponse?.success;\n\n // This is checking to see if the query has changed since the data was fetched.\n // If so, we just want to discard the data since there should be a new query\n // right behind it.\n const queryChangedSinceFetch = pageFetchQueryKey !== this.pageFetchQueryKey;\n if (queryChangedSinceFetch) return;\n\n if (!success) {\n const errorMsg = searchResponse?.error?.message;\n const detailMsg = searchResponse?.error?.details?.message;\n\n this.queryErrorMessage = `${errorMsg ?? ''}${\n detailMsg ? `; ${detailMsg}` : ''\n }`;\n\n if (!this.queryErrorMessage) {\n this.queryErrorMessage = 'Missing or malformed response from backend';\n // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'\n window?.Sentry?.captureMessage?.(this.queryErrorMessage, 'error');\n }\n\n for (let i = 0; i < numPages; i += 1) {\n this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);\n }\n\n this.setSearchResultsLoading(false);\n this.requestHostUpdate();\n return;\n }\n\n this.totalResults = success.response.totalResults - this.offset;\n if (this.activeOnHost) {\n this.host.setTotalResultCount(this.totalResults);\n\n // display event to offshoot when result count is zero.\n if (this.totalResults === 0) {\n this.host.emitEmptyResults();\n }\n }\n\n if (this.host.withinCollection) {\n console.log(\n 'host is within collection, setting collection info:',\n success.response.collectionExtraInfo\n );\n this.collectionExtraInfo = success.response.collectionExtraInfo;\n\n // For collections, we want the UI to respect the default sort option\n // which can be specified in metadata, or otherwise assumed to be week:desc\n this.host.applyDefaultCollectionSort(this.collectionExtraInfo);\n\n if (this.collectionExtraInfo) {\n this.parentCollections = [].concat(\n this.collectionExtraInfo.public_metadata?.collection ?? []\n );\n }\n } else if (this.host.withinProfile) {\n console.log(\n 'host is within profile, setting acct info:',\n success.response.accountExtraInfo,\n success.response.pageElements\n );\n this.accountExtraInfo = success.response.accountExtraInfo;\n this.pageElements = success.response.pageElements;\n } else {\n console.log(\n 'not within profile/collxn',\n this.host.withinCollection,\n this.host.withinProfile\n );\n }\n\n const { results, collectionTitles } = success.response;\n if (results && results.length > 0) {\n // Load any collection titles present on the response into the cache,\n // or queue up preload fetches for them if none were present.\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles.set(id, title);\n }\n }\n\n // Update the data source for each returned page\n for (let i = 0; i < numPages; i += 1) {\n const pageStartIndex = this.pageSize * i;\n this.addTilesToDataSource(\n pageNumber + i,\n results.slice(pageStartIndex, pageStartIndex + this.pageSize)\n );\n }\n }\n\n // When we reach the end of the data, we can set the infinite scroller's\n // item count to the real total number of results (rather than the\n // temporary estimates based on pages rendered so far).\n const resultCountDiscrepancy = numRows - results.length;\n if (resultCountDiscrepancy > 0) {\n console.log('End of data reached');\n this.endOfDataReached = true;\n if (this.activeOnHost) this.host.setTileCount(this.totalResults);\n }\n\n for (let i = 0; i < numPages; i += 1) {\n this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);\n }\n\n this.requestHostUpdate();\n }\n\n /**\n * Update the datasource from the fetch response\n *\n * @param pageNumber\n * @param results\n */\n private addTilesToDataSource(\n pageNumber: number,\n results: SearchResult[]\n ): void {\n const tiles: TileModel[] = [];\n results?.forEach(result => {\n if (!result.identifier) return;\n tiles.push(new TileModel(result));\n });\n this.addPage(pageNumber, tiles);\n const visiblePages = this.host.currentVisiblePageNumbers;\n const needsReload = visiblePages.includes(pageNumber);\n if (needsReload) {\n this.refreshVisibleResults();\n }\n }\n\n /**\n * Fetches the aggregation buckets for the given prefix filter type.\n */\n private async fetchPrefixFilterBuckets(\n filterType: PrefixFilterType\n ): Promise<Bucket[]> {\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return [];\n\n const filterAggregationKey = prefixFilterAggregationKeys[filterType];\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n rows: 0,\n filters: this.filterMap,\n // Only fetch the firstTitle or firstCreator aggregation\n aggregations: { simpleParams: [filterAggregationKey] },\n // Fetch all 26 letter buckets\n aggregationsSize: 26,\n };\n params.uid = await this.requestUID(\n { ...params, sort: sortParams },\n 'aggregations'\n );\n\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n\n return (searchResponse?.success?.response?.aggregations?.[\n filterAggregationKey\n ]?.buckets ?? []) as Bucket[];\n }\n\n /**\n * Fetches and caches the prefix filter counts for the given filter type.\n */\n async updatePrefixFilterCounts(filterType: PrefixFilterType): Promise<void> {\n const { facetFetchQueryKey } = this;\n const buckets = await this.fetchPrefixFilterBuckets(filterType);\n\n // Don't update the filter counts for an outdated query (if it has been changed\n // since we sent the request)\n const queryChangedSinceFetch =\n facetFetchQueryKey !== this.facetFetchQueryKey;\n if (queryChangedSinceFetch) return;\n\n // Unpack the aggregation buckets into a simple map like { 'A': 50, 'B': 25, ... }\n this.prefixFilterCountMap = { ...this.prefixFilterCountMap }; // Clone the object to trigger an update\n this.prefixFilterCountMap[filterType] = buckets.reduce(\n (acc: Record<string, number>, bucket: Bucket) => {\n acc[(bucket.key as string).toUpperCase()] = bucket.doc_count;\n return acc;\n },\n {}\n );\n\n this.requestHostUpdate();\n }\n}\n"]}
1
+ {"version":3,"file":"collection-browser-data-source.js","sourceRoot":"","sources":["../../../src/data-source/collection-browser-data-source.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveControllerHost } from 'lit';\nimport {\n AccountExtraInfo,\n Aggregation,\n Bucket,\n CollectionExtraInfo,\n FilterConstraint,\n FilterMap,\n FilterMapBuilder,\n PageElementMap,\n SearchParams,\n SearchResult,\n SearchType,\n} from '@internetarchive/search-service';\nimport {\n prefixFilterAggregationKeys,\n type FacetBucket,\n type PrefixFilterType,\n TileModel,\n PrefixFilterCounts,\n RequestKind,\n} from '../models';\nimport type { PageSpecifierParams } from './models';\nimport type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';\nimport type { CollectionBrowserSearchInterface } from './collection-browser-query-state';\nimport { sha1 } from '../utils/sha1';\n\nexport class CollectionBrowserDataSource\n implements CollectionBrowserDataSourceInterface\n{\n private pages: Record<string, TileModel[]> = {};\n\n private offset = 0;\n\n private numTileModels = 0;\n\n /**\n * A set of fetch IDs that are valid for the current query state\n */\n private fetchesInProgress = new Set<string>();\n\n /**\n * A record of the query key used for the last search.\n * If this changes, we need to load new results.\n */\n private previousQueryKey: string = '';\n\n private searchResultsLoading = false;\n\n private facetsLoading = false;\n\n // TEMP for ease of debugging\n private id = Math.random();\n\n /**\n * @inheritdoc\n */\n totalResults = 0;\n\n /**\n * @inheritdoc\n */\n endOfDataReached = false;\n\n /**\n * @inheritdoc\n */\n queryInitialized = false;\n\n /**\n * @inheritdoc\n */\n aggregations?: Record<string, Aggregation>;\n\n /**\n * @inheritdoc\n */\n yearHistogramAggregation?: Aggregation;\n\n /**\n * @inheritdoc\n */\n collectionTitles = new Map<string, string>();\n\n /**\n * @inheritdoc\n */\n collectionExtraInfo?: CollectionExtraInfo;\n\n /**\n * @inheritdoc\n */\n accountExtraInfo?: AccountExtraInfo;\n\n /**\n * @inheritdoc\n */\n pageElements?: PageElementMap;\n\n /**\n * @inheritdoc\n */\n parentCollections?: string[] = [];\n\n /**\n * @inheritdoc\n */\n prefixFilterCountMap: Partial<Record<PrefixFilterType, PrefixFilterCounts>> =\n {};\n\n /**\n * @inheritdoc\n */\n queryErrorMessage?: string;\n\n /**\n * Internal property to store the `resolve` function for the most recent\n * `initialSearchComplete` promise, allowing us to resolve it at the appropriate time.\n */\n private _initialSearchCompleteResolver!: (val: boolean) => void;\n\n /**\n * Internal property to store the private value backing the `initialSearchComplete` getter.\n */\n private _initialSearchCompletePromise: Promise<boolean> = new Promise(res => {\n this._initialSearchCompleteResolver = res;\n });\n\n /**\n * @inheritdoc\n */\n get initialSearchComplete(): Promise<boolean> {\n return this._initialSearchCompletePromise;\n }\n\n // eslint-disable-next-line no-useless-constructor\n constructor(\n /** The host element to which this controller should attach listeners */\n private readonly host: ReactiveControllerHost &\n CollectionBrowserSearchInterface,\n /** Default size of result pages */\n private pageSize: number\n ) {\n // Just setting some property values\n }\n\n hostUpdate(): void {\n console.log(\n 'hostUpdate',\n this.id,\n this.previousQueryKey,\n this.pageFetchQueryKey\n );\n // This reactive controller hook is run whenever the host component (collection-browser) performs an update.\n // We check whether the host's state has changed in a way which should trigger a reset & new results fetch.\n\n // Only the currently-installed data source should react to the update\n if (!this.activeOnHost) return;\n\n // Copy loading states onto the host\n this.setSearchResultsLoading(this.searchResultsLoading);\n this.setFacetsLoading(this.facetsLoading);\n\n // Can't perform searches without a search service\n if (!this.host.searchService) return;\n\n // We should only reset if part of the full query state has changed\n const queryKeyChanged = this.pageFetchQueryKey !== this.previousQueryKey;\n console.log('query keys', this.pageFetchQueryKey, this.previousQueryKey);\n if (!queryKeyChanged) return;\n\n // We should only reset if either:\n // (a) our state permits a valid search, or\n // (b) we have a blank query that we want to show empty results for\n const shouldShowEmptyQueryResults =\n this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';\n if (!(this.canPerformSearch || shouldShowEmptyQueryResults)) return;\n\n if (this.activeOnHost) this.host.emitQueryStateChanged();\n this.handleQueryChange();\n }\n\n /**\n * Returns whether this data source is the one currently installed on the host component.\n */\n private get activeOnHost(): boolean {\n return this.host.dataSource === this;\n }\n\n /**\n * @inheritdoc\n */\n get size(): number {\n return this.numTileModels;\n }\n\n /**\n * @inheritdoc\n */\n reset(): void {\n this.pages = {};\n this.aggregations = {};\n this.yearHistogramAggregation = undefined;\n this.pageElements = undefined;\n this.parentCollections = [];\n this.prefixFilterCountMap = {};\n this.queryErrorMessage = undefined;\n\n this.offset = 0;\n this.numTileModels = 0;\n this.totalResults = 0;\n this.endOfDataReached = false;\n this.queryInitialized = false;\n\n // Invalidate any fetches in progress\n this.fetchesInProgress.clear();\n\n if (this.activeOnHost) this.host.setTotalResultCount(0);\n this.requestHostUpdate();\n }\n\n /**\n * @inheritdoc\n */\n addPage(pageNum: number, pageTiles: TileModel[]): void {\n this.pages[pageNum] = pageTiles;\n this.numTileModels += pageTiles.length;\n this.requestHostUpdate();\n }\n\n /**\n * @inheritdoc\n */\n getPage(pageNum: number): TileModel[] {\n return this.pages[pageNum];\n }\n\n /**\n * @inheritdoc\n */\n getAllPages(): Record<string, TileModel[]> {\n return this.pages;\n }\n\n /**\n * @inheritdoc\n */\n hasPage(pageNum: number): boolean {\n return !!this.pages[pageNum];\n }\n\n /**\n * @inheritdoc\n */\n getTileModelAt(index: number): TileModel | undefined {\n const pageNum = Math.floor(index / this.pageSize) + 1;\n const indexOnPage = index % this.pageSize;\n return this.pages[pageNum]?.[indexOnPage];\n }\n\n /**\n * @inheritdoc\n */\n indexOf(tile: TileModel): number {\n return Object.values(this.pages).flat().indexOf(tile);\n }\n\n /**\n * @inheritdoc\n */\n setPageSize(pageSize: number): void {\n this.reset();\n this.pageSize = pageSize;\n }\n\n /**\n * @inheritdoc\n */\n async handleQueryChange(): Promise<void> {\n this.reset();\n\n // Reset the `initialSearchComplete` promise with a new value for the imminent search\n this._initialSearchCompletePromise = new Promise(res => {\n this._initialSearchCompleteResolver = res;\n });\n\n // Fire the initial page & facet requests\n this.queryInitialized = true;\n await Promise.all([\n this.doInitialPageFetch(),\n this.host.suppressFacets ? null : this.fetchFacets(),\n ]);\n\n // Resolve the `initialSearchComplete` promise for this search\n this._initialSearchCompleteResolver(true);\n }\n\n /**\n * @inheritdoc\n */\n map(\n callback: (model: TileModel, index: number, array: TileModel[]) => TileModel\n ): void {\n this.pages = Object.fromEntries(\n Object.entries(this.pages).map(([page, tileModels]) => [\n page,\n tileModels.map((model, index, array) =>\n model ? callback(model, index, array) : model\n ),\n ])\n );\n this.requestHostUpdate();\n this.refreshVisibleResults();\n }\n\n /**\n * @inheritdoc\n */\n checkAllTiles = (): void => {\n this.map(model => {\n const cloned = model.clone();\n cloned.checked = true;\n return cloned;\n });\n };\n\n /**\n * @inheritdoc\n */\n uncheckAllTiles = (): void => {\n this.map(model => {\n const cloned = model.clone();\n cloned.checked = false;\n return cloned;\n });\n };\n\n /**\n * @inheritdoc\n */\n removeCheckedTiles = (): void => {\n // To make sure our data source remains page-aligned, we will offset our data source by\n // the number of removed tiles, so that we can just add the offset when the infinite\n // scroller queries for cell contents.\n // This only matters while we're still viewing the same set of results. If the user changes\n // their query/filters/sort, then the data source is overwritten and the offset cleared.\n const { checkedTileModels, uncheckedTileModels } = this;\n const numChecked = checkedTileModels.length;\n if (numChecked === 0) return;\n this.offset += numChecked;\n const newPages: typeof this.pages = {};\n\n // Which page the remaining tile models start on, post-offset\n let offsetPageNumber = Math.floor(this.offset / this.pageSize) + 1;\n let indexOnPage = this.offset % this.pageSize;\n\n // Fill the pages up to that point with empty models\n for (let page = 1; page <= offsetPageNumber; page += 1) {\n const remainingHidden = this.offset - this.pageSize * (page - 1);\n const offsetCellsOnPage = Math.min(this.pageSize, remainingHidden);\n newPages[page] = Array(offsetCellsOnPage).fill(undefined);\n }\n\n // Shift all the remaining tiles into their new positions in the data source\n for (const model of uncheckedTileModels) {\n if (!newPages[offsetPageNumber]) newPages[offsetPageNumber] = [];\n newPages[offsetPageNumber].push(model);\n indexOnPage += 1;\n if (indexOnPage >= this.pageSize) {\n offsetPageNumber += 1;\n indexOnPage = 0;\n }\n }\n\n // Swap in the new pages\n this.pages = newPages;\n this.numTileModels -= numChecked;\n this.requestHostUpdate();\n this.refreshVisibleResults();\n };\n\n /**\n * @inheritdoc\n */\n get checkedTileModels(): TileModel[] {\n return this.getFilteredTileModels(model => model.checked);\n }\n\n /**\n * @inheritdoc\n */\n get uncheckedTileModels(): TileModel[] {\n return this.getFilteredTileModels(model => !model.checked);\n }\n\n /**\n * Returns a flattened, filtered array of all the tile models in the data source\n * for which the given predicate returns a truthy value.\n *\n * @param predicate A callback function to apply on each tile model, as with Array.filter\n * @returns A filtered array of tile models satisfying the predicate\n */\n private getFilteredTileModels(\n predicate: (model: TileModel, index: number, array: TileModel[]) => unknown\n ): TileModel[] {\n return Object.values(this.pages)\n .flat()\n .filter((model, index, array) =>\n model ? predicate(model, index, array) : false\n );\n }\n\n /**\n * @inheritdoc\n */\n get canPerformSearch(): boolean {\n if (!this.host.searchService) return false;\n\n const trimmedQuery = this.host.baseQuery?.trim();\n const hasNonEmptyQuery = !!trimmedQuery;\n const isCollectionSearch = !!this.host.withinCollection;\n const isProfileSearch = !!this.host.withinProfile;\n const hasProfileElement = !!this.host.profileElement;\n const isMetadataSearch = this.host.searchType === SearchType.METADATA;\n\n // Metadata searches within a collection/profile are allowed to have no query.\n // Otherwise, a non-empty query must be set.\n return (\n hasNonEmptyQuery ||\n (isCollectionSearch && isMetadataSearch) ||\n (isProfileSearch && hasProfileElement && isMetadataSearch)\n );\n }\n\n /**\n * Sets the state for whether the initial set of search results for the\n * current query is loading\n */\n private setSearchResultsLoading(loading: boolean): void {\n this.searchResultsLoading = loading;\n if (this.activeOnHost) {\n this.host.setSearchResultsLoading(loading);\n }\n }\n\n /**\n * Sets the state for whether the facets for a query is loading\n */\n private setFacetsLoading(loading: boolean): void {\n this.facetsLoading = loading;\n if (this.activeOnHost) {\n this.host.setFacetsLoading(loading);\n }\n }\n\n /**\n * Requests that the host perform an update, provided this data\n * source is actively installed on it.\n */\n private requestHostUpdate(): void {\n if (this.activeOnHost) {\n this.host.requestUpdate();\n }\n }\n\n /**\n * Requests that the host refresh its visible tiles, provided this\n * data source is actively installed on it.\n */\n private refreshVisibleResults(): void {\n if (this.activeOnHost) {\n this.host.refreshVisibleResults();\n }\n }\n\n /**\n * The query key is a string that uniquely identifies the current search.\n * It consists of:\n * - The current base query\n * - The current collection/profile target & page element\n * - The current search type\n * - Any currently-applied facets\n * - Any currently-applied date range\n * - Any currently-applied prefix filters\n * - The current sort options\n *\n * This lets us internally keep track of queries so we don't persist data that's\n * no longer relevant. Not meant to be human-readable.\n */\n get pageFetchQueryKey(): string {\n const profileKey = `pf;${this.host.withinProfile}--pe;${this.host.profileElement}`;\n const pageTarget = this.host.withinCollection ?? profileKey;\n const sortField = this.host.sortParam?.field ?? 'none';\n const sortDirection = this.host.sortParam?.direction ?? 'none';\n return `fq:${this.fullQuery}-pt:${pageTarget}-st:${this.host.searchType}-sf:${sortField}-sd:${sortDirection}`;\n }\n\n /**\n * Similar to `pageFetchQueryKey` above, but excludes sort fields since they\n * are not relevant in determining aggregation queries.\n */\n get facetFetchQueryKey(): string {\n const profileKey = `${this.host.withinProfile}--${this.host.profileElement}`;\n const pageTarget = this.host.withinCollection ?? profileKey;\n return `${this.fullQuery}-${pageTarget}-${this.host.searchType}`;\n }\n\n /**\n * Constructs a search service FilterMap object from the combination of\n * all the currently-applied filters. This includes any facets, letter\n * filters, and date range.\n */\n get filterMap(): FilterMap {\n const builder = new FilterMapBuilder();\n\n // Add the date range, if applicable\n if (this.host.minSelectedDate) {\n builder.addFilter(\n 'year',\n this.host.minSelectedDate,\n FilterConstraint.GREATER_OR_EQUAL\n );\n }\n if (this.host.maxSelectedDate) {\n builder.addFilter(\n 'year',\n this.host.maxSelectedDate,\n FilterConstraint.LESS_OR_EQUAL\n );\n }\n\n // Add any selected facets\n if (this.host.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n this.host.selectedFacets\n )) {\n const { name, values } = this.prepareFacetForFetch(\n facetName,\n facetValues\n );\n for (const [value, bucket] of Object.entries(values)) {\n let constraint;\n if (bucket.state === 'selected') {\n constraint = FilterConstraint.INCLUDE;\n } else if (bucket.state === 'hidden') {\n constraint = FilterConstraint.EXCLUDE;\n }\n\n if (constraint) {\n builder.addFilter(name, value, constraint);\n }\n }\n }\n }\n\n // Add any letter filters\n if (this.host.selectedTitleFilter) {\n builder.addFilter(\n 'firstTitle',\n this.host.selectedTitleFilter,\n FilterConstraint.INCLUDE\n );\n }\n if (this.host.selectedCreatorFilter) {\n builder.addFilter(\n 'firstCreator',\n this.host.selectedCreatorFilter,\n FilterConstraint.INCLUDE\n );\n }\n\n const filterMap = builder.build();\n return filterMap;\n }\n\n /**\n * Produces a compact unique ID for a search request that can help with debugging\n * on the backend by making related requests easier to trace through different services.\n * (e.g., tying the hits/aggregations requests for the same page back to a single hash).\n *\n * @param params The search service parameters for the request\n * @param kind The kind of request (hits-only, aggregations-only, or both)\n * @returns A Promise resolving to the uid to apply to the request\n */\n async requestUID(params: SearchParams, kind: RequestKind): Promise<string> {\n const paramsToHash = JSON.stringify({\n pageType: params.pageType,\n pageTarget: params.pageTarget,\n query: params.query,\n fields: params.fields,\n filters: params.filters,\n sort: params.sort,\n searchType: this.host.searchType,\n });\n\n const fullQueryHash = (await sha1(paramsToHash)).slice(0, 20); // First 80 bits of SHA-1 are plenty for this\n const sessionId = (await this.host.getSessionId()).slice(0, 20); // Likewise\n const page = params.page ?? 0;\n const kindPrefix = kind.charAt(0); // f = full, h = hits, a = aggregations\n const currentTime = Date.now();\n\n return `R:${fullQueryHash}-S:${sessionId}-P:${page}-K:${kindPrefix}-T:${currentTime}`;\n }\n\n /**\n * @inheritdoc\n */\n get pageSpecifierParams(): PageSpecifierParams | null {\n if (this.host.withinCollection) {\n return {\n pageType: 'collection_details',\n pageTarget: this.host.withinCollection,\n };\n }\n if (this.host.withinProfile) {\n return {\n pageType: 'account_details',\n pageTarget: this.host.withinProfile,\n pageElements: this.host.profileElement\n ? [this.host.profileElement]\n : [],\n };\n }\n return null;\n }\n\n /**\n * The full query, including year facets and date range clauses\n */\n private get fullQuery(): string | undefined {\n let fullQuery = this.host.baseQuery?.trim() ?? '';\n\n const { facetQuery, dateRangeQueryClause, sortFilterQueries } = this;\n\n if (facetQuery) {\n fullQuery += ` AND ${facetQuery}`;\n }\n if (dateRangeQueryClause) {\n fullQuery += ` AND ${dateRangeQueryClause}`;\n }\n if (sortFilterQueries) {\n fullQuery += ` AND ${sortFilterQueries}`;\n }\n return fullQuery.trim();\n }\n\n /**\n * Generates a query string representing the current set of applied facets\n *\n * Example: `mediatype:(\"collection\" OR \"audio\" OR -\"etree\") AND year:(\"2000\" OR \"2001\")`\n */\n private get facetQuery(): string | undefined {\n if (!this.host.selectedFacets) return undefined;\n const facetClauses = [];\n for (const [facetName, facetValues] of Object.entries(\n this.host.selectedFacets\n )) {\n facetClauses.push(this.buildFacetClause(facetName, facetValues));\n }\n return this.joinFacetClauses(facetClauses)?.trim();\n }\n\n private get dateRangeQueryClause(): string | undefined {\n if (!this.host.minSelectedDate || !this.host.maxSelectedDate) {\n return undefined;\n }\n\n return `year:[${this.host.minSelectedDate} TO ${this.host.maxSelectedDate}]`;\n }\n\n private get sortFilterQueries(): string {\n const queries = [this.titleQuery, this.creatorQuery];\n return queries.filter(q => q).join(' AND ');\n }\n\n /**\n * Returns a query clause identifying the currently selected title filter,\n * e.g., `firstTitle:X`.\n */\n private get titleQuery(): string | undefined {\n return this.host.selectedTitleFilter\n ? `firstTitle:${this.host.selectedTitleFilter}`\n : undefined;\n }\n\n /**\n * Returns a query clause identifying the currently selected creator filter,\n * e.g., `firstCreator:X`.\n */\n private get creatorQuery(): string | undefined {\n return this.host.selectedCreatorFilter\n ? `firstCreator:${this.host.selectedCreatorFilter}`\n : undefined;\n }\n\n /**\n * Builds an OR-joined facet clause for the given facet name and values.\n *\n * E.g., for name `subject` and values\n * `{ foo: { state: 'selected' }, bar: { state: 'hidden' } }`\n * this will produce the clause\n * `subject:(\"foo\" OR -\"bar\")`.\n *\n * @param facetName The facet type (e.g., 'collection')\n * @param facetValues The facet buckets, mapped by their keys\n */\n private buildFacetClause(\n facetName: string,\n facetValues: Record<string, FacetBucket>\n ): string {\n const { name: facetQueryName, values } = this.prepareFacetForFetch(\n facetName,\n facetValues\n );\n const facetEntries = Object.entries(values);\n if (facetEntries.length === 0) return '';\n\n const facetValuesArray: string[] = [];\n for (const [key, facetData] of facetEntries) {\n const plusMinusPrefix = facetData.state === 'hidden' ? '-' : '';\n facetValuesArray.push(`${plusMinusPrefix}\"${key}\"`);\n }\n\n const valueQuery = facetValuesArray.join(` OR `);\n return `${facetQueryName}:(${valueQuery})`;\n }\n\n /**\n * Handles some special pre-request normalization steps for certain facet types\n * that require them.\n *\n * @param facetName The name of the facet type (e.g., 'language')\n * @param facetValues An array of values for that facet type\n */\n private prepareFacetForFetch(\n facetName: string,\n facetValues: Record<string, FacetBucket>\n ): { name: string; values: Record<string, FacetBucket> } {\n // eslint-disable-next-line prefer-const\n let [normalizedName, normalizedValues] = [facetName, facetValues];\n\n // The full \"search engine\" name of the lending field is \"lending___status\"\n if (facetName === 'lending') {\n normalizedName = 'lending___status';\n }\n\n return {\n name: normalizedName,\n values: normalizedValues,\n };\n }\n\n /**\n * Takes an array of facet clauses, and combines them into a\n * full AND-joined facet query string. Empty clauses are ignored.\n */\n private joinFacetClauses(facetClauses: string[]): string | undefined {\n const nonEmptyFacetClauses = facetClauses.filter(\n clause => clause.length > 0\n );\n return nonEmptyFacetClauses.length > 0\n ? `(${nonEmptyFacetClauses.join(' AND ')})`\n : undefined;\n }\n\n /**\n * Fires a backend request to fetch a set of aggregations (representing UI facets) for\n * the current search state.\n */\n private async fetchFacets(): Promise<void> {\n console.log('fetchFacets', this.id, this.host.profileElement);\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return;\n console.log('will actually fetch facets');\n\n const { facetFetchQueryKey } = this;\n if (this.fetchesInProgress.has(facetFetchQueryKey)) return;\n this.fetchesInProgress.add(facetFetchQueryKey);\n\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n rows: 0,\n filters: this.filterMap,\n // Fetch a few extra buckets beyond the 6 we show, in case some get suppressed\n aggregationsSize: 10,\n // Note: we don't need an aggregations param to fetch the default aggregations from the PPS.\n // The default aggregations for the search_results page type should be what we need here.\n };\n params.uid = await this.requestUID(\n { ...params, sort: sortParams },\n 'aggregations'\n );\n\n this.setFacetsLoading(true);\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n const success = searchResponse?.success;\n\n // This is checking to see if the query has changed since the data was fetched.\n // If so, we just want to discard this set of aggregations because they are\n // likely no longer valid for the newer query.\n const queryChangedSinceFetch =\n this.fetchesInProgress.has(facetFetchQueryKey);\n this.fetchesInProgress.delete(facetFetchQueryKey);\n if (queryChangedSinceFetch) {\n console.log(\n 'facet query has changed since fetch, returning. new/old:',\n this.facetFetchQueryKey,\n facetFetchQueryKey\n );\n return;\n }\n\n if (!success) {\n const errorMsg = searchResponse?.error?.message;\n const detailMsg = searchResponse?.error?.details?.message;\n\n if (!errorMsg && !detailMsg) {\n // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'\n window?.Sentry?.captureMessage?.(\n 'Missing or malformed facet response from backend',\n 'error'\n );\n }\n\n this.setFacetsLoading(false);\n return;\n }\n\n const { aggregations, collectionTitles } = success.response;\n this.aggregations = aggregations;\n\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles.set(id, title);\n }\n }\n\n this.yearHistogramAggregation =\n success?.response?.aggregations?.year_histogram;\n\n this.setFacetsLoading(false);\n this.requestHostUpdate();\n }\n\n /**\n * Performs the initial page fetch(es) for the current search state.\n */\n private async doInitialPageFetch(): Promise<void> {\n this.setSearchResultsLoading(true);\n // Try to batch 2 initial page requests when possible\n await this.fetchPage(this.host.initialPageNumber, 2);\n this.setSearchResultsLoading(false);\n }\n\n /**\n * Fetches one or more pages of results and updates the data source.\n *\n * @param pageNumber The page number to fetch\n * @param numInitialPages If this is an initial page fetch (`pageNumber = 1`),\n * specifies how many pages to batch together in one request. Ignored\n * if `pageNumber != 1`, defaulting to a single page.\n */\n async fetchPage(pageNumber: number, numInitialPages = 1): Promise<void> {\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return;\n\n // if we already have data, don't fetch again\n if (this.hasPage(pageNumber)) return;\n\n if (this.endOfDataReached) return;\n\n // Batch multiple initial page requests together if needed (e.g., can request\n // pages 1 and 2 together in a single request).\n const numPages = pageNumber === 1 ? numInitialPages : 1;\n const numRows = this.pageSize * numPages;\n\n // if a fetch is already in progress for this query and page, don't fetch again\n const { pageFetchQueryKey } = this;\n const currentPageKey = `${pageFetchQueryKey}-p:${pageNumber}`;\n if (this.fetchesInProgress.has(currentPageKey)) return;\n // const pageFetches =\n // this.fetchesInProgress[pageFetchQueryKey] ?? new Set();\n // if (pageFetches.has(pageNumber)) return;\n\n for (let i = 0; i < numPages; i += 1) {\n this.fetchesInProgress.add(`${pageFetchQueryKey}-p:${pageNumber + i}`);\n }\n console.log(\n `fetchPage(${pageNumber})`,\n this.id,\n this.canPerformSearch,\n this.hasPage(pageNumber),\n this.endOfDataReached,\n this.host.baseQuery,\n JSON.stringify(this.host.selectedFacets),\n this.pageFetchQueryKey\n );\n this.previousQueryKey = pageFetchQueryKey;\n\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n page: pageNumber,\n rows: numRows,\n sort: sortParams,\n filters: this.filterMap,\n aggregations: { omit: true },\n };\n params.uid = await this.requestUID(params, 'hits');\n\n console.log('=== FIRING PAGE REQUEST ===');\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n console.log('=== RECEIVED PAGE RESPONSE IN CB === ');\n const success = searchResponse?.success;\n\n // This is checking to see if the fetch has been invalidated since it was fired off.\n // If so, we just want to discard the response since it is for an obsolete query state.\n if (!this.fetchesInProgress.has(currentPageKey)) return;\n for (let i = 0; i < numPages; i += 1) {\n this.fetchesInProgress.delete(`${pageFetchQueryKey}-p:${pageNumber + i}`);\n }\n\n if (!success) {\n const errorMsg = searchResponse?.error?.message;\n const detailMsg = searchResponse?.error?.details?.message;\n\n this.queryErrorMessage = `${errorMsg ?? ''}${\n detailMsg ? `; ${detailMsg}` : ''\n }`;\n\n if (!this.queryErrorMessage) {\n this.queryErrorMessage = 'Missing or malformed response from backend';\n // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'\n window?.Sentry?.captureMessage?.(this.queryErrorMessage, 'error');\n }\n\n this.setSearchResultsLoading(false);\n this.requestHostUpdate();\n return;\n }\n\n this.totalResults = success.response.totalResults - this.offset;\n if (this.activeOnHost) {\n this.host.setTotalResultCount(this.totalResults);\n\n // display event to offshoot when result count is zero.\n if (this.totalResults === 0) {\n this.host.emitEmptyResults();\n }\n }\n\n if (this.host.withinCollection) {\n console.log(\n 'host is within collection, setting collection info:',\n success.response.collectionExtraInfo\n );\n this.collectionExtraInfo = success.response.collectionExtraInfo;\n\n // For collections, we want the UI to respect the default sort option\n // which can be specified in metadata, or otherwise assumed to be week:desc\n this.host.applyDefaultCollectionSort(this.collectionExtraInfo);\n\n if (this.collectionExtraInfo) {\n this.parentCollections = [].concat(\n this.collectionExtraInfo.public_metadata?.collection ?? []\n );\n }\n } else if (this.host.withinProfile) {\n console.log(\n 'host is within profile, setting acct info:',\n success.response.accountExtraInfo,\n success.response.pageElements\n );\n this.accountExtraInfo = success.response.accountExtraInfo;\n this.pageElements = success.response.pageElements;\n } else {\n console.log(\n 'not within profile/collxn',\n this.host.withinCollection,\n this.host.withinProfile\n );\n }\n\n const { results, collectionTitles } = success.response;\n if (results && results.length > 0) {\n // Load any collection titles present on the response into the cache,\n // or queue up preload fetches for them if none were present.\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles.set(id, title);\n }\n }\n\n // Update the data source for each returned page\n for (let i = 0; i < numPages; i += 1) {\n const pageStartIndex = this.pageSize * i;\n this.addTilesToDataSource(\n pageNumber + i,\n results.slice(pageStartIndex, pageStartIndex + this.pageSize)\n );\n }\n }\n\n // When we reach the end of the data, we can set the infinite scroller's\n // item count to the real total number of results (rather than the\n // temporary estimates based on pages rendered so far).\n const resultCountDiscrepancy = numRows - results.length;\n if (resultCountDiscrepancy > 0) {\n console.log('End of data reached');\n this.endOfDataReached = true;\n if (this.activeOnHost) this.host.setTileCount(this.totalResults);\n }\n\n this.requestHostUpdate();\n }\n\n /**\n * Update the datasource from the fetch response\n *\n * @param pageNumber\n * @param results\n */\n private addTilesToDataSource(\n pageNumber: number,\n results: SearchResult[]\n ): void {\n const tiles: TileModel[] = [];\n results?.forEach(result => {\n if (!result.identifier) return;\n tiles.push(new TileModel(result));\n });\n this.addPage(pageNumber, tiles);\n const visiblePages = this.host.currentVisiblePageNumbers;\n const needsReload = visiblePages.includes(pageNumber);\n if (needsReload) {\n this.refreshVisibleResults();\n }\n }\n\n /**\n * Fetches the aggregation buckets for the given prefix filter type.\n */\n private async fetchPrefixFilterBuckets(\n filterType: PrefixFilterType\n ): Promise<Bucket[]> {\n const trimmedQuery = this.host.baseQuery?.trim();\n if (!this.canPerformSearch) return [];\n\n const filterAggregationKey = prefixFilterAggregationKeys[filterType];\n const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n rows: 0,\n filters: this.filterMap,\n // Only fetch the firstTitle or firstCreator aggregation\n aggregations: { simpleParams: [filterAggregationKey] },\n // Fetch all 26 letter buckets\n aggregationsSize: 26,\n };\n params.uid = await this.requestUID(\n { ...params, sort: sortParams },\n 'aggregations'\n );\n\n const searchResponse = await this.host.searchService?.search(\n params,\n this.host.searchType\n );\n\n return (searchResponse?.success?.response?.aggregations?.[\n filterAggregationKey\n ]?.buckets ?? []) as Bucket[];\n }\n\n /**\n * Fetches and caches the prefix filter counts for the given filter type.\n */\n async updatePrefixFilterCounts(filterType: PrefixFilterType): Promise<void> {\n const { facetFetchQueryKey } = this;\n const buckets = await this.fetchPrefixFilterBuckets(filterType);\n\n // Don't update the filter counts for an outdated query (if it has been changed\n // since we sent the request)\n const queryChangedSinceFetch =\n facetFetchQueryKey !== this.facetFetchQueryKey;\n if (queryChangedSinceFetch) return;\n\n // Unpack the aggregation buckets into a simple map like { 'A': 50, 'B': 25, ... }\n this.prefixFilterCountMap = { ...this.prefixFilterCountMap }; // Clone the object to trigger an update\n this.prefixFilterCountMap[filterType] = buckets.reduce(\n (acc: Record<string, number>, bucket: Bucket) => {\n acc[(bucket.key as string).toUpperCase()] = bucket.doc_count;\n return acc;\n },\n {}\n );\n\n this.requestHostUpdate();\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The Internet Archive Collection Browser.",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Internet Archive",
6
- "version": "1.14.17-alpha.37",
6
+ "version": "1.14.17-alpha.38",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
@@ -35,9 +35,9 @@ export class CollectionBrowserDataSource
35
35
  private numTileModels = 0;
36
36
 
37
37
  /**
38
- * Maps the full query key to the pages being fetched for that query
38
+ * A set of fetch IDs that are valid for the current query state
39
39
  */
40
- private pageFetchesInProgress: Record<string, Set<number>> = {};
40
+ private fetchesInProgress = new Set<string>();
41
41
 
42
42
  /**
43
43
  * A record of the query key used for the last search.
@@ -133,6 +133,7 @@ export class CollectionBrowserDataSource
133
133
  return this._initialSearchCompletePromise;
134
134
  }
135
135
 
136
+ // eslint-disable-next-line no-useless-constructor
136
137
  constructor(
137
138
  /** The host element to which this controller should attach listeners */
138
139
  private readonly host: ReactiveControllerHost &
@@ -140,7 +141,7 @@ export class CollectionBrowserDataSource
140
141
  /** Default size of result pages */
141
142
  private pageSize: number
142
143
  ) {
143
- //this.host.addController(this);
144
+ // Just setting some property values
144
145
  }
145
146
 
146
147
  hostUpdate(): void {
@@ -200,7 +201,6 @@ export class CollectionBrowserDataSource
200
201
  this.pages = {};
201
202
  this.aggregations = {};
202
203
  this.yearHistogramAggregation = undefined;
203
- this.pageFetchesInProgress = {};
204
204
  this.pageElements = undefined;
205
205
  this.parentCollections = [];
206
206
  this.prefixFilterCountMap = {};
@@ -212,6 +212,9 @@ export class CollectionBrowserDataSource
212
212
  this.endOfDataReached = false;
213
213
  this.queryInitialized = false;
214
214
 
215
+ // Invalidate any fetches in progress
216
+ this.fetchesInProgress.clear();
217
+
215
218
  if (this.activeOnHost) this.host.setTotalResultCount(0);
216
219
  this.requestHostUpdate();
217
220
  }
@@ -771,6 +774,8 @@ export class CollectionBrowserDataSource
771
774
  console.log('will actually fetch facets');
772
775
 
773
776
  const { facetFetchQueryKey } = this;
777
+ if (this.fetchesInProgress.has(facetFetchQueryKey)) return;
778
+ this.fetchesInProgress.add(facetFetchQueryKey);
774
779
 
775
780
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
776
781
  const params: SearchParams = {
@@ -799,7 +804,8 @@ export class CollectionBrowserDataSource
799
804
  // If so, we just want to discard this set of aggregations because they are
800
805
  // likely no longer valid for the newer query.
801
806
  const queryChangedSinceFetch =
802
- facetFetchQueryKey !== this.facetFetchQueryKey;
807
+ this.fetchesInProgress.has(facetFetchQueryKey);
808
+ this.fetchesInProgress.delete(facetFetchQueryKey);
803
809
  if (queryChangedSinceFetch) {
804
810
  console.log(
805
811
  'facet query has changed since fetch, returning. new/old:',
@@ -875,12 +881,14 @@ export class CollectionBrowserDataSource
875
881
 
876
882
  // if a fetch is already in progress for this query and page, don't fetch again
877
883
  const { pageFetchQueryKey } = this;
878
- const pageFetches =
879
- this.pageFetchesInProgress[pageFetchQueryKey] ?? new Set();
880
- if (pageFetches.has(pageNumber)) return;
884
+ const currentPageKey = `${pageFetchQueryKey}-p:${pageNumber}`;
885
+ if (this.fetchesInProgress.has(currentPageKey)) return;
886
+ // const pageFetches =
887
+ // this.fetchesInProgress[pageFetchQueryKey] ?? new Set();
888
+ // if (pageFetches.has(pageNumber)) return;
881
889
 
882
890
  for (let i = 0; i < numPages; i += 1) {
883
- pageFetches.add(pageNumber + i);
891
+ this.fetchesInProgress.add(`${pageFetchQueryKey}-p:${pageNumber + i}`);
884
892
  }
885
893
  console.log(
886
894
  `fetchPage(${pageNumber})`,
@@ -892,7 +900,6 @@ export class CollectionBrowserDataSource
892
900
  JSON.stringify(this.host.selectedFacets),
893
901
  this.pageFetchQueryKey
894
902
  );
895
- this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
896
903
  this.previousQueryKey = pageFetchQueryKey;
897
904
 
898
905
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
@@ -915,11 +922,12 @@ export class CollectionBrowserDataSource
915
922
  console.log('=== RECEIVED PAGE RESPONSE IN CB === ');
916
923
  const success = searchResponse?.success;
917
924
 
918
- // This is checking to see if the query has changed since the data was fetched.
919
- // If so, we just want to discard the data since there should be a new query
920
- // right behind it.
921
- const queryChangedSinceFetch = pageFetchQueryKey !== this.pageFetchQueryKey;
922
- if (queryChangedSinceFetch) return;
925
+ // This is checking to see if the fetch has been invalidated since it was fired off.
926
+ // If so, we just want to discard the response since it is for an obsolete query state.
927
+ if (!this.fetchesInProgress.has(currentPageKey)) return;
928
+ for (let i = 0; i < numPages; i += 1) {
929
+ this.fetchesInProgress.delete(`${pageFetchQueryKey}-p:${pageNumber + i}`);
930
+ }
923
931
 
924
932
  if (!success) {
925
933
  const errorMsg = searchResponse?.error?.message;
@@ -935,10 +943,6 @@ export class CollectionBrowserDataSource
935
943
  window?.Sentry?.captureMessage?.(this.queryErrorMessage, 'error');
936
944
  }
937
945
 
938
- for (let i = 0; i < numPages; i += 1) {
939
- this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
940
- }
941
-
942
946
  this.setSearchResultsLoading(false);
943
947
  this.requestHostUpdate();
944
948
  return;
@@ -1016,10 +1020,6 @@ export class CollectionBrowserDataSource
1016
1020
  if (this.activeOnHost) this.host.setTileCount(this.totalResults);
1017
1021
  }
1018
1022
 
1019
- for (let i = 0; i < numPages; i += 1) {
1020
- this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
1021
- }
1022
-
1023
1023
  this.requestHostUpdate();
1024
1024
  }
1025
1025