@internetarchive/collection-browser 2.12.1-alpha-webdev5427.7 → 2.12.1

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 (69) hide show
  1. package/.editorconfig +29 -29
  2. package/.husky/pre-commit +4 -4
  3. package/LICENSE +661 -661
  4. package/README.md +83 -83
  5. package/dist/src/app-root.d.ts +0 -1
  6. package/dist/src/app-root.js +2 -48
  7. package/dist/src/app-root.js.map +1 -1
  8. package/dist/src/collection-browser.js +4 -13
  9. package/dist/src/collection-browser.js.map +1 -1
  10. package/dist/src/collection-facets/facet-row.js +1 -7
  11. package/dist/src/collection-facets/facet-row.js.map +1 -1
  12. package/dist/src/collection-facets/more-facets-content.d.ts +0 -1
  13. package/dist/src/collection-facets/more-facets-content.js +4 -19
  14. package/dist/src/collection-facets/more-facets-content.js.map +1 -1
  15. package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +3 -4
  16. package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -1
  17. package/dist/src/collection-facets.d.ts +1 -3
  18. package/dist/src/collection-facets.js +7 -37
  19. package/dist/src/collection-facets.js.map +1 -1
  20. package/dist/src/data-source/collection-browser-data-source.js +11 -16
  21. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  22. package/dist/src/expanded-date-picker.d.ts +0 -1
  23. package/dist/src/expanded-date-picker.js +1 -7
  24. package/dist/src/expanded-date-picker.js.map +1 -1
  25. package/dist/src/models.d.ts +5 -22
  26. package/dist/src/models.js +3 -64
  27. package/dist/src/models.js.map +1 -1
  28. package/dist/src/restoration-state-handler.js +3 -8
  29. package/dist/src/restoration-state-handler.js.map +1 -1
  30. package/dist/src/utils/facet-utils.js +2 -8
  31. package/dist/src/utils/facet-utils.js.map +1 -1
  32. package/dist/src/utils/local-date-from-utc.js +1 -1
  33. package/dist/src/utils/local-date-from-utc.js.map +1 -1
  34. package/dist/test/collection-facets.test.js +0 -27
  35. package/dist/test/collection-facets.test.js.map +1 -1
  36. package/dist/test/restoration-state-handler.test.js +10 -17
  37. package/dist/test/restoration-state-handler.test.js.map +1 -1
  38. package/dist/test/tiles/grid/item-tile.test.js +1 -1
  39. package/dist/test/tiles/grid/item-tile.test.js.map +1 -1
  40. package/dist/test/tiles/list/tile-list-compact.test.js +1 -1
  41. package/dist/test/tiles/list/tile-list-compact.test.js.map +1 -1
  42. package/dist/test/tiles/list/tile-list.test.js +3 -3
  43. package/dist/test/tiles/list/tile-list.test.js.map +1 -1
  44. package/dist/test/utils/local-date-from-utc.test.js +4 -4
  45. package/dist/test/utils/local-date-from-utc.test.js.map +1 -1
  46. package/local.archive.org.cert +86 -86
  47. package/local.archive.org.key +27 -27
  48. package/package.json +4 -4
  49. package/renovate.json +6 -6
  50. package/src/app-root.ts +2 -49
  51. package/src/collection-browser.ts +3 -16
  52. package/src/collection-facets/facet-row.ts +1 -8
  53. package/src/collection-facets/more-facets-content.ts +5 -21
  54. package/src/collection-facets/smart-facets/smart-facet-bar.ts +2 -2
  55. package/src/collection-facets.ts +8 -37
  56. package/src/data-source/collection-browser-data-source.ts +15 -27
  57. package/src/expanded-date-picker.ts +1 -5
  58. package/src/models.ts +10 -82
  59. package/src/restoration-state-handler.ts +1 -8
  60. package/src/utils/facet-utils.ts +3 -5
  61. package/src/utils/local-date-from-utc.ts +1 -1
  62. package/test/collection-facets.test.ts +0 -33
  63. package/test/restoration-state-handler.test.ts +10 -10
  64. package/test/tiles/grid/item-tile.test.ts +1 -1
  65. package/test/tiles/list/tile-list-compact.test.ts +1 -1
  66. package/test/tiles/list/tile-list.test.ts +3 -3
  67. package/test/utils/local-date-from-utc.test.ts +4 -4
  68. package/web-dev-server.config.mjs +30 -30
  69. package/web-test-runner.config.mjs +41 -41
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\nimport { msg } from '@lit/localize';\nimport type { MediaType } from '@internetarchive/field-parsers';\nimport {\n AggregationSortType,\n Review,\n SearchResult,\n SortDirection,\n} from '@internetarchive/search-service';\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\nimport { resolveMediatype } from './utils/resolve-mediatype';\n\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\nimport { restrictedIcon } from './assets/img/icons/restricted';\n\n/**\n * Flags that can affect the visibility of content on a tile\n */\ninterface TileFlags {\n loginRequired: boolean;\n contentWarning: boolean;\n}\n\n/**\n * Different types of tile overlays, corresponding to the above flags.\n */\nexport type TileOverlayType = 'login-required' | 'content-warning';\n\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\n 'login-required': msg('Log in to view this item'),\n 'content-warning': msg('Content may be inappropriate'),\n};\n\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\n 'login-required': loginRequiredIcon,\n 'content-warning': restrictedIcon,\n};\n\n/**\n * Class for converting & storing raw search results in the correct format for UI tiles.\n */\nexport class TileModel {\n averageRating?: number;\n\n captureDates?: Date[]; // List of capture dates for a URL, used on profile Web Archives tiles\n\n checked: boolean; // Whether this tile is currently checked for item management functions\n\n collectionIdentifier?: string;\n\n collectionName?: string;\n\n collectionFilesCount: number;\n\n collections: string[];\n\n collectionSize: number;\n\n commentCount: number;\n\n creator?: string;\n\n creators: string[];\n\n dateStr?: string; // A string representation of the publication date, used strictly for passing preformatted dates to the parent\n\n dateAdded?: Date; // Date added to public search (software-defined) [from: addeddate]\n\n dateArchived?: Date; // Date archived (software-defined) item created on archive.org [from: publicdate]\n\n datePublished?: Date; // Date work published in the world (user-defined) [from: date]\n\n dateReviewed?: Date; // Date reviewed (user-created) most recent review [from: reviewdate]\n\n description?: string;\n\n favCount: number;\n\n href?: string;\n\n identifier?: string;\n\n issue?: string;\n\n itemCount: number;\n\n mediatype: MediaType;\n\n review?: Review;\n\n source?: string;\n\n snippets?: string[];\n\n subjects: string[];\n\n thumbnailUrl?: string;\n\n title: string;\n\n tvClipCount?: number;\n\n viewCount?: number;\n\n volume?: string;\n\n weeklyViewCount?: number;\n\n loginRequired: boolean;\n\n contentWarning: boolean;\n\n constructor(result: SearchResult) {\n const flags = this.getFlags(result);\n\n this.averageRating = result.avg_rating?.value;\n this.captureDates = result.capture_dates?.values;\n this.checked = false;\n this.collections = result.collection?.values ?? [];\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\n this.collectionSize = result.collection_size?.value ?? 0;\n this.commentCount = result.num_reviews?.value ?? 0;\n this.creator = result.creator?.value;\n this.creators = result.creator?.values ?? [];\n this.dateAdded = result.addeddate?.value;\n this.dateArchived = result.publicdate?.value;\n this.datePublished = result.date?.value;\n this.dateReviewed = result.reviewdate?.value;\n this.description = result.description?.values.join('\\n');\n this.favCount = result.num_favorites?.value ?? 0;\n this.href = collapseRepeatedQuotes(\n result.review?.__href__ ?? result.__href__?.value,\n );\n this.identifier = TileModel.cleanIdentifier(result.identifier);\n this.issue = result.issue?.value;\n this.itemCount = result.item_count?.value ?? 0;\n this.mediatype = resolveMediatype(result);\n this.review = result.review;\n this.snippets = result.highlight?.values ?? [];\n this.source = result.source?.value;\n this.subjects = result.subject?.values ?? [];\n this.thumbnailUrl = result.__img__?.value;\n this.title = result.title?.value ?? '';\n this.tvClipCount = result.num_clips?.value ?? 0;\n this.volume = result.volume?.value;\n this.viewCount = result.downloads?.value;\n this.weeklyViewCount = result.week?.value;\n this.loginRequired = flags.loginRequired;\n this.contentWarning = flags.contentWarning;\n }\n\n /**\n * Copies the contents of this TileModel onto a new instance\n */\n clone(): TileModel {\n const cloned = new TileModel({});\n cloned.averageRating = this.averageRating;\n cloned.captureDates = this.captureDates;\n cloned.checked = this.checked;\n cloned.collections = this.collections;\n cloned.collectionFilesCount = this.collectionFilesCount;\n cloned.collectionSize = this.collectionSize;\n cloned.commentCount = this.commentCount;\n cloned.creator = this.creator;\n cloned.creators = this.creators;\n cloned.dateStr = this.dateStr;\n cloned.dateAdded = this.dateAdded;\n cloned.dateArchived = this.dateArchived;\n cloned.datePublished = this.datePublished;\n cloned.dateReviewed = this.dateReviewed;\n cloned.description = this.description;\n cloned.favCount = this.favCount;\n cloned.href = this.href;\n cloned.identifier = this.identifier;\n cloned.issue = this.issue;\n cloned.itemCount = this.itemCount;\n cloned.mediatype = this.mediatype;\n cloned.snippets = this.snippets;\n cloned.source = this.source;\n cloned.subjects = this.subjects;\n cloned.thumbnailUrl = this.thumbnailUrl;\n cloned.title = this.title;\n cloned.tvClipCount = this.tvClipCount;\n cloned.volume = this.volume;\n cloned.viewCount = this.viewCount;\n cloned.weeklyViewCount = this.weeklyViewCount;\n cloned.loginRequired = this.loginRequired;\n cloned.contentWarning = this.contentWarning;\n return cloned;\n }\n\n /**\n * Determines the appropriate tile flags for the given search result\n * (login required and/or content warning)\n */\n private getFlags(result: SearchResult): TileFlags {\n const flags: TileFlags = {\n loginRequired: false,\n contentWarning: false,\n };\n\n // Check if item and item in \"modifying\" collection, setting above flags\n if (\n result.collection?.values.length &&\n result.mediatype?.value !== 'collection'\n ) {\n for (const collection of result.collection?.values ?? []) {\n if (collection === 'loggedin') {\n flags.loginRequired = true;\n if (flags.contentWarning) break;\n }\n if (collection === 'no-preview') {\n flags.contentWarning = true;\n if (flags.loginRequired) break;\n }\n }\n }\n\n return flags;\n }\n\n private static cleanIdentifier(\n identifier: string | undefined,\n ): string | undefined {\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\n // are suffixed with values that need to be stripped. Those values are separated\n // from the item identifier itself with '|'.\n const barIndex = identifier?.indexOf('|') ?? -1;\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\n return cleaned;\n }\n}\n\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\n\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\n\nexport type TileDisplayMode =\n | 'grid'\n | 'list-compact'\n | 'list-detail'\n | 'list-header';\n\n/**\n * This is mainly used to set the cookies for the collection display mode.\n *\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\n */\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\n\n/**\n * The sort fields shown in the sort filter bar\n */\nexport enum SortField {\n 'default' = 'default',\n 'unrecognized' = 'unrecognized',\n 'relevance' = 'relevance',\n 'alltimeview' = 'alltimeview',\n 'weeklyview' = 'weeklyview',\n 'title' = 'title',\n 'date' = 'date',\n 'datearchived' = 'datearchived',\n 'datereviewed' = 'datereviewed',\n 'dateadded' = 'dateadded',\n 'datefavorited' = 'datefavorited',\n 'creator' = 'creator',\n}\n\nexport interface SortOption {\n /**\n * The SortField enum member corresponding to this option.\n */\n field: SortField;\n\n /**\n * The default sort direction to apply when this sort option is first selected.\n */\n defaultSortDirection: SortDirection | null;\n\n /**\n * Whether this sort option allows its sort direction to be changed from the default.\n */\n canSetDirection: boolean;\n\n /**\n * Whether this sort option may appear in the sort bar.\n */\n shownInSortBar: boolean;\n\n /**\n * Whether this sort option should be saved to the URL.\n * If false, then no `sort` param will be added to the URL when this sort option\n * is selected.\n */\n shownInURL: boolean;\n\n /**\n * Whether this sort option is passed to the search service.\n * If false, then no sort param will be passed to the search service at all when\n * this sort option is selected.\n */\n handledBySearchService: boolean;\n\n /**\n * The string identifying this sort field to the search service & backend API.\n */\n searchServiceKey?: string;\n\n /**\n * The human-readable name to use for this option in the sort bar (if applicable).\n */\n displayName: string;\n\n /**\n * A list of URL param keys that should be mapped to this sort option.\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\n */\n urlNames: (string | null | undefined)[];\n}\n\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\n // In these cases, we defer to whatever sort the backend chooses.\n // For the search page, the default is always relevance sort.\n // For collection pages _without a query_, the default is usually weekly views, but this can be\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\n // default is again relevance sort.\n // For fav-* collections only, the default is instead sorting by date favorited.\n [SortField.default]: {\n field: SortField.default,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\n displayName: '',\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\n },\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\n // when searching, but they are not displayed in the sort bar and we do not actively manage\n // their URL param beyond flipping the direction as needed.\n [SortField.unrecognized]: {\n field: SortField.unrecognized,\n defaultSortDirection: null,\n canSetDirection: true,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\n displayName: '',\n urlNames: [],\n },\n // Relevance sort is unique in that it does not produce a URL param when it is set.\n // It is only available when there is a user-specified query that relevancy can be scored against.\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\n [SortField.relevance]: {\n field: SortField.relevance,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: true,\n shownInURL: false,\n handledBySearchService: false,\n displayName: 'Relevance',\n urlNames: ['_score'],\n },\n [SortField.alltimeview]: {\n field: SortField.alltimeview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'downloads',\n displayName: 'All-time views',\n urlNames: ['downloads'],\n },\n [SortField.weeklyview]: {\n field: SortField.weeklyview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'week',\n displayName: 'Weekly views',\n urlNames: ['week'],\n },\n [SortField.title]: {\n field: SortField.title,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'titleSorter',\n displayName: 'Title',\n urlNames: ['title', 'titleSorter'],\n },\n [SortField.date]: {\n field: SortField.date,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'date',\n displayName: 'Date published',\n urlNames: ['date'],\n },\n [SortField.datearchived]: {\n field: SortField.datearchived,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'publicdate',\n displayName: 'Date archived',\n urlNames: ['publicdate'],\n },\n [SortField.datereviewed]: {\n field: SortField.datereviewed,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'reviewdate',\n displayName: 'Date reviewed',\n urlNames: ['reviewdate'],\n },\n [SortField.dateadded]: {\n field: SortField.dateadded,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'addeddate',\n displayName: 'Date added',\n urlNames: ['addeddate'],\n },\n [SortField.datefavorited]: {\n field: SortField.datefavorited,\n defaultSortDirection: 'desc',\n canSetDirection: false,\n shownInSortBar: true, // But only when viewing fav-* collections\n shownInURL: false,\n handledBySearchService: false,\n searchServiceKey: 'favoritedate',\n displayName: 'Date favorited',\n urlNames: ['favoritedate'],\n },\n [SortField.creator]: {\n field: SortField.creator,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'creatorSorter',\n displayName: 'Creator',\n urlNames: ['creator', 'creatorSorter'],\n },\n};\n\n/**\n * Returns the SortOption corresponding to the given API sort name, or\n * the \"unrecognized\" SortOption if none matches.\n */\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\n return (\n Object.values(SORT_OPTIONS).find(opt =>\n opt.urlNames.some(name => sortName === name),\n ) ?? SORT_OPTIONS[SortField.unrecognized]\n );\n}\n\nexport const defaultProfileElementSorts: Record<\n string,\n Exclude<SortField, SortField.default>\n> = {\n uploads: SortField.datearchived,\n reviews: SortField.datereviewed,\n collections: SortField.datearchived,\n web_archives: SortField.datearchived,\n};\n\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\nexport type PrefixFilterType = 'title' | 'creator';\n\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\nexport type PrefixFilterCounts = Record<string, number>;\n\n/**\n * A map from prefix filter types to the corresponding aggregation keys\n * that are needed to fetch the filter counts from the backend.\n */\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\n title: 'firstTitle',\n creator: 'firstCreator',\n};\n\n/**\n * Different facet loading strategies that can be used with collection browser.\n * - `eager`: Facet data is always loaded as soon as a search is performed\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\n * any logged in user.\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\n * In the mobile layout, functions exactly as `lazy-mobile`.\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\n * indicating that they are unavailable.\n */\nexport type FacetLoadStrategy =\n | 'eager'\n | 'lazy-mobile'\n | 'opt-in-or-login'\n | 'opt-in'\n | 'off';\n\n/**\n * Union of the facet types that are available in the sidebar.\n */\nexport type FacetOption =\n | 'subject'\n | 'lending'\n | 'mediatype'\n | 'language'\n | 'creator'\n | 'collection'\n | 'year'\n // TV-specific facet options:\n | 'program'\n | 'person'\n | 'sponsor';\n\nexport type SelectedFacetState = 'selected' | 'hidden';\n\nexport type FacetState = SelectedFacetState | 'none';\n\nexport interface FacetBucket {\n key: string;\n count: number;\n state: FacetState;\n // for some facets, we augment the key with a display value\n displayText?: string;\n // for TV channel facets, we add a parenthesized secondary name\n extraNote?: string;\n}\n\nexport interface FacetGroup {\n title: string;\n key: FacetOption;\n buckets: FacetBucket[];\n}\n\n/**\n * Information about a user interaction event on a facet.\n */\nexport type FacetEventDetails = {\n /**\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\n */\n facetType: FacetOption;\n /**\n * The bucket corresponding to the facet that was interacted with, including the\n * updated state of the facet after the interaction.\n */\n bucket: FacetBucket;\n /**\n * Whether the interaction occurred on a negative facet.\n */\n negative: boolean;\n};\n\nexport type FacetValue = string;\n\nexport type SelectedFacets = Partial<\n Record<FacetOption, Record<FacetValue, FacetBucket>>\n>;\n\nexport const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({\n subject: {},\n lending: {},\n mediatype: {},\n language: {},\n creator: {},\n collection: {},\n year: {},\n program: {},\n person: {},\n sponsor: {},\n});\n\n/**\n * Facet display order when presenting results for all search types *except* TV (see below).\n */\nexport const defaultFacetDisplayOrder: FacetOption[] = [\n 'mediatype',\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\n 'year',\n 'subject',\n 'collection',\n 'creator',\n 'language',\n];\n\n/**\n * Specialized facet ordering when displaying TV search results\n */\nexport const tvFacetDisplayOrder: FacetOption[] = [\n 'program',\n 'creator',\n 'year',\n 'subject',\n 'collection',\n 'person',\n 'sponsor',\n 'language',\n];\n\n/**\n * Human-readable titles for each facet group.\n */\nexport const facetTitles: Record<FacetOption, string> = {\n subject: 'Subject',\n lending: 'Availability',\n mediatype: 'Media Type',\n language: 'Language',\n creator: 'Creator',\n collection: 'Collection',\n year: 'Year',\n program: 'Program',\n person: 'Person',\n sponsor: 'Sponsor',\n};\n\n/**\n * The default sort type to use for each facet type\n */\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.COUNT,\n lending: AggregationSortType.COUNT,\n mediatype: AggregationSortType.COUNT,\n language: AggregationSortType.COUNT,\n creator: AggregationSortType.COUNT,\n collection: AggregationSortType.COUNT,\n year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default\n program: AggregationSortType.COUNT,\n person: AggregationSortType.COUNT,\n sponsor: AggregationSortType.COUNT,\n};\n\n/**\n * The sort type corresponding to facet bucket values, for each facet type\n * (i.e., the opposite of \"sort by count\" for that type).\n */\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.ALPHABETICAL,\n lending: AggregationSortType.ALPHABETICAL,\n mediatype: AggregationSortType.ALPHABETICAL,\n language: AggregationSortType.ALPHABETICAL,\n creator: AggregationSortType.ALPHABETICAL,\n collection: AggregationSortType.ALPHABETICAL,\n year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)\n program: AggregationSortType.ALPHABETICAL,\n person: AggregationSortType.ALPHABETICAL,\n sponsor: AggregationSortType.ALPHABETICAL,\n};\n\n/**\n * Extra parenthesized labels to show next to certain TV channel facets\n *\n * TODO this is temporary for testing\n */\nexport const tvChannelFacetLabels: Record<string, string> = Object.fromEntries(\n // prettier-ignore\n Object.entries({\n 'Al Jazeera' : ['ALJAZAM', 'ALJAZ'],\n 'Bloomberg' : ['BLOOMBERG'],\n 'BBC' : ['BBC', 'BBC1', 'BBC2'],\n 'BBC America' : ['BBCAMERICA'],\n 'BBC News' : ['BBCNEWS'],\n 'GB News' : ['GBN'],\n 'BET' : ['BETW'],\n 'CNBC' : ['CNBC'],\n 'CNN' : ['CNNW', 'CNN'],\n 'Comedy Central' : ['COM', 'COMW'],\n 'CSPAN' : ['CSPAN', 'CSPAN2', 'CSPAN3'],\n 'Current' : ['CURRENT'],\n 'Deutsche Welle' : ['DW'],\n 'France 24' : ['FRANCE24'],\n 'FOX Business' : ['FBC'],\n 'FOX News' : ['FOXNEWSW', 'FOXNEWS'],\n 'LINKTV' : ['LINKTV'],\n 'MSNBC' : ['MSNBCW', 'MSNBC'],\n 'NHK World' : ['NHK'],\n 'RT' : ['RT'],\n 'Sky News' : ['SKY'],\n }).reduce(\n (acc, [label, channels]) => acc.concat(channels.map(ch => [ch, label])),\n [] as [string, string][],\n ),\n);\n\nexport type LendingFacetKey =\n | 'is_lendable'\n | 'is_borrowable'\n | 'available_to_borrow'\n | 'is_browsable'\n | 'available_to_browse'\n | 'is_readable'\n | 'available_to_waitlist';\n\n/**\n * Maps valid lending keys to whether they should be visible in the facet sidebar\n */\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\n is_lendable: true,\n is_borrowable: false,\n available_to_borrow: true,\n is_browsable: false,\n available_to_browse: false,\n is_readable: true,\n available_to_waitlist: false,\n};\n\n/**\n * Maps valid, visible lending keys to their facet sidebar display text\n */\nexport const lendingFacetDisplayNames: Partial<\n Record<LendingFacetKey, string>\n> = {\n is_lendable: 'Lending Library',\n available_to_borrow: 'Borrow 14 Days',\n is_readable: 'Always Available',\n};\n\n/**\n * A record of which admin-only collections should be suppressed from being displayed\n * as facets or in an item's list of collections.\n */\nexport const suppressedCollections: Record<string, boolean> = {\n deemphasize: true,\n community: true,\n stream_only: true,\n samples_only: true,\n test_collection: true,\n printdisabled: true,\n 'openlibrary-ol': true,\n nationalemergencylibrary: true,\n china: true,\n americana: true,\n toronto: true,\n};\n\n/**\n * A record of manageable item\n */\nexport interface ManageableItem {\n identifier: string;\n title?: string;\n dateStr?: string;\n date?: string;\n}\n"]}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\nimport { msg } from '@lit/localize';\nimport type { MediaType } from '@internetarchive/field-parsers';\nimport {\n AggregationSortType,\n Review,\n SearchResult,\n SortDirection,\n} from '@internetarchive/search-service';\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\nimport { resolveMediatype } from './utils/resolve-mediatype';\n\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\nimport { restrictedIcon } from './assets/img/icons/restricted';\n\n/**\n * Flags that can affect the visibility of content on a tile\n */\ninterface TileFlags {\n loginRequired: boolean;\n contentWarning: boolean;\n}\n\n/**\n * Different types of tile overlays, corresponding to the above flags.\n */\nexport type TileOverlayType = 'login-required' | 'content-warning';\n\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\n 'login-required': msg('Log in to view this item'),\n 'content-warning': msg('Content may be inappropriate'),\n};\n\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\n 'login-required': loginRequiredIcon,\n 'content-warning': restrictedIcon,\n};\n\n/**\n * Class for converting & storing raw search results in the correct format for UI tiles.\n */\nexport class TileModel {\n averageRating?: number;\n\n captureDates?: Date[]; // List of capture dates for a URL, used on profile Web Archives tiles\n\n checked: boolean; // Whether this tile is currently checked for item management functions\n\n collectionIdentifier?: string;\n\n collectionName?: string;\n\n collectionFilesCount: number;\n\n collections: string[];\n\n collectionSize: number;\n\n commentCount: number;\n\n creator?: string;\n\n creators: string[];\n\n dateStr?: string; // A string representation of the publication date, used strictly for passing preformatted dates to the parent\n\n dateAdded?: Date; // Date added to public search (software-defined) [from: addeddate]\n\n dateArchived?: Date; // Date archived (software-defined) item created on archive.org [from: publicdate]\n\n datePublished?: Date; // Date work published in the world (user-defined) [from: date]\n\n dateReviewed?: Date; // Date reviewed (user-created) most recent review [from: reviewdate]\n\n description?: string;\n\n favCount: number;\n\n href?: string;\n\n identifier?: string;\n\n issue?: string;\n\n itemCount: number;\n\n mediatype: MediaType;\n\n review?: Review;\n\n source?: string;\n\n snippets?: string[];\n\n subjects: string[];\n\n thumbnailUrl?: string;\n\n title: string;\n\n tvClipCount?: number;\n\n viewCount?: number;\n\n volume?: string;\n\n weeklyViewCount?: number;\n\n loginRequired: boolean;\n\n contentWarning: boolean;\n\n constructor(result: SearchResult) {\n const flags = this.getFlags(result);\n\n this.averageRating = result.avg_rating?.value;\n this.captureDates = result.capture_dates?.values;\n this.checked = false;\n this.collections = result.collection?.values ?? [];\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\n this.collectionSize = result.collection_size?.value ?? 0;\n this.commentCount = result.num_reviews?.value ?? 0;\n this.creator = result.creator?.value;\n this.creators = result.creator?.values ?? [];\n this.dateAdded = result.addeddate?.value;\n this.dateArchived = result.publicdate?.value;\n this.datePublished = result.date?.value;\n this.dateReviewed = result.reviewdate?.value;\n this.description = result.description?.values.join('\\n');\n this.favCount = result.num_favorites?.value ?? 0;\n this.href = collapseRepeatedQuotes(\n result.review?.__href__ ?? result.__href__?.value,\n );\n this.identifier = TileModel.cleanIdentifier(result.identifier);\n this.issue = result.issue?.value;\n this.itemCount = result.item_count?.value ?? 0;\n this.mediatype = resolveMediatype(result);\n this.review = result.review;\n this.snippets = result.highlight?.values ?? [];\n this.source = result.source?.value;\n this.subjects = result.subject?.values ?? [];\n this.thumbnailUrl = result.__img__?.value;\n this.title = result.title?.value ?? '';\n this.tvClipCount = result.num_clips?.value ?? 0;\n this.volume = result.volume?.value;\n this.viewCount = result.downloads?.value;\n this.weeklyViewCount = result.week?.value;\n this.loginRequired = flags.loginRequired;\n this.contentWarning = flags.contentWarning;\n }\n\n /**\n * Copies the contents of this TileModel onto a new instance\n */\n clone(): TileModel {\n const cloned = new TileModel({});\n cloned.averageRating = this.averageRating;\n cloned.captureDates = this.captureDates;\n cloned.checked = this.checked;\n cloned.collections = this.collections;\n cloned.collectionFilesCount = this.collectionFilesCount;\n cloned.collectionSize = this.collectionSize;\n cloned.commentCount = this.commentCount;\n cloned.creator = this.creator;\n cloned.creators = this.creators;\n cloned.dateStr = this.dateStr;\n cloned.dateAdded = this.dateAdded;\n cloned.dateArchived = this.dateArchived;\n cloned.datePublished = this.datePublished;\n cloned.dateReviewed = this.dateReviewed;\n cloned.description = this.description;\n cloned.favCount = this.favCount;\n cloned.href = this.href;\n cloned.identifier = this.identifier;\n cloned.issue = this.issue;\n cloned.itemCount = this.itemCount;\n cloned.mediatype = this.mediatype;\n cloned.snippets = this.snippets;\n cloned.source = this.source;\n cloned.subjects = this.subjects;\n cloned.thumbnailUrl = this.thumbnailUrl;\n cloned.title = this.title;\n cloned.tvClipCount = this.tvClipCount;\n cloned.volume = this.volume;\n cloned.viewCount = this.viewCount;\n cloned.weeklyViewCount = this.weeklyViewCount;\n cloned.loginRequired = this.loginRequired;\n cloned.contentWarning = this.contentWarning;\n return cloned;\n }\n\n /**\n * Determines the appropriate tile flags for the given search result\n * (login required and/or content warning)\n */\n private getFlags(result: SearchResult): TileFlags {\n const flags: TileFlags = {\n loginRequired: false,\n contentWarning: false,\n };\n\n // Check if item and item in \"modifying\" collection, setting above flags\n if (\n result.collection?.values.length &&\n result.mediatype?.value !== 'collection'\n ) {\n for (const collection of result.collection?.values ?? []) {\n if (collection === 'loggedin') {\n flags.loginRequired = true;\n if (flags.contentWarning) break;\n }\n if (collection === 'no-preview') {\n flags.contentWarning = true;\n if (flags.loginRequired) break;\n }\n }\n }\n\n return flags;\n }\n\n private static cleanIdentifier(\n identifier: string | undefined,\n ): string | undefined {\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\n // are suffixed with values that need to be stripped. Those values are separated\n // from the item identifier itself with '|'.\n const barIndex = identifier?.indexOf('|') ?? -1;\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\n return cleaned;\n }\n}\n\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\n\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\n\nexport type TileDisplayMode =\n | 'grid'\n | 'list-compact'\n | 'list-detail'\n | 'list-header';\n\n/**\n * This is mainly used to set the cookies for the collection display mode.\n *\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\n */\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\n\n/**\n * The sort fields shown in the sort filter bar\n */\nexport enum SortField {\n 'default' = 'default',\n 'unrecognized' = 'unrecognized',\n 'relevance' = 'relevance',\n 'alltimeview' = 'alltimeview',\n 'weeklyview' = 'weeklyview',\n 'title' = 'title',\n 'date' = 'date',\n 'datearchived' = 'datearchived',\n 'datereviewed' = 'datereviewed',\n 'dateadded' = 'dateadded',\n 'datefavorited' = 'datefavorited',\n 'creator' = 'creator',\n}\n\nexport interface SortOption {\n /**\n * The SortField enum member corresponding to this option.\n */\n field: SortField;\n\n /**\n * The default sort direction to apply when this sort option is first selected.\n */\n defaultSortDirection: SortDirection | null;\n\n /**\n * Whether this sort option allows its sort direction to be changed from the default.\n */\n canSetDirection: boolean;\n\n /**\n * Whether this sort option may appear in the sort bar.\n */\n shownInSortBar: boolean;\n\n /**\n * Whether this sort option should be saved to the URL.\n * If false, then no `sort` param will be added to the URL when this sort option\n * is selected.\n */\n shownInURL: boolean;\n\n /**\n * Whether this sort option is passed to the search service.\n * If false, then no sort param will be passed to the search service at all when\n * this sort option is selected.\n */\n handledBySearchService: boolean;\n\n /**\n * The string identifying this sort field to the search service & backend API.\n */\n searchServiceKey?: string;\n\n /**\n * The human-readable name to use for this option in the sort bar (if applicable).\n */\n displayName: string;\n\n /**\n * A list of URL param keys that should be mapped to this sort option.\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\n */\n urlNames: (string | null | undefined)[];\n}\n\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\n // In these cases, we defer to whatever sort the backend chooses.\n // For the search page, the default is always relevance sort.\n // For collection pages _without a query_, the default is usually weekly views, but this can be\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\n // default is again relevance sort.\n // For fav-* collections only, the default is instead sorting by date favorited.\n [SortField.default]: {\n field: SortField.default,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\n displayName: '',\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\n },\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\n // when searching, but they are not displayed in the sort bar and we do not actively manage\n // their URL param beyond flipping the direction as needed.\n [SortField.unrecognized]: {\n field: SortField.unrecognized,\n defaultSortDirection: null,\n canSetDirection: true,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\n displayName: '',\n urlNames: [],\n },\n // Relevance sort is unique in that it does not produce a URL param when it is set.\n // It is only available when there is a user-specified query that relevancy can be scored against.\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\n [SortField.relevance]: {\n field: SortField.relevance,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: true,\n shownInURL: false,\n handledBySearchService: false,\n displayName: 'Relevance',\n urlNames: ['_score'],\n },\n [SortField.alltimeview]: {\n field: SortField.alltimeview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'downloads',\n displayName: 'All-time views',\n urlNames: ['downloads'],\n },\n [SortField.weeklyview]: {\n field: SortField.weeklyview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'week',\n displayName: 'Weekly views',\n urlNames: ['week'],\n },\n [SortField.title]: {\n field: SortField.title,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'titleSorter',\n displayName: 'Title',\n urlNames: ['title', 'titleSorter'],\n },\n [SortField.date]: {\n field: SortField.date,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'date',\n displayName: 'Date published',\n urlNames: ['date'],\n },\n [SortField.datearchived]: {\n field: SortField.datearchived,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'publicdate',\n displayName: 'Date archived',\n urlNames: ['publicdate'],\n },\n [SortField.datereviewed]: {\n field: SortField.datereviewed,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'reviewdate',\n displayName: 'Date reviewed',\n urlNames: ['reviewdate'],\n },\n [SortField.dateadded]: {\n field: SortField.dateadded,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'addeddate',\n displayName: 'Date added',\n urlNames: ['addeddate'],\n },\n [SortField.datefavorited]: {\n field: SortField.datefavorited,\n defaultSortDirection: 'desc',\n canSetDirection: false,\n shownInSortBar: true, // But only when viewing fav-* collections\n shownInURL: false,\n handledBySearchService: false,\n searchServiceKey: 'favoritedate',\n displayName: 'Date favorited',\n urlNames: ['favoritedate'],\n },\n [SortField.creator]: {\n field: SortField.creator,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'creatorSorter',\n displayName: 'Creator',\n urlNames: ['creator', 'creatorSorter'],\n },\n};\n\n/**\n * Returns the SortOption corresponding to the given API sort name, or\n * the \"unrecognized\" SortOption if none matches.\n */\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\n return (\n Object.values(SORT_OPTIONS).find(opt =>\n opt.urlNames.some(name => sortName === name),\n ) ?? SORT_OPTIONS[SortField.unrecognized]\n );\n}\n\nexport const defaultProfileElementSorts: Record<\n string,\n Exclude<SortField, SortField.default>\n> = {\n uploads: SortField.datearchived,\n reviews: SortField.datereviewed,\n collections: SortField.datearchived,\n web_archives: SortField.datearchived,\n};\n\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\nexport type PrefixFilterType = 'title' | 'creator';\n\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\nexport type PrefixFilterCounts = Record<string, number>;\n\n/**\n * A map from prefix filter types to the corresponding aggregation keys\n * that are needed to fetch the filter counts from the backend.\n */\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\n title: 'firstTitle',\n creator: 'firstCreator',\n};\n\n/**\n * Different facet loading strategies that can be used with collection browser.\n * - `eager`: Facet data is always loaded as soon as a search is performed\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\n * any logged in user.\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\n * In the mobile layout, functions exactly as `lazy-mobile`.\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\n * indicating that they are unavailable.\n */\nexport type FacetLoadStrategy =\n | 'eager'\n | 'lazy-mobile'\n | 'opt-in-or-login'\n | 'opt-in'\n | 'off';\n\n/**\n * Union of the facet types that are available in the sidebar.\n */\nexport type FacetOption =\n | 'subject'\n | 'lending'\n | 'mediatype'\n | 'language'\n | 'creator'\n | 'collection'\n | 'year';\n\nexport type SelectedFacetState = 'selected' | 'hidden';\n\nexport type FacetState = SelectedFacetState | 'none';\n\nexport interface FacetBucket {\n // for some facets, we augment the key with a display value\n displayText?: string;\n key: string;\n count: number;\n state: FacetState;\n}\n\nexport interface FacetGroup {\n title: string;\n key: FacetOption;\n buckets: FacetBucket[];\n}\n\n/**\n * Information about a user interaction event on a facet.\n */\nexport type FacetEventDetails = {\n /**\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\n */\n facetType: FacetOption;\n /**\n * The bucket corresponding to the facet that was interacted with, including the\n * updated state of the facet after the interaction.\n */\n bucket: FacetBucket;\n /**\n * Whether the interaction occurred on a negative facet.\n */\n negative: boolean;\n};\n\nexport type FacetValue = string;\n\nexport type SelectedFacets = Record<\n FacetOption,\n Record<FacetValue, FacetBucket>\n>;\n\nexport const getDefaultSelectedFacets = (): SelectedFacets => ({\n subject: {},\n lending: {},\n mediatype: {},\n language: {},\n creator: {},\n collection: {},\n year: {},\n});\n\nexport const facetDisplayOrder: FacetOption[] = [\n 'mediatype',\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\n 'year',\n 'subject',\n 'collection',\n 'creator',\n 'language',\n];\n\nexport const facetTitles: Record<FacetOption, string> = {\n subject: 'Subject',\n lending: 'Availability',\n mediatype: 'Media Type',\n language: 'Language',\n creator: 'Creator',\n collection: 'Collection',\n year: 'Year',\n};\n\n/**\n * The default sort type to use for each facet type\n */\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.COUNT,\n lending: AggregationSortType.COUNT,\n mediatype: AggregationSortType.COUNT,\n language: AggregationSortType.COUNT,\n creator: AggregationSortType.COUNT,\n collection: AggregationSortType.COUNT,\n year: AggregationSortType.NUMERIC,\n};\n\n/**\n * The sort type corresponding to facet bucket values, for each facet type\n * (i.e., the opposite of \"sort by count\" for that type).\n */\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.ALPHABETICAL,\n lending: AggregationSortType.ALPHABETICAL,\n mediatype: AggregationSortType.ALPHABETICAL,\n language: AggregationSortType.ALPHABETICAL,\n creator: AggregationSortType.ALPHABETICAL,\n collection: AggregationSortType.ALPHABETICAL,\n year: AggregationSortType.NUMERIC,\n};\n\nexport type LendingFacetKey =\n | 'is_lendable'\n | 'is_borrowable'\n | 'available_to_borrow'\n | 'is_browsable'\n | 'available_to_browse'\n | 'is_readable'\n | 'available_to_waitlist';\n\n/**\n * Maps valid lending keys to whether they should be visible in the facet sidebar\n */\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\n is_lendable: true,\n is_borrowable: false,\n available_to_borrow: true,\n is_browsable: false,\n available_to_browse: false,\n is_readable: true,\n available_to_waitlist: false,\n};\n\n/**\n * Maps valid, visible lending keys to their facet sidebar display text\n */\nexport const lendingFacetDisplayNames: Partial<\n Record<LendingFacetKey, string>\n> = {\n is_lendable: 'Lending Library',\n available_to_borrow: 'Borrow 14 Days',\n is_readable: 'Always Available',\n};\n\n/**\n * A record of which admin-only collections should be suppressed from being displayed\n * as facets or in an item's list of collections.\n */\nexport const suppressedCollections: Record<string, boolean> = {\n deemphasize: true,\n community: true,\n stream_only: true,\n samples_only: true,\n test_collection: true,\n printdisabled: true,\n 'openlibrary-ol': true,\n nationalemergencylibrary: true,\n china: true,\n americana: true,\n toronto: true,\n};\n\n/**\n * A record of manageable item\n */\nexport interface ManageableItem {\n identifier: string;\n title?: string;\n dateStr?: string;\n date?: string;\n}\n"]}
@@ -44,7 +44,7 @@ export class RestorationStateHandler {
44
44
  return 'list-compact';
45
45
  }
46
46
  persistQueryStateToUrl(state, options = {}) {
47
- var _a, _b, _c, _d, _e;
47
+ var _a, _b, _c;
48
48
  const url = new URL(window.location.href);
49
49
  const oldParams = new URLSearchParams(url.searchParams);
50
50
  const newParams = this.removeRecognizedParams(url.searchParams);
@@ -122,12 +122,8 @@ export class RestorationStateHandler {
122
122
  }
123
123
  }
124
124
  }
125
- const dateField = ((_b = state.minSelectedDate) === null || _b === void 0 ? void 0 : _b.includes('-')) ||
126
- ((_c = state.maxSelectedDate) === null || _c === void 0 ? void 0 : _c.includes('-'))
127
- ? 'date'
128
- : 'year';
129
125
  if (state.minSelectedDate && state.maxSelectedDate) {
130
- newParams.append('and[]', `${dateField}:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`);
126
+ newParams.append('and[]', `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`);
131
127
  }
132
128
  if (state.titleQuery) {
133
129
  newParams.append('and[]', state.titleQuery);
@@ -166,7 +162,7 @@ export class RestorationStateHandler {
166
162
  // we just want to overwrite it.
167
163
  historyMethod = 'replaceState';
168
164
  }
169
- (_e = (_d = window.history)[historyMethod]) === null || _e === void 0 ? void 0 : _e.call(_d, {
165
+ (_c = (_b = window.history)[historyMethod]) === null || _c === void 0 ? void 0 : _c.call(_b, {
170
166
  query: state.baseQuery,
171
167
  searchType: state.searchType,
172
168
  page: state.currentPage,
@@ -255,7 +251,6 @@ export class RestorationStateHandler {
255
251
  return;
256
252
  }
257
253
  switch (field) {
258
- case 'date':
259
254
  case 'year': {
260
255
  const [minDate, maxDate] = value.split(' TO ');
261
256
  // we have two potential ways of filtering by date:
@@ -1 +1 @@
1
- {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { SearchType, SortDirection } from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n getDefaultSelectedFacets,\n sortOptionFromAPIString,\n SORT_OPTIONS,\n} from './models';\nimport { arrayEquals } from './utils/array-equals';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStatePersistOptions {\n forceReplace?: boolean;\n persistMetadataSearchType?: boolean;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(\n state: RestorationState,\n options?: RestorationStatePersistOptions,\n ): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state, options);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ) {\n const url = new URL(window.location.href);\n const oldParams = new URLSearchParams(url.searchParams);\n const newParams = this.removeRecognizedParams(url.searchParams);\n\n let replaceEmptySin = false;\n\n if (state.baseQuery) {\n newParams.set('query', state.baseQuery);\n }\n\n switch (state.searchType) {\n case SearchType.FULLTEXT:\n newParams.set('sin', 'TXT');\n break;\n case SearchType.RADIO:\n newParams.set('sin', 'RADIO');\n break;\n case SearchType.TV:\n newParams.set('sin', 'TV');\n break;\n case SearchType.METADATA:\n // Only write the param for metadata when it isn't already the default.\n // Currently this is only the case within TV collections.\n if (options.persistMetadataSearchType || oldParams.get('sin') === 'MD')\n newParams.set('sin', 'MD');\n break;\n }\n\n if (oldParams.get('sin') === '') {\n // Treat empty sin the same as no sin at all\n oldParams.delete('sin');\n replaceEmptySin = true;\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n newParams.set('page', state.currentPage.toString());\n } else {\n newParams.delete('page');\n }\n }\n\n if (state.selectedSort) {\n const sortOption = SORT_OPTIONS[state.selectedSort];\n let prefix = this.sortDirectionPrefix(state.sortDirection);\n\n if (sortOption.field === SortField.unrecognized) {\n // For unrecognized sorts, use the existing param, possibly updating its direction\n const oldSortParam = oldParams.get('sort') ?? '';\n const { field, direction } =\n this.getSortFieldAndDirection(oldSortParam);\n\n // Use the state-specified direction if available, or extract one from the param if not\n if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);\n\n if (field) {\n newParams.set('sort', `${prefix}${field}`);\n } else {\n newParams.set('sort', oldSortParam);\n }\n } else if (sortOption.shownInURL) {\n // Otherwise, use the canonical API form of the sort option\n const canonicalApiSort = sortOption.urlNames[0];\n newParams.set('sort', `${prefix}${canonicalApiSort}`);\n }\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets,\n )) {\n const facetEntries = Object.entries(facetValues);\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n newParams.append('not[]', paramValue);\n } else {\n newParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n const dateField =\n state.minSelectedDate?.includes('-') ||\n state.maxSelectedDate?.includes('-')\n ? 'date'\n : 'year';\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n newParams.append(\n 'and[]',\n `${dateField}:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`,\n );\n }\n\n if (state.titleQuery) {\n newParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n newParams.append('and[]', state.creatorQuery);\n }\n\n // Ensure we aren't pushing consecutive identical states to the history stack.\n // - If the state has changed, we push a new history entry.\n // - If only the page number has changed, we replace the current history entry.\n // - If the state hasn't changed, then do nothing.\n let historyMethod: 'pushState' | 'replaceState' = options.forceReplace\n ? 'replaceState'\n : 'pushState';\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\n 'sin',\n 'sort',\n 'and[]',\n 'not[]',\n ]);\n\n if (\n nonQueryParamsMatch &&\n this.paramsMatch(oldParams, newParams, ['query'])\n ) {\n if (replaceEmptySin) {\n // Get rid of any empty sin param\n newParams.delete('sin');\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\n // For page number, we want to replace the page state when it changes,\n // not push a new history entry. If it hasn't changed, then we're done.\n return;\n }\n historyMethod = 'replaceState';\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\n // Similarly, if the only non-matching param was a legacy query param, then\n // we just want to overwrite it.\n historyMethod = 'replaceState';\n }\n\n window.history[historyMethod]?.(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: { field: state.selectedSort, direction: state.sortDirection },\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url,\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n // We also need to check for the presence of params like 'and[0]', 'not[1]', etc.\n // since Facebook automatically converts URLs with [] into those forms.\n for (const [key, val] of url.searchParams.entries()) {\n if (/and\\[\\d+\\]/.test(key)) {\n facetAnds.push(val);\n } else if (/not\\[\\d+\\]/.test(key)) {\n facetNots.push(val);\n }\n }\n\n // Legacy search allowed `q` and `search` params for the query, so in the interest\n // of backwards-compatibility with old bookmarks, we recognize those here too.\n // (However, they still get upgraded to a `query` param when we persist our state\n // to the URL).\n const legacySearchQuery =\n url.searchParams.get('q') ?? url.searchParams.get('search');\n\n const restorationState: RestorationState = {\n selectedFacets: getDefaultSelectedFacets(),\n };\n\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n } else if (legacySearchQuery) {\n restorationState.baseQuery = legacySearchQuery;\n }\n\n switch (searchInside) {\n case 'TXT':\n restorationState.searchType = SearchType.FULLTEXT;\n break;\n case 'RADIO':\n restorationState.searchType = SearchType.RADIO;\n break;\n case 'TV':\n restorationState.searchType = SearchType.TV;\n break;\n case 'MD':\n restorationState.searchType = SearchType.METADATA;\n break;\n default:\n restorationState.searchType = SearchType.DEFAULT;\n break;\n }\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n\n if (sortQuery) {\n const { field, direction } = this.getSortFieldAndDirection(sortQuery);\n\n const sortOption = sortOptionFromAPIString(field);\n restorationState.selectedSort = sortOption.field;\n\n if (['asc', 'desc'].includes(direction)) {\n restorationState.sortDirection = direction as SortDirection;\n }\n }\n\n if (facetAnds) {\n facetAnds.forEach(and => {\n // eslint-disable-next-line prefer-const\n let [field, value] = and.split(':');\n\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\n field = field.replace(/Sorter$/, '');\n\n // Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`\n // which we want to normalize to a not[] param instead\n if (field.startsWith('-')) {\n facetNots.push(and.slice(1));\n return;\n }\n\n switch (field) {\n case 'date':\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length,\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1,\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n });\n }\n\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden',\n );\n });\n }\n\n return restorationState;\n }\n\n /**\n * Converts a URL sort param into a field/direction pair, if possible.\n * Either or both may be undefined if the param is not in a recognized format.\n */\n private getSortFieldAndDirection(sortParam: string) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortParam.indexOf(' ') > -1;\n let field;\n let direction;\n if (hasSpace) {\n [field, direction] = sortParam.split(' ');\n } else {\n field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;\n direction = sortParam.startsWith('-') ? 'desc' : 'asc';\n }\n\n return { field, direction };\n }\n\n /** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */\n private sortDirectionPrefix(sortDirection?: string) {\n return sortDirection === 'desc' ? '-' : '';\n }\n\n /** Remove optional opening and closing quotes from a string */\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n\n return value;\n }\n\n /**\n * Returns whether the two given URLSearchParams objects have\n * identical values for all of the given param keys. If either\n * object contains more than one value for a given key, then\n * all of the values for that key must match (disregarding order).\n */\n private paramsMatch(\n searchParams1: URLSearchParams,\n searchParams2: URLSearchParams,\n keys: string[],\n ): boolean {\n return keys.every(key =>\n arrayEquals(\n searchParams1.getAll(key).sort(),\n searchParams2.getAll(key).sort(),\n ),\n );\n }\n\n /**\n * Deletes any params from the given URLSearchParams object that are recognized\n * when loading state from the URL.\n */\n private removeRecognizedParams(\n searchParams: URLSearchParams,\n ): URLSearchParams {\n // Remove all of our standard params\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n // Remove any and/not facet params that contain numbers in their square brackets\n for (const key of searchParams.keys()) {\n if (/(and|not)\\[\\d+\\]/.test(key)) {\n searchParams.delete(key);\n }\n }\n\n // Also remove some legacy params that should have been upgraded to the ones above\n searchParams.delete('q');\n searchParams.delete('search');\n\n return searchParams;\n }\n\n /**\n * Returns whether the given URLSearchParams object contains a param that is\n * only recognized as a holdover from legacy search, and should not be\n * persisted to the URL.\n */\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\n return searchParams.has('q') || searchParams.has('search');\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState,\n ): void {\n const facet = selectedFacets[field];\n if (!facet) return; // Unrecognized facet group, ignore it.\n\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
1
+ {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { SearchType, SortDirection } from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n getDefaultSelectedFacets,\n sortOptionFromAPIString,\n SORT_OPTIONS,\n} from './models';\nimport { arrayEquals } from './utils/array-equals';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStatePersistOptions {\n forceReplace?: boolean;\n persistMetadataSearchType?: boolean;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(\n state: RestorationState,\n options?: RestorationStatePersistOptions,\n ): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state, options);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ) {\n const url = new URL(window.location.href);\n const oldParams = new URLSearchParams(url.searchParams);\n const newParams = this.removeRecognizedParams(url.searchParams);\n\n let replaceEmptySin = false;\n\n if (state.baseQuery) {\n newParams.set('query', state.baseQuery);\n }\n\n switch (state.searchType) {\n case SearchType.FULLTEXT:\n newParams.set('sin', 'TXT');\n break;\n case SearchType.RADIO:\n newParams.set('sin', 'RADIO');\n break;\n case SearchType.TV:\n newParams.set('sin', 'TV');\n break;\n case SearchType.METADATA:\n // Only write the param for metadata when it isn't already the default.\n // Currently this is only the case within TV collections.\n if (options.persistMetadataSearchType || oldParams.get('sin') === 'MD')\n newParams.set('sin', 'MD');\n break;\n }\n\n if (oldParams.get('sin') === '') {\n // Treat empty sin the same as no sin at all\n oldParams.delete('sin');\n replaceEmptySin = true;\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n newParams.set('page', state.currentPage.toString());\n } else {\n newParams.delete('page');\n }\n }\n\n if (state.selectedSort) {\n const sortOption = SORT_OPTIONS[state.selectedSort];\n let prefix = this.sortDirectionPrefix(state.sortDirection);\n\n if (sortOption.field === SortField.unrecognized) {\n // For unrecognized sorts, use the existing param, possibly updating its direction\n const oldSortParam = oldParams.get('sort') ?? '';\n const { field, direction } =\n this.getSortFieldAndDirection(oldSortParam);\n\n // Use the state-specified direction if available, or extract one from the param if not\n if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);\n\n if (field) {\n newParams.set('sort', `${prefix}${field}`);\n } else {\n newParams.set('sort', oldSortParam);\n }\n } else if (sortOption.shownInURL) {\n // Otherwise, use the canonical API form of the sort option\n const canonicalApiSort = sortOption.urlNames[0];\n newParams.set('sort', `${prefix}${canonicalApiSort}`);\n }\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets,\n )) {\n const facetEntries = Object.entries(facetValues);\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n newParams.append('not[]', paramValue);\n } else {\n newParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n newParams.append(\n 'and[]',\n `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`,\n );\n }\n\n if (state.titleQuery) {\n newParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n newParams.append('and[]', state.creatorQuery);\n }\n\n // Ensure we aren't pushing consecutive identical states to the history stack.\n // - If the state has changed, we push a new history entry.\n // - If only the page number has changed, we replace the current history entry.\n // - If the state hasn't changed, then do nothing.\n let historyMethod: 'pushState' | 'replaceState' = options.forceReplace\n ? 'replaceState'\n : 'pushState';\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\n 'sin',\n 'sort',\n 'and[]',\n 'not[]',\n ]);\n\n if (\n nonQueryParamsMatch &&\n this.paramsMatch(oldParams, newParams, ['query'])\n ) {\n if (replaceEmptySin) {\n // Get rid of any empty sin param\n newParams.delete('sin');\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\n // For page number, we want to replace the page state when it changes,\n // not push a new history entry. If it hasn't changed, then we're done.\n return;\n }\n historyMethod = 'replaceState';\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\n // Similarly, if the only non-matching param was a legacy query param, then\n // we just want to overwrite it.\n historyMethod = 'replaceState';\n }\n\n window.history[historyMethod]?.(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: { field: state.selectedSort, direction: state.sortDirection },\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url,\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n // We also need to check for the presence of params like 'and[0]', 'not[1]', etc.\n // since Facebook automatically converts URLs with [] into those forms.\n for (const [key, val] of url.searchParams.entries()) {\n if (/and\\[\\d+\\]/.test(key)) {\n facetAnds.push(val);\n } else if (/not\\[\\d+\\]/.test(key)) {\n facetNots.push(val);\n }\n }\n\n // Legacy search allowed `q` and `search` params for the query, so in the interest\n // of backwards-compatibility with old bookmarks, we recognize those here too.\n // (However, they still get upgraded to a `query` param when we persist our state\n // to the URL).\n const legacySearchQuery =\n url.searchParams.get('q') ?? url.searchParams.get('search');\n\n const restorationState: RestorationState = {\n selectedFacets: getDefaultSelectedFacets(),\n };\n\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n } else if (legacySearchQuery) {\n restorationState.baseQuery = legacySearchQuery;\n }\n\n switch (searchInside) {\n case 'TXT':\n restorationState.searchType = SearchType.FULLTEXT;\n break;\n case 'RADIO':\n restorationState.searchType = SearchType.RADIO;\n break;\n case 'TV':\n restorationState.searchType = SearchType.TV;\n break;\n case 'MD':\n restorationState.searchType = SearchType.METADATA;\n break;\n default:\n restorationState.searchType = SearchType.DEFAULT;\n break;\n }\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n\n if (sortQuery) {\n const { field, direction } = this.getSortFieldAndDirection(sortQuery);\n\n const sortOption = sortOptionFromAPIString(field);\n restorationState.selectedSort = sortOption.field;\n\n if (['asc', 'desc'].includes(direction)) {\n restorationState.sortDirection = direction as SortDirection;\n }\n }\n\n if (facetAnds) {\n facetAnds.forEach(and => {\n // eslint-disable-next-line prefer-const\n let [field, value] = and.split(':');\n\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\n field = field.replace(/Sorter$/, '');\n\n // Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`\n // which we want to normalize to a not[] param instead\n if (field.startsWith('-')) {\n facetNots.push(and.slice(1));\n return;\n }\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length,\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1,\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n });\n }\n\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden',\n );\n });\n }\n\n return restorationState;\n }\n\n /**\n * Converts a URL sort param into a field/direction pair, if possible.\n * Either or both may be undefined if the param is not in a recognized format.\n */\n private getSortFieldAndDirection(sortParam: string) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortParam.indexOf(' ') > -1;\n let field;\n let direction;\n if (hasSpace) {\n [field, direction] = sortParam.split(' ');\n } else {\n field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;\n direction = sortParam.startsWith('-') ? 'desc' : 'asc';\n }\n\n return { field, direction };\n }\n\n /** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */\n private sortDirectionPrefix(sortDirection?: string) {\n return sortDirection === 'desc' ? '-' : '';\n }\n\n /** Remove optional opening and closing quotes from a string */\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n\n return value;\n }\n\n /**\n * Returns whether the two given URLSearchParams objects have\n * identical values for all of the given param keys. If either\n * object contains more than one value for a given key, then\n * all of the values for that key must match (disregarding order).\n */\n private paramsMatch(\n searchParams1: URLSearchParams,\n searchParams2: URLSearchParams,\n keys: string[],\n ): boolean {\n return keys.every(key =>\n arrayEquals(\n searchParams1.getAll(key).sort(),\n searchParams2.getAll(key).sort(),\n ),\n );\n }\n\n /**\n * Deletes any params from the given URLSearchParams object that are recognized\n * when loading state from the URL.\n */\n private removeRecognizedParams(\n searchParams: URLSearchParams,\n ): URLSearchParams {\n // Remove all of our standard params\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n // Remove any and/not facet params that contain numbers in their square brackets\n for (const key of searchParams.keys()) {\n if (/(and|not)\\[\\d+\\]/.test(key)) {\n searchParams.delete(key);\n }\n }\n\n // Also remove some legacy params that should have been upgraded to the ones above\n searchParams.delete('q');\n searchParams.delete('search');\n\n return searchParams;\n }\n\n /**\n * Returns whether the given URLSearchParams object contains a param that is\n * only recognized as a holdover from legacy search, and should not be\n * persisted to the URL.\n */\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\n return searchParams.has('q') || searchParams.has('search');\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState,\n ): void {\n const facet = selectedFacets[field];\n if (!facet) return; // Unrecognized facet group, ignore it.\n\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
@@ -41,7 +41,6 @@ export function forEachFacetBucket(selectedFacets, fn) {
41
41
  * the `'none'` state in place.
42
42
  */
43
43
  export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omitNoneState = false) {
44
- var _a;
45
44
  const defaultedSelectedFacets = selectedFacets !== null && selectedFacets !== void 0 ? selectedFacets : getDefaultSelectedFacets();
46
45
  const newFacets = {
47
46
  ...defaultedSelectedFacets,
@@ -51,7 +50,7 @@ export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omi
51
50
  },
52
51
  };
53
52
  if (omitNoneState && bucket.state === 'none') {
54
- (_a = newFacets[facetType]) === null || _a === void 0 ? true : delete _a[bucket.key];
53
+ delete newFacets[facetType][bucket.key];
55
54
  }
56
55
  return newFacets;
57
56
  }
@@ -69,8 +68,6 @@ export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omi
69
68
  export function cloneSelectedFacets(selectedFacets) {
70
69
  const cloneResult = getDefaultSelectedFacets();
71
70
  forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {
72
- if (!cloneResult[facetType])
73
- cloneResult[facetType] = {};
74
71
  cloneResult[facetType][bucketKey] = bucket;
75
72
  });
76
73
  return cloneResult;
@@ -98,15 +95,12 @@ export function cloneSelectedFacets(selectedFacets) {
98
95
  export function mergeSelectedFacets(destination, source) {
99
96
  const mergeResult = cloneSelectedFacets(destination);
100
97
  forEachFacetBucket(source, (facetType, bucketKey, bucket) => {
101
- if (!mergeResult[facetType])
102
- mergeResult[facetType] = {};
103
98
  mergeResult[facetType][bucketKey] = bucket;
104
99
  });
105
100
  // Normalize any 'none' states on the result (from either source or destination)
106
101
  forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {
107
- var _a;
108
102
  if (bucket.state === 'none') {
109
- (_a = mergeResult[facetType]) === null || _a === void 0 ? true : delete _a[bucketKey];
103
+ delete mergeResult[facetType][bucketKey];
110
104
  }
111
105
  });
112
106
  return mergeResult;
@@ -1 +1 @@
1
- {"version":3,"file":"facet-utils.js","sourceRoot":"","sources":["../../../src/utils/facet-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AggregationSortType } from '@internetarchive/search-service';\nimport {\n FacetOption,\n getDefaultSelectedFacets,\n type FacetBucket,\n type SelectedFacets,\n} from '../models';\n\n// This file contains several helper functions designed to make working immutably\n// with SelectedFacet objects and FacetGroups cleaner & easier.\n\n/**\n * Calls the given function for each FacetBucket specified in the given SelectedFacets\n * object. The function is always called with the facet type, bucket key, bucket object,\n * and the given SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object whose buckets should be iterated over\n * @param fn The function to apply to each facet bucket.\n *\n * @example\n * forEachFacetBucket(\n * myFacets,\n * (facetType, bucketKey, bucket) => {\n * if (facetType === 'collection' && bucket.state === 'hidden') {\n * console.log(`Excluding any results in the ${bucketKey} collection`);\n * }\n * }\n * );\n */\nexport function forEachFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n fn: (\n facetType: FacetOption,\n bucketKey: string,\n bucket: FacetBucket,\n selectedFacets: SelectedFacets,\n ) => unknown,\n): void {\n if (!selectedFacets) return;\n for (const [facetType, facetBuckets] of Object.entries(selectedFacets)) {\n for (const [bucketKey, bucket] of Object.entries(facetBuckets)) {\n fn(facetType as FacetOption, bucketKey, bucket, selectedFacets);\n }\n }\n}\n\n/**\n * Returns a new SelectedFacets object having only the specified bucket changed to\n * reflect its new provided value. The bucket key is determined from the provided\n * `bucket` itself.\n * @param selectedFacets The SelectedFacets object to produce an updated clone of\n * @param facetType The type of facet to be modified (e.g., 'mediatype', 'subject', ...)\n * @param bucket The new bucket that should be present on the result\n * @param omitNoneState If set to true, the returned object will omit the given\n * bucket entirely if it is updated to state `'none'`. Default is false, which leaves\n * the `'none'` state in place.\n */\nexport function updateSelectedFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n facetType: FacetOption,\n bucket: FacetBucket,\n omitNoneState = false,\n): SelectedFacets {\n const defaultedSelectedFacets = selectedFacets ?? getDefaultSelectedFacets();\n const newFacets: SelectedFacets = {\n ...defaultedSelectedFacets,\n [facetType]: {\n ...defaultedSelectedFacets[facetType],\n [bucket.key]: bucket,\n },\n };\n\n if (omitNoneState && bucket.state === 'none') {\n delete newFacets[facetType]?.[bucket.key];\n }\n\n return newFacets;\n}\n\n/**\n * Creates a clone of the given SelectedFacets object.\n *\n * Note that the underlying FacetBucket objects are not deep-cloned -- they will\n * be references to the same objects as in the input. However, the objects\n * containing the FacetBuckets for each FacetOption are created anew.\n *\n * If the provided argument is undefined, returns an empty SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object to be cloned\n */\nexport function cloneSelectedFacets(\n selectedFacets: SelectedFacets | undefined,\n): SelectedFacets {\n const cloneResult = getDefaultSelectedFacets();\n forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {\n if (!cloneResult[facetType]) cloneResult[facetType] = {};\n cloneResult[facetType][bucketKey] = bucket;\n });\n return cloneResult;\n}\n\n/**\n * Creates a new SelectedFacets object representing a merge of the `source` facets object\n * into the `destination` facets object. Any facets existing in `source` take precedence\n * over those in `destination` in the event of conflicts.\n *\n * The resulting SelectedFacets object is normalized to omit any facet buckets whose\n * state is `'none'` in the merged result. Consequently, any facets buckets with state\n * `'none'` in `source` will always be absent from the end result. Likewise, any facet\n * buckets with state `'none'` in `destination` will be absent _unless_ they are also\n * present in `source` with a state of `'selected'` or `'hidden'` (in which case `source`\n * takes precedence as usual).\n *\n * @param source The source of the new facets to merge in. Any facet buckets existing in\n * this `source` object will take precedence over those in `destination` having the same\n * key, if they exist in both. Any facet buckets that are _not_ present in `source` will\n * remain unmodified from their state in `destination`, if they are present there at all.\n * @param destination The destination onto which facets should be merged. Note that this\n * object is _not_ re-used for the return value, but it is conceptually the \"existing base\"\n * onto which the source facets are merged.\n */\nexport function mergeSelectedFacets(\n destination: SelectedFacets | undefined,\n source: SelectedFacets | undefined,\n): SelectedFacets {\n const mergeResult = cloneSelectedFacets(destination);\n forEachFacetBucket(source, (facetType, bucketKey, bucket) => {\n if (!mergeResult[facetType]) mergeResult[facetType] = {};\n mergeResult[facetType][bucketKey] = bucket;\n });\n\n // Normalize any 'none' states on the result (from either source or destination)\n forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {\n if (bucket.state === 'none') {\n delete mergeResult[facetType]?.[bucketKey];\n }\n });\n\n return mergeResult;\n}\n\n/**\n * Defines the order of states in which to display SelectedFacets buckets\n */\nconst BUCKET_STATE_ORDER = ['selected', 'hidden', 'none'];\n\n/**\n * Sorts the provided FacetBuckets so that:\n * - Any selected items come first\n * - Any hidden items come after all the selected items\n * - Any unselected / unhidden items come last\n *\n * Within each of the above groups, the buckets will be sorted according to\n * the provided sort type, or by their bucket count by default.\n *\n * The sort is performed in-place using `Array.sort`, so the return value is\n * a reference to the same array that was passed in, only sorted.\n *\n * @param buckets The array of facet buckets to sort\n * @param sort (Optional) How buckets within each state group should be sorted.\n * Defaults to `AggregationSortType.COUNT` (i.e., descending by bucket count).\n */\nexport function sortBucketsBySelectionState(\n buckets: FacetBucket[],\n sort = AggregationSortType.COUNT,\n) {\n return buckets.sort((a, b) => {\n const aStateIndex = BUCKET_STATE_ORDER.indexOf(a.state);\n const bStateIndex = BUCKET_STATE_ORDER.indexOf(b.state);\n const stateDiff = aStateIndex - bStateIndex; // Sort bucket states primarily in the order defined by BUCKET_STATE_ORDER\n\n let secondaryDiff;\n if (sort === AggregationSortType.ALPHABETICAL) {\n secondaryDiff = a.key.localeCompare(b.key); // Ascending alphabetically by bucket key\n } else if (sort === AggregationSortType.NUMERIC) {\n secondaryDiff = Number(b.key) - Number(a.key); // Descending numerically by bucket key\n } else {\n secondaryDiff = b.count - a.count; // Descending by bucket count\n }\n\n return stateDiff || secondaryDiff; // Primary sort on state, secondary sort on the given sort type (defaulting to descending count)\n });\n}\n"]}
1
+ {"version":3,"file":"facet-utils.js","sourceRoot":"","sources":["../../../src/utils/facet-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AggregationSortType } from '@internetarchive/search-service';\nimport {\n FacetOption,\n getDefaultSelectedFacets,\n type FacetBucket,\n type SelectedFacets,\n} from '../models';\n\n// This file contains several helper functions designed to make working immutably\n// with SelectedFacet objects and FacetGroups cleaner & easier.\n\n/**\n * Calls the given function for each FacetBucket specified in the given SelectedFacets\n * object. The function is always called with the facet type, bucket key, bucket object,\n * and the given SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object whose buckets should be iterated over\n * @param fn The function to apply to each facet bucket.\n *\n * @example\n * forEachFacetBucket(\n * myFacets,\n * (facetType, bucketKey, bucket) => {\n * if (facetType === 'collection' && bucket.state === 'hidden') {\n * console.log(`Excluding any results in the ${bucketKey} collection`);\n * }\n * }\n * );\n */\nexport function forEachFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n fn: (\n facetType: FacetOption,\n bucketKey: string,\n bucket: FacetBucket,\n selectedFacets: SelectedFacets,\n ) => unknown,\n): void {\n if (!selectedFacets) return;\n for (const [facetType, facetBuckets] of Object.entries(selectedFacets)) {\n for (const [bucketKey, bucket] of Object.entries(facetBuckets)) {\n fn(facetType as FacetOption, bucketKey, bucket, selectedFacets);\n }\n }\n}\n\n/**\n * Returns a new SelectedFacets object having only the specified bucket changed to\n * reflect its new provided value. The bucket key is determined from the provided\n * `bucket` itself.\n * @param selectedFacets The SelectedFacets object to produce an updated clone of\n * @param facetType The type of facet to be modified (e.g., 'mediatype', 'subject', ...)\n * @param bucket The new bucket that should be present on the result\n * @param omitNoneState If set to true, the returned object will omit the given\n * bucket entirely if it is updated to state `'none'`. Default is false, which leaves\n * the `'none'` state in place.\n */\nexport function updateSelectedFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n facetType: FacetOption,\n bucket: FacetBucket,\n omitNoneState = false,\n): SelectedFacets {\n const defaultedSelectedFacets = selectedFacets ?? getDefaultSelectedFacets();\n const newFacets = {\n ...defaultedSelectedFacets,\n [facetType]: {\n ...defaultedSelectedFacets[facetType],\n [bucket.key]: bucket,\n },\n };\n\n if (omitNoneState && bucket.state === 'none') {\n delete newFacets[facetType][bucket.key];\n }\n\n return newFacets;\n}\n\n/**\n * Creates a clone of the given SelectedFacets object.\n *\n * Note that the underlying FacetBucket objects are not deep-cloned -- they will\n * be references to the same objects as in the input. However, the objects\n * containing the FacetBuckets for each FacetOption are created anew.\n *\n * If the provided argument is undefined, returns an empty SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object to be cloned\n */\nexport function cloneSelectedFacets(\n selectedFacets: SelectedFacets | undefined,\n): SelectedFacets {\n const cloneResult = getDefaultSelectedFacets();\n forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {\n cloneResult[facetType][bucketKey] = bucket;\n });\n return cloneResult;\n}\n\n/**\n * Creates a new SelectedFacets object representing a merge of the `source` facets object\n * into the `destination` facets object. Any facets existing in `source` take precedence\n * over those in `destination` in the event of conflicts.\n *\n * The resulting SelectedFacets object is normalized to omit any facet buckets whose\n * state is `'none'` in the merged result. Consequently, any facets buckets with state\n * `'none'` in `source` will always be absent from the end result. Likewise, any facet\n * buckets with state `'none'` in `destination` will be absent _unless_ they are also\n * present in `source` with a state of `'selected'` or `'hidden'` (in which case `source`\n * takes precedence as usual).\n *\n * @param source The source of the new facets to merge in. Any facet buckets existing in\n * this `source` object will take precedence over those in `destination` having the same\n * key, if they exist in both. Any facet buckets that are _not_ present in `source` will\n * remain unmodified from their state in `destination`, if they are present there at all.\n * @param destination The destination onto which facets should be merged. Note that this\n * object is _not_ re-used for the return value, but it is conceptually the \"existing base\"\n * onto which the source facets are merged.\n */\nexport function mergeSelectedFacets(\n destination: SelectedFacets | undefined,\n source: SelectedFacets | undefined,\n): SelectedFacets {\n const mergeResult = cloneSelectedFacets(destination);\n forEachFacetBucket(source, (facetType, bucketKey, bucket) => {\n mergeResult[facetType][bucketKey] = bucket;\n });\n\n // Normalize any 'none' states on the result (from either source or destination)\n forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {\n if (bucket.state === 'none') {\n delete mergeResult[facetType][bucketKey];\n }\n });\n\n return mergeResult;\n}\n\n/**\n * Defines the order of states in which to display SelectedFacets buckets\n */\nconst BUCKET_STATE_ORDER = ['selected', 'hidden', 'none'];\n\n/**\n * Sorts the provided FacetBuckets so that:\n * - Any selected items come first\n * - Any hidden items come after all the selected items\n * - Any unselected / unhidden items come last\n *\n * Within each of the above groups, the buckets will be sorted according to\n * the provided sort type, or by their bucket count by default.\n *\n * The sort is performed in-place using `Array.sort`, so the return value is\n * a reference to the same array that was passed in, only sorted.\n *\n * @param buckets The array of facet buckets to sort\n * @param sort (Optional) How buckets within each state group should be sorted.\n * Defaults to `AggregationSortType.COUNT` (i.e., descending by bucket count).\n */\nexport function sortBucketsBySelectionState(\n buckets: FacetBucket[],\n sort = AggregationSortType.COUNT,\n) {\n return buckets.sort((a, b) => {\n const aStateIndex = BUCKET_STATE_ORDER.indexOf(a.state);\n const bStateIndex = BUCKET_STATE_ORDER.indexOf(b.state);\n const stateDiff = aStateIndex - bStateIndex; // Sort bucket states primarily in the order defined by BUCKET_STATE_ORDER\n\n let secondaryDiff;\n if (sort === AggregationSortType.ALPHABETICAL) {\n secondaryDiff = a.key.localeCompare(b.key); // Ascending alphabetically by bucket key\n } else if (sort === AggregationSortType.NUMERIC) {\n secondaryDiff = Number(b.key) - Number(a.key); // Descending numerically by bucket key\n } else {\n secondaryDiff = b.count - a.count; // Descending by bucket count\n }\n\n return stateDiff || secondaryDiff; // Primary sort on state, secondary sort on the given sort type (defaulting to descending count)\n });\n}\n"]}
@@ -11,6 +11,6 @@ export function localDateFromUTC(date) {
11
11
  export function isFirstMillisecondOfUTCYear(date) {
12
12
  if (!date)
13
13
  return false;
14
- return localDateFromUTC(date).toISOString().endsWith('-01-01T00:00:00.000Z');
14
+ return date.toISOString().endsWith('-01-01T00:00:00.000Z');
15
15
  }
16
16
  //# sourceMappingURL=local-date-from-utc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-date-from-utc.js","sourceRoot":"","sources":["../../../src/utils/local-date-from-utc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAW;IACrD,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["/**\n * Converts a given UTC date into the equivalent local-timestamp one.\n */\nexport function localDateFromUTC(date: Date): Date {\n return new Date(date.getTime() - date.getTimezoneOffset() * 1000 * 60);\n}\n\n/**\n * Returns whether a given UTC date corresponds to the first\n * millisecond of the year (e.g., Jan 1 at exactly midnight).\n */\nexport function isFirstMillisecondOfUTCYear(date?: Date): boolean {\n if (!date) return false;\n return localDateFromUTC(date).toISOString().endsWith('-01-01T00:00:00.000Z');\n}\n"]}
1
+ {"version":3,"file":"local-date-from-utc.js","sourceRoot":"","sources":["../../../src/utils/local-date-from-utc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAW;IACrD,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["/**\n * Converts a given UTC date into the equivalent local-timestamp one.\n */\nexport function localDateFromUTC(date: Date): Date {\n return new Date(date.getTime() - date.getTimezoneOffset() * 1000 * 60);\n}\n\n/**\n * Returns whether a given UTC date corresponds to the first\n * millisecond of the year (e.g., Jan 1 at exactly midnight).\n */\nexport function isFirstMillisecondOfUTCYear(date?: Date): boolean {\n if (!date) return false;\n return date.toISOString().endsWith('-01-01T00:00:00.000Z');\n}\n"]}
@@ -503,33 +503,6 @@ describe('Collection Facets', () => {
503
503
  expect(facetRows === null || facetRows === void 0 ? void 0 : facetRows.length).to.equal(8);
504
504
  expect((_d = (_c = facetRows === null || facetRows === void 0 ? void 0 : facetRows[7]) === null || _c === void 0 ? void 0 : _c.bucket) === null || _d === void 0 ? void 0 : _d.key).to.equal('collection');
505
505
  });
506
- it('uses specified facet display order', async () => {
507
- var _a;
508
- const el = await fixture(html `<collection-facets
509
- .facetDisplayOrder=${['language', 'creator']}
510
- ></collection-facets>`);
511
- const aggs = {
512
- mediatype: new Aggregation({
513
- buckets: [{ key: 'texts', doc_count: 5 }],
514
- }),
515
- collection: new Aggregation({
516
- buckets: [{ key: 'foo', doc_count: 10 }],
517
- }),
518
- creator: new Aggregation({
519
- buckets: [{ key: 'bar', doc_count: 15 }],
520
- }),
521
- language: new Aggregation({
522
- buckets: [{ key: 'baz', doc_count: 20 }],
523
- }),
524
- };
525
- el.aggregations = aggs;
526
- await el.updateComplete;
527
- const facetHeaders = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.facet-group-header');
528
- // The only two facet groups should be Language and Creator (in that order)
529
- expect(facetHeaders === null || facetHeaders === void 0 ? void 0 : facetHeaders.length).to.equal(2);
530
- expect(facetHeaders === null || facetHeaders === void 0 ? void 0 : facetHeaders[0].textContent).to.contain('Language');
531
- expect(facetHeaders === null || facetHeaders === void 0 ? void 0 : facetHeaders[1].textContent).to.contain('Creator');
532
- });
533
506
  describe('More Facets', () => {
534
507
  it('Does not render < allowedFacetCount', async () => {
535
508
  var _a;