Skip to content

[Codex] Add SQLite dictionary storage with experimental legacy migration action#2335

Draft
bee-san wants to merge 3 commits intoyomidevs:masterfrom
bee-san:yomitan-sqlite-migration-pr
Draft

[Codex] Add SQLite dictionary storage with experimental legacy migration action#2335
bee-san wants to merge 3 commits intoyomidevs:masterfrom
bee-san:yomitan-sqlite-migration-pr

Conversation

@bee-san
Copy link
Copy Markdown

@bee-san bee-san commented Mar 13, 2026

Human note

  • Ripped from Manabitan
  • Auto-update work is intentionally not part of this PR; that stays in a separate PR
  • All micro-optimisations are removed; this keeps the migration path simpler while it is still experimental

AI speaking now

Summary

  • add SQLite-backed dictionary storage
  • add an experimental settings action for migrating legacy IndexedDB dictionaries into SQLite
  • warn users that the migration might break their dictionary collection and require an explicit click instead of running automatically
  • add regression tests for the manual migration path and the populated-SQLite no-op path

Testing

  • npx eslint ext/js/dictionary/dictionary-database.js ext/js/background/backend.js ext/js/comm/api.js ext/js/background/offscreen-proxy.js ext/js/background/offscreen.js ext/js/pages/settings/backup-controller.js types/ext/api.d.ts types/ext/backend.d.ts types/ext/offscreen.d.ts test/database.test.js
  • npm run test:unit -- test/database.test.js -t 'Migrates dictionaries from legacy IndexedDB into SQLite only when requested|Skips legacy IndexedDB migration when SQLite already has dictionaries'

@bee-san bee-san requested a review from a team as a code owner March 13, 2026 11:51
@bee-san bee-san changed the title Add legacy IndexedDB migration for SQLite dictionary storage [Codex] Add legacy IndexedDB migration for SQLite dictionary storage Mar 13, 2026
@bee-san bee-san marked this pull request as draft March 13, 2026 11:53
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 13, 2026

Merging this PR will degrade performance by 48.47%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 4 untouched benchmarks
⏩ 1 skipped benchmark1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
Translator.prototype.findKanji - (n=3) 3.9 ms 7.6 ms -48.47%

Comparing bee-san:yomitan-sqlite-migration-pr (9d42893) with master (78eee11)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 197ab49637

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1060 to +1064
if (this._db !== null) {
this._clearCachedStatements();
this._db.close();
this._db = null;
this._usesFallbackStorage = false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reopen dictionary DB after failed import

This method closes the active database before attempting importOpfsDatabase, but there is no recovery path if the import payload is invalid/corrupt and that call throws. In that failure case, _db stays null, so subsequent dictionary operations fail with "Database not open" until the extension is restarted, which turns a single bad backup file selection into a persistent runtime failure.

Useful? React with 👍 / 👎.

async importDatabase(content) {
await this._offscreen.sendMessagePromise({
action: 'importDictionaryDatabaseOffscreen',
params: {content: arrayBufferToBase64(content)},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop base64-wrapping full DB backups over offscreen RPC

The new offscreen bridge converts the entire SQLite backup payload to a base64 string before messaging, which inflates size and forces additional full-buffer copies. For large dictionary collections, this can cause import/export failures due to memory pressure or message transport limits even though the underlying database export/import logic is valid; using transferable ArrayBuffers or chunked streaming avoids this regression.

Useful? React with 👍 / 👎.

@bee-san bee-san changed the title [Codex] Add legacy IndexedDB migration for SQLite dictionary storage [Codex] Add SQLite dictionary storage with experimental legacy migration action Mar 13, 2026
@bee-san bee-san marked this pull request as ready for review March 13, 2026 12:13
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d428938d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

void this._settingsController.application.api.triggerDatabaseUpdated('dictionary', 'import');
async _importDatabase(file) {
const content = await this._readFileArrayBuffer(file);
await this._settingsController.application.api.importDictionaryDatabase(content);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve support for legacy JSON dictionary backups

This import path now unconditionally treats the selected file as a SQLite payload and sends it to importDictionaryDatabase, but previous releases exported dictionary backups as Dexie JSON; those existing backups will fail to restore after upgrade because DictionaryDatabase.importDatabase only imports SQLite images via OPFS. Combined with the new file picker filter in ext/settings.html, users who only have pre-SQLite .json backups lose their recovery path.

Useful? React with 👍 / 👎.

@bee-san bee-san marked this pull request as draft March 13, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant