@@ -7,10 +7,10 @@ import {
77 clearAccounts ,
88 clearFlaggedAccounts ,
99 type FlaggedAccountStorageV1 ,
10+ getStoragePath ,
1011 loadFlaggedAccounts ,
11- saveAccounts ,
12- saveFlaggedAccounts ,
1312 snapshotAccountStorage ,
13+ withAccountAndFlaggedStorageTransaction ,
1414} from "./storage.js" ;
1515
1616export const DESTRUCTIVE_ACTION_COPY = {
@@ -99,74 +99,62 @@ export interface DestructiveActionResult {
9999 quotaCacheCleared : boolean ;
100100}
101101
102- function asError ( error : unknown , fallbackMessage : string ) : Error {
103- return error instanceof Error
104- ? error
105- : new Error ( `${ fallbackMessage } : ${ String ( error ) } ` ) ;
106- }
107-
108102export async function deleteAccountAtIndex ( options : {
109103 storage : AccountStorageV3 ;
110104 index : number ;
111105} ) : Promise < DeleteAccountResult | null > {
112- const target = options . storage . accounts . at ( options . index ) ;
113- if ( ! target ) return null ;
114- const flagged = await loadFlaggedAccounts ( ) ;
115- await snapshotAccountStorage ( { reason : "delete-account" } ) ;
116- const nextStorage : AccountStorageV3 = {
117- ...options . storage ,
118- accounts : options . storage . accounts . map ( ( account ) => ( { ...account } ) ) ,
119- activeIndexByFamily : { ...( options . storage . activeIndexByFamily ?? { } ) } ,
120- } ;
121- const previousStorage : AccountStorageV3 = {
122- ...options . storage ,
123- accounts : options . storage . accounts . map ( ( account ) => ( { ...account } ) ) ,
124- activeIndexByFamily : { ...( options . storage . activeIndexByFamily ?? { } ) } ,
125- } ;
106+ const requestedTarget = options . storage . accounts . at ( options . index ) ;
107+ if ( ! requestedTarget ) return null ;
126108
127- nextStorage . accounts . splice ( options . index , 1 ) ;
128- rebaseActiveIndicesAfterDelete ( nextStorage , options . index ) ;
129- clampActiveIndices ( nextStorage ) ;
130- await saveAccounts ( nextStorage ) ;
131-
132- const remainingFlagged = flagged . accounts . filter (
133- ( account ) => account . refreshToken !== target . refreshToken ,
134- ) ;
135- const removedFlaggedCount = flagged . accounts . length - remainingFlagged . length ;
136- let updatedFlagged = flagged ;
137- if ( removedFlaggedCount > 0 ) {
138- updatedFlagged = { ...flagged , accounts : remainingFlagged } ;
139- try {
140- await saveFlaggedAccounts ( updatedFlagged ) ;
141- } catch ( error ) {
142- const originalError = asError (
143- error ,
144- "Failed to save flagged account storage after deleting an account" ,
145- ) ;
146- try {
147- await saveAccounts ( previousStorage ) ;
148- } catch ( rollbackError ) {
149- throw new AggregateError (
150- [
151- originalError ,
152- asError (
153- rollbackError ,
154- "Failed to roll back account storage after flagged save failure" ,
155- ) ,
156- ] ,
157- "Deleting the account partially failed and rollback also failed." ,
158- ) ;
159- }
160- throw originalError ;
109+ return withAccountAndFlaggedStorageTransaction ( async ( current , persist ) => {
110+ const sourceStorage = current ?? options . storage ;
111+ const targetIndex = sourceStorage . accounts . findIndex (
112+ ( account ) => account . refreshToken === requestedTarget . refreshToken ,
113+ ) ;
114+ if ( targetIndex < 0 ) {
115+ return null ;
116+ }
117+ const target = sourceStorage . accounts [ targetIndex ] ;
118+ if ( ! target ) {
119+ return null ;
161120 }
162- }
163121
164- return {
165- storage : nextStorage ,
166- flagged : updatedFlagged ,
167- removedAccount : target ,
168- removedFlaggedCount,
169- } ;
122+ const flagged = await loadFlaggedAccounts ( ) ;
123+ await snapshotAccountStorage ( {
124+ reason : "delete-account" ,
125+ storage : sourceStorage ,
126+ storagePath : getStoragePath ( ) ,
127+ } ) ;
128+
129+ const nextStorage : AccountStorageV3 = {
130+ ...sourceStorage ,
131+ accounts : sourceStorage . accounts . map ( ( account ) => ( { ...account } ) ) ,
132+ activeIndexByFamily : { ...( sourceStorage . activeIndexByFamily ?? { } ) } ,
133+ } ;
134+
135+ nextStorage . accounts . splice ( targetIndex , 1 ) ;
136+ rebaseActiveIndicesAfterDelete ( nextStorage , targetIndex ) ;
137+ clampActiveIndices ( nextStorage ) ;
138+
139+ const remainingFlagged = flagged . accounts . filter (
140+ ( account ) => account . refreshToken !== target . refreshToken ,
141+ ) ;
142+ const removedFlaggedCount =
143+ flagged . accounts . length - remainingFlagged . length ;
144+ const updatedFlagged =
145+ removedFlaggedCount > 0
146+ ? { ...flagged , accounts : remainingFlagged }
147+ : flagged ;
148+
149+ await persist ( nextStorage , updatedFlagged ) ;
150+
151+ return {
152+ storage : nextStorage ,
153+ flagged : updatedFlagged ,
154+ removedAccount : target ,
155+ removedFlaggedCount,
156+ } ;
157+ } ) ;
170158}
171159
172160/**
0 commit comments