Skip to content

Commit 68f20ce

Browse files
fix: more workspace change determinism.
1 parent e740c9d commit 68f20ce

6 files changed

Lines changed: 79 additions & 82 deletions

src/modules/app-core/github-workflows.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,6 @@ const initializeGitHubWorkflows = ({
244244
setSelectedRepository: setCurrentSelectedRepository,
245245
getFileCommits: getWorkspacePrFileCommits,
246246
getEditorSyncTargets,
247-
persistWorkspaceMetadataOnSubmit: async () => {
248-
if (typeof flushWorkspaceSave !== 'function') {
249-
return
250-
}
251-
252-
await flushWorkspaceSave({ preserveRecordId: true })
253-
},
254247
getTopLevelDeclarations,
255248
getRenderMode,
256249
getStyleMode,

src/modules/app-core/pr-context-state-change-handler.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ const createPrContextStateChangeHandler = ({
99
getWorkspaceRepositoryFullName,
1010
setWorkspaceRepositoryFullName,
1111
getWorkspacePrContextState,
12-
getHasObservedActivePrContextInSession,
1312
setHasObservedActivePrContextInSession,
1413
githubPrStatus,
15-
githubPrHeadBranch,
16-
githubPrTitle,
1714
workspacePrSessionHandoffController,
1815
setWorkspacePrNumber,
1916
persistWorkspacePrContextState,
@@ -38,12 +35,8 @@ const createPrContextStateChangeHandler = ({
3835
),
3936
workspaceRepositoryFullName: getWorkspaceRepositoryFullName(),
4037
workspacePrContextState: getWorkspacePrContextState(),
41-
hasObservedActivePrContextInSession: getHasObservedActivePrContextInSession(),
4238
statusText:
4339
typeof githubPrStatus?.textContent === 'string' ? githubPrStatus.textContent : '',
44-
headBranchValue:
45-
typeof githubPrHeadBranch?.value === 'string' ? githubPrHeadBranch.value : '',
46-
prTitleValue: typeof githubPrTitle?.value === 'string' ? githubPrTitle.value : '',
4740
})
4841

4942
if (transition.kind === 'ignore') {
@@ -72,10 +65,6 @@ const createPrContextStateChangeHandler = ({
7265
} else if (transition.kind === 'mark-closed') {
7366
setHasObservedActivePrContextInSession(false)
7467
persistWorkspacePrContextState('closed')
75-
} else if (transition.kind === 'mark-inactive') {
76-
setHasObservedActivePrContextInSession(false)
77-
setWorkspacePrNumber(null)
78-
persistWorkspacePrContextState('inactive')
7968
}
8069

8170
editedIndicatorVisibilityController.refreshIndicators()

src/modules/app-core/pr-context-transition.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
hasClosedPrVerificationStatus,
3-
hasIncompletePrMetadataInputs,
43
hasSelectedRepositoryMismatch,
54
hasWorkspaceRepositoryMismatch,
65
} from './pr-context-state.js'
@@ -11,10 +10,7 @@ const resolvePrContextTransition = ({
1110
selectedRepositoryFullName,
1211
workspaceRepositoryFullName,
1312
workspacePrContextState,
14-
hasObservedActivePrContextInSession,
1513
statusText,
16-
headBranchValue,
17-
prTitleValue,
1814
}) => {
1915
if (hasActiveContextPayload) {
2016
if (
@@ -49,16 +45,6 @@ const resolvePrContextTransition = ({
4945
return { kind: 'mark-closed' }
5046
}
5147

52-
if (
53-
hasObservedActivePrContextInSession &&
54-
hasIncompletePrMetadataInputs({
55-
headBranchValue,
56-
prTitleValue,
57-
})
58-
) {
59-
return { kind: 'mark-inactive' }
60-
}
61-
6248
return { kind: 'noop' }
6349
}
6450

src/modules/app-core/workspace-pr-session-handoff-controller.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,19 +303,7 @@ export const createWorkspacePrSessionHandoffController = ({
303303
headBranch: archiveSnapshot.head,
304304
})
305305

306-
const saved = await workspaceStorage.upsertWorkspace(archiveSnapshot)
307-
308-
const staleActiveRecordIds = activeRecordsForContext
309-
.map(record => toNonEmptyWorkspaceText(record.id))
310-
.filter(recordId => recordId && recordId !== toNonEmptyWorkspaceText(saved?.id))
311-
312-
if (staleActiveRecordIds.length > 0) {
313-
await Promise.all(
314-
staleActiveRecordIds.map(recordId =>
315-
workspaceStorage.removeWorkspace(recordId),
316-
),
317-
)
318-
}
306+
await workspaceStorage.upsertWorkspace(archiveSnapshot)
319307

320308
await refreshLocalContextOptions()
321309
} catch (error) {

src/modules/app-core/workspace-save-controller.js

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ const createWorkspaceSaveController = ({
7272
const buildSaveSnapshot = ({
7373
preserveRecordId = false,
7474
allowDuplicateWorkspaceKey = false,
75+
allowIdentityMutation = false,
76+
allowWorkspacePrune = false,
7577
} = {}) => {
7678
const activeRecordId =
7779
preserveRecordId && typeof getActiveWorkspaceRecordId === 'function'
@@ -85,6 +87,14 @@ const createWorkspaceSaveController = ({
8587
snapshot.allowDuplicateWorkspaceKey = true
8688
}
8789

90+
if (allowIdentityMutation) {
91+
snapshot.allowIdentityMutation = true
92+
}
93+
94+
if (allowWorkspacePrune) {
95+
snapshot.allowWorkspacePrune = true
96+
}
97+
8898
snapshot.loadTransactionId = getCurrentWorkspaceLoadTransactionId()
8999
return snapshot
90100
}
@@ -96,40 +106,41 @@ const createWorkspaceSaveController = ({
96106
}
97107

98108
const payloadRecordId = toNonEmptyWorkspaceText(payload?.id)
109+
let existingRecord = null
99110
if (payloadRecordId) {
100-
const existingRecord = await workspaceStorage.getWorkspaceById(payloadRecordId)
101-
if (existingRecord && typeof existingRecord === 'object') {
102-
const existingWorkspaceKey = toNonEmptyWorkspaceText(
103-
existingRecord.workspaceKey,
104-
)
105-
const payloadWorkspaceKey = toNonEmptyWorkspaceText(payload?.workspaceKey)
106-
if (
107-
existingWorkspaceKey &&
108-
payloadWorkspaceKey &&
109-
existingWorkspaceKey !== payloadWorkspaceKey
110-
) {
111-
const existingWorkspaceScope =
112-
toNonEmptyWorkspaceText(existingRecord.workspaceScope).toLowerCase() ||
113-
'local'
114-
const payloadWorkspaceScope =
115-
toNonEmptyWorkspaceText(payload?.workspaceScope).toLowerCase() || 'local'
116-
const existingRepository = toNonEmptyWorkspaceText(existingRecord.repo)
117-
const payloadRepository = toNonEmptyWorkspaceText(payload?.repo)
118-
119-
const isLocalToRepositoryRekey =
120-
existingWorkspaceScope === 'local' &&
121-
payloadWorkspaceScope === 'repository' &&
122-
!existingRepository &&
123-
Boolean(payloadRepository)
124-
125-
if (!isLocalToRepositoryRekey) {
126-
return null
127-
}
128-
}
129-
}
111+
existingRecord = await workspaceStorage.getWorkspaceById(payloadRecordId)
130112
}
131113

132-
const { loadTransactionId: _loadTransactionId, ...persistablePayload } = payload
114+
const {
115+
loadTransactionId: _loadTransactionId,
116+
allowIdentityMutation: _allowIdentityMutation,
117+
allowWorkspacePrune: _allowWorkspacePrune,
118+
...persistablePayload
119+
} = payload
120+
121+
const allowIdentityMutation =
122+
payload && typeof payload === 'object'
123+
? payload.allowIdentityMutation === true
124+
: false
125+
const allowWorkspacePrune =
126+
payload && typeof payload === 'object'
127+
? payload.allowWorkspacePrune === true
128+
: false
129+
130+
if (
131+
!allowIdentityMutation &&
132+
existingRecord &&
133+
typeof existingRecord === 'object'
134+
) {
135+
persistablePayload.workspaceScope = toNonEmptyWorkspaceText(
136+
existingRecord.workspaceScope,
137+
)
138+
persistablePayload.workspaceKey = toNonEmptyWorkspaceText(
139+
existingRecord.workspaceKey,
140+
)
141+
persistablePayload.repo = toNonEmptyWorkspaceText(existingRecord.repo)
142+
persistablePayload.head = toNonEmptyWorkspaceText(existingRecord.head)
143+
}
133144

134145
const allowDuplicateWorkspaceKey =
135146
persistablePayload && typeof persistablePayload === 'object'
@@ -148,6 +159,7 @@ const createWorkspaceSaveController = ({
148159

149160
if (
150161
normalizedSavedWorkspaceKey &&
162+
allowWorkspacePrune &&
151163
!allowDuplicateWorkspaceKey &&
152164
!isSavedInactiveWithoutPrNumber
153165
) {
@@ -252,25 +264,39 @@ const createWorkspaceSaveController = ({
252264
const queueWorkspaceSave = ({
253265
preserveRecordId = false,
254266
allowDuplicateWorkspaceKey = false,
267+
allowIdentityMutation = false,
268+
allowWorkspacePrune = false,
255269
} = {}) => {
256270
if (!canPersistWorkspaceState()) {
257271
return
258272
}
259273

260-
const snapshot = buildSaveSnapshot({ preserveRecordId, allowDuplicateWorkspaceKey })
274+
const snapshot = buildSaveSnapshot({
275+
preserveRecordId,
276+
allowDuplicateWorkspaceKey,
277+
allowIdentityMutation,
278+
allowWorkspacePrune,
279+
})
261280
setActiveWorkspaceRecordId(snapshot.id)
262281
workspaceSaver.queue(snapshot)
263282
}
264283

265284
const flushWorkspaceSave = async ({
266285
preserveRecordId = false,
267286
allowDuplicateWorkspaceKey = false,
287+
allowIdentityMutation = false,
288+
allowWorkspacePrune = false,
268289
} = {}) => {
269290
if (!canPersistWorkspaceState()) {
270291
return
271292
}
272293

273-
const snapshot = buildSaveSnapshot({ preserveRecordId, allowDuplicateWorkspaceKey })
294+
const snapshot = buildSaveSnapshot({
295+
preserveRecordId,
296+
allowDuplicateWorkspaceKey,
297+
allowIdentityMutation,
298+
allowWorkspacePrune,
299+
})
274300
setActiveWorkspaceRecordId(snapshot.id)
275301
await workspaceSaver.flushNow(snapshot)
276302
}
@@ -281,22 +307,34 @@ const createWorkspaceSaveController = ({
281307
preserveRecordIdOnInput = false,
282308
preserveRecordIdOnChange = false,
283309
rekeyOnBlur = true,
310+
allowIdentityMutationOnInput = false,
311+
allowIdentityMutationOnChange = false,
312+
allowIdentityMutationOnBlur = rekeyOnBlur,
284313
} = {},
285314
) => {
286315
if (!(element instanceof HTMLInputElement || element instanceof HTMLSelectElement)) {
287316
return
288317
}
289318

290319
const queue = () => {
291-
queueWorkspaceSave({ preserveRecordId: preserveRecordIdOnInput })
320+
queueWorkspaceSave({
321+
preserveRecordId: preserveRecordIdOnInput,
322+
allowIdentityMutation: allowIdentityMutationOnInput,
323+
})
292324
}
293325

294326
const queueFromChange = () => {
295-
queueWorkspaceSave({ preserveRecordId: preserveRecordIdOnChange })
327+
queueWorkspaceSave({
328+
preserveRecordId: preserveRecordIdOnChange,
329+
allowIdentityMutation: allowIdentityMutationOnChange,
330+
})
296331
}
297332

298333
const flush = () => {
299-
void flushWorkspaceSave({ preserveRecordId: !rekeyOnBlur }).catch(() => {
334+
void flushWorkspaceSave({
335+
preserveRecordId: !rekeyOnBlur,
336+
allowIdentityMutation: allowIdentityMutationOnBlur,
337+
}).catch(() => {
300338
/* Save failures are already surfaced through saver onError. */
301339
})
302340
}

src/modules/app-core/workspace-scope-fork-actions.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ export const createWorkspaceScopeForkActions = ({
5353
setWorkspaceScopeMarker(
5454
toWorkspaceScopeMarker(normalizedRepositoryFullName ? 'repository' : 'local'),
5555
)
56-
await flushWorkspaceSave({ preserveRecordId: !rekeyRecord })
56+
await flushWorkspaceSave({
57+
preserveRecordId: !rekeyRecord,
58+
allowIdentityMutation: true,
59+
})
5760
}
5861

5962
const setActiveWorkspaceScopeMarker = async nextScope => {

0 commit comments

Comments
 (0)