@internetarchive/collection-browser 0.0.1-alpha.48 → 0.0.1-alpha.49

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 (51) hide show
  1. package/demo/index.html +2 -2
  2. package/dist/src/async-collection-name.d.ts +11 -0
  3. package/dist/src/async-collection-name.js +38 -0
  4. package/dist/src/async-collection-name.js.map +1 -0
  5. package/dist/src/collection-name-cache.d.ts +18 -0
  6. package/dist/src/collection-name-cache.js +89 -0
  7. package/dist/src/collection-name-cache.js.map +1 -0
  8. package/dist/src/language-code-handler/language-codes.d.ts +0 -0
  9. package/dist/src/language-code-handler/language-codes.js +439 -0
  10. package/dist/src/language-code-handler/language-codes.js.map +1 -0
  11. package/dist/src/restoration-state-handler.d.ts +1 -0
  12. package/dist/src/restoration-state-handler.js +14 -6
  13. package/dist/src/restoration-state-handler.js.map +1 -1
  14. package/dist/src/tiles/grid/item-tile.d.ts +2 -3
  15. package/dist/src/tiles/grid/item-tile.js +9 -87
  16. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  17. package/dist/src/tiles/item-image.d.ts +1 -1
  18. package/dist/src/tiles/item-image.js +71 -8
  19. package/dist/src/tiles/item-image.js.map +1 -1
  20. package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
  21. package/dist/src/tiles/list/tile-list-compact.js +1 -1
  22. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  23. package/dist/src/tiles/list/tile-list.d.ts +1 -1
  24. package/dist/src/tiles/list/tile-list.js +1 -1
  25. package/dist/src/tiles/list/tile-list.js.map +1 -1
  26. package/dist/src/tiles/mediatype-icon.d.ts +9 -0
  27. package/dist/src/tiles/mediatype-icon.js +78 -0
  28. package/dist/src/tiles/mediatype-icon.js.map +1 -0
  29. package/dist/test/collection-name-cache.test.d.ts +1 -0
  30. package/dist/test/collection-name-cache.test.js +158 -0
  31. package/dist/test/collection-name-cache.test.js.map +1 -0
  32. package/dist/test/mocks/mock-search-response.d.ts +5 -0
  33. package/dist/test/mocks/mock-search-response.js +62 -0
  34. package/dist/test/mocks/mock-search-response.js.map +1 -0
  35. package/dist/test/mocks/mock-search-service.d.ts +13 -0
  36. package/dist/test/mocks/mock-search-service.js +20 -0
  37. package/dist/test/mocks/mock-search-service.js.map +1 -0
  38. package/package.json +1 -1
  39. package/src/restoration-state-handler.ts +20 -6
  40. package/src/tiles/grid/item-tile.ts +11 -95
  41. package/src/tiles/item-image.ts +206 -0
  42. package/src/tiles/list/tile-list-compact.ts +1 -1
  43. package/src/tiles/list/tile-list.ts +1 -1
  44. package/src/{mediatype-icon.ts → tiles/mediatype-icon.ts} +1 -1
  45. package/dist/src/assets/img/icons/mediatype/mediatype-color.d.ts +0 -3
  46. package/dist/src/assets/img/icons/mediatype/mediatype-color.js +0 -15
  47. package/dist/src/assets/img/icons/mediatype/mediatype-color.js.map +0 -1
  48. package/dist/src/tiles/waveform-thumbnail.d.ts +0 -7
  49. package/dist/src/tiles/waveform-thumbnail.js +0 -106
  50. package/dist/src/tiles/waveform-thumbnail.js.map +0 -1
  51. package/src/waveform-thumbnail.ts +0 -102
package/demo/index.html CHANGED
@@ -13,8 +13,8 @@
13
13
  color: #2C2C2C;
14
14
  }
15
15
  </style>
16
- <script
17
- src="https://polyfill.archive.org/v3/polyfill.min.js?features=scrollIntoView%2CElement.prototype.scrollIntoView"></script>
16
+ <!-- <script
17
+ src="https://polyfill.archive.org/v3/polyfill.min.js?features=scrollIntoView%2CElement.prototype.scrollIntoView"></script> -->
18
18
 
19
19
  </head>
20
20
  <body>
@@ -0,0 +1,11 @@
1
+ import { LitElement, PropertyValues } from "lit";
2
+ import { CollectionNameCacheInterface } from "./collection-name-cache";
3
+ export declare class AsyncCollectionName extends LitElement {
4
+ collectionNameCache?: CollectionNameCacheInterface;
5
+ identifier?: string;
6
+ name?: string | null;
7
+ render(): import("lit-html").TemplateResult<1>;
8
+ protected createRenderRoot(): Element | ShadowRoot;
9
+ updated(changed: PropertyValues): void;
10
+ private fetchName;
11
+ }
@@ -0,0 +1,38 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, LitElement } from "lit";
3
+ import { customElement, property, state } from "lit/decorators.js";
4
+ let AsyncCollectionName = class AsyncCollectionName extends LitElement {
5
+ render() {
6
+ return html `
7
+ ${this.name ? this.name : this.identifier}
8
+ `;
9
+ }
10
+ // disable the shadowRoot for this component so consumers can style it as they need
11
+ createRenderRoot() {
12
+ return this;
13
+ }
14
+ updated(changed) {
15
+ if (changed.has("identifier") || changed.has("collectionNameCache")) {
16
+ this.fetchName();
17
+ }
18
+ }
19
+ async fetchName() {
20
+ if (!this.identifier || !this.collectionNameCache)
21
+ return;
22
+ this.name = await this.collectionNameCache.collectionNameFor(this.identifier);
23
+ }
24
+ };
25
+ __decorate([
26
+ property({ type: Object })
27
+ ], AsyncCollectionName.prototype, "collectionNameCache", void 0);
28
+ __decorate([
29
+ property({ type: String })
30
+ ], AsyncCollectionName.prototype, "identifier", void 0);
31
+ __decorate([
32
+ state()
33
+ ], AsyncCollectionName.prototype, "name", void 0);
34
+ AsyncCollectionName = __decorate([
35
+ customElement('async-collection-name')
36
+ ], AsyncCollectionName);
37
+ export { AsyncCollectionName };
38
+ //# sourceMappingURL=async-collection-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-collection-name.js","sourceRoot":"","sources":["../../src/async-collection-name.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAInE,IAAa,mBAAmB,GAAhC,MAAa,mBAAoB,SAAQ,UAAU;IAOjD,MAAM;QACJ,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU;KAC1C,CAAC;IACJ,CAAC;IAED,mFAAmF;IACzE,gBAAgB;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,OAAuB;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE;YACnE,IAAI,CAAC,SAAS,EAAE,CAAC;SAClB;IACH,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,mBAAmB;YAAE,OAAO;QAC1D,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChF,CAAC;CACF,CAAA;AA3B6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gEAAoD;AAEnD;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAAqB;AAEvC;IAAR,KAAK,EAAE;iDAAsB;AALnB,mBAAmB;IAD/B,aAAa,CAAC,uBAAuB,CAAC;GAC1B,mBAAmB,CA4B/B;SA5BY,mBAAmB","sourcesContent":["import { html, LitElement, PropertyValues } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { CollectionNameCacheInterface } from \"./collection-name-cache\";\n\n@customElement('async-collection-name')\nexport class AsyncCollectionName extends LitElement {\n @property({ type: Object }) collectionNameCache?: CollectionNameCacheInterface;\n\n @property({ type: String }) identifier?: string;\n\n @state() name?: string | null;\n\n render() {\n return html`\n ${this.name ? this.name : this.identifier}\n `;\n }\n\n // disable the shadowRoot for this component so consumers can style it as they need\n protected createRenderRoot(): Element | ShadowRoot {\n return this;\n }\n\n updated(changed: PropertyValues): void {\n if (changed.has(\"identifier\") || changed.has(\"collectionNameCache\")) {\n this.fetchName();\n }\n }\n\n private async fetchName(): Promise<void> {\n if (!this.identifier || !this.collectionNameCache) return;\n this.name = await this.collectionNameCache.collectionNameFor(this.identifier);\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { SearchServiceInterface } from '@internetarchive/search-service';
2
+ export interface CollectionNameCacheInterface {
3
+ collectionNameFor(identifier: string): Promise<string | null>;
4
+ preloadIdentifiers(identifiers: string[]): Promise<void>;
5
+ }
6
+ export declare class CollectionNameCache implements CollectionNameCacheInterface {
7
+ collectionNameFor(identifier: string): Promise<string | null>;
8
+ preloadIdentifiers(identifiers: string[]): Promise<void>;
9
+ private pendingIdentifierQueue;
10
+ private pendingPromises;
11
+ private collectionNameCache;
12
+ private searchService;
13
+ constructor(options: {
14
+ searchService: SearchServiceInterface;
15
+ loadInterval?: number;
16
+ });
17
+ private loadPendingIdentifiers;
18
+ }
@@ -0,0 +1,89 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable no-continue */
3
+ import { SearchParams, } from '@internetarchive/search-service';
4
+ export class CollectionNameCache {
5
+ constructor(options) {
6
+ var _a;
7
+ this.pendingIdentifierQueue = [];
8
+ this.pendingPromises = {};
9
+ this.collectionNameCache = {};
10
+ this.searchService = options.searchService;
11
+ setInterval(() => {
12
+ this.loadPendingIdentifiers();
13
+ }, (_a = options.loadInterval) !== null && _a !== void 0 ? _a : 250);
14
+ }
15
+ async collectionNameFor(identifier) {
16
+ const lowercaseIdentifier = identifier.toLowerCase();
17
+ const cachedName = this.collectionNameCache[lowercaseIdentifier];
18
+ // we're specifically looking for `undefined`, because `null`
19
+ // means we queried the search service and found nothing so
20
+ // don't query again
21
+ if (cachedName !== undefined)
22
+ return cachedName;
23
+ return new Promise(resolve => {
24
+ var _a;
25
+ this.pendingIdentifierQueue.push(lowercaseIdentifier);
26
+ const currentPromises = (_a = this.pendingPromises[lowercaseIdentifier]) !== null && _a !== void 0 ? _a : [];
27
+ const resultHandler = async (name) => {
28
+ resolve(name);
29
+ };
30
+ currentPromises.push(resultHandler);
31
+ this.pendingPromises[lowercaseIdentifier] = currentPromises;
32
+ });
33
+ }
34
+ async preloadIdentifiers(identifiers) {
35
+ const lowercaseIdentifiers = identifiers.map(identifier => identifier.toLowerCase());
36
+ for (const identifier of lowercaseIdentifiers) {
37
+ if (this.collectionNameCache[identifier])
38
+ continue;
39
+ this.pendingIdentifierQueue.push(identifier);
40
+ }
41
+ await this.loadPendingIdentifiers();
42
+ }
43
+ async loadPendingIdentifiers() {
44
+ var _a, _b, _c;
45
+ const pendingIdentifiers = this.pendingIdentifierQueue.splice(0, 100);
46
+ if (pendingIdentifiers.length === 0)
47
+ return;
48
+ const searchParams = new SearchParams({
49
+ query: `identifier:(${pendingIdentifiers.join(' OR ')})`,
50
+ fields: ['title', 'identifier'],
51
+ rows: pendingIdentifiers.length,
52
+ });
53
+ const results = await this.searchService.search(searchParams);
54
+ const docs = (_b = (_a = results.success) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.docs;
55
+ // first process the identifiers that were received from the search service
56
+ // and remove them from the pendingIdentifierQueue
57
+ if (docs && docs.length > 0) {
58
+ for (const result of docs) {
59
+ const { identifier, title } = result;
60
+ if (!identifier)
61
+ continue;
62
+ const lowercaseIdentifier = identifier.toLowerCase();
63
+ pendingIdentifiers.splice(pendingIdentifiers.indexOf(lowercaseIdentifier), 1);
64
+ const collectionName = (_c = title === null || title === void 0 ? void 0 : title.value) !== null && _c !== void 0 ? _c : null;
65
+ this.collectionNameCache[lowercaseIdentifier] = collectionName;
66
+ const currentPromises = this.pendingPromises[lowercaseIdentifier];
67
+ if (currentPromises) {
68
+ for (const promise of currentPromises) {
69
+ promise(collectionName);
70
+ }
71
+ delete this.pendingPromises[lowercaseIdentifier];
72
+ }
73
+ }
74
+ }
75
+ // if the search service did not return titles for all of the identifiers,
76
+ // we still need to complete the promises and just return `null` for the rest
77
+ for (const identifier of pendingIdentifiers) {
78
+ this.collectionNameCache[identifier] = null;
79
+ const currentPromises = this.pendingPromises[identifier];
80
+ if (currentPromises) {
81
+ for (const promise of currentPromises) {
82
+ promise(null);
83
+ }
84
+ delete this.pendingPromises[identifier];
85
+ }
86
+ }
87
+ }
88
+ }
89
+ //# sourceMappingURL=collection-name-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-name-cache.js","sourceRoot":"","sources":["../../src/collection-name-cache.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable camelcase */\n/* eslint-disable no-continue */\nimport {\n SearchParams,\n SearchServiceInterface,\n} from '@internetarchive/search-service';\n\nexport interface CollectionNameCacheInterface {\n collectionNameFor(identifier: string): Promise<string | null>;\n preloadIdentifiers(identifiers: string[]): Promise<void>;\n}\n\n// this is the callback type received after the name is fetched\ntype CollectionNameResolver = (name: string | null) => Promise<void>;\n\nexport class CollectionNameCache implements CollectionNameCacheInterface {\n async collectionNameFor(identifier: string): Promise<string | null> {\n const lowercaseIdentifier = identifier.toLowerCase();\n const cachedName = this.collectionNameCache[lowercaseIdentifier];\n // we're specifically looking for `undefined`, because `null`\n // means we queried the search service and found nothing so\n // don't query again\n if (cachedName !== undefined) return cachedName;\n\n return new Promise(resolve => {\n this.pendingIdentifierQueue.push(lowercaseIdentifier);\n const currentPromises = this.pendingPromises[lowercaseIdentifier] ?? [];\n const resultHandler: CollectionNameResolver = async (\n name: string | null\n ) => {\n resolve(name);\n };\n currentPromises.push(resultHandler);\n this.pendingPromises[lowercaseIdentifier] = currentPromises;\n });\n }\n\n async preloadIdentifiers(identifiers: string[]): Promise<void> {\n const lowercaseIdentifiers = identifiers.map(identifier => identifier.toLowerCase());\n for (const identifier of lowercaseIdentifiers) {\n if (this.collectionNameCache[identifier]) continue;\n this.pendingIdentifierQueue.push(identifier);\n }\n await this.loadPendingIdentifiers();\n }\n\n private pendingIdentifierQueue: string[] = [];\n\n private pendingPromises: { [key: string]: CollectionNameResolver[] } = {};\n\n private collectionNameCache: { [key: string]: string | null | undefined } =\n {};\n\n private searchService: SearchServiceInterface;\n\n constructor(options: {\n searchService: SearchServiceInterface;\n loadInterval?: number;\n }) {\n this.searchService = options.searchService;\n\n setInterval(() => {\n this.loadPendingIdentifiers();\n }, options.loadInterval ?? 250);\n }\n\n private async loadPendingIdentifiers(): Promise<void> {\n const pendingIdentifiers = this.pendingIdentifierQueue.splice(0, 100);\n if (pendingIdentifiers.length === 0) return;\n\n const searchParams = new SearchParams({\n query: `identifier:(${pendingIdentifiers.join(' OR ')})`,\n fields: ['title', 'identifier'],\n rows: pendingIdentifiers.length,\n });\n\n const results = await this.searchService.search(searchParams);\n const docs = results.success?.response?.docs;\n\n // first process the identifiers that were received from the search service\n // and remove them from the pendingIdentifierQueue\n if (docs && docs.length > 0) {\n for (const result of docs) {\n const { identifier, title } = result;\n if (!identifier) continue;\n const lowercaseIdentifier = identifier.toLowerCase();\n pendingIdentifiers.splice(pendingIdentifiers.indexOf(lowercaseIdentifier), 1);\n const collectionName = title?.value ?? null;\n this.collectionNameCache[lowercaseIdentifier] = collectionName;\n const currentPromises = this.pendingPromises[lowercaseIdentifier];\n if (currentPromises) {\n for (const promise of currentPromises) {\n promise(collectionName);\n }\n delete this.pendingPromises[lowercaseIdentifier];\n }\n }\n }\n\n // if the search service did not return titles for all of the identifiers,\n // we still need to complete the promises and just return `null` for the rest\n for (const identifier of pendingIdentifiers) {\n this.collectionNameCache[identifier] = null;\n const currentPromises = this.pendingPromises[identifier];\n if (currentPromises) {\n for (const promise of currentPromises) {\n promise(null);\n }\n delete this.pendingPromises[identifier];\n }\n }\n }\n}\n"]}