Tavenem / Blazor.IndexedDB

IndexedDB access for Blazor.
MIT License
8 stars 1 forks source link

One IndexedDbService per table? #2

Open robertmclaws opened 4 months ago

robertmclaws commented 4 months ago

So I'm trying to figure out how to use this library if I have multiple tables, of the same type that needs to live in multiple tables (think managing a queue).

Does each table name correspond to the "storeName" in the instructions, and I need to have one IndexedDbService per table?

Thanks!

WilStead commented 4 months ago

IndexedDB object stores are better thought of as NoSQL key-value stores, rather than SQL-style tables. They don't enforce any structure on the objects you put in them, other than a shared key. The storeName parameter for the IndexedDb constructor corresponds directly to the name parameter of the IndexedDB API's objectStore method.

If your use case involves duplicate keys among your tables, then the solution you described is absolutely correct. Set up multiple IndexedDb objects with different store names. Instead of calling the AddIndexedDb convenience method, you can use keyed services to register separate instances of the service for each database. You can find the correct call here. I may make that process easier in a future update.

If you don't have duplicate keys among your objects, nothing prevents you from putting them all in the same store. Even if you would normally want them in separate tables in a SQL database, NoSQL storage like IndexedDB can be much more tolerant of mixed content. You can use whichever setup seems best to you for your use case.

robertmclaws commented 4 months ago

I really appreciate your time in building this library and answering my question so quickly.

I'm basically building an IndexedDB backing store for my SimpleMessageBus library, so I can build an out-of-band processing system for Blazor WebWorkers. The experience I'm looking for is to let the developer be able to open DevTools and see different "tables" in the IndexedDB to see which calls have succeeded or failed.

The other backing stores we've built (file system and Azure Storage Queues) have the same structure, so we want to be consistent.

I'm not 100% thrilled with the idea of having to inject multiple services, but I will try it and see what happens.

I'm looking at this library also. What I like about it is that it has essentially a DbContext that lets you have object sets mapped to different storenames in a single DB "object". What I don't like is how out of date its dependencies are.

You definitely do a better job of keeping your code up to date, making the end user NOT have to register the JS themselves, and your compiled JS does not have Webpack artifacts in it, so kudos to you there.

You might consider updating your JS assets under the covers are putting out an updated build. I think idb is on V8.0 now, among other dependencies. And if you have your assets compile to "wwwroot" instead of "assets", you won't have to have so many extra MSBuild instructions in your project file.

HTH!

WilStead commented 4 months ago

You make some excellent points.

I've just refactored the project to make the API a little bit more rational. I also updated and improved my build process a bit.

The service is now responsible only for JavaScript interop and should only be injected once (with a new extension AddIndexedDbService).

The IndexedDb object now serves much more as a representation of a database. They can be registered with dependency injection as keyed services with the AddIndexedDb extension, or simply instantiated with a constructor as needed.

The new IndexedDbStore object represents object stores directly, and the methods formerly used on the service are now instance methods on this object. The IndexedDb object contains a dictionary property for these, and also has an indexer for direct access. The indexer also supports lazy initialization: retrieving a store which was not explicitly added beforehand creates, adds, and returns it on demand.

v4.0 is available on NuGet now