feat(engine): P0 stroke engine + persistence
Per the full-refactor plan §9 (input-independent half of P0): - engine: canonical EditorStroke (lossless InkStroke round-trip) + stroke_geometry (single getStroke outline) + revision-gated StrokeStore - render: static/live ink painters + ink_picture_cache (revision-keyed) + annotation_layer (RepaintBoundary) - persistence: DB v6 (ink, notebook_pages) + editor_repository diff-write (UPSERT changed / DELETE removed in one txn; id-set after commit) + save_scheduler - pdf_service export now FILLS the getStroke outline (R7 hairline fix) Not yet wired into the live editor (input relocation pending pen-pressure diagnostic). 28 new tests pass.
This commit is contained in:
@@ -41,7 +41,7 @@ class DatabaseService {
|
||||
|
||||
_database = await openDatabase(
|
||||
dbPath,
|
||||
version: 5,
|
||||
version: 6,
|
||||
onCreate: _onCreate,
|
||||
onUpgrade: _onUpgrade,
|
||||
);
|
||||
@@ -156,12 +156,71 @@ class DatabaseService {
|
||||
await db.execute(
|
||||
'CREATE INDEX idx_scratchpads_doc ON scratchpads(document_id)',
|
||||
);
|
||||
|
||||
// Editor ink strokes (v6)
|
||||
await db.execute('''
|
||||
CREATE TABLE ink (
|
||||
id TEXT PRIMARY KEY,
|
||||
host_kind TEXT NOT NULL,
|
||||
host_id TEXT NOT NULL,
|
||||
stroke_json TEXT NOT NULL,
|
||||
ordinal INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
''');
|
||||
|
||||
await db.execute(
|
||||
'CREATE INDEX idx_ink_host ON ink(host_kind, host_id)',
|
||||
);
|
||||
|
||||
// Notebook pages (v6)
|
||||
await db.execute('''
|
||||
CREATE TABLE notebook_pages (
|
||||
id TEXT PRIMARY KEY,
|
||||
document_id TEXT NOT NULL,
|
||||
ordinal INTEGER NOT NULL,
|
||||
source_page_index INTEGER NOT NULL,
|
||||
kind TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL
|
||||
)
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
|
||||
if (oldVersion < 3) await _migrateV2toV3(db);
|
||||
if (oldVersion < 4) {} // v3->v4: version boundary (no-op schema)
|
||||
if (oldVersion < 5) await _migrateV4toV5(db);
|
||||
if (oldVersion < 6) await _migrateV5toV6(db);
|
||||
}
|
||||
|
||||
Future<void> _migrateV5toV6(Database db) async {
|
||||
await db.transaction((txn) async {
|
||||
await txn.execute('''
|
||||
CREATE TABLE ink (
|
||||
id TEXT PRIMARY KEY,
|
||||
host_kind TEXT NOT NULL,
|
||||
host_id TEXT NOT NULL,
|
||||
stroke_json TEXT NOT NULL,
|
||||
ordinal INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
''');
|
||||
|
||||
await txn.execute(
|
||||
'CREATE INDEX idx_ink_host ON ink(host_kind, host_id)',
|
||||
);
|
||||
|
||||
await txn.execute('''
|
||||
CREATE TABLE notebook_pages (
|
||||
id TEXT PRIMARY KEY,
|
||||
document_id TEXT NOT NULL,
|
||||
ordinal INTEGER NOT NULL,
|
||||
source_page_index INTEGER NOT NULL,
|
||||
kind TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL
|
||||
)
|
||||
''');
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _migrateV2toV3(Database db) async {
|
||||
|
||||
Reference in New Issue
Block a user