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
@@ -62,27 +62,29 @@ export function locationTypeToJSON(object: LocationType): string {
62
62
 
63
63
  export interface Stop {
64
64
  name: string;
65
+ sourceStopId: string;
65
66
  lat?: number | undefined;
66
67
  lon?: number | undefined;
67
- children: string[];
68
- parent?: string | undefined;
68
+ children: number[];
69
+ parent?: number | undefined;
69
70
  locationType: LocationType;
70
71
  platform?: string | undefined;
71
72
  }
72
73
 
73
74
  export interface StopsMap {
74
75
  version: string;
75
- stops: { [key: string]: Stop };
76
+ stops: { [key: number]: Stop };
76
77
  }
77
78
 
78
79
  export interface StopsMap_StopsEntry {
79
- key: string;
80
+ key: number;
80
81
  value: Stop | undefined;
81
82
  }
82
83
 
83
84
  function createBaseStop(): Stop {
84
85
  return {
85
86
  name: "",
87
+ sourceStopId: "",
86
88
  lat: undefined,
87
89
  lon: undefined,
88
90
  children: [],
@@ -97,23 +99,28 @@ export const Stop: MessageFns<Stop> = {
97
99
  if (message.name !== "") {
98
100
  writer.uint32(10).string(message.name);
99
101
  }
102
+ if (message.sourceStopId !== "") {
103
+ writer.uint32(18).string(message.sourceStopId);
104
+ }
100
105
  if (message.lat !== undefined) {
101
- writer.uint32(17).double(message.lat);
106
+ writer.uint32(25).double(message.lat);
102
107
  }
103
108
  if (message.lon !== undefined) {
104
- writer.uint32(25).double(message.lon);
109
+ writer.uint32(33).double(message.lon);
105
110
  }
111
+ writer.uint32(42).fork();
106
112
  for (const v of message.children) {
107
- writer.uint32(34).string(v!);
113
+ writer.uint32(v);
108
114
  }
115
+ writer.join();
109
116
  if (message.parent !== undefined) {
110
- writer.uint32(42).string(message.parent);
117
+ writer.uint32(48).uint32(message.parent);
111
118
  }
112
119
  if (message.locationType !== 0) {
113
- writer.uint32(48).int32(message.locationType);
120
+ writer.uint32(56).int32(message.locationType);
114
121
  }
115
122
  if (message.platform !== undefined) {
116
- writer.uint32(58).string(message.platform);
123
+ writer.uint32(66).string(message.platform);
117
124
  }
118
125
  return writer;
119
126
  },
@@ -134,11 +141,11 @@ export const Stop: MessageFns<Stop> = {
134
141
  continue;
135
142
  }
136
143
  case 2: {
137
- if (tag !== 17) {
144
+ if (tag !== 18) {
138
145
  break;
139
146
  }
140
147
 
141
- message.lat = reader.double();
148
+ message.sourceStopId = reader.string();
142
149
  continue;
143
150
  }
144
151
  case 3: {
@@ -146,35 +153,53 @@ export const Stop: MessageFns<Stop> = {
146
153
  break;
147
154
  }
148
155
 
149
- message.lon = reader.double();
156
+ message.lat = reader.double();
150
157
  continue;
151
158
  }
152
159
  case 4: {
153
- if (tag !== 34) {
160
+ if (tag !== 33) {
154
161
  break;
155
162
  }
156
163
 
157
- message.children.push(reader.string());
164
+ message.lon = reader.double();
158
165
  continue;
159
166
  }
160
167
  case 5: {
161
- if (tag !== 42) {
162
- break;
168
+ if (tag === 40) {
169
+ message.children.push(reader.uint32());
170
+
171
+ continue;
163
172
  }
164
173
 
165
- message.parent = reader.string();
166
- continue;
174
+ if (tag === 42) {
175
+ const end2 = reader.uint32() + reader.pos;
176
+ while (reader.pos < end2) {
177
+ message.children.push(reader.uint32());
178
+ }
179
+
180
+ continue;
181
+ }
182
+
183
+ break;
167
184
  }
168
185
  case 6: {
169
186
  if (tag !== 48) {
170
187
  break;
171
188
  }
172
189
 
173
- message.locationType = reader.int32() as any;
190
+ message.parent = reader.uint32();
174
191
  continue;
175
192
  }
176
193
  case 7: {
177
- if (tag !== 58) {
194
+ if (tag !== 56) {
195
+ break;
196
+ }
197
+
198
+ message.locationType = reader.int32() as any;
199
+ continue;
200
+ }
201
+ case 8: {
202
+ if (tag !== 66) {
178
203
  break;
179
204
  }
180
205
 
@@ -193,10 +218,11 @@ export const Stop: MessageFns<Stop> = {
193
218
  fromJSON(object: any): Stop {
194
219
  return {
195
220
  name: isSet(object.name) ? globalThis.String(object.name) : "",
221
+ sourceStopId: isSet(object.sourceStopId) ? globalThis.String(object.sourceStopId) : "",
196
222
  lat: isSet(object.lat) ? globalThis.Number(object.lat) : undefined,
197
223
  lon: isSet(object.lon) ? globalThis.Number(object.lon) : undefined,
198
- children: globalThis.Array.isArray(object?.children) ? object.children.map((e: any) => globalThis.String(e)) : [],
199
- parent: isSet(object.parent) ? globalThis.String(object.parent) : undefined,
224
+ children: globalThis.Array.isArray(object?.children) ? object.children.map((e: any) => globalThis.Number(e)) : [],
225
+ parent: isSet(object.parent) ? globalThis.Number(object.parent) : undefined,
200
226
  locationType: isSet(object.locationType) ? locationTypeFromJSON(object.locationType) : 0,
201
227
  platform: isSet(object.platform) ? globalThis.String(object.platform) : undefined,
202
228
  };
@@ -207,6 +233,9 @@ export const Stop: MessageFns<Stop> = {
207
233
  if (message.name !== "") {
208
234
  obj.name = message.name;
209
235
  }
236
+ if (message.sourceStopId !== "") {
237
+ obj.sourceStopId = message.sourceStopId;
238
+ }
210
239
  if (message.lat !== undefined) {
211
240
  obj.lat = message.lat;
212
241
  }
@@ -214,10 +243,10 @@ export const Stop: MessageFns<Stop> = {
214
243
  obj.lon = message.lon;
215
244
  }
216
245
  if (message.children?.length) {
217
- obj.children = message.children;
246
+ obj.children = message.children.map((e) => Math.round(e));
218
247
  }
219
248
  if (message.parent !== undefined) {
220
- obj.parent = message.parent;
249
+ obj.parent = Math.round(message.parent);
221
250
  }
222
251
  if (message.locationType !== 0) {
223
252
  obj.locationType = locationTypeToJSON(message.locationType);
@@ -234,6 +263,7 @@ export const Stop: MessageFns<Stop> = {
234
263
  fromPartial<I extends Exact<DeepPartial<Stop>, I>>(object: I): Stop {
235
264
  const message = createBaseStop();
236
265
  message.name = object.name ?? "";
266
+ message.sourceStopId = object.sourceStopId ?? "";
237
267
  message.lat = object.lat ?? undefined;
238
268
  message.lon = object.lon ?? undefined;
239
269
  message.children = object.children?.map((e) => e) || [];
@@ -298,8 +328,8 @@ export const StopsMap: MessageFns<StopsMap> = {
298
328
  return {
299
329
  version: isSet(object.version) ? globalThis.String(object.version) : "",
300
330
  stops: isObject(object.stops)
301
- ? Object.entries(object.stops).reduce<{ [key: string]: Stop }>((acc, [key, value]) => {
302
- acc[key] = Stop.fromJSON(value);
331
+ ? Object.entries(object.stops).reduce<{ [key: number]: Stop }>((acc, [key, value]) => {
332
+ acc[globalThis.Number(key)] = Stop.fromJSON(value);
303
333
  return acc;
304
334
  }, {})
305
335
  : {},
@@ -329,9 +359,9 @@ export const StopsMap: MessageFns<StopsMap> = {
329
359
  fromPartial<I extends Exact<DeepPartial<StopsMap>, I>>(object: I): StopsMap {
330
360
  const message = createBaseStopsMap();
331
361
  message.version = object.version ?? "";
332
- message.stops = Object.entries(object.stops ?? {}).reduce<{ [key: string]: Stop }>((acc, [key, value]) => {
362
+ message.stops = Object.entries(object.stops ?? {}).reduce<{ [key: number]: Stop }>((acc, [key, value]) => {
333
363
  if (value !== undefined) {
334
- acc[key] = Stop.fromPartial(value);
364
+ acc[globalThis.Number(key)] = Stop.fromPartial(value);
335
365
  }
336
366
  return acc;
337
367
  }, {});
@@ -340,13 +370,13 @@ export const StopsMap: MessageFns<StopsMap> = {
340
370
  };
341
371
 
342
372
  function createBaseStopsMap_StopsEntry(): StopsMap_StopsEntry {
343
- return { key: "", value: undefined };
373
+ return { key: 0, value: undefined };
344
374
  }
345
375
 
346
376
  export const StopsMap_StopsEntry: MessageFns<StopsMap_StopsEntry> = {
347
377
  encode(message: StopsMap_StopsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
348
- if (message.key !== "") {
349
- writer.uint32(10).string(message.key);
378
+ if (message.key !== 0) {
379
+ writer.uint32(8).uint32(message.key);
350
380
  }
351
381
  if (message.value !== undefined) {
352
382
  Stop.encode(message.value, writer.uint32(18).fork()).join();
@@ -362,11 +392,11 @@ export const StopsMap_StopsEntry: MessageFns<StopsMap_StopsEntry> = {
362
392
  const tag = reader.uint32();
363
393
  switch (tag >>> 3) {
364
394
  case 1: {
365
- if (tag !== 10) {
395
+ if (tag !== 8) {
366
396
  break;
367
397
  }
368
398
 
369
- message.key = reader.string();
399
+ message.key = reader.uint32();
370
400
  continue;
371
401
  }
372
402
  case 2: {
@@ -388,15 +418,15 @@ export const StopsMap_StopsEntry: MessageFns<StopsMap_StopsEntry> = {
388
418
 
389
419
  fromJSON(object: any): StopsMap_StopsEntry {
390
420
  return {
391
- key: isSet(object.key) ? globalThis.String(object.key) : "",
421
+ key: isSet(object.key) ? globalThis.Number(object.key) : 0,
392
422
  value: isSet(object.value) ? Stop.fromJSON(object.value) : undefined,
393
423
  };
394
424
  },
395
425
 
396
426
  toJSON(message: StopsMap_StopsEntry): unknown {
397
427
  const obj: any = {};
398
- if (message.key !== "") {
399
- obj.key = message.key;
428
+ if (message.key !== 0) {
429
+ obj.key = Math.round(message.key);
400
430
  }
401
431
  if (message.value !== undefined) {
402
432
  obj.value = Stop.toJSON(message.value);
@@ -409,7 +439,7 @@ export const StopsMap_StopsEntry: MessageFns<StopsMap_StopsEntry> = {
409
439
  },
410
440
  fromPartial<I extends Exact<DeepPartial<StopsMap_StopsEntry>, I>>(object: I): StopsMap_StopsEntry {
411
441
  const message = createBaseStopsMap_StopsEntry();
412
- message.key = object.key ?? "";
442
+ message.key = object.key ?? 0;
413
443
  message.value = (object.value !== undefined && object.value !== null) ? Stop.fromPartial(object.value) : undefined;
414
444
  return message;
415
445
  },
@@ -1,4 +1,8 @@
1
- export type StopId = string;
1
+ // A stop ID defined in the source of the transit data (e.g. GTFS)
2
+ export type SourceStopId = string;
3
+ // An internally indexed StopId
4
+ export type StopId = number;
5
+
2
6
  export type Platform = string;
3
7
  export type Latitude = number;
4
8
  export type Longitude = number;
@@ -12,6 +16,7 @@ export type LocationType =
12
16
 
13
17
  export type Stop = {
14
18
  id: StopId;
19
+ sourceStopId: SourceStopId;
15
20
  name: string;
16
21
  lat?: Latitude;
17
22
  lon?: Longitude;
@@ -21,4 +26,11 @@ export type Stop = {
21
26
  platform?: Platform;
22
27
  };
23
28
 
29
+ /**
30
+ * Mapping internal StopIds to Stop objects.
31
+ */
24
32
  export type StopsMap = Map<StopId, Stop>;
33
+ /**
34
+ * Mapping source stopIds to internal stopIds;
35
+ */
36
+ export type SourceStopsMap = Map<SourceStopId, StopId>;
@@ -6,7 +6,13 @@ import { addAll, createIndex, search, SearchResult } from 'slimsearch';
6
6
  import { generateAccentVariants } from './i18n.js';
7
7
  import { deserializeStopsMap, serializeStopsMap } from './io.js';
8
8
  import { StopsMap as ProtoStopsMap } from './proto/stops.js';
9
- import { Stop, StopId, StopsMap } from './stops.js';
9
+ import {
10
+ SourceStopId,
11
+ SourceStopsMap,
12
+ Stop,
13
+ StopId,
14
+ StopsMap,
15
+ } from './stops.js';
10
16
 
11
17
  type StopPoint = { id: StopId; lat: number; lon: number };
12
18
 
@@ -17,19 +23,24 @@ type StopPoint = { id: StopId; lat: number; lon: number };
17
23
  */
18
24
  export class StopsIndex {
19
25
  private readonly stopsMap: StopsMap;
26
+ private readonly sourceStopsMap: SourceStopsMap;
20
27
  private readonly textIndex;
21
28
  private readonly geoIndex: KDTree;
22
29
  private readonly stopPoints: StopPoint[];
23
30
 
24
31
  constructor(stopsMap: StopsMap) {
25
32
  this.stopsMap = stopsMap;
33
+ this.sourceStopsMap = new Map<SourceStopId, StopId>();
34
+ for (const [id, stop] of stopsMap.entries()) {
35
+ this.sourceStopsMap.set(stop.sourceStopId, id);
36
+ }
26
37
  this.textIndex = createIndex({
27
38
  fields: ['name'],
28
39
  storeFields: ['id'],
29
40
  searchOptions: { prefix: true, fuzzy: 0.2 },
30
41
  processTerm: generateAccentVariants,
31
42
  });
32
- const stopsSet = new Map<string, { id: StopId; name: string }>();
43
+ const stopsSet = new Map<StopId, { id: StopId; name: string }>();
33
44
  for (const [id, stop] of stopsMap.entries()) {
34
45
  const effectiveStopId = stop.parent ?? id;
35
46
  if (!stopsSet.has(effectiveStopId)) {
@@ -86,6 +97,15 @@ export class StopsIndex {
86
97
  return writer.finish();
87
98
  }
88
99
 
100
+ /**
101
+ * Returns the number of stops in the index.
102
+ *
103
+ * @returns The total number of stops.
104
+ */
105
+ size(): number {
106
+ return this.stopsMap.size;
107
+ }
108
+
89
109
  /**
90
110
  * Finds stops by their name using a text search.
91
111
  *
@@ -95,7 +115,7 @@ export class StopsIndex {
95
115
  */
96
116
  findStopsByName(query: string, maxResults = 5): Stop[] {
97
117
  const results = search(this.textIndex, query).map(
98
- (result: SearchResult) => this.stopsMap.get(result.id as string) as Stop,
118
+ (result: SearchResult) => this.stopsMap.get(result.id as number) as Stop,
99
119
  );
100
120
  return results.slice(0, maxResults);
101
121
  }
@@ -129,16 +149,37 @@ export class StopsIndex {
129
149
  }
130
150
 
131
151
  /**
132
- * Finds a stop by its ID.
152
+ * Finds a stop by its internal ID.
133
153
  *
134
- * @param id - The ID of the stop to search for.
154
+ * @param id - The internal ID of the stop to search for.
135
155
  * @returns The Stop object that matches the specified ID, or undefined if not found.
136
156
  */
137
157
  findStopById(id: StopId): Stop | undefined {
138
158
  return this.stopsMap.get(id);
139
159
  }
140
160
 
141
- equivalentStops(id: StopId): StopId[] {
161
+ /**
162
+ * Finds a stop by its ID in the transit data source (e.g. GTFS).
163
+ *
164
+ * @param id - The source ID of the stop to search for.
165
+ * @returns The Stop object that matches the specified ID, or undefined if not found.
166
+ */
167
+ findStopBySourceStopId(sourceStopId: SourceStopId): Stop | undefined {
168
+ const stopId = this.sourceStopsMap.get(sourceStopId);
169
+ if (stopId === undefined) {
170
+ return;
171
+ }
172
+ return this.findStopById(stopId);
173
+ }
174
+
175
+ /**
176
+ * Find ids of all sibling stops.
177
+ */
178
+ equivalentStops(sourceId: SourceStopId): Stop[] {
179
+ const id = this.sourceStopsMap.get(sourceId);
180
+ if (id === undefined) {
181
+ return [];
182
+ }
142
183
  const stop = this.stopsMap.get(id);
143
184
  if (!stop) {
144
185
  return [];
@@ -146,6 +187,8 @@ export class StopsIndex {
146
187
  const equivalentStops = stop.parent
147
188
  ? (this.stopsMap.get(stop.parent)?.children ?? [])
148
189
  : stop.children;
149
- return Array.from(new Set([id, ...equivalentStops]));
190
+ return Array.from(new Set([id, ...equivalentStops])).map(
191
+ (stopId) => this.stopsMap.get(stopId) as Stop,
192
+ );
150
193
  }
151
194
  }
@@ -20,18 +20,18 @@ import {
20
20
  describe('timetable io', () => {
21
21
  const stopsAdjacency: StopsAdjacency = new Map([
22
22
  [
23
- 'stop1',
23
+ 1,
24
24
  {
25
- transfers: [{ destination: 'stop2', type: 'RECOMMENDED' }],
25
+ transfers: [{ destination: 2, type: 'RECOMMENDED' }],
26
26
  routes: ['route1'],
27
27
  },
28
28
  ],
29
29
  [
30
- 'stop2',
30
+ 2,
31
31
  {
32
32
  transfers: [
33
33
  {
34
- destination: 'stop1',
34
+ destination: 1,
35
35
  type: 'GUARANTEED',
36
36
  minTransferTime: Duration.fromMinutes(3),
37
37
  },
@@ -44,18 +44,15 @@ describe('timetable io', () => {
44
44
  [
45
45
  'route1',
46
46
  {
47
- stopTimes: [
48
- {
49
- arrival: Time.fromSeconds(1000),
50
- departure: Time.fromSeconds(1010),
51
- pickUpType: 'REGULAR',
52
- dropOffType: 'REGULAR',
53
- },
54
- ],
55
- stops: ['stop1', 'stop2'],
47
+ stopTimes: new Uint32Array([
48
+ Time.fromHMS(0, 16, 40).toSeconds(),
49
+ Time.fromHMS(0, 16, 50).toSeconds(),
50
+ ]),
51
+ pickUpDropOffTypes: new Uint8Array([0, 0]), // REGULAR
52
+ stops: new Uint32Array([1, 2]),
56
53
  stopIndices: new Map([
57
- ['stop1', 0],
58
- ['stop2', 1],
54
+ [1, 0],
55
+ [2, 1],
59
56
  ]),
60
57
  serviceRouteId: 'gtfs1',
61
58
  },
@@ -63,18 +60,15 @@ describe('timetable io', () => {
63
60
  [
64
61
  'route2',
65
62
  {
66
- stopTimes: [
67
- {
68
- arrival: Time.fromSeconds(2000),
69
- departure: Time.fromSeconds(2010),
70
- pickUpType: 'REGULAR',
71
- dropOffType: 'REGULAR',
72
- },
73
- ],
74
- stops: ['stop2', 'stop1'],
63
+ stopTimes: new Uint32Array([
64
+ Time.fromHMS(0, 33, 20).toSeconds(),
65
+ Time.fromHMS(0, 33, 30).toSeconds(),
66
+ ]),
67
+ pickUpDropOffTypes: new Uint8Array([0, 0]), // REGULAR
68
+ stops: new Uint32Array([2, 1]),
75
69
  stopIndices: new Map([
76
- ['stop2', 0],
77
- ['stop1', 1],
70
+ [2, 0],
71
+ [1, 1],
78
72
  ]),
79
73
  serviceRouteId: 'gtfs2',
80
74
  },
@@ -84,17 +78,16 @@ describe('timetable io', () => {
84
78
  ['gtfs1', { type: 'RAIL', name: 'Route 1' }],
85
79
  ['gtfs2', { type: 'RAIL', name: 'Route 2' }],
86
80
  ]);
87
-
88
81
  const stopsAdjacencyProto = {
89
82
  stops: {
90
- stop1: {
91
- transfers: [{ destination: 'stop2', type: 0 }],
83
+ '1': {
84
+ transfers: [{ destination: 2, type: 0 }],
92
85
  routes: ['route1'],
93
86
  },
94
- stop2: {
87
+ '2': {
95
88
  transfers: [
96
89
  {
97
- destination: 'stop1',
90
+ destination: 1,
98
91
  type: 1,
99
92
  minTransferTime: 180,
100
93
  },
@@ -107,27 +100,25 @@ describe('timetable io', () => {
107
100
  const routesAdjacencyProto = {
108
101
  routes: {
109
102
  route1: {
110
- stopTimes: [
111
- {
112
- arrival: 1000,
113
- departure: 1010,
114
- pickUpType: undefined,
115
- dropOffType: undefined,
116
- },
117
- ],
118
- stops: ['stop1', 'stop2'],
103
+ stopTimes: new Uint8Array(
104
+ new Uint32Array([
105
+ Time.fromHMS(0, 16, 40).toSeconds(),
106
+ Time.fromHMS(0, 16, 50).toSeconds(),
107
+ ]).buffer,
108
+ ),
109
+ pickUpDropOffTypes: new Uint8Array([0, 0]), // REGULAR
110
+ stops: new Uint8Array(new Uint32Array([1, 2]).buffer),
119
111
  serviceRouteId: 'gtfs1',
120
112
  },
121
113
  route2: {
122
- stopTimes: [
123
- {
124
- arrival: 2000,
125
- departure: 2010,
126
- pickUpType: undefined,
127
- dropOffType: undefined,
128
- },
129
- ],
130
- stops: ['stop2', 'stop1'],
114
+ stopTimes: new Uint8Array(
115
+ new Uint32Array([
116
+ Time.fromHMS(0, 33, 20).toSeconds(),
117
+ Time.fromHMS(0, 33, 30).toSeconds(),
118
+ ]).buffer,
119
+ ),
120
+ pickUpDropOffTypes: new Uint8Array([0, 0]), // REGULAR
121
+ stops: new Uint8Array(new Uint32Array([2, 1]).buffer),
131
122
  serviceRouteId: 'gtfs2',
132
123
  },
133
124
  },