@salesforce/lds-runtime-aura 1.322.0 → 1.324.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.
@@ -20,6 +20,7 @@ import useRelatedListsPredictions from '@salesforce/gate/lds.pdl.useRelatedLists
20
20
  import useCmpDefPredictions from '@salesforce/gate/lds.pdl.useCmpDefPredictions';
21
21
  import applyPredictionRequestLimit from '@salesforce/gate/lds.pdl.applyRequestLimit';
22
22
  import useExactMatchesPlusGate from '@salesforce/gate/lds.pdl.useExactMatchesPlus';
23
+ import useRecordTypeId from '@salesforce/gate/lds.pdl.useRecordTypeId';
23
24
  import { GetApexWireAdapterFactory, registerPrefetcher as registerPrefetcher$1 } from 'force/ldsAdaptersApex';
24
25
  import { getRecordAvatarsAdapterFactory, getRecordAdapterFactory, coerceFieldIdArray, getRecordsAdapterFactory, getRecordActionsAdapterFactory, getObjectInfosAdapterFactory, coerceObjectIdArray, getObjectInfoAdapterFactory, coerceObjectId, getRelatedListsActionsAdapterFactory, getRelatedListInfoBatchAdapterFactory, getRelatedListInfoAdapterFactory, getRelatedListRecordsBatchAdapterFactory, getRelatedListRecordsAdapterFactory, getListInfoByNameAdapterFactory, getListInfosByObjectNameAdapterFactory, getListRecordsByNameAdapterFactory, getListObjectInfoAdapterFactory, instrument, configuration, InMemoryRecordRepresentationQueryEvaluator, UiApiNamespace, RecordRepresentationRepresentationType, registerPrefetcher } from 'force/ldsAdaptersUiapi';
25
26
  import { getInstrumentation } from 'o11y/client';
@@ -1215,6 +1216,35 @@ function buildServiceDescriptor$1(cache) {
1215
1216
  };
1216
1217
  }
1217
1218
 
1219
+ /**
1220
+ * Copyright (c) 2022, Salesforce, Inc.,
1221
+ * All rights reserved.
1222
+ * For full license text, see the LICENSE.txt file
1223
+ */
1224
+
1225
+ /**
1226
+ * Most-recently set of published services.
1227
+ */
1228
+ let servicesAvailable;
1229
+ new Promise((resolve) => (servicesAvailable = resolve));
1230
+ /**
1231
+ * Sets the services that will be used to satisfy calls to getServices().
1232
+ * Any previously registered services are replaced with the services provided.
1233
+ * Note overwriting services should be done with great care as previous callers
1234
+ * of getServices() will not be aware of the new services.
1235
+ *
1236
+ * The default implementation provided by this module only supports a single
1237
+ * set of active services. Runtime environments that require multiple sets of
1238
+ * active services will need to override this module with their own
1239
+ * implementation.
1240
+
1241
+ * @param services services to be used to satisfy future getServices() requests
1242
+ */
1243
+ function setServices(services) {
1244
+ resolvedPromiseLike(services);
1245
+ servicesAvailable(services);
1246
+ }
1247
+
1218
1248
  /**
1219
1249
  * Copyright (c) 2022, Salesforce, Inc.,
1220
1250
  * All rights reserved.
@@ -1722,27 +1752,8 @@ const SFAP_BASE_URL = 'api.salesforce.com';
1722
1752
  const sfapJwtRepository = new JwtRepository();
1723
1753
  const sfapJwtManager = new JwtManager(sfapJwtRepository, platformSfapJwtResolver);
1724
1754
  function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
1725
- const jwtRequestModifier = ({ baseUri }, [resource, request]) => {
1726
- if (typeof resource !== 'string' && !(resource instanceof URL)) {
1727
- // istanbul ignore else: this will not be tested in NODE_ENV = production for test coverage
1728
- if (process.env.NODE_ENV !== 'production') {
1729
- throw new Error('SFAP fetch service expects a string or URL resource');
1730
- }
1731
- return [resource, request];
1732
- }
1733
- const overrideUrl = new URL(baseUri);
1734
- const url = typeof resource === 'string' ? new URL(resource) : new URL(resource.toString());
1735
- if (!(url.host === SFAP_BASE_URL)) {
1736
- logger.warn(`SFAP fetch service requires that the host of the resource is ${SFAP_BASE_URL}`);
1737
- return [resource, request];
1738
- }
1739
- url.host = overrideUrl.host;
1740
- url.protocol = overrideUrl.protocol;
1741
- return [url, request];
1742
- };
1743
- const jwtRequestHeaderInterceptor = buildJwtRequestHeaderInterceptor(sfapJwtManager, jwtRequestModifier);
1744
1755
  const jwtAuthorizedFetchService = buildServiceDescriptor({
1745
- request: [jwtRequestHeaderInterceptor],
1756
+ request: [buildJwtRequestInterceptor(logger)],
1746
1757
  });
1747
1758
  return {
1748
1759
  ...jwtAuthorizedFetchService,
@@ -1779,10 +1790,13 @@ function buildCopilotFetchServiceDescriptor(logger) {
1779
1790
  return resolvedPromiseLike(sfapJwtManager.getJwt()).then((token) => {
1780
1791
  // replace the body's instanceConfig.endpoint with the JWT's iss value
1781
1792
  const body = JSON.parse(requestInit.body);
1782
- if (!body || !body.instanceConfig || !token.decodedInfo.iss) {
1793
+ if (!body || !token.decodedInfo || !token.decodedInfo.iss) {
1783
1794
  logger.warn('skipping injection of endpoint into start session request');
1784
1795
  }
1785
1796
  else {
1797
+ if (!body.instanceConfig) {
1798
+ body.instanceConfig = {};
1799
+ }
1786
1800
  body.instanceConfig.endpoint = token.decodedInfo.iss;
1787
1801
  }
1788
1802
  return [
@@ -1794,6 +1808,7 @@ function buildCopilotFetchServiceDescriptor(logger) {
1794
1808
  ];
1795
1809
  });
1796
1810
  },
1811
+ buildJwtRequestInterceptor(logger),
1797
1812
  ],
1798
1813
  }),
1799
1814
  tags: { specialHacksFor: 'copilot' },
@@ -1806,6 +1821,28 @@ function buildUnauthorizedFetchServiceDescriptor() {
1806
1821
  tags: { authenticationScopes: '' },
1807
1822
  };
1808
1823
  }
1824
+ function buildJwtRequestInterceptor(logger) {
1825
+ const jwtRequestModifier = ({ baseUri }, [resource, request]) => {
1826
+ if (typeof resource !== 'string' && !(resource instanceof URL)) {
1827
+ // istanbul ignore else: this will not be tested in NODE_ENV = production for test coverage
1828
+ if (process.env.NODE_ENV !== 'production') {
1829
+ throw new Error('SFAP fetch service expects a string or URL resource');
1830
+ }
1831
+ return [resource, request];
1832
+ }
1833
+ const overrideUrl = new URL(baseUri);
1834
+ const url = typeof resource === 'string' ? new URL(resource) : new URL(resource.toString());
1835
+ if (!(url.host === SFAP_BASE_URL)) {
1836
+ logger.warn(`SFAP fetch service requires that the host of the resource is ${SFAP_BASE_URL}`);
1837
+ return [resource, request];
1838
+ }
1839
+ url.host = overrideUrl.host;
1840
+ url.protocol = overrideUrl.protocol;
1841
+ return [url, request];
1842
+ };
1843
+ const jwtRequestHeaderInterceptor = buildJwtRequestHeaderInterceptor(sfapJwtManager, jwtRequestModifier);
1844
+ return jwtRequestHeaderInterceptor;
1845
+ }
1809
1846
 
1810
1847
  const PDL_EXECUTE_ASYNC_OPTIONS = {
1811
1848
  LOG_ERROR_ONLY: true,
@@ -1853,7 +1890,17 @@ const { create, keys, hasOwnProperty, entries } = Object;
1853
1890
  const { isArray, from } = Array;
1854
1891
  const { stringify } = JSON;
1855
1892
 
1893
+ // Note: exported enum for core usage.
1894
+ var PdlRequestPriority;
1895
+ (function (PdlRequestPriority) {
1896
+ PdlRequestPriority[PdlRequestPriority["LOW"] = 0] = "LOW";
1897
+ PdlRequestPriority[PdlRequestPriority["NORMAL"] = 1] = "NORMAL";
1898
+ PdlRequestPriority[PdlRequestPriority["HIGH"] = 2] = "HIGH";
1899
+ })(PdlRequestPriority || (PdlRequestPriority = {}));
1856
1900
  class RequestStrategy {
1901
+ getRequestPriority(_request, _context) {
1902
+ return 1 /* RequestPriority.NORMAL */;
1903
+ }
1857
1904
  /**
1858
1905
  * Perform any transformations required to prepare the request for saving.
1859
1906
  *
@@ -4065,6 +4112,39 @@ async function runRequestsWithLimit(requests, runner, concurrentRequestsLimit, p
4065
4112
  // Wait for all initial requests to complete
4066
4113
  await Promise.all(promises);
4067
4114
  }
4115
+ /**
4116
+ * Compares two request entries based on their priority and, if the priorities are the same, their request times.
4117
+ * This function is typically used for sorting requests where priority takes precedence, and timing is used
4118
+ * as a secondary criterion. The function assumes that any necessary filtering of requests has already been done.
4119
+ *
4120
+ * @template Context - Extends `DefaultPageContext`, provides additional context for the request priority determination.
4121
+ *
4122
+ * @param {RequestEntry<LexRequest>} requestA - The first request entry containing the request and its metadata.
4123
+ * @param {RequestEntry<LexRequest>} requestB - The second request entry containing the request and its metadata.
4124
+ * @param {RequestStrategyManager} requestStrategyManager - Manager that provides access to request strategies based on adapter names.
4125
+ * @param {Context} context - The context in which the requests are being compared, used to determine request priority.
4126
+ *
4127
+ * @returns {number} A negative number if the first request should come before the second, a positive number if the
4128
+ * second should come before the first, or zero if they are considered equal for sorting purposes.
4129
+ * This is determined first by the priority (higher priority comes first) and then by the request
4130
+ * time (earlier request comes first) if priorities are the same. The priorities are fetched from
4131
+ * the `requestStrategyManager` for each request's `adapterName`. If a strategy is not found,
4132
+ * the priority defaults to `RequestPriority.LOW`.
4133
+ */
4134
+ function compareByPriorityThenTime({ request: requestA, requestMetadata: requestMetadataA }, { request: requestB, requestMetadata: requestMetadataB }, requestStrategyManager, context) {
4135
+ const aPriority = requestStrategyManager.get(requestA.adapterName)?.getRequestPriority(requestA, context) ||
4136
+ 0 /* RequestPriority.LOW */;
4137
+ const bPriority = requestStrategyManager.get(requestB.adapterName)?.getRequestPriority(requestB, context) ||
4138
+ 0 /* RequestPriority.LOW */;
4139
+ if (aPriority === bPriority) {
4140
+ // when both requests have the same priority, use the request time in waterfall.
4141
+ return requestMetadataA.requestTime - requestMetadataB.requestTime;
4142
+ }
4143
+ else {
4144
+ // sort by priority, descending
4145
+ return bPriority - aPriority;
4146
+ }
4147
+ }
4068
4148
 
4069
4149
  function isBoxcarableRequest({ request: { adapterName } }, requestStrategyManager) {
4070
4150
  const strategy = requestStrategyManager.get(adapterName);
@@ -4117,20 +4197,22 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
4117
4197
  return [...exactPageRequests, ...similarPageRequests];
4118
4198
  }
4119
4199
  async predict() {
4200
+ // perf: caching access, to avoid this.prop in loops.
4201
+ const { requestStrategyManager, context } = this;
4120
4202
  const alwaysRequests = this.page.getAlwaysRunRequests();
4121
4203
  const pageRequests = this.getAllPageRequests();
4122
4204
  // IMPORTANT: Because there's no way to differentiate a cmpDef prediction from the page
4123
4205
  // requesting the cmpDef, we need to predict cmpDefs before we start watching
4124
4206
  // for predictions in the page. Having this code after an
4125
4207
  // await will make the predictions to be saved as predictions too.
4126
- predictNonBoxcarableRequest(pageRequests.filter((r) => !isBoxcarableRequest(r, this.requestStrategyManager)), this.requestRunner);
4208
+ predictNonBoxcarableRequest(pageRequests.filter((r) => !isBoxcarableRequest(r, requestStrategyManager)), this.requestRunner);
4127
4209
  const alwaysRequestEntries = alwaysRequests.map((request) => {
4128
4210
  return {
4129
4211
  request,
4130
4212
  requestMetadata: { requestTime: 0 }, // ensures always requests are executed, and executed first.
4131
4213
  };
4132
4214
  });
4133
- const boxcarablePredictions = pageRequests.filter((r) => isBoxcarableRequest(r, this.requestStrategyManager));
4215
+ const boxcarablePredictions = pageRequests.filter((r) => isBoxcarableRequest(r, requestStrategyManager));
4134
4216
  const reducedPredictions = this.page.shouldReduceAlwaysRequestsWithPredictions()
4135
4217
  ? this.requestRunner.reduceRequests([...boxcarablePredictions, ...alwaysRequestEntries])
4136
4218
  : this.requestRunner.reduceRequests(boxcarablePredictions);
@@ -4138,7 +4220,7 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
4138
4220
  ? [...alwaysRequestEntries, ...reducedPredictions]
4139
4221
  : reducedPredictions)
4140
4222
  // Sorting in order requested
4141
- .sort((a, b) => a.requestMetadata.requestTime - b.requestMetadata.requestTime);
4223
+ .sort((a, b) => compareByPriorityThenTime(a, b, requestStrategyManager, context));
4142
4224
  this.totalRequestCount = predictedRequestsWithLimit.length;
4143
4225
  await runRequestsWithLimit(predictedRequestsWithLimit, this.requestRunner, this.options.inflightRequestLimit,
4144
4226
  // `this.repository.pageStartTime` would be the correct here,
@@ -4296,7 +4378,7 @@ function getEnvironmentSetting(name) {
4296
4378
  }
4297
4379
  return undefined;
4298
4380
  }
4299
- // version: 1.322.0-87f682c9f3
4381
+ // version: 1.324.0-f16f2a27c7
4300
4382
 
4301
4383
  const forceRecordTransactionsDisabled = getEnvironmentSetting(EnvironmentSettings.ForceRecordTransactionsDisabled);
4302
4384
  //TODO: Some duplication here that can be most likely moved to a util class
@@ -4809,7 +4891,8 @@ function setupPredictivePrefetcher(luvio) {
4809
4891
  const inflightRequestLimit = applyPredictionRequestLimit.isOpen({ fallback: false })
4810
4892
  ? getInflightRequestLimit()
4811
4893
  : 1000;
4812
- const useExactMatchesPlus = useExactMatchesPlusGate.isOpen({ fallback: false });
4894
+ const useExactMatchesPlus = useExactMatchesPlusGate.isOpen({ fallback: false }) &&
4895
+ useRecordTypeId.isOpen({ fallback: false }) === false;
4813
4896
  const prefetcherOptions = {
4814
4897
  inflightRequestLimit,
4815
4898
  useExactMatchesPlus,
@@ -4971,6 +5054,7 @@ function initializeOneStore() {
4971
5054
  buildServiceDescriptor$8(),
4972
5055
  ];
4973
5056
  serviceBroker.publish(services);
5057
+ setServices(services);
4974
5058
  }
4975
5059
  function initializeOnestoreUiApiAdapters() {
4976
5060
  configuration.setGetObjectInfoAdapter(getObjectInfo);
@@ -4996,5 +5080,5 @@ function ldsEngineCreator() {
4996
5080
  return { name: 'ldsEngineCreator' };
4997
5081
  }
4998
5082
 
4999
- export { LexRequestStrategy, buildPredictorForContext, ldsEngineCreator as default, initializeLDS, initializeOneStore, registerRequestStrategy, saveRequestAsPrediction, unregisterRequestStrategy, whenPredictionsReady };
5000
- // version: 1.322.0-6aa042602a
5083
+ export { LexRequestStrategy, PdlRequestPriority, buildPredictorForContext, ldsEngineCreator as default, initializeLDS, initializeOneStore, registerRequestStrategy, saveRequestAsPrediction, unregisterRequestStrategy, whenPredictionsReady };
5084
+ // version: 1.324.0-62e02d2ff9
@@ -1,6 +1,7 @@
1
1
  import { type RecordHomePageContext } from './predictive-loading';
2
2
  import type { LexRequestStrategy } from './predictive-loading/request-strategy/lex-request-strategy';
3
3
  import { type LexRequest } from './predictive-loading/lex';
4
+ export { PdlRequestPriority } from './predictive-loading';
4
5
  export { LexRequestStrategy } from './predictive-loading/request-strategy/lex-request-strategy';
5
6
  /**
6
7
  * Registers a request strategy to be utilized by PDL.
@@ -1,5 +1,8 @@
1
1
  import type { RequestRunner } from '../request-runner';
2
2
  import type { RequestEntry } from '../common';
3
+ import type { LexRequest } from '../lex';
4
+ import type { RequestStrategyManager } from '../request-strategy-manager/request-strategy-manager';
5
+ import type { DefaultPageContext } from '../pages';
3
6
  /**
4
7
  * Runs a list of requests with a specified concurrency limit.
5
8
  *
@@ -14,3 +17,23 @@ import type { RequestEntry } from '../common';
14
17
  * Requests are only processed if their `requestTime` is less than the time elapsed since `pageStartTime`.
15
18
  */
16
19
  export declare function runRequestsWithLimit<Request>(requests: RequestEntry<Request>[], runner: RequestRunner<Request>, concurrentRequestsLimit: number, pageStartTime: number): Promise<void>;
20
+ /**
21
+ * Compares two request entries based on their priority and, if the priorities are the same, their request times.
22
+ * This function is typically used for sorting requests where priority takes precedence, and timing is used
23
+ * as a secondary criterion. The function assumes that any necessary filtering of requests has already been done.
24
+ *
25
+ * @template Context - Extends `DefaultPageContext`, provides additional context for the request priority determination.
26
+ *
27
+ * @param {RequestEntry<LexRequest>} requestA - The first request entry containing the request and its metadata.
28
+ * @param {RequestEntry<LexRequest>} requestB - The second request entry containing the request and its metadata.
29
+ * @param {RequestStrategyManager} requestStrategyManager - Manager that provides access to request strategies based on adapter names.
30
+ * @param {Context} context - The context in which the requests are being compared, used to determine request priority.
31
+ *
32
+ * @returns {number} A negative number if the first request should come before the second, a positive number if the
33
+ * second should come before the first, or zero if they are considered equal for sorting purposes.
34
+ * This is determined first by the priority (higher priority comes first) and then by the request
35
+ * time (earlier request comes first) if priorities are the same. The priorities are fetched from
36
+ * the `requestStrategyManager` for each request's `adapterName`. If a strategy is not found,
37
+ * the priority defaults to `RequestPriority.LOW`.
38
+ */
39
+ export declare function compareByPriorityThenTime<Context extends DefaultPageContext = DefaultPageContext>({ request: requestA, requestMetadata: requestMetadataA }: RequestEntry<LexRequest>, { request: requestB, requestMetadata: requestMetadataB }: RequestEntry<LexRequest>, requestStrategyManager: RequestStrategyManager, context: Context): number;
@@ -3,6 +3,16 @@ export type BaseAdapterRequest<Config = unknown> = {
3
3
  adapterName: string;
4
4
  config: Config;
5
5
  };
6
+ export declare const enum RequestPriority {
7
+ LOW = 0,
8
+ NORMAL = 1,
9
+ HIGH = 2
10
+ }
11
+ export declare enum PdlRequestPriority {
12
+ LOW = 0,
13
+ NORMAL = 1,
14
+ HIGH = 2
15
+ }
6
16
  export declare abstract class RequestStrategy<Config, Request extends BaseAdapterRequest<Config>, Context> {
7
17
  /**
8
18
  * Name of the adapter used in this strategy.
@@ -10,6 +20,7 @@ export declare abstract class RequestStrategy<Config, Request extends BaseAdapte
10
20
  abstract adapterName: string;
11
21
  abstract execute(config: Config): any;
12
22
  abstract buildConcreteRequest(similarRequest: Request, context: Context): Request;
23
+ getRequestPriority(_request: Request, _context: Context): RequestPriority;
13
24
  /**
14
25
  * Perform any transformations required to prepare the request for saving.
15
26
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-aura",
3
- "version": "1.322.0",
3
+ "version": "1.324.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Aura runtime",
6
6
  "main": "dist/ldsEngineCreator.js",
@@ -34,34 +34,36 @@
34
34
  "release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-aura"
35
35
  },
36
36
  "devDependencies": {
37
- "@luvio/service-broker": "5.13.0",
38
- "@salesforce/lds-adapters-apex": "^1.322.0",
39
- "@salesforce/lds-adapters-uiapi": "^1.322.0",
37
+ "@luvio/service-broker": "5.14.0",
38
+ "@luvio/service-provisioner": "5.14.0",
39
+ "@salesforce/lds-adapters-apex": "^1.324.0",
40
+ "@salesforce/lds-adapters-uiapi": "^1.324.0",
40
41
  "@salesforce/lds-adapters-uiapi-lex": "^1.302.0",
41
- "@salesforce/lds-ads-bridge": "^1.322.0",
42
- "@salesforce/lds-aura-storage": "^1.322.0",
43
- "@salesforce/lds-bindings": "^1.322.0",
44
- "@salesforce/lds-instrumentation": "^1.322.0",
45
- "@salesforce/lds-network-aura": "^1.322.0",
46
- "@salesforce/lds-network-fetch-with-jwt": "^1.322.0"
42
+ "@salesforce/lds-ads-bridge": "^1.324.0",
43
+ "@salesforce/lds-aura-storage": "^1.324.0",
44
+ "@salesforce/lds-bindings": "^1.324.0",
45
+ "@salesforce/lds-instrumentation": "^1.324.0",
46
+ "@salesforce/lds-network-aura": "^1.324.0",
47
+ "@salesforce/lds-network-fetch-with-jwt": "^1.324.0",
48
+ "jwt-encode": "1.0.1"
47
49
  },
48
50
  "dependencies": {
49
- "@luvio/command-aura-network": "5.13.0",
50
- "@luvio/command-aura-resource-cache-control": "5.13.0",
51
- "@luvio/command-fetch-network": "5.13.0",
52
- "@luvio/command-network": "5.13.0",
53
- "@luvio/command-sse": "5.13.0",
54
- "@luvio/command-streaming": "5.13.0",
51
+ "@luvio/command-aura-network": "5.14.0",
52
+ "@luvio/command-aura-resource-cache-control": "5.14.0",
53
+ "@luvio/command-fetch-network": "5.14.0",
54
+ "@luvio/command-network": "5.14.0",
55
+ "@luvio/command-sse": "5.14.0",
56
+ "@luvio/command-streaming": "5.14.0",
55
57
  "@luvio/network-adapter-composable": "0.156.5",
56
58
  "@luvio/network-adapter-fetch": "0.156.5",
57
- "@luvio/service-aura-network": "5.13.0",
58
- "@luvio/service-cache": "5.13.0",
59
- "@luvio/service-cache-control": "5.13.0",
60
- "@luvio/service-fetch-network": "5.13.0",
61
- "@luvio/service-instrument-command": "5.13.0",
62
- "@luvio/service-store": "5.13.0",
63
- "@luvio/utils": "5.13.0",
64
- "@salesforce/lds-adapters-uiapi-lex": "^1.322.0"
59
+ "@luvio/service-aura-network": "5.14.0",
60
+ "@luvio/service-cache": "5.14.0",
61
+ "@luvio/service-cache-control": "5.14.0",
62
+ "@luvio/service-fetch-network": "5.14.0",
63
+ "@luvio/service-instrument-command": "5.14.0",
64
+ "@luvio/service-store": "5.14.0",
65
+ "@luvio/utils": "5.14.0",
66
+ "@salesforce/lds-adapters-uiapi-lex": "^1.324.0"
65
67
  },
66
68
  "luvioBundlesize": [
67
69
  {