Files
orca/src/main/folder-workspace-diff-comments.ts
T
JinjingandOrca d41cb21e94 Sta 4062 folder note rollback (#14232)
* fix(persistence): keep folder-workspace notes across a build rollback

normalizeFolderWorkspaces rebuilds each FolderWorkspace field-by-field, so the
inline diffComments field #14112 added is dropped by any build that predates it
— and the next full-state write makes the loss durable with no user edit.

Move the on-disk home to an optional top-level PersistedState.folderWorkspaceDiffComments,
which older builds round-trip untouched through their {...defaults, ...parsed} load
spread and omit-style getDurableState(). load() hydrates it onto the records and
deletes it from Store state; buildStateToSave() is the only producer. The in-memory
FolderWorkspace shape, and therefore every IPC/RPC/renderer/mobile path, is unchanged.

Co-authored-by: Orca <help@stably.ai>

* fix(persistence): prefer inline folder notes over a stale map entry

Hydrate preferred a non-empty folderWorkspaceDiffComments entry over non-empty
inline notes. A rollback to a notes-capable #14112 build writes notes inline and
leaves the older map untouched, so re-upgrading deleted everything authored while
rolled back. Inline now wins when present; the map only fills a stripped record.

Co-authored-by: Orca <help@stably.ai>

* Extract folder workspace diff comments to dedicated module

Moves normalizeFolderWorkspaceDiffComments and
collectFolderWorkspaceDiffComments from persistence.ts to a new
folder-workspace-diff-comments.ts module for better code organization.

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-13 00:34:57 -07:00

38 lines
1.3 KiB
TypeScript

import type { DiffComment, FolderWorkspace } from '../shared/types'
// Why shape-only: this replaces folder-workspaces.ts's verbatim `Array.isArray(raw.diffComments)` read.
// Filtering members would make the fix itself a new deletion path for user-authored prose.
export function normalizeFolderWorkspaceDiffComments(
value: unknown
): Record<string, DiffComment[]> | undefined {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
return undefined
}
const normalized: Record<string, DiffComment[]> = {}
let kept = false
for (const [id, comments] of Object.entries(value)) {
if (!Array.isArray(comments)) {
continue
}
normalized[id] = comments as DiffComment[]
kept = true
}
return kept ? normalized : undefined
}
// Why derive on every write: the map self-GCs, so delete paths need no pruning code.
export function collectFolderWorkspaceDiffComments(
workspaces: readonly FolderWorkspace[] | undefined
): Record<string, DiffComment[]> | undefined {
const collected: Record<string, DiffComment[]> = {}
let kept = false
for (const workspace of workspaces ?? []) {
const comments = workspace.diffComments
if (Array.isArray(comments) && comments.length > 0) {
collected[workspace.id] = comments
kept = true
}
}
return kept ? collected : undefined
}