From e25cce874d56418ac2480d255a402eb3d906653e Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Thu, 12 Nov 2026 15:52:31 -0800 Subject: [PATCH] Read an ArcGIS load stopped at maxFeatures as truncated Paging stopped once maxFeatures were read before it noted that the upstream had more, so a page holding exactly the cap with exceededTransferLimit set read as the whole dataset. FEMA USA Structures (2,000 features, one page) never showed PARTIAL in a dense view. Stopping at the cap or the last page with more upstream now marks the load truncated. --- src/library/formats.js | 11 +++++++++-- src/library/formats.test.mjs | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/library/formats.js b/src/library/formats.js index e603a1276..c3d887997 100644 --- a/src/library/formats.js +++ b/src/library/formats.js @@ -429,8 +429,15 @@ export async function loadLibraryDataset( const parsed = parseLibraryBody('arcgis', await readPage(url, budget)); candidates.push(...parsed.candidates); if (!parsed.exceededTransferLimit || !parsed.candidates.length) break; - if (candidates.length >= source.maxFeatures) break; - if (page === source.maxPages - 1) truncated = true; + // The upstream holds more than was read: stopping here, at the + // feature cap or the last page, leaves the dataset partial. + if ( + candidates.length >= source.maxFeatures || + page === source.maxPages - 1 + ) { + truncated = true; + break; + } } } else { const parsed = parseLibraryBody( diff --git a/src/library/formats.test.mjs b/src/library/formats.test.mjs index 4337ba818..fe164e4c7 100644 --- a/src/library/formats.test.mjs +++ b/src/library/formats.test.mjs @@ -182,6 +182,27 @@ test('ArcGIS paging follows exceededTransferLimit up to maxPages', async () => { assert.equal(collection.truncated, true); }); +test('ArcGIS stopping at maxFeatures with more upstream reads as truncated', async () => { + const value = entry({ + format: 'arcgis', + url: 'https://s.example.org/FeatureServer/0', + maxFeatures: 3, + maxPages: 5, + }); + let pages = 0; + const collection = await loadLibraryDataset(value, async () => { + pages += 1; + return JSON.stringify({ + type: 'FeatureCollection', + properties: { exceededTransferLimit: true }, + features: [point(1, 0), point(2, 0), point(3, 0)], + }); + }); + assert.equal(pages, 1); + assert.equal(collection.features.length, 3); + assert.equal(collection.truncated, true); +}); + test('a plain dataset request carries the manifest query once', async () => { const value = entry({ format: 'geojson',