1
- import { WorkspaceFolder } from 'vscode' ;
1
+ import { WorkspaceFolder , Uri , workspace } from 'vscode' ;
2
2
import { IndexerKey , IndexerStorage , IndexedFilePath , SavedIndex } from 'types/indexer' ;
3
3
import { IndexDataSerializer } from './IndexDataSerializer' ;
4
- import Context from 'common/Context' ;
5
4
import ExtensionState from 'common/ExtensionState' ;
5
+ import * as path from 'path' ;
6
+ import Logger from 'util/Logger' ;
6
7
7
8
export default class IndexStorage {
8
9
private _indexStorage : IndexerStorage = { } ;
@@ -31,7 +32,7 @@ export default class IndexStorage {
31
32
return ! ! this . _indexStorage [ workspaceFolder . uri . fsPath ] ?. [ key ] ;
32
33
}
33
34
34
- public saveIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
35
+ public async saveIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
35
36
const indexData = this . _indexStorage [ workspaceFolder . uri . fsPath ] [ key ] ;
36
37
37
38
const savedIndex : SavedIndex = {
@@ -40,31 +41,88 @@ export default class IndexStorage {
40
41
} ;
41
42
const serialized = this . serializer . serialize ( savedIndex ) ;
42
43
43
- ExtensionState . context . globalState . update (
44
- `index-storage-${ workspaceFolder . uri . fsPath } -${ key } ` ,
45
- serialized
46
- ) ;
44
+ const storageUri = this . getStorageUri ( ) ;
45
+ const indexFileUri = this . getIndexFileUri ( storageUri , workspaceFolder , key ) ;
46
+
47
+ // Ensure the storage directory exists
48
+ await this . ensureStorageDirectoryExists ( storageUri ) ;
49
+
50
+ // Write the index data to disk
51
+ await workspace . fs . writeFile ( indexFileUri , Buffer . from ( serialized , 'utf8' ) ) ;
47
52
}
48
53
49
- public loadIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
50
- const serialized = ExtensionState . context . globalState . get < string > (
51
- `index-storage-${ workspaceFolder . uri . fsPath } -${ key } `
52
- ) ;
54
+ public async loadIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
55
+ let serialized : string | undefined ;
56
+
57
+ try {
58
+ const storageUri = this . getStorageUri ( ) ;
59
+ const indexFileUri = this . getIndexFileUri ( storageUri , workspaceFolder , key ) ;
60
+
61
+ const fileData = await workspace . fs . readFile ( indexFileUri ) ;
62
+ serialized = fileData . toString ( ) ;
63
+ } catch ( error ) {
64
+ Logger . logWithTime ( 'Failed to load index' , workspaceFolder . name , key , String ( error ) ) ;
65
+ }
53
66
54
67
if ( ! serialized ) {
55
68
return undefined ;
56
69
}
57
70
58
- const savedIndex = this . serializer . deserialize ( serialized ) ;
71
+ try {
72
+ const savedIndex = this . serializer . deserialize ( serialized ) ;
59
73
60
- if ( savedIndex . version !== version ) {
74
+ if ( savedIndex . version !== version ) {
75
+ return undefined ;
76
+ }
77
+
78
+ if ( ! this . _indexStorage [ workspaceFolder . uri . fsPath ] ) {
79
+ this . _indexStorage [ workspaceFolder . uri . fsPath ] = { } ;
80
+ }
81
+
82
+ this . _indexStorage [ workspaceFolder . uri . fsPath ] [ key ] = savedIndex . data ;
83
+ } catch ( error ) {
84
+ console . error (
85
+ `Failed to deserialize index ${ key } for workspace ${ workspaceFolder . name } :` ,
86
+ error
87
+ ) ;
61
88
return undefined ;
62
89
}
90
+ }
63
91
64
- if ( ! this . _indexStorage [ workspaceFolder . uri . fsPath ] ) {
65
- this . _indexStorage [ workspaceFolder . uri . fsPath ] = { } ;
92
+ private getStorageUri ( ) : Uri {
93
+ const storageUri = ExtensionState . context . storageUri ;
94
+ if ( ! storageUri ) {
95
+ throw new Error ( 'Extension storage URI is not available' ) ;
96
+ }
97
+ return storageUri ;
98
+ }
99
+
100
+ private getIndexFileUri ( storageUri : Uri , workspaceFolder : WorkspaceFolder , key : IndexerKey ) : Uri {
101
+ const workspaceName = path . basename ( workspaceFolder . uri . fsPath ) ;
102
+ const workspaceHash = this . createHash ( workspaceFolder . uri . fsPath ) ;
103
+ const filename = `index-${ workspaceName } -${ workspaceHash } -${ key } .json` ;
104
+ return Uri . joinPath ( storageUri , 'indexes' , filename ) ;
105
+ }
106
+
107
+ private async ensureStorageDirectoryExists ( storageUri : Uri ) : Promise < void > {
108
+ const indexesDir = Uri . joinPath ( storageUri , 'indexes' ) ;
109
+ try {
110
+ await workspace . fs . createDirectory ( indexesDir ) ;
111
+ } catch ( error ) {
112
+ // Directory might already exist, which is fine
113
+ if ( error && typeof error === 'object' && 'code' in error && error . code !== 'FileExists' ) {
114
+ throw error ;
115
+ }
66
116
}
117
+ }
67
118
68
- this . _indexStorage [ workspaceFolder . uri . fsPath ] [ key ] = savedIndex . data ;
119
+ private createHash ( input : string ) : string {
120
+ let hash = 0 ;
121
+ for ( let i = 0 ; i < input . length ; i ++ ) {
122
+ const char = input . charCodeAt ( i ) ;
123
+ hash = ( hash << 5 ) - hash + char ;
124
+ hash = hash & hash ;
125
+ }
126
+ return Math . abs ( hash ) . toString ( 36 ) ;
69
127
}
70
128
}
0 commit comments