@githolon/runtime 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.
@@ -21835,6 +21835,15 @@ var ReplicaFollowController = class {
21835
21835
  }
21836
21836
  if (result.stillAhead || result.pushFailed || result.directOfferDeferred || result.reconnectRequired) {
21837
21837
  if (result.directOfferDeferred) {
21838
+ if (!result.reconnectRequired) {
21839
+ this.#desk.transition(result.workspace, {
21840
+ case: ReplicaFollowEventKind.Failed,
21841
+ nowUnixMillis,
21842
+ failure: "remote workspace opening; retrying",
21843
+ retryWithinMillis: 5e3
21844
+ });
21845
+ return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
21846
+ }
21838
21847
  this.#desk.transition(result.workspace, {
21839
21848
  case: ReplicaFollowEventKind.DependencyDeferred,
21840
21849
  nowUnixMillis,
@@ -23740,6 +23749,34 @@ function resolveCustodyDisagreement(kernel, mount, requestId, policy, verdict) {
23740
23749
  init_define_NOMOS_KERNEL_RELEASE();
23741
23750
  var CUSTODY_OFFER_MEDIA_TYPE = "application/vnd.nomos.custody-offer-batch+protobuf";
23742
23751
  var CUSTODY_OFFER_RESULT_MEDIA_TYPE = "application/vnd.nomos.custody-offer-result+protobuf";
23752
+ function settleCustodyOfferExchange(awaiting, response) {
23753
+ if (response.status === 202 && response.contentType?.includes("application/json")) {
23754
+ try {
23755
+ const pending = JSON.parse(new TextDecoder().decode(response.body));
23756
+ if (pending?.retryable === true && typeof pending.preparing === "string") {
23757
+ return { case: "maintenance", kind: pending.preparing };
23758
+ }
23759
+ } catch {
23760
+ }
23761
+ }
23762
+ if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
23763
+ return {
23764
+ case: "unexpected",
23765
+ status: response.status,
23766
+ ...response.contentType === void 0 ? {} : { contentType: response.contentType }
23767
+ };
23768
+ }
23769
+ const verdict = decodeCustodyOffer(response.body, awaiting.requestId);
23770
+ const receipt = custodyOfferReceipt(awaiting.requestId, verdict);
23771
+ switch (verdict.case) {
23772
+ case "admission":
23773
+ return { case: "admission", value: verdict.value, receipt, status: response.status };
23774
+ case "failure":
23775
+ return { case: "failure", value: verdict.value, receipt, status: response.status };
23776
+ case "blocked":
23777
+ return { case: "blocked", value: verdict.value, receipt, status: response.status };
23778
+ }
23779
+ }
23743
23780
  function encodeInlineCustodyOffer(args) {
23744
23781
  return toBinary(CustodyOfferBatchRequestSchema, create(CustodyOfferBatchRequestSchema, {
23745
23782
  protocolVersion: 2,
@@ -23866,6 +23903,7 @@ function summarizeCustodyAdmission(admission) {
23866
23903
  var PLACEMENT_REF3 = "refs/nomos/placement";
23867
23904
  var LAW_PRODUCTS_MEDIA_TYPE = "application/vnd.nomos.export-law-products-response+protobuf";
23868
23905
  var WorkspaceSyncPhase = Object.freeze({
23906
+ Idle: "idle",
23869
23907
  Probe: "probe",
23870
23908
  Offer: "offer",
23871
23909
  Lease: "lease",
@@ -23899,7 +23937,6 @@ var WorkspaceSyncWork = class {
23899
23937
  #rediscover;
23900
23938
  /** The route the directory's answer yields, recomputed once that answer is observed. */
23901
23939
  #reroute;
23902
- #placementFetch;
23903
23940
  #discoveredFrontier;
23904
23941
  #observePlacement;
23905
23942
  /** Ask the directory for the provider's current placement frontier this round although a
@@ -23908,19 +23945,14 @@ var WorkspaceSyncWork = class {
23908
23945
  #directoryAnswered;
23909
23946
  #placementFetched;
23910
23947
  /** A round which converged without leasing, finishing once placement alone is fetched. */
23911
- #afterPlacement;
23912
23948
  #leased = false;
23913
- #lease;
23914
23949
  #command;
23915
23950
  #requestId;
23916
23951
  #started;
23917
- #phase = WorkspaceSyncPhase.Lease;
23952
+ #state = { phase: WorkspaceSyncPhase.Idle };
23918
23953
  #localHead;
23919
23954
  #offerHead;
23920
23955
  #previousHead;
23921
- #fetchStarted;
23922
- #offerStarted;
23923
- #offerRequestId;
23924
23956
  #pushMillis = 0;
23925
23957
  #pushBytes = 0n;
23926
23958
  #desiredHead;
@@ -24015,7 +24047,7 @@ var WorkspaceSyncWork = class {
24015
24047
  throw new Error(`replica '${this.#binding.replicaId}' has no custody remote`);
24016
24048
  }
24017
24049
  if (this.#rediscover || this.#recheckPlacement || !this.#route?.placementObserved && !this.#route?.placementFrontier && !this.#kernel.resolveRef(this.#mount, this.#requestId, PLACEMENT_REF3)) {
24018
- this.#phase = WorkspaceSyncPhase.Discover;
24050
+ this.#state = { phase: WorkspaceSyncPhase.Discover };
24019
24051
  return this.#remember({
24020
24052
  case: "pending",
24021
24053
  value: create(CorrespondencePendingSchema, {
@@ -24035,13 +24067,13 @@ var WorkspaceSyncWork = class {
24035
24067
  #openRound() {
24036
24068
  if (this.#receiveState || this.#replaceLocalHead !== void 0) return this.#leaseEffect();
24037
24069
  if (!this.#localHead) return this.#leaseEffect();
24038
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
24070
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
24039
24071
  return this.#beginOffer(encodeInlineCustodyOffer({
24040
24072
  session: this.#binding.replicaId,
24041
- requestId: this.#offerRequestId,
24073
+ requestId,
24042
24074
  observedHead: this.#localHead,
24043
24075
  intents: []
24044
- }), true);
24076
+ }), { case: "awaiting", requestId }, true);
24045
24077
  }
24046
24078
  #offerOrReconcile() {
24047
24079
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
@@ -24062,13 +24094,13 @@ var WorkspaceSyncWork = class {
24062
24094
  throw new Error(`kernel did not classify transport for intent '${unspecified.intentId}'`);
24063
24095
  }
24064
24096
  if (suffix.length > 0) {
24065
- this.#offerStarted = this.#clock.monotonicNanoseconds();
24066
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
24097
+ const requestId2 = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
24098
+ const startedAt = this.#clock.monotonicNanoseconds();
24067
24099
  this.#offerAfterConverge = true;
24068
24100
  this.#rebaseFrom = this.#previousHead;
24069
24101
  return this.#beginOffer(encodeInlineCustodyOffer({
24070
24102
  session: this.#binding.replicaId,
24071
- requestId: this.#offerRequestId,
24103
+ requestId: requestId2,
24072
24104
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
24073
24105
  observedHead: this.#localHead,
24074
24106
  intents: suffix,
@@ -24079,17 +24111,17 @@ var WorkspaceSyncWork = class {
24079
24111
  this.#previousHead
24080
24112
  ) : void 0,
24081
24113
  fastForwardOnly: true
24082
- }));
24114
+ }), { case: "awaiting", requestId: requestId2, startedAt });
24083
24115
  }
24084
24116
  }
24085
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
24117
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
24086
24118
  return this.#beginOffer(encodeInlineCustodyOffer({
24087
24119
  session: this.#binding.replicaId,
24088
- requestId: this.#offerRequestId,
24120
+ requestId,
24089
24121
  baseHead: this.#previousHead,
24090
24122
  observedHead: this.#localHead,
24091
24123
  intents: []
24092
- }));
24124
+ }), { case: "awaiting", requestId });
24093
24125
  }
24094
24126
  /**
24095
24127
  * NO COMMON BASE — a round that cannot converge, and must not pay for history to find out.
@@ -24165,18 +24197,18 @@ var WorkspaceSyncWork = class {
24165
24197
  #pullBeforeOffer() {
24166
24198
  this.#offerAfterConverge = true;
24167
24199
  this.#rebaseFrom = this.#previousHead;
24168
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
24200
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
24169
24201
  return this.#beginOffer(encodeInlineCustodyOffer({
24170
24202
  session: this.#binding.replicaId,
24171
- requestId: this.#offerRequestId,
24203
+ requestId,
24172
24204
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
24173
24205
  observedHead: this.#localHead,
24174
24206
  intents: []
24175
- }));
24207
+ }), { case: "awaiting", requestId });
24176
24208
  }
24177
- #leaseEffect() {
24209
+ #leaseEffect(afterPlacement) {
24178
24210
  const token = this.#authToken();
24179
- this.#phase = WorkspaceSyncPhase.Lease;
24211
+ this.#state = { phase: WorkspaceSyncPhase.Lease, ...afterPlacement ? { afterPlacement } : {} };
24180
24212
  return this.#remember({
24181
24213
  case: "pending",
24182
24214
  value: create(CorrespondencePendingSchema, {
@@ -24205,35 +24237,38 @@ var WorkspaceSyncWork = class {
24205
24237
  `workspace sync '${this.workId}' expected effect '${expected}', received '${receipt.effectId}'`
24206
24238
  );
24207
24239
  }
24240
+ const state = this.#state;
24208
24241
  const previousReceipt = this.#lastReceiptEffectId;
24209
24242
  this.#lastReceiptEffectId = receipt.effectId;
24210
24243
  try {
24211
24244
  if (receipt.outcome.case === "failure") {
24212
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#openRound();
24245
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#openRound();
24213
24246
  return this.#transportFailure(
24214
24247
  receipt.outcome.value.message,
24215
24248
  receipt.outcome.value.reason === PeerEffectFailureReason.OFFLINE
24216
24249
  );
24217
24250
  }
24218
- if (this.#phase === WorkspaceSyncPhase.Offer || this.#phase === WorkspaceSyncPhase.Probe) return this.#acceptOffer(receipt);
24219
- if (this.#phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt);
24220
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
24221
- if (this.#phase === WorkspaceSyncPhase.Placement) {
24222
- if (!this.#placementFetch || !this.#lease) throw new Error("placement transfer lost its lease");
24223
- this.#placementFetch.accept(receipt);
24251
+ if (state.phase === WorkspaceSyncPhase.Offer || state.phase === WorkspaceSyncPhase.Probe) {
24252
+ return this.#acceptOffer(receipt, state);
24253
+ }
24254
+ if (state.phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt, state);
24255
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
24256
+ if (state.phase === WorkspaceSyncPhase.Placement) {
24257
+ state.transfer.accept(receipt);
24224
24258
  this.#placementFetched?.();
24225
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
24226
- return this.#beginMainFetch(this.#lease);
24259
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
24260
+ return this.#beginMainFetch(state.lease);
24227
24261
  }
24228
- if (this.#phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt);
24262
+ if (state.phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt, state);
24229
24263
  throw new Error(`workspace sync '${this.workId}' is already complete`);
24230
24264
  } catch (error) {
24231
24265
  this.#lastReceiptEffectId = previousReceipt;
24232
24266
  throw error;
24233
24267
  }
24234
24268
  }
24235
- #beginOffer(body, probe = false) {
24236
- this.#phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
24269
+ #beginOffer(body, exchange, probe = false) {
24270
+ const phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
24271
+ this.#state = { phase, exchange };
24237
24272
  const token = this.#authToken();
24238
24273
  this.#pushBytes += BigInt(body.byteLength);
24239
24274
  return this.#remember({
@@ -24243,7 +24278,7 @@ var WorkspaceSyncWork = class {
24243
24278
  effect: {
24244
24279
  case: "http",
24245
24280
  value: create(PeerHttpEffectSchema, {
24246
- effectId: `${this.workId}:${this.#phase}`,
24281
+ effectId: `${this.workId}:${phase}`,
24247
24282
  method: PeerHttpMethod.POST,
24248
24283
  url: this.#offerEndpoint(),
24249
24284
  contentType: CUSTODY_OFFER_MEDIA_TYPE,
@@ -24260,28 +24295,30 @@ var WorkspaceSyncWork = class {
24260
24295
  })
24261
24296
  });
24262
24297
  }
24263
- #acceptOffer(receipt) {
24264
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
24298
+ #acceptOffer(receipt, state) {
24299
+ const exchange = state.exchange;
24300
+ this.#pushMillis = exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, exchange.startedAt);
24265
24301
  if (receipt.outcome.case !== "response") {
24266
24302
  throw new Error("platform returned the wrong receipt for a custody offer");
24267
24303
  }
24268
- const response = receipt.outcome.value;
24269
- if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
24304
+ const outcome = settleCustodyOfferExchange(exchange, receipt.outcome.value);
24305
+ if (outcome.case === "maintenance") {
24306
+ return this.#finishOfferOutcome(true, false);
24307
+ }
24308
+ if (outcome.case === "unexpected") {
24270
24309
  this.#pushError = create(RuntimeTransportFailureSchema, {
24271
24310
  endpoint: this.#offerEndpoint(),
24272
- status: response.status,
24311
+ status: outcome.status,
24273
24312
  refused: false,
24274
- message: `Sync received an unexpected server response (HTTP ${response.status}; ${response.contentType || "no content type"}). No custody receipt was returned.`
24313
+ message: `Sync received an unexpected server response (HTTP ${outcome.status}; ${outcome.contentType || "no content type"}). No custody receipt was returned.`
24275
24314
  });
24276
24315
  return this.#finishOfferOutcome(false);
24277
24316
  }
24278
- if (!this.#offerRequestId) throw new Error("custody offer has no request identity");
24279
- const outcome = decodeCustodyOffer(response.body, this.#offerRequestId);
24280
- this.#offerReceipt = custodyOfferReceipt(this.#offerRequestId, outcome);
24317
+ this.#offerReceipt = outcome.receipt;
24281
24318
  if (outcome.case === "failure") {
24282
24319
  this.#pushError = create(RuntimeTransportFailureSchema, {
24283
24320
  endpoint: this.#offerEndpoint(),
24284
- status: response.status,
24321
+ status: outcome.status,
24285
24322
  refused: false,
24286
24323
  message: `${outcome.value.code}: ${outcome.value.message}`
24287
24324
  });
@@ -24290,12 +24327,12 @@ var WorkspaceSyncWork = class {
24290
24327
  if (outcome.case === "blocked") {
24291
24328
  return this.#finishOfferOutcome(true);
24292
24329
  }
24293
- if (response.status < 200 || response.status >= 300) {
24330
+ if (outcome.status < 200 || outcome.status >= 300) {
24294
24331
  this.#pushError = create(RuntimeTransportFailureSchema, {
24295
24332
  endpoint: this.#offerEndpoint(),
24296
- status: response.status,
24297
- refused: response.status === 422,
24298
- message: `custody offer returned an admission verdict with HTTP ${response.status}`
24333
+ status: outcome.status,
24334
+ refused: outcome.status === 422,
24335
+ message: `custody offer returned an admission verdict with HTTP ${outcome.status}`
24299
24336
  });
24300
24337
  return this.#finishOfferOutcome(false);
24301
24338
  }
@@ -24303,7 +24340,7 @@ var WorkspaceSyncWork = class {
24303
24340
  this.#desiredHead = admission.main || void 0;
24304
24341
  if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
24305
24342
  this.#candidateDurable = admission.sealedMain === this.#desiredHead;
24306
- if (this.#phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
24343
+ if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
24307
24344
  if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
24308
24345
  if (this.#alreadyJudged(this.#desiredHead)) {
24309
24346
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -24365,7 +24402,7 @@ var WorkspaceSyncWork = class {
24365
24402
  if (admission.recoveryRequired !== false) return this.#leaseEffect();
24366
24403
  return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
24367
24404
  }
24368
- #acceptLease(receipt) {
24405
+ #acceptLease(receipt, state) {
24369
24406
  if (receipt.outcome.case !== "response") {
24370
24407
  throw new Error("platform returned the wrong receipt for a Git read lease");
24371
24408
  }
@@ -24381,21 +24418,25 @@ var WorkspaceSyncWork = class {
24381
24418
  this.#leased = true;
24382
24419
  const frontier = this.#placementFrontier();
24383
24420
  if (frontier) {
24384
- this.#placementFetch = new PlacementFetch(
24421
+ const transfer = new PlacementFetch(
24385
24422
  this.#kernel,
24386
24423
  this.#mount,
24387
24424
  this.#requestId,
24388
24425
  this.workId,
24389
24426
  frontier
24390
24427
  );
24391
- const pending = this.#placementFetch.start(lease);
24428
+ const pending = transfer.start(lease);
24392
24429
  if (pending) {
24393
- this.#phase = WorkspaceSyncPhase.Placement;
24394
- this.#lease = lease;
24430
+ this.#state = {
24431
+ phase: WorkspaceSyncPhase.Placement,
24432
+ transfer,
24433
+ lease,
24434
+ ...state.afterPlacement ? { afterPlacement: state.afterPlacement } : {}
24435
+ };
24395
24436
  return this.#remember({ case: "pending", value: pending });
24396
24437
  }
24397
24438
  }
24398
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
24439
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
24399
24440
  return this.#beginMainFetch(lease);
24400
24441
  }
24401
24442
  /** The provider's placement frontier as this round knows it: what the directory named in this
@@ -24415,8 +24456,7 @@ var WorkspaceSyncWork = class {
24415
24456
  if (!new PlacementFetch(this.#kernel, this.#mount, this.#requestId, this.workId, frontier).wanted()) {
24416
24457
  return void 0;
24417
24458
  }
24418
- this.#afterPlacement = presented;
24419
- return this.#leaseEffect();
24459
+ return this.#leaseEffect(presented);
24420
24460
  }
24421
24461
  #acceptDiscovery(receipt) {
24422
24462
  this.#directoryAnswered?.();
@@ -24440,9 +24480,11 @@ var WorkspaceSyncWork = class {
24440
24480
  return this.#replaceLocalHead !== void 0 || this.#localHead === void 0 && this.#previousHead === void 0;
24441
24481
  }
24442
24482
  #beginMainFetch(lease) {
24443
- this.#phase = WorkspaceSyncPhase.Fetch;
24444
24483
  const lawProducts = this.#lawProductsAlongside();
24445
- this.#fetchStarted = this.#clock.monotonicNanoseconds();
24484
+ this.#state = {
24485
+ phase: WorkspaceSyncPhase.Fetch,
24486
+ startedAt: this.#clock.monotonicNanoseconds()
24487
+ };
24446
24488
  const haves = this.#replaceLocalHead !== void 0 ? this.#repairMissingCommit ? [] : [this.#kernel.resolveRef(this.#mount, this.#requestId, deferredRemote)].filter(
24447
24489
  (head) => !!head
24448
24490
  ) : [...new Set([
@@ -24473,7 +24515,7 @@ var WorkspaceSyncWork = class {
24473
24515
  })
24474
24516
  });
24475
24517
  }
24476
- #acceptFetch(receipt) {
24518
+ #acceptFetch(receipt, state) {
24477
24519
  if (receipt.outcome.case !== "gitFetch") {
24478
24520
  throw new Error("platform returned the wrong receipt for a Git object fetch");
24479
24521
  }
@@ -24483,7 +24525,7 @@ var WorkspaceSyncWork = class {
24483
24525
  if (fetched.pack.byteLength > 0) {
24484
24526
  this.#kernel.applyPack(this.#mount, this.#requestId, fetched.pack, fetched.head, fetched.shallow);
24485
24527
  }
24486
- const prefetchMillis = this.#fetchStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#fetchStarted);
24528
+ const prefetchMillis = elapsedMillis(this.#clock, state.startedAt);
24487
24529
  const candidateHead = this.#receiveState ? this.#kernel.resolveStatePosition?.(this.#mount, this.#requestId, fetched.head, this.#receiveState) : fetched.head;
24488
24530
  if (!candidateHead) {
24489
24531
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -24834,11 +24876,11 @@ var WorkspaceSyncWork = class {
24834
24876
  pushBytes: this.#pushBytes,
24835
24877
  pullBytes: BigInt(receivedBytes),
24836
24878
  serverMillis: this.#admissionSummary?.serverMillis ?? 0,
24837
- offerInPush: this.#offerRequestId !== void 0
24879
+ offerInPush: this.#pushBytes > 0n
24838
24880
  })
24839
24881
  });
24840
24882
  }
24841
- #finishOfferOutcome(blocked) {
24883
+ #finishOfferOutcome(blocked, reconnectRequired = true) {
24842
24884
  return this.#finish(create(SyncWorkspaceResponseSchema, {
24843
24885
  workspace: this.#mount.workspace,
24844
24886
  previousHead: this.#previousHead,
@@ -24846,7 +24888,7 @@ var WorkspaceSyncWork = class {
24846
24888
  admitted: BigInt(this.#admissionSummary?.admittedIntentIds.length ?? 0),
24847
24889
  refused: BigInt((this.#admissionSummary?.refusedMessages.length ?? 0) + this.#parkedLocal),
24848
24890
  deferred: BigInt(this.#admissionSummary ? this.#admissionSummary.blockedMessages.length + this.#admissionSummary.deadLetteredMessages.length + this.#admissionSummary.quarantinedMessages.length + this.#admissionSummary.deferredMessages.length : blocked ? 1 : 0),
24849
- reconnectRequired: true,
24891
+ reconnectRequired,
24850
24892
  stillAhead: this.#localHead !== this.#previousHead,
24851
24893
  directOfferDeferred: blocked,
24852
24894
  offerReceipt: this.#offerReceipt,
@@ -24860,15 +24902,16 @@ var WorkspaceSyncWork = class {
24860
24902
  }));
24861
24903
  }
24862
24904
  #transportFailure(message, offline, status = -1) {
24863
- const pushFailed = this.#phase === WorkspaceSyncPhase.Offer;
24905
+ const state = this.#state;
24906
+ const pushFailed = state.phase === WorkspaceSyncPhase.Offer;
24864
24907
  const failedEndpoint = this.#offerEndpoint();
24865
24908
  const failure = create(RuntimeTransportFailureSchema, {
24866
24909
  endpoint: pushFailed ? failedEndpoint : this.#binding.cloud ?? "",
24867
24910
  status,
24868
24911
  message
24869
24912
  });
24870
- if (pushFailed) {
24871
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
24913
+ if (state.phase === WorkspaceSyncPhase.Offer) {
24914
+ this.#pushMillis = state.exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, state.exchange.startedAt);
24872
24915
  this.#pushError = failure;
24873
24916
  }
24874
24917
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -24885,7 +24928,7 @@ var WorkspaceSyncWork = class {
24885
24928
  pushMillis: this.#pushMillis,
24886
24929
  pushBytes: this.#pushBytes,
24887
24930
  prefetchMillis: elapsedMillis(this.#clock, this.#started),
24888
- offerInPush: this.#offerRequestId !== void 0
24931
+ offerInPush: this.#pushBytes > 0n
24889
24932
  })
24890
24933
  }));
24891
24934
  }
@@ -24895,7 +24938,7 @@ var WorkspaceSyncWork = class {
24895
24938
  return step;
24896
24939
  }
24897
24940
  #finish(value) {
24898
- this.#phase = WorkspaceSyncPhase.Done;
24941
+ this.#state = { phase: WorkspaceSyncPhase.Done };
24899
24942
  this.#current = void 0;
24900
24943
  return this.#remember({ case: "synced", value });
24901
24944
  }