minotor 1.0.7 → 2.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 (60) hide show
  1. package/CHANGELOG.md +9 -3
  2. package/README.md +3 -2
  3. package/dist/cli.mjs +604 -531
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/gtfs/stops.d.ts +19 -5
  6. package/dist/gtfs/transfers.d.ts +5 -4
  7. package/dist/gtfs/trips.d.ts +7 -5
  8. package/dist/gtfs/utils.d.ts +7 -8
  9. package/dist/parser.cjs.js +569 -501
  10. package/dist/parser.cjs.js.map +1 -1
  11. package/dist/parser.esm.js +569 -501
  12. package/dist/parser.esm.js.map +1 -1
  13. package/dist/router.cjs.js +1 -1
  14. package/dist/router.cjs.js.map +1 -1
  15. package/dist/router.d.ts +3 -3
  16. package/dist/router.esm.js +1 -1
  17. package/dist/router.esm.js.map +1 -1
  18. package/dist/router.umd.js +1 -1
  19. package/dist/router.umd.js.map +1 -1
  20. package/dist/routing/__tests__/route.test.d.ts +1 -0
  21. package/dist/routing/query.d.ts +7 -7
  22. package/dist/routing/result.d.ts +3 -3
  23. package/dist/routing/route.d.ts +1 -0
  24. package/dist/stops/proto/stops.d.ts +5 -4
  25. package/dist/stops/stops.d.ts +10 -1
  26. package/dist/stops/stopsIndex.d.ts +21 -4
  27. package/dist/timetable/proto/timetable.d.ts +21 -18
  28. package/dist/timetable/timetable.d.ts +38 -14
  29. package/package.json +4 -3
  30. package/src/cli/repl.ts +13 -10
  31. package/src/gtfs/__tests__/parser.test.ts +50 -579
  32. package/src/gtfs/__tests__/stops.test.ts +181 -112
  33. package/src/gtfs/__tests__/transfers.test.ts +170 -12
  34. package/src/gtfs/__tests__/trips.test.ts +212 -141
  35. package/src/gtfs/__tests__/utils.test.ts +4 -4
  36. package/src/gtfs/parser.ts +22 -13
  37. package/src/gtfs/stops.ts +63 -28
  38. package/src/gtfs/transfers.ts +14 -6
  39. package/src/gtfs/trips.ts +110 -47
  40. package/src/gtfs/utils.ts +11 -11
  41. package/src/router.ts +2 -4
  42. package/src/routing/__tests__/route.test.ts +112 -0
  43. package/src/routing/__tests__/router.test.ts +234 -244
  44. package/src/routing/query.ts +7 -7
  45. package/src/routing/result.ts +9 -6
  46. package/src/routing/route.ts +11 -0
  47. package/src/routing/router.ts +26 -24
  48. package/src/stops/__tests__/io.test.ts +9 -8
  49. package/src/stops/__tests__/stopFinder.test.ts +45 -36
  50. package/src/stops/io.ts +8 -5
  51. package/src/stops/proto/stops.proto +8 -7
  52. package/src/stops/proto/stops.ts +68 -38
  53. package/src/stops/stops.ts +13 -1
  54. package/src/stops/stopsIndex.ts +50 -7
  55. package/src/timetable/__tests__/io.test.ts +40 -49
  56. package/src/timetable/__tests__/timetable.test.ts +50 -58
  57. package/src/timetable/io.ts +69 -56
  58. package/src/timetable/proto/timetable.proto +22 -17
  59. package/src/timetable/proto/timetable.ts +94 -184
  60. package/src/timetable/timetable.ts +62 -29
@@ -1,11 +1,11 @@
1
- import { StopId } from '../stops/stops.js';
1
+ import { SourceStopId } from '../stops/stops.js';
2
2
  import { Duration } from '../timetable/duration.js';
3
3
  import { Time } from '../timetable/time.js';
4
4
  import { ALL_TRANSPORT_MODES, RouteType } from '../timetable/timetable.js';
5
5
 
6
6
  export class Query {
7
- from: StopId;
8
- to: StopId[];
7
+ from: SourceStopId;
8
+ to: SourceStopId[];
9
9
  departureTime: Time;
10
10
  lastDepartureTime?: Time;
11
11
  options: {
@@ -22,8 +22,8 @@ export class Query {
22
22
  }
23
23
 
24
24
  static Builder = class {
25
- fromValue!: StopId;
26
- toValue: StopId[] = [];
25
+ fromValue!: SourceStopId;
26
+ toValue: SourceStopId[] = [];
27
27
  departureTimeValue!: Time;
28
28
  // lastDepartureTimeValue?: Date;
29
29
  // via: StopId[] = [];
@@ -37,12 +37,12 @@ export class Query {
37
37
  transportModes: ALL_TRANSPORT_MODES,
38
38
  };
39
39
 
40
- from(from: StopId): this {
40
+ from(from: SourceStopId): this {
41
41
  this.fromValue = from;
42
42
  return this;
43
43
  }
44
44
 
45
- to(to: StopId | StopId[]): this {
45
+ to(to: SourceStopId | SourceStopId[]): this {
46
46
  this.toValue = Array.isArray(to) ? to : [to];
47
47
  return this;
48
48
  }
@@ -1,4 +1,4 @@
1
- import { StopId } from '../stops/stops.js';
1
+ import { SourceStopId, StopId } from '../stops/stops.js';
2
2
  import { StopsIndex } from '../stops/stopsIndex.js';
3
3
  import { Query } from './query.js';
4
4
  import { Leg, Route } from './route.js';
@@ -29,7 +29,7 @@ export class Result {
29
29
  * @param to The destination stop. Defaults to the destination of the original query.
30
30
  * @returns a route to the destination stop if it exists.
31
31
  */
32
- bestRoute(to?: StopId | StopId[]): Route | undefined {
32
+ bestRoute(to?: SourceStopId | SourceStopId[]): Route | undefined {
33
33
  const destinationList = Array.isArray(to) ? to : to ? [to] : this.query.to;
34
34
  const destinations = destinationList.flatMap((destination) =>
35
35
  this.stopsIndex.equivalentStops(destination),
@@ -38,13 +38,13 @@ export class Result {
38
38
  let fastestDestination: StopId | undefined = undefined;
39
39
  let fastestTime: ReachingTime | undefined = undefined;
40
40
  for (const destination of destinations) {
41
- const arrivalTime = this.earliestArrivals.get(destination);
41
+ const arrivalTime = this.earliestArrivals.get(destination.id);
42
42
  if (arrivalTime !== undefined) {
43
43
  if (
44
44
  fastestTime === undefined ||
45
45
  arrivalTime.time.toSeconds() < fastestTime.time.toSeconds()
46
46
  ) {
47
- fastestDestination = destination;
47
+ fastestDestination = destination.id;
48
48
  fastestTime = arrivalTime;
49
49
  }
50
50
  }
@@ -81,7 +81,10 @@ export class Result {
81
81
  * @param maxTransfers The optional maximum number of transfers allowed.
82
82
  * @returns The arrival time if the target stop is reachable, otherwise undefined.
83
83
  */
84
- arrivalAt(stop: StopId, maxTransfers?: number): ReachingTime | undefined {
84
+ arrivalAt(
85
+ stop: SourceStopId,
86
+ maxTransfers?: number,
87
+ ): ReachingTime | undefined {
85
88
  const equivalentStops = this.stopsIndex.equivalentStops(stop);
86
89
  let earliestArrival: ReachingTime | undefined = undefined;
87
90
 
@@ -92,7 +95,7 @@ export class Result {
92
95
  : this.earliestArrivals;
93
96
 
94
97
  for (const equivalentStop of equivalentStops) {
95
- const arrivalTime = relevantArrivals.get(equivalentStop);
98
+ const arrivalTime = relevantArrivals.get(equivalentStop.id);
96
99
  if (arrivalTime !== undefined) {
97
100
  if (
98
101
  earliestArrival === undefined ||
@@ -3,6 +3,12 @@ import { Duration } from '../timetable/duration.js';
3
3
  import { Time } from '../timetable/time.js';
4
4
  import { ServiceRoute, TransferType } from '../timetable/timetable.js';
5
5
 
6
+ export type PickUpDropOffType =
7
+ | 'REGULAR'
8
+ | 'NOT_AVAILABLE'
9
+ | 'MUST_PHONE_AGENCY'
10
+ | 'MUST_COORDINATE_WITH_DRIVER';
11
+
6
12
  export type BaseLeg = {
7
13
  from: Stop;
8
14
  to: Stop;
@@ -17,6 +23,11 @@ export type VehicleLeg = BaseLeg & {
17
23
  route: ServiceRoute;
18
24
  departureTime: Time;
19
25
  arrivalTime: Time;
26
+ // TODO support pick up and drop off types
27
+ /*
28
+ pickUpType: PickUpDropOffType;
29
+ dropOffType: PickUpDropOffType;
30
+ */
20
31
  };
21
32
 
22
33
  export type Leg = Transfer | VehicleLeg;
@@ -3,7 +3,7 @@ import { StopId } from '../stops/stops.js';
3
3
  import { StopsIndex } from '../stops/stopsIndex.js';
4
4
  import { Duration } from '../timetable/duration.js';
5
5
  import { Time } from '../timetable/time.js';
6
- import { Timetable } from '../timetable/timetable.js';
6
+ import { NOT_AVAILABLE, Timetable } from '../timetable/timetable.js';
7
7
  import { Query } from './query.js';
8
8
  import { Result } from './result.js';
9
9
  import { Leg } from './route.js';
@@ -113,16 +113,16 @@ export class Router {
113
113
  const markedStops = new Set<StopId>();
114
114
 
115
115
  for (const originStop of origins) {
116
- markedStops.add(originStop);
117
- earliestArrivals.set(originStop, {
116
+ markedStops.add(originStop.id);
117
+ earliestArrivals.set(originStop.id, {
118
118
  time: departureTime,
119
119
  legNumber: 0,
120
- origin: originStop,
120
+ origin: originStop.id,
121
121
  });
122
- earliestArrivalsWithoutAnyLeg.set(originStop, {
122
+ earliestArrivalsWithoutAnyLeg.set(originStop.id, {
123
123
  time: departureTime,
124
124
  legNumber: 0,
125
- origin: originStop,
125
+ origin: originStop.id,
126
126
  });
127
127
  }
128
128
  // on the first round we need to first consider transfers to discover all possible route origins
@@ -150,13 +150,17 @@ export class Router {
150
150
  const route = this.timetable.getRoute(routeId)!;
151
151
  let currentTrip: CurrentTrip | undefined = undefined;
152
152
  const hopOnIndex = route.stopIndices.get(hopOnStop)!;
153
- // for each stops in the route starting with the hop-on one
153
+ // for each stop in the route starting with the hop-on one
154
154
  for (let i = hopOnIndex; i < route.stops.length; i++) {
155
155
  const currentStop = route.stops[i]!;
156
156
  const stopNumbers = route.stops.length;
157
157
  if (currentTrip !== undefined) {
158
- const currentStopTimes =
159
- route.stopTimes[currentTrip.trip * stopNumbers + i]!;
158
+ const currentArrivalIndex =
159
+ (currentTrip.trip * stopNumbers + i) * 2;
160
+ const currentArrivalTime = Time.fromSeconds(
161
+ route.stopTimes[currentArrivalIndex]!,
162
+ );
163
+ const currentDropOffType = route.pickUpDropOffTypes[i * 2 + 1];
160
164
  const earliestArrivalAtCurrentStop =
161
165
  earliestArrivals.get(currentStop)?.time ?? UNREACHED;
162
166
  let arrivalToImprove = earliestArrivalAtCurrentStop;
@@ -166,7 +170,7 @@ export class Router {
166
170
  // should compare to the earliest arrival at any of them
167
171
  for (const destinationStop of destinations) {
168
172
  const earliestArrivalAtDestination =
169
- earliestArrivals.get(destinationStop)?.time ?? UNREACHED;
173
+ earliestArrivals.get(destinationStop.id)?.time ?? UNREACHED;
170
174
  earliestArrivalsAtDestinations.push(
171
175
  earliestArrivalAtDestination,
172
176
  );
@@ -180,19 +184,19 @@ export class Router {
180
184
  );
181
185
  }
182
186
  if (
183
- currentStopTimes.dropOffType !== 'NOT_AVAILABLE' &&
184
- currentStopTimes.arrival.toSeconds() <
185
- arrivalToImprove.toSeconds()
187
+ currentDropOffType !== NOT_AVAILABLE &&
188
+ currentArrivalTime.toSeconds() < arrivalToImprove.toSeconds()
186
189
  ) {
187
190
  const bestHopOnStopIndex = route.stopIndices.get(
188
191
  currentTrip.bestHopOnStop,
189
192
  )!;
190
- const bestHopOnStopTimes =
191
- route.stopTimes[
192
- currentTrip.trip * stopNumbers + bestHopOnStopIndex
193
- ]!;
193
+ const bestHopOnStopDepartureIndex =
194
+ currentTrip.trip * stopNumbers * 2 + bestHopOnStopIndex * 2 + 1;
195
+ const bestHopOnDepartureTime = Time.fromSeconds(
196
+ route.stopTimes[bestHopOnStopDepartureIndex]!,
197
+ );
194
198
  arrivalsAtCurrentRound.set(currentStop, {
195
- time: currentStopTimes.arrival,
199
+ time: currentArrivalTime,
196
200
  legNumber: round,
197
201
  origin: currentTrip.origin,
198
202
  leg: {
@@ -200,13 +204,13 @@ export class Router {
200
204
  currentTrip.bestHopOnStop,
201
205
  )!,
202
206
  to: this.stopsIndex.findStopById(currentStop)!,
203
- departureTime: bestHopOnStopTimes.departure,
204
- arrivalTime: currentStopTimes.arrival,
207
+ departureTime: bestHopOnDepartureTime,
208
+ arrivalTime: currentArrivalTime,
205
209
  route: this.timetable.getServiceRoute(route.serviceRouteId)!,
206
210
  },
207
211
  });
208
212
  earliestArrivals.set(currentStop, {
209
- time: currentStopTimes.arrival,
213
+ time: currentArrivalTime,
210
214
  legNumber: round,
211
215
  origin: currentTrip.origin,
212
216
  });
@@ -221,9 +225,7 @@ export class Router {
221
225
  earliestArrivalOnPreviousRound !== undefined &&
222
226
  (currentTrip === undefined ||
223
227
  earliestArrivalOnPreviousRound.toSeconds() <=
224
- route.stopTimes[
225
- currentTrip.trip * stopNumbers + i
226
- ]!.departure.toSeconds())
228
+ route.stopTimes[(currentTrip.trip * stopNumbers + i) * 2]!)
227
229
  ) {
228
230
  const earliestTrip = this.timetable.findEarliestTrip(
229
231
  route,
@@ -7,33 +7,34 @@ import { StopsMap } from '../stops.js';
7
7
  describe('stops io', () => {
8
8
  const stopsMap: StopsMap = new Map([
9
9
  [
10
- 'stop1',
10
+ 1,
11
11
  {
12
- id: 'stop1',
12
+ id: 1,
13
+ sourceStopId: 'stop1',
13
14
  name: 'Stop 1',
14
15
  lat: 40.712776,
15
16
  lon: -74.005974,
16
- children: ['stop2'],
17
- parent: 'parentStop',
17
+ children: [2],
18
+ parent: 3,
18
19
  locationType: 'SIMPLE_STOP_OR_PLATFORM',
19
20
  platform: 'Platform 1',
20
21
  },
21
22
  ],
22
23
  [
23
- 'stop2',
24
+ 2,
24
25
  {
25
- id: 'stop2',
26
+ id: 2,
27
+ sourceStopId: 'stop2',
26
28
  name: 'Stop 2',
27
29
  lat: 34.052235,
28
30
  lon: -118.243683,
29
31
  children: [],
30
- parent: 'stop1',
32
+ parent: 1,
31
33
  locationType: 'STATION',
32
34
  platform: 'Platform 2',
33
35
  },
34
36
  ],
35
37
  ]);
36
-
37
38
  it('should serialize and deserialize stops correctly', () => {
38
39
  const serializedData = serializeStopsMap(stopsMap);
39
40
  const deserializedStopsMap = deserializeStopsMap(serializedData);
@@ -5,9 +5,10 @@ import { StopsMap } from '../stops.js';
5
5
  import { StopsIndex } from '../stopsIndex.js';
6
6
  const mockStops: StopsMap = new Map([
7
7
  [
8
- '8587255',
8
+ 1,
9
9
  {
10
- id: '8587255',
10
+ id: 1,
11
+ sourceStopId: '8587255',
11
12
  name: 'Fribourg, Tilleul/Cathédrale',
12
13
  lat: 46.8061375857565,
13
14
  lon: 7.16145029437328,
@@ -16,9 +17,10 @@ const mockStops: StopsMap = new Map([
16
17
  },
17
18
  ],
18
19
  [
19
- '8592383',
20
+ 2,
20
21
  {
21
- id: '8592383',
22
+ id: 2,
23
+ sourceStopId: '8592383',
22
24
  name: 'Fribourg, Neuveville/Court-Ch.',
23
25
  lat: 46.8042990960992,
24
26
  lon: 7.16060587800609,
@@ -27,9 +29,10 @@ const mockStops: StopsMap = new Map([
27
29
  },
28
30
  ],
29
31
  [
30
- '8592386',
32
+ 3,
31
33
  {
32
- id: '8592386',
34
+ id: 3,
35
+ sourceStopId: '8592386',
33
36
  name: 'Fribourg, Petit-St-Jean',
34
37
  lat: 46.8035550740648,
35
38
  lon: 7.16806189486532,
@@ -38,50 +41,54 @@ const mockStops: StopsMap = new Map([
38
41
  },
39
42
  ],
40
43
  [
41
- 'Parent8504100',
44
+ 4,
42
45
  {
43
- id: 'Parent8504100',
46
+ id: 4,
47
+ sourceStopId: 'Parent8504100',
44
48
  name: 'Fribourg/Freiburg',
45
49
  lat: 46.8031492395272,
46
50
  lon: 7.15104780338173,
47
- children: ['8504100:0:1', '8504100:0:1AB', '8504100:0:2'],
51
+ children: [5, 6, 7],
48
52
  locationType: 'STATION',
49
53
  },
50
54
  ],
51
55
  [
52
- '8504100:0:1',
56
+ 5,
53
57
  {
54
- id: '8504100:0:1',
58
+ id: 5,
59
+ sourceStopId: '8504100:0:1',
55
60
  name: 'Fribourg/Freiburg',
56
61
  lat: 46.8031492395272,
57
62
  lon: 7.15104780338173,
58
63
  children: [],
59
64
  locationType: 'SIMPLE_STOP_OR_PLATFORM',
60
- parent: 'Parent8504100',
65
+ parent: 4,
61
66
  },
62
67
  ],
63
68
  [
64
- '8504100:0:1AB',
69
+ 6,
65
70
  {
66
- id: '8504100:0:1AB',
71
+ id: 6,
72
+ sourceStopId: '8504100:0:1AB',
67
73
  name: 'Fribourg/Freiburg',
68
74
  lat: 46.8031492395272,
69
75
  lon: 7.15104780338173,
70
76
  children: [],
71
77
  locationType: 'SIMPLE_STOP_OR_PLATFORM',
72
- parent: 'Parent8504100',
78
+ parent: 4,
73
79
  },
74
80
  ],
75
81
  [
76
- '8504100:0:2',
82
+ 7,
77
83
  {
78
- id: '8504100:0:2',
84
+ id: 7,
85
+ sourceStopId: '8504100:0:2',
79
86
  name: 'Fribourg/Freiburg',
80
87
  lat: 46.8031492395272,
81
88
  lon: 7.15104780338173,
82
89
  children: [],
83
90
  locationType: 'SIMPLE_STOP_OR_PLATFORM',
84
- parent: 'Parent8504100',
91
+ parent: 4,
85
92
  },
86
93
  ],
87
94
  ]);
@@ -98,25 +105,25 @@ describe('StopFinder', () => {
98
105
  const results = stopFinder.findStopsByName(
99
106
  'Fribourg, Tilleul/Cathédrale',
100
107
  );
101
- assert.strictEqual(results[0]?.id, '8587255');
108
+ assert.strictEqual(results[0]?.id, 1);
102
109
  });
103
110
 
104
111
  it('should not include children stops', () => {
105
112
  const results = stopFinder.findStopsByName('Fribourg/Freiburg', 2);
106
- assert.strictEqual(results[0]?.id, 'Parent8504100');
107
- assert.strictEqual(results[1]?.id, '8587255');
113
+ assert.strictEqual(results[0]?.id, 4);
114
+ assert.strictEqual(results[1]?.id, 1);
108
115
  });
109
116
 
110
117
  it('should find stops by partial name', () => {
111
118
  const results = stopFinder.findStopsByName('Cathédrale');
112
119
  assert.strictEqual(results.length, 1);
113
- assert.strictEqual(results[0]?.id, '8587255');
120
+ assert.strictEqual(results[0]?.id, 1);
114
121
  });
115
122
 
116
123
  it('should find stops by name with accents', () => {
117
124
  const results = stopFinder.findStopsByName('Cathedrale');
118
125
  assert.strictEqual(results.length, 1);
119
- assert.strictEqual(results[0]?.id, '8587255');
126
+ assert.strictEqual(results[0]?.id, 1);
120
127
  });
121
128
 
122
129
  it('should return an empty array if no stops match the query', () => {
@@ -129,22 +136,22 @@ describe('StopFinder', () => {
129
136
  it('should find stops by geographic location', () => {
130
137
  const results = stopFinder.findStopsByLocation(46.8061, 7.1614, 1);
131
138
  assert.strictEqual(results.length, 1);
132
- assert.strictEqual(results[0]?.id, '8587255');
139
+ assert.strictEqual(results[0]?.id, 1);
133
140
  });
134
141
 
135
142
  it('should find multiple stops within the radius', () => {
136
143
  const results = stopFinder.findStopsByLocation(46.8, 7.16, 10, 0.75);
137
144
  assert.strictEqual(results.length, 3);
138
- assert.strictEqual(results[0]?.id, '8592383');
139
- assert.strictEqual(results[1]?.id, '8587255');
140
- assert.strictEqual(results[2]?.id, '8592386');
145
+ assert.strictEqual(results[0]?.id, 2);
146
+ assert.strictEqual(results[1]?.id, 1);
147
+ assert.strictEqual(results[2]?.id, 3);
141
148
  });
142
149
 
143
150
  it('should find the N closest stops', () => {
144
151
  const results = stopFinder.findStopsByLocation(46.8, 7.16, 2, 10);
145
152
  assert.strictEqual(results.length, 2);
146
- assert.strictEqual(results[0]?.id, '8592383');
147
- assert.strictEqual(results[1]?.id, '8587255');
153
+ assert.strictEqual(results[0]?.id, 2);
154
+ assert.strictEqual(results[1]?.id, 1);
148
155
  });
149
156
 
150
157
  it('should return an empty array if no stops are within the radius', () => {
@@ -165,20 +172,22 @@ describe('StopFinder', () => {
165
172
  describe('equivalentStops', () => {
166
173
  it('should find equivalent stops for a given stop ID', () => {
167
174
  const equivalentStops = stopFinder.equivalentStops('8504100:0:1');
168
- assert.deepStrictEqual(equivalentStops, [
169
- '8504100:0:1',
170
- '8504100:0:1AB',
171
- '8504100:0:2',
172
- ]);
175
+ assert.deepStrictEqual(
176
+ equivalentStops.map((stop) => stop.id),
177
+ [5, 6, 7],
178
+ );
173
179
  });
174
180
 
175
181
  it('should return the same stop ID in an array if no equivalents', () => {
176
182
  const equivalentStops = stopFinder.equivalentStops('8587255');
177
- assert.deepStrictEqual(equivalentStops, ['8587255']);
183
+ assert.deepStrictEqual(
184
+ equivalentStops.map((stop) => stop.id),
185
+ [1],
186
+ );
178
187
  });
179
188
 
180
189
  it('should return an empty array for non-existent stop ID', () => {
181
- const equivalentStops = stopFinder.equivalentStops('nonexistent');
190
+ const equivalentStops = stopFinder.equivalentStops('999');
182
191
  assert.deepStrictEqual(equivalentStops, []);
183
192
  });
184
193
  });
package/src/stops/io.ts CHANGED
@@ -3,12 +3,13 @@ import {
3
3
  Stop as ProtoStop,
4
4
  StopsMap as ProtoStopsMap,
5
5
  } from './proto/stops.js';
6
- import { LocationType, Stop, StopId, StopsMap } from './stops.js';
6
+ import { LocationType, Stop, StopsMap } from './stops.js';
7
7
 
8
- const CURRENT_VERSION = '0.0.1';
8
+ const CURRENT_VERSION = '0.0.2';
9
9
  const serializeStop = (stop: Stop): ProtoStop => {
10
10
  return {
11
11
  name: stop.name,
12
+ sourceStopId: stop.sourceStopId,
12
13
  lat: stop.lat,
13
14
  lon: stop.lon,
14
15
  children: stop.children,
@@ -24,16 +25,17 @@ export const serializeStopsMap = (stopsMap: StopsMap): ProtoStopsMap => {
24
25
  stops: {},
25
26
  };
26
27
 
27
- stopsMap.forEach((value: Stop, key: string) => {
28
+ stopsMap.forEach((value: Stop, key: number) => {
28
29
  protoStopsMap.stops[key] = serializeStop(value);
29
30
  });
30
31
 
31
32
  return protoStopsMap;
32
33
  };
33
34
 
34
- const deserializeStop = (stopId: StopId, protoStop: ProtoStop): Stop => {
35
+ const deserializeStop = (stopId: number, protoStop: ProtoStop): Stop => {
35
36
  return {
36
37
  id: stopId,
38
+ sourceStopId: protoStop.sourceStopId,
37
39
  name: protoStop.name,
38
40
  lat: protoStop.lat,
39
41
  lon: protoStop.lon,
@@ -51,7 +53,8 @@ export const deserializeStopsMap = (protoStopsMap: ProtoStopsMap): StopsMap => {
51
53
  const stopsMap: StopsMap = new Map();
52
54
 
53
55
  Object.entries(protoStopsMap.stops).forEach(([key, value]) => {
54
- stopsMap.set(key, deserializeStop(key, value));
56
+ const intKey = parseInt(key, 10);
57
+ stopsMap.set(intKey, deserializeStop(intKey, value));
55
58
  });
56
59
 
57
60
  return stopsMap;
@@ -12,15 +12,16 @@ enum LocationType {
12
12
 
13
13
  message Stop {
14
14
  string name = 1;
15
- optional double lat = 2;
16
- optional double lon = 3;
17
- repeated string children = 4;
18
- optional string parent = 5;
19
- LocationType locationType = 6;
20
- optional string platform = 7;
15
+ string sourceStopId = 2;
16
+ optional double lat = 3;
17
+ optional double lon = 4;
18
+ repeated uint32 children = 5;
19
+ optional uint32 parent = 6;
20
+ LocationType locationType = 7;
21
+ optional string platform = 8;
21
22
  }
22
23
 
23
24
  message StopsMap {
24
25
  string version = 1;
25
- map<string, Stop> stops = 2;
26
+ map<uint32, Stop> stops = 2;
26
27
  }