@salesforce/lds-runtime-webruntime 1.394.0 → 1.396.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.
@@ -581,6 +581,14 @@ class CacheControlRequestRunner {
581
581
  }
582
582
  }
583
583
  class CacheControlCommand extends BaseCommand {
584
+ /**
585
+ * Creates a new CacheControlCommand instance
586
+ *
587
+ * @param services - Required services including cache controller and optional pub/sub service
588
+ * @param services.cacheController - The cache controller service for managing cache operations
589
+ * @param services.pubSub - Optional pub/sub service for cache invalidation notifications
590
+ * @param services - Additional services specific to the implementation
591
+ */
584
592
  constructor(services) {
585
593
  super();
586
594
  this.services = services;
@@ -588,16 +596,31 @@ class CacheControlCommand extends BaseCommand {
588
596
  this.keysUpdated = void 0;
589
597
  this._isInternalExecution = false;
590
598
  this.lastResult = void 0;
591
- this.unsubscribeFromKeysImpl = () => void 0;
599
+ this.unsubscribers = [];
592
600
  this.subscriptions = [];
593
601
  this.instantiationTime = Date.now() / 1e3;
594
602
  }
595
603
  get isInternalExecution() {
596
604
  return this._isInternalExecution;
597
605
  }
606
+ /**
607
+ * Executes the cache control command with optional overrides
608
+ *
609
+ * This method orchestrates the cache control flow by:
610
+ * 1. Clearing any existing subscriptions
611
+ * 2. Merging configuration overrides with the base strategy config
612
+ * 3. Building a request runner for cache operations
613
+ * 4. Executing the cache controller with the request runner
614
+ * 5. Handling the result and setting up subscriptions if needed
615
+ *
616
+ * @param overrides - Optional execution overrides including timestamp and cache control config
617
+ * @param overrides.now - Override the current timestamp for cache control calculations
618
+ * @param overrides.cacheControlConfig - Override cache control strategy configuration
619
+ * @returns A subscribable result containing either the cached/network data or an error
620
+ */
598
621
  execute(overrides) {
599
622
  this.keysUpdated = void 0;
600
- this.unsubscribeFromKeys();
623
+ this.unsubscribe();
601
624
  const mergedCacheControlConfig = mergeCacheControlConfigs(
602
625
  this.cacheControlStrategyConfig,
603
626
  overrides
@@ -619,6 +642,17 @@ class CacheControlCommand extends BaseCommand {
619
642
  });
620
643
  });
621
644
  }
645
+ /**
646
+ * Handles the result from the cache controller and builds the appropriate subscribable result
647
+ *
648
+ * This method processes the cache controller execution result and determines the appropriate
649
+ * response based on network errors, cache errors, and available data. It handles graceful
650
+ * degradation scenarios where network data is available even when cache operations fail.
651
+ *
652
+ * @param result - The result from the cache controller execution
653
+ * @param requestRunner - The request runner containing network data and errors
654
+ * @returns A subscribable result with the appropriate data or error
655
+ */
622
656
  handleCacheControllerResult(result, requestRunner) {
623
657
  const { networkError, networkData, returnData } = requestRunner;
624
658
  return this.publishUpdatedKeys().then(() => {
@@ -654,11 +688,21 @@ class CacheControlCommand extends BaseCommand {
654
688
  );
655
689
  }
656
690
  if (this.subscriptions.length > 0) {
657
- this.subscribeToKeysUsed();
691
+ this.subscribe();
658
692
  }
659
693
  return returnData;
660
694
  });
661
695
  }
696
+ /**
697
+ * Builds a request runner that orchestrates cache read, network request, and cache write operations
698
+ *
699
+ * The request runner encapsulates the three main operations:
700
+ * 1. Reading from cache with subscription setup
701
+ * 2. Requesting data from the network
702
+ * 3. Writing network results to cache and recording keys
703
+ *
704
+ * @returns A configured request runner for the cache controller
705
+ */
662
706
  buildRequestRunner() {
663
707
  return new CacheControlRequestRunner(
664
708
  (cache) => this.buildResultWithSubscribe(cache),
@@ -666,6 +710,15 @@ class CacheControlCommand extends BaseCommand {
666
710
  (cache, networkResult) => this.writeToCacheAndRecordKeys(cache, networkResult)
667
711
  );
668
712
  }
713
+ /**
714
+ * Publishes cache update events for keys that were modified during the operation
715
+ *
716
+ * This method notifies other parts of the system about cache changes by publishing
717
+ * a 'cacheUpdate' event with the set of keys that were updated. This enables
718
+ * cache invalidation and reactive updates across the application.
719
+ *
720
+ * @returns A promise that resolves when the update event is published (or immediately if no pub/sub service)
721
+ */
669
722
  publishUpdatedKeys() {
670
723
  if (this.services.pubSub) {
671
724
  if (this.keysUpdated !== void 0 && this.keysUpdated.size > 0) {
@@ -680,11 +733,25 @@ class CacheControlCommand extends BaseCommand {
680
733
  get operationType() {
681
734
  return "query";
682
735
  }
683
- subscribeToKeysUsed() {
684
- this.unsubscribeFromKeys();
736
+ /**
737
+ * Subscribes to cache update and invalidation events for reactive updates
738
+ *
739
+ * This method sets up subscriptions to listen for changes that affect the data returned
740
+ * by this Command.
741
+ *
742
+ * By default, it subscribes to two types of events on the PubSub service:
743
+ * - 'cacheUpdate': Triggers a rebuild with the original instantiation time
744
+ * - 'cacheInvalidation': Triggers a full refresh without time constraints
745
+ *
746
+ * This method can be extended by subclasses to add additional subscriptions.
747
+ *
748
+ * Note: ALL subscriptions should push an unsubscribe function to the unsubscribers array,
749
+ * for the lifecycle to work correctly and avoid memory leaks.
750
+ */
751
+ subscribe() {
752
+ this.unsubscribe();
685
753
  const { pubSub } = this.services;
686
754
  if (!pubSub) {
687
- this.unsubscribeFromKeysImpl = () => void 0;
688
755
  return;
689
756
  }
690
757
  const rebuildUnsubscribe = pubSub.subscribe({
@@ -699,21 +766,58 @@ class CacheControlCommand extends BaseCommand {
699
766
  callback: () => this.rerun().then(() => void 0),
700
767
  keys: this.keysUsed
701
768
  });
702
- this.unsubscribeFromKeysImpl = () => {
703
- rebuildUnsubscribe();
704
- refreshUnsubscribe();
705
- };
706
- return;
769
+ this.unsubscribers.push(rebuildUnsubscribe, refreshUnsubscribe);
707
770
  }
708
- unsubscribeFromKeys() {
709
- this.unsubscribeFromKeysImpl();
771
+ /**
772
+ * Unsubscribes from all stored subscriptions
773
+ *
774
+ * This method calls all stored unsubscribe functions to clean up event listeners
775
+ * and prevent memory leaks. It should be called when the command is no longer
776
+ * needed and is also called before setting up new subscriptions.
777
+ */
778
+ unsubscribe() {
779
+ while (this.unsubscribers.length > 0) {
780
+ const unsubscriber = this.unsubscribers.pop();
781
+ unsubscriber == null ? void 0 : unsubscriber();
782
+ }
710
783
  }
711
- // TODO: This should likely be abstract in v2. For v1, provide default comparison logic.
784
+ /**
785
+ * Compares two result values for equality to determine if a cache update should trigger a rerun
786
+ *
787
+ * This method is used to prevent unnecessary reruns when the cached data hasn't actually changed.
788
+ * The default implementation uses deep equality comparison, but subclasses can override this
789
+ * to provide more efficient or domain-specific comparison logic.
790
+ *
791
+ * @param result1 - The first result to compare
792
+ * @param result2 - The second result to compare
793
+ * @returns True if the results are equal, false otherwise
794
+ *
795
+ * @todo This should likely be abstract in v2. For v1, provide default comparison logic.
796
+ */
712
797
  equals(result1, result2) {
713
798
  return deepEquals(result1, result2);
714
799
  }
800
+ /**
801
+ * Hook method called after a network request completes
802
+ *
803
+ * This method provides a point for subclasses to perform post-request operations
804
+ * such as logging, metrics collection, or cleanup. The default implementation
805
+ * is empty and can be overridden by subclasses as needed.
806
+ *
807
+ * @param _options - Request completion options
808
+ * @param _options.statusCode - HTTP status code from the network response
809
+ */
715
810
  async afterRequestHooks(_options) {
716
811
  }
812
+ /**
813
+ * Forces a refresh of the cached data by bypassing cache and fetching from network
814
+ *
815
+ * This method executes the command with a "no-cache" configuration, ensuring that
816
+ * fresh data is fetched from the network regardless of cache state. It's useful
817
+ * for scenarios where you need to ensure the most up-to-date data.
818
+ *
819
+ * @returns A refresh result indicating success or failure of the refresh operation
820
+ */
717
821
  refresh() {
718
822
  return this.rerun({ cacheControlConfig: { type: "no-cache" } }).then((result) => {
719
823
  if (result.isErr()) {
@@ -722,6 +826,17 @@ class CacheControlCommand extends BaseCommand {
722
826
  return ok$1(void 0);
723
827
  });
724
828
  }
829
+ /**
830
+ * Writes network result to cache and records the keys that were updated
831
+ *
832
+ * This method wraps the cache write operation with key tracking functionality.
833
+ * It uses a recordable cache wrapper to capture which keys are modified during
834
+ * the write operation, then updates the internal tracking of used and updated keys.
835
+ *
836
+ * @param cache - The cache instance to write to
837
+ * @param networkResult - The network result containing data to write to cache
838
+ * @returns A result indicating success or failure of the write operation
839
+ */
725
840
  writeToCacheAndRecordKeys(cache, networkResult) {
726
841
  const recordableCache = cache.record();
727
842
  return this.writeToCache(recordableCache, networkResult).then((result) => {
@@ -730,6 +845,16 @@ class CacheControlCommand extends BaseCommand {
730
845
  return ok$1(result);
731
846
  });
732
847
  }
848
+ /**
849
+ * Builds a subscribable result by reading from cache and setting up subscriptions
850
+ *
851
+ * This method reads data from the cache and wraps the result in a subscribable
852
+ * structure that allows consumers to subscribe to updates. It also tracks which
853
+ * cache keys were read for future invalidation purposes.
854
+ *
855
+ * @param cache - The readonly cache to read from
856
+ * @returns A subscribable result containing the cached data or error
857
+ */
733
858
  buildResultWithSubscribe(cache) {
734
859
  const recordableCache = cache.record();
735
860
  const result = this.readFromCache(recordableCache);
@@ -757,23 +882,35 @@ class CacheControlCommand extends BaseCommand {
757
882
  * the last known value. If a change is detected, the provided
758
883
  * callback is invoked.
759
884
  *
760
- * @param keysRead - keys of interest that were read during readFromCache
761
885
  * @returns an unsubscribe function to stop watching for updates
762
886
  */
763
887
  buildSubscribe() {
764
888
  return (consumerCallback) => {
765
889
  if (this.subscriptions.length === 0 && this.operationType === "query") {
766
- this.subscribeToKeysUsed();
890
+ this.subscribe();
767
891
  }
768
892
  this.subscriptions.push(consumerCallback);
769
893
  return () => {
770
894
  this.subscriptions = this.subscriptions.filter((cb) => cb !== consumerCallback);
771
895
  if (this.subscriptions.length === 0) {
772
- this.unsubscribeFromKeys();
896
+ this.unsubscribe();
773
897
  }
774
898
  };
775
899
  };
776
900
  }
901
+ /**
902
+ * Re-runs the command execution with optional overrides and notifies subscribers of changes
903
+ *
904
+ * This method is called internally when cache updates occur that affect the command's data.
905
+ * It executes the command with the provided overrides and compares the result with the
906
+ * last known result. If the data has changed, it notifies all subscribers with the new data.
907
+ *
908
+ * The method handles deduplication to prevent unnecessary notifications when the data
909
+ * hasn't actually changed, and properly manages the internal execution state.
910
+ *
911
+ * @param overrides - Optional execution overrides for the rerun
912
+ * @returns A promise that resolves to the execution result
913
+ */
777
914
  rerun(overrides) {
778
915
  this._isInternalExecution = true;
779
916
  return this.execute(overrides).then((result) => {
@@ -790,6 +927,15 @@ class CacheControlCommand extends BaseCommand {
790
927
  return result;
791
928
  });
792
929
  }
930
+ /**
931
+ * Invokes all registered consumer callbacks with the provided data
932
+ *
933
+ * This private method safely calls all registered subscriber callbacks with the
934
+ * provided result data. It includes error handling to prevent callback failures
935
+ * from affecting other callbacks or the overall system.
936
+ *
937
+ * @param data - The result data to send to all subscribers
938
+ */
793
939
  invokeConsumerCallbacks(data) {
794
940
  this.subscriptions.forEach((cb) => {
795
941
  try {
@@ -3688,7 +3834,7 @@ class AuraGraphQLNormalizedCacheControlCommand extends AuraNormalizedCacheContro
3688
3834
  return this.runOriginalRequest();
3689
3835
  }
3690
3836
  if (this.subscriptions.length > 0) {
3691
- this.subscribeToKeysUsed();
3837
+ this.subscribe();
3692
3838
  }
3693
3839
  return returnData;
3694
3840
  });
@@ -3806,7 +3952,7 @@ class HttpGraphQLNormalizedCacheControlCommand extends HttpNormalizedCacheContro
3806
3952
  return this.runOriginalRequest();
3807
3953
  }
3808
3954
  if (this.subscriptions.length > 0) {
3809
- this.subscribeToKeysUsed();
3955
+ this.subscribe();
3810
3956
  }
3811
3957
  return returnData;
3812
3958
  });
@@ -3925,7 +4071,7 @@ function buildServiceDescriptor$2(luvio) {
3925
4071
  },
3926
4072
  };
3927
4073
  }
3928
- // version: 1.394.0-db58817a4e
4074
+ // version: 1.396.0-216c6e4547
3929
4075
 
3930
4076
  /**
3931
4077
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -3951,7 +4097,7 @@ function buildServiceDescriptor$1(notifyRecordUpdateAvailable, getNormalizedLuvi
3951
4097
  },
3952
4098
  };
3953
4099
  }
3954
- // version: 1.394.0-db58817a4e
4100
+ // version: 1.396.0-216c6e4547
3955
4101
 
3956
4102
  /*!
3957
4103
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -4292,7 +4438,7 @@ class JwtManager {
4292
4438
  * All rights reserved.
4293
4439
  * For full license text, see the LICENSE.txt file
4294
4440
  */
4295
- function buildServiceDescriptor(interceptors = { request: [], response: [] }) {
4441
+ function buildServiceDescriptor(interceptors = { request: [], response: [] }, retryService) {
4296
4442
  return {
4297
4443
  type: "fetch",
4298
4444
  version: "1.0",
@@ -4302,7 +4448,12 @@ function buildServiceDescriptor(interceptors = { request: [], response: [] }) {
4302
4448
  (previousPromise, interceptor) => previousPromise.then(interceptor),
4303
4449
  resolvedPromiseLike$3(args)
4304
4450
  );
4305
- return pending.then((args2) => fetch(...args2)).then((response) => {
4451
+ return pending.then((args2) => {
4452
+ if (retryService) {
4453
+ return retryService.applyRetry(() => fetch(...args2));
4454
+ }
4455
+ return fetch(...args2);
4456
+ }).then((response) => {
4306
4457
  return responseInterceptors.reduce(
4307
4458
  (previousPromise, interceptor) => previousPromise.then(interceptor),
4308
4459
  resolvedPromiseLike$3(response)
@@ -4571,4 +4722,4 @@ const services = [
4571
4722
  buildServiceDescriptor$1({}, {}),
4572
4723
  ];
4573
4724
  setServices(services);
4574
- // version: 1.394.0-9f5a21c62e
4725
+ // version: 1.396.0-08650966f4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-webruntime",
3
- "version": "1.394.0",
3
+ "version": "1.396.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Webruntime runtime",
6
6
  "main": "dist/ldsWebruntimeOneStoreInit.js",
@@ -35,35 +35,35 @@
35
35
  "ready": "yarn build && jest --collectCoverage && yarn test:size && yarn release:corejar"
36
36
  },
37
37
  "devDependencies": {
38
- "@luvio/service-provisioner": "5.64.2",
39
- "@luvio/tools-core": "5.64.2",
38
+ "@luvio/service-provisioner": "5.65.1",
39
+ "@luvio/tools-core": "5.65.1",
40
40
  "jwt-encode": "1.0.1"
41
41
  },
42
42
  "dependencies": {
43
- "@luvio/command-aura-network": "5.64.2",
44
- "@luvio/command-aura-normalized-cache-control": "5.64.2",
45
- "@luvio/command-aura-resource-cache-control": "5.64.2",
46
- "@luvio/command-fetch-network": "5.64.2",
47
- "@luvio/command-http-normalized-cache-control": "5.64.2",
48
- "@luvio/command-ndjson": "5.64.2",
49
- "@luvio/command-network": "5.64.2",
50
- "@luvio/command-sse": "5.64.2",
51
- "@luvio/command-streaming": "5.64.2",
52
- "@luvio/jwt-manager": "5.64.2",
43
+ "@luvio/command-aura-network": "5.65.1",
44
+ "@luvio/command-aura-normalized-cache-control": "5.65.1",
45
+ "@luvio/command-aura-resource-cache-control": "5.65.1",
46
+ "@luvio/command-fetch-network": "5.65.1",
47
+ "@luvio/command-http-normalized-cache-control": "5.65.1",
48
+ "@luvio/command-ndjson": "5.65.1",
49
+ "@luvio/command-network": "5.65.1",
50
+ "@luvio/command-sse": "5.65.1",
51
+ "@luvio/command-streaming": "5.65.1",
52
+ "@luvio/jwt-manager": "5.65.1",
53
53
  "@luvio/network-adapter-composable": "0.158.7",
54
54
  "@luvio/network-adapter-fetch": "0.158.7",
55
- "@luvio/service-aura-network": "5.64.2",
56
- "@luvio/service-cache": "5.64.2",
57
- "@luvio/service-cache-control": "5.64.2",
58
- "@luvio/service-cache-inclusion-policy": "5.64.2",
59
- "@luvio/service-fetch-network": "5.64.2",
60
- "@luvio/service-instrument-command": "5.64.2",
61
- "@luvio/service-pubsub": "5.64.2",
62
- "@luvio/service-store": "5.64.2",
63
- "@luvio/utils": "5.64.2",
64
- "@salesforce/lds-adapters-uiapi-lex": "^1.394.0",
65
- "@salesforce/lds-luvio-service": "^1.394.0",
66
- "@salesforce/lds-luvio-uiapi-records-service": "^1.394.0"
55
+ "@luvio/service-aura-network": "5.65.1",
56
+ "@luvio/service-cache": "5.65.1",
57
+ "@luvio/service-cache-control": "5.65.1",
58
+ "@luvio/service-cache-inclusion-policy": "5.65.1",
59
+ "@luvio/service-fetch-network": "5.65.1",
60
+ "@luvio/service-instrument-command": "5.65.1",
61
+ "@luvio/service-pubsub": "5.65.1",
62
+ "@luvio/service-store": "5.65.1",
63
+ "@luvio/utils": "5.65.1",
64
+ "@salesforce/lds-adapters-uiapi-lex": "^1.396.0",
65
+ "@salesforce/lds-luvio-service": "^1.396.0",
66
+ "@salesforce/lds-luvio-uiapi-records-service": "^1.396.0"
67
67
  },
68
68
  "luvioBundlesize": [
69
69
  {