{"id":20253170,"url":"https://github.com/jeremylikness/sqlitewasmhelper","last_synced_at":"2025-05-07T12:32:51.473Z","repository":{"id":40934343,"uuid":"476889356","full_name":"JeremyLikness/SqliteWasmHelper","owner":"JeremyLikness","description":"Persistent SQLite in Blazor WebAssembly apps with EF Core 6.0 and your browser's cache.","archived":true,"fork":false,"pushed_at":"2025-02-07T00:58:02.000Z","size":318,"stargazers_count":121,"open_issues_count":0,"forks_count":27,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-02T23:37:48.861Z","etag":null,"topics":["asp-net-core","blazor","sqlite","wasm","webassembly"],"latest_commit_sha":null,"homepage":"https://youtu.be/ZeJISZgy-FM","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JeremyLikness.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-01T22:52:32.000Z","updated_at":"2025-03-17T21:30:12.000Z","dependencies_parsed_at":"2023-02-06T07:02:01.213Z","dependency_job_id":"4001d2ec-8672-4f51-9d3c-68d446574cc5","html_url":"https://github.com/JeremyLikness/SqliteWasmHelper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FSqliteWasmHelper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FSqliteWasmHelper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FSqliteWasmHelper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FSqliteWasmHelper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JeremyLikness","download_url":"https://codeload.github.com/JeremyLikness/SqliteWasmHelper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252876648,"owners_count":21818220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net-core","blazor","sqlite","wasm","webassembly"],"created_at":"2024-11-14T10:21:56.216Z","updated_at":"2025-05-07T12:32:51.439Z","avatar_url":"https://github.com/JeremyLikness.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e **ALTERNATIVE REPO (we make no claims or endorsements) [https://www.nuget.org/packages/Bit.Besql/](https://www.nuget.org/packages/Bit.Besql/)\n\n\n# SqliteWasmHelper\n\n\n\n[![.NET Builds](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/build.yml/badge.svg)](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/build.yml)\n[![.NET Tests](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/tests.yml/badge.svg)](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/tests.yml)\n[![Generate and Publish Documentation](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/documentation.yml/badge.svg)](https://github.com/JeremyLikness/SqliteWasmHelper/actions/workflows/documentation.yml)\n\nDownload this package from [Nuget](https://www.nuget.org/packages/SqliteWasmHelper/).\n\n`SqliteWasmHelper` is a package designed to make it easy to work with SQLite databases\nin Blazor Wasm apps. Although you *could* install [Eric Sink](https://github.com/ericsink)'s \n[SQLitePCLRaw.bundle_e_sqlite3](https://www.nuget.org/packages/SQLitePCLRaw.bundle_e_sqlite3/) \npackage directly, that will only provide an in-memory implementation. This package \nautomatically injects the code needed to persist your database in cache with the\nhelp of [EF Core](https://docs.microsoft.com/ef). \n\n\u003e **WARNING** The browser cache is both easily accessible by the end user and can be flushed\nany time. Do not use SQLite in the browser to store sensitive data. Do not use it to store\nuser-entered data unless the data is temporary in nature or you have a process to synchronize\ndata to the back end. \n\n## Links\n\n- [MIT license](./LICENSE.txt)\n- [API documentation](https://github.com/JeremyLikness/SqliteWasmHelper/blob/main/SqliteWasmHelper/docs/SqliteWasmHelper.md)\n- [Release notes](./ReleaseNotes.md)\n- [Contributing](./CONTRIBUTING.md)\n- [Code of conduct](./CODE_OF_CONDUCT.md)\n\n## Quick start\n\nLet's get right to the point! Boring text follows, a more exciting video with questionable audio quality can be viewed here:\n\n📽️ [How to use SQLiteWasmHelper to add EF Core 6.0 and SQLite to your Blazor WebAssembly projects](https://youtu.be/ZeJISZgy-FM)\n\n### Prerequisites\n\nFor the Wasm client to get properly linked, you must have the [WebAssembly Tools workload](https://docs.microsoft.com/en-us/core/blazor/webassembly-native-dependencies)\ninstalled.\n\n### Instlallation and use\n\n1. Install the lastest [SQlite in WebAssembly helper NuGet package](https://www.nuget.org/packages/SqliteWasmHelper/) or reference the `SqliteWasmHelper` project. This automatically installs all necessary dependencies:\n    1. `SqliteWasmHelper`\n    1. [Entity Framework Core and the SQLite provider](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite.Core/)\n    1. The [SQLitePCLRaw.bundle](https://www.nuget.org/packages/SQLitePCLRaw.bundle_e_sqlite3/) for running SQLite in WebAssembly\n1. Add the following to the `.csproj` file for your Blazor WebAssembly project (it can be added to an\nexisting `PropertyGroup`):\n    ```xml\n    \u003cPropertyGroup\u003e\n        \u003cWasmBuildNative\u003etrue\u003c/WasmBuildNative\u003e\n    \u003c/PropertyGroup\u003e\n    ```\n1. Add `using SqliteWasmHelper;` to the top of the `Program.cs` file in your Blazor WebAssembly project\n1. Use the extension method to add a special `DbContext` factory:\n    ```csharp\n      builder.Services.AddSqliteWasmDbContextFactory\u003cThingContext\u003e(\n        opts =\u003e opts.UseSqlite(\"Data Source=things.sqlite3\"));\n    ```\n1. Inject the factory into the components that need it\n    ```csharp\n    @inject ISqliteWasmDbContextFactory\u003cThingContext\u003e Factory\n    ```\n1. Use the `DbContext` as you normally would\n    ```csharp\n    using var ctx = await Factory.CreateDbContextAsync();\n    ctx.Things.Add(new Thing { Name = newThing });\n    await ctx.SaveChangesAsync();\n    ```\n1. If you want access to the file, look at the [GenerateDownloadLinkAsync](SqliteWasmHelper/docs/SqliteWasmHelper/IBrowserCache/GenerateDownloadLinkAsync.md) documentation\nor use/customize the [BackupLink](https://github.com/JeremyLikness/SqliteWasmHelper/blob/main/SqliteWasmHelper/BackupLink.razor) component.\n\nThe `BlazorWasmExample` is a working example to show it in use.\n\n\u003e **⚠️ IMPORTANT** The helper requires JavaScript interop to store the database in cache. For this reason, it is important you **always call `SaveChangesAsync` not `SaveChanges` when saving updates**. Any other operations such as calling `EnsureCreated` or executing queries can be done either synchronously or asynchronously.\n\n\u003e **⚠️ ALSO IMPORTANT** The helper calls `EnsureCreated` on the database before \npassing control to JavaScript. This won't  conflict with other calls but may lead to \nunexpected behavior. For example, if you seed your database based on a successful call, \nyou will need to change your logic to check for data in tables instead of using the `EnsureCreated`\nresult.\n\n## How it works\n\nWhen your app requests a `DbContext`, the special factory uses JavaScript interop to \ncheck for the existence of a cache. If the cache exists, it is restored and returned,\notherwise a new database is created.\n\n```mermaid\ngraph TD\nA(Start) --\u003e B[Get filename from data source]\nB --\u003e C{First time?}\nC --\u003e|Yes| D[Generate restore filename]\nC --\u003e|No| E[Generate backup filename]\nD --\u003e G[Call JavaScript]\nE --\u003e F[Backup database]\nF --\u003e G\nG --\u003e H{First time?}\nH --\u003e|Yes| I{Backup in cache?}\nH --\u003e|No| K[Store backup to cache]\nI --\u003e|Yes| J[Restore to Wasm filesystem]\nI --\u003e |No| L\nJ --\u003e L[Return to DotNet]\nK --\u003e L\nL --\u003e M{Backup loaded from cache?}\nM --\u003e |Yes| N[Restore database]\nM --\u003e |No| O(End)\nN --\u003e O\n```\n\nThe first time you context is generated, the database will be restored if a backup exists in cache. Any call to `SaveChangesAsync` will result in the database being saved to cache.\n\nTo see the cache, open developer tools in your browser and navigate to Application -\u003e Cache -\u003e Cache Storage -\u003e SqliteWasmHelper. The key for your database is `/data/cache/filename`.\n\n## Access your database for troubleshooting\n\nRun the application and use F12 to open developer tools. Navigate to the Console tab. Open the cache:\n\n```javascript\nconst cache = await caches.open('SqliteWasmHelper');\n```\n\nNow load the database backup from the cache. Swap `things.db` with the filename of *your* database.\n\n```javascript\nconst resp = await cache.match('/data/cache/things.db');\n```\n\nIf the `resp` instance is populated, access the underlying blob:\n\n```javascript\nconst blob = await resp.blob();\n```\n\nFinally, generate the link. This should emit a link to the console you can click on to download your database.\n\n```javascript\nURL.createObjectURL(blob);\n```\n\nYou can then examine the database with your SQLite tool of choice. You can use a similar approach for synchronization but sending the blob to the server.\n\n## API documentation\n\nRead the autogenerated\n[API Docs](SqliteWasmHelper/docs/SqliteWasmHelper.md).\n\n## Release notes\n\nRead the [release notes](./ReleaseNotes.md).\n\n## Summary\n\nQuestions? DM [@JeremyLikness](https://twitter.com/JeremyLikness) or open a\n[GitHub issue](https://github.com/JeremyLikness/SqliteWasmHelper/issues/new).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremylikness%2Fsqlitewasmhelper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremylikness%2Fsqlitewasmhelper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremylikness%2Fsqlitewasmhelper/lists"}