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
package/dist/config.js ADDED
@@ -0,0 +1,200 @@
1
+ /**
2
+ * City configuration matrix for Lithuanian Public Transport SDK
3
+ * @module config
4
+ */
5
+ // =============================================================================
6
+ // City Configuration Matrix
7
+ // =============================================================================
8
+ /**
9
+ * Base URL for stops.lt infrastructure.
10
+ */
11
+ const BASE_URL = 'https://www.stops.lt';
12
+ /**
13
+ * Helper to build GPS full URL.
14
+ */
15
+ function gpsFullUrl(city) {
16
+ return `${BASE_URL}/${city}/gps_full.txt`;
17
+ }
18
+ /**
19
+ * Helper to build GPS lite URL.
20
+ */
21
+ function gpsLiteUrl(city) {
22
+ return `${BASE_URL}/${city}/gps.txt`;
23
+ }
24
+ /**
25
+ * Helper to build GTFS URL.
26
+ * Note: URL pattern uses double city name: /city/city/gtfs.zip
27
+ */
28
+ function gtfsUrl(city) {
29
+ return `${BASE_URL}/${city}/${city}/gtfs.zip`;
30
+ }
31
+ /**
32
+ * City configuration matrix with all supported cities.
33
+ *
34
+ * Data Quality Tiers:
35
+ * - Gold: Full GPS streams with 12-18 columns including destination, delay, equipment
36
+ * - Silver: Lite GPS streams with 8-9 columns, requires GTFS enrichment for destinations
37
+ * - Bronze: GTFS only, no real-time GPS data available
38
+ *
39
+ * Column Counts (empirically verified 2026-01-05):
40
+ * - Vilnius: 18 columns (MatavimoLaikas, KryptiesTipas, ReisoIdGTFS)
41
+ * - Kaunas: 14 columns (Grafikas, SekanciosStotelesNum, AtvykimoLaikasSekundemis - NO MatavimoLaikas)
42
+ * - Klaipėda: 12 columns (minimal format)
43
+ * - Alytus: 13 columns
44
+ * - Druskininkai: 13 columns
45
+ * - Panevėžys: 9 columns lite (no header)
46
+ * - Tauragė: 8 columns lite (no header, alphanumeric routes like S11)
47
+ */
48
+ const CITY_CONFIGS_INTERNAL = {
49
+ vilnius: {
50
+ id: 'vilnius',
51
+ tier: 'gold',
52
+ gps: {
53
+ enabled: true,
54
+ format: 'full',
55
+ url: gpsFullUrl('vilnius'),
56
+ },
57
+ gtfs: {
58
+ enabled: true,
59
+ url: gtfsUrl('vilnius'),
60
+ },
61
+ },
62
+ kaunas: {
63
+ id: 'kaunas',
64
+ tier: 'gold',
65
+ gps: {
66
+ enabled: true,
67
+ format: 'full',
68
+ url: gpsFullUrl('kaunas'),
69
+ },
70
+ gtfs: {
71
+ enabled: true,
72
+ url: gtfsUrl('kaunas'),
73
+ },
74
+ },
75
+ klaipeda: {
76
+ id: 'klaipeda',
77
+ tier: 'gold',
78
+ gps: {
79
+ enabled: true,
80
+ format: 'full',
81
+ url: gpsFullUrl('klaipeda'),
82
+ },
83
+ gtfs: {
84
+ enabled: true,
85
+ url: gtfsUrl('klaipeda'),
86
+ },
87
+ },
88
+ alytus: {
89
+ id: 'alytus',
90
+ tier: 'gold',
91
+ gps: {
92
+ enabled: true,
93
+ format: 'full',
94
+ url: gpsFullUrl('alytus'),
95
+ },
96
+ gtfs: {
97
+ enabled: true,
98
+ url: gtfsUrl('alytus'),
99
+ },
100
+ },
101
+ druskininkai: {
102
+ id: 'druskininkai',
103
+ tier: 'gold',
104
+ gps: {
105
+ enabled: true,
106
+ format: 'full',
107
+ url: gpsFullUrl('druskininkai'),
108
+ },
109
+ gtfs: {
110
+ enabled: true,
111
+ url: gtfsUrl('druskininkai'),
112
+ },
113
+ },
114
+ panevezys: {
115
+ id: 'panevezys',
116
+ tier: 'silver',
117
+ gps: {
118
+ enabled: true,
119
+ format: 'lite',
120
+ url: gpsLiteUrl('panevezys'),
121
+ },
122
+ gtfs: {
123
+ enabled: true,
124
+ url: gtfsUrl('panevezys'),
125
+ },
126
+ },
127
+ taurage: {
128
+ id: 'taurage',
129
+ tier: 'silver',
130
+ gps: {
131
+ enabled: true,
132
+ format: 'lite',
133
+ url: gpsLiteUrl('taurage'),
134
+ },
135
+ gtfs: {
136
+ enabled: true,
137
+ url: gtfsUrl('taurage'),
138
+ },
139
+ },
140
+ siauliai: {
141
+ id: 'siauliai',
142
+ tier: 'bronze',
143
+ gps: {
144
+ enabled: false,
145
+ format: null,
146
+ url: null,
147
+ },
148
+ gtfs: {
149
+ enabled: true,
150
+ url: gtfsUrl('siauliai'),
151
+ },
152
+ },
153
+ utena: {
154
+ id: 'utena',
155
+ tier: 'bronze',
156
+ gps: {
157
+ enabled: false,
158
+ format: null,
159
+ url: null,
160
+ },
161
+ gtfs: {
162
+ enabled: true,
163
+ url: gtfsUrl('utena'),
164
+ },
165
+ },
166
+ };
167
+ /**
168
+ * City configuration matrix with all supported cities.
169
+ */
170
+ export const CITY_CONFIGS = CITY_CONFIGS_INTERNAL;
171
+ /**
172
+ * List of all supported city IDs.
173
+ */
174
+ export const ALL_CITY_IDS = Object.keys(CITY_CONFIGS);
175
+ /**
176
+ * Get configuration for a specific city.
177
+ * @throws Error if city ID is invalid
178
+ */
179
+ export function getCityConfig(city) {
180
+ return CITY_CONFIGS[city];
181
+ }
182
+ /**
183
+ * Get all cities of a specific tier.
184
+ */
185
+ export function getCitiesByTier(tier) {
186
+ return ALL_CITY_IDS.filter(city => CITY_CONFIGS[city].tier === tier);
187
+ }
188
+ /**
189
+ * Check if a city has GPS data available.
190
+ */
191
+ export function hasGpsData(city) {
192
+ return CITY_CONFIGS[city].gps.enabled;
193
+ }
194
+ /**
195
+ * Check if a city has GTFS data available.
196
+ */
197
+ export function hasGtfsData(city) {
198
+ return CITY_CONFIGS[city].gtfs.enabled;
199
+ }
200
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqEH,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF;;GAEG;AACH,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC;;GAEG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,GAAG,QAAQ,IAAI,IAAI,eAAe,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,GAAG,QAAQ,IAAI,IAAI,UAAU,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,GAAG,QAAQ,IAAI,IAAI,IAAI,IAAI,WAAW,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,qBAAqB,GAAG;IAC5B,OAAO,EAAE;QACP,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC;SAC3B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC;SACxB;KACF;IAED,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,QAAQ,CAAC;SAC1B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC;SACvB;KACF;IAED,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC;SAC5B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC;SACzB;KACF;IAED,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,QAAQ,CAAC;SAC1B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC;SACvB;KACF;IAED,YAAY,EAAE;QACZ,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,cAAc,CAAC;SAChC;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,cAAc,CAAC;SAC7B;KACF;IAED,SAAS,EAAE;QACT,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC;SAC7B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC;SAC1B;KACF;IAED,OAAO,EAAE;QACP,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE;YACH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC;SAC3B;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC;SACxB;KACF;IAED,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE;YACH,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,IAAI;SACV;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC;SACzB;KACF;IAED,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE;YACH,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,IAAI;SACV;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC;SACtB;KACF;CACO,CAAC;AAQX;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAyC,qBAAqB,CAAC;AAExF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAa,CAAC;AAErF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;AACzC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Enrichment module exports
3
+ * @module enrichment
4
+ */
5
+ export { matchRoute, enrichVehicle, enrichVehicles, type EnrichmentResult, } from './route-matcher.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/enrichment/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Enrichment module exports
3
+ * @module enrichment
4
+ */
5
+ export { matchRoute, enrichVehicle, enrichVehicles, } from './route-matcher.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/enrichment/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,GAEf,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Route matching and data enrichment for silver-tier cities
3
+ * @module enrichment/route-matcher
4
+ *
5
+ * Silver-tier cities (Panevėžys, Tauragė) provide lite GPS streams
6
+ * that lack destination and route long name. This module enriches
7
+ * vehicles with data from GTFS routes.
8
+ */
9
+ import type { Route, Vehicle } from '../types.js';
10
+ /**
11
+ * Result of route enrichment lookup.
12
+ */
13
+ export interface EnrichmentResult {
14
+ /** Destination/terminus name from route long name */
15
+ destination: string | null;
16
+ /** Full route name */
17
+ routeLongName: string | null;
18
+ /** Whether a match was found */
19
+ matched: boolean;
20
+ }
21
+ /**
22
+ * Route cache with O(1) case-insensitive lookup.
23
+ * The normalized map uses uppercase keys for fast matching.
24
+ */
25
+ export interface RouteCache {
26
+ /** Primary map: exact short name -> Route */
27
+ readonly routes: Map<string, Route>;
28
+ /** Normalized map: uppercase short name -> Route (for O(1) case-insensitive lookup) */
29
+ readonly normalizedRoutes: Map<string, Route>;
30
+ }
31
+ /**
32
+ * Build a RouteCache from a routes map.
33
+ * Pre-builds the normalized (uppercase) lookup map.
34
+ */
35
+ export declare function buildRouteCache(routes: Map<string, Route>): RouteCache;
36
+ /**
37
+ * Match a GPS route to GTFS route data.
38
+ *
39
+ * Matching strategy:
40
+ * 1. Exact match on route short name (case-sensitive) - O(1)
41
+ * 2. Case-insensitive match via normalized map - O(1)
42
+ *
43
+ * @param gpsRoute - Route identifier from GPS stream
44
+ * @param cache - RouteCache with pre-built normalized lookup
45
+ * @returns Enrichment result with destination and route name
46
+ */
47
+ export declare function matchRoute(gpsRoute: string, cache: RouteCache): EnrichmentResult;
48
+ /**
49
+ * Enrich a vehicle with GTFS route data.
50
+ *
51
+ * @param vehicle - Vehicle to enrich
52
+ * @param cache - RouteCache with pre-built normalized lookup
53
+ * @returns New vehicle with enriched data (or original if no match)
54
+ */
55
+ export declare function enrichVehicle(vehicle: Vehicle, cache: RouteCache): Vehicle;
56
+ /**
57
+ * Enrich an array of vehicles with GTFS route data.
58
+ *
59
+ * @param vehicles - Vehicles to enrich
60
+ * @param cache - RouteCache with pre-built normalized lookup
61
+ * @returns New array with enriched vehicles
62
+ */
63
+ export declare function enrichVehicles(vehicles: Vehicle[], cache: RouteCache): Vehicle[];
64
+ //# sourceMappingURL=route-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-matcher.d.ts","sourceRoot":"","sources":["../../src/enrichment/route-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAMlD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,sBAAsB;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC,uFAAuF;IACvF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,UAAU,CAQtE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,GAChB,gBAAgB,CAsBlB;AA6CD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,GAChB,OAAO,CAiBT;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,UAAU,GAChB,OAAO,EAAE,CAEX"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Route matching and data enrichment for silver-tier cities
3
+ * @module enrichment/route-matcher
4
+ *
5
+ * Silver-tier cities (Panevėžys, Tauragė) provide lite GPS streams
6
+ * that lack destination and route long name. This module enriches
7
+ * vehicles with data from GTFS routes.
8
+ */
9
+ /**
10
+ * Build a RouteCache from a routes map.
11
+ * Pre-builds the normalized (uppercase) lookup map.
12
+ */
13
+ export function buildRouteCache(routes) {
14
+ const normalizedRoutes = new Map();
15
+ for (const [key, route] of routes) {
16
+ normalizedRoutes.set(key.toUpperCase(), route);
17
+ }
18
+ return { routes, normalizedRoutes };
19
+ }
20
+ // =============================================================================
21
+ // Route Matcher
22
+ // =============================================================================
23
+ /**
24
+ * Match a GPS route to GTFS route data.
25
+ *
26
+ * Matching strategy:
27
+ * 1. Exact match on route short name (case-sensitive) - O(1)
28
+ * 2. Case-insensitive match via normalized map - O(1)
29
+ *
30
+ * @param gpsRoute - Route identifier from GPS stream
31
+ * @param cache - RouteCache with pre-built normalized lookup
32
+ * @returns Enrichment result with destination and route name
33
+ */
34
+ export function matchRoute(gpsRoute, cache) {
35
+ // Empty route - no enrichment possible
36
+ if (!gpsRoute || gpsRoute.trim() === '') {
37
+ return { destination: null, routeLongName: null, matched: false };
38
+ }
39
+ const normalized = gpsRoute.trim();
40
+ // 1. Try exact match - O(1)
41
+ const exactRoute = cache.routes.get(normalized);
42
+ if (exactRoute) {
43
+ return extractEnrichment(exactRoute);
44
+ }
45
+ // 2. Try case-insensitive match via normalized map - O(1)
46
+ const upperRoute = cache.normalizedRoutes.get(normalized.toUpperCase());
47
+ if (upperRoute) {
48
+ return extractEnrichment(upperRoute);
49
+ }
50
+ // 3. No match found
51
+ return { destination: null, routeLongName: null, matched: false };
52
+ }
53
+ /**
54
+ * Extract enrichment data from a matched route.
55
+ */
56
+ function extractEnrichment(route) {
57
+ // Parse destination from long name
58
+ // Common patterns:
59
+ // - "Terminus A - Terminus B"
60
+ // - "Terminus A – Terminus B" (en-dash)
61
+ // - Just use the full long name if no separator
62
+ let destination = null;
63
+ if (route.longName !== '' && route.longName.length > 0) {
64
+ // Try to extract destination (usually after separator)
65
+ const separators = [' - ', ' – ', ' — ', ' / '];
66
+ for (const sep of separators) {
67
+ if (route.longName.includes(sep)) {
68
+ const parts = route.longName.split(sep);
69
+ const lastPart = parts[parts.length - 1];
70
+ // Use the last part as destination (typical direction)
71
+ if (lastPart !== undefined) {
72
+ destination = lastPart.trim();
73
+ }
74
+ break;
75
+ }
76
+ }
77
+ // If no separator found, use full long name
78
+ destination ??= route.longName;
79
+ }
80
+ return {
81
+ destination,
82
+ routeLongName: route.longName !== '' ? route.longName : null,
83
+ matched: true,
84
+ };
85
+ }
86
+ // =============================================================================
87
+ // Vehicle Enrichment
88
+ // =============================================================================
89
+ /**
90
+ * Enrich a vehicle with GTFS route data.
91
+ *
92
+ * @param vehicle - Vehicle to enrich
93
+ * @param cache - RouteCache with pre-built normalized lookup
94
+ * @returns New vehicle with enriched data (or original if no match)
95
+ */
96
+ export function enrichVehicle(vehicle, cache) {
97
+ // Skip if already has destination
98
+ if (vehicle.destination !== null && vehicle.destination !== '') {
99
+ return vehicle;
100
+ }
101
+ const enrichment = matchRoute(vehicle.route, cache);
102
+ if (!enrichment.matched) {
103
+ return vehicle;
104
+ }
105
+ // Return new vehicle with enriched data
106
+ return {
107
+ ...vehicle,
108
+ destination: enrichment.destination,
109
+ };
110
+ }
111
+ /**
112
+ * Enrich an array of vehicles with GTFS route data.
113
+ *
114
+ * @param vehicles - Vehicles to enrich
115
+ * @param cache - RouteCache with pre-built normalized lookup
116
+ * @returns New array with enriched vehicles
117
+ */
118
+ export function enrichVehicles(vehicles, cache) {
119
+ return vehicles.map(v => enrichVehicle(v, cache));
120
+ }
121
+ //# sourceMappingURL=route-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-matcher.js","sourceRoot":"","sources":["../../src/enrichment/route-matcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Custom error types for Lithuanian Public Transport SDK
3
+ * @module errors
4
+ */
5
+ import type { CityId } from './types.js';
6
+ /**
7
+ * Base error class for transport SDK errors.
8
+ */
9
+ export declare abstract class TransportError extends Error {
10
+ /** City associated with this error, if applicable */
11
+ abstract readonly city: CityId | null;
12
+ constructor(message: string);
13
+ }
14
+ /**
15
+ * Error thrown when a network request fails.
16
+ */
17
+ export declare class TransportNetworkError extends TransportError {
18
+ readonly cityId: CityId;
19
+ readonly statusCode?: number | undefined;
20
+ readonly cause?: Error | undefined;
21
+ readonly city: CityId;
22
+ constructor(message: string, cityId: CityId, statusCode?: number | undefined, cause?: Error | undefined);
23
+ }
24
+ /**
25
+ * Error thrown when GPS data is requested for a bronze-tier city.
26
+ */
27
+ export declare class GpsNotAvailableError extends TransportError {
28
+ readonly city: CityId;
29
+ constructor(cityId: CityId);
30
+ }
31
+ /**
32
+ * Error thrown when GTFS data is required but not yet synced.
33
+ */
34
+ export declare class SyncRequiredError extends TransportError {
35
+ readonly city: CityId;
36
+ constructor(cityId: CityId);
37
+ }
38
+ /**
39
+ * Error thrown when GTFS sync fails.
40
+ */
41
+ export declare class GtfsSyncError extends TransportError {
42
+ readonly cause?: Error | undefined;
43
+ readonly city: CityId;
44
+ constructor(cityId: CityId, message: string, cause?: Error | undefined);
45
+ }
46
+ /**
47
+ * Error thrown when parsing GPS or GTFS data fails.
48
+ */
49
+ export declare class ParseError extends TransportError {
50
+ readonly line?: number | undefined;
51
+ readonly rawData?: string | undefined;
52
+ readonly city: CityId | null;
53
+ constructor(message: string, cityId?: CityId, line?: number | undefined, rawData?: string | undefined);
54
+ }
55
+ /**
56
+ * Error thrown when an invalid city ID is provided.
57
+ */
58
+ export declare class InvalidCityError extends TransportError {
59
+ readonly city: null;
60
+ constructor(providedCity: string);
61
+ }
62
+ /**
63
+ * Type guard to check if an error is a TransportError.
64
+ */
65
+ export declare function isTransportError(error: unknown): error is TransportError;
66
+ /**
67
+ * Type guard to check if an error is a network error.
68
+ */
69
+ export declare function isNetworkError(error: unknown): error is TransportNetworkError;
70
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,8BAAsB,cAAe,SAAQ,KAAK;IAChD,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE1B,OAAO,EAAE,MAAM;CAQ5B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;aAKrC,MAAM,EAAE,MAAM;aACd,UAAU,CAAC,EAAE,MAAM;aACnB,KAAK,CAAC,EAAE,KAAK;IAN/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM;CAI3B;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,cAAc;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM;CAI3B;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,cAAc;aAM7B,KAAK,CAAC,EAAE,KAAK;IAL/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,cAAc;aAM1B,IAAI,CAAC,EAAE,MAAM;aACb,OAAO,CAAC,EAAE,MAAM;IANlC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;gBAG3B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,OAAO,CAAC,EAAE,MAAM,YAAA;CAQnC;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;IAClD,QAAQ,CAAC,IAAI,OAAQ;gBAET,YAAY,EAAE,MAAM;CAGjC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAExE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAE7E"}
package/dist/errors.js ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Custom error types for Lithuanian Public Transport SDK
3
+ * @module errors
4
+ */
5
+ /**
6
+ * Base error class for transport SDK errors.
7
+ */
8
+ export class TransportError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = this.constructor.name;
12
+ // Maintains proper stack trace for where error was thrown (V8 engines)
13
+ if (typeof Error.captureStackTrace === 'function') {
14
+ Error.captureStackTrace(this, this.constructor);
15
+ }
16
+ }
17
+ }
18
+ /**
19
+ * Error thrown when a network request fails.
20
+ */
21
+ export class TransportNetworkError extends TransportError {
22
+ cityId;
23
+ statusCode;
24
+ cause;
25
+ city;
26
+ constructor(message, cityId, statusCode, cause) {
27
+ super(message);
28
+ this.cityId = cityId;
29
+ this.statusCode = statusCode;
30
+ this.cause = cause;
31
+ this.city = cityId;
32
+ }
33
+ }
34
+ /**
35
+ * Error thrown when GPS data is requested for a bronze-tier city.
36
+ */
37
+ export class GpsNotAvailableError extends TransportError {
38
+ city;
39
+ constructor(cityId) {
40
+ super(`GPS data is not available for ${cityId} (bronze tier city). Use GTFS static data instead.`);
41
+ this.city = cityId;
42
+ }
43
+ }
44
+ /**
45
+ * Error thrown when GTFS data is required but not yet synced.
46
+ */
47
+ export class SyncRequiredError extends TransportError {
48
+ city;
49
+ constructor(cityId) {
50
+ super(`GTFS data for ${cityId} is not synced. Call sync('${cityId}') first.`);
51
+ this.city = cityId;
52
+ }
53
+ }
54
+ /**
55
+ * Error thrown when GTFS sync fails.
56
+ */
57
+ export class GtfsSyncError extends TransportError {
58
+ cause;
59
+ city;
60
+ constructor(cityId, message, cause) {
61
+ super(`GTFS sync failed for ${cityId}: ${message}`);
62
+ this.cause = cause;
63
+ this.city = cityId;
64
+ }
65
+ }
66
+ /**
67
+ * Error thrown when parsing GPS or GTFS data fails.
68
+ */
69
+ export class ParseError extends TransportError {
70
+ line;
71
+ rawData;
72
+ city;
73
+ constructor(message, cityId, line, rawData) {
74
+ const fullMessage = cityId !== undefined
75
+ ? `Parse error for ${cityId}${line !== undefined ? ` at line ${String(line)}` : ''}: ${message}`
76
+ : `Parse error: ${message}`;
77
+ super(fullMessage);
78
+ this.line = line;
79
+ this.rawData = rawData;
80
+ this.city = cityId ?? null;
81
+ }
82
+ }
83
+ /**
84
+ * Error thrown when an invalid city ID is provided.
85
+ */
86
+ export class InvalidCityError extends TransportError {
87
+ city = null;
88
+ constructor(providedCity) {
89
+ super(`Invalid city ID: '${providedCity}'. See ALL_CITY_IDS for valid options.`);
90
+ }
91
+ }
92
+ /**
93
+ * Type guard to check if an error is a TransportError.
94
+ */
95
+ export function isTransportError(error) {
96
+ return error instanceof TransportError;
97
+ }
98
+ /**
99
+ * Type guard to check if an error is a network error.
100
+ */
101
+ export function isNetworkError(error) {
102
+ return error instanceof TransportNetworkError;
103
+ }
104
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,OAAgB,cAAe,SAAQ,KAAK;IAIhD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,uEAAuE;QACvE,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAClD,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,cAAc;IAKrC;IACA;IACA;IANT,IAAI,CAAS;IAEtB,YACE,OAAe,EACC,MAAc,EACd,UAAmB,EACnB,KAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAS;QACnB,UAAK,GAAL,KAAK,CAAQ;QAG7B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,cAAc;IAC7C,IAAI,CAAS;IAEtB,YAAY,MAAc;QACxB,KAAK,CAAC,iCAAiC,MAAM,oDAAoD,CAAC,CAAC;QACnG,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IAC1C,IAAI,CAAS;IAEtB,YAAY,MAAc;QACxB,KAAK,CAAC,iBAAiB,MAAM,8BAA8B,MAAM,WAAW,CAAC,CAAC;QAC9E,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,cAAc;IAM7B;IALT,IAAI,CAAS;IAEtB,YACE,MAAc,EACd,OAAe,EACC,KAAa;QAE7B,KAAK,CAAC,wBAAwB,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;QAFpC,UAAK,GAAL,KAAK,CAAQ;QAG7B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,cAAc;IAM1B;IACA;IANT,IAAI,CAAgB;IAE7B,YACE,OAAe,EACf,MAAe,EACC,IAAa,EACb,OAAgB;QAEhC,MAAM,WAAW,GAAG,MAAM,KAAK,SAAS;YACtC,CAAC,CAAC,mBAAmB,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE;YAChG,CAAC,CAAC,gBAAgB,OAAO,EAAE,CAAC;QAC9B,KAAK,CAAC,WAAW,CAAC,CAAC;QANH,SAAI,GAAJ,IAAI,CAAS;QACb,YAAO,GAAP,OAAO,CAAS;QAMhC,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,IAAI,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IACzC,IAAI,GAAG,IAAI,CAAC;IAErB,YAAY,YAAoB;QAC9B,KAAK,CAAC,qBAAqB,YAAY,wCAAwC,CAAC,CAAC;IACnF,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,KAAK,YAAY,cAAc,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,KAAK,YAAY,qBAAqB,CAAC;AAChD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * GTFS module exports
3
+ * @module gtfs
4
+ */
5
+ export { parseRoutesContent, parseStopsContent, } from './parser.js';
6
+ export { syncGtfs, loadGtfsCache, loadCachedRoutes, loadCachedStops, type SyncOptions, type GtfsCache, } from './sync.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gtfs/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,WAAW,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * GTFS module exports
3
+ * @module gtfs
4
+ */
5
+ export { parseRoutesContent, parseStopsContent, } from './parser.js';
6
+ export { syncGtfs, loadGtfsCache, loadCachedRoutes, loadCachedStops, } from './sync.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gtfs/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,eAAe,GAGhB,MAAM,WAAW,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * GTFS file parsers for routes.txt and stops.txt
3
+ * @module gtfs/parser
4
+ */
5
+ import type { Route, Stop } from '../types.js';
6
+ /**
7
+ * Parse routes.txt content into a Map keyed by route short name.
8
+ *
9
+ * GTFS routes.txt fields:
10
+ * - route_id: Unique identifier
11
+ * - agency_id: Agency reference
12
+ * - route_short_name: Short name (e.g., "4G", "N1")
13
+ * - route_long_name: Full name with endpoints
14
+ * - route_desc: Description
15
+ * - route_type: GTFS route type (3=bus, 800=trolleybus)
16
+ * - route_url: URL
17
+ * - route_color: Background color (hex)
18
+ * - route_text_color: Text color (hex)
19
+ *
20
+ * @param content - Raw routes.txt content
21
+ * @returns Map from route short name to Route object
22
+ */
23
+ export declare function parseRoutesContent(content: string): Map<string, Route>;
24
+ /**
25
+ * Parse stops.txt content into an array of Stop objects.
26
+ *
27
+ * GTFS stops.txt fields:
28
+ * - stop_id: Unique identifier
29
+ * - stop_code: Short code
30
+ * - stop_name: Human-readable name
31
+ * - stop_desc: Description
32
+ * - stop_lat: Latitude
33
+ * - stop_lon: Longitude
34
+ *
35
+ * @param content - Raw stops.txt content
36
+ * @returns Array of Stop objects
37
+ */
38
+ export declare function parseStopsContent(content: string): Stop[];
39
+ //# sourceMappingURL=parser.d.ts.map