1- import { WorkspaceFolder } from 'vscode' ;
1+ import { WorkspaceFolder , Uri , workspace } from 'vscode' ;
22import { IndexerKey , IndexerStorage , IndexedFilePath , SavedIndex } from 'types/indexer' ;
33import { IndexDataSerializer } from './IndexDataSerializer' ;
4- import Context from 'common/Context' ;
54import ExtensionState from 'common/ExtensionState' ;
5+ import * as path from 'path' ;
6+ import Logger from 'util/Logger' ;
67
78export default class IndexStorage {
89 private _indexStorage : IndexerStorage = { } ;
@@ -31,7 +32,7 @@ export default class IndexStorage {
3132 return ! ! this . _indexStorage [ workspaceFolder . uri . fsPath ] ?. [ key ] ;
3233 }
3334
34- public saveIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
35+ public async saveIndex ( workspaceFolder : WorkspaceFolder , key : IndexerKey , version : number ) {
3536 const indexData = this . _indexStorage [ workspaceFolder . uri . fsPath ] [ key ] ;
3637
3738 const savedIndex : SavedIndex = {
@@ -40,31 +41,88 @@ export default class IndexStorage {
4041 } ;
4142 const serialized = this . serializer . serialize ( savedIndex ) ;
4243
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' ) ) ;
4752 }
4853
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+ }
5366
5467 if ( ! serialized ) {
5568 return undefined ;
5669 }
5770
58- const savedIndex = this . serializer . deserialize ( serialized ) ;
71+ try {
72+ const savedIndex = this . serializer . deserialize ( serialized ) ;
5973
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+ ) ;
6188 return undefined ;
6289 }
90+ }
6391
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+ }
66116 }
117+ }
67118
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 ) ;
69127 }
70128}
0 commit comments