| author | |
| committer | |
| log | 4abf8b46c591ae2b36aa29598c388100df651411 |
| tree | 58b522667a51675ce5e7c9dd2cecc94fa49877bb |
| parent | 3083d712eefb8009f7366ba53040eb2d477bfa33 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Codex <codex@openai.com>2 files changed, 22 insertions(+), 0 deletions(-)
packages/client-runtime/src/state/shellReducer.test.ts+20| ... | @@ -44,6 +44,26 @@ const stubThread = { | ... | @@ -44,6 +44,26 @@ const stubThread = { |
| 44 | } as const; | 44 | } as const; |
| 45 | 45 | ||
| 46 | describe("applyShellStreamEvent", () => { | 46 | describe("applyShellStreamEvent", () => { |
| 47 | it("ignores stale project upserts without mutating the snapshot", () => { | ||
| 48 | const snapshotWithProject: OrchestrationShellSnapshot = { | ||
| 49 | ...baseSnapshot, | ||
| 50 | snapshotSequence: 4, | ||
| 51 | projects: [stubProject], | ||
| 52 | }; | ||
| 53 | |||
| 54 | for (const sequence of [3, 4]) { | ||
| 55 | const next = applyShellStreamEvent(snapshotWithProject, { | ||
| 56 | kind: "project-upserted", | ||
| 57 | sequence, | ||
| 58 | project: { ...stubProject, title: "Stale Title" }, | ||
| 59 | }); | ||
| 60 | |||
| 61 | expect(next).toBe(snapshotWithProject); | ||
| 62 | expect(next.snapshotSequence).toBe(4); | ||
| 63 | expect(next.projects[0]?.title).toBe("Test Project"); | ||
| 64 | } | ||
| 65 | }); | ||
| 66 | |||
| 47 | describe("project-upserted", () => { | 67 | describe("project-upserted", () => { |
| 48 | it("adds a new project", () => { | 68 | it("adds a new project", () => { |
| 49 | const event: OrchestrationShellStreamEvent = { | 69 | const event: OrchestrationShellStreamEvent = { |
packages/client-runtime/src/state/shellReducer.ts+2| ... | @@ -13,6 +13,8 @@ export function applyShellStreamEvent( | ... | @@ -13,6 +13,8 @@ export function applyShellStreamEvent( |
| 13 | snapshot: OrchestrationShellSnapshot, | 13 | snapshot: OrchestrationShellSnapshot, |
| 14 | event: OrchestrationShellStreamEvent, | 14 | event: OrchestrationShellStreamEvent, |
| 15 | ): OrchestrationShellSnapshot { | 15 | ): OrchestrationShellSnapshot { |
| 16 | if (event.sequence <= snapshot.snapshotSequence) return snapshot; | ||
| 17 | |||
| 16 | switch (event.kind) { | 18 | switch (event.kind) { |
| 17 | case "project-upserted": { | 19 | case "project-upserted": { |
| 18 | const projects = snapshot.projects.some((p) => p.id === event.project.id) | 20 | const projects = snapshot.projects.some((p) => p.id === event.project.id) |