@@ -24,6 +24,7 @@ const AppState = {
2424 preparedGtfsSource : null ,
2525 routeRuntimeSource : null ,
2626 loadedRuntimeRouteIds : new Set ( ) ,
27+ resolvedRuntimeRouteIds : new Set ( ) ,
2728 loadingRuntimeRouteIds : new Set ( ) ,
2829 routeRuntimeRequestSeq : 0 ,
2930 lastRequestedRuntimeRouteId : null ,
@@ -1168,10 +1169,12 @@ function setRuntimeCollectionsState(runtimeData) {
11681169 if ( Array . isArray ( runtimeData ?. calendarDateRows ) ) AppState . calendarDateRows = runtimeData . calendarDateRows ;
11691170 AppState . tariffIndex = runtimeData ?. tariffIndex || { } ;
11701171 if ( runtimeData ?. tripCountBySid ) AppState . tripCountBySid = runtimeData . tripCountBySid ;
1171- AppState . loadedRuntimeRouteIds = new Set ( [
1172+ const presentRouteIds = new Set ( [
11721173 ...AppState . trips . map ( ( trip ) => String ( trip ?. rid || '' ) . trim ( ) ) . filter ( Boolean ) ,
11731174 ...AppState . shapes . map ( ( shape ) => String ( shape ?. rid || '' ) . trim ( ) ) . filter ( Boolean ) ,
11741175 ] ) ;
1176+ AppState . loadedRuntimeRouteIds = presentRouteIds ;
1177+ AppState . resolvedRuntimeRouteIds = runtimeData ?. capped ? new Set ( ) : new Set ( presentRouteIds ) ;
11751178 window . dispatchEvent ( new CustomEvent ( 'app-runtime-data-change' ) ) ;
11761179}
11771180
@@ -1245,11 +1248,28 @@ function getLoadedRuntimeRouteIdsState() {
12451248 return AppState . loadedRuntimeRouteIds instanceof Set ? AppState . loadedRuntimeRouteIds : new Set ( ) ;
12461249}
12471250
1251+ function getResolvedRuntimeRouteIdsState ( ) {
1252+ return AppState . resolvedRuntimeRouteIds instanceof Set ? AppState . resolvedRuntimeRouteIds : new Set ( ) ;
1253+ }
1254+
12481255function isRuntimeRouteLoadedState ( routeId ) {
12491256 const rid = String ( routeId || '' ) . trim ( ) ;
12501257 return ! ! rid && getLoadedRuntimeRouteIdsState ( ) . has ( rid ) ;
12511258}
12521259
1260+ function isRuntimeRouteResolvedState ( routeId ) {
1261+ const rid = String ( routeId || '' ) . trim ( ) ;
1262+ return ! ! rid && getResolvedRuntimeRouteIdsState ( ) . has ( rid ) ;
1263+ }
1264+
1265+ function markRuntimeRouteResolvedState ( routeId , resolved = true ) {
1266+ const rid = String ( routeId || '' ) . trim ( ) ;
1267+ if ( ! rid ) return ;
1268+ if ( ! ( AppState . resolvedRuntimeRouteIds instanceof Set ) ) AppState . resolvedRuntimeRouteIds = new Set ( ) ;
1269+ if ( resolved ) AppState . resolvedRuntimeRouteIds . add ( rid ) ;
1270+ else AppState . resolvedRuntimeRouteIds . delete ( rid ) ;
1271+ }
1272+
12531273function setRuntimeRouteLoadingState ( routeId , loading ) {
12541274 const rid = String ( routeId || '' ) . trim ( ) ;
12551275 if ( ! rid ) return ;
@@ -1873,6 +1893,7 @@ window.LegacyCityBridge = createLegacyBridge(() => ({
18731893 AppState . preparedGtfsSource = null ;
18741894 AppState . routeRuntimeSource = null ;
18751895 AppState . loadedRuntimeRouteIds = new Set ( ) ;
1896+ AppState . resolvedRuntimeRouteIds = new Set ( ) ;
18761897 AppState . loadingRuntimeRouteIds = new Set ( ) ;
18771898 AppState . routeRuntimeRequestSeq = 0 ;
18781899 AppState . lastRequestedRuntimeRouteId = null ;
@@ -1952,6 +1973,9 @@ window.LegacyDataBridge = createLegacyBridge(() => ({
19521973 mergeRuntimeCollections : mergeRuntimeCollectionsState ,
19531974 getLoadedRuntimeRouteIds : getLoadedRuntimeRouteIdsState ,
19541975 isRuntimeRouteLoaded : isRuntimeRouteLoadedState ,
1976+ getResolvedRuntimeRouteIds : getResolvedRuntimeRouteIdsState ,
1977+ isRuntimeRouteResolved : isRuntimeRouteResolvedState ,
1978+ markRuntimeRouteResolved : markRuntimeRouteResolvedState ,
19551979 setRuntimeRouteLoading : setRuntimeRouteLoadingState ,
19561980 isRuntimeRouteLoading : isRuntimeRouteLoadingState ,
19571981 beginRuntimeRouteRequest : beginRuntimeRouteRequestState ,
@@ -2047,6 +2071,7 @@ window.LegacyAppBridge = createLegacyBridge(() => ({
20472071 invalidateMapCaches : ( ) => { _cachedVisTrips = null ; _cachedVisShapes = null ; _filteredStopsCache = null ; _filteredStopIdSetCache = null ; } ,
20482072 setShowTrail : ( value ) => { showTrail = value ; } ,
20492073 setCurrentMapStyle : ( value ) => { currentMapStyle = value || 'auto' ; } ,
2074+ loadRouteRuntimeSubset : ( routeId ) => callManager ( 'DataManager' , 'loadRouteRuntimeSubset' , [ routeId ] ) ,
20502075 } ) ) ;
20512076
20522077const legacySimulationContext = {
@@ -2337,13 +2362,7 @@ function inferTripDirectionLabel(trip) {
23372362function getOrderedStopsForPattern ( routeId , routeShort , patternDir , patternHead , filteredTrips ) {
23382363 const stopInfoMap = AppState . stopInfo || { } ;
23392364
2340- // Primary: trips with pre-built stop arrays (small feeds)
2341- const tripWithStops = filteredTrips . find ( ( t ) => t . st && t . st . length > 1 ) ;
2342- if ( tripWithStops ) {
2343- return tripWithStops . st . map ( ( { sid } ) => ( { sid, name : stopInfoMap [ sid ] ?. [ 2 ] || sid } ) ) ;
2344- }
2345-
2346- // Find best trip_id from stopTariffIndex (most timepoint stops for the route/pattern)
2365+ // Primary: full stop list from preparedGtfsSource via stopTariffIndex (all stops, including non-timepoints)
23472366 const tariff = AppState . stopTariffIndex || { } ;
23482367 const tripCounts = { } ;
23492368 for ( const entries of Object . values ( tariff ) ) {
@@ -2359,20 +2378,28 @@ function getOrderedStopsForPattern(routeId, routeShort, patternDir, patternHead,
23592378 for ( const [ tripId , count ] of Object . entries ( tripCounts ) ) {
23602379 if ( count > bestCount ) { bestCount = count ; bestTripId = tripId ; }
23612380 }
2362- if ( ! bestTripId ) return [ ] ;
23632381
2364- // Full stop list: on-demand loaded source first, then parse-time source (always populated)
2365- const rawTripStops =
2366- AppState . routeRuntimeSource ?. tripStops ?. [ bestTripId ] ||
2367- AppState . preparedGtfsSource ?. tripStops ?. [ bestTripId ] ;
2368- if ( rawTripStops ?. length > 0 ) {
2369- return rawTripStops
2370- . map ( ( [ seq , , sid ] ) => ( { sid, name : stopInfoMap [ sid ] ?. [ 2 ] || sid , seq } ) )
2371- . sort ( ( a , b ) => a . seq - b . seq )
2372- . map ( ( { sid, name } ) => ( { sid, name } ) ) ;
2382+ if ( bestTripId ) {
2383+ const rawTripStops =
2384+ AppState . routeRuntimeSource ?. tripStops ?. [ bestTripId ] ||
2385+ AppState . preparedGtfsSource ?. tripStops ?. [ bestTripId ] ;
2386+ if ( rawTripStops ?. length > 0 ) {
2387+ return rawTripStops
2388+ . map ( ( [ seq , , sid ] ) => ( { sid, name : stopInfoMap [ sid ] ?. [ 2 ] || sid , seq } ) )
2389+ . sort ( ( a , b ) => a . seq - b . seq )
2390+ . map ( ( { sid, name } ) => ( { sid, name } ) ) ;
2391+ }
2392+ }
2393+
2394+ // Secondary: pre-built stop arrays on trip objects (small feeds / attachStopSequences)
2395+ const tripWithStops = filteredTrips . find ( ( t ) => t . st && t . st . length > 1 ) ;
2396+ if ( tripWithStops ) {
2397+ return tripWithStops . st . map ( ( { sid } ) => ( { sid, name : stopInfoMap [ sid ] ?. [ 2 ] || sid } ) ) ;
23732398 }
23742399
2375- // Last resort: use only timepoint entries from stopTariffIndex for bestTripId
2400+ if ( ! bestTripId ) return [ ] ;
2401+
2402+ // Last resort: timepoint-only entries from stopTariffIndex for bestTripId
23762403 const fallback = [ ] ;
23772404 for ( const [ sid , entries ] of Object . entries ( tariff ) ) {
23782405 for ( const e of entries ) {
0 commit comments