4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import { VSBuffer } from '../../../../../base/common/buffer.js' ;
7
- import { StringSHA1 } from '../../../../../base/common/hash.js' ;
7
+ import { hashAsync } from '../../../../../base/common/hash.js' ;
8
8
import { ResourceMap } from '../../../../../base/common/map.js' ;
9
9
import { joinPath } from '../../../../../base/common/resources.js' ;
10
10
import { URI } from '../../../../../base/common/uri.js' ;
@@ -147,36 +147,48 @@ export class ChatEditingSessionStorage {
147
147
}
148
148
}
149
149
150
- const fileContents = new Map < string , string > ( ) ;
151
- const addFileContent = ( content : string ) : string => {
152
- const shaComputer = new StringSHA1 ( ) ;
153
- shaComputer . update ( content ) ;
154
- const sha = shaComputer . digest ( ) . substring ( 0 , 7 ) ;
155
- fileContents . set ( sha , content ) ;
156
- return sha ;
150
+ const contentWritePromises = new Map < string , Promise < string > > ( ) ;
151
+
152
+ // saves a file content under a path containing a hash of the content.
153
+ // Returns the hash to represent the content.
154
+ const writeContent = async ( content : string ) : Promise < string > => {
155
+ const buffer = VSBuffer . fromString ( content ) ;
156
+ const hash = ( await hashAsync ( buffer ) ) . substring ( 0 , 7 ) ;
157
+ if ( ! existingContents . has ( hash ) ) {
158
+ await this . _fileService . writeFile ( joinPath ( contentsFolder , hash ) , buffer ) ;
159
+ }
160
+ return hash ;
161
+ } ;
162
+ const addFileContent = async ( content : string ) : Promise < string > => {
163
+ let storedContentHash = contentWritePromises . get ( content ) ;
164
+ if ( ! storedContentHash ) {
165
+ storedContentHash = writeContent ( content ) ;
166
+ contentWritePromises . set ( content , storedContentHash ) ;
167
+ }
168
+ return storedContentHash ;
157
169
} ;
158
- const serializeResourceMap = < T > ( resourceMap : ResourceMap < T > , serialize : ( value : T ) => any ) : ResourceMapDTO < T > => {
159
- return Array . from ( resourceMap . entries ( ) ) . map ( ( [ resourceURI , value ] ) => [ resourceURI . toString ( ) , serialize ( value ) ] ) ;
170
+ const serializeResourceMap = async < T , U > ( resourceMap : ResourceMap < T > , serialize : ( value : T ) => Promise < U > ) : Promise < ResourceMapDTO < U > > => {
171
+ return await Promise . all ( Array . from ( resourceMap . entries ( ) ) . map ( async ( [ resourceURI , value ] ) => [ resourceURI . toString ( ) , await serialize ( value ) ] ) ) ;
160
172
} ;
161
- const serializeChatEditingSessionStop = ( stop : IChatEditingSessionStop ) : IChatEditingSessionStopDTO => {
173
+ const serializeChatEditingSessionStop = async ( stop : IChatEditingSessionStop ) : Promise < IChatEditingSessionStopDTO > => {
162
174
return {
163
175
stopId : stop . stopId ,
164
- entries : Array . from ( stop . entries . values ( ) ) . map ( serializeSnapshotEntry )
176
+ entries : await Promise . all ( Array . from ( stop . entries . values ( ) ) . map ( serializeSnapshotEntry ) )
165
177
} ;
166
178
} ;
167
- const serializeChatEditingSessionSnapshot = ( snapshot : IChatEditingSessionSnapshot ) : IChatEditingSessionSnapshotDTO2 => {
179
+ const serializeChatEditingSessionSnapshot = async ( snapshot : IChatEditingSessionSnapshot ) : Promise < IChatEditingSessionSnapshotDTO2 > => {
168
180
return {
169
181
requestId : snapshot . requestId ,
170
- stops : snapshot . stops . map ( serializeChatEditingSessionStop ) ,
171
- postEdit : snapshot . postEdit ? Array . from ( snapshot . postEdit . values ( ) ) . map ( serializeSnapshotEntry ) : undefined
182
+ stops : await Promise . all ( snapshot . stops . map ( serializeChatEditingSessionStop ) ) ,
183
+ postEdit : snapshot . postEdit ? await Promise . all ( Array . from ( snapshot . postEdit . values ( ) ) . map ( serializeSnapshotEntry ) ) : undefined
172
184
} ;
173
185
} ;
174
- const serializeSnapshotEntry = ( entry : ISnapshotEntry ) : ISnapshotEntryDTO => {
186
+ const serializeSnapshotEntry = async ( entry : ISnapshotEntry ) : Promise < ISnapshotEntryDTO > => {
175
187
return {
176
188
resource : entry . resource . toString ( ) ,
177
189
languageId : entry . languageId ,
178
- originalHash : addFileContent ( entry . original ) ,
179
- currentHash : addFileContent ( entry . current ) ,
190
+ originalHash : await addFileContent ( entry . original ) ,
191
+ currentHash : await addFileContent ( entry . current ) ,
180
192
state : entry . state ,
181
193
snapshotUri : entry . snapshotUri . toString ( ) ,
182
194
telemetryInfo : { requestId : entry . telemetryInfo . requestId , agentId : entry . telemetryInfo . agentId , command : entry . telemetryInfo . command }
@@ -187,20 +199,14 @@ export class ChatEditingSessionStorage {
187
199
const data : IChatEditingSessionDTO = {
188
200
version : STORAGE_VERSION ,
189
201
sessionId : this . chatSessionId ,
190
- linearHistory : state . linearHistory . map ( serializeChatEditingSessionSnapshot ) ,
202
+ linearHistory : await Promise . all ( state . linearHistory . map ( serializeChatEditingSessionSnapshot ) ) ,
191
203
linearHistoryIndex : state . linearHistoryIndex ,
192
- initialFileContents : serializeResourceMap ( state . initialFileContents , value => addFileContent ( value ) ) ,
193
- pendingSnapshot : state . pendingSnapshot ? serializeChatEditingSessionStop ( state . pendingSnapshot ) : undefined ,
194
- recentSnapshot : serializeChatEditingSessionStop ( state . recentSnapshot ) ,
204
+ initialFileContents : await serializeResourceMap ( state . initialFileContents , value => addFileContent ( value ) ) ,
205
+ pendingSnapshot : state . pendingSnapshot ? await serializeChatEditingSessionStop ( state . pendingSnapshot ) : undefined ,
206
+ recentSnapshot : await serializeChatEditingSessionStop ( state . recentSnapshot ) ,
195
207
} ;
196
208
197
- this . _logService . debug ( `chatEditingSession: Storing editing session at ${ storageFolder . toString ( ) } : ${ fileContents . size } files` ) ;
198
-
199
- for ( const [ hash , content ] of fileContents ) {
200
- if ( ! existingContents . has ( hash ) ) {
201
- await this . _fileService . writeFile ( joinPath ( contentsFolder , hash ) , VSBuffer . fromString ( content ) ) ;
202
- }
203
- }
209
+ this . _logService . debug ( `chatEditingSession: Storing editing session at ${ storageFolder . toString ( ) } : ${ contentWritePromises . size } files` ) ;
204
210
205
211
await this . _fileService . writeFile ( joinPath ( storageFolder , STORAGE_STATE_FILE ) , VSBuffer . fromString ( JSON . stringify ( data ) ) ) ;
206
212
} catch ( e ) {
0 commit comments