{"_id":"@aquienpz/asset-compressor-native","_rev":"2-71b1bbe36387361376d59313db9a25b7","name":"@aquienpz/asset-compressor-native","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aquienpz/asset-compressor-native","version":"0.1.0","license":"UNLICENSED","_id":"@aquienpz/asset-compressor-native@0.1.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://github.com/espaciofuturoio/aquienpz/tree/main/packages/asset-compressor-native","dist":{"shasum":"83902932fc50e2c695f285bfcbd72bea235c1de6","tarball":"https://registry.npmjs.org/@aquienpz/asset-compressor-native/-/asset-compressor-native-0.1.0.tgz","fileCount":6,"integrity":"sha512-3JVXgwdzhBYHhEYFdxKFF87xDdgdFyZ9PdqSxiNfsmLC5bH6jAeYdgpkna7y6IVufdbc0yOB2z8EZHRbAnOnfA==","signatures":[{"sig":"MEYCIQDGSN6ayadyjubHE8kS0+XGz8HWUNRe7RhrUUjvk7fHHAIhAKWI4sjN4y7t0o8RvGPQ3HAG6vDaGiPQkF00Co+53hWH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16288},"type":"module","shasum":"83902932fc50e2c695f285bfcbd72bea235c1de6","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts"}},"private":false,"scripts":{"type-check":"tsc --noEmit"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_integrity":"sha512-3JVXgwdzhBYHhEYFdxKFF87xDdgdFyZ9PdqSxiNfsmLC5bH6jAeYdgpkna7y6IVufdbc0yOB2z8EZHRbAnOnfA==","repository":{"url":"https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/asset-compressor-native"},"_npmVersion":"10.8.3","description":"Native (iOS/Android) image compression for the @aquienpz upload pipeline. JS API mirrors @aquienpz/asset-compressor-web so call sites are identical across web and React Native.","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^6.0.3","react-native":"0.83.4","react-native-compressor":"^1.11.0"},"peerDependencies":{"react-native":"*","react-native-compressor":">=1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asset-compressor-native_0.1.0_1778982515406_0.47248004440586566","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aquienpz/asset-compressor-native","version":"0.2.0","description":"Native (iOS/Android) image compression for the @aquienpz upload pipeline. JS API mirrors @aquienpz/asset-compressor-web so call sites are identical across web and React Native.","private":false,"publishConfig":{"access":"public","provenance":true},"repository":{"type":"git","url":"https://github.com/espaciofuturoio/aquienpz.git","directory":"packages/asset-compressor-native"},"homepage":"https://github.com/espaciofuturoio/aquienpz/tree/main/packages/asset-compressor-native","license":"UNLICENSED","type":"module","sideEffects":false,"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"bun run build","type-check":"tsc --noEmit"},"peerDependencies":{"react-native":"*","react-native-compressor":">=1.10.0"},"devDependencies":{"react-native":"0.83.4","react-native-compressor":"^1.11.0","tsup":"^8.5.1","typescript":"^6.0.3"},"_id":"@aquienpz/asset-compressor-native@0.2.0","_integrity":"sha512-XTwXPTZc0s71Y+TZzPlELexEzWlUKk+FcShbs99Oa5D++W2V1xxh+Rv28unhY+Xw+ooHyWtVM4C35PCA3c9mZQ==","_nodeVersion":"24.3.0","_npmVersion":"10.8.3","shasum":"6de872d80ae079f88665077189a54fcd6eca438b","dist":{"integrity":"sha512-XTwXPTZc0s71Y+TZzPlELexEzWlUKk+FcShbs99Oa5D++W2V1xxh+Rv28unhY+Xw+ooHyWtVM4C35PCA3c9mZQ==","shasum":"6de872d80ae079f88665077189a54fcd6eca438b","tarball":"https://registry.npmjs.org/@aquienpz/asset-compressor-native/-/asset-compressor-native-0.2.0.tgz","fileCount":9,"unpackedSize":37150,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD0Z3O07gfQ/vNUysIdPwRfxTDRUUOa7Nj6nszmBiB4JQIgY0sbDOLOezvp/bdR4THv14/tNEbE6g0jH17QqJ4Imrk="}]},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"directories":{},"maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/asset-compressor-native_0.2.0_1779002068471_0.35322637793237077"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-17T01:48:35.292Z","modified":"2026-05-17T07:14:28.770Z","0.1.0":"2026-05-17T01:48:35.579Z","0.2.0":"2026-05-17T07:14:28.654Z"},"license":"UNLICENSED","homepage":"https://github.com/espaciofuturoio/aquienpz/tree/main/packages/asset-compressor-native","repository":{"type":"git","url":"https://github.com/espaciofuturoio/aquienpz.git","directory":"packages/asset-compressor-native"},"description":"Native (iOS/Android) image compression for the @aquienpz upload pipeline. JS API mirrors @aquienpz/asset-compressor-web so call sites are identical across web and React Native.","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"readme":"# @aquienpz/asset-compressor-native\n\nFast, native (iOS + Android) image compression for React Native apps that\nupload to the [aquienpz](https://aquienpz.com) asset platform. Pairs with\n`@aquienpz/asset-uploader-expo` and mirrors the API of\n`@aquienpz/asset-compressor-web` so call sites are identical across\nplatforms.\n\n## Why this exists\n\n`expo-image-manipulator` is the default option in Expo apps, but it\nruns the resize + re-encode through the JS bridge and ships an\nintermediate bitmap as a JS-heap allocation. On a 12MP iPhone HEIC, a\nsingle resize-to-2880px + JPEG q=0.85 takes ~2–4 seconds — long enough\nto make a 10-photo batch upload feel broken.\n\nThis package wraps [`react-native-compressor`](https://github.com/numandev1/react-native-compressor),\nwhich calls `libjpeg-turbo` (iOS) / `Bitmap.compress` (Android) on a\nbackground thread and **never moves pixel data across the bridge**. The\nsame operation runs in ~250–350ms — roughly **5–10× faster** than the\nExpo equivalent on identical hardware.\n\n## Install\n\n```sh\n# in your Expo / RN app\nnpm install @aquienpz/asset-compressor-native react-native-compressor\n# Expo: also run the config-plugin once\nnpx expo prebuild\n```\n\nAdd the plugin entry to `app.json`:\n\n```json\n{\n  \"expo\": {\n    \"plugins\": [\"react-native-compressor\"]\n  }\n}\n```\n\n## Usage\n\n```ts\nimport { compressImage, compressImages } from \"@aquienpz/asset-compressor-native\";\n\n// Single image\nconst result = await compressImage({\n  uri: pickerAsset.uri,\n  filename: pickerAsset.fileName ?? \"photo.jpg\",\n});\n// → { uri: 'file:///.../photo.jpg', size: 412903, originalSize: 4218876, compressionRatio: 0.097 }\n\n// Batch\nconst { successful, failed } = await compressImages(\n  pickerAssets.map((a, i) => ({ uri: a.uri, filename: a.fileName ?? `photo-${i}.jpg`, id: a.assetId })),\n  { quality: 0.85, maxWidth: 2880, concurrency: 1 },\n  (id, status, index) => console.log(`[${index}] ${id} → ${status}`),\n);\n```\n\n## Output format\n\nOutput is **always JPEG**. `react-native-compressor` natively supports\nonly `jpg` / `png`, and the asset-manager re-encodes every uploaded\nimage to WebP server-side anyway when generating size variants — so\nforcing WebP on device would cost binary size + native module\nmaintenance for zero net bandwidth win.\n\nThe on-device savings (HEIC/big-JPEG → 2880px JPEG q=0.85) are already\n~80–95% before the upload starts.\n\n## API parity with `@aquienpz/asset-compressor-web`\n\n| Web                                      | Native                                          |\n| ---------------------------------------- | ----------------------------------------------- |\n| input `Blob`                             | input `uri` (file://, content://, ph://)        |\n| output `Blob` (mime configurable)        | output file `uri` on disk (always JPEG)         |\n| `compressionStatus: convertingHeic`      | not emitted (HEIC decode is part of `compressing`) |\n| concurrency: `p-limit` / `navigator.hwc` | concurrency: bounded worker pool, default 1     |\n| HEIC fallback: `heic2any`                | HEIC handled natively by ImageIO / android-heif |\n\nEverything else (quality default 0.85, maxWidth/Height 2880, status\ncallback shape, error collection in `compressImages`) is identical.\n\n## Cleanup\n\n`react-native-compressor` writes outputs to the app's cache directory.\niOS will reclaim it under memory pressure; Android does the same when\nthe cache exceeds `cacheQuotaBytes`. If you upload + don't need the\nlocal copy, delete it yourself with `expo-file-system` or\n`react-native-fs` once the upload completes.\n","readmeFilename":"README.md"}