fix: offline download — wait for completion, suppress transient errors
createPack() resolves when the pack is registered, not when tiles are
done downloading. Wrapping in a Promise that resolves only on
status.state === 'complete' keeps the progress modal visible and the
'Download complete' alert fires only when the pack is actually ready.
Transient tile errors ('stream was reset: CANCEL') are silently ignored
in the error listener — MapLibre retries them internally and they do not
indicate a failed download. The onError callback is removed from the
public API since it was causing spurious alerts mid-download.
This commit is contained in:
+30
-18
@@ -22,31 +22,43 @@ export interface OfflineRegion {
|
||||
|
||||
// ── Download ──────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function downloadRegion(
|
||||
/**
|
||||
* Download a region and return a Promise that resolves only when the pack
|
||||
* reaches state 'complete'. Transient tile-fetch errors (e.g. "stream was
|
||||
* reset: CANCEL") are silently ignored — MapLibre retries them internally
|
||||
* and they do not indicate a failed download.
|
||||
*/
|
||||
export function downloadRegion(
|
||||
name: string,
|
||||
bounds: LngLatBounds,
|
||||
onProgress: (pct: number, tilesDown: number, sizeBytes: number) => void,
|
||||
onError: (msg: string) => void,
|
||||
): Promise<string> {
|
||||
OfflineManager.setProgressEventThrottle(500);
|
||||
|
||||
const pack = await OfflineManager.createPack(
|
||||
{
|
||||
mapStyle: OFFLINE_STYLE_URL,
|
||||
bounds,
|
||||
minZoom: MIN_ZOOM,
|
||||
maxZoom: MAX_ZOOM,
|
||||
metadata: { name, createdAt: new Date().toISOString() },
|
||||
},
|
||||
(_pack, status: OfflinePackStatus) => {
|
||||
onProgress(status.percentage, status.completedTileCount, status.completedTileSize);
|
||||
},
|
||||
(_pack, error) => {
|
||||
onError(error.message);
|
||||
},
|
||||
);
|
||||
return new Promise((resolve, reject) => {
|
||||
let packId: string;
|
||||
|
||||
return pack.id;
|
||||
OfflineManager.createPack(
|
||||
{
|
||||
mapStyle: OFFLINE_STYLE_URL,
|
||||
bounds,
|
||||
minZoom: MIN_ZOOM,
|
||||
maxZoom: MAX_ZOOM,
|
||||
metadata: { name, createdAt: new Date().toISOString() },
|
||||
},
|
||||
(pack, status: OfflinePackStatus) => {
|
||||
packId = pack.id;
|
||||
onProgress(status.percentage, status.completedTileCount, status.completedTileSize);
|
||||
if (status.state === 'complete') {
|
||||
resolve(packId);
|
||||
}
|
||||
},
|
||||
(_pack, _error) => {
|
||||
// Transient tile-level errors — MapLibre retries these automatically.
|
||||
// Do not reject: the overall download is still in progress.
|
||||
},
|
||||
).catch(reject); // only rejects on createPack failure (e.g. bad style URL)
|
||||
});
|
||||
}
|
||||
|
||||
// ── List ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user