@salesforce/lds-worker-api 1.467.0 → 1.468.0

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.
@@ -4282,7 +4282,7 @@
4282
4282
  }
4283
4283
  callbacks.push(callback);
4284
4284
  }
4285
- // version: 1.467.0-4f065d2a2a
4285
+ // version: 1.468.0-9ef0fbdaee
4286
4286
 
4287
4287
  // TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
4288
4288
  function instrumentAdapter$1(createFunction, _metadata) {
@@ -5326,7 +5326,7 @@
5326
5326
  const { apiFamily, name } = metadata;
5327
5327
  return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
5328
5328
  }
5329
- // version: 1.467.0-4f065d2a2a
5329
+ // version: 1.468.0-9ef0fbdaee
5330
5330
 
5331
5331
  function isSupportedEntity(_objectApiName) {
5332
5332
  return true;
@@ -32571,7 +32571,7 @@
32571
32571
  throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
32572
32572
  throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
32573
32573
  });
32574
- // version: 1.467.0-049a8b6027
32574
+ // version: 1.468.0-c060a9b9c6
32575
32575
 
32576
32576
  var draftQueueMaxRetryAttemptsGate = {
32577
32577
  isOpen: function (e) {
@@ -32652,6 +32652,15 @@
32652
32652
  },
32653
32653
  };
32654
32654
 
32655
+ var sideEffectRefreshKillSwitch = {
32656
+ isOpen: function (e) {
32657
+ return e.fallback;
32658
+ },
32659
+ hasError: function () {
32660
+ return !0;
32661
+ },
32662
+ };
32663
+
32655
32664
  var caseSensitiveUserId = '005B0000000GR4OIAW';
32656
32665
 
32657
32666
  /**
@@ -48707,6 +48716,48 @@
48707
48716
  await this.startQueue();
48708
48717
  }
48709
48718
  }
48719
+ /**
48720
+ * Builds the set of actions deleted by removing `action`, validating
48721
+ * before any store mutation. Same-tag actions are ordered newest-first so
48722
+ * the clicked create is handled last and each intermediate side-effect
48723
+ * replay reflects a valid undo prefix.
48724
+ */
48725
+ resolveActionsToRemove(action, queue, isUploading) {
48726
+ const shouldDeleteRelated = this.getHandler(action.handler).shouldDeleteActionByTagOnRemoval(action);
48727
+ const removedActions = shouldDeleteRelated
48728
+ ? queue.filter((a) => a.tag === action.tag).reverse()
48729
+ : [action];
48730
+ const uploading = removedActions.find((a) => isUploading(a.id));
48731
+ if (uploading !== undefined) {
48732
+ // eslint-disable-next-line @salesforce/lds/no-error-in-production
48733
+ throw new Error(`Cannot remove an uploading draft action with ID ${uploading.id}`);
48734
+ }
48735
+ return {
48736
+ shouldDeleteRelated,
48737
+ removed: removedActions.map((a) => ({
48738
+ action: a,
48739
+ handler: this.getHandler(a.handler),
48740
+ })),
48741
+ };
48742
+ }
48743
+ /**
48744
+ * Runs every removed action's handler cleanup before emitting any
48745
+ * ActionDeleted event, so listeners observe the final side-effect state.
48746
+ */
48747
+ async notifyActionsRemoved(removed, queue) {
48748
+ const removedIds = new Set(removed.map(({ action }) => action.id));
48749
+ const remaining = queue.filter((a) => !removedIds.has(a.id));
48750
+ for (const { action, handler } of removed) {
48751
+ await handler.handleActionRemoved(action, remaining);
48752
+ }
48753
+ for (const { action } of removed) {
48754
+ await this.notifyChangedListeners({
48755
+ type: DraftQueueEventType.ActionDeleted,
48756
+ action,
48757
+ draftCount: this.draftStore.getCount(),
48758
+ });
48759
+ }
48760
+ }
48710
48761
  async removeDraftAction(actionId) {
48711
48762
  const queue = await this.getQueueActions();
48712
48763
  //Get the store key for the removed action
@@ -48716,32 +48767,18 @@
48716
48767
  throw new Error(`No removable action with id ${actionId}`);
48717
48768
  }
48718
48769
  const action = actions[0];
48719
- if (action.id === this.uploadingActionId) {
48720
- // eslint-disable-next-line @salesforce/lds/no-error-in-production
48721
- throw new Error(`Cannot remove an uploading draft action with ID ${actionId}`);
48722
- }
48723
- const handler = this.getHandler(action.handler);
48724
- const shouldDeleteRelated = handler.shouldDeleteActionByTagOnRemoval(action);
48770
+ const { shouldDeleteRelated, removed } = this.resolveActionsToRemove(action, queue, (id) => id === this.uploadingActionId);
48725
48771
  if (shouldDeleteRelated) {
48726
48772
  await this.draftStore.deleteByTag(action.tag);
48727
- queue.forEach((queuedAction) => {
48728
- if (queuedAction.tag === action.tag) {
48729
- this.uploadStartTimes.delete(queuedAction.id);
48730
- this.actionQueueWaitEmittedIds.delete(queuedAction.id);
48731
- }
48732
- });
48733
48773
  }
48734
48774
  else {
48735
48775
  await this.draftStore.deleteDraft(action.id);
48736
- this.uploadStartTimes.delete(action.id);
48737
- this.actionQueueWaitEmittedIds.delete(action.id);
48738
48776
  }
48739
- await handler.handleActionRemoved(action, queue.filter((x) => x.id !== actionId));
48740
- await this.notifyChangedListeners({
48741
- type: DraftQueueEventType.ActionDeleted,
48742
- action,
48743
- draftCount: this.draftStore.getCount(),
48777
+ removed.forEach(({ action: a }) => {
48778
+ this.uploadStartTimes.delete(a.id);
48779
+ this.actionQueueWaitEmittedIds.delete(a.id);
48744
48780
  });
48781
+ await this.notifyActionsRemoved(removed, queue);
48745
48782
  if (this.userState === DraftQueueState.Started &&
48746
48783
  this.state !== DraftQueueState.Started &&
48747
48784
  this.replacingAction === undefined) {
@@ -48780,15 +48817,12 @@
48780
48817
  return this.replaceOrMergeActions(targetActionId, sourceActionId, true);
48781
48818
  }
48782
48819
  async retryAction(actionId) {
48783
- this.stopQueueManually(true);
48784
- const actions = await this.getQueueActions();
48785
- const target = actions[0];
48786
- if (!target || target.id !== actionId) {
48787
- throw Error(`Action ${actionId} not found at the head of the draft queue`);
48788
- }
48820
+ // Validate before stopping so a rejected retry leaves the queue state untouched.
48821
+ const target = await this.getRetryTarget(actionId);
48789
48822
  if (!isDraftError(target)) {
48790
48823
  throw Error(`Action ${actionId} is not in Error state`);
48791
48824
  }
48825
+ this.stopQueueManually(true);
48792
48826
  // A manual retry is a fresh start: clear the persisted upload retry-attempt
48793
48827
  // count so the action doesn't immediately re-cap after a single failure.
48794
48828
  const { [DRAFT_ACTION_RETRY_COUNT_METADATA_KEY]: _retryCount, ...metadataWithoutRetryCount } = target.metadata || {};
@@ -48807,6 +48841,18 @@
48807
48841
  await this.startQueueSafe();
48808
48842
  return pendingAction;
48809
48843
  }
48844
+ /**
48845
+ * The action `retryAction` may retry. Only the head: an errored head is what blocks a
48846
+ * strictly ordered queue.
48847
+ */
48848
+ async getRetryTarget(actionId) {
48849
+ const actions = await this.getQueueActions();
48850
+ const target = actions[0];
48851
+ if (!target || target.id !== actionId) {
48852
+ throw Error(`Action ${actionId} not found at the head of the draft queue`);
48853
+ }
48854
+ return target;
48855
+ }
48810
48856
  async setMetadata(actionId, metadata) {
48811
48857
  const keys$1 = keys$4(metadata);
48812
48858
  const compatibleKeys = keys$1.filter((key) => {
@@ -50409,27 +50455,17 @@
50409
50455
  throw new Error(`No removable action with id ${actionId}`);
50410
50456
  }
50411
50457
  const action = actions[0];
50412
- if (this.uploadingActionIds.has(action.id)) {
50413
- // eslint-disable-next-line @salesforce/lds/no-error-in-production
50414
- throw new Error(`Cannot remove an uploading draft action with ID ${actionId}`);
50415
- }
50458
+ const { shouldDeleteRelated, removed } = this.resolveActionsToRemove(action, queue, (id) => this.uploadingActionIds.has(id));
50416
50459
  // A removed action must not leave a dangling backoff timer that would
50417
50460
  // later fire and re-drive the scheduler for an id that no longer exists.
50418
- this.clearActionRetry(action.id);
50419
- const handler = this.getHandler(action.handler);
50420
- const shouldDeleteRelated = handler.shouldDeleteActionByTagOnRemoval(action);
50461
+ removed.forEach(({ action: a }) => this.clearActionRetry(a.id));
50421
50462
  if (shouldDeleteRelated) {
50422
50463
  await this.draftStore.deleteByTag(action.tag);
50423
50464
  }
50424
50465
  else {
50425
50466
  await this.draftStore.deleteDraft(action.id);
50426
50467
  }
50427
- await handler.handleActionRemoved(action, queue.filter((x) => x.id !== actionId));
50428
- await this.notifyChangedListeners({
50429
- type: DraftQueueEventType.ActionDeleted,
50430
- action,
50431
- draftCount: this.draftStore.getCount(),
50432
- });
50468
+ await this.notifyActionsRemoved(removed, queue);
50433
50469
  if (this.userState === DraftQueueState.Started &&
50434
50470
  this.state !== DraftQueueState.Started &&
50435
50471
  this.replacingAction === undefined) {
@@ -50568,6 +50604,27 @@
50568
50604
  }
50569
50605
  return super.startQueue();
50570
50606
  }
50607
+ /**
50608
+ * The head of the shared store may belong to the other queue, so targets are resolved
50609
+ * against the actions this queue owns. With strict ordering only the owned head can be
50610
+ * retried (it is what blocks dispatch); without it an errored action blocks nothing, so
50611
+ * any errored action this queue owns can be retried.
50612
+ */
50613
+ async getRetryTarget(actionId) {
50614
+ const owned = await this.getOwnedQueueActions();
50615
+ if (this.strictOrdering) {
50616
+ const head = owned[0];
50617
+ if (!head || head.id !== actionId) {
50618
+ throw Error(`Action ${actionId} not found at the head of the draft queue`);
50619
+ }
50620
+ return head;
50621
+ }
50622
+ const target = owned.find((action) => action.id === actionId);
50623
+ if (target === undefined) {
50624
+ throw Error(`Action ${actionId} not found in the draft queue`);
50625
+ }
50626
+ return target;
50627
+ }
50571
50628
  async retryAllErrors() {
50572
50629
  const actions = await this.getOwnedQueueActions();
50573
50630
  const errored = actions.filter((a) => a.status === DraftActionStatus.Error);
@@ -50672,6 +50729,8 @@
50672
50729
  removeHandler(id) {
50673
50730
  return this.primary.removeHandler(id);
50674
50731
  }
50732
+ // Removes only the action itself. Removing a binary action through RoutingDraftManager also
50733
+ // removes the serial actions that depend on it; this façade does not.
50675
50734
  async removeDraftAction(actionId) {
50676
50735
  const owner = await this.routeByActionId(actionId);
50677
50736
  return owner.removeDraftAction(actionId);
@@ -51113,27 +51172,12 @@
51113
51172
  return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
51114
51173
  }
51115
51174
 
51116
- function hasGetOwnedQueueActions(queue) {
51117
- return typeof queue.getOwnedQueueActions === 'function';
51118
- }
51119
- function hasGetCreatedDraftIds(queue) {
51120
- return typeof queue.getCreatedDraftIds === 'function';
51121
- }
51122
- function hasGetOwnedActionsReferencing(queue) {
51123
- return typeof queue.getOwnedActionsReferencing === 'function';
51124
- }
51125
- function hasRetryAllErrors(queue) {
51126
- return typeof queue.retryAllErrors === 'function';
51127
- }
51128
51175
  /**
51129
51176
  * Gate-ON DraftManager: the concurrent-binary upload variant, instantiated only when the
51130
51177
  * `concurrentBinaryQueue` feature flag is on. It wraps a strict-ordering serial draft queue
51131
51178
  * plus a parallel binary queue over one shared store, stamps each draft's routing `lane`, and
51132
- * drives the binary-queue lifecycle/read methods the native Pending Images UI consumes.
51133
- *
51134
- * The base `DraftManager` (gate-OFF) keeps every one of these methods as an inert stub so the
51135
- * native bridge surface is identical regardless of the flag; this subclass supplies the real
51136
- * behavior. Current (non-SCE) users never instantiate this class — they run the unchanged base.
51179
+ * routes lifecycle, remove, and retry calls to the queue that owns each action. Current
51180
+ * (non-SCE) users never instantiate this class — they run the unchanged base.
51137
51181
  */
51138
51182
  class RoutingDraftManager extends DraftManager {
51139
51183
  constructor(draftQueue, binaryQueue, laneLabels) {
@@ -51143,6 +51187,7 @@
51143
51187
  __nimbus.plugins.JSLoggerPlugin !== undefined
51144
51188
  ? __nimbus.plugins.JSLoggerPlugin
51145
51189
  : undefined;
51190
+ this.serialQueue = draftQueue;
51146
51191
  this.binaryQueue = binaryQueue;
51147
51192
  this.laneLabels = laneLabels;
51148
51193
  // Surface binary-queue change events through the same listener pipeline as the serial
@@ -51157,21 +51202,6 @@
51157
51202
  }))
51158
51203
  .then(toQueueState(this.draftQueue));
51159
51204
  }
51160
- /**
51161
- * Get the current state of each of the DraftActions in the binary DraftQueue
51162
- * (ContentDocument/Version/Link uploads).
51163
- */
51164
- getBinaryQueue() {
51165
- const queue = this.binaryQueue;
51166
- const getActions = hasGetOwnedQueueActions(queue)
51167
- ? queue.getOwnedQueueActions()
51168
- : queue.getQueueActions();
51169
- return getActions
51170
- .then((queueActions) => {
51171
- return queueActions.map(this.buildDraftQueueItem);
51172
- })
51173
- .then(toQueueState(queue));
51174
- }
51175
51205
  /**
51176
51206
  * Starts both the serial and binary draft queues and begins processing their items.
51177
51207
  */
@@ -51186,40 +51216,58 @@
51186
51216
  return Promise.all([this.draftQueue.stopQueue(), this.binaryQueue.stopQueue()]).then(() => undefined);
51187
51217
  }
51188
51218
  /**
51189
- * Starts the binary draft queue (for ContentDocument/Version/Link uploads). Separate from
51190
- * startQueue() so the binary queue can be paused/resumed independently from the regular
51191
- * draft queue and from stopQueueWhileRunning() interruptions.
51219
+ * Pauses both queues while `action` runs. Nests each queue's own stopQueueWhileRunning so
51220
+ * each restarts afterwards only if it was user-started before.
51192
51221
  */
51193
- startBinaryQueue() {
51194
- return this.binaryQueue.startQueue();
51195
- }
51196
- /** Stops the binary draft queue; pairs with startBinaryQueue(). */
51197
- stopBinaryQueue() {
51198
- return this.binaryQueue.stopQueue();
51222
+ stopQueueWhileRunning(action) {
51223
+ return this.draftQueue.stopQueueWhileRunning(() => this.binaryQueue.stopQueueWhileRunning(action));
51199
51224
  }
51200
51225
  async retryAllErrors() {
51201
- if (hasRetryAllErrors(this.draftQueue)) {
51202
- await this.draftQueue.retryAllErrors();
51203
- }
51204
- if (hasRetryAllErrors(this.binaryQueue)) {
51205
- await this.binaryQueue.retryAllErrors();
51206
- }
51226
+ await this.serialQueue.retryAllErrors();
51227
+ await this.binaryQueue.retryAllErrors();
51207
51228
  }
51208
51229
  /**
51209
51230
  * Routes the remove to the queue that owns the action. The serial queue reads the shared
51210
51231
  * store, so it sees binary-owned actions too, but has no handler registered for them and
51211
51232
  * would throw.
51233
+ *
51234
+ * A binary remove pauses the serial queue so a dependent can't start uploading between the
51235
+ * uploading check and its removal. Only the serial queue: stopping the binary queue would
51236
+ * clear every binary action's retry backoff. The serial queue's own removeDraftAction
51237
+ * restarts it, so the pause covers the first dependent only.
51212
51238
  */
51213
51239
  removeDraftAction(actionId) {
51214
51240
  return this.binaryActionsById()
51215
51241
  .then((binaryById) => {
51216
51242
  const binaryAction = binaryById.get(actionId);
51217
51243
  return binaryAction !== undefined
51218
- ? this.removeBinaryActionAndDependents(binaryAction)
51244
+ ? this.serialQueue.stopQueueWhileRunning(() => this.removeBinaryActionAndDependents(binaryAction))
51219
51245
  : this.draftQueue.removeDraftAction(actionId);
51220
51246
  })
51221
51247
  .then(() => this.getQueue());
51222
51248
  }
51249
+ /**
51250
+ * Routes to the queue that owns the action, for the same reason as removeDraftAction.
51251
+ * Native sets metadata on every image upload right after enqueueing it, so a serial-only
51252
+ * setMetadata fails the upload call and native never links the image to its record.
51253
+ */
51254
+ async setMetadata(actionId, metadata) {
51255
+ const binaryById = await this.binaryActionsById();
51256
+ if (!binaryById.has(actionId)) {
51257
+ return super.setMetadata(actionId, metadata);
51258
+ }
51259
+ const updated = await this.binaryQueue.setMetadata(actionId, metadata);
51260
+ return this.buildDraftQueueItem(this.stampLane(updated, true));
51261
+ }
51262
+ /** Routes to the queue that owns the action, for the same reason as removeDraftAction. */
51263
+ async retryAction(actionId) {
51264
+ const binaryById = await this.binaryActionsById();
51265
+ if (!binaryById.has(actionId)) {
51266
+ return super.retryAction(actionId);
51267
+ }
51268
+ const retried = await this.binaryQueue.retryAction(actionId);
51269
+ return this.buildDraftQueueItem(this.stampLane(retried, true));
51270
+ }
51223
51271
  /**
51224
51272
  * Removes a binary action plus the serial actions that reference a draft id it creates
51225
51273
  * (e.g. the ContentDocumentLink native enqueues to link an uploaded image to a record).
@@ -51257,29 +51305,17 @@
51257
51305
  }
51258
51306
  }
51259
51307
  serialActionsDependingOn(action) {
51260
- const binary = this.binaryQueue;
51261
- const serial = this.draftQueue;
51262
- if (!hasGetCreatedDraftIds(binary) || !hasGetOwnedActionsReferencing(serial)) {
51263
- return Promise.resolve([]);
51264
- }
51265
- const draftIds = binary.getCreatedDraftIds(action);
51308
+ const draftIds = this.binaryQueue.getCreatedDraftIds(action);
51266
51309
  return draftIds.length === 0
51267
51310
  ? Promise.resolve([])
51268
- : serial.getOwnedActionsReferencing(draftIds);
51311
+ : this.serialQueue.getOwnedActionsReferencing(draftIds);
51269
51312
  }
51270
51313
  /**
51271
51314
  * Binary-lane actions keyed by id, carrying the lane's transient `Uploading` status.
51272
51315
  * `getQueue` uses it to stamp the `concurrentBinary` lane and source the correct status.
51273
- * An empty map means "treat every action as serial" — returned both when the binary queue
51274
- * can't report ownership and (harmlessly) when it is simply empty; the caller doesn't need
51275
- * to tell those apart.
51276
51316
  */
51277
51317
  binaryActionsById() {
51278
- const binary = this.binaryQueue;
51279
- if (!hasGetOwnedQueueActions(binary)) {
51280
- return Promise.resolve(new Map());
51281
- }
51282
- return binary
51318
+ return this.binaryQueue
51283
51319
  .getOwnedQueueActions()
51284
51320
  .then((actions) => new Map(actions.map((action) => [action.id, action])));
51285
51321
  }
@@ -83821,6 +83857,12 @@
83821
83857
  // debug-only
83822
83858
  }
83823
83859
  }
83860
+ // Ingestion timestamp that makes the uploaded record stale for the next read. Ingested at
83861
+ // epoch+1 the record is expired under any ttl: the record ttl, a record ttl override, the
83862
+ // default ttl override or a host metadata ttl. (Not 0, which falsy checks treat as missing.)
83863
+ // Expiring it with luvio.storeExpirePossibleStaleRecords or a 0 ttl does not work when a ttl
83864
+ // override is set, since the override replaces the ttl.
83865
+ const STALE_INGESTION_TIMESTAMP = 1;
83824
83866
  class UiApiActionHandler extends AbstractResourceRequestActionHandler {
83825
83867
  constructor(getLuvio, networkAdapter, draftQueue, getRecordAdapter, objectInfoService, isDraftId, recordService, sideEffectService, durableRecordStore) {
83826
83868
  super(draftQueue, networkAdapter, getLuvio, recordService);
@@ -83835,6 +83877,8 @@
83835
83877
  this.durableRecordStore = durableRecordStore;
83836
83878
  this.handlerId = LDS_ACTION_HANDLER_ID;
83837
83879
  this.sideEffectHooks = [];
83880
+ // side effect field values of the create actions being completed, by action id
83881
+ this.injectedFieldsByActionId = new Map();
83838
83882
  recordService.registerRecordHandler(this);
83839
83883
  }
83840
83884
  setSideEffectHooks(hooks) {
@@ -83945,7 +83989,40 @@
83945
83989
  await this.evictKey(completedAction.tag);
83946
83990
  return;
83947
83991
  }
83948
- return super.handleActionCompleted(completedAction, queueOperations);
83992
+ if (method !== 'post') {
83993
+ return super.handleActionCompleted(completedAction, queueOperations);
83994
+ }
83995
+ // super removes the action's side effects before it ingests the response, so what the
83996
+ // create's side effects set has to be captured first
83997
+ const injectedFields = this.getFieldsToInject(completedAction);
83998
+ if (injectedFields !== undefined) {
83999
+ this.injectedFieldsByActionId.set(completedAction.id, injectedFields);
84000
+ }
84001
+ try {
84002
+ await super.handleActionCompleted(completedAction, queueOperations);
84003
+ }
84004
+ finally {
84005
+ this.injectedFieldsByActionId.delete(completedAction.id);
84006
+ }
84007
+ }
84008
+ // The create response only has the fields that were requested, so a field that only a side
84009
+ // effect sets (e.g. ProductConsumed.IsProduct2Serialized) is missing from the cached
84010
+ // server record once the draft's effects are gone. Returns the values of those fields.
84011
+ // Only called for a POST: handleActionCompleted hands every other method straight to super.
84012
+ getFieldsToInject(completedAction) {
84013
+ if (sideEffectRefreshKillSwitch.isOpen({ fallback: false })) {
84014
+ return undefined;
84015
+ }
84016
+ const fields = {};
84017
+ this.recordService.getEffectsForAction(completedAction).forEach((effect) => {
84018
+ if (effect.type === 'record-field-set' && effect.key === completedAction.tag) {
84019
+ fields[effect.fieldName] = { value: effect.value, displayValue: null };
84020
+ }
84021
+ });
84022
+ if (keys$3(fields).length === 0) {
84023
+ return undefined;
84024
+ }
84025
+ return fields;
83949
84026
  }
83950
84027
  async fetchReferenceRecord(referenceFields) {
83951
84028
  const promises = referenceFields.map(async (referenceFieldInfo) => {
@@ -84608,10 +84685,35 @@
84608
84685
  getTypeCacheKeys$1u$1(cacheKeys, this.getLuvio(), record);
84609
84686
  return cacheKeys;
84610
84687
  }
84611
- synchronousIngest(response) {
84688
+ synchronousIngest(response, action) {
84612
84689
  const luvio = this.getLuvio();
84690
+ const injected = this.injectedFieldsByActionId.get(action.id);
84691
+ if (injected === undefined) {
84692
+ const key = keyBuilderFromType$g(luvio, response);
84693
+ luvio.storeIngest(key, ingest$1o$1, response);
84694
+ return;
84695
+ }
84696
+ // never replace what the server sent
84697
+ const fields = { ...response.fields };
84698
+ let injectedAny = false;
84699
+ keys$3(injected).forEach((fieldName) => {
84700
+ if (fields[fieldName] === undefined) {
84701
+ fields[fieldName] = injected[fieldName];
84702
+ injectedAny = true;
84703
+ }
84704
+ });
84613
84705
  const key = keyBuilderFromType$g(luvio, response);
84614
- luvio.storeIngest(key, ingest$1o$1, response);
84706
+ luvio.storeIngest(key, ingest$1o$1, { ...response, fields });
84707
+ if (injectedAny) {
84708
+ // after ingestRecord, which publishes the metadata with a fresh ttl
84709
+ luvio.publishStoreMetadata(key, {
84710
+ ttl: TTL$k,
84711
+ representationName: 'RecordRepresentation',
84712
+ namespace: 'UiApi',
84713
+ version: VERSION$1v$1,
84714
+ ingestionTimestamp: STALE_INGESTION_TIMESTAMP,
84715
+ });
84716
+ }
84615
84717
  }
84616
84718
  mergeRequestBody(targetBody, sourceBody) {
84617
84719
  // IMPORTANT: spread operator isn't deep clone so we have to individually
@@ -84681,6 +84783,10 @@
84681
84783
  await this.sideEffectStore.removeEffects(operations);
84682
84784
  return new Set(operations.map((o) => o.key));
84683
84785
  }
84786
+ // returns the side effects queued for the given action, oldest first
84787
+ getEffectsForAction(action) {
84788
+ return this.sideEffectStore.getEffectsByTag(action.id);
84789
+ }
84684
84790
  // reads a set of records out of the durable store, re-applies current side
84685
84791
  // effects and persists the changed record
84686
84792
  async reapplyRecordSideEffects(recordKeys, lifecycle) {
@@ -93617,21 +93723,10 @@
93617
93723
  *
93618
93724
  * This instance is leveraged in the LMR webview which proxies DraftQueue requests
93619
93725
  * to a concrete implementation running in jscore.
93620
- *
93621
- * The Nimbus plugin name targeted by this proxy can be parameterized via the
93622
- * constructor (defaults to 'LdsDraftQueue'); pass 'LdsPerformanceDraftQueue' to
93623
- * target the primer's Performance Upload draft queue.
93624
93726
  */
93625
93727
  class NimbusDraftQueue {
93626
- constructor(pluginName = 'LdsDraftQueue') {
93627
- this.pluginName = pluginName;
93628
- }
93629
- get callProxyMethod() {
93630
- const plugin = __nimbus.plugins[this.pluginName];
93631
- return plugin && plugin.callProxyMethod;
93632
- }
93633
93728
  enqueue(handlerId, data, observabilityContext) {
93634
- const callProxyMethod = this.callProxyMethod;
93729
+ const callProxyMethod = __nimbus.plugins.LdsDraftQueue.callProxyMethod;
93635
93730
  if (callProxyMethod === undefined) {
93636
93731
  return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
93637
93732
  }
@@ -93658,7 +93753,7 @@
93658
93753
  return Promise.reject(new Error('Cannot call processNextAction from the NimbusDraftQueue'));
93659
93754
  }
93660
93755
  getQueueActions() {
93661
- const callProxyMethod = this.callProxyMethod;
93756
+ const callProxyMethod = __nimbus.plugins.LdsDraftQueue.callProxyMethod;
93662
93757
  if (callProxyMethod === undefined) {
93663
93758
  return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
93664
93759
  }
@@ -93671,7 +93766,7 @@
93671
93766
  });
93672
93767
  }
93673
93768
  getDataForAction(action) {
93674
- const callProxyMethod = this.callProxyMethod;
93769
+ const callProxyMethod = __nimbus.plugins.LdsDraftQueue.callProxyMethod;
93675
93770
  if (callProxyMethod === undefined) {
93676
93771
  return Promise.reject('callProxyMethod not defined on the nimbus plugin');
93677
93772
  }
@@ -93877,7 +93972,7 @@
93877
93972
  if (typeof __nimbus !== 'undefined' &&
93878
93973
  __nimbus.plugins !== undefined &&
93879
93974
  __nimbus.plugins.LdsDraftQueue !== undefined) {
93880
- return new NimbusDraftQueue('LdsDraftQueue');
93975
+ return new NimbusDraftQueue();
93881
93976
  }
93882
93977
  // Legacy gate-OFF path: no shared store / options → today's plain queue.
93883
93978
  if (draftStore === undefined && options === undefined) {
@@ -93892,14 +93987,10 @@
93892
93987
  }
93893
93988
  /**
93894
93989
  * Builds the Performance Upload draft queue (ContentDocument/Version/Link
93895
- * multipart uploads, concurrency > 1). Only constructed on the gate-ON path.
93990
+ * multipart uploads, concurrency > 1). Only constructed on the gate-ON path, in the
93991
+ * worker realm.
93896
93992
  */
93897
93993
  function buildLdsPerformanceDraftQueue(durableStore, draftStore, options) {
93898
- if (typeof __nimbus !== 'undefined' &&
93899
- __nimbus.plugins !== undefined &&
93900
- __nimbus.plugins.LdsPerformanceDraftQueue !== undefined) {
93901
- return new NimbusDraftQueue('LdsPerformanceDraftQueue');
93902
- }
93903
93994
  const store = draftStore ?? new DurableDraftStore(durableStore);
93904
93995
  const draftQueue = new PerformanceDraftQueue(store, options);
93905
93996
  return instrumentDraftQueue(draftQueue);
@@ -98827,7 +98918,10 @@
98827
98918
  if (isSubscribableResult(newResult)) {
98828
98919
  const value = newResult.isOk() ? ok$1(newResult.value.data) : err$1(newResult.error.failure);
98829
98920
  this.subscriptions.forEach((cb) => {
98830
- cb(value);
98921
+ try {
98922
+ cb(value);
98923
+ } catch {
98924
+ }
98831
98925
  });
98832
98926
  }
98833
98927
  return ok$1(void 0);
@@ -99769,7 +99863,10 @@
99769
99863
  if (isSubscribableResult(newResult)) {
99770
99864
  const value = newResult.isOk() ? ok$1(newResult.value.data) : err$1(newResult.error.failure);
99771
99865
  this.subscriptions.forEach((cb) => {
99772
- cb(value);
99866
+ try {
99867
+ cb(value);
99868
+ } catch {
99869
+ }
99773
99870
  });
99774
99871
  }
99775
99872
  return ok$1(void 0);
@@ -99791,6 +99888,79 @@
99791
99888
  }
99792
99889
  };
99793
99890
  }
99891
+ function fetchFromNetwork(getRequest, hooks, contextSeed) {
99892
+ try {
99893
+ const {
99894
+ services,
99895
+ params: [input, init],
99896
+ operationType,
99897
+ requestOptions
99898
+ } = getRequest();
99899
+ const initWithOptions = applyOperationRequestOptions$1(init, operationType, requestOptions);
99900
+ const seed = operationType === void 0 ? contextSeed : { operationType, ...contextSeed };
99901
+ const initWithSeed = seed === void 0 ? initWithOptions : { ...initWithOptions, __contextSeed: seed };
99902
+ const fetchCall = initWithSeed === void 0 ? services.fetch(input) : services.fetch(input, initWithSeed);
99903
+ return convertFetchResponseToData(fetchCall, hooks);
99904
+ } catch (reason) {
99905
+ return resolvedPromiseLike$2(err$1(toError(reason)));
99906
+ }
99907
+ }
99908
+ function convertFetchResponseToData(response, hooks) {
99909
+ return response.then(
99910
+ (response2) => {
99911
+ if (response2.ok) {
99912
+ let resultPromise;
99913
+ if (hooks.isSemanticNullResponse(response2)) {
99914
+ resultPromise = Promise.resolve(ok$1(null));
99915
+ } else if (hooks.isProtocolNoBodyStatus(response2.status) && !hooks.isSemanticNullResponse(response2)) {
99916
+ resultPromise = Promise.resolve(
99917
+ err$1(
99918
+ toError(
99919
+ `Unexpected ${response2.status} response: no-content status was not declared in the API specification. Declare this response in your OAS without a content property.`
99920
+ )
99921
+ )
99922
+ );
99923
+ } else {
99924
+ resultPromise = response2.json().then(
99925
+ (json) => ok$1(json),
99926
+ (reason) => err$1(toError(reason))
99927
+ );
99928
+ }
99929
+ return resultPromise.finally(() => {
99930
+ try {
99931
+ hooks.afterRequestHooks({ statusCode: response2.status });
99932
+ } catch {
99933
+ }
99934
+ });
99935
+ } else {
99936
+ return hooks.coerceError(response2).then((coercedError) => {
99937
+ return err$1(coercedError);
99938
+ }).finally(() => {
99939
+ try {
99940
+ hooks.afterRequestHooks({ statusCode: response2.status });
99941
+ } catch {
99942
+ }
99943
+ });
99944
+ }
99945
+ },
99946
+ (reason) => err$1(toError(reason))
99947
+ );
99948
+ }
99949
+ function completeRefresh(result, getSubscriptions, options = {}) {
99950
+ const { previousResult } = options;
99951
+ if (!options.suppressEqualSuccesses || result.isErr() || !previousResult || previousResult.isErr() || !deepEquals$1(previousResult.value, result.value)) {
99952
+ const subscriptions = getSubscriptions();
99953
+ const callbacks = options.skipRemovedSubscriptions ? [...subscriptions] : subscriptions;
99954
+ callbacks.forEach((callback) => {
99955
+ if (options.skipRemovedSubscriptions && !getSubscriptions().includes(callback)) return;
99956
+ try {
99957
+ callback(result);
99958
+ } catch {
99959
+ }
99960
+ });
99961
+ }
99962
+ return options.reportFailure && result.isErr() ? result : ok$1(void 0);
99963
+ }
99794
99964
  function isAbortableCommand(command) {
99795
99965
  return !!command && typeof command === "object" && "isAbortableCommand" in command && command.isAbortableCommand === true;
99796
99966
  }
@@ -99819,18 +99989,18 @@
99819
99989
  }
99820
99990
  if (prop === "fetchParams") {
99821
99991
  const originalFetchParams = Reflect.get(target, prop, receiver);
99822
- const isInternal = Reflect.get(target, "isInternalExecution", receiver) === true;
99992
+ const suppressAbortSignal = Reflect.get(target, "isInternalExecution", receiver) === true;
99823
99993
  if (typeof originalFetchParams === "function") {
99824
99994
  return function(...args) {
99825
99995
  const originalReturnValue = originalFetchParams.apply(this, args);
99826
- if (!isInternal) {
99996
+ if (!suppressAbortSignal) {
99827
99997
  const [url, init = {}] = originalReturnValue;
99828
99998
  return [url, { signal, ...init }];
99829
99999
  }
99830
100000
  return originalReturnValue;
99831
100001
  };
99832
100002
  } else {
99833
- if (!isInternal && originalFetchParams && Array.isArray(originalFetchParams)) {
100003
+ if (!suppressAbortSignal && originalFetchParams && Array.isArray(originalFetchParams)) {
99834
100004
  const [url, init = {}] = originalFetchParams;
99835
100005
  return [url, { signal, ...init }];
99836
100006
  }
@@ -99857,38 +100027,35 @@
99857
100027
  this.services = services;
99858
100028
  this.additionalNullResponses = [];
99859
100029
  }
99860
- /**
99861
- * The command's operation type. Generated command subclasses override this
99862
- * getter with their concrete operation (see the generator's
99863
- * `generateOperationType`); the base returns `undefined` for commands that
99864
- * don't declare one (e.g. hand-written commands). Transport-layer
99865
- * interceptors use it to tell a read (`query`) apart from a write — see
99866
- * `fetch`, which folds it into the context seed and derives
99867
- * `onestore.retrySafe` from it.
99868
- */
99869
100030
  get operationType() {
99870
100031
  return void 0;
99871
100032
  }
99872
- /** Declared `onestore` options (`handleServerError`, `compression`); generated overrides (`generateRequestOptionsGetter`). */
99873
100033
  get requestOptions() {
99874
100034
  return void 0;
99875
100035
  }
99876
100036
  fetch(contextSeed) {
99877
- try {
99878
- const [input, init] = this.fetchParams;
99879
- const operationType = this.operationType;
99880
- const initWithOptions = applyOperationRequestOptions$1(
99881
- init,
99882
- operationType,
99883
- this.requestOptions
99884
- );
99885
- const seed = operationType === void 0 ? contextSeed : { operationType, ...contextSeed };
99886
- const initWithSeed = seed === void 0 ? initWithOptions : { ...initWithOptions, __contextSeed: seed };
99887
- const fetchCall = initWithSeed === void 0 ? this.services.fetch(input) : this.services.fetch(input, initWithSeed);
99888
- return this.convertFetchResponseToData(fetchCall);
99889
- } catch (reason) {
99890
- return resolvedPromiseLike$2(err$1(toError(reason)));
99891
- }
100037
+ return fetchFromNetwork(
100038
+ () => ({
100039
+ services: this.services,
100040
+ params: this.fetchParams,
100041
+ operationType: this.operationType,
100042
+ requestOptions: this.requestOptions
100043
+ }),
100044
+ {
100045
+ isSemanticNullResponse: (response) => this.isSemanticNullResponse(response),
100046
+ isProtocolNoBodyStatus: (status) => this.isProtocolNoBodyStatus(status),
100047
+ coerceError: (response) => this.coerceError(response),
100048
+ afterRequestHooks: (options) => this.afterRequestHooks(options)
100049
+ },
100050
+ contextSeed
100051
+ );
100052
+ }
100053
+ refresh() {
100054
+ return this.execute().then((newResult) => {
100055
+ if (!isSubscribableResult(newResult)) return ok$1(void 0);
100056
+ const result = newResult.isOk() ? ok$1(newResult.value.data) : err$1(newResult.error.failure);
100057
+ return completeRefresh(result, () => this.subscriptions);
100058
+ });
99892
100059
  }
99893
100060
  isSemanticNullResponse(response) {
99894
100061
  return this.additionalNullResponses.includes(response.status);
@@ -99896,53 +100063,9 @@
99896
100063
  isProtocolNoBodyStatus(status) {
99897
100064
  return status === 204 || status === 205;
99898
100065
  }
99899
- isUndeclaredNoBodyResponse(response) {
99900
- return this.isProtocolNoBodyStatus(response.status) && !this.isSemanticNullResponse(response);
99901
- }
99902
100066
  async coerceError(errorResponse) {
99903
100067
  return toError(errorResponse.statusText);
99904
100068
  }
99905
- convertFetchResponseToData(response) {
99906
- return response.then(
99907
- (response2) => {
99908
- if (response2.ok) {
99909
- let resultPromise;
99910
- if (this.isSemanticNullResponse(response2)) {
99911
- resultPromise = Promise.resolve(ok$1(null));
99912
- } else if (this.isUndeclaredNoBodyResponse(response2)) {
99913
- resultPromise = Promise.resolve(
99914
- err$1(
99915
- toError(
99916
- `Unexpected ${response2.status} response: no-content status was not declared in the API specification. Declare this response in your OAS without a content property.`
99917
- )
99918
- )
99919
- );
99920
- } else {
99921
- resultPromise = response2.json().then(
99922
- (json) => ok$1(json),
99923
- (reason) => err$1(toError(reason))
99924
- );
99925
- }
99926
- return resultPromise.finally(() => {
99927
- try {
99928
- this.afterRequestHooks({ statusCode: response2.status });
99929
- } catch {
99930
- }
99931
- });
99932
- } else {
99933
- return this.coerceError(response2).then((coercedError) => {
99934
- return err$1(coercedError);
99935
- }).finally(() => {
99936
- try {
99937
- this.afterRequestHooks({ statusCode: response2.status });
99938
- } catch {
99939
- }
99940
- });
99941
- }
99942
- },
99943
- (reason) => err$1(toError(reason))
99944
- );
99945
- }
99946
100069
  };
99947
100070
  _FetchNetworkCommand.availableDecorators = {
99948
100071
  abortable: createAbortableDecorator
@@ -101006,7 +101129,7 @@
101006
101129
  },
101007
101130
  };
101008
101131
  }
101009
- // version: 1.467.0-4f065d2a2a
101132
+ // version: 1.468.0-9ef0fbdaee
101010
101133
 
101011
101134
  /**
101012
101135
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -101032,7 +101155,7 @@
101032
101155
  },
101033
101156
  };
101034
101157
  }
101035
- // version: 1.467.0-4f065d2a2a
101158
+ // version: 1.468.0-9ef0fbdaee
101036
101159
 
101037
101160
  function findExecutableOperation$1(input) {
101038
101161
  const operations = input.query.definitions.filter(
@@ -101895,6 +102018,53 @@
101895
102018
  }
101896
102019
  };
101897
102020
  }
102021
+ function assertSubscribable(result, report) {
102022
+ if (!isSubscribableResult(result)) {
102023
+ report("Non-subscribable result encountered - please use correct operation type");
102024
+ throw new Error("Internal error in Lightning Data Service adapter occurred");
102025
+ }
102026
+ }
102027
+ function toQueryUpdate(result) {
102028
+ return result.isOk() ? { data: result.value, error: void 0 } : { data: void 0, error: unwrapUserlandError(result.error) };
102029
+ }
102030
+ class SubscribableImperativeBindingsService {
102031
+ bind(getCommand, exposeRefresh = false) {
102032
+ return buildBaseImperativeInvoker(
102033
+ getCommand,
102034
+ (result) => this.transformResult(result, exposeRefresh)
102035
+ );
102036
+ }
102037
+ transformResult(result, exposeRefresh = false) {
102038
+ assertSubscribable(result, (message) => console.error(message));
102039
+ if (result.isErr()) throwUnwrappedUserlandError(result.error.failure);
102040
+ deepFreeze(result.value.data);
102041
+ const api = {
102042
+ data: result.value.data,
102043
+ subscribe: (callback) => result.value.subscribe((update) => {
102044
+ const { data, error } = toQueryUpdate(update);
102045
+ return callback({ data, error });
102046
+ })
102047
+ };
102048
+ if (exposeRefresh) {
102049
+ return {
102050
+ ...api,
102051
+ refresh: () => result.value.refresh().then((refreshed) => {
102052
+ if (refreshed.isOk()) return void 0;
102053
+ throw refreshed.error;
102054
+ })
102055
+ };
102056
+ }
102057
+ return api;
102058
+ }
102059
+ }
102060
+ function buildServiceDescriptor$7() {
102061
+ return {
102062
+ type: "subscribableImperativeBindings",
102063
+ version: "1.0",
102064
+ service: new SubscribableImperativeBindingsService()
102065
+ };
102066
+ }
102067
+
101898
102068
  const supportedCachePolicyTypes = ["no-cache", "only-if-cached"];
101899
102069
  function requestContextIsSupportedCachePolicy(requestContext) {
101900
102070
  return typeof requestContext === "object" && requestContext !== null && "cachePolicy" in requestContext && typeof requestContext.cachePolicy === "object" && requestContext.cachePolicy !== null && "type" in requestContext.cachePolicy && typeof requestContext.cachePolicy.type === "string" && supportedCachePolicyTypes.includes(
@@ -101947,7 +102117,7 @@
101947
102117
  });
101948
102118
  }
101949
102119
  }
101950
- function buildServiceDescriptor$6() {
102120
+ function buildServiceDescriptor$5() {
101951
102121
  return {
101952
102122
  type: "defaultImperativeBindings",
101953
102123
  version: "1.0",
@@ -101967,70 +102137,13 @@
101967
102137
  });
101968
102138
  }
101969
102139
  }
101970
- function buildServiceDescriptor$5() {
102140
+ function buildServiceDescriptor$4() {
101971
102141
  return {
101972
102142
  type: "queryImperativeBindings",
101973
102143
  version: "1.0",
101974
102144
  service: new QueryImperativeBindingsService()
101975
102145
  };
101976
102146
  }
101977
- class SubscribableImperativeBindingsService {
101978
- bind(getCommand, exposeRefresh = false) {
101979
- return buildBaseImperativeInvoker(
101980
- getCommand,
101981
- (result) => this.transformResult(result, exposeRefresh)
101982
- );
101983
- }
101984
- transformResult(result, exposeRefresh = false) {
101985
- if (!isSubscribableResult(result)) {
101986
- console.error(
101987
- "Non-subscribable result encountered - please use correct operation type"
101988
- );
101989
- throw new Error("Internal error in Lightning Data Service adapter occurred");
101990
- }
101991
- if (result.isOk()) {
101992
- deepFreeze(result.value.data);
101993
- const api = {
101994
- data: result.value.data,
101995
- subscribe: (cb) => {
101996
- return result.value.subscribe((result2) => {
101997
- if (result2.isErr()) {
101998
- return cb({
101999
- data: void 0,
102000
- error: unwrapUserlandError(result2.error)
102001
- });
102002
- }
102003
- return cb({ data: result2.value, error: void 0 });
102004
- });
102005
- }
102006
- };
102007
- if (exposeRefresh) {
102008
- return {
102009
- ...api,
102010
- refresh: () => {
102011
- return result.value.refresh().then((res) => {
102012
- if (res.isOk()) {
102013
- return void 0;
102014
- }
102015
- throw res.error;
102016
- });
102017
- }
102018
- };
102019
- } else {
102020
- return api;
102021
- }
102022
- } else {
102023
- throwUnwrappedUserlandError(result.error.failure);
102024
- }
102025
- }
102026
- }
102027
- function buildServiceDescriptor$4() {
102028
- return {
102029
- type: "subscribableImperativeBindings",
102030
- version: "1.0",
102031
- service: new SubscribableImperativeBindingsService()
102032
- };
102033
- }
102034
102147
  class LegacyImperativeBindingsService {
102035
102148
  bind(getCommand) {
102036
102149
  const invoke = async (config, requestContext, callback) => {
@@ -102332,7 +102445,7 @@
102332
102445
  };
102333
102446
  }
102334
102447
  }
102335
- function buildServiceDescriptor$7() {
102448
+ function buildServiceDescriptor$6() {
102336
102449
  return {
102337
102450
  type: "graphQLMutationBindings",
102338
102451
  version: "1.0",
@@ -103480,13 +103593,13 @@
103480
103593
  featureFlagsServiceDescriptor,
103481
103594
  buildServiceDescriptor$b(luvio),
103482
103595
  luvioUiapiRecordsServiceDescriptor,
103483
- buildServiceDescriptor$6(),
103484
103596
  buildServiceDescriptor$5(),
103485
103597
  buildServiceDescriptor$4(),
103598
+ buildServiceDescriptor$7(),
103486
103599
  buildServiceDescriptor$3(),
103487
103600
  buildServiceDescriptor$2$1(),
103488
103601
  buildServiceDescriptor$1$2(),
103489
- buildServiceDescriptor$7(),
103602
+ buildServiceDescriptor$6(),
103490
103603
  buildServiceDescriptor$1$1(),
103491
103604
  buildServiceDescriptor$2(),
103492
103605
  // TODO [W-18753648]: See note above.
@@ -103651,12 +103764,19 @@
103651
103764
  logInfo(`Serial draft queue created with batching=${useQueueBatching}, strictOrdering=true`);
103652
103765
  lazyDraftQueue = buildLdsDraftQueue(lazyDurableStore, sharedDraftStore, {
103653
103766
  // No peer queues when there's no binary lane (batching-only).
103654
- getPeerQueues: () => (useConcurrentBinaryQueue ? [lazyBinaryDraftQueue] : []),
103767
+ getPeerQueues: () => lazyBinaryDraftQueue !== undefined ? [lazyBinaryDraftQueue] : [],
103655
103768
  concurrency: 1,
103656
103769
  strictOrdering: true,
103657
103770
  queueBatching: useQueueBatching,
103658
103771
  });
103659
- if (useConcurrentBinaryQueue) {
103772
+ // The binary lane lives only in the worker realm. In the WebView realm the serial
103773
+ // queue is a Nimbus proxy to the worker's routing façade, which already routes
103774
+ // binary uploads to the worker's binary lane; a local binary queue there would
103775
+ // take uploads the worker never sees. Only worker-realm queues expose
103776
+ // isHandlerRegistered.
103777
+ if (useConcurrentBinaryQueue &&
103778
+ typeof lazyDraftQueue.isHandlerRegistered ===
103779
+ 'function') {
103660
103780
  lazyBinaryDraftQueue = buildLdsPerformanceDraftQueue(lazyDurableStore, sharedDraftStore, {
103661
103781
  getPeerQueues: () => [lazyDraftQueue],
103662
103782
  concurrency: 4,
@@ -103677,27 +103797,19 @@
103677
103797
  const updateRecordQuickActionHandler = new UpdateRecordQuickActionExecutionRepresentationHandler(() => lazyLuvio, draftService, lazyDraftQueue, lazyNetworkAdapter, isGenerated, lazySideEffectService);
103678
103798
  // Route the CD composite to the concurrent binary queue when gate-ON so
103679
103799
  // multipart uploads run in parallel and don't block other DML.
103680
- const contentDocumentTargetQueue = useConcurrentBinaryQueue
103681
- ? lazyBinaryDraftQueue
103682
- : lazyDraftQueue;
103683
- logInfo(`ContentDocumentVersion handler routed to ${useConcurrentBinaryQueue ? 'concurrent draft queue' : 'serial draft queue'}`);
103800
+ const contentDocumentTargetQueue = lazyBinaryDraftQueue ?? lazyDraftQueue;
103801
+ logInfo(`ContentDocumentVersion handler routed to ${lazyBinaryDraftQueue !== undefined ? 'concurrent draft queue' : 'serial draft queue'}`);
103684
103802
  const contentDocumentCompositeActionHandler = new ContentDocumentCompositeRepresentationActionHandler(() => lazyLuvio, userId, draftService, lazyObjectInfoService, contentDocumentTargetQueue, lazyNetworkAdapter, isGenerated, NimbusBinaryStore, lazySideEffectService);
103685
103803
  lazyDraftQueue.addHandler(uiApiRecordHandler);
103686
103804
  lazyDraftQueue.addHandler(quickActionHandler);
103687
103805
  lazyDraftQueue.addHandler(updateRecordQuickActionHandler);
103688
103806
  contentDocumentTargetQueue.addHandler(contentDocumentCompositeActionHandler);
103689
- // Build the routing façade only with the flag on AND over concrete, handler-owning
103690
- // queues. Only the worker-realm queues expose isHandlerRegistered; the WebView realm's
103691
- // Nimbus proxies lack it. Feature-detect that method rather than sniffing the realm via
103692
- // `window`: it tests the exact invariant the DurableDraftQueue casts below rely on, and
103693
- // stays correct in non-browser (e.g. jest) realms where `window` is an unreliable realm
103694
- // signal. The flag must stay the first term — it short-circuits the queue accesses, and
103695
- // the gate-OFF path never builds lazyBinaryDraftQueue (it is undefined there).
103696
- const shouldBuildRoutingQueue = useConcurrentBinaryQueue &&
103697
- typeof lazyDraftQueue.isHandlerRegistered ===
103698
- 'function' &&
103699
- typeof lazyBinaryDraftQueue
103700
- .isHandlerRegistered === 'function';
103807
+ // Build the routing façade and manager only when the binary lane exists: flag on and
103808
+ // in the worker realm, over concrete, handler-owning queues (see where it is built).
103809
+ // Feature-detecting isHandlerRegistered rather than sniffing the realm via `window` tests
103810
+ // the exact invariant the queue casts below rely on, and stays correct in non-browser
103811
+ // (e.g. jest) realms where `window` is an unreliable realm signal.
103812
+ const shouldBuildRoutingQueue = lazyBinaryDraftQueue !== undefined;
103701
103813
  if (shouldBuildRoutingQueue) {
103702
103814
  // Serial is the primary/fallback lane, so the bridged `draftQueue` routes enqueue
103703
103815
  // by handler ownership in the worker. Lane labels are stamped onto each action
@@ -103712,7 +103824,9 @@
103712
103824
  },
103713
103825
  ]);
103714
103826
  }
103715
- lazyDraftManager = useConcurrentBinaryQueue
103827
+ // The WebView realm's (unused) manager falls back to the base DraftManager: native only
103828
+ // drives the worker-realm manager, and RoutingDraftManager needs the concrete queues.
103829
+ lazyDraftManager = shouldBuildRoutingQueue
103716
103830
  ? new RoutingDraftManager(lazyDraftQueue, lazyBinaryDraftQueue, DRAFT_QUEUE_LANE)
103717
103831
  : new DraftManager(lazyDraftQueue);
103718
103832
  const objectInfoCachingEnvironment = enableObjectInfoCaching(durableEnv, lazyObjectInfoService.ensureObjectInfoCached);
@@ -103790,8 +103904,6 @@
103790
103904
  environment: lazyEnvironment,
103791
103905
  draftManager: lazyDraftManager,
103792
103906
  draftQueue: lazyRoutingDraftQueue ?? lazyDraftQueue,
103793
- serialDraftQueue: lazyDraftQueue,
103794
- binaryDraftQueue: lazyBinaryDraftQueue,
103795
103907
  createPrimingSession: (config) => {
103796
103908
  return primingSessionFactory({
103797
103909
  store: lazyDurableStore,
@@ -103817,7 +103929,7 @@
103817
103929
  id: '@salesforce/lds-network-adapter',
103818
103930
  instrument: instrument$2,
103819
103931
  });
103820
- // version: 1.467.0-4f065d2a2a
103932
+ // version: 1.468.0-9ef0fbdaee
103821
103933
 
103822
103934
  const { create: create$2, keys: keys$2 } = Object;
103823
103935
  const { stringify, parse } = JSON;
@@ -111367,7 +111479,7 @@
111367
111479
  cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager);
111368
111480
  }
111369
111481
  }
111370
- // version: 1.467.0-049a8b6027
111482
+ // version: 1.468.0-c060a9b9c6
111371
111483
 
111372
111484
  function createFragmentMap(documentNode) {
111373
111485
  const fragments = {};
@@ -140596,7 +140708,7 @@
140596
140708
  configuration: { ...configurationForGraphQLAdapters$1 },
140597
140709
  instrument: instrument$1,
140598
140710
  });
140599
- // version: 1.467.0-049a8b6027
140711
+ // version: 1.468.0-c060a9b9c6
140600
140712
 
140601
140713
  // On core the unstable adapters are re-exported with different names,
140602
140714
  // we want to match them here.
@@ -140748,7 +140860,7 @@
140748
140860
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
140749
140861
  graphQLImperative = ldsAdapter;
140750
140862
  });
140751
- // version: 1.467.0-049a8b6027
140863
+ // version: 1.468.0-c060a9b9c6
140752
140864
 
140753
140865
  var gqlApi = /*#__PURE__*/Object.freeze({
140754
140866
  __proto__: null,
@@ -141600,7 +141712,7 @@
141600
141712
  function register(r) {
141601
141713
  callbacks$1.forEach((callback) => callback(r));
141602
141714
  }
141603
- // version: 1.467.0-4f065d2a2a
141715
+ // version: 1.468.0-9ef0fbdaee
141604
141716
 
141605
141717
  /**
141606
141718
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -142911,4 +143023,4 @@
142911
143023
  exports.subscribeToAdapter = subscribeToAdapter;
142912
143024
 
142913
143025
  }));
142914
- // version: 1.467.0-4f065d2a2a
143026
+ // version: 1.468.0-9ef0fbdaee