minotor 11.2.1 → 11.2.2

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.
@@ -69,7 +69,7 @@ export declare class RangeRaptorState implements IRaptorState {
69
69
  */
70
70
  get destinationBest(): Time;
71
71
  isDestination(stop: StopId): boolean;
72
- /** Updates both the per-run state and the cross-run shared labels. */
72
+ /** Updates the per-run aggregate best when improved, and always considers the cross-run shared label. */
73
73
  updateArrival(stop: StopId, time: Time, round: number): void;
74
74
  /**
75
75
  * initialized round `k` from round `k-1`: τk(p) ← min(τk(p), τk-1(p)).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minotor",
3
- "version": "11.2.1",
3
+ "version": "11.2.2",
4
4
  "description": "A lightweight client-side transit routing library.",
5
5
  "keywords": [
6
6
  "minotor",
@@ -229,6 +229,94 @@ describe('RangeRaptorState', () => {
229
229
  });
230
230
  });
231
231
 
232
+ describe('updateArrival aggregate overwrite behavior', () => {
233
+ it('does not overwrite the current run aggregate with a later arrival from a higher round', () => {
234
+ const state = new RangeRaptorState(
235
+ MAX_ROUNDS,
236
+ NB_STOPS,
237
+ timeFromHM(12, 0),
238
+ );
239
+ const run = RoutingState.fromTestData({
240
+ nbStops: NB_STOPS,
241
+ destinations: [2],
242
+ arrivals: [[2, timeFromHM(8, 30), 1]],
243
+ });
244
+ state.setCurrentRun(run);
245
+
246
+ state.updateArrival(2, timeFromHM(8, 45), 2);
247
+
248
+ assert.deepStrictEqual(run.getArrival(2), {
249
+ arrival: timeFromHM(8, 30),
250
+ legNumber: 1,
251
+ });
252
+ assert.strictEqual(state.roundLabels[2]![2], timeFromHM(8, 45));
253
+ });
254
+
255
+ it('does not overwrite the current run aggregate with an equal-time arrival using more legs', () => {
256
+ const state = new RangeRaptorState(
257
+ MAX_ROUNDS,
258
+ NB_STOPS,
259
+ timeFromHM(12, 0),
260
+ );
261
+ const run = RoutingState.fromTestData({
262
+ nbStops: NB_STOPS,
263
+ destinations: [2],
264
+ arrivals: [[2, timeFromHM(8, 30), 2]],
265
+ });
266
+ state.setCurrentRun(run);
267
+
268
+ state.updateArrival(2, timeFromHM(8, 30), 3);
269
+
270
+ assert.deepStrictEqual(run.getArrival(2), {
271
+ arrival: timeFromHM(8, 30),
272
+ legNumber: 2,
273
+ });
274
+ assert.strictEqual(state.roundLabels[3]![2], timeFromHM(8, 30));
275
+ });
276
+
277
+ it('prefers fewer legs for the current run aggregate when arrival time is equal', () => {
278
+ const state = new RangeRaptorState(
279
+ MAX_ROUNDS,
280
+ NB_STOPS,
281
+ timeFromHM(12, 0),
282
+ );
283
+ const run = RoutingState.fromTestData({
284
+ nbStops: NB_STOPS,
285
+ destinations: [2],
286
+ arrivals: [[2, timeFromHM(8, 30), 3]],
287
+ });
288
+ state.setCurrentRun(run);
289
+
290
+ state.updateArrival(2, timeFromHM(8, 30), 2);
291
+
292
+ assert.deepStrictEqual(run.getArrival(2), {
293
+ arrival: timeFromHM(8, 30),
294
+ legNumber: 2,
295
+ });
296
+ });
297
+
298
+ it('still updates the current run aggregate when the new arrival is earlier', () => {
299
+ const state = new RangeRaptorState(
300
+ MAX_ROUNDS,
301
+ NB_STOPS,
302
+ timeFromHM(12, 0),
303
+ );
304
+ const run = RoutingState.fromTestData({
305
+ nbStops: NB_STOPS,
306
+ destinations: [2],
307
+ arrivals: [[2, timeFromHM(8, 45), 1]],
308
+ });
309
+ state.setCurrentRun(run);
310
+
311
+ state.updateArrival(2, timeFromHM(8, 30), 3);
312
+
313
+ assert.deepStrictEqual(run.getArrival(2), {
314
+ arrival: timeFromHM(8, 30),
315
+ legNumber: 3,
316
+ });
317
+ });
318
+ });
319
+
232
320
  describe('isDestination', () => {
233
321
  it('delegates to the current run', () => {
234
322
  const state = new RangeRaptorState(
@@ -113,9 +113,19 @@ export class RangeRaptorState implements IRaptorState {
113
113
  return this.currentRun.isDestination(stop);
114
114
  }
115
115
 
116
- /** Updates both the per-run state and the cross-run shared labels. */
116
+ /** Updates the per-run aggregate best when improved, and always considers the cross-run shared label. */
117
117
  updateArrival(stop: StopId, time: Time, round: number): void {
118
- this.currentRun.updateArrival(stop, time, round);
118
+ const currentRunArrival = this.currentRun.getArrival(stop);
119
+ const improvesCurrentRunAggregate =
120
+ currentRunArrival === undefined ||
121
+ time < currentRunArrival.arrival ||
122
+ (time === currentRunArrival.arrival &&
123
+ round < currentRunArrival.legNumber);
124
+
125
+ if (improvesCurrentRunAggregate) {
126
+ this.currentRun.updateArrival(stop, time, round);
127
+ }
128
+
119
129
  if (time < this.roundLabels[round]![stop]!) {
120
130
  this.roundLabels[round]![stop] = time;
121
131
  this.changedInRound[round]!.push(stop);