מבנה הרפו: ה‑package הראשי (
seforim_library_updater) יושב ב‑root, כמו קודם. בתיקיותotzaria_manager/ו-library_manager/יושבים packages נוספים, נפרדים, לניהול עדכון/התקנה/הפעלה של אפליקציית אוצריא עצמה ולחיווט המסד לתוך לאנצ'ר מאוחד, בהתאמה — חלק ממיזם לאנצ'ר מאוחד.launcher_app/הוא אפליקציית ה-Flutter (Windows ו-macOS) שמחווטת את שני המודולים האלה לדשבורד אחד (חנות התוספים עדיין placeholder). לכל package ישpubspec.yamlמשלו.תמיכת macOS: הלאנצ'ר בונה ורץ ב-macOS 10.15+, ומנהל שם את אוצריא דרך
otzaria-macos.zip(חבילת.app) במקום ה-installer של Windows. הפירוט — מה נבחר, איך מותקן ואיפה יושבים הנתיבים — ב-README שלotzaria_manager,library_managerו-launcher_app.
חבילת Flutter לצריכת הפצות הדלתא של Otzaria/SeforimLibrary.
החבילה היא צד‑הלקוח של פורמט ההפצה: היא מגלה גרסאות ב‑GitHub Releases, בוחרת מסלול עדכון
(דלתא או הורדה מלאה), מורידה ומאמתת קובצי patch-vX-vY.db.zst, מחילה אותם אטומית על ה‑DB
המקומי, ומוודאת שטביעת‑האצבע הלוגית (hash) של התוצאה תואמת למה שה‑Kotlin ייצר.
לא יצרן — צרכן. מאגר ה‑Kotlin (
SeforimLibrary) מייצר את ה‑DB וההפרשים; חבילה זו צורכת אותם. שני רכיבים כאן הם תרגום ישיר של לוגיקת ה‑Kotlin וחייבים להסכים איתה בית‑בית:LogicalContentHasher(תואםLogicalContentHasher.kt) ו‑PatchApplier.
החבילה הומרה מ‑Dart טהור ל‑Flutter package: pubspec.yaml מכריז תלות ב‑flutter (sdk),
ונוסף sqlite3_flutter_libs כדי לספק את ספריות ה‑native של SQLite עבור
Android/iOS/macOS/Windows/Linux בלי הסתמכות על ספריית מערכת מותקנת מראש. הלוגיקה עצמה
(המודלים והשירותים תחת lib/src) לא השתנתה — היא Dart טהור ועובדת זהה בתוך אפליקציית
Flutter. אין ב‑package הזה widgets או UI; האינטגרציה עם ממשק המשתמש (progress bars, כפתורי
עדכון וכו') היא באחריות האפליקציה הצורכת.
חילוץ zstd עדיין מוזרק על‑ידי הצרכן (ל‑PatchDownloader.decompress), כך שה‑package לא
נעול לספריית דחיסה מסוימת.
חישוב ה‑SHA‑256 עצמו (גם ב‑LogicalContentHasher וגם באימות הנכסים ב‑PatchDownloader) עובר
דרך FastSha256 ולא דרך sha256.startChunkedConversion ישירות. הסיבה מדידה: המימוש של
package:crypto הוא דארט טהור ומגיע ל‑~50MB/s, מול ~1,225MB/s לאותו אלגוריתם דרך ספריית
ההצפנה של המערכת — ואימות ה‑hash הלוגי קורא את כל המסד (~7.4GB) בכל patch.
Windows דרך CNG (bcrypt.dll), macOS דרך CommonCrypto ב‑libSystem, וכל השאר (כולל לינוקס
ב‑CI) נופל ל‑package:crypto. ה‑digest זהה בשלושת המסלולים — חוזה ה‑hash מול ה‑Kotlin נוגע
לזרם הבתים, לא למימוש ה‑SHA. בטעינה הראשונה (פעם אחת לכל isolate) מורצת בדיקה עצמית מול
package:crypto, ומסלול נייטיבי שאינו מסכים איתה מושתק — מימוש שגוי היה דוחה כל עדכון.
הערת web: Flutter Web אינו תומך ב‑dart:io, שבו משתמשים PatchApplier,
LibraryDbRecoveryService ו‑LocalDbVersionReader. החבילה מיועדת לפלטפורמות ה‑native
(Android, iOS, macOS, Windows, Linux) בלבד.
LogicalContentHasher.compute ו‑PatchApplier.apply הן סינכרוניות וכבדות (חישוב ה‑hash
עשוי להימשך עשרות שניות על DB מלא). אל תריץ אותן על ה‑UI isolate — עטוף ב‑Isolate.run:
await Isolate.run(() => const PatchApplier().apply(/* ... */));- fixtures inline — הבדיקות בונות DB זעירים בזיכרון (
openInMemory), כולל golden hash קבוע ומקרה BOM; רצים תמיד ולוכדים רגרסיה בחוזה מול Kotlin. - בדיקות מול הפצות אמיתיות — אופציונליות, מופעלות כשמשתנה הסביבה
SEFORIM_LIBRARY_RELEASES_DIRמצביע לתיקייה עםv14/seforim.dbו‑v15/{seforim.db, patch-v14-v15.db, patch-v14-v15r.db}. אחרת מדלגות.
dart test # fixtures בלבד
SEFORIM_LIBRARY_RELEASES_DIR=/path/to/releases dart test # + חוזה מלא