generated from uwu/neptune-template
-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib - Added ContextMenu & Playlist/Album ItemCaches
- Loading branch information
Showing
9 changed files
with
242 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { fetchIsrcIterable } from "@inrixia/lib/api/tidal/isrc"; | ||
import { Resource } from "@inrixia/lib/api/tidal/types/ISRC"; | ||
import { ExtendedTrackItem } from "@inrixia/lib/Caches/ExtendedTrackItem"; | ||
import { TrackItemCache } from "@inrixia/lib/Caches/TrackItemCache"; | ||
import { ItemId, TrackItem } from "neptune-types/tidal"; | ||
import { hasHiRes } from "."; | ||
|
||
export class MaxTrack { | ||
private static readonly _idMap: Record<ItemId, Promise<Resource | false>> = {}; | ||
public static async fastCacheMaxId(itemId: ItemId): Promise<Resource | false> { | ||
if (itemId === undefined) return false; | ||
return MaxTrack._idMap[itemId]; | ||
} | ||
public static async getMaxId(itemId: ItemId | undefined): Promise<Resource | false> { | ||
if (itemId === undefined) return false; | ||
|
||
const idMapping = MaxTrack._idMap[itemId]; | ||
if (idMapping !== undefined) return idMapping; | ||
|
||
const extTrackItem = await ExtendedTrackItem.get(itemId); | ||
const trackItem = extTrackItem?.trackItem; | ||
if (trackItem !== undefined && hasHiRes(trackItem)) return false; | ||
|
||
const isrcs = await extTrackItem?.isrcs(); | ||
if (isrcs === undefined) return (this._idMap[itemId] = Promise.resolve(false)); | ||
|
||
return (this._idMap[itemId] = (async () => { | ||
for (const isrc of isrcs) { | ||
for await (const { resource } of fetchIsrcIterable(isrc)) { | ||
if (resource?.id !== undefined && hasHiRes(<TrackItem>resource)) { | ||
if (resource.artifactType !== "track") continue; | ||
const maxTrackItem = await TrackItemCache.ensure(resource?.id); | ||
if (maxTrackItem !== undefined && !hasHiRes(maxTrackItem)) continue; | ||
else return resource; | ||
} | ||
} | ||
} | ||
return false; | ||
})()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { actions } from "@neptune"; | ||
import type { ItemId, MediaItem, TrackItem } from "neptune-types/tidal"; | ||
import { interceptPromise } from "../intercept/interceptPromise"; | ||
import { SharedObjectStoreExpirable } from "../storage/SharedObjectStoreExpirable"; | ||
import { retryPending } from "./retryPending"; | ||
|
||
import { libTrace } from "../trace"; | ||
|
||
export class PlaylistCache { | ||
private static readonly _trackItemsCache: SharedObjectStoreExpirable<ItemId, { playlistUUID: ItemId; trackItems: TrackItem[] }> = new SharedObjectStoreExpirable("PlaylistCache.trackItems", { | ||
maxAge: 30000, | ||
storeSchema: { keyPath: "playlistUUID" }, | ||
}); | ||
public static async getTrackItems(playlistUUID?: ItemId) { | ||
if (playlistUUID === undefined) return undefined; | ||
|
||
let playlistTrackItems = await this._trackItemsCache.get(playlistUUID); | ||
const updatePromise = this.updateTrackItems(playlistUUID); | ||
if (playlistTrackItems?.trackItems !== undefined) return playlistTrackItems.trackItems; | ||
return updatePromise; | ||
} | ||
public static async updateTrackItems(playlistUUID: ItemId) { | ||
const result = await interceptPromise( | ||
() => actions.content.loadListItemsPage({ loadAll: true, listName: `playlists/${playlistUUID}`, listType: "mediaItems" }), | ||
["content/LOAD_LIST_ITEMS_PAGE_SUCCESS"], | ||
["content/LOAD_LIST_ITEMS_PAGE_FAIL"], | ||
{ timeoutMs: 2000 } | ||
).catch(libTrace.warn.withContext("PlaylistCache.getTrackItems.interceptPromise")); | ||
if (result?.[0]?.items === undefined) { | ||
const playlistTrackItems = await this._trackItemsCache.get(playlistUUID); | ||
return playlistTrackItems?.trackItems; | ||
} | ||
const trackItems = Array.from((<Immutable.List<MediaItem>>result?.[0]?.items).map((mediaItem) => mediaItem?.item).filter((item) => item?.contentType === "track")); | ||
await this._trackItemsCache.put({ playlistUUID, trackItems }); | ||
return trackItems; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export const retryPending = <V>(getter: () => Promise<V>): Promise<V | undefined> => | ||
new Promise((res) => { | ||
const timeout = setTimeout(() => { | ||
clearInterval(interval); | ||
res(undefined); | ||
}, 5000); | ||
const interval = setInterval(async () => { | ||
const value = await getter(); | ||
if (value !== undefined) { | ||
res(value); | ||
clearInterval(interval); | ||
clearTimeout(timeout); | ||
} | ||
}, 100); | ||
}); |
Oops, something went wrong.