11import initSqlJs from 'sql.js' ;
22import type { SqlJsStatic } from 'sql.js' ;
33import { GtfsSqlJs } from 'gtfs-sqljs' ;
4+ import { createSqlJsAdapter } from 'gtfs-sqljs/adapters/sql-js' ;
45import type { Route , Trip , StopTime , Agency , Alert , VehiclePosition , TripWithRealtime , StopTimeWithRealtime } from 'gtfs-sqljs' ;
56
67let gtfs : GtfsSqlJs ;
@@ -38,7 +39,7 @@ async function loadGTFS(url: string) {
3839 // Load GTFS data
3940 // Skip shapes.txt to reduce memory usage and improve load time
4041 gtfs = await GtfsSqlJs . fromZip ( source , {
41- SQL ,
42+ adapter : await createSqlJsAdapter ( { SQL } ) ,
4243 skipFiles : [ 'shapes.txt' ]
4344 } ) ;
4445
@@ -60,13 +61,13 @@ async function loadGTFS(url: string) {
6061 setupRTButtons ( ) ;
6162
6263 // Render initial data
63- renderAgencies ( ) ;
64- renderActiveCalendars ( ) ;
65- renderRoutes ( ) ;
64+ await renderAgencies ( ) ;
65+ await renderActiveCalendars ( ) ;
66+ await renderRoutes ( ) ;
6667
6768 // Clear RT displays
68- renderAlerts ( ) ;
69- renderVehicleCount ( ) ;
69+ await renderAlerts ( ) ;
70+ await renderVehicleCount ( ) ;
7071 } catch ( error ) {
7172 console . error ( 'Error loading GTFS data:' , error ) ;
7273 loadingEl . style . display = 'none' ;
@@ -121,11 +122,11 @@ function initDatePicker() {
121122 selectedDate = `${ year } ${ month } ${ day } ` ; // YYYYMMDD format for GTFS
122123
123124 // Listen for date changes
124- dateInput . addEventListener ( 'change' , ( e ) => {
125+ dateInput . addEventListener ( 'change' , async ( e ) => {
125126 const target = e . target as HTMLInputElement ;
126127 const [ y , m , d ] = target . value . split ( '-' ) ;
127128 selectedDate = `${ y } ${ m } ${ d } ` ;
128- renderActiveCalendars ( ) ;
129+ await renderActiveCalendars ( ) ;
129130
130131 // Reset trips section
131132 document . getElementById ( 'trips-section' ) ! . style . display = 'none' ;
@@ -134,11 +135,11 @@ function initDatePicker() {
134135}
135136
136137// Render agencies
137- function renderAgencies ( ) {
138+ async function renderAgencies ( ) {
138139 const agenciesListEl = document . getElementById ( 'agencies-list' ) ! ;
139140
140141 try {
141- const agencies = gtfs . getAgencies ( ) ;
142+ const agencies = await gtfs . getAgencies ( ) ;
142143
143144 if ( agencies . length === 0 ) {
144145 agenciesListEl . innerHTML = '<p>No agency information available</p>' ;
@@ -166,11 +167,11 @@ function renderAgencies() {
166167}
167168
168169// Render active calendars for selected date
169- function renderActiveCalendars ( ) {
170+ async function renderActiveCalendars ( ) {
170171 const activeCalendarsEl = document . getElementById ( 'active-calendars' ) ! ;
171172
172173 try {
173- const serviceIds = gtfs . getActiveServiceIds ( selectedDate ) ;
174+ const serviceIds = await gtfs . getActiveServiceIds ( selectedDate ) ;
174175
175176 if ( serviceIds . length === 0 ) {
176177 activeCalendarsEl . innerHTML = '<p class="info-text">No active service calendars for this date</p>' ;
@@ -190,9 +191,9 @@ function renderActiveCalendars() {
190191}
191192
192193// Render routes list
193- function renderRoutes ( ) {
194+ async function renderRoutes ( ) {
194195 const routesListEl = document . getElementById ( 'routes-list' ) ! ;
195- const routes = gtfs . getRoutes ( ) ;
196+ const routes = await gtfs . getRoutes ( ) ;
196197
197198 if ( routes . length === 0 ) {
198199 routesListEl . innerHTML = '<p>No routes found</p>' ;
@@ -218,7 +219,7 @@ function renderRoutes() {
218219}
219220
220221// Show trips for a route
221- ( window as any ) . showTrips = function ( routeId : string , routeName : string ) {
222+ ( window as any ) . showTrips = async function ( routeId : string , routeName : string ) {
222223 const tripsSectionEl = document . getElementById ( 'trips-section' ) ! ;
223224 const tripsListEl = document . getElementById ( 'trips-list' ) ! ;
224225 const selectedRouteNameEl = document . getElementById ( 'selected-route-name' ) ! ;
@@ -228,11 +229,11 @@ function renderRoutes() {
228229 stopTimesSectionEl . style . display = 'none' ;
229230
230231 // Get trips for this route on the selected date (with realtime data)
231- const trips = gtfs . getTrips ( {
232+ const trips = ( await gtfs . getTrips ( {
232233 routeId : routeId ,
233234 date : selectedDate ,
234235 includeRealtime : true
235- } ) as TripWithRealtime [ ] ;
236+ } ) ) as TripWithRealtime [ ] ;
236237
237238 if ( trips . length === 0 ) {
238239 tripsListEl . innerHTML = '<p>No trips found for this route on the selected date</p>' ;
@@ -339,16 +340,16 @@ function renderRoutes() {
339340} ;
340341
341342// Show stop times for a trip
342- ( window as any ) . showStopTimes = function ( tripId : string , tripName : string ) {
343+ ( window as any ) . showStopTimes = async function ( tripId : string , tripName : string ) {
343344 const stopTimesSectionEl = document . getElementById ( 'stop-times-section' ) ! ;
344345 const stopTimesListEl = document . getElementById ( 'stop-times-list' ) ! ;
345346 const selectedTripNameEl = document . getElementById ( 'selected-trip-name' ) ! ;
346347
347348 // Get stop times for this trip (with realtime data)
348- const stopTimes = gtfs . getStopTimes ( {
349+ const stopTimes = ( await gtfs . getStopTimes ( {
349350 tripId : tripId ,
350351 includeRealtime : true
351- } ) as StopTimeWithRealtime [ ] ;
352+ } ) ) as StopTimeWithRealtime [ ] ;
352353
353354 if ( stopTimes . length === 0 ) {
354355 stopTimesListEl . innerHTML = '<p>No stop times found for this trip</p>' ;
@@ -358,8 +359,8 @@ function renderRoutes() {
358359 }
359360
360361 // Render stop times with stop names and realtime data
361- const html = stopTimes . map ( st => {
362- const stops = gtfs . getStops ( { stopId : st . stop_id } ) ;
362+ const html = ( await Promise . all ( stopTimes . map ( async st => {
363+ const stops = await gtfs . getStops ( { stopId : st . stop_id } ) ;
363364 const stop = stops . length > 0 ? stops [ 0 ] : null ;
364365 const stopName = stop ? stop . stop_name : st . stop_id ;
365366
@@ -393,7 +394,7 @@ function renderRoutes() {
393394 <div class="stop-name">${ escapeHtml ( stopName ) } </div>
394395 </div>
395396 ` ;
396- } ) . join ( '' ) ;
397+ } ) ) ) . join ( '' ) ;
397398
398399 stopTimesListEl . innerHTML = html ;
399400 stopTimesSectionEl . style . display = 'block' ;
@@ -417,8 +418,8 @@ async function fetchRealtimeData() {
417418 await gtfs . fetchRealtimeData ( [ proxyUrl ] ) ;
418419
419420 // Update displays
420- renderAlerts ( ) ;
421- renderVehicleCount ( ) ;
421+ await renderAlerts ( ) ;
422+ await renderVehicleCount ( ) ;
422423 } catch ( error ) {
423424 console . error ( 'Error fetching realtime data:' , error ) ;
424425 alert ( `Failed to fetch realtime data: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
@@ -466,18 +467,18 @@ function setupRTButtons() {
466467}
467468
468469// Render alerts
469- function renderAlerts ( ) {
470+ async function renderAlerts ( ) {
470471 const alertsListEl = document . getElementById ( 'alerts-list' ) ! ;
471472
472473 try {
473- const alerts = gtfs . getAlerts ( { activeOnly : true } ) ;
474+ const alerts = await gtfs . getAlerts ( { activeOnly : true } ) ;
474475
475476 if ( alerts . length === 0 ) {
476477 alertsListEl . innerHTML = '<p class="no-data">No active alerts</p>' ;
477478 return ;
478479 }
479480
480- const html = alerts . map ( alert => {
481+ const html = ( await Promise . all ( alerts . map ( async alert => {
481482 let headerText = 'Alert' ;
482483 if ( alert . header_text ) {
483484 try {
@@ -508,16 +509,16 @@ function renderAlerts() {
508509 . map ( e => e . route_id )
509510 . slice ( 0 , 10 ) ; // Show max 10 routes
510511
511- const routesBadges = affectedRoutes . map ( routeId => {
512- const routes = gtfs . getRoutes ( { routeId : routeId ! } ) ;
512+ const routesBadges = ( await Promise . all ( affectedRoutes . map ( async routeId => {
513+ const routes = await gtfs . getRoutes ( { routeId : routeId ! } ) ;
513514 const route = routes . length > 0 ? routes [ 0 ] : null ;
514515 if ( ! route ) return '' ;
515516
516517 const bgColor = route . route_color ? `#${ route . route_color } ` : '#64748b' ;
517518 const textColor = route . route_text_color ? `#${ route . route_text_color } ` : getContrastColor ( bgColor ) ;
518519
519520 return `<span class="route-badge" style="background-color: ${ bgColor } ; color: ${ textColor } ;">${ escapeHtml ( route . route_short_name ?? '' ) } </span>` ;
520- } ) . join ( '' ) ;
521+ } ) ) ) . join ( '' ) ;
521522
522523 const moreRoutes = alert . informed_entity . filter ( e => e . route_id ) . length > 10
523524 ? `<span class="route-badge-more">+${ alert . informed_entity . filter ( e => e . route_id ) . length - 10 } more</span>`
@@ -530,7 +531,7 @@ function renderAlerts() {
530531 ${ routesBadges || moreRoutes ? `<div class="alert-routes">Affected routes: ${ routesBadges } ${ moreRoutes } </div>` : '' }
531532 </div>
532533 ` ;
533- } ) . join ( '' ) ;
534+ } ) ) ) . join ( '' ) ;
534535
535536 alertsListEl . innerHTML = html ;
536537 } catch ( error ) {
@@ -540,11 +541,11 @@ function renderAlerts() {
540541}
541542
542543// Render vehicle count
543- function renderVehicleCount ( ) {
544+ async function renderVehicleCount ( ) {
544545 const vehiclesCountEl = document . getElementById ( 'vehicles-count' ) ! ;
545546
546547 try {
547- const vehicles = gtfs . getVehiclePositions ( ) ;
548+ const vehicles = await gtfs . getVehiclePositions ( ) ;
548549
549550 if ( vehicles . length === 0 ) {
550551 vehiclesCountEl . innerHTML = '<p class="no-data">No tracked vehicles</p>' ;
@@ -568,10 +569,10 @@ function setupDownloadButton() {
568569 const downloadBtn = document . getElementById ( 'download-db-btn' ) as HTMLButtonElement ;
569570 if ( ! downloadBtn ) return ;
570571
571- downloadBtn . addEventListener ( 'click' , ( ) => {
572+ downloadBtn . addEventListener ( 'click' , async ( ) => {
572573 try {
573574 // Export database to ArrayBuffer
574- const dbData = gtfs . export ( ) ;
575+ const dbData = await gtfs . export ( ) ;
575576
576577 // Create blob and download
577578 const blob = new Blob ( [ dbData ] , { type : 'application/x-sqlite3' } ) ;
0 commit comments