@salesforce/lds-runtime-mobile 1.121.0 → 1.122.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.
Files changed (3) hide show
  1. package/dist/main.js +40 -25
  2. package/package.json +1 -1
  3. package/sfdc/main.js +40 -25
package/dist/main.js CHANGED
@@ -6365,7 +6365,7 @@ function recordLoaderFactory(query) {
6365
6365
  return new DataLoader(batchRecordQuery);
6366
6366
  }
6367
6367
 
6368
- function createContext(store, objectInfos, eventEmitter, settings, snapshot) {
6368
+ function createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions) {
6369
6369
  store.query.bind(store);
6370
6370
  const query = (sql, params) => {
6371
6371
  const now = Date.now();
@@ -6392,6 +6392,7 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot) {
6392
6392
  Record,
6393
6393
  snapshot,
6394
6394
  seenRecordIds: new Set(),
6395
+ draftFunctions,
6395
6396
  };
6396
6397
  }
6397
6398
 
@@ -6777,7 +6778,7 @@ function dateTimeRange(input, op, field, alias) {
6777
6778
  }
6778
6779
 
6779
6780
  const MultiPickListValueSeparator = ';';
6780
- function filterToPredicates(where, recordType, alias, objectInfoMap, joins) {
6781
+ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
6781
6782
  if (!where)
6782
6783
  return [];
6783
6784
  let predicates = [];
@@ -6859,38 +6860,52 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins) {
6859
6860
  }
6860
6861
  }
6861
6862
  else {
6863
+ //`field` match the filedInfo's apiName
6862
6864
  for (const [op, value] of entries$2(where[field])) {
6863
6865
  const operator = operatorToSql(op);
6864
- const fieldInfo = objectInfoMap[recordType].fields[field];
6865
- const coerceIdNeeded = isCoerceIdNeeded(fieldInfo, field, op);
6866
+ /**
6867
+ Two types ID processing might be needed. Draft ID swapping is optional, which depends on DraftFunctions existence.
6868
+ 1. Coercing is needed when query is executed against local db if field is Id field of entity or a reference to an entity. It is OK to use 15 char ID to query agaist server,
6869
+ so there is no need to coerce the ID in injected AST which is used by luvio to do the network request when necessary.
6870
+ 2. Draft ID swapping is needed when adapter rebuild is triggered. Draft ID swapping also happens in field injection phase when adapter call is invoked. The injected AST node has
6871
+ the canonical ID and is passed to Luvio
6872
+ */
6873
+ const idProcessingNeeded = isIDValueField(fieldInfo);
6866
6874
  const makePredicate = fieldInfo.dataType === 'MultiPicklist'
6867
6875
  ? createMultiPicklistPredicate
6868
6876
  : createSinglePredicate;
6869
- predicates.push(makePredicate(coerceIdNeeded ? generateCoercedPredicateValue(value) : value, operator, fieldInfo, alias));
6877
+ predicates.push(makePredicate(idProcessingNeeded
6878
+ ? sanitizePredicateIDValue(value, draftFunctions)
6879
+ : value, operator, fieldInfo, alias));
6870
6880
  }
6871
6881
  }
6872
6882
  }
6873
6883
  return predicates;
6874
6884
  }
6875
6885
  /**
6876
- * Coercing is needed when query is executed against local db if field is Id field of entity or a reference to an entity. It is OK to use 15 char ID to query agaist server,
6877
- * so there is no need to coerce the ID in injected AST which is used by luvio to do the network request when necessary.
6886
+ *
6878
6887
  * @param fieldInfo
6879
- * @param fieldName
6880
- * @returns true if coerce is needed
6888
+ * @returns true if field is of IDValue type
6881
6889
  */
6882
- function isCoerceIdNeeded(fieldInfo, fieldName, op) {
6883
- return ((fieldName === 'Id' ||
6884
- (fieldInfo.apiName === fieldName && fieldInfo.referenceToInfos.length > 0)) &&
6885
- (op === 'eq' || op === 'ne' || op === 'in' || op === 'nin'));
6890
+ function isIDValueField(fieldInfo) {
6891
+ return fieldInfo.apiName === 'Id' || fieldInfo.referenceToInfos.length > 0;
6886
6892
  }
6887
- function generateCoercedPredicateValue(value) {
6893
+ /**
6894
+ * Coerces and swaps ID if it is a draft ID.
6895
+ * @param value Predicate value which might be a string value like 'John' or a List like ['Acme', 'John']
6896
+ * @param draftFunction optional. If undefined, draft ID swapping does not happen
6897
+ * @returns sanitized previdicate value
6898
+ */
6899
+ function sanitizePredicateIDValue(value, draftFunction) {
6888
6900
  if (isArray$2(value)) {
6889
- return value.map(generateCoercedPredicateValue);
6901
+ return value.map((singleValue) => sanitizePredicateIDValue(singleValue, draftFunction));
6890
6902
  }
6891
6903
  else {
6892
6904
  const coercedId = getRecordId18(value);
6893
6905
  if (coercedId !== undefined) {
6906
+ if (draftFunction !== undefined && draftFunction.isDraftId(coercedId)) {
6907
+ return draftFunction.getCanonicalId(coercedId);
6908
+ }
6894
6909
  return coercedId;
6895
6910
  }
6896
6911
  return value;
@@ -8306,7 +8321,7 @@ function addResolversToSchema(schema, polyFields) {
8306
8321
  }
8307
8322
  async function connectionEdgeResolver(obj, _args, context) {
8308
8323
  const { parentArgs = {}, parentRecord, currentFieldName } = obj;
8309
- const { query, objectInfos } = context;
8324
+ const { query, objectInfos, draftFunctions } = context;
8310
8325
  let joins = [];
8311
8326
  let alias = currentFieldName;
8312
8327
  let childRelationshipFieldName = undefined;
@@ -8323,7 +8338,7 @@ async function connectionEdgeResolver(obj, _args, context) {
8323
8338
  }
8324
8339
  // Alias starts as entity's ApiName
8325
8340
  const predicates = [
8326
- ...filterToPredicates(parentArgs.where, alias, alias, context.objectInfos, joins),
8341
+ ...filterToPredicates(parentArgs.where, alias, alias, context.objectInfos, joins, draftFunctions),
8327
8342
  ...scopeToPredicates(parentArgs.scope, context.settings),
8328
8343
  ...childRelationshipToPredicates(childRelationshipFieldName, parentRecord.id),
8329
8344
  ];
@@ -8885,7 +8900,7 @@ function createSchema(objectInfos) {
8885
8900
  return addResolversToSchema(schema, polyFieldTypeNames);
8886
8901
  }
8887
8902
 
8888
- async function evaluate(config, observers, settings, objectInfos, store, snapshot) {
8903
+ async function evaluate(config, observers, settings, objectInfos, store, snapshot, draftFunctions) {
8889
8904
  const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, observers);
8890
8905
  // this is only wrapped in a try to execute the event after the result was returned
8891
8906
  try {
@@ -8918,7 +8933,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
8918
8933
  eventEmitter({ type: 'graphql-preconditions-met' });
8919
8934
  // create the resolver request context, runtime values and functions for
8920
8935
  // resolvers to do their job.
8921
- const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot);
8936
+ const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions);
8922
8937
  // We're building this from scratch from each request. If this becomes a
8923
8938
  // hotspot we can pull it up and memoize it later
8924
8939
  const schema = createSchema(objectInfos);
@@ -12244,11 +12259,11 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
12244
12259
  let internalRequestContext = {
12245
12260
  ...requestContext,
12246
12261
  };
12262
+ const draftFunctions = {
12263
+ isDraftId,
12264
+ getCanonicalId,
12265
+ };
12247
12266
  try {
12248
- const draftFunctions = {
12249
- isDraftId,
12250
- getCanonicalId,
12251
- };
12252
12267
  ({
12253
12268
  modifiedAST: injectedAST,
12254
12269
  objectInfos: objectInfoNeeded,
@@ -12331,7 +12346,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
12331
12346
  let { result: rebuildResult, seenRecordIds } = await evaluate({
12332
12347
  ...config,
12333
12348
  query: injectedAST,
12334
- }, observers, { userId }, objectInfoNeeded, store, originalSnapshot);
12349
+ }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, draftFunctions);
12335
12350
  if (!rebuildResult.errors) {
12336
12351
  rebuildResult = removeSyntheticFields(rebuildResult, config.query);
12337
12352
  }
@@ -15629,4 +15644,4 @@ register({
15629
15644
  });
15630
15645
 
15631
15646
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
15632
- // version: 1.121.0-f722acdeb
15647
+ // version: 1.122.0-aa6cc75e0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-mobile",
3
- "version": "1.121.0",
3
+ "version": "1.122.0",
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
@@ -6365,7 +6365,7 @@ function recordLoaderFactory(query) {
6365
6365
  return new DataLoader(batchRecordQuery);
6366
6366
  }
6367
6367
 
6368
- function createContext(store, objectInfos, eventEmitter, settings, snapshot) {
6368
+ function createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions) {
6369
6369
  store.query.bind(store);
6370
6370
  const query = (sql, params) => {
6371
6371
  const now = Date.now();
@@ -6392,6 +6392,7 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot) {
6392
6392
  Record,
6393
6393
  snapshot,
6394
6394
  seenRecordIds: new Set(),
6395
+ draftFunctions,
6395
6396
  };
6396
6397
  }
6397
6398
 
@@ -6777,7 +6778,7 @@ function dateTimeRange(input, op, field, alias) {
6777
6778
  }
6778
6779
 
6779
6780
  const MultiPickListValueSeparator = ';';
6780
- function filterToPredicates(where, recordType, alias, objectInfoMap, joins) {
6781
+ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
6781
6782
  if (!where)
6782
6783
  return [];
6783
6784
  let predicates = [];
@@ -6859,38 +6860,52 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins) {
6859
6860
  }
6860
6861
  }
6861
6862
  else {
6863
+ //`field` match the filedInfo's apiName
6862
6864
  for (const [op, value] of entries$2(where[field])) {
6863
6865
  const operator = operatorToSql(op);
6864
- const fieldInfo = objectInfoMap[recordType].fields[field];
6865
- const coerceIdNeeded = isCoerceIdNeeded(fieldInfo, field, op);
6866
+ /**
6867
+ Two types ID processing might be needed. Draft ID swapping is optional, which depends on DraftFunctions existence.
6868
+ 1. Coercing is needed when query is executed against local db if field is Id field of entity or a reference to an entity. It is OK to use 15 char ID to query agaist server,
6869
+ so there is no need to coerce the ID in injected AST which is used by luvio to do the network request when necessary.
6870
+ 2. Draft ID swapping is needed when adapter rebuild is triggered. Draft ID swapping also happens in field injection phase when adapter call is invoked. The injected AST node has
6871
+ the canonical ID and is passed to Luvio
6872
+ */
6873
+ const idProcessingNeeded = isIDValueField(fieldInfo);
6866
6874
  const makePredicate = fieldInfo.dataType === 'MultiPicklist'
6867
6875
  ? createMultiPicklistPredicate
6868
6876
  : createSinglePredicate;
6869
- predicates.push(makePredicate(coerceIdNeeded ? generateCoercedPredicateValue(value) : value, operator, fieldInfo, alias));
6877
+ predicates.push(makePredicate(idProcessingNeeded
6878
+ ? sanitizePredicateIDValue(value, draftFunctions)
6879
+ : value, operator, fieldInfo, alias));
6870
6880
  }
6871
6881
  }
6872
6882
  }
6873
6883
  return predicates;
6874
6884
  }
6875
6885
  /**
6876
- * Coercing is needed when query is executed against local db if field is Id field of entity or a reference to an entity. It is OK to use 15 char ID to query agaist server,
6877
- * so there is no need to coerce the ID in injected AST which is used by luvio to do the network request when necessary.
6886
+ *
6878
6887
  * @param fieldInfo
6879
- * @param fieldName
6880
- * @returns true if coerce is needed
6888
+ * @returns true if field is of IDValue type
6881
6889
  */
6882
- function isCoerceIdNeeded(fieldInfo, fieldName, op) {
6883
- return ((fieldName === 'Id' ||
6884
- (fieldInfo.apiName === fieldName && fieldInfo.referenceToInfos.length > 0)) &&
6885
- (op === 'eq' || op === 'ne' || op === 'in' || op === 'nin'));
6890
+ function isIDValueField(fieldInfo) {
6891
+ return fieldInfo.apiName === 'Id' || fieldInfo.referenceToInfos.length > 0;
6886
6892
  }
6887
- function generateCoercedPredicateValue(value) {
6893
+ /**
6894
+ * Coerces and swaps ID if it is a draft ID.
6895
+ * @param value Predicate value which might be a string value like 'John' or a List like ['Acme', 'John']
6896
+ * @param draftFunction optional. If undefined, draft ID swapping does not happen
6897
+ * @returns sanitized previdicate value
6898
+ */
6899
+ function sanitizePredicateIDValue(value, draftFunction) {
6888
6900
  if (isArray$2(value)) {
6889
- return value.map(generateCoercedPredicateValue);
6901
+ return value.map((singleValue) => sanitizePredicateIDValue(singleValue, draftFunction));
6890
6902
  }
6891
6903
  else {
6892
6904
  const coercedId = getRecordId18(value);
6893
6905
  if (coercedId !== undefined) {
6906
+ if (draftFunction !== undefined && draftFunction.isDraftId(coercedId)) {
6907
+ return draftFunction.getCanonicalId(coercedId);
6908
+ }
6894
6909
  return coercedId;
6895
6910
  }
6896
6911
  return value;
@@ -8306,7 +8321,7 @@ function addResolversToSchema(schema, polyFields) {
8306
8321
  }
8307
8322
  async function connectionEdgeResolver(obj, _args, context) {
8308
8323
  const { parentArgs = {}, parentRecord, currentFieldName } = obj;
8309
- const { query, objectInfos } = context;
8324
+ const { query, objectInfos, draftFunctions } = context;
8310
8325
  let joins = [];
8311
8326
  let alias = currentFieldName;
8312
8327
  let childRelationshipFieldName = undefined;
@@ -8323,7 +8338,7 @@ async function connectionEdgeResolver(obj, _args, context) {
8323
8338
  }
8324
8339
  // Alias starts as entity's ApiName
8325
8340
  const predicates = [
8326
- ...filterToPredicates(parentArgs.where, alias, alias, context.objectInfos, joins),
8341
+ ...filterToPredicates(parentArgs.where, alias, alias, context.objectInfos, joins, draftFunctions),
8327
8342
  ...scopeToPredicates(parentArgs.scope, context.settings),
8328
8343
  ...childRelationshipToPredicates(childRelationshipFieldName, parentRecord.id),
8329
8344
  ];
@@ -8885,7 +8900,7 @@ function createSchema(objectInfos) {
8885
8900
  return addResolversToSchema(schema, polyFieldTypeNames);
8886
8901
  }
8887
8902
 
8888
- async function evaluate(config, observers, settings, objectInfos, store, snapshot) {
8903
+ async function evaluate(config, observers, settings, objectInfos, store, snapshot, draftFunctions) {
8889
8904
  const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, observers);
8890
8905
  // this is only wrapped in a try to execute the event after the result was returned
8891
8906
  try {
@@ -8918,7 +8933,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
8918
8933
  eventEmitter({ type: 'graphql-preconditions-met' });
8919
8934
  // create the resolver request context, runtime values and functions for
8920
8935
  // resolvers to do their job.
8921
- const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot);
8936
+ const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions);
8922
8937
  // We're building this from scratch from each request. If this becomes a
8923
8938
  // hotspot we can pull it up and memoize it later
8924
8939
  const schema = createSchema(objectInfos);
@@ -12244,11 +12259,11 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
12244
12259
  let internalRequestContext = {
12245
12260
  ...requestContext,
12246
12261
  };
12262
+ const draftFunctions = {
12263
+ isDraftId,
12264
+ getCanonicalId,
12265
+ };
12247
12266
  try {
12248
- const draftFunctions = {
12249
- isDraftId,
12250
- getCanonicalId,
12251
- };
12252
12267
  ({
12253
12268
  modifiedAST: injectedAST,
12254
12269
  objectInfos: objectInfoNeeded,
@@ -12331,7 +12346,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
12331
12346
  let { result: rebuildResult, seenRecordIds } = await evaluate({
12332
12347
  ...config,
12333
12348
  query: injectedAST,
12334
- }, observers, { userId }, objectInfoNeeded, store, originalSnapshot);
12349
+ }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, draftFunctions);
12335
12350
  if (!rebuildResult.errors) {
12336
12351
  rebuildResult = removeSyntheticFields(rebuildResult, config.query);
12337
12352
  }
@@ -15629,4 +15644,4 @@ register({
15629
15644
  });
15630
15645
 
15631
15646
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
15632
- // version: 1.121.0-f722acdeb
15647
+ // version: 1.122.0-aa6cc75e0