@softerist/heuristic-mcp 3.2.2 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/features/lifecycle.js +30 -0
- package/index.js +51 -6
- package/lib/cache.js +118 -86
- package/lib/constants.js +8 -7
- package/lib/vector-store-binary.js +607 -369
- package/package.json +1 -1
package/features/lifecycle.js
CHANGED
|
@@ -1269,6 +1269,36 @@ export async function status({ fix = false, cacheOnly = false, workspaceDir = nu
|
|
|
1269
1269
|
if (binaryTelemetry.lastError?.message) {
|
|
1270
1270
|
console.info(` Last binary error: ${binaryTelemetry.lastError.message}`);
|
|
1271
1271
|
}
|
|
1272
|
+
if (
|
|
1273
|
+
(totals.corruptionDetected || 0) > 0 ||
|
|
1274
|
+
(totals.corruptionAutoCleared || 0) > 0 ||
|
|
1275
|
+
(totals.corruptionSecondaryReadonlyBlocked || 0) > 0
|
|
1276
|
+
) {
|
|
1277
|
+
console.info(
|
|
1278
|
+
` Corruption telemetry: detected=${totals.corruptionDetected || 0} autoCleared=${totals.corruptionAutoCleared || 0} secondaryBlocked=${totals.corruptionSecondaryReadonlyBlocked || 0}`
|
|
1279
|
+
);
|
|
1280
|
+
}
|
|
1281
|
+
if (binaryTelemetry.lastCorruption?.at || binaryTelemetry.lastCorruption?.message) {
|
|
1282
|
+
const atLabel = binaryTelemetry.lastCorruption?.at
|
|
1283
|
+
? formatDateTime(binaryTelemetry.lastCorruption.at)
|
|
1284
|
+
: 'unknown time';
|
|
1285
|
+
const actionLabel =
|
|
1286
|
+
typeof binaryTelemetry.lastCorruption?.action === 'string'
|
|
1287
|
+
? binaryTelemetry.lastCorruption.action
|
|
1288
|
+
: 'unknown';
|
|
1289
|
+
const contextLabel =
|
|
1290
|
+
typeof binaryTelemetry.lastCorruption?.context === 'string'
|
|
1291
|
+
? binaryTelemetry.lastCorruption.context
|
|
1292
|
+
: 'n/a';
|
|
1293
|
+
const msgLabel =
|
|
1294
|
+
typeof binaryTelemetry.lastCorruption?.message === 'string' &&
|
|
1295
|
+
binaryTelemetry.lastCorruption.message.trim().length > 0
|
|
1296
|
+
? ` message=${binaryTelemetry.lastCorruption.message}`
|
|
1297
|
+
: '';
|
|
1298
|
+
console.info(
|
|
1299
|
+
` Last corruption event: ${atLabel} action=${actionLabel} context=${contextLabel}${msgLabel}`
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1272
1302
|
}
|
|
1273
1303
|
|
|
1274
1304
|
if (metaData && isProgressIncomplete) {
|
package/index.js
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
} from './lib/server-lifecycle.js';
|
|
51
51
|
|
|
52
52
|
import { EmbeddingsCache } from './lib/cache.js';
|
|
53
|
-
import { cleanupStaleBinaryArtifacts } from './lib/vector-store-binary.js';
|
|
53
|
+
import { cleanupStaleBinaryArtifacts, recordBinaryStoreCorruption } from './lib/vector-store-binary.js';
|
|
54
54
|
import { CodebaseIndexer } from './features/index-codebase.js';
|
|
55
55
|
import { HybridSearch } from './features/hybrid-search.js';
|
|
56
56
|
|
|
@@ -879,7 +879,25 @@ async function initialize(workspaceDir) {
|
|
|
879
879
|
stopStartupMemory();
|
|
880
880
|
}
|
|
881
881
|
};
|
|
882
|
-
const
|
|
882
|
+
const handleCorruptCacheAfterLoad = async ({ context, canReindex }) => {
|
|
883
|
+
if (!cache.consumeAutoReindex()) return false;
|
|
884
|
+
cache.clearInMemoryState();
|
|
885
|
+
await recordBinaryStoreCorruption(config.cacheDirectory, {
|
|
886
|
+
context,
|
|
887
|
+
action: canReindex ? 'auto-cleared' : 'secondary-readonly-blocked',
|
|
888
|
+
});
|
|
889
|
+
if (canReindex) {
|
|
890
|
+
console.warn(
|
|
891
|
+
`[Server] Cache corruption detected while ${context}; in-memory cache was cleared and a full re-index will run.`
|
|
892
|
+
);
|
|
893
|
+
} else {
|
|
894
|
+
console.warn(
|
|
895
|
+
`[Server] Cache corruption detected while ${context}. This server is secondary read-only and cannot re-index. Reload the IDE window for this workspace or use the primary instance to rebuild the cache.`
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
return true;
|
|
899
|
+
};
|
|
900
|
+
const tryAutoAttachWorkspaceCache = async (reason, { canReindex = workspaceLockAcquired } = {}) => {
|
|
883
901
|
const candidate = await findAutoAttachWorkspaceCandidate({
|
|
884
902
|
excludeCacheDirectory: config.cacheDirectory,
|
|
885
903
|
});
|
|
@@ -897,6 +915,10 @@ async function initialize(workspaceDir) {
|
|
|
897
915
|
await cleanupStaleBinaryArtifacts(config.cacheDirectory, { logger: console });
|
|
898
916
|
}
|
|
899
917
|
await cache.load();
|
|
918
|
+
await handleCorruptCacheAfterLoad({
|
|
919
|
+
context: `auto-attaching workspace cache (${reason})`,
|
|
920
|
+
canReindex,
|
|
921
|
+
});
|
|
900
922
|
console.info(
|
|
901
923
|
`[Server] Auto-attached workspace cache (${reason}): ${candidate.workspace} via ${candidate.source}`
|
|
902
924
|
);
|
|
@@ -916,7 +938,9 @@ async function initialize(workspaceDir) {
|
|
|
916
938
|
console.warn(
|
|
917
939
|
`[Server] Detected system fallback workspace: ${config.searchDirectory}. Attempting cache auto-attach.`
|
|
918
940
|
);
|
|
919
|
-
const attached = await tryAutoAttachWorkspaceCache('system-fallback'
|
|
941
|
+
const attached = await tryAutoAttachWorkspaceCache('system-fallback', {
|
|
942
|
+
canReindex: workspaceLockAcquired,
|
|
943
|
+
});
|
|
920
944
|
if (!attached) {
|
|
921
945
|
console.warn(
|
|
922
946
|
'[Server] Waiting for a proper workspace root (MCP roots, env vars, or f_set_workspace).'
|
|
@@ -932,8 +956,12 @@ async function initialize(workspaceDir) {
|
|
|
932
956
|
try {
|
|
933
957
|
console.info('[Server] Secondary instance detected; loading cache in read-only mode.');
|
|
934
958
|
await cache.load();
|
|
959
|
+
await handleCorruptCacheAfterLoad({
|
|
960
|
+
context: 'loading cache in secondary read-only mode',
|
|
961
|
+
canReindex: false,
|
|
962
|
+
});
|
|
935
963
|
if (cache.getStoreSize() === 0) {
|
|
936
|
-
await tryAutoAttachWorkspaceCache('secondary-empty-cache');
|
|
964
|
+
await tryAutoAttachWorkspaceCache('secondary-empty-cache', { canReindex: false });
|
|
937
965
|
}
|
|
938
966
|
if (config.verbose) {
|
|
939
967
|
logMemory('[Server] Memory (after cache load)');
|
|
@@ -947,9 +975,10 @@ async function initialize(workspaceDir) {
|
|
|
947
975
|
|
|
948
976
|
void preloadEmbeddingModel();
|
|
949
977
|
|
|
950
|
-
try {
|
|
951
|
-
console.info('[Server] Loading cache (deferred)...');
|
|
978
|
+
try {
|
|
979
|
+
console.info('[Server] Loading cache (deferred)...');
|
|
952
980
|
await cache.load();
|
|
981
|
+
await handleCorruptCacheAfterLoad({ context: 'startup cache load', canReindex: true });
|
|
953
982
|
if (config.verbose) {
|
|
954
983
|
logMemory('[Server] Memory (after cache load)');
|
|
955
984
|
}
|
|
@@ -1105,6 +1134,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1105
1134
|
try {
|
|
1106
1135
|
await fs.mkdir(config.cacheDirectory, { recursive: true });
|
|
1107
1136
|
await cache.load();
|
|
1137
|
+
if (cache.consumeAutoReindex()) {
|
|
1138
|
+
cache.clearInMemoryState();
|
|
1139
|
+
await recordBinaryStoreCorruption(config.cacheDirectory, {
|
|
1140
|
+
context: 'f_set_workspace read-only attach',
|
|
1141
|
+
action: 'secondary-readonly-blocked',
|
|
1142
|
+
});
|
|
1143
|
+
return {
|
|
1144
|
+
content: [
|
|
1145
|
+
{
|
|
1146
|
+
type: 'text',
|
|
1147
|
+
text: `Attached cache for ${normalizedPath}, but it is corrupt. This secondary read-only instance cannot rebuild it. Reload the IDE window for this workspace or run indexing from the primary instance.`,
|
|
1148
|
+
},
|
|
1149
|
+
],
|
|
1150
|
+
isError: true,
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1108
1153
|
trustWorkspacePath(normalizedPath);
|
|
1109
1154
|
return {
|
|
1110
1155
|
content: [
|
package/lib/cache.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { Worker } from 'worker_threads';
|
|
4
|
-
import { StreamingJsonWriter } from './json-writer.js';
|
|
5
|
-
import { BinaryVectorStore } from './vector-store-binary.js';
|
|
6
|
-
import { SqliteVectorStore } from './vector-store-sqlite.js';
|
|
7
|
-
import { isNonProjectDirectory } from './config.js';
|
|
3
|
+
import { Worker } from 'worker_threads';
|
|
4
|
+
import { StreamingJsonWriter } from './json-writer.js';
|
|
8
5
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
BinaryVectorStore,
|
|
7
|
+
BinaryStoreCorruptionError,
|
|
8
|
+
recordBinaryStoreCorruption,
|
|
9
|
+
} from './vector-store-binary.js';
|
|
10
|
+
import { SqliteVectorStore } from './vector-store-sqlite.js';
|
|
11
|
+
import { isNonProjectDirectory } from './config.js';
|
|
12
|
+
import {
|
|
13
|
+
JSON_WORKER_THRESHOLD_BYTES,
|
|
14
|
+
ANN_DIMENSION_SAMPLE_SIZE,
|
|
15
|
+
HNSWLIB_ERROR_RESET_MS,
|
|
12
16
|
DEFAULT_READER_WAIT_TIMEOUT_MS,
|
|
13
17
|
} from './constants.js';
|
|
14
18
|
|
|
@@ -266,12 +270,12 @@ export class EmbeddingsCache {
|
|
|
266
270
|
};
|
|
267
271
|
|
|
268
272
|
|
|
269
|
-
this.saveQueue = Promise.resolve();
|
|
270
|
-
this._saveTimer = null;
|
|
271
|
-
this._saveRequested = false;
|
|
272
|
-
this._savePromise = null;
|
|
273
|
-
this._saveThrowOnError = false;
|
|
274
|
-
this.lastSaveError = null;
|
|
273
|
+
this.saveQueue = Promise.resolve();
|
|
274
|
+
this._saveTimer = null;
|
|
275
|
+
this._saveRequested = false;
|
|
276
|
+
this._savePromise = null;
|
|
277
|
+
this._saveThrowOnError = false;
|
|
278
|
+
this.lastSaveError = null;
|
|
275
279
|
|
|
276
280
|
|
|
277
281
|
this.annIndex = null;
|
|
@@ -303,8 +307,23 @@ export class EmbeddingsCache {
|
|
|
303
307
|
|
|
304
308
|
this._clearedAfterIndex = false;
|
|
305
309
|
this._loadPromise = null;
|
|
310
|
+
this._corruptionDetected = false;
|
|
306
311
|
}
|
|
307
312
|
|
|
313
|
+
/**
|
|
314
|
+
* Returns true if the last load() detected binary store corruption.
|
|
315
|
+
* Used by the server to decide whether to trigger an automatic re-index.
|
|
316
|
+
*/
|
|
317
|
+
shouldAutoReindex() {
|
|
318
|
+
return this._corruptionDetected === true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
consumeAutoReindex() {
|
|
322
|
+
const should = this._corruptionDetected === true;
|
|
323
|
+
this._corruptionDetected = false;
|
|
324
|
+
return should;
|
|
325
|
+
}
|
|
326
|
+
|
|
308
327
|
|
|
309
328
|
addInitError(stage, error) {
|
|
310
329
|
this.initErrors.push({
|
|
@@ -510,6 +529,7 @@ export class EmbeddingsCache {
|
|
|
510
529
|
|
|
511
530
|
async load({ forceVectorLoadMode } = {}) {
|
|
512
531
|
if (!this.config.enableCache) return;
|
|
532
|
+
this._corruptionDetected = false;
|
|
513
533
|
|
|
514
534
|
try {
|
|
515
535
|
await fs.mkdir(this.config.cacheDirectory, { recursive: true });
|
|
@@ -660,7 +680,19 @@ export class EmbeddingsCache {
|
|
|
660
680
|
});
|
|
661
681
|
} catch (err) {
|
|
662
682
|
this.binaryStore = null;
|
|
663
|
-
|
|
683
|
+
const isCorruption = err instanceof BinaryStoreCorruptionError ||
|
|
684
|
+
err?.name === 'BinaryStoreCorruptionError';
|
|
685
|
+
if (isCorruption) {
|
|
686
|
+
console.warn(`[Cache] Binary store corruption detected: ${err.message}`);
|
|
687
|
+
this._corruptionDetected = true;
|
|
688
|
+
await recordBinaryStoreCorruption(this.config.cacheDirectory, {
|
|
689
|
+
message: err.message,
|
|
690
|
+
context: 'cache.load binary store',
|
|
691
|
+
action: 'detected',
|
|
692
|
+
});
|
|
693
|
+
} else {
|
|
694
|
+
console.warn(`[Cache] Failed to load binary vector store: ${err.message}`);
|
|
695
|
+
}
|
|
664
696
|
}
|
|
665
697
|
}
|
|
666
698
|
|
|
@@ -773,39 +805,39 @@ export class EmbeddingsCache {
|
|
|
773
805
|
|
|
774
806
|
|
|
775
807
|
|
|
776
|
-
save({ throwOnError = false } = {}) {
|
|
777
|
-
if (!this.config.enableCache) return Promise.resolve();
|
|
778
|
-
|
|
779
|
-
this._saveRequested = true;
|
|
780
|
-
if (throwOnError) {
|
|
781
|
-
this._saveThrowOnError = true;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (this._saveTimer) return this._savePromise ?? Promise.resolve();
|
|
808
|
+
save({ throwOnError = false } = {}) {
|
|
809
|
+
if (!this.config.enableCache) return Promise.resolve();
|
|
810
|
+
|
|
811
|
+
this._saveRequested = true;
|
|
812
|
+
if (throwOnError) {
|
|
813
|
+
this._saveThrowOnError = true;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (this._saveTimer) return this._savePromise ?? Promise.resolve();
|
|
785
817
|
|
|
786
818
|
const debounceMs = Number.isInteger(this.config.saveDebounceMs)
|
|
787
819
|
? this.config.saveDebounceMs
|
|
788
820
|
: 250;
|
|
789
821
|
|
|
790
|
-
this._savePromise = new Promise((resolve, reject) => {
|
|
791
|
-
this._saveTimer = setTimeout(() => {
|
|
792
|
-
this._saveTimer = null;
|
|
793
|
-
const rejectOnSaveError = this._saveThrowOnError;
|
|
794
|
-
this._saveThrowOnError = false;
|
|
795
|
-
|
|
796
|
-
this.saveQueue = this.saveQueue
|
|
797
|
-
.catch(() => {
|
|
798
|
-
|
|
799
|
-
})
|
|
800
|
-
.then(async () => {
|
|
801
|
-
while (this._saveRequested) {
|
|
802
|
-
this._saveRequested = false;
|
|
803
|
-
await this.performSave({ throwOnError: rejectOnSaveError });
|
|
804
|
-
}
|
|
805
|
-
})
|
|
806
|
-
.then(resolve, reject)
|
|
807
|
-
.finally(() => {
|
|
808
|
-
this._savePromise = null;
|
|
822
|
+
this._savePromise = new Promise((resolve, reject) => {
|
|
823
|
+
this._saveTimer = setTimeout(() => {
|
|
824
|
+
this._saveTimer = null;
|
|
825
|
+
const rejectOnSaveError = this._saveThrowOnError;
|
|
826
|
+
this._saveThrowOnError = false;
|
|
827
|
+
|
|
828
|
+
this.saveQueue = this.saveQueue
|
|
829
|
+
.catch(() => {
|
|
830
|
+
|
|
831
|
+
})
|
|
832
|
+
.then(async () => {
|
|
833
|
+
while (this._saveRequested) {
|
|
834
|
+
this._saveRequested = false;
|
|
835
|
+
await this.performSave({ throwOnError: rejectOnSaveError });
|
|
836
|
+
}
|
|
837
|
+
})
|
|
838
|
+
.then(resolve, reject)
|
|
839
|
+
.finally(() => {
|
|
840
|
+
this._savePromise = null;
|
|
809
841
|
});
|
|
810
842
|
}, debounceMs);
|
|
811
843
|
});
|
|
@@ -813,24 +845,24 @@ export class EmbeddingsCache {
|
|
|
813
845
|
return this._savePromise;
|
|
814
846
|
}
|
|
815
847
|
|
|
816
|
-
async performSave({ throwOnError = false } = {}) {
|
|
817
|
-
|
|
818
|
-
this._saveInProgress = true;
|
|
819
|
-
if (
|
|
820
|
-
this.config.allowSystemWorkspaceCache !== true &&
|
|
821
|
-
this.config.searchDirectory &&
|
|
822
|
-
isNonProjectDirectory(this.config.searchDirectory)
|
|
823
|
-
) {
|
|
824
|
-
const source = this.config.workspaceResolution?.source || 'unknown';
|
|
825
|
-
console.warn(
|
|
826
|
-
`[Cache] Skipping cache save for non-project workspace (${source}): ${this.config.searchDirectory}`
|
|
827
|
-
);
|
|
828
|
-
this._saveInProgress = false;
|
|
829
|
-
return;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
if (this.activeReads > 0) {
|
|
848
|
+
async performSave({ throwOnError = false } = {}) {
|
|
849
|
+
|
|
850
|
+
this._saveInProgress = true;
|
|
851
|
+
if (
|
|
852
|
+
this.config.allowSystemWorkspaceCache !== true &&
|
|
853
|
+
this.config.searchDirectory &&
|
|
854
|
+
isNonProjectDirectory(this.config.searchDirectory)
|
|
855
|
+
) {
|
|
856
|
+
const source = this.config.workspaceResolution?.source || 'unknown';
|
|
857
|
+
console.warn(
|
|
858
|
+
`[Cache] Skipping cache save for non-project workspace (${source}): ${this.config.searchDirectory}`
|
|
859
|
+
);
|
|
860
|
+
this._saveInProgress = false;
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
if (this.activeReads > 0) {
|
|
834
866
|
const timeoutMs = this.config.saveReaderWaitTimeoutMs ?? DEFAULT_READER_WAIT_TIMEOUT_MS;
|
|
835
867
|
const allReadersFinished = await this.waitForReadersWithTimeout(timeoutMs);
|
|
836
868
|
if (!allReadersFinished && !this.config.forceSaveWithActiveReaders) {
|
|
@@ -998,9 +1030,9 @@ export class EmbeddingsCache {
|
|
|
998
1030
|
|
|
999
1031
|
|
|
1000
1032
|
|
|
1001
|
-
if (
|
|
1002
|
-
this.config.annIndexCache !== false &&
|
|
1003
|
-
this.annPersistDirty &&
|
|
1033
|
+
if (
|
|
1034
|
+
this.config.annIndexCache !== false &&
|
|
1035
|
+
this.annPersistDirty &&
|
|
1004
1036
|
!this.annDirty &&
|
|
1005
1037
|
!this._annWriting &&
|
|
1006
1038
|
this.annIndex &&
|
|
@@ -1019,12 +1051,12 @@ export class EmbeddingsCache {
|
|
|
1019
1051
|
console.warn(`[ANN] Failed to persist ANN index: ${error.message}`);
|
|
1020
1052
|
} finally {
|
|
1021
1053
|
this._annWriting = false;
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
this.lastSaveError = null;
|
|
1025
|
-
} catch (error) {
|
|
1026
|
-
this.lastSaveError = error instanceof Error ? error : new Error(String(error));
|
|
1027
|
-
console.warn('[Cache] Failed to save cache:', this.lastSaveError.message);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
this.lastSaveError = null;
|
|
1057
|
+
} catch (error) {
|
|
1058
|
+
this.lastSaveError = error instanceof Error ? error : new Error(String(error));
|
|
1059
|
+
console.warn('[Cache] Failed to save cache:', this.lastSaveError.message);
|
|
1028
1060
|
|
|
1029
1061
|
if (
|
|
1030
1062
|
this.config.vectorStoreFormat === 'binary' &&
|
|
@@ -1043,9 +1075,9 @@ export class EmbeddingsCache {
|
|
|
1043
1075
|
}
|
|
1044
1076
|
}
|
|
1045
1077
|
|
|
1046
|
-
if (
|
|
1047
|
-
this.config.vectorStoreFormat === 'sqlite' &&
|
|
1048
|
-
!this.sqliteStore
|
|
1078
|
+
if (
|
|
1079
|
+
this.config.vectorStoreFormat === 'sqlite' &&
|
|
1080
|
+
!this.sqliteStore
|
|
1049
1081
|
) {
|
|
1050
1082
|
try {
|
|
1051
1083
|
console.info('[Cache] Attempting to recover SQLite store after failed save...');
|
|
@@ -1055,19 +1087,19 @@ export class EmbeddingsCache {
|
|
|
1055
1087
|
}
|
|
1056
1088
|
} catch (recoverErr) {
|
|
1057
1089
|
console.warn(`[Cache] Failed to recover SQLite store: ${recoverErr.message}`);
|
|
1058
|
-
this.sqliteStore = null;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
if (throwOnError) {
|
|
1062
|
-
const wrapped = new Error(`Cache save failed: ${this.lastSaveError.message}`);
|
|
1063
|
-
wrapped.cause = this.lastSaveError;
|
|
1064
|
-
throw wrapped;
|
|
1065
|
-
}
|
|
1066
|
-
} finally {
|
|
1067
|
-
this.isSaving = false;
|
|
1068
|
-
this._saveInProgress = false;
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1090
|
+
this.sqliteStore = null;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (throwOnError) {
|
|
1094
|
+
const wrapped = new Error(`Cache save failed: ${this.lastSaveError.message}`);
|
|
1095
|
+
wrapped.cause = this.lastSaveError;
|
|
1096
|
+
throw wrapped;
|
|
1097
|
+
}
|
|
1098
|
+
} finally {
|
|
1099
|
+
this.isSaving = false;
|
|
1100
|
+
this._saveInProgress = false;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1071
1103
|
|
|
1072
1104
|
|
|
1073
1105
|
|
package/lib/constants.js
CHANGED
|
@@ -248,8 +248,9 @@ export const EMBEDDING_PROCESS_GC_STATE_INITIAL = Object.freeze({
|
|
|
248
248
|
/**
|
|
249
249
|
* Binary vector store format version.
|
|
250
250
|
* Increment when binary format changes to trigger re-indexing.
|
|
251
|
+
* v2: added writeId (4 bytes) + CRC32 (4 bytes) + 8 bytes reserved to all headers.
|
|
251
252
|
*/
|
|
252
|
-
export const BINARY_STORE_VERSION =
|
|
253
|
+
export const BINARY_STORE_VERSION = 2;
|
|
253
254
|
|
|
254
255
|
/**
|
|
255
256
|
* SQLite vector store format version.
|
|
@@ -259,21 +260,21 @@ export const SQLITE_STORE_VERSION = 1;
|
|
|
259
260
|
|
|
260
261
|
/**
|
|
261
262
|
* Binary vector file header size in bytes.
|
|
262
|
-
* Contains: magic (4) + version (4) + dim (4) + count (4) +
|
|
263
|
+
* Contains: magic (4) + version (4) + dim (4) + count (4) + writeId (4) + crc32 (4) + reserved (8)
|
|
263
264
|
*/
|
|
264
|
-
export const BINARY_VECTOR_HEADER_SIZE =
|
|
265
|
+
export const BINARY_VECTOR_HEADER_SIZE = 32;
|
|
265
266
|
|
|
266
267
|
/**
|
|
267
268
|
* Binary record file header size in bytes.
|
|
268
|
-
* Contains: magic (4) + version (4) + count (4) + reserved (8)
|
|
269
|
+
* Contains: magic (4) + version (4) + count (4) + fileCount (4) + writeId (4) + crc32 (4) + reserved (8)
|
|
269
270
|
*/
|
|
270
|
-
export const BINARY_RECORD_HEADER_SIZE =
|
|
271
|
+
export const BINARY_RECORD_HEADER_SIZE = 32;
|
|
271
272
|
|
|
272
273
|
/**
|
|
273
274
|
* Binary content file header size in bytes.
|
|
274
|
-
* Contains: magic (4) + version (4) +
|
|
275
|
+
* Contains: magic (4) + version (4) + totalBytes (8) + writeId (4) + crc32 (4) + reserved (8)
|
|
275
276
|
*/
|
|
276
|
-
export const BINARY_CONTENT_HEADER_SIZE =
|
|
277
|
+
export const BINARY_CONTENT_HEADER_SIZE = 32;
|
|
277
278
|
|
|
278
279
|
/**
|
|
279
280
|
* Size of a single record entry in bytes.
|