@jolibox/sdk 1.1.2 → 1.1.4-beta.0

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 (89) hide show
  1. package/.eslintrc.js +3 -0
  2. package/.rush/temp/package-deps_build.json +28 -0
  3. package/.rush/temp/shrinkwrap-deps.json +76 -0
  4. package/README.md +1 -96
  5. package/dist/api/__tests__/canIUse.test.d.ts +1 -0
  6. package/dist/api/can-i-use.d.ts +1 -0
  7. package/dist/api/get-system-info.d.ts +3 -0
  8. package/dist/api/index.d.ts +2 -0
  9. package/dist/errors.d.ts +2 -0
  10. package/dist/index.cjs.js +1 -0
  11. package/dist/index.d.ts +19 -337
  12. package/dist/index.es.js +1 -0
  13. package/dist/index.iife.js +1 -12
  14. package/dist/loader/h5.d.ts +6 -0
  15. package/dist/loader/index.d.ts +16 -0
  16. package/dist/loader/native.d.ts +6 -0
  17. package/dist/loader/version.d.ts +2 -0
  18. package/dist/sdks/ads.d.ts +11 -0
  19. package/dist/sdks/keyboard.d.ts +34 -0
  20. package/dist/sdks/lifecycle.d.ts +16 -0
  21. package/dist/sdks/runtime.d.ts +1 -0
  22. package/dist/sdks/sdk.d.ts +11 -0
  23. package/dist/sdks/storage.d.ts +8 -0
  24. package/dist/utils/can-i-use.d.ts +2 -0
  25. package/dist/utils/report.d.ts +3 -0
  26. package/package.json +23 -33
  27. package/sdk.build.log +17 -0
  28. package/src/api/__tests__/canIUse.test.ts +76 -0
  29. package/src/api/can-i-use.ts +38 -0
  30. package/src/api/get-system-info.ts +14 -0
  31. package/src/api/index.ts +2 -0
  32. package/src/errors.ts +42 -0
  33. package/src/index.ts +29 -0
  34. package/src/loader/h5.ts +175 -0
  35. package/src/loader/index.ts +65 -0
  36. package/src/loader/native.ts +62 -0
  37. package/src/loader/version.ts +44 -0
  38. package/src/sdks/ads.ts +32 -0
  39. package/src/sdks/keyboard.ts +50 -0
  40. package/src/sdks/lifecycle.ts +32 -0
  41. package/src/sdks/runtime.ts +3 -0
  42. package/src/sdks/sdk.ts +22 -0
  43. package/src/sdks/storage.ts +35 -0
  44. package/src/utils/can-i-use.ts +24 -0
  45. package/src/utils/report.ts +23 -0
  46. package/tsconfig.json +12 -107
  47. package/README-zh_cn.md +0 -96
  48. package/dist/index.cjs +0 -2
  49. package/dist/index.cjs.map +0 -1
  50. package/dist/index.d.cts +0 -342
  51. package/dist/index.iife.js.map +0 -1
  52. package/dist/index.js +0 -2
  53. package/dist/index.js.map +0 -1
  54. package/docs/.nojekyll +0 -1
  55. package/docs/assets/highlight.css +0 -106
  56. package/docs/assets/icons.js +0 -18
  57. package/docs/assets/icons.svg +0 -1
  58. package/docs/assets/main.js +0 -60
  59. package/docs/assets/navigation.js +0 -1
  60. package/docs/assets/search.js +0 -1
  61. package/docs/assets/style.css +0 -1493
  62. package/docs/classes/ads.JoliboxAds.html +0 -41
  63. package/docs/classes/index.JoliboxSDK.html +0 -4
  64. package/docs/classes/loader.JoliboxSDKLoader.html +0 -7
  65. package/docs/classes/runtime.JoliboxRuntime.html +0 -8
  66. package/docs/documents/README.html +0 -38
  67. package/docs/enums/runtime.JoliboxRuntimeEvents.html +0 -7
  68. package/docs/index.html +0 -38
  69. package/docs/interfaces/ads.IAdConfigParams.html +0 -12
  70. package/docs/interfaces/ads.IAdUnitParams.html +0 -11
  71. package/docs/interfaces/ads.IAdsInitParams.html +0 -5
  72. package/docs/interfaces/ads.IInterstitialsParams.html +0 -15
  73. package/docs/interfaces/ads.IPlacementInfo.html +0 -59
  74. package/docs/interfaces/ads.IPrerollParams.html +0 -6
  75. package/docs/interfaces/ads.IRewardParams.html +0 -18
  76. package/docs/interfaces/index.IJoliboxConfig.html +0 -3
  77. package/docs/interfaces/loader.IJoliboxSDKLoaderConfig.html +0 -3
  78. package/docs/interfaces/loader.IRemoteVersionMetadata.html +0 -4
  79. package/docs/interfaces/loader.IVersionMetadata.html +0 -4
  80. package/docs/modules/ads.html +0 -12
  81. package/docs/modules/index.html +0 -4
  82. package/docs/modules/loader.html +0 -5
  83. package/docs/modules/runtime.html +0 -4
  84. package/docs/modules.html +0 -6
  85. package/docs/types/ads.AdUnitFormat.html +0 -2
  86. package/docs/types/ads.IAdBreakParams.html +0 -2
  87. package/tsup.config.ts +0 -27
  88. package/typedoc.config.mjs +0 -19
  89. package/vitest.config.ts +0 -10
package/src/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ /** load implement at very first time */
2
+ /**
3
+ * global error catch
4
+ */
5
+ import './errors';
6
+ import './loader';
7
+
8
+ /**
9
+ * @public Jolibox JS SDK Entry
10
+ */
11
+ import { getSystemInfo, getSystemInfoSync, canIUse } from './api';
12
+ import { RuntimeSDK } from './sdks/runtime';
13
+ import { LifecycleSDK } from './sdks/lifecycle';
14
+ import { StorageSDK } from './sdks/storage';
15
+ import { JoliboxAds } from './sdks/ads';
16
+ import { KeyboardSDK } from './sdks/keyboard';
17
+
18
+ export class JoliboxSDK {
19
+ readonly runtime = new RuntimeSDK();
20
+ readonly ads = new JoliboxAds();
21
+ readonly lifecycle = new LifecycleSDK();
22
+ readonly storage = new StorageSDK();
23
+ readonly keyboard = new KeyboardSDK();
24
+
25
+ //global API
26
+ getSystemInfo = getSystemInfo.bind(this);
27
+ getSystemInfoSync = getSystemInfoSync.bind(this);
28
+ canIUse = canIUse.bind(this);
29
+ }
@@ -0,0 +1,175 @@
1
+ import { compare, major } from './version';
2
+ import { track, trackPerformance } from '../utils/report';
3
+ import { InternalJSModuleEvalError, InternalJSModuleFetchError } from '@jolibox/common';
4
+ import { getBoostrapModuleUrl, getImplementModuleUrl } from './index';
5
+ import { reportError } from '../errors';
6
+
7
+ const LOCAL_STORE_KEY = 'jolibox-sdk-loadermeta';
8
+ interface LocalStoreMeta {
9
+ bootstrap_version?: string;
10
+ bootstrap_script?: string;
11
+
12
+ implement_version?: string;
13
+ implement_script?: string;
14
+ timestamp?: number;
15
+ }
16
+
17
+ const CURRENT_VERSION_STORE: LocalStoreMeta = JSON.parse(localStorage.getItem(LOCAL_STORE_KEY) ?? '{}');
18
+ const now = Date.now();
19
+
20
+ const expired = (now: number, prev: number) =>
21
+ now > prev && Math.abs(now - prev) / (1000 * 60 * 60 * 24) >= 7;
22
+
23
+ const isLegalScript = (str: string) =>
24
+ !/^(Failed to fetch version|Couldn't find the requested file)/.test(str);
25
+ async function fetchCurrentRemoteScript() {
26
+ // TODO: adjust host
27
+ const path = `https://stg-api.jolibox.com/api/fe-configs/js-sdk/version_metadata`;
28
+ try {
29
+ const response = await fetch(path, {
30
+ method: 'GET',
31
+ headers: {
32
+ 'Content-Type': 'application/json'
33
+ }
34
+ });
35
+ const { implement_version, bootstrap_version }: LocalStoreMeta = await response.json();
36
+ let currentStore: LocalStoreMeta = { ...CURRENT_VERSION_STORE, timestamp: now };
37
+ if (bootstrap_version) {
38
+ const { bootstrap_version: currentLocalBootstrapVersion } = CURRENT_VERSION_STORE;
39
+ if (currentLocalBootstrapVersion && compare(currentLocalBootstrapVersion, bootstrap_version)) {
40
+ // no-op
41
+ } else {
42
+ const currentBootstrapModuleStr = await (await fetch(getBoostrapModuleUrl(bootstrap_version))).text();
43
+ isLegalScript(currentBootstrapModuleStr) &&
44
+ (currentStore = {
45
+ ...currentStore,
46
+ bootstrap_version,
47
+ bootstrap_script: currentBootstrapModuleStr
48
+ });
49
+ }
50
+ }
51
+ if (implement_version) {
52
+ const { implement_version: currentLocalImpelementVersion } = CURRENT_VERSION_STORE;
53
+ if (currentLocalImpelementVersion && compare(currentLocalImpelementVersion, implement_version)) {
54
+ // no-op
55
+ } else {
56
+ const currentImplementModuleStr = await (
57
+ await fetch(getImplementModuleUrl(implement_version))
58
+ ).text();
59
+ isLegalScript(currentImplementModuleStr) &&
60
+ (currentStore = {
61
+ ...currentStore,
62
+ implement_version,
63
+ implement_script: currentImplementModuleStr
64
+ });
65
+ }
66
+ }
67
+
68
+ localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(currentStore));
69
+ } catch (error) {
70
+ console.warn('Failed to fetch loader metadata: ', error);
71
+ }
72
+ }
73
+
74
+ export const createLoadImplement = (params: {
75
+ currentVersion: string;
76
+ currentMajorVersion: number;
77
+ bootstrapUrl: string;
78
+ implementUrl: string;
79
+ }) => {
80
+ const { currentMajorVersion, currentVersion, bootstrapUrl, implementUrl } = params;
81
+ function fetchCurrentBootstrapModule():
82
+ | { script: string; type: 'localscript' | 'fetch_from_cdn' }
83
+ | undefined {
84
+ const { bootstrap_version, bootstrap_script, timestamp } = CURRENT_VERSION_STORE;
85
+ if (bootstrap_version && bootstrap_script && timestamp) {
86
+ /**
87
+ * if current SDK major version is same && remote version is larget than current, use latest version
88
+ */
89
+ if (
90
+ !expired(now, timestamp) &&
91
+ major(bootstrap_version) == currentMajorVersion &&
92
+ compare(bootstrap_version, currentVersion) > 0
93
+ ) {
94
+ return { script: bootstrap_script, type: 'localscript' };
95
+ }
96
+ }
97
+ try {
98
+ const xhr = new XMLHttpRequest();
99
+ xhr.open('GET', bootstrapUrl, false);
100
+ xhr.send();
101
+ return { script: xhr.responseText, type: 'fetch_from_cdn' };
102
+ } catch (e) {
103
+ reportError(new InternalJSModuleFetchError(`Bootstrap module faile to fetch ${e}`));
104
+ }
105
+ }
106
+
107
+ function loadBootstrapModule() {
108
+ const startToLoad = Date.now();
109
+ track('js_sdk_begin', {
110
+ t: startToLoad
111
+ });
112
+
113
+ const { script: currentBootstrapModule, type } = fetchCurrentBootstrapModule() ?? {};
114
+ if (currentBootstrapModule) {
115
+ const script = document.createElement('script');
116
+ script.type = 'text/javascript';
117
+ script.innerHTML = currentBootstrapModule;
118
+ document.head.appendChild(script);
119
+ trackPerformance('bootstrapModuleLoaded', Date.now() - startToLoad, { type });
120
+ }
121
+ }
122
+
123
+ function evalLocalJSModule(code: string) {
124
+ const evalJS = async (code: string) => {
125
+ try {
126
+ const blob = new Blob([code], { type: 'application/javascript' });
127
+ const blobUrl = URL.createObjectURL(blob);
128
+ const module = await import(blobUrl);
129
+ URL.revokeObjectURL(blobUrl);
130
+ return module;
131
+ } catch (error) {
132
+ reportError(new InternalJSModuleEvalError(`implement module evaluate error in h5:${error} `));
133
+ }
134
+ };
135
+ evalJS(code);
136
+ }
137
+
138
+ // load remote impletation
139
+ function loadRemoteImplementation() {
140
+ const implStartLoad = Date.now();
141
+ const { implement_script, implement_version, timestamp } = CURRENT_VERSION_STORE;
142
+ if (implement_script && implement_version && timestamp) {
143
+ /**
144
+ * if current SDK major version is same && remote version is larget than current, use latest version
145
+ */
146
+ if (
147
+ !expired(now, timestamp) &&
148
+ major(implement_version) == currentMajorVersion &&
149
+ compare(implement_version, currentVersion) > 0
150
+ ) {
151
+ evalLocalJSModule(implement_script);
152
+ trackPerformance('implementModuleLoaded', Date.now() - implStartLoad, { type: 'loadscript' });
153
+ return;
154
+ }
155
+ }
156
+ const asyncScript = document.createElement('script');
157
+ asyncScript.type = 'module';
158
+ asyncScript.crossOrigin = 'anonymous';
159
+ asyncScript.src = implementUrl;
160
+ asyncScript.onload = () => {
161
+ trackPerformance('bootstrapModuleLoaded', Date.now() - implStartLoad, { type: 'fetch_from_cdn' });
162
+ };
163
+ document.head.appendChild(asyncScript);
164
+ }
165
+
166
+ return () => {
167
+ try {
168
+ loadBootstrapModule();
169
+ loadRemoteImplementation();
170
+ fetchCurrentRemoteScript();
171
+ } catch (e) {
172
+ reportError(new InternalJSModuleEvalError(`module evaluate error: ${e}`));
173
+ }
174
+ };
175
+ };
@@ -0,0 +1,65 @@
1
+ import { major } from './version';
2
+
3
+ import { createLoadImplement as createH5LoadImplement } from './h5';
4
+ import { createLoadImplement as createNativeLoadImplement } from './native';
5
+ //TODO: temp
6
+ const BUILD_VERSION = '1.0.0';
7
+ const currentVersion = BUILD_VERSION;
8
+ const currentMajorVersion = major(currentVersion);
9
+
10
+ /**
11
+ * Due to security restrictions on iOS, dynamically loading script tags is not supported.
12
+ * Therefore, a loadScript method needs to be injected on the client side to implement evalJavascriptFun.
13
+ * Link:https://mabin004.github.io/2018/06/25/iOS%E5%BA%94%E7%94%A8%E6%B2%99%E7%AE%B1/
14
+ */
15
+
16
+ declare global {
17
+ interface Window {
18
+ // WebBridge: AndroidBridge | null;
19
+ webkit?: unknown;
20
+ }
21
+ }
22
+ const loadScript = window.webkit
23
+ ? (params: { path: string }) => {
24
+ return window.prompt('loadScript', JSON.stringify(params));
25
+ }
26
+ : undefined;
27
+
28
+ const isNative = typeof loadScript !== 'undefined';
29
+
30
+ /**
31
+ * Do not expose the logic of dynamically retrieving URL information in the config,
32
+ * as this logic needs to remain self-contained within the SDK.
33
+ */
34
+ export const getBoostrapModuleUrl = (version: string | number) =>
35
+ `http://cdn.jsdelivr.net/npm/@jolibox/bootstrap@${version}/dist/index.js`;
36
+ export const getImplementModuleUrl = (version: string | number) =>
37
+ `http://cdn.jsdelivr.net/npm/@jolibox/implementation@${version}/dist/index.js`;
38
+ /**
39
+ * localTest
40
+ */
41
+ // export const getBoostrapModuleUrl = (version: string | number) => `http://localhost:3000/get-bootstrap`;
42
+ // export const getImplementModuleUrl = (version: string | number) => `http://localhost:3000/get-implement`;
43
+ const IMMEDIATE_SCRIPT_URL = getBoostrapModuleUrl(currentMajorVersion);
44
+ const REMOTE_IMPLEMENT_URL = getImplementModuleUrl(currentMajorVersion);
45
+
46
+ /**
47
+ * load entry
48
+ */
49
+ function loadImplement(): void {
50
+ if (isNative) {
51
+ createNativeLoadImplement(loadScript!, {
52
+ bootstrapUrl: IMMEDIATE_SCRIPT_URL,
53
+ implementUrl: REMOTE_IMPLEMENT_URL
54
+ })();
55
+ } else {
56
+ createH5LoadImplement({
57
+ bootstrapUrl: IMMEDIATE_SCRIPT_URL,
58
+ implementUrl: REMOTE_IMPLEMENT_URL,
59
+ currentMajorVersion,
60
+ currentVersion
61
+ })();
62
+ }
63
+ }
64
+
65
+ loadImplement();
@@ -0,0 +1,62 @@
1
+ import { track, trackPerformance } from '@/utils/report';
2
+ import { InternalJSModuleEvalError } from '@jolibox/common';
3
+ import { reportError } from '../errors';
4
+
5
+ export const createLoadImplement = (
6
+ loadScript: (params: { path: string }) => string | null,
7
+ params: {
8
+ bootstrapUrl: string;
9
+ implementUrl: string;
10
+ }
11
+ ) => {
12
+ const tryLoadScript = (url: string): string => {
13
+ const funStr = loadScript!({ path: url });
14
+ if (!funStr) {
15
+ throw `module ${url} load failed ${funStr}`;
16
+ }
17
+ return funStr;
18
+ };
19
+
20
+ function evalLocalJSModule(code: string) {
21
+ const evalJS = async (code: string) => {
22
+ try {
23
+ const blob = new Blob([code], { type: 'application/javascript' });
24
+ const blobUrl = URL.createObjectURL(blob);
25
+ const module = await import(blobUrl);
26
+ URL.revokeObjectURL(blobUrl);
27
+ return module;
28
+ } catch (error) {
29
+ reportError(new InternalJSModuleEvalError(`implement module evaluate error in native:${error} `));
30
+ }
31
+ };
32
+ evalJS(code);
33
+ }
34
+ return () => {
35
+ try {
36
+ const startToLoad = Date.now();
37
+ track('js_sdk_begin', {
38
+ t: startToLoad
39
+ });
40
+ /**
41
+ * bootstrap module
42
+ */
43
+ const bootstrapModuleStr = tryLoadScript(params.bootstrapUrl);
44
+ const script = document.createElement('script');
45
+ script.type = 'text/javascript';
46
+ script.innerHTML = bootstrapModuleStr;
47
+ document.head.appendChild(script);
48
+ trackPerformance('implementModuleLoaded', Date.now() - startToLoad, { type: 'native' });
49
+
50
+ /**
51
+ * implement module
52
+ */
53
+ const implModuleStr = tryLoadScript(params.implementUrl);
54
+ evalLocalJSModule(implModuleStr);
55
+ trackPerformance('bootstrapModuleLoaded', Date.now() - startToLoad, { type: 'native' });
56
+ } catch (e) {
57
+ console.error(`native load script error: ${e}`);
58
+ // TODO
59
+ reportError(new InternalJSModuleEvalError(`module load failed ${e}`));
60
+ }
61
+ };
62
+ };
@@ -0,0 +1,44 @@
1
+ const splitSemver = (
2
+ version: string
3
+ ): {
4
+ major: string;
5
+ minor: string;
6
+ patch: string;
7
+ prerelease?: string;
8
+ build?: string;
9
+ } => {
10
+ const prerelease = version.split('-')[1] as string | undefined;
11
+ if (prerelease) {
12
+ version = version.replace(`-${prerelease}`, '');
13
+ }
14
+
15
+ const build = version.split('+')[1] as string | undefined;
16
+ if (build) {
17
+ version = version.replace(`+${build}`, '');
18
+ }
19
+
20
+ const splitted = version.split('.').slice(0, 3);
21
+ const [major, minor, patch] = [splitted[0] ?? '0', splitted[1] ?? '0', splitted[2] ?? '0'];
22
+ return { major, minor, patch, prerelease, build };
23
+ };
24
+
25
+ export const major = (version: string): number => parseInt(splitSemver(version).major, 10);
26
+
27
+ export const compare = (v1: string, v2: string): -1 | 0 | 1 => {
28
+ const { major: major1, minor: minor1, patch: patch1 } = splitSemver(v1);
29
+ const { major: major2, minor: minor2, patch: patch2 } = splitSemver(v2);
30
+
31
+ if (major1 !== major2) {
32
+ return major1 > major2 ? 1 : -1;
33
+ }
34
+
35
+ if (minor1 !== minor2) {
36
+ return minor1 > minor2 ? 1 : -1;
37
+ }
38
+
39
+ if (patch1 !== patch2) {
40
+ return patch1 > patch2 ? 1 : -1;
41
+ }
42
+
43
+ return 0;
44
+ };
@@ -0,0 +1,32 @@
1
+ import type {
2
+ IAdBreakParams,
3
+ IAdConfigParams,
4
+ IAdsInitParams,
5
+ IAdUnitParams,
6
+ JoliboxAds as IJoliboxAds
7
+ } from '@jolibox/types/dist/sdks/ads';
8
+ import { BaseSDK, BaseSDKEventMap } from './sdk';
9
+
10
+ type JoliboxAdsEventMap = BaseSDKEventMap
11
+
12
+ export class JoliboxAds extends BaseSDK<JoliboxAdsEventMap> implements IJoliboxAds {
13
+ constructor() {
14
+ super();
15
+ }
16
+
17
+ init = (config?: IAdsInitParams) => {
18
+ this.commands.executeCommand('AdsSDK.init', config);
19
+ };
20
+
21
+ adConfig = (params: IAdConfigParams) => {
22
+ this.commands.executeCommand('AdsSDK.adConfig', params);
23
+ };
24
+
25
+ adBreak = (params: IAdBreakParams) => {
26
+ this.commands.executeCommand('AdsSDK.adBreak', params);
27
+ };
28
+
29
+ adUnit = (params: IAdUnitParams) => {
30
+ this.commands.executeCommand('AdsSDK.adUnit', params);
31
+ };
32
+ }
@@ -0,0 +1,50 @@
1
+ import { BaseSDK } from './sdk';
2
+ import { Keyboard, ResponseType } from '@jolibox/types';
3
+
4
+ export class KeyboardSDK extends BaseSDK implements Keyboard {
5
+ /**
6
+ * 显示键盘
7
+ * @param params
8
+ * @returns
9
+ */
10
+ showKeyboard(params: { defaultValue?: string; maxLength?: number; multiple?: boolean }) {
11
+ const canUse = this.canUse('keyboard.showKeyboard');
12
+ if (!canUse) {
13
+ return {
14
+ code: 'FAILURE' as ResponseType,
15
+ message: `[Jolibox SDK] keyboard.showKeyboard is not supported in this platform`
16
+ };
17
+ }
18
+
19
+ this.commands.executeCommand('KeyboardSDK.showKeyboard', params);
20
+ }
21
+ /**
22
+ * 更新键盘
23
+ * @param value
24
+ * @returns
25
+ */
26
+ updateKeyboard(value: string) {
27
+ const canUse = this.canUse('keyboard.updateKeyboard');
28
+ if (!canUse) {
29
+ return {
30
+ code: 'FAILURE' as ResponseType,
31
+ message: `[Jolibox SDK] keyboard.updateKeyboard is not supported in this platform`
32
+ };
33
+ }
34
+ this.commands.executeCommand('KeyboardSDK.updateKeyboard', value);
35
+ }
36
+ /**
37
+ * 隐藏键盘
38
+ * @returns
39
+ */
40
+ hideKeyboard() {
41
+ const canUse = this.canUse('keyboard.hideKeyboard');
42
+ if (!canUse) {
43
+ return {
44
+ code: 'FAILURE' as ResponseType,
45
+ message: `[Jolibox SDK] keyboard.hideKeyboard is not supported in this platform`
46
+ };
47
+ }
48
+ this.commands.executeCommand('KeyboardSDK.hideKeyboard');
49
+ }
50
+ }
@@ -0,0 +1,32 @@
1
+ import { Env, Lifecycle } from '@jolibox/types';
2
+ import { BaseSDK, BaseSDKEventMap } from './sdk';
3
+
4
+ const LIFECYCLE_ON_READY = 'LifecycleSDK.onReady';
5
+ interface LifecycleSDKEventMap extends BaseSDKEventMap {
6
+ [LIFECYCLE_ON_READY]: Env['hostUserInfo'] | undefined;
7
+ }
8
+
9
+ export class LifecycleSDK extends BaseSDK<LifecycleSDKEventMap> implements Lifecycle {
10
+ constructor() {
11
+ super();
12
+ }
13
+
14
+ onReady(callback: (info?: Env['hostUserInfo']) => void) {
15
+ const wrappedOnReady = (info?: Env['hostUserInfo']) => {
16
+ callback.call(this, info);
17
+ this.triggerEvent(LIFECYCLE_ON_READY, info);
18
+ };
19
+ this.commands.executeCommand('LifecycleSDK.onReady', wrappedOnReady.bind(this));
20
+ }
21
+
22
+ exitGame(params: { onBeforeExit: () => void }) {
23
+ this.commands.executeCommand('LifecycleSDK.exitGame', params.onBeforeExit);
24
+ }
25
+
26
+ onGameHide(params: () => void) {
27
+ this.commands.executeCommand('LifecycleSDK.onGameHide', params.bind(this));
28
+ }
29
+ onGameShow(params: () => void) {
30
+ this.commands.executeCommand('LifecycleSDK.onGameShow', params.bind(this));
31
+ }
32
+ }
@@ -0,0 +1,3 @@
1
+ //eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
+ //@ts-ignore
3
+ export const RuntimeSDK = window.JoliboxRuntime;
@@ -0,0 +1,22 @@
1
+ import { canIUse } from '@/api';
2
+ import { createCommands, EventEmitter } from '@jolibox/common';
3
+ export interface BaseSDKEventMap {
4
+ _baseSDKMarker?: never;
5
+ }
6
+
7
+ export abstract class BaseSDK<T = BaseSDKEventMap> {
8
+ readonly commands = createCommands();
9
+ readonly _emitter = new EventEmitter();
10
+
11
+ addEventListener<K extends keyof T & string>(event: K, callback: (data: T[K]) => void) {
12
+ this._emitter.on(event, (...args) => callback(args[0] as T[K]));
13
+ }
14
+
15
+ triggerEvent<K extends keyof T & string>(event: K, params: T[K]) {
16
+ this._emitter.emit(event, params);
17
+ }
18
+
19
+ canUse(command: string) {
20
+ return canIUse(command);
21
+ }
22
+ }
@@ -0,0 +1,35 @@
1
+ import { BaseSDK } from './sdk';
2
+ import { StandardResponse, Storage } from '@jolibox/types';
3
+
4
+ export class StorageSDK extends BaseSDK implements Storage {
5
+ async getItem(key: string) {
6
+ const result = await this.commands.executeCommand('StorageSDK.getItem', key);
7
+ return result;
8
+ }
9
+
10
+ async setItem(key: string, value: number | string | boolean): Promise<StandardResponse<void>> {
11
+ if (key.length > 128) {
12
+ return {
13
+ code: 'PARAMETER_ERROR',
14
+ message: '[SDK] cloud storage setItem error: length of key should be less than 128'
15
+ };
16
+ }
17
+
18
+ const valueToStore = typeof value == 'string' ? value : String(value);
19
+ if (key.length + valueToStore.length > 1024) {
20
+ return {
21
+ code: 'PARAMETER_ERROR',
22
+ message: '[SDK] cloud storage setItem error: length of key and value should be less than 1024'
23
+ };
24
+ }
25
+ return await this.commands.executeCommand('StorageSDK.setItem', key, value);
26
+ }
27
+
28
+ async removeItem(key: string) {
29
+ return this.commands.executeCommand('StorageSDK.removeItem', key);
30
+ }
31
+
32
+ async clear() {
33
+ return this.commands.executeCommand('StorageSDK.clear');
34
+ }
35
+ }
@@ -0,0 +1,24 @@
1
+ import { canIUseConfig } from '@jolibox/common';
2
+
3
+ export function getCanIUseConfig(platform: 'h5' | 'native', key: string) {
4
+ return canIUseConfig.config[platform]?.[key];
5
+ }
6
+
7
+ export function get<T extends Record<string, any>, P extends string | string[], Default = undefined>(
8
+ obj: T,
9
+ path: P,
10
+ defaultValue?: Default
11
+ ): unknown {
12
+ const pathArray = Array.isArray(path) ? path : (path as string).replace(/\[(\d+)\]/g, '.$1').split('.');
13
+
14
+ let result: any = obj;
15
+ for (const key of pathArray) {
16
+ if (result && (typeof result === 'object' || Array.isArray(result))) {
17
+ result = result[key];
18
+ } else {
19
+ return defaultValue as any;
20
+ }
21
+ }
22
+
23
+ return result === undefined ? defaultValue : result;
24
+ }
@@ -0,0 +1,23 @@
1
+ import { createCommands } from '@jolibox/common';
2
+ import { TrackEvent, PerformanceType } from '@jolibox/types';
3
+
4
+ const commands = createCommands();
5
+
6
+ export const track = (event: TrackEvent, info: Record<string, unknown>) => {
7
+ commands.executeCommand('ReportSDK.traceSystem', {
8
+ event,
9
+ info
10
+ });
11
+ };
12
+
13
+ export const trackPerformance = (
14
+ event: PerformanceType,
15
+ duration: number,
16
+ extra?: Record<string, unknown>
17
+ ) => {
18
+ commands.executeCommand('ReportSDK.traceSystemTimeline', {
19
+ event,
20
+ duration,
21
+ extra
22
+ });
23
+ };