diff --git a/apps/planner/app/lib/brouter.ts b/apps/planner/app/lib/brouter.ts index 76b7450..36e8b65 100644 --- a/apps/planner/app/lib/brouter.ts +++ b/apps/planner/app/lib/brouter.ts @@ -79,22 +79,27 @@ export async function readBodyWithCap(response: Response, maxBytes: number): Pro if (Number.isFinite(declared) && declared > maxBytes) { throw new BRouterError(`response too large (${declared} bytes)`, 502); } - // Stream the body, abort once we've seen `maxBytes`. + // Stream the body, abort once we've seen `maxBytes`. The read + + // done-check live in the for header so the loop reads as "iterate + // over reads until done"; TS narrows `chunk.value` to Uint8Array + // inside the body because the false-done branch rules out + // `{ done: true, value: undefined }`. const reader = response.body?.getReader(); if (!reader) return await response.text(); const decoder = new TextDecoder(); let received = 0; let out = ""; - // eslint-disable-next-line no-constant-condition - while (true) { - const { value, done } = await reader.read(); - if (done) break; - received += value.byteLength; + for ( + let chunk = await reader.read(); + !chunk.done; + chunk = await reader.read() + ) { + received += chunk.value.byteLength; if (received > maxBytes) { try { await reader.cancel(); } catch { /* ignore */ } throw new BRouterError(`response exceeded ${maxBytes} bytes`, 502); } - out += decoder.decode(value, { stream: true }); + out += decoder.decode(chunk.value, { stream: true }); } out += decoder.decode(); return out; diff --git a/packages/gpx/src/parse.ts b/packages/gpx/src/parse.ts index d9589aa..1ea7faa 100644 --- a/packages/gpx/src/parse.ts +++ b/packages/gpx/src/parse.ts @@ -15,21 +15,6 @@ async function getDOMParser(): Promise { return _LinkedDOMParser; } -export function parseGpx(xml: string): GpxData { - // Synchronous path for browser - if (typeof DOMParser !== "undefined") { - return parseGpxWithParser(new DOMParser(), xml); - } - // Fallback: try linkedom synchronously (works in Node with top-level await or CJS) - try { - // eslint-disable-next-line @typescript-eslint/no-require-imports - const { DOMParser: LP } = require("linkedom"); - return parseGpxWithParser(new LP() as unknown as DOMParser, xml); - } catch { - throw new Error("DOMParser not available — install linkedom"); - } -} - export async function parseGpxAsync(xml: string): Promise { const Parser = await getDOMParser(); return parseGpxWithParser(new Parser(), xml);