fix(y-indexeddb): alert user when write operation unfinished (#2085)
This commit is contained in:
@@ -240,6 +240,31 @@ describe('indexeddb provider', () => {
|
|||||||
expect(yDoc.getMap().get('foo')).toBe('bar');
|
expect(yDoc.getMap().get('foo')).toBe('bar');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('beforeunload', async () => {
|
||||||
|
const oldAddEventListener = window.addEventListener;
|
||||||
|
window.addEventListener = vi.fn((event: string, fn, options) => {
|
||||||
|
expect(event).toBe('beforeunload');
|
||||||
|
return oldAddEventListener(event, fn, options);
|
||||||
|
});
|
||||||
|
const oldRemoveEventListener = window.removeEventListener;
|
||||||
|
window.removeEventListener = vi.fn((event: string, fn, options) => {
|
||||||
|
expect(event).toBe('beforeunload');
|
||||||
|
return oldRemoveEventListener(event, fn, options);
|
||||||
|
});
|
||||||
|
const doc = new Doc();
|
||||||
|
const provider = createIndexedDBProvider('1', doc);
|
||||||
|
const map = doc.getMap('map');
|
||||||
|
map.set('1', 1);
|
||||||
|
provider.connect();
|
||||||
|
await provider.whenSynced;
|
||||||
|
|
||||||
|
expect(window.addEventListener).toBeCalledTimes(1);
|
||||||
|
expect(window.removeEventListener).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
window.addEventListener = oldAddEventListener;
|
||||||
|
window.removeEventListener = oldRemoveEventListener;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('milestone', () => {
|
describe('milestone', () => {
|
||||||
|
|||||||
@@ -21,6 +21,25 @@ const snapshotOrigin = Symbol('snapshot-origin');
|
|||||||
|
|
||||||
let mergeCount = 500;
|
let mergeCount = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
const saveAlert = (event: BeforeUnloadEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
return (event.returnValue =
|
||||||
|
'Data is not saved. Are you sure you want to leave?');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const writeOperation = async (op: Promise<unknown>) => {
|
||||||
|
window.addEventListener('beforeunload', saveAlert, {
|
||||||
|
capture: true,
|
||||||
|
});
|
||||||
|
await op;
|
||||||
|
window.removeEventListener('beforeunload', saveAlert, {
|
||||||
|
capture: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export function setMergeCount(count: number) {
|
export function setMergeCount(count: number) {
|
||||||
mergeCount = count;
|
mergeCount = count;
|
||||||
}
|
}
|
||||||
@@ -169,9 +188,9 @@ export const createIndexedDBProvider = (
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
await store.put(data);
|
await writeOperation(store.put(data));
|
||||||
} else {
|
} else {
|
||||||
await store.put(data);
|
await writeOperation(store.put(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +224,8 @@ export const createIndexedDBProvider = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
await db.put('workspace', {
|
await writeOperation(
|
||||||
|
db.put('workspace', {
|
||||||
id,
|
id,
|
||||||
updates: [
|
updates: [
|
||||||
{
|
{
|
||||||
@@ -213,7 +233,8 @@ export const createIndexedDBProvider = (
|
|||||||
update: encodeStateAsUpdate(doc),
|
update: encodeStateAsUpdate(doc),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const updates = data.updates.map(({ update }) => update);
|
const updates = data.updates.map(({ update }) => update);
|
||||||
const fakeDoc = new Doc();
|
const fakeDoc = new Doc();
|
||||||
@@ -226,7 +247,8 @@ export const createIndexedDBProvider = (
|
|||||||
encodeStateAsUpdate(doc),
|
encodeStateAsUpdate(doc),
|
||||||
encodeStateAsUpdate(fakeDoc)
|
encodeStateAsUpdate(fakeDoc)
|
||||||
);
|
);
|
||||||
await store.put({
|
await writeOperation(
|
||||||
|
store.put({
|
||||||
...data,
|
...data,
|
||||||
updates: [
|
updates: [
|
||||||
...data.updates,
|
...data.updates,
|
||||||
@@ -235,7 +257,8 @@ export const createIndexedDBProvider = (
|
|||||||
update: newUpdate,
|
update: newUpdate,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
})
|
||||||
|
);
|
||||||
doc.transact(() => {
|
doc.transact(() => {
|
||||||
updates.forEach(update => {
|
updates.forEach(update => {
|
||||||
applyUpdate(doc, update);
|
applyUpdate(doc, update);
|
||||||
|
|||||||
Reference in New Issue
Block a user