diff --git a/services/web/app/src/Features/Compile/ClsiCacheManager.mjs b/services/web/app/src/Features/Compile/ClsiCacheManager.mjs index de78c0edc4..496bc9a97b 100644 --- a/services/web/app/src/Features/Compile/ClsiCacheManager.mjs +++ b/services/web/app/src/Features/Compile/ClsiCacheManager.mjs @@ -252,29 +252,53 @@ async function createTemplateClsiCache({ const compileBackendClass = Settings.apis.clsi.submissionBackendClass const submissionId = new ObjectId().toString() const editorId = Crypto.randomUUID() + const historyId = project.overleaf.history.id + const rawSnapshot = { + files: Object.fromEntries( + docEntries + .map(doc => [doc.path.replace(/^\//, ''), { content: doc.docLines }]) + .concat( + fileEntries.map(file => [ + file.path.replace(/^\//, ''), + { hash: file.file.hash, byteLength: 0 /* stub */ }, + ]) + ) + ), + } + const globalBlobs = new Set() + ClsiManager.collectGlobalBlobsFromRawSnapshot(rawSnapshot, globalBlobs) + let rootResourcePath + for (const doc of docEntries) { + if (project.rootDoc_id.equals(doc.doc._id)) { + rootResourcePath = doc.path.replace(/^\//, '') + break + } + } const options = { editorId, compileGroup, compileBackendClass, timeout: 60, - syncType: 'full', + syncType: 'history-full', compileFromClsiCache: false, populateClsiCache: true, enablePdfCaching: false, pdfCachingMinChunkSize: 0, metricsPath: 'clsi-cache-template', + rootResourcePath, + historyId, + rawSnapshot, + rawChangeOperations: [], + globalBlobs: Array.from(globalBlobs), + // Trigger a full sync + baseHistoryVersion: Date.now(), } const req = ClsiManager._finaliseRequest( submissionId, options, project, - Object.fromEntries( - docEntries.map(doc => [ - doc.path, - { _id: doc.doc._id, lines: doc.docLines.split('\n') }, - ]) - ), - Object.fromEntries(fileEntries.map(file => [file.path, file.file])) + [], + [] ) let clsiServerId = await ClsiCookieManager.promises.getServerId( submissionId, diff --git a/services/web/app/src/Features/Compile/ClsiManager.mjs b/services/web/app/src/Features/Compile/ClsiManager.mjs index d310d95f79..3e8e9c35e7 100644 --- a/services/web/app/src/Features/Compile/ClsiManager.mjs +++ b/services/web/app/src/Features/Compile/ClsiManager.mjs @@ -912,6 +912,17 @@ function _collectGlobalBlobs(rawChangeOperations) { return globalBlobs } +function collectGlobalBlobsFromRawSnapshot(rawSnapshot, globalBlobs) { + for (const { hash, rangesHash } of Object.values(rawSnapshot.files)) { + if (hash && HistoryManager.isGlobalBlob(hash)) { + globalBlobs.add(hash) + } + if (rangesHash && HistoryManager.isGlobalBlob(rangesHash)) { + globalBlobs.add(rangesHash) + } + } +} + async function _buildRequestFromHistoryFull( projectId, historyId, @@ -933,14 +944,7 @@ async function _buildRequestFromHistoryFull( ]) const rawChangeOperations = _rawChangeOperationsFromChanges(rawChanges) const globalBlobs = _collectGlobalBlobs(rawChangeOperations) - for (const { hash, rangesHash } of Object.values(rawSnapshot.files)) { - if (hash && HistoryManager.isGlobalBlob(hash)) { - globalBlobs.add(hash) - } - if (rangesHash && HistoryManager.isGlobalBlob(rangesHash)) { - globalBlobs.add(rangesHash) - } - } + collectGlobalBlobsFromRawSnapshot(rawSnapshot, globalBlobs) options = { ...options, syncType: 'history-full', @@ -1258,6 +1262,7 @@ function _getClsiServerIdFromResponse(response) { } export default { + collectGlobalBlobsFromRawSnapshot, _finaliseRequest, sendRequest: callbackifyMultiResult(sendRequest, [ 'status', diff --git a/services/web/app/src/Features/Project/ProjectCreationHandler.mjs b/services/web/app/src/Features/Project/ProjectCreationHandler.mjs index 718b646f9f..eb78a4582d 100644 --- a/services/web/app/src/Features/Project/ProjectCreationHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectCreationHandler.mjs @@ -310,6 +310,9 @@ async function _createRootDoc(project, ownerId, docLines) { null ) await ProjectEntityUpdateHandler.promises.setRootDoc(project._id, doc._id) + // update the rootDoc id on the project in memory + // used to identify the rootResourcePath when doing an initial compile from history + project.rootDoc_id = doc._id return doc } catch (error) { throw OError.tag(error, 'error adding root doc when creating project')