Skip to content

Commit be1426e

Browse files
feat: save index on disk
1 parent 1100fd5 commit be1426e

File tree

3 files changed

+77
-18
lines changed

3 files changed

+77
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
66

77
## [Unreleased]
88
- Fixed: Issue [#92](https://github.com/magebitcom/magento-toolbox/issues/92) (Definitions and hovers dont work on element content values that are on a new line)
9+
- Changed: Indexer now stores index files on disk instead of using Extension Context state
910

1011
## [1.6.0] - 2025-04-09
1112

src/indexer/IndexManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class IndexManager {
7777
Logger.logWithTime('Indexing workspace', workspaceFolder.name);
7878

7979
for (const indexer of this.indexers) {
80-
this.indexStorage.loadIndex(workspaceFolder, indexer.getId(), indexer.getVersion());
80+
await this.indexStorage.loadIndex(workspaceFolder, indexer.getId(), indexer.getVersion());
8181

8282
if (!force && !this.shouldIndex(workspaceFolder, indexer)) {
8383
Logger.logWithTime('Loaded index from storage', workspaceFolder.name, indexer.getId());
@@ -116,7 +116,7 @@ class IndexManager {
116116
}
117117

118118
this.indexStorage.set(workspaceFolder, indexer.getId(), indexData);
119-
this.indexStorage.saveIndex(workspaceFolder, indexer.getId(), indexer.getVersion());
119+
await this.indexStorage.saveIndex(workspaceFolder, indexer.getId(), indexer.getVersion());
120120

121121
clear([indexer.getId()]);
122122

src/indexer/IndexStorage.ts

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { WorkspaceFolder } from 'vscode';
1+
import { WorkspaceFolder, Uri, workspace } from 'vscode';
22
import { IndexerKey, IndexerStorage, IndexedFilePath, SavedIndex } from 'types/indexer';
33
import { IndexDataSerializer } from './IndexDataSerializer';
4-
import Context from 'common/Context';
54
import ExtensionState from 'common/ExtensionState';
5+
import * as path from 'path';
6+
import Logger from 'util/Logger';
67

78
export 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

Comments
 (0)