lt-public-transport-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/assets/architecture.png +0 -0
  4. package/dist/config.d.ts +221 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +200 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/enrichment/index.d.ts +6 -0
  9. package/dist/enrichment/index.d.ts.map +1 -0
  10. package/dist/enrichment/index.js +6 -0
  11. package/dist/enrichment/index.js.map +1 -0
  12. package/dist/enrichment/route-matcher.d.ts +64 -0
  13. package/dist/enrichment/route-matcher.d.ts.map +1 -0
  14. package/dist/enrichment/route-matcher.js +121 -0
  15. package/dist/enrichment/route-matcher.js.map +1 -0
  16. package/dist/errors.d.ts +70 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +104 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/gtfs/index.d.ts +7 -0
  21. package/dist/gtfs/index.d.ts.map +1 -0
  22. package/dist/gtfs/index.js +7 -0
  23. package/dist/gtfs/index.js.map +1 -0
  24. package/dist/gtfs/parser.d.ts +39 -0
  25. package/dist/gtfs/parser.d.ts.map +1 -0
  26. package/dist/gtfs/parser.js +189 -0
  27. package/dist/gtfs/parser.js.map +1 -0
  28. package/dist/gtfs/sync.d.ts +72 -0
  29. package/dist/gtfs/sync.d.ts.map +1 -0
  30. package/dist/gtfs/sync.js +271 -0
  31. package/dist/gtfs/sync.js.map +1 -0
  32. package/dist/index.d.ts +203 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +342 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/parsers/gps-full.d.ts +39 -0
  37. package/dist/parsers/gps-full.d.ts.map +1 -0
  38. package/dist/parsers/gps-full.js +212 -0
  39. package/dist/parsers/gps-full.js.map +1 -0
  40. package/dist/parsers/gps-lite.d.ts +60 -0
  41. package/dist/parsers/gps-lite.d.ts.map +1 -0
  42. package/dist/parsers/gps-lite.js +141 -0
  43. package/dist/parsers/gps-lite.js.map +1 -0
  44. package/dist/parsers/index.d.ts +7 -0
  45. package/dist/parsers/index.d.ts.map +1 -0
  46. package/dist/parsers/index.js +7 -0
  47. package/dist/parsers/index.js.map +1 -0
  48. package/dist/schemas.d.ts +129 -0
  49. package/dist/schemas.d.ts.map +1 -0
  50. package/dist/schemas.js +200 -0
  51. package/dist/schemas.js.map +1 -0
  52. package/dist/scripts/test-city-specific.d.ts +2 -0
  53. package/dist/scripts/test-city-specific.d.ts.map +1 -0
  54. package/dist/scripts/test-city-specific.js +264 -0
  55. package/dist/scripts/test-city-specific.js.map +1 -0
  56. package/dist/scripts/test-config-options.d.ts +2 -0
  57. package/dist/scripts/test-config-options.d.ts.map +1 -0
  58. package/dist/scripts/test-config-options.js +166 -0
  59. package/dist/scripts/test-config-options.js.map +1 -0
  60. package/dist/scripts/test-data-quality.d.ts +2 -0
  61. package/dist/scripts/test-data-quality.d.ts.map +1 -0
  62. package/dist/scripts/test-data-quality.js +204 -0
  63. package/dist/scripts/test-data-quality.js.map +1 -0
  64. package/dist/scripts/test-error-handling.d.ts +2 -0
  65. package/dist/scripts/test-error-handling.d.ts.map +1 -0
  66. package/dist/scripts/test-error-handling.js +146 -0
  67. package/dist/scripts/test-error-handling.js.map +1 -0
  68. package/dist/scripts/test-live.d.ts +2 -0
  69. package/dist/scripts/test-live.d.ts.map +1 -0
  70. package/dist/scripts/test-live.js +121 -0
  71. package/dist/scripts/test-live.js.map +1 -0
  72. package/dist/types.d.ts +120 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +25 -0
  75. package/dist/types.js.map +1 -0
  76. package/dist/utils/coordinates.d.ts +68 -0
  77. package/dist/utils/coordinates.d.ts.map +1 -0
  78. package/dist/utils/coordinates.js +98 -0
  79. package/dist/utils/coordinates.js.map +1 -0
  80. package/dist/utils/encoding.d.ts +47 -0
  81. package/dist/utils/encoding.d.ts.map +1 -0
  82. package/dist/utils/encoding.js +153 -0
  83. package/dist/utils/encoding.js.map +1 -0
  84. package/dist/utils/index.d.ts +8 -0
  85. package/dist/utils/index.d.ts.map +1 -0
  86. package/dist/utils/index.js +8 -0
  87. package/dist/utils/index.js.map +1 -0
  88. package/dist/utils/time.d.ts +50 -0
  89. package/dist/utils/time.d.ts.map +1 -0
  90. package/dist/utils/time.js +94 -0
  91. package/dist/utils/time.js.map +1 -0
  92. package/package.json +84 -0
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Lithuanian Public Transport SDK
3
+ *
4
+ * A production-grade TypeScript SDK for accessing real-time Lithuanian
5
+ * public transport data from stops.lt infrastructure.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { LtTransport } from 'lt-public-transport-sdk';
10
+ *
11
+ * const transport = new LtTransport();
12
+ *
13
+ * // Sync GTFS data (required for enrichment)
14
+ * await transport.sync('vilnius');
15
+ *
16
+ * // Get real-time vehicle positions
17
+ * const vehicles = await transport.getVehicles('vilnius');
18
+ *
19
+ * // Get static stop data
20
+ * const stops = await transport.getStops('vilnius');
21
+ * ```
22
+ *
23
+ * @module
24
+ */
25
+ import type { CityId, Route, Stop, SyncResult, Vehicle } from './types.js';
26
+ import { type CityConfig } from './config.js';
27
+ /**
28
+ * Configuration options for LtTransport client.
29
+ */
30
+ export interface LtTransportConfig {
31
+ /**
32
+ * Directory for caching GTFS data.
33
+ * Defaults to system temp directory.
34
+ */
35
+ cacheDir?: string;
36
+ /**
37
+ * Request timeout in milliseconds.
38
+ * @default 10000
39
+ */
40
+ requestTimeout?: number;
41
+ /**
42
+ * User-Agent header for HTTP requests.
43
+ * @default 'lt-public-transport-sdk/1.0.0'
44
+ */
45
+ userAgent?: string;
46
+ /**
47
+ * Threshold in milliseconds for marking data as stale.
48
+ * @default 300000 (5 minutes)
49
+ */
50
+ staleThresholdMs?: number;
51
+ /**
52
+ * Whether to automatically enrich silver-tier cities with GTFS data.
53
+ * Requires prior sync() call for the city.
54
+ * @default true
55
+ */
56
+ autoEnrich?: boolean;
57
+ /**
58
+ * Whether to filter out vehicles with invalid (out of Lithuania) coordinates.
59
+ * @default true
60
+ */
61
+ filterInvalidCoords?: boolean;
62
+ /**
63
+ * Whether to filter out stale data.
64
+ * @default false
65
+ */
66
+ filterStale?: boolean;
67
+ }
68
+ /**
69
+ * Lithuanian Public Transport SDK client.
70
+ *
71
+ * Provides unified access to real-time GPS vehicle positions and
72
+ * static GTFS data for Lithuanian cities.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const transport = new LtTransport();
77
+ *
78
+ * // Get vehicles from Vilnius (gold tier - rich data)
79
+ * const vilniusVehicles = await transport.getVehicles('vilnius');
80
+ *
81
+ * // Get vehicles from Panevėžys (silver tier - needs enrichment)
82
+ * await transport.sync('panevezys'); // Sync GTFS first
83
+ * const panevezysVehicles = await transport.getVehicles('panevezys');
84
+ * ```
85
+ */
86
+ export declare class LtTransport {
87
+ private readonly cacheDir;
88
+ private readonly requestTimeout;
89
+ private readonly userAgent;
90
+ private readonly staleThresholdMs;
91
+ private readonly autoEnrich;
92
+ private readonly filterInvalidCoords;
93
+ private readonly filterStale;
94
+ /** In-memory route cache for fast enrichment */
95
+ private readonly routeCaches;
96
+ /** Last sync timestamps for throttling */
97
+ private readonly lastSyncTimes;
98
+ /**
99
+ * Create a new LtTransport client.
100
+ *
101
+ * @param config - Client configuration options
102
+ */
103
+ constructor(config?: LtTransportConfig);
104
+ /**
105
+ * Get real-time vehicle positions for a city.
106
+ *
107
+ * For silver-tier cities (Panevėžys, Tauragė), vehicles will be enriched
108
+ * with GTFS data if `sync()` has been called and `autoEnrich` is enabled.
109
+ *
110
+ * @param city - City identifier
111
+ * @returns Array of vehicle positions
112
+ * @throws {GpsNotAvailableError} If city is bronze tier (no GPS data)
113
+ * @throws {TransportNetworkError} If network request fails
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const vehicles = await transport.getVehicles('vilnius');
118
+ * console.log(`Found ${vehicles.length} vehicles`);
119
+ * ```
120
+ */
121
+ getVehicles(city: CityId): Promise<Vehicle[]>;
122
+ /**
123
+ * Sync GTFS static data for a city.
124
+ *
125
+ * Downloads the GTFS ZIP archive if newer than cached version,
126
+ * extracts routes and stops, and caches for future use.
127
+ *
128
+ * Throttled to minimum 60 seconds between calls for same city.
129
+ *
130
+ * @param city - City to sync
131
+ * @param force - Force re-download even if cache is current
132
+ * @returns Sync result with counts and status
133
+ * @throws {GtfsSyncError} If sync fails
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const result = await transport.sync('vilnius');
138
+ * console.log(`Synced ${result.routeCount} routes`);
139
+ * ```
140
+ */
141
+ sync(city: CityId, force?: boolean): Promise<SyncResult>;
142
+ /**
143
+ * Get static stop data for a city.
144
+ *
145
+ * Requires prior `sync()` call to download GTFS data.
146
+ *
147
+ * @param city - City to get stops for
148
+ * @returns Array of stops
149
+ * @throws {SyncRequiredError} If GTFS data not synced
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * await transport.sync('vilnius');
154
+ * const stops = await transport.getStops('vilnius');
155
+ * console.log(`Found ${stops.length} stops`);
156
+ * ```
157
+ */
158
+ getStops(city: CityId): Promise<Stop[]>;
159
+ /**
160
+ * Get route information for a city.
161
+ *
162
+ * Requires prior `sync()` call to download GTFS data.
163
+ *
164
+ * @param city - City to get routes for
165
+ * @returns Array of routes
166
+ * @throws {SyncRequiredError} If GTFS data not synced
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * await transport.sync('vilnius');
171
+ * const routes = await transport.getRoutes('vilnius');
172
+ * console.log(`Found ${routes.length} routes`);
173
+ * ```
174
+ */
175
+ getRoutes(city: CityId): Promise<Route[]>;
176
+ /**
177
+ * Get list of all supported city IDs.
178
+ */
179
+ getCities(): readonly CityId[];
180
+ /**
181
+ * Get configuration for a specific city.
182
+ */
183
+ getCityConfig(city: CityId): CityConfig;
184
+ /**
185
+ * Validate that city ID is valid.
186
+ */
187
+ private validateCity;
188
+ /**
189
+ * Fetch text content from URL.
190
+ */
191
+ private fetchText;
192
+ /**
193
+ * Get route cache for a city, loading from disk if needed.
194
+ */
195
+ private getRouteCache;
196
+ }
197
+ export type { CityId, CityTier, VehicleType, Vehicle, Stop, Route, SyncResult, } from './types.js';
198
+ export { GTFS_ROUTE_TYPE_MAP, LT_TRANSPORT_TYPE_MAP } from './types.js';
199
+ export { CITY_CONFIGS, ALL_CITY_IDS, getCityConfig, getCitiesByTier, hasGpsData, hasGtfsData } from './config.js';
200
+ export type { CityConfig, GpsConfig, GtfsConfig } from './config.js';
201
+ export { TransportError, TransportNetworkError, GpsNotAvailableError, SyncRequiredError, GtfsSyncError, ParseError, InvalidCityError, isTransportError, isNetworkError, } from './errors.js';
202
+ export { normalizeCoordinate, isValidLithuaniaCoord, LITHUANIA_BOUNDS, repairMojibake, secondsFromMidnightToDate, isDataStale, } from './utils/index.js';
203
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Lithuanian Public Transport SDK
3
+ *
4
+ * A production-grade TypeScript SDK for accessing real-time Lithuanian
5
+ * public transport data from stops.lt infrastructure.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { LtTransport } from 'lt-public-transport-sdk';
10
+ *
11
+ * const transport = new LtTransport();
12
+ *
13
+ * // Sync GTFS data (required for enrichment)
14
+ * await transport.sync('vilnius');
15
+ *
16
+ * // Get real-time vehicle positions
17
+ * const vehicles = await transport.getVehicles('vilnius');
18
+ *
19
+ * // Get static stop data
20
+ * const stops = await transport.getStops('vilnius');
21
+ * ```
22
+ *
23
+ * @module
24
+ */
25
+ import { tmpdir } from 'node:os';
26
+ import { join } from 'node:path';
27
+ import { CITY_CONFIGS, getCityConfig, ALL_CITY_IDS } from './config.js';
28
+ import { TransportNetworkError, GpsNotAvailableError, SyncRequiredError, InvalidCityError, } from './errors.js';
29
+ import { parseGpsFullStream } from './parsers/gps-full.js';
30
+ import { parseGpsLiteStream, isLiteCity } from './parsers/gps-lite.js';
31
+ import { syncGtfs, loadGtfsCache, loadCachedRoutes, loadCachedStops } from './gtfs/sync.js';
32
+ import { enrichVehicles, buildRouteCache } from './enrichment/route-matcher.js';
33
+ import { clientConfigSchema } from './schemas.js';
34
+ // =============================================================================
35
+ // Default Values
36
+ // =============================================================================
37
+ const DEFAULT_TIMEOUT = 10000;
38
+ const DEFAULT_USER_AGENT = 'lt-public-transport-sdk/1.0.0';
39
+ const DEFAULT_STALE_THRESHOLD = 5 * 60 * 1000; // 5 minutes
40
+ /**
41
+ * Get default cache directory.
42
+ */
43
+ function getDefaultCacheDir() {
44
+ return join(tmpdir(), 'lt-transport-sdk-cache');
45
+ }
46
+ // =============================================================================
47
+ // Main Client Class
48
+ // =============================================================================
49
+ /**
50
+ * Lithuanian Public Transport SDK client.
51
+ *
52
+ * Provides unified access to real-time GPS vehicle positions and
53
+ * static GTFS data for Lithuanian cities.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const transport = new LtTransport();
58
+ *
59
+ * // Get vehicles from Vilnius (gold tier - rich data)
60
+ * const vilniusVehicles = await transport.getVehicles('vilnius');
61
+ *
62
+ * // Get vehicles from Panevėžys (silver tier - needs enrichment)
63
+ * await transport.sync('panevezys'); // Sync GTFS first
64
+ * const panevezysVehicles = await transport.getVehicles('panevezys');
65
+ * ```
66
+ */
67
+ export class LtTransport {
68
+ cacheDir;
69
+ requestTimeout;
70
+ userAgent;
71
+ staleThresholdMs;
72
+ autoEnrich;
73
+ filterInvalidCoords;
74
+ filterStale;
75
+ /** In-memory route cache for fast enrichment */
76
+ routeCaches = new Map();
77
+ /** Last sync timestamps for throttling */
78
+ lastSyncTimes = new Map();
79
+ /**
80
+ * Create a new LtTransport client.
81
+ *
82
+ * @param config - Client configuration options
83
+ */
84
+ constructor(config = {}) {
85
+ // Validate config with Zod schema for runtime safety
86
+ const validated = clientConfigSchema.parse({
87
+ cacheDir: config.cacheDir,
88
+ requestTimeout: config.requestTimeout ?? DEFAULT_TIMEOUT,
89
+ userAgent: config.userAgent ?? DEFAULT_USER_AGENT,
90
+ staleThresholdMs: config.staleThresholdMs ?? DEFAULT_STALE_THRESHOLD,
91
+ autoEnrich: config.autoEnrich ?? true,
92
+ filterInvalidCoords: config.filterInvalidCoords ?? true,
93
+ filterStale: config.filterStale ?? false,
94
+ });
95
+ this.cacheDir = validated.cacheDir ?? getDefaultCacheDir();
96
+ this.requestTimeout = validated.requestTimeout;
97
+ this.userAgent = validated.userAgent;
98
+ this.staleThresholdMs = validated.staleThresholdMs;
99
+ this.autoEnrich = validated.autoEnrich;
100
+ this.filterInvalidCoords = validated.filterInvalidCoords;
101
+ this.filterStale = validated.filterStale;
102
+ }
103
+ // ===========================================================================
104
+ // Public API
105
+ // ===========================================================================
106
+ /**
107
+ * Get real-time vehicle positions for a city.
108
+ *
109
+ * For silver-tier cities (Panevėžys, Tauragė), vehicles will be enriched
110
+ * with GTFS data if `sync()` has been called and `autoEnrich` is enabled.
111
+ *
112
+ * @param city - City identifier
113
+ * @returns Array of vehicle positions
114
+ * @throws {GpsNotAvailableError} If city is bronze tier (no GPS data)
115
+ * @throws {TransportNetworkError} If network request fails
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const vehicles = await transport.getVehicles('vilnius');
120
+ * console.log(`Found ${vehicles.length} vehicles`);
121
+ * ```
122
+ */
123
+ async getVehicles(city) {
124
+ this.validateCity(city);
125
+ const config = getCityConfig(city);
126
+ if (!config.gps.enabled || config.gps.url === null) {
127
+ throw new GpsNotAvailableError(city);
128
+ }
129
+ // Fetch GPS data
130
+ const text = await this.fetchText(config.gps.url, city);
131
+ // Parse based on format
132
+ let vehicles;
133
+ if (config.gps.format === 'full') {
134
+ vehicles = parseGpsFullStream(text, city, {
135
+ staleThresholdMs: this.staleThresholdMs,
136
+ filterStale: this.filterStale,
137
+ filterInvalidCoords: this.filterInvalidCoords,
138
+ });
139
+ }
140
+ else if (isLiteCity(city)) {
141
+ vehicles = parseGpsLiteStream(text, city, {
142
+ filterInvalidCoords: this.filterInvalidCoords,
143
+ });
144
+ // Enrich silver-tier cities with GTFS data
145
+ if (this.autoEnrich) {
146
+ const routeCache = await this.getRouteCache(city);
147
+ if (routeCache) {
148
+ vehicles = enrichVehicles(vehicles, routeCache);
149
+ }
150
+ }
151
+ }
152
+ else {
153
+ // Unknown format
154
+ vehicles = [];
155
+ }
156
+ return vehicles;
157
+ }
158
+ /**
159
+ * Sync GTFS static data for a city.
160
+ *
161
+ * Downloads the GTFS ZIP archive if newer than cached version,
162
+ * extracts routes and stops, and caches for future use.
163
+ *
164
+ * Throttled to minimum 60 seconds between calls for same city.
165
+ *
166
+ * @param city - City to sync
167
+ * @param force - Force re-download even if cache is current
168
+ * @returns Sync result with counts and status
169
+ * @throws {GtfsSyncError} If sync fails
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const result = await transport.sync('vilnius');
174
+ * console.log(`Synced ${result.routeCount} routes`);
175
+ * ```
176
+ */
177
+ async sync(city, force = false) {
178
+ this.validateCity(city);
179
+ // Throttle sync calls (60s minimum between calls)
180
+ const lastSync = this.lastSyncTimes.get(city);
181
+ const now = Date.now();
182
+ if (!force && lastSync !== undefined && (now - lastSync) < 60000) {
183
+ // Return cached result
184
+ const cache = await loadGtfsCache(city, this.cacheDir);
185
+ if (cache) {
186
+ return {
187
+ city,
188
+ status: 'up-to-date',
189
+ routeCount: cache.meta.routeCount,
190
+ stopCount: cache.meta.stopCount,
191
+ lastModified: cache.meta.lastModified,
192
+ syncedAt: new Date(cache.meta.syncedAt),
193
+ };
194
+ }
195
+ }
196
+ const result = await syncGtfs(city, {
197
+ cacheDir: this.cacheDir,
198
+ timeout: this.requestTimeout * 3, // Longer timeout for downloads
199
+ userAgent: this.userAgent,
200
+ force,
201
+ });
202
+ this.lastSyncTimes.set(city, now);
203
+ // Clear in-memory cache to force reload
204
+ this.routeCaches.delete(city);
205
+ return result;
206
+ }
207
+ /**
208
+ * Get static stop data for a city.
209
+ *
210
+ * Requires prior `sync()` call to download GTFS data.
211
+ *
212
+ * @param city - City to get stops for
213
+ * @returns Array of stops
214
+ * @throws {SyncRequiredError} If GTFS data not synced
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * await transport.sync('vilnius');
219
+ * const stops = await transport.getStops('vilnius');
220
+ * console.log(`Found ${stops.length} stops`);
221
+ * ```
222
+ */
223
+ async getStops(city) {
224
+ this.validateCity(city);
225
+ const stops = await loadCachedStops(this.cacheDir, city);
226
+ if (!stops) {
227
+ throw new SyncRequiredError(city);
228
+ }
229
+ return stops;
230
+ }
231
+ /**
232
+ * Get route information for a city.
233
+ *
234
+ * Requires prior `sync()` call to download GTFS data.
235
+ *
236
+ * @param city - City to get routes for
237
+ * @returns Array of routes
238
+ * @throws {SyncRequiredError} If GTFS data not synced
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * await transport.sync('vilnius');
243
+ * const routes = await transport.getRoutes('vilnius');
244
+ * console.log(`Found ${routes.length} routes`);
245
+ * ```
246
+ */
247
+ async getRoutes(city) {
248
+ this.validateCity(city);
249
+ const routeCache = await this.getRouteCache(city);
250
+ if (!routeCache) {
251
+ throw new SyncRequiredError(city);
252
+ }
253
+ // Deduplicate (cache has entries by both short name and ID)
254
+ const seen = new Set();
255
+ const routes = [];
256
+ for (const route of routeCache.routes.values()) {
257
+ if (!seen.has(route.id)) {
258
+ seen.add(route.id);
259
+ routes.push(route);
260
+ }
261
+ }
262
+ return routes;
263
+ }
264
+ /**
265
+ * Get list of all supported city IDs.
266
+ */
267
+ getCities() {
268
+ return ALL_CITY_IDS;
269
+ }
270
+ /**
271
+ * Get configuration for a specific city.
272
+ */
273
+ getCityConfig(city) {
274
+ this.validateCity(city);
275
+ return getCityConfig(city);
276
+ }
277
+ // ===========================================================================
278
+ // Private Helpers
279
+ // ===========================================================================
280
+ /**
281
+ * Validate that city ID is valid.
282
+ */
283
+ validateCity(city) {
284
+ if (!(city in CITY_CONFIGS)) {
285
+ throw new InvalidCityError(city);
286
+ }
287
+ }
288
+ /**
289
+ * Fetch text content from URL.
290
+ */
291
+ async fetchText(url, city) {
292
+ const controller = new AbortController();
293
+ const timeout = setTimeout(() => { controller.abort(); }, this.requestTimeout);
294
+ try {
295
+ const response = await fetch(url, {
296
+ headers: { 'User-Agent': this.userAgent },
297
+ signal: controller.signal,
298
+ });
299
+ if (!response.ok) {
300
+ throw new TransportNetworkError(`HTTP ${String(response.status)}: ${response.statusText}`, city, response.status);
301
+ }
302
+ return await response.text();
303
+ }
304
+ catch (error) {
305
+ if (error instanceof TransportNetworkError) {
306
+ throw error;
307
+ }
308
+ const message = error instanceof Error ? error.message : 'Unknown error';
309
+ throw new TransportNetworkError(message, city, undefined, error instanceof Error ? error : undefined);
310
+ }
311
+ finally {
312
+ clearTimeout(timeout);
313
+ }
314
+ }
315
+ /**
316
+ * Get route cache for a city, loading from disk if needed.
317
+ */
318
+ async getRouteCache(city) {
319
+ // Check in-memory cache first
320
+ const cached = this.routeCaches.get(city);
321
+ if (cached) {
322
+ return cached;
323
+ }
324
+ // Load from disk
325
+ const routes = await loadCachedRoutes(this.cacheDir, city);
326
+ if (routes) {
327
+ // Build RouteCache with normalized lookup map for O(1) case-insensitive matching
328
+ const cache = buildRouteCache(routes);
329
+ this.routeCaches.set(city, cache);
330
+ return cache;
331
+ }
332
+ return null;
333
+ }
334
+ }
335
+ export { GTFS_ROUTE_TYPE_MAP, LT_TRANSPORT_TYPE_MAP } from './types.js';
336
+ // Config
337
+ export { CITY_CONFIGS, ALL_CITY_IDS, getCityConfig, getCitiesByTier, hasGpsData, hasGtfsData } from './config.js';
338
+ // Errors
339
+ export { TransportError, TransportNetworkError, GpsNotAvailableError, SyncRequiredError, GtfsSyncError, ParseError, InvalidCityError, isTransportError, isNetworkError, } from './errors.js';
340
+ // Utilities
341
+ export { normalizeCoordinate, isValidLithuaniaCoord, LITHUANIA_BOUNDS, repairMojibake, secondsFromMidnightToDate, isDataStale, } from './utils/index.js';
342
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * GPS Full Format Parser with dynamic header-based column mapping
3
+ * @module parsers/gps-full
4
+ *
5
+ * Handles the "full" GPS format used by gold-tier cities (Vilnius, Kaunas, Klaipėda, Alytus, Druskininkai).
6
+ * Each city has different column layouts, so we parse headers dynamically.
7
+ *
8
+ * Column counts by city (empirically verified):
9
+ * - Vilnius: 18 columns
10
+ * - Kaunas: 14 columns
11
+ * - Klaipėda: 12 columns
12
+ * - Alytus: 13 columns
13
+ * - Druskininkai: 13 columns
14
+ */
15
+ import type { CityId, Vehicle } from '../types.js';
16
+ /**
17
+ * Options for GPS full format parsing.
18
+ */
19
+ export interface GpsFullParseOptions {
20
+ /** Threshold in ms for marking data as stale (default: 5 minutes) */
21
+ staleThresholdMs?: number;
22
+ /** Whether to filter out stale records (default: false) */
23
+ filterStale?: boolean;
24
+ /** Whether to filter out records with invalid coordinates (default: true) */
25
+ filterInvalidCoords?: boolean;
26
+ }
27
+ /**
28
+ * Parse GPS full format stream from a gold-tier city.
29
+ *
30
+ * Uses header-based dynamic column mapping to handle different
31
+ * column layouts across cities.
32
+ *
33
+ * @param text - Raw text content from gps_full.txt
34
+ * @param city - City identifier for context
35
+ * @param options - Parse options
36
+ * @returns Array of normalized Vehicle objects
37
+ */
38
+ export declare function parseGpsFullStream(text: string, city: CityId, options?: GpsFullParseOptions): Vehicle[];
39
+ //# sourceMappingURL=gps-full.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gps-full.d.ts","sourceRoot":"","sources":["../../src/parsers/gps-full.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAsGhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,OAAO,EAAE,CAyEX"}