{"_id":"@athex/react-native-bg-upload","name":"@athex/react-native-bg-upload","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.1":{"name":"@athex/react-native-bg-upload","version":"1.0.1","description":"Background uploader for react native applications","main":"./lib/commonjs/index.js","types":"./lib/typescript/src/index.d.ts","exports":{".":{"source":"./src/index.tsx","types":"./lib/typescript/src/index.d.ts","import":"./lib/module/index.js","require":"./lib/commonjs/index.js"},"./package.json":"./package.json"},"scripts":{"example":"yarn workspace react-native-bg-upload-example","clean":"del-cli android/build example/android/build example/android/app/build example/ios/build lib","prepare":"bob build","typecheck":"tsc","lint":"eslint \"**/*.{js,ts,tsx}\"","test":"jest","release":"release-it","release:patch":"npm version patch && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:major":"npm version major && git push --follow-tags"},"keywords":["react-native","background","upload","file","chunk","resume","workmanager","urlsession"],"repository":{"type":"git","url":"git+https://github.com/athex/react-native-bg-upload.git"},"author":{"name":"Your Name"},"license":"MIT","bugs":{"url":"https://github.com/athex/react-native-bg-upload/issues"},"homepage":"https://github.com/athex/react-native-bg-upload#readme","app":["plugin/build"],"publishConfig":{"registry":"https://registry.npmjs.org/"},"devDependencies":{"@commitlint/cli":"^19.0.0","@commitlint/config-conventional":"^19.0.0","@eslint/compat":"^1.3.2","@eslint/eslintrc":"^3.3.1","@eslint/js":"^9.35.0","@react-native-community/cli":"20.0.1","@react-native-community/netinfo":"^11.4.1","@react-native/babel-preset":"0.81.1","@react-native/eslint-config":"^0.81.1","@release-it/conventional-changelog":"^10.0.1","@types/jest":"^29.5.14","@types/react":"^19.1.0","commitlint":"^19.8.1","del-cli":"^6.0.0","eslint":"^9.35.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","jest":"^29.7.0","lefthook":"^2.0.3","prettier":"^2.8.8","react":"19.1.0","react-native":"0.81.1","react-native-builder-bob":"^0.40.16","react-native-mmkv":"^3.0.2","release-it":"^19.0.4","turbo":"^2.5.6","typescript":"^5.9.2"},"peerDependencies":{"@react-native-community/netinfo":">=9.0.0","react":"*","react-native":"*","react-native-mmkv":">=2.0.0"},"workspaces":["example"],"packageManager":"yarn@4.11.0","react-native-builder-bob":{"source":"src","output":"lib","targets":["commonjs","module"]},"codegenConfig":{"name":"BgUploadSpec","type":"modules","jsSrcsDir":"src","android":{"javaPackageName":"com.athex.bgupload"}},"prettier":{"quoteProps":"consistent","singleQuote":true,"tabWidth":2,"trailingComma":"es5","useTabs":false},"commitlint":{"extends":["@commitlint/config-conventional"]},"release-it":{"git":{"commitMessage":"chore: release ${version}","tagName":"v${version}"},"npm":{"publish":true},"github":{"release":true},"plugins":{"@release-it/conventional-changelog":{"preset":{"name":"angular"}}}},"jest":{"preset":"react-native","modulePathIgnorePatterns":["<rootDir>/example/node_modules","<rootDir>/lib/"]},"create-react-native-library":{"languages":"kotlin-objc","type":"turbo-module","tools":["eslint","lefthook","release-it","jest"],"version":"0.55.1"},"eslintIgnore":["node_modules/","lib/"],"_id":"@athex/react-native-bg-upload@1.0.1","gitHead":"482beb9f96e1b09949db3e8a17c08d0e5b55dfd1","_nodeVersion":"24.10.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-ICF9CaZ+Qyhgl8AjWXkKqDB6dprjaaeXPvowDqmo6DpUq/4BrgVBq8AUSRsL+qHpXm4ox87T1nhqZYDuS5mdSw==","shasum":"629541a6a2a651202626657b29f336f3bc0e4075","tarball":"https://registry.npmjs.org/@athex/react-native-bg-upload/-/react-native-bg-upload-1.0.1.tgz","fileCount":182,"unpackedSize":427685,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIErn9UgvKzP1moEWdbDXYatnAeWNLHQinGP7yZeKTl/2AiEA9k/odoTYgPIVSrrvcPG9yfddUvVaEjSwgp5AGD18GRc="}]},"_npmUser":{"name":"athex","email":"athexweb3@gmail.com"},"directories":{},"maintainers":[{"name":"athex","email":"athexweb3@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-native-bg-upload_1.0.1_1764219191739_0.4753232331055288"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-27T04:53:11.644Z","1.0.1":"2025-11-27T04:53:11.923Z","modified":"2025-11-27T04:53:12.233Z"},"maintainers":[{"name":"athex","email":"athexweb3@gmail.com"}],"description":"Background uploader for react native applications","homepage":"https://github.com/athex/react-native-bg-upload#readme","keywords":["react-native","background","upload","file","chunk","resume","workmanager","urlsession"],"repository":{"type":"git","url":"git+https://github.com/athex/react-native-bg-upload.git"},"author":{"name":"Your Name"},"bugs":{"url":"https://github.com/athex/react-native-bg-upload/issues"},"license":"MIT","readme":"<p align=\"center\">\n  <h1 align=\"center\">React Native Background Upload SDK</h1>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-native-bg-upload\">\n    <img src=\"https://img.shields.io/npm/v/react-native-bg-upload?style=flat-square&color=4630EB\" />\n  </a>\n  <a href=\"LICENSE\">\n    <img src=\"https://img.shields.io/github/license/athexweb3/react-native-bg-upload?style=flat-square&color=4630EB\" />\n  </a>\n</p>\n\n<p align=\"center\">\n  <b>Production-grade SDK for reliable background file uploads on React Native. Survives app kills, network drops, and device reboots.</b>\n</p>\n\n## ✨ Features\n\n- **🔄 Resumable**: Survives app kills, low memory, and device reboots\n- **📦 Chunking**: Automatic chunking for large files with resume capability\n- **🔁 Retry Logic**: Exponential backoff with jitter for transient failures\n- **📡 Network Aware**: Auto pause/resume on connectivity changes\n- **🔐 Secure**: Credential refresh hooks, no long-term token storage\n- **📱 Native Notifications**: Foreground service with progress (Android)\n- **💾 Persistent Queue**: MMKV-based storage for instant recovery\n- **🎣 React Hooks**: `useUpload()` for seamless integration\n- **📊 Observable**: Progress, completion, error events\n- **🧪 Battle Tested**: Comprehensive test suite included\n\n## 📱 Platform Support\n\n| Feature | Android (API 21+) | iOS (11+) |\n| :--- | :---: | :---: |\n| Background Uploads | ✅ WorkManager | ✅ URLSession |\n| App Kill Survival | ✅ | ✅ |\n| Device Reboot | ✅ | ✅ |\n| Chunking & Resume | ✅ | ✅ |\n| Retry & Backoff | ✅ | ✅ |\n| Progress Notification | ✅ | N/A |\n| Network Monitoring | ✅ | ✅ |\n\n## 📦 Installation\n\n```bash\nnpm install react-native-bg-upload react-native-mmkv @react-native-community/netinfo\n# or\nyarn add react-native-bg-upload react-native-mmkv @react-native-community/netinfo\n```\n\n**iOS**: `cd ios && pod install`\n\n## 🚀 Quick Start\n\n```typescript\nimport { BgUpload } from 'react-native-bg-upload';\n\n// Start an upload\nconst taskId = await BgUpload.start({\n  id: 'video-upload-1',\n  url: 'https://api.example.com/upload',\n  path: 'file:///path/to/large-video.mp4',\n  headers: {\n    'Authorization': 'Bearer YOUR_TOKEN'\n  },\n  chunking: {\n    enabled: true, // Auto-enabled for files > 5MB\n    chunkSize: 5 * 1024 * 1024 // 5MB chunks\n  },\n  retryPolicy: {\n    maxAttempts: 5,\n    baseDelay: 1000,\n    maxDelay: 30000\n  },\n  // Android only\n  notification: {\n    enabled: true,\n    title: 'Uploading Video'\n  }\n});\n```\n\n## 🎣 Using Hooks\n\n```typescript\nimport { useUpload } from 'react-native-bg-upload';\n\nfunction UploadScreen({ taskId }) {\n  const task = useUpload(taskId);\n\n  if (!task) return null;\n\n  return (\n    <View>\n      <Text>State: {task.state}</Text>\n      <Text>Progress: {task.progress}%</Text>\n      <ProgressBar progress={task.progress / 100} />\n      \n      {task.state === 'UPLOADING' && (\n        <Button title=\"Pause\" onPress={() => BgUpload.pause(taskId)} />\n      )}\n      \n      {task.error && <Text style={{color: 'red'}}>{task.error}</Text>}\n    </View>\n  );\n}\n```\n\n## 📖 API Reference\n\n### `BgUpload.start(options): Promise<string>`\n\nStart a background upload. Returns the task ID.\n\n#### Options\n\n| Option | Type | Required | Description |\n| :--- | :--- | :---: | :--- |\n| `id` | `string` | ✅ | Unique task identifier |\n| `url` | `string` | ✅ | Upload destination URL |\n| `path` | `string` | ✅ | Absolute file path (file://) |\n| `method` | `string` | | HTTP method (default: POST) |\n| `headers` | `object` | | HTTP headers |\n| `networkType` | `string` | | 'ANY', 'WIFI_ONLY', 'UNMETERED' |\n| `chunking` | `object` | | Chunking configuration |\n| `retryPolicy` | `object` | | Retry configuration |\n| `onCredentialRefresh` | `function` | | Token refresh callback |\n| `notification` | `object` | | Android notification config |\n\n#### Chunking Options\n\n```typescript\n{\n  enabled?: boolean;       // Enable chunking (default: true for > 5MB)\n  chunkSize?: number;      // Chunk size in bytes (default: 5MB)\n  maxConcurrent?: number;  // Max concurrent chunks (default: 3)\n}\n```\n\n#### Retry Policy\n\n```typescript\n{\n  maxAttempts?: number;   // Max retry attempts (default: 5)\n  baseDelay?: number;     // Base delay in ms (default: 1000)\n  maxDelay?: number;      // Max delay in ms (default: 30000)\n  jitter?: number;        // Random jitter in ms (default: 500)\n}\n```\n\n### Other Methods\n\n- `BgUpload.cancel(taskId)`: Cancel upload\n- `BgUpload.pause(taskId)`: Pause upload  \n- `BgUpload.resume(taskId)`: Resume upload\n- `BgUpload.getPending()`: Get all pending uploads\n- `BgUpload.addListener(event, callback)`: Add event listener\n\n## 🔐 Security\n\n### Credential Refresh\n\n```typescript\nBgUpload.start({\n  id: 'secure-upload',\n  url: 'https://api.example.com/upload',\n  path: filePath,\n  onCredentialRefresh: async () => {\n    // Refresh your auth token\n    const newToken = await refreshAuthToken();\n    return {\n      'Authorization': `Bearer ${newToken}`\n    };\n  }\n});\n```\n\n### Best Practices\n\n- ✅ Use short-lived signed URLs (S3, Azure)\n- ✅ Implement `onCredentialRefresh` for token rotation\n- ✅ Don't store tokens in upload options (use refresh hook)\n- ✅ Use HTTPS only\n- ❌ Don't hardcode credentials\n\n## 🧪 Testing\n\n### Running Tests\n\n```bash\nyarn test                    # Unit tests\nyarn test:integration       # Integration tests (requires mock server)\n```\n\n### Example Test Scenarios\n\n- Large file (1GB+) with chunking\n- App kill during upload → resume\n- Network offline/online toggle\n- Retry on server 500 errors\n- Notification cancel action (Android)\n\nSee [IMPLEMENTATION_NOTES.md](./IMPLEMENTATION_NOTES.md) for server-side contract.\n\n## 📝 Implementation Notes\n\n### Android\n\n- Uses `WorkManager` for reliable background execution\n- Foreground Service with notification during active uploads\n- Persists task state to survive process death\n- Chunks stored with offset tracking for resume\n\n### iOS\n\n- Uses `URL Session` background configuration\n- OS handles upload continuation when app is killed\n- Delegate callbacks for progress/completion\n- Task state synced via `UserDefaults`\n\n### Storage\n\n- **Queue**: MMKV for instant read/write\n- **Tasks**: Serialized JSON with chunk metadata\n- **Credentials**: Never persisted (use refresh hook)\n\n## 🤝 Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md)\n\n## 📄 License\n\nMIT © 2025\n\n## 🔗 Links\n\n- [API Documentation](./docs)\n- [Implementation Notes](./IMPLEMENTATION_NOTES.md)\n- [Security Guide](./SECURITY.md)\n- [Changelog](./CHANGELOG.md)\n","readmeFilename":"README.md","_rev":"1-c0a9ff506905644a193a59e2dc2fd8d9"}