Releases: dexie/Dexie.js
Dexie v3.1.0-alpha.4
Observability broadcasted between tabs and workers
This version broadcasts txcommitted events between tabs and workers within same origin. It does so using BroadcastChannel so that not only tabs/windows are involved but also workers. This makes the built-in observability in Dexie a nice replacement for dexie-observable addon - and better, as that addon doesnt support workers, you will probably not need the dexie-observable addon anymore unless you use it as a base for dexie-syncable. Note also that dexie-observable slows down write performance a lot while the new built-in liveQuery feature does not.
Any part of an origin (a tab, a frame, a window, a web worker, shared worker or service worker) can observe the database no matter where the database was modified. Any thread can be either producer or consumer. If one peer writes to a Dexie instance, the other part can subscribe and get notified when something change.
Sparing DOM resources
Hidden tabs and minimized windows are not being bothered. Instead they get notified when they are visible again - with an accumulated result so nothing that had happened while being asleep will get lost.
Fallback to storage-event
The implementation falls back to using storage event and localStorage if browser doesnt support BroadcastChannel (Safari). The fallback implementation does only propagate changes across windows/tabs - not workers. It would however possible to make a standalone polyfill for BroadcastChannel that would support this for workers also. I currently don't know of any such polyfill except broadcastchannel-polyfill that currently not supports workers either. If I will have time I may complement it to support all kinds of workers as well as the structuring cloning.
Example
Worker
importScripts("https://unpkg.com/[email protected]");
const db = new Dexie('mydb');
db.version(1).stores({
logItems: '++id'
});
// Write to DB now and then...
setInterval (()=>{
db.logItems.add({foo: "bar", time: new Date()});
}, 1000);
Browser
import React from "react";
import Dexie from "dexie";
import { useLiveQuery } from "dexie-react-hooks";
const db = new Dexie('mydb');
db.version(1).stores({
logItems: '++id'
});
function LogWatcherComponent({limit = 50}) {
// Observe the last {limit} items in log:
const logItems = useLiveQuery(
() => db.logItems.reverse().limit(limit).toArray()
);
return <div>
<h1>Log viewer</h1>
<ul>
{logItems.map(logItem => <li key={logItem.id}>
{logItem.time.toLocaleTimeString()} {logItem.foo}
</li>)}
</ul>
</div>;
}
Read more?
Awesome React integration coming (Blog post)
Dexie v3.1.0-alpha.3
Just a bugfix for Dexie v3.1.0-alpha.1 and some typing corrections for dexie-react-hooks.
The big news are in Dexie v3.1.0-alpha.1!
Dexie v3.1.0-alpha.1
Dexie.js with Built-in observability
This version gives Dexie.js built-in observability which has been one of the Visions for dexie, earlier named db.observe().
It's called liveQuery() instead because it is not tied to a single db instance but it is capable of turning an expression or a async function with several statements and a final return value, into a observable (compatible with the es-observable spec).
import Dexie, { liveQuery } from "dexie";
// Turn any promise-returning function into an observable:
const observable = liveQuery(
() => getFriendsWithContactInfos({minAge: 18, maxAge: 64})
);
// The function can do several requests in a flow and/or in paralell
// and finally return a result.
// The result is what is being observed:
async function getFriendsWithContactInfos ({minAge, maxAge}) {
// Get all friends within range:
const friends = await db.friends
.where('age').between(minAge, maxAge, true, true)
.toArray();
// Map an array of contactInfos related to each friend:
const contactInfos = await Promise.all(friends =>
db.contactInfos.where({friendId: friend.id})
.toArray()
);
// Put the resolved contactInfos as an array prop on each friend to return
friends.forEach((friend, idx) => friend.contactInfos = contactInfos[idx]);
return friends; // This result is what will be observed by the observable.
}
Ok, so now we have an observable of this. Let's subscribe to it:
const subscription = observable.subscribe({
next: result => console.log("Got result:", result),
error: console.error
});
Lets update something that would affect the result of the query:
db.contactInfos.add({friendId: 2, type: "phoneNo", value: "1234567"});
When the above statement has been successfully committed to the DB, the function will re-execute if and only if friend with id 2 is within the queried age range (!), and our subscriber will be called with the new result of the callback.
The main reason for this new feature is better integration with frontend libraries like angular and react.
Especially for react, I've also release a new library dexie-react-hooks
with the hook useLiveQuery()
that will make data reactive data-fetching from IndexedDB very easy. Angular uses observables natively - so probably our ES-compliant observable can be used as it is.
A new library dexie-react-hooks
This library integrates React with the new liveQuery functionality described above
export function useLiveQuery<T, TDefault=undefined> (
querier: () => Promise<T> | T,
deps?: any[], // ...like deps for useMemo(). Defaults to empty array.
defaultResult?: TDefault // Default value returned while data is loading
) : T | TDefault;
Example
const db = new Dexie('news-db');
db.version(1).stores({
articles: '++id, title',
articleLikes: '[articleId+userId]'
});
function MyComponent({articleId, currentUser}) {
const article = useLiveQuery(() => db.articles.get(articleId), [articleId]);
const numLikes = useLiveQuery(() => db.articleLikes.where({articleId: articleId}).count(), [articleId]);
return <>
<Article article={article} numLikes={numLikes} />
<button onClick={() => db.articleLikes.put({userId: currentUser.id, articleId})}>
Like! {/* clicking button will increase like count if current user hadnt liked it before */}
</button>
</>;
}
See more examples in dexie-react-hooks
Dexie v3.0.3
Changes since 3.0.2
This release contains fixes that improves error resilience, typing correctness and bug fixes for some edge cases.
Typing fixes
- Fix Table.bulkGet return typing to include undefined #1098
- Allow readonly arrays for bulk put & get methods #1106
- Use error keys insted of values for typescript #1115
NOTE: Conditional types is now being used in dist/dexie.d.ts. If you are on an ancient typescript version (below 2.8) you will need to update typescript in your dev deps!
Improvements
- Verify schema on open #1108
- Repro + resolve issue #1112: typescript declaration of id makes autoInc fail #1119
- #1136: Allow declaration-only tables for TS users
Bugfixes
- Allow middleware hooks to return objects that contained field names that contain dotted strings #1130
- Resolve #1127 #1131
- #1146: Resolve #1145 Regression: SchemaError during version upgrade
- Bugfix of #1154 (PR #1155): WhereClause.equals(undefined) should fail, but it does not fail in dexie 3.0.0-3.0.2. It behaved correctly in dexie 2.x so it's a regression. It is important that libraries fail on invalid arguments so that subtle application bugs are nailed down more easily.
Addons
- Issue 1048 Typings of addons for Dexie 3.0 #1117
The addons are released with the "next" tag on npm, so please test them and help me verify that #1048 is solved:npm i [email protected] npm i [email protected]
- #1138: Dexie.Observable: startObserving function: remove read-only query in order to avoid TransactionInactiveError
- Bugfix of #1148 (PR #1149).
v3.0.3-rc.4
Dexie v3.0.3-rc.3
Dexie v3.0.3-rc.2
Another Release Candidate
Please help me test this release candidate that contains various fixes and improvements. It's released with the "next" tag on npm instead of "latest". Will release it with the "latest" tag after a week unless someone finds backward compability issues or regression bugs.
npm i [email protected]
New fixes since 3.0.3-rc.1
- #1146: Resolve #1145 Regression: SchemaError during version upgrade
- #1138: Dexie.Observable: startObserving function: remove read-only query in order to avoid TransactionInactiveError
- #1136: Allow declaration-only tables for TS users
Dexie-observable & dexie-syncable are on version 3.x now
This regards to the previous release candidate as well: You need to upgrade dexie-observable and dexie-syncable if you have them, to their latest major versions.
Dexie v3.0.3-rc.1
Release Candidate
Please help me test this release candidate that contains various fixes and improvements. It's released with the "next" tag on npm. Will release it with the "latest" tag after a week or two unless someone finds backward compability issues or regression bugs.
npm i [email protected]
Typing fixes
- Fix Table.bulkGet return typing to include undefined #1098
- Allow readonly arrays for bulk put & get methods #1106
- Use error keys insted of values for typescript #1115
Improvements
- Verify schema on open #1108
- Repro + resolve issue #1112: typescript declaration of id makes autoInc fail #1119
Bugfixes
- Allow middleware hooks to return objects that contained field names that contain dotted strings #1130
- Resolve #1127 #1131
Addons
- Issue 1048 Typings of addons for Dexie 3.0 #1117
The addons are released with the "next" tag on npm, so please test them and help me verify that #1048 is solved:npm i [email protected] npm i [email protected]
v3.0.2
Dexie v3.0.1
Maintainance Release
Changes
- Dexie.getDatabaseNames() use new standard IDBFactory.databases() API instead of old obsolete webkitGetDatabaseNames()
- Consistent names in DBCore’s typescript interfaces
- #1042 Be more unobtrusive with Promise.allSettled() and Promise.any()
Bug fixes
- #791 Dexie.Observable: Cannot read property 'indexOf' of null
- #1039 Table named 'schema' not working in Dexie 3
Other
- Released [email protected]
- Released [email protected]
- npm audit and updated dev dependencies.