fix(web): normalize workspace paths to resolve Windows session list f…#21504
fix(web): normalize workspace paths to resolve Windows session list f…#21504chenyy9527 wants to merge 1 commit intoanomalyco:devfrom
Conversation
…ailures Closes anomalyco#21441 - Client: use workspaceKey() for all child store internal map keys (children, vcsCache, metaCache, iconCache, lifecycle, pins, disposers) to prevent duplicate stores from mixed path formats (D:/foo vs D:\foo) - Client: add canonicalDir map to preserve original directory for API calls that require server-side exact match (isBooting, isLoadingSessions, onDispose) - Client: deduplicate loadSessions requests via sessionLoads keyed by workspaceKey() - Client: sortedRootSessions accepts optional dir fallback for bootstrap: false - Server: add normalizeDirectory() (mirrors workspaceKey() logic) for Session createNext (write) and Session.list/listGlobal (query) - Server: fromRow normalizes directory in API response for consistency
|
The following comment was made by an LLM, it may be inaccurate: The search results show PR #21504 is the current PR (as expected). I found one potentially related historical PR: Related PR:
However, no currently open PRs appear to be duplicates of PR #21504. The search results primarily return the current PR itself, indicating this is the primary/only open PR addressing this specific Windows path normalization issue with session lists. |
PR #18709 is a low-level type system refactoring, while PR #21504 fixes a client-side session list display issue. |
…ailures
Closes #21441
Issue for this PR
Closes #21441
Type of change
What does this PR do?
On Windows, the same directory can be passed with different path formats (
D:/foovsD:\foo). This caused three problems:Duplicate child stores —
child-store.tsused the raw directory string as map keys, so the same physical directory created two independent stores. When total stores exceededMAX_DIR_STORES=30, eviction disposed one store andloadSessionswrote to the disposed store — session data was lost.Duplicate API requests — On page refresh, two
/sessionrequests were sent with different path formats. The backslash request returned empty becauseSession.listused SQL exact match against forward-slash values in the DB.Empty session list before bootstrap —
sortedRootSessionsonly usedstore.path.directoryfor filtering. Whenbootstrap: falsewas passed,path.directorywas empty and all sessions were filtered out.Fix:
workspaceKey()(normalized).canonicalDirpreserves original path for API calls.loadSessionsdeduplicates viasessionLoadskeyed byworkspaceKey().sortedRootSessionsaccepts optionaldirfallback for pre-bootstrap state.normalizeDirectory()(identical logic toworkspaceKey()) applied inSession.createNext(write),Session.list/Session.listGlobal(query), andfromRow(response).How did you verify your code works?
bun typecheckpasses inpackages/opencodeandpackages/app(pre-existingcustom-elements.d.tserror is unrelated).loadSessionscall paths → API requests → store writes → render, confirming the normalization unifies all paths.normalizeDirectory()andworkspaceKey()produce identical output for all edge cases (D:/,/,D:\foo\bar\, empty string).Screenshots / recordings
N/A
Checklist