@jolibox/implement 1.3.3 → 1.3.5-beta.10
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/.rush/temp/package-deps_build.json +8 -8
- package/dist/common/report/task-track/index.d.ts +1 -1
- package/dist/common/utils/index.d.ts +6 -0
- package/dist/index.js +39 -39
- package/dist/index.native.js +103 -103
- package/implement.build.log +2 -2
- package/package.json +6 -6
- package/src/common/report/task-track/index.ts +2 -1
- package/src/common/utils/index.ts +9 -0
- package/src/h5/api/ads.ts +5 -1
- package/src/h5/api/runtime.ts +3 -0
- package/src/native/api/ads.ts +5 -1
- package/src/native/api/rewards.ts +151 -1
- package/src/native/bootstrap/index.ts +29 -1
package/implement.build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Invoking: npm run clean && npm run build:esm && tsc
|
|
2
2
|
|
|
3
|
-
> @jolibox/implement@1.3.
|
|
3
|
+
> @jolibox/implement@1.3.5-beta.10 clean
|
|
4
4
|
> rimraf ./dist
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
> @jolibox/implement@1.3.
|
|
7
|
+
> @jolibox/implement@1.3.5-beta.10 build:esm
|
|
8
8
|
> BUILD_VERSION=$(node -p "require('./package.json').version") node esbuild.config.js --format=esm
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jolibox/implement",
|
|
3
3
|
"description": "This project is Jolibox JS-SDk implement for Native && H5",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.5-beta.10",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@jolibox/common": "1.3.
|
|
10
|
-
"@jolibox/types": "1.3.
|
|
11
|
-
"@jolibox/native-bridge": "1.3.
|
|
12
|
-
"@jolibox/ads": "1.3.
|
|
9
|
+
"@jolibox/common": "1.3.5-beta.10",
|
|
10
|
+
"@jolibox/types": "1.3.5-beta.10",
|
|
11
|
+
"@jolibox/native-bridge": "1.3.5-beta.10",
|
|
12
|
+
"@jolibox/ads": "1.3.5-beta.10",
|
|
13
13
|
"localforage": "1.10.0",
|
|
14
|
-
"@jolibox/ui": "1.3.
|
|
14
|
+
"@jolibox/ui": "1.3.5-beta.10",
|
|
15
15
|
"web-vitals": "4.2.4"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
@@ -11,7 +11,8 @@ type TaskEvent =
|
|
|
11
11
|
| 'ADS_UNLOCK_GAME' // 广告解锁
|
|
12
12
|
| 'GAME_TASK_EVENT' // 关卡行为
|
|
13
13
|
| 'GAME_ENDED' // 游戏结束
|
|
14
|
-
| 'GAME_LEVEL_UP'
|
|
14
|
+
| 'GAME_LEVEL_UP' // 游戏关卡升级
|
|
15
|
+
| 'COMPLETE_WATCH_ADS'; // 完成观看广告
|
|
15
16
|
export type TaskPoint = {
|
|
16
17
|
event: TaskEvent;
|
|
17
18
|
params?: Record<string, unknown>;
|
|
@@ -13,6 +13,9 @@ const JOLIBOX_JOLI_UNLOGIN_MODAL_EVENT = 'JOLIBOX_JOLI_UNLOGIN_MODAL_EVENT'; //
|
|
|
13
13
|
const JOLIBOX_GET_USER_SUB_STATUS = 'JOLIBOX_GET_USER_SUB_STATUS';
|
|
14
14
|
const JOLIBOX_SUB_EVENT = 'JOLIBOX_SUB_EVENT';
|
|
15
15
|
|
|
16
|
+
const CP_LOAD_FINISH = 'CP_LOAD_FINISH';
|
|
17
|
+
const CP_LOAD_PROGRESS = 'CP_LOAD_PROGRESS';
|
|
18
|
+
|
|
16
19
|
interface JoliboxCustomEvent {
|
|
17
20
|
[JOLIBOX_CUSTOM_ADS_EVENT_TYPE]: {
|
|
18
21
|
isAdShowing: boolean;
|
|
@@ -52,6 +55,12 @@ interface JoliboxCustomEvent {
|
|
|
52
55
|
[JOLIBOX_SUB_EVENT]: {
|
|
53
56
|
sequenceId: string;
|
|
54
57
|
};
|
|
58
|
+
[CP_LOAD_FINISH]: {
|
|
59
|
+
// no data
|
|
60
|
+
};
|
|
61
|
+
[CP_LOAD_PROGRESS]: {
|
|
62
|
+
progress: number;
|
|
63
|
+
};
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
const notifyCustomEvent = <T extends keyof JoliboxCustomEvent>(eventName: T, data: JoliboxCustomEvent[T]) => {
|
package/src/h5/api/ads.ts
CHANGED
|
@@ -125,7 +125,11 @@ const adsContext: IAdsContext<'GAME'> = {
|
|
|
125
125
|
osType: platform.isAndroid ? 'ANDROID' : platform.isiOS ? 'IOS' : 'PC',
|
|
126
126
|
runtimeType: 'WEB',
|
|
127
127
|
platform: 1000, // WebSDK
|
|
128
|
-
joliSource: context.joliSource ?? ''
|
|
128
|
+
joliSource: context.joliSource ?? '',
|
|
129
|
+
deviceInfo: {
|
|
130
|
+
platform: 'h5',
|
|
131
|
+
nativeSDKVersionCode: 0 // not support in h5
|
|
132
|
+
}
|
|
129
133
|
};
|
|
130
134
|
}
|
|
131
135
|
};
|
package/src/h5/api/runtime.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { createCommands } from '@jolibox/common';
|
|
2
2
|
import { track } from '../report';
|
|
3
3
|
import { context } from '@/common/context';
|
|
4
|
+
import { notifyCustomEvent } from '@/common/utils';
|
|
4
5
|
|
|
5
6
|
const commands = createCommands();
|
|
6
7
|
|
|
7
8
|
commands.registerCommand('RuntimeSDK.loadFinishedEvent', () => {
|
|
8
9
|
const duration = performance.now();
|
|
10
|
+
notifyCustomEvent('CP_LOAD_FINISH', { duration });
|
|
9
11
|
track('loadFinished', {
|
|
10
12
|
duration
|
|
11
13
|
});
|
|
12
14
|
});
|
|
13
15
|
|
|
14
16
|
commands.registerCommand('RuntimeSDK.loadProgressEvent', (progress) => {
|
|
17
|
+
notifyCustomEvent('CP_LOAD_PROGRESS', { progress });
|
|
15
18
|
console.log('RuntimeSDK.loadProgressEvent', progress);
|
|
16
19
|
});
|
package/src/native/api/ads.ts
CHANGED
|
@@ -85,7 +85,11 @@ const adsContext: IAdsContext<'GAME'> = {
|
|
|
85
85
|
osType: context.platform === 'android' ? 'ANDROID' : context.platform === 'ios' ? 'IOS' : 'PC',
|
|
86
86
|
runtimeType: 'APP',
|
|
87
87
|
platform: 1000, // WebSDK
|
|
88
|
-
joliSource: context.joliSource ?? ''
|
|
88
|
+
joliSource: context.joliSource ?? '',
|
|
89
|
+
deviceInfo: {
|
|
90
|
+
platform: context.platform,
|
|
91
|
+
nativeSDKVersionCode: context.sdkInfo.nativeSDKVersionCode ?? 0
|
|
92
|
+
}
|
|
89
93
|
};
|
|
90
94
|
}
|
|
91
95
|
};
|
|
@@ -1,9 +1,76 @@
|
|
|
1
1
|
import { BaseError, wrapUserFunction, createCommands } from '@jolibox/common';
|
|
2
|
-
import { canIUseNative, createAPI, registerCanIUse, t } from './base';
|
|
2
|
+
import { canIUseNative, createAPI, createSyncAPI, registerCanIUse, t } from './base';
|
|
3
3
|
import { StandardResponse, ICoinDetailsData } from '@jolibox/types';
|
|
4
4
|
import { context } from '@/common/context';
|
|
5
5
|
import { createAPIError } from '@/common/report/errors';
|
|
6
6
|
import { invokeNative } from '@jolibox/native-bridge';
|
|
7
|
+
import { IAdsContext } from '@jolibox/ads/dist/type/base';
|
|
8
|
+
import { adEventEmitter } from '@/common/ads';
|
|
9
|
+
import { taskTracker, track } from '../report';
|
|
10
|
+
import { JoliboxAdsForGame } from '@jolibox/ads';
|
|
11
|
+
import { innerFetch as fetch } from '../network';
|
|
12
|
+
|
|
13
|
+
const checkNetworkStatus = () => {
|
|
14
|
+
const { data } = invokeNative('getNetworkStatusSync');
|
|
15
|
+
return !!data?.isConnected;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const httpClient = {
|
|
19
|
+
get: <T>(url: string, options?: any) =>
|
|
20
|
+
fetch<T>(url, {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
responseType: 'json',
|
|
23
|
+
appendHostCookie: true,
|
|
24
|
+
...options
|
|
25
|
+
}).then((res) => res.response.data as T),
|
|
26
|
+
post: <T>(url: string, options?: any) =>
|
|
27
|
+
fetch<T>(url, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
responseType: 'json',
|
|
30
|
+
appendHostCookie: true,
|
|
31
|
+
...options
|
|
32
|
+
}).then((res) => res.response.data as T)
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const adsContext: IAdsContext<'TASK'> = {
|
|
36
|
+
httpClient,
|
|
37
|
+
checkNetwork: checkNetworkStatus,
|
|
38
|
+
track,
|
|
39
|
+
eventEmitter: adEventEmitter,
|
|
40
|
+
getWindowInfo: () => ({
|
|
41
|
+
width: window.innerWidth * window.devicePixelRatio,
|
|
42
|
+
height: window.innerHeight * window.devicePixelRatio,
|
|
43
|
+
statusBarHeight: 30
|
|
44
|
+
}),
|
|
45
|
+
handleLinkClicked: (link) => {
|
|
46
|
+
window.open(link, '_blank');
|
|
47
|
+
},
|
|
48
|
+
getContextInfo: () => {
|
|
49
|
+
return {
|
|
50
|
+
hostAppId: context.hostInfo?.aid ?? '1',
|
|
51
|
+
deviceId: context.deviceInfo.did ?? '',
|
|
52
|
+
adId: context.deviceInfo.adId ?? '',
|
|
53
|
+
sessionId: context.sessionId ?? '',
|
|
54
|
+
userId: context.hostUserInfo?.uid ?? '',
|
|
55
|
+
objectType: 'TASK',
|
|
56
|
+
objectId: context.mpId,
|
|
57
|
+
testAdsMode: context.testAdsMode,
|
|
58
|
+
channel: context.joliSource ?? '',
|
|
59
|
+
deviceBrand: context.deviceInfo.brand,
|
|
60
|
+
deviceModel: context.deviceInfo.model,
|
|
61
|
+
osType: context.platform === 'android' ? 'ANDROID' : context.platform === 'ios' ? 'IOS' : 'PC',
|
|
62
|
+
runtimeType: 'APP',
|
|
63
|
+
platform: 1000, // WebSDK
|
|
64
|
+
joliSource: context.joliSource ?? '',
|
|
65
|
+
deviceInfo: {
|
|
66
|
+
platform: context.platform,
|
|
67
|
+
nativeSDKVersionCode: context.sdkInfo.nativeSDKVersionCode ?? 0
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// const ads = new JoliboxAdsForGame(adsContext);
|
|
7
74
|
|
|
8
75
|
const commands = createCommands();
|
|
9
76
|
|
|
@@ -83,3 +150,86 @@ commands.registerCommand('RewardsSDK.getCoinDetails', getCoinDetails);
|
|
|
83
150
|
registerCanIUse('rewards.getCoinDetails', {
|
|
84
151
|
version: '1.3.2'
|
|
85
152
|
});
|
|
153
|
+
|
|
154
|
+
const createRewardsAdsManager = createAPI('createRewardsAdsManager', {
|
|
155
|
+
implement: async () => {
|
|
156
|
+
try {
|
|
157
|
+
const ads = new JoliboxAdsForGame(adsContext);
|
|
158
|
+
if (context.mpType !== 'miniApp') {
|
|
159
|
+
throw createAPIError({
|
|
160
|
+
code: -1,
|
|
161
|
+
msg: '[JoliboxSDK]: createRewardsAdsManager not supported in games. Only supported in mini apps.'
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
code: 'SUCCESS',
|
|
166
|
+
message: 'Successfully created RewardsAdsManager',
|
|
167
|
+
data: {
|
|
168
|
+
init: async () => {
|
|
169
|
+
await ads.init();
|
|
170
|
+
ads.adConfig({
|
|
171
|
+
preloadAdBreaks: 'on',
|
|
172
|
+
sound: 'off',
|
|
173
|
+
onReady: () => {
|
|
174
|
+
// do nothing
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
showAd: async (callbacks: {
|
|
179
|
+
onAdLoaded?: () => void;
|
|
180
|
+
onAdError?: (error: Error) => void;
|
|
181
|
+
onAdRewarded?: () => void;
|
|
182
|
+
onAdDismissed?: () => void;
|
|
183
|
+
}) => {
|
|
184
|
+
ads.adBreak({
|
|
185
|
+
type: 'reward',
|
|
186
|
+
beforeReward: (showAdFn) => {
|
|
187
|
+
showAdFn();
|
|
188
|
+
callbacks.onAdLoaded?.();
|
|
189
|
+
},
|
|
190
|
+
adDismissed: () => {
|
|
191
|
+
// do nothing
|
|
192
|
+
callbacks.onAdDismissed?.();
|
|
193
|
+
},
|
|
194
|
+
adViewed: () => {
|
|
195
|
+
// do nothing
|
|
196
|
+
},
|
|
197
|
+
adBreakDone: (placementInfo) => {
|
|
198
|
+
const breakStatus = placementInfo.breakStatus;
|
|
199
|
+
const noAdPreloaded =
|
|
200
|
+
breakStatus === 'frequencyCapped' ||
|
|
201
|
+
breakStatus === 'other' ||
|
|
202
|
+
breakStatus === 'error' ||
|
|
203
|
+
breakStatus === 'noAdPreloaded';
|
|
204
|
+
if (breakStatus === 'viewed') {
|
|
205
|
+
// reward should be given to user
|
|
206
|
+
console.log('-----> complete watch ads');
|
|
207
|
+
taskTracker.reporter({
|
|
208
|
+
event: 'COMPLETE_WATCH_ADS'
|
|
209
|
+
});
|
|
210
|
+
callbacks.onAdRewarded?.();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (noAdPreloaded) {
|
|
214
|
+
console.log('-----> no ad preloaded or error occurred', breakStatus);
|
|
215
|
+
callbacks.onAdError?.(new Error('No ad preloaded or error occurred: ' + breakStatus));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
} catch (error) {
|
|
223
|
+
return {
|
|
224
|
+
code: 'FAILURE',
|
|
225
|
+
message: '[JoliboxSDK]: Failed to create RewardsAdsManager'
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
commands.registerCommand('Rewards.createRewardsAdsManager', createRewardsAdsManager);
|
|
232
|
+
|
|
233
|
+
registerCanIUse('rewards.createRewardsAdsManager', {
|
|
234
|
+
version: '1.3.4'
|
|
235
|
+
});
|
|
@@ -9,6 +9,7 @@ import { innerFetch } from '../network';
|
|
|
9
9
|
import { Env } from '@jolibox/types';
|
|
10
10
|
import { registerLanguageHandler } from '@jolibox/ui';
|
|
11
11
|
import { createIframeModal, registerIframeModalToGlobal } from '../ui/modal-iframe';
|
|
12
|
+
import { onFCP, onLCP, onTTFB } from 'web-vitals';
|
|
12
13
|
interface IBasicMetaConfig {
|
|
13
14
|
canShowRecommended: boolean;
|
|
14
15
|
}
|
|
@@ -75,7 +76,7 @@ RuntimeLoader.onReady(() => {
|
|
|
75
76
|
function addShowAdListener() {
|
|
76
77
|
adEventEmitter.on('isAdShowing', (isShowing) => {
|
|
77
78
|
isAdShowing = isShowing;
|
|
78
|
-
if (isBoolean(isAdShowing)) {
|
|
79
|
+
if (isBoolean(isAdShowing) && context.mpType === 'game') {
|
|
79
80
|
invokeNative('updateContainerConfigSync', {
|
|
80
81
|
displayCapsuleButton: !isAdShowing,
|
|
81
82
|
webviewId: context.webviewId
|
|
@@ -217,6 +218,32 @@ function addDoExitLoader() {
|
|
|
217
218
|
});
|
|
218
219
|
}
|
|
219
220
|
|
|
221
|
+
function trackPerformance() {
|
|
222
|
+
onFCP((metric) => {
|
|
223
|
+
track('GameFCP', {
|
|
224
|
+
value: metric.value,
|
|
225
|
+
rating: metric.rating,
|
|
226
|
+
navigationType: metric.navigationType
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
onLCP((metric) => {
|
|
231
|
+
track('GameLCP', {
|
|
232
|
+
value: metric.value,
|
|
233
|
+
rating: metric.rating,
|
|
234
|
+
navigationType: metric.navigationType
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
onTTFB((metric) => {
|
|
239
|
+
track('GameTTFB', {
|
|
240
|
+
value: metric.value,
|
|
241
|
+
rating: metric.rating,
|
|
242
|
+
navigationType: metric.navigationType
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
220
247
|
async function fetchMetaConfig() {
|
|
221
248
|
try {
|
|
222
249
|
const url = `/api/fe-configs/js-sdk/basic-meta`;
|
|
@@ -242,6 +269,7 @@ export function config(): void {
|
|
|
242
269
|
addWebviewReadyListener();
|
|
243
270
|
addI18nChangedListener();
|
|
244
271
|
fetchMetaConfig();
|
|
272
|
+
trackPerformance();
|
|
245
273
|
unregisterIframeModal = registerIframeModalToGlobal();
|
|
246
274
|
|
|
247
275
|
cleanStyles = initializeNativeEnv();
|