@jolibox/implement 1.1.9 → 1.1.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 +9 -9
- package/dist/common/report/base-tracker.d.ts +0 -3
- package/dist/h5/http/index.d.ts +14 -3
- package/dist/index.js +3 -3
- package/dist/index.native.js +3 -3
- package/implement.build.log +2 -2
- package/package.json +3 -3
- package/src/common/report/base-tracker.ts +2 -20
- package/src/h5/api/ads.ts +4 -3
- package/src/h5/api/storage.ts +6 -7
- package/src/h5/bootstrap/index.ts +4 -1
- package/src/h5/http/index.ts +125 -80
- package/src/h5/report/event-tracker.ts +10 -7
- package/src/h5/report/task-tracker.ts +2 -2
- package/src/native/bootstrap/index.ts +4 -1
package/src/h5/http/index.ts
CHANGED
|
@@ -20,19 +20,52 @@ const timeoutFn = (ms: number) => {
|
|
|
20
20
|
|
|
21
21
|
(AbortSignal as any).timeout ??= timeoutFn;
|
|
22
22
|
|
|
23
|
-
export class
|
|
23
|
+
export class HttpClientManager {
|
|
24
|
+
private static _instance: HttpClientManager;
|
|
25
|
+
private httpClients = new WeakSet<JoliboxHttpClient>();
|
|
26
|
+
private networkRequests: boolean[] = [];
|
|
27
|
+
private maxRequestsToTrack = 20;
|
|
28
|
+
|
|
29
|
+
static getInstance(): HttpClientManager {
|
|
30
|
+
if (!HttpClientManager._instance) {
|
|
31
|
+
HttpClientManager._instance = new HttpClientManager();
|
|
32
|
+
}
|
|
33
|
+
return HttpClientManager._instance;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
create(config?: IHttpClientInitParams): JoliboxHttpClient {
|
|
37
|
+
const client = new JoliboxHttpClient(config);
|
|
38
|
+
HttpClientManager.getInstance().httpClients.add(client);
|
|
39
|
+
return client;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
recordNetworkRequest(success: boolean): void {
|
|
43
|
+
this.networkRequests.push(success);
|
|
44
|
+
if (this.networkRequests.length > this.maxRequestsToTrack) {
|
|
45
|
+
this.networkRequests.shift();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getNetworkStatus(): boolean {
|
|
50
|
+
if (this.networkRequests.length === 0) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const successCount = this.networkRequests.filter((success) => success).length;
|
|
55
|
+
const successRate = successCount / this.networkRequests.length;
|
|
56
|
+
|
|
57
|
+
return successRate >= 0.6;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
class JoliboxHttpClient implements IHttpClient {
|
|
24
62
|
private baseUrl: string;
|
|
25
|
-
|
|
63
|
+
protected xua = xUserAgent();
|
|
26
64
|
|
|
27
65
|
private getJoliSource = () => {
|
|
28
66
|
return context.joliSource;
|
|
29
67
|
};
|
|
30
68
|
|
|
31
|
-
// private getApiBaseURL = () => {
|
|
32
|
-
// const urlParams = new URLSearchParams(window.location.search);
|
|
33
|
-
// return urlParams.get('apiBaseURL') ?? null;
|
|
34
|
-
// };
|
|
35
|
-
|
|
36
69
|
constructor(config?: IHttpClientInitParams) {
|
|
37
70
|
const defaultUrl = context.testMode ? 'https://stg-api.jolibox.com' : 'https://api.jolibox.com';
|
|
38
71
|
this.baseUrl = config?.baseUrl ?? defaultUrl;
|
|
@@ -46,26 +79,34 @@ export class JoliboxHttpClient implements IHttpClient {
|
|
|
46
79
|
timeout?: number;
|
|
47
80
|
}
|
|
48
81
|
) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
try {
|
|
83
|
+
const { query, timeout } = configs ?? {};
|
|
84
|
+
let { headers } = configs ?? {};
|
|
85
|
+
const searchParams = query ? new URLSearchParams(query) : null;
|
|
86
|
+
const search = searchParams?.toString();
|
|
87
|
+
const url = `${this.baseUrl}${path}${search ? `?${search}` : ''}`;
|
|
88
|
+
const xua = this.xua;
|
|
89
|
+
const joliSource = this.getJoliSource();
|
|
90
|
+
headers = Object.assign(
|
|
91
|
+
{},
|
|
92
|
+
headers ?? {},
|
|
93
|
+
xua ? { 'x-user-agent': xua } : {},
|
|
94
|
+
joliSource ? { 'x-joli-source': joliSource } : {}
|
|
95
|
+
);
|
|
96
|
+
const response = await fetch(url, {
|
|
97
|
+
method: 'GET',
|
|
98
|
+
headers,
|
|
99
|
+
credentials: 'include',
|
|
100
|
+
signal: timeoutFn(timeout ?? 30000)
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
HttpClientManager.getInstance().recordNetworkRequest(true);
|
|
104
|
+
|
|
105
|
+
return (await response.json()) as T;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
HttpClientManager.getInstance().recordNetworkRequest(false);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
69
110
|
}
|
|
70
111
|
|
|
71
112
|
async post<T = any>(
|
|
@@ -77,62 +118,65 @@ export class JoliboxHttpClient implements IHttpClient {
|
|
|
77
118
|
timeout?: number;
|
|
78
119
|
}
|
|
79
120
|
) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
try {
|
|
122
|
+
const { data, query, timeout } = configs ?? {};
|
|
123
|
+
let { headers } = configs ?? {};
|
|
124
|
+
const searchParams = query ? new URLSearchParams(query) : null;
|
|
125
|
+
const search = searchParams?.toString();
|
|
126
|
+
const url = `${this.baseUrl}${path}${search ? `?${search}` : ''}`;
|
|
127
|
+
const xua = this.xua;
|
|
128
|
+
const joliSource = this.getJoliSource();
|
|
129
|
+
headers = Object.assign(
|
|
130
|
+
{},
|
|
131
|
+
headers ?? {},
|
|
132
|
+
{ 'Content-Type': 'application/json' },
|
|
133
|
+
xua ? { 'x-user-agent': xua } : {},
|
|
134
|
+
joliSource ? { 'x-joli-source': joliSource } : {}
|
|
135
|
+
);
|
|
136
|
+
const response = await fetch(url, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers,
|
|
139
|
+
body: JSON.stringify(data),
|
|
140
|
+
signal: timeoutFn(timeout ?? 30000),
|
|
141
|
+
credentials: 'include'
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
HttpClientManager.getInstance().recordNetworkRequest(true);
|
|
145
|
+
|
|
146
|
+
const responseContentType = response.headers.get('content-type');
|
|
147
|
+
|
|
148
|
+
if (responseContentType?.includes('application/octet-stream')) {
|
|
149
|
+
try {
|
|
150
|
+
return response.blob() as unknown as T;
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return (await response.arrayBuffer()) as unknown as T;
|
|
153
|
+
}
|
|
110
154
|
}
|
|
111
|
-
}
|
|
112
155
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
156
|
+
if (
|
|
157
|
+
responseContentType?.includes('multipart/form-data') ||
|
|
158
|
+
responseContentType?.includes('application/x-www-form-urlencoded')
|
|
159
|
+
) {
|
|
160
|
+
try {
|
|
161
|
+
return response.formData() as unknown as T;
|
|
162
|
+
} catch (e) {
|
|
163
|
+
return (await response.text()) as unknown as T;
|
|
164
|
+
}
|
|
122
165
|
}
|
|
123
|
-
}
|
|
124
166
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
167
|
+
if (responseContentType?.includes('application/json')) {
|
|
168
|
+
try {
|
|
169
|
+
return (await response.json()) as T;
|
|
170
|
+
} catch (e) {
|
|
171
|
+
return (await response.text()) as unknown as T;
|
|
172
|
+
}
|
|
131
173
|
}
|
|
132
|
-
}
|
|
133
174
|
|
|
134
|
-
|
|
135
|
-
|
|
175
|
+
return response as unknown as T;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
HttpClientManager.getInstance().recordNetworkRequest(false);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
136
180
|
}
|
|
137
181
|
|
|
138
182
|
async put<T>(
|
|
@@ -163,14 +207,15 @@ export class JoliboxHttpClient implements IHttpClient {
|
|
|
163
207
|
method: 'PUT',
|
|
164
208
|
headers,
|
|
165
209
|
credentials: 'include',
|
|
166
|
-
body: JSON.stringify(data ?? {})
|
|
210
|
+
body: JSON.stringify(data ?? {})
|
|
167
211
|
});
|
|
168
212
|
|
|
169
|
-
// 检查响应状态
|
|
170
213
|
if (!response.ok) {
|
|
214
|
+
HttpClientManager.getInstance().recordNetworkRequest(false);
|
|
171
215
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
172
216
|
}
|
|
173
217
|
|
|
218
|
+
HttpClientManager.getInstance().recordNetworkRequest(true);
|
|
174
219
|
const result = (await response.json()) as T;
|
|
175
220
|
return result;
|
|
176
221
|
} catch (error) {
|
|
@@ -182,4 +227,4 @@ export class JoliboxHttpClient implements IHttpClient {
|
|
|
182
227
|
|
|
183
228
|
window.JoliboxHttpClient = JoliboxHttpClient;
|
|
184
229
|
|
|
185
|
-
export
|
|
230
|
+
export const httpClientManager = HttpClientManager.getInstance();
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { context } from '@/common/context';
|
|
2
|
-
import { logger } from '@jolibox/common';
|
|
3
2
|
import { EventTracker } from '@/common/report';
|
|
4
|
-
import
|
|
3
|
+
import { httpClientManager } from '@/h5/http';
|
|
5
4
|
|
|
6
5
|
export class H5EventTracker extends EventTracker {
|
|
7
6
|
private hostToApiMap: Record<string | 'default', { test: string; prod: string }> = {
|
|
@@ -24,15 +23,19 @@ export class H5EventTracker extends EventTracker {
|
|
|
24
23
|
return context.testMode ?? false ? api.test : api.prod;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
private httpClient =
|
|
26
|
+
private httpClient = httpClientManager.create({
|
|
28
27
|
baseUrl: this.apiBaseURL
|
|
29
28
|
});
|
|
30
29
|
|
|
31
30
|
doReport(event: unknown[]): void {
|
|
32
|
-
this.httpClient
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
this.httpClient
|
|
32
|
+
.post('/report', {
|
|
33
|
+
data: event,
|
|
34
|
+
timeout: 5000
|
|
35
|
+
})
|
|
36
|
+
.catch((e) => {
|
|
37
|
+
console.info('report error', e);
|
|
38
|
+
});
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
import { context } from '@/common/context';
|
|
6
6
|
import { TaskTracker, TaskPoint } from '@/common/report/task-track';
|
|
7
7
|
import { EventEmitter, logger } from '@jolibox/common';
|
|
8
|
-
import
|
|
8
|
+
import { httpClientManager } from '../http';
|
|
9
9
|
import type { Track } from '.';
|
|
10
10
|
import type { TrackEvent } from '@jolibox/types';
|
|
11
11
|
|
|
12
12
|
export class H5TaskTracker extends TaskTracker {
|
|
13
13
|
private gameId: string;
|
|
14
14
|
private sessionId: string;
|
|
15
|
-
private httpClient =
|
|
15
|
+
private httpClient = httpClientManager.create();
|
|
16
16
|
private track: Track;
|
|
17
17
|
|
|
18
18
|
constructor(track: Track, eventEmitter: EventEmitter<{ visible: [boolean] }>, interval?: number) {
|
|
@@ -50,7 +50,10 @@ function addWebviewReadyListener() {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function handleTaskTracker(duration?: number) {
|
|
53
|
-
|
|
53
|
+
// 只有小游戏场景需要上报进度
|
|
54
|
+
if (context.mpType === 'game') {
|
|
55
|
+
taskTracker.start(duration);
|
|
56
|
+
}
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
function addGameServiceReadyListener() {
|