@maestro_io/maestro-web-sdk 2.1.1 → 2.1.3
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.
- package/dist/MaestroEventDelegate.js +60 -0
- package/dist/components/atoms/BaseButton/BaseButton.js +11 -0
- package/dist/components/atoms/BaseButton/index.js +2 -0
- package/dist/components/atoms/Image/index.js +30 -0
- package/dist/components/atoms/Rive/index.d.ts +1 -0
- package/dist/components/atoms/Rive/index.js +53 -0
- package/dist/components/atoms/SvgIcon/BetGeneralIcon.js +9 -0
- package/dist/components/atoms/SvgIcon/BetsIcon.js +11 -0
- package/dist/components/atoms/SvgIcon/BetsWarningIcon.js +11 -0
- package/dist/components/atoms/SvgIcon/CheckmarkIcon.js +6 -0
- package/dist/components/atoms/SvgIcon/CollapseIcon.js +6 -0
- package/dist/components/atoms/SvgIcon/ExpandIcon.js +6 -0
- package/dist/components/atoms/SvgIcon/FantasyIcon.js +8 -0
- package/dist/components/atoms/SvgIcon/FlameIcon.js +11 -0
- package/dist/components/atoms/SvgIcon/Icon.js +42 -0
- package/dist/components/atoms/SvgIcon/KeyPlaysIcon.js +10 -0
- package/dist/components/atoms/SvgIcon/MobilePhoneIcon.js +11 -0
- package/dist/components/atoms/SvgIcon/PlayIcon.js +8 -0
- package/dist/components/atoms/SvgIcon/StatsIcon.js +12 -0
- package/dist/components/atoms/SvgIcon/TimesIcon.js +6 -0
- package/dist/components/atoms/SvgIcon/WarningIcon.js +8 -0
- package/dist/components/atoms/SvgIcon/index.js +2 -0
- package/dist/components/core/App/App.js +41 -0
- package/dist/components/core/App/index.js +2 -0
- package/dist/components/core/OverlayContainer.js +58 -0
- package/dist/components/core/PanelManager/PanelManager.js +80 -0
- package/dist/components/core/PanelManager/index.js +2 -0
- package/dist/components/core/ScrollableContainer/FocusableItem.js +38 -0
- package/dist/components/core/ScrollableContainer/ScrollableContainer.js +166 -0
- package/dist/components/core/ScrollableContainer/index.js +2 -0
- package/dist/components/molecules/ActionButton/ActionButton.d.ts +1 -0
- package/dist/components/molecules/ActionButton/ActionButton.js +10 -0
- package/dist/components/molecules/ActionButton/index.js +2 -0
- package/dist/components/molecules/Overlay/Overlay.js +139 -0
- package/dist/components/molecules/Overlay/index.js +2 -0
- package/dist/components/molecules/PanelNavButton/PanelNavButton.d.ts +1 -0
- package/dist/components/molecules/PanelNavButton/PanelNavButton.js +40 -0
- package/dist/components/molecules/PanelNavButton/index.js +2 -0
- package/dist/components/molecules/SegmentButton/SegmentButton.js +10 -0
- package/dist/components/molecules/SegmentButton/index.js +2 -0
- package/dist/components/molecules/WatchButton/WatchButton.js +15 -0
- package/dist/components/molecules/WatchButton/index.js +2 -0
- package/dist/components/organisms/PanelNavigation/PanelNavigation.js +71 -0
- package/dist/components/organisms/PanelNavigation/index.js +2 -0
- package/dist/components/organisms/SegmentController/SegmentController.d.ts +2 -2
- package/dist/components/organisms/SegmentController/SegmentController.js +68 -0
- package/dist/components/organisms/SegmentController/index.d.ts +1 -1
- package/dist/components/organisms/SegmentController/index.js +2 -0
- package/dist/external/AxiosNetworkClient.js +83 -0
- package/dist/external/LocalStorageCacheManager.js +213 -0
- package/dist/external/ReactRenderer.d.ts +2 -2
- package/dist/external/ReactRenderer.js +86 -0
- package/dist/external/mocks/MockExternalNetworkClient.js +161 -0
- package/dist/external/ports/cacheManager.js +1 -0
- package/dist/external/ports/networkClient.js +1 -0
- package/dist/external/ports/renderer.js +1 -0
- package/dist/external/spatial-navigation/index.d.ts +3 -4
- package/dist/external/spatial-navigation/index.js +3 -0
- package/dist/external/spatial-navigation/measureLayout.js +30 -0
- package/dist/external/spatial-navigation/spatialNavigation.d.ts +2 -4
- package/dist/external/spatial-navigation/spatialNavigation.js +864 -0
- package/dist/external/spatial-navigation/utils.js +6 -0
- package/dist/external/spatial-navigation/visualDebugger.js +76 -0
- package/dist/external/spatial-navigation/withFocusable.d.ts +1 -0
- package/dist/external/spatial-navigation/withFocusable.js +245 -0
- package/dist/helpers/Observable.js +37 -0
- package/dist/helpers/deliver-focus.js +12 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +192 -0
- package/dist/interfaces/IMaestroEvent.js +6 -0
- package/dist/interfaces/IMaestroEventDelegate.js +1 -0
- package/dist/interfaces/IMaestroManager.js +1 -0
- package/dist/maestro-web-sdk.umd.js +3 -3
- package/dist/maestro-web-sdk.umd.js.map +1 -1
- package/dist/models/IModel.js +1 -0
- package/dist/models/IPanel.js +53 -0
- package/dist/models/ITheme.js +20 -0
- package/dist/models/IWinningBet.js +1 -0
- package/dist/modules/bets/interfaces/IBets.js +1 -0
- package/dist/modules/bets/mocks.js +572 -0
- package/dist/modules/bets/view/BetsView.js +116 -0
- package/dist/modules/bets/view/HotProps/HotPropsView.d.ts +7 -6
- package/dist/modules/bets/view/HotProps/HotPropsView.js +139 -0
- package/dist/modules/bets/view/SixPack/SixPackView.d.ts +2 -2
- package/dist/modules/bets/view/SixPack/SixPackView.js +103 -0
- package/dist/modules/bets/view/TabLoadFailureView.d.ts +1 -0
- package/dist/modules/bets/view/TabLoadFailureView.js +12 -0
- package/dist/modules/bets/view/UserBets/BetResult/BetResult.js +6 -0
- package/dist/modules/bets/view/UserBets/BetsCard/BetsCard.d.ts +7 -6
- package/dist/modules/bets/view/UserBets/BetsCard/BetsCard.js +122 -0
- package/dist/modules/bets/view/UserBets/BetsCard/BetsCardEvent.js +34 -0
- package/dist/modules/bets/view/UserBets/BetsCard/BetsCardFooter.js +22 -0
- package/dist/modules/bets/view/UserBets/Boost/Boost.js +6 -0
- package/dist/modules/bets/view/UserBets/OutcomeBadge/OutcomeBadge.js +9 -0
- package/dist/modules/bets/view/UserBets/Parlay/Parlay.js +13 -0
- package/dist/modules/bets/view/UserBets/Straight/Straight.js +6 -0
- package/dist/modules/bets/view/UserBets/Teaser/Teaser.js +13 -0
- package/dist/modules/bets/view/UserBets/UserBetsView.js +114 -0
- package/dist/modules/bets/view/components/Bet/Bet.d.ts +1 -0
- package/dist/modules/bets/view/components/Bet/Bet.js +32 -0
- package/dist/modules/bets/view/components/BetPill/BetPill.js +6 -0
- package/dist/modules/bets/view/components/BetsCard/BetsCard.js +15 -0
- package/dist/modules/bets/view/components/BetsCard/BetsCardHeader.js +20 -0
- package/dist/modules/bets/view/components/GamblingDisclaimer/GamblingDisclaimer.js +14 -0
- package/dist/modules/bets/view/components/LocationWarning/LocationWarning.js +16 -0
- package/dist/modules/bets/view/components/PromoCodeBanner/PromoCodeBanner.d.ts +2 -2
- package/dist/modules/bets/view/components/PromoCodeBanner/PromoCodeBanner.js +63 -0
- package/dist/modules/bets/view/components/PromoCodeBanner/index.d.ts +1 -1
- package/dist/modules/bets/view/components/PromoCodeBanner/index.js +1 -0
- package/dist/modules/bets/view-model/BetsViewModel.js +767 -0
- package/dist/modules/key-plays/constants.js +292 -0
- package/dist/modules/key-plays/interfaces/IKeyPlays.d.ts +4 -4
- package/dist/modules/key-plays/interfaces/IKeyPlays.js +14 -0
- package/dist/modules/key-plays/interfaces/IKeyPlaysResponse.js +1 -0
- package/dist/modules/key-plays/view/KeyPlayCardScoreTagView.js +13 -0
- package/dist/modules/key-plays/view/KeyPlayCardView.d.ts +0 -4
- package/dist/modules/key-plays/view/KeyPlayCardView.js +120 -0
- package/dist/modules/key-plays/view/KeyPlayErrorStateView.js +58 -0
- package/dist/modules/key-plays/view/KeyPlaysView.js +166 -0
- package/dist/modules/key-plays/view-model/KeyPlaysViewModel.js +182 -0
- package/dist/modules/stats/interfaces/IStats.d.ts +166 -0
- package/dist/modules/stats/interfaces/IStats.js +1 -0
- package/dist/modules/stats/mocks.d.ts +82 -0
- package/dist/modules/stats/mocks.js +686 -0
- package/dist/modules/stats/utils/renderTeamStatistic.d.ts +21 -0
- package/dist/modules/stats/utils/renderTeamStatistic.js +16 -0
- package/dist/modules/stats/utils.d.ts +39 -0
- package/dist/modules/stats/utils.js +62 -0
- package/dist/modules/stats/view/ActiveAthletes/ActiveAthletes.d.ts +34 -0
- package/dist/modules/stats/view/ActiveAthletes/ActiveAthletes.js +78 -0
- package/dist/modules/stats/view/ActiveAthletes/CollapsedAthletes/CollapsedAthletes.d.ts +5 -0
- package/dist/modules/stats/view/ActiveAthletes/CollapsedAthletes/CollapsedAthletes.js +27 -0
- package/dist/modules/stats/view/ActiveAthletes/ExpandedAthletes/ExpandedAthletes.d.ts +10 -0
- package/dist/modules/stats/view/ActiveAthletes/ExpandedAthletes/ExpandedAthletes.js +15 -0
- package/dist/modules/stats/view/ActiveAthletes/index.d.ts +2 -0
- package/dist/modules/stats/view/ActiveAthletes/index.js +2 -0
- package/dist/modules/stats/view/GameLeaders/GameLeaders.d.ts +8 -0
- package/dist/modules/stats/view/GameLeaders/GameLeaders.js +9 -0
- package/dist/modules/stats/view/GameLeaders/index.d.ts +2 -0
- package/dist/modules/stats/view/GameLeaders/index.js +2 -0
- package/dist/modules/stats/view/MatchPredictor/DonutChart/DonutChart.d.ts +17 -0
- package/dist/modules/stats/view/MatchPredictor/DonutChart/DonutChart.js +55 -0
- package/dist/modules/stats/view/MatchPredictor/DonutChart/index.d.ts +2 -0
- package/dist/modules/stats/view/MatchPredictor/DonutChart/index.js +1 -0
- package/dist/modules/stats/view/MatchPredictor/MatchPredictorView.d.ts +53 -0
- package/dist/modules/stats/view/MatchPredictor/MatchPredictorView.js +66 -0
- package/dist/modules/stats/view/MatchPredictor/index.d.ts +3 -0
- package/dist/modules/stats/view/MatchPredictor/index.js +2 -0
- package/dist/modules/stats/view/RecentGames/RecentGames.d.ts +63 -0
- package/dist/modules/stats/view/RecentGames/RecentGames.js +22 -0
- package/dist/modules/stats/view/RecentGames/index.d.ts +2 -0
- package/dist/modules/stats/view/RecentGames/index.js +2 -0
- package/dist/modules/stats/view/StatsQRCode/StatsQRCodeView.d.ts +52 -0
- package/dist/modules/stats/view/StatsQRCode/StatsQRCodeView.js +38 -0
- package/dist/modules/stats/view/StatsQRCode/index.d.ts +2 -0
- package/dist/modules/stats/view/StatsQRCode/index.js +1 -0
- package/dist/modules/stats/view/StatsView.d.ts +20 -0
- package/dist/modules/stats/view/StatsView.js +107 -0
- package/dist/modules/stats/view/TeamStats/TeamStatsView.d.ts +54 -0
- package/dist/modules/stats/view/TeamStats/TeamStatsView.js +69 -0
- package/dist/modules/stats/view/TeamStats/index.d.ts +2 -0
- package/dist/modules/stats/view/TeamStats/index.js +1 -0
- package/dist/modules/stats/view/Teams/StatsCarousel.d.ts +8 -0
- package/dist/modules/stats/view/Teams/StatsCarousel.js +14 -0
- package/dist/modules/stats/view/Teams/StatsProgressBar.d.ts +7 -0
- package/dist/modules/stats/view/Teams/StatsProgressBar.js +18 -0
- package/dist/modules/stats/view/Teams/Teams.d.ts +68 -0
- package/dist/modules/stats/view/Teams/Teams.js +42 -0
- package/dist/modules/stats/view/Teams/index.d.ts +2 -0
- package/dist/modules/stats/view/Teams/index.js +2 -0
- package/dist/modules/stats/view/WinProbability/WinProbability.d.ts +63 -0
- package/dist/modules/stats/view/WinProbability/WinProbability.js +27 -0
- package/dist/modules/stats/view/WinProbability/index.d.ts +2 -0
- package/dist/modules/stats/view/WinProbability/index.js +2 -0
- package/dist/modules/stats/view/components/AthletesStatistics/AthletesStatistics.d.ts +67 -0
- package/dist/modules/stats/view/components/AthletesStatistics/AthletesStatistics.js +29 -0
- package/dist/modules/stats/view/components/AthletesStatistics/StatisticTable.d.ts +4 -0
- package/dist/modules/stats/view/components/AthletesStatistics/StatisticTable.js +12 -0
- package/dist/modules/stats/view/components/AthletesStatistics/index.d.ts +2 -0
- package/dist/modules/stats/view/components/AthletesStatistics/index.js +2 -0
- package/dist/modules/stats/view/index.d.ts +2 -0
- package/dist/modules/stats/view/index.js +2 -0
- package/dist/modules/stats/view-model/StatsViewModel.d.ts +31 -0
- package/dist/modules/stats/view-model/StatsViewModel.js +90 -0
- package/dist/services/BetsService.js +102 -0
- package/dist/services/NetworkManager/NetworkManager.js +410 -0
- package/dist/services/NetworkManager/errors.js +45 -0
- package/dist/services/StatsService.d.ts +36 -0
- package/dist/services/StatsService.js +68 -0
- package/dist/services/ThemeManager/constants.js +47 -0
- package/dist/test-polyfills.d.ts +1 -0
- package/dist/test-polyfills.js +15 -0
- package/dist/types/OverlayTypes.js +4 -0
- package/dist/view-models/MaestroEventViewModel.d.ts +9 -0
- package/dist/view-models/MaestroEventViewModel.js +168 -0
- package/dist/view-models/OverlayViewModel.js +222 -0
- package/dist/view-models/PanelManagerViewModel.js +80 -0
- package/dist/view-models/ViewModel.js +32 -0
- package/dist/view-models/index.js +59 -0
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
const REQUEST_TIMEOUT = 5000;
|
|
3
|
+
class AxiosNetworkClient {
|
|
4
|
+
constructor({ baseURL, retries, delay, backoff, axiosInstance, }) {
|
|
5
|
+
Object.defineProperty(this, "client", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "retries", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(this, "delay", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "backoff", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
this.retries = retries;
|
|
30
|
+
this.delay = delay;
|
|
31
|
+
this.backoff = backoff;
|
|
32
|
+
this.client =
|
|
33
|
+
axiosInstance ||
|
|
34
|
+
axios.create({
|
|
35
|
+
baseURL,
|
|
36
|
+
headers: {
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
},
|
|
39
|
+
timeout: REQUEST_TIMEOUT,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async retry(operation, attempt = 0) {
|
|
43
|
+
try {
|
|
44
|
+
return await operation();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const axiosError = error;
|
|
48
|
+
// Check if we should retry
|
|
49
|
+
const shouldRetry = attempt < this.retries &&
|
|
50
|
+
((axiosError.response && axiosError.response.status === 429) ||
|
|
51
|
+
axiosError.code === 'ECONNABORTED');
|
|
52
|
+
if (shouldRetry) {
|
|
53
|
+
const delayTime = this.delay * Math.pow(this.backoff, attempt);
|
|
54
|
+
console.log(`Retrying request in ${delayTime}ms due to: ${axiosError.message}`);
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, delayTime));
|
|
56
|
+
return this.retry(operation, attempt + 1);
|
|
57
|
+
}
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async get(endpoint, params, headers) {
|
|
62
|
+
return this.retry(async () => {
|
|
63
|
+
const response = await this.client.get(endpoint, {
|
|
64
|
+
params,
|
|
65
|
+
headers,
|
|
66
|
+
});
|
|
67
|
+
return response.data;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async post(endpoint, data) {
|
|
71
|
+
return this.retry(async () => {
|
|
72
|
+
const response = await this.client.post(endpoint, data);
|
|
73
|
+
return response.data;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
setAuthentication(token, apiKey) {
|
|
77
|
+
this.client.defaults.headers.common['Authorization'] = token
|
|
78
|
+
? `Bearer ${token}`
|
|
79
|
+
: '';
|
|
80
|
+
this.client.defaults.headers.common['x-maestro-api-key'] = apiKey || '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export default AxiosNetworkClient;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages caching using localStorage with support for TTL, size limits, and versioning.
|
|
3
|
+
* This class implements the ICacheManager interface and provides methods for setting, getting,
|
|
4
|
+
* and clearing cache entries.
|
|
5
|
+
*/
|
|
6
|
+
export default class LocalStorageCacheManager {
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new LocalStorageCacheManager instance.
|
|
9
|
+
* @param cacheDuration - The time-to-live (TTL) for cache entries in milliseconds.
|
|
10
|
+
* @param maxSize - The maximum size of the cache in bytes.
|
|
11
|
+
* @param version - The version of the cache. Used to invalidate cache entries when the version changes.
|
|
12
|
+
*/
|
|
13
|
+
constructor(cacheDuration = 3600000, maxSize = 5 * 1024 * 1024, version = '1.0') {
|
|
14
|
+
Object.defineProperty(this, "prefix", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: 'maestro-cache-'
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "cacheDuration", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: void 0
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "maxSize", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "version", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "accessLog", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: void 0
|
|
43
|
+
});
|
|
44
|
+
this.cacheDuration = cacheDuration;
|
|
45
|
+
this.maxSize = maxSize;
|
|
46
|
+
this.version = version;
|
|
47
|
+
this.accessLog = new Map();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Produces a cache key by combining the prefix, version, and the provided key.
|
|
51
|
+
* @param key - The key to be used in the cache.
|
|
52
|
+
* @returns The generated cache key.
|
|
53
|
+
*/
|
|
54
|
+
produceCacheKey(key) {
|
|
55
|
+
return `${this.prefix}${this.version}:${key}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Calculates the current size of the cache in bytes.
|
|
59
|
+
* @returns The total size of the cache in bytes.
|
|
60
|
+
*/
|
|
61
|
+
getCurrentSize() {
|
|
62
|
+
let totalSize = 0;
|
|
63
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
64
|
+
const key = localStorage.key(i);
|
|
65
|
+
if (key?.startsWith(this.prefix)) {
|
|
66
|
+
const value = localStorage.getItem(key);
|
|
67
|
+
if (value) {
|
|
68
|
+
totalSize += key.length + value.length;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return totalSize;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Cleans up old cache entries based on their TTL.
|
|
76
|
+
*/
|
|
77
|
+
cleanupOldEntries() {
|
|
78
|
+
const now = Date.now();
|
|
79
|
+
// Collect keys to remove first
|
|
80
|
+
const keysToRemove = [];
|
|
81
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
82
|
+
const key = localStorage.key(i);
|
|
83
|
+
if (key?.startsWith(this.prefix)) {
|
|
84
|
+
const value = localStorage.getItem(key);
|
|
85
|
+
if (value) {
|
|
86
|
+
try {
|
|
87
|
+
const { timestamp } = JSON.parse(value);
|
|
88
|
+
if (now - timestamp > this.cacheDuration) {
|
|
89
|
+
keysToRemove.push(key);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
keysToRemove.push(key);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
keysToRemove.forEach((key) => {
|
|
99
|
+
localStorage.removeItem(key);
|
|
100
|
+
// Remove from accessLog
|
|
101
|
+
const logicalKey = key.replace(this.prefix + this.version + ':', '');
|
|
102
|
+
this.accessLog.delete(logicalKey);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Cleans up least recently used cache entries when the cache is full.
|
|
107
|
+
*/
|
|
108
|
+
cleanupLRUEntries(newItemSize) {
|
|
109
|
+
// Remove oldest entries until we're under the size limit
|
|
110
|
+
const entries = Array.from(this.accessLog.entries()).sort(([, a], [, b]) => a - b);
|
|
111
|
+
while (this.getCurrentSize() + newItemSize > this.maxSize &&
|
|
112
|
+
entries.length > 0) {
|
|
113
|
+
const [key] = entries.shift();
|
|
114
|
+
localStorage.removeItem(this.produceCacheKey(key));
|
|
115
|
+
this.accessLog.delete(key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Sets a value in the cache with the specified key.
|
|
120
|
+
* @param key - The key to store the value under.
|
|
121
|
+
* @param data - The value to be stored in the cache.
|
|
122
|
+
*/
|
|
123
|
+
setCache(key, data) {
|
|
124
|
+
this.cleanupOldEntries();
|
|
125
|
+
const cacheKey = this.produceCacheKey(key);
|
|
126
|
+
const cacheData = {
|
|
127
|
+
data,
|
|
128
|
+
timestamp: Date.now(),
|
|
129
|
+
};
|
|
130
|
+
const newItemSize = cacheKey.length + JSON.stringify(cacheData).length;
|
|
131
|
+
this.cleanupLRUEntries(newItemSize);
|
|
132
|
+
// After cleanup, check if it fits
|
|
133
|
+
if (this.getCurrentSize() + newItemSize > this.maxSize) {
|
|
134
|
+
// Still doesn't fit, don't add
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
|
|
138
|
+
this.accessLog.set(key, Date.now());
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Retrieves a value from the cache by its key.
|
|
142
|
+
* @param key - The key to retrieve the value for.
|
|
143
|
+
* @returns The cached value, or null if the key is not found or the entry has expired.
|
|
144
|
+
*/
|
|
145
|
+
getCache(key) {
|
|
146
|
+
this.cleanupOldEntries();
|
|
147
|
+
const cacheKey = this.produceCacheKey(key);
|
|
148
|
+
const cachedData = localStorage.getItem(cacheKey);
|
|
149
|
+
if (!cachedData) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const { data, timestamp } = JSON.parse(cachedData);
|
|
154
|
+
const now = Date.now();
|
|
155
|
+
if (now - timestamp > this.cacheDuration) {
|
|
156
|
+
localStorage.removeItem(cacheKey);
|
|
157
|
+
this.accessLog.delete(key);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
// Update last access time
|
|
161
|
+
this.accessLog.set(key, now);
|
|
162
|
+
return data;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
localStorage.removeItem(cacheKey);
|
|
166
|
+
this.accessLog.delete(key);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Clears a specific cache entry by its key.
|
|
172
|
+
* @param key - The key of the cache entry to clear.
|
|
173
|
+
*/
|
|
174
|
+
clearCache(key) {
|
|
175
|
+
const cacheKey = this.produceCacheKey(key);
|
|
176
|
+
localStorage.removeItem(cacheKey);
|
|
177
|
+
this.accessLog.delete(key);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Clears all cache entries that match the specified pattern.
|
|
181
|
+
* @param pattern - The pattern to match against cache keys.
|
|
182
|
+
*/
|
|
183
|
+
clearCacheByPattern(pattern) {
|
|
184
|
+
// Collect all matching keys first
|
|
185
|
+
const keysToRemove = [];
|
|
186
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
187
|
+
const key = localStorage.key(i);
|
|
188
|
+
if (key?.startsWith(this.prefix) && key.includes(pattern)) {
|
|
189
|
+
keysToRemove.push(key);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
keysToRemove.forEach((key) => {
|
|
193
|
+
localStorage.removeItem(key);
|
|
194
|
+
// Remove from accessLog
|
|
195
|
+
const logicalKey = key.replace(this.prefix + this.version + ':', '');
|
|
196
|
+
this.accessLog.delete(logicalKey);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Clears all cache entries.
|
|
201
|
+
*/
|
|
202
|
+
clearAllCache() {
|
|
203
|
+
const keysToRemove = [];
|
|
204
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
205
|
+
const key = localStorage.key(i);
|
|
206
|
+
if (key?.startsWith(this.prefix)) {
|
|
207
|
+
keysToRemove.push(key);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
keysToRemove.forEach((key) => localStorage.removeItem(key));
|
|
211
|
+
this.accessLog.clear();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IRenderer } from './ports/renderer';
|
|
2
2
|
import { MaestroViewModels } from '@/view-models';
|
|
3
|
-
import
|
|
3
|
+
import IMaestroEventDelegate from '@/interfaces/IMaestroEventDelegate';
|
|
4
4
|
declare class ReactRenderer implements IRenderer {
|
|
5
5
|
private renderersMap;
|
|
6
6
|
viewModels: MaestroViewModels | null;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { MaestroViewModels } from '@/view-models';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom';
|
|
4
|
+
import OverlayContainer from '../components/core/OverlayContainer';
|
|
5
|
+
class ReactRenderer {
|
|
6
|
+
constructor() {
|
|
7
|
+
Object.defineProperty(this, "renderersMap", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: new Map()
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "viewModels", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: null
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Sets the view models for the renderer
|
|
22
|
+
* @param eventId The event ID to create view models for
|
|
23
|
+
* @param delegate The event delegate to use
|
|
24
|
+
*/
|
|
25
|
+
async setViewModels(eventId, delegate) {
|
|
26
|
+
try {
|
|
27
|
+
if (!delegate) {
|
|
28
|
+
console.error('No event delegate provided');
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
this.viewModels = await MaestroViewModels.fromEventId(eventId, delegate);
|
|
32
|
+
return this.viewModels;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error('Error creating view models from event ID', error);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Renders the panel manager
|
|
41
|
+
* @param id The element ID to render in
|
|
42
|
+
* @param options Options for rendering including height and width
|
|
43
|
+
*/
|
|
44
|
+
async renderPanel(id) {
|
|
45
|
+
const renderer = await this.getRenderer(id);
|
|
46
|
+
if (!this.viewModels) {
|
|
47
|
+
throw new Error('Cannot render panel manager: No view models set');
|
|
48
|
+
}
|
|
49
|
+
const App = require('../components/core/App').default;
|
|
50
|
+
const PanelManager = require('../components/core/PanelManager').default;
|
|
51
|
+
renderer.render(React.createElement(App, null,
|
|
52
|
+
React.createElement(PanelManager, null),
|
|
53
|
+
React.createElement(OverlayContainer, {
|
|
54
|
+
viewModels: this.viewModels,
|
|
55
|
+
})));
|
|
56
|
+
return () => {
|
|
57
|
+
renderer.unmount();
|
|
58
|
+
this.renderersMap.delete(id);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @description Get the render function and renderer for the MaestroWebSDK. Useful to configure the renderer and fonts before rendering the component.
|
|
63
|
+
* @param {string} id - The id of the element to render the component in.
|
|
64
|
+
* @param {{ height: number; width: number }} options - The height and width of the component.
|
|
65
|
+
*/
|
|
66
|
+
async getRenderer(id) {
|
|
67
|
+
if (this.renderersMap.has(id)) {
|
|
68
|
+
return this.renderersMap.get(id);
|
|
69
|
+
}
|
|
70
|
+
const el = document.getElementById(id);
|
|
71
|
+
if (!el) {
|
|
72
|
+
throw new Error(`Element with id ${id} not found`);
|
|
73
|
+
}
|
|
74
|
+
const renderer = {
|
|
75
|
+
render: (children) => {
|
|
76
|
+
ReactDOM.render(children, el);
|
|
77
|
+
},
|
|
78
|
+
unmount: () => {
|
|
79
|
+
ReactDOM.unmountComponentAtNode(el);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
this.renderersMap.set(id, renderer);
|
|
83
|
+
return renderer;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export default ReactRenderer;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A mock implementation of the INetworkClient interface for testing
|
|
3
|
+
* and development purposes.
|
|
4
|
+
*/
|
|
5
|
+
class MockNetworkClient {
|
|
6
|
+
/**
|
|
7
|
+
* Constructor for MockNetworkClient
|
|
8
|
+
*
|
|
9
|
+
* @param mockResponses - Optional initial mock responses mapping
|
|
10
|
+
* @param mockErrors - Optional initial mock errors mapping
|
|
11
|
+
* @param defaultResponse - Default response for unmocked endpoints
|
|
12
|
+
* @param delay - Simulated network delay in milliseconds
|
|
13
|
+
*/
|
|
14
|
+
constructor({ mockResponses = {}, mockErrors = {}, defaultResponse = { success: true }, delay = 0, } = {}) {
|
|
15
|
+
Object.defineProperty(this, "mockResponses", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: new Map()
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(this, "mockErrors", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: new Map()
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(this, "defaultResponse", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: { success: true }
|
|
32
|
+
});
|
|
33
|
+
Object.defineProperty(this, "defaultError", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
writable: true,
|
|
37
|
+
value: null
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(this, "latestRequest", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: null
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(this, "delay", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: 0
|
|
50
|
+
});
|
|
51
|
+
// Convert object to Map
|
|
52
|
+
Object.entries(mockResponses).forEach(([key, value]) => {
|
|
53
|
+
this.mockResponses.set(key, value);
|
|
54
|
+
});
|
|
55
|
+
Object.entries(mockErrors).forEach(([key, value]) => {
|
|
56
|
+
this.mockErrors.set(key, value);
|
|
57
|
+
});
|
|
58
|
+
this.defaultResponse = defaultResponse;
|
|
59
|
+
this.delay = delay;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the latest request made to this mock client
|
|
63
|
+
*/
|
|
64
|
+
getLatestRequest() {
|
|
65
|
+
return this.latestRequest;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Set a mock response for a specific endpoint
|
|
69
|
+
*
|
|
70
|
+
* @param endpoint - The API endpoint
|
|
71
|
+
* @param response - The mock response data
|
|
72
|
+
*/
|
|
73
|
+
setMockResponse(endpoint, response) {
|
|
74
|
+
this.mockResponses.set(endpoint, response);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set a mock error for a specific endpoint
|
|
78
|
+
*
|
|
79
|
+
* @param endpoint - The API endpoint
|
|
80
|
+
* @param error - The error to throw
|
|
81
|
+
*/
|
|
82
|
+
setMockError(endpoint, error) {
|
|
83
|
+
this.mockErrors.set(endpoint, error);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Set a default mock response for all unmocked endpoints
|
|
87
|
+
*
|
|
88
|
+
* @param response - The default response data
|
|
89
|
+
*/
|
|
90
|
+
setDefaultResponse(response) {
|
|
91
|
+
this.defaultResponse = response;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Set a default error for all endpoints not configured with specific errors
|
|
95
|
+
*
|
|
96
|
+
* @param error - The default error
|
|
97
|
+
*/
|
|
98
|
+
setDefaultError(error) {
|
|
99
|
+
this.defaultError = error;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Set the simulated network delay
|
|
103
|
+
*
|
|
104
|
+
* @param delayMs - Delay in milliseconds
|
|
105
|
+
*/
|
|
106
|
+
setDelay(delayMs) {
|
|
107
|
+
this.delay = delayMs;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Clear all mock responses and errors
|
|
111
|
+
*/
|
|
112
|
+
reset() {
|
|
113
|
+
this.mockResponses.clear();
|
|
114
|
+
this.mockErrors.clear();
|
|
115
|
+
this.defaultResponse = { success: true };
|
|
116
|
+
this.defaultError = null;
|
|
117
|
+
this.latestRequest = null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Helper method to handle the common response/error/delay logic
|
|
121
|
+
*/
|
|
122
|
+
async handleRequest(method, endpoint, data, params, headers) {
|
|
123
|
+
this.latestRequest = { method, endpoint, data, params, headers };
|
|
124
|
+
// Apply delay if configured
|
|
125
|
+
if (this.delay > 0) {
|
|
126
|
+
await new Promise((resolve) => setTimeout(resolve, this.delay));
|
|
127
|
+
}
|
|
128
|
+
// Check if there's a specific error for this endpoint
|
|
129
|
+
if (this.mockErrors.has(endpoint)) {
|
|
130
|
+
throw this.mockErrors.get(endpoint);
|
|
131
|
+
}
|
|
132
|
+
// Check if there's a default error
|
|
133
|
+
if (this.defaultError) {
|
|
134
|
+
throw this.defaultError;
|
|
135
|
+
}
|
|
136
|
+
// Return mock response for the endpoint, or the default response
|
|
137
|
+
return this.mockResponses.has(endpoint)
|
|
138
|
+
? this.mockResponses.get(endpoint)
|
|
139
|
+
: this.defaultResponse;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Mock implementation of the get method
|
|
143
|
+
*/
|
|
144
|
+
async get(endpoint, params, headers) {
|
|
145
|
+
return this.handleRequest('GET', endpoint, undefined, params, headers);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Mock implementation of the post method
|
|
149
|
+
*/
|
|
150
|
+
async post(endpoint, data) {
|
|
151
|
+
return this.handleRequest('POST', endpoint, data);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Mock implementation of setAuthentication
|
|
155
|
+
*/
|
|
156
|
+
setAuthentication(token, apiKey) {
|
|
157
|
+
// No-op in mock implementation
|
|
158
|
+
console.log('setAuthentication called with token:', token, 'and apiKey:', apiKey);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export default MockNetworkClient;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import withFocusable, { WithFocusableProps } from './withFocusable';
|
|
2
|
-
import { InitOptions, KeyMap } from './spatialNavigation';
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
export type { InitOptions, KeyMap, WithFocusableProps };
|
|
2
|
+
import SpatialNavigation, { InitOptions, KeyMap } from './spatialNavigation';
|
|
3
|
+
export { withFocusable, SpatialNavigation };
|
|
4
|
+
export { InitOptions, KeyMap, WithFocusableProps };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const ELEMENT_NODE = 1;
|
|
2
|
+
const getRect = (node) => {
|
|
3
|
+
let { offsetParent } = node;
|
|
4
|
+
const height = node.offsetHeight;
|
|
5
|
+
const width = node.offsetWidth;
|
|
6
|
+
let left = node.offsetLeft;
|
|
7
|
+
let top = node.offsetTop;
|
|
8
|
+
while (offsetParent && offsetParent.nodeType === ELEMENT_NODE) {
|
|
9
|
+
left += offsetParent.offsetLeft - offsetParent.scrollLeft;
|
|
10
|
+
top += offsetParent.offsetTop - offsetParent.scrollTop;
|
|
11
|
+
({ offsetParent } = offsetParent);
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
height,
|
|
15
|
+
left,
|
|
16
|
+
top,
|
|
17
|
+
width,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const measureLayout = (node, callback) => {
|
|
21
|
+
const relativeNode = node && node.parentNode;
|
|
22
|
+
if (relativeNode) {
|
|
23
|
+
const relativeRect = getRect(relativeNode);
|
|
24
|
+
const { height, left, top, width } = getRect(node);
|
|
25
|
+
const x = left - relativeRect.left;
|
|
26
|
+
const y = top - relativeRect.top;
|
|
27
|
+
callback(x, y, width, height, left, top);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export default measureLayout;
|
|
@@ -72,7 +72,6 @@ declare class SpatialNavigation {
|
|
|
72
72
|
private focusableComponents;
|
|
73
73
|
private focusKey;
|
|
74
74
|
private parentsHavingFocusedChild;
|
|
75
|
-
private enabled;
|
|
76
75
|
private nativeMode;
|
|
77
76
|
private throttle;
|
|
78
77
|
private throttleKeypresses;
|
|
@@ -105,7 +104,7 @@ declare class SpatialNavigation {
|
|
|
105
104
|
* They used as a base to measure adjacent slices
|
|
106
105
|
*/
|
|
107
106
|
sortSiblingsByPriority(siblings: FocusableComponent[], currentLayout: Layout, direction: Direction, _focusKey: string): FocusableComponent[];
|
|
108
|
-
constructor();
|
|
107
|
+
constructor(options?: InitOptions);
|
|
109
108
|
init({ debug, visualDebug, nativeMode, throttle, throttleKeypresses, }?: InitOptions): void;
|
|
110
109
|
startDrawLayouts(): void;
|
|
111
110
|
destroy(): void;
|
|
@@ -153,5 +152,4 @@ declare class SpatialNavigation {
|
|
|
153
152
|
/**
|
|
154
153
|
* Export singleton
|
|
155
154
|
*/
|
|
156
|
-
|
|
157
|
-
export default _default;
|
|
155
|
+
export default SpatialNavigation;
|