Fix shared spec references in session; clarify undoLast contract
commitAssignment and moveEntry stored the same spec object in both stack.spec and entry.spec. A later, more complete scan enriching stack.spec would retroactively mutate the entry that first created the stack, making it appear as if it had been scanned with data it never actually had. Both places now store independent shallow copies so the entries log and the stacks spec (comparison baseline) can't leak into each other. Also documents that undoLast intentionally reverts the last *recorded* entry, not the last *action* - a subsequent moveEntry/removeEntry on a different entry does not change what undoLast will take back - and adds a test pinning that contract after a reorder.
This commit is contained in:
+12
-4
@@ -42,7 +42,7 @@ export function proposeAssignment(session, spec) {
|
||||
export function commitAssignment(session, spec, source, stackId) {
|
||||
let stack = session.stacks.find((candidate) => candidate.id === stackId);
|
||||
if (!stack) {
|
||||
stack = { id: stackId, spec, count: 0 };
|
||||
stack = { id: stackId, spec: { ...spec }, count: 0 };
|
||||
session.stacks.push(stack);
|
||||
session.stacks.sort((a, b) => a.id.localeCompare(b.id));
|
||||
} else {
|
||||
@@ -55,7 +55,9 @@ export function commitAssignment(session, spec, source, stackId) {
|
||||
}
|
||||
|
||||
stack.count += 1;
|
||||
const entry = { entryId: session.nextEntryId++, spec, stackId, source };
|
||||
// entry.spec ist das Protokoll dessen, was tatsaechlich gescannt wurde, und muss
|
||||
// unabhaengig vom Stapel-Spec bleiben - eigene Kopie, kein geteiltes Objekt.
|
||||
const entry = { entryId: session.nextEntryId++, spec: { ...spec }, stackId, source };
|
||||
session.entries.push(entry);
|
||||
return entry;
|
||||
}
|
||||
@@ -64,7 +66,13 @@ function dropEmptyStacks(session) {
|
||||
session.stacks = session.stacks.filter((stack) => stack.count > 0);
|
||||
}
|
||||
|
||||
/** Nimmt den zuletzt erfassten Eintrag zurueck. */
|
||||
/**
|
||||
* Nimmt den zuletzt erfassten Eintrag zurueck - nicht die zuletzt ausgefuehrte
|
||||
* Handlung. Die Oberflaeche zeigt neben der Rueckgaengig-Flaeche stets den
|
||||
* zuletzt erfassten Eintrag an, und genau der wird hier zurueckgenommen. Ein
|
||||
* zwischenzeitliches Umsortieren (moveEntry) oder Entfernen (removeEntry)
|
||||
* eines anderen Eintrags bleibt davon unberuehrt.
|
||||
*/
|
||||
export function undoLast(session) {
|
||||
const entry = session.entries.pop();
|
||||
if (!entry) return null;
|
||||
@@ -84,7 +92,7 @@ export function moveEntry(session, entryId, stackId) {
|
||||
|
||||
let to = session.stacks.find((candidate) => candidate.id === stackId);
|
||||
if (!to) {
|
||||
to = { id: stackId, spec: entry.spec, count: 0 };
|
||||
to = { id: stackId, spec: { ...entry.spec }, count: 0 };
|
||||
session.stacks.push(to);
|
||||
session.stacks.sort((a, b) => a.id.localeCompare(b.id));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user