@jolibox/implement 1.1.4-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.
Files changed (195) hide show
  1. package/.eslintrc.js +13 -0
  2. package/.rush/temp/package-deps_build.json +105 -0
  3. package/.rush/temp/shrinkwrap-deps.json +79 -0
  4. package/README.md +1 -0
  5. package/dist/common/api-factory/index.d.ts +21 -0
  6. package/dist/common/api-factory/validator/__tests__/validate/any.test.d.ts +1 -0
  7. package/dist/common/api-factory/validator/__tests__/validate/array.test.d.ts +1 -0
  8. package/dist/common/api-factory/validator/__tests__/validate/arraybuffer.test.d.ts +1 -0
  9. package/dist/common/api-factory/validator/__tests__/validate/boolean.test.d.ts +1 -0
  10. package/dist/common/api-factory/validator/__tests__/validate/enum.test.d.ts +1 -0
  11. package/dist/common/api-factory/validator/__tests__/validate/function.test.d.ts +1 -0
  12. package/dist/common/api-factory/validator/__tests__/validate/literal.test.d.ts +1 -0
  13. package/dist/common/api-factory/validator/__tests__/validate/nullish.test.d.ts +1 -0
  14. package/dist/common/api-factory/validator/__tests__/validate/number.test.d.ts +1 -0
  15. package/dist/common/api-factory/validator/__tests__/validate/object.test.d.ts +1 -0
  16. package/dist/common/api-factory/validator/__tests__/validate/or.test.d.ts +1 -0
  17. package/dist/common/api-factory/validator/__tests__/validate/record.test.d.ts +1 -0
  18. package/dist/common/api-factory/validator/__tests__/validate/string.test.d.ts +1 -0
  19. package/dist/common/api-factory/validator/__tests__/validate/symbol.test.d.ts +1 -0
  20. package/dist/common/api-factory/validator/__tests__/validate/tuple.test.d.ts +1 -0
  21. package/dist/common/api-factory/validator/__tests__/validate/type-asserts.test.d.ts +1 -0
  22. package/dist/common/api-factory/validator/__tests__/validate/utils.test.d.ts +1 -0
  23. package/dist/common/api-factory/validator/index.d.ts +29 -0
  24. package/dist/common/api-factory/validator/validate.d.ts +119 -0
  25. package/dist/common/can-i-use.d.ts +2 -0
  26. package/dist/common/context/index.d.ts +16 -0
  27. package/dist/common/context/types.d.ts +5 -0
  28. package/dist/common/context/url-parse.d.ts +22 -0
  29. package/dist/common/http/index.d.ts +13 -0
  30. package/dist/common/http/uuid.d.ts +2 -0
  31. package/dist/common/http/xua.d.ts +17 -0
  32. package/dist/common/report/base-tracker.d.ts +13 -0
  33. package/dist/common/report/create-trace.d.ts +7 -0
  34. package/dist/common/report/errors/error-types.d.ts +122 -0
  35. package/dist/common/report/errors/index.d.ts +13 -0
  36. package/dist/common/report/errors/report/index.d.ts +51 -0
  37. package/dist/common/report/errors/report/listeners.d.ts +1 -0
  38. package/dist/common/report/index.d.ts +3 -0
  39. package/dist/common/report/task-track/index.d.ts +25 -0
  40. package/dist/common/report/track.d.ts +3 -0
  41. package/dist/common/report/types.d.ts +75 -0
  42. package/dist/h5/ads/ads-action-detection.d.ts +6 -0
  43. package/dist/h5/ads/anti-cheating.d.ts +61 -0
  44. package/dist/h5/ads/index.d.ts +275 -0
  45. package/dist/h5/api/base.d.ts +13 -0
  46. package/dist/h5/api/get-system-info.d.ts +1 -0
  47. package/dist/h5/api/index.d.ts +4 -0
  48. package/dist/h5/api/lifecycle.d.ts +1 -0
  49. package/dist/h5/api/storage.d.ts +27 -0
  50. package/dist/h5/api/task.d.ts +1 -0
  51. package/dist/h5/bootstrap/index.d.ts +1 -0
  52. package/dist/h5/http/index.d.ts +33 -0
  53. package/dist/h5/http/utils/__tests__/uuid.test.d.ts +1 -0
  54. package/dist/h5/http/utils/__tests__/xua.test.d.ts +1 -0
  55. package/dist/h5/http/utils/index.d.ts +14 -0
  56. package/dist/h5/http/utils/session.d.ts +1 -0
  57. package/dist/h5/report/errors/index.d.ts +4 -0
  58. package/dist/h5/report/event-tracker.d.ts +8 -0
  59. package/dist/h5/report/index.d.ts +10 -0
  60. package/dist/h5/report/task-tracker.d.ts +18 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.js +13 -0
  63. package/dist/index.native.d.ts +2 -0
  64. package/dist/index.native.js +3 -0
  65. package/dist/native/api/ads.d.ts +1 -0
  66. package/dist/native/api/base.d.ts +13 -0
  67. package/dist/native/api/get-system-info.d.ts +1 -0
  68. package/dist/native/api/index.d.ts +8 -0
  69. package/dist/native/api/keyboard.d.ts +9 -0
  70. package/dist/native/api/lifecycle.d.ts +1 -0
  71. package/dist/native/api/login.d.ts +1 -0
  72. package/dist/native/api/request.d.ts +1 -0
  73. package/dist/native/api/storage.d.ts +25 -0
  74. package/dist/native/api/task.d.ts +1 -0
  75. package/dist/native/bootstrap/bridge.d.ts +4 -0
  76. package/dist/native/bootstrap/index.d.ts +1 -0
  77. package/dist/native/js-bridge/const.d.ts +5 -0
  78. package/dist/native/js-bridge/index.d.ts +2 -0
  79. package/dist/native/js-bridge/invoke.d.ts +21 -0
  80. package/dist/native/js-bridge/js-bridge.d.ts +6 -0
  81. package/dist/native/js-bridge/report.d.ts +63 -0
  82. package/dist/native/js-bridge/subscribe.d.ts +8 -0
  83. package/dist/native/js-bridge/types.d.ts +14 -0
  84. package/dist/native/js-bridge/utils.d.ts +17 -0
  85. package/dist/native/js-core/index.d.ts +3 -0
  86. package/dist/native/js-core/jolibox-js-core.d.ts +45 -0
  87. package/dist/native/js-core/message-port.d.ts +12 -0
  88. package/dist/native/js-core/utils.d.ts +7 -0
  89. package/dist/native/network/create-fetch.d.ts +27 -0
  90. package/dist/native/network/index.d.ts +11 -0
  91. package/dist/native/network/report.d.ts +15 -0
  92. package/dist/native/network/types.d.ts +61 -0
  93. package/dist/native/network/utils.d.ts +9 -0
  94. package/dist/native/report/errors/index.d.ts +4 -0
  95. package/dist/native/report/index.d.ts +10 -0
  96. package/dist/native/report/task-tracker.d.ts +24 -0
  97. package/dist/utils/index.d.ts +0 -0
  98. package/esbuild.config.js +66 -0
  99. package/implement.build.log +9 -0
  100. package/package.json +30 -0
  101. package/src/common/api-factory/index.ts +188 -0
  102. package/src/common/api-factory/validator/__tests__/validate/any.test.ts +68 -0
  103. package/src/common/api-factory/validator/__tests__/validate/array.test.ts +402 -0
  104. package/src/common/api-factory/validator/__tests__/validate/arraybuffer.test.ts +48 -0
  105. package/src/common/api-factory/validator/__tests__/validate/boolean.test.ts +27 -0
  106. package/src/common/api-factory/validator/__tests__/validate/enum.test.ts +106 -0
  107. package/src/common/api-factory/validator/__tests__/validate/function.test.ts +54 -0
  108. package/src/common/api-factory/validator/__tests__/validate/literal.test.ts +130 -0
  109. package/src/common/api-factory/validator/__tests__/validate/nullish.test.ts +41 -0
  110. package/src/common/api-factory/validator/__tests__/validate/number.test.ts +147 -0
  111. package/src/common/api-factory/validator/__tests__/validate/object.test.ts +131 -0
  112. package/src/common/api-factory/validator/__tests__/validate/or.test.ts +96 -0
  113. package/src/common/api-factory/validator/__tests__/validate/record.test.ts +274 -0
  114. package/src/common/api-factory/validator/__tests__/validate/string.test.ts +187 -0
  115. package/src/common/api-factory/validator/__tests__/validate/symbol.test.ts +23 -0
  116. package/src/common/api-factory/validator/__tests__/validate/tuple.test.ts +86 -0
  117. package/src/common/api-factory/validator/__tests__/validate/type-asserts.test.ts +13 -0
  118. package/src/common/api-factory/validator/__tests__/validate/utils.test.ts +44 -0
  119. package/src/common/api-factory/validator/index.ts +107 -0
  120. package/src/common/api-factory/validator/validate.ts +641 -0
  121. package/src/common/can-i-use.ts +19 -0
  122. package/src/common/context/index.ts +85 -0
  123. package/src/common/context/types.ts +5 -0
  124. package/src/common/context/url-parse.ts +63 -0
  125. package/src/common/http/index.ts +29 -0
  126. package/src/common/http/uuid.ts +11 -0
  127. package/src/common/http/xua.ts +79 -0
  128. package/src/common/report/base-tracker.ts +134 -0
  129. package/src/common/report/create-trace.ts +17 -0
  130. package/src/common/report/errors/error-types.ts +206 -0
  131. package/src/common/report/errors/index.ts +20 -0
  132. package/src/common/report/errors/report/index.ts +63 -0
  133. package/src/common/report/errors/report/listeners.ts +80 -0
  134. package/src/common/report/index.ts +3 -0
  135. package/src/common/report/task-track/index.ts +102 -0
  136. package/src/common/report/track.ts +49 -0
  137. package/src/common/report/types.ts +90 -0
  138. package/src/h5/ads/ads-action-detection.ts +31 -0
  139. package/src/h5/ads/anti-cheating.ts +244 -0
  140. package/src/h5/ads/index.ts +658 -0
  141. package/src/h5/api/base.ts +9 -0
  142. package/src/h5/api/get-system-info.ts +59 -0
  143. package/src/h5/api/index.ts +4 -0
  144. package/src/h5/api/lifecycle.ts +95 -0
  145. package/src/h5/api/storage.ts +173 -0
  146. package/src/h5/api/task.ts +190 -0
  147. package/src/h5/bootstrap/index.ts +16 -0
  148. package/src/h5/http/index.ts +189 -0
  149. package/src/h5/http/utils/__tests__/uuid.test.ts +16 -0
  150. package/src/h5/http/utils/__tests__/xua.test.ts +27 -0
  151. package/src/h5/http/utils/index.ts +19 -0
  152. package/src/h5/http/utils/session.ts +10 -0
  153. package/src/h5/report/errors/index.ts +40 -0
  154. package/src/h5/report/event-tracker.ts +40 -0
  155. package/src/h5/report/index.ts +56 -0
  156. package/src/h5/report/task-tracker.ts +42 -0
  157. package/src/index.native.ts +7 -0
  158. package/src/index.ts +9 -0
  159. package/src/native/api/ads.ts +52 -0
  160. package/src/native/api/base.ts +8 -0
  161. package/src/native/api/get-system-info.ts +44 -0
  162. package/src/native/api/index.ts +8 -0
  163. package/src/native/api/keyboard.ts +75 -0
  164. package/src/native/api/lifecycle.ts +76 -0
  165. package/src/native/api/login.ts +73 -0
  166. package/src/native/api/request.ts +154 -0
  167. package/src/native/api/storage.ts +287 -0
  168. package/src/native/api/task.ts +227 -0
  169. package/src/native/bootstrap/bridge.ts +59 -0
  170. package/src/native/bootstrap/index.ts +59 -0
  171. package/src/native/js-bridge/const.ts +11 -0
  172. package/src/native/js-bridge/index.ts +2 -0
  173. package/src/native/js-bridge/invoke.ts +210 -0
  174. package/src/native/js-bridge/js-bridge.ts +23 -0
  175. package/src/native/js-bridge/report.ts +311 -0
  176. package/src/native/js-bridge/subscribe.ts +50 -0
  177. package/src/native/js-bridge/types.ts +26 -0
  178. package/src/native/js-bridge/utils.ts +116 -0
  179. package/src/native/js-core/index.ts +4 -0
  180. package/src/native/js-core/jolibox-js-core.ts +188 -0
  181. package/src/native/js-core/message-port.ts +52 -0
  182. package/src/native/js-core/utils.ts +9 -0
  183. package/src/native/network/create-fetch.ts +237 -0
  184. package/src/native/network/index.ts +15 -0
  185. package/src/native/network/report.ts +58 -0
  186. package/src/native/network/types.ts +77 -0
  187. package/src/native/network/utils.ts +90 -0
  188. package/src/native/report/errors/index.ts +27 -0
  189. package/src/native/report/index.ts +51 -0
  190. package/src/native/report/task-tracker.ts +72 -0
  191. package/src/native/types/global.d.ts +26 -0
  192. package/src/native/types/native-method-map.d.ts +282 -0
  193. package/src/native/types/native-method.d.ts +30 -0
  194. package/src/utils/index.ts +0 -0
  195. package/tsconfig.json +18 -0
@@ -0,0 +1,85 @@
1
+ import { mergeArray, mergeWith } from '@jolibox/common';
2
+ import { DeviceInfo, HostInfo, HostUserInfo, SdkInfo } from './types';
3
+ import { Env } from '@jolibox/types';
4
+ import { parseUrlQuery } from './url-parse';
5
+ import { getAppVersion, getDeviceId } from '../http/xua';
6
+
7
+ declare const globalThis: {
8
+ joliboxJSCore?: {
9
+ env: () => Env | undefined;
10
+ };
11
+ };
12
+
13
+ const defaultEnv: Env = {
14
+ deviceInfo: {
15
+ brand: 'UnknownBrand',
16
+ model: 'UnknownModel',
17
+ did: getDeviceId(),
18
+ pixelRatio: window.devicePixelRatio || 1,
19
+ platform: 'h5',
20
+ system: 'UnknownSystemVersion',
21
+ lang: 'zh'
22
+ },
23
+ sdkInfo: {
24
+ nativeSDKVersion: '',
25
+ jssdkVersion: getAppVersion()
26
+ },
27
+ schema: '',
28
+ platform: 'h5'
29
+ };
30
+
31
+ const nativeEnv = globalThis.joliboxJSCore?.env;
32
+
33
+ const env = Object.assign({}, nativeEnv?.() ?? defaultEnv);
34
+
35
+ const wrapContext = () => {
36
+ const { payloadJson, headerJson } = parseUrlQuery(env.schema);
37
+ const defaultSessionId = `${env.deviceInfo.did}-${new Date().getTime()}`;
38
+ const urlParams = new URLSearchParams(env.schema.length ? env.schema : window.location.search);
39
+ const defaultGameID = urlParams.get('appId') ?? urlParams.get('gameId') ?? '';
40
+ const sessionId = payloadJson.sessionId ?? urlParams.get('sessionId') ?? defaultSessionId;
41
+ const testAdsMode = !!(payloadJson.testAdsMode ?? urlParams.get('testAdsMode') === 'true');
42
+ const joliboxEnv = payloadJson.joliboxEnv ?? urlParams.get('joliboxEnv') ?? 'production';
43
+ const testMode = joliboxEnv === 'staging';
44
+
45
+ return {
46
+ get testMode(): boolean {
47
+ return testMode; // TODO: true test mode
48
+ },
49
+ get testAdsMode(): boolean {
50
+ return testAdsMode;
51
+ },
52
+ get joliboxEnv() {
53
+ return joliboxEnv;
54
+ },
55
+ get mpId(): string {
56
+ return defaultGameID ?? payloadJson['id'];
57
+ },
58
+ get mpVersion(): string {
59
+ return headerJson.ver ?? getAppVersion();
60
+ },
61
+ get platform(): Env['platform'] {
62
+ return env.platform;
63
+ },
64
+ get deviceInfo(): DeviceInfo {
65
+ return env.deviceInfo;
66
+ },
67
+ get sdkInfo(): SdkInfo {
68
+ return env.sdkInfo;
69
+ },
70
+ get hostInfo(): HostInfo {
71
+ return env.hostInfo;
72
+ },
73
+ get hostUserInfo(): HostUserInfo {
74
+ return env.hostUserInfo;
75
+ },
76
+ get sessionId(): string {
77
+ return env.clientSessionId ?? sessionId ?? defaultSessionId;
78
+ },
79
+ onEnvConfigChanged: (newConfig: Partial<Env>) => {
80
+ mergeWith(env, newConfig, mergeArray);
81
+ }
82
+ };
83
+ };
84
+
85
+ export const context = wrapContext();
@@ -0,0 +1,5 @@
1
+ import { Env } from '@jolibox/types';
2
+ export type DeviceInfo = Env['deviceInfo'];
3
+ export type HostInfo = Env['hostInfo'];
4
+ export type SdkInfo = Env['sdkInfo'];
5
+ export type HostUserInfo = Env['hostUserInfo'];
@@ -0,0 +1,63 @@
1
+ import { InternalSchemaParseError } from '@jolibox/common';
2
+ import { reportError } from '../report/errors/report';
3
+
4
+ interface HeaderJson {
5
+ ver?: string;
6
+ channel?: string;
7
+ subChannel?: string;
8
+ }
9
+
10
+ interface PayloadJson {
11
+ id?: string;
12
+ testAdsMode?: boolean;
13
+ joliboxEnv?: 'staging' | 'production';
14
+ sessionId?: string;
15
+ }
16
+
17
+ interface Signature {
18
+ headerSig?: string;
19
+ payloadSig?: string;
20
+ }
21
+
22
+ interface QueryParams {
23
+ headerJson: HeaderJson;
24
+ payloadJson: PayloadJson;
25
+ signature: Signature;
26
+ }
27
+
28
+ const base64UrlDecode = <T>(input: string): T => {
29
+ const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
30
+ const padding = base64.length % 4 === 0 ? '' : '='.repeat(4 - (base64.length % 4));
31
+ const jsonStr = atob(base64 + padding);
32
+ try {
33
+ return JSON.parse(jsonStr) as T;
34
+ } catch (e) {
35
+ return {} as T;
36
+ }
37
+ };
38
+
39
+ export const parseUrlQuery = (url: string): QueryParams => {
40
+ try {
41
+ const urlObj = new URL(url);
42
+ const params = urlObj.searchParams;
43
+
44
+ const joli_source = params.get('joliSource')?.split('.');
45
+ if (joli_source?.length) {
46
+ const [headerJsonStr, payloadJsonStr, signatureJsonStr] = joli_source;
47
+ return {
48
+ headerJson: base64UrlDecode<HeaderJson>(headerJsonStr),
49
+ payloadJson: base64UrlDecode<PayloadJson>(payloadJsonStr),
50
+ signature: base64UrlDecode<Signature>(signatureJsonStr)
51
+ };
52
+ } else {
53
+ throw `joli_source is missing`;
54
+ }
55
+ } catch (e) {
56
+ reportError(new InternalSchemaParseError(`${url} not a valid schema: ${e}`));
57
+ return {
58
+ headerJson: {},
59
+ payloadJson: {},
60
+ signature: {}
61
+ };
62
+ }
63
+ };
@@ -0,0 +1,29 @@
1
+ export interface IHttpClient {
2
+ get<T>(
3
+ path: string,
4
+ {
5
+ query,
6
+ headers,
7
+ timeout
8
+ }: {
9
+ query?: Record<string, string>;
10
+ headers?: Record<string, string>;
11
+ timeout?: number;
12
+ }
13
+ ): Promise<T>;
14
+
15
+ post<T = any>(
16
+ path: string,
17
+ {
18
+ data,
19
+ query,
20
+ headers,
21
+ timeout
22
+ }: {
23
+ data?: any;
24
+ query?: Record<string, string>;
25
+ headers?: Record<string, string>;
26
+ timeout?: number;
27
+ }
28
+ ): Promise<T>;
29
+ }
@@ -0,0 +1,11 @@
1
+ export const uuidv4 = () => {
2
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
3
+ const r = (Math.random() * 16) | 0;
4
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
5
+ return v.toString(16);
6
+ });
7
+ };
8
+
9
+ export const isValidUUIDV4 = (uuid: string) => {
10
+ return /^[\da-f]{8}-[\da-f]{4}-4[\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}$/i.test(uuid);
11
+ };
@@ -0,0 +1,79 @@
1
+ import { uuidv4 } from './uuid';
2
+
3
+ export const platform = {
4
+ isiOS:
5
+ navigator.userAgent.includes('iPhone') ||
6
+ navigator.userAgent.includes('iPod') ||
7
+ navigator.userAgent.includes('iPad') ||
8
+ navigator.userAgent.includes('iPhone OS'),
9
+ iosVersion: () => {
10
+ const v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/) as string[];
11
+ return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || '0', 10)];
12
+ },
13
+ isAndroid: navigator.userAgent.includes('Android'),
14
+ isMac: navigator.userAgent.includes('Mac'),
15
+ isFacebook: navigator.userAgent.includes('FB_IAB'),
16
+ isPC: !navigator.userAgent.includes('iPhone') && !navigator.userAgent.includes('Android')
17
+ };
18
+
19
+ export const getPlatform = () => {
20
+ if (platform.isiOS) {
21
+ return 'iOS';
22
+ } else if (platform.isAndroid) {
23
+ return 'Android';
24
+ } else if (platform.isMac) {
25
+ return 'Mac';
26
+ } else if (platform.isFacebook) {
27
+ return 'Facebook';
28
+ } else {
29
+ return 'PC';
30
+ }
31
+ };
32
+
33
+ const jssdkVersion = '__JOLIBOX_LOCAL_SDK_VERSION__';
34
+
35
+ export const getAppVersion = () => {
36
+ return jssdkVersion;
37
+ };
38
+
39
+ export const DEVICE_ID = 'device_id';
40
+ export const ADVERTISING_ID = 'advertising_id';
41
+
42
+ export const getStorage = (cookieKey: string) => {
43
+ if (!localStorage.getItem(cookieKey)) {
44
+ localStorage.setItem(cookieKey, uuidv4());
45
+ }
46
+ return localStorage.getItem(cookieKey)!;
47
+ };
48
+
49
+ export const getDeviceId = () => {
50
+ return getStorage(DEVICE_ID);
51
+ };
52
+
53
+ export const getAdvertisingId = () => {
54
+ return getStorage(ADVERTISING_ID);
55
+ };
56
+
57
+ const firstCharUpperCase = (chars: string) => chars.charAt(0).toUpperCase() + chars.slice(1);
58
+
59
+ export const getUtmSource = () => {
60
+ const urlParams = new URLSearchParams(window.location.search);
61
+ return firstCharUpperCase(urlParams.get('utm_source') ?? '') || 'JoliboxSDK';
62
+ };
63
+
64
+ export const xUserAgent = () => {
65
+ const applicationName = 'JoliboxWebSDK';
66
+ const thePlatform = getPlatform();
67
+ const locale = navigator.language;
68
+ const deviceId = getDeviceId();
69
+ const adid = getAdvertisingId();
70
+ const appVersion = getAppVersion();
71
+ // const parserResult = getUAParser();
72
+ // const deviceModel = parserResult.device.model;
73
+ const deviceModel = 'UnknownModel';
74
+ // const systemVersion = parserResult.os.version;
75
+ const systemVersion = 'UnknownSystemVersion';
76
+ return `${applicationName} (${getUtmSource()}${thePlatform}; ${deviceModel}; ${systemVersion}; ${locale}) uuid/${deviceId} adid/${adid} version/${
77
+ appVersion || ''
78
+ }`;
79
+ };
@@ -0,0 +1,134 @@
1
+ import { context } from '@/common/context';
2
+ import { logger } from '@jolibox/common';
3
+ import { IDevice, IPage, IEventPackage, IEvent, EProject } from '@/common/report/types';
4
+
5
+ const keysOfPage: (keyof IPage)[] = ['name', 'params'];
6
+ const keysOfEvent: (keyof IEvent)[] = ['name', 'type', 'location', 'target', 'extra', 'timestamp', 'userId'];
7
+ const keysOfDevice: (keyof IDevice)[] = [
8
+ 'platform',
9
+ 'os',
10
+ 'appVersion',
11
+ 'appId',
12
+ 'model',
13
+ 'brand',
14
+ 'uuid',
15
+ 'jsSdkVersion',
16
+ 'extra'
17
+ ];
18
+ function serializeObject<T>(obj: T, order: (keyof T)[]): any[] {
19
+ return order.map((key) => {
20
+ if (key === 'params' && obj[key]) {
21
+ const params = obj[key] as Record<string, any>;
22
+ return Object.keys(params).reduce((acc, k) => {
23
+ acc[k] = String(params[k]);
24
+ return acc;
25
+ }, {} as Record<string, any>);
26
+ }
27
+ return obj[key];
28
+ });
29
+ }
30
+
31
+ function serializeEvent(event: IEvent): any[] {
32
+ const location = event.location ? serializeObject(event.location, keysOfPage) : null;
33
+ const target = event.target ? serializeObject(event.target, keysOfPage) : null;
34
+
35
+ // 定义IEvent的序列化顺序
36
+ return serializeObject({ ...event, location, target }, keysOfEvent);
37
+ }
38
+
39
+ function serializeEventPackage(eventPackage: IEventPackage): any[] {
40
+ // 序列化事件数组
41
+ const events = eventPackage.events.map((event) => serializeEvent(event));
42
+
43
+ // 定义IDevice的序列化顺序
44
+ const device = serializeObject(eventPackage.device, keysOfDevice);
45
+
46
+ return [eventPackage.protocolVersion, events, device, eventPackage.project];
47
+ }
48
+
49
+ export abstract class EventTracker {
50
+ deviceInfo: IDevice | null = null;
51
+
52
+ abstract doReport(event: unknown[]): void;
53
+ abstract doReport<T extends Record<string, unknown>>(event: unknown[], extra: T): void;
54
+ abstract doReport<T extends Record<string, unknown>>(event: unknown[], extra?: T): void;
55
+
56
+ private pastTrackings: boolean[] = [];
57
+
58
+ private pushPastTracking = (tracking: boolean) => {
59
+ this.pastTrackings.push(tracking);
60
+ if (this.pastTrackings.length > 10) {
61
+ this.pastTrackings.slice(-10);
62
+ }
63
+ };
64
+
65
+ public get networkIsOk() {
66
+ // in the past 10 trackings, at least 60% of them are successful
67
+ return (
68
+ this.pastTrackings.length <= 4 ||
69
+ this.pastTrackings.filter(Boolean).length / this.pastTrackings.length >= 0.6
70
+ );
71
+ }
72
+
73
+ getDevice(): IDevice {
74
+ const { nativeSDKVersion, jssdkVersion } = context.sdkInfo;
75
+ return {
76
+ platform: 1000,
77
+ os: context.deviceInfo.platform,
78
+ appVersion: nativeSDKVersion ?? jssdkVersion ?? '1.0.0', // mock
79
+ appId: context.hostInfo?.aid ?? '1',
80
+ model: context.deviceInfo.model ?? 'UnknownModel',
81
+ brand: context.deviceInfo.brand ?? 'UnknownBrand',
82
+ uuid: context.deviceInfo.did,
83
+ jsSdkVersion: jssdkVersion, // mock
84
+ extra: {}
85
+ };
86
+ }
87
+
88
+ getLocation(): IPage {
89
+ const urlParams = new URLSearchParams(window.location.search);
90
+ const params: Record<string, any> = {};
91
+ urlParams.forEach((value, key) => {
92
+ params[key] = value;
93
+ });
94
+ return {
95
+ name: 'GamePage',
96
+ params
97
+ };
98
+ }
99
+
100
+ async trackEvent(event: IEvent, project: EProject, extraInfo?: Record<string, unknown>) {
101
+ const location = event.location ? event.location : await this.getLocation();
102
+ const target = event.target || null;
103
+ const extra = event.extra || null;
104
+ if (!this.deviceInfo) {
105
+ this.deviceInfo = await this.getDevice();
106
+ }
107
+ const device = this.deviceInfo;
108
+ const events: IEvent[] = [
109
+ {
110
+ ...event,
111
+ location,
112
+ target,
113
+ extra,
114
+ timestamp: Date.now(),
115
+ userId: null
116
+ }
117
+ ];
118
+ const eventPackage: IEventPackage = {
119
+ protocolVersion: '1.0.0',
120
+ events,
121
+ device,
122
+ project
123
+ };
124
+ try {
125
+ extraInfo
126
+ ? this.doReport(serializeEventPackage(eventPackage), extraInfo)
127
+ : this.doReport(serializeEventPackage(eventPackage));
128
+ this.pushPastTracking(true);
129
+ } catch (e) {
130
+ this.pushPastTracking(false);
131
+ logger.log('[Jolibox SDK] report API error', e);
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,17 @@
1
+ import { createTrack, createTrackPerformance } from './track';
2
+ import { Track, TrackPerformance, ReportHandler, CommonReportConfig } from './types';
3
+
4
+ interface Tracks {
5
+ track: Track;
6
+ trackPerformance: TrackPerformance;
7
+ }
8
+
9
+ export function createTracks(reportHandler: ReportHandler, common: CommonReportConfig): Tracks {
10
+ const track = createTrack(reportHandler, common);
11
+ const trackPerformance = createTrackPerformance(track);
12
+
13
+ return {
14
+ track,
15
+ trackPerformance
16
+ };
17
+ }
@@ -0,0 +1,206 @@
1
+ type InternalLifeCycleErrorName = 'INTERNAL_GAME_LAUNCH_ERROR';
2
+
3
+ // API
4
+ type InternalAPIErrorName = 'INTERNAL_API_ERROR';
5
+
6
+ // 前端埋点
7
+ type InternalMetricErrorName = 'INTERNAL_METRIC_REPORT_ERROR';
8
+
9
+ // reporter
10
+ type InternalReporterErrorName = 'INTERNAL_REPORTER_ERROR';
11
+
12
+ // 内部错误
13
+ type InternalUtilErrorName = 'INTERNAL_BUFFER_ERROR' | 'INTERNAL_SCHEMA_PARSE_ERROR';
14
+
15
+ // Native Inject Error
16
+ type InternalInjectErrorName = 'INTERNAL_CONTEXT_ERROR' | 'INTERNAL_JSCORE_ERROR';
17
+
18
+ type InternalBridgeErrorName =
19
+ | 'INTERNAL_INVOKE_NATIVE_ERROR'
20
+ | 'INTERNAL_APPLY_NATIVE_ERROR'
21
+ | 'INTERNAL_INVOKE_METHOD_ERROR';
22
+
23
+ // User
24
+ type UserErrorName =
25
+ | 'USER_VALIDATE_ERROR'
26
+ | 'USER_GLOBAL_ERROR'
27
+ | 'USER_FETCH_ERROR'
28
+ | 'API_ERROR'
29
+ | 'USER_CUSTOM_ERROR';
30
+
31
+ export type ErrorName =
32
+ | InternalLifeCycleErrorName
33
+ | InternalInjectErrorName
34
+ | InternalAPIErrorName
35
+ | InternalBridgeErrorName
36
+ | InternalUtilErrorName
37
+ | InternalReporterErrorName
38
+ | UserErrorName
39
+ | InternalMetricErrorName;
40
+
41
+ export type ErrorKind = 'INTERNAL_ERROR' | 'USER_ERROR' | 'API_ERROR';
42
+ export type ErrorEnv = 'native' | 'h5';
43
+ export type LoadScriptError = BaseError & { code?: number };
44
+ export enum LoadScriptCode {
45
+ DEVELOPER_FILE_NOT_FOUND = 0,
46
+ INTERNAL_IOS_CAN_NOT_FOUND_PKG = 1,
47
+ USER_IOS_LOAD_TIMEOUT = 2,
48
+ INTERNAL_IOS_PKG_LOAD_ERROR = 3,
49
+ INTERNAL_IOS_PKG_PARSE_FAIL = 4,
50
+ USER_IOS_GET_EMPTY_DATA = 5,
51
+ USER_ANDROID_GET_PKG_FAIL = 6,
52
+ DEVELOPER_ANDROID_PACKAGE_FILE_UNEXPECTED_REQUIRE = 7
53
+ }
54
+
55
+ export abstract class BaseError extends Error {
56
+ abstract kind: ErrorKind;
57
+ abstract name: ErrorName;
58
+ priority: 'P0' | 'P1';
59
+ env?: ErrorEnv;
60
+ raw?: Error;
61
+ component?: string;
62
+ constructor(error: string | Error) {
63
+ if (typeof error === 'string') {
64
+ super(error);
65
+ this.priority = 'P1';
66
+ return;
67
+ }
68
+ super(error.message);
69
+ this.priority = 'P1';
70
+ this.stack = error.stack;
71
+ this.raw = error;
72
+ }
73
+ }
74
+
75
+ export abstract class InternalError extends BaseError {
76
+ readonly kind = 'INTERNAL_ERROR';
77
+ }
78
+ export abstract class UserError extends BaseError {
79
+ readonly kind = 'USER_ERROR';
80
+ }
81
+
82
+ export class UserValidateError extends UserError {
83
+ readonly name = 'USER_VALIDATE_ERROR';
84
+ }
85
+
86
+ export class UserGlobalError extends UserError {
87
+ readonly name = 'USER_GLOBAL_ERROR';
88
+ readonly priority = 'P0';
89
+ }
90
+
91
+ export class UserCustomError extends UserError {
92
+ readonly name = 'USER_CUSTOM_ERROR';
93
+ errMsg: string;
94
+ extra?: { [key: string]: unknown };
95
+
96
+ constructor(readonly message: string, readonly errNo?: number, extra?: { [key: string]: unknown }) {
97
+ super(message);
98
+ this.errMsg = message;
99
+
100
+ if (extra) {
101
+ this.extra = Object.assign({}, this.extra, extra);
102
+ }
103
+ }
104
+ }
105
+
106
+ export class UserFetchError extends UserError {
107
+ readonly name = 'USER_FETCH_ERROR';
108
+ errMsg: string;
109
+ extra?: { [key: string]: unknown };
110
+
111
+ constructor(readonly message: string, readonly errNo?: number, extra?: { [key: string]: unknown }) {
112
+ super(message);
113
+ this.errMsg = message;
114
+
115
+ if (extra) {
116
+ this.extra = Object.assign({}, this.extra, extra);
117
+ }
118
+ }
119
+ }
120
+
121
+ export class InternalSchemaParseError extends InternalError {
122
+ readonly name = 'INTERNAL_SCHEMA_PARSE_ERROR';
123
+ readonly priority = 'P0';
124
+ }
125
+
126
+ export class InternalInvokeNativeError extends InternalError {
127
+ readonly name = 'INTERNAL_INVOKE_NATIVE_ERROR';
128
+ }
129
+
130
+ export class InternalApplyNativeError extends InternalError {
131
+ readonly name = 'INTERNAL_APPLY_NATIVE_ERROR';
132
+ errorType?: string;
133
+ errorCode?: number;
134
+ constructor(message: string, readonly errNo?: number, errorType?: string, errorCode?: number) {
135
+ super(message);
136
+ this.errorType = errorType;
137
+ this.errorCode = errorCode;
138
+ }
139
+ }
140
+
141
+ export class InternalInvokeMethodError extends InternalError {
142
+ readonly name = 'INTERNAL_INVOKE_METHOD_ERROR';
143
+ }
144
+
145
+ export class InternalJSCoreNotFoundError extends InternalError {
146
+ readonly name = 'INTERNAL_JSCORE_ERROR';
147
+ }
148
+
149
+ export class InternalBufferError extends InternalError {
150
+ readonly name = 'INTERNAL_BUFFER_ERROR';
151
+ }
152
+
153
+ export class InternalContextError extends InternalError {
154
+ readonly name = 'INTERNAL_CONTEXT_ERROR';
155
+ readonly property: string;
156
+ constructor(readonly message: string, property: string) {
157
+ super(message);
158
+ this.property = property;
159
+ }
160
+ }
161
+
162
+ export class APIError extends BaseError {
163
+ readonly kind = 'API_ERROR';
164
+ readonly name = 'API_ERROR';
165
+ extra?: Record<string, unknown>;
166
+ errorType?: string;
167
+
168
+ constructor(
169
+ readonly message: string,
170
+ readonly code: number,
171
+ errorType?: string,
172
+ stack?: string,
173
+ priority?: 'P0' | 'P1'
174
+ ) {
175
+ super(message);
176
+
177
+ if (errorType) {
178
+ this.errorType = errorType;
179
+ }
180
+
181
+ if (stack !== undefined) {
182
+ this.stack = stack;
183
+ }
184
+ if (priority) {
185
+ this.priority = priority;
186
+ }
187
+ }
188
+
189
+ toJSON() {
190
+ return {
191
+ message: this.message,
192
+ stack: this.stack,
193
+ name: this.name,
194
+ code: this.code,
195
+ errorType: this.errorType
196
+ };
197
+ }
198
+ }
199
+
200
+ export class InternalMetricReportError extends InternalError {
201
+ readonly name = 'INTERNAL_METRIC_REPORT_ERROR';
202
+ }
203
+
204
+ export class InternalReporterError extends InternalError {
205
+ readonly name = 'INTERNAL_REPORTER_ERROR';
206
+ }
@@ -0,0 +1,20 @@
1
+ import './report';
2
+ import { APIError, UserCustomError } from '@jolibox/common';
3
+
4
+ export function formatErrorCode(method: string, code?: number) {
5
+ return `[${method}]:${code}`;
6
+ }
7
+
8
+ // 创建APIError异常对象
9
+ export const createAPIError = (
10
+ error: { code: number; msg: string; type?: string },
11
+ params?: { errNo?: number; errMsg?: string }
12
+ ) => {
13
+ return new APIError(params?.errMsg ?? error.msg ?? '', error.code, error.type);
14
+ };
15
+
16
+ export const createUserAPIError = (msg: string) => {
17
+ return new UserCustomError(msg);
18
+ };
19
+
20
+ export { errorReportEmitter, ErrorData } from './report';