minotor 7.0.1 → 8.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 (59) hide show
  1. package/.cspell.json +11 -1
  2. package/CHANGELOG.md +8 -3
  3. package/README.md +26 -24
  4. package/dist/cli.mjs +1268 -290
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/gtfs/transfers.d.ts +13 -4
  7. package/dist/gtfs/trips.d.ts +12 -7
  8. package/dist/parser.cjs.js +519 -95
  9. package/dist/parser.cjs.js.map +1 -1
  10. package/dist/parser.esm.js +519 -95
  11. package/dist/parser.esm.js.map +1 -1
  12. package/dist/router.cjs.js +1 -1
  13. package/dist/router.cjs.js.map +1 -1
  14. package/dist/router.d.ts +2 -2
  15. package/dist/router.esm.js +1 -1
  16. package/dist/router.esm.js.map +1 -1
  17. package/dist/router.umd.js +1 -1
  18. package/dist/router.umd.js.map +1 -1
  19. package/dist/routing/__tests__/plotter.test.d.ts +1 -0
  20. package/dist/routing/plotter.d.ts +42 -3
  21. package/dist/routing/result.d.ts +23 -7
  22. package/dist/routing/route.d.ts +2 -0
  23. package/dist/routing/router.d.ts +78 -19
  24. package/dist/timetable/__tests__/tripId.test.d.ts +1 -0
  25. package/dist/timetable/io.d.ts +4 -2
  26. package/dist/timetable/proto/timetable.d.ts +13 -1
  27. package/dist/timetable/route.d.ts +41 -8
  28. package/dist/timetable/timetable.d.ts +18 -3
  29. package/dist/timetable/tripId.d.ts +15 -0
  30. package/package.json +1 -1
  31. package/src/__e2e__/router.test.ts +114 -105
  32. package/src/__e2e__/timetable/stops.bin +2 -2
  33. package/src/__e2e__/timetable/timetable.bin +2 -2
  34. package/src/cli/repl.ts +259 -1
  35. package/src/gtfs/__tests__/transfers.test.ts +468 -12
  36. package/src/gtfs/__tests__/trips.test.ts +350 -28
  37. package/src/gtfs/parser.ts +16 -4
  38. package/src/gtfs/transfers.ts +61 -18
  39. package/src/gtfs/trips.ts +97 -22
  40. package/src/router.ts +2 -2
  41. package/src/routing/__tests__/plotter.test.ts +230 -0
  42. package/src/routing/__tests__/result.test.ts +486 -125
  43. package/src/routing/__tests__/route.test.ts +7 -3
  44. package/src/routing/__tests__/router.test.ts +378 -172
  45. package/src/routing/plotter.ts +279 -48
  46. package/src/routing/result.ts +114 -34
  47. package/src/routing/route.ts +0 -3
  48. package/src/routing/router.ts +332 -209
  49. package/src/timetable/__tests__/io.test.ts +33 -1
  50. package/src/timetable/__tests__/route.test.ts +10 -3
  51. package/src/timetable/__tests__/timetable.test.ts +225 -57
  52. package/src/timetable/__tests__/tripId.test.ts +27 -0
  53. package/src/timetable/io.ts +71 -10
  54. package/src/timetable/proto/timetable.proto +14 -2
  55. package/src/timetable/proto/timetable.ts +218 -20
  56. package/src/timetable/route.ts +152 -19
  57. package/src/timetable/time.ts +23 -9
  58. package/src/timetable/timetable.ts +46 -9
  59. package/src/timetable/tripId.ts +29 -0
@@ -12,7 +12,8 @@ import {
12
12
  serializeStopsAdjacency,
13
13
  } from './io.js';
14
14
  import { Timetable as ProtoTimetable } from './proto/timetable.js';
15
- import { Route, RouteId } from './route.js';
15
+ import { Route, RouteId, TripRouteIndex } from './route.js';
16
+ import { encode, TripId } from './tripId.js';
16
17
 
17
18
  export type TransferType =
18
19
  | 'RECOMMENDED'
@@ -26,8 +27,15 @@ export type Transfer = {
26
27
  minTransferTime?: Duration;
27
28
  };
28
29
 
30
+ export type TripBoarding = {
31
+ hopOnStop: StopId;
32
+ routeId: RouteId;
33
+ tripIndex: TripRouteIndex;
34
+ };
35
+
29
36
  export type StopAdjacency = {
30
- transfers: Transfer[];
37
+ transfers?: Transfer[];
38
+ tripContinuations?: Map<TripId, TripBoarding[]>;
31
39
  routes: RouteId[];
32
40
  };
33
41
 
@@ -68,7 +76,9 @@ export const ALL_TRANSPORT_MODES: Set<RouteType> = new Set([
68
76
  'MONORAIL',
69
77
  ]);
70
78
 
71
- export const CURRENT_VERSION = '0.0.7';
79
+ const EMPTY_TRIP_CONTINUATIONS: TripBoarding[] = [];
80
+
81
+ export const CURRENT_VERSION = '0.0.8';
72
82
 
73
83
  /**
74
84
  * The internal transit timetable format.
@@ -89,9 +99,12 @@ export class Timetable {
89
99
  this.serviceRoutes = routes;
90
100
  this.activeStops = new Set<StopId>();
91
101
  for (let i = 0; i < stopsAdjacency.length; i++) {
92
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
93
102
  const stop = stopsAdjacency[i]!;
94
- if (stop.routes.length > 0 || stop.transfers.length > 0) {
103
+ if (
104
+ stop.routes.length > 0 ||
105
+ (stop.transfers && stop.transfers.length > 0) ||
106
+ (stop.tripContinuations && stop.tripContinuations.size > 0)
107
+ ) {
95
108
  this.activeStops.add(i);
96
109
  }
97
110
  }
@@ -166,7 +179,33 @@ export class Timetable {
166
179
  * @returns An array of transfer options available at the stop.
167
180
  */
168
181
  getTransfers(stopId: StopId): Transfer[] {
169
- return this.stopsAdjacency[stopId]?.transfers ?? [];
182
+ const stopAdjacency = this.stopsAdjacency[stopId];
183
+ if (!stopAdjacency) {
184
+ throw new Error(`Stop ID ${stopId} not found`);
185
+ }
186
+ return stopAdjacency.transfers || [];
187
+ }
188
+
189
+ /**
190
+ * Retrieves all trip continuation options available at the specified stop for a given trip.
191
+ *
192
+ * @param stopId - The ID of the stop to get trip continuations for.
193
+ * @param tripIndex - The index of the trip to get continuations for.
194
+ * @returns An array of trip continuation options available at the stop for the specified trip.
195
+ */
196
+ getContinuousTrips(
197
+ stopId: StopId,
198
+ routeId: RouteId,
199
+ tripIndex: TripRouteIndex,
200
+ ): TripBoarding[] {
201
+ const stopAdjacency = this.stopsAdjacency[stopId];
202
+ if (!stopAdjacency) {
203
+ throw new Error(`Stop ID ${stopId} not found`);
204
+ }
205
+ return (
206
+ stopAdjacency.tripContinuations?.get(encode(routeId, tripIndex)) ||
207
+ EMPTY_TRIP_CONTINUATIONS
208
+ );
170
209
  }
171
210
 
172
211
  /**
@@ -184,9 +223,7 @@ export class Timetable {
184
223
  `Service route not found for route ID: ${route.serviceRoute()}`,
185
224
  );
186
225
  }
187
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
188
- const { routes, ...serviceRouteInfo } = serviceRoute;
189
- return serviceRouteInfo;
226
+ return { type: serviceRoute.type, name: serviceRoute.name };
190
227
  }
191
228
 
192
229
  /**
@@ -0,0 +1,29 @@
1
+ import { RouteId, TripRouteIndex } from './route.js';
2
+
3
+ // const ROUTE_ID_BITS = 17;
4
+ const TRIP_INDEX_BITS = 15;
5
+ const TRIP_INDEX_MASK = (1 << TRIP_INDEX_BITS) - 1;
6
+
7
+ // A TripId encodes a route ID and trip index into a value
8
+ export type TripId = number;
9
+
10
+ /**
11
+ * Encodes a route ID and trip index into a single trip ID.
12
+ * @param routeId - The route identifier, needs to fit on 17 bits
13
+ * @param tripIndex - The index of the trip within the route, needs to fit on 15 bits
14
+ * @returns The encoded trip ID
15
+ */
16
+ export const encode = (routeId: RouteId, tripIndex: TripRouteIndex): TripId => {
17
+ return (routeId << TRIP_INDEX_BITS) | tripIndex;
18
+ };
19
+
20
+ /**
21
+ * Decodes a trip ID back into its constituent route ID and trip index.
22
+ * @param tripId - The encoded trip ID
23
+ * @returns A tuple containing the route ID and trip index
24
+ */
25
+ export const decode = (tripId: TripId): [RouteId, TripRouteIndex] => {
26
+ const routeId = tripId >>> TRIP_INDEX_BITS;
27
+ const tripIndex = tripId & TRIP_INDEX_MASK;
28
+ return [routeId, tripIndex];
29
+ };