Repository navigation
The next account signed in on a tab does not see the previous account's chat draft, conversation or answers - #1238
Conversation
…'s chat draft, conversation or answers Signed-off-by: dada-yan <BinjunYann@gmail.com>
WaylandYang
left a comment
There was a problem hiding this comment.
Thank you for the thorough write-up and the tests that drive the real handlers. The coverage is complete: answers, unread marks, workspace/base, draft, last-conversation keys and the cache are everything the tab keeps for a person, and the clearing order with liveAnswer.clear → convMarks.clear is right.
One change before merging. Tying the clear to "a sign-in happened on this page" causes the regression you list under Limits: the same person whose session expired loses their unsent draft and last conversations. It also misses sign-ins this page doesn't see, such as SSO started from a link or a proxy, or a sign-in in another tab. Please tie it to who is signed in instead: remember the owning user id (e.g. utopia.account), and in the me queryFn and in Login onSuccess clear the tab's state only when that id differs from the signed-in user. Shell doesn't render children until me resolves, so the check runs before Chat reads the draft. Keep the full clear on explicit sign-out. Then the SSO-button hook isn't needed, and a test for "same user signs back in, draft kept" would cover the regression.
…ry sign-in Signed-off-by: dada-yan <BinjunYann@gmail.com>
|
Thank you. Done in c27c026.
One change from a single key: the owner is recorded twice under
Either copy alone fails one case:
"Same account signs back in, draft kept" is a test now. It fails on the first commit. I also checked both sign-in cases by hand on a local server. |
WaylandYang
left a comment
There was a problem hiding this comment.
Thank you, this is the right shape. Recording the owner per tab and per browser separates what belongs to the tab from what all tabs share, and running the claim in fetchMe covers sign-ins this page never sees, as well as a sign-in in another tab once this one reloads. The same person signing back in now keeps their draft, and the four tests cover sign-out, another account, the same account, and another tab. Please update the description: the SSO-redirect hook and the draft-loss limit no longer apply. Merging.
#533 made sign-in clear the query cache. Its acceptance list asked that signing out and signing in as another user in the same tab leave "no trace of the first user's name, bases or alerts". Chat keeps state outside that cache, and all of it survives both.
Problem
What survives:
chat:draftin sessionStorage). The next account's composer opens with it, on any base.chat:last:<kb>) and the answers the page holds in memory (liveAnswer, which keeps a finished answer until the next question).conversation_detailfilters byuser_id.utopia.unreadand the in-memory sets) and the remembered workspace and base (utopia.ws,utopia.kb).Single sign-on reloads the page, so memory goes, but sessionStorage stays: the draft and the last-conversation keys come back.
To reproduce on dev 70bf7a7:
The composer holds A's text, and the page shows A's conversation.
Change
utopia.accountrecords the signed-in user's id in sessionStorage, for what the tab keeps (draft, last-conversation keys, answers in memory), and in localStorage, for what tabs share (unread marks, remembered workspace and base). One copy alone is not enough:claimFor(user.id)clears a scope only when its owner is someone else or nobody. It runs in two places:fetchMe, which every["me"]query now uses. Shell renders children only aftermeresolves, so the check runs before Chat reads the draft. It also covers single sign-on started anywhere.onSuccess, which still clears the query cache (Returning to a page does not refetch what the stream keeps fresh #533).clearSessionStateclears everything, including the query cache, and forgets the owner.liveAnswer.clear()drops every entry, then disconnects its readers. It sends no Stop, so the server finishes and saves the previous account's answer. Unread marks are cleared after the answers, because dropping a running answer marks it unread.Verification
macOS (arm64), Node 26.3 (CI uses Node 20), pnpm 10.2.1.
authSession.test.tsdrives the real sign-out and sign-in handlers andfetchMe, with a real QueryClient and the real chat stores. The previous account claims the tab throughfetchMeand leaves a base, a draft, a last conversation, a finished unread answer and a running one.clears all of it on sign-out.clears it when another account signs in.keeps it when the same account signs back in after its session expired: fails on this PR's first commit, which cleared on every sign-in.drops a tab's draft on reload after another account signed in in another tab: the new account's shared state stays.On dev 70bf7a7, with
fetchMestubbed toapi.me, all three tests that expect a clear fail. Removing either owner write, or clearing unread marks before answers, also fails a test.liveAnswer.stream.test.tsadds one test:clear()aborts the reader and sends no Stop.pnpm test: 38 files, 276 tests passed.pnpm buildpasses.Manual check on a local server, two accounts sharing a base:
Limits
mefetch.menever goes stale, so that means a reload; until then the tab shows the previous person's state.