hk-bus-eta 3.7.0 → 3.7.2

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.
@@ -10,8 +10,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.fetchEstJourneyTime = void 0;
13
+ const date_fns_tz_1 = require("date-fns-tz");
13
14
  const __HK_BUS_ETA_JT_CACHE__ = {};
14
15
  function fetchEstJourneyTimeBasedOnHistoricalData({ route, startSeq, endSeq, }) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const requests = [];
18
+ for (let i = startSeq; i < endSeq; ++i) {
19
+ const start = Object.values(route.stops)[0][startSeq];
20
+ const end = Object.values(route.stops)[0][endSeq];
21
+ const day = parseInt((0, date_fns_tz_1.formatInTimeZone)(new Date(), "Asia/Hong_Kong", "i"), 10) - 1;
22
+ const hour = (0, date_fns_tz_1.formatInTimeZone)(new Date(), "Asia/Hong_Kong", "HH");
23
+ requests.push(fetch(`https://raw.githubusercontent.com/HK-Bus-ETA/hk-bus-time-between-stops/refs/heads/pages/times_hourly/${day}/${hour}/${start.slice(0, 2)}.json`)
24
+ .then((r) => r.json())
25
+ .then((r) => {
26
+ if (r[start][end]) {
27
+ return r[start][end];
28
+ }
29
+ throw new Error("not found");
30
+ }));
31
+ }
32
+ return Promise.all(requests).then((seconds) => Math.ceil(seconds.reduce((acc, cur) => acc + cur, 0) / 60));
33
+ });
34
+ }
35
+ function fetchEstJourneyTimeBasedOnHistoricalAvgData({ route, startSeq, endSeq, }) {
15
36
  return __awaiter(this, void 0, void 0, function* () {
16
37
  const requests = [];
17
38
  for (let i = startSeq; i < endSeq; ++i) {
@@ -65,7 +86,7 @@ function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, batchSize = 4,
65
86
  {
66
87
  startSeq: i,
67
88
  endSeq: i + 1,
68
- }
89
+ },
69
90
  ]);
70
91
  if (payloads.length < batchSize && i !== endSeq - 1) {
71
92
  // skip fetching until whole batch filled
@@ -78,8 +99,16 @@ function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, batchSize = 4,
78
99
  return Promise.resolve(__HK_BUS_ETA_JT_CACHE__[key].s);
79
100
  }
80
101
  return fetchEstJourneyTimeBasedOnHistoricalData({
81
- route, startSeq, endSeq
82
- }).catch(() => (fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
102
+ route,
103
+ startSeq,
104
+ endSeq,
105
+ })
106
+ .catch(() => fetchEstJourneyTimeBasedOnHistoricalAvgData({
107
+ route,
108
+ startSeq,
109
+ endSeq,
110
+ }))
111
+ .catch(() => fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
83
112
  method: "POST",
84
113
  headers: {
85
114
  "Content-Type": "application/json",
@@ -95,21 +124,23 @@ function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, batchSize = 4,
95
124
  speedStr !== undefined &&
96
125
  !isNaN(parseInt(speedStr, 10))) {
97
126
  // Set the speed limit as 70 km/h
98
- return (distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60 * 60;
127
+ return ((distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60);
99
128
  }
100
129
  console.warn("Unable to parse TDAS response for more precise journey time. Falling back.");
101
- const [hh, mm] = eta.split(":").map((v) => parseInt(v, 10));
102
- return (hh * 60 + mm) * 60;
130
+ const [hh, mm] = eta
131
+ .split(":")
132
+ .map((v) => parseInt(v, 10));
133
+ return hh * 60 + mm;
103
134
  })
104
135
  .catch(() => {
105
136
  // for any error, assume 4 minutes journey time blindly
106
- return 4 * 60;
137
+ return 4;
107
138
  })
108
139
  .then((s) => {
109
140
  __HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
110
141
  // margin for car accelerating, decelerating, and passenger picking up and dropping off
111
142
  return s * 1.1;
112
- })));
143
+ }));
113
144
  }));
114
145
  seconds.forEach((s) => {
115
146
  ret += s;
@@ -1 +1 @@
1
- {"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,24 @@
1
+ import { formatInTimeZone } from "date-fns-tz";
1
2
  const __HK_BUS_ETA_JT_CACHE__ = {};
2
3
  async function fetchEstJourneyTimeBasedOnHistoricalData({ route, startSeq, endSeq, }) {
4
+ const requests = [];
5
+ for (let i = startSeq; i < endSeq; ++i) {
6
+ const start = Object.values(route.stops)[0][startSeq];
7
+ const end = Object.values(route.stops)[0][endSeq];
8
+ const day = parseInt(formatInTimeZone(new Date(), "Asia/Hong_Kong", "i"), 10) - 1;
9
+ const hour = formatInTimeZone(new Date(), "Asia/Hong_Kong", "HH");
10
+ requests.push(fetch(`https://raw.githubusercontent.com/HK-Bus-ETA/hk-bus-time-between-stops/refs/heads/pages/times_hourly/${day}/${hour}/${start.slice(0, 2)}.json`)
11
+ .then((r) => r.json())
12
+ .then((r) => {
13
+ if (r[start][end]) {
14
+ return r[start][end];
15
+ }
16
+ throw new Error("not found");
17
+ }));
18
+ }
19
+ return Promise.all(requests).then((seconds) => Math.ceil(seconds.reduce((acc, cur) => acc + cur, 0) / 60));
20
+ }
21
+ async function fetchEstJourneyTimeBasedOnHistoricalAvgData({ route, startSeq, endSeq, }) {
3
22
  const requests = [];
4
23
  for (let i = startSeq; i < endSeq; ++i) {
5
24
  const start = Object.values(route.stops)[0][startSeq];
@@ -50,7 +69,7 @@ export async function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, b
50
69
  {
51
70
  startSeq: i,
52
71
  endSeq: i + 1,
53
- }
72
+ },
54
73
  ]);
55
74
  if (payloads.length < batchSize && i !== endSeq - 1) {
56
75
  // skip fetching until whole batch filled
@@ -63,8 +82,16 @@ export async function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, b
63
82
  return Promise.resolve(__HK_BUS_ETA_JT_CACHE__[key].s);
64
83
  }
65
84
  return fetchEstJourneyTimeBasedOnHistoricalData({
66
- route, startSeq, endSeq
67
- }).catch(() => (fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
85
+ route,
86
+ startSeq,
87
+ endSeq,
88
+ })
89
+ .catch(() => fetchEstJourneyTimeBasedOnHistoricalAvgData({
90
+ route,
91
+ startSeq,
92
+ endSeq,
93
+ }))
94
+ .catch(() => fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
68
95
  method: "POST",
69
96
  headers: {
70
97
  "Content-Type": "application/json",
@@ -80,21 +107,23 @@ export async function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, b
80
107
  speedStr !== undefined &&
81
108
  !isNaN(parseInt(speedStr, 10))) {
82
109
  // Set the speed limit as 70 km/h
83
- return (distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60 * 60;
110
+ return ((distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60);
84
111
  }
85
112
  console.warn("Unable to parse TDAS response for more precise journey time. Falling back.");
86
- const [hh, mm] = eta.split(":").map((v) => parseInt(v, 10));
87
- return (hh * 60 + mm) * 60;
113
+ const [hh, mm] = eta
114
+ .split(":")
115
+ .map((v) => parseInt(v, 10));
116
+ return hh * 60 + mm;
88
117
  })
89
118
  .catch(() => {
90
119
  // for any error, assume 4 minutes journey time blindly
91
- return 4 * 60;
120
+ return 4;
92
121
  })
93
122
  .then((s) => {
94
123
  __HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
95
124
  // margin for car accelerating, decelerating, and passenger picking up and dropping off
96
125
  return s * 1.1;
97
- })));
126
+ }));
98
127
  }));
99
128
  seconds.forEach((s) => {
100
129
  ret += s;
@@ -1 +1 @@
1
- {"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hk-bus-eta",
3
- "version": "3.7.0",
3
+ "version": "3.7.2",
4
4
  "description": "Query the ETA (Estimated Time of Arrival) of HK Bus/Minibus/MTR/Lightrail",
5
5
  "main": "dist/index.js",
6
6
  "module": "esm/index.js",
@@ -49,5 +49,9 @@
49
49
  "ts-jest": "^29.1.1",
50
50
  "ts-node": "^10.9.1",
51
51
  "typescript": "^5.2.2"
52
+ },
53
+ "dependencies": {
54
+ "date-fns": "^4.1.0",
55
+ "date-fns-tz": "^3.2.0"
52
56
  }
53
57
  }
@@ -1,4 +1,5 @@
1
1
  import { RouteListEntry, StopList } from "./type";
2
+ import { formatInTimeZone } from "date-fns-tz";
2
3
 
3
4
  type JT_CACHE = Record<
4
5
  string,
@@ -19,8 +20,42 @@ async function fetchEstJourneyTimeBasedOnHistoricalData({
19
20
  startSeq: number;
20
21
  endSeq: number;
21
22
  }): Promise<number> {
22
- const requests = []
23
- for ( let i=startSeq;i<endSeq;++i ) {
23
+ const requests = [];
24
+ for (let i = startSeq; i < endSeq; ++i) {
25
+ const start = Object.values(route.stops)[0][startSeq];
26
+ const end = Object.values(route.stops)[0][endSeq];
27
+ const day =
28
+ parseInt(formatInTimeZone(new Date(), "Asia/Hong_Kong", "i"), 10) - 1;
29
+ const hour = formatInTimeZone(new Date(), "Asia/Hong_Kong", "HH");
30
+ requests.push(
31
+ fetch(
32
+ `https://raw.githubusercontent.com/HK-Bus-ETA/hk-bus-time-between-stops/refs/heads/pages/times_hourly/${day}/${hour}/${start.slice(0, 2)}.json`,
33
+ )
34
+ .then((r) => r.json())
35
+ .then((r) => {
36
+ if (r[start][end]) {
37
+ return r[start][end];
38
+ }
39
+ throw new Error("not found");
40
+ }),
41
+ );
42
+ }
43
+ return Promise.all(requests).then((seconds) =>
44
+ Math.ceil(seconds.reduce((acc, cur) => acc + cur, 0) / 60),
45
+ );
46
+ }
47
+
48
+ async function fetchEstJourneyTimeBasedOnHistoricalAvgData({
49
+ route,
50
+ startSeq,
51
+ endSeq,
52
+ }: {
53
+ route: RouteListEntry;
54
+ startSeq: number;
55
+ endSeq: number;
56
+ }): Promise<number> {
57
+ const requests = [];
58
+ for (let i = startSeq; i < endSeq; ++i) {
24
59
  const start = Object.values(route.stops)[0][startSeq];
25
60
  const end = Object.values(route.stops)[0][endSeq];
26
61
  requests.push(
@@ -32,12 +67,13 @@ async function fetchEstJourneyTimeBasedOnHistoricalData({
32
67
  if (r[start][end]) {
33
68
  return r[start][end];
34
69
  }
35
- throw new Error("not found")
36
- })
37
- )
70
+ throw new Error("not found");
71
+ }),
72
+ );
38
73
  }
39
- return Promise.all(requests).then((seconds) => Math.ceil(seconds.reduce((acc, cur) => acc+cur, 0) / 60))
40
-
74
+ return Promise.all(requests).then((seconds) =>
75
+ Math.ceil(seconds.reduce((acc, cur) => acc + cur, 0) / 60),
76
+ );
41
77
  }
42
78
 
43
79
  /**
@@ -91,15 +127,15 @@ export async function fetchEstJourneyTime({
91
127
  }),
92
128
  {
93
129
  startSeq: i,
94
- endSeq: i+1,
95
- }
130
+ endSeq: i + 1,
131
+ },
96
132
  ]);
97
133
  if (payloads.length < batchSize && i !== endSeq - 1) {
98
134
  // skip fetching until whole batch filled
99
135
  continue;
100
136
  }
101
137
  const seconds = await Promise.all(
102
- payloads.map(([key, payload, {startSeq, endSeq}]) => {
138
+ payloads.map(([key, payload, { startSeq, endSeq }]) => {
103
139
  // load from cache if it is query within 15 minutes
104
140
  if (
105
141
  key in __HK_BUS_ETA_JT_CACHE__ &&
@@ -109,43 +145,57 @@ export async function fetchEstJourneyTime({
109
145
  }
110
146
 
111
147
  return fetchEstJourneyTimeBasedOnHistoricalData({
112
- route, startSeq, endSeq
113
- }).catch(() => (
114
- fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
115
- method: "POST",
116
- headers: {
117
- "Content-Type": "application/json",
118
- },
119
- body: payload,
120
- signal,
121
- })
122
- .then((r) => r.json())
123
- .then(({ eta, distM, jSpeed }) => {
124
- const speedStr = /(\d+)公里\/小時/g.exec(jSpeed)?.[1];
125
- if (
126
- speedStr !== null &&
127
- speedStr !== undefined &&
128
- !isNaN(parseInt(speedStr, 10))
129
- ) {
130
- // Set the speed limit as 70 km/h
131
- return (distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60 * 60;
132
- }
133
- console.warn(
134
- "Unable to parse TDAS response for more precise journey time. Falling back.",
135
- );
136
- const [hh, mm] = eta.split(":").map((v: string) => parseInt(v, 10));
137
- return ( hh * 60 + mm ) * 60;
138
- })
139
- .catch(() => {
140
- // for any error, assume 4 minutes journey time blindly
141
- return 4 * 60;
142
- })
143
- .then((s) => {
144
- __HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
145
- // margin for car accelerating, decelerating, and passenger picking up and dropping off
146
- return s * 1.1;
148
+ route,
149
+ startSeq,
150
+ endSeq,
151
+ })
152
+ .catch(() =>
153
+ fetchEstJourneyTimeBasedOnHistoricalAvgData({
154
+ route,
155
+ startSeq,
156
+ endSeq,
157
+ }),
158
+ )
159
+ .catch(() =>
160
+ fetch("https://tdas-api.hkemobility.gov.hk/tdas/api/route", {
161
+ method: "POST",
162
+ headers: {
163
+ "Content-Type": "application/json",
164
+ },
165
+ body: payload,
166
+ signal,
147
167
  })
148
- ))
168
+ .then((r) => r.json())
169
+ .then(({ eta, distM, jSpeed }) => {
170
+ const speedStr = /(\d+)公里\/小時/g.exec(jSpeed)?.[1];
171
+ if (
172
+ speedStr !== null &&
173
+ speedStr !== undefined &&
174
+ !isNaN(parseInt(speedStr, 10))
175
+ ) {
176
+ // Set the speed limit as 70 km/h
177
+ return (
178
+ (distM / Math.min(parseInt(speedStr, 10), 70) / 1000) * 60
179
+ );
180
+ }
181
+ console.warn(
182
+ "Unable to parse TDAS response for more precise journey time. Falling back.",
183
+ );
184
+ const [hh, mm] = eta
185
+ .split(":")
186
+ .map((v: string) => parseInt(v, 10));
187
+ return hh * 60 + mm;
188
+ })
189
+ .catch(() => {
190
+ // for any error, assume 4 minutes journey time blindly
191
+ return 4;
192
+ })
193
+ .then((s) => {
194
+ __HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
195
+ // margin for car accelerating, decelerating, and passenger picking up and dropping off
196
+ return s * 1.1;
197
+ }),
198
+ );
149
199
  }),
150
200
  );
151
201
  seconds.forEach((s) => {