@salesforce/lds-runtime-aura 1.320.0 → 1.322.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.
@@ -73,7 +73,7 @@ class NetworkCommand extends BaseCommand {
73
73
  return this.fetch();
74
74
  }
75
75
  }
76
- function buildServiceDescriptor$9() {
76
+ function buildServiceDescriptor$a() {
77
77
  return {
78
78
  type: 'networkCommandBaseClass',
79
79
  version: '1.0',
@@ -88,6 +88,10 @@ function buildServiceDescriptor$9() {
88
88
  */
89
89
 
90
90
 
91
+ const { create: create$1, freeze, keys: keys$1 } = Object;
92
+ const { isArray: isArray$1 } = Array;
93
+ const { stringify: stringify$1 } = JSON;
94
+
91
95
  const LogLevelMap$1 = {
92
96
  TRACE: 4,
93
97
  DEBUG: 3,
@@ -215,6 +219,61 @@ function rejectedPromiseLike(reason) {
215
219
  function isPromiseLike(x) {
216
220
  return typeof x === 'object' && typeof (x === null || x === void 0 ? void 0 : x.then) === 'function';
217
221
  }
222
+ /**
223
+ * A deterministic JSON stringify implementation. Heavily adapted from https://github.com/epoberezkin/fast-json-stable-stringify.
224
+ * This is needed because insertion order for JSON.stringify(object) affects output:
225
+ * JSON.stringify({a: 1, b: 2})
226
+ * "{"a":1,"b":2}"
227
+ * JSON.stringify({b: 2, a: 1})
228
+ * "{"b":2,"a":1}"
229
+ * @param data Data to be JSON-stringified.
230
+ * @returns JSON.stringified value with consistent ordering of keys.
231
+ */
232
+ function stableJSONStringify$2(node) {
233
+ // This is for Date values.
234
+ if (node && node.toJSON && typeof node.toJSON === 'function') {
235
+ // eslint-disable-next-line no-param-reassign
236
+ node = node.toJSON();
237
+ }
238
+ if (node === undefined) {
239
+ return;
240
+ }
241
+ if (typeof node === 'number') {
242
+ return isFinite(node) ? '' + node : 'null';
243
+ }
244
+ if (typeof node !== 'object') {
245
+ return stringify$1(node);
246
+ }
247
+ let i;
248
+ let out;
249
+ if (isArray$1(node)) {
250
+ out = '[';
251
+ for (i = 0; i < node.length; i++) {
252
+ if (i) {
253
+ out += ',';
254
+ }
255
+ out += stableJSONStringify$2(node[i]) || 'null';
256
+ }
257
+ return out + ']';
258
+ }
259
+ if (node === null) {
260
+ return 'null';
261
+ }
262
+ const objKeys = keys$1(node).sort();
263
+ out = '';
264
+ for (i = 0; i < objKeys.length; i++) {
265
+ const key = objKeys[i];
266
+ const value = stableJSONStringify$2(node[key]);
267
+ if (!value) {
268
+ continue;
269
+ }
270
+ if (out) {
271
+ out += ',';
272
+ }
273
+ out += stringify$1(key) + ':' + value;
274
+ }
275
+ return '{' + out + '}';
276
+ }
218
277
  /**
219
278
  * Converts an arbitrary value to an Error.
220
279
  *
@@ -271,7 +330,7 @@ class AuraNetworkCommand extends NetworkCommand {
271
330
  }
272
331
  }
273
332
 
274
- function buildServiceDescriptor$8() {
333
+ function buildServiceDescriptor$9() {
275
334
  return {
276
335
  type: 'auraNetworkCommandBaseClass',
277
336
  version: '1.0',
@@ -286,6 +345,116 @@ function buildServiceDescriptor$8() {
286
345
  */
287
346
 
288
347
 
348
+ /**
349
+ * An implementation of BaseCommand that allows for extending abstract cache methods
350
+ *
351
+ * @typeParam Data cache result for read operations
352
+ * @typeParam NetworkResult cache result including network metadata
353
+ * @typeParam ExtraServices additional named services needed by a subclass
354
+ */
355
+ class CacheControlCommand extends BaseCommand {
356
+ constructor(services) {
357
+ super();
358
+ this.services = services;
359
+ }
360
+ execute() {
361
+ return this.services.cacheController.execute(this.cacheControlStrategyConfig, (cache) => this.buildRequestRunner(cache));
362
+ }
363
+ buildRequestRunner(cache) {
364
+ return {
365
+ readFromCache: () => this.readFromCache(cache),
366
+ requestFromNetwork: () => this.requestFromNetwork(),
367
+ writeToCache: (networkResult) => this.writeToCache(cache, networkResult),
368
+ };
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Copyright (c) 2022, Salesforce, Inc.,
374
+ * All rights reserved.
375
+ * For full license text, see the LICENSE.txt file
376
+ */
377
+
378
+
379
+ /**
380
+ * An implementation of BaseCommand that allows for extending abstract cache methods
381
+ *
382
+ * @typeParam Data cache result for read operations
383
+ * @typeParam NetworkResult cache result including network metadata
384
+ * @typeParam ExtraServices additional named services needed by a subclass
385
+ */
386
+ class AuraResourceCacheControlCommand extends CacheControlCommand {
387
+ constructor(services) {
388
+ super(services);
389
+ this.services = services;
390
+ this.actionConfig = {
391
+ background: false,
392
+ hotspot: true,
393
+ longRunning: false,
394
+ storable: false,
395
+ };
396
+ }
397
+ execute() {
398
+ return super.execute();
399
+ }
400
+ readFromCache(cache) {
401
+ var _a;
402
+ return resolvedPromiseLike(ok((_a = cache.get(this.buildKey())) === null || _a === void 0 ? void 0 : _a.value));
403
+ }
404
+ requestFromNetwork() {
405
+ return this.convertAuraResponseToData(this.services.auraNetwork(this.endpoint, this.auraParams, this.actionConfig));
406
+ }
407
+ convertAuraResponseToData(responsePromise) {
408
+ return responsePromise
409
+ .then((response) => {
410
+ return ok(response.getReturnValue());
411
+ })
412
+ .catch((error) => {
413
+ if (!error || !error.getError) {
414
+ return err(toError('Failed to get error from response'));
415
+ }
416
+ const actionErrors = error.getError();
417
+ if (actionErrors.length > 0) {
418
+ return err(new AuraError(actionErrors));
419
+ }
420
+ return err(toError('Error fetching component'));
421
+ });
422
+ }
423
+ writeToCache(cache, networkResult) {
424
+ if (networkResult.isOk()) {
425
+ cache.set(this.buildKey(), {
426
+ value: networkResult.value,
427
+ metadata: { cacheControl: this.buildCacheControlMetadata(networkResult.value) },
428
+ });
429
+ }
430
+ return resolvedPromiseLike(undefined);
431
+ }
432
+ buildKey() {
433
+ return `{"endpoint":${this.endpoint},"params":${stableJSONStringify$2(this.auraParams)}}`;
434
+ }
435
+ }
436
+ class AuraError extends Error {
437
+ constructor(data) {
438
+ super();
439
+ this.data = data;
440
+ }
441
+ }
442
+
443
+ function buildServiceDescriptor$8() {
444
+ return {
445
+ type: 'auraResourceCacheControlCommand',
446
+ version: '1.0',
447
+ service: AuraResourceCacheControlCommand,
448
+ };
449
+ }
450
+
451
+ /**
452
+ * Copyright (c) 2022, Salesforce, Inc.,
453
+ * All rights reserved.
454
+ * For full license text, see the LICENSE.txt file
455
+ */
456
+
457
+
289
458
  /**
290
459
  * An implementation of NetworkCommand that uses HTTP/fetch as the transport mechanism.
291
460
  */
@@ -1040,7 +1209,7 @@ class CacheController {
1040
1209
 
1041
1210
  function buildServiceDescriptor$1(cache) {
1042
1211
  return {
1043
- type: 'cacheControl',
1212
+ type: 'cacheController',
1044
1213
  version: '1.0',
1045
1214
  service: new CacheController({ cache }),
1046
1215
  };
@@ -1550,9 +1719,9 @@ const composedNetworkAdapter$1 = {
1550
1719
  function e(e){this.message=e;}e.prototype=new Error,e.prototype.name="InvalidCharacterError";"undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(r){var t=String(r).replace(/=+$/,"");if(t.length%4==1)throw new e("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,o,a=0,i=0,c="";o=t.charAt(i++);~o&&(n=a%4?64*n+o:o,a++%4)?c+=String.fromCharCode(255&n>>(-2*a&6)):0)o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(o);return c};function n(e){this.message=e;}n.prototype=new Error,n.prototype.name="InvalidTokenError";
1551
1720
 
1552
1721
  const SFAP_BASE_URL = 'api.salesforce.com';
1722
+ const sfapJwtRepository = new JwtRepository();
1723
+ const sfapJwtManager = new JwtManager(sfapJwtRepository, platformSfapJwtResolver);
1553
1724
  function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
1554
- const jwtRepository = new JwtRepository();
1555
- const jwtManager = new JwtManager(jwtRepository, platformSfapJwtResolver);
1556
1725
  const jwtRequestModifier = ({ baseUri }, [resource, request]) => {
1557
1726
  if (typeof resource !== 'string' && !(resource instanceof URL)) {
1558
1727
  // istanbul ignore else: this will not be tested in NODE_ENV = production for test coverage
@@ -1571,7 +1740,7 @@ function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
1571
1740
  url.protocol = overrideUrl.protocol;
1572
1741
  return [url, request];
1573
1742
  };
1574
- const jwtRequestHeaderInterceptor = buildJwtRequestHeaderInterceptor(jwtManager, jwtRequestModifier);
1743
+ const jwtRequestHeaderInterceptor = buildJwtRequestHeaderInterceptor(sfapJwtManager, jwtRequestModifier);
1575
1744
  const jwtAuthorizedFetchService = buildServiceDescriptor({
1576
1745
  request: [jwtRequestHeaderInterceptor],
1577
1746
  });
@@ -1580,6 +1749,56 @@ function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
1580
1749
  tags: { authenticationScopes: 'sfap_api' },
1581
1750
  };
1582
1751
  }
1752
+ /**
1753
+ * Returns a service descriptor for a fetch service that includes one-off copilot
1754
+ * hacks. This fetch service is not intended for use by anything other than
1755
+ * copilot commands.
1756
+ */
1757
+ function buildCopilotFetchServiceDescriptor(logger) {
1758
+ return {
1759
+ // Note that this layers the Interceptor below directly on top of fetch(). WHen
1760
+ // we switch to JWT authentication this will need to change to incorporate the
1761
+ // Interceptor here with the logic in buildJwtAuthorizedSfapFetchServiceDescriptor()
1762
+ // above.
1763
+ ...buildServiceDescriptor({
1764
+ request: [
1765
+ // Note that this function is VERY closely tied to the fetchParams generated
1766
+ // by copilotStartSessionCommand. Any changes to those parameters will require
1767
+ // corresponding updates to the logic below.
1768
+ (args) => {
1769
+ const [url, requestInit] = args;
1770
+ // ignore anything other than a start session request
1771
+ if (typeof url !== 'string' ||
1772
+ !url.endsWith('/sessions') ||
1773
+ !requestInit ||
1774
+ requestInit.method !== 'POST' ||
1775
+ !requestInit.body ||
1776
+ typeof requestInit.body !== 'string') {
1777
+ return resolvedPromiseLike(args);
1778
+ }
1779
+ return resolvedPromiseLike(sfapJwtManager.getJwt()).then((token) => {
1780
+ // replace the body's instanceConfig.endpoint with the JWT's iss value
1781
+ const body = JSON.parse(requestInit.body);
1782
+ if (!body || !body.instanceConfig || !token.decodedInfo.iss) {
1783
+ logger.warn('skipping injection of endpoint into start session request');
1784
+ }
1785
+ else {
1786
+ body.instanceConfig.endpoint = token.decodedInfo.iss;
1787
+ }
1788
+ return [
1789
+ args[0],
1790
+ {
1791
+ ...args[1],
1792
+ body: JSON.stringify(body),
1793
+ },
1794
+ ];
1795
+ });
1796
+ },
1797
+ ],
1798
+ }),
1799
+ tags: { specialHacksFor: 'copilot' },
1800
+ };
1801
+ }
1583
1802
  function buildUnauthorizedFetchServiceDescriptor() {
1584
1803
  const fetchService = buildServiceDescriptor();
1585
1804
  return {
@@ -1594,21 +1813,27 @@ const PDL_EXECUTE_ASYNC_OPTIONS = {
1594
1813
  };
1595
1814
 
1596
1815
  class PredictivePrefetchPage {
1597
- constructor(context) {
1816
+ constructor(context, similarContext) {
1598
1817
  this.context = context;
1599
- this.similarContext = undefined;
1818
+ this.similarContext = similarContext;
1819
+ }
1820
+ getExactKey() {
1821
+ return { ...this.context };
1822
+ }
1823
+ getSimilarKey() {
1824
+ return { ...this.similarContext };
1600
1825
  }
1601
1826
  }
1602
1827
 
1603
1828
  class LexDefaultPage extends PredictivePrefetchPage {
1604
- constructor(context) {
1605
- super(context);
1829
+ constructor(context, similarContext) {
1830
+ super(context, similarContext);
1606
1831
  }
1607
1832
  supportsRequest(_request) {
1608
1833
  return true;
1609
1834
  }
1610
1835
  buildSaveRequestData(request) {
1611
- return [{ context: this.context, request }];
1836
+ return [{ key: this.getExactKey(), request }];
1612
1837
  }
1613
1838
  resolveSimilarRequest(similarRequest) {
1614
1839
  return similarRequest;
@@ -2379,6 +2604,15 @@ class GetRelatedListInfoBatchRequestStrategy extends LuvioAdapterRequestStrategy
2379
2604
  },
2380
2605
  };
2381
2606
  }
2607
+ isContextDependent(context, request) {
2608
+ // We have a higher degree of confidence of being able to use a similar request when
2609
+ // optional config is not set AND the object type of the page context is the same as the
2610
+ // object type related list is for. This approach is based heavily with early predictions
2611
+ // and the max of 12 aura requests in mind. Same approach is taken in the single version of
2612
+ // this request
2613
+ return (context.objectApiName === request.config.parentObjectApiName &&
2614
+ request.config.recordTypeId === undefined);
2615
+ }
2382
2616
  canCombine(reqA, reqB) {
2383
2617
  return reqA.parentObjectApiName === reqB.parentObjectApiName;
2384
2618
  }
@@ -2400,9 +2634,11 @@ class GetRelatedListInfoRequestStrategy extends LuvioAdapterRequestStrategy {
2400
2634
  * @override
2401
2635
  */
2402
2636
  isContextDependent(context, request) {
2403
- // we have a higher degree of confidence of being able to use a similar request when
2637
+ // We have a higher degree of confidence of being able to use a similar request when
2404
2638
  // optional config is not set AND the object type of the page context is the same as the
2405
- // object type related list is for
2639
+ // object type related list is for. This approach is based heavily with early predictions
2640
+ // and the max of 12 aura requests in mind. Same approach is taken in the batch version of
2641
+ // this request
2406
2642
  return (context.objectApiName === request.config.parentObjectApiName &&
2407
2643
  this.isRequiredOnlyConfig(request.config));
2408
2644
  }
@@ -2597,10 +2833,13 @@ class PrefetchRepository {
2597
2833
  existingRequestEntry.requestMetadata.requestTime = requestTime;
2598
2834
  }
2599
2835
  });
2600
- const { modifyBeforeSaveHook } = this.options;
2836
+ const { modifyBeforeSaveHook, modifyPageBeforeSavingHook } = this.options;
2601
2837
  if (modifyBeforeSaveHook !== undefined) {
2602
2838
  page.requests = modifyBeforeSaveHook(page.requests);
2603
2839
  }
2840
+ if (modifyPageBeforeSavingHook !== undefined) {
2841
+ modifyPageBeforeSavingHook(page);
2842
+ }
2604
2843
  setPromises.push(this.storage.set(id, page));
2605
2844
  }
2606
2845
  this.clearRequestBuffer();
@@ -2619,10 +2858,13 @@ class PrefetchRepository {
2619
2858
  this.requestBuffer.set(identifier, batchForKey);
2620
2859
  }
2621
2860
  getPage(key) {
2622
- const identifier = stableJSONStringify$1(key);
2861
+ const identifier = this.getKeyId(key);
2623
2862
  return this.storage.get(identifier);
2624
2863
  }
2625
2864
  getPageRequests(key) {
2865
+ if (!key) {
2866
+ return [];
2867
+ }
2626
2868
  const page = this.getPage(key);
2627
2869
  if (page === undefined) {
2628
2870
  return [];
@@ -2920,21 +3162,23 @@ const RECORD_HOME_SUPPORTED_ADAPTERS = new Set([
2920
3162
  GET_RELATED_LIST_RECORDS_BATCH_ADAPTER_NAME,
2921
3163
  GET_RELATED_LIST_RECORDS_ADAPTER_NAME,
2922
3164
  GET_RELATED_LISTS_ACTIONS_ADAPTER_NAME,
3165
+ 'templateApi', // external - getTemplateDescriptorWithExpansionBundle
2923
3166
  ]);
2924
3167
  class RecordHomePage extends LexDefaultPage {
2925
3168
  constructor(context, requestStrategyManager, options) {
2926
- super(context);
3169
+ super(context, {
3170
+ ...context,
3171
+ recordId: '*',
3172
+ });
2927
3173
  this.requestStrategyManager = requestStrategyManager;
2928
3174
  this.options = options;
2929
- const { recordId: _, ...rest } = this.context;
2930
- this.similarContext = {
2931
- recordId: '*',
2932
- ...rest,
2933
- };
2934
3175
  }
2935
3176
  supportsRequest(request) {
2936
3177
  return RECORD_HOME_SUPPORTED_ADAPTERS.has(request.adapterName);
2937
3178
  }
3179
+ getExactKey() {
3180
+ return RecordHomePage.contextToExactKey(this.context);
3181
+ }
2938
3182
  buildSaveRequestData(request) {
2939
3183
  const requestBuckets = [];
2940
3184
  const { adapterName } = request;
@@ -2944,7 +3188,7 @@ class RecordHomePage extends LexDefaultPage {
2944
3188
  }
2945
3189
  if (matchingRequestStrategy.isContextDependent(this.context, request)) {
2946
3190
  requestBuckets.push({
2947
- context: this.similarContext,
3191
+ key: this.getSimilarKey(),
2948
3192
  request: matchingRequestStrategy.transformForSaveSimilarRequest(request),
2949
3193
  });
2950
3194
  // When `options.useExactMatchesPlus` is not enabled, we can save this request on the similar bucket only
@@ -2954,7 +3198,7 @@ class RecordHomePage extends LexDefaultPage {
2954
3198
  }
2955
3199
  if (!matchingRequestStrategy.onlySavedInSimilar) {
2956
3200
  requestBuckets.push({
2957
- context: this.context,
3201
+ key: this.getExactKey(),
2958
3202
  request: matchingRequestStrategy.transformForSave(request),
2959
3203
  });
2960
3204
  }
@@ -3005,6 +3249,10 @@ class RecordHomePage extends LexDefaultPage {
3005
3249
  context.recordId !== undefined &&
3006
3250
  context.type === 'recordPage');
3007
3251
  }
3252
+ static contextToExactKey(context) {
3253
+ const { recordTypeId: _, ...key } = context;
3254
+ return key;
3255
+ }
3008
3256
  }
3009
3257
 
3010
3258
  const OBJECT_HOME_SUPPORTED_ADAPTERS = new Set([
@@ -3016,10 +3264,9 @@ const OBJECT_HOME_SUPPORTED_ADAPTERS = new Set([
3016
3264
  ]);
3017
3265
  class ObjectHomePage extends LexDefaultPage {
3018
3266
  constructor(context, requestStrategyManager, options) {
3019
- super(context);
3267
+ super(context, context);
3020
3268
  this.requestStrategyManager = requestStrategyManager;
3021
3269
  this.options = options;
3022
- this.similarContext = context;
3023
3270
  }
3024
3271
  supportsRequest(request) {
3025
3272
  return OBJECT_HOME_SUPPORTED_ADAPTERS.has(request.adapterName);
@@ -3033,7 +3280,7 @@ class ObjectHomePage extends LexDefaultPage {
3033
3280
  }
3034
3281
  if (matchingRequestStrategy.isContextDependent(this.context, request)) {
3035
3282
  requestBuckets.push({
3036
- context: this.similarContext,
3283
+ key: this.getSimilarKey(),
3037
3284
  request: matchingRequestStrategy.transformForSaveSimilarRequest(request),
3038
3285
  });
3039
3286
  // When `options.useExactMatchesPlus` is not enabled, we can save this request on the similar bucket only
@@ -3042,7 +3289,7 @@ class ObjectHomePage extends LexDefaultPage {
3042
3289
  }
3043
3290
  }
3044
3291
  requestBuckets.push({
3045
- context: this.context,
3292
+ key: this.getExactKey(),
3046
3293
  request: matchingRequestStrategy.transformForSave(request),
3047
3294
  });
3048
3295
  return requestBuckets;
@@ -3721,10 +3968,10 @@ class ApplicationPredictivePrefetcher {
3721
3968
  if (this.page.supportsRequest(request)) {
3722
3969
  const saveBuckets = this.page.buildSaveRequestData(request);
3723
3970
  saveBuckets.forEach((saveBucket) => {
3724
- const { request: requestToSave, context } = saveBucket;
3971
+ const { request: requestToSave, key } = saveBucket;
3725
3972
  // No need to differentiate from predictions requests because these
3726
3973
  // are made from the adapters factory, which are not prediction aware.
3727
- this.repository.saveRequest(context, requestToSave);
3974
+ this.repository.saveRequest(key, requestToSave);
3728
3975
  });
3729
3976
  }
3730
3977
  return Promise.resolve().then();
@@ -3732,8 +3979,8 @@ class ApplicationPredictivePrefetcher {
3732
3979
  }
3733
3980
  async predict() {
3734
3981
  const alwaysRequests = this.page.getAlwaysRunRequests();
3735
- const similarPageRequests = await this.getSimilarPageRequests();
3736
- const exactPageRequests = await this.getExactPageRequest();
3982
+ const similarPageRequests = this.getSimilarPageRequests();
3983
+ const exactPageRequests = this.getExactPageRequests();
3737
3984
  // Always requests can't be reduced in - Some of them are essential to keep the page rendering at the beginning.
3738
3985
  const reducedRequests = this.requestRunner
3739
3986
  .reduceRequests([...exactPageRequests, ...similarPageRequests])
@@ -3744,13 +3991,9 @@ class ApplicationPredictivePrefetcher {
3744
3991
  return Promise.all(predictedRequests.map((request) => this.requestRunner.runRequest(request))).then();
3745
3992
  }
3746
3993
  getPredictionSummary() {
3747
- const exactPageRequests = this.repository.getPageRequests(this.context) || [];
3748
- const similarPageRequests = this.page.similarContext !== undefined
3749
- ? this.repository.getPageRequests(this.page.similarContext)
3750
- : [];
3751
3994
  return {
3752
- exact: exactPageRequests.length,
3753
- similar: similarPageRequests.length,
3995
+ exact: this.getExactPageRequests().length,
3996
+ similar: this.getSimilarPageRequests().length,
3754
3997
  totalRequestCount: this.totalRequestCount,
3755
3998
  };
3756
3999
  }
@@ -3759,22 +4002,15 @@ class ApplicationPredictivePrefetcher {
3759
4002
  return summary.exact > 0 || summary.similar > 0;
3760
4003
  }
3761
4004
  getSimilarPageRequests() {
3762
- let resolvedSimilarPageRequests = [];
3763
- if (this.page.similarContext !== undefined) {
3764
- const similarPageRequests = this.repository.getPageRequests(this.page.similarContext);
3765
- if (similarPageRequests !== undefined) {
3766
- resolvedSimilarPageRequests = similarPageRequests.map((entry) => {
3767
- return {
3768
- ...entry,
3769
- request: this.page.resolveSimilarRequest(entry.request),
3770
- };
3771
- });
3772
- }
3773
- }
3774
- return resolvedSimilarPageRequests;
4005
+ return this.repository.getPageRequests(this.page.getSimilarKey()).map((entry) => {
4006
+ return {
4007
+ ...entry,
4008
+ request: this.page.resolveSimilarRequest(entry.request),
4009
+ };
4010
+ });
3775
4011
  }
3776
- getExactPageRequest() {
3777
- return this.repository.getPageRequests(this.context) || [];
4012
+ getExactPageRequests() {
4013
+ return this.repository.getPageRequests(this.page.getExactKey()) || [];
3778
4014
  }
3779
4015
  }
3780
4016
 
@@ -3838,6 +4074,7 @@ function predictNonBoxcarableRequest(nonBoxcaredPredictions, requestRunner) {
3838
4074
  const reducedPredictions = requestRunner.reduceRequests(nonBoxcaredPredictions);
3839
4075
  reducedPredictions.map((request) => requestRunner.runRequest(request.request));
3840
4076
  }
4077
+ const DEFAULT_RECORD_TYPE_ID = '012000000000000AAA';
3841
4078
  class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
3842
4079
  constructor(context, repository, requestRunner,
3843
4080
  // These strategies need to be in sync with the "predictiveDataLoadCapable" list
@@ -3850,6 +4087,17 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
3850
4087
  }
3851
4088
  getPage() {
3852
4089
  if (RecordHomePage.handlesContext(this.context)) {
4090
+ /*
4091
+ * `recordTypeId` is required in order to create similar request keys. However, the means by which it is
4092
+ * obtained varies based on when in the app lifecycle predictions are requested.
4093
+ */
4094
+ // check context for record type
4095
+ if (!this.context.recordTypeId) {
4096
+ // don't have it (i.e., early predictions), so need try to obtain via exact matches
4097
+ const exact = this.repository.getPage(RecordHomePage.contextToExactKey(this.context));
4098
+ // use found recordTypeId, otherwise fallback to default
4099
+ this.context.recordTypeId = (exact && exact.recordTypeId) || DEFAULT_RECORD_TYPE_ID;
4100
+ }
3853
4101
  return new RecordHomePage(this.context, this.requestStrategyManager, this.options);
3854
4102
  }
3855
4103
  else if (ObjectHomePage.handlesContext(this.context)) {
@@ -3858,7 +4106,7 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
3858
4106
  return new LexDefaultPage(this.context);
3859
4107
  }
3860
4108
  getAllPageRequests() {
3861
- const exactPageRequests = this.getExactPageRequest();
4109
+ const exactPageRequests = this.getExactPageRequests();
3862
4110
  let similarPageRequests = this.getSimilarPageRequests();
3863
4111
  if (exactPageRequests.length > 0 && this.options.useExactMatchesPlus === true) {
3864
4112
  similarPageRequests = similarPageRequests.filter((requestEntry) => {
@@ -3871,7 +4119,7 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
3871
4119
  async predict() {
3872
4120
  const alwaysRequests = this.page.getAlwaysRunRequests();
3873
4121
  const pageRequests = this.getAllPageRequests();
3874
- // IMPORTANT: Because there's no way to diferentiate a cmpDef prediction from the page
4122
+ // IMPORTANT: Because there's no way to differentiate a cmpDef prediction from the page
3875
4123
  // requesting the cmpDef, we need to predict cmpDefs before we start watching
3876
4124
  // for predictions in the page. Having this code after an
3877
4125
  // await will make the predictions to be saved as predictions too.
@@ -4048,7 +4296,7 @@ function getEnvironmentSetting(name) {
4048
4296
  }
4049
4297
  return undefined;
4050
4298
  }
4051
- // version: 1.320.0-e3e5f3d984
4299
+ // version: 1.322.0-87f682c9f3
4052
4300
 
4053
4301
  const forceRecordTransactionsDisabled = getEnvironmentSetting(EnvironmentSettings.ForceRecordTransactionsDisabled);
4054
4302
  //TODO: Some duplication here that can be most likely moved to a util class
@@ -4552,6 +4800,11 @@ function setupPredictivePrefetcher(luvio) {
4552
4800
  const requestRunner = new LexRequestRunner(requestStrategyManager);
4553
4801
  const repository = new PrefetchRepository(storage, {
4554
4802
  modifyBeforeSaveHook: (requests) => requestRunner.reduceRequests(requests),
4803
+ modifyPageBeforeSavingHook: (page) => {
4804
+ if (RecordHomePage.handlesContext(__lexPrefetcher.context)) {
4805
+ page.recordTypeId = __lexPrefetcher.context.recordTypeId;
4806
+ }
4807
+ },
4555
4808
  });
4556
4809
  const inflightRequestLimit = applyPredictionRequestLimit.isOpen({ fallback: false })
4557
4810
  ? getInflightRequestLimit()
@@ -4630,13 +4883,12 @@ function buildPredictorForContext(context) {
4630
4883
  }
4631
4884
  const currentContext = __lexPrefetcher.context;
4632
4885
  let isSameContext = false;
4633
- if (currentContext && currentContext.type === 'recordPage') {
4634
- const rhPageContext = currentContext;
4886
+ if (RecordHomePage.handlesContext(currentContext)) {
4635
4887
  isSameContext =
4636
- rhPageContext.actionName === context.actionName &&
4637
- rhPageContext.objectApiName === context.objectApiName &&
4638
- rhPageContext.recordId === context.recordId &&
4639
- rhPageContext.type === context.type;
4888
+ currentContext.actionName === context.actionName &&
4889
+ currentContext.objectApiName === context.objectApiName &&
4890
+ currentContext.recordId === context.recordId &&
4891
+ currentContext.type === context.type;
4640
4892
  }
4641
4893
  // // This chunk configures which page we're going to use to try and preload.
4642
4894
  __lexPrefetcher.context = context;
@@ -4707,14 +4959,16 @@ function initializeOneStore() {
4707
4959
  instrumentationServiceDescriptor,
4708
4960
  buildUnauthorizedFetchServiceDescriptor(),
4709
4961
  buildJwtAuthorizedSfapFetchServiceDescriptor(loggerService),
4962
+ buildCopilotFetchServiceDescriptor(loggerService),
4710
4963
  buildAuraNetworkService(),
4711
4964
  buildServiceDescriptor$4(instrumentationServiceDescriptor.service),
4712
4965
  buildServiceDescriptor$1(cacheServiceDescriptor.service),
4713
- buildServiceDescriptor$8(),
4714
- buildServiceDescriptor$7(),
4715
4966
  buildServiceDescriptor$9(),
4967
+ buildServiceDescriptor$7(),
4968
+ buildServiceDescriptor$a(),
4716
4969
  buildServiceDescriptor$6(),
4717
4970
  buildServiceDescriptor$5(),
4971
+ buildServiceDescriptor$8(),
4718
4972
  ];
4719
4973
  serviceBroker.publish(services);
4720
4974
  }
@@ -4743,4 +4997,4 @@ function ldsEngineCreator() {
4743
4997
  }
4744
4998
 
4745
4999
  export { LexRequestStrategy, buildPredictorForContext, ldsEngineCreator as default, initializeLDS, initializeOneStore, registerRequestStrategy, saveRequestAsPrediction, unregisterRequestStrategy, whenPredictionsReady };
4746
- // version: 1.320.0-85be789480
5000
+ // version: 1.322.0-6aa042602a
@@ -1,6 +1,12 @@
1
1
  import { type FetchServiceDescriptor } from '@luvio/service-fetch-network/v1';
2
2
  import { type LoggerService } from '@luvio/utils';
3
3
  export declare function buildJwtAuthorizedSfapFetchServiceDescriptor(logger: LoggerService): FetchServiceDescriptor;
4
+ /**
5
+ * Returns a service descriptor for a fetch service that includes one-off copilot
6
+ * hacks. This fetch service is not intended for use by anything other than
7
+ * copilot commands.
8
+ */
9
+ export declare function buildCopilotFetchServiceDescriptor(logger: LoggerService): FetchServiceDescriptor;
4
10
  export declare const lightningJwtResolver: {
5
11
  getJwt(): Promise<any>;
6
12
  };
@@ -9,9 +9,9 @@ export type RequestEntry<Request> = {
9
9
  };
10
10
  };
11
11
  /**
12
- * Request and Context data to be saved.
12
+ * Request and context-based Key data to be saved.
13
13
  */
14
14
  export type SaveRequestData<Request, Context> = {
15
15
  request: Request;
16
- context: Context;
16
+ key: Context;
17
17
  };
@@ -2,10 +2,10 @@ import type { BaseAdapterRequest } from '../request-strategy';
2
2
  import { PredictivePrefetchPage } from './predictive-prefetch-page';
3
3
  export type DefaultPageContext = Record<string, any>;
4
4
  export declare class LexDefaultPage<Request extends BaseAdapterRequest, Context extends DefaultPageContext> extends PredictivePrefetchPage<Request, Context> {
5
- constructor(context: Context);
5
+ constructor(context: Context, similarContext?: Context);
6
6
  supportsRequest(_request: Request): boolean;
7
7
  buildSaveRequestData(request: Request): {
8
- context: Context;
8
+ key: Context;
9
9
  request: Request;
10
10
  }[];
11
11
  resolveSimilarRequest(similarRequest: Request): Request;
@@ -11,11 +11,10 @@ export declare const OBJECT_HOME_SUPPORTED_ADAPTERS: Set<string>;
11
11
  export declare class ObjectHomePage extends LexDefaultPage<LexRequest, ObjectHomePageContext> {
12
12
  private requestStrategyManager;
13
13
  private options;
14
- similarContext: ObjectHomePageContext;
15
14
  constructor(context: ObjectHomePageContext, requestStrategyManager: RequestStrategyManager, options: LexPrefetcherOptions);
16
15
  supportsRequest(request: LexRequest): boolean;
17
16
  buildSaveRequestData(request: LexRequest): {
18
- context: ObjectHomePageContext;
17
+ key: ObjectHomePageContext;
19
18
  request: LexRequest<unknown>;
20
19
  }[];
21
20
  resolveSimilarRequest(similarRequest: LexRequest): LexRequest;
@@ -1,10 +1,12 @@
1
1
  import type { SaveRequestData } from '../common';
2
2
  export declare abstract class PredictivePrefetchPage<Request, Context> {
3
- context: Context;
4
- similarContext: Partial<Context> | undefined;
5
- constructor(context: Context);
3
+ protected context: Context;
4
+ protected similarContext?: Context | undefined;
5
+ protected constructor(context: Context, similarContext?: Context | undefined);
6
6
  abstract supportsRequest(request: Request): boolean;
7
7
  abstract buildSaveRequestData(request: Request): SaveRequestData<Request, Context>[];
8
8
  abstract resolveSimilarRequest(similarRequest: Request): Request;
9
9
  abstract getAlwaysRunRequests(): Request[];
10
+ getExactKey(): Context;
11
+ getSimilarKey(): Context;
10
12
  }
@@ -6,17 +6,18 @@ export declare const RECORD_HOME_SUPPORTED_ADAPTERS: Set<string>;
6
6
  export type RecordHomePageContext = {
7
7
  objectApiName: string;
8
8
  recordId: string;
9
+ recordTypeId?: string;
9
10
  actionName: string;
10
11
  type: 'recordPage';
11
12
  };
12
13
  export declare class RecordHomePage extends LexDefaultPage<LexRequest, RecordHomePageContext> {
13
14
  private requestStrategyManager;
14
15
  private options;
15
- similarContext: RecordHomePageContext;
16
16
  constructor(context: RecordHomePageContext, requestStrategyManager: RequestStrategyManager, options: LexPrefetcherOptions);
17
17
  supportsRequest(request: LexRequest): boolean;
18
+ getExactKey(): RecordHomePageContext;
18
19
  buildSaveRequestData(request: LexRequest): {
19
- context: RecordHomePageContext;
20
+ key: RecordHomePageContext;
20
21
  request: LexRequest<unknown>;
21
22
  }[];
22
23
  resolveSimilarRequest(similarRequest: LexRequest): LexRequest;
@@ -35,4 +36,5 @@ export declare class RecordHomePage extends LexDefaultPage<LexRequest, RecordHom
35
36
  */
36
37
  shouldExecuteAlwaysRequestByThemself(): boolean;
37
38
  static handlesContext(context: DefaultPageContext): context is RecordHomePageContext;
39
+ static contextToExactKey(context: RecordHomePageContext): RecordHomePageContext;
38
40
  }
@@ -1,7 +1,7 @@
1
+ import { LexDefaultPage } from '../pages';
1
2
  import { ApplicationPredictivePrefetcher } from './predictive-prefetcher';
2
- import { LexDefaultPage } from '../pages/lex-default-page';
3
3
  import type { RequestRunner } from '../request-runner';
4
- import type { PrefetchRepository } from '../repository/prefetch-repository';
4
+ import type { PrefetchRepository } from '../repository';
5
5
  import type { RequestEntry } from '../common';
6
6
  import type { LexContext, LexPrefetcherOptions, LexRequest } from '../lex';
7
7
  import type { RequestStrategyManager } from '../request-strategy-manager/request-strategy-manager';
@@ -9,7 +9,7 @@ export declare class LexPredictivePrefetcher extends ApplicationPredictivePrefet
9
9
  protected options: LexPrefetcherOptions;
10
10
  page: LexDefaultPage<LexRequest, LexContext>;
11
11
  private requestStrategyManager;
12
- constructor(context: LexContext, repository: PrefetchRepository, requestRunner: RequestRunner<LexRequest>, requestStrategyManager: RequestStrategyManager, options: LexPrefetcherOptions);
12
+ constructor(context: LexContext, repository: PrefetchRepository<LexRequest>, requestRunner: RequestRunner<LexRequest>, requestStrategyManager: RequestStrategyManager, options: LexPrefetcherOptions);
13
13
  getPage(): LexDefaultPage<LexRequest, LexContext>;
14
14
  getAllPageRequests(): RequestEntry<LexRequest>[];
15
15
  predict(): Promise<void>;
@@ -1,16 +1,16 @@
1
1
  import type { PrefetchRepository } from '../repository';
2
2
  import type { PredictivePrefetchPage } from '../pages';
3
3
  import type { RequestRunner } from '../request-runner';
4
- import type { RequestEntry } from '../common';
5
- export declare abstract class ApplicationPredictivePrefetcher<Request, Context extends Record<string, any>> {
6
- protected repository: PrefetchRepository;
4
+ import type { BaseAdapterRequest } from '../request-strategy';
5
+ export declare abstract class ApplicationPredictivePrefetcher<Request extends BaseAdapterRequest, Context extends Record<string, any>> {
6
+ protected repository: PrefetchRepository<Request>;
7
7
  protected requestRunner: RequestRunner<Request>;
8
8
  private _context;
9
9
  isRecording: boolean;
10
10
  totalRequestCount: Number;
11
11
  page: PredictivePrefetchPage<Request, Context>;
12
12
  queuedPredictionRequests: Request[];
13
- constructor(context: Context, repository: PrefetchRepository, requestRunner: RequestRunner<Request>);
13
+ protected constructor(context: Context, repository: PrefetchRepository<Request>, requestRunner: RequestRunner<Request>);
14
14
  abstract getPage(): PredictivePrefetchPage<Request, Context>;
15
15
  set context(value: Context);
16
16
  get context(): Context;
@@ -24,6 +24,11 @@ export declare abstract class ApplicationPredictivePrefetcher<Request, Context e
24
24
  totalRequestCount: Number;
25
25
  };
26
26
  hasPredictions(): boolean;
27
- getSimilarPageRequests(): RequestEntry<Request>[];
28
- getExactPageRequest(): RequestEntry<Request>[];
27
+ getSimilarPageRequests(): {
28
+ request: Request;
29
+ requestMetadata: {
30
+ requestTime: number;
31
+ };
32
+ }[];
33
+ getExactPageRequests(): import("../common").RequestEntry<Request>[];
29
34
  }
@@ -7,23 +7,25 @@ export type History = {
7
7
  };
8
8
  export type PageEntry<Request> = {
9
9
  id: string;
10
+ recordTypeId?: string;
10
11
  requests: RequestEntry<Request>[];
11
12
  };
12
- export type PrefetchRepositoryOptions = {
13
- modifyBeforeSaveHook?: (requests: RequestEntry<any>[]) => RequestEntry<any>[];
13
+ export type PrefetchRepositoryOptions<Request> = {
14
+ modifyBeforeSaveHook?: (requests: RequestEntry<Request>[]) => RequestEntry<Request>[];
15
+ modifyPageBeforeSavingHook?: (page: PageEntry<Request>) => void;
14
16
  };
15
- export declare class PrefetchRepository {
17
+ export declare class PrefetchRepository<Request> {
16
18
  private storage;
17
19
  private options;
18
20
  private requestBuffer;
19
- constructor(storage: PrefetchStorage, options?: PrefetchRepositoryOptions);
21
+ constructor(storage: PrefetchStorage, options?: PrefetchRepositoryOptions<Request>);
20
22
  clearRequestBuffer(): void;
21
23
  pageStartTime: number;
22
24
  markPageStart(): void;
23
25
  flushRequestsToStorage(): Promise<void>;
24
26
  getKeyId(key: Key): string;
25
27
  saveRequest<Request>(key: Key, request: Request): void;
26
- getPage<Request>(key: Key): PageEntry<Request> | undefined;
27
- getPageRequests<Request>(key: Key): RequestEntry<Request>[];
28
+ getPage(key: Key): PageEntry<Request> | undefined;
29
+ getPageRequests(key: Key): RequestEntry<Request>[];
28
30
  }
29
31
  export {};
@@ -6,6 +6,7 @@ export type GetRelatedListInfoBatchRequest = {
6
6
  };
7
7
  type GetRelatedListInfoBatchContext = {
8
8
  objectApiName: string;
9
+ recordTypeId: string;
9
10
  };
10
11
  export declare const GET_RELATED_LIST_INFO_BATCH_ADAPTER_NAME = "getRelatedListInfoBatch";
11
12
  export declare class GetRelatedListInfoBatchRequestStrategy extends LuvioAdapterRequestStrategy<GetRelatedListInfoBatchConfig, GetRelatedListInfoBatchRequest, GetRelatedListInfoBatchContext> {
@@ -16,6 +17,7 @@ export declare class GetRelatedListInfoBatchRequestStrategy extends LuvioAdapter
16
17
  * @override
17
18
  */
18
19
  transformForSave(request: GetRelatedListInfoBatchRequest): GetRelatedListInfoBatchRequest;
20
+ isContextDependent(context: GetRelatedListInfoBatchContext, request: GetRelatedListInfoBatchRequest): boolean;
19
21
  canCombine(reqA: GetRelatedListInfoBatchConfig, reqB: GetRelatedListInfoBatchConfig): boolean;
20
22
  combineRequests(reqA: GetRelatedListInfoBatchConfig, reqB: GetRelatedListInfoBatchConfig): GetRelatedListInfoBatchConfig;
21
23
  }
@@ -8,6 +8,7 @@ export type GetRelatedListInfoRequest = {
8
8
  };
9
9
  type GetRelatedListInfoContext = {
10
10
  objectApiName: string;
11
+ recordTypeId: string;
11
12
  };
12
13
  export declare const GET_RELATED_LIST_INFO_ADAPTER_NAME = "getRelatedListInfo";
13
14
  export declare class GetRelatedListInfoRequestStrategy extends LuvioAdapterRequestStrategy<GetRelatedListInfoConfig, GetRelatedListInfoRequest, GetRelatedListInfoContext> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-aura",
3
- "version": "1.320.0",
3
+ "version": "1.322.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Aura runtime",
6
6
  "main": "dist/ldsEngineCreator.js",
@@ -34,33 +34,34 @@
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.11.0",
38
- "@salesforce/lds-adapters-apex": "^1.320.0",
39
- "@salesforce/lds-adapters-uiapi": "^1.320.0",
37
+ "@luvio/service-broker": "5.13.0",
38
+ "@salesforce/lds-adapters-apex": "^1.322.0",
39
+ "@salesforce/lds-adapters-uiapi": "^1.322.0",
40
40
  "@salesforce/lds-adapters-uiapi-lex": "^1.302.0",
41
- "@salesforce/lds-ads-bridge": "^1.320.0",
42
- "@salesforce/lds-aura-storage": "^1.320.0",
43
- "@salesforce/lds-bindings": "^1.320.0",
44
- "@salesforce/lds-instrumentation": "^1.320.0",
45
- "@salesforce/lds-network-aura": "^1.320.0",
46
- "@salesforce/lds-network-fetch-with-jwt": "^1.320.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"
47
47
  },
48
48
  "dependencies": {
49
- "@luvio/command-aura-network": "5.11.0",
50
- "@luvio/command-fetch-network": "5.11.0",
51
- "@luvio/command-network": "5.11.0",
52
- "@luvio/command-sse": "5.11.0",
53
- "@luvio/command-streaming": "5.11.0",
54
- "@luvio/network-adapter-composable": "0.156.4",
55
- "@luvio/network-adapter-fetch": "0.156.4",
56
- "@luvio/service-aura-network": "5.11.0",
57
- "@luvio/service-cache": "5.11.0",
58
- "@luvio/service-cache-control": "5.11.0",
59
- "@luvio/service-fetch-network": "5.11.0",
60
- "@luvio/service-instrument-command": "5.11.0",
61
- "@luvio/service-store": "5.11.0",
62
- "@luvio/utils": "5.11.0",
63
- "@salesforce/lds-adapters-uiapi-lex": "^1.320.0"
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",
55
+ "@luvio/network-adapter-composable": "0.156.5",
56
+ "@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"
64
65
  },
65
66
  "luvioBundlesize": [
66
67
  {