@zabaca/lattice 1.0.3 → 1.0.4
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/dist/main.js +54 -17
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -832,7 +832,6 @@ EmbeddingService = __legacyDecorateClassTS([
|
|
|
832
832
|
], EmbeddingService);
|
|
833
833
|
|
|
834
834
|
// src/graph/graph.service.ts
|
|
835
|
-
import { existsSync as existsSync3, unlinkSync } from "fs";
|
|
836
835
|
import { DuckDBInstance } from "@duckdb/node-api";
|
|
837
836
|
import { Injectable as Injectable6, Logger as Logger3 } from "@nestjs/common";
|
|
838
837
|
import { ConfigService as ConfigService2 } from "@nestjs/config";
|
|
@@ -845,11 +844,35 @@ class GraphService {
|
|
|
845
844
|
connecting = null;
|
|
846
845
|
vectorIndexes = new Set;
|
|
847
846
|
embeddingDimensions;
|
|
847
|
+
signalHandlersRegistered = false;
|
|
848
848
|
constructor(configService) {
|
|
849
849
|
this.configService = configService;
|
|
850
850
|
ensureLatticeHome();
|
|
851
851
|
this.dbPath = getDatabasePath();
|
|
852
852
|
this.embeddingDimensions = this.configService.get("EMBEDDING_DIMENSIONS") || 512;
|
|
853
|
+
this.registerSignalHandlers();
|
|
854
|
+
}
|
|
855
|
+
registerSignalHandlers() {
|
|
856
|
+
if (this.signalHandlersRegistered)
|
|
857
|
+
return;
|
|
858
|
+
this.signalHandlersRegistered = true;
|
|
859
|
+
const gracefulShutdown = async (signal) => {
|
|
860
|
+
this.logger.log(`Received ${signal}, checkpointing before exit...`);
|
|
861
|
+
try {
|
|
862
|
+
await this.checkpoint();
|
|
863
|
+
await this.disconnect();
|
|
864
|
+
} catch (error) {
|
|
865
|
+
this.logger.error(`Error during graceful shutdown: ${error instanceof Error ? error.message : String(error)}`);
|
|
866
|
+
}
|
|
867
|
+
process.exit(0);
|
|
868
|
+
};
|
|
869
|
+
process.on("SIGINT", () => gracefulShutdown("SIGINT"));
|
|
870
|
+
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
|
|
871
|
+
process.on("beforeExit", async () => {
|
|
872
|
+
if (this.connection) {
|
|
873
|
+
await this.checkpoint();
|
|
874
|
+
}
|
|
875
|
+
});
|
|
853
876
|
}
|
|
854
877
|
async onModuleDestroy() {
|
|
855
878
|
await this.disconnect();
|
|
@@ -875,12 +898,7 @@ class GraphService {
|
|
|
875
898
|
}
|
|
876
899
|
async connect() {
|
|
877
900
|
try {
|
|
878
|
-
|
|
879
|
-
if (existsSync3(walPath)) {
|
|
880
|
-
this.logger.warn(`Removing WAL file to prevent HNSW index replay failure`);
|
|
881
|
-
unlinkSync(walPath);
|
|
882
|
-
}
|
|
883
|
-
this.instance = await DuckDBInstance.create(this.dbPath, {
|
|
901
|
+
this.instance = await DuckDBInstance.create(":memory:", {
|
|
884
902
|
allow_unsigned_extensions: "true"
|
|
885
903
|
});
|
|
886
904
|
this.connection = await this.instance.connect();
|
|
@@ -894,8 +912,10 @@ class GraphService {
|
|
|
894
912
|
} catch (e) {
|
|
895
913
|
this.logger.warn(`DuckPGQ extension not available: ${e instanceof Error ? e.message : String(e)}`);
|
|
896
914
|
}
|
|
915
|
+
await this.connection.run(`ATTACH '${this.dbPath}' AS lattice (READ_WRITE);`);
|
|
916
|
+
await this.connection.run("USE lattice;");
|
|
897
917
|
await this.initializeSchema();
|
|
898
|
-
this.logger.log(`Connected to DuckDB at ${this.dbPath}`);
|
|
918
|
+
this.logger.log(`Connected to DuckDB (in-memory + ATTACH) at ${this.dbPath}`);
|
|
899
919
|
} catch (error) {
|
|
900
920
|
this.connection = null;
|
|
901
921
|
this.instance = null;
|
|
@@ -905,11 +925,7 @@ class GraphService {
|
|
|
905
925
|
}
|
|
906
926
|
async disconnect() {
|
|
907
927
|
if (this.connection) {
|
|
908
|
-
|
|
909
|
-
await this.connection.run("CHECKPOINT;");
|
|
910
|
-
} catch {
|
|
911
|
-
this.logger.debug("Checkpoint failed during disconnect");
|
|
912
|
-
}
|
|
928
|
+
await this.checkpoint();
|
|
913
929
|
this.connection.closeSync();
|
|
914
930
|
this.connection = null;
|
|
915
931
|
this.logger.log("Disconnected from DuckDB");
|
|
@@ -918,6 +934,17 @@ class GraphService {
|
|
|
918
934
|
this.instance = null;
|
|
919
935
|
}
|
|
920
936
|
}
|
|
937
|
+
async checkpoint() {
|
|
938
|
+
if (!this.connection) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
try {
|
|
942
|
+
await this.connection.run("CHECKPOINT;");
|
|
943
|
+
this.logger.debug("Checkpoint completed");
|
|
944
|
+
} catch (error) {
|
|
945
|
+
this.logger.warn(`Checkpoint failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
921
948
|
async initializeSchema() {
|
|
922
949
|
if (!this.connection) {
|
|
923
950
|
throw new Error("Cannot initialize schema: not connected");
|
|
@@ -1384,7 +1411,7 @@ import { Command as Command4, CommandRunner as CommandRunner4, Option as Option3
|
|
|
1384
1411
|
|
|
1385
1412
|
// src/sync/manifest.service.ts
|
|
1386
1413
|
import { createHash as createHash2 } from "crypto";
|
|
1387
|
-
import { existsSync as
|
|
1414
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1388
1415
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
1389
1416
|
import { Injectable as Injectable8 } from "@nestjs/common";
|
|
1390
1417
|
|
|
@@ -1412,7 +1439,7 @@ class ManifestService {
|
|
|
1412
1439
|
}
|
|
1413
1440
|
async load() {
|
|
1414
1441
|
try {
|
|
1415
|
-
if (
|
|
1442
|
+
if (existsSync3(this.manifestPath)) {
|
|
1416
1443
|
const content = await readFile3(this.manifestPath, "utf-8");
|
|
1417
1444
|
this.manifest = SyncManifestSchema.parse(JSON.parse(content));
|
|
1418
1445
|
} else {
|
|
@@ -1898,7 +1925,7 @@ CascadeService = __legacyDecorateClassTS([
|
|
|
1898
1925
|
], CascadeService);
|
|
1899
1926
|
|
|
1900
1927
|
// src/sync/path-resolver.service.ts
|
|
1901
|
-
import { existsSync as
|
|
1928
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1902
1929
|
import { isAbsolute, resolve as resolve2 } from "path";
|
|
1903
1930
|
import { Injectable as Injectable10 } from "@nestjs/common";
|
|
1904
1931
|
class PathResolverService {
|
|
@@ -1920,7 +1947,7 @@ class PathResolverService {
|
|
|
1920
1947
|
if (requireInDocs && !this.isUnderDocs(resolvedPath)) {
|
|
1921
1948
|
throw new Error(`Path "${userPath}" resolves to "${resolvedPath}" which is outside the docs directory (${this.docsPath})`);
|
|
1922
1949
|
}
|
|
1923
|
-
if (requireExists && !
|
|
1950
|
+
if (requireExists && !existsSync4(resolvedPath)) {
|
|
1924
1951
|
throw new Error(`Path "${userPath}" does not exist (resolved to: ${resolvedPath})`);
|
|
1925
1952
|
}
|
|
1926
1953
|
return resolvedPath;
|
|
@@ -2048,10 +2075,13 @@ class SyncService {
|
|
|
2048
2075
|
}
|
|
2049
2076
|
if (!options.dryRun) {
|
|
2050
2077
|
result.entityEmbeddingsGenerated = await this.syncEntities(uniqueEntities, options);
|
|
2078
|
+
await this.graph.checkpoint();
|
|
2051
2079
|
if (options.verbose) {
|
|
2052
2080
|
this.logger.log(`Synced ${uniqueEntities.size} entities, generated ${result.entityEmbeddingsGenerated} embeddings`);
|
|
2053
2081
|
}
|
|
2054
2082
|
}
|
|
2083
|
+
const CHECKPOINT_BATCH_SIZE = 10;
|
|
2084
|
+
let processedCount = 0;
|
|
2055
2085
|
for (const change of changes) {
|
|
2056
2086
|
try {
|
|
2057
2087
|
const doc = docsByPath.get(change.path);
|
|
@@ -2074,12 +2104,19 @@ class SyncService {
|
|
|
2074
2104
|
if (change.embeddingGenerated) {
|
|
2075
2105
|
result.embeddingsGenerated++;
|
|
2076
2106
|
}
|
|
2107
|
+
processedCount++;
|
|
2108
|
+
if (!options.dryRun && processedCount % CHECKPOINT_BATCH_SIZE === 0) {
|
|
2109
|
+
await this.graph.checkpoint();
|
|
2110
|
+
}
|
|
2077
2111
|
} catch (error) {
|
|
2078
2112
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2079
2113
|
result.errors.push({ path: change.path, error: errorMessage });
|
|
2080
2114
|
this.logger.warn(`Error processing ${change.path}: ${errorMessage}`);
|
|
2081
2115
|
}
|
|
2082
2116
|
}
|
|
2117
|
+
if (!options.dryRun && processedCount > 0) {
|
|
2118
|
+
await this.graph.checkpoint();
|
|
2119
|
+
}
|
|
2083
2120
|
if (!options.dryRun) {
|
|
2084
2121
|
await this.manifest.save();
|
|
2085
2122
|
}
|