bandcamp-fetch/src/lib/BandcampFetch.ts
2023-10-30 01:13:03 +08:00

148 lines
4.8 KiB
TypeScript

import Bottleneck from 'bottleneck';
import AlbumAPI, { LimiterAlbumAPI } from './album/AlbumAPI.js';
import ArticleAPI, { LimiterArticleAPI } from './article/ArticleAPI.js';
import AutocompleteAPI, { LimiterAutocompleteAPI } from './autocomplete/AutocompleteAPI.js';
import BandAPI, { LimiterBandAPI } from './band/BandAPI.js';
import DiscoveryAPI, { LimiterDiscoveryAPI } from './discovery/DiscoveryAPI.js';
import FanAPI, { LimiterFanAPI } from './fan/FanAPI.js';
import ImageAPI, { LimiterImageAPI } from './image/ImageAPI.js';
import SearchAPI, { LimiterSearchAPI } from './search/SearchAPI.js';
import ShowAPI, { LimiterShowAPI } from './show/ShowAPI.js';
import TagAPI, { LimiterTagAPI } from './tag/TagAPI.js';
import TrackAPI, { LimiterTrackAPI } from './track/TrackAPI.js';
import Cache, { CacheDataType } from './utils/Cache.js';
import Fetcher from './utils/Fetcher.js';
import Limiter from './utils/Limiter.js';
import StreamAPI, { LimiterStreamAPI } from './stream/StreamAPI.js';
export interface BandcampFetchParams {
cookie?: string | null;
}
export default class BandcampFetch {
#cookie?: string | null;
#fetcher: Fetcher;
#cache: Cache;
#wrappedCache: CacheWrapper;
#limiter: Limiter;
readonly album: AlbumAPI;
readonly track: TrackAPI;
readonly discovery: DiscoveryAPI;
readonly image: ImageAPI;
readonly band: BandAPI;
readonly tag: TagAPI;
readonly article: ArticleAPI;
readonly show: ShowAPI;
readonly fan: FanAPI;
readonly search: SearchAPI;
readonly autocomplete: AutocompleteAPI;
readonly stream: StreamAPI;
readonly limiter: {
readonly album: LimiterAlbumAPI;
readonly track: LimiterTrackAPI;
readonly discovery: LimiterDiscoveryAPI;
readonly image: LimiterImageAPI;
readonly band: LimiterBandAPI;
readonly tag: LimiterTagAPI;
readonly article: LimiterArticleAPI;
readonly show: LimiterShowAPI;
readonly fan: LimiterFanAPI;
readonly search: LimiterSearchAPI;
readonly autocomplete: LimiterAutocompleteAPI;
readonly stream: StreamAPI;
updateSettings: (options?: Bottleneck.ConstructorOptions) => void;
};
constructor(params?: BandcampFetchParams) {
this.#cookie = params?.cookie;
this.#cache = new Cache({
[CacheDataType.Constants]: 3600,
[CacheDataType.Page]: 300
}, { page: 10 });
this.#wrappedCache = new CacheWrapper(this.#cache);
this.#fetcher = new Fetcher({
cookie: this.#cookie,
cache: this.#cache
});
this.#limiter = new Limiter();
const baseAPIParams = {
fetcher: this.#fetcher,
cache: this.#cache,
limiter: this.#limiter
};
this.image = new ImageAPI(baseAPIParams);
const baseAPIWithImageSupportParams = {
...baseAPIParams,
imageAPI: this.image
};
this.album = new AlbumAPI(baseAPIWithImageSupportParams);
this.track = new TrackAPI(baseAPIWithImageSupportParams);
this.discovery = new DiscoveryAPI(baseAPIWithImageSupportParams);
this.image = new ImageAPI(baseAPIParams);
this.band = new BandAPI(baseAPIWithImageSupportParams);
this.tag = new TagAPI(baseAPIWithImageSupportParams);
this.article = new ArticleAPI(baseAPIWithImageSupportParams);
this.show = new ShowAPI(baseAPIWithImageSupportParams);
this.fan = new FanAPI(baseAPIWithImageSupportParams);
this.search = new SearchAPI(baseAPIWithImageSupportParams);
this.autocomplete = new AutocompleteAPI(baseAPIParams);
this.stream = new StreamAPI(baseAPIParams);
this.limiter = {
album: new LimiterAlbumAPI(baseAPIWithImageSupportParams),
track: new LimiterTrackAPI(baseAPIWithImageSupportParams),
discovery: new LimiterDiscoveryAPI(baseAPIWithImageSupportParams),
image: new LimiterImageAPI(baseAPIParams),
band: new LimiterBandAPI(baseAPIWithImageSupportParams),
tag: new LimiterTagAPI(baseAPIWithImageSupportParams),
article: new LimiterArticleAPI(baseAPIWithImageSupportParams),
show: new LimiterShowAPI(baseAPIWithImageSupportParams),
fan: new LimiterFanAPI(baseAPIWithImageSupportParams),
search: new LimiterSearchAPI(baseAPIWithImageSupportParams),
autocomplete: new LimiterAutocompleteAPI(baseAPIParams),
stream: new LimiterStreamAPI(baseAPIParams),
updateSettings: this.#limiter.updateSettings.bind(this.#limiter)
};
}
setCookie(value?: string | null) {
this.#cookie = value;
this.#fetcher.setCookie(value);
}
get cookie() {
return this.#cookie;
}
get cache() {
return this.#wrappedCache;
}
}
export class CacheWrapper {
#cache: Cache;
constructor(cache: Cache) {
this.#cache = cache;
}
clear(type?: CacheDataType) {
this.#cache.clear(type);
}
setTTL(type: CacheDataType, ttl: number) {
this.#cache.setTTL(type, ttl);
}
setMaxPages(maxPages: number) {
this.#cache.setMaxEntries(CacheDataType.Page, maxPages);
}
}