Skip to content

Commit

Permalink
Support Firefox < 126: Don't use compoun indexes with auto-incremente…
Browse files Browse the repository at this point in the history
…d PK.
  • Loading branch information
dfahlander committed Jun 19, 2024
1 parent 1c4b5b0 commit 0e069f1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
11 changes: 6 additions & 5 deletions src/classes/version/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ export class Version implements IVersion {
// u is the update data from Y.js
// f is a flag indicating if the update comes from this client or another.
// Index use cases:
// * Load entire document: Use index k (part of [k+i] )
// * After object load, observe updates on a certain document since a given revision: Use index [k+i]
// * After initial sync, observe flagged updates since a given revision: Use index [f+i]. Local updates are flagged
// while remote updates are not.
// * Load entire document: Use index k
// * After object load, observe updates on a certain document since a given revision: Use index k or i since [k+i] is not supported before Firefox 126.
// * After initial sync, observe flagged updates since a given revision: Use index i and ignore unflagged.
// Could be using an index [f+i] but that wouldn't gain too much and Firefox before 126 doesnt support it.
// Local updates are flagged while remote updates are not.
//
{ [yProp.updTable]: '++i,[k+i],[f+i]' },
{ [yProp.updTable]: '++i,k' },
outSchema
);
}
Expand Down
51 changes: 33 additions & 18 deletions src/yjs/observeYDocUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
import type { EntityTable } from '../public/types/entity-table';
import { throwIfDestroyed } from './docCache';
import { liveQuery } from '../live-query';
import { cmp } from '../functions/cmp';

export function observeYDocUpdates(
provider: DexieYProvider,
Expand All @@ -22,32 +23,46 @@ export function observeYDocUpdates(
let initial = true;
const subscription = liveQuery(() => {
throwIfDestroyed(doc);
return Promise.all([(db.table(updatesTableName) as EntityTable<YUpdateRow, 'i'>)
.where('[k+i]')
.between([id, lastUpdateId], [id, Infinity], false)
.toArray()
.then((updates) => {
const updatesTable = db.table(updatesTableName) as EntityTable<
YUpdateRow,
'i'
>;
return Promise.all([
(lastUpdateId > 0
? updatesTable
.where('i')
.between(lastUpdateId, Infinity, false)
.toArray()
.then((updates) =>
updates.filter((update) => cmp(update.k, id) === 0)
)
: updatesTable.where({ k: id }).toArray()
).then((updates) => {
if (updates.length > 0) lastUpdateId = updates[updates.length - 1].i;
return updates;
}), db.table(parentTableName).where(':id').equals(id).count()])
}),
db.table(parentTableName).where(':id').equals(id).toArray(), // Why not just count() or get()? Because of cache only works with toArray() currently (optimization)
]);
}).subscribe(
([updates, parentRowExists]) => {
if (!parentRowExists) {
([updates, parentRow]) => {
if (parentRow.length === 0) {
// Row deleted. Destroy Y.Doc.
doc.destroy();
return;
}
throwIfDestroyed(doc);
Y.transact(
doc,
() => {
updates.forEach((update) => {
Y.applyUpdateV2(doc, update.u);
});
},
subscription,
false
);
if (updates.length > 0) {
Y.transact(
doc,
() => {
updates.forEach((update) => {
Y.applyUpdateV2(doc, update.u);
});
},
subscription,
false
);
}
if (initial) {
initial = false;
provider.on('load').fire(provider);
Expand Down

0 comments on commit 0e069f1

Please sign in to comment.