From 4c1ebfb87733359aa344c1a0e92f8a1086a5b56f Mon Sep 17 00:00:00 2001 From: quanticsoul4772 <71096528+quanticsoul4772@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:42:49 -0700 Subject: [PATCH] fix(traffic): pass fetchFlowDetail through the layer's source slot Co-Authored-By: Claude Opus 5.5 --- src/data/traffic.js | 9 +++ src/data/traffic.test.mjs | 124 ++++++++++++++++++++++++++++++++------ 2 files changed, 114 insertions(+), 19 deletions(-) diff --git a/src/data/traffic.js b/src/data/traffic.js index dbab8cb8f..ad77d92a9 100644 --- a/src/data/traffic.js +++ b/src/data/traffic.js @@ -9,9 +9,18 @@ const sourceSlot = createSourceSlot( { getFlowSessionStats: () => ({ tilesFetched: 0 }), resetFlowTileCache: () => {}, + // The layer reads stale cached tiles through this; a source without it + // answers with fresh segments only. + fetchFlowDetail: async (...args) => ({ + segments: await sourceSlot.source.fetchFlowForBounds(...args), + stale: false, + oldestTileAt: null, + }), }, ); export const configureTrafficSource = sourceSlot.configure; +/** The source the traffic layer reads, as configured. */ +export const trafficSource = sourceSlot.source; const layer = createApplicationTraffic({ source: sourceSlot.source, }); diff --git a/src/data/traffic.test.mjs b/src/data/traffic.test.mjs index 04739e200..23924448a 100644 --- a/src/data/traffic.test.mjs +++ b/src/data/traffic.test.mjs @@ -22,7 +22,10 @@ import { DataLayerManager, layerFeedState } from './manager.js'; const LIVE_CLAIM = /\bLIVE\b|\bGPS\b|\breal[- ]?time\b/; test('a superseded flow fetch is not an outage', () => { - assert.equal(deriveTrafficFlowError({ name: 'AbortError', message: 'aborted' }), null); + assert.equal( + deriveTrafficFlowError({ name: 'AbortError', message: 'aborted' }), + null, + ); assert.equal(deriveTrafficFlowError(null), null); assert.equal(deriveTrafficFlowError(undefined), null); }); @@ -30,10 +33,22 @@ test('a superseded flow fetch is not an outage', () => { test('flow failures map onto short, specific reasons', () => { const reason = (message) => deriveTrafficFlowError(new Error(message)); assert.equal(reason('flow tile 12/1/1: HTTP 503'), 'TomTom key unavailable'); - assert.equal(reason('flow tile 12/1/1: HTTP 429'), 'TomTom daily budget reached'); - assert.equal(reason('flow tile 12/1/1: HTTP 502'), 'TomTom upstream unreachable'); - assert.equal(reason('flow tile 12/1/1: HTTP 504'), 'TomTom upstream unreachable'); - assert.equal(reason('flow tile 12/1/1: HTTP 418'), 'TomTom flow error (HTTP 418)'); + assert.equal( + reason('flow tile 12/1/1: HTTP 429'), + 'TomTom daily budget reached', + ); + assert.equal( + reason('flow tile 12/1/1: HTTP 502'), + 'TomTom upstream unreachable', + ); + assert.equal( + reason('flow tile 12/1/1: HTTP 504'), + 'TomTom upstream unreachable', + ); + assert.equal( + reason('flow tile 12/1/1: HTTP 418'), + 'TomTom flow error (HTTP 418)', + ); assert.equal(reason('flow fetch failed'), 'TomTom flow unavailable'); }); @@ -56,19 +71,32 @@ test('no keyless label ever implies a live feed', () => { trafficFeedPresentation({ liveMode: false, fetching: false }), trafficFeedPresentation({ liveMode: false, fetching: true }), trafficFeedPresentation({ statusUnavailable: true }), - trafficFeedPresentation({ liveMode: true, flowError: 'TomTom flow unavailable' }), - trafficFeedPresentation({ liveMode: true, fetching: true, flowError: 'TomTom flow unavailable' }), + trafficFeedPresentation({ + liveMode: true, + flowError: 'TomTom flow unavailable', + }), + trafficFeedPresentation({ + liveMode: true, + fetching: true, + flowError: 'TomTom flow unavailable', + }), ].map((feed) => feed.loadingLabel); for (const label of labels) { assert.ok(!LIVE_CLAIM.test(label), `label implies live data: ${label}`); - assert.ok(label.startsWith('SIMULATED'), `fallback label must lead with the mode: ${label}`); + assert.ok( + label.startsWith('SIMULATED'), + `fallback label must lead with the mode: ${label}`, + ); } }); test('simulating because the status probe failed reads differently from keyless by design', () => { const probeDown = trafficFeedPresentation({ statusUnavailable: true }); assert.equal(probeDown.mode, 'sim'); - assert.equal(probeDown.loadingLabel, 'SIMULATED — traffic service unreachable'); + assert.equal( + probeDown.loadingLabel, + 'SIMULATED — traffic service unreachable', + ); }); test('a healthy keyed layer reports live flow with its real coverage', () => { @@ -76,7 +104,8 @@ test('a healthy keyed layer reports live flow with its real coverage', () => { assert.deepEqual(idle, { mode: 'live', error: null, - loadingLabel: 'LIVE · Roads: OpenStreetMap · Flow: TomTom · 87% cov · Unmatched: simulated', + loadingLabel: + 'LIVE · Roads: OpenStreetMap · Flow: TomTom · 87% cov · Unmatched: simulated', }); assert.equal( trafficFeedPresentation({ liveMode: true, fetching: true }).loadingLabel, @@ -100,7 +129,11 @@ test('a mid-session flow outage degrades instead of reporting stale live coverag fetching: true, flowError: 'TomTom daily budget reached', }); - assert.deepEqual(busy, down, 'the degraded state reads the same whether or not a load is in flight'); + assert.deepEqual( + busy, + down, + 'the degraded state reads the same whether or not a load is in flight', + ); }); test('the rendered steady-state meta line carries the SIMULATED copy', () => { @@ -116,10 +149,12 @@ test('the rendered steady-state meta line carries the SIMULATED copy', () => { assert.equal( mgr._buildMetaText({ source: 'OpenStreetMap', - stats: stats(trafficFeedPresentation({ - liveMode: true, - flowError: 'TomTom daily budget reached', - })), + stats: stats( + trafficFeedPresentation({ + liveMode: true, + flowError: 'TomTom daily budget reached', + }), + ), }), 'DEGRADED · OpenStreetMap · SIMULATED — TomTom daily budget reached', ); @@ -128,17 +163,26 @@ test('the rendered steady-state meta line carries the SIMULATED copy', () => { test('the manager reads keyless as FALLBACK and an outage as DEGRADED', () => { const settled = { count: 4200, lastUpdate: Date.now() }; assert.equal( - layerFeedState({ ...settled, ...trafficFeedPresentation({ liveMode: false }) }), + layerFeedState({ + ...settled, + ...trafficFeedPresentation({ liveMode: false }), + }), 'fallback', ); assert.equal( - layerFeedState({ ...settled, ...trafficFeedPresentation({ liveMode: true }) }), + layerFeedState({ + ...settled, + ...trafficFeedPresentation({ liveMode: true }), + }), 'nominal', ); assert.equal( layerFeedState({ ...settled, - ...trafficFeedPresentation({ liveMode: true, flowError: 'TomTom flow unavailable' }), + ...trafficFeedPresentation({ + liveMode: true, + flowError: 'TomTom flow unavailable', + }), }), 'degraded', ); @@ -148,7 +192,10 @@ test('the shipped layer boots keyless-honest before any status check', () => { const stats = trafficLayer.getStats(); assert.equal(stats.mode, 'sim'); assert.equal(stats.error, null); - assert.ok(!LIVE_CLAIM.test(stats.loadingLabel), `boot label implies live data: ${stats.loadingLabel}`); + assert.ok( + !LIVE_CLAIM.test(stats.loadingLabel), + `boot label implies live data: ${stats.loadingLabel}`, + ); assert.equal(layerFeedState(stats), 'fallback'); }); @@ -167,3 +214,42 @@ test('zero matched dots never claims live coverage', () => { assert.match(feed.loadingLabel, /TomTom \(no matches\)/); assert.ok(!LIVE_CLAIM.test(feed.loadingLabel)); }); + +test('the traffic layer source passes fetchFlowDetail through, so stale tiles reach the layer', async () => { + const { trafficSource, configureTrafficSource } = + await import('./traffic.js'); + assert.equal(typeof trafficSource.fetchFlowDetail, 'function'); + const base = { + requestRoads: async () => ({}), + getStatus: async () => ({}), + fetchFlowForBounds: async () => ['segment'], + }; + let release = configureTrafficSource({ + ...base, + fetchFlowDetail: async () => ({ + segments: ['segment'], + stale: true, + oldestTileAt: 1000, + }), + }); + try { + assert.deepEqual(await trafficSource.fetchFlowDetail({}), { + segments: ['segment'], + stale: true, + oldestTileAt: 1000, + }); + } finally { + release(); + } + // A source without fetchFlowDetail answers with fresh segments. + release = configureTrafficSource(base); + try { + assert.deepEqual(await trafficSource.fetchFlowDetail({}), { + segments: ['segment'], + stale: false, + oldestTileAt: null, + }); + } finally { + release(); + } +});