@gmickel/gno 1.12.2 → 1.12.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/README.md +1 -1
- package/assets/skill/SKILL.md +4 -2
- package/package.json +2 -1
- package/src/core/context-resolver.ts +285 -0
- package/src/core/indexed-reference.ts +68 -0
- package/src/core/ref-parser.ts +6 -1
- package/src/index.ts +11 -2
- package/src/ingestion/sync.ts +182 -15
- package/src/ingestion/types.ts +2 -0
- package/src/mcp/resources/index.ts +71 -47
- package/src/mcp/tools/get.ts +108 -93
- package/src/mcp/tools/index.ts +3 -3
- package/src/mcp/tools/multi-get.ts +116 -99
- package/src/pipeline/answer-prompt.ts +80 -0
- package/src/pipeline/answer.ts +12 -26
- package/src/pipeline/hybrid.ts +2 -0
- package/src/pipeline/result-context.ts +51 -0
- package/src/pipeline/search.ts +5 -1
- package/src/pipeline/vsearch.ts +2 -0
- package/src/sdk/client.ts +56 -31
- package/src/serve/public/components/AIModelSelector.tsx +22 -7
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/pages/Dashboard.tsx +1 -1
- package/src/serve/routes/api.ts +26 -1
- package/src/serve/server.ts +11 -2
- package/src/serve/status.ts +24 -0
- package/src/serve/watch-service.ts +2 -1
- package/src/store/sqlite/adapter.ts +106 -49
- package/src/store/sqlite/scoped-index.ts +68 -0
- package/src/store/types.ts +9 -1
|
@@ -396,7 +396,7 @@ export default function Dashboard({ navigate }: PageProps) {
|
|
|
396
396
|
</div>
|
|
397
397
|
|
|
398
398
|
<div className="flex flex-wrap items-center gap-3 md:justify-end">
|
|
399
|
-
<AIModelSelector showLabel={false} />
|
|
399
|
+
<AIModelSelector appStatus={status} showLabel={false} />
|
|
400
400
|
<Button
|
|
401
401
|
disabled={syncing}
|
|
402
402
|
onClick={() => void handleSync()}
|
package/src/serve/routes/api.ts
CHANGED
|
@@ -736,6 +736,31 @@ export function handleHealth(): Response {
|
|
|
736
736
|
return jsonResponse({ ok: true });
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
+
const statusBuilds = new WeakMap<
|
|
740
|
+
ServerContext,
|
|
741
|
+
Promise<Awaited<ReturnType<typeof buildAppStatus>>>
|
|
742
|
+
>();
|
|
743
|
+
|
|
744
|
+
async function getCoalescedAppStatus(
|
|
745
|
+
ctx: ServerContext,
|
|
746
|
+
deps?: StatusBuildDeps
|
|
747
|
+
): Promise<Awaited<ReturnType<typeof buildAppStatus>>> {
|
|
748
|
+
const existing = statusBuilds.get(ctx);
|
|
749
|
+
if (existing) {
|
|
750
|
+
return existing;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const build = buildAppStatus(ctx, deps ?? {});
|
|
754
|
+
statusBuilds.set(ctx, build);
|
|
755
|
+
try {
|
|
756
|
+
return await build;
|
|
757
|
+
} finally {
|
|
758
|
+
if (statusBuilds.get(ctx) === build) {
|
|
759
|
+
statusBuilds.delete(ctx);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
739
764
|
/**
|
|
740
765
|
* GET /api/status
|
|
741
766
|
* Returns index status matching status.schema.json.
|
|
@@ -745,7 +770,7 @@ export async function handleStatus(
|
|
|
745
770
|
deps?: StatusBuildDeps
|
|
746
771
|
): Promise<Response> {
|
|
747
772
|
try {
|
|
748
|
-
const status = await
|
|
773
|
+
const status = await getCoalescedAppStatus(ctx, deps);
|
|
749
774
|
return jsonResponse(status);
|
|
750
775
|
} catch (error) {
|
|
751
776
|
return errorResponse(
|
package/src/serve/server.ts
CHANGED
|
@@ -163,6 +163,10 @@ export async function startServer(
|
|
|
163
163
|
|
|
164
164
|
process.once("SIGINT", shutdown);
|
|
165
165
|
process.once("SIGTERM", shutdown);
|
|
166
|
+
const removeShutdownHandlers = (): void => {
|
|
167
|
+
process.off("SIGINT", shutdown);
|
|
168
|
+
process.off("SIGTERM", shutdown);
|
|
169
|
+
};
|
|
166
170
|
|
|
167
171
|
// Start server with try/catch for port-in-use etc.
|
|
168
172
|
let server: ReturnType<typeof Bun.serve>;
|
|
@@ -679,6 +683,7 @@ export async function startServer(
|
|
|
679
683
|
},
|
|
680
684
|
});
|
|
681
685
|
} catch (e) {
|
|
686
|
+
removeShutdownHandlers();
|
|
682
687
|
await runtime.dispose();
|
|
683
688
|
return {
|
|
684
689
|
success: false,
|
|
@@ -696,7 +701,11 @@ export async function startServer(
|
|
|
696
701
|
});
|
|
697
702
|
});
|
|
698
703
|
|
|
699
|
-
|
|
700
|
-
|
|
704
|
+
removeShutdownHandlers();
|
|
705
|
+
try {
|
|
706
|
+
await server.stop(true);
|
|
707
|
+
} finally {
|
|
708
|
+
await runtime.dispose();
|
|
709
|
+
}
|
|
701
710
|
return { success: true };
|
|
702
711
|
}
|
package/src/serve/status.ts
CHANGED
|
@@ -381,6 +381,29 @@ async function buildModelCheck(
|
|
|
381
381
|
};
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
+
function buildVectorCheck(ctx: ServerContext): HealthCheck | null {
|
|
385
|
+
const vectorIndex = ctx.vectorIndex;
|
|
386
|
+
if (!vectorIndex || vectorIndex.searchAvailable) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const reason = vectorIndex.loadError?.trim();
|
|
391
|
+
const guidance = vectorIndex.guidance?.trim();
|
|
392
|
+
return {
|
|
393
|
+
id: "vector-runtime",
|
|
394
|
+
title: "Vector search",
|
|
395
|
+
status: "warn",
|
|
396
|
+
summary: "Semantic search acceleration is unavailable",
|
|
397
|
+
detail: [
|
|
398
|
+
reason ? `sqlite-vec failed to load: ${reason}` : null,
|
|
399
|
+
guidance ?? "Run `gno doctor` for recovery guidance.",
|
|
400
|
+
"BM25 search remains available.",
|
|
401
|
+
]
|
|
402
|
+
.filter((part): part is string => part !== null)
|
|
403
|
+
.join(" "),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
384
407
|
async function buildDiskCheck(
|
|
385
408
|
status: IndexStatus,
|
|
386
409
|
deps: StatusBuildDeps
|
|
@@ -636,6 +659,7 @@ export async function buildAppStatus(
|
|
|
636
659
|
buildCollectionCheck(status),
|
|
637
660
|
buildIndexingCheck(status),
|
|
638
661
|
modelCheck,
|
|
662
|
+
buildVectorCheck(ctx),
|
|
639
663
|
diskCheck,
|
|
640
664
|
backgroundCheck,
|
|
641
665
|
].filter((check): check is HealthCheck => check !== null);
|
|
@@ -209,9 +209,10 @@ export class CollectionWatchService {
|
|
|
209
209
|
collection: collection.name,
|
|
210
210
|
relPaths,
|
|
211
211
|
});
|
|
212
|
-
const result = await defaultSyncService.
|
|
212
|
+
const result = await defaultSyncService.syncPaths(
|
|
213
213
|
collection,
|
|
214
214
|
this.#store,
|
|
215
|
+
relPaths,
|
|
215
216
|
{
|
|
216
217
|
...this.#syncOptions,
|
|
217
218
|
runUpdateCmd: false,
|
|
@@ -278,6 +278,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
278
278
|
private configPath = ""; // Set by CLI layer for status output
|
|
279
279
|
private txDepth = 0; // Transaction nesting depth
|
|
280
280
|
private txCounter = 0; // Savepoint counter for unique names
|
|
281
|
+
private contextGeneration = 0;
|
|
281
282
|
|
|
282
283
|
// ─────────────────────────────────────────────────────────────────────────
|
|
283
284
|
// Lifecycle
|
|
@@ -341,6 +342,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
341
342
|
return result;
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
this.contextGeneration += 1;
|
|
344
346
|
return result;
|
|
345
347
|
} catch (cause) {
|
|
346
348
|
const message =
|
|
@@ -517,6 +519,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
517
519
|
});
|
|
518
520
|
|
|
519
521
|
transaction();
|
|
522
|
+
this.contextGeneration += 1;
|
|
520
523
|
return ok(undefined);
|
|
521
524
|
} catch (cause) {
|
|
522
525
|
return err(
|
|
@@ -559,6 +562,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
559
562
|
}
|
|
560
563
|
}
|
|
561
564
|
|
|
565
|
+
getContextGeneration(): number {
|
|
566
|
+
return this.contextGeneration;
|
|
567
|
+
}
|
|
568
|
+
|
|
562
569
|
// ─────────────────────────────────────────────────────────────────────────
|
|
563
570
|
// Documents
|
|
564
571
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -3014,18 +3021,35 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
3014
3021
|
}
|
|
3015
3022
|
}
|
|
3016
3023
|
|
|
3017
|
-
async backfillDocEdges(
|
|
3024
|
+
async backfillDocEdges(
|
|
3025
|
+
sourceDocumentIds?: number[]
|
|
3026
|
+
): Promise<StoreResult<{ inserted: number }>> {
|
|
3018
3027
|
try {
|
|
3019
3028
|
const db = this.ensureOpen();
|
|
3029
|
+
const sourceIds = sourceDocumentIds
|
|
3030
|
+
? [...new Set(sourceDocumentIds)].filter((id) => id > 0)
|
|
3031
|
+
: undefined;
|
|
3032
|
+
if (sourceIds?.length === 0) {
|
|
3033
|
+
return ok({ inserted: 0 });
|
|
3034
|
+
}
|
|
3035
|
+
const sourcePlaceholders = sourceIds
|
|
3036
|
+
? sourceIds.map(() => "?").join(", ")
|
|
3037
|
+
: "";
|
|
3038
|
+
const sourceFilter = sourceIds
|
|
3039
|
+
? `AND src.id IN (${sourcePlaceholders})`
|
|
3040
|
+
: "";
|
|
3020
3041
|
let inserted = 0;
|
|
3021
3042
|
|
|
3022
3043
|
const transaction = db.transaction(() => {
|
|
3023
|
-
db.run(
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3044
|
+
db.run(
|
|
3045
|
+
`DELETE FROM doc_edges
|
|
3046
|
+
WHERE source IN (?, ?)
|
|
3047
|
+
${sourceIds ? `AND src_doc_id IN (${sourcePlaceholders})` : ""}`,
|
|
3048
|
+
["wikilink", "markdown-link", ...(sourceIds ?? [])]
|
|
3049
|
+
);
|
|
3027
3050
|
|
|
3028
|
-
const insertWiki = db.run(
|
|
3051
|
+
const insertWiki = db.run(
|
|
3052
|
+
`
|
|
3029
3053
|
INSERT OR IGNORE INTO doc_edges (
|
|
3030
3054
|
src_doc_id, dst_doc_id, edge_type, confidence, source
|
|
3031
3055
|
)
|
|
@@ -3044,9 +3068,13 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
3044
3068
|
WHERE src.active = 1
|
|
3045
3069
|
AND tgt.active = 1
|
|
3046
3070
|
AND dl.link_type = 'wiki'
|
|
3047
|
-
|
|
3071
|
+
${sourceFilter}
|
|
3072
|
+
`,
|
|
3073
|
+
sourceIds ?? []
|
|
3074
|
+
);
|
|
3048
3075
|
|
|
3049
|
-
const insertMarkdown = db.run(
|
|
3076
|
+
const insertMarkdown = db.run(
|
|
3077
|
+
`
|
|
3050
3078
|
INSERT OR IGNORE INTO doc_edges (
|
|
3051
3079
|
src_doc_id, dst_doc_id, edge_type, confidence, source
|
|
3052
3080
|
)
|
|
@@ -3063,7 +3091,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
3063
3091
|
AND tgt.rel_path = dl.target_ref_norm
|
|
3064
3092
|
WHERE src.active = 1
|
|
3065
3093
|
AND dl.link_type = 'markdown'
|
|
3066
|
-
|
|
3094
|
+
${sourceFilter}
|
|
3095
|
+
`,
|
|
3096
|
+
sourceIds ?? []
|
|
3097
|
+
);
|
|
3067
3098
|
|
|
3068
3099
|
inserted = insertWiki.changes + insertMarkdown.changes;
|
|
3069
3100
|
});
|
|
@@ -3804,36 +3835,56 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
3804
3835
|
const collectionStats = db
|
|
3805
3836
|
.query<CollectionStat, [string | null, string | null, string | null]>(
|
|
3806
3837
|
`
|
|
3838
|
+
WITH document_stats AS (
|
|
3839
|
+
SELECT
|
|
3840
|
+
collection,
|
|
3841
|
+
COUNT(*) AS total,
|
|
3842
|
+
SUM(CASE WHEN active = 1 THEN 1 ELSE 0 END) AS active,
|
|
3843
|
+
SUM(CASE WHEN last_error_code IS NOT NULL THEN 1 ELSE 0 END) AS errored,
|
|
3844
|
+
SUM(CASE WHEN mirror_hash IS NOT NULL THEN 1 ELSE 0 END) AS chunked
|
|
3845
|
+
FROM documents
|
|
3846
|
+
GROUP BY collection
|
|
3847
|
+
),
|
|
3848
|
+
active_collection_mirrors AS (
|
|
3849
|
+
SELECT DISTINCT collection, mirror_hash
|
|
3850
|
+
FROM documents
|
|
3851
|
+
WHERE active = 1 AND mirror_hash IS NOT NULL
|
|
3852
|
+
),
|
|
3853
|
+
matching_vectors AS (
|
|
3854
|
+
SELECT mirror_hash, seq, MAX(embedded_at) AS embedded_at
|
|
3855
|
+
FROM content_vectors
|
|
3856
|
+
WHERE (? IS NULL OR (
|
|
3857
|
+
model = ? AND embed_fingerprint = ?
|
|
3858
|
+
))
|
|
3859
|
+
GROUP BY mirror_hash, seq
|
|
3860
|
+
),
|
|
3861
|
+
collection_chunks AS (
|
|
3862
|
+
SELECT
|
|
3863
|
+
acm.collection,
|
|
3864
|
+
COUNT(*) AS chunk_count,
|
|
3865
|
+
SUM(CASE
|
|
3866
|
+
WHEN mv.embedded_at >= cc.created_at THEN 1
|
|
3867
|
+
ELSE 0
|
|
3868
|
+
END) AS embedded_count
|
|
3869
|
+
FROM active_collection_mirrors acm
|
|
3870
|
+
JOIN content_chunks cc ON cc.mirror_hash = acm.mirror_hash
|
|
3871
|
+
LEFT JOIN matching_vectors mv
|
|
3872
|
+
ON mv.mirror_hash = cc.mirror_hash AND mv.seq = cc.seq
|
|
3873
|
+
GROUP BY acm.collection
|
|
3874
|
+
)
|
|
3807
3875
|
SELECT
|
|
3808
3876
|
c.name,
|
|
3809
3877
|
c.path,
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
(
|
|
3815
|
-
|
|
3816
|
-
WHERE d2.collection = c.name AND d2.active = 1) as chunk_count,
|
|
3817
|
-
(SELECT COUNT(*) FROM content_chunks cc
|
|
3818
|
-
WHERE EXISTS (
|
|
3819
|
-
SELECT 1 FROM documents d3
|
|
3820
|
-
WHERE d3.collection = c.name
|
|
3821
|
-
AND d3.active = 1
|
|
3822
|
-
AND d3.mirror_hash = cc.mirror_hash
|
|
3823
|
-
)
|
|
3824
|
-
AND EXISTS (
|
|
3825
|
-
SELECT 1 FROM content_vectors cv
|
|
3826
|
-
WHERE cv.mirror_hash = cc.mirror_hash
|
|
3827
|
-
AND cv.seq = cc.seq
|
|
3828
|
-
AND (? IS NULL OR (
|
|
3829
|
-
cv.model = ?
|
|
3830
|
-
AND cv.embed_fingerprint = ?
|
|
3831
|
-
))
|
|
3832
|
-
AND cv.embedded_at >= cc.created_at
|
|
3833
|
-
)) as embedded_count
|
|
3878
|
+
COALESCE(ds.total, 0) AS total,
|
|
3879
|
+
COALESCE(ds.active, 0) AS active,
|
|
3880
|
+
COALESCE(ds.errored, 0) AS errored,
|
|
3881
|
+
COALESCE(ds.chunked, 0) AS chunked,
|
|
3882
|
+
COALESCE(ch.chunk_count, 0) AS chunk_count,
|
|
3883
|
+
COALESCE(ch.embedded_count, 0) AS embedded_count
|
|
3834
3884
|
FROM collections c
|
|
3835
|
-
LEFT JOIN
|
|
3836
|
-
|
|
3885
|
+
LEFT JOIN document_stats ds ON ds.collection = c.name
|
|
3886
|
+
LEFT JOIN collection_chunks ch ON ch.collection = c.name
|
|
3887
|
+
ORDER BY c.name
|
|
3837
3888
|
`
|
|
3838
3889
|
)
|
|
3839
3890
|
.all(embedModel, embedModel, embedFingerprint);
|
|
@@ -3865,21 +3916,27 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
3865
3916
|
[string | null, string | null, string | null]
|
|
3866
3917
|
>(
|
|
3867
3918
|
`
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
WHERE
|
|
3872
|
-
)
|
|
3873
|
-
|
|
3874
|
-
SELECT
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
))
|
|
3881
|
-
AND v.embedded_at >= c.created_at
|
|
3919
|
+
WITH active_mirrors AS (
|
|
3920
|
+
SELECT DISTINCT mirror_hash
|
|
3921
|
+
FROM documents
|
|
3922
|
+
WHERE active = 1 AND mirror_hash IS NOT NULL
|
|
3923
|
+
),
|
|
3924
|
+
matching_vectors AS (
|
|
3925
|
+
SELECT mirror_hash, seq, MAX(embedded_at) AS embedded_at
|
|
3926
|
+
FROM content_vectors
|
|
3927
|
+
WHERE (? IS NULL OR (
|
|
3928
|
+
model = ? AND embed_fingerprint = ?
|
|
3929
|
+
))
|
|
3930
|
+
GROUP BY mirror_hash, seq
|
|
3882
3931
|
)
|
|
3932
|
+
SELECT COUNT(*) AS count
|
|
3933
|
+
FROM active_mirrors am
|
|
3934
|
+
JOIN content_chunks c ON c.mirror_hash = am.mirror_hash
|
|
3935
|
+
LEFT JOIN matching_vectors mv
|
|
3936
|
+
ON mv.mirror_hash = c.mirror_hash
|
|
3937
|
+
AND mv.seq = c.seq
|
|
3938
|
+
AND mv.embedded_at >= c.created_at
|
|
3939
|
+
WHERE mv.mirror_hash IS NULL
|
|
3883
3940
|
`
|
|
3884
3941
|
)
|
|
3885
3942
|
.get(embedModel, embedModel, embedFingerprint);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Config } from "../../config/types";
|
|
2
|
+
|
|
3
|
+
import { getIndexDbPath } from "../../app/constants";
|
|
4
|
+
import { indexesMatch } from "../../core/indexed-reference";
|
|
5
|
+
import { SqliteAdapter } from "./adapter";
|
|
6
|
+
|
|
7
|
+
export interface ScopedIndexStore {
|
|
8
|
+
store: SqliteAdapter;
|
|
9
|
+
indexName?: string;
|
|
10
|
+
owned: boolean;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function openScopedIndexStore(options: {
|
|
15
|
+
activeStore: SqliteAdapter;
|
|
16
|
+
activeIndexName?: string;
|
|
17
|
+
requestedIndexName?: string;
|
|
18
|
+
config: Config;
|
|
19
|
+
configPath: string | null;
|
|
20
|
+
}): Promise<ScopedIndexStore> {
|
|
21
|
+
const requestedIndexName =
|
|
22
|
+
options.requestedIndexName ?? options.activeIndexName;
|
|
23
|
+
if (indexesMatch(requestedIndexName, options.activeIndexName)) {
|
|
24
|
+
return {
|
|
25
|
+
store: options.activeStore,
|
|
26
|
+
indexName: requestedIndexName,
|
|
27
|
+
owned: false,
|
|
28
|
+
close: () => Promise.resolve(),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const dbPath = getIndexDbPath(requestedIndexName);
|
|
33
|
+
if (!(await Bun.file(dbPath).exists())) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Index "${requestedIndexName}" does not exist at ${dbPath}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const store = new SqliteAdapter();
|
|
40
|
+
store.setConfigPath(options.configPath ?? "<inline-config>");
|
|
41
|
+
const openResult = await store.open(dbPath, options.config.ftsTokenizer);
|
|
42
|
+
if (!openResult.ok) {
|
|
43
|
+
throw new Error(openResult.error.message);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const collectionsResult = await store.syncCollections(
|
|
47
|
+
options.config.collections
|
|
48
|
+
);
|
|
49
|
+
if (!collectionsResult.ok) {
|
|
50
|
+
await store.close();
|
|
51
|
+
throw new Error(collectionsResult.error.message);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const contextsResult = await store.syncContexts(
|
|
55
|
+
options.config.contexts ?? []
|
|
56
|
+
);
|
|
57
|
+
if (!contextsResult.ok) {
|
|
58
|
+
await store.close();
|
|
59
|
+
throw new Error(contextsResult.error.message);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
store,
|
|
64
|
+
indexName: requestedIndexName,
|
|
65
|
+
owned: true,
|
|
66
|
+
close: () => store.close(),
|
|
67
|
+
};
|
|
68
|
+
}
|
package/src/store/types.ts
CHANGED
|
@@ -800,6 +800,12 @@ export interface StorePort {
|
|
|
800
800
|
*/
|
|
801
801
|
syncContexts(contexts: Context[]): Promise<StoreResult<void>>;
|
|
802
802
|
|
|
803
|
+
/**
|
|
804
|
+
* Monotonic in-process generation for the persisted context snapshot.
|
|
805
|
+
* Changes after a successful context sync or when the store is reopened.
|
|
806
|
+
*/
|
|
807
|
+
getContextGeneration(): number;
|
|
808
|
+
|
|
803
809
|
/**
|
|
804
810
|
* Get all collections from DB.
|
|
805
811
|
*/
|
|
@@ -1110,7 +1116,9 @@ export interface StorePort {
|
|
|
1110
1116
|
/**
|
|
1111
1117
|
* Rebuild derived semantic edges from currently indexed links.
|
|
1112
1118
|
*/
|
|
1113
|
-
backfillDocEdges(
|
|
1119
|
+
backfillDocEdges(
|
|
1120
|
+
sourceDocumentIds?: number[]
|
|
1121
|
+
): Promise<StoreResult<{ inserted: number }>>;
|
|
1114
1122
|
|
|
1115
1123
|
// ─────────────────────────────────────────────────────────────────────────
|
|
1116
1124
|
// Graph
|