From b3c797aad1c82a919552ae8f1dc83bb1a7714f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 28 May 2024 10:31:17 +0200 Subject: [PATCH] Dont remove assets still referenced by other recordings (#492) --- .changeset/fluffy-cars-provide.md | 5 +++ packages/replayio/src/commands/record.ts | 2 +- packages/replayio/src/commands/remove.ts | 6 ++-- packages/replayio/src/commands/upload.ts | 2 +- .../src/utils/recordings/removeFromDisk.ts | 34 ++++++++++++++++--- 5 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 .changeset/fluffy-cars-provide.md diff --git a/.changeset/fluffy-cars-provide.md b/.changeset/fluffy-cars-provide.md new file mode 100644 index 00000000..218dcee8 --- /dev/null +++ b/.changeset/fluffy-cars-provide.md @@ -0,0 +1,5 @@ +--- +"replayio": patch +--- + +Assets (like source maps) still referenced by other recordings won't be removed prematurely when removing a recording diff --git a/packages/replayio/src/commands/record.ts b/packages/replayio/src/commands/record.ts index 44d9559c..ef0509bb 100644 --- a/packages/replayio/src/commands/record.ts +++ b/packages/replayio/src/commands/record.ts @@ -54,7 +54,7 @@ async function record(url: string = "about:blank") { } } - const recordingsAfter = await getRecordings(processGroupId); + const recordingsAfter = getRecordings(processGroupId); const nextCrashedRecordings: LocalRecording[] = []; const nextRecordings: LocalRecording[] = []; diff --git a/packages/replayio/src/commands/remove.ts b/packages/replayio/src/commands/remove.ts index 6ac366f4..8160f237 100644 --- a/packages/replayio/src/commands/remove.ts +++ b/packages/replayio/src/commands/remove.ts @@ -15,7 +15,7 @@ registerCommand("remove") .action(remove); async function remove(shortIds: string[], { all = false }: { all?: boolean }) { - const allRecordings = await getRecordings(); + const allRecordings = getRecordings(); if (allRecordings.length === 0) { console.log("No recordings found"); @@ -47,10 +47,10 @@ async function remove(shortIds: string[], { all = false }: { all?: boolean }) { console.log(printRecordings(selectedRecordings, { showHeaderRow: false })); for (const recording of selectedRecordings) { - await removeFromDisk(recording.id); + removeFromDisk(recording.id); } - const countAfter = (await getRecordings()).length; + const countAfter = getRecordings().length; if (countAfter < countBefore) { console.log("%s recording(s) deleted", countBefore - countAfter); diff --git a/packages/replayio/src/commands/upload.ts b/packages/replayio/src/commands/upload.ts index 38ced2f3..61e78b89 100644 --- a/packages/replayio/src/commands/upload.ts +++ b/packages/replayio/src/commands/upload.ts @@ -23,7 +23,7 @@ async function upload( all?: boolean; } = {} ) { - const recordings = await getRecordings(); + const recordings = getRecordings(); let selectedRecordings: LocalRecording[] = []; if (shortIds.length > 0) { diff --git a/packages/replayio/src/utils/recordings/removeFromDisk.ts b/packages/replayio/src/utils/recordings/removeFromDisk.ts index 00d25c32..66efa124 100644 --- a/packages/replayio/src/utils/recordings/removeFromDisk.ts +++ b/packages/replayio/src/utils/recordings/removeFromDisk.ts @@ -4,7 +4,24 @@ import { recordingLogPath, recordingsPath } from "./config"; import { debug } from "./debug"; import { getRecordings } from "./getRecordings"; import { readRecordingLogLines } from "./readRecordingLogLines"; -import { LogEntry, RECORDING_LOG_KIND } from "./types"; +import { LocalRecording, LogEntry, RECORDING_LOG_KIND } from "./types"; + +function getAssetsUsageMap(recordings: LocalRecording[]) { + const usageMap: Record = {}; + + for (const recording of recordings) { + for (const sourceMap of recording.metadata.sourceMaps) { + usageMap[sourceMap.path] ??= 0; + usageMap[sourceMap.path]++; + + for (const originalSource of sourceMap.originalSources) { + usageMap[originalSource.path] ??= 0; + usageMap[originalSource.path]++; + } + } + } + return usageMap; +} export function removeFromDisk(id?: string) { if (id) { @@ -13,15 +30,22 @@ export function removeFromDisk(id?: string) { const recordings = getRecordings(); const recording = recordings.find(recording => recording.id.startsWith(id)); if (recording) { + const assetsUsageMap = getAssetsUsageMap(recordings); + const { metadata, path } = recording; metadata.sourceMaps.forEach(sourceMap => { - debug("Removing recording source-map file %s", sourceMap.path); - removeSync(sourceMap.path); + if (assetsUsageMap[sourceMap.path] === 1) { + debug("Removing recording source-map file %s", sourceMap.path); + removeSync(sourceMap.path); + removeSync(sourceMap.path.replace(/\.map$/, ".lookup")); + } sourceMap.originalSources.forEach(source => { - debug("Removing recording original source file %s", source.path); - removeSync(source.path); + if (assetsUsageMap[source.path] === 1) { + debug("Removing recording original source file %s", source.path); + removeSync(source.path); + } }); });