@salesforce/lds-worker-api 1.453.0 → 1.455.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.
@@ -4154,7 +4154,7 @@
4154
4154
  }
4155
4155
  return resourceParams;
4156
4156
  }
4157
- // engine version: 0.161.0-fe06f180
4157
+ // engine version: 0.161.2-bd1bd38a
4158
4158
 
4159
4159
  /**
4160
4160
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -4282,7 +4282,7 @@
4282
4282
  }
4283
4283
  callbacks.push(callback);
4284
4284
  }
4285
- // version: 1.453.0-725e09cf25
4285
+ // version: 1.455.0-c53c97de2a
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.453.0-725e09cf25
5329
+ // version: 1.455.0-c53c97de2a
5330
5330
 
5331
5331
  function isSupportedEntity(_objectApiName) {
5332
5332
  return true;
@@ -5432,11 +5432,11 @@
5432
5432
  TypeCheckShapes[TypeCheckShapes["Integer"] = 3] = "Integer";
5433
5433
  TypeCheckShapes[TypeCheckShapes["Unsupported"] = 4] = "Unsupported";
5434
5434
  })(TypeCheckShapes || (TypeCheckShapes = {}));
5435
- // engine version: 0.161.0-fe06f180
5435
+ // engine version: 0.161.2-bd1bd38a
5436
5436
 
5437
5437
  const { keys: ObjectKeys$4, create: ObjectCreate$4 } = Object;
5438
5438
 
5439
- const { assign: assign$7, create: create$9, freeze: freeze$6, isFrozen: isFrozen$4, keys: keys$a } = Object;
5439
+ const { assign: assign$7, create: create$9, freeze: freeze$6, getPrototypeOf: getPrototypeOf$3, isFrozen: isFrozen$4, keys: keys$a } = Object;
5440
5440
 
5441
5441
  /**
5442
5442
  * Defines configuration for the module with a default value which can be overridden by the runtime environment.
@@ -6071,7 +6071,7 @@
6071
6071
  }
6072
6072
  const keyPrefix$3 = 'UiApi';
6073
6073
 
6074
- const { assign: assign$6, create: create$8, freeze: freeze$5, isFrozen: isFrozen$3, keys: keys$9 } = Object;
6074
+ const { assign: assign$6, create: create$8, freeze: freeze$5, getPrototypeOf: getPrototypeOf$2, isFrozen: isFrozen$3, keys: keys$9 } = Object;
6075
6075
  const { hasOwnProperty: hasOwnProperty$5 } = Object.prototype;
6076
6076
  const { split: split$1, endsWith: endsWith$1 } = String.prototype;
6077
6077
  const { isArray: isArray$8 } = Array;
@@ -32553,7 +32553,7 @@
32553
32553
  throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
32554
32554
  throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
32555
32555
  });
32556
- // version: 1.453.0-e6dc0c039a
32556
+ // version: 1.455.0-96e9b41a18
32557
32557
 
32558
32558
  var draftQueueMaxRetryAttemptsGate = {
32559
32559
  isOpen: function (e) {
@@ -47855,16 +47855,18 @@
47855
47855
  }
47856
47856
 
47857
47857
  class AsyncWorkerPool {
47858
- constructor(concurrency) {
47858
+ constructor(concurrency, onWorkTiming) {
47859
47859
  this.queue = [];
47860
47860
  this.activeWork = [];
47861
47861
  this.concurrency = concurrency;
47862
+ this.onWorkTiming = onWorkTiming;
47862
47863
  }
47863
47864
  push(work) {
47864
47865
  return new Promise((resolve, reject) => {
47865
47866
  this.queue.push({
47866
47867
  ...work,
47867
47868
  workFn: (abortController) => work.workFn(abortController).then(resolve).catch(reject),
47869
+ enqueuedAt: Date.now(),
47868
47870
  });
47869
47871
  this.doWork();
47870
47872
  });
@@ -47907,10 +47909,30 @@
47907
47909
  const abortController = new LdsAbortController();
47908
47910
  const newWork = { ...work, abortController };
47909
47911
  this.activeWork.push(newWork);
47910
- const { workFn } = work;
47912
+ const { workFn, enqueuedAt } = work;
47913
+ const onWorkTiming = this.onWorkTiming;
47914
+ let startedAt = 0;
47915
+ let waitMs = 0;
47916
+ let queueDepthAtStart = 0;
47917
+ if (onWorkTiming !== undefined) {
47918
+ startedAt = Date.now();
47919
+ waitMs = startedAt - enqueuedAt;
47920
+ // depth AFTER this unit was shifted off — units still waiting behind it.
47921
+ queueDepthAtStart = this.queue.length;
47922
+ }
47911
47923
  workFn(abortController).finally(() => {
47912
- this.activeWork = this.activeWork.filter((w) => w !== newWork);
47913
- this.doWork();
47924
+ try {
47925
+ if (onWorkTiming !== undefined) {
47926
+ onWorkTiming(waitMs, Date.now() - startedAt, queueDepthAtStart);
47927
+ }
47928
+ }
47929
+ catch {
47930
+ // Instrumentation must not prevent the pool from releasing the worker slot.
47931
+ }
47932
+ finally {
47933
+ this.activeWork = this.activeWork.filter((w) => w !== newWork);
47934
+ this.doWork();
47935
+ }
47914
47936
  });
47915
47937
  }
47916
47938
  }
@@ -48240,6 +48262,25 @@
48240
48262
  */
48241
48263
  const DRAFT_ACTION_RETRY_COUNT_METADATA_KEY = 'retryCount';
48242
48264
  class DurableDraftQueue {
48265
+ // Instrumentation is strictly measure-only: a broken sink must never change queue behavior.
48266
+ // Pass the sink into the callback so methods are invoked through their owning object and retain
48267
+ // their receiver (some sinks use `this` to reach their metric registry).
48268
+ emitInstrumentation(emit) {
48269
+ const { instrumentation } = this;
48270
+ if (instrumentation === undefined) {
48271
+ return;
48272
+ }
48273
+ try {
48274
+ emit(instrumentation);
48275
+ }
48276
+ catch {
48277
+ // Telemetry failures must not interrupt draft processing.
48278
+ }
48279
+ }
48280
+ resetDrainCycle() {
48281
+ this.drainCycleStart = undefined;
48282
+ this.drainCycleBatchCount = 0;
48283
+ }
48243
48284
  getHandler(id) {
48244
48285
  const handler = this.handlers[id];
48245
48286
  if (handler === undefined) {
@@ -48262,9 +48303,19 @@
48262
48303
  ? __nimbus.plugins.JSLoggerPlugin
48263
48304
  : undefined;
48264
48305
  this.handlers = {};
48306
+ // Drain-wait attribution state. uploadStartTimes stamps when each action first began
48307
+ // uploading (keyed by action id) so actionCompleted/failed can emit its end-to-end drain time,
48308
+ // including automatic retries/backoff. actionQueueWaitEmittedIds ensures those retries do not
48309
+ // report the original enqueue wait more than once. drainCycleStart/BatchCount track one full
48310
+ // idle->empty sweep. All measure-only; when no instrumentation is injected these stay untouched.
48311
+ this.uploadStartTimes = new Map();
48312
+ this.actionQueueWaitEmittedIds = new Set();
48313
+ this.drainCycleBatchCount = 0;
48265
48314
  this.draftStore = draftStore;
48266
- this.workerPool = new AsyncWorkerPool(1);
48267
48315
  this.instrumentation = instrumentation;
48316
+ this.workerPool = new AsyncWorkerPool(1, instrumentation?.onWorkerTiming !== undefined
48317
+ ? (waitMs, holdMs, queueDepth) => this.emitInstrumentation((sink) => sink.onWorkerTiming?.(waitMs, holdMs, queueDepth))
48318
+ : undefined);
48268
48319
  }
48269
48320
  addHandler(handler) {
48270
48321
  const id = handler.handlerId;
@@ -48352,6 +48403,9 @@
48352
48403
  clearTimeout(this.timeoutHandler);
48353
48404
  this.timeoutHandler = undefined;
48354
48405
  }
48406
+ // A stop/user edit breaks the current sweep. A later restart starts a fresh cycle rather
48407
+ // than attributing stopped time to an offline drain.
48408
+ this.resetDrainCycle();
48355
48409
  this.state = DraftQueueState.Stopped;
48356
48410
  }
48357
48411
  async getQueueActions() {
@@ -48382,7 +48436,7 @@
48382
48436
  }
48383
48437
  return aTime - bTime;
48384
48438
  });
48385
- instrumentation?.onGetQueueActions?.(Date.now() - start, sorted.length);
48439
+ this.emitInstrumentation((sink) => sink.onGetQueueActions?.(Date.now() - start, sorted.length));
48386
48440
  return sorted;
48387
48441
  }
48388
48442
  async enqueue(handlerId, data, observabilityContext) {
@@ -48426,6 +48480,13 @@
48426
48480
  await handler.handleActionCompleted(action, queueOperations, values$2(this.handlers));
48427
48481
  this.retryIntervalMilliseconds = 0;
48428
48482
  this.uploadingActionId = undefined;
48483
+ // The action finished draining — emit its end-to-end drain time and
48484
+ // count it toward the current drain-cycle batch. Measure-only.
48485
+ this.emitActionDrainDuration(action.id, action.handler);
48486
+ this.actionQueueWaitEmittedIds.delete(action.id);
48487
+ if (this.drainCycleStart !== undefined) {
48488
+ this.drainCycleBatchCount += 1;
48489
+ }
48429
48490
  await this.notifyChangedListeners({
48430
48491
  type: DraftQueueEventType.ActionCompleted,
48431
48492
  action,
@@ -48437,6 +48498,16 @@
48437
48498
  },
48438
48499
  });
48439
48500
  }
48501
+ // Read+clear the action's upload-start stamp and emit its drain duration. Safe to
48502
+ // call when instrumentation is absent or the id was never stamped (no-op). Never emits the id.
48503
+ emitActionDrainDuration(id, handlerId) {
48504
+ const start = this.uploadStartTimes.get(id);
48505
+ if (start === undefined) {
48506
+ return;
48507
+ }
48508
+ this.uploadStartTimes.delete(id);
48509
+ this.emitInstrumentation((sink) => sink.onActionDrainDuration?.(handlerId, Date.now() - start));
48510
+ }
48440
48511
  async actionFailed(action, retry, retryDelayInMs, actionDataChanged) {
48441
48512
  if (actionDataChanged === true) {
48442
48513
  await this.draftStore.writeAction({
@@ -48446,14 +48517,24 @@
48446
48517
  }
48447
48518
  this.uploadingActionId = undefined;
48448
48519
  if (retry && this.state !== DraftQueueState.Stopped) {
48520
+ // A retry means this action is NOT done draining. Keep its first-upload stamp and the
48521
+ // open cycle so the eventual outcome includes network time and retry/backoff.
48449
48522
  this.state = DraftQueueState.Waiting;
48450
48523
  return retryDelayInMs !== undefined
48451
48524
  ? this.scheduleRetryWithSpecifiedDelay(retryDelayInMs)
48452
48525
  : this.scheduleRetry();
48453
48526
  }
48454
48527
  else if (isDraftError(action)) {
48528
+ // Terminal failure — this action is done draining. Emit its drain time.
48529
+ this.emitActionDrainDuration(action.id, action.handler);
48530
+ // This was not a clean drain-to-empty. Discard the sweep before user intervention so a
48531
+ // later manual retry/removal cannot inherit its elapsed time or completed batch count.
48532
+ this.resetDrainCycle();
48455
48533
  return this.handleServerError(action, action.error);
48456
48534
  }
48535
+ // Any other terminal path — ensure no stale start stamp lingers.
48536
+ this.emitActionDrainDuration(action.id, action.handler);
48537
+ this.resetDrainCycle();
48457
48538
  }
48458
48539
  handle(action) {
48459
48540
  const handler = this.getHandler(action.handler);
@@ -48473,12 +48554,22 @@
48473
48554
  this.state = DraftQueueState.Started;
48474
48555
  }
48475
48556
  this.processingAction = undefined;
48557
+ // The queue drained empty — close the drain-cycle window if one was open.
48558
+ if (this.drainCycleStart !== undefined) {
48559
+ const durationMs = Date.now() - this.drainCycleStart;
48560
+ const batchSize = this.drainCycleBatchCount;
48561
+ this.resetDrainCycle();
48562
+ this.emitInstrumentation((sink) => sink.onDrainCycle?.(durationMs, batchSize));
48563
+ }
48476
48564
  return ProcessActionResult.NO_ACTION_TO_PROCESS;
48477
48565
  }
48478
48566
  const { status, id } = action;
48479
48567
  if (status === DraftActionStatus.Error) {
48480
48568
  this.state = DraftQueueState.Error;
48481
48569
  this.processingAction = undefined;
48570
+ // The sweep is blocked on an errored action, not a clean drain-to-empty —
48571
+ // discard the open drain-cycle window so it doesn't inflate a later cycle's duration.
48572
+ this.resetDrainCycle();
48482
48573
  await this.notifyChangedListeners({
48483
48574
  type: DraftQueueEventType.ActionFailed,
48484
48575
  action: action,
@@ -48496,6 +48587,31 @@
48496
48587
  if (this.state === DraftQueueState.Waiting) {
48497
48588
  this.state = DraftQueueState.Started;
48498
48589
  }
48590
+ // The action is now leaving the queue to upload. Emit head-of-line FIFO wait
48591
+ // (enqueue -> upload start), stamp its drain-start for end-to-end timing on completion, and
48592
+ // open a drain-cycle window if the queue was previously idle. All measure-only.
48593
+ const { instrumentation } = this;
48594
+ if (instrumentation !== undefined) {
48595
+ const now = Date.now();
48596
+ const { timestamp } = action;
48597
+ if (instrumentation.onActionQueueWait !== undefined &&
48598
+ !this.actionQueueWaitEmittedIds.has(id) &&
48599
+ typeof timestamp === 'number' &&
48600
+ timestamp > 0) {
48601
+ // Mark before invoking the sink: even a throwing callback must not make a retry
48602
+ // report the same action's enqueue wait again.
48603
+ this.actionQueueWaitEmittedIds.add(id);
48604
+ this.emitInstrumentation((sink) => sink.onActionQueueWait?.(action.handler, now - timestamp));
48605
+ }
48606
+ if (instrumentation.onActionDrainDuration !== undefined &&
48607
+ !this.uploadStartTimes.has(id)) {
48608
+ this.uploadStartTimes.set(id, now);
48609
+ }
48610
+ if (instrumentation.onDrainCycle !== undefined && this.drainCycleStart === undefined) {
48611
+ this.drainCycleStart = now;
48612
+ this.drainCycleBatchCount = 0;
48613
+ }
48614
+ }
48499
48615
  await this.notifyChangedListeners({
48500
48616
  type: DraftQueueEventType.ActionUploading,
48501
48617
  action: { ...action, status: DraftActionStatus.Uploading },
@@ -48533,7 +48649,7 @@
48533
48649
  results.push(listener(event));
48534
48650
  }
48535
48651
  // W-23515682: listener fan-out per event type. Measure-only.
48536
- this.instrumentation?.onNotifyChangedListeners?.(event.type, draftQueueLen);
48652
+ this.emitInstrumentation((sink) => sink.onNotifyChangedListeners?.(event.type, draftQueueLen));
48537
48653
  await Promise.all(results);
48538
48654
  }
48539
48655
  /**
@@ -48562,9 +48678,17 @@
48562
48678
  const shouldDeleteRelated = handler.shouldDeleteActionByTagOnRemoval(action);
48563
48679
  if (shouldDeleteRelated) {
48564
48680
  await this.draftStore.deleteByTag(action.tag);
48681
+ queue.forEach((queuedAction) => {
48682
+ if (queuedAction.tag === action.tag) {
48683
+ this.uploadStartTimes.delete(queuedAction.id);
48684
+ this.actionQueueWaitEmittedIds.delete(queuedAction.id);
48685
+ }
48686
+ });
48565
48687
  }
48566
48688
  else {
48567
48689
  await this.draftStore.deleteDraft(action.id);
48690
+ this.uploadStartTimes.delete(action.id);
48691
+ this.actionQueueWaitEmittedIds.delete(action.id);
48568
48692
  }
48569
48693
  await handler.handleActionRemoved(action, queue.filter((x) => x.id !== actionId));
48570
48694
  await this.notifyChangedListeners({
@@ -80196,6 +80320,20 @@
80196
80320
  const DRAFT_QUEUE_NOTIFY_CHANGED_LISTENERS_COUNT = 'draft-queue-notify-changed-listeners-count';
80197
80321
  const DRAFT_QUEUE_DURABLE_OP_COUNT = 'draft-queue-durable-op-count';
80198
80322
  const DRAFT_QUEUE_DURABLE_OP_DURATION = 'draft-queue-durable-op-duration';
80323
+ // Drain-wait attribution telemetry: the wall-clock spine of where an offline drain actually spends
80324
+ // WAITING. Operational counts/durations/depths only — no draft content, field values, or server
80325
+ // record ids (matching the existing draft-queue privacy stance).
80326
+ const DRAFT_QUEUE_WORKER_WAIT_DURATION = 'draft-queue-worker-wait-duration';
80327
+ const DRAFT_QUEUE_WORKER_HOLD_DURATION = 'draft-queue-worker-hold-duration';
80328
+ const DRAFT_QUEUE_ACTION_QUEUE_WAIT_DURATION = 'draft-queue-action-queue-wait-duration';
80329
+ const DRAFT_QUEUE_ACTION_DRAIN_DURATION = 'draft-queue-action-drain-duration';
80330
+ const DRAFT_QUEUE_DRAIN_CYCLE_DURATION = 'draft-queue-drain-cycle-duration';
80331
+ const DRAFT_QUEUE_DRAIN_CYCLE_BATCH_SIZE = 'draft-queue-drain-cycle-batch-size';
80332
+ const DRAFT_QUEUE_ACTION_NETWORK_DURATION = 'draft-queue-action-network-duration';
80333
+ const DRAFT_QUEUE_ACTION_RETRY_ATTEMPT = 'draft-queue-action-retry-attempt';
80334
+ const DRAFT_QUEUE_SIDEEFFECT_OP_DURATION = 'draft-queue-sideeffect-op-duration';
80335
+ const DRAFT_QUEUE_SIDEEFFECT_MAP_SIZE = 'draft-queue-sideeffect-map-size';
80336
+ const DRAFT_QUEUE_SIDEEFFECT_REGION_DURATION = 'draft-queue-sideeffect-region-duration';
80199
80337
  /** Content Document */
80200
80338
  const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
80201
80339
  const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
@@ -80315,6 +80453,134 @@
80315
80453
  });
80316
80454
  ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_DURABLE_OP_DURATION, durationMs);
80317
80455
  }
80456
+ const DRAIN_DURATION_BUCKETS = [50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000];
80457
+ const WORKER_DEPTH_BUCKETS = [1, 2, 5, 10, 20, 50, 100, 250, 500];
80458
+ // Handler ids are extensible through DraftManager, so only retain the fixed mobile handlers in
80459
+ // metric tags. Everything else shares one bounded bucket rather than creating an unbounded series.
80460
+ function draftQueueHandlerTagOf(handlerId) {
80461
+ switch (handlerId) {
80462
+ case 'LDS_ACTION_HANDLER':
80463
+ case 'ContentDocumentCompositeRepresentationActionHandler':
80464
+ case 'QUICK_ACTION_HANDLER':
80465
+ case 'UPDATE_RECORD_QUICK_ACTION_HANDLER':
80466
+ return handlerId;
80467
+ default:
80468
+ return 'custom';
80469
+ }
80470
+ }
80471
+ // Coarse, bounded-cardinality label for the pool depth a unit saw when it began, so the
80472
+ // wait/hold durations can be sliced BY backlog size without emitting depth as a free integer tag.
80473
+ function workerDepthBucketOf(queueDepth) {
80474
+ if (queueDepth <= 0) {
80475
+ return '0';
80476
+ }
80477
+ if (queueDepth <= 2) {
80478
+ return '1-2';
80479
+ }
80480
+ if (queueDepth <= 10) {
80481
+ return '3-10';
80482
+ }
80483
+ if (queueDepth <= 50) {
80484
+ return '11-50';
80485
+ }
80486
+ if (queueDepth <= 250) {
80487
+ return '51-250';
80488
+ }
80489
+ return '250+';
80490
+ }
80491
+ /**
80492
+ * Per-unit lifecycle split for the AsyncWorkerPool(1) serial queue, emitted once when a unit settles
80493
+ * so the two halves are a JOINED event (rather than shipping wait and depth as unrelated aggregates).
80494
+ * Isolates WHERE the time goes:
80495
+ * waitMs — enqueue -> work began (waiting on the serial queue before any logic runs).
80496
+ * holdMs — work began -> work settled (the critical section's own O(N) service time).
80497
+ * Both are additionally tagged by a depthBucket so "does per-unit cost scale with backlog depth"
80498
+ * (the O(N^2) signature) survives aggregation. queueDepth itself is also tracked. Operational only.
80499
+ */
80500
+ function reportDraftQueueWorkerTiming(waitMs, holdMs, queueDepth) {
80501
+ const depthBucket = workerDepthBucketOf(queueDepth);
80502
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_WORKER_WAIT_DURATION, waitMs, undefined, {
80503
+ depthBucket,
80504
+ });
80505
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_WORKER_HOLD_DURATION, holdMs, undefined, {
80506
+ depthBucket,
80507
+ });
80508
+ ldsMobileInstrumentation$2.bucketValue(DRAFT_QUEUE_WORKER_WAIT_DURATION + '-depth', queueDepth, WORKER_DEPTH_BUCKETS);
80509
+ }
80510
+ /**
80511
+ * Head-of-line FIFO wait for one draft (enqueue -> upload start), bucketed so the
80512
+ * "does wait grow with backlog depth" (O(N^2)) signal is visible per handler type. Custom handler
80513
+ * ids are normalized to one bounded tag so caller-defined values never become metric dimensions.
80514
+ */
80515
+ function reportDraftQueueActionQueueWait(handlerId, waitMs) {
80516
+ ldsMobileInstrumentation$2.bucketValue(DRAFT_QUEUE_ACTION_QUEUE_WAIT_DURATION, waitMs, DRAIN_DURATION_BUCKETS, undefined, { handlerId: draftQueueHandlerTagOf(handlerId) });
80517
+ }
80518
+ /**
80519
+ * End-to-end drain time for one action (first upload attempt -> completed/failed), including
80520
+ * retry/backoff. Compare it with network-duration and retry-attempt signals to understand the
80521
+ * non-request portion of the drain interval.
80522
+ */
80523
+ function reportDraftQueueActionDrainDuration(handlerId, durationMs) {
80524
+ ldsMobileInstrumentation$2.bucketValue(DRAFT_QUEUE_ACTION_DRAIN_DURATION, durationMs, DRAIN_DURATION_BUCKETS, undefined, { handlerId: draftQueueHandlerTagOf(handlerId) });
80525
+ }
80526
+ /**
80527
+ * One full drain sweep — first action starts uploading -> queue empties. Both raw values share a
80528
+ * bounded batch-size cohort so aggregate duration remains sliceable by the number of actions drained.
80529
+ */
80530
+ function reportDraftQueueDrainCycle(durationMs, batchSize) {
80531
+ const batchSizeBucket = workerDepthBucketOf(batchSize);
80532
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_DRAIN_CYCLE_DURATION, durationMs, undefined, {
80533
+ batchSizeBucket,
80534
+ });
80535
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_DRAIN_CYCLE_BATCH_SIZE, batchSize, undefined, {
80536
+ batchSizeBucket,
80537
+ });
80538
+ }
80539
+ /**
80540
+ * Server round-trip duration for one upload. Isolates slow-network from CPU-bound
80541
+ * quadratic work — today only a THROWN error is captured, so a slow-but-successful (or slow 4xx/5xx)
80542
+ * response is invisible. Tags: handler type, HTTP method, and a bucketed status class ('2xx'/'4xx'/
80543
+ * '5xx'/'0'). No URL, body, or record id.
80544
+ */
80545
+ function reportDraftQueueActionNetworkDuration(handlerId, method, statusBucket, durationMs) {
80546
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_ACTION_NETWORK_DURATION, durationMs, undefined, {
80547
+ handlerId: draftQueueHandlerTagOf(handlerId),
80548
+ method,
80549
+ statusBucket,
80550
+ });
80551
+ }
80552
+ /**
80553
+ * Retry event count. Repeated events identify actions cycling through the drain even when the retry
80554
+ * cap is disabled and an exact attempt number is not persisted. cappedOut marks cap exhaustion.
80555
+ */
80556
+ function reportDraftQueueActionRetryAttempt(handlerId, cappedOut) {
80557
+ ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_ACTION_RETRY_ATTEMPT, 1, undefined, {
80558
+ handlerId: draftQueueHandlerTagOf(handlerId),
80559
+ cappedOut: String(cappedOut),
80560
+ });
80561
+ }
80562
+ /**
80563
+ * SideEffectStore operation duration + map size. The incremental map sped up the by-KEY lookup but
80564
+ * getEffectsByTag still linearly scans all effects — this measures whether that residual scan is
80565
+ * silently quadratic during churn. op is 'add'|'remove'|'getByTag'; incremental flags the fast path;
80566
+ * mapSize is an integer effect count. No record keys, field names, or field values.
80567
+ */
80568
+ function reportDraftQueueSideEffectOp(op, incremental, durationMs, mapSize) {
80569
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_SIDEEFFECT_OP_DURATION, durationMs, undefined, {
80570
+ op,
80571
+ incremental: String(incremental),
80572
+ });
80573
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_SIDEEFFECT_MAP_SIZE, mapSize, undefined, {
80574
+ op,
80575
+ });
80576
+ }
80577
+ /**
80578
+ * Broad side-effect lifecycle duration. The fixed region and lifecycle tags identify which part of
80579
+ * serialized draft processing is slow without emitting record keys, action ids, or field data.
80580
+ */
80581
+ function reportDraftQueueSideEffectRegionDuration(region, lifecycle, durationMs) {
80582
+ ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_SIDEEFFECT_REGION_DURATION, durationMs, undefined, { region, lifecycle });
80583
+ }
80318
80584
  /**
80319
80585
  * Reports an exception thrown while uploading a draft action. The thrown error is
80320
80586
  * otherwise swallowed by the upload handler's retry path, leaving the failure
@@ -80522,8 +80788,16 @@
80522
80788
  const dispatchOptions = action.observabilityContext !== undefined
80523
80789
  ? { requestCorrelator: { observabilityContext: action.observabilityContext } }
80524
80790
  : {};
80791
+ const method = request?.method?.toUpperCase() ?? 'UNKNOWN';
80792
+ const networkStart = Date.now();
80793
+ let responseReceived = false;
80525
80794
  try {
80526
80795
  const response = await this.networkAdapter(request, dispatchOptions);
80796
+ responseReceived = true;
80797
+ // Time the round-trip regardless of outcome (ok, retryable HTTP error, or non-ok
80798
+ // terminal error) — today only a THROWN error is visible; a slow-but-successful or
80799
+ // slow 4xx/5xx response is not.
80800
+ this.reportNetworkDuration(method, statusBucketOf(response.status), networkStart);
80527
80801
  if (response.ok) {
80528
80802
  await actionCompleted({
80529
80803
  ...action,
@@ -80609,19 +80883,32 @@
80609
80883
  actionDataChanged = true;
80610
80884
  }
80611
80885
  else if (!this.isServerGeneratedError(response.body)) {
80612
- // Killswitch CLOSED (default) — only an edge/gateway-injected 400 (no
80886
+ // Killswitch CLOSED (default) — an edge/gateway-injected 400 (no
80613
80887
  // recognizable server error body) is retried with the SAME key, so the
80614
80888
  // server can dedupe a write that may already have committed at the origin.
80615
- // A real, server-generated 400 (UiApiError[] or an enhancedErrorType body,
80616
- // e.g. a field-validation failure) falls through to the error path below:
80617
- // retrying it unchanged would only be rejected again, so the draft is
80618
- // errored for the user to fix or discard — the same terminal outcome as
80619
- // before this fix, minus the duplicating key rotation. The key is only ever
80620
- // rotated by the recognized idempotency error codes above, by a backdating
80621
- // collision (new body), or when the user edits an errored draft
80622
- // (mergeActions/handleReplaceAction).
80889
+ // Rotating here is what duplicated the WOLI records (@W-23445154), so the
80890
+ // key is preserved.
80623
80891
  shouldRetry = true;
80624
80892
  }
80893
+ else {
80894
+ // Killswitch CLOSED — a REAL, server-generated 400 (UiApiError[] or an
80895
+ // enhancedErrorType body, e.g. a field-validation failure). The origin
80896
+ // understood the request and rejected it, so it definitively did NOT
80897
+ // commit — there is no already-written record to duplicate, which is what
80898
+ // makes rotation safe here (unlike the edge-injected case above).
80899
+ //
80900
+ // We still do NOT retry (shouldRetry stays false): the request as-is would
80901
+ // just be rejected again and wedge the queue. The draft errors for the user
80902
+ // to fix or discard. But we DO rotate the key: the server's idempotency
80903
+ // layer caches the 400 against the key, so if the same request is later
80904
+ // resubmitted unchanged after the server-side validation rule changes to
80905
+ // allow it, reusing the key would replay that cached 400 and the now-valid
80906
+ // write would never be applied. Rotating gives the retried request a fresh
80907
+ // key so the origin re-evaluates it. @W-23445154
80908
+ updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
80909
+ reportIdempotencyKeyRotated(updatedAction.targetId, 'server-validation-400');
80910
+ actionDataChanged = true;
80911
+ }
80625
80912
  }
80626
80913
  if (response.status === HttpStatusCode$2.BadRequest &&
80627
80914
  this.isBackdatingError(response.body, action)) {
@@ -80666,6 +80953,11 @@
80666
80953
  const error = normalizeError$1(e);
80667
80954
  const attempt = this.getUploadRetryCount(action) + 1;
80668
80955
  reportDraftActionUploadError(error, this.handlerId, attempt);
80956
+ // A thrown network call still has a round-trip duration worth surfacing — a slow
80957
+ // FAILING call is otherwise as invisible as a slow successful one.
80958
+ if (!responseReceived) {
80959
+ this.reportNetworkDuration(method, 'error', networkStart);
80960
+ }
80669
80961
  await this.retryOrCap(action, error, actionErrored);
80670
80962
  return ProcessActionResult.NETWORK_ERROR;
80671
80963
  }
@@ -80701,12 +80993,17 @@
80701
80993
  */
80702
80994
  async retryOrCap(action, lastFailure, actionErrored, retryDelayInMs, actionDataChanged) {
80703
80995
  if (!draftQueueMaxRetryAttemptsGate.isOpen({ fallback: false })) {
80704
- // Gate closed: preserve the pre-existing unbounded-retry behavior exactly.
80996
+ // Gate closed: preserve the pre-existing unbounded-retry behavior exactly. The
80997
+ // metric is still emitted (measure-only) so retry attempts are visible even with
80998
+ // the cap gate closed — cappedOut is always false here since nothing ever caps
80999
+ // out on this path.
81000
+ this.reportRetryAttempt(false);
80705
81001
  await actionErrored(action, true, retryDelayInMs, actionDataChanged);
80706
81002
  return;
80707
81003
  }
80708
81004
  const attempt = this.getUploadRetryCount(action) + 1;
80709
81005
  if (attempt >= MAX_RETRY_ATTEMPTS) {
81006
+ this.reportRetryAttempt(true);
80710
81007
  await actionErrored({
80711
81008
  ...action,
80712
81009
  error: buildMaxRetryError(lastFailure),
@@ -80714,6 +81011,7 @@
80714
81011
  }, false);
80715
81012
  return;
80716
81013
  }
81014
+ this.reportRetryAttempt(false);
80717
81015
  // Persist the incremented attempt count so it survives restarts. Forcing
80718
81016
  // actionDataChanged ensures the queue writes the updated metadata before the
80719
81017
  // action is rescheduled for retry.
@@ -80727,12 +81025,12 @@
80727
81025
  await actionErrored(retryingAction, true, retryDelayInMs, true);
80728
81026
  }
80729
81027
  async handleActionEnqueued(action) {
80730
- const impactedKeys = await this.recordService.setSideEffectsForActions([action]);
80731
- await this.recordService.reapplyRecordSideEffects(impactedKeys);
81028
+ const impactedKeys = await this.recordService.setSideEffectsForActions([action], 'enqueued');
81029
+ await this.recordService.reapplyRecordSideEffects(impactedKeys, 'enqueued');
80732
81030
  }
80733
81031
  async handleActionRemoved(action) {
80734
81032
  const impactedKeys = await this.recordService.removeSideEffectsForAction(action);
80735
- await this.recordService.reapplyRecordSideEffects(impactedKeys);
81033
+ await this.recordService.reapplyRecordSideEffects(impactedKeys, 'removed');
80736
81034
  }
80737
81035
  async handleActionReplaced(target, source) {
80738
81036
  // remove both the siden effects from the actions being merged before we
@@ -80740,10 +81038,10 @@
80740
81038
  const impactedKeysFromRemove = await this.recordService.removeSideEffectsForAction(source);
80741
81039
  const removedSideEffectFromSet = await this.recordService.removeSideEffectsForAction(target);
80742
81040
  // revert the values in the DEFAULT store back to what it was before the removed side effects
80743
- await this.recordService.reapplyRecordSideEffects(new Set([...impactedKeysFromRemove, ...removedSideEffectFromSet]));
81041
+ await this.recordService.reapplyRecordSideEffects(new Set([...impactedKeysFromRemove, ...removedSideEffectFromSet]), 'replaced-remove');
80744
81042
  // set the new side effect values for the merged action
80745
- const impactedKeysFromSet = await this.recordService.setSideEffectsForActions([target]);
80746
- await this.recordService.reapplyRecordSideEffects(new Set([...impactedKeysFromSet]));
81043
+ const impactedKeysFromSet = await this.recordService.setSideEffectsForActions([target], 'replaced-set');
81044
+ await this.recordService.reapplyRecordSideEffects(new Set([...impactedKeysFromSet]), 'replaced-set');
80747
81045
  }
80748
81046
  async handleActionCompleted(action, queueOperations) {
80749
81047
  const { data: request, tag } = action;
@@ -80777,8 +81075,8 @@
80777
81075
  actionsNeedingReplay.push(qo.action);
80778
81076
  }
80779
81077
  });
80780
- const impactedKeys = await this.recordService.setSideEffectsForActions(actionsNeedingReplay);
80781
- await this.recordService.reapplyRecordSideEffects(impactedKeys);
81078
+ const impactedKeys = await this.recordService.setSideEffectsForActions(actionsNeedingReplay, 'completed-replay');
81079
+ await this.recordService.reapplyRecordSideEffects(impactedKeys, 'completed-replay');
80782
81080
  }
80783
81081
  getQueueOperationsForCompletingDrafts(queue, action) {
80784
81082
  const queueOperations = [];
@@ -81104,6 +81402,39 @@
81104
81402
  return new StoreKeyMap();
81105
81403
  });
81106
81404
  }
81405
+ reportNetworkDuration(method, statusBucket, startedAt) {
81406
+ try {
81407
+ reportDraftQueueActionNetworkDuration(this.handlerId, method, statusBucket, Date.now() - startedAt);
81408
+ }
81409
+ catch {
81410
+ // Telemetry must not change upload processing behavior.
81411
+ }
81412
+ }
81413
+ reportRetryAttempt(cappedOut) {
81414
+ try {
81415
+ reportDraftQueueActionRetryAttempt(this.handlerId, cappedOut);
81416
+ }
81417
+ catch {
81418
+ // Telemetry must not change retry or cap behavior.
81419
+ }
81420
+ }
81421
+ }
81422
+ // Classifies an HTTP status into a small, greppable tag set for the network-duration metric —
81423
+ // never the raw status, to keep the metric's tag cardinality bounded.
81424
+ function statusBucketOf(status) {
81425
+ if (status === 0) {
81426
+ return '0';
81427
+ }
81428
+ if (status >= 200 && status <= 299) {
81429
+ return '2xx';
81430
+ }
81431
+ if (status >= 400 && status <= 499) {
81432
+ return '4xx';
81433
+ }
81434
+ if (status >= 500) {
81435
+ return '5xx';
81436
+ }
81437
+ return 'other';
81107
81438
  }
81108
81439
  function actionsForTag(tag, queue) {
81109
81440
  return queue.filter((action) => action.tag === tag);
@@ -81467,10 +81798,16 @@
81467
81798
  }
81468
81799
  // calculates the side effects for a given set of actions
81469
81800
  // and returns a set of impacted record keys
81470
- async setSideEffectsForActions(changedActions) {
81471
- const operations = await this.recalculateForChangedActions(changedActions);
81472
- await this.sideEffectStore.addEffects(operations);
81473
- return new Set(operations.map((o) => o.key));
81801
+ async setSideEffectsForActions(changedActions, lifecycle) {
81802
+ const startedAt = Date.now();
81803
+ try {
81804
+ const operations = await this.recalculateForChangedActions(changedActions);
81805
+ await this.sideEffectStore.addEffects(operations);
81806
+ return new Set(operations.map((o) => o.key));
81807
+ }
81808
+ finally {
81809
+ this.reportSideEffectRegionDuration('set', lifecycle, startedAt);
81810
+ }
81474
81811
  }
81475
81812
  // removes the associated side effects for a given action and returns
81476
81813
  // a set of impacted record keys
@@ -81481,31 +81818,45 @@
81481
81818
  }
81482
81819
  // reads a set of records out of the durable store, re-applies current side
81483
81820
  // effects and persists the changed record
81484
- async reapplyRecordSideEffects(recordKeys) {
81485
- const luvio = this.getLuvio();
81486
- const keys = Array.from(recordKeys);
81487
- const recordEntries = await this.durableRecordStore.getRecordsWithMetadata(keys);
81488
- keys.forEach((key) => {
81489
- let record;
81490
- const metadata = {
81491
- namespace: 'UiApi',
81492
- representationName: 'RecordRepresentation',
81493
- version: VERSION$1v$1,
81494
- ingestionTimestamp: Date.now(),
81495
- ttl: Number.MAX_SAFE_INTEGER,
81496
- };
81497
- const recordEntry = recordEntries.get(key);
81498
- if (recordEntry) {
81499
- record = recordEntry.record;
81500
- if (recordEntry.metadata) {
81501
- metadata.ingestionTimestamp = recordEntry.metadata.ingestionTimestamp;
81502
- metadata.ttl = TTL$z;
81821
+ async reapplyRecordSideEffects(recordKeys, lifecycle) {
81822
+ const startedAt = Date.now();
81823
+ try {
81824
+ const luvio = this.getLuvio();
81825
+ const keys = Array.from(recordKeys);
81826
+ const recordEntries = await this.durableRecordStore.getRecordsWithMetadata(keys);
81827
+ keys.forEach((key) => {
81828
+ let record;
81829
+ const metadata = {
81830
+ namespace: 'UiApi',
81831
+ representationName: 'RecordRepresentation',
81832
+ version: VERSION$1v$1,
81833
+ ingestionTimestamp: Date.now(),
81834
+ ttl: Number.MAX_SAFE_INTEGER,
81835
+ };
81836
+ const recordEntry = recordEntries.get(key);
81837
+ if (recordEntry) {
81838
+ record = recordEntry.record;
81839
+ if (recordEntry.metadata) {
81840
+ metadata.ingestionTimestamp = recordEntry.metadata.ingestionTimestamp;
81841
+ metadata.ttl = TTL$z;
81842
+ }
81503
81843
  }
81504
- }
81505
- luvio.storePublish(key, record);
81506
- luvio.publishStoreMetadata(key, metadata);
81507
- });
81508
- await luvio.storeBroadcast();
81844
+ luvio.storePublish(key, record);
81845
+ luvio.publishStoreMetadata(key, metadata);
81846
+ });
81847
+ await luvio.storeBroadcast();
81848
+ }
81849
+ finally {
81850
+ this.reportSideEffectRegionDuration('reapply', lifecycle, startedAt);
81851
+ }
81852
+ }
81853
+ reportSideEffectRegionDuration(region, lifecycle, startedAt) {
81854
+ try {
81855
+ reportDraftQueueSideEffectRegionDuration(region, lifecycle, Date.now() - startedAt);
81856
+ }
81857
+ catch {
81858
+ // Telemetry must not change draft processing behavior.
81859
+ }
81509
81860
  }
81510
81861
  async synthesizeId(apiName) {
81511
81862
  const objectInfo = await this.objectInfoService.getObjectInfo(apiName);
@@ -81741,7 +82092,7 @@
81741
82092
  // since we don't ingest a record from the response, we need to manually trigger a re-apply here to ensure we
81742
82093
  // re-ingest the record without effects applied
81743
82094
  await this.recordService.removeSideEffectsForAction(action);
81744
- await this.recordService.reapplyRecordSideEffects(new Set([action.tag]));
82095
+ await this.recordService.reapplyRecordSideEffects(new Set([action.tag]), 'quick-action-completed');
81745
82096
  // notify luvio that record is now changed and needs to be refreshed
81746
82097
  await luvio.notifyStoreUpdateAvailable([action.tag]);
81747
82098
  }
@@ -90421,6 +90772,18 @@
90421
90772
  onDurableOperation(op, segment, durationMs) {
90422
90773
  reportDraftQueueDurableOperation(op, segment, durationMs);
90423
90774
  },
90775
+ onWorkerTiming(waitMs, holdMs, queueDepth) {
90776
+ reportDraftQueueWorkerTiming(waitMs, holdMs, queueDepth);
90777
+ },
90778
+ onActionQueueWait(handlerId, waitMs) {
90779
+ reportDraftQueueActionQueueWait(handlerId, waitMs);
90780
+ },
90781
+ onActionDrainDuration(handlerId, durationMs) {
90782
+ reportDraftQueueActionDrainDuration(handlerId, durationMs);
90783
+ },
90784
+ onDrainCycle(durationMs, batchSize) {
90785
+ reportDraftQueueDrainCycle(durationMs, batchSize);
90786
+ },
90424
90787
  };
90425
90788
 
90426
90789
  // so eslint doesn't complain about nimbus
@@ -93763,6 +94126,9 @@
93763
94126
  this.initialize();
93764
94127
  }
93765
94128
  async addEffects(effects) {
94129
+ // Wall-clock across the whole method (including the durable write), matching
94130
+ // how the equivalent removeEffects/getEffectsByTag windows are measured.
94131
+ const startTime = Date.now();
93766
94132
  const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
93767
94133
  const durableEntries = {};
93768
94134
  effects.forEach((effect) => {
@@ -93777,8 +94143,11 @@
93777
94143
  this.regenerateKeyToEffectMap();
93778
94144
  }
93779
94145
  await this.durableStore.setEntries(durableEntries, SIDE_EFFECT_SEGMENT);
94146
+ this.reportOperation('add', incremental, startTime);
93780
94147
  }
93781
94148
  async removeEffects(effects) {
94149
+ // See addEffects — same wall-clock-across-the-method measurement.
94150
+ const startTime = Date.now();
93782
94151
  const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
93783
94152
  const effectKeys = effects.map((e) => e.uniqueId);
93784
94153
  effects.forEach((effect) => {
@@ -93792,6 +94161,7 @@
93792
94161
  this.regenerateKeyToEffectMap();
93793
94162
  }
93794
94163
  await this.durableStore.evictEntries(effectKeys, SIDE_EFFECT_SEGMENT);
94164
+ this.reportOperation('remove', incremental, startTime);
93795
94165
  }
93796
94166
  getEffects(key) {
93797
94167
  const effects = this.keyToEffectMap.get(key);
@@ -93801,6 +94171,10 @@
93801
94171
  return effects;
93802
94172
  }
93803
94173
  getEffectsByTag(tag) {
94174
+ // This scan is still O(N) over every effect regardless of the incremental-map
94175
+ // gate — timing it tells us whether that residual scan is the quadratic hotspot during churn.
94176
+ const startTime = Date.now();
94177
+ const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
93804
94178
  const filteredEffects = [];
93805
94179
  const { keyToEffectMap } = this;
93806
94180
  // Loop through every entry in the map
@@ -93810,7 +94184,17 @@
93810
94184
  // Add the matching effects to the filtered list
93811
94185
  filteredEffects.push(...matchingEffects);
93812
94186
  }
93813
- return filteredEffects.sort((a, b) => a.timestamp - b.timestamp);
94187
+ const result = filteredEffects.sort((a, b) => a.timestamp - b.timestamp);
94188
+ this.reportOperation('getByTag', incremental, startTime);
94189
+ return result;
94190
+ }
94191
+ reportOperation(op, incremental, startedAt) {
94192
+ try {
94193
+ reportDraftQueueSideEffectOp(op, incremental, Date.now() - startedAt, this.allEffects.size);
94194
+ }
94195
+ catch {
94196
+ // Telemetry must not change side-effect store behavior.
94197
+ }
93814
94198
  }
93815
94199
  async initialize() {
93816
94200
  const effects = await this.durableStore.getAllEntries(SIDE_EFFECT_SEGMENT);
@@ -97007,7 +97391,7 @@
97007
97391
  },
97008
97392
  };
97009
97393
  }
97010
- // version: 1.453.0-725e09cf25
97394
+ // version: 1.455.0-c53c97de2a
97011
97395
 
97012
97396
  /**
97013
97397
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -97033,7 +97417,7 @@
97033
97417
  },
97034
97418
  };
97035
97419
  }
97036
- // version: 1.453.0-725e09cf25
97420
+ // version: 1.455.0-c53c97de2a
97037
97421
 
97038
97422
  function findExecutableOperation$1(input) {
97039
97423
  const operations = input.query.definitions.filter(
@@ -99742,7 +100126,7 @@
99742
100126
  id: '@salesforce/lds-network-adapter',
99743
100127
  instrument: instrument$2,
99744
100128
  });
99745
- // version: 1.453.0-725e09cf25
100129
+ // version: 1.455.0-c53c97de2a
99746
100130
 
99747
100131
  const { create: create$2, keys: keys$2 } = Object;
99748
100132
  const { stringify, parse } = JSON;
@@ -107277,7 +107661,7 @@
107277
107661
  cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager, useOneStoreGraphQL);
107278
107662
  }
107279
107663
  }
107280
- // version: 1.453.0-e6dc0c039a
107664
+ // version: 1.455.0-96e9b41a18
107281
107665
 
107282
107666
  function createFragmentMap(documentNode) {
107283
107667
  const fragments = {};
@@ -124006,7 +124390,7 @@
124006
124390
  return keyBuilder$z(luvio, keyParams);
124007
124391
  }
124008
124392
 
124009
- const { assign: assign$1, create: create$1, freeze: freeze$1, isFrozen: isFrozen$1, keys: keys$1 } = Object;
124393
+ const { assign: assign$1, create: create$1, freeze: freeze$1, getPrototypeOf: getPrototypeOf$1, isFrozen: isFrozen$1, keys: keys$1 } = Object;
124010
124394
  const { isArray: isArray$2 } = Array;
124011
124395
  const { concat: concat$1, filter: filter$1, includes: includes$1, push: push$1, reduce: reduce$1 } = Array.prototype;
124012
124396
 
@@ -136520,7 +136904,7 @@
136520
136904
  configuration: { ...configurationForGraphQLAdapters$1 },
136521
136905
  instrument: instrument$1,
136522
136906
  });
136523
- // version: 1.453.0-e6dc0c039a
136907
+ // version: 1.455.0-96e9b41a18
136524
136908
 
136525
136909
  // On core the unstable adapters are re-exported with different names,
136526
136910
  // we want to match them here.
@@ -136672,7 +137056,7 @@
136672
137056
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
136673
137057
  graphQLImperative = ldsAdapter;
136674
137058
  });
136675
- // version: 1.453.0-e6dc0c039a
137059
+ // version: 1.455.0-96e9b41a18
136676
137060
 
136677
137061
  var gqlApi = /*#__PURE__*/Object.freeze({
136678
137062
  __proto__: null,
@@ -137471,7 +137855,7 @@
137471
137855
  function register(r) {
137472
137856
  callbacks$1.forEach((callback) => callback(r));
137473
137857
  }
137474
- // version: 1.453.0-725e09cf25
137858
+ // version: 1.455.0-c53c97de2a
137475
137859
 
137476
137860
  /**
137477
137861
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -137757,7 +138141,7 @@
137757
138141
  }
137758
138142
  const keyPrefix = 'UiApi';
137759
138143
 
137760
- const { assign, create, freeze, isFrozen, keys } = Object;
138144
+ const { assign, create, freeze, getPrototypeOf, isFrozen, keys } = Object;
137761
138145
  const { isArray } = Array;
137762
138146
  const { concat, filter, includes, push, reduce } = Array.prototype;
137763
138147
 
@@ -138781,4 +139165,4 @@
138781
139165
  exports.subscribeToAdapter = subscribeToAdapter;
138782
139166
 
138783
139167
  }));
138784
- // version: 1.453.0-725e09cf25
139168
+ // version: 1.455.0-c53c97de2a