@salesforce/lds-runtime-aura 1.303.0 → 1.305.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.
@@ -27,14 +27,16 @@ import { serviceBroker } from 'force/luvioServiceBroker5';
27
27
  import oneStoreEnabled from '@salesforce/gate/lds.oneStoreEnabled.ltng';
28
28
  import oneStoreUiapiEnabled from '@salesforce/gate/lds.oneStoreUiapiEnabled.ltng';
29
29
  import { getDefinition, executeGlobalControllerRawResponse } from 'aura';
30
- import { buildJwtNetworkAdapter } from 'force/ldsNetworkFetchWithJwt';
31
- import auraNetworkAdapter, { dispatchAuraAction, defaultActionConfig, instrument as instrument$1, forceRecordTransactionsDisabled, ldsNetworkAdapterInstrument } from 'force/ldsNetwork';
32
- import { LRUCache, instrumentAdapter, instrumentLuvio, setupInstrumentation as setupInstrumentation$1, logObjectInfoChanged as logObjectInfoChanged$1, updatePercentileHistogramMetric, incrementCounterMetric, incrementGetRecordNotifyChangeAllowCount, incrementGetRecordNotifyChangeDropCount, incrementNotifyRecordUpdateAvailableAllowCount, incrementNotifyRecordUpdateAvailableDropCount, setLdsAdaptersUiapiInstrumentation, setLdsNetworkAdapterInstrumentation, executeAsyncActivity, METRIC_KEYS, onIdleDetected } from 'force/ldsInstrumentation';
33
- import { REFRESH_ADAPTER_EVENT, ADAPTER_UNFULFILLED_ERROR, instrument as instrument$2 } from 'force/ldsBindings';
30
+ import { buildJwtNetworkAdapter, instrument as instrument$2, setupLexJwtNetworkAdapter } from 'force/ldsNetworkFetchWithJwt';
31
+ import auraNetworkAdapter, { dispatchAuraAction, defaultActionConfig, instrument as instrument$1, forceRecordTransactionsDisabled as forceRecordTransactionsDisabled$1, ldsNetworkAdapterInstrument, CrudEventState, CrudEventType, UIAPI_RECORDS_PATH, UIAPI_RELATED_LIST_RECORDS_BATCH_PATH, UIAPI_RELATED_LIST_RECORDS_PATH } from 'force/ldsNetwork';
32
+ import { LRUCache, instrumentAdapter, instrumentLuvio, setupInstrumentation as setupInstrumentation$1, logObjectInfoChanged as logObjectInfoChanged$1, updatePercentileHistogramMetric, incrementCounterMetric, incrementGetRecordNotifyChangeAllowCount, incrementGetRecordNotifyChangeDropCount, incrementNotifyRecordUpdateAvailableAllowCount, incrementNotifyRecordUpdateAvailableDropCount, setLdsAdaptersUiapiInstrumentation, logError, setLdsNetworkAdapterInstrumentation, executeAsyncActivity, METRIC_KEYS, onIdleDetected } from 'force/ldsInstrumentation';
33
+ import { REFRESH_ADAPTER_EVENT, ADAPTER_UNFULFILLED_ERROR, instrument as instrument$3 } from 'force/ldsBindings';
34
34
  import { counter, registerCacheStats, perfStart, perfEnd, registerPeriodicLogger, interaction, timer } from 'instrumentation/service';
35
- import { instrument as instrument$3 } from 'force/adsBridge';
35
+ import { instrument as instrument$4 } from 'force/adsBridge';
36
36
  import { withRegistration, register, setDefaultLuvio } from 'force/ldsEngine';
37
37
  import { createStorage, clearStorages } from 'force/ldsStorage';
38
+ import useHttpInsteadAuraTransport from '@salesforce/gate/lds.useHttpInsteadAuraTransport';
39
+ import { ThirdPartyTracker } from 'instrumentation:beaconLib';
38
40
  import { getObjectInfo, getObjectInfos } from 'force/ldsAdaptersUiapiLex';
39
41
 
40
42
  /**
@@ -1696,9 +1698,15 @@ class LexDefaultPage extends PredictivePrefetchPage {
1696
1698
  getAlwaysRunRequests() {
1697
1699
  return [];
1698
1700
  }
1701
+ shouldReduceAlwaysRequestsWithPredictions() {
1702
+ return true;
1703
+ }
1704
+ shouldExecuteAlwaysRequestByThemself() {
1705
+ return false;
1706
+ }
1699
1707
  }
1700
1708
 
1701
- class RecordHomePage extends PredictivePrefetchPage {
1709
+ class RecordHomePage extends LexDefaultPage {
1702
1710
  constructor(context, requestStrategies, options) {
1703
1711
  super(context);
1704
1712
  this.requestStrategies = requestStrategies;
@@ -1753,6 +1761,23 @@ class RecordHomePage extends PredictivePrefetchPage {
1753
1761
  },
1754
1762
  ];
1755
1763
  }
1764
+ /**
1765
+ * In RH, we know that there will be predictions, and we want to reduce the always requests (getRecord(id, type))
1766
+ * with one of the predictions in case some request containing the fields was missed in the predictions.
1767
+ *
1768
+ * @returns true
1769
+ */
1770
+ shouldReduceAlwaysRequestsWithPredictions() {
1771
+ return true;
1772
+ }
1773
+ /**
1774
+ * In RH, we should execute the getRecord(id, type) by itself as we want the result asap, so
1775
+ * it does not stop rendering.
1776
+ * @returns true
1777
+ */
1778
+ shouldExecuteAlwaysRequestByThemself() {
1779
+ return true;
1780
+ }
1756
1781
  static handlesContext(context) {
1757
1782
  const maybeRecordHomePageContext = context;
1758
1783
  return (maybeRecordHomePageContext !== undefined &&
@@ -1763,7 +1788,7 @@ class RecordHomePage extends PredictivePrefetchPage {
1763
1788
  }
1764
1789
  }
1765
1790
 
1766
- class ObjectHomePage extends PredictivePrefetchPage {
1791
+ class ObjectHomePage extends LexDefaultPage {
1767
1792
  constructor(context, requestStrategies, options) {
1768
1793
  super(context);
1769
1794
  this.requestStrategies = requestStrategies;
@@ -1832,6 +1857,24 @@ class ObjectHomePage extends PredictivePrefetchPage {
1832
1857
  },
1833
1858
  ];
1834
1859
  }
1860
+ /**
1861
+ * AlwaysRequests must be reduced with predictions.
1862
+ *
1863
+ * @returns true
1864
+ */
1865
+ shouldReduceAlwaysRequestsWithPredictions() {
1866
+ return true;
1867
+ }
1868
+ /**
1869
+ * In OH, the always requests are reduced with predictions, and because they
1870
+ * can't be merged with other predictions, they will always run by themself.
1871
+ * This value must be `false`, otherwise we may see repeated requests.
1872
+ *
1873
+ * @returns false
1874
+ */
1875
+ shouldExecuteAlwaysRequestByThemself() {
1876
+ return false;
1877
+ }
1835
1878
  // Identifies a valid ObjectHomeContext
1836
1879
  static handlesContext(context) {
1837
1880
  const maybeObjectHomePageContext = context;
@@ -1888,8 +1931,8 @@ const TOTAL_ADAPTER_REQUEST_SUCCESS_COUNT = {
1888
1931
  },
1889
1932
  };
1890
1933
 
1891
- const { create, keys } = Object;
1892
- const { isArray } = Array;
1934
+ const { create, keys, hasOwnProperty } = Object;
1935
+ const { isArray, from } = Array;
1893
1936
  const { stringify } = JSON;
1894
1937
 
1895
1938
  /**
@@ -2365,16 +2408,19 @@ function setAuraInstrumentationHooks() {
2365
2408
  networkResponse: incrementRequestResponseCount,
2366
2409
  });
2367
2410
  instrument$2({
2411
+ error: logError,
2412
+ });
2413
+ instrument$3({
2368
2414
  refreshCalled: instrumentation.handleRefreshApiCall.bind(instrumentation),
2369
2415
  instrumentAdapter: instrumentation.instrumentAdapter.bind(instrumentation),
2370
2416
  });
2371
- instrument$3({
2417
+ instrument$4({
2372
2418
  timerMetricAddDuration: updateTimerMetric,
2373
2419
  });
2374
2420
  // Our getRecord through aggregate-ui CRUD logging has moved
2375
2421
  // to lds-network-adapter. We still need to respect the
2376
2422
  // orgs environment setting
2377
- if (forceRecordTransactionsDisabled === false) {
2423
+ if (forceRecordTransactionsDisabled$1 === false) {
2378
2424
  ldsNetworkAdapterInstrument({
2379
2425
  getRecordAggregateResolve: (cb) => {
2380
2426
  const { recordId, apiName } = cb();
@@ -2516,10 +2562,11 @@ async function runRequestsWithLimit(requests, runner, concurrentRequestsLimit, p
2516
2562
  // queue for pending prediction requests
2517
2563
  const requestQueue = [...requests];
2518
2564
  // Function to process the next request in the queue
2519
- const processNextRequest = async () => {
2520
- const timeInWaterfall = Date.now() - pageStartTime - 5; /* 5ms padding */
2565
+ const processNextRequest = async (verifyPastTime = true) => {
2566
+ const timeInWaterfall = Date.now() - pageStartTime;
2521
2567
  while (requestQueue.length > 0 &&
2522
- requestQueue[0].requestMetadata.requestTime < timeInWaterfall) {
2568
+ verifyPastTime &&
2569
+ requestQueue[0].requestMetadata.requestTime <= timeInWaterfall) {
2523
2570
  requestQueue.shift();
2524
2571
  }
2525
2572
  if (requestQueue.length > 0) {
@@ -2538,7 +2585,13 @@ async function runRequestsWithLimit(requests, runner, concurrentRequestsLimit, p
2538
2585
  const initialRequests = Math.min(concurrentRequestsLimit, requestQueue.length);
2539
2586
  const promises = [];
2540
2587
  for (let i = 0; i < initialRequests; i++) {
2541
- promises.push(processNextRequest());
2588
+ // Initial requests should always execute, without verifying if they are past due.
2589
+ // Reasoning:
2590
+ // It may be that one of the alwaysRequest (with 0 as start time) that is reduced
2591
+ // with the regular requests to make these to have 0 as the initial time in the waterfall.
2592
+ // Because predictions are behind an await (see W-16139321), it could be that when this code is evaluated
2593
+ // is already past time for the request.
2594
+ promises.push(processNextRequest(false));
2542
2595
  }
2543
2596
  // Wait for all initial requests to complete
2544
2597
  await Promise.all(promises);
@@ -2547,6 +2600,10 @@ async function runRequestsWithLimit(requests, runner, concurrentRequestsLimit, p
2547
2600
  function isCmpDefsRequest({ request: { adapterName } }) {
2548
2601
  return adapterName === 'getComponentsDef';
2549
2602
  }
2603
+ function predictComponentDefs(cmpDefPredictions, requestRunner) {
2604
+ const reducedPredictions = requestRunner.reduceRequests(cmpDefPredictions);
2605
+ reducedPredictions.map((request) => requestRunner.runRequest(request.request));
2606
+ }
2550
2607
  class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
2551
2608
  constructor(context, repository, requestRunner,
2552
2609
  // These strategies need to be in sync with the "predictiveDataLoadCapable" list
@@ -2576,36 +2633,35 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
2576
2633
  }
2577
2634
  async predict() {
2578
2635
  const alwaysRequests = this.page.getAlwaysRunRequests();
2579
- // IMPORTANT: The `await` has no effect on this operation because `getAllPageRequests`
2580
- // is sync; however if removed, it will have a negative effect when used with
2581
- // Aura Network: predictions will be boxcar'd, which likely will result in a
2582
- // perf regression.
2583
- const pageRequests = await this.getAllPageRequests();
2636
+ const pageRequests = this.getAllPageRequests();
2637
+ // IMPORTANT: Because there's no way to diferentiate a cmpDef prediction from the page
2638
+ // requesting the cmpDef, we need to predict cmpDefs before we start watching
2639
+ // for predictions in the page. Having this code after an
2640
+ // await will make the predictions to be saved as predictions too.
2641
+ predictComponentDefs(pageRequests.filter(isCmpDefsRequest), this.requestRunner);
2584
2642
  const alwaysRequestEntries = alwaysRequests.map((request) => {
2585
2643
  return {
2586
2644
  request,
2587
2645
  requestMetadata: { requestTime: 0 }, // ensures always requests are executed, and executed first.
2588
2646
  };
2589
2647
  });
2590
- const reducedPredictions = this.requestRunner.reduceRequests([
2591
- ...pageRequests,
2592
- ...alwaysRequestEntries,
2593
- ]); // In future - remove alwaysRequestEntries when on OneStore
2594
- const nonCmpDefPredictions = reducedPredictions.filter((r) => !isCmpDefsRequest(r));
2595
- const cmpDefPredictions = reducedPredictions.filter(isCmpDefsRequest);
2596
- // Non CmpDefs requests are limited by AuraActions concurent inflight limit.
2597
- // Always requests must go by themself - Some of them are essential to keep the page rendering at the beginning.
2598
- const predictedRequestsWithLimit = [...alwaysRequestEntries, ...nonCmpDefPredictions].sort((a, b) => a.requestMetadata.requestTime - b.requestMetadata.requestTime); // In future - choose sort algorithm via Gate?;
2599
- const inflightPredictionRequests = runRequestsWithLimit(predictedRequestsWithLimit, this.requestRunner, this.options.inflightRequestLimit, this.repository.pageStartTime);
2600
- const inflightCmpRequests = cmpDefPredictions.map((request) => this.requestRunner.runRequest(request.request));
2601
- return Promise.all([inflightPredictionRequests, ...inflightCmpRequests]).then();
2648
+ const nonCmpDefPredictions = pageRequests.filter((r) => !isCmpDefsRequest(r));
2649
+ const reducedPredictions = this.page.shouldReduceAlwaysRequestsWithPredictions()
2650
+ ? this.requestRunner.reduceRequests([...nonCmpDefPredictions, ...alwaysRequestEntries])
2651
+ : this.requestRunner.reduceRequests(nonCmpDefPredictions);
2652
+ const predictedRequestsWithLimit = (this.page.shouldExecuteAlwaysRequestByThemself()
2653
+ ? [...alwaysRequestEntries, ...reducedPredictions]
2654
+ : reducedPredictions).sort((a, b) => a.requestMetadata.requestTime - b.requestMetadata.requestTime); // In future - choose sort algorithm via Gate?;
2655
+ await runRequestsWithLimit(predictedRequestsWithLimit, this.requestRunner, this.options.inflightRequestLimit,
2656
+ // `this.repository.pageStartTime` would be the correct here,
2657
+ // but when doing predict+watch, it could be (set in watch)
2658
+ // repository.startTime is not set yet, Date.now() is a better alternative,
2659
+ // that is correct, and works on both cases.
2660
+ Date.now());
2602
2661
  }
2603
2662
  }
2604
2663
 
2605
2664
  // Copy-pasted from adapter-utils. This util should be extracted from generated code and imported in prefetch repository.
2606
- const { keys: ObjectKeys$2 } = Object;
2607
- const { stringify: JSONStringify } = JSON;
2608
- const { isArray: ArrayIsArray$1 } = Array;
2609
2665
  /**
2610
2666
  * A deterministic JSON stringify implementation. Heavily adapted from https://github.com/epoberezkin/fast-json-stable-stringify.
2611
2667
  * This is needed because insertion order for JSON.stringify(object) affects output:
@@ -2629,11 +2685,11 @@ function stableJSONStringify(node) {
2629
2685
  return isFinite(node) ? '' + node : 'null';
2630
2686
  }
2631
2687
  if (typeof node !== 'object') {
2632
- return JSONStringify(node);
2688
+ return stringify(node);
2633
2689
  }
2634
2690
  let i;
2635
2691
  let out;
2636
- if (ArrayIsArray$1(node)) {
2692
+ if (isArray(node)) {
2637
2693
  out = '[';
2638
2694
  for (i = 0; i < node.length; i++) {
2639
2695
  if (i) {
@@ -2646,10 +2702,10 @@ function stableJSONStringify(node) {
2646
2702
  if (node === null) {
2647
2703
  return 'null';
2648
2704
  }
2649
- const keys = ObjectKeys$2(node).sort();
2705
+ const keys$1 = keys(node).sort();
2650
2706
  out = '';
2651
- for (i = 0; i < keys.length; i++) {
2652
- const key = keys[i];
2707
+ for (i = 0; i < keys$1.length; i++) {
2708
+ const key = keys$1[i];
2653
2709
  const value = stableJSONStringify(node[key]);
2654
2710
  if (!value) {
2655
2711
  continue;
@@ -2657,7 +2713,7 @@ function stableJSONStringify(node) {
2657
2713
  if (out) {
2658
2714
  out += ',';
2659
2715
  }
2660
- out += JSONStringify(key) + ':' + value;
2716
+ out += stringify(key) + ':' + value;
2661
2717
  }
2662
2718
  return '{' + out + '}';
2663
2719
  }
@@ -2673,8 +2729,8 @@ function deepEquals(objA, objB) {
2673
2729
  if (!isObject(objA) || !isObject(objB))
2674
2730
  return false;
2675
2731
  // Filter out keys set as undefined, we can compare undefined as equals.
2676
- const keysA = ObjectKeys$2(objA).filter((key) => objA[key] !== undefined);
2677
- const keysB = ObjectKeys$2(objB).filter((key) => objB[key] !== undefined);
2732
+ const keysA = keys(objA).filter((key) => objA[key] !== undefined);
2733
+ const keysB = keys(objB).filter((key) => objB[key] !== undefined);
2678
2734
  // If the objects do not have the same set of keys, they are not deeply equal
2679
2735
  if (keysA.length !== keysB.length)
2680
2736
  return false;
@@ -2940,9 +2996,10 @@ function requestComponents(config) {
2940
2996
  try {
2941
2997
  for (let index = 0, n = config.length; index < n; index++) {
2942
2998
  const def = config[index];
2943
- if (!(def.includes('forceGenerated') ||
2944
- def.includes('one:onePreloads') ||
2945
- onePreloads.has(def))) {
2999
+ if (def.startsWith('markup://') &&
3000
+ !(def.includes('forceGenerated') ||
3001
+ def.includes('one:onePreloads') ||
3002
+ onePreloads.has(def))) {
2946
3003
  getDefinition(def, noop);
2947
3004
  }
2948
3005
  }
@@ -2965,9 +3022,10 @@ class GetComponentsDefStrategy extends RequestStrategy {
2965
3022
  };
2966
3023
  }
2967
3024
  transformForSave(request) {
3025
+ const normalizedConfig = (request.config || []).map((def) => def.indexOf('://') === -1 ? 'markup://' + def : def);
2968
3026
  return {
2969
3027
  ...request,
2970
- config: request.config || [],
3028
+ config: normalizedConfig,
2971
3029
  };
2972
3030
  }
2973
3031
  canCombine() {
@@ -2985,7 +3043,14 @@ class GetComponentsDefStrategy extends RequestStrategy {
2985
3043
 
2986
3044
  const LDS_PDL_CMP_IDENTIFIER = 'lds:pdl';
2987
3045
  const DEFAULT_RESOURCE_CONTEXT = {
2988
- sourceContext: { tagName: LDS_PDL_CMP_IDENTIFIER },
3046
+ sourceContext: {
3047
+ tagName: LDS_PDL_CMP_IDENTIFIER,
3048
+ actionConfig: {
3049
+ background: false,
3050
+ hotspot: true,
3051
+ longRunning: false,
3052
+ },
3053
+ },
2989
3054
  };
2990
3055
  class LuvioAdapterRequestStrategy extends RequestStrategy {
2991
3056
  constructor(luvio) {
@@ -3155,7 +3220,7 @@ class GetRecordsRequestStrategy extends LuvioAdapterRequestStrategy {
3155
3220
  }
3156
3221
 
3157
3222
  function normalizeRecordIds(recordIds) {
3158
- if (!ArrayIsArray$1(recordIds)) {
3223
+ if (!isArray(recordIds)) {
3159
3224
  return [recordIds];
3160
3225
  }
3161
3226
  return recordIds;
@@ -3164,7 +3229,7 @@ function normalizeApiNames(apiNames) {
3164
3229
  if (apiNames === undefined || apiNames === null) {
3165
3230
  return [];
3166
3231
  }
3167
- return ArrayIsArray$1(apiNames) ? apiNames : [apiNames];
3232
+ return isArray(apiNames) ? apiNames : [apiNames];
3168
3233
  }
3169
3234
  class GetRecordActionsRequestStrategy extends LuvioAdapterRequestStrategy {
3170
3235
  constructor() {
@@ -3331,11 +3396,9 @@ class GetObjectInfoRequestStrategy extends LuvioAdapterRequestStrategy {
3331
3396
  }
3332
3397
  }
3333
3398
 
3334
- const { keys: ObjectKeys$1 } = Object;
3335
- const { isArray: ArrayIsArray, from: ArrayFrom } = Array;
3336
3399
  function isReduceAbleRelatedListConfig(config) {
3337
3400
  return config.relatedListsActionParameters.every((rlReq) => {
3338
- return rlReq.relatedListId !== undefined && ObjectKeys$1(rlReq).length === 1;
3401
+ return rlReq.relatedListId !== undefined && keys(rlReq).length === 1;
3339
3402
  });
3340
3403
  }
3341
3404
  class GetRelatedListsActionsRequestStrategy extends LuvioAdapterRequestStrategy {
@@ -3379,7 +3442,7 @@ class GetRelatedListsActionsRequestStrategy extends LuvioAdapterRequestStrategy
3379
3442
  */
3380
3443
  canCombine(reqA, reqB) {
3381
3444
  const [recordIdA, recordIdB] = [reqA.recordIds, reqB.recordIds].map((recordIds) => {
3382
- return ArrayIsArray(recordIds)
3445
+ return isArray(recordIds)
3383
3446
  ? recordIds.length === 1
3384
3447
  ? recordIds[0]
3385
3448
  : null
@@ -3397,7 +3460,7 @@ class GetRelatedListsActionsRequestStrategy extends LuvioAdapterRequestStrategy
3397
3460
  });
3398
3461
  return {
3399
3462
  recordIds: reqA.recordIds,
3400
- relatedListsActionParameters: ArrayFrom(relatedListsIncluded).map((relatedListId) => ({
3463
+ relatedListsActionParameters: from(relatedListsIncluded).map((relatedListId) => ({
3401
3464
  relatedListId,
3402
3465
  })),
3403
3466
  };
@@ -3539,9 +3602,18 @@ class GetRelatedListRecordsRequestStrategy extends LuvioAdapterRequestStrategy {
3539
3602
  }
3540
3603
  }
3541
3604
 
3605
+ const APEX_RESOURCE_CONTEXT = {
3606
+ ...DEFAULT_RESOURCE_CONTEXT,
3607
+ sourceContext: {
3608
+ ...DEFAULT_RESOURCE_CONTEXT.sourceContext,
3609
+ // We don't want to override anything for Apex, it is not part
3610
+ // of UiApi, and it can cause undesired behavior.
3611
+ actionConfig: undefined,
3612
+ },
3613
+ };
3542
3614
  function getApexPdlFactory(luvio) {
3543
- return ({ invokerParams, config }) => {
3544
- return GetApexWireAdapterFactory(luvio, invokerParams)(config);
3615
+ return ({ invokerParams, config }, requestContext) => {
3616
+ return GetApexWireAdapterFactory(luvio, invokerParams)(config, requestContext);
3545
3617
  };
3546
3618
  }
3547
3619
  class GetApexRequestStrategy extends LuvioAdapterRequestStrategy {
@@ -3553,6 +3625,9 @@ class GetApexRequestStrategy extends LuvioAdapterRequestStrategy {
3553
3625
  buildConcreteRequest(similarRequest) {
3554
3626
  return similarRequest;
3555
3627
  }
3628
+ execute(config, _requestContext) {
3629
+ return super.execute(config, APEX_RESOURCE_CONTEXT);
3630
+ }
3556
3631
  }
3557
3632
 
3558
3633
  const GET_LIST_INFO_BY_NAME_ADAPTER_NAME = 'getListInfoByName';
@@ -3717,7 +3792,6 @@ class InMemoryPrefetchStorage {
3717
3792
  }
3718
3793
  }
3719
3794
 
3720
- const { keys: ObjectKeys } = Object;
3721
3795
  const DEFAULT_STORAGE_OPTIONS = {
3722
3796
  name: 'ldsPredictiveLoading',
3723
3797
  persistent: true,
@@ -3756,7 +3830,7 @@ class AuraPrefetchStorage {
3756
3830
  * then they will (potentially incorrectly) think that we don't have any predictions.
3757
3831
  */
3758
3832
  auraStorage.getAll().then((results) => {
3759
- ObjectKeys(results).forEach((key) => this.inMemoryStorage.set(key, results[key]));
3833
+ keys(results).forEach((key) => this.inMemoryStorage.set(key, results[key]));
3760
3834
  });
3761
3835
  }
3762
3836
  set(key, value) {
@@ -3792,9 +3866,308 @@ function buildComposableNetworkAdapter(composedAdapters) {
3792
3866
  };
3793
3867
  }
3794
3868
 
3869
+ /**
3870
+ * Copyright (c) 2022, Salesforce, Inc.,
3871
+ * All rights reserved.
3872
+ * For full license text, see the LICENSE.txt file
3873
+ */
3874
+
3875
+ /*
3876
+ * ATTENTION!
3877
+ * THIS IS A GENERATED FILE FROM https://github.com/salesforce-experience-platform-emu/lds-lightning-platform
3878
+ * If you would like to contribute to LDS, please follow the steps outlined in the git repo.
3879
+ * Any changes made to this file in p4 will be automatically overwritten.
3880
+ * *******************************************************************************************
3881
+ */
3882
+ /* proxy-compat-disable */
3883
+ var EnvironmentSettings;
3884
+ (function (EnvironmentSettings) {
3885
+ EnvironmentSettings["ForceRecordTransactionsDisabled"] = "forceRecordTransactionsDisabled";
3886
+ })(EnvironmentSettings || (EnvironmentSettings = {}));
3887
+ const GATE_FORCE_RECORD_TRANSACTIONS_DISABLED = '$Browser.S1Features.forceRecordTransactionsDisabled';
3888
+ const supportedEnvironmentSettings = {
3889
+ [EnvironmentSettings.ForceRecordTransactionsDisabled]: GATE_FORCE_RECORD_TRANSACTIONS_DISABLED,
3890
+ };
3891
+ /**
3892
+ * Returns aura configuration settings. Used to check gate/perm statuses.
3893
+ * @param name Name of the setting to check.
3894
+ * @returns Value of the setting, or undefined if $A is not available.
3895
+ */
3896
+ function getEnvironmentSetting(name) {
3897
+ if (typeof window === 'undefined') {
3898
+ // server environment i.e. SSR in LWR
3899
+ return undefined;
3900
+ }
3901
+ const environmentSetting = supportedEnvironmentSettings[name];
3902
+ if (typeof window.$A !== 'undefined' && environmentSetting !== undefined) {
3903
+ return window.$A.get(environmentSetting);
3904
+ }
3905
+ return undefined;
3906
+ }
3907
+ // version: 1.305.0-ec92f7304c
3908
+
3909
+ const forceRecordTransactionsDisabled = getEnvironmentSetting(EnvironmentSettings.ForceRecordTransactionsDisabled);
3910
+ //TODO: Some duplication here that can be most likely moved to a util class
3911
+ const NO_RECORD_ID_204 = '204_NO_RECORD_ID';
3912
+ const NO_RECORD_TYPE_204 = '204_NO_RECORD_TYPE';
3913
+ let crudInstrumentationCallbacks = {};
3914
+ let crudRLInstrumentationCallbacks = {};
3915
+ if (forceRecordTransactionsDisabled === false) {
3916
+ // Record callbacks
3917
+ crudInstrumentationCallbacks = {
3918
+ createRecordRejectFunction: (config) => {
3919
+ logCRUDLightningInteraction(CrudEventType.CREATE, {
3920
+ // recordId: config.params.recordInput.apiName, // seems wrong?
3921
+ recordId: config.params.recordId || NO_RECORD_ID_204,
3922
+ state: CrudEventState.ERROR,
3923
+ });
3924
+ },
3925
+ createRecordResolveFunction: (config) => {
3926
+ const recordId = config.body ? config.body.id : NO_RECORD_ID_204;
3927
+ const recordType = config.body ? config.body.apiName : NO_RECORD_TYPE_204;
3928
+ logCRUDLightningInteraction(CrudEventType.CREATE, {
3929
+ recordId,
3930
+ recordType,
3931
+ state: CrudEventState.SUCCESS,
3932
+ });
3933
+ },
3934
+ deleteRecordRejectFunction: (config) => {
3935
+ logCRUDLightningInteraction(CrudEventType.DELETE, {
3936
+ recordId: config.params.recordId,
3937
+ state: CrudEventState.ERROR,
3938
+ });
3939
+ },
3940
+ deleteRecordResolveFunction: (config) => {
3941
+ logCRUDLightningInteraction(CrudEventType.DELETE, {
3942
+ recordId: config.params.recordId,
3943
+ state: CrudEventState.SUCCESS,
3944
+ });
3945
+ },
3946
+ // These should be handled by the network adapater?
3947
+ // getRecordAggregateRejectFunction: (config: InstrumentationRejectConfig) => {
3948
+ // logCRUDLightningInteraction(CrudEventType.READ, {
3949
+ // recordId: config.params.recordId,
3950
+ // state: CrudEventState.ERROR,
3951
+ // });
3952
+ // },
3953
+ // getRecordAggregateResolveFunction: (config: InstrumentationResolveConfig) => {
3954
+ // logCRUDLightningInteraction(CrudEventType.READ, {
3955
+ // recordId: config.params.recordId,
3956
+ // recordType: config.body.apiName,
3957
+ // state: CrudEventState.SUCCESS,
3958
+ // });
3959
+ // },
3960
+ getRecordRejectFunction: (config) => {
3961
+ logCRUDLightningInteraction(CrudEventType.READ, {
3962
+ recordId: config.params.recordId,
3963
+ state: CrudEventState.ERROR,
3964
+ });
3965
+ },
3966
+ getRecordResolveFunction: (config) => {
3967
+ logCRUDLightningInteraction(CrudEventType.READ, {
3968
+ recordId: config.params.recordId,
3969
+ recordType: config.body.apiName,
3970
+ state: CrudEventState.SUCCESS,
3971
+ });
3972
+ },
3973
+ updateRecordRejectFunction: (config) => {
3974
+ logCRUDLightningInteraction(CrudEventType.UPDATE, {
3975
+ recordId: config.params.recordId,
3976
+ state: CrudEventState.ERROR,
3977
+ });
3978
+ },
3979
+ updateRecordResolveFunction: (config) => {
3980
+ const recordType = config.body ? config.body.apiName : NO_RECORD_TYPE_204;
3981
+ logCRUDLightningInteraction(CrudEventType.UPDATE, {
3982
+ recordId: config.params.recordId,
3983
+ recordType,
3984
+ state: CrudEventState.SUCCESS,
3985
+ });
3986
+ },
3987
+ };
3988
+ // Related list callbacks
3989
+ crudRLInstrumentationCallbacks = {
3990
+ getRelatedListRecordsRejectFunction: (config) => {
3991
+ logCRUDLightningInteraction(CrudEventType.READS, {
3992
+ parentRecordId: config.params.parentRecordId,
3993
+ relatedListId: config.params.relatedListId,
3994
+ state: CrudEventState.ERROR,
3995
+ });
3996
+ },
3997
+ getRelatedListRecordsResolveFunction: (config) => {
3998
+ logGetRelatedListRecordsInteraction(config.body);
3999
+ },
4000
+ getRelatedListRecordsBatchRejectFunction: (config) => {
4001
+ logCRUDLightningInteraction(CrudEventType.READS, {
4002
+ parentRecordId: config.params.parentRecordId,
4003
+ relatedListIds: config.params.relatedListParameters.map((entry) => entry.relatedListId),
4004
+ state: CrudEventState.ERROR,
4005
+ });
4006
+ },
4007
+ getRelatedListRecordsBatchResolveFunction: (config) => {
4008
+ config.body.results.forEach((res) => {
4009
+ // Log for each RL that was returned from batch endpoint
4010
+ if (res.statusCode === 200) {
4011
+ logGetRelatedListRecordsInteraction(res.result);
4012
+ }
4013
+ });
4014
+ },
4015
+ };
4016
+ }
4017
+ // Helper function copied from ui-api
4018
+ function logGetRelatedListRecordsInteraction(body) {
4019
+ const records = body.records;
4020
+ // Don't log anything if the related list has no records.
4021
+ if (records.length === 0) {
4022
+ return;
4023
+ }
4024
+ const recordIds = records.map((record) => {
4025
+ return record.id;
4026
+ });
4027
+ /**
4028
+ * In almost every case - the relatedList records will all be of the same apiName, but there is an edge case for
4029
+ Activities entity that could return Events & Tasks- so handle that case by returning a joined string.
4030
+ ADS Implementation only looks at the first record returned to determine the apiName.
4031
+ See force/recordLibrary/recordMetricsPlugin.js _getRecordType method.
4032
+ */
4033
+ logCRUDLightningInteraction(CrudEventType.READS, {
4034
+ parentRecordId: body.listReference.inContextOfRecordId,
4035
+ relatedListId: body.listReference.relatedListId,
4036
+ recordIds,
4037
+ recordType: body.records[0].apiName,
4038
+ state: CrudEventState.SUCCESS,
4039
+ });
4040
+ }
4041
+ const crudInstrumentationConfig = {
4042
+ records: {
4043
+ post: {
4044
+ rejectFn: crudInstrumentationCallbacks.createRecordRejectFunction,
4045
+ resolveFn: crudInstrumentationCallbacks.createRecordResolveFunction,
4046
+ },
4047
+ get: {
4048
+ rejectFn: crudInstrumentationCallbacks.getRecordRejectFunction,
4049
+ resolveFn: crudInstrumentationCallbacks.getRecordResolveFunction,
4050
+ },
4051
+ patch: {
4052
+ rejectFn: crudInstrumentationCallbacks.updateRecordRejectFunction,
4053
+ resolveFn: crudInstrumentationCallbacks.updateRecordResolveFunction,
4054
+ },
4055
+ delete: {
4056
+ rejectFn: crudInstrumentationCallbacks.deleteRecordRejectFunction,
4057
+ resolveFn: crudInstrumentationCallbacks.deleteRecordResolveFunction,
4058
+ },
4059
+ },
4060
+ relatedListRecords: {
4061
+ post: {
4062
+ rejectFn: crudRLInstrumentationCallbacks.getRelatedListRecordsRejectFunction,
4063
+ resolveFn: crudRLInstrumentationCallbacks.getRelatedListRecordsResolveFunction,
4064
+ },
4065
+ },
4066
+ relatedListRecordsBatch: {
4067
+ post: {
4068
+ rejectFn: crudRLInstrumentationCallbacks.getRelatedListRecordsBatchRejectFunction,
4069
+ resolveFn: crudRLInstrumentationCallbacks.getRelatedListRecordsBatchResolveFunction,
4070
+ },
4071
+ },
4072
+ };
4073
+ function checkAndLogCrudInteraction(request, isResolve, error, response) {
4074
+ let configPath;
4075
+ const baseUrl = `${request.baseUri}${request.basePath}`;
4076
+ if (baseUrl.startsWith(UIAPI_RECORDS_PATH)) {
4077
+ configPath = crudInstrumentationConfig['records']; // maybe use a constant for this
4078
+ }
4079
+ else if (baseUrl.startsWith(UIAPI_RELATED_LIST_RECORDS_BATCH_PATH)) {
4080
+ configPath = crudInstrumentationConfig['relatedListRecordsBatch'];
4081
+ }
4082
+ else if (baseUrl.startsWith(UIAPI_RELATED_LIST_RECORDS_PATH)) {
4083
+ configPath = crudInstrumentationConfig['relatedListRecords'];
4084
+ }
4085
+ if (configPath) {
4086
+ const crudCallbacks = configPath[request.method];
4087
+ if (crudCallbacks) {
4088
+ if (isResolve && crudCallbacks.resolveFn) {
4089
+ crudCallbacks.resolveFn(setResolveConfig(request, response));
4090
+ }
4091
+ else if (crudCallbacks.rejectFn) {
4092
+ crudCallbacks.rejectFn(setRejectConfig(request, error));
4093
+ }
4094
+ }
4095
+ }
4096
+ }
4097
+ function setResolveConfig(request, response) {
4098
+ const responseBody = response ? response.body : {};
4099
+ const urlParams = request.urlParams || {};
4100
+ return {
4101
+ body: responseBody,
4102
+ params: {
4103
+ recordId: urlParams.recordId,
4104
+ },
4105
+ };
4106
+ }
4107
+ function setRejectConfig(request, error) {
4108
+ const requestBody = request.body || {};
4109
+ const urlParams = request.urlParams || {};
4110
+ return {
4111
+ err: error,
4112
+ params: {
4113
+ recordId: urlParams.recordId,
4114
+ // pass these in even if they're undefined
4115
+ parentRecordId: urlParams.parentRecordId,
4116
+ relatedListId: urlParams.relatedListId,
4117
+ relatedListParameters: requestBody.relatedListParameters,
4118
+ },
4119
+ };
4120
+ }
4121
+
4122
+ const UIAPI_FAMILY = '/ui-api/'; // swap this to an allowlist per family (or build it off package.jsons?)
4123
+ // Denylist
4124
+ const PRIVATE_RESOURCES = ['record-avatars', 'user-state']; // These resources have Connect client filters, must be requested through UiTier :eyeroll:
4125
+ function isPrivatePath(basePath) {
4126
+ return PRIVATE_RESOURCES.some((privateResource) => basePath.includes(privateResource));
4127
+ }
4128
+ const modifyLexResourceRequest = function (resourceRequest, jwtToken) {
4129
+ const jwtBaseUri = jwtToken.decodedInfo.iss;
4130
+ return {
4131
+ ...resourceRequest,
4132
+ baseUri: jwtBaseUri + resourceRequest.baseUri,
4133
+ };
4134
+ };
4135
+ const requestTracker = {
4136
+ registerHandler: (request, name, loadedCheck) => {
4137
+ ThirdPartyTracker.registerHandler(request, name, loadedCheck);
4138
+ },
4139
+ markFinished: (request) => {
4140
+ ThirdPartyTracker.markLoaded(request);
4141
+ },
4142
+ };
4143
+ const requestLogger = {
4144
+ resolve: (request, response = {}) => {
4145
+ checkAndLogCrudInteraction(request, true, null, response);
4146
+ },
4147
+ reject: (request, error) => {
4148
+ checkAndLogCrudInteraction(request, false, error);
4149
+ },
4150
+ };
4151
+ const composedFetchNetworkAdapter = {
4152
+ shouldHandleRequest(resourceRequest) {
4153
+ return (resourceRequest.basePath.startsWith(UIAPI_FAMILY) &&
4154
+ !isPrivatePath(resourceRequest.basePath));
4155
+ },
4156
+ adapter: setupLexJwtNetworkAdapter(auraNetworkAdapter, modifyLexResourceRequest, requestTracker, requestLogger),
4157
+ };
4158
+
4159
+ function getComposedAdapters() {
4160
+ const composedAdapters = [
4161
+ composedNetworkAdapter$1, // SFAP adapter
4162
+ ];
4163
+ if (useHttpInsteadAuraTransport.isOpen({ fallback: false })) {
4164
+ composedAdapters.push(composedFetchNetworkAdapter); // UIAPI Fetch adapter?
4165
+ }
4166
+ return composedAdapters;
4167
+ }
3795
4168
  const composedNetworkAdapter = buildComposableNetworkAdapter([
3796
- composedNetworkAdapter$1,
3797
- // The aura network adapter must be the default.
4169
+ ...getComposedAdapters(),
4170
+ // The aura network adapter must be the default.
3798
4171
  {
3799
4172
  shouldHandleRequest() {
3800
4173
  return true;
@@ -3854,12 +4227,20 @@ function setupQueryEvaluators(luvio, store) {
3854
4227
  }
3855
4228
  let __lexPrefetcher;
3856
4229
  const HARDCODED_REQUEST_LIMIT = 9;
4230
+ function getInflightRequestLimit() {
4231
+ try {
4232
+ return window['$A'].clientService.maxAllowedParallelXHRCounts() - 3;
4233
+ }
4234
+ catch (e) {
4235
+ return HARDCODED_REQUEST_LIMIT;
4236
+ }
4237
+ }
3857
4238
  function setupPredictivePrefetcher(luvio) {
3858
4239
  const storage = buildAuraPrefetchStorage();
3859
4240
  const repository = new PrefetchRepository(storage);
3860
4241
  const requestRunner = new LexRequestRunner(luvio);
3861
4242
  const inflightRequestLimit = applyPredictionRequestLimit.isOpen({ fallback: false })
3862
- ? HARDCODED_REQUEST_LIMIT
4243
+ ? getInflightRequestLimit()
3863
4244
  : 1000;
3864
4245
  const useExactMatchesPlus = useExactMatchesPlusGate.isOpen({ fallback: false });
3865
4246
  const prefetcherOptions = {
@@ -3889,30 +4270,31 @@ function setupPredictivePrefetcher(luvio) {
3889
4270
  registerPrefetcher$1(luvio, prefetcher);
3890
4271
  }
3891
4272
  __lexPrefetcher = prefetcher;
3892
- if (useCmpDefPredictions.isOpen({ fallback: false })) {
3893
- window['$A'].installOverride('ComponentDefLoader.loadingComplete', (...args) => {
3894
- /**
3895
- * To install an override (taken from the Aura.Utils.Override):
3896
- *
3897
- * The function supplied should have the following code in it:
3898
- * ------
3899
- * var config = Array.prototype.shift.apply(arguments);
3900
- * var ret = config["fn"].apply(config["scope"], arguments);
3901
- * return ret
3902
- * ------
3903
- */
3904
- const config = Array.prototype.shift.apply(args);
3905
- const ret = config['fn'].apply(config['scope'], args);
3906
- const [hasErrors, descriptors] = args;
3907
- if (!hasErrors && Array.isArray(descriptors) && descriptors.length > 0) {
3908
- __lexPrefetcher.saveRequest({
3909
- adapterName: 'getComponentsDef',
3910
- config: descriptors,
3911
- });
3912
- }
3913
- return ret;
4273
+ }
4274
+ function loadComponentsDefStartedOverride(...args) {
4275
+ /**
4276
+ * To install an override (taken from the Aura.Utils.Override):
4277
+ *
4278
+ * The function supplied should have the following code in it:
4279
+ * ------
4280
+ * var config = Array.prototype.shift.apply(arguments);
4281
+ * var ret = config["fn"].apply(config["scope"], arguments);
4282
+ * return ret
4283
+ * ------
4284
+ */
4285
+ const config = Array.prototype.shift.apply(args);
4286
+ const ret = config['fn'].apply(config['scope'], args);
4287
+ try {
4288
+ const defs = keys(args[0] || {});
4289
+ __lexPrefetcher.saveRequest({
4290
+ adapterName: 'getComponentsDef',
4291
+ config: defs,
3914
4292
  });
3915
4293
  }
4294
+ catch (e) {
4295
+ // dismiss any error, the activity will log it.
4296
+ }
4297
+ return ret;
3916
4298
  }
3917
4299
  /**
3918
4300
  * @typedef {Object} RecordHomePageContext
@@ -3953,8 +4335,14 @@ function buildPredictorForContext(context) {
3953
4335
  watchPageLoadForPredictions() {
3954
4336
  // This chunk tells the prefetcher to receive events, send off any predictions we have from previous loads, then setup idle detection to stop predicting.
3955
4337
  __lexPrefetcher.startRecording();
4338
+ if (useCmpDefPredictions.isOpen({ fallback: false })) {
4339
+ window['$A'].installOverride('ComponentService.loadComponentDefsStarted', loadComponentsDefStartedOverride);
4340
+ }
3956
4341
  onIdleDetected(() => {
3957
4342
  __lexPrefetcher.stopRecording();
4343
+ if (useCmpDefPredictions.isOpen({ fallback: false })) {
4344
+ window['$A'].uninstallOverride('ComponentService.loadComponentDefsStarted', loadComponentsDefStartedOverride);
4345
+ }
3958
4346
  });
3959
4347
  },
3960
4348
  runPredictions() {
@@ -4067,4 +4455,4 @@ function ldsEngineCreator() {
4067
4455
  }
4068
4456
 
4069
4457
  export { buildPredictorForContext, ldsEngineCreator as default, initializeLDS, initializeOneStore };
4070
- // version: 1.303.0-a698c7cc67
4458
+ // version: 1.305.0-ec970f4bea
@@ -1 +1,3 @@
1
1
  export declare function buildJwtNetworkAdapter(): void;
2
+ export declare function setupLexJwtNetworkAdapter(): void;
3
+ export declare function instrument(): void;
@@ -0,0 +1,7 @@
1
+ declare function registerHandler(_cmp: any, _name: string, _loadedCheck: () => boolean): void;
2
+ declare function markLoaded(_cmp: any): void;
3
+ export declare const ThirdPartyTracker: {
4
+ registerHandler: typeof registerHandler;
5
+ markLoaded: typeof markLoaded;
6
+ };
7
+ export {};
@@ -0,0 +1,18 @@
1
+ declare const create: {
2
+ (o: object | null): any;
3
+ (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
4
+ }, keys: {
5
+ (o: object): string[];
6
+ (o: {}): string[];
7
+ }, hasOwnProperty: (v: PropertyKey) => boolean;
8
+ declare const isArray: (arg: any) => arg is any[], from: {
9
+ <T>(arrayLike: ArrayLike<T>): T[];
10
+ <T_1, U>(arrayLike: ArrayLike<T_1>, mapfn: (v: T_1, k: number) => U, thisArg?: any): U[];
11
+ <T_2>(iterable: Iterable<T_2> | ArrayLike<T_2>): T_2[];
12
+ <T_3, U_1>(iterable: Iterable<T_3> | ArrayLike<T_3>, mapfn: (v: T_3, k: number) => U_1, thisArg?: any): U_1[];
13
+ };
14
+ declare const stringify: {
15
+ (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
16
+ (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
17
+ };
18
+ export { create as ObjectCreate, keys as ObjectKeys, hasOwnProperty as ObjectHasOwnProperty, isArray as ArrayIsArray, from as ArrayFrom, stringify as JSONStringify, };
@@ -0,0 +1,8 @@
1
+ import { type ResourceRequest } from '@luvio/engine';
2
+ import type { ModifyResourceRequestHook, RequestLogger } from '@salesforce/lds-network-fetch-with-jwt';
3
+ export declare const modifyLexResourceRequest: ModifyResourceRequestHook<unknown, any>;
4
+ export declare const requestLogger: RequestLogger;
5
+ export declare const composedFetchNetworkAdapter: {
6
+ shouldHandleRequest(resourceRequest: ResourceRequest): boolean;
7
+ adapter: import("@luvio/engine").NetworkAdapter;
8
+ };
@@ -0,0 +1,2 @@
1
+ import type { FetchResponse, ResourceRequest } from '@luvio/engine';
2
+ export declare function checkAndLogCrudInteraction(request: ResourceRequest, isResolve: boolean, error: any, response?: FetchResponse<any>): void;
@@ -1,12 +1,14 @@
1
1
  import type { LexRequest } from '../prefetcher';
2
2
  import { PredictivePrefetchPage } from './predictive-prefetch-page';
3
3
  export type DefaultPageContext = Record<string, any>;
4
- export declare class LexDefaultPage extends PredictivePrefetchPage<LexRequest, DefaultPageContext> {
5
- constructor(context: DefaultPageContext);
6
- buildSaveRequestData(request: LexRequest): {
7
- context: DefaultPageContext;
8
- request: LexRequest;
4
+ export declare class LexDefaultPage<Request extends LexRequest, Context extends DefaultPageContext> extends PredictivePrefetchPage<Request, Context> {
5
+ constructor(context: Context);
6
+ buildSaveRequestData(request: Request): {
7
+ context: Context;
8
+ request: Request;
9
9
  }[];
10
- resolveSimilarRequest(similarRequest: LexRequest): LexRequest;
11
- getAlwaysRunRequests(): LexRequest[];
10
+ resolveSimilarRequest(similarRequest: Request): Request;
11
+ getAlwaysRunRequests(): Request[];
12
+ shouldReduceAlwaysRequestsWithPredictions(): boolean;
13
+ shouldExecuteAlwaysRequestByThemself(): boolean;
12
14
  }
@@ -1,13 +1,13 @@
1
1
  import type { LexContext, LexPrefetcherOptions } from '../prefetcher';
2
2
  import type { GetListInfoByNameRequestStrategy, GetListInfoByNameRequest, GetListRecordsByNameRequestStrategy, GetListRecordsByNameRequest, GetListInfosByObjectNameRequestStrategy, GetListInfosByObjectNameRequest, GetObjectInfosRequest, GetObjectInfosRequestStrategy, GetListObjectInfoRequest, GetListObjectInfoRequestStrategy } from '../request-strategy';
3
- import { PredictivePrefetchPage } from './predictive-prefetch-page';
3
+ import { LexDefaultPage } from './lex-default-page';
4
4
  export type ObjectHomePageContext = {
5
5
  objectApiName: string;
6
6
  listViewApiName: string;
7
7
  type: 'objectHomePage';
8
8
  };
9
9
  export type ObjectHomePageRequest = GetListInfoByNameRequest | GetListObjectInfoRequest | GetListRecordsByNameRequest | GetListInfosByObjectNameRequest | GetObjectInfosRequest;
10
- export declare class ObjectHomePage extends PredictivePrefetchPage<ObjectHomePageRequest, ObjectHomePageContext> {
10
+ export declare class ObjectHomePage extends LexDefaultPage<ObjectHomePageRequest, ObjectHomePageContext> {
11
11
  private requestStrategies;
12
12
  private options;
13
13
  similarContext: ObjectHomePageContext;
@@ -24,5 +24,19 @@ export declare class ObjectHomePage extends PredictivePrefetchPage<ObjectHomePag
24
24
  }[];
25
25
  resolveSimilarRequest(similarRequest: ObjectHomePageRequest): ObjectHomePageRequest;
26
26
  getAlwaysRunRequests(): ObjectHomePageRequest[];
27
+ /**
28
+ * AlwaysRequests must be reduced with predictions.
29
+ *
30
+ * @returns true
31
+ */
32
+ shouldReduceAlwaysRequestsWithPredictions(): boolean;
33
+ /**
34
+ * In OH, the always requests are reduced with predictions, and because they
35
+ * can't be merged with other predictions, they will always run by themself.
36
+ * This value must be `false`, otherwise we may see repeated requests.
37
+ *
38
+ * @returns false
39
+ */
40
+ shouldExecuteAlwaysRequestByThemself(): boolean;
27
41
  static handlesContext(context: LexContext): context is ObjectHomePageContext;
28
42
  }
@@ -1,6 +1,6 @@
1
1
  import type { LexContext, LexPrefetcherOptions } from '../prefetcher';
2
2
  import type { GetRecordRequest, GetRecordsRequest, GetRecordRequestStrategy, GetRecordsRequestStrategy, GetRecordActionsRequestStrategy, GetRecordActionsRequest, GetRecordAvatarsRequest, GetRecordAvatarsRequestStrategy, GetObjectInfoRequest, GetObjectInfosRequest, GetObjectInfoRequestStrategy, GetObjectInfosRequestStrategy, GetRelatedListsActionsRequestStrategy, GetRelatedListsActionsRequest, GetRelatedListInfoBatchRequestStrategy, GetRelatedListInfoBatchRequest, GetRelatedListRecordsRequestStrategy, GetRelatedListRecordsRequest, GetRelatedListRecordsBatchRequestStrategy, GetRelatedListRecordsBatchRequest, GetApexRequest, GetComponentsRequest, GetApexRequestStrategy, GetComponentsDefStrategy } from '../request-strategy';
3
- import { PredictivePrefetchPage } from './predictive-prefetch-page';
3
+ import { LexDefaultPage } from './lex-default-page';
4
4
  export type RecordHomePageContext = {
5
5
  objectApiName: string;
6
6
  recordId: string;
@@ -22,7 +22,7 @@ type RecordHomePageRequestStrategies = {
22
22
  getApex: GetApexRequestStrategy;
23
23
  getComponentsDef: GetComponentsDefStrategy;
24
24
  };
25
- export declare class RecordHomePage extends PredictivePrefetchPage<RecordHomePageRequest, RecordHomePageContext> {
25
+ export declare class RecordHomePage extends LexDefaultPage<RecordHomePageRequest, RecordHomePageContext> {
26
26
  private requestStrategies;
27
27
  private options;
28
28
  similarContext: RecordHomePageContext;
@@ -33,6 +33,19 @@ export declare class RecordHomePage extends PredictivePrefetchPage<RecordHomePag
33
33
  }[];
34
34
  resolveSimilarRequest(similarRequest: RecordHomePageRequest): RecordHomePageRequest;
35
35
  getAlwaysRunRequests(): RecordHomePageRequest[];
36
+ /**
37
+ * In RH, we know that there will be predictions, and we want to reduce the always requests (getRecord(id, type))
38
+ * with one of the predictions in case some request containing the fields was missed in the predictions.
39
+ *
40
+ * @returns true
41
+ */
42
+ shouldReduceAlwaysRequestsWithPredictions(): boolean;
43
+ /**
44
+ * In RH, we should execute the getRecord(id, type) by itself as we want the result asap, so
45
+ * it does not stop rendering.
46
+ * @returns true
47
+ */
48
+ shouldExecuteAlwaysRequestByThemself(): boolean;
36
49
  static handlesContext(context: LexContext): context is RecordHomePageContext;
37
50
  }
38
51
  export {};
@@ -1,5 +1,6 @@
1
1
  import { ApplicationPredictivePrefetcher } from './predictive-prefetcher';
2
- import type { DefaultPageContext, PredictivePrefetchPage } from '../pages';
2
+ import { LexDefaultPage } from '../pages/lex-default-page';
3
+ import type { DefaultPageContext } from '../pages';
3
4
  import type { GetRecordActionsRequestStrategy, GetRecordAvatarsRequestStrategy, GetRecordRequestStrategy, GetRecordsRequestStrategy, GetObjectInfoRequestStrategy, GetObjectInfosRequestStrategy, GetRelatedListsActionsRequestStrategy, GetRelatedListInfoBatchRequestStrategy, GetRelatedListRecordsRequestStrategy, GetRelatedListRecordsBatchRequestStrategy, GetListInfoByNameRequestStrategy, GetListRecordsByNameRequestStrategy, GetApexRequestStrategy, GetComponentsDefStrategy, GetListInfosByObjectNameRequestStrategy, GetListObjectInfoRequestStrategy } from '../request-strategy';
4
5
  import type { RequestRunner } from '../request-runner';
5
6
  import type { PrefetchRepository } from '../repository/prefetch-repository';
@@ -25,6 +26,7 @@ export type LexPrefetcherOptions = {
25
26
  export declare class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher<LexRequest, LexContext> {
26
27
  private requestStrategies;
27
28
  protected options: LexPrefetcherOptions;
29
+ page: LexDefaultPage<LexRequest, LexContext>;
28
30
  constructor(context: LexContext, repository: PrefetchRepository, requestRunner: RequestRunner<LexRequest>, requestStrategies: {
29
31
  getRecord: GetRecordRequestStrategy;
30
32
  getRecords: GetRecordsRequestStrategy;
@@ -43,7 +45,7 @@ export declare class LexPredictivePrefetcher extends ApplicationPredictivePrefet
43
45
  getApex: GetApexRequestStrategy;
44
46
  getComponentsDef: GetComponentsDefStrategy;
45
47
  }, options: LexPrefetcherOptions);
46
- getPage(): PredictivePrefetchPage<LexRequest, LexContext>;
48
+ getPage(): LexDefaultPage<LexRequest, LexContext>;
47
49
  getAllPageRequests(): RequestEntry<LexRequest>[];
48
50
  predict(): Promise<void>;
49
51
  }
@@ -1,5 +1,3 @@
1
- export declare const ObjectPrototypeHasOwnProperty: (v: PropertyKey) => boolean;
2
- export declare const ArrayIsArray: (arg: any) => arg is any[];
3
1
  /**
4
2
  * A deterministic JSON stringify implementation. Heavily adapted from https://github.com/epoberezkin/fast-json-stable-stringify.
5
3
  * This is needed because insertion order for JSON.stringify(object) affects output:
@@ -1,5 +1,5 @@
1
1
  import type { ApexInvokerParams } from '@salesforce/lds-adapters-apex';
2
- import type { Luvio } from '@luvio/engine';
2
+ import type { AdapterRequestContext, Luvio, Snapshot } from '@luvio/engine';
3
3
  import { LuvioAdapterRequestStrategy } from './luvio-adapter-request-strategy';
4
4
  export type GetApexConfig = {
5
5
  name: string;
@@ -10,11 +10,12 @@ export type GetApexRequest = {
10
10
  adapterName: 'getApex';
11
11
  config: GetApexConfig;
12
12
  };
13
- export declare function getApexPdlFactory(luvio: Luvio): ({ invokerParams, config }: GetApexConfig) => import("@luvio/engine").Snapshot<any> | Promise<import("@luvio/engine").Snapshot<any>> | null;
13
+ export declare function getApexPdlFactory(luvio: Luvio): ({ invokerParams, config }: GetApexConfig, requestContext?: AdapterRequestContext) => Snapshot<any> | Promise<Snapshot<any>> | null;
14
14
  type GetApexContext = Record<string, unknown>;
15
15
  export declare class GetApexRequestStrategy extends LuvioAdapterRequestStrategy<GetApexConfig, GetApexRequest, GetApexContext> {
16
16
  adapterName: string;
17
17
  adapterFactory: typeof getApexPdlFactory;
18
18
  buildConcreteRequest(similarRequest: GetApexRequest): GetApexRequest;
19
+ execute(config: GetApexConfig, _requestContext?: AdapterRequestContext | undefined): Snapshot<any> | Promise<Snapshot<any>> | null;
19
20
  }
20
21
  export {};
@@ -1,6 +1,16 @@
1
1
  import type { AdapterFactory, AdapterRequestContext, Luvio, Snapshot } from '@luvio/engine';
2
2
  import type { BaseAdapterRequest } from './request-strategy';
3
3
  import { RequestStrategy } from './request-strategy';
4
+ export declare const DEFAULT_RESOURCE_CONTEXT: {
5
+ sourceContext: {
6
+ tagName: string;
7
+ actionConfig: {
8
+ background: boolean;
9
+ hotspot: boolean;
10
+ longRunning: boolean;
11
+ };
12
+ };
13
+ };
4
14
  export declare abstract class LuvioAdapterRequestStrategy<AdapterConfig, Request extends BaseAdapterRequest<AdapterConfig>, Context> extends RequestStrategy<AdapterConfig, Request, Context> {
5
15
  private luvio;
6
16
  constructor(luvio: Luvio);
@@ -1,4 +1,5 @@
1
- import { InMemoryPrefetchStorage, type PrefetchStorage } from '.';
1
+ import { type PrefetchStorage } from '.';
2
+ import { InMemoryPrefetchStorage } from './in-memory-prefetch-storage';
2
3
  import { type AuraStorage, type AuraStorageConfig } from '@salesforce/lds-aura-storage';
3
4
  export declare const DEFAULT_STORAGE_OPTIONS: {
4
5
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-aura",
3
- "version": "1.303.0",
3
+ "version": "1.305.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Aura runtime",
6
6
  "main": "dist/ldsEngineCreator.js",
@@ -35,15 +35,15 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@luvio/service-broker": "5.3.1",
38
- "@salesforce/lds-adapters-apex": "^1.303.0",
39
- "@salesforce/lds-adapters-uiapi": "^1.303.0",
38
+ "@salesforce/lds-adapters-apex": "^1.305.0",
39
+ "@salesforce/lds-adapters-uiapi": "^1.305.0",
40
40
  "@salesforce/lds-adapters-uiapi-lex": "^1.302.0",
41
- "@salesforce/lds-ads-bridge": "^1.303.0",
42
- "@salesforce/lds-aura-storage": "^1.303.0",
43
- "@salesforce/lds-bindings": "^1.303.0",
44
- "@salesforce/lds-instrumentation": "^1.303.0",
45
- "@salesforce/lds-network-aura": "^1.303.0",
46
- "@salesforce/lds-network-fetch-with-jwt": "^1.303.0"
41
+ "@salesforce/lds-ads-bridge": "^1.305.0",
42
+ "@salesforce/lds-aura-storage": "^1.305.0",
43
+ "@salesforce/lds-bindings": "^1.305.0",
44
+ "@salesforce/lds-instrumentation": "^1.305.0",
45
+ "@salesforce/lds-network-aura": "^1.305.0",
46
+ "@salesforce/lds-network-fetch-with-jwt": "^1.305.0"
47
47
  },
48
48
  "dependencies": {
49
49
  "@luvio/command-aura-network": "5.3.1",
@@ -52,6 +52,7 @@
52
52
  "@luvio/command-sse": "5.3.1",
53
53
  "@luvio/command-streaming": "5.3.1",
54
54
  "@luvio/network-adapter-composable": "0.156.3",
55
+ "@luvio/network-adapter-fetch": "0.156.3",
55
56
  "@luvio/runtime": "5.3.1",
56
57
  "@luvio/service-aura-network": "5.3.1",
57
58
  "@luvio/service-cache-inclusion-policy": "5.3.1",
@@ -63,15 +64,15 @@
63
64
  "@luvio/service-subscription": "5.3.1",
64
65
  "@luvio/service-type-registry": "5.3.1",
65
66
  "@luvio/utils": "5.3.1",
66
- "@salesforce/lds-adapters-uiapi-lex": "^1.303.0"
67
+ "@salesforce/lds-adapters-uiapi-lex": "^1.305.0"
67
68
  },
68
69
  "luvioBundlesize": [
69
70
  {
70
71
  "path": "./dist/ldsEngineCreator.js",
71
72
  "maxSize": {
72
- "none": "151 kB",
73
- "min": "62 kB",
74
- "compressed": "28 kB"
73
+ "none": "170 kB",
74
+ "min": "70 kB",
75
+ "compressed": "31 kB"
75
76
  }
76
77
  }
77
78
  ],
@@ -1,13 +0,0 @@
1
- declare const create: {
2
- (o: object | null): any;
3
- (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
4
- }, keys: {
5
- (o: object): string[];
6
- (o: {}): string[];
7
- };
8
- declare const isArray: (arg: any) => arg is any[];
9
- declare const stringify: {
10
- (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
11
- (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
12
- };
13
- export { create as ObjectCreate, keys as ObjectKeys, isArray as ArrayIsArray, stringify as JSONStringify, };