Comments (8)
One small comment:
The version should be a whole number > 0. The reason it is f64 in web-sys is that all numbers in javascript are f64. This has a consequence that numbers above a certain value are not possible to represent (as f64). This number is exposed as Number.MAX_SAFE_INTEGER
in javascript. For this reason, I would use NonZeroU32
(u32::max_value() < Number.MAX_SAFE_INTEGER
). If you expose an f64 parameter, you're just giving the library user a footgun - I'm pretty sure fractional versions get rounded through some crazy scheme (and I have no idea what happens for NaN).
Related reading: w3c/IndexedDB#147
from gloo.
I've created a futures based wrapper around indexed db: https://crates.io/crates/rexie
Feedback on API is welcome.
from gloo.
@c410-f3r It's not clear to me why two separate interfaces are proposed. Could you share more about your thinking here?
I have an additional question: should we guarantee that handles onto the database are unique? E.g. if a particular table is opened somewhere, then any subsequent calls to open the same table fail. I haven't completely thought this through yet, but it feels like at this abstraction layer that might help save some (accidental) concurrency problems.
I guess this would in particular be applicable to the IndexedDb
interface in the proposal. It doesn't have a constructor other than Default
which means that when two handles to it are opened without realizing they're not unique, the underlying data might be mixed and arbitrarily overwritten, leading to database corruption.
from gloo.
@c410-f3r It's not clear to me why two separate interfaces are proposed. Could you share more about your thinking here?
Previous discussions showed a desire for a simple key/value API but that would effectively limit the user's freedom, preventing him to use some built-in features like version
. These two APIs are an attempt to reach a middle ground.
I have an additional question: should we guarantee that handles onto the database are unique?
Nice question. IndexeDB
deals with these concurrency problems by versioning the database and for the IndexedDb
API, we can generate a new version for each modification/transaction (clear, delete, set) or simply block the user request using the onblocked
event.
from gloo.
@c410-f3r I still not entirely convinced this would be the right way to split the API. Instead I feel we could likely have the best of both worlds through a single API with different constructors. To illustrate:
Generalized API
// Open a database
let db = await? Idb::open("cat_db", 1);
let db = await? Idb::builder("cat_db", 1)
.on_upgrade(|&db, diff_data| /* handle upgrade code here */)
.build();
// Open a "store" on a database (idb equivalent of a table)
let store = await? Idb::open_store("cat_db", 1, "cats");
let store = await? db.store("cats");
let store = await? db.store_builder("cats")
.key_path("id")
.auto_increment(true)
.build();
// set, get, del a value.
await? store.set("cat", "chashu");
let val = await? store.get("cat");
assert_eq(val, "chashu");
await? store.delete("cat");
"Convenient" Subset
let store = await? Idb::open_store("my_db", 1, "cats");
await? store.set("cat", "chashu");
let val = await? store.get("cat");
await? store.delete("cat");
note: because of the nature of idb, all of these methods have to be async. I believe going with futures over callbacks is the right approach here.
The convenient subset would allow people to store data rather easily, just by exposing a few convenience functions. This would also allow us to sidestep any type problems about code that wants to be able to take either type of database -- which would seem like could definitely become a thing if someone ever moves from the simple API to the full API because they need more features.
Something else I just thought of: idb doesn't accept versions under 1. We could possibly leverage NonZeroUsize for that. With the tradeoff that floats can no longer be used as the version number, which I have a gut feeling about unlikely to be a problem for practical use.
from gloo.
@yoshuawuyts Great idea! This unifies both APIs in a graceful way.
Just an opinion. To avoid user input, it is even possible to provide methods like:
let _ = await? Idb::open_with_automatic_versioning("cat_db");
let _ = await? Idb::open_store_with_latest_version("cat_db", "cats");
let _ = await? Idb::open_fixed_store_with_latest_version("cat_db");
Something else I just thought of: idb doesn't accept versions under 1. We could possibly leverage NonZeroUsize for that
IdbOpenDbOptions
requires f64
and with NonZeroUsize
, it would be necessary to convert NonZeroUsize
-> usize
and then cast usize
-> f64
. I think an assert!(v >= 1.0)
should be enough.
from gloo.
Indexedb is hardddddddd!
I've been trying to make progress on a rust-y wrapper, but here are so many moving parts that it's really hard to come up with a good api. For example: https://www.w3.org/TR/IndexedDB-2/#handling-versionchange shows how to reload the page when the same origin on a different browser page requests an upgrade and you have a database open.
I can think of two ways to make progress, either trying to model indexeddb as a state machine and working out what different states it can be in, or trying to list all the things a user might want to do with it.
If category theory taught us anything, it is that the way to handle a hard problem is to decompose it into smaller simpler pieces and then re-assemble them. But I'm not sure if you can do that with the indexeddb api because all parts of it interact.
from gloo.
This thread will be closed since I personally don't have the motivation or time to continue pursuing this API.
Feel free to create another proposal or re-open this issue if needed. Good luck!
from gloo.
Related Issues (20)
- Patch required to fix confusing docs that still show `from_serde` and `into_serde` examples the wrong way around
- `gloo_net`'s `RequestBuilder` is not public
- Use OnceCell for gloo-history HOT 2
- gloo-histroy Support custom query decoder / encoder HOT 9
- Retries for EventSource HOT 1
- async wasm tests don't seem to actually do anything HOT 2
- [history] BrowserHistory: Loaded wrong state HOT 2
- gloo-net: Allow RequestBuilder.query to accept a struct that implements serde::Serialize as an argument HOT 1
- How to close a WebSocket after calling `.split()` ?
- Cloning gloo-worker bridges does not assign new HandlerIds
- Not working with recent yew-0.21.0 HOT 1
- Blob & ObjecUrl generate invalid dowload link HOT 3
- Allow calling `terminate` on workers
- [history] Inconsitent type between gloo_history and gloo_utils HOT 10
- Remove event in another event HOT 2
- Complete gloo-worker webassembly example running in a browser HOT 2
- Feature request: MissedTickBehavior for gloo_timers::future::IntervalStream
- Documentation - broken method reference
- Error `closure invoked recursively or after being dropped` when opening `ObjectUrl` via `window().open_with_url()`
- [`gloo_history::HashHistory`] Assertion failed when calling `HashHistory`'s `location()`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gloo.