perf: use undici instead of axios

This commit is contained in:
Starcea 2024-11-02 14:00:41 +09:00
commit 5a15d50cfc
No known key found for this signature in database
GPG key ID: B7A77E32374911E1
5 changed files with 59 additions and 97 deletions

View file

@ -1,6 +1,6 @@
import axios from 'axios'
import { BASE_URL, USER_AGENT } from './constants'
import DataManager from './data'
import HTTP from './http'
import School from './models/School'
import type { Timetable } from './models/Timetable'
import { mergeMap } from './utils/array'
@ -8,24 +8,22 @@ import { encodeBase64, encodeEUCKR } from './utils/encode'
import { parseResponse } from './utils/parse'
export default class Comcigan {
private readonly rest = axios.create({
private readonly http = new HTTP({
baseURL: BASE_URL,
headers: {
'User-Agent': USER_AGENT,
},
headers: { 'User-Agent': USER_AGENT },
})
private readonly dataManager = new DataManager(this.rest)
private readonly dataManager = new DataManager(this.http)
/** 학교를 검색합니다. */
async searchSchools(schoolName: string): Promise<School[]> {
const { mainRoute, searchRoute } = await this.dataManager.getData()
const res = await this.rest.get(
`${mainRoute}?${searchRoute}l${encodeEUCKR(schoolName)}`,
)
const res = await this.http
.get(`${mainRoute}?${searchRoute}l${encodeEUCKR(schoolName)}`)
.then((res) => res.body.text())
const { 학교검색: data } = parseResponse<{
: [number, string, string, number][]
}>(res.data)
}>(res)
return data.map(
([regionCode, regionName, schoolName, schoolCode]) =>
@ -48,10 +46,12 @@ export default class Comcigan {
dayCode,
subjectCode,
} = await this.dataManager.getData()
const res = await this.rest.get(
`${mainRoute}_T?${encodeBase64(`${timetableRoute}_${schoolCode}_0_1`)}`,
)
const data = parseResponse(res.data)
const res = await this.http
.get(
`${mainRoute}_T?${encodeBase64(`${timetableRoute}_${schoolCode}_0_1`)}`,
)
.then((res) => res.body.text())
const data = parseResponse(res)
const teachers = data[`자료${teacherCode}`] as string[]
const teachersLen = Math.floor(Math.log10(teachers.length - 1)) + 1

View file

@ -1,6 +1,6 @@
import type { AxiosInstance } from 'axios'
import { decode } from 'iconv-lite'
import { RegExes } from './constants'
import type HTTP from './http'
interface Data {
mainRoute: string
@ -18,13 +18,11 @@ export default class DataManager {
private _lastFetchDate = 0
constructor(private readonly rest: AxiosInstance) {}
constructor(private readonly http: HTTP) {}
private async fetchData(): Promise<Data> {
const res = await this.rest.get('/st', {
responseType: 'arraybuffer',
})
const data = decode(Buffer.from(res.data), 'euc-kr')
const res = await this.http.get('/st').then((res) => res.body.arrayBuffer())
const data = decode(Buffer.from(res), 'euc-kr')
const main = RegExes.MainRoute.exec(data)
if (!main) throw new Error('Failed to fetch main route')

20
src/http.ts Normal file
View file

@ -0,0 +1,20 @@
import { request } from 'undici'
export default class HTTP {
private readonly baseURL: string
private readonly headers: Record<string, string>
constructor({
baseURL,
headers,
}: { baseURL: string; headers: Record<string, string> }) {
this.baseURL = baseURL
this.headers = headers
}
async get(url: string) {
return request(`${new URL(url, this.baseURL)}`, {
headers: this.headers,
})
}
}