sdk: auto-init from license file, promise-based init waiting
- common/sdk: add awaitInitialization(), initializeFromLicense(), markInitialized() - license: await XuqmSDK init before checkLicense - update: await XuqmSDK init before checkAppUpdate Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
这个提交包含在:
父节点
c0c458817a
当前提交
ce9062a0f1
@ -1,6 +1,7 @@
|
|||||||
export { XuqmSDK } from './sdk'
|
export { XuqmSDK } from './sdk'
|
||||||
export type { XuqmInitOptions, XuqmConfig } from './config'
|
export type { XuqmInitOptions, XuqmConfig } from './config'
|
||||||
export { getConfig, isInitialized, setUserId, getUserId } from './config'
|
export { getConfig, isInitialized, setUserId, getUserId } from './config'
|
||||||
|
export { awaitInitialization } from './sdk'
|
||||||
export { apiRequest, configureHttp, _getToken, _saveToken, _clearToken } from './http'
|
export { apiRequest, configureHttp, _getToken, _saveToken, _clearToken } from './http'
|
||||||
export { DEFAULT_TENANT_PLATFORM_URL, DEFAULT_IM_WS_URL } from './constants'
|
export { DEFAULT_TENANT_PLATFORM_URL, DEFAULT_IM_WS_URL } from './constants'
|
||||||
export { getDeviceId, getDeviceInfo, detectPushVendor } from './device'
|
export { getDeviceId, getDeviceInfo, detectPushVendor } from './device'
|
||||||
|
|||||||
@ -2,6 +2,23 @@ import { initConfigFromRemote, isInitialized, type XuqmInitOptions, setUserId as
|
|||||||
import { DEFAULT_IM_WS_URL, DEFAULT_TENANT_PLATFORM_URL } from './constants'
|
import { DEFAULT_IM_WS_URL, DEFAULT_TENANT_PLATFORM_URL } from './constants'
|
||||||
import { configureHttp } from './http'
|
import { configureHttp } from './http'
|
||||||
|
|
||||||
|
let _initPromise: Promise<void> | null = null
|
||||||
|
let _initResolve: (() => void) | null = null
|
||||||
|
|
||||||
|
function ensureInitPromise(): Promise<void> {
|
||||||
|
if (!_initPromise) {
|
||||||
|
_initPromise = new Promise((resolve) => { _initResolve = resolve })
|
||||||
|
}
|
||||||
|
return _initPromise
|
||||||
|
}
|
||||||
|
|
||||||
|
function markInitialized(): void {
|
||||||
|
if (_initResolve) {
|
||||||
|
_initResolve()
|
||||||
|
_initResolve = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const XuqmSDK = {
|
export const XuqmSDK = {
|
||||||
/**
|
/**
|
||||||
* @param options.appKey - Your application key (from the tenant platform)
|
* @param options.appKey - Your application key (from the tenant platform)
|
||||||
@ -36,6 +53,7 @@ export const XuqmSDK = {
|
|||||||
})
|
})
|
||||||
if (options.debug) console.warn('[XuqmSDK] Config fetch failed, using fallback URLs', e)
|
if (options.debug) console.warn('[XuqmSDK] Config fetch failed, using fallback URLs', e)
|
||||||
}
|
}
|
||||||
|
markInitialized()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +71,31 @@ export const XuqmSDK = {
|
|||||||
baseUrl: DEFAULT_TENANT_PLATFORM_URL,
|
baseUrl: DEFAULT_TENANT_PLATFORM_URL,
|
||||||
debug: options.debug,
|
debug: options.debug,
|
||||||
})
|
})
|
||||||
|
markInitialized()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize from a decrypted license file object.
|
||||||
|
* Use @xuqm/rn-license's decryptLicenseFile() to decrypt the raw file content first.
|
||||||
|
*/
|
||||||
|
initializeFromLicense(file: { appKey: string; baseUrl?: string; serverUrl?: string }, options?: { debug?: boolean }): void {
|
||||||
|
if (isInitialized()) return
|
||||||
|
const serverUrl = file.serverUrl || file.baseUrl || DEFAULT_TENANT_PLATFORM_URL
|
||||||
|
initConfigFromRemote({ appKey: file.appKey, debug: options?.debug }, {
|
||||||
|
imWsUrl: DEFAULT_IM_WS_URL,
|
||||||
|
fileServiceUrl: serverUrl,
|
||||||
|
apiUrl: serverUrl,
|
||||||
|
})
|
||||||
|
configureHttp({ baseUrl: serverUrl, debug: options?.debug })
|
||||||
|
markInitialized()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for initialization to complete.
|
||||||
|
*/
|
||||||
|
async awaitInitialization(): Promise<void> {
|
||||||
|
if (isInitialized()) return
|
||||||
|
await ensureInitPromise()
|
||||||
},
|
},
|
||||||
|
|
||||||
setUserId(userId: string | null): void {
|
setUserId(userId: string | null): void {
|
||||||
@ -63,3 +106,8 @@ export const XuqmSDK = {
|
|||||||
return getCommonUserId()
|
return getCommonUserId()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function awaitInitialization(): Promise<void> {
|
||||||
|
if (isInitialized()) return
|
||||||
|
await ensureInitPromise()
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
import { getDeviceId as getCommonDeviceId, getDeviceInfo } from '@xuqm/rn-common'
|
import { getDeviceId as getCommonDeviceId, getDeviceInfo, awaitInitialization } from '@xuqm/rn-common'
|
||||||
import { decryptLicenseFile } from './crypto'
|
import { decryptLicenseFile } from './crypto'
|
||||||
import * as store from './store'
|
import * as store from './store'
|
||||||
import type { LicenseFile, LicenseResult, LicenseStatus, LicenseUserInfo, RegisterRequest, RegisterResponse, VerifyRequest, VerifyResponse } from './models'
|
import type { LicenseFile, LicenseResult, LicenseStatus, LicenseUserInfo, RegisterRequest, RegisterResponse, VerifyRequest, VerifyResponse } from './models'
|
||||||
@ -40,7 +40,10 @@ export async function initializeFromFile(encryptedContent: string): Promise<void
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function checkLicense(userInfo?: LicenseUserInfo): Promise<LicenseResult> {
|
export async function checkLicense(userInfo?: LicenseUserInfo): Promise<LicenseResult> {
|
||||||
if (!_config) return { type: 'error', message: 'LicenseSDK not initialized' }
|
if (!_config) {
|
||||||
|
await awaitInitialization()
|
||||||
|
if (!_config) return { type: 'error', message: 'LicenseSDK not initialized' }
|
||||||
|
}
|
||||||
const { appKey, baseUrl } = _config
|
const { appKey, baseUrl } = _config
|
||||||
|
|
||||||
// In-memory cache check
|
// In-memory cache check
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
|
|||||||
import { Linking, Platform } from 'react-native'
|
import { Linking, Platform } from 'react-native'
|
||||||
import { apiRequest, getConfig, getUserId } from '@xuqm/rn-common'
|
import { apiRequest, getConfig, getUserId } from '@xuqm/rn-common'
|
||||||
import { getAppVersionCode, getAppVersionName, _devSetAppVersion } from './NativeVersion'
|
import { getAppVersionCode, getAppVersionName, _devSetAppVersion } from './NativeVersion'
|
||||||
|
import { awaitInitialization } from '@xuqm/rn-common'
|
||||||
|
|
||||||
export interface PluginMeta {
|
export interface PluginMeta {
|
||||||
moduleId: string
|
moduleId: string
|
||||||
@ -84,6 +85,7 @@ export const UpdateSDK = {
|
|||||||
* App version is read automatically from native code (XuqmVersionModule).
|
* App version is read automatically from native code (XuqmVersionModule).
|
||||||
*/
|
*/
|
||||||
async checkAppUpdate(): Promise<AppUpdateInfo> {
|
async checkAppUpdate(): Promise<AppUpdateInfo> {
|
||||||
|
await awaitInitialization()
|
||||||
const config = getConfig()
|
const config = getConfig()
|
||||||
const currentVersionCode = getAppVersionCode()
|
const currentVersionCode = getAppVersionCode()
|
||||||
const userId = getUserId()?.trim()
|
const userId = getUserId()?.trim()
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户