@capillarytech/cap-ui-utils 3.0.5 → 3.0.7-alpha.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/utils/loadable.js +43 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capillarytech/cap-ui-utils",
3
- "version": "3.0.5",
3
+ "version": "3.0.7-alpha.0",
4
4
  "description": "Utility functions shared accross all the modules",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/utils/loadable.js CHANGED
@@ -2,6 +2,8 @@ import React, { lazy } from 'react';
2
2
 
3
3
  export const FORCE_REFRESH_NOTIFIER = 'showForceRefreshNotifier';
4
4
  export const FORCE_REFRESH_SECONDS = 5;
5
+ export const MAX_RETRY_ATTEMPTS = 3;
6
+ const DEFAULT_STORAGE_PREFIX = 'invalid_import_';
5
7
 
6
8
  class DummyComponent extends React.Component {
7
9
  render() {
@@ -17,40 +19,53 @@ const reloadWithDelay = (delay = FORCE_REFRESH_SECONDS) =>
17
19
  }, delay * 1000);
18
20
  });
19
21
 
20
- export const lazyWithRetry = (importFunction) =>
21
- lazy(async () => {
22
- // get refresh flag from session storage
23
- const pageHasAlreadyBeenForceRefreshed = JSON.parse(
24
- window.sessionStorage.getItem(
25
- 'page-has-been-force-refreshed'
26
- ) || 'false'
27
- );
22
+ const getStorageKey = (key, prefix = DEFAULT_STORAGE_PREFIX) => `${prefix}__${key}`;
23
+
24
+ const clearRetryCount = (prefix) => {
25
+ window.localStorage.removeItem(getStorageKey('retry-count', prefix));
26
+ };
27
+
28
+ // Generate a unique prefix based on the import function
29
+ const generateUniquePrefix = (importFunction) => {
30
+ // Convert the import function to string and create a hash
31
+ const importStr = importFunction.toString();
32
+ let hash = 0;
33
+ for (let i = 0; i < importStr.length; i++) {
34
+ const char = importStr.charCodeAt(i);
35
+ hash = ((hash << 5) - hash) + char;
36
+ hash = hash & hash; // Convert to 32-bit integer
37
+ }
38
+ // Convert to base36 (alphanumeric) to make it shorter and URL-safe
39
+ return `${DEFAULT_STORAGE_PREFIX}${Math.abs(hash).toString(36)}`;
40
+ };
41
+
42
+ export const lazyWithRetry = (importFunction) => {
43
+ // Generate unique prefix based on the import function
44
+ const uniquePrefix = generateUniquePrefix(importFunction);
45
+
46
+ return lazy(async () => {
47
+ // get retry count from localStorage
48
+ const retryCount = parseInt(window.localStorage.getItem(getStorageKey('retry-count', uniquePrefix)) || '0', 10);
28
49
  try {
29
50
  const component = await importFunction();
30
- // set refresh flag to false once component is imported
31
- window.sessionStorage.setItem(
32
- 'page-has-been-force-refreshed',
33
- 'false'
34
- );
51
+ // clear retry count once component is successfully imported
52
+ clearRetryCount(uniquePrefix);
35
53
  return component;
36
54
  } catch (error) {
37
- if (!pageHasAlreadyBeenForceRefreshed) {
38
- // Assuming that the user is NOT on the latest version of the application.
39
- window.sessionStorage.setItem(
40
- 'page-has-been-force-refreshed',
41
- 'true'
42
- );
43
- // Notify the main app to show notification if needed
44
- window.postMessage(FORCE_REFRESH_NOTIFIER, window.location.origin);
45
- // Let's refresh the page immediately.
46
- await reloadWithDelay();
47
- return { default: DummyComponent };
55
+ // Check if we've exceeded max retries
56
+ if (retryCount >= MAX_RETRY_ATTEMPTS) {
57
+ clearRetryCount(uniquePrefix);
58
+ throw error;
48
59
  }
49
- // The page has already been reloaded
50
- // Assuming that user is already using the latest version of the application.
51
- // Let's let the application crash and raise the error.
52
- throw error;
60
+ // Increment retry count and refresh
61
+ window.localStorage.setItem(getStorageKey('retry-count', uniquePrefix), (retryCount + 1).toString());
62
+ // Notify the main app to show notification if needed
63
+ window.postMessage(FORCE_REFRESH_NOTIFIER, window.location.origin);
64
+ // Let's refresh the page immediately.
65
+ await reloadWithDelay();
66
+ return { default: DummyComponent };
53
67
  }
54
68
  });
69
+ };
55
70
 
56
71
  export default lazyWithRetry;