# XuqmGroup React Native SDK Modular React Native SDK providing IM, Push, App/Plugin Update, WebView, and License management for XuqmGroup platform applications. ## Table of Contents - [Overview](#overview) - [Package Structure](#package-structure) - [Installation](#installation) - [Quick Start](#quick-start) - [Package Details](#package-details) - [Development](#development) - [Plugin Scaffolding](#plugin-scaffolding) --- ## Overview `@xuqm/rn-sdk` is the meta-package that re-exports all sub-modules. It provides a unified `XuqmSDK` entry point with coordinated login/logout that wires up IM, Push, and token management in a single call. You can install the meta-package for full functionality, or pick individual packages as needed. **Peer Dependencies** (required in host app): | Package | Version | |---------|---------| | `react` | >= 18.0.0 | | `react-native` | >= 0.76.0 | | `@react-native-async-storage/async-storage` | >= 1.21.0 | --- ## Package Structure ``` XuqmGroup-RNSDK/ # @xuqm/rn-sdk (meta-package, private) ├── src/ │ ├── index.ts # Re-exports all sub-packages │ └── sdk.ts # Unified login / logout ├── packages/ │ ├── common/ @xuqm/rn-common # Init, network, device, token, HTTP, auto-init │ ├── im/ @xuqm/rn-im # IM messaging (WebSocket/STOMP + WatermelonDB) │ ├── push/ @xuqm/rn-push # Multi-vendor push registration │ ├── update/ @xuqm/rn-update # App update check + RN plugin hot-update │ └── xwebview/ @xuqm/rn-xwebview # Enhanced WebView with JSBridge ``` All packages are at version **0.2.2**. --- ## Installation ### 1. Configure the npm registry ```bash # In your host project root cat > .npmrc << 'EOF' registry=https://nexus.xuqinmin.com/repository/npm/ legacy-peer-deps=true EOF ``` ### 2. Install **Option A -- Meta-package (all modules):** ```bash yarn add @xuqm/rn-sdk yarn add @react-native-async-storage/async-storage ``` **Option B -- Individual packages:** ```bash yarn add @xuqm/rn-common @xuqm/rn-update @xuqm/rn-xwebview yarn add @react-native-async-storage/async-storage ``` ### 3. Install optional peer dependencies ```bash # IM module (if using @xuqm/rn-im) yarn add @nozbe/watermelondb # XWebView module yarn add react-native-webview react-native-blob-util react-native-svg # Config file decryption (auto-init) yarn add react-native-quick-crypto ``` --- ## Quick Start ### Zero-config initialization (recommended) Place an encrypted `.xuqmconfig` file (XUQM-CONFIG-V1 format) in your project, then add a Metro alias so the SDK can auto-discover it: ```js // metro.config.js const { getDefaultConfig } = require('metro-config'); module.exports = (async () => { const config = await getDefaultConfig(__dirname); config.resolver.extraNodeModules = { '@xuqm/autoinit-config': './path/to/your.xuqmconfig', }; return config; })(); ``` That is it. When `@xuqm/rn-common` is imported, it silently calls `XuqmSDK.initWithConfigFile()` using the encrypted file. No explicit init code needed. ### Manual initialization ```ts import { XuqmSDK } from '@xuqm/rn-sdk'; // Init with appKey (fetches config from server) await XuqmSDK.initialize({ appKey: 'your-app-key' }); // Login (wires up IM + Push automatically) await XuqmSDK.login({ userId: 'user123', userSig: '...' }); // Logout await XuqmSDK.logout(); ``` ### Using individual modules ```ts import { ImSDK } from '@xuqm/rn-im'; import { PushSDK } from '@xuqm/rn-push'; import { UpdateSDK } from '@xuqm/rn-update'; import { XWebViewScreen } from '@xuqm/rn-xwebview'; ``` --- ## Package Details ### @xuqm/rn-common Core module. Handles SDK initialization, HTTP requests, token persistence, device identification, and auto-initialization from encrypted config files. | Export | Description | |--------|-------------| | `XuqmSDK.initialize(opts)` | Init with `appKey`, fetches remote config | | `XuqmSDK.initWithConfigFile(encrypted)` | Init from `XUQM-CONFIG-V1` encrypted file | | `XuqmSDK.initializeFromLicense(file)` | Init from decrypted config data | | `XuqmSDK.awaitInitialization()` | Wait for async init to complete | | `XuqmSDK.setUserId / getUserId` | Manage current user ID | | `XuqmSDK.setUserInfo / getUserInfo` | Manage current user profile | | `apiRequest(url, options?)` | HTTP request with Bearer token auth | | `configureHttp(opts)` | Override HTTP base URL or headers | | `getDeviceId()` | Stable per-install UUID | | `getDeviceInfo()` | Device brand/model/OS info | | `detectPushVendor()` | Detect push vendor from device brand | | `ScaledImage` | Image component with aspect-ratio scaling | | `isInitialized()` | Check if SDK is ready | | `getConfig()` | Get resolved config | **Auto-init mechanism:** On import, `autoInit.ts` tries `require('@xuqm/autoinit-config')`. If the Metro alias is configured, it decrypts the file and calls `initWithConfigFile` silently. If the alias is not configured, it skips without error. **Encrypted config format:** `XUQM-CONFIG-V1.{base64url-salt}.{base64url-iv}.{base64url-ciphertext}` -- decrypted via PBKDF2 (120k iterations, SHA-256) + AES-256-GCM using `react-native-quick-crypto`. --- ### @xuqm/rn-im Full-featured IM module. WebSocket/STOMP transport with WatermelonDB local persistence. Supports single and group chat with 15 message types. **Message types:** `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `FILE`, `CUSTOM`, `LOCATION`, `NOTIFY`, `RICH_TEXT`, `CALL_AUDIO`, `CALL_VIDEO`, `QUOTE`, `MERGE`, `REVOKED`, `FORWARD` | Export | Description | |--------|-------------| | `ImSDK.login(userId, userSig)` | Connect to IM server | | `ImSDK.disconnect()` | Disconnect | | `ImSDK.sendMessage(params)` | Send a message | | `ImSDK.getConversations()` | List conversations | | `ImSDK.getHistory(query)` | Fetch message history | | `ImSDK.createGroup(...)` | Create a group | | `ImSDK.joinGroup(groupId)` | Join a group | | `ImSDK.getGroupInfo(groupId)` | Get group details | | `ImSDK.getGroupMembers(groupId)` | List group members | | `listFriends / addFriend / removeFriend` | Friend management | | `setFriendGroup / listFriendGroups` | Friend grouping | | `checkBlacklist` | Blacklist check | | `searchUsers / searchGroups / searchMessages` | Search | | `editMessage` | Edit a sent message | | `setConversationHidden / setConversationGroup` | Conversation management | | `locateHistoryPage / locateGroupHistoryPage` | Jump to specific history page | | `syncOfflineMessages / offlineMessageCount` | Offline message handling | | `ImClient` | Low-level STOMP client | | `ImDatabase` | WatermelonDB wrapper | | `uploadFile` | File upload for IM | **Additional peer dependency:** `@nozbe/watermelondb >= 0.27.0` --- ### @xuqm/rn-push Multi-vendor push registration. Automatically detects the device vendor (Huawei, Xiaomi, OPPO, vivo, Honor, FCM, APNS) and bridges to the native push module. | Export | Description | |--------|-------------| | `PushSDK.initialize(userId?)` | Initialize push and register device token | | `PushSDK.registerToken(userId, token, vendor?)` | Register a push token with server | | `PushSDK.unregisterToken(userId)` | Unregister push token | | `PushSDK.setDeviceToken(token, vendor?)` | Manually set device token | | `PushSDK.onPushToken(callback)` | Listen for push token updates | | `PushSDK.logout(userId?)` | Unregister and clean up | | `isNativePushAvailable()` | Check if native push module is linked | | `detectVendorNative()` | Detect vendor via native module | | `registerPushNative()` | Trigger native vendor registration | **Native module:** Requires `NativeModules.XuqmPushModule` to be linked in the host app. --- ### @xuqm/rn-update App update check and RN plugin (bundle) hot-update. Checks for new app versions and downloads/caches RN bundles for OTA delivery. | Export | Description | |--------|-------------| | `UpdateSDK.registerPlugin(meta)` | Register plugin metadata at bundle load time | | `UpdateSDK.checkAppUpdate(bypassIgnore?)` | Check for app-level update | | `UpdateSDK.openStore(url?, marketUrl?)` | Open app store page | | `UpdateSDK.checkPluginUpdate(moduleId)` | Check if a plugin bundle has an update | | `UpdateSDK.downloadPluginBundle(url)` | Download bundle source text | | `UpdateSDK.cachePluginBundle(id, ver, md5, src)` | Cache bundle to AsyncStorage | | `UpdateSDK.getCachedPluginBundle(id)` | Read cached bundle | | `UpdateSDK.checkAndCachePlugin(id)` | One-step check + download + cache | | `UpdateSDK.getRegisteredPlugins()` | List all registered plugins | | `UpdateSDK.getAppVersionCode / getAppVersionName` | Get host app version | **Types:** `PluginMeta`, `AppUpdateInfo`, `PluginUpdateInfo`, `CachedRnBundle` --- ### @xuqm/rn-xwebview Enhanced WebView with JSBridge for bidirectional communication between RN and web content. Includes progress bar, inline view, and full-screen screen components. | Export | Description | |--------|-------------| | `XWebViewScreen` | Full-screen WebView (React Navigation screen) | | `XWebViewView` | Inline WebView component | | `XWebViewProgress` | Progress bar component | | `openXWebView(url, options?)` | Open WebView programmatically | | `setXWebViewController(controller)` | Set global WebView controller | | `getXWebViewConfig()` | Get current WebView config | **Additional dependencies:** `react-native-webview`, `react-native-blob-util`, `react-native-svg` **Additional peer dependency:** `@react-navigation/native >= 7.0.0` --- ## Development ### Prerequisites - Node.js >= 18 - Yarn (workspaces) - React Native development environment ### Commands ```bash # Type-check all packages yarn typecheck # Type-check a single package cd packages/im && yarn typecheck ``` ### Publishing Packages are published to the private npm registry at `https://nexus.xuqinmin.com/repository/npm-hosted/`. ```bash # Publish a single package cd packages/common npm publish # Publish all packages (from each package directory) for pkg in common im push update xwebview; do cd packages/$pkg && npm publish && cd ../.. done ``` ### Project layout ``` packages// ├── src/ │ └── index.ts # Public API ├── package.json ├── tsconfig.json └── README.md ``` Each package has its own `package.json`, `tsconfig.json`, and `publishConfig` pointing to the hosted registry. The root `package.json` is a private meta-package that depends on all sub-packages. --- ## Plugin Scaffolding The `create-plugin.mjs` script generates a new UpdateSDK plugin skeleton and auto-registers it into the host project. ### Usage ```bash # Interactive mode node packages/update/scripts/create-plugin.mjs # CLI mode node packages/update/scripts/create-plugin.mjs [title] [subtitle] [accentColor] ``` ### What it generates - `bundle.ts` -- Plugin entry point - `{PascalCase}Screen.tsx` -- Screen component - `plugin.json` -- Plugin metadata ### What it auto-registers - `pluginCatalog.ts` -- Adds plugin to catalog - `debugPlugins.ts` -- Adds to debug plugin list - `package.json` -- Adds build script for the new bundle - `metro.split.config.js` -- Adds bundle entry - `babel.config.js` -- Adds module alias - `tsconfig.json` -- Adds path mapping **Module ID rules:** Lowercase alphanumeric, must be unique across all plugins.