@jolibox/implement 1.1.11-beta.10 → 1.1.11-beta.11

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.
@@ -1,9 +1,9 @@
1
1
  Invoking: npm run clean && npm run build:esm && tsc
2
2
 
3
- > @jolibox/implement@1.1.11-beta.10 clean
3
+ > @jolibox/implement@1.1.11-beta.11 clean
4
4
  > rimraf ./dist
5
5
 
6
6
 
7
- > @jolibox/implement@1.1.11-beta.10 build:esm
7
+ > @jolibox/implement@1.1.11-beta.11 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,13 +1,13 @@
1
1
  {
2
2
  "name": "@jolibox/implement",
3
3
  "description": "This project is Jolibox JS-SDk implement for Native && H5",
4
- "version": "1.1.11-beta.10",
4
+ "version": "1.1.11-beta.11",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
7
7
  "license": "MIT",
8
8
  "dependencies": {
9
- "@jolibox/common": "1.1.11-beta.10",
10
- "@jolibox/types": "1.1.11-beta.10",
9
+ "@jolibox/common": "1.1.11-beta.11",
10
+ "@jolibox/types": "1.1.11-beta.11",
11
11
  "localforage": "1.10.0",
12
12
  "@jolibox/ui": "1.0.0",
13
13
  "web-vitals": "4.2.4"
@@ -100,6 +100,9 @@ const wrapContext = () => {
100
100
  get from(): number | undefined {
101
101
  return payloadJson?.__from;
102
102
  },
103
+ get baseApiHost(): string {
104
+ return testMode ? 'https://stg-api.jolibox.com' : 'https://api.jolibox.com';
105
+ },
103
106
  onEnvConfigChanged: (newConfig: Partial<Env>) => {
104
107
  mergeWith(env, newConfig, mergeArray);
105
108
  },
@@ -1,16 +1,18 @@
1
1
  import { createAPIError } from '@/common/report/errors';
2
2
  import { createFetch } from '../network/create-fetch';
3
- import { createAPI, registerCanIUse, t } from './base';
3
+ import { createSyncAPI, registerCanIUse, t } from './base';
4
4
  import { dirtyURL, normalizeHeader, normalizeMethod, normalizeTimeout } from '../network/utils';
5
5
  import { BaseError, createCommands, Deferred, wrapUserFunction } from '@jolibox/common';
6
6
  import { AnyFunction, ResponseType } from '@jolibox/types';
7
7
  import { reportError } from '@/common/report/errors/report';
8
8
  import { FetchOptions } from '../network/types';
9
+ import { context } from '@/common/context';
9
10
 
10
11
  const LIMIT = 15;
11
12
 
12
13
  const publicFetch = createFetch('createRequestTaskSync', 'operateRequestTaskSync', {
13
- type: 'public'
14
+ type: 'public',
15
+ baseUrl: context.baseApiHost
14
16
  });
15
17
 
16
18
  /** current active count */
@@ -41,12 +43,12 @@ const request = (_params: unknown) => {
41
43
  // noop
42
44
  };
43
45
 
44
- const _request = createAPI('request', {
46
+ const _request = createSyncAPI('request', {
45
47
  paramsSchema: t.tuple(
46
48
  t.object({
47
49
  url: t.string(),
48
50
  method: t.string(),
49
- header: t.object(),
51
+ headers: t.object(),
50
52
  data: t.object().optional(),
51
53
  query: t.object().optional(),
52
54
  dataType: t.string().default('json'),
@@ -68,9 +70,10 @@ const request = (_params: unknown) => {
68
70
  if (deferred.state !== 'pending') {
69
71
  return;
70
72
  }
73
+
71
74
  const { data, dataType, responseType, enableCache, appendHostCookie } = params;
72
75
 
73
- const header = normalizeHeader(params.header);
76
+ const header = normalizeHeader(params.headers);
74
77
  const method = normalizeMethod(params.method);
75
78
  const timeout = normalizeTimeout(params.timeout);
76
79
  const url = dirtyURL(params.url, method, data);
@@ -89,15 +92,21 @@ const request = (_params: unknown) => {
89
92
 
90
93
  if (timeout) _params['timeout'] = timeout;
91
94
 
92
- const task = publicFetch<string | ArrayBuffer | JSON>(url, _params);
93
-
95
+ const task = publicFetch<
96
+ string | ArrayBuffer | JSON | { status: number; data: string | ArrayBuffer | JSON }
97
+ >(url, _params);
94
98
  {
95
99
  const { response } = await task;
96
100
  const { code, data, message } = response;
97
-
101
+ if (data && typeof data === 'object' && 'status' in data && data.status !== 200) {
102
+ throw createAPIError({
103
+ code: data.status || -1,
104
+ msg: `request:fail status ${data.status}`
105
+ });
106
+ }
98
107
  deferred.resolve({
99
108
  code: (code ?? 'SUCCESS') as ResponseType,
100
- data,
109
+ data: data as string | ArrayBuffer | JSON,
101
110
  message: message ?? 'request:ok'
102
111
  });
103
112
 
@@ -132,7 +141,7 @@ const request = (_params: unknown) => {
132
141
  }
133
142
  });
134
143
 
135
- _request(_params);
144
+ _request(_params as Parameters<typeof _request>[0]);
136
145
 
137
146
  return {
138
147
  /**
@@ -1,4 +1,4 @@
1
- import { invokeNative, onNative, RuntimeLoader, subscribe } from './bridge';
1
+ import { invokeNative, onNative, RuntimeLoader } from './bridge';
2
2
  import { joliboxJSCore } from '../js-core';
3
3
  import { context } from '@/common/context';
4
4
  import { hostEmitter, isBoolean } from '@jolibox/common';
@@ -6,65 +6,52 @@ import { taskTracker, track } from '../report';
6
6
  import { initializeNativeEnv } from './init-env';
7
7
  import { adEventEmitter } from '@/common/ads';
8
8
  import { openRetentionSchema } from '../ui/retention';
9
+ import { innerFetch } from '../network';
9
10
 
10
- let cleanStyles: () => void;
11
- RuntimeLoader.onReady(() => {
12
- // TODO: merge some env config
13
- });
11
+ interface IBasicMetaConfig {
12
+ canShowRecommended: boolean;
13
+ }
14
14
 
15
- const doActualExit = () => {
16
- //埋点上报
17
- track('onBeforeExit', {
18
- timestamp: Date.now()
19
- });
20
- cleanStyles?.();
21
- taskTracker.close(Date.now() - start_timestamp);
22
- };
15
+ /**
16
+ * 全局变量
17
+ */
23
18
 
24
19
  /**
25
- * 退出逻辑
26
- * 1. 如果正在展示广告,则禁止退出
27
- * 2. 如果指定退出挽留逻辑,则按照指定逻辑运行
28
- * 3. 如果退出挽留逻辑返回 true,则按照指定逻辑运行
29
- * 4. 否则,按照默认逻辑运行
20
+ * 清除safari jolibox样式
30
21
  */
31
- RuntimeLoader.doExit(async () => {
32
- if (isAdShowing) {
33
- return true; // Forbid exit on watching ads
34
- }
22
+ let cleanStyles: () => void;
35
23
 
36
- // 指定退出挽留逻辑,则按照指定逻辑运行
37
- if (isBoolean(context.shouldInterupt)) {
38
- // 不需要打断退出,上报埋点
39
- if (!context.shouldInterupt) {
40
- doActualExit();
41
- }
42
- return context.shouldInterupt;
43
- }
24
+ /**
25
+ * 启动时间戳
26
+ */
27
+ let start_timestamp: number;
44
28
 
45
- const stay = await openRetentionSchema();
46
- if (stay) {
47
- // 挽留成功,打断退出
48
- return true;
49
- }
29
+ /**
30
+ * 是否展示广告
31
+ */
32
+ let isAdShowing = false;
50
33
 
51
- // 退出,对应上报
52
- //埋点上报
53
- doActualExit();
54
- return false;
55
- });
34
+ let baskcMeta: IBasicMetaConfig | null = null;
56
35
 
57
- let isAdShowing = false;
58
- adEventEmitter.on('isAdShowing', (isShowing) => {
59
- isAdShowing = isShowing;
60
- if (isBoolean(isAdShowing)) {
61
- invokeNative('updateContainerConfigSync', {
62
- displayCapsuleButton: !isAdShowing,
63
- webviewId: context.webviewId
64
- });
65
- }
36
+ RuntimeLoader.onReady(() => {
37
+ // TODO: merge some env config
66
38
  });
67
39
 
40
+ /**
41
+ * 添加广告展示监听
42
+ */
43
+ function addShowAdListener() {
44
+ adEventEmitter.on('isAdShowing', (isShowing) => {
45
+ isAdShowing = isShowing;
46
+ if (isBoolean(isAdShowing)) {
47
+ invokeNative('updateContainerConfigSync', {
48
+ displayCapsuleButton: !isAdShowing,
49
+ webviewId: context.webviewId
50
+ });
51
+ }
52
+ });
53
+ }
54
+
68
55
  /**
69
56
  * The DOMContentLoaded event might be triggered very early,
70
57
  * so the global loaded listener should be executed during the bootstrap process.
@@ -105,11 +92,71 @@ function addGameServiceReadyListener() {
105
92
  joliboxJSCore?.doExit(uuid);
106
93
  });
107
94
  }
108
- let start_timestamp: number;
95
+
96
+ function addDoExitLoader() {
97
+ /**
98
+ * 退出逻辑
99
+ * 1. 如果正在展示广告,则禁止退出
100
+ * 2. 如果指定退出挽留逻辑,则按照指定逻辑运行
101
+ * 3. 如果退出挽留逻辑返回 true,则按照指定逻辑运行
102
+ * 4. 否则,按照默认逻辑运行
103
+ */
104
+
105
+ const doActualExit = () => {
106
+ //埋点上报
107
+ track('onBeforeExit', {
108
+ timestamp: Date.now()
109
+ });
110
+ cleanStyles?.();
111
+ taskTracker.close(Date.now() - start_timestamp);
112
+ };
113
+
114
+ RuntimeLoader.doExit(async () => {
115
+ if (isAdShowing) {
116
+ return true; // Forbid exit on watching ads
117
+ }
118
+
119
+ // 指定退出挽留逻辑,则按照指定逻辑运行
120
+ if (isBoolean(context.shouldInterupt)) {
121
+ // 不需要打断退出,上报埋点
122
+ if (!context.shouldInterupt) {
123
+ doActualExit();
124
+ }
125
+ return context.shouldInterupt;
126
+ }
127
+
128
+ if (baskcMeta?.canShowRecommended) {
129
+ const stay = await openRetentionSchema();
130
+ if (stay) {
131
+ // 挽留成功,打断退出
132
+ return true;
133
+ }
134
+ }
135
+
136
+ // 退出,对应上报
137
+ //埋点上报
138
+ doActualExit();
139
+ return false;
140
+ });
141
+ }
142
+
143
+ async function fetchMetaConfig() {
144
+ const url = `${context.baseApiHost}/api/fe-configs/js-sdk/basic-meta`;
145
+ const {
146
+ response: { data }
147
+ } = await innerFetch<IBasicMetaConfig>(url);
148
+
149
+ if (data) {
150
+ baskcMeta = data;
151
+ }
152
+ }
109
153
 
110
154
  export function config(): void {
111
155
  start_timestamp = Date.now();
112
156
  addGameServiceReadyListener();
157
+ addShowAdListener();
158
+ addDoExitLoader();
113
159
  addWebviewReadyListener();
160
+ fetchMetaConfig();
114
161
  cleanStyles = initializeNativeEnv();
115
162
  }
@@ -46,6 +46,7 @@ export function createFetch(
46
46
  operateMethod: 'operateRequestTaskSync',
47
47
  options?: {
48
48
  baseUrl?: string;
49
+ defaultHeaders?: Record<string, string>;
49
50
  type: 'public';
50
51
  }
51
52
  ): PublicFetch;
@@ -79,12 +79,19 @@ export function dirtyURL(url: string, method: HTTPMethod, data?: unknown) {
79
79
 
80
80
  if (!isObject(data)) return url;
81
81
 
82
- const [_url, search = ''] = url.split('?');
82
+ const [baseUrl, search = ''] = url.split('?');
83
83
 
84
- const query = JSON.stringify({
85
- ...JSON.parse(search),
86
- ...data
87
- });
84
+ // Parse existing query parameters
85
+ const dataParams = new URLSearchParams(search);
88
86
 
89
- return `${_url}?${query}`;
87
+ // Add new parameters from data object
88
+ for (const [key, value] of Object.entries(data)) {
89
+ if (value !== undefined && value !== null) {
90
+ dataParams.append(key, String(value));
91
+ }
92
+ }
93
+
94
+ const queryString = dataParams.toString();
95
+
96
+ return queryString ? `${baseUrl}?${queryString}` : baseUrl;
90
97
  }