@tiducto/spider-sdk-typescript 0.1.1 → 1.0.0
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/README.md +1 -1
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +19 -0
- package/dist/client.js.map +1 -1
- package/dist/contract/routing/Leg.d.ts +1 -0
- package/dist/contract/routing/Leg.d.ts.map +1 -1
- package/dist/contract/routing/PlanConnectionStreamData.d.ts +5 -0
- package/dist/contract/routing/PlanConnectionStreamData.d.ts.map +1 -0
- package/dist/contract/routing/PlanConnectionStreamData.js +2 -0
- package/dist/contract/routing/PlanConnectionStreamData.js.map +1 -0
- package/dist/contract/routing/PlanConnectionStreamResponse.d.ts +7 -0
- package/dist/contract/routing/PlanConnectionStreamResponse.d.ts.map +1 -0
- package/dist/contract/routing/PlanConnectionStreamResponse.js +2 -0
- package/dist/contract/routing/PlanConnectionStreamResponse.js.map +1 -0
- package/dist/contract/routing/PlanConnectionStreamVariables.d.ts +18 -0
- package/dist/contract/routing/PlanConnectionStreamVariables.d.ts.map +1 -0
- package/dist/contract/routing/PlanConnectionStreamVariables.js +2 -0
- package/dist/contract/routing/PlanConnectionStreamVariables.js.map +1 -0
- package/dist/contract/routing/Route.d.ts +3 -0
- package/dist/contract/routing/Route.d.ts.map +1 -1
- package/dist/contract/routing/Stop.d.ts +2 -0
- package/dist/contract/routing/Stop.d.ts.map +1 -1
- package/dist/contract/routing/StopDeparturesData.d.ts +3 -3
- package/dist/contract/routing/StopDeparturesData.d.ts.map +1 -1
- package/dist/contract/routing/StopDeparturesRoute.d.ts +3 -0
- package/dist/contract/routing/StopDeparturesRoute.d.ts.map +1 -1
- package/dist/contract/routing/StopDeparturesStop.d.ts +1 -5
- package/dist/contract/routing/StopDeparturesStop.d.ts.map +1 -1
- package/dist/contract/routing/StopDeparturesStop2.d.ts +9 -0
- package/dist/contract/routing/StopDeparturesStop2.d.ts.map +1 -0
- package/dist/contract/routing/StopDeparturesStop2.js +2 -0
- package/dist/contract/routing/StopDeparturesStop2.js.map +1 -0
- package/dist/contract/routing/StopDeparturesStoptime.d.ts +14 -0
- package/dist/contract/routing/StopDeparturesStoptime.d.ts.map +1 -0
- package/dist/contract/routing/StopDeparturesStoptime.js +2 -0
- package/dist/contract/routing/StopDeparturesStoptime.js.map +1 -0
- package/dist/contract/routing/StopDeparturesTrip.d.ts +2 -0
- package/dist/contract/routing/StopDeparturesTrip.d.ts.map +1 -1
- package/dist/contract/routing/StopDeparturesVariables.d.ts +2 -2
- package/dist/contract/routing/StopDeparturesVariables.d.ts.map +1 -1
- package/dist/contract/routing/Stoptime.d.ts +4 -3
- package/dist/contract/routing/Stoptime.d.ts.map +1 -1
- package/dist/contract/routing/TripRoute.d.ts +3 -0
- package/dist/contract/routing/TripRoute.d.ts.map +1 -1
- package/dist/contract/routing/TripStop.d.ts +2 -0
- package/dist/contract/routing/TripStop.d.ts.map +1 -1
- package/dist/contract/routing/TripTrip.d.ts +4 -2
- package/dist/contract/routing/TripTrip.d.ts.map +1 -1
- package/dist/contract/routing/index.d.ts +5 -1
- package/dist/contract/routing/index.d.ts.map +1 -1
- package/dist/contract.d.ts +0 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +0 -12
- package/dist/contract.js.map +1 -1
- package/dist/contractVersion.d.ts +1 -1
- package/dist/contractVersion.js +1 -1
- package/dist/enums.d.ts +11 -4
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +43 -24
- package/dist/enums.js.map +1 -1
- package/dist/errors.d.ts +30 -10
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +55 -18
- package/dist/errors.js.map +1 -1
- package/dist/http.d.ts +39 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +78 -32
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/location.d.ts +4 -0
- package/dist/location.d.ts.map +1 -1
- package/dist/location.js +4 -0
- package/dist/location.js.map +1 -1
- package/dist/persistedQueries.d.ts +1 -0
- package/dist/persistedQueries.d.ts.map +1 -1
- package/dist/persistedQueries.js +4 -3
- package/dist/persistedQueries.js.map +1 -1
- package/dist/polling.d.ts +2 -1
- package/dist/polling.d.ts.map +1 -1
- package/dist/polling.js +5 -2
- package/dist/polling.js.map +1 -1
- package/dist/realtime.d.ts +23 -2
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +42 -21
- package/dist/realtime.js.map +1 -1
- package/dist/routing.d.ts +133 -32
- package/dist/routing.d.ts.map +1 -1
- package/dist/routing.js +309 -86
- package/dist/routing.js.map +1 -1
- package/dist/sdk.d.ts +1 -1
- package/dist/sdkVersion.d.ts +1 -1
- package/dist/sdkVersion.js +1 -1
- package/dist/serviceDate.d.ts +6 -0
- package/dist/serviceDate.d.ts.map +1 -0
- package/dist/serviceDate.js +17 -0
- package/dist/serviceDate.js.map +1 -0
- package/dist/stops.d.ts +12 -1
- package/dist/stops.d.ts.map +1 -1
- package/dist/stops.js +15 -6
- package/dist/stops.js.map +1 -1
- package/package.json +1 -1
- package/dist/contract/routing/TripStoptime.d.ts +0 -13
- package/dist/contract/routing/TripStoptime.d.ts.map +0 -1
- package/dist/contract/routing/TripStoptime.js +0 -2
- package/dist/contract/routing/TripStoptime.js.map +0 -1
package/dist/routing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
|
package/dist/routing.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { failure, success } from "./result.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { DecodingError, TransportError, badRequest, httpFailure, toSpiderError } from "./errors.js";
|
|
3
|
+
import { graphqlFailure } from "./http.js";
|
|
4
|
+
import { bikesAllowedFromWire, inputFieldFromWire, realtimeStateFromWire, routingErrorCodeFromWire, transitModeFromWire, wheelchairFromWire, } from "./enums.js";
|
|
4
5
|
import { decodePolyline } from "./polyline.js";
|
|
5
|
-
import {
|
|
6
|
+
import { invalidServiceDate, serviceDateOf } from "./serviceDate.js";
|
|
7
|
+
import { DEPARTURES, PLAN, PLAN_STREAM, TRIP } from "./persistedQueries.js";
|
|
6
8
|
const DEFAULT_SEARCH_WINDOW_MINUTES = 60;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
9
|
+
const DEFAULT_NUMBER_OF_DEPARTURES = 30;
|
|
10
|
+
const MAX_TIME_RANGE_SECONDS = 24 * 60 * 60;
|
|
11
|
+
// Fixed platform limits; the env-set ones (search window, result count, via count) are the server's to check.
|
|
12
|
+
const MIN_STREAM_WINDOW_MINUTES = 120;
|
|
13
|
+
const MAX_VIA_STOP_IDS = 10;
|
|
14
|
+
const MAX_VIA_WAIT_SECONDS = 24 * 60 * 60;
|
|
11
15
|
// The OTP transit modes valid in a modes filter — the public TransitMode union also carries street/leg
|
|
12
16
|
// values (WALK, BICYCLE, CAR, TRANSIT, UNKNOWN) that are not transit modes and must not reach the wire.
|
|
13
17
|
const WIRE_TRANSIT_MODES = new Set([
|
|
@@ -34,8 +38,139 @@ export class SpiderRouting {
|
|
|
34
38
|
searchWindowMinutes: options.searchWindowMinutes ?? DEFAULT_SEARCH_WINDOW_MINUTES,
|
|
35
39
|
wheelchairAccessible: options.wheelchairAccessible ?? false,
|
|
36
40
|
};
|
|
41
|
+
const invalid = invalidVia(request.via);
|
|
42
|
+
if (invalid != null)
|
|
43
|
+
return failure(invalid);
|
|
37
44
|
return this.page(request);
|
|
38
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Streams itineraries over Server-Sent Events as the router sweeps the search window forward, emitting them
|
|
48
|
+
* as they finalize instead of one batched page. Lazy and cancellable: iteration opens the request, and
|
|
49
|
+
* `break`ing out of the `for await` cancels the underlying stream. Each `result` event carries itineraries
|
|
50
|
+
* with realtime delays already on their legs; a terminal `done` event then carries the continuation
|
|
51
|
+
* {@link RoutePageInfo} and any `routingErrors` (or a terminal `failure`). Never throws — transport, HTTP and
|
|
52
|
+
* request errors surface as a `failure` event.
|
|
53
|
+
*
|
|
54
|
+
* `targetResults` (a soft floor the sweep aims to reach) and `maxWindowMinutes` (how far it may search, at
|
|
55
|
+
* least 2 h) are required. This opens a fresh stream; to continue, call {@link planStreamNext} with
|
|
56
|
+
* `done.pageInfo.endCursor` (when `hasNextPage`) or {@link planStreamPrevious} with `done.pageInfo.startCursor`
|
|
57
|
+
* (when `hasPreviousPage`). For a single batched page instead, use {@link plan}.
|
|
58
|
+
*/
|
|
59
|
+
async *planStream(options) {
|
|
60
|
+
yield* this.openPlanStream(options);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Continues a stream forward from a prior `done` event's `endCursor`. Takes the same options as
|
|
64
|
+
* {@link planStream} (so `targetResults` / `maxWindowMinutes` can vary per continuation) plus the raw cursor.
|
|
65
|
+
* Call only when the prior `done.pageInfo.hasNextPage` was true.
|
|
66
|
+
*/
|
|
67
|
+
async *planStreamNext(options, after) {
|
|
68
|
+
yield* this.openPlanStream(options, { after });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Continues a stream backward from a prior `done` event's `startCursor`. Takes the same options as
|
|
72
|
+
* {@link planStream} plus the raw cursor. Call only when the prior `done.pageInfo.hasPreviousPage` was true.
|
|
73
|
+
*/
|
|
74
|
+
async *planStreamPrevious(options, before) {
|
|
75
|
+
yield* this.openPlanStream(options, { before });
|
|
76
|
+
}
|
|
77
|
+
// Builds the SSE request variables from the public options plus an optional raw continuation cursor. Forward
|
|
78
|
+
// paging sets `after`, backward sets `before`; an initial stream sets neither.
|
|
79
|
+
streamVariables(options, cursor) {
|
|
80
|
+
const time = options.arriveBy != null
|
|
81
|
+
? { kind: 'arriveBy', epochMs: toEpochMs(options.arriveBy) }
|
|
82
|
+
: { kind: 'departAt', epochMs: toEpochMs(options.departAt ?? Date.now()) };
|
|
83
|
+
const iso = new Date(time.epochMs).toISOString();
|
|
84
|
+
const via = options.via ?? [];
|
|
85
|
+
return {
|
|
86
|
+
dateTime: time.kind === 'departAt' ? { earliestDeparture: iso } : { latestArrival: iso },
|
|
87
|
+
origin: locationToInput(options.origin),
|
|
88
|
+
destination: locationToInput(options.destination),
|
|
89
|
+
via: via.length > 0 ? via.map(viaToInput) : undefined,
|
|
90
|
+
modes: modesInput(options.allowedTransitModes ?? []),
|
|
91
|
+
preferences: preferencesInput({
|
|
92
|
+
maxTransfers: options.maxTransfers,
|
|
93
|
+
wheelchairAccessible: options.wheelchairAccessible ?? false,
|
|
94
|
+
}),
|
|
95
|
+
targetResults: options.targetResults,
|
|
96
|
+
maxWindow: `PT${Math.floor(options.maxWindowMinutes)}M`,
|
|
97
|
+
before: cursor?.before,
|
|
98
|
+
after: cursor?.after,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Opens the SSE `plan-stream` request and turns its `chunk`/`pageInfo`/`done`/`error` records into a
|
|
102
|
+
// PlanStreamEvent stream. Invalid options, a non-2xx response, a transport error, or a decoding slip becomes a
|
|
103
|
+
// terminal `failure` event rather than a throw. Reading stops when the server closes the stream or the
|
|
104
|
+
// consumer stops iterating (which cancels the reader → aborts the request).
|
|
105
|
+
async *openPlanStream(options, cursor) {
|
|
106
|
+
const invalid = invalidStreamOptions(options);
|
|
107
|
+
if (invalid != null) {
|
|
108
|
+
yield { type: 'failure', error: invalid };
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
let response;
|
|
112
|
+
try {
|
|
113
|
+
response = await this.transport.stream(PLAN_STREAM, this.streamVariables(options, cursor));
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
yield { type: 'failure', error: toSpiderError(e) };
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
yield { type: 'failure', error: toSpiderError(httpFailure('routing plan-stream', response.status, await drainText(response))) };
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const body = response.body;
|
|
124
|
+
if (body == null) {
|
|
125
|
+
yield { type: 'failure', error: toSpiderError(new TransportError('no_data', 'routing plan-stream returned no body')) };
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const reader = body.getReader();
|
|
129
|
+
const decoder = new TextDecoder();
|
|
130
|
+
let buffer = '';
|
|
131
|
+
// The gateway answers some rejections (e.g. a missing required variable) with a 2xx GraphQL JSON body
|
|
132
|
+
// before any event, so a body that opens with `{` is read whole and mapped like a batch response.
|
|
133
|
+
let json = (response.headers.get('content-type') ?? '').includes('json') ? true : undefined;
|
|
134
|
+
try {
|
|
135
|
+
for (;;) {
|
|
136
|
+
const { value, done } = await reader.read();
|
|
137
|
+
if (done)
|
|
138
|
+
break;
|
|
139
|
+
buffer = (buffer + decoder.decode(value, { stream: true })).replace(/\r\n/g, '\n');
|
|
140
|
+
if (json === undefined) {
|
|
141
|
+
const head = buffer.trimStart();
|
|
142
|
+
if (head !== '')
|
|
143
|
+
json = head.startsWith('{');
|
|
144
|
+
}
|
|
145
|
+
if (json !== false)
|
|
146
|
+
continue;
|
|
147
|
+
// SSE records are separated by a blank line; parse every complete one and keep the remainder buffered.
|
|
148
|
+
let boundary;
|
|
149
|
+
while ((boundary = buffer.indexOf('\n\n')) !== -1) {
|
|
150
|
+
const record = parseSseFrame(buffer.slice(0, boundary));
|
|
151
|
+
buffer = buffer.slice(boundary + 2);
|
|
152
|
+
const event = parsePlanStreamRecord(record.event, record.data);
|
|
153
|
+
if (event != null)
|
|
154
|
+
yield event;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (json === true) {
|
|
158
|
+
yield { type: 'failure', error: streamErrorToSpiderError(buffer) };
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// A trailing record the server didn't terminate with a blank line before closing.
|
|
162
|
+
const record = parseSseFrame(buffer);
|
|
163
|
+
const event = parsePlanStreamRecord(record.event, record.data);
|
|
164
|
+
if (event != null)
|
|
165
|
+
yield event;
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
yield { type: 'failure', error: toSpiderError(e) };
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
await reader.cancel().catch(() => { });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
39
174
|
async planNext(route) {
|
|
40
175
|
if (!route.pageInfo.hasNextPage)
|
|
41
176
|
return null;
|
|
@@ -49,66 +184,19 @@ export class SpiderRouting {
|
|
|
49
184
|
return this.page(requestOf(route), route.pageInfo.startCursor ?? undefined, undefined);
|
|
50
185
|
}
|
|
51
186
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* whole window in one search, so a busy window yields more — `targetResults` is a soft floor, the window
|
|
55
|
-
* that reaches it is yielded whole. Lazy: `for await ... break` stops stepping and skips the remaining OTP
|
|
56
|
-
* searches. Each yield is one step's `SpiderResult` (a terminal error ends the stream), matching the
|
|
57
|
-
* non-throwing poll helpers.
|
|
58
|
-
*
|
|
59
|
-
* The step is `searchWindowMinutes` and it is fixed for the whole walk — OTP locks the window into the
|
|
60
|
-
* paging cursor after the first search and ignores it thereafter, so a wider step means a wider
|
|
61
|
-
* `searchWindowMinutes` here, not on a continuation.
|
|
187
|
+
* Upcoming departures from a stop or station: `numberOfDepartures` (default 30, up to the environment's
|
|
188
|
+
* limit) within `options.timeRangeSeconds` (default 24 h) from `options.startTime` (default now).
|
|
62
189
|
*/
|
|
63
|
-
async
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const first = await this.plan(planOptions);
|
|
68
|
-
yield first;
|
|
69
|
-
if (!first.isSuccess)
|
|
70
|
-
return;
|
|
71
|
-
yield* this.stepFrom(first.data, 'forward', steps - 1, target, first.data.edges.length);
|
|
72
|
-
}
|
|
73
|
-
/** Streaming form of `planNext`: steps forward from `prev`, one (fixed) search window per step. */
|
|
74
|
-
async *planNextUntil(prev, options) {
|
|
75
|
-
const steps = stepCount(options?.maxTraversalMinutes ?? DEFAULT_MAX_TRAVERSAL_MINUTES, requestOf(prev).searchWindowMinutes);
|
|
76
|
-
yield* this.stepFrom(prev, 'forward', steps, options?.targetResults ?? DEFAULT_TARGET_RESULTS, 0);
|
|
77
|
-
}
|
|
78
|
-
/** Streaming form of `planPrevious`: steps backward from `prev`, one (fixed) search window per step. */
|
|
79
|
-
async *planPreviousUntil(prev, options) {
|
|
80
|
-
const steps = stepCount(options?.maxTraversalMinutes ?? DEFAULT_MAX_TRAVERSAL_MINUTES, requestOf(prev).searchWindowMinutes);
|
|
81
|
-
yield* this.stepFrom(prev, 'backward', steps, options?.targetResults ?? DEFAULT_TARGET_RESULTS, 0);
|
|
82
|
-
}
|
|
83
|
-
// Step from `start` one search window at a time, accumulating itinerary count. Stop at `targetResults`, when a
|
|
84
|
-
// step has no next page, or on an error. `collectedSoFar` seeds the count (planUntil already yielded step 1).
|
|
85
|
-
async *stepFrom(start, direction, remainingSteps, targetResults, collectedSoFar) {
|
|
86
|
-
if (collectedSoFar >= targetResults)
|
|
87
|
-
return;
|
|
88
|
-
let prev = start;
|
|
89
|
-
let collected = collectedSoFar;
|
|
90
|
-
for (let i = 0; i < Math.max(0, remainingSteps); i++) {
|
|
91
|
-
const res = direction === 'forward'
|
|
92
|
-
? await this.planNext(prev)
|
|
93
|
-
: await this.planPrevious(prev);
|
|
94
|
-
if (res === null)
|
|
95
|
-
return;
|
|
96
|
-
yield res;
|
|
97
|
-
if (!res.isSuccess)
|
|
98
|
-
return;
|
|
99
|
-
collected += res.data.edges.length;
|
|
100
|
-
if (collected >= targetResults)
|
|
101
|
-
return;
|
|
102
|
-
prev = res.data;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
async departures(stopId, numberOfDepartures = 30, options) {
|
|
190
|
+
async departures(stopId, numberOfDepartures = DEFAULT_NUMBER_OF_DEPARTURES, options) {
|
|
191
|
+
const timeRange = Math.floor(options?.timeRangeSeconds ?? MAX_TIME_RANGE_SECONDS);
|
|
192
|
+
if (!(timeRange > 0 && timeRange <= MAX_TIME_RANGE_SECONDS))
|
|
193
|
+
return failure(badRequest('timeRange'));
|
|
106
194
|
try {
|
|
107
195
|
const variables = {
|
|
108
196
|
id: stopId,
|
|
109
197
|
numberOfDepartures,
|
|
110
198
|
startTime: options?.startTime != null ? Math.floor(toEpochMs(options.startTime) / 1000) : undefined,
|
|
111
|
-
timeRange
|
|
199
|
+
timeRange,
|
|
112
200
|
};
|
|
113
201
|
const data = await this.transport.graphql(DEPARTURES, variables);
|
|
114
202
|
const stop = data.asStop ?? data.asStation;
|
|
@@ -118,12 +206,14 @@ export class SpiderRouting {
|
|
|
118
206
|
return success(mapDepartures(stop));
|
|
119
207
|
}
|
|
120
208
|
catch (e) {
|
|
121
|
-
if (e instanceof SpiderContractMismatchError)
|
|
122
|
-
throw e;
|
|
123
209
|
return failure(toSpiderError(e));
|
|
124
210
|
}
|
|
125
211
|
}
|
|
212
|
+
/** One trip on one service date (ISO `YYYY-MM-DD`, e.g. a {@link Departure.serviceDate}); undefined = today. */
|
|
126
213
|
async trip(tripId, serviceDate) {
|
|
214
|
+
const invalid = serviceDate != null ? invalidServiceDate(serviceDate) : null;
|
|
215
|
+
if (invalid != null)
|
|
216
|
+
return failure(invalid);
|
|
127
217
|
try {
|
|
128
218
|
const variables = { id: tripId, serviceDate };
|
|
129
219
|
const data = await this.transport.graphql(TRIP, variables);
|
|
@@ -134,8 +224,6 @@ export class SpiderRouting {
|
|
|
134
224
|
return success(mapTrip(trip));
|
|
135
225
|
}
|
|
136
226
|
catch (e) {
|
|
137
|
-
if (e instanceof SpiderContractMismatchError)
|
|
138
|
-
throw e;
|
|
139
227
|
return failure(toSpiderError(e));
|
|
140
228
|
}
|
|
141
229
|
}
|
|
@@ -144,8 +232,6 @@ export class SpiderRouting {
|
|
|
144
232
|
return success(await this.fetchPlan(request, before, after));
|
|
145
233
|
}
|
|
146
234
|
catch (e) {
|
|
147
|
-
if (e instanceof SpiderContractMismatchError)
|
|
148
|
-
throw e;
|
|
149
235
|
return failure(toSpiderError(e));
|
|
150
236
|
}
|
|
151
237
|
}
|
|
@@ -161,8 +247,7 @@ export class SpiderRouting {
|
|
|
161
247
|
via: request.via.length > 0 ? request.via.map(viaToInput) : undefined,
|
|
162
248
|
modes: modesInput(request.allowedTransitModes),
|
|
163
249
|
preferences: preferencesInput(request),
|
|
164
|
-
|
|
165
|
-
searchWindow: `PT${Math.max(1, Math.floor(request.searchWindowMinutes))}M`,
|
|
250
|
+
searchWindow: `PT${Math.floor(request.searchWindowMinutes)}M`,
|
|
166
251
|
before,
|
|
167
252
|
after,
|
|
168
253
|
};
|
|
@@ -180,11 +265,7 @@ export class SpiderRouting {
|
|
|
180
265
|
hasPreviousPage: plan.pageInfo.hasPreviousPage,
|
|
181
266
|
searchWindowUsed: plan.pageInfo.searchWindowUsed ?? null,
|
|
182
267
|
},
|
|
183
|
-
routingErrors: plan.routingErrors.map(
|
|
184
|
-
code: re.code,
|
|
185
|
-
description: re.description,
|
|
186
|
-
inputField: re.inputField ?? null,
|
|
187
|
-
})),
|
|
268
|
+
routingErrors: plan.routingErrors.map(mapRoutingError),
|
|
188
269
|
searchDateTime: plan.searchDateTime ?? null,
|
|
189
270
|
};
|
|
190
271
|
return Object.assign({}, route, { [ROUTE_REQUEST]: request });
|
|
@@ -196,13 +277,23 @@ function requestOf(route) {
|
|
|
196
277
|
function toEpochMs(value) {
|
|
197
278
|
return typeof value === 'number' ? value : value.getTime();
|
|
198
279
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
280
|
+
function invalidStreamOptions(options) {
|
|
281
|
+
// Required by the type; a plain-JS caller can still omit it, and `PTNaNM` must never reach the wire.
|
|
282
|
+
if (options.maxWindowMinutes == null)
|
|
283
|
+
return badRequest('maxWindow', 'is required');
|
|
284
|
+
if (!(Math.floor(options.maxWindowMinutes) >= MIN_STREAM_WINDOW_MINUTES))
|
|
285
|
+
return badRequest('maxWindow');
|
|
286
|
+
return invalidVia(options.via ?? []);
|
|
201
287
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
288
|
+
function invalidVia(via) {
|
|
289
|
+
for (const v of via) {
|
|
290
|
+
const valid = v.kind === 'passThrough'
|
|
291
|
+
? v.stopIds.length >= 1 && v.stopIds.length <= MAX_VIA_STOP_IDS
|
|
292
|
+
: v.minimumWaitSeconds >= 0 && v.minimumWaitSeconds <= MAX_VIA_WAIT_SECONDS;
|
|
293
|
+
if (!valid)
|
|
294
|
+
return badRequest('via');
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
206
297
|
}
|
|
207
298
|
function locationToInput(location) {
|
|
208
299
|
if (location.kind === 'stop') {
|
|
@@ -230,18 +321,122 @@ function viaToInput(via) {
|
|
|
230
321
|
function modesInput(modes) {
|
|
231
322
|
const transit = modes
|
|
232
323
|
.filter((m) => WIRE_TRANSIT_MODES.has(m))
|
|
233
|
-
.map((mode) => ({ mode }));
|
|
324
|
+
.map((mode) => ({ mode: mode }));
|
|
234
325
|
return transit.length > 0 ? { transit: { transit } } : undefined;
|
|
235
326
|
}
|
|
236
327
|
function preferencesInput(request) {
|
|
328
|
+
// The router indexes legs with leg 0 = the initial access (walk, or nothing), so its wire
|
|
329
|
+
// `maximumTransfers` counts boardings = transfers + 1 (wire 0 = walk-only, not exposed here).
|
|
330
|
+
// `maxTransfers` is a transfer count, so map it to boardings: 0 transfers = 1 boarding (direct).
|
|
237
331
|
const transit = request.maxTransfers != null
|
|
238
|
-
? { transfer: { maximumTransfers: request.maxTransfers } }
|
|
332
|
+
? { transfer: { maximumTransfers: request.maxTransfers + 1 } }
|
|
239
333
|
: undefined;
|
|
240
334
|
const accessibility = request.wheelchairAccessible ? { wheelchair: { enabled: true } } : undefined;
|
|
241
335
|
if (transit === undefined && accessibility === undefined)
|
|
242
336
|
return undefined;
|
|
243
337
|
return { transit, accessibility };
|
|
244
338
|
}
|
|
339
|
+
// ISO-8601 time-only duration (e.g. "PT1M30S", "PT-90S") → seconds, with a plain-integer-seconds fallback;
|
|
340
|
+
// mirrors the batch plan's realtime-delay handling. Returns null for absent or unparseable values.
|
|
341
|
+
function durationSecondsFromWire(raw) {
|
|
342
|
+
if (raw == null)
|
|
343
|
+
return null;
|
|
344
|
+
const iso = /^(-)?PT(?:(-?\d+)H)?(?:(-?\d+)M)?(?:(-?\d+(?:\.\d+)?)S)?$/i.exec(raw);
|
|
345
|
+
if (iso != null && (iso[2] != null || iso[3] != null || iso[4] != null)) {
|
|
346
|
+
const sign = iso[1] === '-' ? -1 : 1;
|
|
347
|
+
return sign * (Number(iso[2] ?? 0) * 3600 + Number(iso[3] ?? 0) * 60 + Number(iso[4] ?? 0));
|
|
348
|
+
}
|
|
349
|
+
const plain = Number(raw);
|
|
350
|
+
return Number.isFinite(plain) ? plain : null;
|
|
351
|
+
}
|
|
352
|
+
const SSE_DEFAULT_EVENT = 'message';
|
|
353
|
+
// Parses one finished SSE record (its event name + accumulated data) into a PlanStreamEvent; returns null for
|
|
354
|
+
// records the SDK doesn't surface (heartbeats, unknown events, the terminal `done` telemetry frame). A
|
|
355
|
+
// malformed payload becomes a terminal `failure` rather than throwing. Exported so the wire-contract test
|
|
356
|
+
// exercises it directly. A `chunk` frame → `result`; the `pageInfo` frame → terminal `done` (carrying the
|
|
357
|
+
// RoutePageInfo and routingErrors); the wire `done` telemetry frame just ends the stream and is dropped.
|
|
358
|
+
export function parsePlanStreamRecord(event, data) {
|
|
359
|
+
if (data.trim() === '')
|
|
360
|
+
return null;
|
|
361
|
+
switch (event) {
|
|
362
|
+
case 'chunk':
|
|
363
|
+
return decodeStreamRecord('chunk', data, (chunk) => ({
|
|
364
|
+
type: 'result',
|
|
365
|
+
itineraries: (chunk.results ?? []).map(mapItinerary),
|
|
366
|
+
}));
|
|
367
|
+
case 'pageInfo':
|
|
368
|
+
return decodeStreamRecord('pageInfo', data, (page) => ({
|
|
369
|
+
type: 'done',
|
|
370
|
+
pageInfo: {
|
|
371
|
+
startCursor: page.startCursor ?? null,
|
|
372
|
+
endCursor: page.endCursor ?? null,
|
|
373
|
+
hasNextPage: page.hasNextPage ?? false,
|
|
374
|
+
hasPreviousPage: page.hasPreviousPage ?? false,
|
|
375
|
+
searchWindowUsed: page.searchWindowUsed ?? null,
|
|
376
|
+
},
|
|
377
|
+
routingErrors: (page.routingErrors ?? []).map(mapRoutingError),
|
|
378
|
+
}));
|
|
379
|
+
case 'error':
|
|
380
|
+
return { type: 'failure', error: streamErrorToSpiderError(data) };
|
|
381
|
+
default:
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function decodeStreamRecord(frame, data, map) {
|
|
386
|
+
try {
|
|
387
|
+
return map(JSON.parse(data));
|
|
388
|
+
}
|
|
389
|
+
catch (e) {
|
|
390
|
+
return { type: 'failure', error: toSpiderError(new DecodingError(`failed to decode plan-stream ${frame}`, e)) };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// Splits one raw SSE record into its event name (default "message") and data (multiple `data:` lines joined
|
|
394
|
+
// with "\n"), per the SSE line format: `field: value`, a leading space after the colon stripped, `:` comments
|
|
395
|
+
// and blank lines ignored.
|
|
396
|
+
function parseSseFrame(record) {
|
|
397
|
+
let event = SSE_DEFAULT_EVENT;
|
|
398
|
+
const data = [];
|
|
399
|
+
for (const line of record.split('\n')) {
|
|
400
|
+
if (line === '' || line.startsWith(':'))
|
|
401
|
+
continue;
|
|
402
|
+
const colon = line.indexOf(':');
|
|
403
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
404
|
+
let value = colon === -1 ? '' : line.slice(colon + 1);
|
|
405
|
+
if (value.startsWith(' '))
|
|
406
|
+
value = value.slice(1);
|
|
407
|
+
if (field === 'event')
|
|
408
|
+
event = value;
|
|
409
|
+
else if (field === 'data')
|
|
410
|
+
data.push(value);
|
|
411
|
+
}
|
|
412
|
+
return { event, data: data.join('\n') };
|
|
413
|
+
}
|
|
414
|
+
// A stream `error` record (or a 2xx JSON body in place of the stream) is the same GraphQL error envelope the
|
|
415
|
+
// batch path returns, so it maps through the same taxonomy: a BAD_REQUEST becomes bad_request with its field.
|
|
416
|
+
function streamErrorToSpiderError(data) {
|
|
417
|
+
let env;
|
|
418
|
+
try {
|
|
419
|
+
env = JSON.parse(data);
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
return toSpiderError(new TransportError('upstream', `routing plan-stream error: ${data.slice(0, 300)}`));
|
|
423
|
+
}
|
|
424
|
+
if (env.errors != null && env.errors.length > 0) {
|
|
425
|
+
return toSpiderError(graphqlFailure('routing plan-stream', env.errors));
|
|
426
|
+
}
|
|
427
|
+
return toSpiderError(new TransportError('upstream', `routing plan-stream error: ${env.message ?? data.slice(0, 300)}`));
|
|
428
|
+
}
|
|
429
|
+
async function drainText(response) {
|
|
430
|
+
try {
|
|
431
|
+
return await response.text();
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
return '';
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function mapRoutingError(re) {
|
|
438
|
+
return { code: routingErrorCodeFromWire(re.code), description: re.description, inputField: inputFieldFromWire(re.inputField) };
|
|
439
|
+
}
|
|
245
440
|
function mapItinerary(node) {
|
|
246
441
|
return {
|
|
247
442
|
start: node.start ?? null,
|
|
@@ -258,10 +453,26 @@ function mapLeg(leg) {
|
|
|
258
453
|
mode: transitModeFromWire(leg.mode),
|
|
259
454
|
startScheduled: leg.start.scheduledTime,
|
|
260
455
|
endScheduled: leg.end.scheduledTime,
|
|
456
|
+
startEstimated: leg.start.estimated?.time ?? null,
|
|
457
|
+
endEstimated: leg.end.estimated?.time ?? null,
|
|
458
|
+
startDelaySeconds: durationSecondsFromWire(leg.start.estimated?.delay),
|
|
459
|
+
endDelaySeconds: durationSecondsFromWire(leg.end.estimated?.delay),
|
|
460
|
+
isRealtime: leg.realTime ?? false,
|
|
461
|
+
realtimeState: realtimeStateFromWire(leg.realtimeState),
|
|
462
|
+
serviceDate: leg.serviceDate ?? null,
|
|
261
463
|
fromName: leg.from.name ?? null,
|
|
262
464
|
toName: leg.to.name ?? null,
|
|
465
|
+
fromGtfsId: leg.from.stop?.gtfsId ?? null,
|
|
466
|
+
toGtfsId: leg.to.stop?.gtfsId ?? null,
|
|
467
|
+
fromPlatformCode: leg.from.stop?.platformCode ?? null,
|
|
468
|
+
toPlatformCode: leg.to.stop?.platformCode ?? null,
|
|
469
|
+
fromZoneId: leg.from.stop?.zoneId ?? null,
|
|
470
|
+
toZoneId: leg.to.stop?.zoneId ?? null,
|
|
471
|
+
routeGtfsId: leg.route?.gtfsId ?? null,
|
|
263
472
|
routeShortName: leg.route?.shortName ?? null,
|
|
264
473
|
routeLongName: leg.route?.longName ?? null,
|
|
474
|
+
routeColor: leg.route?.color ?? null,
|
|
475
|
+
routeTextColor: leg.route?.textColor ?? null,
|
|
265
476
|
headsign: leg.headsign ?? null,
|
|
266
477
|
distanceMeters: leg.distance ?? null,
|
|
267
478
|
durationSeconds: leg.duration ?? null,
|
|
@@ -274,31 +485,36 @@ function mapLeg(leg) {
|
|
|
274
485
|
};
|
|
275
486
|
}
|
|
276
487
|
function mapDepartures(stop) {
|
|
277
|
-
const stopName = stop.name.trim().toLowerCase();
|
|
278
488
|
const out = [];
|
|
279
489
|
for (const st of stop.stoptimesWithoutPatterns ?? []) {
|
|
280
490
|
const serviceDay = st.serviceDay;
|
|
281
491
|
const scheduledOffset = st.scheduledDeparture;
|
|
282
492
|
if (serviceDay == null || scheduledOffset == null)
|
|
283
493
|
continue;
|
|
284
|
-
if (st.headsign != null && st.headsign.trim().toLowerCase() === stopName)
|
|
285
|
-
continue;
|
|
286
494
|
const route = st.trip?.route;
|
|
287
495
|
out.push({
|
|
288
496
|
scheduledTimeEpochMs: (serviceDay + scheduledOffset) * 1000,
|
|
289
497
|
realtimeTimeEpochMs: st.realtimeDeparture != null ? (serviceDay + st.realtimeDeparture) * 1000 : null,
|
|
290
498
|
isRealtime: st.realtime ?? false,
|
|
291
|
-
realtimeState: st.realtimeState
|
|
499
|
+
realtimeState: realtimeStateFromWire(st.realtimeState),
|
|
292
500
|
headsign: st.headsign ?? null,
|
|
293
501
|
tripGtfsId: st.trip?.gtfsId ?? null,
|
|
502
|
+
serviceDate: serviceDateOf(serviceDay),
|
|
503
|
+
routeGtfsId: route?.gtfsId ?? null,
|
|
294
504
|
routeShortName: route?.shortName ?? null,
|
|
295
505
|
routeLongName: route?.longName ?? null,
|
|
506
|
+
routeColor: route?.color ?? null,
|
|
507
|
+
routeTextColor: route?.textColor ?? null,
|
|
296
508
|
mode: transitModeFromWire(route?.mode),
|
|
509
|
+
stopGtfsId: st.stop?.gtfsId ?? null,
|
|
510
|
+
platformCode: st.stop?.platformCode ?? null,
|
|
511
|
+
wheelchairAccessible: wheelchairFromWire(st.trip?.wheelchairAccessible),
|
|
297
512
|
});
|
|
298
513
|
}
|
|
299
514
|
return out;
|
|
300
515
|
}
|
|
301
516
|
function mapTrip(trip) {
|
|
517
|
+
const serviceDay = trip.stoptimesForDate?.find((st) => st.serviceDay != null)?.serviceDay;
|
|
302
518
|
const stops = [];
|
|
303
519
|
for (const st of trip.stoptimesForDate ?? []) {
|
|
304
520
|
const s = st.stop;
|
|
@@ -317,16 +533,23 @@ function mapTrip(trip) {
|
|
|
317
533
|
realtimeDepartureEpochMs: at(st.realtimeDeparture),
|
|
318
534
|
isRealtime: st.realtime ?? false,
|
|
319
535
|
wheelchairBoarding: wheelchairFromWire(s.wheelchairBoarding),
|
|
536
|
+
platformCode: s.platformCode ?? null,
|
|
537
|
+
zoneId: s.zoneId ?? null,
|
|
320
538
|
});
|
|
321
539
|
}
|
|
322
540
|
return {
|
|
323
541
|
gtfsId: trip.gtfsId,
|
|
542
|
+
serviceDate: serviceDay != null ? serviceDateOf(serviceDay) : null,
|
|
543
|
+
routeGtfsId: trip.route.gtfsId ?? null,
|
|
324
544
|
routeShortName: trip.route.shortName ?? null,
|
|
325
545
|
routeLongName: trip.route.longName ?? null,
|
|
546
|
+
routeColor: trip.route.color ?? null,
|
|
547
|
+
routeTextColor: trip.route.textColor ?? null,
|
|
326
548
|
mode: transitModeFromWire(trip.route.mode),
|
|
327
549
|
headsign: trip.tripHeadsign ?? null,
|
|
328
550
|
directionId: trip.directionId ?? null,
|
|
329
551
|
bikesAllowed: bikesAllowedFromWire(trip.bikesAllowed),
|
|
552
|
+
wheelchairAccessible: wheelchairFromWire(trip.wheelchairAccessible),
|
|
330
553
|
stops,
|
|
331
554
|
geometry: trip.tripGeometry?.points ? decodePolyline(trip.tripGeometry.points) : [],
|
|
332
555
|
};
|