@salesforce/lds-runtime-mobile 1.171.0 → 1.171.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/main.js +82 -36
  2. package/package.json +1 -1
  3. package/sfdc/main.js +82 -36
package/dist/main.js CHANGED
@@ -4978,9 +4978,14 @@ function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromC
4978
4978
  if (options.forDeleteAdapter === true) {
4979
4979
  // delete adapters attempt to evict the record on successful network response,
4980
4980
  // since draft-aware delete adapters do soft-delete (record stays in cache
4981
- // with a "drafts.deleted" property) we want storeEvict to just be a no-op
4982
- const storeEvict = function (_key) {
4983
- // no-op
4981
+ // with a "drafts.deleted" property) we just want to let the environment know so it can
4982
+ // decrement its ref count for the record
4983
+ const storeEvict = function (key) {
4984
+ const softEvict = luvio.environment.softEvict;
4985
+ if (softEvict === undefined) {
4986
+ throw Error('DraftAwareEnvironment not configured correctly');
4987
+ }
4988
+ softEvict(key);
4984
4989
  };
4985
4990
  return create$4(luvio, {
4986
4991
  dispatchResourceRequest: { value: dispatchResourceRequest },
@@ -6434,29 +6439,46 @@ function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueu
6434
6439
  };
6435
6440
  const storePublish = function (key, data) {
6436
6441
  const draftMetadataForKey = draftMetadata[key];
6442
+ let handled = false;
6437
6443
  for (const handler of handlers) {
6438
6444
  if (handler.canHandlePublish(key)) {
6445
+ handled = true;
6439
6446
  handler.applyDraftsToIncomingData(key, data, draftMetadataForKey && draftMetadataForKey.metadata, env.storePublish);
6440
- return;
6447
+ // deletes the draft metadata once it is published and has 0 ref.
6448
+ if (draftMetadataForKey &&
6449
+ draftMetadataForKey.metadata &&
6450
+ draftMetadataForKey.refCount === 0) {
6451
+ delete draftMetadata[key];
6452
+ }
6453
+ break;
6441
6454
  }
6442
6455
  }
6456
+ decrementRefCount(key);
6457
+ // no handler could handle it so publish
6458
+ if (!handled) {
6459
+ env.storePublish(key, data);
6460
+ }
6461
+ };
6462
+ const decrementRefCount = function (key) {
6463
+ const draftMetadataForKey = draftMetadata[key];
6443
6464
  if (draftMetadataForKey !== undefined) {
6444
- // WARNING: this code depends on the fact that RecordRepresentation
6445
- // fields get published before the root record.
6465
+ // metadata is needed for a once-draft record to create ref link for spanning fields.
6446
6466
  if (draftMetadataForKey.refCount === 1) {
6447
- delete draftMetadata[key];
6448
- }
6449
- else {
6450
- draftMetadataForKey.refCount--;
6467
+ draftMetadata[key].metadata.recordOperations = [];
6451
6468
  }
6469
+ draftMetadataForKey.refCount--;
6452
6470
  }
6453
- // no handler could handle it so publish
6454
- env.storePublish(key, data);
6471
+ };
6472
+ // when a record is soft deleted it won't be published so won't decrement the ref count
6473
+ // this is a backdoor to decrement the ref count
6474
+ const softEvict = function (key) {
6475
+ decrementRefCount(key);
6455
6476
  };
6456
6477
  // note the makeEnvironmentUiApiRecordDraftAware will eventually go away once the adapters become draft aware
6457
6478
  return create$4(env, {
6458
6479
  storePublish: { value: storePublish },
6459
6480
  handleSuccessResponse: { value: handleSuccessResponse },
6481
+ softEvict: { value: softEvict },
6460
6482
  });
6461
6483
  }
6462
6484
 
@@ -11193,23 +11215,35 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11193
11215
  // update last modified date to draft action time and
11194
11216
  // last modified to user id
11195
11217
  const lastModifiedDate = new Date(draftOperation.timestamp).toISOString();
11196
- record.lastModifiedById = userId;
11197
- record.lastModifiedDate = lastModifiedDate;
11198
- record.fields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] = { value: userId, displayValue: null };
11199
- record.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE] = {
11200
- value: lastModifiedDate,
11201
- displayValue: lastModifiedDate,
11202
- };
11218
+ const internalTrackableFields = {};
11219
+ if (record.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE] === undefined && record.lastModifiedDate) {
11220
+ internalTrackableFields[DEFAULT_FIELD_LAST_MODIFIED_DATE] = {
11221
+ value: record.lastModifiedDate,
11222
+ displayValue: formatDisplayValue(record.lastModifiedDate, 'DateTime'),
11223
+ };
11224
+ }
11225
+ if (record.fields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] === undefined && record.lastModifiedById) {
11226
+ internalTrackableFields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] = {
11227
+ value: record.lastModifiedById,
11228
+ displayValue: null,
11229
+ };
11230
+ }
11203
11231
  if (draftActionType === 'delete') {
11204
11232
  if (recordOperations.length > 0) {
11205
11233
  throw Error('cannot contain drafts after a terminal delete');
11206
11234
  }
11207
11235
  record.drafts.deleted = true;
11208
- return record;
11209
11236
  }
11210
- const fields = draftOperation.fields;
11237
+ // 'lastModifiedById' and 'lastModifiedDate' are modified in 'delete' and 'update' action
11238
+ const fields = draftActionType === 'delete' ? {} : draftOperation.fields;
11211
11239
  const apiName = draftOperation.apiName;
11212
- const draftFields = buildRecordFieldValueRepresentationsFromDraftFields(luvio, apiName, fields, objectInfos, referencedRecords, formatDisplayValue);
11240
+ // automaticlly add 'lastModifiedById' and 'lastModifiedByDate' and use an internal draft field copy since it is mutable
11241
+ const internalFields = {
11242
+ ...fields,
11243
+ LastModifiedById: userId,
11244
+ LastModifiedDate: lastModifiedDate,
11245
+ };
11246
+ const draftFields = buildRecordFieldValueRepresentationsFromDraftFields(luvio, apiName, internalFields, objectInfos, referencedRecords, formatDisplayValue);
11213
11247
  const fieldNames = keys$2(draftFields);
11214
11248
  for (let i = 0, len = fieldNames.length; i < len; i++) {
11215
11249
  const fieldName = fieldNames[i];
@@ -11226,7 +11260,11 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11226
11260
  };
11227
11261
  }
11228
11262
  else {
11229
- record.drafts.serverValues[fieldName] = record.fields[fieldName];
11263
+ if (record.fields[fieldName] !== undefined ||
11264
+ internalTrackableFields[fieldName] !== undefined) {
11265
+ record.drafts.serverValues[fieldName] = (record.fields[fieldName] ||
11266
+ internalTrackableFields[fieldName]);
11267
+ }
11230
11268
  }
11231
11269
  }
11232
11270
  // a change to the record type is reflected in the fields and the root,
@@ -11239,9 +11277,18 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11239
11277
  record.recordTypeInfo = objectInfo.recordTypeInfos[updatedRecordTypeId];
11240
11278
  }
11241
11279
  }
11280
+ if (fieldName === DEFAULT_FIELD_LAST_MODIFIED_BY_ID) {
11281
+ record.lastModifiedById = userId;
11282
+ }
11283
+ if (fieldName === DEFAULT_FIELD_LAST_MODIFIED_DATE) {
11284
+ record.lastModifiedDate = lastModifiedDate;
11285
+ }
11286
+ // extra fields might be added into records, which is necessary for the spanning field link generation when record is ingested.
11242
11287
  record.fields[fieldName] = draftFields[fieldName];
11243
11288
  }
11244
- record.drafts.edited = true;
11289
+ if (draftActionType === 'update') {
11290
+ record.drafts.edited = true;
11291
+ }
11245
11292
  return recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations);
11246
11293
  }
11247
11294
  /**
@@ -11284,21 +11331,18 @@ function removeDrafts(record, luvio, objectInfo) {
11284
11331
  updatedFields[fieldName] = field;
11285
11332
  }
11286
11333
  }
11287
- // W-11677795 we don't currently persist lastModified* top level properties, these need to be persisted
11288
- // to restore them when a draft is removed. To work around this for now, we have to change the last modified
11289
- // time slightly to trigger a change in the record so it gets republished after a draft is removed
11290
- const serverLastModifiedById = record.lastModifiedById;
11291
- let serverLastModifiedDate;
11292
- if (record.lastModifiedDate === null) {
11293
- serverLastModifiedDate = null;
11334
+ // restore lastModifiedById
11335
+ const serverLastModifiedByIdFieldValue = drafts.serverValues[DEFAULT_FIELD_LAST_MODIFIED_BY_ID];
11336
+ if (serverLastModifiedByIdFieldValue !== undefined) {
11337
+ record.lastModifiedById = serverLastModifiedByIdFieldValue.value;
11294
11338
  }
11295
- else {
11296
- serverLastModifiedDate = new Date(Date.parse(record.lastModifiedDate) - 1).toISOString();
11339
+ // restore lastModifiedDate
11340
+ const serverLastModifiedDateFieldValue = drafts.serverValues[DEFAULT_FIELD_LAST_MODIFIED_DATE];
11341
+ if (serverLastModifiedDateFieldValue !== undefined) {
11342
+ record.lastModifiedDate = serverLastModifiedDateFieldValue.value;
11297
11343
  }
11298
11344
  return {
11299
11345
  ...record,
11300
- lastModifiedById: serverLastModifiedById,
11301
- lastModifiedDate: serverLastModifiedDate,
11302
11346
  drafts: undefined,
11303
11347
  fields: updatedFields,
11304
11348
  };
@@ -11737,6 +11781,8 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
11737
11781
  ...recordWithSpanningRefLinks,
11738
11782
  ...data,
11739
11783
  fields: { ...data.fields },
11784
+ lastModifiedDate: recordWithDrafts.lastModifiedDate,
11785
+ lastModifiedById: recordWithDrafts.lastModifiedById,
11740
11786
  };
11741
11787
  for (const fieldName of keys$2(recordWithSpanningRefLinks.fields)) {
11742
11788
  const fieldKey = buildRecordFieldStoreKey(key, fieldName);
@@ -16172,4 +16218,4 @@ register({
16172
16218
  });
16173
16219
 
16174
16220
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
16175
- // version: 1.171.0-2b2365b14
16221
+ // version: 1.171.1-73b444bbc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-mobile",
3
- "version": "1.171.0",
3
+ "version": "1.171.1",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS runtime for mobile/hybrid environments.",
6
6
  "main": "dist/main.js",
package/sfdc/main.js CHANGED
@@ -4978,9 +4978,14 @@ function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromC
4978
4978
  if (options.forDeleteAdapter === true) {
4979
4979
  // delete adapters attempt to evict the record on successful network response,
4980
4980
  // since draft-aware delete adapters do soft-delete (record stays in cache
4981
- // with a "drafts.deleted" property) we want storeEvict to just be a no-op
4982
- const storeEvict = function (_key) {
4983
- // no-op
4981
+ // with a "drafts.deleted" property) we just want to let the environment know so it can
4982
+ // decrement its ref count for the record
4983
+ const storeEvict = function (key) {
4984
+ const softEvict = luvio.environment.softEvict;
4985
+ if (softEvict === undefined) {
4986
+ throw Error('DraftAwareEnvironment not configured correctly');
4987
+ }
4988
+ softEvict(key);
4984
4989
  };
4985
4990
  return create$4(luvio, {
4986
4991
  dispatchResourceRequest: { value: dispatchResourceRequest },
@@ -6434,29 +6439,46 @@ function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueu
6434
6439
  };
6435
6440
  const storePublish = function (key, data) {
6436
6441
  const draftMetadataForKey = draftMetadata[key];
6442
+ let handled = false;
6437
6443
  for (const handler of handlers) {
6438
6444
  if (handler.canHandlePublish(key)) {
6445
+ handled = true;
6439
6446
  handler.applyDraftsToIncomingData(key, data, draftMetadataForKey && draftMetadataForKey.metadata, env.storePublish);
6440
- return;
6447
+ // deletes the draft metadata once it is published and has 0 ref.
6448
+ if (draftMetadataForKey &&
6449
+ draftMetadataForKey.metadata &&
6450
+ draftMetadataForKey.refCount === 0) {
6451
+ delete draftMetadata[key];
6452
+ }
6453
+ break;
6441
6454
  }
6442
6455
  }
6456
+ decrementRefCount(key);
6457
+ // no handler could handle it so publish
6458
+ if (!handled) {
6459
+ env.storePublish(key, data);
6460
+ }
6461
+ };
6462
+ const decrementRefCount = function (key) {
6463
+ const draftMetadataForKey = draftMetadata[key];
6443
6464
  if (draftMetadataForKey !== undefined) {
6444
- // WARNING: this code depends on the fact that RecordRepresentation
6445
- // fields get published before the root record.
6465
+ // metadata is needed for a once-draft record to create ref link for spanning fields.
6446
6466
  if (draftMetadataForKey.refCount === 1) {
6447
- delete draftMetadata[key];
6448
- }
6449
- else {
6450
- draftMetadataForKey.refCount--;
6467
+ draftMetadata[key].metadata.recordOperations = [];
6451
6468
  }
6469
+ draftMetadataForKey.refCount--;
6452
6470
  }
6453
- // no handler could handle it so publish
6454
- env.storePublish(key, data);
6471
+ };
6472
+ // when a record is soft deleted it won't be published so won't decrement the ref count
6473
+ // this is a backdoor to decrement the ref count
6474
+ const softEvict = function (key) {
6475
+ decrementRefCount(key);
6455
6476
  };
6456
6477
  // note the makeEnvironmentUiApiRecordDraftAware will eventually go away once the adapters become draft aware
6457
6478
  return create$4(env, {
6458
6479
  storePublish: { value: storePublish },
6459
6480
  handleSuccessResponse: { value: handleSuccessResponse },
6481
+ softEvict: { value: softEvict },
6460
6482
  });
6461
6483
  }
6462
6484
 
@@ -11193,23 +11215,35 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11193
11215
  // update last modified date to draft action time and
11194
11216
  // last modified to user id
11195
11217
  const lastModifiedDate = new Date(draftOperation.timestamp).toISOString();
11196
- record.lastModifiedById = userId;
11197
- record.lastModifiedDate = lastModifiedDate;
11198
- record.fields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] = { value: userId, displayValue: null };
11199
- record.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE] = {
11200
- value: lastModifiedDate,
11201
- displayValue: lastModifiedDate,
11202
- };
11218
+ const internalTrackableFields = {};
11219
+ if (record.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE] === undefined && record.lastModifiedDate) {
11220
+ internalTrackableFields[DEFAULT_FIELD_LAST_MODIFIED_DATE] = {
11221
+ value: record.lastModifiedDate,
11222
+ displayValue: formatDisplayValue(record.lastModifiedDate, 'DateTime'),
11223
+ };
11224
+ }
11225
+ if (record.fields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] === undefined && record.lastModifiedById) {
11226
+ internalTrackableFields[DEFAULT_FIELD_LAST_MODIFIED_BY_ID] = {
11227
+ value: record.lastModifiedById,
11228
+ displayValue: null,
11229
+ };
11230
+ }
11203
11231
  if (draftActionType === 'delete') {
11204
11232
  if (recordOperations.length > 0) {
11205
11233
  throw Error('cannot contain drafts after a terminal delete');
11206
11234
  }
11207
11235
  record.drafts.deleted = true;
11208
- return record;
11209
11236
  }
11210
- const fields = draftOperation.fields;
11237
+ // 'lastModifiedById' and 'lastModifiedDate' are modified in 'delete' and 'update' action
11238
+ const fields = draftActionType === 'delete' ? {} : draftOperation.fields;
11211
11239
  const apiName = draftOperation.apiName;
11212
- const draftFields = buildRecordFieldValueRepresentationsFromDraftFields(luvio, apiName, fields, objectInfos, referencedRecords, formatDisplayValue);
11240
+ // automaticlly add 'lastModifiedById' and 'lastModifiedByDate' and use an internal draft field copy since it is mutable
11241
+ const internalFields = {
11242
+ ...fields,
11243
+ LastModifiedById: userId,
11244
+ LastModifiedDate: lastModifiedDate,
11245
+ };
11246
+ const draftFields = buildRecordFieldValueRepresentationsFromDraftFields(luvio, apiName, internalFields, objectInfos, referencedRecords, formatDisplayValue);
11213
11247
  const fieldNames = keys$2(draftFields);
11214
11248
  for (let i = 0, len = fieldNames.length; i < len; i++) {
11215
11249
  const fieldName = fieldNames[i];
@@ -11226,7 +11260,11 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11226
11260
  };
11227
11261
  }
11228
11262
  else {
11229
- record.drafts.serverValues[fieldName] = record.fields[fieldName];
11263
+ if (record.fields[fieldName] !== undefined ||
11264
+ internalTrackableFields[fieldName] !== undefined) {
11265
+ record.drafts.serverValues[fieldName] = (record.fields[fieldName] ||
11266
+ internalTrackableFields[fieldName]);
11267
+ }
11230
11268
  }
11231
11269
  }
11232
11270
  // a change to the record type is reflected in the fields and the root,
@@ -11239,9 +11277,18 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
11239
11277
  record.recordTypeInfo = objectInfo.recordTypeInfos[updatedRecordTypeId];
11240
11278
  }
11241
11279
  }
11280
+ if (fieldName === DEFAULT_FIELD_LAST_MODIFIED_BY_ID) {
11281
+ record.lastModifiedById = userId;
11282
+ }
11283
+ if (fieldName === DEFAULT_FIELD_LAST_MODIFIED_DATE) {
11284
+ record.lastModifiedDate = lastModifiedDate;
11285
+ }
11286
+ // extra fields might be added into records, which is necessary for the spanning field link generation when record is ingested.
11242
11287
  record.fields[fieldName] = draftFields[fieldName];
11243
11288
  }
11244
- record.drafts.edited = true;
11289
+ if (draftActionType === 'update') {
11290
+ record.drafts.edited = true;
11291
+ }
11245
11292
  return recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations);
11246
11293
  }
11247
11294
  /**
@@ -11284,21 +11331,18 @@ function removeDrafts(record, luvio, objectInfo) {
11284
11331
  updatedFields[fieldName] = field;
11285
11332
  }
11286
11333
  }
11287
- // W-11677795 we don't currently persist lastModified* top level properties, these need to be persisted
11288
- // to restore them when a draft is removed. To work around this for now, we have to change the last modified
11289
- // time slightly to trigger a change in the record so it gets republished after a draft is removed
11290
- const serverLastModifiedById = record.lastModifiedById;
11291
- let serverLastModifiedDate;
11292
- if (record.lastModifiedDate === null) {
11293
- serverLastModifiedDate = null;
11334
+ // restore lastModifiedById
11335
+ const serverLastModifiedByIdFieldValue = drafts.serverValues[DEFAULT_FIELD_LAST_MODIFIED_BY_ID];
11336
+ if (serverLastModifiedByIdFieldValue !== undefined) {
11337
+ record.lastModifiedById = serverLastModifiedByIdFieldValue.value;
11294
11338
  }
11295
- else {
11296
- serverLastModifiedDate = new Date(Date.parse(record.lastModifiedDate) - 1).toISOString();
11339
+ // restore lastModifiedDate
11340
+ const serverLastModifiedDateFieldValue = drafts.serverValues[DEFAULT_FIELD_LAST_MODIFIED_DATE];
11341
+ if (serverLastModifiedDateFieldValue !== undefined) {
11342
+ record.lastModifiedDate = serverLastModifiedDateFieldValue.value;
11297
11343
  }
11298
11344
  return {
11299
11345
  ...record,
11300
- lastModifiedById: serverLastModifiedById,
11301
- lastModifiedDate: serverLastModifiedDate,
11302
11346
  drafts: undefined,
11303
11347
  fields: updatedFields,
11304
11348
  };
@@ -11737,6 +11781,8 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
11737
11781
  ...recordWithSpanningRefLinks,
11738
11782
  ...data,
11739
11783
  fields: { ...data.fields },
11784
+ lastModifiedDate: recordWithDrafts.lastModifiedDate,
11785
+ lastModifiedById: recordWithDrafts.lastModifiedById,
11740
11786
  };
11741
11787
  for (const fieldName of keys$2(recordWithSpanningRefLinks.fields)) {
11742
11788
  const fieldKey = buildRecordFieldStoreKey(key, fieldName);
@@ -16172,4 +16218,4 @@ register({
16172
16218
  });
16173
16219
 
16174
16220
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
16175
- // version: 1.171.0-2b2365b14
16221
+ // version: 1.171.1-73b444bbc