mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(search): Nominatim as the last-resort geocoder (#573)
Supersedes #350 by @sendmebits, ported onto the current component layout with fixes from review. Verified before merge: format, package boundaries, unit suite, build, and the browser tracking suite; a browser harness for the change where one applies; adversarial review applied. Co-authored-by: sendmebits <[email protected]>
This commit is contained in:
1 parent
cca6442997
commit
7fa0cfbb26
15 files changed
+1077
-48
No files matched your search
@@ -5,42 +5,52 @@ import {
|
||||
|
||||
const REGIONAL_MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
||||
|
||||
async function fetchRegionalJson(
|
||||
url,
|
||||
{
|
||||
/**
|
||||
* One bounded upstream read for the regional providers.
|
||||
*
|
||||
* The deadline covers the BODY, not just the headers. `return`ing the reader's
|
||||
* promise from inside a try/finally leaves the try block the moment the promise
|
||||
* exists, so the abort timer used to be cleared before a single byte of body had
|
||||
* arrived — an upstream that answered its headers and then stalled had no
|
||||
* deadline at all. Awaiting inside the try keeps the timer alive until the body
|
||||
* is in hand, and the same signal is handed to the reader so an abort stops the
|
||||
* read rather than just the connect.
|
||||
*
|
||||
* `redirect` is stated rather than inherited: feeds that legitimately redirect
|
||||
* (news RSS) follow, and a fixed API endpoint can be given 'error' so a
|
||||
* redirect cannot steer the proxy at a destination this code never named.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {{headers?: object, timeoutMs?: number, maxBytes?: number, redirect?: 'follow'|'error'|'manual'}} [options]
|
||||
*/
|
||||
async function fetchRegional(url, read, options = {}) {
|
||||
const {
|
||||
headers = {},
|
||||
timeoutMs = 9000,
|
||||
maxBytes = REGIONAL_MAX_RESPONSE_BYTES,
|
||||
} = {},
|
||||
) {
|
||||
redirect = 'follow',
|
||||
} = options;
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
const response = await fetch(url, { signal: controller.signal, headers });
|
||||
const response = await fetch(url, {
|
||||
signal: controller.signal,
|
||||
headers,
|
||||
redirect,
|
||||
});
|
||||
if (!response.ok) throw new Error(`Upstream returned ${response.status}`);
|
||||
return readResponseJsonCapped(response, maxBytes);
|
||||
return await read(response, maxBytes, controller.signal);
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchRegionalText(
|
||||
url,
|
||||
{
|
||||
headers = {},
|
||||
timeoutMs = 9000,
|
||||
maxBytes = REGIONAL_MAX_RESPONSE_BYTES,
|
||||
} = {},
|
||||
) {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
const response = await fetch(url, { signal: controller.signal, headers });
|
||||
if (!response.ok) throw new Error(`Upstream returned ${response.status}`);
|
||||
return readResponseTextCapped(response, maxBytes);
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
function fetchRegionalJson(url, options = {}) {
|
||||
return fetchRegional(url, readResponseJsonCapped, options);
|
||||
}
|
||||
|
||||
function fetchRegionalText(url, options = {}) {
|
||||
return fetchRegional(url, readResponseTextCapped, options);
|
||||
}
|
||||
|
||||
export { fetchRegionalJson, fetchRegionalText };
|
||||
Reference in new issue
Block a user