뷰포트에 관계없이 백엔드 캐시의 전체 선박을 검색 가능하도록 개선.
- backend: GET /api/vessels/all 엔드포인트 추가 (getAllVessels)
- vesselSignalClient: onAllVessels? 콜백 추가; PollingClient는 3분마다 pollAll(), WS Client는 필터링 전 전송
- useVesselSignals: { vessels, allVessels } 반환, 초기 스냅샷도 allVessels에 반영
- MapView: allVessels prop 추가, VesselSearchBar에 우선 전달
- OilSpillView/HNSView/RescueView/IncidentsView: allVessels 구조분해 후 MapView/VesselSearchBar에 전달
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import type { VesselPosition, BoundingBox } from './vesselTypes.js';
|
|
|
|
const VESSEL_TTL_MS = 10 * 60 * 1000; // 10분
|
|
|
|
const cachedVessels = new Map<string, VesselPosition>();
|
|
let lastUpdated: Date | null = null;
|
|
|
|
// lastUpdate가 TTL을 초과한 선박을 캐시에서 제거.
|
|
// lastUpdate 파싱이 불가능한 경우 보수적으로 유지한다.
|
|
function evictStale(): void {
|
|
const now = Date.now();
|
|
for (const [mmsi, vessel] of cachedVessels) {
|
|
const ts = Date.parse(vessel.lastUpdate);
|
|
if (Number.isNaN(ts)) continue;
|
|
if (now - ts > VESSEL_TTL_MS) {
|
|
cachedVessels.delete(mmsi);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function updateVesselCache(vessels: VesselPosition[]): void {
|
|
for (const vessel of vessels) {
|
|
if (!vessel.mmsi) continue;
|
|
cachedVessels.set(vessel.mmsi, vessel);
|
|
}
|
|
evictStale();
|
|
lastUpdated = new Date();
|
|
}
|
|
|
|
export function getVesselsInBounds(bounds: BoundingBox): VesselPosition[] {
|
|
const result: VesselPosition[] = [];
|
|
for (const v of cachedVessels.values()) {
|
|
if (
|
|
v.lon >= bounds.minLon &&
|
|
v.lon <= bounds.maxLon &&
|
|
v.lat >= bounds.minLat &&
|
|
v.lat <= bounds.maxLat
|
|
) {
|
|
result.push(v);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function getAllVessels(): VesselPosition[] {
|
|
return Array.from(cachedVessels.values());
|
|
}
|
|
|
|
export function getCacheStatus(): {
|
|
count: number;
|
|
bangjeCount: number;
|
|
lastUpdated: Date | null;
|
|
} {
|
|
let bangjeCount = 0;
|
|
for (const v of cachedVessels.values()) {
|
|
if (v.shipNm && v.shipNm.toUpperCase().includes('BANGJE')) bangjeCount++;
|
|
}
|
|
return { count: cachedVessels.size, bangjeCount, lastUpdated };
|
|
}
|