@salesforce/lds-runtime-mobile 1.316.0 → 1.317.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
@@ -53,7 +53,7 @@ import graphqlL2AdapterGate from '@salesforce/gate/lmr.graphqlL2Adapter';
53
53
 
54
54
  const { parse: parse$7, stringify: stringify$7 } = JSON;
55
55
  const { join: join$2, push: push$3, unshift } = Array.prototype;
56
- const { isArray: isArray$5 } = Array;
56
+ const { isArray: isArray$6 } = Array;
57
57
  const { entries: entries$6, keys: keys$9 } = Object;
58
58
 
59
59
  const UI_API_BASE_URI = '/services/data/v63.0/ui-api';
@@ -278,7 +278,7 @@ const getRecordDispatcher = (req) => {
278
278
  }
279
279
  }
280
280
  const recordId = urlParams.recordId;
281
- const fieldsArray = fields !== undefined && isArray$5(fields) ? fields : [];
281
+ const fieldsArray = fields !== undefined && isArray$6(fields) ? fields : [];
282
282
  const optionalFieldsArray = optionalFields !== undefined && Array.isArray(optionalFields)
283
283
  ? optionalFields
284
284
  : [];
@@ -1844,7 +1844,7 @@ var QueueOperationType;
1844
1844
 
1845
1845
  const { keys: keys$7, create: create$7, assign: assign$7, values: values$4 } = Object;
1846
1846
  const { stringify: stringify$6, parse: parse$6 } = JSON;
1847
- const { isArray: isArray$4 } = Array;
1847
+ const { isArray: isArray$5 } = Array;
1848
1848
 
1849
1849
  const DraftIdMappingKeyPrefix240 = 'DraftIdMapping::';
1850
1850
  const DRAFT_ID_MAPPINGS_SEGMENT = 'DRAFT_ID_MAPPINGS';
@@ -2211,9 +2211,6 @@ class DurableDraftQueue {
2211
2211
  async getQueueActions() {
2212
2212
  const drafts = (await this.draftStore.getAllDrafts());
2213
2213
  const queue = [];
2214
- if (drafts === undefined) {
2215
- return queue;
2216
- }
2217
2214
  drafts.forEach((draft) => {
2218
2215
  if (draft.id === this.uploadingActionId) {
2219
2216
  draft.status = DraftActionStatus.Uploading;
@@ -2765,23 +2762,15 @@ class DurableDraftStore {
2765
2762
  for (let i = 0, len = keys$1.length; i < len; i++) {
2766
2763
  const entry = durableEntries[keys$1[i]];
2767
2764
  const action = entry.data;
2768
- if (action !== undefined) {
2769
- if (process.env.NODE_ENV !== 'production') {
2770
- // the `version` property was introduced in 242, we should assert version
2771
- // exists once we are sure there are no durable stores that contain
2772
- // versionless actions
2773
- if (action.version && action.version !== '242.0.0') {
2774
- return Promise.reject('Unexpected draft action version found in the durable store');
2775
- }
2776
- }
2777
- draftStore[action.id] = action;
2778
- }
2779
- else {
2780
- if (process.env.NODE_ENV !== 'production') {
2781
- const err = new Error('Expected draft action to be defined in the durable store');
2782
- return Promise.reject(err);
2765
+ if (process.env.NODE_ENV !== 'production') {
2766
+ // the `version` property was introduced in 242, we should assert version
2767
+ // exists once we are sure there are no durable stores that contain
2768
+ // versionless actions
2769
+ if (action.version && action.version !== '242.0.0') {
2770
+ return Promise.reject('Unexpected draft action version found in the durable store');
2783
2771
  }
2784
2772
  }
2773
+ draftStore[action.id] = action;
2785
2774
  }
2786
2775
  return this.runQueuedOperations();
2787
2776
  })
@@ -2817,494 +2806,6 @@ class DurableDraftStore {
2817
2806
  }
2818
2807
  }
2819
2808
 
2820
- const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
2821
- const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
2822
- const ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED = 'IDEMPOTENCY_FEATURE_NOT_ENABLED';
2823
- const ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED = 'IDEMPOTENCY_NOT_SUPPORTED';
2824
- const ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER = 'IDEMPOTENCY_KEY_USED_DIFFERENT_USER';
2825
- const ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST = 'IDEMPOTENCY_CONCURRENT_REQUEST';
2826
- const ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED = 'IDEMPOTENCY_KEY_ALREADY_USED';
2827
- const ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR = 'IDEMPOTENCY_BACKEND_OPERATION_ERROR';
2828
- /**
2829
- * Get the retry after in milliseconds from the response headers, undefined if not specified.
2830
- * The header could have two different format.
2831
- * Retry-After: <http-date>, like Wed, 21 Oct 2015 07:28:00 GMT
2832
- * Retry-After: <delay-seconds>, like 1.5s
2833
- * @param headers http headers
2834
- * @returns the time to delat in millisconds.
2835
- */
2836
- function getRetryAfterInMs(headers) {
2837
- const retryAfterHeader = headers && headers[HTTP_HEADER_RETRY_AFTER];
2838
- if (retryAfterHeader === undefined) {
2839
- return undefined;
2840
- }
2841
- const delayInSecond = parseFloat(retryAfterHeader);
2842
- if (retryAfterHeader === delayInSecond.toString()) {
2843
- return Math.round(delayInSecond * 1000);
2844
- }
2845
- const delayUntilDateTime = Date.parse(retryAfterHeader);
2846
- if (isNaN(delayUntilDateTime)) {
2847
- return undefined;
2848
- }
2849
- return delayUntilDateTime - Date.now();
2850
- }
2851
-
2852
- const DEFAULT_FIELD_LAST_MODIFIED_DATE$1 = 'LastModifiedDate';
2853
- const DEFAULT_FIELD_CREATED_DATE$1 = 'CreatedDate';
2854
- class AbstractResourceRequestActionHandler {
2855
- constructor(draftQueue, networkAdapter, getLuvio) {
2856
- this.draftQueue = draftQueue;
2857
- this.networkAdapter = networkAdapter;
2858
- this.getLuvio = getLuvio;
2859
- // NOTE[W-12567340]: This property stores in-memory mappings between draft
2860
- // ids and canonical ids for the current session. Having a local copy of
2861
- // these mappings is necessary to avoid a race condition between publishing
2862
- // new mappings to the durable store and those mappings being loaded into
2863
- // the luvio store redirect table, during which a new draft might be enqueued
2864
- // which would not see a necessary mapping.
2865
- this.ephemeralRedirects = {};
2866
- // determined by Server setup.
2867
- this.isIdempotencySupported = true;
2868
- // idempotency write flag set by lds
2869
- this.isLdsIdempotencyWriteDisabled = ldsIdempotencyWriteDisabled.isOpen({
2870
- fallback: false,
2871
- });
2872
- this.isBackdatingEnabled = ldsBackdatingEnabled.isOpen({ fallback: false });
2873
- }
2874
- enqueue(data) {
2875
- return this.draftQueue.enqueue(this.handlerId, data);
2876
- }
2877
- async handleAction(action, actionCompleted, actionErrored) {
2878
- const { data: request } = action;
2879
- // no context is stored in draft action
2880
- try {
2881
- const response = await this.networkAdapter(request, {});
2882
- if (response.ok) {
2883
- await actionCompleted({
2884
- ...action,
2885
- response,
2886
- status: DraftActionStatus.Completed,
2887
- });
2888
- return ProcessActionResult.ACTION_SUCCEEDED;
2889
- }
2890
- let shouldRetry = false;
2891
- let retryDelayInMs = undefined;
2892
- let actionDataChanged = false;
2893
- let updatedAction = action;
2894
- if (request && request.headers && request.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
2895
- const status = response.status;
2896
- switch (status) {
2897
- case 408 /* IdempotentWriteSpecificHttpStatusCode.RequestTimeout */:
2898
- case 503 /* IdempotentWriteSpecificHttpStatusCode.ServiceUnavailable */:
2899
- retryDelayInMs = getRetryAfterInMs(response.headers);
2900
- shouldRetry = true;
2901
- break;
2902
- case HttpStatusCode.ServerError: {
2903
- shouldRetry = true;
2904
- if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR)) {
2905
- this.isIdempotencySupported = false;
2906
- retryDelayInMs = 0;
2907
- actionDataChanged = true;
2908
- }
2909
- break;
2910
- }
2911
- case 409 /* IdempotentWriteSpecificHttpStatusCode.Conflict */: {
2912
- if (this.isUiApiErrors(response.body)) {
2913
- const errorCode = response.body[0].errorCode;
2914
- if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER)) {
2915
- retryDelayInMs = 0;
2916
- actionDataChanged = true;
2917
- }
2918
- else if (errorCode === ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST) {
2919
- retryDelayInMs = getRetryAfterInMs(response.headers);
2920
- }
2921
- shouldRetry = true;
2922
- }
2923
- break;
2924
- }
2925
- case HttpStatusCode.BadRequest: {
2926
- if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED, ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED)) {
2927
- retryDelayInMs = 0;
2928
- actionDataChanged = true;
2929
- shouldRetry = true;
2930
- }
2931
- break;
2932
- }
2933
- case 422 /* IdempotentWriteSpecificHttpStatusCode.UnProcessableEntity */: {
2934
- if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED)) {
2935
- retryDelayInMs = 0;
2936
- actionDataChanged = true;
2937
- shouldRetry = true;
2938
- }
2939
- break;
2940
- }
2941
- }
2942
- }
2943
- if (this.isBackdatingEnabled &&
2944
- response.status === HttpStatusCode.BadRequest &&
2945
- this.isBackdatingError(response.body, action)) {
2946
- updatedAction.timestamp = Date.now();
2947
- updatedAction.data.body.fields = {
2948
- ...updatedAction.data.body.fields,
2949
- LastModifiedDate: new Date(updatedAction.timestamp).toISOString(),
2950
- };
2951
- if (this.hasIdempotencySupport() &&
2952
- updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
2953
- updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
2954
- }
2955
- shouldRetry = true;
2956
- actionDataChanged = true;
2957
- }
2958
- await actionErrored(shouldRetry
2959
- ? updatedAction
2960
- : {
2961
- ...updatedAction,
2962
- error: response,
2963
- status: DraftActionStatus.Error,
2964
- }, shouldRetry, retryDelayInMs, actionDataChanged);
2965
- return ProcessActionResult.ACTION_ERRORED;
2966
- }
2967
- catch (e) {
2968
- await actionErrored(action, true);
2969
- return ProcessActionResult.NETWORK_ERROR;
2970
- }
2971
- }
2972
- // true if response is an idempotency server error. updates or deletes idempotency key if the reponse is idempotency related error. Idempotency related error is in format of UiApiError array.
2973
- handleIdempotencyServerError(responseBody, action, updateIdempotencyKey, ...targetErrorCodes) {
2974
- if (this.isUiApiErrors(responseBody)) {
2975
- const errorCode = responseBody[0].errorCode;
2976
- if (targetErrorCodes.includes(errorCode)) {
2977
- action.data.headers = action.data.headers || {};
2978
- if (updateIdempotencyKey) {
2979
- action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
2980
- }
2981
- else {
2982
- delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
2983
- }
2984
- return true;
2985
- }
2986
- }
2987
- return false;
2988
- }
2989
- // checks if the body is an array of UiApiError. Sometimes the body has `enhancedErrorType` field as an error indicator(one example is the field validation failure). In such case Action being processed updates to an Error Action.
2990
- isUiApiErrors(body) {
2991
- return body !== undefined && isArray$4(body) && body.length > 0 && body[0].errorCode;
2992
- }
2993
- isBackdatingError(body, action) {
2994
- if (body.enhancedErrorType &&
2995
- body.enhancedErrorType === 'RecordError' &&
2996
- body.output &&
2997
- body.output.errors &&
2998
- isArray$4(body.output.errors) &&
2999
- body.output.errors.length > 0 &&
3000
- action.data.body &&
3001
- action.data.body.fields &&
3002
- action.data.body.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE$1]) {
3003
- return body.output.errors.some((error) => error.errorCode === 'CollisionDetectedException');
3004
- }
3005
- return false;
3006
- }
3007
- async buildPendingAction(request, queue) {
3008
- const targetId = await this.getIdFromRequest(request);
3009
- const tag = this.buildTagForTargetId(targetId);
3010
- const handlerActions = queue.filter((x) => x.handler === this.handlerId);
3011
- if (request.method === 'post' && actionsForTag(tag, handlerActions).length > 0) {
3012
- return Promise.reject(new Error('Cannot enqueue a POST draft action with an existing tag'));
3013
- }
3014
- if (deleteActionsForTag(tag, handlerActions).length > 0) {
3015
- return Promise.reject(new Error('Cannot enqueue a draft action for a deleted record'));
3016
- }
3017
- return {
3018
- handler: this.handlerId,
3019
- targetId,
3020
- tag,
3021
- data: request,
3022
- status: DraftActionStatus.Pending,
3023
- id: generateUniqueDraftActionId(queue.map((x) => x.id)),
3024
- timestamp: Date.now(),
3025
- metadata: {},
3026
- version: '242.0.0',
3027
- };
3028
- }
3029
- async handleActionEnqueued(_action) { }
3030
- handleActionRemoved(action) {
3031
- return this.reingestRecord(action);
3032
- }
3033
- getQueueOperationsForCompletingDrafts(queue, action) {
3034
- const queueOperations = [];
3035
- const redirects = this.getRedirectMappings(action);
3036
- if (redirects !== undefined) {
3037
- const { length } = queue;
3038
- for (let i = 0; i < length; i++) {
3039
- const queueAction = queue[i];
3040
- // if this queueAction is the action that is completing we can move on,
3041
- // it is about to be deleted and won't have the draft ID in it
3042
- if (queueAction.id === action.id) {
3043
- continue;
3044
- }
3045
- if (isResourceRequestAction(queueAction)) {
3046
- let queueOperationMutated = false;
3047
- let updatedActionTag = undefined;
3048
- let updatedActionTargetId = undefined;
3049
- const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
3050
- let { basePath, body } = queueActionRequest;
3051
- let stringifiedBody = stringify$6(body);
3052
- // for each redirected ID/key we loop over the operation to see if it needs
3053
- // to be updated
3054
- for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
3055
- if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
3056
- basePath = basePath.replace(draftId, canonicalId);
3057
- stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
3058
- queueOperationMutated = true;
3059
- }
3060
- // if the action is performed on a previous draft id, we need to replace the action
3061
- // with a new one at the updated canonical key
3062
- if (queueActionTag === draftKey) {
3063
- updatedActionTag = canonicalKey;
3064
- updatedActionTargetId = canonicalId;
3065
- }
3066
- }
3067
- if (queueOperationMutated) {
3068
- if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
3069
- const updatedAction = {
3070
- ...queueAction,
3071
- tag: updatedActionTag,
3072
- targetId: updatedActionTargetId,
3073
- data: {
3074
- ...queueActionRequest,
3075
- basePath: basePath,
3076
- body: parse$6(stringifiedBody),
3077
- },
3078
- };
3079
- // item needs to be replaced with a new item at the new record key
3080
- queueOperations.push({
3081
- type: QueueOperationType.Delete,
3082
- id: queueActionId,
3083
- });
3084
- queueOperations.push({
3085
- type: QueueOperationType.Add,
3086
- action: updatedAction,
3087
- });
3088
- }
3089
- else {
3090
- const updatedAction = {
3091
- ...queueAction,
3092
- data: {
3093
- ...queueActionRequest,
3094
- basePath: basePath,
3095
- body: parse$6(stringifiedBody),
3096
- },
3097
- };
3098
- // item needs to be updated
3099
- queueOperations.push({
3100
- type: QueueOperationType.Update,
3101
- id: queueActionId,
3102
- action: updatedAction,
3103
- });
3104
- }
3105
- }
3106
- }
3107
- }
3108
- }
3109
- // delete completed action
3110
- queueOperations.push({
3111
- type: QueueOperationType.Delete,
3112
- id: action.id,
3113
- });
3114
- return queueOperations;
3115
- }
3116
- getRedirectMappings(action) {
3117
- if (action.data.method !== 'post') {
3118
- return undefined;
3119
- }
3120
- const body = action.response.body;
3121
- const canonicalId = this.getIdFromResponseBody(body);
3122
- const draftId = action.targetId;
3123
- if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
3124
- this.ephemeralRedirects[draftId] = canonicalId;
3125
- }
3126
- return [
3127
- {
3128
- draftId,
3129
- canonicalId,
3130
- draftKey: this.buildTagForTargetId(draftId),
3131
- canonicalKey: this.buildTagForTargetId(canonicalId),
3132
- },
3133
- ];
3134
- }
3135
- async handleActionCompleted(action, queueOperations, allHandlers) {
3136
- const { data: request, tag } = action;
3137
- const { method } = request;
3138
- if (method === 'delete') {
3139
- return this.evictKey(tag);
3140
- }
3141
- const recordsToIngest = [];
3142
- recordsToIngest.push({
3143
- response: action.response.body,
3144
- synchronousIngest: this.synchronousIngest.bind(this),
3145
- buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
3146
- });
3147
- const recordsNeedingReplay = queueOperations.filter((x) => x.type === QueueOperationType.Update);
3148
- for (const recordNeedingReplay of recordsNeedingReplay) {
3149
- const { action } = recordNeedingReplay;
3150
- if (isResourceRequestAction(action)) {
3151
- // We can't assume the queue operation is for our handler, have to find the handler.
3152
- const handler = allHandlers.find((h) => h.handlerId === action.handler);
3153
- if (handler !== undefined) {
3154
- const record = await handler.getDataForAction(action);
3155
- if (record !== undefined) {
3156
- recordsToIngest.push({
3157
- response: record,
3158
- synchronousIngest: handler.synchronousIngest.bind(handler),
3159
- buildCacheKeysForResponse: handler.buildCacheKeysFromResponse.bind(handler),
3160
- });
3161
- }
3162
- }
3163
- }
3164
- }
3165
- await this.ingestResponses(recordsToIngest, action);
3166
- }
3167
- handleReplaceAction(targetAction, sourceAction) {
3168
- //reject if the action to replace is a POST action
3169
- const pendingAction = targetAction;
3170
- if (pendingAction.data.method === 'post') {
3171
- throw Error('Cannot replace a POST action');
3172
- }
3173
- if (this.isActionOfType(targetAction) &&
3174
- this.isActionOfType(sourceAction)) {
3175
- targetAction.status = DraftActionStatus.Pending;
3176
- targetAction.data = sourceAction.data;
3177
- return targetAction;
3178
- }
3179
- else {
3180
- throw Error('Incompatible Action types to replace one another');
3181
- }
3182
- }
3183
- mergeActions(targetAction, sourceAction) {
3184
- const { id: targetId, data: targetData, metadata: targetMetadata, timestamp: targetTimestamp, } = targetAction;
3185
- const { method: targetMethod, body: targetBody } = targetData;
3186
- const { data: sourceData, metadata: sourceMetadata } = sourceAction;
3187
- const { method: sourceMethod, body: sourceBody } = sourceData;
3188
- if (targetMethod.toLowerCase() === 'delete' || sourceMethod.toLowerCase() === 'delete') {
3189
- throw Error('Cannot merge DELETE actions.');
3190
- }
3191
- if (targetMethod.toLowerCase() === 'patch' && sourceMethod.toLowerCase() === 'post') {
3192
- // overlaying a POST over a PATCH is not supported
3193
- throw Error('Cannot merge a POST action over top of a PATCH action.');
3194
- }
3195
- // overlay top-level properties, maintain target's timestamp and id
3196
- const merged = {
3197
- ...targetAction,
3198
- ...sourceAction,
3199
- timestamp: targetTimestamp,
3200
- id: targetId,
3201
- };
3202
- // overlay data
3203
- // NOTE: we stick to the target's ResourceRequest properties (except body
3204
- // which is merged) because we don't want to overwrite a POST with a PATCH
3205
- // (all other cases should be fine or wouldn't have passed pre-requisites)
3206
- merged.data = {
3207
- ...targetData,
3208
- body: this.mergeRequestBody(targetBody, sourceBody),
3209
- };
3210
- // Updates Idempotency key if target has one
3211
- if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
3212
- merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
3213
- }
3214
- // overlay metadata
3215
- merged.metadata = { ...targetMetadata, ...sourceMetadata };
3216
- // put status back to pending to auto upload if queue is active and targed is at the head.
3217
- merged.status = DraftActionStatus.Pending;
3218
- return merged;
3219
- }
3220
- shouldDeleteActionByTagOnRemoval(action) {
3221
- return action.data.method === 'post';
3222
- }
3223
- updateMetadata(_existingMetadata, incomingMetadata) {
3224
- return incomingMetadata;
3225
- }
3226
- isActionOfType(action) {
3227
- return action.handler === this.handlerId;
3228
- }
3229
- async reingestRecord(action) {
3230
- const record = await this.getDataForAction(action);
3231
- if (record !== undefined) {
3232
- await this.ingestResponses([
3233
- {
3234
- response: record,
3235
- synchronousIngest: this.synchronousIngest.bind(this),
3236
- buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
3237
- },
3238
- ], action);
3239
- }
3240
- else {
3241
- await this.evictKey(action.tag);
3242
- }
3243
- }
3244
- // Given an action for this handler this method should return the draft IDs.
3245
- // Most of the time it will simply be the targetId, but certain handlers might
3246
- // have multiple draft-created IDs so they would override this to return them.
3247
- getDraftIdsFromAction(action) {
3248
- return [action.targetId];
3249
- }
3250
- hasIdempotencySupport() {
3251
- return this.isIdempotencySupported && !this.isLdsIdempotencyWriteDisabled;
3252
- }
3253
- async ingestResponses(responses, action) {
3254
- const luvio = this.getLuvio();
3255
- await luvio.handleSuccessResponse(() => {
3256
- if (action.status === DraftActionStatus.Completed) {
3257
- const mappings = this.getRedirectMappings(action);
3258
- if (mappings) {
3259
- mappings.forEach((mapping) => {
3260
- luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
3261
- });
3262
- }
3263
- }
3264
- for (const entry of responses) {
3265
- const { response, synchronousIngest } = entry;
3266
- synchronousIngest(response, action);
3267
- }
3268
- return luvio.storeBroadcast();
3269
- },
3270
- // getTypeCacheKeysRecord uses the response, not the full path factory
3271
- // so 2nd parameter will be unused
3272
- () => {
3273
- const keySet = new StoreKeyMap();
3274
- for (const entry of responses) {
3275
- const { response, buildCacheKeysForResponse } = entry;
3276
- const set = buildCacheKeysForResponse(response);
3277
- for (const key of set.keys()) {
3278
- const value = set.get(key);
3279
- if (value !== undefined) {
3280
- keySet.set(key, value);
3281
- }
3282
- }
3283
- }
3284
- return keySet;
3285
- });
3286
- }
3287
- async evictKey(key) {
3288
- const luvio = this.getLuvio();
3289
- await luvio.handleSuccessResponse(() => {
3290
- luvio.storeEvict(key);
3291
- return luvio.storeBroadcast();
3292
- }, () => {
3293
- return new StoreKeyMap();
3294
- });
3295
- }
3296
- }
3297
- function actionsForTag(tag, queue) {
3298
- return queue.filter((action) => action.tag === tag);
3299
- }
3300
- function deleteActionsForTag(tag, queue) {
3301
- return queue.filter((action) => action.tag === tag && action.data.method === 'delete');
3302
- }
3303
- function isResourceRequestAction(action) {
3304
- const dataAsAny = action.data;
3305
- return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
3306
- }
3307
-
3308
2809
  /**
3309
2810
  * Denotes what kind of operation a DraftQueueItem represents.
3310
2811
  */
@@ -3340,7 +2841,7 @@ var DraftQueueOperationType;
3340
2841
  * @param action
3341
2842
  */
3342
2843
  function getOperationTypeFrom(action) {
3343
- if (isResourceRequestAction(action)) {
2844
+ if (isResourceRequestAction$1(action)) {
3344
2845
  if (action.data !== undefined && action.data.method !== undefined) {
3345
2846
  switch (action.data.method) {
3346
2847
  case 'put':
@@ -3581,7 +3082,7 @@ class DraftManager {
3581
3082
  if (isDraftError(action)) {
3582
3083
  // We should always return an array, if the body is just a dictionary,
3583
3084
  // stick it in an array
3584
- const body = isArray$4(action.error.body) ? action.error.body : [action.error.body];
3085
+ const body = isArray$5(action.error.body) ? action.error.body : [action.error.body];
3585
3086
  const bodyString = stringify$6(body);
3586
3087
  item.error = {
3587
3088
  status: action.error.status || 0,
@@ -3680,6 +3181,10 @@ class DraftManager {
3680
3181
  });
3681
3182
  }
3682
3183
  }
3184
+ function isResourceRequestAction$1(action) {
3185
+ const dataAsAny = action.data;
3186
+ return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
3187
+ }
3683
3188
 
3684
3189
  function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
3685
3190
  const draftMetadata = {};
@@ -3808,7 +3313,7 @@ function objectsDeepEqual(lhs, rhs) {
3808
3313
  const { keys: keys$6, values: values$3, create: create$6, assign: assign$6, freeze: freeze$2, entries: entries$5 } = Object;
3809
3314
  const { stringify: stringify$5, parse: parse$5 } = JSON;
3810
3315
  const { shift: shift$1 } = Array.prototype;
3811
- const { isArray: isArray$3, from: from$2 } = Array;
3316
+ const { isArray: isArray$4, from: from$3 } = Array;
3812
3317
 
3813
3318
  /**
3814
3319
  * Retrieves a denormalized record from the store
@@ -4036,7 +3541,7 @@ function isRequestForGetRecords(request) {
4036
3541
  */
4037
3542
  function extractRecordIdsFromResourceRequest(request) {
4038
3543
  const ids = request.urlParams['recordIds'];
4039
- if (isArray$3(ids) === false) {
3544
+ if (isArray$4(ids) === false) {
4040
3545
  return undefined;
4041
3546
  }
4042
3547
  return ids;
@@ -4207,6 +3712,499 @@ function makeEnvironmentUiApiRecordDraftAware(luvio, options, env) {
4207
3712
  return create$6(adapterSpecificEnvironments, {});
4208
3713
  }
4209
3714
 
3715
+ const { keys: keys$5, create: create$5, assign: assign$5, entries: entries$4 } = Object;
3716
+ const { stringify: stringify$4, parse: parse$4 } = JSON;
3717
+ const { push: push$2, join: join$1, slice: slice$1, shift } = Array.prototype;
3718
+ const { isArray: isArray$3, from: from$2 } = Array;
3719
+
3720
+ const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
3721
+ const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
3722
+ const ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED = 'IDEMPOTENCY_FEATURE_NOT_ENABLED';
3723
+ const ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED = 'IDEMPOTENCY_NOT_SUPPORTED';
3724
+ const ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER = 'IDEMPOTENCY_KEY_USED_DIFFERENT_USER';
3725
+ const ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST = 'IDEMPOTENCY_CONCURRENT_REQUEST';
3726
+ const ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED = 'IDEMPOTENCY_KEY_ALREADY_USED';
3727
+ const ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR = 'IDEMPOTENCY_BACKEND_OPERATION_ERROR';
3728
+ /**
3729
+ * Get the retry after in milliseconds from the response headers, undefined if not specified.
3730
+ * The header could have two different format.
3731
+ * Retry-After: <http-date>, like Wed, 21 Oct 2015 07:28:00 GMT
3732
+ * Retry-After: <delay-seconds>, like 1.5s
3733
+ * @param headers http headers
3734
+ * @returns the time to delat in millisconds.
3735
+ */
3736
+ function getRetryAfterInMs(headers) {
3737
+ const retryAfterHeader = headers && headers[HTTP_HEADER_RETRY_AFTER];
3738
+ if (retryAfterHeader === undefined) {
3739
+ return undefined;
3740
+ }
3741
+ const delayInSecond = parseFloat(retryAfterHeader);
3742
+ if (retryAfterHeader === delayInSecond.toString()) {
3743
+ return Math.round(delayInSecond * 1000);
3744
+ }
3745
+ const delayUntilDateTime = Date.parse(retryAfterHeader);
3746
+ if (isNaN(delayUntilDateTime)) {
3747
+ return undefined;
3748
+ }
3749
+ return delayUntilDateTime - Date.now();
3750
+ }
3751
+
3752
+ const DEFAULT_FIELD_LAST_MODIFIED_DATE$1 = 'LastModifiedDate';
3753
+ const DEFAULT_FIELD_CREATED_DATE$1 = 'CreatedDate';
3754
+ class AbstractResourceRequestActionHandler {
3755
+ constructor(draftQueue, networkAdapter, getLuvio) {
3756
+ this.draftQueue = draftQueue;
3757
+ this.networkAdapter = networkAdapter;
3758
+ this.getLuvio = getLuvio;
3759
+ // NOTE[W-12567340]: This property stores in-memory mappings between draft
3760
+ // ids and canonical ids for the current session. Having a local copy of
3761
+ // these mappings is necessary to avoid a race condition between publishing
3762
+ // new mappings to the durable store and those mappings being loaded into
3763
+ // the luvio store redirect table, during which a new draft might be enqueued
3764
+ // which would not see a necessary mapping.
3765
+ this.ephemeralRedirects = {};
3766
+ // determined by Server setup.
3767
+ this.isIdempotencySupported = true;
3768
+ // idempotency write flag set by lds
3769
+ this.isLdsIdempotencyWriteDisabled = ldsIdempotencyWriteDisabled.isOpen({
3770
+ fallback: false,
3771
+ });
3772
+ this.isBackdatingEnabled = ldsBackdatingEnabled.isOpen({ fallback: false });
3773
+ }
3774
+ enqueue(data) {
3775
+ return this.draftQueue.enqueue(this.handlerId, data);
3776
+ }
3777
+ async handleAction(action, actionCompleted, actionErrored) {
3778
+ const { data: request } = action;
3779
+ // no context is stored in draft action
3780
+ try {
3781
+ const response = await this.networkAdapter(request, {});
3782
+ if (response.ok) {
3783
+ await actionCompleted({
3784
+ ...action,
3785
+ response,
3786
+ status: DraftActionStatus.Completed,
3787
+ });
3788
+ return ProcessActionResult.ACTION_SUCCEEDED;
3789
+ }
3790
+ let shouldRetry = false;
3791
+ let retryDelayInMs = undefined;
3792
+ let actionDataChanged = false;
3793
+ let updatedAction = action;
3794
+ if (request && request.headers && request.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
3795
+ const status = response.status;
3796
+ switch (status) {
3797
+ case 408 /* IdempotentWriteSpecificHttpStatusCode.RequestTimeout */:
3798
+ case 503 /* IdempotentWriteSpecificHttpStatusCode.ServiceUnavailable */:
3799
+ retryDelayInMs = getRetryAfterInMs(response.headers);
3800
+ shouldRetry = true;
3801
+ break;
3802
+ case HttpStatusCode.ServerError: {
3803
+ shouldRetry = true;
3804
+ if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR)) {
3805
+ this.isIdempotencySupported = false;
3806
+ retryDelayInMs = 0;
3807
+ actionDataChanged = true;
3808
+ }
3809
+ break;
3810
+ }
3811
+ case 409 /* IdempotentWriteSpecificHttpStatusCode.Conflict */: {
3812
+ if (this.isUiApiErrors(response.body)) {
3813
+ const errorCode = response.body[0].errorCode;
3814
+ if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER)) {
3815
+ retryDelayInMs = 0;
3816
+ actionDataChanged = true;
3817
+ }
3818
+ else if (errorCode === ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST) {
3819
+ retryDelayInMs = getRetryAfterInMs(response.headers);
3820
+ }
3821
+ shouldRetry = true;
3822
+ }
3823
+ break;
3824
+ }
3825
+ case HttpStatusCode.BadRequest: {
3826
+ if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED, ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED)) {
3827
+ retryDelayInMs = 0;
3828
+ actionDataChanged = true;
3829
+ shouldRetry = true;
3830
+ }
3831
+ break;
3832
+ }
3833
+ case 422 /* IdempotentWriteSpecificHttpStatusCode.UnProcessableEntity */: {
3834
+ if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED)) {
3835
+ retryDelayInMs = 0;
3836
+ actionDataChanged = true;
3837
+ shouldRetry = true;
3838
+ }
3839
+ break;
3840
+ }
3841
+ }
3842
+ }
3843
+ if (this.isBackdatingEnabled &&
3844
+ response.status === HttpStatusCode.BadRequest &&
3845
+ this.isBackdatingError(response.body, action)) {
3846
+ updatedAction.timestamp = Date.now();
3847
+ updatedAction.data.body.fields = {
3848
+ ...updatedAction.data.body.fields,
3849
+ LastModifiedDate: new Date(updatedAction.timestamp).toISOString(),
3850
+ };
3851
+ if (this.hasIdempotencySupport() &&
3852
+ updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
3853
+ updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
3854
+ }
3855
+ shouldRetry = true;
3856
+ actionDataChanged = true;
3857
+ }
3858
+ await actionErrored(shouldRetry
3859
+ ? updatedAction
3860
+ : {
3861
+ ...updatedAction,
3862
+ error: response,
3863
+ status: DraftActionStatus.Error,
3864
+ }, shouldRetry, retryDelayInMs, actionDataChanged);
3865
+ return ProcessActionResult.ACTION_ERRORED;
3866
+ }
3867
+ catch (e) {
3868
+ await actionErrored(action, true);
3869
+ return ProcessActionResult.NETWORK_ERROR;
3870
+ }
3871
+ }
3872
+ // true if response is an idempotency server error. updates or deletes idempotency key if the reponse is idempotency related error. Idempotency related error is in format of UiApiError array.
3873
+ handleIdempotencyServerError(responseBody, action, updateIdempotencyKey, ...targetErrorCodes) {
3874
+ if (this.isUiApiErrors(responseBody)) {
3875
+ const errorCode = responseBody[0].errorCode;
3876
+ if (targetErrorCodes.includes(errorCode)) {
3877
+ action.data.headers = action.data.headers || {};
3878
+ if (updateIdempotencyKey) {
3879
+ action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
3880
+ }
3881
+ else {
3882
+ delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
3883
+ }
3884
+ return true;
3885
+ }
3886
+ }
3887
+ return false;
3888
+ }
3889
+ // checks if the body is an array of UiApiError. Sometimes the body has `enhancedErrorType` field as an error indicator(one example is the field validation failure). In such case Action being processed updates to an Error Action.
3890
+ isUiApiErrors(body) {
3891
+ return body !== undefined && isArray$3(body) && body.length > 0 && body[0].errorCode;
3892
+ }
3893
+ isBackdatingError(body, action) {
3894
+ if (body.enhancedErrorType &&
3895
+ body.enhancedErrorType === 'RecordError' &&
3896
+ body.output &&
3897
+ body.output.errors &&
3898
+ isArray$3(body.output.errors) &&
3899
+ body.output.errors.length > 0 &&
3900
+ action.data.body &&
3901
+ action.data.body.fields &&
3902
+ action.data.body.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE$1]) {
3903
+ return body.output.errors.some((error) => error.errorCode === 'CollisionDetectedException');
3904
+ }
3905
+ return false;
3906
+ }
3907
+ async buildPendingAction(request, queue) {
3908
+ const targetId = await this.getIdFromRequest(request);
3909
+ const tag = this.buildTagForTargetId(targetId);
3910
+ const handlerActions = queue.filter((x) => x.handler === this.handlerId);
3911
+ if (request.method === 'post' && actionsForTag(tag, handlerActions).length > 0) {
3912
+ return Promise.reject(new Error('Cannot enqueue a POST draft action with an existing tag'));
3913
+ }
3914
+ if (deleteActionsForTag(tag, handlerActions).length > 0) {
3915
+ return Promise.reject(new Error('Cannot enqueue a draft action for a deleted record'));
3916
+ }
3917
+ return {
3918
+ handler: this.handlerId,
3919
+ targetId,
3920
+ tag,
3921
+ data: request,
3922
+ status: DraftActionStatus.Pending,
3923
+ id: generateUniqueDraftActionId(queue.map((x) => x.id)),
3924
+ timestamp: Date.now(),
3925
+ metadata: {},
3926
+ version: '242.0.0',
3927
+ };
3928
+ }
3929
+ async handleActionEnqueued(_action) { }
3930
+ handleActionRemoved(action) {
3931
+ return this.reingestRecord(action);
3932
+ }
3933
+ getQueueOperationsForCompletingDrafts(queue, action) {
3934
+ const queueOperations = [];
3935
+ const redirects = this.getRedirectMappings(action);
3936
+ if (redirects !== undefined) {
3937
+ const { length } = queue;
3938
+ for (let i = 0; i < length; i++) {
3939
+ const queueAction = queue[i];
3940
+ // if this queueAction is the action that is completing we can move on,
3941
+ // it is about to be deleted and won't have the draft ID in it
3942
+ if (queueAction.id === action.id) {
3943
+ continue;
3944
+ }
3945
+ if (isResourceRequestAction(queueAction)) {
3946
+ let queueOperationMutated = false;
3947
+ let updatedActionTag = undefined;
3948
+ let updatedActionTargetId = undefined;
3949
+ const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
3950
+ let { basePath, body } = queueActionRequest;
3951
+ let stringifiedBody = stringify$4(body);
3952
+ // for each redirected ID/key we loop over the operation to see if it needs
3953
+ // to be updated
3954
+ for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
3955
+ if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
3956
+ basePath = basePath.replace(draftId, canonicalId);
3957
+ stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
3958
+ queueOperationMutated = true;
3959
+ }
3960
+ // if the action is performed on a previous draft id, we need to replace the action
3961
+ // with a new one at the updated canonical key
3962
+ if (queueActionTag === draftKey) {
3963
+ updatedActionTag = canonicalKey;
3964
+ updatedActionTargetId = canonicalId;
3965
+ }
3966
+ }
3967
+ if (queueOperationMutated) {
3968
+ if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
3969
+ const updatedAction = {
3970
+ ...queueAction,
3971
+ tag: updatedActionTag,
3972
+ targetId: updatedActionTargetId,
3973
+ data: {
3974
+ ...queueActionRequest,
3975
+ basePath: basePath,
3976
+ body: parse$4(stringifiedBody),
3977
+ },
3978
+ };
3979
+ // item needs to be replaced with a new item at the new record key
3980
+ queueOperations.push({
3981
+ type: QueueOperationType.Delete,
3982
+ id: queueActionId,
3983
+ });
3984
+ queueOperations.push({
3985
+ type: QueueOperationType.Add,
3986
+ action: updatedAction,
3987
+ });
3988
+ }
3989
+ else {
3990
+ const updatedAction = {
3991
+ ...queueAction,
3992
+ data: {
3993
+ ...queueActionRequest,
3994
+ basePath: basePath,
3995
+ body: parse$4(stringifiedBody),
3996
+ },
3997
+ };
3998
+ // item needs to be updated
3999
+ queueOperations.push({
4000
+ type: QueueOperationType.Update,
4001
+ id: queueActionId,
4002
+ action: updatedAction,
4003
+ });
4004
+ }
4005
+ }
4006
+ }
4007
+ }
4008
+ }
4009
+ // delete completed action
4010
+ queueOperations.push({
4011
+ type: QueueOperationType.Delete,
4012
+ id: action.id,
4013
+ });
4014
+ return queueOperations;
4015
+ }
4016
+ getRedirectMappings(action) {
4017
+ if (action.data.method !== 'post') {
4018
+ return undefined;
4019
+ }
4020
+ const body = action.response.body;
4021
+ const canonicalId = this.getIdFromResponseBody(body);
4022
+ const draftId = action.targetId;
4023
+ if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
4024
+ this.ephemeralRedirects[draftId] = canonicalId;
4025
+ }
4026
+ return [
4027
+ {
4028
+ draftId,
4029
+ canonicalId,
4030
+ draftKey: this.buildTagForTargetId(draftId),
4031
+ canonicalKey: this.buildTagForTargetId(canonicalId),
4032
+ },
4033
+ ];
4034
+ }
4035
+ async handleActionCompleted(action, queueOperations, allHandlers) {
4036
+ const { data: request, tag } = action;
4037
+ const { method } = request;
4038
+ if (method === 'delete') {
4039
+ return this.evictKey(tag);
4040
+ }
4041
+ const recordsToIngest = [];
4042
+ recordsToIngest.push({
4043
+ response: action.response.body,
4044
+ synchronousIngest: this.synchronousIngest.bind(this),
4045
+ buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
4046
+ });
4047
+ const recordsNeedingReplay = queueOperations.filter((x) => x.type === QueueOperationType.Update);
4048
+ for (const recordNeedingReplay of recordsNeedingReplay) {
4049
+ const { action } = recordNeedingReplay;
4050
+ if (isResourceRequestAction(action)) {
4051
+ // We can't assume the queue operation is for our handler, have to find the handler.
4052
+ const handler = allHandlers.find((h) => h.handlerId === action.handler);
4053
+ if (handler !== undefined) {
4054
+ const record = await handler.getDataForAction(action);
4055
+ if (record !== undefined) {
4056
+ recordsToIngest.push({
4057
+ response: record,
4058
+ synchronousIngest: handler.synchronousIngest.bind(handler),
4059
+ buildCacheKeysForResponse: handler.buildCacheKeysFromResponse.bind(handler),
4060
+ });
4061
+ }
4062
+ }
4063
+ }
4064
+ }
4065
+ await this.ingestResponses(recordsToIngest, action);
4066
+ }
4067
+ handleReplaceAction(targetAction, sourceAction) {
4068
+ //reject if the action to replace is a POST action
4069
+ const pendingAction = targetAction;
4070
+ if (pendingAction.data.method === 'post') {
4071
+ throw Error('Cannot replace a POST action');
4072
+ }
4073
+ if (this.isActionOfType(targetAction) &&
4074
+ this.isActionOfType(sourceAction)) {
4075
+ targetAction.status = DraftActionStatus.Pending;
4076
+ targetAction.data = sourceAction.data;
4077
+ return targetAction;
4078
+ }
4079
+ else {
4080
+ throw Error('Incompatible Action types to replace one another');
4081
+ }
4082
+ }
4083
+ mergeActions(targetAction, sourceAction) {
4084
+ const { id: targetId, data: targetData, metadata: targetMetadata, timestamp: targetTimestamp, } = targetAction;
4085
+ const { method: targetMethod, body: targetBody } = targetData;
4086
+ const { data: sourceData, metadata: sourceMetadata } = sourceAction;
4087
+ const { method: sourceMethod, body: sourceBody } = sourceData;
4088
+ if (targetMethod.toLowerCase() === 'delete' || sourceMethod.toLowerCase() === 'delete') {
4089
+ throw Error('Cannot merge DELETE actions.');
4090
+ }
4091
+ if (targetMethod.toLowerCase() === 'patch' && sourceMethod.toLowerCase() === 'post') {
4092
+ // overlaying a POST over a PATCH is not supported
4093
+ throw Error('Cannot merge a POST action over top of a PATCH action.');
4094
+ }
4095
+ // overlay top-level properties, maintain target's timestamp and id
4096
+ const merged = {
4097
+ ...targetAction,
4098
+ ...sourceAction,
4099
+ timestamp: targetTimestamp,
4100
+ id: targetId,
4101
+ };
4102
+ // overlay data
4103
+ // NOTE: we stick to the target's ResourceRequest properties (except body
4104
+ // which is merged) because we don't want to overwrite a POST with a PATCH
4105
+ // (all other cases should be fine or wouldn't have passed pre-requisites)
4106
+ merged.data = {
4107
+ ...targetData,
4108
+ body: this.mergeRequestBody(targetBody, sourceBody),
4109
+ };
4110
+ // Updates Idempotency key if target has one
4111
+ if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
4112
+ merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
4113
+ }
4114
+ // overlay metadata
4115
+ merged.metadata = { ...targetMetadata, ...sourceMetadata };
4116
+ // put status back to pending to auto upload if queue is active and targed is at the head.
4117
+ merged.status = DraftActionStatus.Pending;
4118
+ return merged;
4119
+ }
4120
+ shouldDeleteActionByTagOnRemoval(action) {
4121
+ return action.data.method === 'post';
4122
+ }
4123
+ updateMetadata(_existingMetadata, incomingMetadata) {
4124
+ return incomingMetadata;
4125
+ }
4126
+ isActionOfType(action) {
4127
+ return action.handler === this.handlerId;
4128
+ }
4129
+ async reingestRecord(action) {
4130
+ const record = await this.getDataForAction(action);
4131
+ if (record !== undefined) {
4132
+ await this.ingestResponses([
4133
+ {
4134
+ response: record,
4135
+ synchronousIngest: this.synchronousIngest.bind(this),
4136
+ buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
4137
+ },
4138
+ ], action);
4139
+ }
4140
+ else {
4141
+ await this.evictKey(action.tag);
4142
+ }
4143
+ }
4144
+ // Given an action for this handler this method should return the draft IDs.
4145
+ // Most of the time it will simply be the targetId, but certain handlers might
4146
+ // have multiple draft-created IDs so they would override this to return them.
4147
+ getDraftIdsFromAction(action) {
4148
+ return [action.targetId];
4149
+ }
4150
+ hasIdempotencySupport() {
4151
+ return this.isIdempotencySupported && !this.isLdsIdempotencyWriteDisabled;
4152
+ }
4153
+ async ingestResponses(responses, action) {
4154
+ const luvio = this.getLuvio();
4155
+ await luvio.handleSuccessResponse(() => {
4156
+ if (action.status === DraftActionStatus.Completed) {
4157
+ const mappings = this.getRedirectMappings(action);
4158
+ if (mappings) {
4159
+ mappings.forEach((mapping) => {
4160
+ luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
4161
+ });
4162
+ }
4163
+ }
4164
+ for (const entry of responses) {
4165
+ const { response, synchronousIngest } = entry;
4166
+ synchronousIngest(response, action);
4167
+ }
4168
+ return luvio.storeBroadcast();
4169
+ },
4170
+ // getTypeCacheKeysRecord uses the response, not the full path factory
4171
+ // so 2nd parameter will be unused
4172
+ () => {
4173
+ const keySet = new StoreKeyMap();
4174
+ for (const entry of responses) {
4175
+ const { response, buildCacheKeysForResponse } = entry;
4176
+ const set = buildCacheKeysForResponse(response);
4177
+ for (const key of set.keys()) {
4178
+ const value = set.get(key);
4179
+ if (value !== undefined) {
4180
+ keySet.set(key, value);
4181
+ }
4182
+ }
4183
+ }
4184
+ return keySet;
4185
+ });
4186
+ }
4187
+ async evictKey(key) {
4188
+ const luvio = this.getLuvio();
4189
+ await luvio.handleSuccessResponse(() => {
4190
+ luvio.storeEvict(key);
4191
+ return luvio.storeBroadcast();
4192
+ }, () => {
4193
+ return new StoreKeyMap();
4194
+ });
4195
+ }
4196
+ }
4197
+ function actionsForTag(tag, queue) {
4198
+ return queue.filter((action) => action.tag === tag);
4199
+ }
4200
+ function deleteActionsForTag(tag, queue) {
4201
+ return queue.filter((action) => action.tag === tag && action.data.method === 'delete');
4202
+ }
4203
+ function isResourceRequestAction(action) {
4204
+ const dataAsAny = action.data;
4205
+ return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
4206
+ }
4207
+
4210
4208
  function clone(obj) {
4211
4209
  return parse$5(stringify$5(obj));
4212
4210
  }
@@ -5274,12 +5272,12 @@ function buildAdapterValidationConfig(displayName, paramsMeta) {
5274
5272
  }
5275
5273
  const keyPrefix = 'UiApi';
5276
5274
 
5277
- const { assign: assign$5, create: create$5, freeze: freeze$1, isFrozen, keys: keys$5 } = Object;
5275
+ const { assign: assign$4, create: create$4, freeze: freeze$1, isFrozen, keys: keys$4 } = Object;
5278
5276
  const { hasOwnProperty } = Object.prototype;
5279
5277
  const { split, endsWith } = String.prototype;
5280
5278
  const { isArray: isArray$2 } = Array;
5281
- const { concat, filter, includes, push: push$2, reduce } = Array.prototype;
5282
- const { parse: parse$4, stringify: stringify$4 } = JSON;
5279
+ const { concat, filter, includes, push: push$1, reduce } = Array.prototype;
5280
+ const { parse: parse$3, stringify: stringify$3 } = JSON;
5283
5281
 
5284
5282
  function isString(value) {
5285
5283
  return typeof value === 'string';
@@ -5303,7 +5301,7 @@ function dedupe(value) {
5303
5301
  for (let i = 0, len = value.length; i < len; i += 1) {
5304
5302
  result[value[i]] = true;
5305
5303
  }
5306
- return keys$5(result);
5304
+ return keys$4(result);
5307
5305
  }
5308
5306
  /**
5309
5307
  * @param source The array of string to filter
@@ -5447,7 +5445,7 @@ function getFieldApiNamesArray(value, options = { onlyQualifiedFieldNames: false
5447
5445
  }
5448
5446
  return undefined;
5449
5447
  }
5450
- push$2.call(array, apiName);
5448
+ push$1.call(array, apiName);
5451
5449
  }
5452
5450
  if (array.length === 0) {
5453
5451
  return undefined;
@@ -6902,14 +6900,14 @@ const getTypeCacheKeys$1u = (rootKeySet, luvio, input, _fullPathFactory) => {
6902
6900
  mergeable: true,
6903
6901
  });
6904
6902
  const input_childRelationships = input.childRelationships;
6905
- const input_childRelationships_keys = keys$5(input_childRelationships);
6903
+ const input_childRelationships_keys = keys$4(input_childRelationships);
6906
6904
  const input_childRelationships_length = input_childRelationships_keys.length;
6907
6905
  for (let i = 0; i < input_childRelationships_length; i++) {
6908
6906
  const key = input_childRelationships_keys[i];
6909
6907
  getTypeCacheKeys$1t(rootKeySet, luvio, input_childRelationships[key], () => rootKey + '__childRelationships' + '__' + key);
6910
6908
  }
6911
6909
  const input_fields = input.fields;
6912
- const field_values = keys$5(input_fields);
6910
+ const field_values = keys$4(input_fields);
6913
6911
  const input_fields_length = field_values.length;
6914
6912
  for (let i = 0; i < input_fields_length; i++) {
6915
6913
  const field_value = input_fields[field_values[i]];
@@ -7365,7 +7363,7 @@ function convertRecordFieldsArrayToTrie(fields, optionalFields = []) {
7365
7363
  function createPathSelection(propertyName, fieldDefinition) {
7366
7364
  const fieldsSelection = [];
7367
7365
  const { children } = fieldDefinition;
7368
- const childrenKeys = keys$5(children);
7366
+ const childrenKeys = keys$4(children);
7369
7367
  for (let i = 0, len = childrenKeys.length; i < len; i += 1) {
7370
7368
  const childKey = childrenKeys[i];
7371
7369
  const childFieldDefinition = children[childKey];
@@ -7403,7 +7401,7 @@ function createPathSelection(propertyName, fieldDefinition) {
7403
7401
  ],
7404
7402
  };
7405
7403
  }
7406
- push$2.call(fieldsSelection, fieldSelection);
7404
+ push$1.call(fieldsSelection, fieldSelection);
7407
7405
  }
7408
7406
  return {
7409
7407
  kind: 'Object',
@@ -7416,7 +7414,7 @@ function createPathSelection(propertyName, fieldDefinition) {
7416
7414
  */
7417
7415
  function createPathSelectionFromValue(fields) {
7418
7416
  const fieldsSelections = [];
7419
- const fieldNames = keys$5(fields);
7417
+ const fieldNames = keys$4(fields);
7420
7418
  for (let i = 0, len = fieldNames.length; i < len; i++) {
7421
7419
  const fieldName = fieldNames[i];
7422
7420
  const { value: fieldValue } = fields[fieldName];
@@ -7451,7 +7449,7 @@ function createPathSelectionFromValue(fields) {
7451
7449
  selections: [DISPLAY_VALUE_SELECTION, SCALAR_VALUE_SELECTION],
7452
7450
  };
7453
7451
  }
7454
- push$2.call(fieldsSelections, fieldSelection);
7452
+ push$1.call(fieldsSelections, fieldSelection);
7455
7453
  }
7456
7454
  return {
7457
7455
  kind: 'Object',
@@ -7461,7 +7459,7 @@ function createPathSelectionFromValue(fields) {
7461
7459
  }
7462
7460
  function extractRecordFieldsRecursively(record) {
7463
7461
  const fields = [];
7464
- const fieldNames = keys$5(record.fields);
7462
+ const fieldNames = keys$4(record.fields);
7465
7463
  for (let i = 0, len = fieldNames.length; i < len; i++) {
7466
7464
  const fieldName = fieldNames[i];
7467
7465
  const { value: fieldValue } = record.fields[fieldName];
@@ -7470,10 +7468,10 @@ function extractRecordFieldsRecursively(record) {
7470
7468
  for (let j = 0, len = spanningRecordFields.length; j < len; j++) {
7471
7469
  spanningRecordFields[j] = `${fieldName}.${spanningRecordFields[j]}`;
7472
7470
  }
7473
- push$2.apply(fields, spanningRecordFields);
7471
+ push$1.apply(fields, spanningRecordFields);
7474
7472
  }
7475
7473
  else {
7476
- push$2.call(fields, fieldName);
7474
+ push$1.call(fields, fieldName);
7477
7475
  }
7478
7476
  }
7479
7477
  return fields;
@@ -9420,7 +9418,7 @@ function mergePendingFields(newRecord, oldRecord) {
9420
9418
  // RecordRepresentationNormalized['fields'] to include `pending:true` property
9421
9419
  const mergedFields = { ...newRecord.fields };
9422
9420
  const merged = { ...newRecord, fields: mergedFields };
9423
- const existingFields = keys$5(oldRecord.fields);
9421
+ const existingFields = keys$4(oldRecord.fields);
9424
9422
  for (let i = 0, len = existingFields.length; i < len; i += 1) {
9425
9423
  const spanningFieldName = existingFields[i];
9426
9424
  if (newRecord.fields[spanningFieldName] === undefined) {
@@ -9543,7 +9541,7 @@ function merge$1(existing, incoming, luvio, _path, recordConflictMap) {
9543
9541
  if (isGraphNode(node)) {
9544
9542
  const dependencies = node.retrieve();
9545
9543
  if (dependencies !== null) {
9546
- const depKeys = keys$5(dependencies);
9544
+ const depKeys = keys$4(dependencies);
9547
9545
  for (let i = 0, len = depKeys.length; i < len; i++) {
9548
9546
  luvio.storeEvict(depKeys[i]);
9549
9547
  }
@@ -9701,14 +9699,14 @@ fieldNode) {
9701
9699
  let fields = [];
9702
9700
  const fieldSubtries = [];
9703
9701
  if (fieldsTrie) {
9704
- push$2.call(fieldSubtries, fieldsTrie);
9702
+ push$1.call(fieldSubtries, fieldsTrie);
9705
9703
  }
9706
9704
  if (optionalFieldsTrie) {
9707
- push$2.call(fieldSubtries, optionalFieldsTrie);
9705
+ push$1.call(fieldSubtries, optionalFieldsTrie);
9708
9706
  }
9709
9707
  for (let i = 0; i < fieldSubtries.length; i++) {
9710
9708
  const subtrie = fieldSubtries[i];
9711
- const fieldNames = keys$5(subtrie.children);
9709
+ const fieldNames = keys$4(subtrie.children);
9712
9710
  for (let i = 0; i < fieldNames.length; i++) {
9713
9711
  const fieldName = fieldNames[i];
9714
9712
  const childTrie = subtrie.children[fieldName];
@@ -9832,13 +9830,13 @@ function isExternalLookupFieldKey(spanningNode) {
9832
9830
  return endsWith.call(spanningNode.scalar('apiName'), CUSTOM_EXTERNAL_OBJECT_FIELD_SUFFIX);
9833
9831
  }
9834
9832
  function convertTrieToFields(root) {
9835
- if (keys$5(root.children).length === 0) {
9833
+ if (keys$4(root.children).length === 0) {
9836
9834
  return [];
9837
9835
  }
9838
9836
  return convertTrieToFieldsRecursively(root);
9839
9837
  }
9840
9838
  function convertTrieToFieldsRecursively(root) {
9841
- const childKeys = keys$5(root.children);
9839
+ const childKeys = keys$4(root.children);
9842
9840
  if (childKeys.length === 0) {
9843
9841
  if (root.name === '') {
9844
9842
  return [];
@@ -9875,7 +9873,7 @@ const getObjectNameFromField = (field) => {
9875
9873
  function mergeFieldsTries(rootA, rootB) {
9876
9874
  const rootAchildren = rootA.children;
9877
9875
  const rootBchildren = rootB.children;
9878
- const childBKeys = keys$5(rootBchildren);
9876
+ const childBKeys = keys$4(rootBchildren);
9879
9877
  for (let i = 0, len = childBKeys.length; i < len; i++) {
9880
9878
  const childBKey = childBKeys[i];
9881
9879
  if (rootAchildren[childBKey] === undefined) {
@@ -10042,8 +10040,8 @@ function isSuperRecordFieldTrie(a, b) {
10042
10040
  }
10043
10041
  const childrenA = a.children;
10044
10042
  const childrenB = b.children;
10045
- const childKeysA = keys$5(childrenA);
10046
- const childKeysB = keys$5(childrenB);
10043
+ const childKeysA = keys$4(childrenA);
10044
+ const childKeysB = keys$4(childrenB);
10047
10045
  const childKeysBLength = childKeysB.length;
10048
10046
  if (childKeysBLength > childKeysA.length) {
10049
10047
  return false;
@@ -10097,9 +10095,9 @@ function fulfill(existing, incoming) {
10097
10095
  return false;
10098
10096
  }
10099
10097
  }
10100
- const headersKeys = keys$5(headers);
10098
+ const headersKeys = keys$4(headers);
10101
10099
  const headersKeyLength = headersKeys.length;
10102
- if (headersKeyLength !== keys$5(existingHeaders).length) {
10100
+ if (headersKeyLength !== keys$4(existingHeaders).length) {
10103
10101
  return false;
10104
10102
  }
10105
10103
  for (let i = 0, len = headersKeyLength; i < len; i++) {
@@ -10728,7 +10726,7 @@ function buildNetworkSnapshot$h(luvio, config, serverRequestCount = 0, options)
10728
10726
 
10729
10727
  // iterate through the map to build configs for network calls
10730
10728
  function resolveConflict(luvio, map) {
10731
- const ids = keys$5(map.conflicts);
10729
+ const ids = keys$4(map.conflicts);
10732
10730
  if (ids.length === 0) {
10733
10731
  instrumentation.recordConflictsResolved(map.serverRequestCount);
10734
10732
  return;
@@ -10744,7 +10742,7 @@ function resolveConflict(luvio, map) {
10744
10742
  else {
10745
10743
  const records = reduce.call(ids, (acc, id) => {
10746
10744
  const { trackedFields } = map.conflicts[id];
10747
- push$2.call(acc, {
10745
+ push$1.call(acc, {
10748
10746
  recordIds: [id],
10749
10747
  optionalFields: convertTrieToFields(trackedFields),
10750
10748
  });
@@ -12175,18 +12173,18 @@ function listFields(luvio, { fields = [], optionalFields = [], sortBy, }, listIn
12175
12173
  return {
12176
12174
  getRecordSelectionFieldSets() {
12177
12175
  const optionalPlusDefaultFields = { ...optionalFields_ };
12178
- const fields = keys$5(defaultFields_);
12176
+ const fields = keys$4(defaultFields_);
12179
12177
  for (let i = 0; i < fields.length; ++i) {
12180
12178
  const field = fields[i];
12181
12179
  if (!fields_[field] && !defaultServerFieldStatus.missingFields[field]) {
12182
12180
  optionalPlusDefaultFields[field] = true;
12183
12181
  }
12184
12182
  }
12185
- return [keys$5(fields_).sort(), keys$5(optionalPlusDefaultFields).sort()];
12183
+ return [keys$4(fields_).sort(), keys$4(optionalPlusDefaultFields).sort()];
12186
12184
  },
12187
12185
  processRecords(records) {
12188
12186
  const { missingFields } = defaultServerFieldStatus;
12189
- const fields = keys$5(missingFields);
12187
+ const fields = keys$4(missingFields);
12190
12188
  for (let i = 0; i < fields.length; ++i) {
12191
12189
  const field = fields[i], splitField = field.split('.').slice(1);
12192
12190
  for (let i = 0; i < records.length; ++i) {
@@ -15666,7 +15664,7 @@ function getRecordId18Array(value) {
15666
15664
  if (apiName === undefined) {
15667
15665
  return undefined;
15668
15666
  }
15669
- push$2.call(array, apiName);
15667
+ push$1.call(array, apiName);
15670
15668
  }
15671
15669
  if (array.length === 0) {
15672
15670
  return undefined;
@@ -16142,15 +16140,15 @@ function buildRecordUiSelector(recordDefs, layoutTypes, modes, recordOptionalFie
16142
16140
  name: mode,
16143
16141
  fragment: layoutSelections$2,
16144
16142
  };
16145
- push$2.call(modeSelections, modeSel);
16143
+ push$1.call(modeSelections, modeSel);
16146
16144
  }
16147
- push$2.call(layoutTypeSelections, sel);
16145
+ push$1.call(layoutTypeSelections, sel);
16148
16146
  }
16149
16147
  const recordLayoutSelections = [];
16150
16148
  const recordSelections = [];
16151
16149
  for (let i = 0, len = recordDefs.length; i < len; i += 1) {
16152
16150
  const { recordId, recordData } = recordDefs[i];
16153
- push$2.call(recordLayoutSelections, {
16151
+ push$1.call(recordLayoutSelections, {
16154
16152
  kind: 'Object',
16155
16153
  name: recordData.apiName,
16156
16154
  required: false,
@@ -16159,7 +16157,7 @@ function buildRecordUiSelector(recordDefs, layoutTypes, modes, recordOptionalFie
16159
16157
  });
16160
16158
  const optionalFields = recordOptionalFields[recordId];
16161
16159
  const fields = extractFields(recordData);
16162
- push$2.call(recordSelections, {
16160
+ push$1.call(recordSelections, {
16163
16161
  kind: 'Link',
16164
16162
  name: recordId,
16165
16163
  fragment: {
@@ -16281,7 +16279,7 @@ function getMissingRecordLookupFields(record, objectInfo) {
16281
16279
  const lookupFields = {};
16282
16280
  const { apiName, fields: recordFields } = record;
16283
16281
  const { fields: objectInfoFields } = objectInfo;
16284
- const objectInfoFieldNames = keys$5(objectInfoFields);
16282
+ const objectInfoFieldNames = keys$4(objectInfoFields);
16285
16283
  for (let i = 0, len = objectInfoFieldNames.length; i < len; i += 1) {
16286
16284
  const fieldName = objectInfoFieldNames[i];
16287
16285
  const field = objectInfoFields[fieldName];
@@ -16300,12 +16298,12 @@ function getMissingRecordLookupFields(record, objectInfo) {
16300
16298
  const nameField = `${apiName}.${relationshipName}.${getNameField(objectInfo, fieldName)}`;
16301
16299
  lookupFields[nameField] = true;
16302
16300
  }
16303
- return keys$5(lookupFields);
16301
+ return keys$4(lookupFields);
16304
16302
  }
16305
16303
  function getRecordUiMissingRecordLookupFields(recordUi) {
16306
16304
  const { records, objectInfos } = recordUi;
16307
16305
  const recordLookupFields = {};
16308
- const recordIds = keys$5(records);
16306
+ const recordIds = keys$4(records);
16309
16307
  for (let i = 0, len = recordIds.length; i < len; i += 1) {
16310
16308
  const recordId = recordIds[i];
16311
16309
  const recordData = records[recordId];
@@ -16343,19 +16341,19 @@ function buildCachedSelectorKey(key) {
16343
16341
  }
16344
16342
  function eachLayout(recordUi, cb) {
16345
16343
  const { layouts } = recordUi;
16346
- const layoutApiNames = keys$5(layouts);
16344
+ const layoutApiNames = keys$4(layouts);
16347
16345
  for (let a = 0, len = layoutApiNames.length; a < len; a += 1) {
16348
16346
  const apiName = layoutApiNames[a];
16349
16347
  const apiNameData = layouts[apiName];
16350
- const recordTypeIds = keys$5(apiNameData);
16348
+ const recordTypeIds = keys$4(apiNameData);
16351
16349
  for (let b = 0, recordTypeIdsLen = recordTypeIds.length; b < recordTypeIdsLen; b += 1) {
16352
16350
  const recordTypeId = recordTypeIds[b];
16353
16351
  const recordTypeData = apiNameData[recordTypeId];
16354
- const layoutTypes = keys$5(recordTypeData);
16352
+ const layoutTypes = keys$4(recordTypeData);
16355
16353
  for (let c = 0, layoutTypesLen = layoutTypes.length; c < layoutTypesLen; c += 1) {
16356
16354
  const layoutType = layoutTypes[c];
16357
16355
  const layoutTypeData = recordTypeData[layoutType];
16358
- const modes = keys$5(layoutTypeData);
16356
+ const modes = keys$4(layoutTypeData);
16359
16357
  for (let d = 0, modesLen = modes.length; d < modesLen; d += 1) {
16360
16358
  const mode = modes[d];
16361
16359
  const layout = layoutTypeData[mode];
@@ -16370,7 +16368,7 @@ function collectRecordDefs(resp, recordIds) {
16370
16368
  for (let i = 0, len = recordIds.length; i < len; i += 1) {
16371
16369
  const recordId = recordIds[i];
16372
16370
  const recordData = resp.records[recordId];
16373
- push$2.call(recordDefs, {
16371
+ push$1.call(recordDefs, {
16374
16372
  recordId,
16375
16373
  recordData,
16376
16374
  recordTypeId: getRecordTypeId$2(recordData),
@@ -16431,7 +16429,7 @@ function prepareRequest$3(luvio, config) {
16431
16429
  // we have to run ingest code and look at the resulting snapshot's seenRecords.
16432
16430
  function getCacheKeys(keySet, luvio, config, key, originalResponseBody) {
16433
16431
  const { recordIds, layoutTypes, modes } = config;
16434
- const responseBody = parse$4(stringify$4(originalResponseBody));
16432
+ const responseBody = parse$3(stringify$3(originalResponseBody));
16435
16433
  eachLayout(responseBody, (apiName, recordTypeId, layout) => {
16436
16434
  if (layout.id === null) {
16437
16435
  return;
@@ -16561,14 +16559,14 @@ function buildNetworkSnapshot$e(luvio, config, dispatchContext) {
16561
16559
  function publishDependencies(luvio, recordIds, depKeys) {
16562
16560
  for (let i = 0, len = recordIds.length; i < len; i += 1) {
16563
16561
  const recordDepKey = dependencyKeyBuilder({ recordId: recordIds[i] });
16564
- const dependencies = create$5(null);
16562
+ const dependencies = create$4(null);
16565
16563
  for (let j = 0, len = depKeys.length; j < len; j++) {
16566
16564
  dependencies[depKeys[j]] = true;
16567
16565
  }
16568
16566
  const node = luvio.getNode(recordDepKey);
16569
16567
  if (isGraphNode(node)) {
16570
16568
  const recordDeps = node.retrieve();
16571
- assign$5(dependencies, recordDeps);
16569
+ assign$4(dependencies, recordDeps);
16572
16570
  }
16573
16571
  luvio.storePublish(recordDepKey, dependencies);
16574
16572
  }
@@ -16686,7 +16684,7 @@ function refresh(luvio, config) {
16686
16684
  }
16687
16685
  if (isUnfulfilledSnapshot$1(snapshot)) {
16688
16686
  if (process.env.NODE_ENV !== 'production') {
16689
- throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$5(snapshot.missingPaths)}`);
16687
+ throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$4(snapshot.missingPaths)}`);
16690
16688
  }
16691
16689
  }
16692
16690
  const { data } = snapshot;
@@ -16733,7 +16731,7 @@ function processRecordUiRepresentation(luvio, refresh, recordId, modes, snapshot
16733
16731
  }
16734
16732
  if (isUnfulfilledSnapshot$1(snapshot)) {
16735
16733
  if (process.env.NODE_ENV !== 'production') {
16736
- throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$5(snapshot.missingPaths)}`);
16734
+ throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$4(snapshot.missingPaths)}`);
16737
16735
  }
16738
16736
  }
16739
16737
  const { data } = snapshot;
@@ -16762,11 +16760,11 @@ const recordLayoutFragmentSelector = [
16762
16760
  function getFieldsFromLayoutMap(layoutMap, objectInfo) {
16763
16761
  let fields = [];
16764
16762
  let optionalFields = [];
16765
- const layoutTypes = keys$5(layoutMap);
16763
+ const layoutTypes = keys$4(layoutMap);
16766
16764
  for (let i = 0, layoutTypesLen = layoutTypes.length; i < layoutTypesLen; i += 1) {
16767
16765
  const layoutType = layoutTypes[i];
16768
16766
  const modesMap = layoutMap[layoutType];
16769
- const modes = keys$5(modesMap);
16767
+ const modes = keys$4(modesMap);
16770
16768
  for (let m = 0, modesLen = modes.length; m < modesLen; m += 1) {
16771
16769
  const mode = modes[m];
16772
16770
  const { fields: modeFields, optionalFields: modeOptionalFields } = getQualifiedFieldApiNamesFromLayout(modesMap[mode], objectInfo);
@@ -16802,7 +16800,7 @@ function getRecordForLayoutableEntities(luvio, refresh, recordId, layoutMap, obj
16802
16800
  return getRecord(luvio, refresh, recordId, [], implicitFields);
16803
16801
  }
16804
16802
  function getRecordForNonLayoutableEntities(luvio, adapterContext, refresh, recordId, objectInfo, configOptionalFields, configFields) {
16805
- const fields = keys$5(configFields ? configFields : {}).map((key) => `${objectInfo.apiName}.${key}`);
16803
+ const fields = keys$4(configFields ? configFields : {}).map((key) => `${objectInfo.apiName}.${key}`);
16806
16804
  // W-12697744
16807
16805
  // Set the implicit fields received from the server in adapter context
16808
16806
  // This ensures that the implicit fields are available when data is read locally or from durable store
@@ -17041,7 +17039,7 @@ function makeRecordLayoutMap(luvio, config, apiName, recordTypeId, layoutTypes,
17041
17039
  }
17042
17040
  const { layoutType, mode, snapshot } = container;
17043
17041
  if (wrapper.layoutMap[layoutType] === undefined) {
17044
- wrapper.layoutMap = assign$5({}, wrapper.layoutMap, {
17042
+ wrapper.layoutMap = assign$4({}, wrapper.layoutMap, {
17045
17043
  [layoutType]: {},
17046
17044
  });
17047
17045
  }
@@ -17777,7 +17775,7 @@ function typeCheckConfig$9(untrustedConfig) {
17777
17775
  }
17778
17776
  }
17779
17777
  if (records.length > 0) {
17780
- assign$5(config, { records });
17778
+ assign$4(config, { records });
17781
17779
  }
17782
17780
  }
17783
17781
  return config;
@@ -43578,8 +43576,8 @@ function isArrayLike(x) {
43578
43576
  (x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1))));
43579
43577
  }
43580
43578
 
43581
- const { create: create$4, keys: keys$4, values: values$2, entries: entries$4, assign: assign$4 } = Object;
43582
- const { stringify: stringify$3, parse: parse$3 } = JSON;
43579
+ const { create: create$3, keys: keys$3, values: values$2, entries: entries$3, assign: assign$3 } = Object;
43580
+ const { stringify: stringify$2, parse: parse$2 } = JSON;
43583
43581
  const { isArray: isArray$1, from: from$1 } = Array;
43584
43582
 
43585
43583
  function recordLoaderFactory(query) {
@@ -43591,7 +43589,7 @@ function recordLoaderFactory(query) {
43591
43589
  rows.forEach((row) => {
43592
43590
  if (!row[0])
43593
43591
  return null;
43594
- const record = parse$3(row[0]);
43592
+ const record = parse$2(row[0]);
43595
43593
  if (record.id === id) {
43596
43594
  foundRow = record;
43597
43595
  }
@@ -43950,11 +43948,11 @@ function dateTimePredicate(input, operator, field, alias) {
43950
43948
  return dateTimeRange(range, operator, field, alias);
43951
43949
  }
43952
43950
  // eslint-disable-next-line @salesforce/lds/no-error-in-production
43953
- throw new Error(`Where filter ${stringify$3(input)} is not supported`);
43951
+ throw new Error(`Where filter ${stringify$2(input)} is not supported`);
43954
43952
  }
43955
43953
  function dateTimeRange(input, op, field, alias) {
43956
43954
  const dateFunction = field.dataType === 'DateTime' ? 'datetime' : 'date';
43957
- const key = keys$4(input)[0];
43955
+ const key = keys$3(input)[0];
43958
43956
  let operator = op;
43959
43957
  if (operator === '=')
43960
43958
  operator = 'BETWEEN';
@@ -44254,7 +44252,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
44254
44252
  if (!where)
44255
44253
  return [];
44256
44254
  let predicates = [];
44257
- const fields = keys$4(where);
44255
+ const fields = keys$3(where);
44258
44256
  for (const field of fields) {
44259
44257
  if (field === 'and' || field === 'or') {
44260
44258
  predicates.push(processCompoundPredicate(field, where[field], recordType, alias, objectInfoMap, joins));
@@ -44279,8 +44277,12 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
44279
44277
  // handles spanning field filter. For example, for 'OwnerId' field within 'Account' objectInfo, both 'OwnerId' and 'Owner' can be
44280
44278
  // treated as reference type, while 'Owner' field spanns since it equals to 'relationshipName'
44281
44279
  if (fieldInfo.dataType === 'Reference' && fieldInfo.relationshipName === field) {
44280
+ let leftPath = `$.fields.${fieldInfo.apiName}.value`;
44281
+ if (fieldInfo.apiName === 'RecordTypeId') {
44282
+ leftPath = '$.recordTypeId';
44283
+ }
44282
44284
  const path = {
44283
- leftPath: `$.fields.${fieldInfo.apiName}.value`,
44285
+ leftPath: leftPath,
44284
44286
  rightPath: `$.id`,
44285
44287
  };
44286
44288
  const childAlias = `${alias}_${field}`;
@@ -44303,7 +44305,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
44303
44305
  }
44304
44306
  else {
44305
44307
  // @W-12618378 polymorphic query sometimes does not work as expected on server. The GQL on certain entities could fail.
44306
- const entityNames = keys$4(where[field]);
44308
+ const entityNames = keys$3(where[field]);
44307
44309
  const polyPredicatesGroups = entityNames
44308
44310
  .filter((entityName) => fieldInfo.referenceToInfos.some((referenceInfo) => referenceInfo.apiName === entityName))
44309
44311
  .map((entityName) => {
@@ -44333,7 +44335,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
44333
44335
  }
44334
44336
  else {
44335
44337
  //`field` match the filedInfo's apiName
44336
- for (const [op, value] of entries$4(where[field])) {
44338
+ for (const [op, value] of entries$3(where[field])) {
44337
44339
  const operator = operatorToSql(op);
44338
44340
  /**
44339
44341
  Two types ID processing might be needed. Draft ID swapping is optional, which depends on DraftFunctions existence.
@@ -45504,7 +45506,7 @@ function depth(json, currentLevel = 0) {
45504
45506
  if (typeof json !== 'object') {
45505
45507
  return currentLevel;
45506
45508
  }
45507
- const keys$1 = keys$4(json);
45509
+ const keys$1 = keys$3(json);
45508
45510
  if (keys$1.length === 0)
45509
45511
  return 0;
45510
45512
  const depths = keys$1.map((key) => {
@@ -45557,7 +45559,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
45557
45559
  return predicates;
45558
45560
  const isSpanning = depth(orderBy) > 2;
45559
45561
  if (isSpanning) {
45560
- const keys$1 = keys$4(orderBy);
45562
+ const keys$1 = keys$3(orderBy);
45561
45563
  for (let i = 0, len = keys$1.length; i < len; i++) {
45562
45564
  const key = keys$1[i];
45563
45565
  const parentFields = objectInfoMap[recordType].fields;
@@ -45587,7 +45589,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
45587
45589
  }
45588
45590
  }
45589
45591
  else {
45590
- const keys$1 = keys$4(orderBy);
45592
+ const keys$1 = keys$3(orderBy);
45591
45593
  for (let i = 0, len = keys$1.length; i < len; i++) {
45592
45594
  const key = keys$1[i];
45593
45595
  if (!objectInfoMap[recordType])
@@ -45802,14 +45804,14 @@ function isLocalCursor(maybeCursor) {
45802
45804
  typeof maybeCursor.i === 'number');
45803
45805
  }
45804
45806
  function encodeV1Cursor(cursor) {
45805
- return base64encode(stringify$3(cursor));
45807
+ return base64encode(stringify$2(cursor));
45806
45808
  }
45807
45809
  const CURSOR_PARSE_ERROR = 'Unable to parse cursor';
45808
45810
  function decodeV1Cursor(base64cursor) {
45809
45811
  let maybeCursor;
45810
45812
  try {
45811
45813
  const cursorString = base64decode(base64cursor);
45812
- maybeCursor = parse$3(cursorString);
45814
+ maybeCursor = parse$2(cursorString);
45813
45815
  }
45814
45816
  catch (error) {
45815
45817
  let message = CURSOR_PARSE_ERROR;
@@ -46013,7 +46015,7 @@ async function readPaginationMetadataForKeys(keys, query) {
46013
46015
  const results = await query(sql, keys.map((k) => k + '__pagination'));
46014
46016
  for (let row of results.rows) {
46015
46017
  let key = row[0].replace(/__pagination$/, '');
46016
- let metadata = parse$3(row[1]);
46018
+ let metadata = parse$2(row[1]);
46017
46019
  metadataMap.set(key, metadata);
46018
46020
  }
46019
46021
  return metadataMap;
@@ -46117,8 +46119,8 @@ async function connectionResolver(obj, args, context, info) {
46117
46119
  //map each sql result with the ingestion timestamp to pass it down a level
46118
46120
  let records = results.rows.map((row, index) => {
46119
46121
  const recordMetadataResult = {
46120
- recordRepresentation: parse$3(row[0]),
46121
- metadata: parse$3(row[1]),
46122
+ recordRepresentation: parse$2(row[0]),
46123
+ metadata: parse$2(row[1]),
46122
46124
  };
46123
46125
  const { recordRepresentation, metadata } = recordMetadataResult;
46124
46126
  context.seenRecordIds.add(recordRepresentation.id);
@@ -46191,7 +46193,7 @@ function buildKeyStringForRecordQuery(operation, variables, argumentNodes, curre
46191
46193
  variables,
46192
46194
  fragmentMap: {},
46193
46195
  });
46194
- const filteredArgumentNodes = assign$4([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
46196
+ const filteredArgumentNodes = assign$3([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
46195
46197
  const argumentString = filteredArgumentNodes.length > 0
46196
46198
  ? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
46197
46199
  : '';
@@ -46606,7 +46608,7 @@ function generateRecordQueries(schema, objectInfoMap) {
46606
46608
  // use a set to not allow duplicate scalars causing error(s)
46607
46609
  let addedTypedScalars = new Set();
46608
46610
  let allPolymorphicFieldTypeNames = new Set();
46609
- for (const name of keys$4(objectInfoMap)) {
46611
+ for (const name of keys$3(objectInfoMap)) {
46610
46612
  const objectInfo = objectInfoMap[name];
46611
46613
  const { apiName } = objectInfo;
46612
46614
  const type = schema.getType(apiName);
@@ -46733,7 +46735,7 @@ function extendExistingRecordType(schema, type, objectInfo, objectInfoMap) {
46733
46735
  // use a set to not allow duplicate scalars causing error(s)
46734
46736
  let typedScalars = new Set();
46735
46737
  let parentRelationshipFields = new Set();
46736
- const existingFields = keys$4(type.getFields());
46738
+ const existingFields = keys$3(type.getFields());
46737
46739
  const missingFields = values$2(objectInfo.fields).filter((field) => {
46738
46740
  return (existingFields.includes(field.apiName) === false ||
46739
46741
  (field.relationshipName !== null && field.referenceToInfos.length > 0));
@@ -47592,7 +47594,7 @@ async function resolveObjectInfos(objectInfotree, pathToObjectApiNamesMap, start
47592
47594
  // eslint-disable-next-line
47593
47595
  throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
47594
47596
  }
47595
- if (keys$4(objectInfos).length < startNodes.size) {
47597
+ if (keys$3(objectInfos).length < startNodes.size) {
47596
47598
  // eslint-disable-next-line
47597
47599
  throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
47598
47600
  }
@@ -48533,7 +48535,7 @@ function removeSyntheticFields(result, query) {
48533
48535
  output.data.uiapi = { ...output.data.uiapi };
48534
48536
  output.data.uiapi.query = { ...output.data.uiapi.query };
48535
48537
  const outputApiParent = output.data.uiapi.query;
48536
- const keys$1 = keys$4(nodeJson);
48538
+ const keys$1 = keys$3(nodeJson);
48537
48539
  keys$1.forEach((recordName) => {
48538
48540
  const outputApi = {};
48539
48541
  // Each connectionSelection's maps its name or alias to one of returned records. The record name could be `apiName' or alias
@@ -48553,7 +48555,7 @@ function removeSyntheticFields(result, query) {
48553
48555
  * @param jsonOutput JsonObject which will be populated with properties. It would only contains properties defined in 'FieldNode'
48554
48556
  */
48555
48557
  function createUserJsonOutput(selection, jsonInput, jsonOutput) {
48556
- const keys$1 = keys$4(jsonInput);
48558
+ const keys$1 = keys$3(jsonInput);
48557
48559
  if (selection.selectionSet) {
48558
48560
  createjsonOutput(selection.selectionSet.selections, jsonInput, jsonOutput);
48559
48561
  }
@@ -48562,7 +48564,7 @@ function createUserJsonOutput(selection, jsonInput, jsonOutput) {
48562
48564
  }
48563
48565
  }
48564
48566
  function createjsonOutput(selections, jsonInput, jsonOutput) {
48565
- const keys$1 = keys$4(jsonInput);
48567
+ const keys$1 = keys$3(jsonInput);
48566
48568
  selections.filter(isFieldNode).forEach((subSelection) => {
48567
48569
  const fieldName = subSelection.alias ? subSelection.alias.value : subSelection.name.value;
48568
48570
  if (keys$1.includes(fieldName)) {
@@ -48938,7 +48940,7 @@ const replaceDraftIdsInVariables = (variables, draftFunctions, unmappedDraftIDs)
48938
48940
  }
48939
48941
  else if (typeof object === 'object' && object !== null) {
48940
48942
  let source = object;
48941
- return keys$4(source).reduce((acc, key) => {
48943
+ return keys$3(source).reduce((acc, key) => {
48942
48944
  acc[key] = replace(source[key]);
48943
48945
  return acc;
48944
48946
  }, {});
@@ -48947,7 +48949,7 @@ const replaceDraftIdsInVariables = (variables, draftFunctions, unmappedDraftIDs)
48947
48949
  return object;
48948
48950
  }
48949
48951
  };
48950
- let newVariables = keys$4(variables).reduce((acc, key) => {
48952
+ let newVariables = keys$3(variables).reduce((acc, key) => {
48951
48953
  acc[key] = replace(variables[key]);
48952
48954
  return acc;
48953
48955
  }, {});
@@ -48959,7 +48961,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
48959
48961
  const getCanonicalId = getCanonicalIdFunction(luvio);
48960
48962
  return async function draftAwareGraphQLAdapter(config, requestContext = {}) {
48961
48963
  //create a copy to not accidentally modify the AST in the astResolver map of luvio
48962
- const copy = parse$3(stringify$3(config.query));
48964
+ const copy = parse$2(stringify$2(config.query));
48963
48965
  // the injected ast has extra fields needed for eval in it
48964
48966
  let injectedAST;
48965
48967
  // the cursor mapped ast is passed upstream so it won't reject on our local cursors
@@ -49053,7 +49055,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
49053
49055
  } = await evaluate({
49054
49056
  ...config,
49055
49057
  //need to create another copy of the ast for future writes
49056
- query: parse$3(stringify$3(injectedAST)),
49058
+ query: parse$2(stringify$2(injectedAST)),
49057
49059
  }, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors));
49058
49060
  }
49059
49061
  catch (throwable) {
@@ -49169,7 +49171,7 @@ function makeGetRecordsConfig(keyMap) {
49169
49171
 
49170
49172
  function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, isDraftId, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy) {
49171
49173
  return async function environmentAwareGraphQLBatchAdapter(config, requestContext = {}) {
49172
- const batchQueryCopy = config.batchQuery.map((query) => parse$3(stringify$3(query)));
49174
+ const batchQueryCopy = config.batchQuery.map((query) => parse$2(stringify$2(query)));
49173
49175
  let injectedBatchQuery = [];
49174
49176
  const getCanonicalId = getCanonicalIdFunction(luvio);
49175
49177
  const draftFunctions = {
@@ -49393,14 +49395,14 @@ const recordIdGenerator = (id) => {
49393
49395
  */
49394
49396
 
49395
49397
 
49396
- const { keys: keys$3, create: create$3, assign: assign$3, entries: entries$3 } = Object;
49397
- const { stringify: stringify$2, parse: parse$2 } = JSON;
49398
- const { push: push$1, join: join$1, slice: slice$1 } = Array.prototype;
49398
+ const { keys: keys$2, create: create$2, assign: assign$2, entries: entries$2 } = Object;
49399
+ const { stringify: stringify$1, parse: parse$1 } = JSON;
49400
+ const { push, join, slice } = Array.prototype;
49399
49401
  const { isArray, from } = Array;
49400
49402
 
49401
49403
  function ldsParamsToString(params) {
49402
- const returnParams = create$3(null);
49403
- const keys$1 = keys$3(params);
49404
+ const returnParams = create$2(null);
49405
+ const keys$1 = keys$2(params);
49404
49406
  for (let i = 0, len = keys$1.length; i < len; i++) {
49405
49407
  const key = keys$1[i];
49406
49408
  const value = params[key];
@@ -49417,8 +49419,8 @@ function ldsParamsToString(params) {
49417
49419
  else {
49418
49420
  returnParams[key] = `${value}`;
49419
49421
  }
49420
- if (isObject(value) === true && keys$3(value).length > 0) {
49421
- returnParams[key] = stringify$2(value);
49422
+ if (isObject(value) === true && keys$2(value).length > 0) {
49423
+ returnParams[key] = stringify$1(value);
49422
49424
  }
49423
49425
  }
49424
49426
  return returnParams;
@@ -49477,13 +49479,13 @@ function stringifyIfPresent(value) {
49477
49479
  if (value === undefined || value === null) {
49478
49480
  return null;
49479
49481
  }
49480
- return stringify$2(value);
49482
+ return stringify$1(value);
49481
49483
  }
49482
49484
  function parseIfPresent(value) {
49483
49485
  if (value === undefined || value === null || value === '') {
49484
49486
  return null;
49485
49487
  }
49486
- return parse$2(value);
49488
+ return parse$1(value);
49487
49489
  }
49488
49490
  function buildNimbusNetworkPluginRequest(resourceRequest, resourceRequestContext) {
49489
49491
  const { basePath, baseUri, method, headers, queryParams, body } = resourceRequest;
@@ -49574,10 +49576,10 @@ class ScopedFields {
49574
49576
  fields.forEach(this.addField, this);
49575
49577
  }
49576
49578
  toQueryParameterValue() {
49577
- const joinedFields = join$1.call(Object.keys(this.fields), SEPARATOR_BETWEEN_FIELDS);
49579
+ const joinedFields = join.call(Object.keys(this.fields), SEPARATOR_BETWEEN_FIELDS);
49578
49580
  return this.isUnScoped()
49579
49581
  ? joinedFields
49580
- : join$1.call([this.scope, joinedFields], SEPARATOR_BETWEEN_SCOPE_AND_FIELDS);
49582
+ : join.call([this.scope, joinedFields], SEPARATOR_BETWEEN_SCOPE_AND_FIELDS);
49581
49583
  }
49582
49584
  toQueryParams() {
49583
49585
  return this.isUnScoped() ? Object.keys(this.fields) : this.toQueryParameterValue();
@@ -49645,7 +49647,7 @@ class ScopedFieldsCollection {
49645
49647
  if (chunk !== undefined)
49646
49648
  result.push(chunk);
49647
49649
  }
49648
- return join$1.call(result, SEPARATOR_BETWEEN_SCOPES);
49650
+ return join.call(result, SEPARATOR_BETWEEN_SCOPES);
49649
49651
  }
49650
49652
  /**
49651
49653
  * split the ScopedFields into multiple ScopedFields
@@ -49818,12 +49820,12 @@ function buildAggregateUiUrl(params, resourceRequest) {
49818
49820
  optionalFields,
49819
49821
  };
49820
49822
  const queryString = [];
49821
- for (const [key, value] of entries$3(mergedParams)) {
49823
+ for (const [key, value] of entries$2(mergedParams)) {
49822
49824
  if (value !== undefined) {
49823
49825
  queryString.push(`${key}=${isArray(value) ? value.join(',') : value}`);
49824
49826
  }
49825
49827
  }
49826
- return `${resourceRequest.baseUri}${resourceRequest.basePath}?${join$1.call(queryString, '&')}`;
49828
+ return `${resourceRequest.baseUri}${resourceRequest.basePath}?${join.call(queryString, '&')}`;
49827
49829
  }
49828
49830
  function shouldUseAggregateUiForFields(fieldsArray, optionalFieldsArray, maxLengthPerChunk) {
49829
49831
  return fieldsArray.length + optionalFieldsArray.length >= maxLengthPerChunk;
@@ -49834,7 +49836,7 @@ function isSpanningRecord(fieldValue) {
49834
49836
  function mergeRecordFields(first, second) {
49835
49837
  const { fields: targetFields } = first;
49836
49838
  const { fields: sourceFields } = second;
49837
- const fieldNames = keys$3(sourceFields);
49839
+ const fieldNames = keys$2(sourceFields);
49838
49840
  for (let i = 0, len = fieldNames.length; i < len; i += 1) {
49839
49841
  const fieldName = fieldNames[i];
49840
49842
  const sourceField = sourceFields[fieldName];
@@ -49932,7 +49934,7 @@ function buildCompositeRequestByFields(referenceId, resourceRequest, recordsComp
49932
49934
  const url = buildAggregateUiUrl({
49933
49935
  fields: fieldChunk,
49934
49936
  }, resourceRequest);
49935
- push$1.call(compositeRequest, {
49937
+ push.call(compositeRequest, {
49936
49938
  url,
49937
49939
  referenceId: `${referenceId}_fields_${i}`,
49938
49940
  });
@@ -49947,7 +49949,7 @@ function buildCompositeRequestByFields(referenceId, resourceRequest, recordsComp
49947
49949
  const url = buildAggregateUiUrl({
49948
49950
  optionalFields: fieldChunk,
49949
49951
  }, resourceRequest);
49950
- push$1.call(compositeRequest, {
49952
+ push.call(compositeRequest, {
49951
49953
  url,
49952
49954
  referenceId: `${referenceId}_optionalFields_${i}`,
49953
49955
  });
@@ -49987,8 +49989,8 @@ function getMaxLengthPerChunkAllowed(request) {
49987
49989
  // Too much work to get exact length of the final url, so use stringified json to get the rough length.
49988
49990
  const roughUrlLengthWithoutFieldsAndOptionFields = request.basePath.length +
49989
49991
  request.baseUri.length +
49990
- (request.urlParams ? stringify$2(request.urlParams).length : 0) +
49991
- stringify$2({ ...request.queryParams, fields: {}, optionalFields: {} }).length;
49992
+ (request.urlParams ? stringify$1(request.urlParams).length : 0) +
49993
+ stringify$1({ ...request.queryParams, fields: {}, optionalFields: {} }).length;
49992
49994
  // MAX_URL_LENGTH - full lenght without fields, optionalFields
49993
49995
  return MAX_URL_LENGTH - roughUrlLengthWithoutFieldsAndOptionFields;
49994
49996
  }
@@ -49998,7 +50000,7 @@ function calculateEstimatedTotalUrlLength(request) {
49998
50000
  const { baseUri, basePath, queryParams } = request;
49999
50001
  let url = `${baseUri}${basePath}`;
50000
50002
  if (queryParams) {
50001
- const queryParamString = entries$3(queryParams)
50003
+ const queryParamString = entries$2(queryParams)
50002
50004
  .map(([key, value]) => `${key}=${value}`)
50003
50005
  .join('&');
50004
50006
  if (queryParamString) {
@@ -50211,10 +50213,6 @@ function makeNetworkAdapterChunkRecordFields(networkAdapter, instrumentationSink
50211
50213
  }, networkAdapter);
50212
50214
  }
50213
50215
 
50214
- const { keys: keys$2, create: create$2, assign: assign$2, entries: entries$2 } = Object;
50215
- const { stringify: stringify$1, parse: parse$1 } = JSON;
50216
- const { push, join, slice, shift } = Array.prototype;
50217
-
50218
50216
  // so eslint doesn't complain about nimbus
50219
50217
  /* global __nimbus */
50220
50218
  /**
@@ -50230,10 +50228,10 @@ class NimbusDraftQueue {
50230
50228
  if (callProxyMethod === undefined) {
50231
50229
  return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
50232
50230
  }
50233
- const serializedAction = stringify$1([handlerId, data]);
50231
+ const serializedAction = stringify$4([handlerId, data]);
50234
50232
  return new Promise((resolve, reject) => {
50235
50233
  callProxyMethod('enqueue', serializedAction, (serializedActionResponse) => {
50236
- const response = parse$1(serializedActionResponse);
50234
+ const response = parse$4(serializedActionResponse);
50237
50235
  resolve(response);
50238
50236
  }, (errorMessage) => {
50239
50237
  reject(new Error(errorMessage));
@@ -50254,8 +50252,8 @@ class NimbusDraftQueue {
50254
50252
  return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
50255
50253
  }
50256
50254
  return new Promise((resolve, reject) => {
50257
- callProxyMethod('getQueueActions', stringify$1([]), (serializedQueue) => {
50258
- resolve(parse$1(serializedQueue));
50255
+ callProxyMethod('getQueueActions', stringify$4([]), (serializedQueue) => {
50256
+ resolve(parse$4(serializedQueue));
50259
50257
  }, (errorMessage) => {
50260
50258
  reject(new Error(errorMessage));
50261
50259
  });
@@ -50266,17 +50264,17 @@ class NimbusDraftQueue {
50266
50264
  if (callProxyMethod === undefined) {
50267
50265
  return Promise.reject('callProxyMethod not defined on the nimbus plugin');
50268
50266
  }
50269
- const stringifiedArgs = stringify$1([action]);
50267
+ const stringifiedArgs = stringify$4([action]);
50270
50268
  return new Promise((resolve, reject) => {
50271
50269
  callProxyMethod('getDataForAction', stringifiedArgs, (data) => {
50272
50270
  if (data === undefined) {
50273
50271
  resolve(undefined);
50274
50272
  }
50275
50273
  else {
50276
- resolve(parse$1(data));
50274
+ resolve(parse$4(data));
50277
50275
  }
50278
50276
  }, (serializedError) => {
50279
- reject(parse$1(serializedError));
50277
+ reject(parse$4(serializedError));
50280
50278
  });
50281
50279
  });
50282
50280
  }
@@ -50346,7 +50344,7 @@ function normalizeError(err) {
50346
50344
  else if (typeof err === 'string') {
50347
50345
  return new Error(err);
50348
50346
  }
50349
- return new Error(stringify$1(err));
50347
+ return new Error(stringify$4(err));
50350
50348
  }
50351
50349
 
50352
50350
  const O11Y_NAMESPACE_LDS_MOBILE = 'lds-mobile';
@@ -50563,7 +50561,7 @@ function instrumentDraftQueue(queue) {
50563
50561
  logError: false,
50564
50562
  });
50565
50563
  };
50566
- const overriddenQueue = create$2(queue, { mergeActions: { value: mergeActions } });
50564
+ const overriddenQueue = create$5(queue, { mergeActions: { value: mergeActions } });
50567
50565
  overriddenQueue.registerOnChangedListener((draftQueueEvent) => {
50568
50566
  switch (draftQueueEvent.type) {
50569
50567
  case DraftQueueEventType.QueueStateChanged: {
@@ -50701,7 +50699,7 @@ function enableObjectInfoCaching(env, ensureObjectInfoCached) {
50701
50699
  function dataIsObjectInfo(key, data) {
50702
50700
  return incomingObjectInfos.has(key);
50703
50701
  }
50704
- return create$2(env, {
50702
+ return create$5(env, {
50705
50703
  handleSuccessResponse: { value: handleSuccessResponse },
50706
50704
  storePublish: { value: storePublish },
50707
50705
  });
@@ -50802,8 +50800,8 @@ class ObjectInfoService {
50802
50800
  }
50803
50801
  };
50804
50802
  // Local in-memory cache for apiName to key prefixes
50805
- this.apiNameToKeyPrefixMemoryCache = create$2(null);
50806
- this.keyPrefixToApiNameMemoryCache = create$2(null);
50803
+ this.apiNameToKeyPrefixMemoryCache = create$5(null);
50804
+ this.keyPrefixToApiNameMemoryCache = create$5(null);
50807
50805
  }
50808
50806
  /**
50809
50807
  * Size of return map not necessarily correlated with number of inputs. The
@@ -50954,8 +50952,8 @@ function registerReportObserver(reportObserver) {
50954
50952
  const index = reportObservers.indexOf(reportObserver);
50955
50953
  if (index > -1) {
50956
50954
  reportObservers = [
50957
- ...slice.call(reportObservers, 0, index),
50958
- ...slice.call(reportObservers, index + 1),
50955
+ ...slice$1.call(reportObservers, 0, index),
50956
+ ...slice$1.call(reportObservers, index + 1),
50959
50957
  ];
50960
50958
  }
50961
50959
  };
@@ -51595,7 +51593,7 @@ function makeEnvironmentGraphqlAware(environment) {
51595
51593
  }
51596
51594
  return environment.applyCachePolicy(luvio, adapterRequestContext, buildSnapshotContext, localBuildCachedSnapshot, buildNetworkSnapshot);
51597
51595
  };
51598
- return create$2(environment, {
51596
+ return create$5(environment, {
51599
51597
  rebuildSnapshot: { value: rebuildSnapshot },
51600
51598
  applyCachePolicy: { value: applyCachePolicy },
51601
51599
  setDefaultCachePolicy: { value: environment.setDefaultCachePolicy.bind(environment) },
@@ -52873,7 +52871,7 @@ async function aggressiveTrim(data, deallocateFn, options = {}) {
52873
52871
  const batchSize = options.batchSize !== undefined ? options.batchSize : DEFAULT_MAX_BATCH_SIZE;
52874
52872
  let deallocatedCount = 0;
52875
52873
  const { pendingTrimKeys, retainedIds, storeRecords } = data;
52876
- const storeKeyLength = keys$2(storeRecords).length;
52874
+ const storeKeyLength = keys$5(storeRecords).length;
52877
52875
  if (storeKeyLength <= maxStoreRecords) {
52878
52876
  return { deallocatedCount, trimKeysSkipped: pendingTrimKeys };
52879
52877
  }
@@ -52941,7 +52939,7 @@ function setupObserver() {
52941
52939
  registerReportObserver((report) => {
52942
52940
  __nimbus.plugins.LdsObserverPlugin.logAdapterExecution({
52943
52941
  name: report.adapterName,
52944
- serializedConfig: stringify$1(report.config),
52942
+ serializedConfig: stringify$4(report.config),
52945
52943
  status: report.result,
52946
52944
  duration: report.executionTime,
52947
52945
  });
@@ -53609,7 +53607,7 @@ const shouldFlush = (key, value) => {
53609
53607
  if (value && typeof value === 'object') {
53610
53608
  const fields = value.fields;
53611
53609
  if (fields && typeof fields === 'object') {
53612
- const keys = keys$2(fields);
53610
+ const keys = keys$5(fields);
53613
53611
  for (const key of keys) {
53614
53612
  const field = fields[key];
53615
53613
  if (fields && field.__state && field.__state.pending === true) {
@@ -53778,4 +53776,4 @@ register({
53778
53776
  });
53779
53777
 
53780
53778
  export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
53781
- // version: 1.316.0-fd56ed976d
53779
+ // version: 1.317.0-374876d2a3