import type { AgencyIndex, AreaIndex, GTFSSource, LoadProgress, RouteIndex, Stop, StopID, Time } from "@gb-transit/gtfs-loader"; import { type PlainJourney } from "./Protocol.js"; export interface ClientLoadOptions { onProgress?: (progress: LoadProgress) => void; /** Plan only for this date, which makes the timetable smaller and the queries faster */ date?: Date; } /** * Plans journeys in a worker, so that loading a feed and scanning it do not block the page. * * The worker keeps the feed and the timetable and only the journeys asked for are sent back. Those * are copies: a leg's trip is not the same object the worker holds, and it carries no Service, so * it cannot be used to ask whether the trip runs on some other date. Ask the worker instead. * * The Worker is constructed by the caller, because resolving a worker's url is a question for * whatever is bundling the application: * * ```js * const worker = new Worker(new URL("raptor-journey-planner/worker", import.meta.url), { type: "module" }); * const planner = new PlannerClient(worker); * ``` */ export declare class PlannerClient { private readonly worker; private readonly pending; private onProgress; private nextId; constructor(worker: Worker); /** * Load a feed, from a url the worker fetches itself or from bytes sent to it. */ load(feed: GTFSSource | { url: string; }, options?: ClientLoadOptions): Promise; /** * Plan between a set of origins and a set of destinations, departing after the given time. */ plan(origins: StopID[], destinations: StopID[], date: Date, time: Time): Promise; /** * The stops of the loaded feed, for naming places in a user interface. */ stops(): Promise; /** * Stop the worker. Anything still waiting on it is rejected rather than left hanging. */ terminate(): void; private send; private receive; } /** * What the worker has, after loading a feed. * * The routes and agencies come with it because a journey's legs do not carry them: a leg names the * route its trip runs on, and these are what turn that id into a route and an operator. They are * few enough - the GB feed has under a hundred routes and 41 agencies - to send whole, once, which * is cheaper than copying an operator's name onto every leg of every journey planned afterwards. * * ```js * const feed = await planner.load({ url }); * const route = feed.routes[leg.trip.routeId]; * const operator = feed.agencies[route.agencyId].name; * ``` * * The areas come with it for a different reason. Nothing in a journey refers to one - an area is a * fares construct and the algorithm has no use for it - but a caller planning between group * stations needs the stops of "London Terminals" to ask about them, and the feed stays inside the * worker. Without this the only way to them is to read the zip a second time: * * ```js * const terminals = feed.areas["1072"].stops; * const journeys = await planner.plan(terminals, ["PLY"], date, time); * ``` */ export interface LoadedFeed { /** Stations the timetable plans between */ stops: number; trips: number; /** Routes of the feed by route id, which is what a leg's trip names */ routes: RouteIndex; /** Agencies of the feed by agency id, which is what a route names */ agencies: AgencyIndex; /** * Areas of the feed by area id - areas.txt and stop_areas.txt read as one thing. * * This is where a group station is: GTFS has no station of stations, so "London Terminals" is an * area holding eighteen stops rather than a parent of them. Empty for a feed with no areas.txt. */ areas: AreaIndex; }