File restore optimization - using snapshot timestamp and file paths (#28546)

* Use snapshot timestamp, remove request for paths at version

* Add timestamp to core Snapshot object

* Avoid mutating function argument

* Explain assumption about editable files

* snapshot.toRaw() in getContentAtVersion

* fix project-history acceptance test

* fix history_v1 test

* fix web tests

* Include the snapshot timestamp in stored chunks

---------

Co-authored-by: Eric Mc Sween <5454374+emcsween@users.noreply.github.com>
GitOrigin-RevId: 376a53e1f927cb56544e6782b47d80345655038c
This commit is contained in:
Domagoj Kriskovic
2025-09-23 12:41:41 +02:00
committed by Copybot
parent 46715191e3
commit 005eba7502
9 changed files with 177 additions and 74 deletions

View File

@@ -294,6 +294,8 @@ class Change {
if (this.v2DocVersions) {
snapshot.updateV2DocVersions(this.v2DocVersions)
}
snapshot.setTimestamp(this.timestamp)
}
/**

View File

@@ -36,7 +36,8 @@ class Snapshot {
return new Snapshot(
FileMap.fromRaw(raw.files),
raw.projectVersion,
V2DocVersions.fromRaw(raw.v2DocVersions)
V2DocVersions.fromRaw(raw.v2DocVersions),
raw.timestamp ? new Date(raw.timestamp) : undefined
)
}
@@ -45,8 +46,15 @@ class Snapshot {
const raw = {
files: this.fileMap.toRaw(),
}
if (this.projectVersion) raw.projectVersion = this.projectVersion
if (this.v2DocVersions) raw.v2DocVersions = this.v2DocVersions.toRaw()
if (this.projectVersion) {
raw.projectVersion = this.projectVersion
}
if (this.v2DocVersions) {
raw.v2DocVersions = this.v2DocVersions.toRaw()
}
if (this.timestamp != null) {
raw.timestamp = this.timestamp.toISOString()
}
return raw
}
@@ -54,13 +62,15 @@ class Snapshot {
* @param {FileMap} [fileMap]
* @param {string} [projectVersion]
* @param {V2DocVersions} [v2DocVersions]
* @param {Date} [timestamp]
*/
constructor(fileMap, projectVersion, v2DocVersions) {
constructor(fileMap, projectVersion, v2DocVersions, timestamp) {
assert.maybe.instance(fileMap, FileMap, 'bad fileMap')
this.fileMap = fileMap || new FileMap({})
this.projectVersion = projectVersion
this.v2DocVersions = v2DocVersions
this.timestamp = timestamp ?? null
}
/**
@@ -109,6 +119,17 @@ class Snapshot {
v2DocVersions.applyTo(this)
}
getTimestamp() {
return this.timestamp
}
/**
* @param {Date} timestamp
*/
setTimestamp(timestamp) {
this.timestamp = timestamp
}
/**
* The underlying file map.
* @return {FileMap}
@@ -268,6 +289,7 @@ class Snapshot {
files: rawFiles,
projectVersion,
v2DocVersions: rawV2DocVersions,
timestamp: this.getTimestamp() ?? undefined,
}
}

View File

@@ -74,6 +74,7 @@ export type RawSnapshot = {
files: RawFileMap
projectVersion?: string
v2DocVersions?: RawV2DocVersions | null
timestamp?: string
}
export type RawHistory = {

View File

@@ -1,10 +1,15 @@
'use strict'
const { expect } = require('chai')
const core = require('..')
const Change = core.Change
const File = core.File
const Operation = core.Operation
const {
Change,
File,
Operation,
AddFileOperation,
Snapshot,
Origin,
RestoreFileOrigin,
} = require('..')
describe('Change', function () {
describe('findBlobHashes', function () {
@@ -37,9 +42,9 @@ describe('Change', function () {
describe('RestoreFileOrigin', function () {
it('should convert to and from raw', function () {
const origin = new core.RestoreFileOrigin(1, 'path', new Date())
const origin = new RestoreFileOrigin(1, 'path', new Date())
const raw = origin.toRaw()
const newOrigin = core.Origin.fromRaw(raw)
const newOrigin = Origin.fromRaw(raw)
expect(newOrigin).to.eql(origin)
})
@@ -56,7 +61,19 @@ describe('Change', function () {
},
})
expect(change.getOrigin()).to.be.an.instanceof(core.RestoreFileOrigin)
expect(change.getOrigin()).to.be.an.instanceof(RestoreFileOrigin)
})
})
describe('applyTo', function () {
it('sets the timestamp on the snapshot', function () {
const snapshot = new Snapshot()
snapshot.addFile('main.tex', File.fromString(''))
const operation = new AddFileOperation('main.tex', File.fromString(''))
const now = new Date()
const change = new Change([operation], now)
change.applyTo(snapshot)
expect(snapshot.getTimestamp().toISOString()).to.equal(now.toISOString())
})
})
})