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.
@@ -14705,6 +14705,15 @@ var init_replica_follow_controller = __esm({
14705
14705
  }
14706
14706
  if (result.stillAhead || result.pushFailed || result.directOfferDeferred || result.reconnectRequired) {
14707
14707
  if (result.directOfferDeferred) {
14708
+ if (!result.reconnectRequired) {
14709
+ this.#desk.transition(result.workspace, {
14710
+ case: ReplicaFollowEventKind.Failed,
14711
+ nowUnixMillis,
14712
+ failure: "remote workspace opening; retrying",
14713
+ retryWithinMillis: 5e3
14714
+ });
14715
+ return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
14716
+ }
14708
14717
  this.#desk.transition(result.workspace, {
14709
14718
  case: ReplicaFollowEventKind.DependencyDeferred,
14710
14719
  nowUnixMillis,
@@ -16709,6 +16718,34 @@ var init_custody_replacement = __esm({
16709
16718
 
16710
16719
  // ../peer-office/src/runtime/custody_offer.ts
16711
16720
  import { create as create53, fromBinary as fromBinary19, toBinary as toBinary17 } from "@bufbuild/protobuf";
16721
+ function settleCustodyOfferExchange(awaiting, response) {
16722
+ if (response.status === 202 && response.contentType?.includes("application/json")) {
16723
+ try {
16724
+ const pending = JSON.parse(new TextDecoder().decode(response.body));
16725
+ if (pending?.retryable === true && typeof pending.preparing === "string") {
16726
+ return { case: "maintenance", kind: pending.preparing };
16727
+ }
16728
+ } catch {
16729
+ }
16730
+ }
16731
+ if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
16732
+ return {
16733
+ case: "unexpected",
16734
+ status: response.status,
16735
+ ...response.contentType === void 0 ? {} : { contentType: response.contentType }
16736
+ };
16737
+ }
16738
+ const verdict = decodeCustodyOffer(response.body, awaiting.requestId);
16739
+ const receipt = custodyOfferReceipt(awaiting.requestId, verdict);
16740
+ switch (verdict.case) {
16741
+ case "admission":
16742
+ return { case: "admission", value: verdict.value, receipt, status: response.status };
16743
+ case "failure":
16744
+ return { case: "failure", value: verdict.value, receipt, status: response.status };
16745
+ case "blocked":
16746
+ return { case: "blocked", value: verdict.value, receipt, status: response.status };
16747
+ }
16748
+ }
16712
16749
  function encodeInlineCustodyOffer(args) {
16713
16750
  return toBinary17(CustodyOfferBatchRequestSchema, create53(CustodyOfferBatchRequestSchema, {
16714
16751
  protocolVersion: 2,
@@ -16862,6 +16899,7 @@ var init_workspace_sync = __esm({
16862
16899
  PLACEMENT_REF3 = "refs/nomos/placement";
16863
16900
  LAW_PRODUCTS_MEDIA_TYPE = "application/vnd.nomos.export-law-products-response+protobuf";
16864
16901
  WorkspaceSyncPhase = Object.freeze({
16902
+ Idle: "idle",
16865
16903
  Probe: "probe",
16866
16904
  Offer: "offer",
16867
16905
  Lease: "lease",
@@ -16892,7 +16930,6 @@ var init_workspace_sync = __esm({
16892
16930
  #rediscover;
16893
16931
  /** The route the directory's answer yields, recomputed once that answer is observed. */
16894
16932
  #reroute;
16895
- #placementFetch;
16896
16933
  #discoveredFrontier;
16897
16934
  #observePlacement;
16898
16935
  /** Ask the directory for the provider's current placement frontier this round although a
@@ -16901,19 +16938,14 @@ var init_workspace_sync = __esm({
16901
16938
  #directoryAnswered;
16902
16939
  #placementFetched;
16903
16940
  /** A round which converged without leasing, finishing once placement alone is fetched. */
16904
- #afterPlacement;
16905
16941
  #leased = false;
16906
- #lease;
16907
16942
  #command;
16908
16943
  #requestId;
16909
16944
  #started;
16910
- #phase = WorkspaceSyncPhase.Lease;
16945
+ #state = { phase: WorkspaceSyncPhase.Idle };
16911
16946
  #localHead;
16912
16947
  #offerHead;
16913
16948
  #previousHead;
16914
- #fetchStarted;
16915
- #offerStarted;
16916
- #offerRequestId;
16917
16949
  #pushMillis = 0;
16918
16950
  #pushBytes = 0n;
16919
16951
  #desiredHead;
@@ -17008,7 +17040,7 @@ var init_workspace_sync = __esm({
17008
17040
  throw new Error(`replica '${this.#binding.replicaId}' has no custody remote`);
17009
17041
  }
17010
17042
  if (this.#rediscover || this.#recheckPlacement || !this.#route?.placementObserved && !this.#route?.placementFrontier && !this.#kernel.resolveRef(this.#mount, this.#requestId, PLACEMENT_REF3)) {
17011
- this.#phase = WorkspaceSyncPhase.Discover;
17043
+ this.#state = { phase: WorkspaceSyncPhase.Discover };
17012
17044
  return this.#remember({
17013
17045
  case: "pending",
17014
17046
  value: create54(CorrespondencePendingSchema, {
@@ -17028,13 +17060,13 @@ var init_workspace_sync = __esm({
17028
17060
  #openRound() {
17029
17061
  if (this.#receiveState || this.#replaceLocalHead !== void 0) return this.#leaseEffect();
17030
17062
  if (!this.#localHead) return this.#leaseEffect();
17031
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
17063
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
17032
17064
  return this.#beginOffer(encodeInlineCustodyOffer({
17033
17065
  session: this.#binding.replicaId,
17034
- requestId: this.#offerRequestId,
17066
+ requestId,
17035
17067
  observedHead: this.#localHead,
17036
17068
  intents: []
17037
- }), true);
17069
+ }), { case: "awaiting", requestId }, true);
17038
17070
  }
17039
17071
  #offerOrReconcile() {
17040
17072
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
@@ -17055,13 +17087,13 @@ var init_workspace_sync = __esm({
17055
17087
  throw new Error(`kernel did not classify transport for intent '${unspecified.intentId}'`);
17056
17088
  }
17057
17089
  if (suffix.length > 0) {
17058
- this.#offerStarted = this.#clock.monotonicNanoseconds();
17059
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
17090
+ const requestId2 = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
17091
+ const startedAt = this.#clock.monotonicNanoseconds();
17060
17092
  this.#offerAfterConverge = true;
17061
17093
  this.#rebaseFrom = this.#previousHead;
17062
17094
  return this.#beginOffer(encodeInlineCustodyOffer({
17063
17095
  session: this.#binding.replicaId,
17064
- requestId: this.#offerRequestId,
17096
+ requestId: requestId2,
17065
17097
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
17066
17098
  observedHead: this.#localHead,
17067
17099
  intents: suffix,
@@ -17072,17 +17104,17 @@ var init_workspace_sync = __esm({
17072
17104
  this.#previousHead
17073
17105
  ) : void 0,
17074
17106
  fastForwardOnly: true
17075
- }));
17107
+ }), { case: "awaiting", requestId: requestId2, startedAt });
17076
17108
  }
17077
17109
  }
17078
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
17110
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
17079
17111
  return this.#beginOffer(encodeInlineCustodyOffer({
17080
17112
  session: this.#binding.replicaId,
17081
- requestId: this.#offerRequestId,
17113
+ requestId,
17082
17114
  baseHead: this.#previousHead,
17083
17115
  observedHead: this.#localHead,
17084
17116
  intents: []
17085
- }));
17117
+ }), { case: "awaiting", requestId });
17086
17118
  }
17087
17119
  /**
17088
17120
  * NO COMMON BASE — a round that cannot converge, and must not pay for history to find out.
@@ -17158,18 +17190,18 @@ var init_workspace_sync = __esm({
17158
17190
  #pullBeforeOffer() {
17159
17191
  this.#offerAfterConverge = true;
17160
17192
  this.#rebaseFrom = this.#previousHead;
17161
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
17193
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
17162
17194
  return this.#beginOffer(encodeInlineCustodyOffer({
17163
17195
  session: this.#binding.replicaId,
17164
- requestId: this.#offerRequestId,
17196
+ requestId,
17165
17197
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
17166
17198
  observedHead: this.#localHead,
17167
17199
  intents: []
17168
- }));
17200
+ }), { case: "awaiting", requestId });
17169
17201
  }
17170
- #leaseEffect() {
17202
+ #leaseEffect(afterPlacement) {
17171
17203
  const token = this.#authToken();
17172
- this.#phase = WorkspaceSyncPhase.Lease;
17204
+ this.#state = { phase: WorkspaceSyncPhase.Lease, ...afterPlacement ? { afterPlacement } : {} };
17173
17205
  return this.#remember({
17174
17206
  case: "pending",
17175
17207
  value: create54(CorrespondencePendingSchema, {
@@ -17198,35 +17230,38 @@ var init_workspace_sync = __esm({
17198
17230
  `workspace sync '${this.workId}' expected effect '${expected}', received '${receipt.effectId}'`
17199
17231
  );
17200
17232
  }
17233
+ const state = this.#state;
17201
17234
  const previousReceipt = this.#lastReceiptEffectId;
17202
17235
  this.#lastReceiptEffectId = receipt.effectId;
17203
17236
  try {
17204
17237
  if (receipt.outcome.case === "failure") {
17205
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#openRound();
17238
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#openRound();
17206
17239
  return this.#transportFailure(
17207
17240
  receipt.outcome.value.message,
17208
17241
  receipt.outcome.value.reason === PeerEffectFailureReason.OFFLINE
17209
17242
  );
17210
17243
  }
17211
- if (this.#phase === WorkspaceSyncPhase.Offer || this.#phase === WorkspaceSyncPhase.Probe) return this.#acceptOffer(receipt);
17212
- if (this.#phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt);
17213
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
17214
- if (this.#phase === WorkspaceSyncPhase.Placement) {
17215
- if (!this.#placementFetch || !this.#lease) throw new Error("placement transfer lost its lease");
17216
- this.#placementFetch.accept(receipt);
17244
+ if (state.phase === WorkspaceSyncPhase.Offer || state.phase === WorkspaceSyncPhase.Probe) {
17245
+ return this.#acceptOffer(receipt, state);
17246
+ }
17247
+ if (state.phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt, state);
17248
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
17249
+ if (state.phase === WorkspaceSyncPhase.Placement) {
17250
+ state.transfer.accept(receipt);
17217
17251
  this.#placementFetched?.();
17218
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
17219
- return this.#beginMainFetch(this.#lease);
17252
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
17253
+ return this.#beginMainFetch(state.lease);
17220
17254
  }
17221
- if (this.#phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt);
17255
+ if (state.phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt, state);
17222
17256
  throw new Error(`workspace sync '${this.workId}' is already complete`);
17223
17257
  } catch (error) {
17224
17258
  this.#lastReceiptEffectId = previousReceipt;
17225
17259
  throw error;
17226
17260
  }
17227
17261
  }
17228
- #beginOffer(body, probe = false) {
17229
- this.#phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
17262
+ #beginOffer(body, exchange, probe = false) {
17263
+ const phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
17264
+ this.#state = { phase, exchange };
17230
17265
  const token = this.#authToken();
17231
17266
  this.#pushBytes += BigInt(body.byteLength);
17232
17267
  return this.#remember({
@@ -17236,7 +17271,7 @@ var init_workspace_sync = __esm({
17236
17271
  effect: {
17237
17272
  case: "http",
17238
17273
  value: create54(PeerHttpEffectSchema, {
17239
- effectId: `${this.workId}:${this.#phase}`,
17274
+ effectId: `${this.workId}:${phase}`,
17240
17275
  method: PeerHttpMethod.POST,
17241
17276
  url: this.#offerEndpoint(),
17242
17277
  contentType: CUSTODY_OFFER_MEDIA_TYPE,
@@ -17253,28 +17288,30 @@ var init_workspace_sync = __esm({
17253
17288
  })
17254
17289
  });
17255
17290
  }
17256
- #acceptOffer(receipt) {
17257
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
17291
+ #acceptOffer(receipt, state) {
17292
+ const exchange = state.exchange;
17293
+ this.#pushMillis = exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, exchange.startedAt);
17258
17294
  if (receipt.outcome.case !== "response") {
17259
17295
  throw new Error("platform returned the wrong receipt for a custody offer");
17260
17296
  }
17261
- const response = receipt.outcome.value;
17262
- if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
17297
+ const outcome = settleCustodyOfferExchange(exchange, receipt.outcome.value);
17298
+ if (outcome.case === "maintenance") {
17299
+ return this.#finishOfferOutcome(true, false);
17300
+ }
17301
+ if (outcome.case === "unexpected") {
17263
17302
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17264
17303
  endpoint: this.#offerEndpoint(),
17265
- status: response.status,
17304
+ status: outcome.status,
17266
17305
  refused: false,
17267
- message: `Sync received an unexpected server response (HTTP ${response.status}; ${response.contentType || "no content type"}). No custody receipt was returned.`
17306
+ message: `Sync received an unexpected server response (HTTP ${outcome.status}; ${outcome.contentType || "no content type"}). No custody receipt was returned.`
17268
17307
  });
17269
17308
  return this.#finishOfferOutcome(false);
17270
17309
  }
17271
- if (!this.#offerRequestId) throw new Error("custody offer has no request identity");
17272
- const outcome = decodeCustodyOffer(response.body, this.#offerRequestId);
17273
- this.#offerReceipt = custodyOfferReceipt(this.#offerRequestId, outcome);
17310
+ this.#offerReceipt = outcome.receipt;
17274
17311
  if (outcome.case === "failure") {
17275
17312
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17276
17313
  endpoint: this.#offerEndpoint(),
17277
- status: response.status,
17314
+ status: outcome.status,
17278
17315
  refused: false,
17279
17316
  message: `${outcome.value.code}: ${outcome.value.message}`
17280
17317
  });
@@ -17283,12 +17320,12 @@ var init_workspace_sync = __esm({
17283
17320
  if (outcome.case === "blocked") {
17284
17321
  return this.#finishOfferOutcome(true);
17285
17322
  }
17286
- if (response.status < 200 || response.status >= 300) {
17323
+ if (outcome.status < 200 || outcome.status >= 300) {
17287
17324
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17288
17325
  endpoint: this.#offerEndpoint(),
17289
- status: response.status,
17290
- refused: response.status === 422,
17291
- message: `custody offer returned an admission verdict with HTTP ${response.status}`
17326
+ status: outcome.status,
17327
+ refused: outcome.status === 422,
17328
+ message: `custody offer returned an admission verdict with HTTP ${outcome.status}`
17292
17329
  });
17293
17330
  return this.#finishOfferOutcome(false);
17294
17331
  }
@@ -17296,7 +17333,7 @@ var init_workspace_sync = __esm({
17296
17333
  this.#desiredHead = admission.main || void 0;
17297
17334
  if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
17298
17335
  this.#candidateDurable = admission.sealedMain === this.#desiredHead;
17299
- if (this.#phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
17336
+ if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
17300
17337
  if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
17301
17338
  if (this.#alreadyJudged(this.#desiredHead)) {
17302
17339
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17358,7 +17395,7 @@ var init_workspace_sync = __esm({
17358
17395
  if (admission.recoveryRequired !== false) return this.#leaseEffect();
17359
17396
  return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
17360
17397
  }
17361
- #acceptLease(receipt) {
17398
+ #acceptLease(receipt, state) {
17362
17399
  if (receipt.outcome.case !== "response") {
17363
17400
  throw new Error("platform returned the wrong receipt for a Git read lease");
17364
17401
  }
@@ -17374,21 +17411,25 @@ var init_workspace_sync = __esm({
17374
17411
  this.#leased = true;
17375
17412
  const frontier = this.#placementFrontier();
17376
17413
  if (frontier) {
17377
- this.#placementFetch = new PlacementFetch(
17414
+ const transfer = new PlacementFetch(
17378
17415
  this.#kernel,
17379
17416
  this.#mount,
17380
17417
  this.#requestId,
17381
17418
  this.workId,
17382
17419
  frontier
17383
17420
  );
17384
- const pending = this.#placementFetch.start(lease);
17421
+ const pending = transfer.start(lease);
17385
17422
  if (pending) {
17386
- this.#phase = WorkspaceSyncPhase.Placement;
17387
- this.#lease = lease;
17423
+ this.#state = {
17424
+ phase: WorkspaceSyncPhase.Placement,
17425
+ transfer,
17426
+ lease,
17427
+ ...state.afterPlacement ? { afterPlacement: state.afterPlacement } : {}
17428
+ };
17388
17429
  return this.#remember({ case: "pending", value: pending });
17389
17430
  }
17390
17431
  }
17391
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
17432
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
17392
17433
  return this.#beginMainFetch(lease);
17393
17434
  }
17394
17435
  /** The provider's placement frontier as this round knows it: what the directory named in this
@@ -17408,8 +17449,7 @@ var init_workspace_sync = __esm({
17408
17449
  if (!new PlacementFetch(this.#kernel, this.#mount, this.#requestId, this.workId, frontier).wanted()) {
17409
17450
  return void 0;
17410
17451
  }
17411
- this.#afterPlacement = presented;
17412
- return this.#leaseEffect();
17452
+ return this.#leaseEffect(presented);
17413
17453
  }
17414
17454
  #acceptDiscovery(receipt) {
17415
17455
  this.#directoryAnswered?.();
@@ -17433,9 +17473,11 @@ var init_workspace_sync = __esm({
17433
17473
  return this.#replaceLocalHead !== void 0 || this.#localHead === void 0 && this.#previousHead === void 0;
17434
17474
  }
17435
17475
  #beginMainFetch(lease) {
17436
- this.#phase = WorkspaceSyncPhase.Fetch;
17437
17476
  const lawProducts = this.#lawProductsAlongside();
17438
- this.#fetchStarted = this.#clock.monotonicNanoseconds();
17477
+ this.#state = {
17478
+ phase: WorkspaceSyncPhase.Fetch,
17479
+ startedAt: this.#clock.monotonicNanoseconds()
17480
+ };
17439
17481
  const haves = this.#replaceLocalHead !== void 0 ? this.#repairMissingCommit ? [] : [this.#kernel.resolveRef(this.#mount, this.#requestId, deferredRemote)].filter(
17440
17482
  (head) => !!head
17441
17483
  ) : [...new Set([
@@ -17466,7 +17508,7 @@ var init_workspace_sync = __esm({
17466
17508
  })
17467
17509
  });
17468
17510
  }
17469
- #acceptFetch(receipt) {
17511
+ #acceptFetch(receipt, state) {
17470
17512
  if (receipt.outcome.case !== "gitFetch") {
17471
17513
  throw new Error("platform returned the wrong receipt for a Git object fetch");
17472
17514
  }
@@ -17476,7 +17518,7 @@ var init_workspace_sync = __esm({
17476
17518
  if (fetched.pack.byteLength > 0) {
17477
17519
  this.#kernel.applyPack(this.#mount, this.#requestId, fetched.pack, fetched.head, fetched.shallow);
17478
17520
  }
17479
- const prefetchMillis = this.#fetchStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#fetchStarted);
17521
+ const prefetchMillis = elapsedMillis(this.#clock, state.startedAt);
17480
17522
  const candidateHead = this.#receiveState ? this.#kernel.resolveStatePosition?.(this.#mount, this.#requestId, fetched.head, this.#receiveState) : fetched.head;
17481
17523
  if (!candidateHead) {
17482
17524
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17827,11 +17869,11 @@ var init_workspace_sync = __esm({
17827
17869
  pushBytes: this.#pushBytes,
17828
17870
  pullBytes: BigInt(receivedBytes),
17829
17871
  serverMillis: this.#admissionSummary?.serverMillis ?? 0,
17830
- offerInPush: this.#offerRequestId !== void 0
17872
+ offerInPush: this.#pushBytes > 0n
17831
17873
  })
17832
17874
  });
17833
17875
  }
17834
- #finishOfferOutcome(blocked) {
17876
+ #finishOfferOutcome(blocked, reconnectRequired = true) {
17835
17877
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
17836
17878
  workspace: this.#mount.workspace,
17837
17879
  previousHead: this.#previousHead,
@@ -17839,7 +17881,7 @@ var init_workspace_sync = __esm({
17839
17881
  admitted: BigInt(this.#admissionSummary?.admittedIntentIds.length ?? 0),
17840
17882
  refused: BigInt((this.#admissionSummary?.refusedMessages.length ?? 0) + this.#parkedLocal),
17841
17883
  deferred: BigInt(this.#admissionSummary ? this.#admissionSummary.blockedMessages.length + this.#admissionSummary.deadLetteredMessages.length + this.#admissionSummary.quarantinedMessages.length + this.#admissionSummary.deferredMessages.length : blocked ? 1 : 0),
17842
- reconnectRequired: true,
17884
+ reconnectRequired,
17843
17885
  stillAhead: this.#localHead !== this.#previousHead,
17844
17886
  directOfferDeferred: blocked,
17845
17887
  offerReceipt: this.#offerReceipt,
@@ -17853,15 +17895,16 @@ var init_workspace_sync = __esm({
17853
17895
  }));
17854
17896
  }
17855
17897
  #transportFailure(message, offline, status = -1) {
17856
- const pushFailed = this.#phase === WorkspaceSyncPhase.Offer;
17898
+ const state = this.#state;
17899
+ const pushFailed = state.phase === WorkspaceSyncPhase.Offer;
17857
17900
  const failedEndpoint = this.#offerEndpoint();
17858
17901
  const failure = create54(RuntimeTransportFailureSchema, {
17859
17902
  endpoint: pushFailed ? failedEndpoint : this.#binding.cloud ?? "",
17860
17903
  status,
17861
17904
  message
17862
17905
  });
17863
- if (pushFailed) {
17864
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
17906
+ if (state.phase === WorkspaceSyncPhase.Offer) {
17907
+ this.#pushMillis = state.exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, state.exchange.startedAt);
17865
17908
  this.#pushError = failure;
17866
17909
  }
17867
17910
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17878,7 +17921,7 @@ var init_workspace_sync = __esm({
17878
17921
  pushMillis: this.#pushMillis,
17879
17922
  pushBytes: this.#pushBytes,
17880
17923
  prefetchMillis: elapsedMillis(this.#clock, this.#started),
17881
- offerInPush: this.#offerRequestId !== void 0
17924
+ offerInPush: this.#pushBytes > 0n
17882
17925
  })
17883
17926
  }));
17884
17927
  }
@@ -17888,7 +17931,7 @@ var init_workspace_sync = __esm({
17888
17931
  return step;
17889
17932
  }
17890
17933
  #finish(value) {
17891
- this.#phase = WorkspaceSyncPhase.Done;
17934
+ this.#state = { phase: WorkspaceSyncPhase.Done };
17892
17935
  this.#current = void 0;
17893
17936
  return this.#remember({ case: "synced", value });
17894
17937
  }