1import { md5 } from "../library/md5.wasm.min.js"; 2import { Sleep } from "./functions.js"; 3import { TCache } from "./tun.cache.js"; 4 5// const BASE_URL = 'https://api.jikan.moe/v4' //TODO: ÐеÑеделаÑÑ 6const BASE_URL = 'https://api.tunime.app/v4'; 7 8class JikanControls { 9 static instance = null; 10 11 constructor() { 12 if (JikanControls.instance) return JikanControls.instance; 13 14 this.cache = new TCache(); 15 JikanControls.instance = this; 16 } 17 18 async hash(url) { 19 return await md5(url); 20 } 21 22 async fetch(url, init, cache, ttl, e) { 23 const hash = await this.hash(url.href); 24 25 if (cache) { 26 const cachedData = await this.cache.get("requests", hash); 27 if (cachedData) { 28 e(cachedData); 29 return cachedData; 30 } 31 } 32 33 return _fetch.bind(this)(); 34 35 function _fetch() { 36 return new Promise((resolve) => { 37 fetch(url, { ...init }).then(async (response) => { 38 if (!response.ok) { 39 if (response.status == 429) { 40 await Sleep(1200); 41 return _fetch(); 42 } 43 return new Error(`ÐÑибка API: ${response.status}`); 44 } 45 46 response.json().then(async value => { 47 if (cache) { 48 await this.cache.put("requests", hash, value, ttl); 49 } 50 e(value); 51 resolve(value); 52 }); 53 }).catch(err => { 54 if (err?.name === "tabort") return; 55 throw err; 56 }); 57 }); 58 } 59 } 60} 61 62export const Jikan = { 63 anime: { 64 getAnimeFullById: (id, e = () => { }) => { 65 const control = new JikanControls(); 66 const url = new URL(`${BASE_URL}/anime/${id}/full`); 67 68 return { 69 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 70 return control.fetch(url, init, cache, ttl, e); 71 } 72 } 73 }, 74 getAnimeSearch: (params = {}, e = () => { }) => { 75 const control = new JikanControls(); 76 const url = new URL(`${BASE_URL}/anime`); 77 78 Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value)); 79 80 return { 81 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 82 return control.fetch(url, init, cache, ttl, e); 83 } 84 } 85 }, 86 getAnimeCharacters: (id, e = () => { }) => { 87 const control = new JikanControls(); 88 const url = new URL(`${BASE_URL}/anime/${id}/characters`); 89 90 return { 91 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 92 return control.fetch(url, init, cache, ttl, e); 93 } 94 } 95 } 96 }, 97 producers: { 98 getProducerById: (id, e = () => { }) => { 99 const control = new JikanControls(); 100 const url = new URL(`${BASE_URL}/producers/${id}`); 101 102 return { 103 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 104 return control.fetch(url, init, cache, ttl, e); 105 } 106 } 107 }, 108 getProducers: (params = {}, e = () => { }) => { 109 const control = new JikanControls(); 110 const url = new URL(`${BASE_URL}/producers`); 111 112 Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value)); 113 114 return { 115 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 116 return control.fetch(url, init, cache, ttl, e); 117 } 118 } 119 } 120 }, 121 seasons: { 122 getSeasonNow: (params = {}, e = () => { }) => { 123 const control = new JikanControls(); 124 const url = new URL(`${BASE_URL}/seasons/now`); 125
126 Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value)); 127 128 return { 129 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 130 return control.fetch(url, init, cache, ttl, e); 131 } 132 } 133 }, 134 getSeason: (year, season, params = {}, e = () => { }) => { 135 const control = new JikanControls(); 136 const url = new URL(`${BASE_URL}/seasons/${year}/${season}`); 137 138 Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value)); 139 140 return { 141 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 142 return control.fetch(url, init, cache, ttl, e); 143 } 144 } 145 }, 146 getSeasonsList: (e = () => { }) => { 147 const control = new JikanControls(); 148 const url = new URL(`${BASE_URL}/seasons`); 149 150 return { 151 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 152 return control.fetch(url, init, cache, ttl, e); 153 } 154 } 155 } 156 }, 157 random: { 158 getRandomAnime: (e = () => { }) => { 159 const control = new JikanControls(); 160 const url = new URL(`${BASE_URL}/random/anime`); 161 162 return { 163 GET: (init = {}, cache = false, ttl = 0) => { 164 return control.fetch(url, init, cache, ttl, e); 165 } 166 } 167 } 168 }, 169 recommendations: { 170 getRecentAnimeRecommendations: (params = {}, e = () => { }) => { 171 const control = new JikanControls(); 172 const url = new URL(`${BASE_URL}/recommendations/anime`); 173 174 Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value)); 175 176 return { 177 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 178 return control.fetch(url, init, cache, ttl, e); 179 } 180 } 181 } 182 }, 183 characters: { 184 getCharacterFullById: (id, e = () => { }) => { 185 const control = new JikanControls(); 186 const url = new URL(`${BASE_URL}/characters/${id}/full`); 187 188 return { 189 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 190 return control.fetch(url, init, cache, ttl, e); 191 } 192 } 193 }, 194 195 getCharacterPictures: (id, e = () => { }) => { 196 const control = new JikanControls(); 197 const url = new URL(`${BASE_URL}/characters/${id}/pictures`); 198 199 return { 200 GET: (init = {}, cache = true, ttl = 60 * 60 * 1000) => { 201 return control.fetch(url, init, cache, ttl, e); 202 } 203 } 204 } 205 } 206}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.