Don't double squash (#3182)

This PR changes the way `Store.squashHistoryEntries` works. Previously,
the function would iterate through every entry and squash it against the
current entry (using `squashRecordDiffs`) to get the new current entry.
However, `squashRecordDiffs` does basically the same pattern, iterating
through the properties of every diff. As a result, each diff would be
iterated through twice: once as itself, and once again in the next
current.

This PR tweaks the function to operate on as many diffs as possible at
once.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

- [x] Unit Tests
- [ ] End to end tests

### Release Notes

- Minor improvement when modifying multiple shapes at once.
This commit is contained in:
Steve Ruiz 2024-03-20 12:44:09 +00:00 committed by GitHub
parent c28f11e4ba
commit 72ae8ddefd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -907,7 +907,9 @@ export function squashRecordDiffs<T extends UnknownRecord>(
}
/**
* Collect all history entries by their sources.
* Collect all history entries by their adjacent sources.
* For example, [user, user, remote, remote, user] would result in [user, remote, user],
* with adjacent entries of the same source squashed into a single entry.
*
* @param entries - The array of history entries.
* @returns A map of history entries by their sources.
@ -916,28 +918,29 @@ export function squashRecordDiffs<T extends UnknownRecord>(
function squashHistoryEntries<T extends UnknownRecord>(
entries: HistoryEntry<T>[]
): HistoryEntry<T>[] {
const result: HistoryEntry<T>[] = []
if (entries.length === 0) return []
let current = entries[0]
const chunked: HistoryEntry<T>[][] = []
let chunk: HistoryEntry<T>[] = [entries[0]]
let entry: HistoryEntry<T>
for (let i = 1, n = entries.length; i < n; i++) {
entry = entries[i]
if (current.source !== entry.source) {
result.push(current)
current = entry
} else {
current = {
source: current.source,
changes: squashRecordDiffs([current.changes, entry.changes]),
}
if (chunk[0].source !== entry.source) {
chunked.push(chunk)
chunk = []
}
chunk.push(entry)
}
// Push the last chunk
chunked.push(chunk)
result.push(current)
return devFreeze(result)
return devFreeze(
chunked.map((chunk) => ({
source: chunk[0].source,
changes: squashRecordDiffs(chunk.map((e) => e.changes)),
}))
)
}
/** @public */