From c931d90f34fd8e1a91fb8dcb76dcc2ac5a41555a Mon Sep 17 00:00:00 2001 From: Domagoj Kriskovic Date: Mon, 15 Jan 2024 10:02:53 +0100 Subject: [PATCH] Wait for "doc:saved" event before compiling (#16153) * wait doc:saved before compiling * Refactor DocumentCompiler class to handle pending operations before compilation * add timeout for pending op * Increase PENDING_OP_MAX_WAIT to 10000 milliseconds * check if currentDoc exists * check doc id on doc:saved * Fix conditional statement * Refactor to add and remove event listeners for doc:saved event * check if getPendingOp exists * typeof getPendingOp * forgot to push updates * add flush-changes event * use promise for handling pending operations * Remove console.logs * add isAwaitingBufferedOps * Revert "add isAwaitingBufferedOps" This reverts commit 56b0bbc13caf6375d1cf50e8f65f599e7263c404. * move _awaitBufferedOps in try block * dont check for matching doc id * add a todo comment GitOrigin-RevId: 9225e7d1a7a69385dc1a26bf7663f89f59db6a8a --- .../js/features/pdf-preview/util/compiler.js | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/services/web/frontend/js/features/pdf-preview/util/compiler.js b/services/web/frontend/js/features/pdf-preview/util/compiler.js index 2887b9234b..75b3f5a26b 100644 --- a/services/web/frontend/js/features/pdf-preview/util/compiler.js +++ b/services/web/frontend/js/features/pdf-preview/util/compiler.js @@ -13,6 +13,9 @@ const AUTO_COMPILE_MAX_WAIT = 5000 // and then again on ack. const AUTO_COMPILE_DEBOUNCE = 2500 +// If there is a pending op, wait for it to be saved before compiling +const PENDING_OP_MAX_WAIT = 10000 + const searchParams = new URLSearchParams(window.location.search) export default class DocumentCompiler { @@ -60,6 +63,40 @@ export default class DocumentCompiler { maxWait: AUTO_COMPILE_MAX_WAIT, } ) + + this._onDocSavedCallback = null + } + + async _awaitBufferedOps() { + const removeEventListener = () => { + clearTimeout(this.pendingOpTimeout) + if (this._onDocSavedCallback) { + window.removeEventListener('doc:saved', this._onDocSavedCallback) + this._onDocSavedCallback = null + } + } + + removeEventListener() + return new Promise(resolve => { + if (!this.currentDoc?.hasBufferedOps?.()) { + return resolve() + } + + this._onDocSavedCallback = docSavedParams => { + // TODO: it's possible that there's more than one doc open with buffered ops, and ideally we'd wait for all docs to be flushed + removeEventListener() + resolve() + } + + clearTimeout(this.pendingOpTimeout) + this.pendingOpTimeout = setTimeout(() => { + removeEventListener() + resolve() + }, PENDING_OP_MAX_WAIT) + + window.addEventListener('doc:saved', this._onDocSavedCallback) + window.dispatchEvent(new CustomEvent('flush-changes')) + }) } // The main "compile" function. @@ -83,13 +120,13 @@ export default class DocumentCompiler { } try { + await this._awaitBufferedOps() + // reset values this.setChangedAt(0) // TODO: wait for doc:saved? this.setSavedAt(0) this.validationIssues = undefined - window.dispatchEvent(new CustomEvent('flush-changes')) // TODO: wait for this? - const params = this.buildCompileParams(options) const t0 = performance.now()