mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-22 22:59:35 +02:00
refactor enrichStations, only load on first request
This commit is contained in:
parent
6ff406ea79
commit
71d1a4f1a9
6 changed files with 66 additions and 56 deletions
33
index.js
33
index.js
|
@ -45,15 +45,23 @@ const loadEnrichedStationData = (profile) => new Promise((resolve, reject) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const applyEnrichedStationData = async (ctx, shouldLoadEnrichedStationData) => {
|
||||||
|
const {profile, common} = ctx;
|
||||||
|
if (shouldLoadEnrichedStationData && !common.locations) {
|
||||||
|
const locations = await loadEnrichedStationData(profile);
|
||||||
|
common.locations = locations;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const createClient = (profile, userAgent, opt = {}) => {
|
const createClient = (profile, userAgent, opt = {}) => {
|
||||||
profile = Object.assign({}, defaultProfile, profile);
|
profile = Object.assign({}, defaultProfile, profile);
|
||||||
validateProfile(profile);
|
validateProfile(profile);
|
||||||
const common = {};
|
const common = {};
|
||||||
if (opt.enrichStations !== false) {
|
let shouldLoadEnrichedStationData = false;
|
||||||
loadEnrichedStationData(profile)
|
if (typeof opt.enrichStations === 'function') {
|
||||||
.then(locations => {
|
profile.enrichStation = opt.enrichStations;
|
||||||
common.locations = locations;
|
} else if (opt.enrichStations !== false) {
|
||||||
});
|
shouldLoadEnrichedStationData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('string' !== typeof userAgent) {
|
if ('string' !== typeof userAgent) {
|
||||||
|
@ -64,6 +72,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const _stationBoard = async (station, type, resultsField, parse, opt = {}) => {
|
const _stationBoard = async (station, type, resultsField, parse, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
if (isObj(station) && station.id) {
|
if (isObj(station) && station.id) {
|
||||||
station = station.id;
|
station = station.id;
|
||||||
} else if ('string' !== typeof station) {
|
} else if ('string' !== typeof station) {
|
||||||
|
@ -129,6 +138,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const journeys = async (from, to, opt = {}) => {
|
const journeys = async (from, to, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
if ('earlierThan' in opt && 'laterThan' in opt) {
|
if ('earlierThan' in opt && 'laterThan' in opt) {
|
||||||
throw new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.');
|
throw new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.');
|
||||||
}
|
}
|
||||||
|
@ -211,6 +221,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshJourney = async (refreshToken, opt = {}) => {
|
const refreshJourney = async (refreshToken, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
if ('string' !== typeof refreshToken || !refreshToken) {
|
if ('string' !== typeof refreshToken || !refreshToken) {
|
||||||
throw new TypeError('refreshToken must be a non-empty string.');
|
throw new TypeError('refreshToken must be a non-empty string.');
|
||||||
}
|
}
|
||||||
|
@ -237,6 +249,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const locations = async (query, opt = {}) => {
|
const locations = async (query, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
if (!isNonEmptyString(query)) {
|
if (!isNonEmptyString(query)) {
|
||||||
throw new TypeError('query must be a non-empty string.');
|
throw new TypeError('query must be a non-empty string.');
|
||||||
}
|
}
|
||||||
|
@ -263,6 +277,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const stop = async (stop, opt = {}) => {
|
const stop = async (stop, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
if (isObj(stop) && stop.id) {
|
if (isObj(stop) && stop.id) {
|
||||||
stop = stop.id;
|
stop = stop.id;
|
||||||
} else if ('string' !== typeof stop) {
|
} else if ('string' !== typeof stop) {
|
||||||
|
@ -284,6 +300,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const nearby = async (location, opt = {}) => {
|
const nearby = async (location, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
validateLocation(location, 'location');
|
validateLocation(location, 'location');
|
||||||
|
|
||||||
opt = Object.assign({
|
opt = Object.assign({
|
||||||
|
@ -314,6 +332,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const trip = async (id, opt = {}) => {
|
const trip = async (id, opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
if (!isNonEmptyString(id)) {
|
if (!isNonEmptyString(id)) {
|
||||||
throw new TypeError('id must be a non-empty string.');
|
throw new TypeError('id must be a non-empty string.');
|
||||||
}
|
}
|
||||||
|
@ -341,6 +361,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
|
|
||||||
// todo [breaking]: rename to trips()?
|
// todo [breaking]: rename to trips()?
|
||||||
const tripsByName = async (_lineNameOrFahrtNr = '*', _opt = {}) => {
|
const tripsByName = async (_lineNameOrFahrtNr = '*', _opt = {}) => {
|
||||||
|
await applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);
|
||||||
|
|
||||||
throw new Error('not implemented');
|
throw new Error('not implemented');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -367,4 +389,5 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createClient,
|
createClient,
|
||||||
|
loadEnrichedStationData,
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {parseTrip} from '../parse/trip.js';
|
||||||
import {parseJourneyLeg} from '../parse/journey-leg.js';
|
import {parseJourneyLeg} from '../parse/journey-leg.js';
|
||||||
import {parseJourney} from '../parse/journey.js';
|
import {parseJourney} from '../parse/journey.js';
|
||||||
import {parseLine} from '../parse/line.js';
|
import {parseLine} from '../parse/line.js';
|
||||||
import {parseLocation} from '../parse/location.js';
|
import {parseLocation, enrichStation} from '../parse/location.js';
|
||||||
import {parsePolyline} from '../parse/polyline.js';
|
import {parsePolyline} from '../parse/polyline.js';
|
||||||
import {parseOperator} from '../parse/operator.js';
|
import {parseOperator} from '../parse/operator.js';
|
||||||
import {parseRemarks, parseCancelled} from '../parse/remarks.js';
|
import {parseRemarks, parseCancelled} from '../parse/remarks.js';
|
||||||
|
@ -82,6 +82,7 @@ const defaultProfile = {
|
||||||
parseLine,
|
parseLine,
|
||||||
parseStationName: id,
|
parseStationName: id,
|
||||||
parseLocation,
|
parseLocation,
|
||||||
|
enrichStation,
|
||||||
parsePolyline,
|
parsePolyline,
|
||||||
parseOperator,
|
parseOperator,
|
||||||
parseRemarks,
|
parseRemarks,
|
||||||
|
|
|
@ -14,7 +14,7 @@ const parseLocation = (ctx, l) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const lid = parse(l.id || l.locationId, {delimiter: '@'});
|
const lid = parse(l.id || l.locationId, {delimiter: '@'});
|
||||||
const res = {
|
let res = {
|
||||||
type: 'location',
|
type: 'location',
|
||||||
id: (l.extId || l.evaNr || lid.L || l.evaNumber || l.evaNo || l.bahnhofsId || '').replace(leadingZeros, '') || null,
|
id: (l.extId || l.evaNr || lid.L || l.evaNumber || l.evaNo || l.bahnhofsId || '').replace(leadingZeros, '') || null,
|
||||||
};
|
};
|
||||||
|
@ -46,13 +46,7 @@ const parseLocation = (ctx, l) => {
|
||||||
stop.products = profile.parseProducts(ctx, l.products);
|
stop.products = profile.parseProducts(ctx, l.products);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common && common.locations && common.locations[stop.id]) {
|
stop = profile.enrichStation(ctx, stop);
|
||||||
delete stop.type;
|
|
||||||
stop = {
|
|
||||||
...common.locations[stop.id],
|
|
||||||
...stop,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO isMeta
|
// TODO isMeta
|
||||||
// TODO entrances, lines
|
// TODO entrances, lines
|
||||||
|
@ -70,6 +64,8 @@ const parseLocation = (ctx, l) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
res.name = name;
|
res.name = name;
|
||||||
|
res = enrichStation(ctx, res);
|
||||||
|
|
||||||
if (l.type === ADDRESS || lid.A == '2') {
|
if (l.type === ADDRESS || lid.A == '2') {
|
||||||
res.address = name;
|
res.address = name;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +76,22 @@ const parseLocation = (ctx, l) => {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const enrichStation = (ctx, stop, locations) => {
|
||||||
|
const {common} = ctx;
|
||||||
|
const locs = locations || common?.locations;
|
||||||
|
const rich = locs && (locs[stop.id] || locs[stop.name]);
|
||||||
|
if (rich) {
|
||||||
|
delete stop.type;
|
||||||
|
delete stop.id;
|
||||||
|
stop = {
|
||||||
|
...rich,
|
||||||
|
...stop,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return stop;
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
parseLocation,
|
parseLocation,
|
||||||
|
enrichStation,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {profile as rawProfile} from '../p/dbweb/index.js';
|
||||||
const res = require('./fixtures/dbweb-departures.json');
|
const res = require('./fixtures/dbweb-departures.json');
|
||||||
import {dbwebDepartures as expected} from './fixtures/dbweb-departures.js';
|
import {dbwebDepartures as expected} from './fixtures/dbweb-departures.js';
|
||||||
|
|
||||||
const client = createClient(rawProfile, 'public-transport/hafas-client:test', {enrichStations: true});
|
const client = createClient(rawProfile, 'public-transport/hafas-client:test', {enrichStations: false});
|
||||||
const {profile} = client;
|
const {profile} = client;
|
||||||
|
|
||||||
const opt = {
|
const opt = {
|
||||||
|
|
|
@ -395,19 +395,10 @@ tap.test('trip details', async (t) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('departures at Berlin Schwedter Str.', async (t) => {
|
tap.test('departures at Berlin Schwedter Str.', async (t) => {
|
||||||
const res = await new Promise((resolve) => {
|
|
||||||
let interval = setInterval(async () => { // repeat evaluating `departures()` until stations are enriched
|
|
||||||
const res = await client.departures(blnSchwedterStr, {
|
const res = await client.departures(blnSchwedterStr, {
|
||||||
duration: 5, when,
|
duration: 5, when,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.departures[0].stop.name !== undefined) { // ctx.common.locations have loaded
|
|
||||||
clearInterval(interval);
|
|
||||||
return resolve(res);
|
|
||||||
}
|
|
||||||
}, 4000);
|
|
||||||
});
|
|
||||||
|
|
||||||
await testDepartures({
|
await testDepartures({
|
||||||
test: t,
|
test: t,
|
||||||
res,
|
res,
|
||||||
|
@ -418,8 +409,6 @@ tap.test('departures at Berlin Schwedter Str.', async (t) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('departures with station object', async (t) => {
|
tap.test('departures with station object', async (t) => {
|
||||||
const res = await new Promise((resolve) => {
|
|
||||||
let interval = setInterval(async () => { // repeat evaluating `departures()` until stations are enriched
|
|
||||||
const res = await client.departures({
|
const res = await client.departures({
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: jungfernheide,
|
id: jungfernheide,
|
||||||
|
@ -431,31 +420,15 @@ tap.test('departures with station object', async (t) => {
|
||||||
},
|
},
|
||||||
}, {when});
|
}, {when});
|
||||||
|
|
||||||
if (res.departures[0].stop.name !== undefined) { // ctx.common.locations have loaded
|
|
||||||
clearInterval(interval);
|
|
||||||
return resolve(res);
|
|
||||||
}
|
|
||||||
}, 4000);
|
|
||||||
});
|
|
||||||
|
|
||||||
validate(t, res, 'departuresResponse', 'res');
|
validate(t, res, 'departuresResponse', 'res');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('arrivals at Berlin Schwedter Str.', async (t) => {
|
tap.test('arrivals at Berlin Schwedter Str.', async (t) => {
|
||||||
const res = await new Promise((resolve) => {
|
|
||||||
let interval = setInterval(async () => { // repeat evaluating `arrivals()` until stations are enriched
|
|
||||||
const res = await client.arrivals(blnSchwedterStr, {
|
const res = await client.arrivals(blnSchwedterStr, {
|
||||||
duration: 5, when,
|
duration: 5, when,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.arrivals[0].stop.name !== undefined) { // ctx.common.locations have loaded
|
|
||||||
clearInterval(interval);
|
|
||||||
return resolve(res);
|
|
||||||
}
|
|
||||||
}, 4000);
|
|
||||||
});
|
|
||||||
|
|
||||||
await testArrivals({
|
await testArrivals({
|
||||||
test: t,
|
test: t,
|
||||||
res,
|
res,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {parseProducts} from '../../parse/products.js';
|
||||||
|
|
||||||
const profile = {
|
const profile = {
|
||||||
parseLocation: parse,
|
parseLocation: parse,
|
||||||
|
enrichStation: (ctx, stop) => stop,
|
||||||
parseStationName: (_, name) => name.toLowerCase(),
|
parseStationName: (_, name) => name.toLowerCase(),
|
||||||
parseProducts,
|
parseProducts,
|
||||||
products: [{
|
products: [{
|
||||||
|
|
Loading…
Add table
Reference in a new issue