/** * Resolve a coordinate to the JMA class10 warning area that contains it, and * load the geometry artifact that makes that possible. * * Two halves, deliberately separable: * * - `resolveJmaArea` is pure and zero-I/O — it takes the area table as an * argument, so a test can drive it with three hand-written rings and never * touch the 285 KB artifact (design pattern 6 in CLAUDE.md). * - `loadJmaAreas` is the artifact's single call site: a memoised dynamic * `import()` of `../data/jmaAreas.js`, so a server that never answers a * Japanese request never pays for parsing it. * * **This is not the optional-dependency pattern.** `src/data/jmaAreas.ts` is * committed and compiled beside every other module, so it is *always present*. * A failure to load it is therefore a **fault, not an absence**: it throws a * fixed message, it is deliberately **not** memoised (the next caller retries), * and it is never classified by `error.code` the way `blitzortung.ts` classifies * a missing `mqtt`. There is no third "absent" state here, and adding one would * turn a broken build into a silent no-coverage answer. * * **Contract, not garnish (G24).** Before this module existed the geometry * would have been a static import, failing loudly at startup for every reason * it might be unusable. A lazy import narrows that to the reasons the call site * explicitly handles and routes the rest into whatever `catch` sits above it. * So every failure here propagates as `JmaAreaDataUnavailableError`, and the * caller must never render it as "no warnings for this location" — that is a * fabricated all-clear on safety data. */ import type { JmaClass10Area } from '../data/jmaAreas.js'; export type { JmaClass10Area }; /** * The geometry artifact could not be loaded. * * A plain `Error` with a fixed, pre-written message: `ApiServiceName` in * `src/errors/ApiError.ts` is a closed union and JMA stays outside it, exactly * as FIRMS and the other peripheral services do. The message names no path, no * module specifier and no underlying error — those go to the structured log. */ export declare class JmaAreaDataUnavailableError extends Error { constructor(); } /** * Resolve `(latitude, longitude)` to the class10 area containing it, or * `undefined` when the point lies outside every area (at sea, or outside * Japan). * * Pure: no I/O, no module state, no dependency on load order. * * Two properties of the artifact make the naive first-match loop correct, and * both were verified against the real data when it was generated: * * - **The areas do not overlap.** No point in 24-46 N / 122-154 E falls * inside two areas, so "first match" and "the match" are the same answer * and there is no tiebreak to get wrong. * - **Every area is a candidate, including the one with no issuing office.** * Code `hoppo` has no `officeCode`; it must still resolve here. Whether an * area without an office renders as a coverage disclosure is the renderer's * decision to disclose, never this function's to silently drop (G53) — a * predicate that quietly skipped it would turn "no office publishes * warnings for this area" into "no warnings", which is the opposite claim. * Do not add an `if (!area.officeCode) continue` here. */ export declare function resolveJmaArea(latitude: number, longitude: number, areas: readonly JmaClass10Area[]): JmaClass10Area | undefined; /** * Load the committed class10 geometry, at most once per process. * * Concurrency: the in-flight promise is assigned **synchronously**, before the * first `await` anywhere in this function, so two callers racing on a cold * start receive the same promise and the `import()` happens once (G17, G20). An * `await` above that assignment would let every concurrent caller past the * guard and re-import — the exact shape that opened three MQTT connections in * v1.25.0. * * Failure: `loadPromise` is cleared in the rejection handler and `loadedAreas` * is left `undefined`, so the next caller retries rather than inheriting a * cached failure. Note the retry cannot heal a genuinely broken module in the * same process — Node caches the failed module record and replays the same * rejection — but it does cover a transient fault, and it keeps a one-off * failure from disabling Japanese coverage for the life of the server. */ export declare function loadJmaAreas(): Promise; //# sourceMappingURL=jmaAreaResolver.d.ts.map