XuqmGroup-RNSDK/packages/common/src/config.ts

171 行
5.6 KiB
TypeScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

export interface XuqmInitOptions {
appKey: string
platformUrl?: string // 不传则使用内置默认公有平台地址
debug?: boolean
}
export interface XuqmConfig {
appKey: string
apiUrl: string
imWsUrl: string
fileServiceUrl: string
debug: boolean
// 服务开通状态(由平台远程配置决定)
imEnabled: boolean
pushEnabled: boolean
// 崩溃采集服务rn-bugcollect 使用)
bugCollectApiUrl: string
bugCollectEnabled: boolean
// 请求签名密钥(从配置文件读取)
signingKey?: string
}
export interface XuqmUserInfo {
userId: string
userSig?: string // IM 登录凭证;未开通 IM 时可不传
name?: string
email?: string
phone?: string
avatar?: string
}
export interface XuqmLoginOptions extends XuqmUserInfo {
/** 公共 HTTP 访问令牌;与 IM userSig 分开存储、分开使用。 */
accessToken?: string
}
export type XuqmUserInfoHandler = (info: XuqmUserInfo | null) => void | Promise<void>
export type XuqmInitializationHandler = (config: Readonly<XuqmConfig>) => void | Promise<void>
// ─── Internal state ────────────────────────────────────────────────────────────
let _config: XuqmConfig | null = null
let _userInfo: XuqmUserInfo | null = null
const _userInfoHandlers = new Map<string, XuqmUserInfoHandler>()
const _initializationHandlers = new Map<string, XuqmInitializationHandler>()
// ─── Config ────────────────────────────────────────────────────────────────────
export interface XuqmRemoteConfig {
imApiUrl?: string
apiUrl?: string
imWsUrl?: string
fileServiceUrl?: string
imEnabled?: boolean
pushEnabled?: boolean
bugCollectApiUrl?: string
bugCollectEnabled?: boolean
}
export function initConfigFromRemote(
options: XuqmInitOptions,
remote: XuqmRemoteConfig,
signingKey?: string,
): void {
const apiUrl = remote.apiUrl ?? remote.imApiUrl ?? ''
_config = {
appKey: options.appKey,
apiUrl,
imWsUrl: remote.imWsUrl ?? '',
fileServiceUrl: remote.fileServiceUrl ?? apiUrl,
debug: options.debug ?? false,
imEnabled: remote.imEnabled ?? !!remote.imWsUrl,
pushEnabled: remote.pushEnabled ?? true,
bugCollectApiUrl: remote.bugCollectApiUrl ?? '',
bugCollectEnabled: remote.bugCollectEnabled ?? false,
signingKey,
}
}
export function getConfig(): XuqmConfig {
if (!_config) throw new Error('[XuqmSDK] Not initialized — call XuqmSDK.initialize() first.')
return _config
}
/**
* Optional SDK context for common capabilities that also work standalone.
* Extension packages should use getConfig() so a missing initialization remains explicit.
*/
export function getOptionalConfig(): XuqmConfig | null {
return _config
}
export function isInitialized(): boolean {
return _config !== null
}
export function _registerInitializationHandler(
name: string,
handler: XuqmInitializationHandler,
): () => void {
if (_initializationHandlers.has(name)) {
throw new Error(`[XuqmSDK] Initialization handler "${name}" is already registered.`)
}
_initializationHandlers.set(name, handler)
const current = _config
if (current) {
Promise.resolve(handler(current)).catch(error => {
console.error(`[XuqmSDK] Late initialization handler failed: ${name}`, error)
})
}
return () => _initializationHandlers.delete(name)
}
export async function _notifyInitialized(): Promise<void> {
const config = getConfig()
const results = await Promise.allSettled(
Array.from(_initializationHandlers.entries(), ([name, handler]) =>
Promise.resolve(handler(config)).catch(error => {
const message = error instanceof Error ? error.message : String(error)
throw new Error(`${name}: ${message}`)
}),
),
)
for (const result of results) {
if (result.status === 'rejected') {
console.error('[XuqmSDK] Extension initialization failed:', result.reason)
}
}
}
// ─── UserId ────────────────────────────────────────────────────────────────────
export function getUserId(): string | null {
return _userInfo?.userId ?? null
}
// ─── UserInfo + subscribers ────────────────────────────────────────────────────
export function _registerUserInfoHandler(name: string, handler: XuqmUserInfoHandler): () => void {
if (_userInfoHandlers.has(name)) {
throw new Error(`[XuqmSDK] User session handler "${name}" is already registered.`)
}
_userInfoHandlers.set(name, handler)
return () => _userInfoHandlers.delete(name)
}
export async function _setUserInfo(info: XuqmUserInfo | null): Promise<void> {
_userInfo = info
const results = await Promise.allSettled(
Array.from(_userInfoHandlers.entries(), async ([name, handler]) => {
try {
await handler(info)
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
throw new Error(`${name}: ${message}`)
}
}),
)
const failures = results
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
.map(result => String(result.reason))
if (failures.length > 0) {
throw new Error(`[XuqmSDK] Session propagation failed: ${failures.join('; ')}`)
}
}
export function getUserInfo(): XuqmUserInfo | null {
return _userInfo
}