UNPKG

butter-lib

Version:

BuTTER Library は、ストレージ上に細分化した状態で保存されているGTFSを基にした時刻表情報を集め、ブラウザ内で必要な情報に加工するライブラリです。DBを使わずにデータ処理をブラウザ内とする

127 lines (112 loc) 4.29 kB
const helperLib = require('./helper.js') const helper = helperLib.helper export class ButterInternal { constructor (rootCA) { this.CONFIG = {} this.RUNTIME = { isReady: false, readyFlags: { ca: false }, cache: {}, pub_key: '' } this.setCA(rootCA) } /** * CA(証明書発行局)の設定を行います。 * @param {string} rootCA - CAのルートURL。 * @returns {Promise<void>} - 処理が完了したら解決されるPromise。 */ async setCA (rootCA) { console.log('setCA') // 末尾をスラッシュなしに統一する if (!rootCA.endsWith('root.json')) { return // TODO ファイルがなかった場合のエラー処理 } this.CONFIG.rootCA = rootCA let req try { console.log('fetchAndParseJSON this.CONFIG.rootCA', this.CONFIG.rootCA) req = await helper.fetchAndParseJSON(this.CONFIG.rootCA) console.log('req', req) } catch (err) { console.error({ err }) throw new Error('Failed to fetch rootCA') } this.RUNTIME.CA = req this.RUNTIME.pub_key = req.pub_keys[0].pubkey console.log('set') const hostList = [] const oneMouthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) // 30日前の日時を設定します for (let i = 0; i < this.RUNTIME.CA.hosts.length; i++) { const host = this.RUNTIME.CA.hosts[i] try { // ホストからのデータ取得を試みる const data = await helper.fetchJSON(`${host}/datalist.json`, this.RUNTIME.pub_key) if (data.updated === null) continue // updatedをISO 8601形式に変換します const updatedISO = data.updated.replace(/_/g, ':') const updatedDate = new Date(updatedISO) // Dateオブジェクトを生成します if (updatedDate > oneMouthAgo) { // 30日以内に更新されていれば、hostListに追加します hostList.push(host) } } catch (e) { console.log(`Failed to fetch data from ${host}:`, e.message) // エラーメッセージをログに出力 continue // このホストはスキップし、次のホストへ移動 } } console.log('hostList', hostList) // ランダムにホストを選びます if (hostList.length > 0) { const randomIndex = Math.floor(Math.random() * hostList.length) this.RUNTIME.host = hostList[randomIndex] console.log(`host: ${this.RUNTIME.host}`) } else { console.log('there are no host which updated last 30 days.') const randomIndex = Math.floor(Math.random() * this.RUNTIME.CA.hosts.length) this.RUNTIME.host = this.RUNTIME.CA.hosts[randomIndex] console.log(`host: ${this.RUNTIME.host}`) } this.RUNTIME.readyFlags = {} this.RUNTIME.readyFlags.ca = true } /** * CAの準備が完了するまで待機します。 * @returns {Promise<void>} - CAの準備が完了したら解決されるPromise。 */ async waitReady () { while (!this.RUNTIME.isReady) { await helper.sleep(100) if (Object.values(this.RUNTIME.readyFlags).every(e => e)) { this.RUNTIME.isReady = true } } } async waitCAReady () { while (!this.RUNTIME.readyFlags.ca) { console.log('waiting CA ready') await helper.sleep(100) } } /** * 緯度と経度から距離を計算します。 * @param {number} lat1 - 最初の緯度。 * @param {number} lon1 - 最初の経度。 * @param {number} lat2 - 2番目の緯度。 * @param {number} lon2 - 2番目の経度。 * @returns {number} - 計算された距離(km単位)。 */ async distance (lat1, lon1, lat2, lon2) { const R = 6371 // 地球の半径(km) const dLat = (lat2 - lat1) * (Math.PI / 180) const dLon = (lon2 - lon1) * (Math.PI / 180) const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) * Math.sin(dLon / 2) * Math.sin(dLon / 2) const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) return R * c } }