Files
masi 89986d5d17 iOS build for sideloading, with the open-lab plugin repository preconfigured
- Background tasks: a JS implementation of the native task module for iOS
  (NativeBackgroundTasksModule.ios.ts) with the Android module's contract:
  per-queue order, 3 concurrent chapter downloads, retries with a delay,
  pause/resume/cancel interruptions, persistence across launches. Tasks run
  while the app is open; periodic library updates and backups are not
  scheduled on iOS. The module is Android-only in autolinking now.
- Reader assets: WKWebView will not load file:// assets into a page whose base
  URL is the source's site, so on iOS the reader CSS, JS and font are inlined
  (scripts/embed-reader-assets.mjs, src/utils/readerAssets). Downloaded
  chapters get a file: base URL and file access on iOS. Android is unchanged.
- Native iOS: downloadFile implemented with URLSession (plugin installs and
  chapter images); volume-button setActive added as a no-op (it is called on
  every chapter).
- Share receiver stub and silent toasts on iOS; TrackSheet uses showToast.
- app.json: bundle id br.dev.marcospaulo.lnreader, http sources allowed, Files
  sharing, deployment target 16.4.
- Fresh installs start with the open-lab plugin repository.
- scripts/build-ios-unsigned.sh and docs/ios-sidestore.md.

Verified on Linux: tsc, eslint, all Jest suites (plus new iOS queue tests),
expo prebuild for iOS, autolinking, and iOS/Android release JS bundles.
Not yet built with Xcode or run on a device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:12:31 -03:00

178 lines
7.0 KiB
JSON

{
"name": "lnreader",
"version": "2.1.4",
"private": true,
"scripts": {
"dev:android:release": "pnpm run generate:env:release && npx expo run:android --variant release",
"dev:android": "pnpm run generate:env:debug && npx expo run:android --app-id com.rajarsheechatterjee.LNReader.debug",
"dev:ios": "npx expo run:ios",
"dev:start": "npx expo start",
"dev:clean-start": "npx expo start --clear",
"build:release:android": "pnpm run generate:env:release && pnpm exec expo prebuild --platform android --clean --no-install && mkdir -p android/app/build/intermediates/sourcemaps/react/release && cd android && NODE_ENV=production ./gradlew :app:assembleRelease --build-cache --parallel -PreleaseAbiSplits=true",
"build:open-apk": "open ./android/app/build/outputs/apk/release/",
"generate:env:debug": "node scripts/generate-env-file.cjs --build-type Debug",
"generate:env:release": "node scripts/generate-env-file.cjs --build-type Release",
"release:package": "node scripts/package-release-artifacts.cjs",
"release:prepare": "node scripts/prepare-release.cjs",
"generate:string-types": "node scripts/generate-string-types.cjs",
"generate:db-migration": "drizzle-kit generate",
"upgrade:migration-format": "drizzle-kit up",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:queries": "jest --testPathPattern=queries",
"test:db": "jest --selectProjects db",
"test:rn": "jest --selectProjects rn",
"lint": "eslint ./src --ext .js,.jsx,.ts,.tsx",
"lint:fix": "pnpm run lint --fix",
"format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx}\" ./scripts",
"format:check": "prettier --check \"./src/**/*.{js,jsx,ts,tsx}\" ./scripts",
"type-check": "tsc --noEmit",
"clean:generated": "rm -rf .expo .rock android/build android/app/build android/app/.cxx modules/*/android/build modules/*/android/.cxx modules/*/lib src/generated tsconfig.tsbuildinfo modules/*/tsconfig.tsbuildinfo",
"clean:full": "pnpm run clean:generated && rm -rf node_modules && pnpm install && cd android && ./gradlew clean && cd .. && npx expo start --clear",
"check": "pnpm run format:check && pnpm run lint && pnpm run type-check",
"prepare": "husky install",
"nix:shell": "nix develop --extra-experimental-features nix-command --extra-experimental-features flakes",
"nix:emulator": "nix develop .#emulator --extra-experimental-features nix-command --extra-experimental-features flakes",
"postinstall": "node scripts/embed-reader-assets.mjs"
},
"dependencies": {
"@gorhom/bottom-sheet": "^5.2.14",
"@legendapp/list": "^3.3.3",
"@noble/ciphers": "^2.2.0",
"@op-engineering/op-sqlite": "^15.2.14",
"@pchmn/expo-material3-theme": "^1.4.0",
"@preeternal/react-native-cookie-manager": "^6.3.3",
"@react-native-google-signin/google-signin": "^16.1.2",
"@react-native-vector-icons/common": "^13.0.1",
"@react-native-vector-icons/material-design-icons": "^13.1.2",
"@react-navigation/bottom-tabs": "^7.18.11",
"@react-navigation/native": "^7.3.11",
"@react-navigation/native-stack": "^7.18.3",
"@rozenite/react-navigation-plugin": "^2.0.0",
"cheerio": "1.0.0-rc.12",
"color": "^5.0.3",
"dayjs": "^1.11.21",
"drizzle-orm": "1.0.0-beta.22",
"expo": "^57.0.7",
"expo-build-properties": "~57.0.6",
"expo-clipboard": "~57.0.1",
"expo-dev-client": "^57.0.7",
"expo-document-picker": "~57.0.1",
"expo-file-system": "~57.0.1",
"expo-haptics": "~57.0.1",
"expo-image": "~57.0.1",
"expo-keep-awake": "~57.0.1",
"expo-linear-gradient": "~57.0.1",
"expo-linking": "~57.0.3",
"expo-localization": "~57.0.1",
"expo-navigation-bar": "~57.0.2",
"expo-speech": "~57.0.1",
"expo-splash-screen": "^57.0.4",
"expo-web-browser": "~57.0.1",
"htmlparser2": "^12.0.0",
"i18n-js": "^4.5.3",
"lodash-es": "^4.18.1",
"prettier": "2.8.8",
"protobufjs": "^8.7.1",
"react": "19.2.3",
"react-native": "^0.86.0",
"react-native-device-info": "^15.0.2",
"react-native-draggable-flatlist": "^4.0.3",
"react-native-drawer-layout": "^4.2.8",
"react-native-edge-to-edge": "^1.8.1",
"react-native-error-boundary": "^3.1.0",
"react-native-gesture-handler": "^2.32.0",
"react-native-keyboard-controller": "^1.22.2",
"react-native-mmkv": "^4.3.2",
"react-native-pager-view": "^8.0.2",
"react-native-paper": "^5.15.3",
"react-native-reanimated": "^4.5.0",
"react-native-safe-area-context": "^5.7.0",
"react-native-screens": "^4.25.2",
"react-native-shimmer-placeholder": "^2.0.9",
"react-native-svg": "15.15.4",
"react-native-tab-view": "^4.3.2",
"react-native-url-polyfill": "^3.0.0",
"react-native-webview": "^13.16.1",
"react-native-worklets": "^0.10.0",
"react-syntax-highlighter": "^16.1.1",
"sanitize-html": "^2.17.6",
"urlencode": "^2.0.0",
"zustand": "^5.0.14"
},
"devDependencies": {
"@babel/core": "^7.29.7",
"@babel/plugin-transform-export-namespace-from": "^7.29.7",
"@babel/preset-env": "^7.29.7",
"@babel/runtime": "^7.29.7",
"@eslint/eslintrc": "^3.3.6",
"@rozenite/expo-atlas-plugin": "^1.13.0",
"@rozenite/metro": "^1.13.0",
"@rozenite/sqlite-plugin": "^1.13.0",
"@testing-library/react-native": "^13.3.3",
"@types/better-sqlite3": "^7.6.13",
"@types/color": "^4.2.1",
"@types/jest": "^29.5.14",
"@types/lodash-es": "^4.17.12",
"@types/react": "~19.2.17",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/sanitize-html": "^2.16.1",
"@typescript-eslint/eslint-plugin": "^8.64.0",
"@typescript-eslint/parser": "^8.64.0",
"babel-plugin-inline-import": "^3.0.0",
"babel-plugin-module-resolver": "^5.0.3",
"babel-plugin-react-compiler": "^1.0.0",
"better-sqlite3": "^12.11.1",
"drizzle-kit": "1.0.0-beta.20",
"eslint": "^9.0.0",
"eslint-config-expo": "~57.0.0",
"eslint-plugin-ft-flow": "^3.0.11",
"eslint-plugin-jest": "^29.15.4",
"eslint-plugin-testing-library": "^7.16.2",
"husky": "^7.0.4",
"jest": "^29.7.0",
"jest-expo": "^57.0.2",
"lint-staged": "^12.5.0",
"nitrogen": "^0.36.1",
"react-native-nitro-modules": "^0.36.0",
"react-test-renderer": "19.2.3",
"typescript": "~6.0.3"
},
"expo": {
"autolinking": {
"exclude": [
"@expo/dom-webview"
]
},
"doctor": {
"reactNativeDirectoryCheck": {
"exclude": [
"native-file",
"native-crash-logs",
"nitro-tts",
"native-volume-button-listener",
"native-zip-archive",
"nitro-epub",
"native-background-tasks",
"@react-native-vector-icons/material-design-icons",
"lottie-ios"
]
}
}
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,md,css,scss,yml,yaml}": [
"prettier --write"
]
},
"engines": {
"node": ">=22.11.0"
},
"packageManager": "pnpm@11.20.0"
}