hk-bus-eta 3.3.2 → 3.3.3

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/esm/hkkf.js CHANGED
@@ -1,29 +1,50 @@
1
- import { isSafari } from "./utils";
2
- export default function fetchEtas({ route, bound, seq }) {
3
- if (seq === 0)
1
+ import { getUpcomingFerry } from "./utils";
2
+ export default function fetchEtas({ freq, seq, holidays, serviceDayMap, }) {
3
+ if (seq >= 1)
4
4
  return Promise.resolve([]);
5
- return fetch(`https://www.hkkfeta.com/opendata/eta/${route.slice(2)}/${bound === "I" ? "inbound" : "outbound"}`, {
5
+ const now = new Date();
6
+ return Promise.resolve(getUpcomingFerry({ holidays, serviceDayMap, freq, date: new Date() })
7
+ .filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000)
8
+ .map(eta => ({
9
+ eta: eta,
10
+ remark: {
11
+ zh: "預定班次",
12
+ en: "Scheduled",
13
+ },
14
+ dest: {
15
+ zh: "",
16
+ en: "",
17
+ },
18
+ co: "fortuneferry",
19
+ })));
20
+ /*
21
+ * the official API is broken most of the time, keep it for reference
22
+ return fetch(
23
+ `https://www.hkkfeta.com/opendata/eta/${route.slice(2)}/${bound === "I" ? "inbound" : "outbound"}`,
24
+ {
6
25
  cache: isSafari ? "default" : "no-store",
7
- })
8
- .then((response) => response.json())
9
- .then(({ data }) => {
10
- if (!data)
11
- return [];
26
+ },
27
+ )
28
+ .then((response) => response.json())
29
+ .then(({ data }) => {
30
+ if (!data) return [];
31
+
12
32
  return data
13
- .map(({ ETA }) => {
33
+ .map(({ETA}: any) => {
14
34
  return {
15
- eta: ETA,
16
- remark: {
17
- zh: "",
18
- en: "",
19
- },
20
- dest: {
21
- zh: "",
22
- en: "",
23
- },
24
- co: "hkkf",
25
- };
26
- });
27
- });
35
+ eta: ETA,
36
+ remark: {
37
+ zh: "",
38
+ en: "",
39
+ },
40
+ dest: {
41
+ zh: "",
42
+ en: "",
43
+ },
44
+ co: "hkkf",
45
+ }
46
+ });
47
+ });
48
+ */
28
49
  }
29
50
  //# sourceMappingURL=hkkf.js.map
package/esm/hkkf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hkkf.js","sourceRoot":"","sources":["../src/hkkf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQnC,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,KAAK,EAAE,KAAK,EAAE,GAAG,EACF;IACf,IAAK,GAAG,KAAK,CAAC;QAAG,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3C,OAAO,KAAK,CACV,wCAAwC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,EAClG;QACE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;KACzC,CACF;SACE,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SACnC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAErB,OAAO,IAAI;aACR,GAAG,CAAC,CAAC,EAAC,GAAG,EAAM,EAAE,EAAE;YAClB,OAAO;gBACL,GAAG,EAAE,GAAG;gBACR,MAAM,EAAE;oBACN,EAAE,EAAE,EAAE;oBACN,EAAE,EAAE,EAAE;iBACP;gBACD,IAAI,EAAE;oBACJ,EAAE,EAAE,EAAE;oBACN,EAAE,EAAE,EAAE;iBACP;gBACD,EAAE,EAAE,MAAM;aACX,CAAA;QACH,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"hkkf.js","sourceRoot":"","sources":["../src/hkkf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAY,MAAM,SAAS,CAAC;AASrD,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,GACnB;IACf,IAAK,GAAG,IAAI,CAAC;QAAG,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,OAAO,OAAO,CAAC,OAAO,CACpB,gBAAgB,CAAC,EAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAC,CAAC;SAChE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,CAAE;SACvE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACX,GAAG,EAAE,GAAG;QACN,MAAM,EAAE;YACN,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,WAAW;SAChB;QACD,IAAI,EAAE;YACJ,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,EAAE;SACP;QACD,EAAE,EAAE,cAAc;KACrB,CAAC,CAAC,CACN,CAAA;IACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4BI;AACN,CAAC"}
package/esm/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { RouteListEntry, EtaDb, Eta, StopList } from "./type";
2
2
  interface fetchEtasProps extends RouteListEntry {
3
3
  stopList: StopList;
4
+ holidays: EtaDb["holidays"];
5
+ serviceDayMap: EtaDb["serviceDayMap"];
4
6
  language: "zh" | "en";
5
7
  seq: number;
6
8
  }
7
- export declare function fetchEtas({ route, stops, bound, dest, seq, serviceType, co, nlbId, gtfsId, stopList, language, }: fetchEtasProps): Promise<Eta[]>;
9
+ export declare function fetchEtas({ route, stops, bound, dest, freq, seq, serviceType, co, nlbId, gtfsId, stopList, language, holidays, serviceDayMap, }: fetchEtasProps): Promise<Eta[]>;
8
10
  export declare function fetchEtaDb(): Promise<EtaDb>;
9
11
  export declare function fetchEtaDbMd5(): Promise<string>;
10
12
  export type * from "./type";
package/esm/index.js CHANGED
@@ -8,7 +8,7 @@ import mtr from "./mtr";
8
8
  import sunferry from "./sunferry";
9
9
  import fortuneferry from "./fortuneferry";
10
10
  import hkkf from "./hkkf";
11
- export async function fetchEtas({ route, stops, bound, dest, seq, serviceType, co, nlbId, gtfsId, stopList, language, }) {
11
+ export async function fetchEtas({ route, stops, bound, dest, freq, seq, serviceType, co, nlbId, gtfsId, stopList, language, holidays, serviceDayMap, }) {
12
12
  try {
13
13
  let _etas = [];
14
14
  for (const company_id of co) {
@@ -48,14 +48,14 @@ export async function fetchEtas({ route, stops, bound, dest, seq, serviceType, c
48
48
  }
49
49
  else if (company_id === "fortuneferry" && stops.fortuneferry) {
50
50
  _etas = _etas.concat(await fortuneferry({
51
- route, stops, seq, stopList
51
+ stops, seq, stopList, freq, serviceDayMap, holidays,
52
52
  }));
53
53
  }
54
54
  else if (company_id === "sunferry" && stops.sunferry) {
55
- _etas = _etas.concat(await sunferry({ route, seq }));
55
+ _etas = _etas.concat(await sunferry({ route, seq, holidays, serviceDayMap, freq }));
56
56
  }
57
57
  else if (company_id === "hkkf" && stops.hkkf) {
58
- _etas = _etas.concat(await hkkf({ route, bound: bound.hkkf, seq }));
58
+ _etas = _etas.concat(await hkkf({ freq, seq, holidays, serviceDayMap }));
59
59
  }
60
60
  }
61
61
  return _etas.sort((a, b) => {
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/esm/sunferry.d.ts CHANGED
@@ -1,7 +1,10 @@
1
- import type { Eta } from "./type";
1
+ import type { Eta, EtaDb, RouteListEntry } from "./type";
2
2
  interface fetchEtasProps {
3
+ freq: RouteListEntry["freq"];
3
4
  route: string;
4
5
  seq: number;
6
+ holidays: EtaDb["holidays"];
7
+ serviceDayMap: EtaDb["serviceDayMap"];
5
8
  }
6
- export default function fetchEtas({ route, seq }: fetchEtasProps): Promise<Eta[]>;
9
+ export default function fetchEtas({ route, seq, freq, holidays, serviceDayMap, }: fetchEtasProps): Promise<Eta[]>;
7
10
  export {};
package/esm/sunferry.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isSafari } from "./utils";
2
- export default function fetchEtas({ route, seq }) {
1
+ import { getUpcomingFerry, isSafari } from "./utils";
2
+ export default function fetchEtas({ route, seq, freq, holidays, serviceDayMap, }) {
3
3
  if (seq === 1)
4
4
  return Promise.resolve([]);
5
5
  return fetch(`https://www.sunferry.com.hk/eta/?route=${route}`, {
@@ -7,6 +7,7 @@ export default function fetchEtas({ route, seq }) {
7
7
  })
8
8
  .then((response) => response.json())
9
9
  .then(({ data }) => {
10
+ throw new Error("");
10
11
  if (!data)
11
12
  return [];
12
13
  return data
@@ -30,6 +31,24 @@ export default function fetchEtas({ route, seq }) {
30
31
  co: "sunferry",
31
32
  };
32
33
  });
34
+ })
35
+ .catch(() => {
36
+ // the API gives CORS error, the below handling is for browser
37
+ const now = new Date();
38
+ return getUpcomingFerry({ holidays, serviceDayMap, freq, date: new Date() })
39
+ .filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000)
40
+ .map(eta => ({
41
+ eta: eta,
42
+ remark: {
43
+ zh: "預定班次",
44
+ en: "Scheduled",
45
+ },
46
+ dest: {
47
+ zh: "",
48
+ en: "",
49
+ },
50
+ co: "sunferry",
51
+ }));
33
52
  });
34
53
  }
35
54
  //# sourceMappingURL=sunferry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sunferry.js","sourceRoot":"","sources":["../src/sunferry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAOnC,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,KAAK,EAAE,GAAG,EACK;IACf,IAAK,GAAG,KAAK,CAAC;QAAG,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3C,OAAO,KAAK,CACV,0CAA0C,KAAK,EAAE,EACjD;QACE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;KACzC,CACF;SACE,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SACnC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAErB,OAAO,IAAI;aACR,GAAG,CAAC,CAAC,EAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAM,EAAE,EAAE;YAC9D,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,GAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,WAAW,CAAA;YACpI,IAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,EAAG;gBAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;gBAChC,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,GAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,WAAW,CAAA;aACjI;YACD,OAAO;gBACL,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE;oBACN,EAAE,EAAE,MAAM;oBACV,EAAE,EAAE,MAAM;iBACX;gBACD,IAAI,EAAE;oBACJ,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC5B,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBAC7B;gBACD,EAAE,EAAE,UAAU;aACf,CAAA;QACH,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"sunferry.js","sourceRoot":"","sources":["../src/sunferry.ts"],"names":[],"mappings":"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"}
package/esm/type.d.ts CHANGED
@@ -49,13 +49,13 @@ export type EtaDb = {
49
49
  stopList: StopList;
50
50
  stopMap: StopMap;
51
51
  serviceDayMap: Record<string, [
52
- 0 | 1,
53
- 0 | 1,
54
- 0 | 1,
55
- 0 | 1,
56
- 0 | 1,
57
- 0 | 1,
58
- 0 | 1
52
+ "0" | "1",
53
+ "0" | "1",
54
+ "0" | "1",
55
+ "0" | "1",
56
+ "0" | "1",
57
+ "0" | "1",
58
+ "0" | "1"
59
59
  ]>;
60
60
  };
61
61
  export type Eta = {
@@ -70,5 +70,5 @@ export type Eta = {
70
70
  };
71
71
  co: Company;
72
72
  lat?: number;
73
- lng: number;
73
+ lng?: number;
74
74
  };
package/esm/utils.d.ts CHANGED
@@ -1 +1,8 @@
1
+ import { EtaDb, RouteListEntry } from "./type";
1
2
  export declare const isSafari: boolean;
3
+ export declare const getUpcomingFerry: ({ holidays, serviceDayMap, date, freq, }: {
4
+ holidays: string[];
5
+ serviceDayMap: EtaDb["serviceDayMap"];
6
+ freq: RouteListEntry["freq"];
7
+ date: Date;
8
+ }) => string[];
package/esm/utils.js CHANGED
@@ -10,4 +10,49 @@ export const isSafari = (() => {
10
10
  return false;
11
11
  }
12
12
  })();
13
+ // fancy handling for timezone, not recommend to use it unless you know what's going on
14
+ // i.e, calling isHoliday(holidays, new Date()) is checking if it was being a holiday at the moment of 8 hours ago
15
+ const isHoliday = (holidays, utcDate) => {
16
+ if (utcDate.getDay() === 0)
17
+ return true;
18
+ return holidays.includes(String(utcDate.getUTCFullYear()) +
19
+ String(utcDate.getUTCMonth() + 1).padStart(2, "0") +
20
+ String(utcDate.getUTCDate()).padStart(2, "0"));
21
+ };
22
+ export const getUpcomingFerry = ({ holidays, serviceDayMap, date, freq, }) => {
23
+ if (freq === null) {
24
+ return [];
25
+ }
26
+ const getEta = (serviceFreq, date) => (Object.keys(serviceFreq).sort((a, b) => a < b ? -1 : 1).reduce((acc, tp) => {
27
+ const ferryTime = new Date(date.getTime());
28
+ ferryTime.setUTCHours(parseInt(tp.slice(0, 2), 10));
29
+ ferryTime.setUTCMinutes(parseInt(tp.slice(2), 10));
30
+ if (ferryTime >= date) {
31
+ acc.push(String(ferryTime.getUTCFullYear()) + "-" +
32
+ String(ferryTime.getUTCMonth() + 1).padStart(2, "0") + "-" +
33
+ String(ferryTime.getUTCDate()).padStart(2, "0") + "T" +
34
+ String(ferryTime.getUTCHours()).padStart(2, "0") + ":" +
35
+ String(ferryTime.getUTCMinutes()).padStart(2, "0") + ":00" +
36
+ ".000+08:00");
37
+ }
38
+ return acc;
39
+ }, []));
40
+ // obtain all ETAs sampling for next 24 hours, fancy handling for timezone
41
+ const ret = Array(24).fill(0).reduce((acc, _, idx) => {
42
+ const refDate = new Date(date.getTime());
43
+ refDate.setUTCHours(refDate.getUTCHours() + 8 + idx);
44
+ for (let serviceKey in freq) {
45
+ if (isHoliday(holidays, refDate)) {
46
+ if (serviceDayMap[serviceKey][0] === '1') {
47
+ return acc.concat(getEta(freq[serviceKey], refDate));
48
+ }
49
+ }
50
+ else if (serviceDayMap[serviceKey][refDate.getDay()]) {
51
+ return acc.concat(getEta(freq[serviceKey], refDate)).sort();
52
+ }
53
+ }
54
+ return acc;
55
+ }, []);
56
+ return [...new Set(ret)].sort((a, b) => a < b ? -1 : 1);
57
+ };
13
58
  //# sourceMappingURL=utils.js.map
package/esm/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE;IAC5B,IAAI;QACF,OAAO,OAAO,CACZ,SAAS;YACP,SAAS,CAAC,SAAS;YACnB,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YACvC,CAAC,CACC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACvC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC1C,CACJ,CAAC;KACH;IAAC,WAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.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.3.2",
3
+ "version": "3.3.3",
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",
@@ -16,8 +16,7 @@
16
16
  "build:esm": "tsc --target es2018 --outDir esm",
17
17
  "build:cjs": "tsc --target es2015 --module commonjs --outDir dist",
18
18
  "build": "yarn build:cjs && yarn build:esm",
19
- "prepublish": "yarn build",
20
- "publish": "npm publish"
19
+ "prepublish": "yarn build"
21
20
  },
22
21
  "repository": {
23
22
  "type": "git",
@@ -1,13 +1,15 @@
1
- import type { Eta, RouteListEntry, StopList } from "./type";
2
- import { isSafari } from "./utils";
1
+ import type { Eta, EtaDb, RouteListEntry, StopList } from "./type";
2
+ import { getUpcomingFerry, isSafari } from "./utils";
3
3
 
4
4
  interface fetchEtasProps {
5
- route: string;
6
5
  stops: {
7
6
  fortuneferry: string[];
8
7
  }
9
8
  seq: number;
10
9
  stopList: StopList;
10
+ freq: RouteListEntry["freq"],
11
+ holidays: EtaDb["holidays"];
12
+ serviceDayMap: EtaDb["serviceDayMap"];
11
13
  }
12
14
 
13
15
  const getCode = (zhName: string) => {
@@ -34,12 +36,33 @@ const getCode = (zhName: string) => {
34
36
  }
35
37
 
36
38
  export default function fetchEtas({
37
- route, stops: { fortuneferry: stops }, seq, stopList
39
+ stops: { fortuneferry: stops }, seq,
40
+ holidays, freq, serviceDayMap
38
41
  }: fetchEtasProps): Promise<Eta[]> {
39
42
  if ( stops.length === seq - 1 ) return Promise.resolve([]);
40
- const u = getCode(stopList[stops[seq]].name.zh)
41
- const v = getCode(stopList[stops[seq+1]].name.zh)
43
+ const now = new Date()
44
+ return Promise.resolve(
45
+ getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
46
+ .filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
47
+ .map(eta => ({
48
+ eta: eta,
49
+ remark: {
50
+ zh: "預定班次",
51
+ en: "Scheduled",
52
+ },
53
+ dest: {
54
+ zh: "",
55
+ en: "",
56
+ },
57
+ co: "fortuneferry",
58
+ }))
59
+ )
60
+
61
+ /*
62
+ * the official API is broken most of the time, keep it for reference
42
63
 
64
+ const v = getCode(stopList[stops[seq+1]].name.zh)
65
+ const u = getCode(stopList[stops[seq]].name.zh)
43
66
  return fetch(
44
67
  `https://www.hongkongwatertaxi.com.hk/eta/?route=${u}${v}`,
45
68
  {
@@ -72,4 +95,5 @@ export default function fetchEtas({
72
95
  }
73
96
  });
74
97
  });
98
+ */
75
99
  }
package/src/hkkf.ts CHANGED
@@ -1,16 +1,36 @@
1
- import type { Eta, RouteListEntry } from "./type";
2
- import { isSafari } from "./utils";
1
+ import type { Eta, EtaDb, RouteListEntry } from "./type";
2
+ import { getUpcomingFerry, isSafari } from "./utils";
3
3
 
4
4
  interface fetchEtasProps {
5
- route: string;
6
- bound: RouteListEntry["bound"]["hkkf"];
5
+ freq: RouteListEntry["freq"];
7
6
  seq: number;
7
+ holidays: EtaDb["holidays"];
8
+ serviceDayMap: EtaDb["serviceDayMap"];
8
9
  }
9
10
 
10
11
  export default function fetchEtas({
11
- route, bound, seq
12
+ freq, seq, holidays, serviceDayMap,
12
13
  }: fetchEtasProps): Promise<Eta[]> {
13
- if ( seq === 0 ) return Promise.resolve([])
14
+ if ( seq >= 1 ) return Promise.resolve([])
15
+ const now = new Date()
16
+ return Promise.resolve(
17
+ getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
18
+ .filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
19
+ .map(eta => ({
20
+ eta: eta,
21
+ remark: {
22
+ zh: "預定班次",
23
+ en: "Scheduled",
24
+ },
25
+ dest: {
26
+ zh: "",
27
+ en: "",
28
+ },
29
+ co: "fortuneferry",
30
+ }))
31
+ )
32
+ /*
33
+ * the official API is broken most of the time, keep it for reference
14
34
  return fetch(
15
35
  `https://www.hkkfeta.com/opendata/eta/${route.slice(2)}/${bound === "I" ? "inbound" : "outbound"}`,
16
36
  {
@@ -37,4 +57,5 @@ export default function fetchEtas({
37
57
  }
38
58
  });
39
59
  });
60
+ */
40
61
  }
package/src/index.ts CHANGED
@@ -12,6 +12,8 @@ import { RouteListEntry, EtaDb, Eta, StopList } from "./type";
12
12
 
13
13
  interface fetchEtasProps extends RouteListEntry {
14
14
  stopList: StopList;
15
+ holidays: EtaDb["holidays"],
16
+ serviceDayMap: EtaDb["serviceDayMap"],
15
17
  language: "zh" | "en";
16
18
  seq: number;
17
19
  }
@@ -21,6 +23,7 @@ export async function fetchEtas({
21
23
  stops,
22
24
  bound,
23
25
  dest,
26
+ freq,
24
27
  seq,
25
28
  serviceType,
26
29
  co,
@@ -28,6 +31,8 @@ export async function fetchEtas({
28
31
  gtfsId,
29
32
  stopList,
30
33
  language,
34
+ holidays,
35
+ serviceDayMap,
31
36
  }: fetchEtasProps): Promise<Eta[]> {
32
37
  try {
33
38
  let _etas: Eta[] = [];
@@ -74,13 +79,13 @@ export async function fetchEtas({
74
79
  } else if (company_id === "fortuneferry" && stops.fortuneferry) {
75
80
  _etas = _etas.concat(
76
81
  await fortuneferry({
77
- route, stops, seq, stopList
82
+ stops, seq, stopList, freq, serviceDayMap, holidays,
78
83
  })
79
84
  )
80
85
  } else if (company_id === "sunferry" && stops.sunferry) {
81
- _etas = _etas.concat(await sunferry({route, seq}))
86
+ _etas = _etas.concat(await sunferry({route, seq, holidays, serviceDayMap, freq}))
82
87
  } else if (company_id === "hkkf" && stops.hkkf) {
83
- _etas = _etas.concat(await hkkf({route, bound: bound.hkkf, seq}))
88
+ _etas = _etas.concat(await hkkf({freq, seq, holidays, serviceDayMap}))
84
89
  }
85
90
  }
86
91
 
package/src/sunferry.ts CHANGED
@@ -1,15 +1,20 @@
1
- import type { Eta } from "./type";
2
- import { isSafari } from "./utils";
1
+ import type { Eta, EtaDb, Freq, RouteListEntry } from "./type";
2
+ import { getUpcomingFerry, isSafari } from "./utils";
3
3
 
4
4
  interface fetchEtasProps {
5
+ freq: RouteListEntry["freq"],
5
6
  route: string;
6
7
  seq: number;
8
+ holidays: EtaDb["holidays"],
9
+ serviceDayMap: EtaDb["serviceDayMap"],
7
10
  }
8
11
 
9
12
  export default function fetchEtas({
10
- route, seq
13
+ route, seq,
14
+ freq, holidays, serviceDayMap,
11
15
  }: fetchEtasProps): Promise<Eta[]> {
12
16
  if ( seq === 1 ) return Promise.resolve([])
17
+
13
18
  return fetch(
14
19
  `https://www.sunferry.com.hk/eta/?route=${route}`,
15
20
  {
@@ -18,8 +23,8 @@ export default function fetchEtas({
18
23
  )
19
24
  .then((response) => response.json())
20
25
  .then(({ data }) => {
26
+ throw new Error("")
21
27
  if (!data) return [];
22
-
23
28
  return data
24
29
  .map(({depart_time, rmk_en, rmk_tc, route_tc, route_en}: any) => {
25
30
  const date = new Date();
@@ -41,5 +46,23 @@ export default function fetchEtas({
41
46
  co: "sunferry",
42
47
  }
43
48
  });
49
+ })
50
+ .catch(() => {
51
+ // the API gives CORS error, the below handling is for browser
52
+ const now = new Date()
53
+ return getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
54
+ .filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
55
+ .map(eta => ({
56
+ eta: eta,
57
+ remark: {
58
+ zh: "預定班次",
59
+ en: "Scheduled",
60
+ },
61
+ dest: {
62
+ zh: "",
63
+ en: "",
64
+ },
65
+ co: "sunferry",
66
+ }))
44
67
  });
45
68
  }
package/src/type.ts CHANGED
@@ -70,7 +70,7 @@ export type EtaDb = {
70
70
  stopMap: StopMap;
71
71
  serviceDayMap: Record<
72
72
  string,
73
- [0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1]
73
+ ["0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1"]
74
74
  >;
75
75
  };
76
76
 
@@ -86,5 +86,5 @@ export type Eta = {
86
86
  };
87
87
  co: Company;
88
88
  lat?: number;
89
- lng: number;
89
+ lng?: number;
90
90
  };
package/src/utils.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { EtaDb, Freq, RouteListEntry } from "./type";
2
+
1
3
  export const isSafari = (() => {
2
4
  try {
3
5
  return Boolean(
@@ -13,3 +15,66 @@ export const isSafari = (() => {
13
15
  return false;
14
16
  }
15
17
  })();
18
+
19
+ // fancy handling for timezone, not recommend to use it unless you know what's going on
20
+ // i.e, calling isHoliday(holidays, new Date()) is checking if it was being a holiday at the moment of 8 hours ago
21
+ const isHoliday = (holidays: string[], utcDate: Date): boolean => {
22
+ if ( utcDate.getDay() === 0 ) return true
23
+ return holidays.includes(
24
+ String(utcDate.getUTCFullYear()) +
25
+ String(utcDate.getUTCMonth()+1).padStart(2, "0") +
26
+ String(utcDate.getUTCDate()).padStart(2, "0")
27
+ );
28
+ }
29
+
30
+ export const getUpcomingFerry = ({
31
+ holidays,
32
+ serviceDayMap,
33
+ date,
34
+ freq,
35
+ }: {
36
+ holidays: string[],
37
+ serviceDayMap: EtaDb["serviceDayMap"],
38
+ freq: RouteListEntry["freq"],
39
+ date: Date
40
+ }): string[] => {
41
+ if ( freq === null ) {
42
+ return [];
43
+ }
44
+
45
+ const getEta = (serviceFreq: Record<string, any>, date: Date): string[] => (
46
+ Object.keys(serviceFreq).sort((a, b) => a < b ? -1 : 1).reduce((acc, tp) => {
47
+ const ferryTime = new Date(date.getTime())
48
+ ferryTime.setUTCHours(parseInt(tp.slice(0, 2), 10))
49
+ ferryTime.setUTCMinutes(parseInt(tp.slice(2), 10))
50
+ if ( ferryTime >= date ) {
51
+ acc.push(
52
+ String(ferryTime.getUTCFullYear()) + "-" +
53
+ String(ferryTime.getUTCMonth()+1).padStart(2, "0") + "-" +
54
+ String(ferryTime.getUTCDate()).padStart(2, "0") + "T" +
55
+ String(ferryTime.getUTCHours()).padStart(2, "0") + ":" +
56
+ String(ferryTime.getUTCMinutes()).padStart(2, "0") + ":00" +
57
+ ".000+08:00"
58
+ )
59
+ }
60
+ return acc
61
+ }, [] as string[])
62
+ )
63
+
64
+ // obtain all ETAs sampling for next 24 hours, fancy handling for timezone
65
+ const ret = Array(24).fill(0).reduce((acc, _, idx) => {
66
+ const refDate = new Date(date.getTime())
67
+ refDate.setUTCHours(refDate.getUTCHours() + 8 + idx)
68
+ for ( let serviceKey in freq ) {
69
+ if ( isHoliday(holidays, refDate) ) {
70
+ if ( serviceDayMap[serviceKey][0] === '1' ) {
71
+ return acc.concat(getEta(freq[serviceKey], refDate))
72
+ }
73
+ } else if ( serviceDayMap[serviceKey][refDate.getDay()] ) {
74
+ return acc.concat(getEta(freq[serviceKey], refDate)).sort()
75
+ }
76
+ }
77
+ return acc
78
+ }, [] as string[]);
79
+ return ([...new Set(ret)] as string[]).sort((a,b) => a < b ? -1 : 1)
80
+ }