@spacemolt/lib 14.0.0 → 14.0.1

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/dist/account.d.ts CHANGED
@@ -380,27 +380,36 @@ export declare class Account {
380
380
  */
381
381
  private checkSubscriptionsAgainstLocation;
382
382
  /**
383
- * Fleet followers do not submit the movement mutation themselves, so their
384
- * arrival is delivered as a plain `ok` push rather than an `action_result`
385
- * carrying a state delta. Bridge the location data present on those pushes
386
- * into the cache. Fleet docking is the one exception: its push only contains
387
- * the station's display name, not the canonical base ID used by `docked_at`,
388
- * so refresh the canonical snapshot instead of caching the wrong identifier.
383
+ * Movement that the state delta does not cover arrives as a plain `ok` push.
384
+ * Bridge its location data into the cache.
385
+ *
386
+ * Two kinds of movement land here. **Transit start** (`travel`/`jump`, and
387
+ * their `fleet_` variants) is never delivered as a delta by design: the
388
+ * server holds one `action_result` back for the arrival so it can settle the
389
+ * mutation on the same `request_id`, and sends this push in the meantime.
390
+ * Everything the departure changed is either on the push or implied by it,
391
+ * so these patch and stop — the one field they cannot carry is `ship.fuel`,
392
+ * which the arrival delta corrects a transit later. **Fleet follower
393
+ * arrival** is the other kind: a follower never submitted the mutation, so
394
+ * on a server that cannot tell their connection speaks v2 there is no delta
395
+ * at all, and only then is a reconcile worth its round trip.
389
396
  *
390
397
  * These pushes carry only the few fields the movement itself changed, so
391
398
  * they go through `patchSection` — unlike a server delta, which always
392
- * carries a complete `location` and is applied with `applyDelta`. Patching
393
- * keeps the rest of the section (system, connections, POI details) intact
394
- * until `reconcileFleetState` refreshes the authoritative snapshot; the
395
- * per-POI fields that the move invalidates are only as stale as that
396
- * round trip.
399
+ * carries a complete `location` and is applied with `applyDelta`.
397
400
  */
398
- private applyFleetMovementPush;
401
+ private applyMovementPush;
399
402
  /**
400
- * Fleet movement pushes omit follower fuel and skill deltas, while docking
401
- * omits the canonical base ID. Reconcile those fields from one authoritative
402
- * snapshot. A newer movement push invalidates an older in-flight query so a
403
- * delayed dock/arrival snapshot cannot move the cache backwards.
403
+ * Refill a fleet follower's location from one authoritative snapshot.
404
+ *
405
+ * An arrival push carries the destination's name and little else, so the
406
+ * system-, POI- and presence-scoped fields it invalidates have nothing to
407
+ * refill them and no formula to derive them. This is the one movement gap a
408
+ * round trip is the only answer to, and only on a server that does not send
409
+ * followers a delta — a current one does, and these branches never run.
410
+ *
411
+ * A newer movement push invalidates an older in-flight query so a delayed
412
+ * snapshot cannot move the cache backwards.
404
413
  */
405
414
  private reconcileFleetState;
406
415
  /** Close the connection deliberately. Suppresses auto-reconnect. */
package/dist/index.js CHANGED
@@ -4189,6 +4189,8 @@ var ARRIVED_IN_NEW_SYSTEM = {
4189
4189
  empire: undefined,
4190
4190
  security_status: undefined
4191
4191
  };
4192
+ var DEPARTED = { ...ARRIVED, poi_id: "", poi_name: "", poi_type: "" };
4193
+ var DEPARTED_SYSTEM = { ...ARRIVED_IN_NEW_SYSTEM, ...DEPARTED, system_id: "", system_name: "" };
4192
4194
  var DEFAULT_URL = "wss://game.spacemolt.com/ws/v2";
4193
4195
  var DEFAULT_CONNECT_TIMEOUT_MS = 15000;
4194
4196
  var DEFAULT_MUTATION_TIMEOUT_MS = 600000;
@@ -4601,25 +4603,26 @@ class Account {
4601
4603
  this.subscribedObservationPoiId = undefined;
4602
4604
  }
4603
4605
  }
4604
- applyFleetMovementPush(frame) {
4606
+ applyMovementPush(frame) {
4605
4607
  if (frame.type !== "ok" || !isRecord(frame.payload) || typeof frame.payload.action !== "string")
4606
4608
  return;
4607
4609
  const payload = frame.payload;
4608
4610
  let changed = [];
4609
4611
  let reconcile = false;
4610
4612
  switch (payload.action) {
4613
+ case "jump":
4611
4614
  case "fleet_jump": {
4612
4615
  if (typeof payload.destination !== "string" || typeof payload.arrival_tick !== "number") {
4613
4616
  this.warnMalformedFrame(frame);
4614
4617
  return;
4615
4618
  }
4616
4619
  changed = this.cache.patchSection("location", {
4620
+ ...DEPARTED_SYSTEM,
4617
4621
  in_transit: true,
4618
4622
  transit_arrival_tick: payload.arrival_tick,
4619
4623
  transit_dest_system_id: payload.destination,
4620
4624
  transit_type: "jump"
4621
4625
  });
4622
- reconcile = true;
4623
4626
  break;
4624
4627
  }
4625
4628
  case "jumped":
@@ -4637,18 +4640,19 @@ class Account {
4637
4640
  reconcile = true;
4638
4641
  break;
4639
4642
  }
4643
+ case "travel":
4640
4644
  case "fleet_travel": {
4641
4645
  if (typeof payload.destination !== "string" || typeof payload.arrival_tick !== "number") {
4642
4646
  this.warnMalformedFrame(frame);
4643
4647
  return;
4644
4648
  }
4645
4649
  changed = this.cache.patchSection("location", {
4650
+ ...DEPARTED,
4646
4651
  in_transit: true,
4647
4652
  transit_arrival_tick: payload.arrival_tick,
4648
4653
  transit_dest_poi_id: payload.destination,
4649
4654
  transit_type: "travel"
4650
4655
  });
4651
- reconcile = true;
4652
4656
  break;
4653
4657
  }
4654
4658
  case "arrived": {
@@ -4668,7 +4672,11 @@ class Account {
4668
4672
  changed = this.cache.patchSection("location", { docked_at: null });
4669
4673
  break;
4670
4674
  case "fleet_dock":
4671
- reconcile = true;
4675
+ if (typeof payload.base_id === "string") {
4676
+ changed = this.cache.patchSection("location", { docked_at: payload.base_id });
4677
+ } else {
4678
+ reconcile = true;
4679
+ }
4672
4680
  break;
4673
4681
  default:
4674
4682
  return;
@@ -4824,7 +4832,9 @@ class Account {
4824
4832
  this.emitStateChange(changed);
4825
4833
  }
4826
4834
  if (!this.correlator.handle(frame)) {
4827
- console.warn(`[spacemolt] action_result for ${frame.request_id ?? "?"} arrived with no matching pending mutation (already timed out?)`);
4835
+ if (frame.request_id) {
4836
+ console.warn(`[spacemolt] action_result for ${frame.request_id} arrived with no matching pending mutation (already timed out?)`);
4837
+ }
4828
4838
  this.emitter.emit(frame);
4829
4839
  }
4830
4840
  return;
@@ -4852,7 +4862,7 @@ class Account {
4852
4862
  return;
4853
4863
  }
4854
4864
  default:
4855
- this.applyFleetMovementPush(frame);
4865
+ this.applyMovementPush(frame);
4856
4866
  this.emitter.emit(frame);
4857
4867
  }
4858
4868
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spacemolt/lib",
3
- "version": "14.0.0",
3
+ "version": "14.0.1",
4
4
  "description": "The definitive TypeScript library for SpaceMolt. WebSocket-v2-first, multi-account, with local state caches. Internals are regenerated from the server's OpenAPI spec.",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",