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