minotor 3.0.2 → 5.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 (43) hide show
  1. package/CHANGELOG.md +9 -3
  2. package/README.md +1 -0
  3. package/dist/cli.mjs +294 -307
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/gtfs/trips.d.ts +12 -6
  6. package/dist/parser.cjs.js +290 -302
  7. package/dist/parser.cjs.js.map +1 -1
  8. package/dist/parser.esm.js +290 -302
  9. package/dist/parser.esm.js.map +1 -1
  10. package/dist/router.cjs.js +1 -1
  11. package/dist/router.cjs.js.map +1 -1
  12. package/dist/router.d.ts +2 -2
  13. package/dist/router.esm.js +1 -1
  14. package/dist/router.esm.js.map +1 -1
  15. package/dist/router.umd.js +1 -1
  16. package/dist/router.umd.js.map +1 -1
  17. package/dist/routing/route.d.ts +3 -3
  18. package/dist/timetable/io.d.ts +5 -4
  19. package/dist/timetable/proto/timetable.d.ts +7 -16
  20. package/dist/timetable/route.d.ts +7 -5
  21. package/dist/timetable/timetable.d.ts +7 -5
  22. package/package.json +1 -1
  23. package/src/__e2e__/timetable/timetable.bin +2 -2
  24. package/src/cli/repl.ts +0 -1
  25. package/src/gtfs/__tests__/parser.test.ts +2 -2
  26. package/src/gtfs/__tests__/routes.test.ts +3 -0
  27. package/src/gtfs/__tests__/trips.test.ts +123 -166
  28. package/src/gtfs/parser.ts +50 -9
  29. package/src/gtfs/routes.ts +1 -0
  30. package/src/gtfs/trips.ts +195 -112
  31. package/src/router.ts +2 -2
  32. package/src/routing/__tests__/route.test.ts +3 -3
  33. package/src/routing/__tests__/router.test.ts +186 -203
  34. package/src/routing/route.ts +3 -3
  35. package/src/routing/router.ts +1 -1
  36. package/src/timetable/__tests__/io.test.ts +52 -64
  37. package/src/timetable/__tests__/route.test.ts +25 -17
  38. package/src/timetable/__tests__/timetable.test.ts +16 -24
  39. package/src/timetable/io.ts +20 -19
  40. package/src/timetable/proto/timetable.proto +7 -9
  41. package/src/timetable/proto/timetable.ts +80 -202
  42. package/src/timetable/route.ts +27 -13
  43. package/src/timetable/timetable.ts +20 -16
@@ -22,6 +22,18 @@ PERFORMANCE OF THIS SOFTWARE.
22
22
  /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
23
23
 
24
24
 
25
+ function __rest(s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ }
36
+
25
37
  function __awaiter(thisArg, _arguments, P, generator) {
26
38
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
39
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12309,148 +12321,6 @@ const Route$1 = {
12309
12321
  return message;
12310
12322
  },
12311
12323
  };
12312
- function createBaseRoutesAdjacency() {
12313
- return { routes: {} };
12314
- }
12315
- const RoutesAdjacency = {
12316
- encode(message, writer = new BinaryWriter()) {
12317
- Object.entries(message.routes).forEach(([key, value]) => {
12318
- RoutesAdjacency_RoutesEntry.encode({ key: key, value }, writer.uint32(10).fork()).join();
12319
- });
12320
- return writer;
12321
- },
12322
- decode(input, length) {
12323
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
12324
- const end = length === undefined ? reader.len : reader.pos + length;
12325
- const message = createBaseRoutesAdjacency();
12326
- while (reader.pos < end) {
12327
- const tag = reader.uint32();
12328
- switch (tag >>> 3) {
12329
- case 1: {
12330
- if (tag !== 10) {
12331
- break;
12332
- }
12333
- const entry1 = RoutesAdjacency_RoutesEntry.decode(reader, reader.uint32());
12334
- if (entry1.value !== undefined) {
12335
- message.routes[entry1.key] = entry1.value;
12336
- }
12337
- continue;
12338
- }
12339
- }
12340
- if ((tag & 7) === 4 || tag === 0) {
12341
- break;
12342
- }
12343
- reader.skip(tag & 7);
12344
- }
12345
- return message;
12346
- },
12347
- fromJSON(object) {
12348
- return {
12349
- routes: isObject(object.routes)
12350
- ? Object.entries(object.routes).reduce((acc, [key, value]) => {
12351
- acc[key] = Route$1.fromJSON(value);
12352
- return acc;
12353
- }, {})
12354
- : {},
12355
- };
12356
- },
12357
- toJSON(message) {
12358
- const obj = {};
12359
- if (message.routes) {
12360
- const entries = Object.entries(message.routes);
12361
- if (entries.length > 0) {
12362
- obj.routes = {};
12363
- entries.forEach(([k, v]) => {
12364
- obj.routes[k] = Route$1.toJSON(v);
12365
- });
12366
- }
12367
- }
12368
- return obj;
12369
- },
12370
- create(base) {
12371
- return RoutesAdjacency.fromPartial(base !== null && base !== void 0 ? base : {});
12372
- },
12373
- fromPartial(object) {
12374
- var _a;
12375
- const message = createBaseRoutesAdjacency();
12376
- message.routes = Object.entries((_a = object.routes) !== null && _a !== void 0 ? _a : {}).reduce((acc, [key, value]) => {
12377
- if (value !== undefined) {
12378
- acc[key] = Route$1.fromPartial(value);
12379
- }
12380
- return acc;
12381
- }, {});
12382
- return message;
12383
- },
12384
- };
12385
- function createBaseRoutesAdjacency_RoutesEntry() {
12386
- return { key: "", value: undefined };
12387
- }
12388
- const RoutesAdjacency_RoutesEntry = {
12389
- encode(message, writer = new BinaryWriter()) {
12390
- if (message.key !== "") {
12391
- writer.uint32(10).string(message.key);
12392
- }
12393
- if (message.value !== undefined) {
12394
- Route$1.encode(message.value, writer.uint32(18).fork()).join();
12395
- }
12396
- return writer;
12397
- },
12398
- decode(input, length) {
12399
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
12400
- const end = length === undefined ? reader.len : reader.pos + length;
12401
- const message = createBaseRoutesAdjacency_RoutesEntry();
12402
- while (reader.pos < end) {
12403
- const tag = reader.uint32();
12404
- switch (tag >>> 3) {
12405
- case 1: {
12406
- if (tag !== 10) {
12407
- break;
12408
- }
12409
- message.key = reader.string();
12410
- continue;
12411
- }
12412
- case 2: {
12413
- if (tag !== 18) {
12414
- break;
12415
- }
12416
- message.value = Route$1.decode(reader, reader.uint32());
12417
- continue;
12418
- }
12419
- }
12420
- if ((tag & 7) === 4 || tag === 0) {
12421
- break;
12422
- }
12423
- reader.skip(tag & 7);
12424
- }
12425
- return message;
12426
- },
12427
- fromJSON(object) {
12428
- return {
12429
- key: isSet(object.key) ? globalThis.String(object.key) : "",
12430
- value: isSet(object.value) ? Route$1.fromJSON(object.value) : undefined,
12431
- };
12432
- },
12433
- toJSON(message) {
12434
- const obj = {};
12435
- if (message.key !== "") {
12436
- obj.key = message.key;
12437
- }
12438
- if (message.value !== undefined) {
12439
- obj.value = Route$1.toJSON(message.value);
12440
- }
12441
- return obj;
12442
- },
12443
- create(base) {
12444
- return RoutesAdjacency_RoutesEntry.fromPartial(base !== null && base !== void 0 ? base : {});
12445
- },
12446
- fromPartial(object) {
12447
- var _a;
12448
- const message = createBaseRoutesAdjacency_RoutesEntry();
12449
- message.key = (_a = object.key) !== null && _a !== void 0 ? _a : "";
12450
- message.value = (object.value !== undefined && object.value !== null) ? Route$1.fromPartial(object.value) : undefined;
12451
- return message;
12452
- },
12453
- };
12454
12324
  function createBaseTransfer() {
12455
12325
  return { destination: 0, type: 0, minTransferTime: undefined };
12456
12326
  }
@@ -12463,7 +12333,7 @@ const Transfer = {
12463
12333
  writer.uint32(16).int32(message.type);
12464
12334
  }
12465
12335
  if (message.minTransferTime !== undefined) {
12466
- writer.uint32(24).int32(message.minTransferTime);
12336
+ writer.uint32(24).uint32(message.minTransferTime);
12467
12337
  }
12468
12338
  return writer;
12469
12339
  },
@@ -12492,7 +12362,7 @@ const Transfer = {
12492
12362
  if (tag !== 24) {
12493
12363
  break;
12494
12364
  }
12495
- message.minTransferTime = reader.int32();
12365
+ message.minTransferTime = reader.uint32();
12496
12366
  continue;
12497
12367
  }
12498
12368
  }
@@ -12574,7 +12444,7 @@ const StopsAdjacency = {
12574
12444
  return {
12575
12445
  stops: isObject(object.stops)
12576
12446
  ? Object.entries(object.stops).reduce((acc, [key, value]) => {
12577
- acc[key] = StopsAdjacency_StopAdjacency.fromJSON(value);
12447
+ acc[globalThis.Number(key)] = StopsAdjacency_StopAdjacency.fromJSON(value);
12578
12448
  return acc;
12579
12449
  }, {})
12580
12450
  : {},
@@ -12601,7 +12471,7 @@ const StopsAdjacency = {
12601
12471
  const message = createBaseStopsAdjacency();
12602
12472
  message.stops = Object.entries((_a = object.stops) !== null && _a !== void 0 ? _a : {}).reduce((acc, [key, value]) => {
12603
12473
  if (value !== undefined) {
12604
- acc[key] = StopsAdjacency_StopAdjacency.fromPartial(value);
12474
+ acc[globalThis.Number(key)] = StopsAdjacency_StopAdjacency.fromPartial(value);
12605
12475
  }
12606
12476
  return acc;
12607
12477
  }, {});
@@ -12616,9 +12486,11 @@ const StopsAdjacency_StopAdjacency = {
12616
12486
  for (const v of message.transfers) {
12617
12487
  Transfer.encode(v, writer.uint32(10).fork()).join();
12618
12488
  }
12489
+ writer.uint32(18).fork();
12619
12490
  for (const v of message.routes) {
12620
- writer.uint32(18).string(v);
12491
+ writer.int32(v);
12621
12492
  }
12493
+ writer.join();
12622
12494
  return writer;
12623
12495
  },
12624
12496
  decode(input, length) {
@@ -12636,11 +12508,18 @@ const StopsAdjacency_StopAdjacency = {
12636
12508
  continue;
12637
12509
  }
12638
12510
  case 2: {
12639
- if (tag !== 18) {
12640
- break;
12511
+ if (tag === 16) {
12512
+ message.routes.push(reader.int32());
12513
+ continue;
12641
12514
  }
12642
- message.routes.push(reader.string());
12643
- continue;
12515
+ if (tag === 18) {
12516
+ const end2 = reader.uint32() + reader.pos;
12517
+ while (reader.pos < end2) {
12518
+ message.routes.push(reader.int32());
12519
+ }
12520
+ continue;
12521
+ }
12522
+ break;
12644
12523
  }
12645
12524
  }
12646
12525
  if ((tag & 7) === 4 || tag === 0) {
@@ -12655,7 +12534,7 @@ const StopsAdjacency_StopAdjacency = {
12655
12534
  transfers: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.transfers)
12656
12535
  ? object.transfers.map((e) => Transfer.fromJSON(e))
12657
12536
  : [],
12658
- routes: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.routes) ? object.routes.map((e) => globalThis.String(e)) : [],
12537
+ routes: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.routes) ? object.routes.map((e) => globalThis.Number(e)) : [],
12659
12538
  };
12660
12539
  },
12661
12540
  toJSON(message) {
@@ -12665,7 +12544,7 @@ const StopsAdjacency_StopAdjacency = {
12665
12544
  obj.transfers = message.transfers.map((e) => Transfer.toJSON(e));
12666
12545
  }
12667
12546
  if ((_b = message.routes) === null || _b === void 0 ? void 0 : _b.length) {
12668
- obj.routes = message.routes;
12547
+ obj.routes = message.routes.map((e) => Math.round(e));
12669
12548
  }
12670
12549
  return obj;
12671
12550
  },
@@ -12681,12 +12560,12 @@ const StopsAdjacency_StopAdjacency = {
12681
12560
  },
12682
12561
  };
12683
12562
  function createBaseStopsAdjacency_StopsEntry() {
12684
- return { key: "", value: undefined };
12563
+ return { key: 0, value: undefined };
12685
12564
  }
12686
12565
  const StopsAdjacency_StopsEntry = {
12687
12566
  encode(message, writer = new BinaryWriter()) {
12688
- if (message.key !== "") {
12689
- writer.uint32(10).string(message.key);
12567
+ if (message.key !== 0) {
12568
+ writer.uint32(8).uint32(message.key);
12690
12569
  }
12691
12570
  if (message.value !== undefined) {
12692
12571
  StopsAdjacency_StopAdjacency.encode(message.value, writer.uint32(18).fork()).join();
@@ -12701,10 +12580,10 @@ const StopsAdjacency_StopsEntry = {
12701
12580
  const tag = reader.uint32();
12702
12581
  switch (tag >>> 3) {
12703
12582
  case 1: {
12704
- if (tag !== 10) {
12583
+ if (tag !== 8) {
12705
12584
  break;
12706
12585
  }
12707
- message.key = reader.string();
12586
+ message.key = reader.uint32();
12708
12587
  continue;
12709
12588
  }
12710
12589
  case 2: {
@@ -12724,14 +12603,14 @@ const StopsAdjacency_StopsEntry = {
12724
12603
  },
12725
12604
  fromJSON(object) {
12726
12605
  return {
12727
- key: isSet(object.key) ? globalThis.String(object.key) : "",
12606
+ key: isSet(object.key) ? globalThis.Number(object.key) : 0,
12728
12607
  value: isSet(object.value) ? StopsAdjacency_StopAdjacency.fromJSON(object.value) : undefined,
12729
12608
  };
12730
12609
  },
12731
12610
  toJSON(message) {
12732
12611
  const obj = {};
12733
- if (message.key !== "") {
12734
- obj.key = message.key;
12612
+ if (message.key !== 0) {
12613
+ obj.key = Math.round(message.key);
12735
12614
  }
12736
12615
  if (message.value !== undefined) {
12737
12616
  obj.value = StopsAdjacency_StopAdjacency.toJSON(message.value);
@@ -12744,7 +12623,7 @@ const StopsAdjacency_StopsEntry = {
12744
12623
  fromPartial(object) {
12745
12624
  var _a;
12746
12625
  const message = createBaseStopsAdjacency_StopsEntry();
12747
- message.key = (_a = object.key) !== null && _a !== void 0 ? _a : "";
12626
+ message.key = (_a = object.key) !== null && _a !== void 0 ? _a : 0;
12748
12627
  message.value = (object.value !== undefined && object.value !== null)
12749
12628
  ? StopsAdjacency_StopAdjacency.fromPartial(object.value)
12750
12629
  : undefined;
@@ -12752,7 +12631,7 @@ const StopsAdjacency_StopsEntry = {
12752
12631
  },
12753
12632
  };
12754
12633
  function createBaseServiceRoute() {
12755
- return { type: 0, name: "" };
12634
+ return { type: 0, name: "", routes: [] };
12756
12635
  }
12757
12636
  const ServiceRoute = {
12758
12637
  encode(message, writer = new BinaryWriter()) {
@@ -12762,6 +12641,11 @@ const ServiceRoute = {
12762
12641
  if (message.name !== "") {
12763
12642
  writer.uint32(18).string(message.name);
12764
12643
  }
12644
+ writer.uint32(26).fork();
12645
+ for (const v of message.routes) {
12646
+ writer.int32(v);
12647
+ }
12648
+ writer.join();
12765
12649
  return writer;
12766
12650
  },
12767
12651
  decode(input, length) {
@@ -12785,6 +12669,20 @@ const ServiceRoute = {
12785
12669
  message.name = reader.string();
12786
12670
  continue;
12787
12671
  }
12672
+ case 3: {
12673
+ if (tag === 24) {
12674
+ message.routes.push(reader.int32());
12675
+ continue;
12676
+ }
12677
+ if (tag === 26) {
12678
+ const end2 = reader.uint32() + reader.pos;
12679
+ while (reader.pos < end2) {
12680
+ message.routes.push(reader.int32());
12681
+ }
12682
+ continue;
12683
+ }
12684
+ break;
12685
+ }
12788
12686
  }
12789
12687
  if ((tag & 7) === 4 || tag === 0) {
12790
12688
  break;
@@ -12797,9 +12695,11 @@ const ServiceRoute = {
12797
12695
  return {
12798
12696
  type: isSet(object.type) ? routeTypeFromJSON(object.type) : 0,
12799
12697
  name: isSet(object.name) ? globalThis.String(object.name) : "",
12698
+ routes: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.routes) ? object.routes.map((e) => globalThis.Number(e)) : [],
12800
12699
  };
12801
12700
  },
12802
12701
  toJSON(message) {
12702
+ var _a;
12803
12703
  const obj = {};
12804
12704
  if (message.type !== 0) {
12805
12705
  obj.type = routeTypeToJSON(message.type);
@@ -12807,16 +12707,20 @@ const ServiceRoute = {
12807
12707
  if (message.name !== "") {
12808
12708
  obj.name = message.name;
12809
12709
  }
12710
+ if ((_a = message.routes) === null || _a === void 0 ? void 0 : _a.length) {
12711
+ obj.routes = message.routes.map((e) => Math.round(e));
12712
+ }
12810
12713
  return obj;
12811
12714
  },
12812
12715
  create(base) {
12813
12716
  return ServiceRoute.fromPartial(base !== null && base !== void 0 ? base : {});
12814
12717
  },
12815
12718
  fromPartial(object) {
12816
- var _a, _b;
12719
+ var _a, _b, _c;
12817
12720
  const message = createBaseServiceRoute();
12818
12721
  message.type = (_a = object.type) !== null && _a !== void 0 ? _a : 0;
12819
12722
  message.name = (_b = object.name) !== null && _b !== void 0 ? _b : "";
12723
+ message.routes = ((_c = object.routes) === null || _c === void 0 ? void 0 : _c.map((e) => e)) || [];
12820
12724
  return message;
12821
12725
  },
12822
12726
  };
@@ -12965,7 +12869,7 @@ const ServiceRoutesMap_RoutesEntry = {
12965
12869
  },
12966
12870
  };
12967
12871
  function createBaseTimetable() {
12968
- return { version: "", stopsAdjacency: undefined, routesAdjacency: undefined, routes: undefined };
12872
+ return { version: "", stopsAdjacency: undefined, routesAdjacency: [], routes: undefined };
12969
12873
  }
12970
12874
  const Timetable$1 = {
12971
12875
  encode(message, writer = new BinaryWriter()) {
@@ -12975,8 +12879,8 @@ const Timetable$1 = {
12975
12879
  if (message.stopsAdjacency !== undefined) {
12976
12880
  StopsAdjacency.encode(message.stopsAdjacency, writer.uint32(18).fork()).join();
12977
12881
  }
12978
- if (message.routesAdjacency !== undefined) {
12979
- RoutesAdjacency.encode(message.routesAdjacency, writer.uint32(26).fork()).join();
12882
+ for (const v of message.routesAdjacency) {
12883
+ Route$1.encode(v, writer.uint32(26).fork()).join();
12980
12884
  }
12981
12885
  if (message.routes !== undefined) {
12982
12886
  ServiceRoutesMap.encode(message.routes, writer.uint32(34).fork()).join();
@@ -13008,7 +12912,7 @@ const Timetable$1 = {
13008
12912
  if (tag !== 26) {
13009
12913
  break;
13010
12914
  }
13011
- message.routesAdjacency = RoutesAdjacency.decode(reader, reader.uint32());
12915
+ message.routesAdjacency.push(Route$1.decode(reader, reader.uint32()));
13012
12916
  continue;
13013
12917
  }
13014
12918
  case 4: {
@@ -13030,11 +12934,14 @@ const Timetable$1 = {
13030
12934
  return {
13031
12935
  version: isSet(object.version) ? globalThis.String(object.version) : "",
13032
12936
  stopsAdjacency: isSet(object.stopsAdjacency) ? StopsAdjacency.fromJSON(object.stopsAdjacency) : undefined,
13033
- routesAdjacency: isSet(object.routesAdjacency) ? RoutesAdjacency.fromJSON(object.routesAdjacency) : undefined,
12937
+ routesAdjacency: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.routesAdjacency)
12938
+ ? object.routesAdjacency.map((e) => Route$1.fromJSON(e))
12939
+ : [],
13034
12940
  routes: isSet(object.routes) ? ServiceRoutesMap.fromJSON(object.routes) : undefined,
13035
12941
  };
13036
12942
  },
13037
12943
  toJSON(message) {
12944
+ var _a;
13038
12945
  const obj = {};
13039
12946
  if (message.version !== "") {
13040
12947
  obj.version = message.version;
@@ -13042,8 +12949,8 @@ const Timetable$1 = {
13042
12949
  if (message.stopsAdjacency !== undefined) {
13043
12950
  obj.stopsAdjacency = StopsAdjacency.toJSON(message.stopsAdjacency);
13044
12951
  }
13045
- if (message.routesAdjacency !== undefined) {
13046
- obj.routesAdjacency = RoutesAdjacency.toJSON(message.routesAdjacency);
12952
+ if ((_a = message.routesAdjacency) === null || _a === void 0 ? void 0 : _a.length) {
12953
+ obj.routesAdjacency = message.routesAdjacency.map((e) => Route$1.toJSON(e));
13047
12954
  }
13048
12955
  if (message.routes !== undefined) {
13049
12956
  obj.routes = ServiceRoutesMap.toJSON(message.routes);
@@ -13054,15 +12961,13 @@ const Timetable$1 = {
13054
12961
  return Timetable$1.fromPartial(base !== null && base !== void 0 ? base : {});
13055
12962
  },
13056
12963
  fromPartial(object) {
13057
- var _a;
12964
+ var _a, _b;
13058
12965
  const message = createBaseTimetable();
13059
12966
  message.version = (_a = object.version) !== null && _a !== void 0 ? _a : "";
13060
12967
  message.stopsAdjacency = (object.stopsAdjacency !== undefined && object.stopsAdjacency !== null)
13061
12968
  ? StopsAdjacency.fromPartial(object.stopsAdjacency)
13062
12969
  : undefined;
13063
- message.routesAdjacency = (object.routesAdjacency !== undefined && object.routesAdjacency !== null)
13064
- ? RoutesAdjacency.fromPartial(object.routesAdjacency)
13065
- : undefined;
12970
+ message.routesAdjacency = ((_b = object.routesAdjacency) === null || _b === void 0 ? void 0 : _b.map((e) => Route$1.fromPartial(e))) || [];
13066
12971
  message.routes = (object.routes !== undefined && object.routes !== null)
13067
12972
  ? ServiceRoutesMap.fromPartial(object.routes)
13068
12973
  : undefined;
@@ -13442,11 +13347,16 @@ class Route {
13442
13347
  * @returns The pick-up type at the specified stop and trip.
13443
13348
  */
13444
13349
  pickUpTypeFrom(stopId, tripIndex) {
13445
- const pickUpIndex = (tripIndex * this.stops.length + this.stopIndex(stopId)) * 2;
13446
- const pickUpValue = this.pickUpDropOffTypes[pickUpIndex];
13447
- if (pickUpValue === undefined) {
13350
+ const globalIndex = tripIndex * this.stops.length + this.stopIndex(stopId);
13351
+ const byteIndex = Math.floor(globalIndex / 2);
13352
+ const isSecondPair = globalIndex % 2 === 1;
13353
+ const byte = this.pickUpDropOffTypes[byteIndex];
13354
+ if (byte === undefined) {
13448
13355
  throw new Error(`Pick up type not found for stop ${stopId} at trip index ${tripIndex} in route ${this.serviceRouteId}`);
13449
13356
  }
13357
+ const pickUpValue = isSecondPair
13358
+ ? (byte >> 6) & 0x03 // Upper 2 bits for second pair
13359
+ : (byte >> 2) & 0x03; // Bits 2-3 for first pair
13450
13360
  return toPickupDropOffType(pickUpValue);
13451
13361
  }
13452
13362
  /**
@@ -13457,11 +13367,16 @@ class Route {
13457
13367
  * @returns The drop-off type at the specified stop and trip.
13458
13368
  */
13459
13369
  dropOffTypeAt(stopId, tripIndex) {
13460
- const dropOffIndex = (tripIndex * this.stops.length + this.stopIndex(stopId)) * 2 + 1;
13461
- const dropOffValue = this.pickUpDropOffTypes[dropOffIndex];
13462
- if (dropOffValue === undefined) {
13370
+ const globalIndex = tripIndex * this.stops.length + this.stopIndex(stopId);
13371
+ const byteIndex = Math.floor(globalIndex / 2);
13372
+ const isSecondPair = globalIndex % 2 === 1;
13373
+ const byte = this.pickUpDropOffTypes[byteIndex];
13374
+ if (byte === undefined) {
13463
13375
  throw new Error(`Drop off type not found for stop ${stopId} at trip index ${tripIndex} in route ${this.serviceRouteId}`);
13464
13376
  }
13377
+ const dropOffValue = isSecondPair
13378
+ ? (byte >> 4) & 0x03 // Bits 4-5 for second pair
13379
+ : byte & 0x03; // Lower 2 bits for first pair
13465
13380
  return toPickupDropOffType(dropOffValue);
13466
13381
  }
13467
13382
  /**
@@ -13616,17 +13531,15 @@ const serializeStopsAdjacency = (stopsAdjacency) => {
13616
13531
  return protoStopsAdjacency;
13617
13532
  };
13618
13533
  const serializeRoutesAdjacency = (routesAdjacency) => {
13619
- const protoRoutesAdjacency = {
13620
- routes: {},
13621
- };
13622
- routesAdjacency.forEach((route, key) => {
13534
+ const protoRoutesAdjacency = [];
13535
+ routesAdjacency.forEach((route) => {
13623
13536
  const routeData = route.serialize();
13624
- protoRoutesAdjacency.routes[key] = {
13537
+ protoRoutesAdjacency.push({
13625
13538
  stopTimes: uint16ArrayToBytes(routeData.stopTimes),
13626
13539
  pickUpDropOffTypes: routeData.pickUpDropOffTypes,
13627
13540
  stops: uint32ArrayToBytes(routeData.stops),
13628
13541
  serviceRouteId: routeData.serviceRouteId,
13629
- };
13542
+ });
13630
13543
  });
13631
13544
  return protoRoutesAdjacency;
13632
13545
  };
@@ -13638,6 +13551,7 @@ const serializeServiceRoutesMap = (serviceRoutesMap) => {
13638
13551
  protoServiceRoutesMap.routes[key] = {
13639
13552
  type: serializeRouteType(value.type),
13640
13553
  name: value.name,
13554
+ routes: value.routes,
13641
13555
  };
13642
13556
  });
13643
13557
  return protoServiceRoutesMap;
@@ -13656,10 +13570,10 @@ const deserializeStopsAdjacency = (protoStopsAdjacency) => {
13656
13570
  return stopsAdjacency;
13657
13571
  };
13658
13572
  const deserializeRoutesAdjacency = (protoRoutesAdjacency) => {
13659
- const routesAdjacency = new Map();
13660
- Object.entries(protoRoutesAdjacency.routes).forEach(([key, value]) => {
13573
+ const routesAdjacency = [];
13574
+ protoRoutesAdjacency.forEach((value) => {
13661
13575
  const stops = bytesToUint32Array(value.stops);
13662
- routesAdjacency.set(key, new Route(bytesToUint16Array(value.stopTimes), value.pickUpDropOffTypes, stops, value.serviceRouteId));
13576
+ routesAdjacency.push(new Route(bytesToUint16Array(value.stopTimes), value.pickUpDropOffTypes, stops, value.serviceRouteId));
13663
13577
  });
13664
13578
  return routesAdjacency;
13665
13579
  };
@@ -13669,6 +13583,7 @@ const deserializeServiceRoutesMap = (protoServiceRoutesMap) => {
13669
13583
  serviceRoutesMap.set(key, {
13670
13584
  type: parseRouteType(value.type),
13671
13585
  name: value.name,
13586
+ routes: value.routes,
13672
13587
  });
13673
13588
  });
13674
13589
  return serviceRoutesMap;
@@ -13763,7 +13678,7 @@ const ALL_TRANSPORT_MODES = new Set([
13763
13678
  'TROLLEYBUS',
13764
13679
  'MONORAIL',
13765
13680
  ]);
13766
- const CURRENT_VERSION = '0.0.3';
13681
+ const CURRENT_VERSION = '0.0.5';
13767
13682
  /**
13768
13683
  * The internal transit timetable format.
13769
13684
  */
@@ -13803,9 +13718,7 @@ class Timetable {
13803
13718
  }
13804
13719
  return new Timetable(
13805
13720
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
13806
- deserializeStopsAdjacency(protoTimetable.stopsAdjacency), deserializeRoutesAdjacency(
13807
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
13808
- protoTimetable.routesAdjacency),
13721
+ deserializeStopsAdjacency(protoTimetable.stopsAdjacency), deserializeRoutesAdjacency(protoTimetable.routesAdjacency),
13809
13722
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
13810
13723
  deserializeServiceRoutesMap(protoTimetable.routes));
13811
13724
  }
@@ -13817,7 +13730,7 @@ class Timetable {
13817
13730
  * or undefined if no such route exists.
13818
13731
  */
13819
13732
  getRoute(routeId) {
13820
- return this.routesAdjacency.get(routeId);
13733
+ return this.routesAdjacency[routeId];
13821
13734
  }
13822
13735
  /**
13823
13736
  * Retrieves all transfer options available at the specified stop.
@@ -13837,9 +13750,14 @@ class Timetable {
13837
13750
  * @param route - The route for which the service route is to be retrieved.
13838
13751
  * @returns The service route corresponding to the provided route.
13839
13752
  */
13840
- getServiceRoute(route) {
13841
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
13842
- return this.routes.get(route.serviceRoute());
13753
+ getServiceRouteInfo(route) {
13754
+ const serviceRoute = this.routes.get(route.serviceRoute());
13755
+ if (!serviceRoute) {
13756
+ throw new Error(`Service route not found for route ID: ${route.serviceRoute()}`);
13757
+ }
13758
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13759
+ const { routes } = serviceRoute, serviceRouteInfo = __rest(serviceRoute, ["routes"]);
13760
+ return serviceRouteInfo;
13843
13761
  }
13844
13762
  /**
13845
13763
  * Finds all routes passing through a stop.
@@ -13854,7 +13772,7 @@ class Timetable {
13854
13772
  }
13855
13773
  const routes = [];
13856
13774
  for (const routeId of stopData.routes) {
13857
- const route = this.routesAdjacency.get(routeId);
13775
+ const route = this.routesAdjacency[routeId];
13858
13776
  if (route) {
13859
13777
  routes.push(route);
13860
13778
  }
@@ -13874,7 +13792,7 @@ class Timetable {
13874
13792
  const reachableRoutes = new Map();
13875
13793
  for (const originStop of fromStops) {
13876
13794
  const validRoutes = this.routesPassingThrough(originStop).filter((route) => {
13877
- const serviceRoute = this.getServiceRoute(route);
13795
+ const serviceRoute = this.getServiceRouteInfo(route);
13878
13796
  return transportModes.has(serviceRoute.type);
13879
13797
  });
13880
13798
  for (const route of validRoutes) {
@@ -15885,6 +15803,7 @@ const parseRoutes = (routesStream_1, ...args_1) => __awaiter(void 0, [routesStre
15885
15803
  routes.set(line.route_id, {
15886
15804
  name: line.route_short_name,
15887
15805
  type: routeType,
15806
+ routes: [],
15888
15807
  });
15889
15808
  }
15890
15809
  }
@@ -16194,15 +16113,95 @@ const parseGtfsTransferType = (gtfsTransferType) => {
16194
16113
  }
16195
16114
  };
16196
16115
 
16116
+ /**
16117
+ * Encodes pickup/drop-off types into a Uint8Array using 2 bits per value.
16118
+ * Layout per byte: [drop_off_1][pickup_1][drop_off_0][pickup_0] for stops 0 and 1
16119
+ */
16120
+ const encodePickUpDropOffTypes = (pickUpTypes, dropOffTypes) => {
16121
+ const stopsCount = pickUpTypes.length;
16122
+ // Each byte stores 2 pickup/drop-off pairs (4 bits each)
16123
+ const arraySize = Math.ceil(stopsCount / 2);
16124
+ const encoded = new Uint8Array(arraySize);
16125
+ for (let i = 0; i < stopsCount; i++) {
16126
+ const byteIndex = Math.floor(i / 2);
16127
+ const isSecondPair = i % 2 === 1;
16128
+ const dropOffType = dropOffTypes[i];
16129
+ const pickUpType = pickUpTypes[i];
16130
+ if (dropOffType !== undefined &&
16131
+ pickUpType !== undefined &&
16132
+ byteIndex < encoded.length) {
16133
+ if (isSecondPair) {
16134
+ // Second pair: upper 4 bits
16135
+ const currentByte = encoded[byteIndex];
16136
+ if (currentByte !== undefined) {
16137
+ encoded[byteIndex] =
16138
+ currentByte | (dropOffType << 4) | (pickUpType << 6);
16139
+ }
16140
+ }
16141
+ else {
16142
+ // First pair: lower 4 bits
16143
+ const currentByte = encoded[byteIndex];
16144
+ if (currentByte !== undefined) {
16145
+ encoded[byteIndex] = currentByte | dropOffType | (pickUpType << 2);
16146
+ }
16147
+ }
16148
+ }
16149
+ }
16150
+ return encoded;
16151
+ };
16152
+ /**
16153
+ * Sorts trips by departure time and creates optimized typed arrays
16154
+ */
16155
+ const finalizeRouteFromBuilder = (builder) => {
16156
+ builder.trips.sort((a, b) => a.firstDeparture - b.firstDeparture);
16157
+ const stopsCount = builder.stops.length;
16158
+ const tripsCount = builder.trips.length;
16159
+ const stopsArray = new Uint32Array(builder.stops);
16160
+ const stopTimesArray = new Uint16Array(stopsCount * tripsCount * 2);
16161
+ const allPickUpTypes = [];
16162
+ const allDropOffTypes = [];
16163
+ for (let tripIndex = 0; tripIndex < tripsCount; tripIndex++) {
16164
+ const trip = builder.trips[tripIndex];
16165
+ if (!trip) {
16166
+ throw new Error(`Missing trip data at index ${tripIndex}`);
16167
+ }
16168
+ const baseIndex = tripIndex * stopsCount * 2;
16169
+ for (let stopIndex = 0; stopIndex < stopsCount; stopIndex++) {
16170
+ const timeIndex = baseIndex + stopIndex * 2;
16171
+ const arrivalTime = trip.arrivalTimes[stopIndex];
16172
+ const departureTime = trip.departureTimes[stopIndex];
16173
+ const pickUpType = trip.pickUpTypes[stopIndex];
16174
+ const dropOffType = trip.dropOffTypes[stopIndex];
16175
+ if (arrivalTime === undefined ||
16176
+ departureTime === undefined ||
16177
+ pickUpType === undefined ||
16178
+ dropOffType === undefined) {
16179
+ throw new Error(`Missing trip data for trip ${tripIndex} at stop ${stopIndex}`);
16180
+ }
16181
+ stopTimesArray[timeIndex] = arrivalTime;
16182
+ stopTimesArray[timeIndex + 1] = departureTime;
16183
+ allDropOffTypes.push(dropOffType);
16184
+ allPickUpTypes.push(pickUpType);
16185
+ }
16186
+ }
16187
+ // Use 2-bit encoding for pickup/drop-off types
16188
+ const pickUpDropOffTypesArray = encodePickUpDropOffTypes(allPickUpTypes, allDropOffTypes);
16189
+ return {
16190
+ serviceRouteId: builder.serviceRouteId,
16191
+ stops: stopsArray,
16192
+ stopTimes: stopTimesArray,
16193
+ pickUpDropOffTypes: pickUpDropOffTypesArray,
16194
+ };
16195
+ };
16197
16196
  /**
16198
16197
  * Parses the trips.txt file from a GTFS feed
16199
16198
  *
16200
16199
  * @param tripsStream The readable stream containing the trips data.
16201
16200
  * @param serviceIds A mapping of service IDs to corresponding route IDs.
16202
- * @param routeIds A mapping of route IDs to route details.
16201
+ * @param serviceRoutes A mapping of route IDs to route details.
16203
16202
  * @returns A mapping of trip IDs to corresponding route IDs.
16204
16203
  */
16205
- const parseTrips = (tripsStream, serviceIds, routeIds) => __awaiter(void 0, void 0, void 0, function* () {
16204
+ const parseTrips = (tripsStream, serviceIds, serviceRoutes) => __awaiter(void 0, void 0, void 0, function* () {
16206
16205
  var _a, e_1, _b, _c;
16207
16206
  const trips = new Map();
16208
16207
  try {
@@ -16215,7 +16214,7 @@ const parseTrips = (tripsStream, serviceIds, routeIds) => __awaiter(void 0, void
16215
16214
  // The trip doesn't correspond to an active service
16216
16215
  continue;
16217
16216
  }
16218
- if (!routeIds.get(line.route_id)) {
16217
+ if (!serviceRoutes.get(line.route_id)) {
16219
16218
  // The trip doesn't correspond to a supported route
16220
16219
  continue;
16221
16220
  }
@@ -16231,21 +16230,22 @@ const parseTrips = (tripsStream, serviceIds, routeIds) => __awaiter(void 0, void
16231
16230
  }
16232
16231
  return trips;
16233
16232
  });
16234
- const buildStopsAdjacencyStructure = (validStops, routes, transfersMap) => {
16235
- var _a;
16233
+ const buildStopsAdjacencyStructure = (validStops, serviceRoutes, routes, transfersMap) => {
16236
16234
  const stopsAdjacency = new Map();
16237
- for (const routeId of routes.keys()) {
16238
- const route = routes.get(routeId);
16239
- if (!route) {
16240
- throw new Error(`Route ${routeId} not found`);
16241
- }
16235
+ routes.forEach((route, index) => {
16236
+ var _a;
16242
16237
  for (const stop of route.stopsIterator()) {
16243
16238
  if (!stopsAdjacency.get(stop) && validStops.has(stop)) {
16244
16239
  stopsAdjacency.set(stop, { routes: [], transfers: [] });
16245
16240
  }
16246
- (_a = stopsAdjacency.get(stop)) === null || _a === void 0 ? void 0 : _a.routes.push(routeId);
16241
+ (_a = stopsAdjacency.get(stop)) === null || _a === void 0 ? void 0 : _a.routes.push(index);
16247
16242
  }
16248
- }
16243
+ const serviceRoute = serviceRoutes.get(route.serviceRoute());
16244
+ if (!serviceRoute) {
16245
+ throw new Error(`Service route ${route.serviceRoute()} not found for route ${index}.`);
16246
+ }
16247
+ serviceRoute.routes.push(index);
16248
+ });
16249
16249
  for (const [stop, transfers] of transfersMap) {
16250
16250
  const s = stopsAdjacency.get(stop);
16251
16251
  if (s) {
@@ -16271,11 +16271,11 @@ const parseStopTimes = (stopTimesStream, stopsMap, validTripIds, validStopIds) =
16271
16271
  var _a, e_2, _b, _c;
16272
16272
  var _d, _e;
16273
16273
  /**
16274
- * Inserts a trip at the right place in the routes adjacency structure.
16274
+ * Adds a trip to the appropriate route builder
16275
16275
  */
16276
16276
  const addTrip = (currentTripId) => {
16277
16277
  const gtfsRouteId = validTripIds.get(currentTripId);
16278
- if (!gtfsRouteId) {
16278
+ if (!gtfsRouteId || stops.length === 0) {
16279
16279
  stops = [];
16280
16280
  arrivalTimes = [];
16281
16281
  departureTimes = [];
@@ -16284,83 +16284,42 @@ const parseStopTimes = (stopTimesStream, stopsMap, validTripIds, validStopIds) =
16284
16284
  return;
16285
16285
  }
16286
16286
  const routeId = `${gtfsRouteId}_${hashIds(stops)}`;
16287
- let route = routes.get(routeId);
16288
- if (!route) {
16289
- const stopsCount = stops.length;
16290
- const stopsArray = new Uint32Array(stops);
16291
- const stopTimesArray = new Uint16Array(stopsCount * 2);
16292
- for (let i = 0; i < stopsCount; i++) {
16293
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16294
- stopTimesArray[i * 2] = arrivalTimes[i];
16295
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16296
- stopTimesArray[i * 2 + 1] = departureTimes[i];
16297
- }
16298
- const pickUpDropOffTypesArray = new Uint8Array(stopsCount * 2);
16299
- for (let i = 0; i < stopsCount; i++) {
16300
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16301
- pickUpDropOffTypesArray[i * 2] = pickUpTypes[i];
16302
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16303
- pickUpDropOffTypesArray[i * 2 + 1] = dropOffTypes[i];
16304
- }
16305
- route = {
16287
+ const firstDeparture = departureTimes[0];
16288
+ if (firstDeparture === undefined) {
16289
+ console.warn(`Empty trip ${currentTripId}`);
16290
+ stops = [];
16291
+ arrivalTimes = [];
16292
+ departureTimes = [];
16293
+ pickUpTypes = [];
16294
+ dropOffTypes = [];
16295
+ return;
16296
+ }
16297
+ let routeBuilder = routeBuilders.get(routeId);
16298
+ if (!routeBuilder) {
16299
+ routeBuilder = {
16306
16300
  serviceRouteId: gtfsRouteId,
16307
- stops: stopsArray,
16308
- stopTimes: stopTimesArray,
16309
- pickUpDropOffTypes: pickUpDropOffTypesArray,
16301
+ stops: [...stops],
16302
+ trips: [],
16310
16303
  };
16311
- routes.set(routeId, route);
16304
+ routeBuilders.set(routeId, routeBuilder);
16312
16305
  for (const stop of stops) {
16313
16306
  validStopIds.add(stop);
16314
16307
  }
16315
16308
  }
16316
- else {
16317
- const tripFirstStopDeparture = departureTimes[0];
16318
- if (tripFirstStopDeparture === undefined) {
16319
- throw new Error(`Empty trip ${currentTripId}`);
16320
- }
16321
- // Find the correct position to insert the new trip
16322
- const stopsCount = stops.length;
16323
- let insertPosition = 0;
16324
- const existingTripsCount = route.stopTimes.length / (stopsCount * 2);
16325
- for (let tripIndex = 0; tripIndex < existingTripsCount; tripIndex++) {
16326
- const currentDeparture = route.stopTimes[tripIndex * stopsCount * 2 + 1];
16327
- if (currentDeparture && tripFirstStopDeparture > currentDeparture) {
16328
- insertPosition = (tripIndex + 1) * stopsCount;
16329
- }
16330
- else {
16331
- break;
16332
- }
16333
- }
16334
- // insert data for the new trip at the right place
16335
- const newStopTimesLength = route.stopTimes.length + stopsCount * 2;
16336
- const newStopTimes = new Uint16Array(newStopTimesLength);
16337
- const newPickUpDropOffTypes = new Uint8Array(newStopTimesLength);
16338
- newStopTimes.set(route.stopTimes.slice(0, insertPosition * 2), 0);
16339
- newPickUpDropOffTypes.set(route.pickUpDropOffTypes.slice(0, insertPosition * 2), 0);
16340
- for (let i = 0; i < stopsCount; i++) {
16341
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16342
- newStopTimes[(insertPosition + i) * 2] = arrivalTimes[i];
16343
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16344
- newStopTimes[(insertPosition + i) * 2 + 1] = departureTimes[i];
16345
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16346
- newPickUpDropOffTypes[(insertPosition + i) * 2] = pickUpTypes[i];
16347
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16348
- newPickUpDropOffTypes[(insertPosition + i) * 2 + 1] = dropOffTypes[i];
16349
- }
16350
- const afterInsertionSlice = route.stopTimes.slice(insertPosition * 2);
16351
- newStopTimes.set(afterInsertionSlice, (insertPosition + stopsCount) * 2);
16352
- const afterInsertionTypesSlice = route.pickUpDropOffTypes.slice(insertPosition * 2);
16353
- newPickUpDropOffTypes.set(afterInsertionTypesSlice, (insertPosition + stopsCount) * 2);
16354
- route.stopTimes = newStopTimes;
16355
- route.pickUpDropOffTypes = newPickUpDropOffTypes;
16356
- }
16309
+ routeBuilder.trips.push({
16310
+ firstDeparture,
16311
+ arrivalTimes: [...arrivalTimes],
16312
+ departureTimes: [...departureTimes],
16313
+ pickUpTypes: [...pickUpTypes],
16314
+ dropOffTypes: [...dropOffTypes],
16315
+ });
16357
16316
  stops = [];
16358
16317
  arrivalTimes = [];
16359
16318
  departureTimes = [];
16360
16319
  pickUpTypes = [];
16361
16320
  dropOffTypes = [];
16362
16321
  };
16363
- const routes = new Map();
16322
+ const routeBuilders = new Map();
16364
16323
  let previousSeq = 0;
16365
16324
  let stops = [];
16366
16325
  let arrivalTimes = [];
@@ -16375,27 +16334,33 @@ const parseStopTimes = (stopTimesStream, stopsMap, validTripIds, validStopIds) =
16375
16334
  const rawLine = _c;
16376
16335
  const line = rawLine;
16377
16336
  if (line.trip_id === currentTripId && line.stop_sequence <= previousSeq) {
16378
- console.warn(`Stop sequences not increasing for trip ${line.trip_id}.`);
16337
+ console.warn(`Stop sequences not increasing for trip ${line.trip_id}: ${line.stop_sequence} > ${previousSeq}.`);
16379
16338
  continue;
16380
16339
  }
16381
16340
  if (!line.arrival_time && !line.departure_time) {
16382
16341
  console.warn(`Missing arrival or departure time for ${line.trip_id} at stop ${line.stop_id}.`);
16383
16342
  continue;
16384
16343
  }
16385
- if (line.pickup_type === 1 && line.drop_off_type === 1) {
16344
+ if (line.pickup_type === '1' && line.drop_off_type === '1') {
16386
16345
  continue;
16387
16346
  }
16388
16347
  if (currentTripId && line.trip_id !== currentTripId && stops.length > 0) {
16389
16348
  addTrip(currentTripId);
16390
16349
  }
16391
16350
  currentTripId = line.trip_id;
16392
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16393
- stops.push(stopsMap.get(line.stop_id).id);
16351
+ const stopData = stopsMap.get(line.stop_id);
16352
+ if (!stopData) {
16353
+ console.warn(`Unknown stop ID: ${line.stop_id}`);
16354
+ continue;
16355
+ }
16356
+ stops.push(stopData.id);
16394
16357
  const departure = (_d = line.departure_time) !== null && _d !== void 0 ? _d : line.arrival_time;
16395
16358
  const arrival = (_e = line.arrival_time) !== null && _e !== void 0 ? _e : line.departure_time;
16396
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16359
+ if (!arrival || !departure) {
16360
+ console.warn(`Missing time data for ${line.trip_id} at stop ${line.stop_id}`);
16361
+ continue;
16362
+ }
16397
16363
  arrivalTimes.push(toTime(arrival).toMinutes());
16398
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16399
16364
  departureTimes.push(toTime(departure).toMinutes());
16400
16365
  pickUpTypes.push(parsePickupDropOffType(line.pickup_type));
16401
16366
  dropOffTypes.push(parsePickupDropOffType(line.drop_off_type));
@@ -16412,9 +16377,10 @@ const parseStopTimes = (stopTimesStream, stopsMap, validTripIds, validStopIds) =
16412
16377
  if (currentTripId) {
16413
16378
  addTrip(currentTripId);
16414
16379
  }
16415
- const routesAdjacency = new Map();
16416
- for (const [routeId, routeData] of routes) {
16417
- routesAdjacency.set(routeId, new Route(routeData.stopTimes, routeData.pickUpDropOffTypes, routeData.stops, routeData.serviceRouteId));
16380
+ const routesAdjacency = [];
16381
+ for (const [, routeBuilder] of routeBuilders) {
16382
+ const routeData = finalizeRouteFromBuilder(routeBuilder);
16383
+ routesAdjacency.push(new Route(routeData.stopTimes, routeData.pickUpDropOffTypes, routeData.stops, routeData.serviceRouteId));
16418
16384
  }
16419
16385
  return routesAdjacency;
16420
16386
  });
@@ -16422,13 +16388,13 @@ const parsePickupDropOffType = (gtfsType) => {
16422
16388
  switch (gtfsType) {
16423
16389
  default:
16424
16390
  return REGULAR;
16425
- case 0:
16391
+ case '0':
16426
16392
  return REGULAR;
16427
- case 1:
16393
+ case '1':
16428
16394
  return NOT_AVAILABLE;
16429
- case 2:
16395
+ case '2':
16430
16396
  return MUST_PHONE_AGENCY;
16431
- case 3:
16397
+ case '3':
16432
16398
  return MUST_COORDINATE_WITH_DRIVER;
16433
16399
  }
16434
16400
  };
@@ -16456,54 +16422,74 @@ class GtfsParser {
16456
16422
  */
16457
16423
  parse(date) {
16458
16424
  return __awaiter(this, void 0, void 0, function* () {
16425
+ log.setLevel('INFO');
16459
16426
  const zip = new StreamZip.async({ file: this.path });
16460
16427
  const entries = yield zip.entries();
16461
16428
  const datetime = DateTime.fromJSDate(date);
16462
16429
  const validServiceIds = new Set();
16463
16430
  const validStopIds = new Set();
16464
16431
  log.info(`Parsing ${STOPS_FILE}`);
16432
+ const stopsStart = performance.now();
16465
16433
  const stopsStream = yield zip.stream(STOPS_FILE);
16466
16434
  const parsedStops = yield parseStops(stopsStream, this.profile.platformParser);
16467
- log.info(`${parsedStops.size} parsed stops.`);
16435
+ const stopsEnd = performance.now();
16436
+ log.info(`${parsedStops.size} parsed stops. (${(stopsEnd - stopsStart).toFixed(2)}ms)`);
16468
16437
  if (entries[CALENDAR_FILE]) {
16469
16438
  log.info(`Parsing ${CALENDAR_FILE}`);
16439
+ const calendarStart = performance.now();
16470
16440
  const calendarStream = yield zip.stream(CALENDAR_FILE);
16471
16441
  yield parseCalendar(calendarStream, validServiceIds, datetime);
16472
- log.info(`${validServiceIds.size} valid services.`);
16442
+ const calendarEnd = performance.now();
16443
+ log.info(`${validServiceIds.size} valid services. (${(calendarEnd - calendarStart).toFixed(2)}ms)`);
16473
16444
  }
16474
16445
  if (entries[CALENDAR_DATES_FILE]) {
16475
16446
  log.info(`Parsing ${CALENDAR_DATES_FILE}`);
16447
+ const calendarDatesStart = performance.now();
16476
16448
  const calendarDatesStream = yield zip.stream(CALENDAR_DATES_FILE);
16477
16449
  yield parseCalendarDates(calendarDatesStream, validServiceIds, datetime);
16478
- log.info(`${validServiceIds.size} valid services.`);
16450
+ const calendarDatesEnd = performance.now();
16451
+ log.info(`${validServiceIds.size} valid services. (${(calendarDatesEnd - calendarDatesStart).toFixed(2)}ms)`);
16479
16452
  }
16480
16453
  log.info(`Parsing ${ROUTES_FILE}`);
16454
+ const routesStart = performance.now();
16481
16455
  const routesStream = yield zip.stream(ROUTES_FILE);
16482
16456
  const validGtfsRoutes = yield parseRoutes(routesStream, this.profile);
16483
- log.info(`${validGtfsRoutes.size} valid GTFS routes.`);
16457
+ const routesEnd = performance.now();
16458
+ log.info(`${validGtfsRoutes.size} valid GTFS routes. (${(routesEnd - routesStart).toFixed(2)}ms)`);
16484
16459
  log.info(`Parsing ${TRIPS_FILE}`);
16460
+ const tripsStart = performance.now();
16485
16461
  const tripsStream = yield zip.stream(TRIPS_FILE);
16486
16462
  const trips = yield parseTrips(tripsStream, validServiceIds, validGtfsRoutes);
16487
- log.info(`${trips.size} valid trips.`);
16463
+ const tripsEnd = performance.now();
16464
+ log.info(`${trips.size} valid trips. (${(tripsEnd - tripsStart).toFixed(2)}ms)`);
16488
16465
  let transfers = new Map();
16489
16466
  if (entries[TRANSFERS_FILE]) {
16490
16467
  log.info(`Parsing ${TRANSFERS_FILE}`);
16468
+ const transfersStart = performance.now();
16491
16469
  const transfersStream = yield zip.stream(TRANSFERS_FILE);
16492
16470
  transfers = yield parseTransfers(transfersStream, parsedStops);
16493
- log.info(`${transfers.size} valid transfers.`);
16471
+ const transfersEnd = performance.now();
16472
+ log.info(`${transfers.size} valid transfers. (${(transfersEnd - transfersStart).toFixed(2)}ms)`);
16494
16473
  }
16495
16474
  log.info(`Parsing ${STOP_TIMES_FILE}`);
16475
+ const stopTimesStart = performance.now();
16496
16476
  const stopTimesStream = yield zip.stream(STOP_TIMES_FILE);
16497
16477
  const routesAdjacency = yield parseStopTimes(stopTimesStream, parsedStops, trips, validStopIds);
16498
- const stopsAdjacency = buildStopsAdjacencyStructure(validStopIds, routesAdjacency, transfers);
16499
- log.info(`${routesAdjacency.size} valid unique routes.`);
16478
+ const stopsAdjacency = buildStopsAdjacencyStructure(validStopIds, validGtfsRoutes, routesAdjacency, transfers);
16479
+ const stopTimesEnd = performance.now();
16480
+ log.info(`${routesAdjacency.length} valid unique routes. (${(stopTimesEnd - stopTimesStart).toFixed(2)}ms)`);
16500
16481
  log.info(`Removing unused stops.`);
16482
+ const indexStopsStart = performance.now();
16501
16483
  const stops = indexStops(parsedStops, validStopIds);
16502
- log.info(`${stops.size} used stop stops, ${parsedStops.size - stops.size} unused.`);
16484
+ const indexStopsEnd = performance.now();
16485
+ log.info(`${stops.size} used stop stops, ${parsedStops.size - stops.size} unused. (${(indexStopsEnd - indexStopsStart).toFixed(2)}ms)`);
16503
16486
  yield zip.close();
16504
16487
  const timetable = new Timetable(stopsAdjacency, routesAdjacency, validGtfsRoutes);
16505
16488
  log.info(`Building stops index.`);
16489
+ const stopsIndexStart = performance.now();
16506
16490
  const stopsIndex = new StopsIndex(stops);
16491
+ const stopsIndexEnd = performance.now();
16492
+ log.info(`Stops index built. (${(stopsIndexEnd - stopsIndexStart).toFixed(2)}ms)`);
16507
16493
  log.info('Parsing complete.');
16508
16494
  return { timetable, stopsIndex };
16509
16495
  });
@@ -16519,9 +16505,11 @@ class GtfsParser {
16519
16505
  return __awaiter(this, void 0, void 0, function* () {
16520
16506
  const zip = new StreamZip.async({ file: this.path });
16521
16507
  log.info(`Parsing ${STOPS_FILE}`);
16508
+ const stopsStart = performance.now();
16522
16509
  const stopsStream = yield zip.stream(STOPS_FILE);
16523
16510
  const stops = indexStops(yield parseStops(stopsStream, this.profile.platformParser));
16524
- log.info(`${stops.size} parsed stops.`);
16511
+ const stopsEnd = performance.now();
16512
+ log.info(`${stops.size} parsed stops. (${(stopsEnd - stopsStart).toFixed(2)}ms)`);
16525
16513
  yield zip.close();
16526
16514
  return new StopsIndex(stops);
16527
16515
  });