@salesforce/lds-runtime-aura 1.251.0 → 1.252.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.
@@ -203,10 +203,11 @@ class ApplicationPredictivePrefetcher {
203
203
  async predict() {
204
204
  const exactPageRequests = (await this.repository.getPageRequests(this.context)) || [];
205
205
  const similarPageRequests = await this.getSimilarPageRequests();
206
- const predictedRequests = [
207
- ...this.requestRunner.reduceRequests([...exactPageRequests, ...similarPageRequests]),
206
+ const predictedRequests = this.requestRunner.reduceRequests([
207
+ ...exactPageRequests,
208
+ ...similarPageRequests,
208
209
  ...this.page.getAlwaysRunRequests(),
209
- ];
210
+ ]);
210
211
  this.queuedPredictionRequests.push(...predictedRequests);
211
212
  return Promise.all(predictedRequests.map((request) => this.requestRunner.runRequest(request))).then();
212
213
  }
@@ -240,7 +241,7 @@ class LexPredictivePrefetcher extends ApplicationPredictivePrefetcher {
240
241
  }
241
242
 
242
243
  // Copy-pasted from adapter-utils. This util should be extracted from generated code and imported in prefetch repository.
243
- const { keys: ObjectKeys } = Object;
244
+ const { keys: ObjectKeys$1 } = Object;
244
245
  const { stringify: JSONStringify } = JSON;
245
246
  const { isArray: ArrayIsArray } = Array;
246
247
  /**
@@ -283,7 +284,7 @@ function stableJSONStringify$1(node) {
283
284
  if (node === null) {
284
285
  return 'null';
285
286
  }
286
- const keys = ObjectKeys(node).sort();
287
+ const keys = ObjectKeys$1(node).sort();
287
288
  out = '';
288
289
  for (i = 0; i < keys.length; i++) {
289
290
  const key = keys[i];
@@ -310,8 +311,8 @@ function deepEquals(objA, objB) {
310
311
  if (!isObject(objA) || !isObject(objB))
311
312
  return false;
312
313
  // Filter out keys set as undefined, we can compare undefined as equals.
313
- const keysA = ObjectKeys(objA).filter((key) => objA[key] !== undefined);
314
- const keysB = ObjectKeys(objB).filter((key) => objB[key] !== undefined);
314
+ const keysA = ObjectKeys$1(objA).filter((key) => objA[key] !== undefined);
315
+ const keysB = ObjectKeys$1(objB).filter((key) => objB[key] !== undefined);
315
316
  // If the objects do not have the same set of keys, they are not deeply equal
316
317
  if (keysA.length !== keysB.length)
317
318
  return false;
@@ -393,7 +394,37 @@ class LuvioAdapterRequestStrategy extends RequestStrategy {
393
394
  return unfilteredRequests.filter((request) => request.adapterName === this.adapterName);
394
395
  }
395
396
  reduce(unfilteredRequests) {
396
- return this.filterRequests(unfilteredRequests);
397
+ const requests = this.filterRequests(unfilteredRequests);
398
+ const visitedRequests = new Set();
399
+ const reducedRequests = [];
400
+ for (let i = 0, n = requests.length; i < n; i++) {
401
+ const currentRequest = requests[i];
402
+ if (!visitedRequests.has(currentRequest)) {
403
+ const combinedRequest = { ...currentRequest };
404
+ for (let j = i + 1; j < n; j++) {
405
+ const hasNotBeenVisited = !visitedRequests.has(requests[j]);
406
+ const canCombineConfigs = this.canCombine(combinedRequest.config, requests[j].config);
407
+ if (hasNotBeenVisited && canCombineConfigs) {
408
+ combinedRequest.config = this.combineRequests(combinedRequest.config, requests[j].config);
409
+ visitedRequests.add(requests[j]);
410
+ }
411
+ }
412
+ reducedRequests.push(combinedRequest);
413
+ visitedRequests.add(currentRequest);
414
+ }
415
+ }
416
+ return reducedRequests;
417
+ }
418
+ canCombine(_reqA, _reqB) {
419
+ // By default, all requests are not comibinable
420
+ return false;
421
+ }
422
+ combineRequests(reqA, _reqB) {
423
+ // By default, this should never be called since requests aren't combinable
424
+ if (process.env.NODE_ENV !== 'production') {
425
+ throw new Error('Not implemented');
426
+ }
427
+ return reqA;
397
428
  }
398
429
  }
399
430
 
@@ -403,14 +434,6 @@ function normalizeRecordIds$1(recordIds) {
403
434
  }
404
435
  return recordIds;
405
436
  }
406
- function canCombine$1(reqA, reqB) {
407
- return reqA.formFactor === reqB.formFactor;
408
- }
409
- function combineRequests$1(reqA, reqB) {
410
- const combined = { ...reqA };
411
- combined.recordIds = Array.from(new Set([...normalizeRecordIds$1(reqA.recordIds), ...normalizeRecordIds$1(reqB.recordIds)]));
412
- return combined;
413
- }
414
437
  class GetRecordAvatarsRequestStrategy extends LuvioAdapterRequestStrategy {
415
438
  constructor() {
416
439
  super(...arguments);
@@ -450,27 +473,13 @@ class GetRecordAvatarsRequestStrategy extends LuvioAdapterRequestStrategy {
450
473
  (request.config.recordIds.length === 1 &&
451
474
  request.config.recordIds[0] === context.recordId)));
452
475
  }
453
- reduce(unfilteredRequests) {
454
- const requests = this.filterRequests(unfilteredRequests);
455
- const visitedRequests = new Set();
456
- const reducedRequests = [];
457
- for (let i = 0, n = requests.length; i < n; i++) {
458
- const currentRequest = requests[i];
459
- if (!visitedRequests.has(currentRequest)) {
460
- const combinedRequest = { ...currentRequest };
461
- for (let j = i + 1; j < n; j++) {
462
- const hasNotBeenVisited = !visitedRequests.has(requests[j]);
463
- const canCombineConfigs = canCombine$1(combinedRequest.config, requests[j].config);
464
- if (hasNotBeenVisited && canCombineConfigs) {
465
- combinedRequest.config = combineRequests$1(combinedRequest.config, requests[j].config);
466
- visitedRequests.add(requests[j]);
467
- }
468
- }
469
- reducedRequests.push(combinedRequest);
470
- visitedRequests.add(currentRequest);
471
- }
472
- }
473
- return reducedRequests;
476
+ canCombine(reqA, reqB) {
477
+ return reqA.formFactor === reqB.formFactor;
478
+ }
479
+ combineRequests(reqA, reqB) {
480
+ const combined = { ...reqA };
481
+ combined.recordIds = Array.from(new Set([...normalizeRecordIds$1(reqA.recordIds), ...normalizeRecordIds$1(reqB.recordIds)]));
482
+ return combined;
474
483
  }
475
484
  }
476
485
 
@@ -506,46 +515,33 @@ class GetRecordRequestStrategy extends LuvioAdapterRequestStrategy {
506
515
  },
507
516
  };
508
517
  }
509
- reduce(unfilteredRequests) {
510
- const requests = this.filterRequests(unfilteredRequests);
511
- const recordIdToRequestMap = {};
512
- const resultRequests = [];
513
- requests.forEach((request) => {
514
- if (request.config.fields === undefined &&
515
- request.config.optionalFields === undefined) {
516
- resultRequests.push(request);
517
- return;
518
- }
519
- if (recordIdToRequestMap[request.config.recordId] === undefined) {
520
- recordIdToRequestMap[request.config.recordId] = [];
521
- }
522
- recordIdToRequestMap[request.config.recordId].push(request);
523
- });
524
- Object.entries(recordIdToRequestMap).forEach(([recordId, requests]) => {
525
- const fields = new Set();
526
- const optionalFields = new Set();
527
- requests.forEach((request) => {
528
- if (request.config.fields !== undefined) {
529
- request.config.fields.forEach((field) => {
530
- fields.add(field);
531
- });
532
- }
533
- if (request.config.optionalFields !== undefined) {
534
- request.config.optionalFields.forEach((field) => {
535
- optionalFields.add(field);
536
- });
537
- }
538
- });
539
- resultRequests.push({
540
- adapterName: 'getRecord',
541
- config: {
542
- recordId,
543
- fields: Array.from(fields),
544
- optionalFields: Array.from(optionalFields),
545
- },
546
- });
547
- });
548
- return resultRequests;
518
+ canCombine(reqA, reqB) {
519
+ // must be same record and
520
+ return (reqA.recordId === reqB.recordId &&
521
+ // both requests are fields requests
522
+ (reqA.optionalFields !== undefined || reqB.optionalFields !== undefined) &&
523
+ (reqB.fields !== undefined || reqB.optionalFields !== undefined));
524
+ }
525
+ combineRequests(reqA, reqB) {
526
+ const fields = new Set();
527
+ const optionalFields = new Set();
528
+ if (reqA.fields !== undefined) {
529
+ reqA.fields.forEach((field) => fields.add(field));
530
+ }
531
+ if (reqB.fields !== undefined) {
532
+ reqB.fields.forEach((field) => fields.add(field));
533
+ }
534
+ if (reqA.optionalFields !== undefined) {
535
+ reqA.optionalFields.forEach((field) => optionalFields.add(field));
536
+ }
537
+ if (reqB.optionalFields !== undefined) {
538
+ reqB.optionalFields.forEach((field) => optionalFields.add(field));
539
+ }
540
+ return {
541
+ recordId: reqA.recordId,
542
+ fields: Array.from(fields),
543
+ optionalFields: Array.from(optionalFields),
544
+ };
549
545
  }
550
546
  }
551
547
 
@@ -572,22 +568,6 @@ function normalizeRecordIds(recordIds) {
572
568
  }
573
569
  return recordIds;
574
570
  }
575
- function canCombine(reqA, reqB) {
576
- return (reqA.retrievalMode === reqB.retrievalMode &&
577
- reqA.formFactor === reqB.formFactor &&
578
- (reqA.actionTypes || []).toString() === (reqB.actionTypes || []).toString() &&
579
- (reqA.sections || []).toString() === (reqB.sections || []).toString());
580
- }
581
- function combineRequests(reqA, reqB) {
582
- const combined = { ...reqA };
583
- // let's merge the recordIds
584
- combined.recordIds = Array.from(new Set([...normalizeRecordIds(reqA.recordIds), ...normalizeRecordIds(reqB.recordIds)]));
585
- if (combined.retrievalMode === 'ALL') {
586
- const combinedSet = new Set([...(combined.apiNames || []), ...(reqB.apiNames || [])]);
587
- combined.apiNames = Array.from(combinedSet);
588
- }
589
- return combined;
590
- }
591
571
  class GetRecordActionsRequestStrategy extends LuvioAdapterRequestStrategy {
592
572
  constructor() {
593
573
  super(...arguments);
@@ -621,33 +601,28 @@ class GetRecordActionsRequestStrategy extends LuvioAdapterRequestStrategy {
621
601
  context,
622
602
  };
623
603
  }
604
+ canCombine(reqA, reqB) {
605
+ return (reqA.retrievalMode === reqB.retrievalMode &&
606
+ reqA.formFactor === reqB.formFactor &&
607
+ (reqA.actionTypes || []).toString() === (reqB.actionTypes || []).toString() &&
608
+ (reqA.sections || []).toString() === (reqB.sections || []).toString());
609
+ }
610
+ combineRequests(reqA, reqB) {
611
+ const combined = { ...reqA };
612
+ // let's merge the recordIds
613
+ combined.recordIds = Array.from(new Set([...normalizeRecordIds(reqA.recordIds), ...normalizeRecordIds(reqB.recordIds)]));
614
+ if (combined.retrievalMode === 'ALL') {
615
+ const combinedSet = new Set([...(combined.apiNames || []), ...(reqB.apiNames || [])]);
616
+ combined.apiNames = Array.from(combinedSet);
617
+ }
618
+ return combined;
619
+ }
624
620
  isGetRecordActionsRequestContextDependent(context, request) {
625
621
  return (request.config.recordIds &&
626
622
  (context.recordId === request.config.recordIds || // some may set this as string instead of array
627
623
  (request.config.recordIds.length === 1 &&
628
624
  request.config.recordIds[0] === context.recordId)));
629
625
  }
630
- reduce(unfilteredRequests) {
631
- const requests = this.filterRequests(unfilteredRequests);
632
- const visitedRequests = new Set();
633
- const reducedRequests = [];
634
- for (let i = 0, n = requests.length; i < n; i++) {
635
- const currentRequest = requests[i];
636
- if (!visitedRequests.has(currentRequest)) {
637
- const combinedRequest = { ...currentRequest };
638
- for (let j = i + 1; j < n; j++) {
639
- if (!visitedRequests.has(requests[j]) &&
640
- canCombine(combinedRequest.config, requests[j].config)) {
641
- combinedRequest.config = combineRequests(combinedRequest.config, requests[j].config);
642
- visitedRequests.add(requests[j]);
643
- }
644
- }
645
- reducedRequests.push(combinedRequest);
646
- visitedRequests.add(currentRequest);
647
- }
648
- }
649
- return reducedRequests;
650
- }
651
626
  }
652
627
 
653
628
  class GetObjectInfoRequestStrategy extends LuvioAdapterRequestStrategy {
@@ -732,13 +707,13 @@ class InMemoryPrefetchStorage {
732
707
  }
733
708
  }
734
709
 
710
+ const { keys: ObjectKeys } = Object;
735
711
  const DEFAULT_STORAGE_OPTIONS = {
736
712
  name: 'ldsPredictiveLoading',
737
713
  persistent: true,
738
714
  secure: true,
739
- maxSize: 20 * 1024 * 1024,
740
- // @todo: there's no way of setting a "no expire" value. We should determine the best ttl for this cache.
741
- expiration: 24 * 60 * 60,
715
+ maxSize: 7 * 1024 * 1024,
716
+ expiration: 12 * 60 * 60,
742
717
  clearOnInit: false,
743
718
  debugLogging: false,
744
719
  };
@@ -747,20 +722,33 @@ function buildAuraPrefetchStorage(options = {}) {
747
722
  ...DEFAULT_STORAGE_OPTIONS,
748
723
  ...options,
749
724
  });
725
+ const inMemoryStorage = new InMemoryPrefetchStorage();
750
726
  if (auraStorage === null) {
751
- return new InMemoryPrefetchStorage();
727
+ return inMemoryStorage;
752
728
  }
753
- return new AuraPrefetchStorage(auraStorage);
729
+ return new AuraPrefetchStorage(auraStorage, inMemoryStorage);
754
730
  }
755
731
  class AuraPrefetchStorage {
756
- constructor(auraStorage) {
732
+ constructor(auraStorage, inMemoryStorage) {
757
733
  this.auraStorage = auraStorage;
734
+ this.inMemoryStorage = inMemoryStorage;
735
+ auraStorage.getAll().then((results) => {
736
+ ObjectKeys(results).forEach((key) => this.inMemoryStorage.set(key, results[key]));
737
+ });
758
738
  }
759
739
  set(key, value) {
760
- return this.auraStorage.set(key, value);
740
+ const inMemoryResult = this.inMemoryStorage.set(key, value);
741
+ this.auraStorage.set(key, value).catch((error) => {
742
+ if (process.env.NODE_ENV !== 'production') {
743
+ // eslint-disable-next-line no-console
744
+ console.error('Error save LDS prediction: ', error);
745
+ }
746
+ });
747
+ return inMemoryResult;
761
748
  }
762
749
  async get(key) {
763
- const result = await this.auraStorage.get(key);
750
+ // we never read from the AuraStorage, except in construction.
751
+ const result = await this.inMemoryStorage.get(key);
764
752
  return result ? result : undefined;
765
753
  }
766
754
  }
@@ -1508,7 +1496,7 @@ function setupPredictivePrefetcher(luvio) {
1508
1496
  __lexPrefetcher = prefetcher;
1509
1497
  }
1510
1498
  // Triggers a payload.
1511
- async function predictiveLoadPage(preloadProps) {
1499
+ async function predictiveLoadPage(preloadProps, runPredictions) {
1512
1500
  // the gate is disabled and the prefetcher was not setup.
1513
1501
  if (__lexPrefetcher === undefined) {
1514
1502
  return;
@@ -1524,10 +1512,10 @@ async function predictiveLoadPage(preloadProps) {
1524
1512
  };
1525
1513
  // This chunk tells the prefetcher to receive events, send off any predictions we have from previous loads, then setup idle detection to stop predicting.
1526
1514
  __lexPrefetcher.startRecording();
1527
- __lexPrefetcher.predict();
1528
1515
  onIdleDetected(() => {
1529
1516
  __lexPrefetcher.stopRecording();
1530
1517
  });
1518
+ return runPredictions ? __lexPrefetcher.predict() : Promise.resolve();
1531
1519
  }
1532
1520
  // LDS initialization logic, invoked directly by Aura component tests
1533
1521
  function initializeLDS() {
@@ -1555,4 +1543,4 @@ function ldsEngineCreator() {
1555
1543
  }
1556
1544
 
1557
1545
  export { ldsEngineCreator as default, initializeLDS, predictiveLoadPage };
1558
- // version: 1.251.0-51b11f205
1546
+ // version: 1.252.0-a960aa048
@@ -13,7 +13,7 @@ type LexPageReference = {
13
13
  state: any;
14
14
  type: string;
15
15
  };
16
- export declare function predictiveLoadPage(preloadProps: PreloadProps): Promise<void>;
16
+ export declare function predictiveLoadPage(preloadProps: PreloadProps, runPredictions: true): Promise<void>;
17
17
  export declare function initializeLDS(): void;
18
18
  declare function ldsEngineCreator(): {
19
19
  name: string;
@@ -1,6 +1,5 @@
1
1
  import type { GetRecordActionsConfig } from '@salesforce/lds-adapters-uiapi';
2
2
  import { LuvioAdapterRequestStrategy } from './luvio-adapter-request-strategy';
3
- import type { LuvioAdapterRequest } from './luvio-adapter-request';
4
3
  export type GetRecordActionsRequest = {
5
4
  adapterName: 'getRecordActions';
6
5
  config: GetRecordActionsConfig;
@@ -16,7 +15,8 @@ export declare class GetRecordActionsRequestStrategy extends LuvioAdapterRequest
16
15
  request: GetRecordActionsRequest;
17
16
  context: C;
18
17
  };
18
+ canCombine(reqA: GetRecordActionsConfig, reqB: GetRecordActionsConfig): boolean;
19
+ combineRequests(reqA: GetRecordActionsConfig, reqB: GetRecordActionsConfig): GetRecordActionsConfig;
19
20
  private isGetRecordActionsRequestContextDependent;
20
- reduce(unfilteredRequests: LuvioAdapterRequest<unknown>[]): GetRecordActionsRequest[];
21
21
  }
22
22
  export {};
@@ -1,6 +1,5 @@
1
1
  import type { GetRecordAvatarsConfig } from '@salesforce/lds-adapters-uiapi';
2
2
  import { LuvioAdapterRequestStrategy } from './luvio-adapter-request-strategy';
3
- import type { LuvioAdapterRequest } from './luvio-adapter-request';
4
3
  export type GetRecordAvatarsRequest = {
5
4
  adapterName: 'getRecordAvatars';
6
5
  config: GetRecordAvatarsConfig;
@@ -17,6 +16,7 @@ export declare class GetRecordAvatarsRequestStrategy extends LuvioAdapterRequest
17
16
  context: C;
18
17
  };
19
18
  private isGetRecordAvatarsRequestContextDependent;
20
- reduce(unfilteredRequests: LuvioAdapterRequest<unknown>[]): GetRecordAvatarsRequest[];
19
+ canCombine(reqA: GetRecordAvatarsConfig, reqB: GetRecordAvatarsConfig): boolean;
20
+ combineRequests(reqA: GetRecordAvatarsConfig, reqB: GetRecordAvatarsConfig): GetRecordAvatarsConfig;
21
21
  }
22
22
  export {};
@@ -4,7 +4,6 @@ export type GetRecordRequest = {
4
4
  adapterName: 'getRecord';
5
5
  config: GetRecordConfig;
6
6
  };
7
- import type { LuvioAdapterRequest } from './luvio-adapter-request';
8
7
  type GetRecordContext = {
9
8
  recordId: string;
10
9
  };
@@ -13,6 +12,7 @@ export declare class GetRecordRequestStrategy extends LuvioAdapterRequestStrateg
13
12
  adapterFactory: import("@luvio/engine").AdapterFactory<GetRecordConfig, import("@salesforce/lds-adapters-uiapi").RecordRepresentation>;
14
13
  buildConcreteRequest(similarRequest: GetRecordRequest, context: GetRecordContext): GetRecordRequest;
15
14
  transformForSave(request: GetRecordRequest): GetRecordRequest;
16
- reduce(unfilteredRequests: LuvioAdapterRequest<unknown>[]): GetRecordRequest[];
15
+ canCombine(reqA: GetRecordConfig, reqB: GetRecordConfig): boolean;
16
+ combineRequests(reqA: GetRecordConfig, reqB: GetRecordConfig): GetRecordConfig;
17
17
  }
18
18
  export {};
@@ -7,4 +7,6 @@ export declare abstract class LuvioAdapterRequestStrategy<AdapterConfig, Request
7
7
  transformForSave(request: Request): Request;
8
8
  protected filterRequests(unfilteredRequests: LuvioAdapterRequest<unknown>[]): Request[];
9
9
  reduce(unfilteredRequests: LuvioAdapterRequest<unknown>[]): Request[];
10
+ canCombine(_reqA: AdapterConfig, _reqB: AdapterConfig): boolean;
11
+ combineRequests(reqA: AdapterConfig, _reqB: AdapterConfig): AdapterConfig;
10
12
  }
@@ -1,4 +1,4 @@
1
- import { type PrefetchStorage } from '.';
1
+ import { InMemoryPrefetchStorage, type PrefetchStorage } from '.';
2
2
  import { type AuraStorage, type AuraStorageConfig } from '@salesforce/lds-aura-storage';
3
3
  export declare const DEFAULT_STORAGE_OPTIONS: {
4
4
  name: string;
@@ -12,7 +12,8 @@ export declare const DEFAULT_STORAGE_OPTIONS: {
12
12
  export declare function buildAuraPrefetchStorage(options?: Partial<AuraStorageConfig>): PrefetchStorage;
13
13
  export declare class AuraPrefetchStorage implements PrefetchStorage {
14
14
  private auraStorage;
15
- constructor(auraStorage: AuraStorage);
15
+ private inMemoryStorage;
16
+ constructor(auraStorage: AuraStorage, inMemoryStorage: InMemoryPrefetchStorage);
16
17
  set<T>(key: string, value: T): Promise<void>;
17
18
  get<T>(key: string): Promise<T | undefined>;
18
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-aura",
3
- "version": "1.251.0",
3
+ "version": "1.252.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Aura runtime",
6
6
  "main": "dist/ldsEngineCreator.js",
@@ -43,7 +43,7 @@
43
43
  "@salesforce/lds-network-fetch-with-jwt": "*"
44
44
  },
45
45
  "dependencies": {
46
- "@luvio/network-adapter-composable": "0.152.2"
46
+ "@luvio/network-adapter-composable": "0.153.0"
47
47
  },
48
48
  "luvioBundlesize": [
49
49
  {