@salesforce/lds-adapters-uiapi 1.229.0-dev1 → 1.229.0-dev10

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.
@@ -12,7 +12,7 @@ declare const assign: {
12
12
  [idx: string]: object | U | null | undefined;
13
13
  }, U extends string | number | bigint | boolean | symbol>(o: T_1): Readonly<T_1>;
14
14
  <T_2>(o: T_2): Readonly<T_2>;
15
- }, keys: {
15
+ }, isFrozen: (o: any) => boolean, keys: {
16
16
  (o: object): string[];
17
17
  (o: {}): string[];
18
18
  };
@@ -39,4 +39,4 @@ declare const parse: (text: string, reviver?: ((this: any, key: string, value: a
39
39
  (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
40
40
  (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
41
41
  };
42
- export { assign as ObjectAssign, create as ObjectCreate, freeze as ObjectFreeze, keys as ObjectKeys, hasOwnProperty as ObjectPrototypeHasOwnProperty, isArray as ArrayIsArray, concat as ArrayPrototypeConcat, filter as ArrayPrototypeFilter, includes as ArrayPrototypeIncludes, push as ArrayPrototypePush, reduce as ArrayPrototypeReduce, split as StringPrototypeSplit, endsWith as StringPrototypeEndsWith, parse as JSONParse, stringify as JSONStringify, };
42
+ export { assign as ObjectAssign, create as ObjectCreate, freeze as ObjectFreeze, isFrozen as ObjectIsFrozen, keys as ObjectKeys, hasOwnProperty as ObjectPrototypeHasOwnProperty, isArray as ArrayIsArray, concat as ArrayPrototypeConcat, filter as ArrayPrototypeFilter, includes as ArrayPrototypeIncludes, push as ArrayPrototypePush, reduce as ArrayPrototypeReduce, split as StringPrototypeSplit, endsWith as StringPrototypeEndsWith, parse as JSONParse, stringify as JSONStringify, };
@@ -1,4 +1,4 @@
1
- import type { ProxyGraphNode, GraphNode, Luvio, NormalizedKeyMetadata } from '@luvio/engine';
1
+ import type { ProxyGraphNode, GraphNode, NormalizedKeyMetadata, Luvio } from '@luvio/engine';
2
2
  import type { FieldValueRepresentation } from '../generated/types/FieldValueRepresentation';
3
3
  import type { RecordCreateDefaultRecordRepresentation } from '../generated/types/RecordCreateDefaultRecordRepresentation';
4
4
  import type { ObjectInfoRepresentation } from '../generated/types/ObjectInfoRepresentation';
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { register } from '@salesforce/lds-default-luvio';
8
- import { serializeStructuredKey, ingestShape, coerceConfig as coerceConfig$1, typeCheckConfig as typeCheckConfig$13, createResourceParams as createResourceParams$Z, StoreKeyMap, StoreKeySet, deepFreeze, buildNetworkSnapshotCachePolicy as buildNetworkSnapshotCachePolicy$R, coerceAdapterRequestContext, Wildcard } from '@luvio/engine';
8
+ import { serializeStructuredKey, ingestShape, coerceConfig as coerceConfig$1, typeCheckConfig as typeCheckConfig$13, createResourceParams as createResourceParams$Z, StoreKeyMap, StoreKeySet, deepFreeze, buildNetworkSnapshotCachePolicy as buildNetworkSnapshotCachePolicy$R, resolveLink, coerceAdapterRequestContext, Wildcard } from '@luvio/engine';
9
9
  import { print, visit, parse as parse$1 } from '@luvio/graphql-parser';
10
10
  import { getRequestedFieldsForType, buildFieldState, createFragmentMap, mergeSelectionSets, serializeFieldArguments, deepMerge, buildQueryTypeStringKey, getOperationFromDocument } from '@luvio/graphql';
11
11
 
@@ -355,7 +355,7 @@ function buildAdapterValidationConfig(displayName, paramsMeta) {
355
355
  }
356
356
  const keyPrefix = 'UiApi';
357
357
 
358
- const { assign, create, freeze, keys } = Object;
358
+ const { assign, create, freeze, isFrozen, keys } = Object;
359
359
  const { hasOwnProperty } = Object.prototype;
360
360
  const { split, endsWith } = String.prototype;
361
361
  const { isArray } = Array;
@@ -4239,7 +4239,7 @@ function extractTrackedFieldsToTrie(recordId, node, root, config, visitedRecordI
4239
4239
  extractTrackedFieldsToTrie(spanningLink.data.__ref, spanning, next, config, spanningVisitedRecordIds, depth + 1);
4240
4240
  // For a spanning record that is detected to be a circular reference, we add the field along with Id and Name.
4241
4241
  // It's possible for spanning record lookup fields to sometimes be circular, and sometimes not - depending on the value of the lookup field.
4242
- // For more information on scenarios that caused this fix: https://salesforce.quip.com/OvzNAh3eNIWY
4242
+ // For more information on scenarios that caused this fix: search "LDS Recursive Spanning Fields Problem" in Quip
4243
4243
  if (keys(next.children).length === 0) {
4244
4244
  addScalarFieldId(next);
4245
4245
  addScalarFieldName(next);
@@ -4574,7 +4574,11 @@ function markNulledOutPath(record, path) {
4574
4574
  }
4575
4575
  const link = fieldValueRepresentation.link(fieldName);
4576
4576
  const resolved = link.follow();
4577
- if (isGraphNode(resolved) && resolved.isScalar('value') && path.length > 0) {
4577
+ if (isGraphNode(resolved) &&
4578
+ resolved.isScalar('value') &&
4579
+ path.length > 0 &&
4580
+ // TODO [W-14082782]: temporary fix
4581
+ !isFrozen(link.data)) {
4578
4582
  const linkState = link.linkData();
4579
4583
  const fields = linkState === undefined ? [] : linkState.fields;
4580
4584
  link.writeLinkData({
@@ -4602,22 +4606,12 @@ function _markMissingPath(record, path) {
4602
4606
  const fieldValueRepresentation = record.object('fields');
4603
4607
  const fieldName = path.shift();
4604
4608
  if (fieldValueRepresentation.isUndefined(fieldName) === true) {
4605
- // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4606
- // an undefined/non-present __ref if isMissing is present
4607
- fieldValueRepresentation.write(fieldName, {
4608
- __ref: undefined,
4609
- isMissing: true,
4610
- });
4609
+ writeMissingFieldToStore(fieldValueRepresentation, fieldName);
4611
4610
  return;
4612
4611
  }
4613
4612
  const link = fieldValueRepresentation.link(fieldName);
4614
4613
  if (link.isPending()) {
4615
- // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4616
- // an undefined/non-present __ref if isMissing is present
4617
- fieldValueRepresentation.write(fieldName, {
4618
- __ref: undefined,
4619
- isMissing: true,
4620
- });
4614
+ writeMissingFieldToStore(fieldValueRepresentation, fieldName);
4621
4615
  }
4622
4616
  else if (path.length > 0 && link.isMissing() === false) {
4623
4617
  const fieldValue = link.follow();
@@ -4633,6 +4627,19 @@ function _markMissingPath(record, path) {
4633
4627
  }
4634
4628
  }
4635
4629
  }
4630
+ /**
4631
+ * Graph Node Directly modifies store entries, which is generally a non-starter.
4632
+ * Until we can refactor this mess, you need to use this function to safely mark the RecordRepresentation
4633
+ * as a seenId in the store when you perform this mutation.
4634
+ */
4635
+ function writeMissingFieldToStore(field, fieldName) {
4636
+ // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4637
+ // an undefined/non-present __ref if isMissing is present
4638
+ field.write(fieldName, {
4639
+ __ref: undefined,
4640
+ isMissing: true,
4641
+ });
4642
+ }
4636
4643
  /**
4637
4644
  * Tells you if an objectApiName is supported by UI API or not.
4638
4645
  * Note: Luvio does not currently support all the entities, the list is limited to UI API supported entities
@@ -4764,8 +4771,11 @@ function mergeAndRefreshLowerVersionRecord(luvio, incoming, existing, incomingTr
4764
4771
  return existing;
4765
4772
  }
4766
4773
  function mergeRecordConflict(luvio, incoming, existing, recordConflictMap) {
4767
- const incomingNode = luvio.wrapNormalizedGraphNode(incoming);
4768
- const existingNode = luvio.wrapNormalizedGraphNode(existing);
4774
+ const recordKey = keyBuilder$35(luvio, {
4775
+ recordId: incoming.id,
4776
+ });
4777
+ const incomingNode = luvio.wrapNormalizedGraphNode(incoming, recordKey);
4778
+ const existingNode = luvio.wrapNormalizedGraphNode(existing, recordKey);
4769
4779
  const incomingTrackedFieldsTrieRoot = {
4770
4780
  name: incoming.apiName,
4771
4781
  children: {},
@@ -4774,9 +4784,6 @@ function mergeRecordConflict(luvio, incoming, existing, recordConflictMap) {
4774
4784
  name: existing.apiName,
4775
4785
  children: {},
4776
4786
  };
4777
- const recordKey = keyBuilder$35(luvio, {
4778
- recordId: incoming.id,
4779
- });
4780
4787
  const trackedFieldsConfig = {
4781
4788
  maxDepth: configurationForRestAdapters.getTrackedFieldDepthOnCacheMergeConflict(),
4782
4789
  onlyFetchLeafNodeIdAndName: configurationForRestAdapters.getTrackedFieldLeafNodeIdAndNameOnly(),
@@ -11798,7 +11805,7 @@ function getLayoutMapAndObjectInfo(recordId, data) {
11798
11805
  // Temp fix until we can mimic the server behavior for non-layoutable entities.
11799
11806
  let layoutMap = {};
11800
11807
  if (hasOwnProperty.call(layouts, apiName)) {
11801
- layoutMap = layouts[apiName][recordTypeId];
11808
+ layoutMap = layouts[apiName][recordTypeId] || {};
11802
11809
  }
11803
11810
  return {
11804
11811
  layoutMap,
@@ -11980,18 +11987,28 @@ const buildLayoutModeCacheSnapshot = (apiName, recordTypeId, layoutType, mode) =
11980
11987
  * These are intermediate lookups to check if the record is in the L2 cache
11981
11988
  * @param {Luvio} luvio
11982
11989
  * @param {GetRecordLayoutTypeConfig} config
11983
- * @param {BuildCachedSnapshot<BuildSnapshotContext} cachedSnapshot
11990
+ * @param {BuildCachedSnapshot<BuildSnapshotContext>} cachedSnapshot
11984
11991
  */
11985
11992
  function makeCacheOnlySnapshot(luvio, config, adapterContext, cachedSnapshot) {
11986
- return luvio.applyCachePolicy({
11987
- cachePolicy: {
11988
- // only looking in the cache so we can check for L2 data offline
11989
- type: 'only-if-cached',
11990
- },
11991
- }, { config, luvio, adapterContext }, cachedSnapshot,
11992
- // this won't be invoked since we're requesting only-if-cached
11993
+ return luvio.applyCachePolicy(
11994
+ // Pass empty context so environment will use its default cache-policy
11995
+ {}, { config, luvio, adapterContext }, cachedSnapshot,
11996
+ // disallow hitting the network by returning a gateway timeout
11993
11997
  () => {
11994
- throw Error('buildNetworkSnapshot should not be called for only-if-cached policy');
11998
+ return new Promise((resolve) => {
11999
+ resolve({
12000
+ state: 'Error',
12001
+ data: undefined,
12002
+ error: {
12003
+ body: undefined,
12004
+ headers: {},
12005
+ ok: false,
12006
+ status: 504,
12007
+ statusText: 'Gateway Timeout',
12008
+ errorType: 'fetchResponse',
12009
+ },
12010
+ });
12011
+ });
11995
12012
  });
11996
12013
  }
11997
12014
  /**
@@ -12202,7 +12219,7 @@ const notifyChangeFactory = (luvio) => {
12202
12219
  const responsePromises = [];
12203
12220
  for (let i = 0, len = entries.length; i < len; i++) {
12204
12221
  const { key, record } = entries[i];
12205
- const node = luvio.wrapNormalizedGraphNode(record);
12222
+ const node = luvio.wrapNormalizedGraphNode(record, key);
12206
12223
  const optionalFields = getTrackedFields(key, node, {
12207
12224
  maxDepth: configurationForRestAdapters.getTrackedFieldDepthOnNotifyChange(),
12208
12225
  onlyFetchLeafNodeIdAndName: configurationForRestAdapters.getTrackedFieldLeafNodeIdAndNameOnly(),
@@ -43072,6 +43089,7 @@ function buildSelectionForField$7(source, reader, sel, variables, fragments, isC
43072
43089
  }
43073
43090
  if (fieldData === null) {
43074
43091
  reader.assignScalar(requestedFieldName, sink, fieldData);
43092
+ reader.exitPath();
43075
43093
  return sink;
43076
43094
  }
43077
43095
  const fieldType = getFieldType(sel);
@@ -43097,17 +43115,8 @@ function buildSelectionForField$7(source, reader, sel, variables, fragments, isC
43097
43115
  return sink;
43098
43116
  }
43099
43117
  function selectTypeLink(sel, fieldData, reader, key, sink, variables, fragments, version, selectFn, isCursorConnection) {
43100
- const resolvedLink = reader.read({
43101
- recordId: fieldData.__ref,
43102
- node: {
43103
- kind: 'Fragment',
43104
- private: [],
43105
- opaque: true,
43106
- version,
43107
- },
43108
- variables: {}
43109
- });
43110
- if (resolvedLink.data !== undefined) {
43118
+ const resolvedLink = resolveLink(reader, fieldData, version);
43119
+ if (resolvedLink && resolvedLink.data !== undefined) {
43111
43120
  if (isCursorConnection) {
43112
43121
  selectTypeLinkWithPagination(resolvedLink, sel, fieldData, reader, key, sink, variables, fragments, selectFn);
43113
43122
  }
@@ -43689,19 +43698,11 @@ function selectType$6(typename, sel, fieldData, reader, key, sink, variables, fr
43689
43698
  }
43690
43699
  case 'PolymorphicParentRelationship':
43691
43700
  case 'RecordRepresentation': {
43692
- const spanningFieldLink = reader.read({
43693
- recordId: fieldData.__ref,
43694
- node: {
43695
- kind: 'Fragment',
43696
- private: [],
43697
- opaque: true,
43698
- version: VERSION$2i,
43699
- },
43700
- variables: {},
43701
- });
43702
- reader.markSeenId(fieldData.__ref);
43703
- const resolvedSpanningFieldValue = spanningFieldLink.data;
43701
+ const spanningFieldLink = resolveLink(reader, fieldData, VERSION$2i);
43702
+ const resolvedSpanningFieldValue = spanningFieldLink && spanningFieldLink.data;
43703
+ const fieldDataRef = fieldData.__ref;
43704
43704
  if (resolvedSpanningFieldValue !== undefined) {
43705
+ reader.markSeenId(fieldDataRef);
43705
43706
  const { value: spanningFieldResult } = resolvedSpanningFieldValue;
43706
43707
  // Handle null values - graphql will return it at the field level, not return nested { value: null }
43707
43708
  if (spanningFieldResult === null || typeof spanningFieldResult !== 'object') {
@@ -43725,7 +43726,9 @@ function selectType$6(typename, sel, fieldData, reader, key, sink, variables, fr
43725
43726
  }
43726
43727
  }
43727
43728
  else {
43728
- reader.markMissingLink(fieldData.__ref);
43729
+ if (fieldDataRef !== undefined) {
43730
+ reader.markMissingLink(fieldDataRef);
43731
+ }
43729
43732
  reader.markMissing();
43730
43733
  }
43731
43734
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-adapters-uiapi",
3
- "version": "1.229.0-dev1",
3
+ "version": "1.229.0-dev10",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "Wire adapters for record related UI API endpoints",
6
6
  "main": "dist/es/es2018/uiapi-records-service.js",
@@ -68,15 +68,15 @@
68
68
  }
69
69
  },
70
70
  "dependencies": {
71
- "@salesforce/lds-bindings": "1.229.0-dev1",
72
- "@salesforce/lds-default-luvio": "1.229.0-dev1"
71
+ "@salesforce/lds-bindings": "1.229.0-dev10",
72
+ "@salesforce/lds-default-luvio": "1.229.0-dev10"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@databases/sqlite": "^3.0.0",
76
- "@salesforce/lds-compiler-plugins": "1.229.0-dev1",
77
- "@salesforce/lds-jest": "1.229.0-dev1",
78
- "@salesforce/lds-store-binary": "1.229.0-dev1",
79
- "@salesforce/lds-uiapi-record-utils": "1.229.0-dev1"
76
+ "@salesforce/lds-compiler-plugins": "1.229.0-dev10",
77
+ "@salesforce/lds-jest": "1.229.0-dev10",
78
+ "@salesforce/lds-store-binary": "1.229.0-dev10",
79
+ "@salesforce/lds-uiapi-record-utils": "1.229.0-dev10"
80
80
  },
81
81
  "luvioBundlesize": [
82
82
  {
@@ -16,7 +16,7 @@ import { register, withDefaultLuvio } from 'force/ldsEngine';
16
16
  import { print, visit, parse, astResolver } from 'force/ldsGraphqlParser';
17
17
  import { createInstrumentedAdapter, createLDSAdapter, createGraphQLWireAdapterConstructor, createGraphQLImperativeAdapter } from 'force/ldsBindings';
18
18
  export { refresh as refreshGraphQL } from 'force/ldsBindings';
19
- import { serializeStructuredKey, deepFreeze, buildNetworkSnapshotCachePolicy as buildNetworkSnapshotCachePolicy$2, StoreKeyMap, createResourceParams as createResourceParams$2, StoreKeySet } from 'force/luvioEngine';
19
+ import { serializeStructuredKey, deepFreeze, resolveLink, buildNetworkSnapshotCachePolicy as buildNetworkSnapshotCachePolicy$2, StoreKeyMap, createResourceParams as createResourceParams$2, StoreKeySet } from 'force/luvioEngine';
20
20
  import { getRequestedFieldsForType, buildFieldState, createFragmentMap, mergeSelectionSets, serializeFieldArguments, deepMerge, buildQueryTypeStringKey, getOperationFromDocument } from 'force/luvioGraphql';
21
21
  import { createIngestRecordWithFields } from 'force/ldsAdaptersUiapi';
22
22
 
@@ -12954,7 +12954,7 @@ function getFieldType$6(field) {
12954
12954
  }
12955
12955
  }
12956
12956
 
12957
- const { assign, create, freeze, keys } = Object;
12957
+ const { assign, create, freeze, isFrozen, keys } = Object;
12958
12958
  const { isArray } = Array;
12959
12959
  const { concat, filter, includes, push, reduce } = Array.prototype;
12960
12960
 
@@ -14393,6 +14393,7 @@ function buildSelectionForField$7(source, reader, sel, variables, fragments, isC
14393
14393
  }
14394
14394
  if (fieldData === null) {
14395
14395
  reader.assignScalar(requestedFieldName, sink, fieldData);
14396
+ reader.exitPath();
14396
14397
  return sink;
14397
14398
  }
14398
14399
  const fieldType = getFieldType(sel);
@@ -14418,17 +14419,8 @@ function buildSelectionForField$7(source, reader, sel, variables, fragments, isC
14418
14419
  return sink;
14419
14420
  }
14420
14421
  function selectTypeLink(sel, fieldData, reader, key, sink, variables, fragments, version, selectFn, isCursorConnection) {
14421
- const resolvedLink = reader.read({
14422
- recordId: fieldData.__ref,
14423
- node: {
14424
- kind: 'Fragment',
14425
- private: [],
14426
- opaque: true,
14427
- version,
14428
- },
14429
- variables: {}
14430
- });
14431
- if (resolvedLink.data !== undefined) {
14422
+ const resolvedLink = resolveLink(reader, fieldData, version);
14423
+ if (resolvedLink && resolvedLink.data !== undefined) {
14432
14424
  if (isCursorConnection) {
14433
14425
  selectTypeLinkWithPagination(resolvedLink, sel, fieldData, reader, key, sink, variables, fragments, selectFn);
14434
14426
  }
@@ -15010,19 +15002,11 @@ function selectType$6(typename, sel, fieldData, reader, key, sink, variables, fr
15010
15002
  }
15011
15003
  case 'PolymorphicParentRelationship':
15012
15004
  case 'RecordRepresentation': {
15013
- const spanningFieldLink = reader.read({
15014
- recordId: fieldData.__ref,
15015
- node: {
15016
- kind: 'Fragment',
15017
- private: [],
15018
- opaque: true,
15019
- version: VERSION$f,
15020
- },
15021
- variables: {},
15022
- });
15023
- reader.markSeenId(fieldData.__ref);
15024
- const resolvedSpanningFieldValue = spanningFieldLink.data;
15005
+ const spanningFieldLink = resolveLink(reader, fieldData, VERSION$f);
15006
+ const resolvedSpanningFieldValue = spanningFieldLink && spanningFieldLink.data;
15007
+ const fieldDataRef = fieldData.__ref;
15025
15008
  if (resolvedSpanningFieldValue !== undefined) {
15009
+ reader.markSeenId(fieldDataRef);
15026
15010
  const { value: spanningFieldResult } = resolvedSpanningFieldValue;
15027
15011
  // Handle null values - graphql will return it at the field level, not return nested { value: null }
15028
15012
  if (spanningFieldResult === null || typeof spanningFieldResult !== 'object') {
@@ -15046,7 +15030,9 @@ function selectType$6(typename, sel, fieldData, reader, key, sink, variables, fr
15046
15030
  }
15047
15031
  }
15048
15032
  else {
15049
- reader.markMissingLink(fieldData.__ref);
15033
+ if (fieldDataRef !== undefined) {
15034
+ reader.markMissingLink(fieldDataRef);
15035
+ }
15050
15036
  reader.markMissing();
15051
15037
  }
15052
15038
  break;
@@ -18121,4 +18107,4 @@ register({
18121
18107
  });
18122
18108
 
18123
18109
  export { configurationForGraphQLAdapters as configuration, graphql, factory$1 as graphqlAdapterFactory, graphqlBatch, graphqlBatch_imperative, graphql_imperative };
18124
- // version: 1.229.0-dev1-5b6d3db67
18110
+ // version: 1.229.0-dev10-abb060196
package/sfdc/index.js CHANGED
@@ -403,7 +403,7 @@ function buildAdapterValidationConfig(displayName, paramsMeta) {
403
403
  }
404
404
  const keyPrefix = 'UiApi';
405
405
 
406
- const { assign, create, freeze, keys } = Object;
406
+ const { assign, create, freeze, isFrozen, keys } = Object;
407
407
  const { hasOwnProperty } = Object.prototype;
408
408
  const { split, endsWith } = String.prototype;
409
409
  const { isArray } = Array;
@@ -4287,7 +4287,7 @@ function extractTrackedFieldsToTrie(recordId, node, root, config, visitedRecordI
4287
4287
  extractTrackedFieldsToTrie(spanningLink.data.__ref, spanning, next, config, spanningVisitedRecordIds, depth + 1);
4288
4288
  // For a spanning record that is detected to be a circular reference, we add the field along with Id and Name.
4289
4289
  // It's possible for spanning record lookup fields to sometimes be circular, and sometimes not - depending on the value of the lookup field.
4290
- // For more information on scenarios that caused this fix: https://salesforce.quip.com/OvzNAh3eNIWY
4290
+ // For more information on scenarios that caused this fix: search "LDS Recursive Spanning Fields Problem" in Quip
4291
4291
  if (keys(next.children).length === 0) {
4292
4292
  addScalarFieldId(next);
4293
4293
  addScalarFieldName(next);
@@ -4440,7 +4440,11 @@ function markNulledOutPath(record, path) {
4440
4440
  }
4441
4441
  const link = fieldValueRepresentation.link(fieldName);
4442
4442
  const resolved = link.follow();
4443
- if (isGraphNode(resolved) && resolved.isScalar('value') && path.length > 0) {
4443
+ if (isGraphNode(resolved) &&
4444
+ resolved.isScalar('value') &&
4445
+ path.length > 0 &&
4446
+ // TODO [W-14082782]: temporary fix
4447
+ !isFrozen(link.data)) {
4444
4448
  const linkState = link.linkData();
4445
4449
  const fields = linkState === undefined ? [] : linkState.fields;
4446
4450
  link.writeLinkData({
@@ -4468,22 +4472,12 @@ function _markMissingPath(record, path) {
4468
4472
  const fieldValueRepresentation = record.object('fields');
4469
4473
  const fieldName = path.shift();
4470
4474
  if (fieldValueRepresentation.isUndefined(fieldName) === true) {
4471
- // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4472
- // an undefined/non-present __ref if isMissing is present
4473
- fieldValueRepresentation.write(fieldName, {
4474
- __ref: undefined,
4475
- isMissing: true,
4476
- });
4475
+ writeMissingFieldToStore(fieldValueRepresentation, fieldName);
4477
4476
  return;
4478
4477
  }
4479
4478
  const link = fieldValueRepresentation.link(fieldName);
4480
4479
  if (link.isPending()) {
4481
- // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4482
- // an undefined/non-present __ref if isMissing is present
4483
- fieldValueRepresentation.write(fieldName, {
4484
- __ref: undefined,
4485
- isMissing: true,
4486
- });
4480
+ writeMissingFieldToStore(fieldValueRepresentation, fieldName);
4487
4481
  }
4488
4482
  else if (path.length > 0 && link.isMissing() === false) {
4489
4483
  const fieldValue = link.follow();
@@ -4499,6 +4493,19 @@ function _markMissingPath(record, path) {
4499
4493
  }
4500
4494
  }
4501
4495
  }
4496
+ /**
4497
+ * Graph Node Directly modifies store entries, which is generally a non-starter.
4498
+ * Until we can refactor this mess, you need to use this function to safely mark the RecordRepresentation
4499
+ * as a seenId in the store when you perform this mutation.
4500
+ */
4501
+ function writeMissingFieldToStore(field, fieldName) {
4502
+ // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
4503
+ // an undefined/non-present __ref if isMissing is present
4504
+ field.write(fieldName, {
4505
+ __ref: undefined,
4506
+ isMissing: true,
4507
+ });
4508
+ }
4502
4509
  /**
4503
4510
  * Tells you if an objectApiName is supported by UI API or not.
4504
4511
  * Note: Luvio does not currently support all the entities, the list is limited to UI API supported entities
@@ -4630,8 +4637,11 @@ function mergeAndRefreshLowerVersionRecord(luvio, incoming, existing, incomingTr
4630
4637
  return existing;
4631
4638
  }
4632
4639
  function mergeRecordConflict(luvio, incoming, existing, recordConflictMap) {
4633
- const incomingNode = luvio.wrapNormalizedGraphNode(incoming);
4634
- const existingNode = luvio.wrapNormalizedGraphNode(existing);
4640
+ const recordKey = keyBuilder$1U(luvio, {
4641
+ recordId: incoming.id,
4642
+ });
4643
+ const incomingNode = luvio.wrapNormalizedGraphNode(incoming, recordKey);
4644
+ const existingNode = luvio.wrapNormalizedGraphNode(existing, recordKey);
4635
4645
  const incomingTrackedFieldsTrieRoot = {
4636
4646
  name: incoming.apiName,
4637
4647
  children: {},
@@ -4640,9 +4650,6 @@ function mergeRecordConflict(luvio, incoming, existing, recordConflictMap) {
4640
4650
  name: existing.apiName,
4641
4651
  children: {},
4642
4652
  };
4643
- const recordKey = keyBuilder$1U(luvio, {
4644
- recordId: incoming.id,
4645
- });
4646
4653
  const trackedFieldsConfig = {
4647
4654
  maxDepth: configurationForRestAdapters.getTrackedFieldDepthOnCacheMergeConflict(),
4648
4655
  onlyFetchLeafNodeIdAndName: configurationForRestAdapters.getTrackedFieldLeafNodeIdAndNameOnly(),
@@ -11330,7 +11337,7 @@ function getLayoutMapAndObjectInfo(recordId, data) {
11330
11337
  // Temp fix until we can mimic the server behavior for non-layoutable entities.
11331
11338
  let layoutMap = {};
11332
11339
  if (hasOwnProperty.call(layouts, apiName)) {
11333
- layoutMap = layouts[apiName][recordTypeId];
11340
+ layoutMap = layouts[apiName][recordTypeId] || {};
11334
11341
  }
11335
11342
  return {
11336
11343
  layoutMap,
@@ -11512,18 +11519,28 @@ const buildLayoutModeCacheSnapshot = (apiName, recordTypeId, layoutType, mode) =
11512
11519
  * These are intermediate lookups to check if the record is in the L2 cache
11513
11520
  * @param {Luvio} luvio
11514
11521
  * @param {GetRecordLayoutTypeConfig} config
11515
- * @param {BuildCachedSnapshot<BuildSnapshotContext} cachedSnapshot
11522
+ * @param {BuildCachedSnapshot<BuildSnapshotContext>} cachedSnapshot
11516
11523
  */
11517
11524
  function makeCacheOnlySnapshot(luvio, config, adapterContext, cachedSnapshot) {
11518
- return luvio.applyCachePolicy({
11519
- cachePolicy: {
11520
- // only looking in the cache so we can check for L2 data offline
11521
- type: 'only-if-cached',
11522
- },
11523
- }, { config, luvio, adapterContext }, cachedSnapshot,
11524
- // this won't be invoked since we're requesting only-if-cached
11525
+ return luvio.applyCachePolicy(
11526
+ // Pass empty context so environment will use its default cache-policy
11527
+ {}, { config, luvio, adapterContext }, cachedSnapshot,
11528
+ // disallow hitting the network by returning a gateway timeout
11525
11529
  () => {
11526
- throw Error('buildNetworkSnapshot should not be called for only-if-cached policy');
11530
+ return new Promise((resolve) => {
11531
+ resolve({
11532
+ state: 'Error',
11533
+ data: undefined,
11534
+ error: {
11535
+ body: undefined,
11536
+ headers: {},
11537
+ ok: false,
11538
+ status: 504,
11539
+ statusText: 'Gateway Timeout',
11540
+ errorType: 'fetchResponse',
11541
+ },
11542
+ });
11543
+ });
11527
11544
  });
11528
11545
  }
11529
11546
  /**
@@ -11734,7 +11751,7 @@ const notifyChangeFactory = (luvio) => {
11734
11751
  const responsePromises = [];
11735
11752
  for (let i = 0, len = entries.length; i < len; i++) {
11736
11753
  const { key, record } = entries[i];
11737
- const node = luvio.wrapNormalizedGraphNode(record);
11754
+ const node = luvio.wrapNormalizedGraphNode(record, key);
11738
11755
  const optionalFields = getTrackedFields(key, node, {
11739
11756
  maxDepth: configurationForRestAdapters.getTrackedFieldDepthOnNotifyChange(),
11740
11757
  onlyFetchLeafNodeIdAndName: configurationForRestAdapters.getTrackedFieldLeafNodeIdAndNameOnly(),
@@ -32853,4 +32870,4 @@ withDefaultLuvio((luvio) => {
32853
32870
  });
32854
32871
 
32855
32872
  export { InMemoryRecordRepresentationQueryEvaluator, MRU, RepresentationType$J as ObjectInfoRepresentationType, RepresentationType$O as RecordRepresentationRepresentationType, TTL$w as RecordRepresentationTTL, RepresentationType$O as RecordRepresentationType, VERSION$17 as RecordRepresentationVersion, keyPrefix as UiApiNamespace, configurationForRestAdapters as configuration, createContentDocumentAndVersion, createContentVersion, createIngestRecordWithFields, createRecord, deleteRecord, getActionOverrides, getActionOverrides_imperative, getAllApps, getAllApps_imperative, getAppDetails, getAppDetails_imperative, getDuplicateConfiguration, getDuplicateConfiguration_imperative, getDuplicates, getDuplicates_imperative, getGlobalActions, getGlobalActions_imperative, getKeywordSearchResults, getKeywordSearchResults_imperative, getLayout, getLayoutUserState, getLayoutUserState_imperative, getLayout_imperative, getListInfoByName, getListInfoByName_imperative, getListInfosByName, getListInfosByName_imperative, getListObjectInfo, getListObjectInfo_imperative, getListRecordsByName, getListRecordsByName_imperative, getListUi, getListUi_imperative, getLookupActions, getLookupActions_imperative, getLookupMetadata, getLookupMetadata_imperative, getLookupRecords, getLookupRecords_imperative, getNavItems, getNavItems_imperative, getObjectCreateActions, getObjectCreateActions_imperative, getObjectInfo, getObjectInfoAdapterFactory, getObjectInfo_imperative, getObjectInfos, getObjectInfosAdapterFactory, getObjectInfos_imperative, getPicklistValues, getPicklistValuesByRecordType, getPicklistValuesByRecordType_imperative, getPicklistValues_imperative, getQuickActionDefaults, getQuickActionDefaults_imperative, getQuickActionLayout, getQuickActionLayout_imperative, getRecord, getRecordActions, getRecordActions_imperative, factory$e as getRecordAdapterFactory, getRecordAvatars, getRecordAvatars_imperative, getRecordCreateDefaults, getRecordCreateDefaults_imperative, getRecordEditActions, getRecordEditActions_imperative, getRecordId18, getRecordNotifyChange, getRecordTemplateClone, getRecordTemplateClone_imperative, getRecordTemplateCreate, getRecordTemplateCreate_imperative, getRecordUi, getRecordUi_imperative, getRecord_imperative, getRecords, getRecordsAdapterFactory, getRecords_imperative, getRelatedListActions, getRelatedListActions_imperative, getRelatedListCount, getRelatedListCount_imperative, getRelatedListInfo, getRelatedListInfoBatch, getRelatedListInfoBatch_imperative, getRelatedListInfo_imperative, getRelatedListPreferences, getRelatedListPreferencesBatch, getRelatedListPreferencesBatch_imperative, getRelatedListPreferences_imperative, getRelatedListRecordActions, getRelatedListRecordActions_imperative, getRelatedListRecords, getRelatedListRecordsBatch, getRelatedListRecordsBatch_imperative, getRelatedListRecords_imperative, getRelatedListsActions, getRelatedListsActions_imperative, getRelatedListsCount, getRelatedListsCount_imperative, getRelatedListsInfo, getRelatedListsInfo_imperative, getResponseCacheKeys as getResponseCacheKeysContentDocumentCompositeRepresentation, getSearchFilterMetadata, getSearchFilterMetadata_imperative, getSearchFilterOptions, getSearchFilterOptions_imperative, getSearchResults, getSearchResults_imperative, getTypeCacheKeys$Q as getTypeCacheKeysRecord, ingest as ingestContentDocumentCompositeRepresentation, ingest$C as ingestObjectInfo, ingest$y as ingestQuickActionExecutionRepresentation, ingest$H as ingestRecord, instrument, keyBuilder as keyBuilderContentDocumentCompositeRepresentation, keyBuilderFromType as keyBuilderFromTypeContentDocumentCompositeRepresentation, keyBuilderFromType$y as keyBuilderFromTypeRecordRepresentation, keyBuilder$1J as keyBuilderObjectInfo, keyBuilder$1D as keyBuilderQuickActionExecutionRepresentation, keyBuilder$1U as keyBuilderRecord, notifyListInfoUpdateAvailable, notifyListViewSummaryUpdateAvailable, notifyQuickActionDefaultsUpdateAvailable, notifyRecordUpdateAvailable, performQuickAction, performUpdateRecordQuickAction, refresh, updateLayoutUserState, updateListInfoByName, updateRecord, updateRecordAvatar, updateRelatedListInfo, updateRelatedListPreferences };
32856
- // version: 1.229.0-dev1-5b6d3db67
32873
+ // version: 1.229.0-dev10-abb060196
@@ -95,11 +95,11 @@ var TypeCheckShapes;
95
95
  TypeCheckShapes[TypeCheckShapes["Integer"] = 3] = "Integer";
96
96
  TypeCheckShapes[TypeCheckShapes["Unsupported"] = 4] = "Unsupported";
97
97
  })(TypeCheckShapes || (TypeCheckShapes = {}));
98
- // engine version: 0.145.2-6a13677c
98
+ // engine version: 0.146.0-dev5-a2ec6e3f
99
99
 
100
100
  const { keys: ObjectKeys, create: ObjectCreate } = Object;
101
101
 
102
- const { assign, create, freeze, keys } = Object;
102
+ const { assign, create, freeze, isFrozen, keys } = Object;
103
103
 
104
104
  function isString(value) {
105
105
  return typeof value === 'string';