@@ -814,6 +814,45 @@ const toWorkspaceRecordId = ({ repositoryFullName, headBranch }) => {
814814 return `workspace_${ headSegment } `
815815}
816816
817+ const resolveWorkspaceRecordIdentity = ( {
818+ repositoryFullName,
819+ headBranch,
820+ activeRecordId,
821+ } = { } ) => {
822+ const canonicalId = toWorkspaceRecordId ( { repositoryFullName, headBranch } )
823+ const currentId = toNonEmptyWorkspaceText ( activeRecordId )
824+
825+ if ( ! currentId ) {
826+ return {
827+ id : canonicalId ,
828+ supersededId : '' ,
829+ }
830+ }
831+
832+ if ( currentId === canonicalId ) {
833+ return {
834+ id : currentId ,
835+ supersededId : '' ,
836+ }
837+ }
838+
839+ const hasRepository = Boolean ( toWorkspaceIdentitySegment ( repositoryFullName ) )
840+ const shouldPromoteLocalIdToRepository =
841+ hasRepository && currentId . startsWith ( 'workspace_' )
842+
843+ if ( shouldPromoteLocalIdToRepository ) {
844+ return {
845+ id : canonicalId ,
846+ supersededId : currentId ,
847+ }
848+ }
849+
850+ return {
851+ id : currentId ,
852+ supersededId : '' ,
853+ }
854+ }
855+
817856const getWorkspaceContextSnapshot = ( ) => {
818857 return {
819858 repositoryFullName : getCurrentSelectedRepository ( ) ,
@@ -1428,16 +1467,21 @@ const reconcileWorkspaceTabsWithEditorSync = ({ componentPath, stylesPath } = {}
14281467
14291468const buildWorkspaceRecordSnapshot = ( { recordId } = { } ) => {
14301469 const context = getWorkspaceContextSnapshot ( )
1431- const id =
1432- recordId ||
1433- activeWorkspaceRecordId ||
1434- toWorkspaceRecordId ( {
1435- repositoryFullName : context . repositoryFullName ,
1436- headBranch : context . headBranch ,
1437- } )
1470+ const identity =
1471+ typeof recordId === 'string' && recordId . length > 0
1472+ ? {
1473+ id : recordId ,
1474+ supersededId : '' ,
1475+ }
1476+ : resolveWorkspaceRecordIdentity ( {
1477+ repositoryFullName : context . repositoryFullName ,
1478+ headBranch : context . headBranch ,
1479+ activeRecordId : activeWorkspaceRecordId ,
1480+ } )
14381481
14391482 return {
1440- id,
1483+ id : identity . id ,
1484+ supersededId : identity . supersededId ,
14411485 repo : context . repositoryFullName || '' ,
14421486 base : context . baseBranch || '' ,
14431487 head : context . headBranch || '' ,
@@ -1532,6 +1576,45 @@ const applyWorkspaceRecord = async (workspace, { silent = false } = {}) => {
15321576workspaceSaver = createDebouncedWorkspaceSaver ( {
15331577 save : async payload => {
15341578 const saved = await workspaceStorage . upsertWorkspace ( payload )
1579+
1580+ const normalizedSavedRepo = toNonEmptyWorkspaceText ( saved . repo )
1581+ const normalizedSavedHead = toNonEmptyWorkspaceText ( saved . head )
1582+
1583+ if ( normalizedSavedHead ) {
1584+ const siblingRecords = normalizedSavedRepo
1585+ ? await workspaceStorage . listWorkspaces ( { repo : normalizedSavedRepo } )
1586+ : await workspaceStorage . listWorkspaces ( )
1587+
1588+ const duplicateRecordIds = siblingRecords
1589+ . filter ( record => {
1590+ if ( ! record || typeof record !== 'object' ) {
1591+ return false
1592+ }
1593+
1594+ if ( toNonEmptyWorkspaceText ( record . id ) === toNonEmptyWorkspaceText ( saved . id ) ) {
1595+ return false
1596+ }
1597+
1598+ return (
1599+ toNonEmptyWorkspaceText ( record . repo ) === normalizedSavedRepo &&
1600+ toNonEmptyWorkspaceText ( record . head ) === normalizedSavedHead
1601+ )
1602+ } )
1603+ . map ( record => toNonEmptyWorkspaceText ( record . id ) )
1604+ . filter ( Boolean )
1605+
1606+ await Promise . all (
1607+ duplicateRecordIds . map ( duplicateId =>
1608+ workspaceStorage . removeWorkspace ( duplicateId ) ,
1609+ ) ,
1610+ )
1611+ }
1612+
1613+ const supersededId = toNonEmptyWorkspaceText ( payload ?. supersededId )
1614+ if ( supersededId && supersededId !== toNonEmptyWorkspaceText ( saved . id ) ) {
1615+ await workspaceStorage . removeWorkspace ( supersededId )
1616+ }
1617+
15351618 activeWorkspaceRecordId = saved . id
15361619 activeWorkspaceCreatedAt = saved . createdAt ?? activeWorkspaceCreatedAt
15371620 await refreshLocalContextOptions ( )
0 commit comments