Files
lnreader/scripts/embed-reader-assets.mjs
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

22 lines
1.1 KiB
JavaScript

// Embeds assets/reader (css, js, fonts) into a TS module for iOS, where WKWebView cannot
// load file:// subresources into a chapter whose base URL is the source's site.
// Run by `pnpm postinstall` and the iOS build script; the output is not committed.
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join, parse } from 'node:path';
const root = join(import.meta.dirname, '..', 'assets', 'reader');
const read = (dir, encoding) =>
Object.fromEntries(
readdirSync(join(root, dir)).sort().map(file => [parse(file).name, readFileSync(join(root, dir, file), encoding)]),
);
const out = join(import.meta.dirname, '..', 'src', 'utils', 'readerAssets', 'embedded.generated.ts');
writeFileSync(
out,
'// Generated by scripts/embed-reader-assets.mjs from assets/reader. Do not edit.\n' +
`export const css: Record<string, string> = ${JSON.stringify(read('css', 'utf8'))};\n` +
`export const js: Record<string, string> = ${JSON.stringify(read('js', 'utf8'))};\n` +
`export const fonts: Record<string, string> = ${JSON.stringify(read('fonts', 'base64'))};\n`,
);
console.log(`reader assets embedded: ${out}`);