hk-bus-eta 3.7.0 → 3.7.1
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.
- package/dist/journeyTime.js +39 -6
- package/dist/journeyTime.js.map +1 -1
- package/esm/journeyTime.js +37 -6
- package/esm/journeyTime.js.map +1 -1
- package/package.json +5 -1
- package/src/journeyTime.ts +98 -46
package/dist/journeyTime.js
CHANGED
|
@@ -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_Koong", "i"), 10) - 1;
|
|
22
|
+
const hour = (0, date_fns_tz_1.formatInTimeZone)(new Date(), "Asia/Hong_Koong", "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,
|
|
82
|
-
|
|
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,10 +124,14 @@ 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) *
|
|
127
|
+
return ((distM / Math.min(parseInt(speedStr, 10), 70) / 1000) *
|
|
128
|
+
60 *
|
|
129
|
+
60);
|
|
99
130
|
}
|
|
100
131
|
console.warn("Unable to parse TDAS response for more precise journey time. Falling back.");
|
|
101
|
-
const [hh, mm] = eta
|
|
132
|
+
const [hh, mm] = eta
|
|
133
|
+
.split(":")
|
|
134
|
+
.map((v) => parseInt(v, 10));
|
|
102
135
|
return (hh * 60 + mm) * 60;
|
|
103
136
|
})
|
|
104
137
|
.catch(() => {
|
|
@@ -109,7 +142,7 @@ function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, batchSize = 4,
|
|
|
109
142
|
__HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
|
|
110
143
|
// margin for car accelerating, decelerating, and passenger picking up and dropping off
|
|
111
144
|
return s * 1.1;
|
|
112
|
-
}))
|
|
145
|
+
}));
|
|
113
146
|
}));
|
|
114
147
|
seconds.forEach((s) => {
|
|
115
148
|
ret += s;
|
package/dist/journeyTime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"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"}
|
package/esm/journeyTime.js
CHANGED
|
@@ -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_Koong", "i"), 10) - 1;
|
|
9
|
+
const hour = formatInTimeZone(new Date(), "Asia/Hong_Koong", "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,
|
|
67
|
-
|
|
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,10 +107,14 @@ 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) *
|
|
110
|
+
return ((distM / Math.min(parseInt(speedStr, 10), 70) / 1000) *
|
|
111
|
+
60 *
|
|
112
|
+
60);
|
|
84
113
|
}
|
|
85
114
|
console.warn("Unable to parse TDAS response for more precise journey time. Falling back.");
|
|
86
|
-
const [hh, mm] = eta
|
|
115
|
+
const [hh, mm] = eta
|
|
116
|
+
.split(":")
|
|
117
|
+
.map((v) => parseInt(v, 10));
|
|
87
118
|
return (hh * 60 + mm) * 60;
|
|
88
119
|
})
|
|
89
120
|
.catch(() => {
|
|
@@ -94,7 +125,7 @@ export async function fetchEstJourneyTime({ route, stopList, startSeq, endSeq, b
|
|
|
94
125
|
__HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
|
|
95
126
|
// margin for car accelerating, decelerating, and passenger picking up and dropping off
|
|
96
127
|
return s * 1.1;
|
|
97
|
-
}))
|
|
128
|
+
}));
|
|
98
129
|
}));
|
|
99
130
|
seconds.forEach((s) => {
|
|
100
131
|
ret += s;
|
package/esm/journeyTime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journeyTime.js","sourceRoot":"","sources":["../src/journeyTime.ts"],"names":[],"mappings":"
|
|
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.
|
|
3
|
+
"version": "3.7.1",
|
|
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
|
}
|
package/src/journeyTime.ts
CHANGED
|
@@ -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 (
|
|
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_Koong", "i"), 10) - 1;
|
|
29
|
+
const hour = formatInTimeZone(new Date(), "Asia/Hong_Koong", "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) =>
|
|
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,59 @@ export async function fetchEstJourneyTime({
|
|
|
109
145
|
}
|
|
110
146
|
|
|
111
147
|
return fetchEstJourneyTimeBasedOnHistoricalData({
|
|
112
|
-
route,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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) *
|
|
179
|
+
60 *
|
|
180
|
+
60
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
console.warn(
|
|
184
|
+
"Unable to parse TDAS response for more precise journey time. Falling back.",
|
|
185
|
+
);
|
|
186
|
+
const [hh, mm] = eta
|
|
187
|
+
.split(":")
|
|
188
|
+
.map((v: string) => parseInt(v, 10));
|
|
189
|
+
return (hh * 60 + mm) * 60;
|
|
190
|
+
})
|
|
191
|
+
.catch(() => {
|
|
192
|
+
// for any error, assume 4 minutes journey time blindly
|
|
193
|
+
return 4 * 60;
|
|
194
|
+
})
|
|
195
|
+
.then((s) => {
|
|
196
|
+
__HK_BUS_ETA_JT_CACHE__[key] = { s: s * 1.1, ts };
|
|
197
|
+
// margin for car accelerating, decelerating, and passenger picking up and dropping off
|
|
198
|
+
return s * 1.1;
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
149
201
|
}),
|
|
150
202
|
);
|
|
151
203
|
seconds.forEach((s) => {
|