@internetarchive/collection-browser 0.4.2 → 0.4.3-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/.editorconfig +29 -29
  2. package/.github/workflows/ci.yml +26 -26
  3. package/.github/workflows/gh-pages-main.yml +39 -39
  4. package/.github/workflows/npm-publish.yml +39 -39
  5. package/.github/workflows/pr-preview.yml +38 -38
  6. package/.husky/pre-commit +4 -4
  7. package/LICENSE +661 -661
  8. package/README.md +83 -83
  9. package/dist/index.d.ts +9 -9
  10. package/dist/index.js +9 -9
  11. package/dist/src/app-root.d.ts +48 -48
  12. package/dist/src/app-root.js +258 -258
  13. package/dist/src/assets/img/icons/arrow-left.d.ts +2 -2
  14. package/dist/src/assets/img/icons/arrow-left.js +2 -2
  15. package/dist/src/assets/img/icons/arrow-right.d.ts +2 -2
  16. package/dist/src/assets/img/icons/arrow-right.js +2 -2
  17. package/dist/src/assets/img/icons/chevron.d.ts +2 -2
  18. package/dist/src/assets/img/icons/chevron.js +2 -2
  19. package/dist/src/assets/img/icons/empty-query.d.ts +2 -2
  20. package/dist/src/assets/img/icons/empty-query.js +2 -2
  21. package/dist/src/assets/img/icons/eye-closed.d.ts +2 -2
  22. package/dist/src/assets/img/icons/eye-closed.js +2 -2
  23. package/dist/src/assets/img/icons/eye.d.ts +2 -2
  24. package/dist/src/assets/img/icons/eye.js +2 -2
  25. package/dist/src/assets/img/icons/favorite-filled.d.ts +1 -1
  26. package/dist/src/assets/img/icons/favorite-filled.js +2 -2
  27. package/dist/src/assets/img/icons/login-required.d.ts +1 -1
  28. package/dist/src/assets/img/icons/login-required.js +2 -2
  29. package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -1
  30. package/dist/src/assets/img/icons/mediatype/account.js +2 -2
  31. package/dist/src/assets/img/icons/mediatype/audio.d.ts +1 -1
  32. package/dist/src/assets/img/icons/mediatype/audio.js +2 -2
  33. package/dist/src/assets/img/icons/mediatype/collection.d.ts +1 -1
  34. package/dist/src/assets/img/icons/mediatype/collection.js +2 -2
  35. package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -1
  36. package/dist/src/assets/img/icons/mediatype/data.js +2 -2
  37. package/dist/src/assets/img/icons/mediatype/etree.d.ts +1 -1
  38. package/dist/src/assets/img/icons/mediatype/etree.js +2 -2
  39. package/dist/src/assets/img/icons/mediatype/film.d.ts +1 -1
  40. package/dist/src/assets/img/icons/mediatype/film.js +2 -2
  41. package/dist/src/assets/img/icons/mediatype/images.d.ts +1 -1
  42. package/dist/src/assets/img/icons/mediatype/images.js +2 -2
  43. package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -1
  44. package/dist/src/assets/img/icons/mediatype/radio.js +2 -2
  45. package/dist/src/assets/img/icons/mediatype/software.d.ts +1 -1
  46. package/dist/src/assets/img/icons/mediatype/software.js +2 -2
  47. package/dist/src/assets/img/icons/mediatype/texts.d.ts +1 -1
  48. package/dist/src/assets/img/icons/mediatype/texts.js +2 -2
  49. package/dist/src/assets/img/icons/mediatype/tv.d.ts +1 -1
  50. package/dist/src/assets/img/icons/mediatype/tv.js +2 -2
  51. package/dist/src/assets/img/icons/mediatype/video.d.ts +1 -1
  52. package/dist/src/assets/img/icons/mediatype/video.js +2 -2
  53. package/dist/src/assets/img/icons/mediatype/web.d.ts +1 -1
  54. package/dist/src/assets/img/icons/mediatype/web.js +2 -2
  55. package/dist/src/assets/img/icons/null-result.d.ts +2 -2
  56. package/dist/src/assets/img/icons/null-result.js +2 -2
  57. package/dist/src/assets/img/icons/restricted.d.ts +1 -1
  58. package/dist/src/assets/img/icons/restricted.js +2 -2
  59. package/dist/src/assets/img/icons/reviews.d.ts +1 -1
  60. package/dist/src/assets/img/icons/reviews.js +2 -2
  61. package/dist/src/assets/img/icons/upload.d.ts +1 -1
  62. package/dist/src/assets/img/icons/upload.js +2 -2
  63. package/dist/src/assets/img/icons/views.d.ts +1 -1
  64. package/dist/src/assets/img/icons/views.js +2 -2
  65. package/dist/src/circular-activity-indicator.d.ts +5 -5
  66. package/dist/src/circular-activity-indicator.js +17 -17
  67. package/dist/src/collection-browser.d.ts +315 -315
  68. package/dist/src/collection-browser.js +1278 -1270
  69. package/dist/src/collection-browser.js.map +1 -1
  70. package/dist/src/collection-facets/facet-tombstone-row.d.ts +5 -5
  71. package/dist/src/collection-facets/facet-tombstone-row.js +15 -15
  72. package/dist/src/collection-facets/facets-template.d.ts +16 -16
  73. package/dist/src/collection-facets/facets-template.js +125 -125
  74. package/dist/src/collection-facets/more-facets-content.d.ts +77 -77
  75. package/dist/src/collection-facets/more-facets-content.js +357 -357
  76. package/dist/src/collection-facets/more-facets-pagination.d.ts +36 -36
  77. package/dist/src/collection-facets/more-facets-pagination.js +192 -192
  78. package/dist/src/collection-facets.d.ts +78 -78
  79. package/dist/src/collection-facets.js +391 -391
  80. package/dist/src/empty-placeholder.d.ts +11 -11
  81. package/dist/src/empty-placeholder.js +42 -42
  82. package/dist/src/language-code-handler/language-code-handler.d.ts +37 -37
  83. package/dist/src/language-code-handler/language-code-handler.js +26 -26
  84. package/dist/src/language-code-handler/language-code-mapping.d.ts +1 -1
  85. package/dist/src/language-code-handler/language-code-mapping.js +562 -562
  86. package/dist/src/mediatype/mediatype-config.d.ts +3 -3
  87. package/dist/src/mediatype/mediatype-config.js +85 -85
  88. package/dist/src/models.d.ts +112 -112
  89. package/dist/src/models.js +125 -125
  90. package/dist/src/restoration-state-handler.d.ts +46 -45
  91. package/dist/src/restoration-state-handler.js +268 -230
  92. package/dist/src/restoration-state-handler.js.map +1 -1
  93. package/dist/src/sort-filter-bar/alpha-bar.d.ts +12 -12
  94. package/dist/src/sort-filter-bar/alpha-bar.js +52 -52
  95. package/dist/src/sort-filter-bar/img/compact.d.ts +1 -1
  96. package/dist/src/sort-filter-bar/img/compact.js +2 -2
  97. package/dist/src/sort-filter-bar/img/list.d.ts +1 -1
  98. package/dist/src/sort-filter-bar/img/list.js +2 -2
  99. package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -1
  100. package/dist/src/sort-filter-bar/img/sort-triangle.js +2 -2
  101. package/dist/src/sort-filter-bar/img/tile.d.ts +1 -1
  102. package/dist/src/sort-filter-bar/img/tile.js +2 -2
  103. package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +108 -108
  104. package/dist/src/sort-filter-bar/sort-filter-bar.js +429 -428
  105. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  106. package/dist/src/styles/item-image-styles.d.ts +8 -8
  107. package/dist/src/styles/item-image-styles.js +9 -9
  108. package/dist/src/tiles/collection-browser-loading-tile.d.ts +5 -5
  109. package/dist/src/tiles/collection-browser-loading-tile.js +15 -15
  110. package/dist/src/tiles/grid/account-tile.d.ts +8 -8
  111. package/dist/src/tiles/grid/account-tile.js +20 -20
  112. package/dist/src/tiles/grid/collection-tile.d.ts +7 -7
  113. package/dist/src/tiles/grid/collection-tile.js +23 -23
  114. package/dist/src/tiles/grid/item-tile.d.ts +24 -24
  115. package/dist/src/tiles/grid/item-tile.js +87 -87
  116. package/dist/src/tiles/grid/tile-stats.d.ts +10 -10
  117. package/dist/src/tiles/grid/tile-stats.js +40 -40
  118. package/dist/src/tiles/image-block.d.ts +17 -17
  119. package/dist/src/tiles/image-block.js +69 -69
  120. package/dist/src/tiles/item-image.d.ts +31 -31
  121. package/dist/src/tiles/item-image.js +106 -106
  122. package/dist/src/tiles/list/account-label.d.ts +1 -1
  123. package/dist/src/tiles/list/account-label.js +6 -6
  124. package/dist/src/tiles/list/date-label.d.ts +1 -1
  125. package/dist/src/tiles/list/date-label.js +12 -12
  126. package/dist/src/tiles/list/tile-list-compact-header.d.ts +12 -12
  127. package/dist/src/tiles/list/tile-list-compact-header.js +41 -41
  128. package/dist/src/tiles/list/tile-list-compact.d.ts +21 -21
  129. package/dist/src/tiles/list/tile-list-compact.js +93 -93
  130. package/dist/src/tiles/list/tile-list.d.ts +50 -50
  131. package/dist/src/tiles/list/tile-list.js +276 -276
  132. package/dist/src/tiles/mediatype-icon.d.ts +9 -9
  133. package/dist/src/tiles/mediatype-icon.js +47 -47
  134. package/dist/src/tiles/overlay/icon-overlay.d.ts +10 -10
  135. package/dist/src/tiles/overlay/icon-overlay.js +40 -40
  136. package/dist/src/tiles/overlay/icon-text-overlay.d.ts +9 -9
  137. package/dist/src/tiles/overlay/icon-text-overlay.js +38 -38
  138. package/dist/src/tiles/overlay/text-overlay.d.ts +10 -10
  139. package/dist/src/tiles/overlay/text-overlay.js +42 -42
  140. package/dist/src/tiles/text-snippet-block.d.ts +29 -29
  141. package/dist/src/tiles/text-snippet-block.js +81 -81
  142. package/dist/src/tiles/tile-dispatcher.d.ts +36 -36
  143. package/dist/src/tiles/tile-dispatcher.js +128 -128
  144. package/dist/src/utils/analytics-events.d.ts +22 -22
  145. package/dist/src/utils/analytics-events.js +24 -24
  146. package/dist/src/utils/array-equals.d.ts +4 -0
  147. package/dist/src/utils/array-equals.js +11 -0
  148. package/dist/src/utils/array-equals.js.map +1 -0
  149. package/dist/src/utils/format-count.d.ts +7 -7
  150. package/dist/src/utils/format-count.js +76 -76
  151. package/dist/src/utils/format-date.d.ts +2 -2
  152. package/dist/src/utils/format-date.js +23 -23
  153. package/dist/test/collection-browser.test.d.ts +1 -1
  154. package/dist/test/collection-browser.test.js +646 -646
  155. package/dist/test/collection-browser.test.js.map +1 -1
  156. package/dist/test/collection-facets/facets-template.test.d.ts +1 -1
  157. package/dist/test/collection-facets/facets-template.test.js +62 -62
  158. package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -1
  159. package/dist/test/collection-facets/more-facets-content.test.js +114 -114
  160. package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -1
  161. package/dist/test/collection-facets/more-facets-pagination.test.js +117 -117
  162. package/dist/test/collection-facets.test.d.ts +2 -2
  163. package/dist/test/collection-facets.test.js +544 -544
  164. package/dist/test/empty-placeholder.test.d.ts +1 -1
  165. package/dist/test/empty-placeholder.test.js +33 -33
  166. package/dist/test/icon-overlay.test.d.ts +1 -1
  167. package/dist/test/icon-overlay.test.js +24 -24
  168. package/dist/test/image-block.test.d.ts +1 -1
  169. package/dist/test/image-block.test.js +48 -48
  170. package/dist/test/item-image.test.d.ts +1 -1
  171. package/dist/test/item-image.test.js +80 -80
  172. package/dist/test/mediatype-config.test.d.ts +1 -1
  173. package/dist/test/mediatype-config.test.js +16 -16
  174. package/dist/test/mocks/mock-analytics-handler.d.ts +10 -10
  175. package/dist/test/mocks/mock-analytics-handler.js +15 -15
  176. package/dist/test/mocks/mock-collection-name-cache.d.ts +7 -7
  177. package/dist/test/mocks/mock-collection-name-cache.js +13 -13
  178. package/dist/test/mocks/mock-search-responses.d.ts +12 -12
  179. package/dist/test/mocks/mock-search-responses.js +341 -341
  180. package/dist/test/mocks/mock-search-service.d.ts +13 -13
  181. package/dist/test/mocks/mock-search-service.js +40 -40
  182. package/dist/test/restoration-state-handler.test.d.ts +1 -1
  183. package/dist/test/restoration-state-handler.test.js +125 -125
  184. package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +1 -1
  185. package/dist/test/sort-filter-bar/alpha-bar.test.js +43 -43
  186. package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +1 -1
  187. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +141 -141
  188. package/dist/test/text-overlay.test.d.ts +1 -1
  189. package/dist/test/text-overlay.test.js +48 -48
  190. package/dist/test/text-snippet-block.test.d.ts +1 -1
  191. package/dist/test/text-snippet-block.test.js +57 -57
  192. package/dist/test/tile-stats.test.d.ts +1 -1
  193. package/dist/test/tile-stats.test.js +33 -33
  194. package/dist/test/tiles/grid/item-tile.test.d.ts +1 -1
  195. package/dist/test/tiles/grid/item-tile.test.js +107 -107
  196. package/dist/test/tiles/list/tile-list-compact.test.d.ts +1 -1
  197. package/dist/test/tiles/list/tile-list-compact.test.js +92 -92
  198. package/dist/test/tiles/list/tile-list.test.d.ts +1 -1
  199. package/dist/test/tiles/list/tile-list.test.js +123 -123
  200. package/dist/test/utils/array-equals.test.d.ts +1 -0
  201. package/dist/test/utils/array-equals.test.js +27 -0
  202. package/dist/test/utils/array-equals.test.js.map +1 -0
  203. package/dist/test/utils/format-count.test.d.ts +1 -1
  204. package/dist/test/utils/format-count.test.js +23 -23
  205. package/dist/test/utils/format-date.test.d.ts +1 -1
  206. package/dist/test/utils/format-date.test.js +17 -17
  207. package/index.html +24 -24
  208. package/local.archive.org.cert +86 -86
  209. package/local.archive.org.key +27 -27
  210. package/package.json +1 -1
  211. package/renovate.json +6 -6
  212. package/src/collection-browser.ts +60 -28
  213. package/src/restoration-state-handler.ts +68 -14
  214. package/src/sort-filter-bar/sort-filter-bar.ts +1 -0
  215. package/src/utils/array-equals.ts +8 -0
  216. package/test/collection-browser.test.ts +7 -7
  217. package/test/utils/array-equals.test.ts +31 -0
  218. package/tsconfig.json +21 -21
  219. package/web-dev-server.config.mjs +30 -30
  220. package/web-test-runner.config.mjs +41 -41
@@ -1,86 +1,86 @@
1
- Certificate:
2
- Data:
3
- Version: 3 (0x2)
4
- Serial Number: 1 (0x1)
5
- Signature Algorithm: sha256WithRSAEncryption
6
- Issuer: CN=devcert
7
- Validity
8
- Not Before: Apr 27 16:27:46 2022 GMT
9
- Not After : Jul 30 16:27:46 2024 GMT
10
- Subject: CN=local.archive.org
11
- Subject Public Key Info:
12
- Public Key Algorithm: rsaEncryption
13
- Public-Key: (2048 bit)
14
- Modulus:
15
- 00:a9:54:ca:34:ff:8b:32:02:39:97:61:bd:f5:12:
16
- 5c:4a:d0:87:2e:d6:42:63:72:ea:b4:90:95:cc:4a:
17
- ef:5a:66:09:9f:1d:08:0d:b2:f4:2e:b3:55:59:9c:
18
- 0f:77:37:1e:d7:a3:5c:b7:3d:81:84:fc:55:af:20:
19
- e7:3c:bd:9e:2b:2b:9e:d1:95:9d:14:90:70:7c:99:
20
- 78:f1:dd:42:2b:fd:87:b9:09:f0:f6:50:c7:90:41:
21
- de:e2:ee:dd:a0:4a:4d:de:20:6a:e8:1b:81:7f:d9:
22
- 17:0d:f5:f2:a1:dc:89:d8:e9:89:9c:ff:40:b7:0e:
23
- bb:16:db:d1:e0:67:5f:24:de:3b:b8:18:b8:a6:dd:
24
- d5:26:8a:2a:a4:f2:03:b1:a8:15:23:31:c9:65:de:
25
- 9b:5a:b0:f0:4f:ef:77:f1:8b:7b:91:95:a0:61:be:
26
- 1f:64:29:c6:2e:2c:03:1b:f0:91:96:b6:ab:fb:11:
27
- b7:1c:41:bc:43:6e:1b:6f:28:88:40:bd:a8:47:28:
28
- 9e:a4:64:31:e0:a5:72:db:09:cb:b0:9e:7a:d5:d0:
29
- 7f:15:15:75:d4:d6:78:41:c9:a1:54:73:48:19:4f:
30
- 72:95:a1:31:b3:4c:81:41:13:43:d9:9b:8c:d0:2e:
31
- 29:09:a2:59:6b:15:6d:5c:93:22:03:f5:72:f0:46:
32
- be:65
33
- Exponent: 65537 (0x10001)
34
- X509v3 extensions:
35
- X509v3 Basic Constraints: critical
36
- CA:FALSE
37
- X509v3 Subject Key Identifier:
38
- E1:20:A8:89:51:79:0C:23:66:20:B7:A5:A4:42:8F:40:7F:7E:C0:CE
39
- X509v3 Authority Key Identifier:
40
- keyid:A8:C7:C5:69:35:49:1B:B6:77:E7:2E:16:5B:B0:75:8C:B7:03:5C:04
41
- DirName:/CN=devcert
42
- serial:DB:1E:4C:08:75:57:8D:4E
43
-
44
- X509v3 Key Usage: critical
45
- Digital Signature, Key Encipherment
46
- X509v3 Extended Key Usage:
47
- TLS Web Server Authentication
48
- X509v3 Subject Alternative Name:
49
- DNS:local.archive.org, DNS:*.local.archive.org
50
- Signature Algorithm: sha256WithRSAEncryption
51
- 5a:20:54:0b:6f:c3:35:e6:70:c1:bd:5c:58:e8:cf:7b:73:33:
52
- 38:80:70:c1:1c:60:2a:ea:5c:0c:eb:63:6a:15:48:fe:4d:f6:
53
- 18:89:e1:89:73:40:45:52:7d:bc:3a:d6:0e:d3:65:2c:e7:b9:
54
- ab:3b:c6:ea:6e:74:74:39:4f:53:3f:bb:59:d9:91:83:db:92:
55
- 96:32:97:25:5f:c2:8d:85:ce:b3:c7:b1:4d:37:b7:bd:81:de:
56
- f7:9f:34:5b:12:70:21:a8:03:8d:94:ed:d7:41:7f:2a:87:30:
57
- bd:4f:07:22:b2:9a:06:ab:bc:41:2c:2f:7c:be:e0:a2:90:60:
58
- 21:79:d4:a1:08:26:c1:f4:83:b2:0a:ff:7d:0a:15:dc:ed:d0:
59
- 49:f9:37:ad:fe:68:d7:59:9d:f8:25:4e:10:01:bf:a5:be:ec:
60
- 21:a8:bf:77:6c:ff:d4:b7:d4:11:9c:43:4a:64:e8:31:76:9a:
61
- 01:3a:54:d9:c0:8a:a6:2c:7a:df:0a:c4:26:6e:19:52:26:9d:
62
- 25:b5:b1:db:6f:12:91:92:83:ab:6c:28:52:e1:e4:63:c2:cf:
63
- 45:f7:b4:da:7d:13:66:47:62:90:e6:8d:2c:b8:aa:d4:2b:8c:
64
- d6:c0:5c:fc:83:e7:1f:71:5f:cb:38:b6:c3:a5:77:7d:97:04:
65
- 87:14:44:83
66
- -----BEGIN CERTIFICATE-----
67
- MIIDdjCCAl6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdkZXZj
68
- ZXJ0MB4XDTIyMDQyNzE2Mjc0NloXDTI0MDczMDE2Mjc0NlowHDEaMBgGA1UEAwwR
69
- bG9jYWwuYXJjaGl2ZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
70
- AQCpVMo0/4syAjmXYb31ElxK0Icu1kJjcuq0kJXMSu9aZgmfHQgNsvQus1VZnA93
71
- Nx7Xo1y3PYGE/FWvIOc8vZ4rK57RlZ0UkHB8mXjx3UIr/Ye5CfD2UMeQQd7i7t2g
72
- Sk3eIGroG4F/2RcN9fKh3InY6Ymc/0C3DrsW29HgZ18k3ju4GLim3dUmiiqk8gOx
73
- qBUjMcll3ptasPBP73fxi3uRlaBhvh9kKcYuLAMb8JGWtqv7EbccQbxDbhtvKIhA
74
- vahHKJ6kZDHgpXLbCcuwnnrV0H8VFXXU1nhByaFUc0gZT3KVoTGzTIFBE0PZm4zQ
75
- LikJollrFW1ckyID9XLwRr5lAgMBAAGjgcwwgckwDAYDVR0TAQH/BAIwADAdBgNV
76
- HQ4EFgQU4SCoiVF5DCNmILelpEKPQH9+wM4wQgYDVR0jBDswOYAUqMfFaTVJG7Z3
77
- 5y4WW7B1jLcDXAShFqQUMBIxEDAOBgNVBAMMB2RldmNlcnSCCQDbHkwIdVeNTjAO
78
- BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwMQYDVR0RBCowKIIR
79
- bG9jYWwuYXJjaGl2ZS5vcmeCEyoubG9jYWwuYXJjaGl2ZS5vcmcwDQYJKoZIhvcN
80
- AQELBQADggEBAFogVAtvwzXmcMG9XFjoz3tzMziAcMEcYCrqXAzrY2oVSP5N9hiJ
81
- 4YlzQEVSfbw61g7TZSznuas7xupudHQ5T1M/u1nZkYPbkpYylyVfwo2FzrPHsU03
82
- t72B3vefNFsScCGoA42U7ddBfyqHML1PByKymgarvEEsL3y+4KKQYCF51KEIJsH0
83
- g7IK/30KFdzt0En5N63+aNdZnfglThABv6W+7CGov3ds/9S31BGcQ0pk6DF2mgE6
84
- VNnAiqYset8KxCZuGVImnSW1sdtvEpGSg6tsKFLh5GPCz0X3tNp9E2ZHYpDmjSy4
85
- qtQrjNbAXPyD5x9xX8s4tsOld32XBIcURIM=
86
- -----END CERTIFICATE-----
1
+ Certificate:
2
+ Data:
3
+ Version: 3 (0x2)
4
+ Serial Number: 1 (0x1)
5
+ Signature Algorithm: sha256WithRSAEncryption
6
+ Issuer: CN=devcert
7
+ Validity
8
+ Not Before: Apr 27 16:27:46 2022 GMT
9
+ Not After : Jul 30 16:27:46 2024 GMT
10
+ Subject: CN=local.archive.org
11
+ Subject Public Key Info:
12
+ Public Key Algorithm: rsaEncryption
13
+ Public-Key: (2048 bit)
14
+ Modulus:
15
+ 00:a9:54:ca:34:ff:8b:32:02:39:97:61:bd:f5:12:
16
+ 5c:4a:d0:87:2e:d6:42:63:72:ea:b4:90:95:cc:4a:
17
+ ef:5a:66:09:9f:1d:08:0d:b2:f4:2e:b3:55:59:9c:
18
+ 0f:77:37:1e:d7:a3:5c:b7:3d:81:84:fc:55:af:20:
19
+ e7:3c:bd:9e:2b:2b:9e:d1:95:9d:14:90:70:7c:99:
20
+ 78:f1:dd:42:2b:fd:87:b9:09:f0:f6:50:c7:90:41:
21
+ de:e2:ee:dd:a0:4a:4d:de:20:6a:e8:1b:81:7f:d9:
22
+ 17:0d:f5:f2:a1:dc:89:d8:e9:89:9c:ff:40:b7:0e:
23
+ bb:16:db:d1:e0:67:5f:24:de:3b:b8:18:b8:a6:dd:
24
+ d5:26:8a:2a:a4:f2:03:b1:a8:15:23:31:c9:65:de:
25
+ 9b:5a:b0:f0:4f:ef:77:f1:8b:7b:91:95:a0:61:be:
26
+ 1f:64:29:c6:2e:2c:03:1b:f0:91:96:b6:ab:fb:11:
27
+ b7:1c:41:bc:43:6e:1b:6f:28:88:40:bd:a8:47:28:
28
+ 9e:a4:64:31:e0:a5:72:db:09:cb:b0:9e:7a:d5:d0:
29
+ 7f:15:15:75:d4:d6:78:41:c9:a1:54:73:48:19:4f:
30
+ 72:95:a1:31:b3:4c:81:41:13:43:d9:9b:8c:d0:2e:
31
+ 29:09:a2:59:6b:15:6d:5c:93:22:03:f5:72:f0:46:
32
+ be:65
33
+ Exponent: 65537 (0x10001)
34
+ X509v3 extensions:
35
+ X509v3 Basic Constraints: critical
36
+ CA:FALSE
37
+ X509v3 Subject Key Identifier:
38
+ E1:20:A8:89:51:79:0C:23:66:20:B7:A5:A4:42:8F:40:7F:7E:C0:CE
39
+ X509v3 Authority Key Identifier:
40
+ keyid:A8:C7:C5:69:35:49:1B:B6:77:E7:2E:16:5B:B0:75:8C:B7:03:5C:04
41
+ DirName:/CN=devcert
42
+ serial:DB:1E:4C:08:75:57:8D:4E
43
+
44
+ X509v3 Key Usage: critical
45
+ Digital Signature, Key Encipherment
46
+ X509v3 Extended Key Usage:
47
+ TLS Web Server Authentication
48
+ X509v3 Subject Alternative Name:
49
+ DNS:local.archive.org, DNS:*.local.archive.org
50
+ Signature Algorithm: sha256WithRSAEncryption
51
+ 5a:20:54:0b:6f:c3:35:e6:70:c1:bd:5c:58:e8:cf:7b:73:33:
52
+ 38:80:70:c1:1c:60:2a:ea:5c:0c:eb:63:6a:15:48:fe:4d:f6:
53
+ 18:89:e1:89:73:40:45:52:7d:bc:3a:d6:0e:d3:65:2c:e7:b9:
54
+ ab:3b:c6:ea:6e:74:74:39:4f:53:3f:bb:59:d9:91:83:db:92:
55
+ 96:32:97:25:5f:c2:8d:85:ce:b3:c7:b1:4d:37:b7:bd:81:de:
56
+ f7:9f:34:5b:12:70:21:a8:03:8d:94:ed:d7:41:7f:2a:87:30:
57
+ bd:4f:07:22:b2:9a:06:ab:bc:41:2c:2f:7c:be:e0:a2:90:60:
58
+ 21:79:d4:a1:08:26:c1:f4:83:b2:0a:ff:7d:0a:15:dc:ed:d0:
59
+ 49:f9:37:ad:fe:68:d7:59:9d:f8:25:4e:10:01:bf:a5:be:ec:
60
+ 21:a8:bf:77:6c:ff:d4:b7:d4:11:9c:43:4a:64:e8:31:76:9a:
61
+ 01:3a:54:d9:c0:8a:a6:2c:7a:df:0a:c4:26:6e:19:52:26:9d:
62
+ 25:b5:b1:db:6f:12:91:92:83:ab:6c:28:52:e1:e4:63:c2:cf:
63
+ 45:f7:b4:da:7d:13:66:47:62:90:e6:8d:2c:b8:aa:d4:2b:8c:
64
+ d6:c0:5c:fc:83:e7:1f:71:5f:cb:38:b6:c3:a5:77:7d:97:04:
65
+ 87:14:44:83
66
+ -----BEGIN CERTIFICATE-----
67
+ MIIDdjCCAl6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdkZXZj
68
+ ZXJ0MB4XDTIyMDQyNzE2Mjc0NloXDTI0MDczMDE2Mjc0NlowHDEaMBgGA1UEAwwR
69
+ bG9jYWwuYXJjaGl2ZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
70
+ AQCpVMo0/4syAjmXYb31ElxK0Icu1kJjcuq0kJXMSu9aZgmfHQgNsvQus1VZnA93
71
+ Nx7Xo1y3PYGE/FWvIOc8vZ4rK57RlZ0UkHB8mXjx3UIr/Ye5CfD2UMeQQd7i7t2g
72
+ Sk3eIGroG4F/2RcN9fKh3InY6Ymc/0C3DrsW29HgZ18k3ju4GLim3dUmiiqk8gOx
73
+ qBUjMcll3ptasPBP73fxi3uRlaBhvh9kKcYuLAMb8JGWtqv7EbccQbxDbhtvKIhA
74
+ vahHKJ6kZDHgpXLbCcuwnnrV0H8VFXXU1nhByaFUc0gZT3KVoTGzTIFBE0PZm4zQ
75
+ LikJollrFW1ckyID9XLwRr5lAgMBAAGjgcwwgckwDAYDVR0TAQH/BAIwADAdBgNV
76
+ HQ4EFgQU4SCoiVF5DCNmILelpEKPQH9+wM4wQgYDVR0jBDswOYAUqMfFaTVJG7Z3
77
+ 5y4WW7B1jLcDXAShFqQUMBIxEDAOBgNVBAMMB2RldmNlcnSCCQDbHkwIdVeNTjAO
78
+ BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwMQYDVR0RBCowKIIR
79
+ bG9jYWwuYXJjaGl2ZS5vcmeCEyoubG9jYWwuYXJjaGl2ZS5vcmcwDQYJKoZIhvcN
80
+ AQELBQADggEBAFogVAtvwzXmcMG9XFjoz3tzMziAcMEcYCrqXAzrY2oVSP5N9hiJ
81
+ 4YlzQEVSfbw61g7TZSznuas7xupudHQ5T1M/u1nZkYPbkpYylyVfwo2FzrPHsU03
82
+ t72B3vefNFsScCGoA42U7ddBfyqHML1PByKymgarvEEsL3y+4KKQYCF51KEIJsH0
83
+ g7IK/30KFdzt0En5N63+aNdZnfglThABv6W+7CGov3ds/9S31BGcQ0pk6DF2mgE6
84
+ VNnAiqYset8KxCZuGVImnSW1sdtvEpGSg6tsKFLh5GPCz0X3tNp9E2ZHYpDmjSy4
85
+ qtQrjNbAXPyD5x9xX8s4tsOld32XBIcURIM=
86
+ -----END CERTIFICATE-----
@@ -1,27 +1,27 @@
1
- -----BEGIN RSA PRIVATE KEY-----
2
- MIIEowIBAAKCAQEAqVTKNP+LMgI5l2G99RJcStCHLtZCY3LqtJCVzErvWmYJnx0I
3
- DbL0LrNVWZwPdzce16Nctz2BhPxVryDnPL2eKyue0ZWdFJBwfJl48d1CK/2HuQnw
4
- 9lDHkEHe4u7doEpN3iBq6BuBf9kXDfXyodyJ2OmJnP9Atw67FtvR4GdfJN47uBi4
5
- pt3VJooqpPIDsagVIzHJZd6bWrDwT+938Yt7kZWgYb4fZCnGLiwDG/CRlrar+xG3
6
- HEG8Q24bbyiIQL2oRyiepGQx4KVy2wnLsJ561dB/FRV11NZ4QcmhVHNIGU9ylaEx
7
- s0yBQRND2ZuM0C4pCaJZaxVtXJMiA/Vy8Ea+ZQIDAQABAoIBAAQgUdEazQyJ61da
8
- BWP8b41PKYwlonaD7V47C7tvtAdy5xcegPy8eKDOs+y8FdBk4naEv5Sjhg10jK34
9
- 0kmzoTASHwuiZrKClosivkS+jIc/5VfH+zw1WbeVM1Y6VeI7DUy1Y4WGbhBsfNhV
10
- PvVcx2smvbi6q5wKWtrCvomGW1YtngNBXJBPDWXysaVZdpF+6iWtw0RjWxbKEeMb
11
- fjZ2sxl7h1EkTXxQR9pfl9WVgl6vRRXp1o+N71M14jp5t95xCyf49YzeEuZmc1Fc
12
- dD77LNGcxr3kpkcQH5FdDP/spla+lR+JKb78FVqhEdPP3WcJ1qcrAstG2npAfKpj
13
- MD9AhsECgYEA3BddOjeK9epaGbTZRKgmIOSgGEHo8WbVHqBHhyQKAb8kFVEPn+Hl
14
- sq2EEQZf0ZJ/HhlVBc0Gj4/2PI8vj1Lzh+QWJnFu+XN/doOm5X62Ctz13qC5oWJp
15
- foQ9HXcg4GAXhm/o3KUIntLrUwoi/UW8YOSRFXS8RSJtuh1rI5P2jjECgYEAxPVP
16
- o/9+12Fc2ujdm8cQ1tB1Ab9Z73/vloG/xit0uMp89OqXUHEmtud/WzaIQvNxdaWi
17
- 9/BqAG9Oml51T3cuYPxNDkSmtd2fieq9Nh17dw8zYGMk0cSYeecgvCJOrRIJnebW
18
- Glyt8vzBb3eD6FzhZoVNOVYareainSP1cwl5YnUCgYAsr2m0OjayeyRT983tDJ7B
19
- Kun+QtOCv7ghgbVEEOMfO6md0llzwq+aOXSI6Fxn9nBssgP7K4dbeoUqAoBLfzIG
20
- sx50K6+2YebNLymhirp3NimNS+CkjZCRqVOnOdqo85mTKAGFWtSHOpegwnwcJB59
21
- Jar3Sj43YygYE4T/Mjlq4QKBgQC8zUcdt2J4xl1Df6xHkuiic0tmdG6a9jHOPex+
22
- 49NM/NYR1Ptd4kmxVXKxFjJCs6jUlQYG1NBYQFrCAcBEf8PWtqSLA+YnOh6gD4R3
23
- ZoWfGNQwFnoKF4HugU/Q6LYwk7TiR5B/zs30urQWzSOGT9rF8wyW5OJIR2kkZ373
24
- WmKgrQKBgGaw32CMejz3wBpzOAXsYJcMsVfNCMD4bJ2EbXhYuY8HB8IEEv6wqMsp
25
- wtXIgHJubfIiA3MlVsfaUkRdtHMHbN+Us1oynu6nByLhYlAMKpOsJFzPVHHwGB/1
26
- g3WtzfFk5eOoZltJBm5K41zjS7lyr1t05648pT6niy9snu6LaF94
27
- -----END RSA PRIVATE KEY-----
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEAqVTKNP+LMgI5l2G99RJcStCHLtZCY3LqtJCVzErvWmYJnx0I
3
+ DbL0LrNVWZwPdzce16Nctz2BhPxVryDnPL2eKyue0ZWdFJBwfJl48d1CK/2HuQnw
4
+ 9lDHkEHe4u7doEpN3iBq6BuBf9kXDfXyodyJ2OmJnP9Atw67FtvR4GdfJN47uBi4
5
+ pt3VJooqpPIDsagVIzHJZd6bWrDwT+938Yt7kZWgYb4fZCnGLiwDG/CRlrar+xG3
6
+ HEG8Q24bbyiIQL2oRyiepGQx4KVy2wnLsJ561dB/FRV11NZ4QcmhVHNIGU9ylaEx
7
+ s0yBQRND2ZuM0C4pCaJZaxVtXJMiA/Vy8Ea+ZQIDAQABAoIBAAQgUdEazQyJ61da
8
+ BWP8b41PKYwlonaD7V47C7tvtAdy5xcegPy8eKDOs+y8FdBk4naEv5Sjhg10jK34
9
+ 0kmzoTASHwuiZrKClosivkS+jIc/5VfH+zw1WbeVM1Y6VeI7DUy1Y4WGbhBsfNhV
10
+ PvVcx2smvbi6q5wKWtrCvomGW1YtngNBXJBPDWXysaVZdpF+6iWtw0RjWxbKEeMb
11
+ fjZ2sxl7h1EkTXxQR9pfl9WVgl6vRRXp1o+N71M14jp5t95xCyf49YzeEuZmc1Fc
12
+ dD77LNGcxr3kpkcQH5FdDP/spla+lR+JKb78FVqhEdPP3WcJ1qcrAstG2npAfKpj
13
+ MD9AhsECgYEA3BddOjeK9epaGbTZRKgmIOSgGEHo8WbVHqBHhyQKAb8kFVEPn+Hl
14
+ sq2EEQZf0ZJ/HhlVBc0Gj4/2PI8vj1Lzh+QWJnFu+XN/doOm5X62Ctz13qC5oWJp
15
+ foQ9HXcg4GAXhm/o3KUIntLrUwoi/UW8YOSRFXS8RSJtuh1rI5P2jjECgYEAxPVP
16
+ o/9+12Fc2ujdm8cQ1tB1Ab9Z73/vloG/xit0uMp89OqXUHEmtud/WzaIQvNxdaWi
17
+ 9/BqAG9Oml51T3cuYPxNDkSmtd2fieq9Nh17dw8zYGMk0cSYeecgvCJOrRIJnebW
18
+ Glyt8vzBb3eD6FzhZoVNOVYareainSP1cwl5YnUCgYAsr2m0OjayeyRT983tDJ7B
19
+ Kun+QtOCv7ghgbVEEOMfO6md0llzwq+aOXSI6Fxn9nBssgP7K4dbeoUqAoBLfzIG
20
+ sx50K6+2YebNLymhirp3NimNS+CkjZCRqVOnOdqo85mTKAGFWtSHOpegwnwcJB59
21
+ Jar3Sj43YygYE4T/Mjlq4QKBgQC8zUcdt2J4xl1Df6xHkuiic0tmdG6a9jHOPex+
22
+ 49NM/NYR1Ptd4kmxVXKxFjJCs6jUlQYG1NBYQFrCAcBEf8PWtqSLA+YnOh6gD4R3
23
+ ZoWfGNQwFnoKF4HugU/Q6LYwk7TiR5B/zs30urQWzSOGT9rF8wyW5OJIR2kkZ373
24
+ WmKgrQKBgGaw32CMejz3wBpzOAXsYJcMsVfNCMD4bJ2EbXhYuY8HB8IEEv6wqMsp
25
+ wtXIgHJubfIiA3MlVsfaUkRdtHMHbN+Us1oynu6nByLhYlAMKpOsJFzPVHHwGB/1
26
+ g3WtzfFk5eOoZltJBm5K41zjS7lyr1t05648pT6niy9snu6LaF94
27
+ -----END RSA PRIVATE KEY-----
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The Internet Archive Collection Browser.",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Internet Archive",
6
- "version": "0.4.2",
6
+ "version": "0.4.3-alpha.2",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
package/renovate.json CHANGED
@@ -1,6 +1,6 @@
1
- {
2
- "extends": [
3
- "config:base",
4
- ":preserveSemverRanges"
5
- ]
6
- }
1
+ {
2
+ "extends": [
3
+ "config:base",
4
+ ":preserveSemverRanges"
5
+ ]
6
+ }
@@ -89,15 +89,15 @@ export class CollectionBrowser
89
89
 
90
90
  @property({ type: String }) displayMode?: CollectionDisplayMode;
91
91
 
92
- @property({ type: Object }) sortParam: SortParam | null = null;
92
+ @property({ type: Object }) sortParam?: SortParam;
93
93
 
94
- @property({ type: String }) selectedSort: SortField = SortField.relevance;
94
+ @property({ type: String }) sortDirection?: SortDirection;
95
95
 
96
- @property({ type: String }) selectedTitleFilter: string | null = null;
96
+ @property({ type: String }) selectedSort: SortField = SortField.relevance;
97
97
 
98
- @property({ type: String }) selectedCreatorFilter: string | null = null;
98
+ @property({ type: String }) selectedTitleFilter?: string;
99
99
 
100
- @property({ type: String }) sortDirection: SortDirection | null = null;
100
+ @property({ type: String }) selectedCreatorFilter?: string;
101
101
 
102
102
  @property({ type: Number }) pageSize = 50;
103
103
 
@@ -277,13 +277,13 @@ export class CollectionBrowser
277
277
 
278
278
  clearFilters() {
279
279
  this.selectedFacets = defaultSelectedFacets;
280
- this.sortParam = null;
281
- this.selectedTitleFilter = null;
282
- this.selectedCreatorFilter = null;
280
+ this.sortParam = undefined;
281
+ this.sortDirection = undefined;
282
+ this.selectedTitleFilter = undefined;
283
+ this.selectedCreatorFilter = undefined;
283
284
  this.titleQuery = undefined;
284
285
  this.creatorQuery = undefined;
285
286
  this.selectedSort = SortField.relevance;
286
- this.sortDirection = null;
287
287
  }
288
288
 
289
289
  /**
@@ -291,6 +291,7 @@ export class CollectionBrowser
291
291
  * the query, the search type, or the sort has changed.
292
292
  */
293
293
  requestSearch() {
294
+ console.log('handling query change by request');
294
295
  this.handleQueryChange();
295
296
  }
296
297
 
@@ -401,7 +402,7 @@ export class CollectionBrowser
401
402
  private userChangedSort(
402
403
  e: CustomEvent<{
403
404
  selectedSort: SortField;
404
- sortDirection: SortDirection | null;
405
+ sortDirection?: SortDirection;
405
406
  }>
406
407
  ) {
407
408
  const { selectedSort, sortDirection } = e.detail;
@@ -414,7 +415,7 @@ export class CollectionBrowser
414
415
  this.currentPage = 1;
415
416
  }
416
417
 
417
- private sendSortByAnalytics(prevSortDirection: SortDirection | null): void {
418
+ private sendSortByAnalytics(prevSortDirection?: SortDirection): void {
418
419
  const directionCleared = prevSortDirection && !this.sortDirection;
419
420
 
420
421
  this.analyticsHandler?.sendEvent({
@@ -427,14 +428,16 @@ export class CollectionBrowser
427
428
  }
428
429
 
429
430
  private selectedSortChanged(): void {
430
- if (this.selectedSort === 'relevance' || this.sortDirection === null) {
431
- this.sortParam = null;
431
+ if (this.selectedSort === 'relevance') {
432
+ this.sortParam = undefined;
432
433
  return;
433
434
  }
434
435
  const sortField = SortFieldToMetadataField[this.selectedSort];
436
+ if (!this.sortDirection) this.sortDirection = 'desc';
435
437
 
436
438
  if (!sortField) return;
437
439
  this.sortParam = { field: sortField, direction: this.sortDirection };
440
+ this.requestUpdate();
438
441
 
439
442
  // Lazy-load the alphabet counts for title/creator sort bar as needed
440
443
  this.updatePrefixFiltersForCurrentSort();
@@ -457,11 +460,11 @@ export class CollectionBrowser
457
460
  /** Send Analytics when sorting by title's first letter
458
461
  * labels: 'start-<ToLetter>' | 'clear-<FromLetter>' | '<FromLetter>-<ToLetter>'
459
462
  * */
460
- private sendFilterByTitleAnalytics(prevSelectedLetter: string | null): void {
463
+ private sendFilterByTitleAnalytics(prevSelectedLetter?: string): void {
461
464
  if (!prevSelectedLetter && !this.selectedTitleFilter) {
462
465
  return;
463
466
  }
464
- const cleared = prevSelectedLetter && this.selectedTitleFilter === null;
467
+ const cleared = prevSelectedLetter && !this.selectedTitleFilter;
465
468
 
466
469
  this.analyticsHandler?.sendEvent({
467
470
  category: this.searchContext,
@@ -481,13 +484,11 @@ export class CollectionBrowser
481
484
  /** Send Analytics when filtering by creator's first letter
482
485
  * labels: 'start-<ToLetter>' | 'clear-<FromLetter>' | '<FromLetter>-<ToLetter>'
483
486
  * */
484
- private sendFilterByCreatorAnalytics(
485
- prevSelectedLetter: string | null
486
- ): void {
487
+ private sendFilterByCreatorAnalytics(prevSelectedLetter?: string): void {
487
488
  if (!prevSelectedLetter && !this.selectedCreatorFilter) {
488
489
  return;
489
490
  }
490
- const cleared = prevSelectedLetter && this.selectedCreatorFilter === null;
491
+ const cleared = prevSelectedLetter && !this.selectedCreatorFilter;
491
492
 
492
493
  this.analyticsHandler?.sendEvent({
493
494
  category: this.searchContext,
@@ -505,12 +506,12 @@ export class CollectionBrowser
505
506
  }
506
507
 
507
508
  private titleLetterSelected(e: CustomEvent<{ selectedLetter: string }>) {
508
- this.selectedCreatorFilter = null;
509
+ this.selectedCreatorFilter = undefined;
509
510
  this.selectedTitleFilter = e.detail.selectedLetter;
510
511
  }
511
512
 
512
513
  private creatorLetterSelected(e: CustomEvent<{ selectedLetter: string }>) {
513
- this.selectedTitleFilter = null;
514
+ this.selectedTitleFilter = undefined;
514
515
  this.selectedCreatorFilter = e.detail.selectedLetter;
515
516
  }
516
517
 
@@ -618,10 +619,12 @@ export class CollectionBrowser
618
619
 
619
620
  firstUpdated(): void {
620
621
  this.setupStateRestorationObserver();
622
+ console.log('first updated - restoring state');
621
623
  this.restoreState();
622
624
  }
623
625
 
624
626
  updated(changed: PropertyValues) {
627
+ console.log('updated', changed);
625
628
  if (
626
629
  changed.has('displayMode') ||
627
630
  changed.has('baseNavigationUrl') ||
@@ -631,12 +634,29 @@ export class CollectionBrowser
631
634
  this.infiniteScroller?.reload();
632
635
  }
633
636
  if (changed.has('baseQuery')) {
637
+ console.log(
638
+ 'base query changed',
639
+ changed.get('baseQuery'),
640
+ this.baseQuery
641
+ );
634
642
  this.emitBaseQueryChanged();
635
643
  }
636
644
  if (changed.has('searchType')) {
645
+ console.log(
646
+ 'search type changed',
647
+ changed.get('searchType'),
648
+ this.searchType
649
+ );
637
650
  this.emitSearchTypeChanged();
638
651
  }
639
652
  if (changed.has('currentPage') || changed.has('displayMode')) {
653
+ console.log(
654
+ 'current page or display mode changed',
655
+ changed.get('currentPage'),
656
+ this.currentPage,
657
+ changed.get('displayMode'),
658
+ this.displayMode
659
+ );
640
660
  this.persistState();
641
661
  }
642
662
  if (
@@ -646,9 +666,14 @@ export class CollectionBrowser
646
666
  changed.has('minSelectedDate') ||
647
667
  changed.has('maxSelectedDate') ||
648
668
  changed.has('sortParam') ||
649
- changed.has('selectedFacets') ||
650
- changed.has('searchService')
669
+ changed.has('selectedFacets')
651
670
  ) {
671
+ console.log(
672
+ 'handling query change',
673
+ changed,
674
+ this.baseQuery,
675
+ this.sortParam
676
+ );
652
677
  this.handleQueryChange();
653
678
  }
654
679
  if (
@@ -783,6 +808,11 @@ export class CollectionBrowser
783
808
  private previousQueryKey?: string;
784
809
 
785
810
  private async handleQueryChange() {
811
+ console.log(
812
+ 'handleQueryChange',
813
+ this.pageFetchQueryKey,
814
+ this.previousQueryKey
815
+ );
786
816
  // only reset if the query has actually changed
787
817
  if (!this.searchService || this.pageFetchQueryKey === this.previousQueryKey)
788
818
  return;
@@ -804,9 +834,9 @@ export class CollectionBrowser
804
834
  this.scrollToPage(this.initialPageNumber);
805
835
  }
806
836
  this.initialQueryChangeHappened = true;
837
+
807
838
  // if the query changed as part of a window.history pop event, we don't want to
808
839
  // persist the state because it overwrites the forward history
809
-
810
840
  if (!this.historyPopOccurred) {
811
841
  this.persistState();
812
842
  this.historyPopOccurred = false;
@@ -840,14 +870,14 @@ export class CollectionBrowser
840
870
  if (restorationState.searchType != null)
841
871
  this.searchType = restorationState.searchType;
842
872
  this.selectedSort = restorationState.selectedSort ?? SortField.relevance;
843
- this.sortDirection = restorationState.sortDirection ?? null;
844
- this.selectedTitleFilter = restorationState.selectedTitleFilter ?? null;
845
- this.selectedCreatorFilter = restorationState.selectedCreatorFilter ?? null;
873
+ this.sortDirection = restorationState.sortDirection;
874
+ this.selectedTitleFilter = restorationState.selectedTitleFilter;
875
+ this.selectedCreatorFilter = restorationState.selectedCreatorFilter;
846
876
  this.selectedFacets = restorationState.selectedFacets;
847
877
  this.baseQuery = restorationState.baseQuery;
848
878
  this.titleQuery = restorationState.titleQuery;
849
879
  this.creatorQuery = restorationState.creatorQuery;
850
- this.sortParam = restorationState.sortParam ?? null;
880
+ this.sortParam = restorationState.sortParam;
851
881
  this.currentPage = restorationState.currentPage ?? 1;
852
882
  this.minSelectedDate = restorationState.minSelectedDate;
853
883
  this.maxSelectedDate = restorationState.maxSelectedDate;
@@ -1290,6 +1320,7 @@ export class CollectionBrowser
1290
1320
  private pageFetchesInProgress: Record<string, Set<number>> = {};
1291
1321
 
1292
1322
  async fetchPage(pageNumber: number) {
1323
+ console.log('maybe fetch page', pageNumber);
1293
1324
  if (!this.filteredQuery) return;
1294
1325
 
1295
1326
  // if we already have data, don't fetch again
@@ -1304,6 +1335,7 @@ export class CollectionBrowser
1304
1335
  if (pageFetches.has(pageNumber)) return;
1305
1336
  pageFetches.add(pageNumber);
1306
1337
  this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
1338
+ console.log('fetching page', pageNumber);
1307
1339
 
1308
1340
  const sortParams = this.sortParam ? [this.sortParam] : [];
1309
1341
  const params: SearchParams = {
@@ -15,6 +15,7 @@ import {
15
15
  FacetBucket,
16
16
  FacetState,
17
17
  } from './models';
18
+ import { arrayEquals } from './utils/array-equals';
18
19
 
19
20
  export interface RestorationState {
20
21
  displayMode?: CollectionDisplayMode;
@@ -89,15 +90,22 @@ export class RestorationStateHandler
89
90
  }
90
91
 
91
92
  private persistQueryStateToUrl(state: RestorationState) {
93
+ console.log('persistQueryStateToUrl', state);
92
94
  const url = new URL(window.location.href);
93
95
  const { searchParams } = url;
94
- searchParams.delete('sin');
95
- searchParams.delete('sort');
96
+ const oldParams = new URLSearchParams(searchParams);
97
+
96
98
  searchParams.delete('query');
99
+ searchParams.delete('sin');
97
100
  searchParams.delete('page');
101
+ searchParams.delete('sort');
98
102
  searchParams.delete('and[]');
99
103
  searchParams.delete('not[]');
100
104
 
105
+ if (state.baseQuery) {
106
+ searchParams.set('query', state.baseQuery);
107
+ }
108
+
101
109
  if (state.searchType) {
102
110
  searchParams.set(
103
111
  'sin',
@@ -105,15 +113,6 @@ export class RestorationStateHandler
105
113
  );
106
114
  }
107
115
 
108
- if (state.sortParam) {
109
- const prefix = state.sortParam.direction === 'desc' ? '-' : '';
110
- searchParams.set('sort', `${prefix}${state.sortParam.field}`);
111
- }
112
-
113
- if (state.baseQuery) {
114
- searchParams.set('query', state.baseQuery);
115
- }
116
-
117
116
  if (state.currentPage) {
118
117
  if (state.currentPage > 1) {
119
118
  searchParams.set('page', state.currentPage.toString());
@@ -122,6 +121,11 @@ export class RestorationStateHandler
122
121
  }
123
122
  }
124
123
 
124
+ if (state.sortParam) {
125
+ const prefix = state.sortParam.direction === 'desc' ? '-' : '';
126
+ searchParams.set('sort', `${prefix}${state.sortParam.field}`);
127
+ }
128
+
125
129
  if (state.selectedFacets) {
126
130
  for (const [facetName, facetValues] of Object.entries(
127
131
  state.selectedFacets
@@ -147,22 +151,45 @@ export class RestorationStateHandler
147
151
  `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`
148
152
  );
149
153
  }
154
+
150
155
  if (state.titleQuery) {
151
156
  searchParams.append('and[]', state.titleQuery);
152
157
  }
158
+
153
159
  if (state.creatorQuery) {
154
160
  searchParams.append('and[]', state.creatorQuery);
155
161
  }
156
162
 
163
+ // Ensure we aren't pushing an identical state to the stack
164
+ console.log('old params', oldParams.toString());
165
+ console.log('new params', searchParams.toString());
166
+ if (
167
+ oldParams.get('query') === searchParams.get('query') &&
168
+ oldParams.get('sin') === searchParams.get('sin') &&
169
+ oldParams.get('page') === searchParams.get('page') &&
170
+ oldParams.get('sort') === searchParams.get('sort') &&
171
+ arrayEquals(
172
+ oldParams.getAll('and[]').sort(),
173
+ searchParams.getAll('and[]').sort()
174
+ ) &&
175
+ arrayEquals(
176
+ oldParams.getAll('not[]').sort(),
177
+ searchParams.getAll('not[]').sort()
178
+ )
179
+ ) {
180
+ console.log('Ignoring identical params');
181
+ return;
182
+ }
183
+
157
184
  window.history.pushState(
158
185
  {
159
- sort: state.sortParam,
160
186
  query: state.baseQuery,
187
+ searchType: state.searchType,
161
188
  page: state.currentPage,
162
- and: state.selectedFacets,
163
- not: state.selectedFacets,
189
+ sort: state.sortParam,
164
190
  minDate: state.minSelectedDate,
165
191
  maxDate: state.maxSelectedDate,
192
+ facets: state.selectedFacets,
166
193
  },
167
194
  '',
168
195
  url
@@ -170,6 +197,7 @@ export class RestorationStateHandler
170
197
  }
171
198
 
172
199
  private loadQueryStateFromUrl(): RestorationState {
200
+ console.log('loadQueryStateFromUrl', window.location.href);
173
201
  const url = new URL(window.location.href);
174
202
  const searchInside = url.searchParams.get('sin');
175
203
  const pageNumber = url.searchParams.get('page');
@@ -295,6 +323,32 @@ export class RestorationStateHandler
295
323
  return value;
296
324
  }
297
325
 
326
+ private selectedFacetStatesEqual(
327
+ facets1: SelectedFacets,
328
+ facets2: SelectedFacets
329
+ ): boolean {
330
+ if (facets1 === facets2) return true;
331
+
332
+ // We can assume they both have the same top-level entries (the allowable facet fields)
333
+ for (const [key, values] of Object.entries(facets1)) {
334
+ const facetField = key as keyof SelectedFacets;
335
+
336
+ // They must have the same number of bucket entries for each field
337
+ const bucketEntries1 = Object.entries(values);
338
+ const bucketEntries2 = Object.entries(facets2[facetField]);
339
+ if (bucketEntries1.length !== bucketEntries2.length) return false;
340
+
341
+ // And since they have the same length, we just ensure every bucket state from the
342
+ // first object matches a corresponding bucket state in the second object.
343
+ // If the corresponding bucket doesn't exist or has a different state, we're done.
344
+ for (const [value, bucket] of bucketEntries1) {
345
+ if (bucket.state !== facets2[facetField][value]?.state) return false;
346
+ }
347
+ }
348
+
349
+ return true;
350
+ }
351
+
298
352
  /**
299
353
  * Sets the facet state for the given field & value to the given state,
300
354
  * creating any previously-undefined buckets as needed.
@@ -303,6 +303,7 @@ export class SortFilterBar
303
303
  this.alphaSelectorVisible = 'creator';
304
304
  this.selectedTitleFilter = null;
305
305
  this.dateSortSelectorVisible = false;
306
+ this.viewSortSelectorVisible = false;
306
307
  this.setSelectedSort(SortField.creator);
307
308
  this.emitTitleLetterChangedEvent();
308
309
  },
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Determines whether two arrays have the same (shallow) contents in the same order
3
+ */
4
+ export function arrayEquals(arr1: unknown[], arr2: unknown[]): boolean {
5
+ if (arr1 === arr2) return true;
6
+ if (arr1.length !== arr2.length) return false;
7
+ return arr1.every((val, i) => val === arr2[i]);
8
+ }