githolon 0.110.0 → 0.110.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.
@@ -12175,6 +12175,15 @@ var ReplicaFollowController = class {
12175
12175
  }
12176
12176
  if (result.stillAhead || result.pushFailed || result.directOfferDeferred || result.reconnectRequired) {
12177
12177
  if (result.directOfferDeferred) {
12178
+ if (!result.reconnectRequired) {
12179
+ this.#desk.transition(result.workspace, {
12180
+ case: ReplicaFollowEventKind.Failed,
12181
+ nowUnixMillis,
12182
+ failure: "remote workspace opening; retrying",
12183
+ retryWithinMillis: 5e3
12184
+ });
12185
+ return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
12186
+ }
12178
12187
  this.#desk.transition(result.workspace, {
12179
12188
  case: ReplicaFollowEventKind.DependencyDeferred,
12180
12189
  nowUnixMillis,
@@ -14076,6 +14085,34 @@ function resolveCustodyDisagreement(kernel, mount, requestId, policy, verdict) {
14076
14085
  import { create as create58, fromBinary as fromBinary23, toBinary as toBinary22 } from "@bufbuild/protobuf";
14077
14086
  var CUSTODY_OFFER_MEDIA_TYPE = "application/vnd.nomos.custody-offer-batch+protobuf";
14078
14087
  var CUSTODY_OFFER_RESULT_MEDIA_TYPE = "application/vnd.nomos.custody-offer-result+protobuf";
14088
+ function settleCustodyOfferExchange(awaiting, response) {
14089
+ if (response.status === 202 && response.contentType?.includes("application/json")) {
14090
+ try {
14091
+ const pending = JSON.parse(new TextDecoder().decode(response.body));
14092
+ if (pending?.retryable === true && typeof pending.preparing === "string") {
14093
+ return { case: "maintenance", kind: pending.preparing };
14094
+ }
14095
+ } catch {
14096
+ }
14097
+ }
14098
+ if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
14099
+ return {
14100
+ case: "unexpected",
14101
+ status: response.status,
14102
+ ...response.contentType === void 0 ? {} : { contentType: response.contentType }
14103
+ };
14104
+ }
14105
+ const verdict = decodeCustodyOffer(response.body, awaiting.requestId);
14106
+ const receipt = custodyOfferReceipt(awaiting.requestId, verdict);
14107
+ switch (verdict.case) {
14108
+ case "admission":
14109
+ return { case: "admission", value: verdict.value, receipt, status: response.status };
14110
+ case "failure":
14111
+ return { case: "failure", value: verdict.value, receipt, status: response.status };
14112
+ case "blocked":
14113
+ return { case: "blocked", value: verdict.value, receipt, status: response.status };
14114
+ }
14115
+ }
14079
14116
  function encodeInlineCustodyOffer(args) {
14080
14117
  return toBinary22(CustodyOfferBatchRequestSchema, create58(CustodyOfferBatchRequestSchema, {
14081
14118
  protocolVersion: 2,
@@ -14202,6 +14239,7 @@ function summarizeCustodyAdmission(admission) {
14202
14239
  var PLACEMENT_REF4 = "refs/nomos/placement";
14203
14240
  var LAW_PRODUCTS_MEDIA_TYPE2 = "application/vnd.nomos.export-law-products-response+protobuf";
14204
14241
  var WorkspaceSyncPhase = Object.freeze({
14242
+ Idle: "idle",
14205
14243
  Probe: "probe",
14206
14244
  Offer: "offer",
14207
14245
  Lease: "lease",
@@ -14235,7 +14273,6 @@ var WorkspaceSyncWork = class {
14235
14273
  #rediscover;
14236
14274
  /** The route the directory's answer yields, recomputed once that answer is observed. */
14237
14275
  #reroute;
14238
- #placementFetch;
14239
14276
  #discoveredFrontier;
14240
14277
  #observePlacement;
14241
14278
  /** Ask the directory for the provider's current placement frontier this round although a
@@ -14244,19 +14281,14 @@ var WorkspaceSyncWork = class {
14244
14281
  #directoryAnswered;
14245
14282
  #placementFetched;
14246
14283
  /** A round which converged without leasing, finishing once placement alone is fetched. */
14247
- #afterPlacement;
14248
14284
  #leased = false;
14249
- #lease;
14250
14285
  #command;
14251
14286
  #requestId;
14252
14287
  #started;
14253
- #phase = WorkspaceSyncPhase.Lease;
14288
+ #state = { phase: WorkspaceSyncPhase.Idle };
14254
14289
  #localHead;
14255
14290
  #offerHead;
14256
14291
  #previousHead;
14257
- #fetchStarted;
14258
- #offerStarted;
14259
- #offerRequestId;
14260
14292
  #pushMillis = 0;
14261
14293
  #pushBytes = 0n;
14262
14294
  #desiredHead;
@@ -14351,7 +14383,7 @@ var WorkspaceSyncWork = class {
14351
14383
  throw new Error(`replica '${this.#binding.replicaId}' has no custody remote`);
14352
14384
  }
14353
14385
  if (this.#rediscover || this.#recheckPlacement || !this.#route?.placementObserved && !this.#route?.placementFrontier && !this.#kernel.resolveRef(this.#mount, this.#requestId, PLACEMENT_REF4)) {
14354
- this.#phase = WorkspaceSyncPhase.Discover;
14386
+ this.#state = { phase: WorkspaceSyncPhase.Discover };
14355
14387
  return this.#remember({
14356
14388
  case: "pending",
14357
14389
  value: create59(CorrespondencePendingSchema, {
@@ -14371,13 +14403,13 @@ var WorkspaceSyncWork = class {
14371
14403
  #openRound() {
14372
14404
  if (this.#receiveState || this.#replaceLocalHead !== void 0) return this.#leaseEffect();
14373
14405
  if (!this.#localHead) return this.#leaseEffect();
14374
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
14406
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
14375
14407
  return this.#beginOffer(encodeInlineCustodyOffer({
14376
14408
  session: this.#binding.replicaId,
14377
- requestId: this.#offerRequestId,
14409
+ requestId,
14378
14410
  observedHead: this.#localHead,
14379
14411
  intents: []
14380
- }), true);
14412
+ }), { case: "awaiting", requestId }, true);
14381
14413
  }
14382
14414
  #offerOrReconcile() {
14383
14415
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
@@ -14398,13 +14430,13 @@ var WorkspaceSyncWork = class {
14398
14430
  throw new Error(`kernel did not classify transport for intent '${unspecified.intentId}'`);
14399
14431
  }
14400
14432
  if (suffix.length > 0) {
14401
- this.#offerStarted = this.#clock.monotonicNanoseconds();
14402
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
14433
+ const requestId2 = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
14434
+ const startedAt = this.#clock.monotonicNanoseconds();
14403
14435
  this.#offerAfterConverge = true;
14404
14436
  this.#rebaseFrom = this.#previousHead;
14405
14437
  return this.#beginOffer(encodeInlineCustodyOffer({
14406
14438
  session: this.#binding.replicaId,
14407
- requestId: this.#offerRequestId,
14439
+ requestId: requestId2,
14408
14440
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
14409
14441
  observedHead: this.#localHead,
14410
14442
  intents: suffix,
@@ -14415,17 +14447,17 @@ var WorkspaceSyncWork = class {
14415
14447
  this.#previousHead
14416
14448
  ) : void 0,
14417
14449
  fastForwardOnly: true
14418
- }));
14450
+ }), { case: "awaiting", requestId: requestId2, startedAt });
14419
14451
  }
14420
14452
  }
14421
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
14453
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
14422
14454
  return this.#beginOffer(encodeInlineCustodyOffer({
14423
14455
  session: this.#binding.replicaId,
14424
- requestId: this.#offerRequestId,
14456
+ requestId,
14425
14457
  baseHead: this.#previousHead,
14426
14458
  observedHead: this.#localHead,
14427
14459
  intents: []
14428
- }));
14460
+ }), { case: "awaiting", requestId });
14429
14461
  }
14430
14462
  /**
14431
14463
  * NO COMMON BASE — a round that cannot converge, and must not pay for history to find out.
@@ -14501,18 +14533,18 @@ var WorkspaceSyncWork = class {
14501
14533
  #pullBeforeOffer() {
14502
14534
  this.#offerAfterConverge = true;
14503
14535
  this.#rebaseFrom = this.#previousHead;
14504
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
14536
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
14505
14537
  return this.#beginOffer(encodeInlineCustodyOffer({
14506
14538
  session: this.#binding.replicaId,
14507
- requestId: this.#offerRequestId,
14539
+ requestId,
14508
14540
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
14509
14541
  observedHead: this.#localHead,
14510
14542
  intents: []
14511
- }));
14543
+ }), { case: "awaiting", requestId });
14512
14544
  }
14513
- #leaseEffect() {
14545
+ #leaseEffect(afterPlacement) {
14514
14546
  const token = this.#authToken();
14515
- this.#phase = WorkspaceSyncPhase.Lease;
14547
+ this.#state = { phase: WorkspaceSyncPhase.Lease, ...afterPlacement ? { afterPlacement } : {} };
14516
14548
  return this.#remember({
14517
14549
  case: "pending",
14518
14550
  value: create59(CorrespondencePendingSchema, {
@@ -14541,35 +14573,38 @@ var WorkspaceSyncWork = class {
14541
14573
  `workspace sync '${this.workId}' expected effect '${expected}', received '${receipt.effectId}'`
14542
14574
  );
14543
14575
  }
14576
+ const state = this.#state;
14544
14577
  const previousReceipt = this.#lastReceiptEffectId;
14545
14578
  this.#lastReceiptEffectId = receipt.effectId;
14546
14579
  try {
14547
14580
  if (receipt.outcome.case === "failure") {
14548
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#openRound();
14581
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#openRound();
14549
14582
  return this.#transportFailure(
14550
14583
  receipt.outcome.value.message,
14551
14584
  receipt.outcome.value.reason === PeerEffectFailureReason.OFFLINE
14552
14585
  );
14553
14586
  }
14554
- if (this.#phase === WorkspaceSyncPhase.Offer || this.#phase === WorkspaceSyncPhase.Probe) return this.#acceptOffer(receipt);
14555
- if (this.#phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt);
14556
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
14557
- if (this.#phase === WorkspaceSyncPhase.Placement) {
14558
- if (!this.#placementFetch || !this.#lease) throw new Error("placement transfer lost its lease");
14559
- this.#placementFetch.accept(receipt);
14587
+ if (state.phase === WorkspaceSyncPhase.Offer || state.phase === WorkspaceSyncPhase.Probe) {
14588
+ return this.#acceptOffer(receipt, state);
14589
+ }
14590
+ if (state.phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt, state);
14591
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
14592
+ if (state.phase === WorkspaceSyncPhase.Placement) {
14593
+ state.transfer.accept(receipt);
14560
14594
  this.#placementFetched?.();
14561
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
14562
- return this.#beginMainFetch(this.#lease);
14595
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
14596
+ return this.#beginMainFetch(state.lease);
14563
14597
  }
14564
- if (this.#phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt);
14598
+ if (state.phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt, state);
14565
14599
  throw new Error(`workspace sync '${this.workId}' is already complete`);
14566
14600
  } catch (error) {
14567
14601
  this.#lastReceiptEffectId = previousReceipt;
14568
14602
  throw error;
14569
14603
  }
14570
14604
  }
14571
- #beginOffer(body, probe = false) {
14572
- this.#phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
14605
+ #beginOffer(body, exchange, probe = false) {
14606
+ const phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
14607
+ this.#state = { phase, exchange };
14573
14608
  const token = this.#authToken();
14574
14609
  this.#pushBytes += BigInt(body.byteLength);
14575
14610
  return this.#remember({
@@ -14579,7 +14614,7 @@ var WorkspaceSyncWork = class {
14579
14614
  effect: {
14580
14615
  case: "http",
14581
14616
  value: create59(PeerHttpEffectSchema, {
14582
- effectId: `${this.workId}:${this.#phase}`,
14617
+ effectId: `${this.workId}:${phase}`,
14583
14618
  method: PeerHttpMethod.POST,
14584
14619
  url: this.#offerEndpoint(),
14585
14620
  contentType: CUSTODY_OFFER_MEDIA_TYPE,
@@ -14596,28 +14631,30 @@ var WorkspaceSyncWork = class {
14596
14631
  })
14597
14632
  });
14598
14633
  }
14599
- #acceptOffer(receipt) {
14600
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
14634
+ #acceptOffer(receipt, state) {
14635
+ const exchange = state.exchange;
14636
+ this.#pushMillis = exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, exchange.startedAt);
14601
14637
  if (receipt.outcome.case !== "response") {
14602
14638
  throw new Error("platform returned the wrong receipt for a custody offer");
14603
14639
  }
14604
- const response = receipt.outcome.value;
14605
- if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
14640
+ const outcome = settleCustodyOfferExchange(exchange, receipt.outcome.value);
14641
+ if (outcome.case === "maintenance") {
14642
+ return this.#finishOfferOutcome(true, false);
14643
+ }
14644
+ if (outcome.case === "unexpected") {
14606
14645
  this.#pushError = create59(RuntimeTransportFailureSchema, {
14607
14646
  endpoint: this.#offerEndpoint(),
14608
- status: response.status,
14647
+ status: outcome.status,
14609
14648
  refused: false,
14610
- message: `Sync received an unexpected server response (HTTP ${response.status}; ${response.contentType || "no content type"}). No custody receipt was returned.`
14649
+ message: `Sync received an unexpected server response (HTTP ${outcome.status}; ${outcome.contentType || "no content type"}). No custody receipt was returned.`
14611
14650
  });
14612
14651
  return this.#finishOfferOutcome(false);
14613
14652
  }
14614
- if (!this.#offerRequestId) throw new Error("custody offer has no request identity");
14615
- const outcome = decodeCustodyOffer(response.body, this.#offerRequestId);
14616
- this.#offerReceipt = custodyOfferReceipt(this.#offerRequestId, outcome);
14653
+ this.#offerReceipt = outcome.receipt;
14617
14654
  if (outcome.case === "failure") {
14618
14655
  this.#pushError = create59(RuntimeTransportFailureSchema, {
14619
14656
  endpoint: this.#offerEndpoint(),
14620
- status: response.status,
14657
+ status: outcome.status,
14621
14658
  refused: false,
14622
14659
  message: `${outcome.value.code}: ${outcome.value.message}`
14623
14660
  });
@@ -14626,12 +14663,12 @@ var WorkspaceSyncWork = class {
14626
14663
  if (outcome.case === "blocked") {
14627
14664
  return this.#finishOfferOutcome(true);
14628
14665
  }
14629
- if (response.status < 200 || response.status >= 300) {
14666
+ if (outcome.status < 200 || outcome.status >= 300) {
14630
14667
  this.#pushError = create59(RuntimeTransportFailureSchema, {
14631
14668
  endpoint: this.#offerEndpoint(),
14632
- status: response.status,
14633
- refused: response.status === 422,
14634
- message: `custody offer returned an admission verdict with HTTP ${response.status}`
14669
+ status: outcome.status,
14670
+ refused: outcome.status === 422,
14671
+ message: `custody offer returned an admission verdict with HTTP ${outcome.status}`
14635
14672
  });
14636
14673
  return this.#finishOfferOutcome(false);
14637
14674
  }
@@ -14639,7 +14676,7 @@ var WorkspaceSyncWork = class {
14639
14676
  this.#desiredHead = admission.main || void 0;
14640
14677
  if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
14641
14678
  this.#candidateDurable = admission.sealedMain === this.#desiredHead;
14642
- if (this.#phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
14679
+ if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
14643
14680
  if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
14644
14681
  if (this.#alreadyJudged(this.#desiredHead)) {
14645
14682
  return this.#finish(create59(SyncWorkspaceResponseSchema, {
@@ -14701,7 +14738,7 @@ var WorkspaceSyncWork = class {
14701
14738
  if (admission.recoveryRequired !== false) return this.#leaseEffect();
14702
14739
  return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
14703
14740
  }
14704
- #acceptLease(receipt) {
14741
+ #acceptLease(receipt, state) {
14705
14742
  if (receipt.outcome.case !== "response") {
14706
14743
  throw new Error("platform returned the wrong receipt for a Git read lease");
14707
14744
  }
@@ -14717,21 +14754,25 @@ var WorkspaceSyncWork = class {
14717
14754
  this.#leased = true;
14718
14755
  const frontier = this.#placementFrontier();
14719
14756
  if (frontier) {
14720
- this.#placementFetch = new PlacementFetch(
14757
+ const transfer = new PlacementFetch(
14721
14758
  this.#kernel,
14722
14759
  this.#mount,
14723
14760
  this.#requestId,
14724
14761
  this.workId,
14725
14762
  frontier
14726
14763
  );
14727
- const pending = this.#placementFetch.start(lease);
14764
+ const pending = transfer.start(lease);
14728
14765
  if (pending) {
14729
- this.#phase = WorkspaceSyncPhase.Placement;
14730
- this.#lease = lease;
14766
+ this.#state = {
14767
+ phase: WorkspaceSyncPhase.Placement,
14768
+ transfer,
14769
+ lease,
14770
+ ...state.afterPlacement ? { afterPlacement: state.afterPlacement } : {}
14771
+ };
14731
14772
  return this.#remember({ case: "pending", value: pending });
14732
14773
  }
14733
14774
  }
14734
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
14775
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
14735
14776
  return this.#beginMainFetch(lease);
14736
14777
  }
14737
14778
  /** The provider's placement frontier as this round knows it: what the directory named in this
@@ -14751,8 +14792,7 @@ var WorkspaceSyncWork = class {
14751
14792
  if (!new PlacementFetch(this.#kernel, this.#mount, this.#requestId, this.workId, frontier).wanted()) {
14752
14793
  return void 0;
14753
14794
  }
14754
- this.#afterPlacement = presented;
14755
- return this.#leaseEffect();
14795
+ return this.#leaseEffect(presented);
14756
14796
  }
14757
14797
  #acceptDiscovery(receipt) {
14758
14798
  this.#directoryAnswered?.();
@@ -14776,9 +14816,11 @@ var WorkspaceSyncWork = class {
14776
14816
  return this.#replaceLocalHead !== void 0 || this.#localHead === void 0 && this.#previousHead === void 0;
14777
14817
  }
14778
14818
  #beginMainFetch(lease) {
14779
- this.#phase = WorkspaceSyncPhase.Fetch;
14780
14819
  const lawProducts = this.#lawProductsAlongside();
14781
- this.#fetchStarted = this.#clock.monotonicNanoseconds();
14820
+ this.#state = {
14821
+ phase: WorkspaceSyncPhase.Fetch,
14822
+ startedAt: this.#clock.monotonicNanoseconds()
14823
+ };
14782
14824
  const haves = this.#replaceLocalHead !== void 0 ? this.#repairMissingCommit ? [] : [this.#kernel.resolveRef(this.#mount, this.#requestId, deferredRemote)].filter(
14783
14825
  (head) => !!head
14784
14826
  ) : [...new Set([
@@ -14809,7 +14851,7 @@ var WorkspaceSyncWork = class {
14809
14851
  })
14810
14852
  });
14811
14853
  }
14812
- #acceptFetch(receipt) {
14854
+ #acceptFetch(receipt, state) {
14813
14855
  if (receipt.outcome.case !== "gitFetch") {
14814
14856
  throw new Error("platform returned the wrong receipt for a Git object fetch");
14815
14857
  }
@@ -14819,7 +14861,7 @@ var WorkspaceSyncWork = class {
14819
14861
  if (fetched.pack.byteLength > 0) {
14820
14862
  this.#kernel.applyPack(this.#mount, this.#requestId, fetched.pack, fetched.head, fetched.shallow);
14821
14863
  }
14822
- const prefetchMillis = this.#fetchStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#fetchStarted);
14864
+ const prefetchMillis = elapsedMillis(this.#clock, state.startedAt);
14823
14865
  const candidateHead = this.#receiveState ? this.#kernel.resolveStatePosition?.(this.#mount, this.#requestId, fetched.head, this.#receiveState) : fetched.head;
14824
14866
  if (!candidateHead) {
14825
14867
  return this.#finish(create59(SyncWorkspaceResponseSchema, {
@@ -15170,11 +15212,11 @@ var WorkspaceSyncWork = class {
15170
15212
  pushBytes: this.#pushBytes,
15171
15213
  pullBytes: BigInt(receivedBytes),
15172
15214
  serverMillis: this.#admissionSummary?.serverMillis ?? 0,
15173
- offerInPush: this.#offerRequestId !== void 0
15215
+ offerInPush: this.#pushBytes > 0n
15174
15216
  })
15175
15217
  });
15176
15218
  }
15177
- #finishOfferOutcome(blocked) {
15219
+ #finishOfferOutcome(blocked, reconnectRequired = true) {
15178
15220
  return this.#finish(create59(SyncWorkspaceResponseSchema, {
15179
15221
  workspace: this.#mount.workspace,
15180
15222
  previousHead: this.#previousHead,
@@ -15182,7 +15224,7 @@ var WorkspaceSyncWork = class {
15182
15224
  admitted: BigInt(this.#admissionSummary?.admittedIntentIds.length ?? 0),
15183
15225
  refused: BigInt((this.#admissionSummary?.refusedMessages.length ?? 0) + this.#parkedLocal),
15184
15226
  deferred: BigInt(this.#admissionSummary ? this.#admissionSummary.blockedMessages.length + this.#admissionSummary.deadLetteredMessages.length + this.#admissionSummary.quarantinedMessages.length + this.#admissionSummary.deferredMessages.length : blocked ? 1 : 0),
15185
- reconnectRequired: true,
15227
+ reconnectRequired,
15186
15228
  stillAhead: this.#localHead !== this.#previousHead,
15187
15229
  directOfferDeferred: blocked,
15188
15230
  offerReceipt: this.#offerReceipt,
@@ -15196,15 +15238,16 @@ var WorkspaceSyncWork = class {
15196
15238
  }));
15197
15239
  }
15198
15240
  #transportFailure(message, offline, status = -1) {
15199
- const pushFailed = this.#phase === WorkspaceSyncPhase.Offer;
15241
+ const state = this.#state;
15242
+ const pushFailed = state.phase === WorkspaceSyncPhase.Offer;
15200
15243
  const failedEndpoint = this.#offerEndpoint();
15201
15244
  const failure2 = create59(RuntimeTransportFailureSchema, {
15202
15245
  endpoint: pushFailed ? failedEndpoint : this.#binding.cloud ?? "",
15203
15246
  status,
15204
15247
  message
15205
15248
  });
15206
- if (pushFailed) {
15207
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
15249
+ if (state.phase === WorkspaceSyncPhase.Offer) {
15250
+ this.#pushMillis = state.exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, state.exchange.startedAt);
15208
15251
  this.#pushError = failure2;
15209
15252
  }
15210
15253
  return this.#finish(create59(SyncWorkspaceResponseSchema, {
@@ -15221,7 +15264,7 @@ var WorkspaceSyncWork = class {
15221
15264
  pushMillis: this.#pushMillis,
15222
15265
  pushBytes: this.#pushBytes,
15223
15266
  prefetchMillis: elapsedMillis(this.#clock, this.#started),
15224
- offerInPush: this.#offerRequestId !== void 0
15267
+ offerInPush: this.#pushBytes > 0n
15225
15268
  })
15226
15269
  }));
15227
15270
  }
@@ -15231,7 +15274,7 @@ var WorkspaceSyncWork = class {
15231
15274
  return step;
15232
15275
  }
15233
15276
  #finish(value) {
15234
- this.#phase = WorkspaceSyncPhase.Done;
15277
+ this.#state = { phase: WorkspaceSyncPhase.Done };
15235
15278
  this.#current = void 0;
15236
15279
  return this.#remember({ case: "synced", value });
15237
15280
  }