@vynix-org/react-native-ads-sdk 0.1.1

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 (128) hide show
  1. package/AdsSdk.podspec +52 -0
  2. package/LICENSE +20 -0
  3. package/README.md +95 -0
  4. package/android/build.gradle +108 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +5 -0
  7. package/android/src/main/java/com/adssdk/AdsSdkModule.kt +23 -0
  8. package/android/src/main/java/com/adssdk/AdsSdkPackage.kt +33 -0
  9. package/ios/AdsSdk.h +5 -0
  10. package/ios/AdsSdk.mm +18 -0
  11. package/lib/module/ads-manager/AppOpenAdsManager.js +131 -0
  12. package/lib/module/ads-manager/AppOpenAdsManager.js.map +1 -0
  13. package/lib/module/ads-manager/GoogleMobileAdsManager.js +62 -0
  14. package/lib/module/ads-manager/GoogleMobileAdsManager.js.map +1 -0
  15. package/lib/module/ads-manager/InterstitialAdsManager.js +291 -0
  16. package/lib/module/ads-manager/InterstitialAdsManager.js.map +1 -0
  17. package/lib/module/ads-manager/NativeAdsManager.js +405 -0
  18. package/lib/module/ads-manager/NativeAdsManager.js.map +1 -0
  19. package/lib/module/ads-manager/RewardedAdsManager.js +328 -0
  20. package/lib/module/ads-manager/RewardedAdsManager.js.map +1 -0
  21. package/lib/module/ads-manager/RewardedInterstitialAdsManager.js +328 -0
  22. package/lib/module/ads-manager/RewardedInterstitialAdsManager.js.map +1 -0
  23. package/lib/module/components/BannerAdComponent.js +159 -0
  24. package/lib/module/components/BannerAdComponent.js.map +1 -0
  25. package/lib/module/components/FullscreenStyles.js +162 -0
  26. package/lib/module/components/FullscreenStyles.js.map +1 -0
  27. package/lib/module/components/NativeAdComponent.js +172 -0
  28. package/lib/module/components/NativeAdComponent.js.map +1 -0
  29. package/lib/module/components/NativeAdFullscreenComponent.js +205 -0
  30. package/lib/module/components/NativeAdFullscreenComponent.js.map +1 -0
  31. package/lib/module/components/NativeStyles.js +143 -0
  32. package/lib/module/components/NativeStyles.js.map +1 -0
  33. package/lib/module/event/custom-event.js +29 -0
  34. package/lib/module/event/custom-event.js.map +1 -0
  35. package/lib/module/hook/useAppOpenAd.js +138 -0
  36. package/lib/module/hook/useAppOpenAd.js.map +1 -0
  37. package/lib/module/hook/useInterstitialAd.js +157 -0
  38. package/lib/module/hook/useInterstitialAd.js.map +1 -0
  39. package/lib/module/hook/useNativeAd.js +147 -0
  40. package/lib/module/hook/useNativeAd.js.map +1 -0
  41. package/lib/module/hook/useRewardedAd.js +166 -0
  42. package/lib/module/hook/useRewardedAd.js.map +1 -0
  43. package/lib/module/hook/useRewardedInterstitialAd.js +166 -0
  44. package/lib/module/hook/useRewardedInterstitialAd.js.map +1 -0
  45. package/lib/module/index.js +14 -0
  46. package/lib/module/index.js.map +1 -0
  47. package/lib/module/package.json +1 -0
  48. package/lib/module/stores/interstitial-ads-store.js +205 -0
  49. package/lib/module/stores/interstitial-ads-store.js.map +1 -0
  50. package/lib/module/stores/native-ads-store.js +204 -0
  51. package/lib/module/stores/native-ads-store.js.map +1 -0
  52. package/lib/module/stores/rewarded-ads-store.js +216 -0
  53. package/lib/module/stores/rewarded-ads-store.js.map +1 -0
  54. package/lib/module/stores/rewarded-interstitial-ads-store.js +216 -0
  55. package/lib/module/stores/rewarded-interstitial-ads-store.js.map +1 -0
  56. package/lib/module/types/ads-types.js +25 -0
  57. package/lib/module/types/ads-types.js.map +1 -0
  58. package/lib/typescript/package.json +1 -0
  59. package/lib/typescript/src/ads-manager/AppOpenAdsManager.d.ts +38 -0
  60. package/lib/typescript/src/ads-manager/AppOpenAdsManager.d.ts.map +1 -0
  61. package/lib/typescript/src/ads-manager/GoogleMobileAdsManager.d.ts +22 -0
  62. package/lib/typescript/src/ads-manager/GoogleMobileAdsManager.d.ts.map +1 -0
  63. package/lib/typescript/src/ads-manager/InterstitialAdsManager.d.ts +22 -0
  64. package/lib/typescript/src/ads-manager/InterstitialAdsManager.d.ts.map +1 -0
  65. package/lib/typescript/src/ads-manager/NativeAdsManager.d.ts +59 -0
  66. package/lib/typescript/src/ads-manager/NativeAdsManager.d.ts.map +1 -0
  67. package/lib/typescript/src/ads-manager/RewardedAdsManager.d.ts +25 -0
  68. package/lib/typescript/src/ads-manager/RewardedAdsManager.d.ts.map +1 -0
  69. package/lib/typescript/src/ads-manager/RewardedInterstitialAdsManager.d.ts +25 -0
  70. package/lib/typescript/src/ads-manager/RewardedInterstitialAdsManager.d.ts.map +1 -0
  71. package/lib/typescript/src/components/BannerAdComponent.d.ts +22 -0
  72. package/lib/typescript/src/components/BannerAdComponent.d.ts.map +1 -0
  73. package/lib/typescript/src/components/FullscreenStyles.d.ts +155 -0
  74. package/lib/typescript/src/components/FullscreenStyles.d.ts.map +1 -0
  75. package/lib/typescript/src/components/NativeAdComponent.d.ts +24 -0
  76. package/lib/typescript/src/components/NativeAdComponent.d.ts.map +1 -0
  77. package/lib/typescript/src/components/NativeAdFullscreenComponent.d.ts +26 -0
  78. package/lib/typescript/src/components/NativeAdFullscreenComponent.d.ts.map +1 -0
  79. package/lib/typescript/src/components/NativeStyles.d.ts +139 -0
  80. package/lib/typescript/src/components/NativeStyles.d.ts.map +1 -0
  81. package/lib/typescript/src/event/custom-event.d.ts +8 -0
  82. package/lib/typescript/src/event/custom-event.d.ts.map +1 -0
  83. package/lib/typescript/src/hook/useAppOpenAd.d.ts +19 -0
  84. package/lib/typescript/src/hook/useAppOpenAd.d.ts.map +1 -0
  85. package/lib/typescript/src/hook/useInterstitialAd.d.ts +20 -0
  86. package/lib/typescript/src/hook/useInterstitialAd.d.ts.map +1 -0
  87. package/lib/typescript/src/hook/useNativeAd.d.ts +20 -0
  88. package/lib/typescript/src/hook/useNativeAd.d.ts.map +1 -0
  89. package/lib/typescript/src/hook/useRewardedAd.d.ts +27 -0
  90. package/lib/typescript/src/hook/useRewardedAd.d.ts.map +1 -0
  91. package/lib/typescript/src/hook/useRewardedInterstitialAd.d.ts +27 -0
  92. package/lib/typescript/src/hook/useRewardedInterstitialAd.d.ts.map +1 -0
  93. package/lib/typescript/src/index.d.ts +10 -0
  94. package/lib/typescript/src/index.d.ts.map +1 -0
  95. package/lib/typescript/src/stores/interstitial-ads-store.d.ts +36 -0
  96. package/lib/typescript/src/stores/interstitial-ads-store.d.ts.map +1 -0
  97. package/lib/typescript/src/stores/native-ads-store.d.ts +36 -0
  98. package/lib/typescript/src/stores/native-ads-store.d.ts.map +1 -0
  99. package/lib/typescript/src/stores/rewarded-ads-store.d.ts +39 -0
  100. package/lib/typescript/src/stores/rewarded-ads-store.d.ts.map +1 -0
  101. package/lib/typescript/src/stores/rewarded-interstitial-ads-store.d.ts +39 -0
  102. package/lib/typescript/src/stores/rewarded-interstitial-ads-store.d.ts.map +1 -0
  103. package/lib/typescript/src/types/ads-types.d.ts +164 -0
  104. package/lib/typescript/src/types/ads-types.d.ts.map +1 -0
  105. package/package.json +177 -0
  106. package/src/ads-manager/AppOpenAdsManager.ts +155 -0
  107. package/src/ads-manager/GoogleMobileAdsManager.ts +68 -0
  108. package/src/ads-manager/InterstitialAdsManager.ts +371 -0
  109. package/src/ads-manager/NativeAdsManager.ts +445 -0
  110. package/src/ads-manager/RewardedAdsManager.ts +383 -0
  111. package/src/ads-manager/RewardedInterstitialAdsManager.ts +410 -0
  112. package/src/components/BannerAdComponent.tsx +205 -0
  113. package/src/components/FullscreenStyles.ts +158 -0
  114. package/src/components/NativeAdComponent.tsx +208 -0
  115. package/src/components/NativeAdFullscreenComponent.tsx +261 -0
  116. package/src/components/NativeStyles.ts +141 -0
  117. package/src/event/custom-event.ts +30 -0
  118. package/src/hook/useAppOpenAd.ts +161 -0
  119. package/src/hook/useInterstitialAd.ts +195 -0
  120. package/src/hook/useNativeAd.ts +173 -0
  121. package/src/hook/useRewardedAd.ts +205 -0
  122. package/src/hook/useRewardedInterstitialAd.ts +212 -0
  123. package/src/index.tsx +33 -0
  124. package/src/stores/interstitial-ads-store.ts +287 -0
  125. package/src/stores/native-ads-store.ts +272 -0
  126. package/src/stores/rewarded-ads-store.ts +290 -0
  127. package/src/stores/rewarded-interstitial-ads-store.ts +318 -0
  128. package/src/types/ads-types.ts +239 -0
@@ -0,0 +1,287 @@
1
+ import { create } from 'zustand';
2
+ import { subscribeWithSelector } from 'zustand/middleware';
3
+ import { interstitialAdsManager } from '../ads-manager/InterstitialAdsManager';
4
+ import {
5
+ AdStatus,
6
+ type InterstitialAdInstance,
7
+ type InterstitialAdConfig,
8
+ } from '../types/ads-types';
9
+
10
+ interface InterstitialAdStore {
11
+ // State
12
+ ads: Map<string, InterstitialAdInstance>;
13
+ loadingKeys: Set<string>;
14
+ errors: Map<string, string>;
15
+
16
+ preloadAd: (config: InterstitialAdConfig) => Promise<void>;
17
+ loadAd: (config: InterstitialAdConfig) => Promise<void>;
18
+ displayAd: (adKey: string) => Promise<InterstitialAdInstance | null>;
19
+ removeAd: (adKey: string) => void;
20
+ refreshAd: (adKey: string) => Promise<void>;
21
+ clearAllAds: () => void;
22
+
23
+ // Getters
24
+ getAd: (adKey: string) => InterstitialAdInstance | null;
25
+ isLoading: (adKey: string) => boolean;
26
+ getError: (adKey: string) => string | null;
27
+ getAllAds: () => InterstitialAdInstance[];
28
+ getLoadedAds: () => InterstitialAdInstance[];
29
+ getErrorAds: () => InterstitialAdInstance[];
30
+ isUsingHighPriority: (adKey: string) => boolean;
31
+ hasTriedHighPriority: (adKey: string) => boolean;
32
+
33
+ // Internal actions
34
+ _updateAd: (ad: InterstitialAdInstance) => void;
35
+ _removeAd: (adKey: string) => void;
36
+ _setLoading: (adKey: string, loading: boolean) => void;
37
+ _setError: (adKey: string, error: string | null) => void;
38
+ _clearError: (adKey: string) => void;
39
+ }
40
+
41
+ export const useInterstitialAdStore = create<InterstitialAdStore>()(
42
+ subscribeWithSelector((set, get) => ({
43
+ // Initial state
44
+ ads: new Map(),
45
+ loadingKeys: new Set(),
46
+ errors: new Map(),
47
+
48
+ // Public actions
49
+ preloadAd: async (config) => {
50
+ const { adKey } = config;
51
+ try {
52
+ get()._setLoading(adKey, true);
53
+ get()._clearError(adKey);
54
+
55
+ await interstitialAdsManager.preloadAd(config);
56
+
57
+ const ad = interstitialAdsManager.getAd(adKey);
58
+ if (ad) {
59
+ get()._updateAd(ad);
60
+ }
61
+ } catch (error) {
62
+ const errorMessage =
63
+ error instanceof Error ? error.message : String(error);
64
+ get()._setError(adKey, errorMessage);
65
+ console.error(
66
+ `Failed to preload interstitial ad ${adKey}:`,
67
+ errorMessage
68
+ );
69
+ } finally {
70
+ get()._setLoading(adKey, false);
71
+ }
72
+ },
73
+
74
+ loadAd: async (config) => {
75
+ return get().preloadAd(config);
76
+ },
77
+
78
+ displayAd: async (adKey) => {
79
+ try {
80
+ get()._clearError(adKey);
81
+
82
+ const ad = await interstitialAdsManager.displayAd(adKey);
83
+ if (ad) {
84
+ get()._updateAd(ad);
85
+ }
86
+ return ad;
87
+ } catch (error) {
88
+ const errorMessage =
89
+ error instanceof Error ? error.message : String(error);
90
+ get()._setError(adKey, errorMessage);
91
+ console.error(
92
+ `Failed to display interstitial ad ${adKey}:`,
93
+ errorMessage
94
+ );
95
+ return null;
96
+ }
97
+ },
98
+
99
+ removeAd: (adKey) => {
100
+ interstitialAdsManager.removeAd(adKey);
101
+ get()._removeAd(adKey);
102
+ },
103
+
104
+ refreshAd: async (adKey) => {
105
+ try {
106
+ get()._setLoading(adKey, true);
107
+ get()._clearError(adKey);
108
+
109
+ await interstitialAdsManager.refreshAd(adKey);
110
+
111
+ const ad = interstitialAdsManager.getAd(adKey);
112
+ if (ad) {
113
+ get()._updateAd(ad);
114
+ }
115
+ } catch (error) {
116
+ const errorMessage =
117
+ error instanceof Error ? error.message : String(error);
118
+ get()._setError(adKey, errorMessage);
119
+ console.error(
120
+ `Failed to refresh interstitial ad ${adKey}:`,
121
+ errorMessage
122
+ );
123
+ } finally {
124
+ get()._setLoading(adKey, false);
125
+ }
126
+ },
127
+
128
+ clearAllAds: () => {
129
+ interstitialAdsManager.clearAllAds();
130
+ set({
131
+ ads: new Map(),
132
+ loadingKeys: new Set(),
133
+ errors: new Map(),
134
+ });
135
+ },
136
+
137
+ // Getters (không thay đổi)
138
+ getAd: (adKey) => {
139
+ return get().ads.get(adKey) || null;
140
+ },
141
+
142
+ isLoading: (adKey) => {
143
+ return get().loadingKeys.has(adKey);
144
+ },
145
+
146
+ getError: (adKey) => {
147
+ return get().errors.get(adKey) || null;
148
+ },
149
+
150
+ getAllAds: () => {
151
+ return Array.from(get().ads.values());
152
+ },
153
+
154
+ getLoadedAds: () => {
155
+ return Array.from(get().ads.values()).filter(
156
+ (ad) => ad.status === AdStatus.LOADED
157
+ );
158
+ },
159
+
160
+ getErrorAds: () => {
161
+ return Array.from(get().ads.values()).filter(
162
+ (ad) => ad.status === AdStatus.ERROR
163
+ );
164
+ },
165
+
166
+ isUsingHighPriority: (adKey) => {
167
+ const ad = get().ads.get(adKey);
168
+ return ad?.isUsingHighPriority || false;
169
+ },
170
+
171
+ hasTriedHighPriority: (adKey) => {
172
+ const ad = get().ads.get(adKey);
173
+ return ad?.hasTriedHighPriority || false;
174
+ },
175
+
176
+ // Internal actions (không thay đổi)
177
+ _updateAd: (ad) => {
178
+ set((state) => ({
179
+ ads: new Map(state.ads.set(ad.adKey, ad)),
180
+ }));
181
+ },
182
+
183
+ _removeAd: (adKey) => {
184
+ set((state) => {
185
+ const newAds = new Map(state.ads);
186
+ const newLoadingKeys = new Set(state.loadingKeys);
187
+ const newErrors = new Map(state.errors);
188
+
189
+ newAds.delete(adKey);
190
+ newLoadingKeys.delete(adKey);
191
+ newErrors.delete(adKey);
192
+
193
+ return {
194
+ ads: newAds,
195
+ loadingKeys: newLoadingKeys,
196
+ errors: newErrors,
197
+ };
198
+ });
199
+ },
200
+
201
+ _setLoading: (adKey, loading) => {
202
+ set((state) => {
203
+ const newLoadingKeys = new Set(state.loadingKeys);
204
+ if (loading) {
205
+ newLoadingKeys.add(adKey);
206
+ } else {
207
+ newLoadingKeys.delete(adKey);
208
+ }
209
+ return { loadingKeys: newLoadingKeys };
210
+ });
211
+ },
212
+
213
+ _setError: (adKey, error) => {
214
+ set((state) => {
215
+ const newErrors = new Map(state.errors);
216
+ if (error) {
217
+ newErrors.set(adKey, error);
218
+ } else {
219
+ newErrors.delete(adKey);
220
+ }
221
+ return { errors: newErrors };
222
+ });
223
+ },
224
+
225
+ _clearError: (adKey) => {
226
+ set((state) => {
227
+ const newErrors = new Map(state.errors);
228
+ newErrors.delete(adKey);
229
+ return { errors: newErrors };
230
+ });
231
+ },
232
+ }))
233
+ );
234
+
235
+ // Setup native manager listeners để sync với Zustand store
236
+ let isListenerSetup = false;
237
+
238
+ const setupInterstitialListeners = () => {
239
+ if (isListenerSetup) return;
240
+
241
+ interstitialAdsManager.on('adLoading', (ad: { adKey: string }) => {
242
+ useInterstitialAdStore.getState()._setLoading(ad.adKey, true);
243
+ });
244
+
245
+ interstitialAdsManager.on('adLoaded', (ad: InterstitialAdInstance) => {
246
+ useInterstitialAdStore.getState()._updateAd(ad);
247
+ useInterstitialAdStore.getState()._setLoading(ad.adKey, false);
248
+ useInterstitialAdStore.getState()._clearError(ad.adKey);
249
+ });
250
+
251
+ interstitialAdsManager.on('adDisplayed', (ad: InterstitialAdInstance) => {
252
+ useInterstitialAdStore.getState()._updateAd(ad);
253
+ });
254
+
255
+ interstitialAdsManager.on('adOpened', (ad: InterstitialAdInstance) => {
256
+ useInterstitialAdStore.getState()._updateAd(ad);
257
+ });
258
+
259
+ interstitialAdsManager.on('adClicked', (ad: InterstitialAdInstance) => {
260
+ useInterstitialAdStore.getState()._updateAd(ad);
261
+ });
262
+
263
+ interstitialAdsManager.on('adClosed', (ad: InterstitialAdInstance) => {
264
+ useInterstitialAdStore.getState()._updateAd(ad);
265
+ });
266
+
267
+ interstitialAdsManager.on('adError', (ad: InterstitialAdInstance) => {
268
+ useInterstitialAdStore.getState()._updateAd(ad);
269
+ useInterstitialAdStore.getState()._setLoading(ad.adKey, false);
270
+ useInterstitialAdStore
271
+ .getState()
272
+ ._setError(ad.adKey, ad.error || 'Unknown error');
273
+ });
274
+
275
+ interstitialAdsManager.on('adRemoved', (adKey: string) => {
276
+ useInterstitialAdStore.getState()._removeAd(adKey);
277
+ });
278
+
279
+ interstitialAdsManager.on('allAdsCleared', () => {
280
+ useInterstitialAdStore.getState().clearAllAds();
281
+ });
282
+
283
+ isListenerSetup = true;
284
+ };
285
+
286
+ // Initialize listeners
287
+ setupInterstitialListeners();
@@ -0,0 +1,272 @@
1
+ import { create } from 'zustand';
2
+ import { subscribeWithSelector } from 'zustand/middleware';
3
+ import { nativeAdsManager } from '../ads-manager/NativeAdsManager';
4
+ import { AdStatus, type AdInstance, type AdConfig } from '../types/ads-types';
5
+ // import { devtools } from 'zustand/middleware';
6
+
7
+ interface NativeAdStore {
8
+ // State
9
+ ads: Map<string, AdInstance>;
10
+ loadingKeys: Set<string>;
11
+ errors: Map<string, string>;
12
+
13
+ // Actions - CHỈ NHẬN CONFIG OBJECT
14
+ preloadAd: (config: AdConfig) => Promise<void>;
15
+ loadAd: (config: AdConfig) => Promise<void>;
16
+ displayAd: (adKey: string) => Promise<AdInstance | null>;
17
+ removeAd: (adKey: string) => void;
18
+ refreshAd: (adKey: string) => Promise<void>;
19
+ clearAllAds: () => void;
20
+
21
+ // Getters
22
+ getAd: (adKey: string) => AdInstance | null;
23
+ isLoading: (adKey: string) => boolean;
24
+ getError: (adKey: string) => string | null;
25
+ getAllAds: () => AdInstance[];
26
+ getLoadedAds: () => AdInstance[];
27
+ getErrorAds: () => AdInstance[];
28
+ isUsingHighPriority: (adKey: string) => boolean;
29
+ hasTriedHighPriority: (adKey: string) => boolean;
30
+
31
+ // Internal actions
32
+ _updateAd: (ad: AdInstance) => void;
33
+ _removeAd: (adKey: string) => void;
34
+ _setLoading: (adKey: string, loading: boolean) => void;
35
+ _setError: (adKey: string, error: string | null) => void;
36
+ _clearError: (adKey: string) => void;
37
+ }
38
+
39
+ export const useNativeAdStore = create<NativeAdStore>()(
40
+ subscribeWithSelector((set, get) => ({
41
+ // Initial state
42
+ ads: new Map(),
43
+ loadingKeys: new Set(),
44
+ errors: new Map(),
45
+
46
+ // Public actions
47
+ preloadAd: async (config) => {
48
+ try {
49
+ get()._setLoading(config.adKey, true);
50
+ get()._clearError(config.adKey);
51
+
52
+ await nativeAdsManager.preloadAd(config);
53
+
54
+ const ad = nativeAdsManager.getAd(config.adKey);
55
+ if (ad) {
56
+ get()._updateAd(ad);
57
+ }
58
+ } catch (error) {
59
+ const errorMessage =
60
+ error instanceof Error ? error.message : String(error);
61
+ get()._setError(config.adKey, errorMessage);
62
+ console.error(`Failed to preload ad ${config.adKey}:`, errorMessage);
63
+ } finally {
64
+ get()._setLoading(config.adKey, false);
65
+ }
66
+ },
67
+
68
+ loadAd: async (config) => {
69
+ return get().preloadAd(config);
70
+ },
71
+
72
+ displayAd: async (adKey) => {
73
+ try {
74
+ get()._clearError(adKey);
75
+
76
+ const ad = await nativeAdsManager.displayAd(adKey);
77
+ if (ad) {
78
+ get()._updateAd(ad);
79
+ }
80
+ return ad;
81
+ } catch (error) {
82
+ const errorMessage =
83
+ error instanceof Error ? error.message : String(error);
84
+ get()._setError(adKey, errorMessage);
85
+ console.error(`Failed to display ad ${adKey}:`, errorMessage);
86
+ return null;
87
+ }
88
+ },
89
+
90
+ removeAd: (adKey) => {
91
+ nativeAdsManager.removeAd(adKey);
92
+ get()._removeAd(adKey);
93
+ },
94
+
95
+ refreshAd: async (adKey) => {
96
+ try {
97
+ get()._setLoading(adKey, true);
98
+ get()._clearError(adKey);
99
+
100
+ await nativeAdsManager.refreshAd(adKey);
101
+
102
+ const ad = nativeAdsManager.getAd(adKey);
103
+ if (ad) {
104
+ get()._updateAd(ad);
105
+ }
106
+ } catch (error) {
107
+ const errorMessage =
108
+ error instanceof Error ? error.message : String(error);
109
+ get()._setError(adKey, errorMessage);
110
+ console.error(`Failed to refresh ad ${adKey}:`, errorMessage);
111
+ } finally {
112
+ get()._setLoading(adKey, false);
113
+ }
114
+ },
115
+
116
+ clearAllAds: () => {
117
+ nativeAdsManager.clearAllAds();
118
+ set({
119
+ ads: new Map(),
120
+ loadingKeys: new Set(),
121
+ errors: new Map(),
122
+ });
123
+ },
124
+
125
+ // Getters - GIỮ NGUYÊN
126
+ getAd: (adKey) => {
127
+ return get().ads.get(adKey) || null;
128
+ },
129
+
130
+ isLoading: (adKey) => {
131
+ return get().loadingKeys.has(adKey);
132
+ },
133
+
134
+ getError: (adKey) => {
135
+ return get().errors.get(adKey) || null;
136
+ },
137
+
138
+ getAllAds: () => {
139
+ return Array.from(get().ads.values());
140
+ },
141
+
142
+ getLoadedAds: () => {
143
+ return Array.from(get().ads.values()).filter(
144
+ (ad) => ad.status === AdStatus.LOADED
145
+ );
146
+ },
147
+
148
+ getErrorAds: () => {
149
+ return Array.from(get().ads.values()).filter(
150
+ (ad) => ad.status === AdStatus.ERROR
151
+ );
152
+ },
153
+
154
+ isUsingHighPriority: (adKey) => {
155
+ const ad = get().ads.get(adKey);
156
+ return ad?.isUsingHighPriority || false;
157
+ },
158
+
159
+ hasTriedHighPriority: (adKey) => {
160
+ const ad = get().ads.get(adKey);
161
+ return ad?.hasTriedHighPriority || false;
162
+ },
163
+
164
+ // Internal actions - GIỮ NGUYÊN
165
+ _updateAd: (ad) => {
166
+ set((state) => ({
167
+ ads: new Map(state.ads.set(ad.adKey, ad)),
168
+ }));
169
+ },
170
+
171
+ _removeAd: (adKey) => {
172
+ set((state) => {
173
+ const newAds = new Map(state.ads);
174
+ const newLoadingKeys = new Set(state.loadingKeys);
175
+ const newErrors = new Map(state.errors);
176
+
177
+ newAds.delete(adKey);
178
+ newLoadingKeys.delete(adKey);
179
+ newErrors.delete(adKey);
180
+
181
+ return {
182
+ ads: newAds,
183
+ loadingKeys: newLoadingKeys,
184
+ errors: newErrors,
185
+ };
186
+ });
187
+ },
188
+
189
+ _setLoading: (adKey, loading) => {
190
+ set((state) => {
191
+ const newLoadingKeys = new Set(state.loadingKeys);
192
+ if (loading) {
193
+ newLoadingKeys.add(adKey);
194
+ } else {
195
+ newLoadingKeys.delete(adKey);
196
+ }
197
+ return { loadingKeys: newLoadingKeys };
198
+ });
199
+ },
200
+
201
+ _setError: (adKey, error) => {
202
+ set((state) => {
203
+ const newErrors = new Map(state.errors);
204
+ if (error) {
205
+ newErrors.set(adKey, error);
206
+ } else {
207
+ newErrors.delete(adKey);
208
+ }
209
+ return { errors: newErrors };
210
+ });
211
+ },
212
+
213
+ _clearError: (adKey) => {
214
+ set((state) => {
215
+ const newErrors = new Map(state.errors);
216
+ newErrors.delete(adKey);
217
+ return { errors: newErrors };
218
+ });
219
+ },
220
+ }))
221
+ );
222
+
223
+ // Setup native manager listeners - GIỮ NGUYÊN
224
+ let isListenerSetup = false;
225
+
226
+ const setupNativeListeners = () => {
227
+ if (isListenerSetup) return;
228
+
229
+ nativeAdsManager.on('adLoading', (ad: { adKey: string }) => {
230
+ useNativeAdStore.getState()._setLoading(ad.adKey, true);
231
+ });
232
+
233
+ nativeAdsManager.on('adLoaded', (ad: AdInstance) => {
234
+ useNativeAdStore.getState()._updateAd(ad);
235
+ useNativeAdStore.getState()._setLoading(ad.adKey, false);
236
+ useNativeAdStore.getState()._clearError(ad.adKey);
237
+ });
238
+
239
+ nativeAdsManager.on('adDisplayed', (ad: AdInstance) => {
240
+ useNativeAdStore.getState()._updateAd(ad);
241
+ });
242
+
243
+ nativeAdsManager.on('adError', (ad: AdInstance) => {
244
+ useNativeAdStore.getState()._updateAd(ad);
245
+ useNativeAdStore.getState()._setLoading(ad.adKey, false);
246
+ useNativeAdStore
247
+ .getState()
248
+ ._setError(ad.adKey, ad.error || 'Unknown error');
249
+ });
250
+
251
+ nativeAdsManager.on('adRemoved', (adKey: string) => {
252
+ useNativeAdStore.getState()._removeAd(adKey);
253
+ });
254
+
255
+ nativeAdsManager.on('allAdsCleared', () => {
256
+ useNativeAdStore.getState().clearAllAds();
257
+ });
258
+
259
+ isListenerSetup = true;
260
+ };
261
+
262
+ // Initialize listeners
263
+ setupNativeListeners();
264
+
265
+ // export const useAdStoreWithDevTools = create<AdStore>()(
266
+ // devtools(
267
+ // subscribeWithSelector((set, get) => ({})),
268
+ // {
269
+ // name: 'ad-store',
270
+ // }
271
+ // )
272
+ // );