perf: use lazy load provider for IDB and SQLITE (#3351)
This commit is contained in:
1 parent
e3f66d7e22
commit
20ee9d485d
25 files changed
+481
-758
No files matched your search
@@ -3,6 +3,7 @@ import {
|
||||
applyUpdate,
|
||||
type Doc,
|
||||
encodeStateAsUpdate,
|
||||
encodeStateVector,
|
||||
encodeStateVectorFromUpdate,
|
||||
} from 'yjs';
|
||||
|
||||
@@ -33,30 +34,30 @@ export const createLazyProvider = (
|
||||
let connected = false;
|
||||
const pendingMap = new Map<string, Uint8Array[]>(); // guid -> pending-updates
|
||||
const disposableMap = new Map<string, Set<() => void>>();
|
||||
const connectedDocs = new Set();
|
||||
const connectedDocs = new Set<string>();
|
||||
let datasourceUnsub: (() => void) | undefined;
|
||||
|
||||
async function syncDoc(doc: Doc) {
|
||||
const guid = doc.guid;
|
||||
// perf: optimize me
|
||||
const currentUpdate = encodeStateAsUpdate(doc);
|
||||
|
||||
const remoteUpdate = await datasource.queryDocState(guid, {
|
||||
stateVector: encodeStateVectorFromUpdate(currentUpdate),
|
||||
stateVector: encodeStateVector(doc),
|
||||
});
|
||||
|
||||
const updates = [currentUpdate];
|
||||
pendingMap.set(guid, []);
|
||||
|
||||
if (remoteUpdate) {
|
||||
applyUpdate(doc, remoteUpdate, selfUpdateOrigin);
|
||||
const newUpdate = encodeStateAsUpdate(
|
||||
doc,
|
||||
encodeStateVectorFromUpdate(remoteUpdate)
|
||||
);
|
||||
updates.push(newUpdate);
|
||||
await datasource.sendDocUpdate(guid, newUpdate);
|
||||
}
|
||||
|
||||
const sv = remoteUpdate
|
||||
? encodeStateVectorFromUpdate(remoteUpdate)
|
||||
: undefined;
|
||||
|
||||
// perf: optimize me
|
||||
// it is possible the doc is only in memory but not yet in the datasource
|
||||
// we need to send the whole update to the datasource
|
||||
await datasource.sendDocUpdate(guid, encodeStateAsUpdate(doc, sv));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,10 +74,7 @@ export const createLazyProvider = (
|
||||
datasource.sendDocUpdate(doc.guid, update).catch(console.error);
|
||||
};
|
||||
|
||||
const subdocLoadHandler = (event: {
|
||||
loaded: Set<Doc>;
|
||||
removed: Set<Doc>;
|
||||
}) => {
|
||||
const subdocsHandler = (event: { loaded: Set<Doc>; removed: Set<Doc> }) => {
|
||||
event.loaded.forEach(subdoc => {
|
||||
connectDoc(subdoc).catch(console.error);
|
||||
});
|
||||
@@ -86,11 +84,11 @@ export const createLazyProvider = (
|
||||
};
|
||||
|
||||
doc.on('update', updateHandler);
|
||||
doc.on('subdocs', subdocLoadHandler);
|
||||
doc.on('subdocs', subdocsHandler);
|
||||
// todo: handle destroy?
|
||||
disposables.add(() => {
|
||||
doc.off('update', updateHandler);
|
||||
doc.off('subdocs', subdocLoadHandler);
|
||||
doc.off('subdocs', subdocsHandler);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,6 +125,7 @@ export const createLazyProvider = (
|
||||
connectedDocs.add(doc.guid);
|
||||
setupDocListener(doc);
|
||||
await syncDoc(doc);
|
||||
|
||||
await Promise.all(
|
||||
[...doc.subdocs]
|
||||
.filter(subdoc => subdoc.shouldLoad)
|
||||
@@ -150,6 +149,7 @@ export const createLazyProvider = (
|
||||
disposables.forEach(dispose => dispose());
|
||||
});
|
||||
disposableMap.clear();
|
||||
connectedDocs.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user