@salesforce/lds-runtime-mobile 1.443.0 → 1.445.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.
package/dist/main.js CHANGED
@@ -19,8 +19,9 @@ import { withRegistration, register } from '@salesforce/lds-default-luvio';
19
19
  import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrumentLuvio, setLdsAdaptersUiapiInstrumentation, setLdsNetworkAdapterInstrumentation } from '@salesforce/lds-instrumentation';
20
20
  import { HttpStatusCode as HttpStatusCode$1, setBypassDeepFreeze, StoreKeySet, StringKeyInMemoryStore, Reader, serializeStructuredKey, deepFreeze as deepFreeze$1, emitAdapterEvent, ingestShape, coerceConfig as coerceConfig$1, typeCheckConfig as typeCheckConfig$h, createResourceParams as createResourceParams$h, StoreKeyMap, buildNetworkSnapshotCachePolicy as buildNetworkSnapshotCachePolicy$f, resolveLink, createCustomAdapterEventEmitter, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
21
21
  import { isSupportedEntity, configuration, getObjectInfoAdapterFactory, RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, extractRecordIdFromStoreKey, buildRecordRepKeyFromId, keyBuilderRecord, RecordRepresentationTTL, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, getRecordId18 as getRecordId18$1, getRecordsAdapterFactory as getRecordsAdapterFactory$1, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationVersion } from '@salesforce/lds-adapters-uiapi';
22
- import allowUpdatesForNonCachedRecords from '@salesforce/gate/lmr.allowUpdatesForNonCachedRecords';
22
+ import draftQueueMaxRetryAttemptsGate from '@salesforce/gate/lmr.draft-queue-max-retry-attempts';
23
23
  import { getInstrumentation, idleDetector } from 'o11y/client';
24
+ import allowUpdatesForNonCachedRecords from '@salesforce/gate/lmr.allowUpdatesForNonCachedRecords';
24
25
  import caseSensitiveUserId from '@salesforce/user/Id';
25
26
  import { Kind as Kind$1, visit as visit$1, isObjectType, defaultFieldResolver, buildSchema, parse as parse$8, extendSchema, isScalarType, execute, print } from '@luvio/graphql-parser';
26
27
  import graphqlRelationshipFieldsPerf from '@salesforce/gate/lds.graphqlRelationshipFieldsPerf';
@@ -2297,7 +2298,7 @@ function customActionHandler(executor, id, draftQueue) {
2297
2298
  }, result.error.type === CustomActionErrorType.NETWORK_ERROR);
2298
2299
  }
2299
2300
  };
2300
- const buildPendingAction = (action, queue) => {
2301
+ const buildPendingAction = (action, queue, observabilityContext) => {
2301
2302
  const { data, tag, targetId, handler } = action;
2302
2303
  const id = generateUniqueDraftActionId(queue.map((a) => a.id));
2303
2304
  return Promise.resolve({
@@ -2309,6 +2310,7 @@ function customActionHandler(executor, id, draftQueue) {
2309
2310
  timestamp: Date.now(),
2310
2311
  metadata: data,
2311
2312
  handler,
2313
+ observabilityContext,
2312
2314
  });
2313
2315
  };
2314
2316
  const getQueueOperationsForCompletingDrafts = (_queue, action) => {
@@ -2344,6 +2346,13 @@ function customActionHandler(executor, id, draftQueue) {
2344
2346
  }
2345
2347
 
2346
2348
  const DRAFT_SEGMENT = 'DRAFT';
2349
+ /**
2350
+ * Metadata key under which an action's upload retry-attempt count is persisted.
2351
+ * Lives in the action's durable `metadata` bag so the count survives app restarts
2352
+ * (the in-memory backoff interval resets on every startQueue()). Written by the
2353
+ * action handler on each retry and cleared when an action is manually retried.
2354
+ */
2355
+ const DRAFT_ACTION_RETRY_COUNT_METADATA_KEY = 'retryCount';
2347
2356
  class DurableDraftQueue {
2348
2357
  getHandler(id) {
2349
2358
  const handler = this.handlers[id];
@@ -2480,12 +2489,12 @@ class DurableDraftQueue {
2480
2489
  return aTime - bTime;
2481
2490
  });
2482
2491
  }
2483
- async enqueue(handlerId, data) {
2492
+ async enqueue(handlerId, data, observabilityContext) {
2484
2493
  return this.workerPool.push({
2485
2494
  workFn: async () => {
2486
2495
  let queue = await this.getQueueActions();
2487
2496
  const handler = this.getHandler(handlerId);
2488
- const pendingAction = (await handler.buildPendingAction(data, queue));
2497
+ const pendingAction = (await handler.buildPendingAction(data, queue, observabilityContext));
2489
2498
  await this.draftStore.writeAction(pendingAction);
2490
2499
  queue = await this.getQueueActions();
2491
2500
  await this.notifyChangedListeners({
@@ -2712,10 +2721,14 @@ class DurableDraftQueue {
2712
2721
  if (!isDraftError(target)) {
2713
2722
  throw Error(`Action ${actionId} is not in Error state`);
2714
2723
  }
2724
+ // A manual retry is a fresh start: clear the persisted upload retry-attempt
2725
+ // count so the action doesn't immediately re-cap after a single failure.
2726
+ const { [DRAFT_ACTION_RETRY_COUNT_METADATA_KEY]: _retryCount, ...metadataWithoutRetryCount } = target.metadata || {};
2715
2727
  let pendingAction = {
2716
2728
  ...target,
2717
2729
  status: DraftActionStatus.Pending,
2718
2730
  error: undefined,
2731
+ metadata: metadataWithoutRetryCount,
2719
2732
  };
2720
2733
  await this.draftStore.writeAction(pendingAction);
2721
2734
  await this.notifyChangedListeners({
@@ -3307,7 +3320,7 @@ class DraftManager {
3307
3320
  }
3308
3321
  buildDraftQueueItem(action) {
3309
3322
  const operationType = getOperationTypeFrom(action);
3310
- const { id, status, timestamp, targetId, metadata } = action;
3323
+ const { id, status, timestamp, targetId, metadata, observabilityContext } = action;
3311
3324
  const item = {
3312
3325
  id,
3313
3326
  targetId,
@@ -3315,6 +3328,7 @@ class DraftManager {
3315
3328
  timestamp,
3316
3329
  operationType,
3317
3330
  metadata,
3331
+ observabilityContext,
3318
3332
  };
3319
3333
  if (isDraftError(action)) {
3320
3334
  // We should always return an array, if the body is just a dictionary,
@@ -3473,7 +3487,7 @@ const snapshotRefreshOptions = {
3473
3487
  * @param data Data to be JSON-stringified.
3474
3488
  * @returns JSON.stringified value with consistent ordering of keys.
3475
3489
  */
3476
- function stableJSONStringify$1(node) {
3490
+ function stableJSONStringify(node) {
3477
3491
  // This is for Date values.
3478
3492
  if (node && node.toJSON && typeof node.toJSON === 'function') {
3479
3493
  // eslint-disable-next-line no-param-reassign
@@ -3496,7 +3510,7 @@ function stableJSONStringify$1(node) {
3496
3510
  if (i) {
3497
3511
  out += ',';
3498
3512
  }
3499
- out += stableJSONStringify$1(node[i]) || 'null';
3513
+ out += stableJSONStringify(node[i]) || 'null';
3500
3514
  }
3501
3515
  return out + ']';
3502
3516
  }
@@ -3507,7 +3521,7 @@ function stableJSONStringify$1(node) {
3507
3521
  out = '';
3508
3522
  for (i = 0; i < keys.length; i++) {
3509
3523
  const key = keys[i];
3510
- const value = stableJSONStringify$1(node[key]);
3524
+ const value = stableJSONStringify(node[key]);
3511
3525
  if (!value) {
3512
3526
  continue;
3513
3527
  }
@@ -40790,7 +40804,7 @@ function ingestTypeWithStrategy(astNode, state, isCursorConnectionType, { key, i
40790
40804
  }
40791
40805
  if (existingData !== undefined && existingData !== null && ObjectPrototypeHasOwnProperty$1.call(existingData, "__type") === false) {
40792
40806
  const mergedData = mergeData(existingData, newData);
40793
- if (!equalsObject(existingData, mergedData, (propA, propB) => stableJSONStringify$1(propA) === stableJSONStringify$1(propB))) { // naive impl
40807
+ if (!equalsObject(existingData, mergedData, (propA, propB) => stableJSONStringify(propA) === stableJSONStringify(propB))) { // naive impl
40794
40808
  luvio.storePublish(key, mergedData);
40795
40809
  }
40796
40810
  }
@@ -42137,6 +42151,324 @@ function makeEnvironmentUiApiRecordDraftAware(luvio, options, env) {
42137
42151
  return create$3(adapterSpecificEnvironments, {});
42138
42152
  }
42139
42153
 
42154
+ /**
42155
+ * This function takes an unknown error and normalizes it to an Error object
42156
+ */
42157
+ function normalizeError$1(error) {
42158
+ if (typeof error === 'object' && error instanceof Error) {
42159
+ return error;
42160
+ }
42161
+ else if (typeof error === 'string') {
42162
+ return new Error(error);
42163
+ }
42164
+ return new Error(stringify$5(error));
42165
+ }
42166
+ /**
42167
+ * Maximum number of times an action's upload will be retried before the action is
42168
+ * transitioned to Error and surfaced to the consumer. Caps the otherwise-unbounded
42169
+ * retry loop that can wedge the single-worker draft queue when an upload fails
42170
+ * deterministically on every dispatch. Only enforced when the
42171
+ * `lmr.draft-queue-max-retry-attempts` gate is open.
42172
+ */
42173
+ const MAX_RETRY_ATTEMPTS = 5;
42174
+ const MAX_RETRY_ERROR_CODE = 'MAX_RETRY_ATTEMPTS_EXCEEDED';
42175
+ function isFetchResponse(failure) {
42176
+ // The union is exactly FetchResponse | Error, so "not an Error" is the FetchResponse.
42177
+ // This is safer than duck-typing on status/ok: a custom Error subclass that happens to
42178
+ // carry those properties would be misclassified by a structural check.
42179
+ return !(failure instanceof Error);
42180
+ }
42181
+ /**
42182
+ * Builds the FetchResponse-shaped error attached to an action that has exhausted its
42183
+ * upload retries. Shaped like a real network error response (status/statusText/ok/
42184
+ * headers/body) so downstream consumers (DraftManager, queue instrumentation) that
42185
+ * read `action.error.status`/`.body`/etc. behave consistently with a server error.
42186
+ *
42187
+ * The failure that caused the final attempt — a non-ok response (HTTP path) or a thrown
42188
+ * error (catch path) — is folded into the body so the surfaced error says WHAT failed,
42189
+ * not merely that the attempt cap was reached.
42190
+ */
42191
+ function buildMaxRetryError(lastFailure) {
42192
+ const capMessage = `Draft action exceeded ${MAX_RETRY_ATTEMPTS} upload retry attempts`;
42193
+ if (isFetchResponse(lastFailure)) {
42194
+ // Preserve the server's own error detail (status + body) so the surfaced error
42195
+ // carries the last response that caused us to give up retrying.
42196
+ return {
42197
+ status: HttpStatusCode$1.ServerError,
42198
+ statusText: capMessage,
42199
+ ok: false,
42200
+ headers: {},
42201
+ body: {
42202
+ errorCode: MAX_RETRY_ERROR_CODE,
42203
+ message: `${capMessage}. Last response: status=${lastFailure.status} ${lastFailure.statusText}`,
42204
+ lastResponseStatus: lastFailure.status,
42205
+ lastResponseBody: lastFailure.body,
42206
+ },
42207
+ };
42208
+ }
42209
+ return {
42210
+ status: HttpStatusCode$1.ServerError,
42211
+ statusText: capMessage,
42212
+ ok: false,
42213
+ headers: {},
42214
+ body: {
42215
+ errorCode: MAX_RETRY_ERROR_CODE,
42216
+ message: `${capMessage}. Last error: ${lastFailure.name}: ${lastFailure.message}`,
42217
+ lastErrorName: lastFailure.name,
42218
+ lastErrorMessage: lastFailure.message,
42219
+ },
42220
+ };
42221
+ }
42222
+
42223
+ function attachObserversToAdapterRequestContext(observers, adapterRequestContext) {
42224
+ if (adapterRequestContext === undefined) {
42225
+ return { eventObservers: observers };
42226
+ }
42227
+ if (adapterRequestContext.eventObservers === undefined) {
42228
+ return { ...adapterRequestContext, eventObservers: observers };
42229
+ }
42230
+ return {
42231
+ ...adapterRequestContext,
42232
+ eventObservers: adapterRequestContext.eventObservers.concat(observers),
42233
+ };
42234
+ }
42235
+ /**
42236
+ * Use this method to sanitize the unknown error object when
42237
+ * we are unsure of the type of the error thrown
42238
+ *
42239
+ * @param err Unknown object to sanitize
42240
+ * @returns an instance of error
42241
+ */
42242
+ function normalizeError(err) {
42243
+ if (err instanceof Error) {
42244
+ return err;
42245
+ }
42246
+ else if (typeof err === 'string') {
42247
+ return new Error(err);
42248
+ }
42249
+ return new Error(stringify$5(err));
42250
+ }
42251
+
42252
+ const O11Y_NAMESPACE_LDS_MOBILE = 'lds-mobile';
42253
+ // metrics
42254
+ /** GraphQL */
42255
+ const GRAPHQL_EVAL_ERROR = 'gql-eval-error';
42256
+ const GRAPHQL_EVAL_DB_READ_DURATION = 'gql-eval-db-read-duration';
42257
+ const GRAPHQL_EVAL_ROOT_QUERY_COUNT = 'gql-eval-root-query-count';
42258
+ const GRAPHQL_EVAL_TOTAL_QUERY_COUNT = 'gql-eval-total-query-count';
42259
+ const GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT = 'gql-eval-max-child-count';
42260
+ const GRAPHQL_EVAL_QUERY_RECORD_COUNT = 'gql-eval-query-record-count';
42261
+ const GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED = 'gql-snapshot-refresh-undefined';
42262
+ /** Draft Queue */
42263
+ const DRAFT_QUEUE_STATE_STARTED = 'draft-queue-state-started';
42264
+ const DRAFT_QUEUE_STATE_ERROR = 'draft-queue-state-error';
42265
+ const DRAFT_QUEUE_STATE_WAITING = 'draft-queue-state-waiting';
42266
+ const DRAFT_QUEUE_STATE_STOPPED = 'draft-queue-state-stopped';
42267
+ const DRAFT_QUEUE_ACTION_ADDED = 'draft-queue-action-added';
42268
+ const DRAFT_QUEUE_ACTION_UPLOADING = 'draft-queue-action-uploading';
42269
+ const DRAFT_QUEUE_ACTION_COMPLETED = 'draft-queue-action-completed';
42270
+ const DRAFT_QUEUE_ACTION_DELETED = 'draft-queue-action-deleted';
42271
+ const DRAFT_QUEUE_ACTION_UPDATED = 'draft-queue-action-updated';
42272
+ const DRAFT_QUEUE_ACTION_FAILED = 'draft-queue-action-failed';
42273
+ const DRAFT_QUEUE_ACTION_UPLOAD_ERROR = 'draft-queue-action-upload-error';
42274
+ const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-calls';
42275
+ /** Content Document */
42276
+ const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
42277
+ const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
42278
+ /** Priming */
42279
+ const PRIMING_TOTAL_SESSION_COUNT = 'priming-total-session-count';
42280
+ const PRIMING_TOTAL_ERROR_COUNT = 'priming-total-error-count';
42281
+ const PRIMING_TOTAL_PRIMED_COUNT = 'priming-total-primed-count';
42282
+ const PRIMING_TOTAL_CONFLICT_COUNT = 'priming-total-conflict-count';
42283
+ // logs
42284
+ const GRAPHQL_QUERY_PARSE_ERROR = 'gql-query-parse-error';
42285
+ const GRAPHQL_SQL_EVAL_PRECONDITION_ERROR = 'gql-sql-pre-eval-error';
42286
+ const GRAPHQL_CREATE_SNAPSHOT_ERROR = 'gql-create-snapshot-error';
42287
+ const DRAFT_AWARE_CREATE_CONTENT_DOCUMENT_AND_VERSION_ERROR = 'draft-aware-create-content-document-and-version-error';
42288
+ /** Garbage Collection */
42289
+ const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_COUNT = 'garbage-collection-aggressive-trim-count';
42290
+ const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_RECORDS_TRIMMED = 'garbage-collection-aggressive-trim-records-trimmed';
42291
+ const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_TOTAL_RECORDS_BEFORE_TRIM = 'garbage-collection-aggressive-trim-total-records-before-trim';
42292
+ const ldsMobileInstrumentation = getInstrumentation(O11Y_NAMESPACE_LDS_MOBILE);
42293
+ const nimbusLogger = typeof __nimbus !== 'undefined' &&
42294
+ __nimbus.plugins !== undefined &&
42295
+ __nimbus.plugins.JSLoggerPlugin !== undefined
42296
+ ? __nimbus.plugins.JSLoggerPlugin
42297
+ : undefined;
42298
+ function reportGraphqlQueryParseError(err) {
42299
+ const error = normalizeError(err);
42300
+ const errorCode = GRAPHQL_QUERY_PARSE_ERROR;
42301
+ // Metric
42302
+ reportGraphqlAdapterError(errorCode);
42303
+ // Log
42304
+ ldsMobileInstrumentation.error(error, errorCode);
42305
+ }
42306
+ function reportGraphqlSqlEvalPreconditionError(err) {
42307
+ const error = normalizeError(err);
42308
+ const errorCode = GRAPHQL_SQL_EVAL_PRECONDITION_ERROR;
42309
+ // Metric
42310
+ reportGraphqlAdapterError(errorCode);
42311
+ // Log
42312
+ ldsMobileInstrumentation.error(error, errorCode);
42313
+ }
42314
+ function reportGraphqlCreateSnapshotError(err) {
42315
+ const error = normalizeError(err);
42316
+ const errorCode = GRAPHQL_CREATE_SNAPSHOT_ERROR;
42317
+ // Metric
42318
+ reportGraphqlAdapterError(errorCode);
42319
+ // Log
42320
+ ldsMobileInstrumentation.error(error, errorCode);
42321
+ }
42322
+ function reportGraphQlEvalDbReadDuration(duration) {
42323
+ ldsMobileInstrumentation.trackValue(GRAPHQL_EVAL_DB_READ_DURATION, duration);
42324
+ }
42325
+ function reportGraphqlAdapterError(errorCode) {
42326
+ // Increment overall count with errorCode as tag
42327
+ ldsMobileInstrumentation.incrementCounter(GRAPHQL_EVAL_ERROR, 1, true, { errorCode });
42328
+ }
42329
+ function reportGraphqlQueryInstrumentation(data) {
42330
+ const queryBuckets = [1, 2, 3, 4, 5, 10, 20, 50, 100];
42331
+ const recordBuckets = [
42332
+ 1, 5, 10, 20, 50, 100, 1000, 2000, 5000, 10000, 50000, 100000, 1000000,
42333
+ ];
42334
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_ROOT_QUERY_COUNT, data.rootQueryCount, queryBuckets);
42335
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_TOTAL_QUERY_COUNT, data.totalQueryCount, queryBuckets);
42336
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT, data.maxChildRelationships, queryBuckets);
42337
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_QUERY_RECORD_COUNT, data.requestedRecordCount, recordBuckets);
42338
+ }
42339
+ function incrementGraphQLRefreshUndfined() {
42340
+ ldsMobileInstrumentation.incrementCounter(GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED);
42341
+ }
42342
+ function reportDraftActionEvent(state, draftCount, message) {
42343
+ if (nimbusLogger) {
42344
+ nimbusLogger.logInfo(`Draft action event: ${state}, depth: ${draftCount}${message ? `, message: ${message}` : ''}`);
42345
+ }
42346
+ switch (state) {
42347
+ case 'added':
42348
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_ADDED);
42349
+ break;
42350
+ case 'uploading':
42351
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_UPLOADING);
42352
+ break;
42353
+ case 'completed':
42354
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_COMPLETED);
42355
+ break;
42356
+ case 'deleted':
42357
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_DELETED);
42358
+ break;
42359
+ case 'failed':
42360
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_FAILED, 1, true);
42361
+ break;
42362
+ case 'updated':
42363
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_UPDATED);
42364
+ break;
42365
+ }
42366
+ }
42367
+ /**
42368
+ * Reports an exception thrown while uploading a draft action. The thrown error is
42369
+ * otherwise swallowed by the upload handler's retry path, leaving the failure
42370
+ * invisible in telemetry; this surfaces it to o11y (log + counter) so a deterministic
42371
+ * upload failure can be diagnosed instead of silently retried forever.
42372
+ *
42373
+ * PII: the device log line carries only the handler id, retry attempt, and the error
42374
+ * NAME (e.g. "TypeError") — never the free-text error message, which can embed record
42375
+ * ids (URL path segments) or server field-validation strings. The full normalized error
42376
+ * (message + stack) is handed only to `ldsMobileInstrumentation.error`, the structured
42377
+ * o11y error pipeline responsible for scrubbing/handling that detail. Also does NOT log
42378
+ * the action's targetId/tag or any request body/field values.
42379
+ */
42380
+ function reportDraftActionUploadError(error, handlerId, attempt) {
42381
+ const normalized = normalizeError(error);
42382
+ if (nimbusLogger) {
42383
+ nimbusLogger.logError(`Draft action upload error: handler=${handlerId}, attempt=${attempt}, name=${normalized.name}`);
42384
+ }
42385
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_UPLOAD_ERROR, 1, true, {
42386
+ handlerId,
42387
+ });
42388
+ ldsMobileInstrumentation.error(normalized, DRAFT_QUEUE_ACTION_UPLOAD_ERROR);
42389
+ }
42390
+ function reportDraftQueueState(state, draftCount) {
42391
+ if (nimbusLogger) {
42392
+ nimbusLogger.logInfo(`Draft state changed: ${state}, depth: ${draftCount}`);
42393
+ }
42394
+ switch (state) {
42395
+ case 'started':
42396
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_STARTED);
42397
+ break;
42398
+ case 'error':
42399
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_ERROR, 1, true);
42400
+ break;
42401
+ case 'waiting':
42402
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_WAITING);
42403
+ break;
42404
+ case 'stopped':
42405
+ ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_STOPPED);
42406
+ break;
42407
+ }
42408
+ }
42409
+ function reportDraftAwareContentDocumentVersionSynthesizeError(err) {
42410
+ let error;
42411
+ if (err.body !== undefined) {
42412
+ error = err.body;
42413
+ }
42414
+ else {
42415
+ error = normalizeError(err);
42416
+ }
42417
+ const errorCode = DRAFT_AWARE_CREATE_CONTENT_DOCUMENT_AND_VERSION_ERROR;
42418
+ const errorType = error.errorType;
42419
+ const tags = {
42420
+ errorCode,
42421
+ };
42422
+ if (errorType !== undefined) {
42423
+ tags.errorType = errorType;
42424
+ }
42425
+ // Metric
42426
+ ldsMobileInstrumentation.incrementCounter(CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR, 1, true, tags);
42427
+ // Log
42428
+ ldsMobileInstrumentation.error(error, errorCode);
42429
+ }
42430
+ function reportDraftAwareContentVersionSynthesizeCalls(mimeType) {
42431
+ ldsMobileInstrumentation.incrementCounter(CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS, 1, undefined, { mimeType });
42432
+ }
42433
+ /** Priming */
42434
+ function reportPrimingSessionCreated() {
42435
+ ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_SESSION_COUNT, 1, undefined, {});
42436
+ }
42437
+ function reportPrimingError(errorType, recordCount) {
42438
+ ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_ERROR_COUNT, recordCount, undefined, {
42439
+ errorType,
42440
+ });
42441
+ }
42442
+ function reportPrimingSuccess(recordCount) {
42443
+ ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_PRIMED_COUNT, recordCount, undefined);
42444
+ }
42445
+ function reportPrimingConflict(resolutionType, recordCount) {
42446
+ ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_CONFLICT_COUNT, recordCount, undefined, {
42447
+ resolutionType,
42448
+ });
42449
+ }
42450
+ /** Network */
42451
+ function reportChunkCandidateUrlLength(urlLength) {
42452
+ const buckets = [8000, 10000, 12000, 14000, 16000];
42453
+ ldsMobileInstrumentation.bucketValue('chunk-candidate-url-length-histogram', urlLength, buckets);
42454
+ }
42455
+ /** Garbage Collection */
42456
+ function reportAggressiveTrimTriggered(trimCount, beforeTrimRecordCount, totalRecordsTrimmed) {
42457
+ ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_COUNT, trimCount);
42458
+ ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_TOTAL_RECORDS_BEFORE_TRIM, beforeTrimRecordCount);
42459
+ ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_RECORDS_TRIMMED, totalRecordsTrimmed);
42460
+ }
42461
+ /** One Store Cache Purge */
42462
+ const ONESTORE_CACHE_PURGING_RECORDS_PURGED = 'onestore-cache-purging-records-purged';
42463
+ const ONESTORE_CACHE_PURGING_RECORDS_ERROR = 'onestore-cache-purging-records-error';
42464
+ function reportOneStoreRecordsPurgedFromCache(recordsPurged) {
42465
+ ldsMobileInstrumentation.trackValue(ONESTORE_CACHE_PURGING_RECORDS_PURGED, recordsPurged);
42466
+ }
42467
+ function reportOneStoreCachePurgingError(error) {
42468
+ const errorMessage = normalizeError(error);
42469
+ ldsMobileInstrumentation.error(errorMessage, ONESTORE_CACHE_PURGING_RECORDS_ERROR);
42470
+ }
42471
+
42140
42472
  const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
42141
42473
  const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
42142
42474
  const ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED = 'IDEMPOTENCY_FEATURE_NOT_ENABLED';
@@ -42180,10 +42512,10 @@ class AbstractResourceRequestActionHandler {
42180
42512
  // determined by Server setup.
42181
42513
  this.isIdempotencySupported = true;
42182
42514
  }
42183
- enqueue(data) {
42184
- return this.draftQueue.enqueue(this.handlerId, data);
42515
+ enqueue(data, observabilityContext) {
42516
+ return this.draftQueue.enqueue(this.handlerId, data, observabilityContext);
42185
42517
  }
42186
- async buildPendingAction(request, queue) {
42518
+ async buildPendingAction(request, queue, observabilityContext) {
42187
42519
  const targetId = await this.getIdFromRequest(request);
42188
42520
  const tag = this.buildTagForTargetId(targetId);
42189
42521
  const handlerActions = queue.filter((x) => x.handler === this.handlerId);
@@ -42203,13 +42535,16 @@ class AbstractResourceRequestActionHandler {
42203
42535
  timestamp: Date.now(),
42204
42536
  metadata: {},
42205
42537
  version: '242.0.0',
42538
+ observabilityContext,
42206
42539
  };
42207
42540
  }
42208
42541
  async handleAction(action, actionCompleted, actionErrored) {
42209
42542
  const { data: request } = action;
42210
- // no context is stored in draft action
42543
+ const dispatchOptions = action.observabilityContext !== undefined
42544
+ ? { requestCorrelator: { observabilityContext: action.observabilityContext } }
42545
+ : {};
42211
42546
  try {
42212
- const response = await this.networkAdapter(request, {});
42547
+ const response = await this.networkAdapter(request, dispatchOptions);
42213
42548
  if (response.ok) {
42214
42549
  await actionCompleted({
42215
42550
  ...action,
@@ -42287,20 +42622,89 @@ class AbstractResourceRequestActionHandler {
42287
42622
  shouldRetry = true;
42288
42623
  actionDataChanged = true;
42289
42624
  }
42290
- await actionErrored(shouldRetry
42291
- ? updatedAction
42292
- : {
42625
+ if (shouldRetry) {
42626
+ // Funnel the retry through the cap: when the gate is open this persists
42627
+ // the attempt count and errors out once the cap is hit; when the gate is
42628
+ // closed it behaves exactly as before. The non-ok response is the failure
42629
+ // that would otherwise be retried.
42630
+ await this.retryOrCap(updatedAction, response, actionErrored, retryDelayInMs, actionDataChanged);
42631
+ }
42632
+ else {
42633
+ await actionErrored({
42293
42634
  ...updatedAction,
42294
42635
  error: response,
42295
42636
  status: DraftActionStatus.Error,
42296
- }, shouldRetry, retryDelayInMs, actionDataChanged);
42637
+ }, false, retryDelayInMs, actionDataChanged);
42638
+ }
42297
42639
  return ProcessActionResult.ACTION_ERRORED;
42298
42640
  }
42299
42641
  catch (e) {
42300
- await actionErrored(action, true);
42642
+ // #3 (ungated): the thrown exception is otherwise swallowed here, leaving a
42643
+ // deterministic upload failure invisible in telemetry. Surface it to o11y
42644
+ // before deciding whether to retry.
42645
+ const error = normalizeError$1(e);
42646
+ const attempt = this.getUploadRetryCount(action) + 1;
42647
+ reportDraftActionUploadError(error, this.handlerId, attempt);
42648
+ await this.retryOrCap(action, error, actionErrored);
42301
42649
  return ProcessActionResult.NETWORK_ERROR;
42302
42650
  }
42303
42651
  }
42652
+ /**
42653
+ * Reads the persisted upload retry-attempt count from the action's durable metadata
42654
+ * bag. The count lives in metadata (rather than in-memory) so it survives app
42655
+ * restarts and queue re-creation — the failure modes that let the unbounded retry
42656
+ * loop run for days.
42657
+ */
42658
+ getUploadRetryCount(action) {
42659
+ const parsed = Number(action.metadata?.[DRAFT_ACTION_RETRY_COUNT_METADATA_KEY]);
42660
+ // Guard against a missing/corrupt persisted value: a NaN, fractional, or negative
42661
+ // count must never weaken the cap. Floor to a non-negative integer, defaulting to 0.
42662
+ if (!Number.isFinite(parsed) || parsed < 0) {
42663
+ return 0;
42664
+ }
42665
+ return Math.floor(parsed);
42666
+ }
42667
+ /**
42668
+ * Enforces the upload retry-attempt cap around the queue's `actionErrored` callback.
42669
+ * Both retry paths — a retryable HTTP error and a thrown exception — funnel through
42670
+ * here.
42671
+ *
42672
+ * The entire cap behavior is gated behind `lmr.draft-queue-max-retry-attempts`. When
42673
+ * the gate is CLOSED this is a transparent passthrough: it issues the same
42674
+ * `actionErrored(action, true, ...)` retry the queue made before this change, and
42675
+ * writes no extra metadata. When the gate is OPEN it persists an incremented attempt
42676
+ * count to the action's durable metadata and, once the action has failed
42677
+ * {@link MAX_RETRY_ATTEMPTS} times, transitions it to Error (carrying a
42678
+ * FetchResponse-shaped error that names the failure that exhausted the retries)
42679
+ * instead of scheduling yet another retry.
42680
+ */
42681
+ async retryOrCap(action, lastFailure, actionErrored, retryDelayInMs, actionDataChanged) {
42682
+ if (!draftQueueMaxRetryAttemptsGate.isOpen({ fallback: false })) {
42683
+ // Gate closed: preserve the pre-existing unbounded-retry behavior exactly.
42684
+ await actionErrored(action, true, retryDelayInMs, actionDataChanged);
42685
+ return;
42686
+ }
42687
+ const attempt = this.getUploadRetryCount(action) + 1;
42688
+ if (attempt >= MAX_RETRY_ATTEMPTS) {
42689
+ await actionErrored({
42690
+ ...action,
42691
+ error: buildMaxRetryError(lastFailure),
42692
+ status: DraftActionStatus.Error,
42693
+ }, false);
42694
+ return;
42695
+ }
42696
+ // Persist the incremented attempt count so it survives restarts. Forcing
42697
+ // actionDataChanged ensures the queue writes the updated metadata before the
42698
+ // action is rescheduled for retry.
42699
+ const retryingAction = {
42700
+ ...action,
42701
+ metadata: {
42702
+ ...action.metadata,
42703
+ [DRAFT_ACTION_RETRY_COUNT_METADATA_KEY]: String(attempt),
42704
+ },
42705
+ };
42706
+ await actionErrored(retryingAction, true, retryDelayInMs, true);
42707
+ }
42304
42708
  async handleActionEnqueued(action) {
42305
42709
  const impactedKeys = await this.recordService.setSideEffectsForActions([action]);
42306
42710
  await this.recordService.reapplyRecordSideEffects(impactedKeys);
@@ -42464,6 +42868,13 @@ class AbstractResourceRequestActionHandler {
42464
42868
  this.isActionOfType(sourceAction)) {
42465
42869
  targetAction.status = DraftActionStatus.Pending;
42466
42870
  targetAction.data = sourceAction.data;
42871
+ // Replacing an action's data re-queues it as a fresh upload, so the persisted
42872
+ // upload retry-attempt count must not carry over — otherwise a previously-
42873
+ // throttled action could immediately re-hit the cap on its first new attempt.
42874
+ // (Mirrors the same clear in mergeActions.)
42875
+ if (targetAction.metadata !== undefined) {
42876
+ delete targetAction.metadata[DRAFT_ACTION_RETRY_COUNT_METADATA_KEY];
42877
+ }
42467
42878
  return targetAction;
42468
42879
  }
42469
42880
  else {
@@ -42489,6 +42900,17 @@ class AbstractResourceRequestActionHandler {
42489
42900
  timestamp: targetTimestamp,
42490
42901
  id: targetId,
42491
42902
  };
42903
+ // The merged action retains the target's observabilityContext, not the source's.
42904
+ // Attribution belongs to the user action that first enqueued the target draft; the
42905
+ // source's context (if any) is intentionally discarded. If the target had no context
42906
+ // when it was enqueued, the merged action has none — we do not promote the source's
42907
+ // context as a fallback.
42908
+ if (targetAction.observabilityContext !== undefined) {
42909
+ merged.observabilityContext = targetAction.observabilityContext;
42910
+ }
42911
+ else {
42912
+ delete merged.observabilityContext;
42913
+ }
42492
42914
  // overlay data
42493
42915
  // NOTE: we stick to the target's ResourceRequest properties (except body
42494
42916
  // which is merged) because we don't want to overwrite a POST with a PATCH
@@ -42503,6 +42925,11 @@ class AbstractResourceRequestActionHandler {
42503
42925
  }
42504
42926
  // overlay metadata
42505
42927
  merged.metadata = { ...targetMetadata, ...sourceMetadata };
42928
+ // A merge folds new user data into the action and re-queues it as a fresh upload,
42929
+ // so the persisted upload retry-attempt count must not carry over — otherwise a
42930
+ // previously-throttled action could immediately re-hit the cap on its first new
42931
+ // attempt.
42932
+ delete merged.metadata[DRAFT_ACTION_RETRY_COUNT_METADATA_KEY];
42506
42933
  // put status back to pending to auto upload if queue is active and targed is at the head.
42507
42934
  merged.status = DraftActionStatus.Pending;
42508
42935
  return merged;
@@ -42636,9 +43063,9 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
42636
43063
  setSideEffectHooks(hooks) {
42637
43064
  this.sideEffectHooks = hooks;
42638
43065
  }
42639
- async buildPendingAction(request, queue) {
43066
+ async buildPendingAction(request, queue, observabilityContext) {
42640
43067
  const resolvedRequest = this.resolveResourceRequest(request);
42641
- let pendingAction = (await super.buildPendingAction(resolvedRequest, queue));
43068
+ let pendingAction = (await super.buildPendingAction(resolvedRequest, queue, observabilityContext));
42642
43069
  const { tag, targetId } = pendingAction;
42643
43070
  const targetApiName = await this.getApiNameForRecordId(targetId, tag, resolvedRequest);
42644
43071
  pendingAction.metadata[LDS_ACTION_METADATA_API_NAME] = targetApiName;
@@ -43081,10 +43508,10 @@ class AbstractQuickActionHandler extends AbstractResourceRequestActionHandler {
43081
43508
  constructor(draftQueue, networkAdapter, getLuvio, recordService) {
43082
43509
  super(draftQueue, networkAdapter, getLuvio, recordService);
43083
43510
  }
43084
- async buildPendingAction(request, queue) {
43511
+ async buildPendingAction(request, queue, observabilityContext) {
43085
43512
  this.resolveResourceRequestBody(request.body);
43086
43513
  // eslint-disable-next-line no-return-await
43087
- return await super.buildPendingAction(request, queue);
43514
+ return await super.buildPendingAction(request, queue, observabilityContext);
43088
43515
  }
43089
43516
  resolveResourceRequestBody(body) {
43090
43517
  let contextId = body.contextId;
@@ -43114,231 +43541,6 @@ class AbstractQuickActionHandler extends AbstractResourceRequestActionHandler {
43114
43541
  }
43115
43542
  }
43116
43543
 
43117
- function attachObserversToAdapterRequestContext(observers, adapterRequestContext) {
43118
- if (adapterRequestContext === undefined) {
43119
- return { eventObservers: observers };
43120
- }
43121
- if (adapterRequestContext.eventObservers === undefined) {
43122
- return { ...adapterRequestContext, eventObservers: observers };
43123
- }
43124
- return {
43125
- ...adapterRequestContext,
43126
- eventObservers: adapterRequestContext.eventObservers.concat(observers),
43127
- };
43128
- }
43129
- /**
43130
- * Use this method to sanitize the unknown error object when
43131
- * we are unsure of the type of the error thrown
43132
- *
43133
- * @param err Unknown object to sanitize
43134
- * @returns an instance of error
43135
- */
43136
- function normalizeError(err) {
43137
- if (err instanceof Error) {
43138
- return err;
43139
- }
43140
- else if (typeof err === 'string') {
43141
- return new Error(err);
43142
- }
43143
- return new Error(stringify$5(err));
43144
- }
43145
-
43146
- const O11Y_NAMESPACE_LDS_MOBILE = 'lds-mobile';
43147
- // metrics
43148
- /** GraphQL */
43149
- const GRAPHQL_EVAL_ERROR = 'gql-eval-error';
43150
- const GRAPHQL_EVAL_DB_READ_DURATION = 'gql-eval-db-read-duration';
43151
- const GRAPHQL_EVAL_ROOT_QUERY_COUNT = 'gql-eval-root-query-count';
43152
- const GRAPHQL_EVAL_TOTAL_QUERY_COUNT = 'gql-eval-total-query-count';
43153
- const GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT = 'gql-eval-max-child-count';
43154
- const GRAPHQL_EVAL_QUERY_RECORD_COUNT = 'gql-eval-query-record-count';
43155
- const GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED = 'gql-snapshot-refresh-undefined';
43156
- /** Draft Queue */
43157
- const DRAFT_QUEUE_STATE_STARTED = 'draft-queue-state-started';
43158
- const DRAFT_QUEUE_STATE_ERROR = 'draft-queue-state-error';
43159
- const DRAFT_QUEUE_STATE_WAITING = 'draft-queue-state-waiting';
43160
- const DRAFT_QUEUE_STATE_STOPPED = 'draft-queue-state-stopped';
43161
- const DRAFT_QUEUE_ACTION_ADDED = 'draft-queue-action-added';
43162
- const DRAFT_QUEUE_ACTION_UPLOADING = 'draft-queue-action-uploading';
43163
- const DRAFT_QUEUE_ACTION_COMPLETED = 'draft-queue-action-completed';
43164
- const DRAFT_QUEUE_ACTION_DELETED = 'draft-queue-action-deleted';
43165
- const DRAFT_QUEUE_ACTION_UPDATED = 'draft-queue-action-updated';
43166
- const DRAFT_QUEUE_ACTION_FAILED = 'draft-queue-action-failed';
43167
- const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-calls';
43168
- /** Content Document */
43169
- const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
43170
- const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
43171
- /** Priming */
43172
- const PRIMING_TOTAL_SESSION_COUNT = 'priming-total-session-count';
43173
- const PRIMING_TOTAL_ERROR_COUNT = 'priming-total-error-count';
43174
- const PRIMING_TOTAL_PRIMED_COUNT = 'priming-total-primed-count';
43175
- const PRIMING_TOTAL_CONFLICT_COUNT = 'priming-total-conflict-count';
43176
- // logs
43177
- const GRAPHQL_QUERY_PARSE_ERROR = 'gql-query-parse-error';
43178
- const GRAPHQL_SQL_EVAL_PRECONDITION_ERROR = 'gql-sql-pre-eval-error';
43179
- const GRAPHQL_CREATE_SNAPSHOT_ERROR = 'gql-create-snapshot-error';
43180
- const DRAFT_AWARE_CREATE_CONTENT_DOCUMENT_AND_VERSION_ERROR = 'draft-aware-create-content-document-and-version-error';
43181
- /** Garbage Collection */
43182
- const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_COUNT = 'garbage-collection-aggressive-trim-count';
43183
- const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_RECORDS_TRIMMED = 'garbage-collection-aggressive-trim-records-trimmed';
43184
- const GARBAGE_COLLECTION_AGGRESSIVE_TRIM_TOTAL_RECORDS_BEFORE_TRIM = 'garbage-collection-aggressive-trim-total-records-before-trim';
43185
- const ldsMobileInstrumentation = getInstrumentation(O11Y_NAMESPACE_LDS_MOBILE);
43186
- const nimbusLogger = typeof __nimbus !== 'undefined' &&
43187
- __nimbus.plugins !== undefined &&
43188
- __nimbus.plugins.JSLoggerPlugin !== undefined
43189
- ? __nimbus.plugins.JSLoggerPlugin
43190
- : undefined;
43191
- function reportGraphqlQueryParseError(err) {
43192
- const error = normalizeError(err);
43193
- const errorCode = GRAPHQL_QUERY_PARSE_ERROR;
43194
- // Metric
43195
- reportGraphqlAdapterError(errorCode);
43196
- // Log
43197
- ldsMobileInstrumentation.error(error, errorCode);
43198
- }
43199
- function reportGraphqlSqlEvalPreconditionError(err) {
43200
- const error = normalizeError(err);
43201
- const errorCode = GRAPHQL_SQL_EVAL_PRECONDITION_ERROR;
43202
- // Metric
43203
- reportGraphqlAdapterError(errorCode);
43204
- // Log
43205
- ldsMobileInstrumentation.error(error, errorCode);
43206
- }
43207
- function reportGraphqlCreateSnapshotError(err) {
43208
- const error = normalizeError(err);
43209
- const errorCode = GRAPHQL_CREATE_SNAPSHOT_ERROR;
43210
- // Metric
43211
- reportGraphqlAdapterError(errorCode);
43212
- // Log
43213
- ldsMobileInstrumentation.error(error, errorCode);
43214
- }
43215
- function reportGraphQlEvalDbReadDuration(duration) {
43216
- ldsMobileInstrumentation.trackValue(GRAPHQL_EVAL_DB_READ_DURATION, duration);
43217
- }
43218
- function reportGraphqlAdapterError(errorCode) {
43219
- // Increment overall count with errorCode as tag
43220
- ldsMobileInstrumentation.incrementCounter(GRAPHQL_EVAL_ERROR, 1, true, { errorCode });
43221
- }
43222
- function reportGraphqlQueryInstrumentation(data) {
43223
- const queryBuckets = [1, 2, 3, 4, 5, 10, 20, 50, 100];
43224
- const recordBuckets = [
43225
- 1, 5, 10, 20, 50, 100, 1000, 2000, 5000, 10000, 50000, 100000, 1000000,
43226
- ];
43227
- ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_ROOT_QUERY_COUNT, data.rootQueryCount, queryBuckets);
43228
- ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_TOTAL_QUERY_COUNT, data.totalQueryCount, queryBuckets);
43229
- ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT, data.maxChildRelationships, queryBuckets);
43230
- ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_QUERY_RECORD_COUNT, data.requestedRecordCount, recordBuckets);
43231
- }
43232
- function incrementGraphQLRefreshUndfined() {
43233
- ldsMobileInstrumentation.incrementCounter(GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED);
43234
- }
43235
- function reportDraftActionEvent(state, draftCount, message) {
43236
- if (nimbusLogger) {
43237
- nimbusLogger.logInfo(`Draft action event: ${state}, depth: ${draftCount}${message ? `, message: ${message}` : ''}`);
43238
- }
43239
- switch (state) {
43240
- case 'added':
43241
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_ADDED);
43242
- break;
43243
- case 'uploading':
43244
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_UPLOADING);
43245
- break;
43246
- case 'completed':
43247
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_COMPLETED);
43248
- break;
43249
- case 'deleted':
43250
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_DELETED);
43251
- break;
43252
- case 'failed':
43253
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_FAILED, 1, true);
43254
- break;
43255
- case 'updated':
43256
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_UPDATED);
43257
- break;
43258
- }
43259
- }
43260
- function reportDraftQueueState(state, draftCount) {
43261
- if (nimbusLogger) {
43262
- nimbusLogger.logInfo(`Draft state changed: ${state}, depth: ${draftCount}`);
43263
- }
43264
- switch (state) {
43265
- case 'started':
43266
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_STARTED);
43267
- break;
43268
- case 'error':
43269
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_ERROR, 1, true);
43270
- break;
43271
- case 'waiting':
43272
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_WAITING);
43273
- break;
43274
- case 'stopped':
43275
- ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_STOPPED);
43276
- break;
43277
- }
43278
- }
43279
- function reportDraftAwareContentDocumentVersionSynthesizeError(err) {
43280
- let error;
43281
- if (err.body !== undefined) {
43282
- error = err.body;
43283
- }
43284
- else {
43285
- error = normalizeError(err);
43286
- }
43287
- const errorCode = DRAFT_AWARE_CREATE_CONTENT_DOCUMENT_AND_VERSION_ERROR;
43288
- const errorType = error.errorType;
43289
- const tags = {
43290
- errorCode,
43291
- };
43292
- if (errorType !== undefined) {
43293
- tags.errorType = errorType;
43294
- }
43295
- // Metric
43296
- ldsMobileInstrumentation.incrementCounter(CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR, 1, true, tags);
43297
- // Log
43298
- ldsMobileInstrumentation.error(error, errorCode);
43299
- }
43300
- function reportDraftAwareContentVersionSynthesizeCalls(mimeType) {
43301
- ldsMobileInstrumentation.incrementCounter(CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS, 1, undefined, { mimeType });
43302
- }
43303
- /** Priming */
43304
- function reportPrimingSessionCreated() {
43305
- ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_SESSION_COUNT, 1, undefined, {});
43306
- }
43307
- function reportPrimingError(errorType, recordCount) {
43308
- ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_ERROR_COUNT, recordCount, undefined, {
43309
- errorType,
43310
- });
43311
- }
43312
- function reportPrimingSuccess(recordCount) {
43313
- ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_PRIMED_COUNT, recordCount, undefined);
43314
- }
43315
- function reportPrimingConflict(resolutionType, recordCount) {
43316
- ldsMobileInstrumentation.incrementCounter(PRIMING_TOTAL_CONFLICT_COUNT, recordCount, undefined, {
43317
- resolutionType,
43318
- });
43319
- }
43320
- /** Network */
43321
- function reportChunkCandidateUrlLength(urlLength) {
43322
- const buckets = [8000, 10000, 12000, 14000, 16000];
43323
- ldsMobileInstrumentation.bucketValue('chunk-candidate-url-length-histogram', urlLength, buckets);
43324
- }
43325
- /** Garbage Collection */
43326
- function reportAggressiveTrimTriggered(trimCount, beforeTrimRecordCount, totalRecordsTrimmed) {
43327
- ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_COUNT, trimCount);
43328
- ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_TOTAL_RECORDS_BEFORE_TRIM, beforeTrimRecordCount);
43329
- ldsMobileInstrumentation.trackValue(GARBAGE_COLLECTION_AGGRESSIVE_TRIM_RECORDS_TRIMMED, totalRecordsTrimmed);
43330
- }
43331
- /** One Store Cache Purge */
43332
- const ONESTORE_CACHE_PURGING_RECORDS_PURGED = 'onestore-cache-purging-records-purged';
43333
- const ONESTORE_CACHE_PURGING_RECORDS_ERROR = 'onestore-cache-purging-records-error';
43334
- function reportOneStoreRecordsPurgedFromCache(recordsPurged) {
43335
- ldsMobileInstrumentation.trackValue(ONESTORE_CACHE_PURGING_RECORDS_PURGED, recordsPurged);
43336
- }
43337
- function reportOneStoreCachePurgingError(error) {
43338
- const errorMessage = normalizeError(error);
43339
- ldsMobileInstrumentation.error(errorMessage, ONESTORE_CACHE_PURGING_RECORDS_ERROR);
43340
- }
43341
-
43342
43544
  const QUICK_ACTION_HANDLER = 'QUICK_ACTION_HANDLER';
43343
43545
  class QuickActionExecutionRepresentationHandler extends AbstractQuickActionHandler {
43344
43546
  constructor(getLuvio, draftRecordService, draftQueue, networkAdapter, isDraftId, sideEffectService, objectInfoService, getRecord) {
@@ -43518,6 +43720,18 @@ function isCreateContentDocumentAndVersionDraftAdapterEvent(customEvent) {
43518
43720
  return customEvent.namespace === CONTENT_DOCUMENT_AND_VERSION_NAMESPACE;
43519
43721
  }
43520
43722
 
43723
+ /**
43724
+ * lds-worker-api packs the user action's ObservabilityContext into
43725
+ * `requestContext.requestCorrelator = { observabilityContext }`. This helper
43726
+ * unwraps it for draft-aware adapter wrappers, which forward the context to
43727
+ * the action handler so retry network spans can be parented to the
43728
+ * originating user action.
43729
+ */
43730
+ function extractObservabilityContext(requestContext) {
43731
+ const correlator = requestContext?.requestCorrelator;
43732
+ return correlator?.observabilityContext;
43733
+ }
43734
+
43521
43735
  function chunkToBase64(chunk) {
43522
43736
  const bytes = new Uint8Array(chunk);
43523
43737
  const CHUNK_SIZE = 64 * 1024; // 64kb, any bigger and fromCharCode() can error out with an overflow.
@@ -43600,7 +43814,10 @@ function createContentDocumentAndVersionDraftAdapterFactory(luvio, binaryStore,
43600
43814
  if (actionHandler.hasIdempotencySupport()) {
43601
43815
  resourceRequest.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
43602
43816
  }
43603
- const action = await actionHandler.enqueue(resourceRequest).catch(async (error) => {
43817
+ const observabilityContext = extractObservabilityContext(requestContext);
43818
+ const action = await actionHandler
43819
+ .enqueue(resourceRequest, observabilityContext)
43820
+ .catch(async (error) => {
43604
43821
  eventEmitter({
43605
43822
  type: 'create-content-document-and-version-synthesized-response-error',
43606
43823
  handle,
@@ -43701,8 +43918,8 @@ class ContentDocumentCompositeRepresentationActionHandler extends AbstractResour
43701
43918
  this.handlerId = HANDLER_ID;
43702
43919
  draftRecordService.registerRecordHandler(this);
43703
43920
  }
43704
- async buildPendingAction(request, queue) {
43705
- const pendingAction = (await super.buildPendingAction(request, queue));
43921
+ async buildPendingAction(request, queue, observabilityContext) {
43922
+ const pendingAction = (await super.buildPendingAction(request, queue, observabilityContext));
43706
43923
  const { targetId } = pendingAction;
43707
43924
  // remember ContentDocument ID
43708
43925
  pendingAction.metadata[CONTENT_DOCUMENT_DRAFT_ID_KEY] = targetId;
@@ -43966,21 +44183,23 @@ function getDescriptionFromResourceRequest(request) {
43966
44183
  return undefined;
43967
44184
  }
43968
44185
 
43969
- /* istanbul ignore file - covered by integration tests */
43970
44186
  /**
43971
44187
  * @param luvio The runtime's luvio instance
43972
44188
  * @param actionHandler The UIAPI Record action handler. NOTE: this adapter doesn't
43973
44189
  * register it with the DraftQueue, runtime should set that up
43974
44190
  */
43975
44191
  function createRecordDraftAdapterFactory(actionHandler, durableRecordStore) {
43976
- return async function createRecordDraftAdapter(config, createResourceRequest) {
44192
+ return async function createRecordDraftAdapter(config, createResourceRequest, requestContext) {
43977
44193
  const request = createResourceRequest(config);
43978
44194
  if (actionHandler.hasIdempotencySupport()) {
43979
44195
  request.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
43980
44196
  }
43981
44197
  request.queryParams = request.queryParams || {};
43982
44198
  request.queryParams['includeFieldsInBody'] = true;
43983
- const action = await actionHandler.enqueue(request).catch((err) => {
44199
+ const observabilityContext = extractObservabilityContext(requestContext);
44200
+ const action = await actionHandler
44201
+ .enqueue(request, observabilityContext)
44202
+ .catch((err) => {
43984
44203
  throw transformErrorToDraftSynthesisError(err);
43985
44204
  });
43986
44205
  let record = await durableRecordStore.getRecord(action.tag);
@@ -44060,34 +44279,34 @@ function updateRecordDraftAdapterFactory(actionHandler, durableRecordStore, obje
44060
44279
  };
44061
44280
  }
44062
44281
 
44063
- /* istanbul ignore file - covered by integration tests */
44064
44282
  /**
44065
44283
  * @param luvio The runtime's luvio instance
44066
44284
  * @param actionHandler The UIAPI Record action handler. NOTE: this adapter doesn't
44067
44285
  * register it with the DraftQueue, runtime should set that up
44068
44286
  */
44069
44287
  function deleteRecordDraftAdapterFactory(actionHandler) {
44070
- return async function deleteRecordDraftAdapter(config, buildResourceRequest) {
44288
+ return async function deleteRecordDraftAdapter(config, buildResourceRequest, requestContext) {
44071
44289
  const request = buildResourceRequest(config);
44072
44290
  if (actionHandler.hasIdempotencySupport()) {
44073
44291
  request.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
44074
44292
  }
44075
- await actionHandler.enqueue(request).catch((err) => {
44293
+ const observabilityContext = extractObservabilityContext(requestContext);
44294
+ await actionHandler.enqueue(request, observabilityContext).catch((err) => {
44076
44295
  throw transformErrorToDraftSynthesisError(err);
44077
44296
  });
44078
44297
  };
44079
44298
  }
44080
44299
 
44081
- /* istanbul ignore file - covered by integration tests */
44082
44300
  /**
44083
44301
  * @param luvio The runtime's luvio instance
44084
44302
  * @param actionHandler The UIAPI Record action handler. NOTE: this adapter doesn't
44085
44303
  * register it with the DraftQueue, runtime should set that up
44086
44304
  */
44087
44305
  function performQuickActionDraftAdapterFactory(actionHandler, userId) {
44088
- return async function performQuickActionDraftAdapter(config, createResourceRequest) {
44306
+ return async function performQuickActionDraftAdapter(config, createResourceRequest, requestContext) {
44089
44307
  const request = createResourceRequest(config);
44090
- const action = await actionHandler.enqueue(request).catch((err) => {
44308
+ const observabilityContext = extractObservabilityContext(requestContext);
44309
+ const action = await actionHandler.enqueue(request, observabilityContext).catch((err) => {
44091
44310
  const error = transformErrorToDraftSynthesisError(err);
44092
44311
  deepFreeze$1(error);
44093
44312
  throw error;
@@ -44114,16 +44333,18 @@ function performQuickActionDraftAdapterFactory(actionHandler, userId) {
44114
44333
  };
44115
44334
  }
44116
44335
 
44117
- /* istanbul ignore file - covered by integration tests */
44118
44336
  /**
44119
44337
  * @param luvio The runtime's luvio instance
44120
44338
  * @param actionHandler The UIAPI Record action handler. NOTE: this adapter doesn't
44121
44339
  * register it with the DraftQueue, runtime should set that up
44122
44340
  */
44123
44341
  function performUpdateRecordQuickActionDraftAdapterFactory(actionHandler, userId) {
44124
- return async function performUpdateRecordQuickActionDraftAdapter(config, createResourceRequest) {
44342
+ return async function performUpdateRecordQuickActionDraftAdapter(config, createResourceRequest, requestContext) {
44125
44343
  const request = createResourceRequest(config);
44126
- const action = await actionHandler.enqueue(request).catch((err) => {
44344
+ const observabilityContext = extractObservabilityContext(requestContext);
44345
+ const action = await actionHandler
44346
+ .enqueue(request, observabilityContext)
44347
+ .catch((err) => {
44127
44348
  const error = transformErrorToDraftSynthesisError(err);
44128
44349
  deepFreeze$1(error);
44129
44350
  throw error;
@@ -51311,6 +51532,7 @@ function buildNimbusNetworkPluginRequest(resourceRequest, resourceRequestContext
51311
51532
  let observabilityContext = null;
51312
51533
  if (resourceRequestContext !== undefined &&
51313
51534
  resourceRequestContext.requestCorrelator !== undefined &&
51535
+ resourceRequestContext.requestCorrelator !== null &&
51314
51536
  resourceRequestContext.requestCorrelator.observabilityContext !==
51315
51537
  undefined) {
51316
51538
  ({ observabilityContext = null } =
@@ -51909,12 +52131,16 @@ function makeNetworkAdapterChunkRecordFields(networkAdapter, instrumentationSink
51909
52131
  * to a concrete implementation running in jscore.
51910
52132
  */
51911
52133
  class NimbusDraftQueue {
51912
- enqueue(handlerId, data) {
52134
+ enqueue(handlerId, data, observabilityContext) {
51913
52135
  const callProxyMethod = __nimbus.plugins.LdsDraftQueue.callProxyMethod;
51914
52136
  if (callProxyMethod === undefined) {
51915
52137
  return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
51916
52138
  }
51917
- const serializedAction = stringify$5([handlerId, data]);
52139
+ const args = [handlerId, data];
52140
+ if (observabilityContext !== undefined) {
52141
+ args.push(observabilityContext);
52142
+ }
52143
+ const serializedAction = stringify$5(args);
51918
52144
  return new Promise((resolve, reject) => {
51919
52145
  callProxyMethod('enqueue', serializedAction, (serializedActionResponse) => {
51920
52146
  const response = parse$5(serializedActionResponse);
@@ -56524,7 +56750,9 @@ function buildSubscribableResult$1(result, subscribe, refresh) {
56524
56750
  }
56525
56751
  function resolvedPromiseLike$2(result) {
56526
56752
  if (isPromiseLike$2(result)) {
56527
- return result.then((nextResult) => nextResult);
56753
+ return result.then(
56754
+ (nextResult) => nextResult
56755
+ );
56528
56756
  }
56529
56757
  return {
56530
56758
  then: (onFulfilled, _onRejected) => {
@@ -56541,7 +56769,9 @@ function resolvedPromiseLike$2(result) {
56541
56769
  }
56542
56770
  function rejectedPromiseLike$2(reason) {
56543
56771
  if (isPromiseLike$2(reason)) {
56544
- return reason.then((nextResult) => nextResult);
56772
+ return reason.then(
56773
+ (nextResult) => nextResult
56774
+ );
56545
56775
  }
56546
56776
  return {
56547
56777
  then: (_onFulfilled, onRejected) => {
@@ -56587,7 +56817,10 @@ function deepEquals$1(x, y) {
56587
56817
  }
56588
56818
  for (let i = 0; i < xkeys.length; ++i) {
56589
56819
  const key = xkeys[i];
56590
- if (!deepEquals$1(x[key], y[key])) {
56820
+ if (!deepEquals$1(
56821
+ x[key],
56822
+ y[key]
56823
+ )) {
56591
56824
  return false;
56592
56825
  }
56593
56826
  }
@@ -56595,49 +56828,6 @@ function deepEquals$1(x, y) {
56595
56828
  }
56596
56829
  return x === y;
56597
56830
  }
56598
- function stableJSONStringify(node) {
56599
- if (node && node.toJSON && typeof node.toJSON === "function") {
56600
- node = node.toJSON();
56601
- }
56602
- if (node === void 0) {
56603
- return;
56604
- }
56605
- if (typeof node === "number") {
56606
- return isFinite(node) ? "" + node : "null";
56607
- }
56608
- if (typeof node !== "object") {
56609
- return stringify$2(node);
56610
- }
56611
- let i;
56612
- let out;
56613
- if (isArray$1(node)) {
56614
- out = "[";
56615
- for (i = 0; i < node.length; i++) {
56616
- if (i) {
56617
- out += ",";
56618
- }
56619
- out += stableJSONStringify(node[i]) || "null";
56620
- }
56621
- return out + "]";
56622
- }
56623
- if (node === null) {
56624
- return "null";
56625
- }
56626
- const objKeys = keys(node).sort();
56627
- out = "";
56628
- for (i = 0; i < objKeys.length; i++) {
56629
- const key = objKeys[i];
56630
- const value = stableJSONStringify(node[key]);
56631
- if (!value) {
56632
- continue;
56633
- }
56634
- if (out) {
56635
- out += ",";
56636
- }
56637
- out += stringify$2(key) + ":" + value;
56638
- }
56639
- return "{" + out + "}";
56640
- }
56641
56831
  function toError(x) {
56642
56832
  if (x instanceof Error) {
56643
56833
  return x;
@@ -56657,6 +56847,19 @@ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
56657
56847
  HttpStatusCode2[HttpStatusCode2["GatewayTimeout"] = 504] = "GatewayTimeout";
56658
56848
  return HttpStatusCode2;
56659
56849
  })(HttpStatusCode || {});
56850
+ function getFetchResponseFromAuraError(err2) {
56851
+ const auraError = err2;
56852
+ if (auraError.data !== void 0 && auraError.data.statusCode !== void 0) {
56853
+ const data = auraError.data;
56854
+ if (auraError.id !== void 0) {
56855
+ data.id = auraError.id;
56856
+ }
56857
+ return new FetchResponse(data.statusCode, data);
56858
+ }
56859
+ return new FetchResponse(500, {
56860
+ error: err2?.message
56861
+ });
56862
+ }
56660
56863
  function getStatusText(status) {
56661
56864
  switch (status) {
56662
56865
  case 200:
@@ -56696,9 +56899,10 @@ function deepFreeze(value) {
56696
56899
  deepFreeze(value[i]);
56697
56900
  }
56698
56901
  } else {
56699
- const keys$1 = keys(value);
56902
+ const record = value;
56903
+ const keys$1 = keys(record);
56700
56904
  for (let i = 0, len = keys$1.length; i < len; i += 1) {
56701
- deepFreeze(value[keys$1[i]]);
56905
+ deepFreeze(record[keys$1[i]]);
56702
56906
  }
56703
56907
  }
56704
56908
  freeze(value);
@@ -56772,7 +56976,7 @@ let NetworkCommand$1 = class NetworkCommand extends BaseCommand {
56772
56976
  async afterRequestHooks(_options) {
56773
56977
  }
56774
56978
  };
56775
- function buildServiceDescriptor$n() {
56979
+ function buildServiceDescriptor$m() {
56776
56980
  return {
56777
56981
  type: "networkCommandBaseClass",
56778
56982
  version: "1.0",
@@ -56798,7 +57002,7 @@ class AuraNetworkCommand extends NetworkCommand$1 {
56798
57002
  );
56799
57003
  }
56800
57004
  coerceAuraErrors(auraErrors) {
56801
- return toError(auraErrors[0]);
57005
+ return new UserVisibleError(getFetchResponseFromAuraError(auraErrors[0]));
56802
57006
  }
56803
57007
  /**
56804
57008
  * Customize how non-2xx fetch fallback responses are converted into errors.
@@ -56878,7 +57082,7 @@ class AuraNetworkCommand extends NetworkCommand$1 {
56878
57082
  return resolvedPromiseLike$2(err$1(toError("Aura/Fetch network services not found")));
56879
57083
  }
56880
57084
  }
56881
- function buildServiceDescriptor$m() {
57085
+ function buildServiceDescriptor$l() {
56882
57086
  return {
56883
57087
  type: "auraNetworkCommandBaseClass",
56884
57088
  version: "1.0",
@@ -56920,7 +57124,9 @@ function buildSubscribableResult(result, subscribe, refresh) {
56920
57124
  }
56921
57125
  function resolvedPromiseLike$1(result) {
56922
57126
  if (isPromiseLike$1(result)) {
56923
- return result.then((nextResult) => nextResult);
57127
+ return result.then(
57128
+ (nextResult) => nextResult
57129
+ );
56924
57130
  }
56925
57131
  return {
56926
57132
  then: (onFulfilled, _onRejected) => {
@@ -56937,7 +57143,9 @@ function resolvedPromiseLike$1(result) {
56937
57143
  }
56938
57144
  function rejectedPromiseLike$1(reason) {
56939
57145
  if (isPromiseLike$1(reason)) {
56940
- return reason.then((nextResult) => nextResult);
57146
+ return reason.then(
57147
+ (nextResult) => nextResult
57148
+ );
56941
57149
  }
56942
57150
  return {
56943
57151
  then: (_onFulfilled, onRejected) => {
@@ -56983,7 +57191,10 @@ function deepEquals(x, y) {
56983
57191
  }
56984
57192
  for (let i = 0; i < xkeys.length; ++i) {
56985
57193
  const key = xkeys[i];
56986
- if (!deepEquals(x[key], y[key])) {
57194
+ if (!deepEquals(
57195
+ x[key],
57196
+ y[key]
57197
+ )) {
56987
57198
  return false;
56988
57199
  }
56989
57200
  }
@@ -57428,7 +57639,7 @@ function mergeCacheControlConfigs(baseConfig, overrides) {
57428
57639
  };
57429
57640
  }
57430
57641
 
57431
- let AuraCacheControlCommand$1 = class AuraCacheControlCommand extends CacheControlCommand {
57642
+ class AuraCacheControlCommand extends CacheControlCommand {
57432
57643
  constructor(services) {
57433
57644
  super(services);
57434
57645
  this.services = services;
@@ -57530,8 +57741,8 @@ let AuraCacheControlCommand$1 = class AuraCacheControlCommand extends CacheContr
57530
57741
  (reason) => err$1(toError(reason))
57531
57742
  );
57532
57743
  }
57533
- };
57534
- class AuraNormalizedCacheControlCommand extends AuraCacheControlCommand$1 {
57744
+ }
57745
+ class AuraNormalizedCacheControlCommand extends AuraCacheControlCommand {
57535
57746
  constructor(services) {
57536
57747
  super(services);
57537
57748
  this.services = services;
@@ -57555,7 +57766,7 @@ class AuraNormalizedCacheControlCommand extends AuraCacheControlCommand$1 {
57555
57766
  return resolvedPromiseLike$2(void 0);
57556
57767
  }
57557
57768
  }
57558
- function buildServiceDescriptor$l() {
57769
+ function buildServiceDescriptor$k() {
57559
57770
  return {
57560
57771
  type: "auraNormalizedCacheControlCommand",
57561
57772
  version: "1.0",
@@ -57563,144 +57774,6 @@ function buildServiceDescriptor$l() {
57563
57774
  };
57564
57775
  }
57565
57776
 
57566
- class AuraCacheControlCommand extends CacheControlCommand {
57567
- constructor(services) {
57568
- super(services);
57569
- this.services = services;
57570
- this.actionConfig = {
57571
- background: false,
57572
- hotspot: true,
57573
- longRunning: false,
57574
- storable: false
57575
- };
57576
- this.networkPreference = "aura";
57577
- }
57578
- get fetchParams() {
57579
- throw new Error(
57580
- "Fetch parameters must be specified when using HTTP transport on an Aura adapter"
57581
- );
57582
- }
57583
- shouldUseAuraNetwork() {
57584
- return this.services.auraNetwork !== void 0 && (this.networkPreference === "aura" || !this.services.fetch);
57585
- }
57586
- shouldUseFetch() {
57587
- return this.services.fetch !== void 0 && (this.networkPreference === "http" || !this.services.auraNetwork);
57588
- }
57589
- requestFromNetwork() {
57590
- if (this.shouldUseAuraNetwork()) {
57591
- return this.convertAuraResponseToData(
57592
- this.services.auraNetwork(this.endpoint, this.auraParams, this.actionConfig),
57593
- (errs) => this.coerceAuraErrors(errs)
57594
- );
57595
- } else if (this.shouldUseFetch()) {
57596
- const params = this.fetchParams;
57597
- try {
57598
- return this.convertFetchResponseToData(this.services.fetch(...params));
57599
- } catch (reason) {
57600
- return resolvedPromiseLike$2(err$1(toError(reason)));
57601
- }
57602
- }
57603
- return resolvedPromiseLike$2(err$1(toError("Aura/Fetch network services not found")));
57604
- }
57605
- coerceAuraErrors(auraErrors) {
57606
- return toError(auraErrors[0]);
57607
- }
57608
- async coerceError(errorResponse) {
57609
- return toError(errorResponse.statusText);
57610
- }
57611
- processAuraReturnValue(auraReturnValue) {
57612
- return ok$1(auraReturnValue);
57613
- }
57614
- processFetchReturnValue(json) {
57615
- return ok$1(json);
57616
- }
57617
- convertAuraResponseToData(responsePromise, coerceError) {
57618
- return responsePromise.then((response) => {
57619
- return this.processAuraReturnValue(response.getReturnValue());
57620
- }).finally(() => {
57621
- try {
57622
- this.afterRequestHooks({ statusCode: 200 });
57623
- } catch {
57624
- }
57625
- }).catch((error) => {
57626
- if (!error) {
57627
- return err$1(toError("Failed to get error from response"));
57628
- }
57629
- if (!error.getError) {
57630
- return err$1(toError(error));
57631
- }
57632
- const actionErrors = error.getError();
57633
- if (actionErrors.length > 0) {
57634
- return err$1(coerceError(actionErrors));
57635
- }
57636
- return err$1(toError("Error fetching component"));
57637
- });
57638
- }
57639
- convertFetchResponseToData(response) {
57640
- return response.then(
57641
- (response2) => {
57642
- if (response2.ok) {
57643
- return response2.json().then(
57644
- (json) => {
57645
- return this.processFetchReturnValue(json);
57646
- },
57647
- (reason) => err$1(toError(reason))
57648
- ).finally(() => {
57649
- try {
57650
- this.afterRequestHooks({ statusCode: response2.status });
57651
- } catch {
57652
- }
57653
- });
57654
- } else {
57655
- return this.coerceError(response2).then((coercedError) => {
57656
- return err$1(coercedError);
57657
- }).finally(() => {
57658
- try {
57659
- this.afterRequestHooks({ statusCode: response2.status });
57660
- } catch {
57661
- }
57662
- });
57663
- }
57664
- },
57665
- (reason) => err$1(toError(reason))
57666
- );
57667
- }
57668
- }
57669
- class AuraResourceCacheControlCommand extends AuraCacheControlCommand {
57670
- constructor(services) {
57671
- super(services);
57672
- this.services = services;
57673
- }
57674
- readFromCache(cache) {
57675
- const data = cache.get(this.buildKey())?.value;
57676
- if (data === void 0) {
57677
- return resolvedPromiseLike$2(err$1(new Error("Failed to find data in cache")));
57678
- }
57679
- return resolvedPromiseLike$2(ok$1(data));
57680
- }
57681
- writeToCache(cache, networkResult) {
57682
- if (networkResult.isOk()) {
57683
- cache.set(this.buildKey(), {
57684
- value: networkResult.value,
57685
- metadata: {
57686
- cacheControl: this.buildCacheControlMetadata(networkResult.value)
57687
- }
57688
- });
57689
- }
57690
- return resolvedPromiseLike$2(void 0);
57691
- }
57692
- buildKey() {
57693
- return `{"endpoint":${this.endpoint},"params":${stableJSONStringify(this.auraParams)}}`;
57694
- }
57695
- }
57696
- function buildServiceDescriptor$k() {
57697
- return {
57698
- type: "auraResourceCacheControlCommand",
57699
- version: "1.0",
57700
- service: AuraResourceCacheControlCommand
57701
- };
57702
- }
57703
-
57704
57777
  class NetworkCommand extends BaseCommand {
57705
57778
  constructor(services) {
57706
57779
  super();
@@ -57744,16 +57817,16 @@ class NetworkCommand extends BaseCommand {
57744
57817
  }
57745
57818
  }
57746
57819
  function isAbortableCommand(command) {
57747
- return "isAbortableCommand" in command && command.isAbortableCommand === true;
57820
+ return !!command && typeof command === "object" && "isAbortableCommand" in command && command.isAbortableCommand === true;
57748
57821
  }
57749
57822
  function hasFetchParams(command) {
57750
- return command && typeof command === "object" && "fetchParams" in command;
57823
+ return !!command && typeof command === "object" && "fetchParams" in command;
57751
57824
  }
57752
57825
  function createAbortableDecorator(command, options) {
57753
- if (!options?.signal || !(options?.signal instanceof AbortSignal)) {
57826
+ const signal = options?.signal;
57827
+ if (!signal || !(signal instanceof AbortSignal)) {
57754
57828
  return command;
57755
57829
  }
57756
- const { signal } = options;
57757
57830
  if (isAbortableCommand(command)) {
57758
57831
  if (process.env.NODE_ENV !== "production") {
57759
57832
  console.warn(
@@ -57764,14 +57837,15 @@ function createAbortableDecorator(command, options) {
57764
57837
  }
57765
57838
  if (!hasFetchParams(command)) {
57766
57839
  if (process.env.NODE_ENV !== "production") {
57840
+ const commandName = typeof command === "object" && command !== null ? command.constructor.name : typeof command;
57767
57841
  console.warn(
57768
- `Command ${command.constructor.name} does not support fetch operations. AbortSignal will be ignored.`
57842
+ `Command ${commandName} does not support fetch operations. AbortSignal will be ignored.`
57769
57843
  );
57770
57844
  }
57771
57845
  return command;
57772
57846
  }
57773
57847
  try {
57774
- return new Proxy(command, {
57848
+ const handler = {
57775
57849
  get(target, prop, receiver) {
57776
57850
  if (prop === "isAbortableCommand") {
57777
57851
  return true;
@@ -57780,8 +57854,8 @@ function createAbortableDecorator(command, options) {
57780
57854
  return signal;
57781
57855
  }
57782
57856
  if (prop === "fetchParams") {
57783
- const originalFetchParams = target[prop];
57784
- const isInternal = target.isInternalExecution === true;
57857
+ const originalFetchParams = Reflect.get(target, prop, receiver);
57858
+ const isInternal = Reflect.get(target, "isInternalExecution", receiver) === true;
57785
57859
  if (typeof originalFetchParams === "function") {
57786
57860
  return function(...args) {
57787
57861
  const originalReturnValue = originalFetchParams.apply(this, args);
@@ -57807,7 +57881,8 @@ function createAbortableDecorator(command, options) {
57807
57881
  }
57808
57882
  return Reflect.has(target, prop);
57809
57883
  }
57810
- });
57884
+ };
57885
+ return new Proxy(command, handler);
57811
57886
  } catch (error) {
57812
57887
  if (process.env.NODE_ENV !== "production") {
57813
57888
  console.error(
@@ -58902,7 +58977,7 @@ function buildServiceDescriptor$b(luvio) {
58902
58977
  },
58903
58978
  };
58904
58979
  }
58905
- // version: 1.443.0-be70f6bb6e
58980
+ // version: 1.445.0-117c9de71a
58906
58981
 
58907
58982
  /**
58908
58983
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -58928,7 +59003,7 @@ function buildServiceDescriptor$a(notifyRecordUpdateAvailable, getNormalizedLuvi
58928
59003
  },
58929
59004
  };
58930
59005
  }
58931
- // version: 1.443.0-be70f6bb6e
59006
+ // version: 1.445.0-117c9de71a
58932
59007
 
58933
59008
  function findExecutableOperation(input) {
58934
59009
  const operations = input.query.definitions.filter(
@@ -59728,7 +59803,7 @@ function findSchemaAtPath(document, ref) {
59728
59803
  let path = "#";
59729
59804
  for (const key of keys) {
59730
59805
  path = `${path}/${key}`;
59731
- if (current[key] === void 0) {
59806
+ if (typeof current !== "object" || current === null || current[key] === void 0) {
59732
59807
  throw new InvalidRefError(
59733
59808
  `Invalid $ref value '${ref}'. Cannot find target schema at '${path}'`
59734
59809
  );
@@ -59968,7 +60043,10 @@ class GraphQLImperativeBindingsService {
59968
60043
  const options = {
59969
60044
  acceptedOperations: ["query"]
59970
60045
  };
59971
- const result = resolveAndValidateGraphQLConfig(params[0], options);
60046
+ const result = resolveAndValidateGraphQLConfig(
60047
+ params[0],
60048
+ options
60049
+ );
59972
60050
  if (result?.isErr()) {
59973
60051
  return result.error;
59974
60052
  }
@@ -60165,7 +60243,10 @@ class GraphQLMutationBindingsService {
60165
60243
  const options = {
60166
60244
  acceptedOperations: ["mutation"]
60167
60245
  };
60168
- const result2 = resolveAndValidateGraphQLConfig(params[0], options);
60246
+ const result2 = resolveAndValidateGraphQLConfig(
60247
+ params[0],
60248
+ options
60249
+ );
60169
60250
  if (result2?.isErr()) {
60170
60251
  return {
60171
60252
  data: void 0,
@@ -60785,7 +60866,9 @@ function addAllToSet(targetSet, sourceSet) {
60785
60866
  }
60786
60867
  function resolvedPromiseLike(result) {
60787
60868
  if (isPromiseLike(result)) {
60788
- return result.then((nextResult) => nextResult);
60869
+ return result.then(
60870
+ (nextResult) => nextResult
60871
+ );
60789
60872
  }
60790
60873
  return {
60791
60874
  then: (onFulfilled, _onRejected) => {
@@ -60802,7 +60885,9 @@ function resolvedPromiseLike(result) {
60802
60885
  }
60803
60886
  function rejectedPromiseLike(reason) {
60804
60887
  if (isPromiseLike(reason)) {
60805
- return reason.then((nextResult) => nextResult);
60888
+ return reason.then(
60889
+ (nextResult) => nextResult
60890
+ );
60806
60891
  }
60807
60892
  return {
60808
60893
  then: (_onFulfilled, onRejected) => {
@@ -61324,12 +61409,11 @@ function initializeOneStore(sqliteStore, luvio) {
61324
61409
  buildNimbusFetchServiceDescriptor(),
61325
61410
  buildServiceDescriptor$f(instrumentationServiceDescriptor.service),
61326
61411
  // NOTE: These do not directly depend on Aura, and are necessary for HTTP fallback support.
61327
- buildServiceDescriptor$m(),
61328
61412
  buildServiceDescriptor$l(),
61329
61413
  buildServiceDescriptor$k(),
61330
61414
  buildServiceDescriptor$g(cacheServiceDescriptor.service, nimbusSqliteOneStoreCacheServiceDescriptor.service, instrumentationServiceDescriptor.service),
61331
61415
  buildServiceDescriptor$j(),
61332
- buildServiceDescriptor$n(),
61416
+ buildServiceDescriptor$m(),
61333
61417
  buildServiceDescriptor$i(),
61334
61418
  buildServiceDescriptor$d(),
61335
61419
  buildServiceDescriptor$9(),
@@ -61608,4 +61692,4 @@ register({
61608
61692
  });
61609
61693
 
61610
61694
  export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, ingest$1o as ingestDenormalizedRecordRepresentation, initializeOneStore, registerReportObserver, reportGraphqlQueryParseError };
61611
- // version: 1.443.0-be70f6bb6e
61695
+ // version: 1.445.0-117c9de71a