@rise-maritime/keelson-js 0.6.0-pre.14 → 0.6.0-pre.16

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.
Files changed (39) hide show
  1. package/dist/index.d.ts +8 -0
  2. package/dist/interfaces/Route.d.ts +97 -5
  3. package/dist/interfaces/Route.js +166 -3
  4. package/dist/interfaces/RoutePlanner.d.ts +19 -1
  5. package/dist/interfaces/RoutePlanner.js +23 -1
  6. package/dist/interfaces/ScenarioControl.d.ts +132 -3
  7. package/dist/interfaces/ScenarioControl.js +439 -37
  8. package/dist/interfaces/serviceRegistry.d.ts +8 -0
  9. package/dist/payloads/ChecklistEvent.d.ts +178 -0
  10. package/dist/payloads/ChecklistEvent.js +539 -0
  11. package/dist/payloads/ChecklistEvidence.d.ts +79 -0
  12. package/dist/payloads/ChecklistEvidence.js +287 -0
  13. package/dist/payloads/ChecklistHandover.d.ts +522 -0
  14. package/dist/payloads/ChecklistHandover.js +1735 -0
  15. package/dist/payloads/ChecklistPresence.d.ts +68 -0
  16. package/dist/payloads/ChecklistPresence.js +286 -0
  17. package/dist/payloads/ChecklistProcedure.d.ts +81 -0
  18. package/dist/payloads/ChecklistProcedure.js +364 -0
  19. package/dist/payloads/ChecklistState.d.ts +283 -0
  20. package/dist/payloads/ChecklistState.js +1100 -0
  21. package/dist/payloads/EnvelopeExceedance.d.ts +216 -0
  22. package/dist/payloads/EnvelopeExceedance.js +461 -0
  23. package/dist/payloads/Route.d.ts +97 -5
  24. package/dist/payloads/Route.js +166 -3
  25. package/dist/payloads/RouteExecution.d.ts +88 -1
  26. package/dist/payloads/RouteExecution.js +215 -1
  27. package/dist/payloads/ScenarioEvent.d.ts +104 -0
  28. package/dist/payloads/ScenarioEvent.js +310 -0
  29. package/dist/payloads/ScenarioTickAck.d.ts +95 -0
  30. package/dist/payloads/ScenarioTickAck.js +239 -0
  31. package/dist/payloads/index.foxglove.d.ts +1 -1
  32. package/dist/payloads/index.foxglove.js +1 -1
  33. package/dist/payloads/index.google.protobuf.d.ts +1 -1
  34. package/dist/payloads/index.google.protobuf.js +1 -1
  35. package/dist/payloads/index.keelson.d.ts +12 -3
  36. package/dist/payloads/index.keelson.js +12 -3
  37. package/dist/qos.json +18 -1
  38. package/dist/subjects.json +15 -1
  39. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -216,6 +216,14 @@ export declare function getInterfaceDefinition(interfaceAndVersion: string): {
216
216
  readonly name: "ScenarioControl";
217
217
  readonly fullName: "keelson.interfaces.scenario_control.ScenarioControl";
218
218
  readonly methods: {
219
+ readonly list_scenarios: {
220
+ readonly name: "list_scenarios";
221
+ readonly requestType: import("./interfaces/ScenarioControl").MessageFns<import("./interfaces/ScenarioControl").ListScenariosRequest>;
222
+ readonly requestStream: false;
223
+ readonly responseType: import("./interfaces/ScenarioControl").MessageFns<import("./interfaces/ScenarioControl").ListScenariosResponse>;
224
+ readonly responseStream: false;
225
+ readonly options: {};
226
+ };
219
227
  readonly load: {
220
228
  readonly name: "load";
221
229
  readonly requestType: import("./interfaces/ScenarioControl").MessageFns<import("./interfaces/ScenarioControl").LoadRequest>;
@@ -88,6 +88,36 @@ export declare enum GeometryType {
88
88
  }
89
89
  export declare function geometryTypeFromJSON(object: any): GeometryType;
90
90
  export declare function geometryTypeToJSON(object: GeometryType): string;
91
+ /**
92
+ * Whether a route's waypoint list closes back on itself. RTZ 1.2 has no such
93
+ * concept, so producers either repeated the first waypoint (breaking id
94
+ * uniqueness) or left closing to consumer convention (silently wrong the first
95
+ * time a consumer chooses not to loop). This field makes the author say.
96
+ *
97
+ * An enum rather than a bool, like every other classification in this file:
98
+ * OPEN says closure was considered and declined, and there is room for a
99
+ * third topology (out-and-back). UNSPECIFIED MUST be read as OPEN; that is
100
+ * the fail-safe direction, since sailing a point-to-point route as a circuit
101
+ * takes the vessel over unplanned water. Terminal behaviour (stop, hold, go
102
+ * round again) is execution policy and belongs on keelson.Voyage, not here.
103
+ * See protocol-specification.md §6.2.1.
104
+ */
105
+ export declare enum RouteTopology {
106
+ ROUTE_TOPOLOGY_UNSPECIFIED = 0,
107
+ /**
108
+ * ROUTE_TOPOLOGY_OPEN - Runs from the first waypoint to the last and ends there. The last
109
+ * waypoint has no outgoing leg.
110
+ */
111
+ ROUTE_TOPOLOGY_OPEN = 1,
112
+ /**
113
+ * ROUTE_TOPOLOGY_CLOSED - A circuit: the last waypoint's outgoing leg terminates at the first
114
+ * waypoint, which is NOT repeated at the end of the list.
115
+ */
116
+ ROUTE_TOPOLOGY_CLOSED = 2,
117
+ UNRECOGNIZED = -1
118
+ }
119
+ export declare function routeTopologyFromJSON(object: any): RouteTopology;
120
+ export declare function routeTopologyToJSON(object: RouteTopology): string;
91
121
  /**
92
122
  * Lifecycle status for the route artifact (authoring + quality).
93
123
  * Execution-side state (vessel sailing, paused, completed) lives on
@@ -108,6 +138,30 @@ export declare enum RouteStatus {
108
138
  }
109
139
  export declare function routeStatusFromJSON(object: any): RouteStatus;
110
140
  export declare function routeStatusToJSON(object: RouteStatus): string;
141
+ /**
142
+ * Which side of an operational limit counts as a breach.
143
+ *
144
+ * RouteInfo's own limit block carries both directions — max_wind_gust_mps is
145
+ * breached above, min_visibility_m below — so nothing about a limit's identity
146
+ * says which way it fails. Consumers of an exceedance record need it: "the most
147
+ * extreme value reached" is undefined without it, and deriving the direction
148
+ * from a `max_` / `min_` name prefix is a string match that fails silently the
149
+ * first time a limit is named anything else.
150
+ *
151
+ * Lives here rather than beside either consumer because it is a property of the
152
+ * limit as authored, not of the monitoring. Read by keelson.EnvelopeExceedance
153
+ * and keelson.EnvelopeLimitState.
154
+ */
155
+ export declare enum EnvelopeBound {
156
+ ENVELOPE_BOUND_UNSPECIFIED = 0,
157
+ /** ENVELOPE_BOUND_UPPER - Breached by going ABOVE the limit value (max_wind_gust_mps, max_roll_deg). */
158
+ ENVELOPE_BOUND_UPPER = 1,
159
+ /** ENVELOPE_BOUND_LOWER - Breached by going BELOW it (min_visibility_m, min_speed_knots). */
160
+ ENVELOPE_BOUND_LOWER = 2,
161
+ UNRECOGNIZED = -1
162
+ }
163
+ export declare function envelopeBoundFromJSON(object: any): EnvelopeBound;
164
+ export declare function envelopeBoundToJSON(object: EnvelopeBound): string;
111
165
  /** Required action for an ActionPoint. */
112
166
  export declare enum ActionPointRequiredAction {
113
167
  ACTION_POINT_REQUIRED_ACTION_UNSPECIFIED = 0,
@@ -272,6 +326,19 @@ export interface RouteInfo {
272
326
  maxWindSpeedMps?: number | undefined;
273
327
  minSpeedKnots?: number | undefined;
274
328
  maxSpeedKnots?: number | undefined;
329
+ /**
330
+ * Minimum visibility the route is valid above. `visibility_range_m` is
331
+ * published, so without this the measurement exists and the limit it should
332
+ * be checked against does not.
333
+ */
334
+ minVisibilityM?: number | undefined;
335
+ /**
336
+ * Gust limit, distinct from the mean-wind limit above. Gust is what governs
337
+ * small-craft operations: 12 m/s mean with 20 m/s gusts is a different
338
+ * proposition from a steady 12 m/s, and only the mean can be constrained
339
+ * today. Checked against the windowed `true_wind_speed_max_mps`.
340
+ */
341
+ maxWindGustMps?: number | undefined;
275
342
  /**
276
343
  * -- Optimization & autonomy ------------------------------------------------
277
344
  * Free-form optimization method label (e.g. "fuel-min", "eta-min", "weather-routed").
@@ -286,10 +353,18 @@ export interface Waypoints {
286
353
  defaults: DefaultWaypoint | undefined;
287
354
  /** Ordered list of waypoints, in route order. */
288
355
  waypoint: Waypoint[];
356
+ /**
357
+ * Whether the list above closes back on itself. Lives here because it is a
358
+ * statement about this list. Unset reads as ROUTE_TOPOLOGY_OPEN (§6.2.1).
359
+ */
360
+ topology: RouteTopology;
289
361
  extensions: Extensions | undefined;
290
362
  }
291
363
  /**
292
- * Default values for waypoint/leg fields. RTZ-aligned.
364
+ * Default values for waypoint/leg fields. RTZ-aligned — the field set matches
365
+ * RTZ's own defaultWaypoint element, which is a separate question from where
366
+ * leg data hangs: a merged default inherits the departure convention of the
367
+ * field it backs, same as an explicit value (§6.2.1).
293
368
  *
294
369
  * The scalars are `optional` for the same reason as their `Waypoint`
295
370
  * counterparts, one level up: without presence there is no way to say "this
@@ -327,8 +402,9 @@ export interface Waypoint {
327
402
  */
328
403
  position: Coordinate | undefined;
329
404
  /**
330
- * Planned speed over ground when leaving this waypoint. `optional` because
331
- * `Waypoints.defaults` backs this field: without presence, "no override,
405
+ * Planned speed over ground when LEAVING this waypoint, i.e. on `leg`
406
+ * below. RTZ indexes this on the arrival waypoint instead (§6.2.1).
407
+ * `optional` because `Waypoints.defaults` backs this field: without presence, "no override,
332
408
  * use the default" and "hold zero speed here" are the same bytes, and 0.0
333
409
  * is the more dangerous reading of the pair.
334
410
  */
@@ -352,12 +428,23 @@ export interface Waypoint {
352
428
  lock: boolean;
353
429
  /** Operational context for this waypoint (open sea, port approach, lock, ...). */
354
430
  operationalContext: OperationalContext;
355
- /** Outgoing leg from this waypoint to the next. The last waypoint has none. */
431
+ /**
432
+ * Outgoing leg from this waypoint to the next: `waypoint[i].leg` is the edge
433
+ * to `waypoint[i+1]`. In an OPEN route the last waypoint has none and a
434
+ * consumer MUST ignore one if present. In a CLOSED route the last waypoint's
435
+ * leg runs to `waypoint[0]`; that is how a circuit closes, never by
436
+ * repeating the first waypoint. RTZ hangs the leg on the ARRIVAL waypoint,
437
+ * so a converter shifts by one (§6.2.1).
438
+ */
356
439
  leg: Leg | undefined;
357
440
  /** Free-form notes attached to this waypoint. */
358
441
  note: string;
359
442
  extensions: Extensions | undefined;
360
443
  }
444
+ /**
445
+ * Every field here describes the edge LEAVING the waypoint that carries it
446
+ * (see Waypoint.leg and §6.2.1 for the RTZ shift).
447
+ */
361
448
  export interface Leg {
362
449
  /**
363
450
  * Cross-track distance (XTD) limits and monitoring thresholds, in metres.
@@ -452,7 +539,12 @@ export interface ScheduleElement {
452
539
  etdWindowEnd: Date | undefined;
453
540
  /** Planned duration of stay at this waypoint (port, anchorage, ...). */
454
541
  stay: Duration | undefined;
455
- /** -- Environmental forecast for this leg ------------------------------------ */
542
+ /**
543
+ * -- Environmental forecast for this leg ------------------------------------
544
+ * The OUTGOING leg — the one leaving `waypoint_id`, matching `Waypoint.leg`
545
+ * and `planned_sog_knots`. The last waypoint of an OPEN route has no
546
+ * outgoing leg and so no forecast to carry (§6.2.1).
547
+ */
456
548
  windSpeedMps: number;
457
549
  windDirectionDeg: number;
458
550
  currentSpeedMps: number;
@@ -5,8 +5,8 @@
5
5
  // protoc v6.30.2
6
6
  // source: Route.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.RouteIssue = exports.RouteChallenge = exports.HazardZone = exports.ActionPoint = exports.ActionPoints = exports.ScheduleElement = exports.Schedule = exports.Schedules = exports.Leg = exports.Waypoint = exports.DefaultWaypoint = exports.Waypoints = exports.RouteInfo = exports.Route = exports.Extensions_Entry_AttributesEntry = exports.Extensions_Entry = exports.Extensions = exports.CircleGeometry = exports.RouteRef = exports.schedule_OriginToJSON = exports.schedule_OriginFromJSON = exports.Schedule_Origin = exports.actionPointRequiredActionToJSON = exports.actionPointRequiredActionFromJSON = exports.ActionPointRequiredAction = exports.routeStatusToJSON = exports.routeStatusFromJSON = exports.RouteStatus = exports.geometryTypeToJSON = exports.geometryTypeFromJSON = exports.GeometryType = exports.colregTrafficIntensityToJSON = exports.colregTrafficIntensityFromJSON = exports.ColregTrafficIntensity = exports.colregSituationToJSON = exports.colregSituationFromJSON = exports.ColregSituation = exports.hazardZoneTypeToJSON = exports.hazardZoneTypeFromJSON = exports.HazardZoneType = exports.routeChallengeTypeToJSON = exports.routeChallengeTypeFromJSON = exports.RouteChallengeType = exports.operationalContextToJSON = exports.operationalContextFromJSON = exports.OperationalContext = exports.autonomyLevelToJSON = exports.autonomyLevelFromJSON = exports.AutonomyLevel = exports.protobufPackage = void 0;
9
- exports.RouteStatusUpdate = exports.RouteSignature = exports.RouteSignatures = void 0;
8
+ exports.Schedule = exports.Schedules = exports.Leg = exports.Waypoint = exports.DefaultWaypoint = exports.Waypoints = exports.RouteInfo = exports.Route = exports.Extensions_Entry_AttributesEntry = exports.Extensions_Entry = exports.Extensions = exports.CircleGeometry = exports.RouteRef = exports.schedule_OriginToJSON = exports.schedule_OriginFromJSON = exports.Schedule_Origin = exports.actionPointRequiredActionToJSON = exports.actionPointRequiredActionFromJSON = exports.ActionPointRequiredAction = exports.envelopeBoundToJSON = exports.envelopeBoundFromJSON = exports.EnvelopeBound = exports.routeStatusToJSON = exports.routeStatusFromJSON = exports.RouteStatus = exports.routeTopologyToJSON = exports.routeTopologyFromJSON = exports.RouteTopology = exports.geometryTypeToJSON = exports.geometryTypeFromJSON = exports.GeometryType = exports.colregTrafficIntensityToJSON = exports.colregTrafficIntensityFromJSON = exports.ColregTrafficIntensity = exports.colregSituationToJSON = exports.colregSituationFromJSON = exports.ColregSituation = exports.hazardZoneTypeToJSON = exports.hazardZoneTypeFromJSON = exports.HazardZoneType = exports.routeChallengeTypeToJSON = exports.routeChallengeTypeFromJSON = exports.RouteChallengeType = exports.operationalContextToJSON = exports.operationalContextFromJSON = exports.OperationalContext = exports.autonomyLevelToJSON = exports.autonomyLevelFromJSON = exports.AutonomyLevel = exports.protobufPackage = void 0;
9
+ exports.RouteStatusUpdate = exports.RouteSignature = exports.RouteSignatures = exports.RouteIssue = exports.RouteChallenge = exports.HazardZone = exports.ActionPoint = exports.ActionPoints = exports.ScheduleElement = void 0;
10
10
  /* eslint-disable */
11
11
  const wire_1 = require("@bufbuild/protobuf/wire");
12
12
  const Coordinate_1 = require("./Coordinate");
@@ -411,6 +411,67 @@ function geometryTypeToJSON(object) {
411
411
  }
412
412
  }
413
413
  exports.geometryTypeToJSON = geometryTypeToJSON;
414
+ /**
415
+ * Whether a route's waypoint list closes back on itself. RTZ 1.2 has no such
416
+ * concept, so producers either repeated the first waypoint (breaking id
417
+ * uniqueness) or left closing to consumer convention (silently wrong the first
418
+ * time a consumer chooses not to loop). This field makes the author say.
419
+ *
420
+ * An enum rather than a bool, like every other classification in this file:
421
+ * OPEN says closure was considered and declined, and there is room for a
422
+ * third topology (out-and-back). UNSPECIFIED MUST be read as OPEN; that is
423
+ * the fail-safe direction, since sailing a point-to-point route as a circuit
424
+ * takes the vessel over unplanned water. Terminal behaviour (stop, hold, go
425
+ * round again) is execution policy and belongs on keelson.Voyage, not here.
426
+ * See protocol-specification.md §6.2.1.
427
+ */
428
+ var RouteTopology;
429
+ (function (RouteTopology) {
430
+ RouteTopology[RouteTopology["ROUTE_TOPOLOGY_UNSPECIFIED"] = 0] = "ROUTE_TOPOLOGY_UNSPECIFIED";
431
+ /**
432
+ * ROUTE_TOPOLOGY_OPEN - Runs from the first waypoint to the last and ends there. The last
433
+ * waypoint has no outgoing leg.
434
+ */
435
+ RouteTopology[RouteTopology["ROUTE_TOPOLOGY_OPEN"] = 1] = "ROUTE_TOPOLOGY_OPEN";
436
+ /**
437
+ * ROUTE_TOPOLOGY_CLOSED - A circuit: the last waypoint's outgoing leg terminates at the first
438
+ * waypoint, which is NOT repeated at the end of the list.
439
+ */
440
+ RouteTopology[RouteTopology["ROUTE_TOPOLOGY_CLOSED"] = 2] = "ROUTE_TOPOLOGY_CLOSED";
441
+ RouteTopology[RouteTopology["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
442
+ })(RouteTopology || (exports.RouteTopology = RouteTopology = {}));
443
+ function routeTopologyFromJSON(object) {
444
+ switch (object) {
445
+ case 0:
446
+ case "ROUTE_TOPOLOGY_UNSPECIFIED":
447
+ return RouteTopology.ROUTE_TOPOLOGY_UNSPECIFIED;
448
+ case 1:
449
+ case "ROUTE_TOPOLOGY_OPEN":
450
+ return RouteTopology.ROUTE_TOPOLOGY_OPEN;
451
+ case 2:
452
+ case "ROUTE_TOPOLOGY_CLOSED":
453
+ return RouteTopology.ROUTE_TOPOLOGY_CLOSED;
454
+ case -1:
455
+ case "UNRECOGNIZED":
456
+ default:
457
+ return RouteTopology.UNRECOGNIZED;
458
+ }
459
+ }
460
+ exports.routeTopologyFromJSON = routeTopologyFromJSON;
461
+ function routeTopologyToJSON(object) {
462
+ switch (object) {
463
+ case RouteTopology.ROUTE_TOPOLOGY_UNSPECIFIED:
464
+ return "ROUTE_TOPOLOGY_UNSPECIFIED";
465
+ case RouteTopology.ROUTE_TOPOLOGY_OPEN:
466
+ return "ROUTE_TOPOLOGY_OPEN";
467
+ case RouteTopology.ROUTE_TOPOLOGY_CLOSED:
468
+ return "ROUTE_TOPOLOGY_CLOSED";
469
+ case RouteTopology.UNRECOGNIZED:
470
+ default:
471
+ return "UNRECOGNIZED";
472
+ }
473
+ }
474
+ exports.routeTopologyToJSON = routeTopologyToJSON;
414
475
  /**
415
476
  * Lifecycle status for the route artifact (authoring + quality).
416
477
  * Execution-side state (vessel sailing, paused, completed) lives on
@@ -492,6 +553,61 @@ function routeStatusToJSON(object) {
492
553
  }
493
554
  }
494
555
  exports.routeStatusToJSON = routeStatusToJSON;
556
+ /**
557
+ * Which side of an operational limit counts as a breach.
558
+ *
559
+ * RouteInfo's own limit block carries both directions — max_wind_gust_mps is
560
+ * breached above, min_visibility_m below — so nothing about a limit's identity
561
+ * says which way it fails. Consumers of an exceedance record need it: "the most
562
+ * extreme value reached" is undefined without it, and deriving the direction
563
+ * from a `max_` / `min_` name prefix is a string match that fails silently the
564
+ * first time a limit is named anything else.
565
+ *
566
+ * Lives here rather than beside either consumer because it is a property of the
567
+ * limit as authored, not of the monitoring. Read by keelson.EnvelopeExceedance
568
+ * and keelson.EnvelopeLimitState.
569
+ */
570
+ var EnvelopeBound;
571
+ (function (EnvelopeBound) {
572
+ EnvelopeBound[EnvelopeBound["ENVELOPE_BOUND_UNSPECIFIED"] = 0] = "ENVELOPE_BOUND_UNSPECIFIED";
573
+ /** ENVELOPE_BOUND_UPPER - Breached by going ABOVE the limit value (max_wind_gust_mps, max_roll_deg). */
574
+ EnvelopeBound[EnvelopeBound["ENVELOPE_BOUND_UPPER"] = 1] = "ENVELOPE_BOUND_UPPER";
575
+ /** ENVELOPE_BOUND_LOWER - Breached by going BELOW it (min_visibility_m, min_speed_knots). */
576
+ EnvelopeBound[EnvelopeBound["ENVELOPE_BOUND_LOWER"] = 2] = "ENVELOPE_BOUND_LOWER";
577
+ EnvelopeBound[EnvelopeBound["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
578
+ })(EnvelopeBound || (exports.EnvelopeBound = EnvelopeBound = {}));
579
+ function envelopeBoundFromJSON(object) {
580
+ switch (object) {
581
+ case 0:
582
+ case "ENVELOPE_BOUND_UNSPECIFIED":
583
+ return EnvelopeBound.ENVELOPE_BOUND_UNSPECIFIED;
584
+ case 1:
585
+ case "ENVELOPE_BOUND_UPPER":
586
+ return EnvelopeBound.ENVELOPE_BOUND_UPPER;
587
+ case 2:
588
+ case "ENVELOPE_BOUND_LOWER":
589
+ return EnvelopeBound.ENVELOPE_BOUND_LOWER;
590
+ case -1:
591
+ case "UNRECOGNIZED":
592
+ default:
593
+ return EnvelopeBound.UNRECOGNIZED;
594
+ }
595
+ }
596
+ exports.envelopeBoundFromJSON = envelopeBoundFromJSON;
597
+ function envelopeBoundToJSON(object) {
598
+ switch (object) {
599
+ case EnvelopeBound.ENVELOPE_BOUND_UNSPECIFIED:
600
+ return "ENVELOPE_BOUND_UNSPECIFIED";
601
+ case EnvelopeBound.ENVELOPE_BOUND_UPPER:
602
+ return "ENVELOPE_BOUND_UPPER";
603
+ case EnvelopeBound.ENVELOPE_BOUND_LOWER:
604
+ return "ENVELOPE_BOUND_LOWER";
605
+ case EnvelopeBound.UNRECOGNIZED:
606
+ default:
607
+ return "UNRECOGNIZED";
608
+ }
609
+ }
610
+ exports.envelopeBoundToJSON = envelopeBoundToJSON;
495
611
  /** Required action for an ActionPoint. */
496
612
  var ActionPointRequiredAction;
497
613
  (function (ActionPointRequiredAction) {
@@ -1311,6 +1427,8 @@ function createBaseRouteInfo() {
1311
1427
  maxWindSpeedMps: undefined,
1312
1428
  minSpeedKnots: undefined,
1313
1429
  maxSpeedKnots: undefined,
1430
+ minVisibilityM: undefined,
1431
+ maxWindGustMps: undefined,
1314
1432
  optimizationMethod: "",
1315
1433
  autonomyLevel: 0,
1316
1434
  extensions: undefined,
@@ -1360,6 +1478,12 @@ exports.RouteInfo = {
1360
1478
  if (message.maxSpeedKnots !== undefined) {
1361
1479
  writer.uint32(277).float(message.maxSpeedKnots);
1362
1480
  }
1481
+ if (message.minVisibilityM !== undefined) {
1482
+ writer.uint32(285).float(message.minVisibilityM);
1483
+ }
1484
+ if (message.maxWindGustMps !== undefined) {
1485
+ writer.uint32(293).float(message.maxWindGustMps);
1486
+ }
1363
1487
  if (message.optimizationMethod !== "") {
1364
1488
  writer.uint32(402).string(message.optimizationMethod);
1365
1489
  }
@@ -1476,6 +1600,20 @@ exports.RouteInfo = {
1476
1600
  message.maxSpeedKnots = reader.float();
1477
1601
  continue;
1478
1602
  }
1603
+ case 35: {
1604
+ if (tag !== 285) {
1605
+ break;
1606
+ }
1607
+ message.minVisibilityM = reader.float();
1608
+ continue;
1609
+ }
1610
+ case 36: {
1611
+ if (tag !== 293) {
1612
+ break;
1613
+ }
1614
+ message.maxWindGustMps = reader.float();
1615
+ continue;
1616
+ }
1479
1617
  case 50: {
1480
1618
  if (tag !== 402) {
1481
1619
  break;
@@ -1521,6 +1659,8 @@ exports.RouteInfo = {
1521
1659
  maxWindSpeedMps: isSet(object.maxWindSpeedMps) ? globalThis.Number(object.maxWindSpeedMps) : undefined,
1522
1660
  minSpeedKnots: isSet(object.minSpeedKnots) ? globalThis.Number(object.minSpeedKnots) : undefined,
1523
1661
  maxSpeedKnots: isSet(object.maxSpeedKnots) ? globalThis.Number(object.maxSpeedKnots) : undefined,
1662
+ minVisibilityM: isSet(object.minVisibilityM) ? globalThis.Number(object.minVisibilityM) : undefined,
1663
+ maxWindGustMps: isSet(object.maxWindGustMps) ? globalThis.Number(object.maxWindGustMps) : undefined,
1524
1664
  optimizationMethod: isSet(object.optimizationMethod) ? globalThis.String(object.optimizationMethod) : "",
1525
1665
  autonomyLevel: isSet(object.autonomyLevel) ? autonomyLevelFromJSON(object.autonomyLevel) : 0,
1526
1666
  extensions: isSet(object.extensions) ? exports.Extensions.fromJSON(object.extensions) : undefined,
@@ -1570,6 +1710,12 @@ exports.RouteInfo = {
1570
1710
  if (message.maxSpeedKnots !== undefined) {
1571
1711
  obj.maxSpeedKnots = message.maxSpeedKnots;
1572
1712
  }
1713
+ if (message.minVisibilityM !== undefined) {
1714
+ obj.minVisibilityM = message.minVisibilityM;
1715
+ }
1716
+ if (message.maxWindGustMps !== undefined) {
1717
+ obj.maxWindGustMps = message.maxWindGustMps;
1718
+ }
1573
1719
  if (message.optimizationMethod !== "") {
1574
1720
  obj.optimizationMethod = message.optimizationMethod;
1575
1721
  }
@@ -1600,6 +1746,8 @@ exports.RouteInfo = {
1600
1746
  message.maxWindSpeedMps = object.maxWindSpeedMps ?? undefined;
1601
1747
  message.minSpeedKnots = object.minSpeedKnots ?? undefined;
1602
1748
  message.maxSpeedKnots = object.maxSpeedKnots ?? undefined;
1749
+ message.minVisibilityM = object.minVisibilityM ?? undefined;
1750
+ message.maxWindGustMps = object.maxWindGustMps ?? undefined;
1603
1751
  message.optimizationMethod = object.optimizationMethod ?? "";
1604
1752
  message.autonomyLevel = object.autonomyLevel ?? 0;
1605
1753
  message.extensions = (object.extensions !== undefined && object.extensions !== null)
@@ -1609,7 +1757,7 @@ exports.RouteInfo = {
1609
1757
  },
1610
1758
  };
1611
1759
  function createBaseWaypoints() {
1612
- return { defaults: undefined, waypoint: [], extensions: undefined };
1760
+ return { defaults: undefined, waypoint: [], topology: 0, extensions: undefined };
1613
1761
  }
1614
1762
  exports.Waypoints = {
1615
1763
  encode(message, writer = new wire_1.BinaryWriter()) {
@@ -1619,6 +1767,9 @@ exports.Waypoints = {
1619
1767
  for (const v of message.waypoint) {
1620
1768
  exports.Waypoint.encode(v, writer.uint32(18).fork()).join();
1621
1769
  }
1770
+ if (message.topology !== 0) {
1771
+ writer.uint32(24).int32(message.topology);
1772
+ }
1622
1773
  if (message.extensions !== undefined) {
1623
1774
  exports.Extensions.encode(message.extensions, writer.uint32(794).fork()).join();
1624
1775
  }
@@ -1645,6 +1796,13 @@ exports.Waypoints = {
1645
1796
  message.waypoint.push(exports.Waypoint.decode(reader, reader.uint32()));
1646
1797
  continue;
1647
1798
  }
1799
+ case 3: {
1800
+ if (tag !== 24) {
1801
+ break;
1802
+ }
1803
+ message.topology = reader.int32();
1804
+ continue;
1805
+ }
1648
1806
  case 99: {
1649
1807
  if (tag !== 794) {
1650
1808
  break;
@@ -1664,6 +1822,7 @@ exports.Waypoints = {
1664
1822
  return {
1665
1823
  defaults: isSet(object.defaults) ? exports.DefaultWaypoint.fromJSON(object.defaults) : undefined,
1666
1824
  waypoint: globalThis.Array.isArray(object?.waypoint) ? object.waypoint.map((e) => exports.Waypoint.fromJSON(e)) : [],
1825
+ topology: isSet(object.topology) ? routeTopologyFromJSON(object.topology) : 0,
1667
1826
  extensions: isSet(object.extensions) ? exports.Extensions.fromJSON(object.extensions) : undefined,
1668
1827
  };
1669
1828
  },
@@ -1675,6 +1834,9 @@ exports.Waypoints = {
1675
1834
  if (message.waypoint?.length) {
1676
1835
  obj.waypoint = message.waypoint.map((e) => exports.Waypoint.toJSON(e));
1677
1836
  }
1837
+ if (message.topology !== 0) {
1838
+ obj.topology = routeTopologyToJSON(message.topology);
1839
+ }
1678
1840
  if (message.extensions !== undefined) {
1679
1841
  obj.extensions = exports.Extensions.toJSON(message.extensions);
1680
1842
  }
@@ -1689,6 +1851,7 @@ exports.Waypoints = {
1689
1851
  ? exports.DefaultWaypoint.fromPartial(object.defaults)
1690
1852
  : undefined;
1691
1853
  message.waypoint = object.waypoint?.map((e) => exports.Waypoint.fromPartial(e)) || [];
1854
+ message.topology = object.topology ?? 0;
1692
1855
  message.extensions = (object.extensions !== undefined && object.extensions !== null)
1693
1856
  ? exports.Extensions.fromPartial(object.extensions)
1694
1857
  : undefined;
@@ -1,6 +1,6 @@
1
1
  import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
2
2
  import { Coordinate } from "./Coordinate";
3
- import { Extensions, Route, RouteInfo, RouteRef } from "./Route";
3
+ import { Extensions, Route, RouteInfo, RouteRef, RouteTopology } from "./Route";
4
4
  export declare const protobufPackage = "keelson.interfaces.route_planner";
5
5
  /**
6
6
  * What the planner should optimise for. A closed set, not the free-form
@@ -46,6 +46,8 @@ export interface PlanRouteRequest {
46
46
  * `Coordinate`, not `Waypoint` — these are the positions the route must
47
47
  * touch, not planned waypoints with turn radii and speeds. Those are the
48
48
  * planner's output, not its input.
49
+ * Under `topology = CLOSED` this list is the circuit's via-points: the first
50
+ * is both departure and final arrival, and it is NOT repeated at the end.
49
51
  */
50
52
  waypoints: Coordinate[];
51
53
  /**
@@ -64,6 +66,15 @@ export interface PlanRouteRequest {
64
66
  * reply with more.
65
67
  */
66
68
  maxAlternatives: number;
69
+ /**
70
+ * Whether the caller wants a point-to-point route or a circuit. Without it
71
+ * a circuit is unrequestable and the planner's own convention becomes the
72
+ * new implicit rule, one layer up from where it was just removed. Under
73
+ * CLOSED the planner MUST set `Waypoints.topology` on every alternative and
74
+ * close it with a leg on the last waypoint, never by appending a copy of
75
+ * `waypoints[0]`. See protocol-specification.md §6.2.1.
76
+ */
77
+ topology: RouteTopology;
67
78
  /**
68
79
  * Vendor-specific planning inputs — deployment tunings, experimental cost
69
80
  * profiles. Anything that becomes generally useful should graduate to a
@@ -94,6 +105,13 @@ export declare const RoutePlannerDefinition: {
94
105
  * Re-run navigability and validation against a (possibly hand-edited)
95
106
  * route, replying it annotated with `challenges`, `issues` and `status`.
96
107
  * Takes a whole `keelson.Route` because that is genuinely the input.
108
+ *
109
+ * The closure invariants of §6.2.1 are part of what is validated, and a
110
+ * breach is a `RouteIssue`: the last waypoint carries a `leg` if and only if
111
+ * the topology is CLOSED, the first waypoint is not repeated at the end,
112
+ * waypoint ids are unique, and a CLOSED route has at least two waypoints.
113
+ * Exactly two is legal but coincident out-and-back geometry — a
114
+ * `RouteChallenge`, not an error.
97
115
  */
98
116
  readonly validate_route: {
99
117
  readonly name: "validate_route";
@@ -87,7 +87,7 @@ function optimizationGoalToJSON(object) {
87
87
  }
88
88
  exports.optimizationGoalToJSON = optimizationGoalToJSON;
89
89
  function createBasePlanRouteRequest() {
90
- return { waypoints: [], constraints: undefined, goal: 0, maxAlternatives: 0, extensions: undefined };
90
+ return { waypoints: [], constraints: undefined, goal: 0, maxAlternatives: 0, topology: 0, extensions: undefined };
91
91
  }
92
92
  exports.PlanRouteRequest = {
93
93
  encode(message, writer = new wire_1.BinaryWriter()) {
@@ -103,6 +103,9 @@ exports.PlanRouteRequest = {
103
103
  if (message.maxAlternatives !== 0) {
104
104
  writer.uint32(32).uint32(message.maxAlternatives);
105
105
  }
106
+ if (message.topology !== 0) {
107
+ writer.uint32(40).int32(message.topology);
108
+ }
106
109
  if (message.extensions !== undefined) {
107
110
  Route_1.Extensions.encode(message.extensions, writer.uint32(794).fork()).join();
108
111
  }
@@ -143,6 +146,13 @@ exports.PlanRouteRequest = {
143
146
  message.maxAlternatives = reader.uint32();
144
147
  continue;
145
148
  }
149
+ case 5: {
150
+ if (tag !== 40) {
151
+ break;
152
+ }
153
+ message.topology = reader.int32();
154
+ continue;
155
+ }
146
156
  case 99: {
147
157
  if (tag !== 794) {
148
158
  break;
@@ -166,6 +176,7 @@ exports.PlanRouteRequest = {
166
176
  constraints: isSet(object.constraints) ? Route_1.RouteInfo.fromJSON(object.constraints) : undefined,
167
177
  goal: isSet(object.goal) ? optimizationGoalFromJSON(object.goal) : 0,
168
178
  maxAlternatives: isSet(object.maxAlternatives) ? globalThis.Number(object.maxAlternatives) : 0,
179
+ topology: isSet(object.topology) ? (0, Route_1.routeTopologyFromJSON)(object.topology) : 0,
169
180
  extensions: isSet(object.extensions) ? Route_1.Extensions.fromJSON(object.extensions) : undefined,
170
181
  };
171
182
  },
@@ -183,6 +194,9 @@ exports.PlanRouteRequest = {
183
194
  if (message.maxAlternatives !== 0) {
184
195
  obj.maxAlternatives = Math.round(message.maxAlternatives);
185
196
  }
197
+ if (message.topology !== 0) {
198
+ obj.topology = (0, Route_1.routeTopologyToJSON)(message.topology);
199
+ }
186
200
  if (message.extensions !== undefined) {
187
201
  obj.extensions = Route_1.Extensions.toJSON(message.extensions);
188
202
  }
@@ -199,6 +213,7 @@ exports.PlanRouteRequest = {
199
213
  : undefined;
200
214
  message.goal = object.goal ?? 0;
201
215
  message.maxAlternatives = object.maxAlternatives ?? 0;
216
+ message.topology = object.topology ?? 0;
202
217
  message.extensions = (object.extensions !== undefined && object.extensions !== null)
203
218
  ? Route_1.Extensions.fromPartial(object.extensions)
204
219
  : undefined;
@@ -226,6 +241,13 @@ exports.RoutePlannerDefinition = {
226
241
  * Re-run navigability and validation against a (possibly hand-edited)
227
242
  * route, replying it annotated with `challenges`, `issues` and `status`.
228
243
  * Takes a whole `keelson.Route` because that is genuinely the input.
244
+ *
245
+ * The closure invariants of §6.2.1 are part of what is validated, and a
246
+ * breach is a `RouteIssue`: the last waypoint carries a `leg` if and only if
247
+ * the topology is CLOSED, the first waypoint is not repeated at the end,
248
+ * waypoint ids are unique, and a CLOSED route has at least two waypoints.
249
+ * Exactly two is legal but coincident out-and-back geometry — a
250
+ * `RouteChallenge`, not an error.
229
251
  */
230
252
  validate_route: {
231
253
  name: "validate_route",