2d819b476c
* fix(db): forward DatabaseOpts to tauri-plugin-turso NativeDatabaseService.open ignored its opts parameter, dropping any experimental feature flags (e.g. 'index_method' needed for FTS / vector indexes) and any encryption config before they could reach the Tauri plugin. Translate DatabaseOpts to the plugin's LoadOptions shape and forward as the single argument Database.load accepts. Skip translation when no relevant opts are set so the existing path-string call shape is preserved for callers without experimental/encryption needs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(db): cover Turso vector primitives + add benchmark harness Verifies the Turso functions Reedy retrieval depends on, with a brute-force per-book kNN test that runs against every DatabaseService backend (node, native, WASM): SELECT vector_distance_cos(embedding, vector32(?)) AS d FROM book_chunks WHERE book_hash = ? ORDER BY d ASC LIMIT k This is the path Turso's own founder recommended in tursodatabase/turso#3778 ("First, focus on efficient SIMD-accelerated brute-force search") and what shipped at commit 1aba105df4f. Native vector index modules don't exist in this engine: `libsql_vector_idx`, `vector_top_k`, and `USING vector/hnsw/diskann/ivfflat` all parse-error against @tursodatabase/database@0.6.0-pre.28 (libsql_vector_idx is a libSQL/sqld fork feature; DiskANN was closed not-planned upstream in #832). The test asserts cross-book isolation and nearest-first ordering using only `WHERE book_hash = ?` and `ORDER BY` — no DDL, no identifier interpolation, no index plumbing. Also adds bench/ harness for manual perf checks: pnpm bench [name] run benchmarks (refuses in CI) pnpm bench --list list available benchmarks pnpm bench --no-record skip results.jsonl append pnpm bench --force override the CI guard Uses Node 24's --experimental-strip-types so no tsx devDep is needed. Appends one JSON line per run to bench/results.jsonl (gitignored, local history; share by pasting tabular stdout into PRs/issues). Explicitly NOT in CI — shared-tenant variance makes synthetic-benchmark regression detection unreliable; production telemetry (reedy_metrics, plan §M1.9) is the right tool for that. First benchmark: vector-retrieval. Measured on M1 Pro: 400 chunks × 384 dim → 0.35 ms / query 400 chunks × 768 dim → 0.45 ms / query 2000 chunks × 768 dim → 2.23 ms / query 10000 chunks × 768 dim → 14.00 ms / query 400 chunks × 1536 dim → 0.70 ms / query Per-chunk cost ~1.1 µs at 768 dim = ~1.4 ns/dim. NEON-class on Apple Silicon, ~50× faster than scalar — confirms SIMD acceleration is active in 0.6.0-pre.28. Per-query latency stays sub-ms at Reedy MVP corpus sizes; the ceiling is ~10K chunks per book before phone-class hardware notices. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
267 lines
14 KiB
JSON
267 lines
14 KiB
JSON
{
|
|
"name": "@readest/readest-app",
|
|
"version": "0.11.1",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "dotenv -e .env.tauri -- next dev",
|
|
"build": "dotenv -e .env.tauri -- next build",
|
|
"start": "dotenv -e .env.tauri -- next start",
|
|
"dev-web": "dotenv -e .env.web -- next dev",
|
|
"build-web": "dotenv -e .env.web -- next build",
|
|
"start-web": "dotenv -e .env.web -- next start",
|
|
"dev-web:vinext": "dotenv -e .env.web -- vinext dev",
|
|
"build-web:vinext": "dotenv -e .env.web -- vinext build",
|
|
"start-web:vinext": "dotenv -e .env.web -- vinext start",
|
|
"build-tauri": "dotenv -e .env.tauri -- next build",
|
|
"build-browser-ext": "pnpm --filter @readest/send-to-readest-extension build",
|
|
"dev-android": "tauri android build -t aarch64 -- --features devtools && adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk",
|
|
"dev-ios": "tauri ios build -- --features devtools && ideviceinstaller install src-tauri/gen/apple/build/arm64/Readest.ipa",
|
|
"i18n:extract": "i18next-scanner --config i18next-scanner.config.cjs",
|
|
"i18n:extract:ext": "pnpm --filter @readest/send-to-readest-extension i18n:extract",
|
|
"lint": "tsgo --noEmit && biome lint . && pnpm lint:lua",
|
|
"lint:lua": "node ../readest.koplugin/scripts/lint-koplugin.mjs",
|
|
"test:lua": "node ../readest.koplugin/scripts/test-koplugin.mjs",
|
|
"test": "dotenv -e .env -e .env.test.local -- vitest",
|
|
"test:extension": "dotenv -e .env -e .env.test.local -- vitest extensions/send-to-readest/ --run",
|
|
"test:coverage": "dotenv -e .env -e .env.test.local -- vitest run --coverage",
|
|
"test:browser": "dotenv -e .env -e .env.test.local -- vitest run --config vitest.browser.config.mts",
|
|
"test:tauri": "bash scripts/test-tauri.sh",
|
|
"test:pr:web": "dotenv -e .env -e .env.test.local -- vitest run --maxWorkers=4 && pnpm test:browser && pnpm test:extension && pnpm build-browser-ext",
|
|
"test:pr:tauri": "bash scripts/test-tauri.sh",
|
|
"test:all": "pnpm test -- --watch=false && pnpm test:browser && bash scripts/test-tauri.sh",
|
|
"bench": "node --experimental-strip-types --no-warnings bench/index.ts",
|
|
"test:e2e": "wdio run wdio.conf.ts",
|
|
"test:e2e:web": "playwright test",
|
|
"test:e2e:web:headed": "playwright test --headed --workers=1 --trace on",
|
|
"test:e2e:web:ui": "playwright test --ui",
|
|
"test:e2e:web:report": "playwright show-report",
|
|
"tauri:dev:test": "dotenv -e .env.tauri -- tauri dev --features webdriver",
|
|
"tauri:build:test": "dotenv -e .env.tauri -- tauri build --debug --features webdriver",
|
|
"tauri": "tauri",
|
|
"fmt:check": "cargo fmt -p Readest --check",
|
|
"clippy:check": "cargo clippy -p Readest --no-deps -- -D warnings",
|
|
"format": "pnpm -w format",
|
|
"format:check": "pnpm -w format:check",
|
|
"prepare-public-vendor": "mkdirp ./public/vendor/pdfjs ./public/vendor/simplecc ./public/vendor/jieba",
|
|
"copy-pdfjs-js": "cpx \"../../packages/foliate-js/node_modules/pdfjs-dist/legacy/build/{pdf.worker.min.mjs,pdf.min.mjs,pdf.d.mts}\" ./public/vendor/pdfjs",
|
|
"copy-pdfjs-wasm": "cpx \"../../packages/foliate-js/node_modules/pdfjs-dist/wasm/{openjpeg.wasm,qcms_bg.wasm}\" ./public/vendor/pdfjs",
|
|
"copy-pdfjs-fonts": "cpx \"../../packages/foliate-js/node_modules/pdfjs-dist/{cmaps,standard_fonts}/*\" ./public/vendor/pdfjs",
|
|
"copy-flatten-pdfjs-annotation-layer-css": "npx postcss \"../../packages/foliate-js/vendor/pdfjs/annotation_layer_builder.css\" --no-map -u postcss-nested > ./public/vendor/pdfjs/annotation_layer_builder.css",
|
|
"copy-flatten-pdfjs-text-layer-css": "npx postcss \"../../packages/foliate-js/vendor/pdfjs/text_layer_builder.css\" --no-map -u postcss-nested > ./public/vendor/pdfjs/text_layer_builder.css",
|
|
"copy-flatten-pdfjs-css": "pnpm copy-flatten-pdfjs-annotation-layer-css && pnpm copy-flatten-pdfjs-text-layer-css",
|
|
"copy-pdfjs": "pnpm copy-pdfjs-js && pnpm copy-pdfjs-wasm && pnpm copy-pdfjs-fonts && pnpm copy-flatten-pdfjs-css",
|
|
"copy-simplecc": "cpx \"../../packages/simplecc-wasm/dist/web/*\" ./public/vendor/simplecc",
|
|
"copy-jieba": "cpx \"./node_modules/jieba-wasm/pkg/web/*\" ./public/vendor/jieba",
|
|
"setup-pdfjs": "pnpm prepare-public-vendor && pnpm copy-pdfjs",
|
|
"setup-simplecc": "pnpm prepare-public-vendor && pnpm copy-simplecc",
|
|
"setup-jieba": "pnpm prepare-public-vendor && pnpm copy-jieba",
|
|
"setup-vendors": "pnpm setup-pdfjs && pnpm setup-simplecc && pnpm setup-jieba",
|
|
"build-win-x64": "dotenv -e .env.tauri.local -- tauri build --target i686-pc-windows-msvc --bundles nsis",
|
|
"build-win-arm64": "dotenv -e .env.tauri.local -- tauri build --target aarch64-pc-windows-msvc --bundles nsis",
|
|
"build-linux-x64": "dotenv -e .env.tauri.local -- tauri build --target x86_64-unknown-linux-gnu --bundles appimage",
|
|
"build-macos-universial": "dotenv -e .env.tauri.local -e .env.apple-nonstore.local -- tauri build -t universal-apple-darwin --bundles dmg",
|
|
"build-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- tauri build -t universal-apple-darwin --bundles app --config src-tauri/tauri.appstore.conf.json",
|
|
"build-macos-universial-appstore-dev": "dotenv -e .env.tauri.local -e .env.apple-appstore-dev.local -- tauri build -t universal-apple-darwin --bundles app --config src-tauri/tauri.appstore-dev.conf.json",
|
|
"build-ios": "dotenv -e .env.ios-appstore-dev.local -- tauri ios build",
|
|
"build-ios-appstore": "dotenv -e .env.ios-appstore.local -- tauri ios build --export-method app-store-connect",
|
|
"release-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- bash scripts/release-mac-appstore.sh",
|
|
"release-ios-appstore": "dotenv -e .env.ios-appstore.local -- bash scripts/release-ios-appstore.sh",
|
|
"release-google-play": "dotenv -e .env.google-play.local -- bash scripts/release-google-play.sh",
|
|
"config-wrangler": "sed -i \"s/\\${TRANSLATIONS_KV_ID}/$TRANSLATIONS_KV_ID/g\" wrangler.toml",
|
|
"preview": "pnpm patch-build-webpack && NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && pnpm restore-build-original && opennextjs-cloudflare preview --ip 0.0.0.0 --port 3001",
|
|
"deploy": "pnpm patch-build-webpack && NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && pnpm restore-build-original && opennextjs-cloudflare deploy",
|
|
"upload": "pnpm patch-build-webpack && NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && pnpm restore-build-original && opennextjs-cloudflare upload",
|
|
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",
|
|
"patch-build-webpack": "if [ \"$(uname)\" = \"Darwin\" ]; then sed -i '' 's/next build\"/next build --webpack\"/' package.json; else sed -i 's/next build\"/next build --webpack\"/' package.json; fi",
|
|
"restore-build-original": "if [ \"$(uname)\" = \"Darwin\" ]; then sed -i '' 's/next build --webpack\"/next build\"/' package.json; else sed -i 's/next build --webpack\"/next build\"/' package.json; fi",
|
|
"update-metadata": "bash ./scripts/sync-release-notes.sh release-notes.json ../../data/metainfo/appdata.xml",
|
|
"check:optional-chaining": "count=$(grep -rno '\\?\\.[a-zA-Z_$]' .next/static/chunks/* out/_next/static/chunks/* | wc -l); if [ \"$count\" -gt 0 ]; then echo '❌ Optional chaining found in output!'; exit 1; else echo '✅ No optional chaining found.'; fi",
|
|
"check:translations": "count=$(grep -rno '__STRING_NOT_TRANSLATED__' public/locales/* | wc -l); if [ \"$count\" -gt 0 ]; then echo '❌ Untranslated strings found!'; exit 1; else echo '✅ All strings translated.'; fi",
|
|
"check:lookbehind-regex": "count=$(grep -rnoE '\\(\\?<[!=]' .next/static/chunks/* out/_next/static/chunks/* | wc -l); if [ \"$count\" -gt 0 ]; then echo '❌ Lookbehind regex found in output!'; exit 1; else echo '✅ No lookbehind regex found.'; fi",
|
|
"check:all": "pnpm check:translations && pnpm check:lookbehind-regex",
|
|
"build-check": "pnpm build && pnpm build-web && pnpm check:all",
|
|
"worktree:new": "pnpm exec tsx scripts/worktree-new.ts",
|
|
"worktree:rm": "pnpm exec tsx scripts/worktree-rm.ts"
|
|
},
|
|
"dependencies": {
|
|
"@ai-sdk/openai-compatible": "^2.0.48",
|
|
"@ai-sdk/react": "^3.0.49",
|
|
"@assistant-ui/react": "0.11.56",
|
|
"@assistant-ui/react-ai-sdk": "1.1.21",
|
|
"@assistant-ui/react-markdown": "0.11.9",
|
|
"@aws-sdk/client-s3": "^3.1000.0",
|
|
"@aws-sdk/s3-request-presigner": "^3.1000.0",
|
|
"@choochmeque/tauri-plugin-sharekit-api": "^0.3.0",
|
|
"@dnd-kit/core": "^6.3.1",
|
|
"@dnd-kit/sortable": "^10.0.0",
|
|
"@dnd-kit/utilities": "^3.2.2",
|
|
"@emnapi/core": "^1.8.1",
|
|
"@emnapi/runtime": "^1.8.1",
|
|
"@fabianlars/tauri-plugin-oauth": "2",
|
|
"@mozilla/readability": "^0.6.0",
|
|
"@napi-rs/wasm-runtime": "^1.1.1",
|
|
"@opennextjs/cloudflare": "^1.19.4",
|
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
"@radix-ui/react-hover-card": "^1.1.15",
|
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
"@radix-ui/react-select": "^2.2.6",
|
|
"@radix-ui/react-separator": "^1.1.8",
|
|
"@radix-ui/react-slot": "^1.2.4",
|
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
"@readest/turso-database-common": "0.6.0-pre.28-readest.0",
|
|
"@readest/turso-database-wasm": "0.6.0-pre.28-readest.0",
|
|
"@readest/turso-database-wasm-common": "0.6.0-pre.28-readest.0",
|
|
"@serwist/next": "^9.5.6",
|
|
"@serwist/webpack-plugin": "^9.5.6",
|
|
"@stripe/react-stripe-js": "^6.2.0",
|
|
"@stripe/stripe-js": "^9.3.1",
|
|
"@supabase/auth-ui-react": "^0.4.7",
|
|
"@supabase/auth-ui-shared": "^0.1.8",
|
|
"@supabase/supabase-js": "^2.76.1",
|
|
"@tauri-apps/api": "2.10.1",
|
|
"@tauri-apps/plugin-cli": "^2.4.1",
|
|
"@tauri-apps/plugin-deep-link": "^2.4.7",
|
|
"@tauri-apps/plugin-dialog": "^2.6.0",
|
|
"@tauri-apps/plugin-fs": "^2.4.5",
|
|
"@tauri-apps/plugin-haptics": "^2.3.2",
|
|
"@tauri-apps/plugin-http": "^2.5.7",
|
|
"@tauri-apps/plugin-log": "^2.8.0",
|
|
"@tauri-apps/plugin-opener": "^2.5.3",
|
|
"@tauri-apps/plugin-os": "^2.3.2",
|
|
"@tauri-apps/plugin-process": "^2.3.1",
|
|
"@tauri-apps/plugin-shell": "~2.3.5",
|
|
"@tauri-apps/plugin-updater": "^2.10.0",
|
|
"@tauri-apps/plugin-websocket": "~2.4.2",
|
|
"@tybys/wasm-util": "^0.10.1",
|
|
"@zip.js/zip.js": "^2.8.16",
|
|
"abortcontroller-polyfill": "^1.7.8",
|
|
"ai": "^6.0.47",
|
|
"ai-sdk-ollama": "^3.2.0",
|
|
"app-store-server-api": "^0.17.1",
|
|
"aws4fetch": "^1.0.20",
|
|
"buffer": "^6.0.3",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"cmdk": "^1.1.1",
|
|
"cors": "^2.8.5",
|
|
"dayjs": "^1.11.13",
|
|
"dompurify": "^3.4.0",
|
|
"fflate": "^0.8.2",
|
|
"foliate-js": "workspace:*",
|
|
"franc-min": "^6.2.0",
|
|
"fzf": "^0.5.2",
|
|
"google-auth-library": "^10.5.0",
|
|
"googleapis": "^164.1.0",
|
|
"highlight.js": "^11.11.1",
|
|
"i18next": "^24.2.0",
|
|
"i18next-browser-languagedetector": "^8.0.2",
|
|
"i18next-http-backend": "^3.0.5",
|
|
"iso-639-2": "^3.0.2",
|
|
"iso-639-3": "^3.0.1",
|
|
"isomorphic-ws": "^5.0.0",
|
|
"jieba-wasm": "^2.4.0",
|
|
"js-md5": "^0.8.3",
|
|
"jwt-decode": "^4.0.0",
|
|
"lucide-react": "^0.562.0",
|
|
"lunr": "^2.3.9",
|
|
"mammoth": "^1.12.0",
|
|
"marked": "^15.0.12",
|
|
"nanoid": "^5.1.6",
|
|
"next": "16.2.6",
|
|
"next-view-transitions": "^0.3.5",
|
|
"nunjucks": "^3.2.4",
|
|
"overlayscrollbars": "^2.11.4",
|
|
"overlayscrollbars-react": "^0.5.6",
|
|
"posthog-js": "^1.246.0",
|
|
"react": "19.2.5",
|
|
"react-color": "^2.19.3",
|
|
"react-dom": "19.2.5",
|
|
"react-i18next": "^15.2.0",
|
|
"react-icons": "^5.4.0",
|
|
"react-responsive": "^10.0.0",
|
|
"react-virtuoso": "^4.17.0",
|
|
"react-window": "^1.8.11",
|
|
"remark-gfm": "^4.0.1",
|
|
"semver": "^7.7.1",
|
|
"streamdown": "^1.6.10",
|
|
"stripe": "^22.0.2",
|
|
"styled-jsx": "^5.1.7",
|
|
"tailwind-merge": "^3.4.0",
|
|
"tauri-plugin-device-info-api": "^1.0.1",
|
|
"tinycolor2": "^1.6.0",
|
|
"uuid": "^14.0.0",
|
|
"ws": "^8.18.3",
|
|
"zod": "^4.0.8",
|
|
"zustand": "5.0.10"
|
|
},
|
|
"devDependencies": {
|
|
"@next/bundle-analyzer": "^15.4.2",
|
|
"@playwright/test": "^1.60.0",
|
|
"@tailwindcss/typography": "^0.5.16",
|
|
"@tauri-apps/cli": "2.10.1",
|
|
"@testing-library/dom": "^10.4.0",
|
|
"@testing-library/react": "^16.3.0",
|
|
"@tursodatabase/database": "0.6.0-pre.28",
|
|
"@types/cors": "^2.8.17",
|
|
"@types/cssbeautify": "^0.3.5",
|
|
"@types/lunr": "^2.3.7",
|
|
"@types/mocha": "^10.0.10",
|
|
"@types/node": "^22.15.31",
|
|
"@types/nunjucks": "^3.2.6",
|
|
"@types/react": "^19.0.0",
|
|
"@types/react-color": "^3.0.13",
|
|
"@types/react-dom": "^19.0.0",
|
|
"@types/react-window": "^1.8.8",
|
|
"@types/semver": "^7.7.0",
|
|
"@types/tinycolor2": "^1.4.6",
|
|
"@types/uuid": "^10.0.0",
|
|
"@types/ws": "^8.18.1",
|
|
"@typescript/native-preview": "7.0.0-dev.20260312.1",
|
|
"@vitejs/plugin-react": "^5.1.1",
|
|
"@vitejs/plugin-rsc": "^0.5.23",
|
|
"@vitest/browser-playwright": "^4.0.18",
|
|
"@vitest/browser-webdriverio": "^4.0.18",
|
|
"@vitest/coverage-v8": "^4.0.18",
|
|
"@wdio/cli": "^9.25.0",
|
|
"@wdio/globals": "^9.23.0",
|
|
"@wdio/local-runner": "^9.24.0",
|
|
"@wdio/mocha-framework": "^9.24.0",
|
|
"@wdio/spec-reporter": "^9.24.0",
|
|
"@wdio/types": "^9.24.0",
|
|
"autoprefixer": "^10.4.20",
|
|
"caniuse-lite": "^1.0.30001746",
|
|
"cpx2": "^8.0.0",
|
|
"daisyui": "^4.12.24",
|
|
"dotenv-cli": "^7.4.4",
|
|
"fast-check": "^4.8.0",
|
|
"i18next-scanner": "^4.6.0",
|
|
"jsdom": "^28.1.0",
|
|
"mkdirp": "^3.0.1",
|
|
"node-env-run": "^4.0.2",
|
|
"playwright": "^1.58.2",
|
|
"postcss": "^8.4.49",
|
|
"postcss-cli": "^11.0.0",
|
|
"postcss-nested": "^7.0.2",
|
|
"raw-loader": "^4.0.2",
|
|
"react-server-dom-webpack": "^19.2.5",
|
|
"serwist": "^9.3.0",
|
|
"tailwindcss": "^3.4.18",
|
|
"typescript": "^5.7.2",
|
|
"vinext": "^0.0.21",
|
|
"vite": "^7.3.3",
|
|
"vite-tsconfig-paths": "^5.1.4",
|
|
"vitest": "^4.0.18",
|
|
"wrangler": "^4.85.0"
|
|
},
|
|
"browserslist": [
|
|
"chrome 92",
|
|
"edge 92",
|
|
"firefox 92",
|
|
"safari 15.2"
|
|
]
|
|
}
|