gitnexus 1.6.6-rc.2 → 1.6.6-rc.21
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/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +8 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/context.d.ts +18 -1
- package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/context.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts +4 -2
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +8 -23
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/cli/analyze.js +65 -3
- package/dist/cli/eval-server.d.ts +14 -3
- package/dist/cli/eval-server.js +79 -9
- package/dist/cli/index.js +3 -1
- package/dist/cli/serve.js +6 -1
- package/dist/cli/setup.js +6 -4
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +32 -8
- package/dist/core/ingestion/languages/cpp/captures.js +165 -9
- package/dist/core/ingestion/languages/cpp/constraint-filter.js +102 -32
- package/dist/core/ingestion/languages/cpp/type-classifier.d.ts +9 -9
- package/dist/core/ingestion/languages/cpp/type-classifier.js +12 -8
- package/dist/core/ingestion/languages/java.js +35 -0
- package/dist/core/ingestion/languages/javascript/arity.d.ts +11 -0
- package/dist/core/ingestion/languages/javascript/arity.js +11 -0
- package/dist/core/ingestion/languages/javascript/captures.d.ts +30 -0
- package/dist/core/ingestion/languages/javascript/captures.js +655 -0
- package/dist/core/ingestion/languages/javascript/import-target.d.ts +29 -0
- package/dist/core/ingestion/languages/javascript/import-target.js +53 -0
- package/dist/core/ingestion/languages/javascript/index.d.ts +48 -0
- package/dist/core/ingestion/languages/javascript/index.js +48 -0
- package/dist/core/ingestion/languages/javascript/interpret.d.ts +29 -0
- package/dist/core/ingestion/languages/javascript/interpret.js +41 -0
- package/dist/core/ingestion/languages/javascript/merge-bindings.d.ts +16 -0
- package/dist/core/ingestion/languages/javascript/merge-bindings.js +18 -0
- package/dist/core/ingestion/languages/javascript/query.d.ts +52 -0
- package/dist/core/ingestion/languages/javascript/query.js +413 -0
- package/dist/core/ingestion/languages/javascript/scope-resolver.d.ts +37 -0
- package/dist/core/ingestion/languages/javascript/scope-resolver.js +73 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.d.ts +32 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.js +37 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +4 -1
- package/dist/core/ingestion/languages/typescript.js +15 -0
- package/dist/core/ingestion/model/field-registry.d.ts +17 -3
- package/dist/core/ingestion/model/field-registry.js +19 -4
- package/dist/core/ingestion/model/owned-members-lookup.d.ts +19 -0
- package/dist/core/ingestion/model/owned-members-lookup.js +43 -0
- package/dist/core/ingestion/model/type-registry.d.ts +9 -0
- package/dist/core/ingestion/model/type-registry.js +18 -0
- package/dist/core/ingestion/registry-primary-flag.js +1 -0
- package/dist/core/ingestion/resolve-references.d.ts +3 -1
- package/dist/core/ingestion/resolve-references.js +5 -1
- package/dist/core/ingestion/scope-extractor.js +4 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +1 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +37 -7
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +2 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +8 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.d.ts +4 -2
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +48 -9
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +2 -0
- package/dist/core/lbug/lbug-adapter.d.ts +3 -1
- package/dist/core/lbug/lbug-adapter.js +33 -19
- package/dist/core/lbug/lbug-config.d.ts +1 -1
- package/dist/core/lbug/lbug-config.js +1 -1
- package/dist/core/lbug/pool-adapter.d.ts +19 -7
- package/dist/core/lbug/pool-adapter.js +70 -44
- package/dist/core/lbug/query-params.d.ts +1 -0
- package/dist/core/lbug/query-params.js +21 -0
- package/dist/core/search/bm25-index.js +4 -6
- package/dist/core/wiki/generator.d.ts +13 -0
- package/dist/core/wiki/generator.js +45 -4
- package/dist/core/wiki/llm-client.d.ts +1 -1
- package/dist/core/wiki/llm-client.js +23 -6
- package/dist/mcp/local/local-backend.d.ts +18 -3
- package/dist/mcp/local/local-backend.js +127 -11
- package/dist/mcp/tools.js +10 -0
- package/dist/server/api.d.ts +3 -0
- package/dist/server/api.js +58 -30
- package/package.json +3 -3
- package/web/assets/agent-SmDhIVj9.js +608 -0
- package/web/assets/{architectureDiagram-UL44E2DR-DvIkEGkp.js → architectureDiagram-UL44E2DR-ChS6kfgC.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-CqJ0oo1x.js → chunk-LCXTWHL2-CikfiTEP.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-D0M6vdq9.js → chunk-RG4AUYOV-D0pH0sP0.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-BB-saqC1.js → classDiagram-KGZ6W3CR-VJjLBrQ3.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-Bp2bAlS5.js → classDiagram-v2-72OJOZXJ-CL_v399n.js} +1 -1
- package/web/assets/{diagram-3NCE3AQN-BUxnDPOY.js → diagram-3NCE3AQN-DTTuOnDj.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-BJTyqqvI.js → diagram-GF46GFSD-Di3e_png.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-DilMHamP.js → diagram-QXG6HAR7-CVQY1hhk.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-8KUrarg1.js → diagram-WEQXMOUZ-BoxS7CN3.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-Doj9mSiW.js → erDiagram-L5TCEMPS-CLTuHusW.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-BOSR-i3p.js → flowDiagram-H6V6AXG4-CQfVb2C4.js} +1 -1
- package/web/assets/{index-j4-NuleT.js → index-BuC2I_Cj.js} +5 -5
- package/web/assets/{infoDiagram-3YFTVSEB-Ce_TvtaV.js → infoDiagram-3YFTVSEB-BOk6LlXV.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js → ishikawaDiagram-BNXS4ZKH-C0sASGB6.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-yYdfm8Kk.js → kanban-definition-75IXJCU3-DT9Lizpz.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-DFNEKM77.js → mindmap-definition-2TDM6QVE-BEYaB7hb.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-iZAqpvhd.js → pieDiagram-CU6KROY3-DCgHNkyY.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-CtDijhnf.js → requirementDiagram-JXO7QTGE-D6vDU9M2.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-BdjvyCHM.js → sequenceDiagram-VS2MUI6T-CJrGCTXy.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-e5odN9fG.js → stateDiagram-7D4R322I-BvxQnQyL.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-vPsvjR2D.js → stateDiagram-v2-36443NZ5-D8ziO9W2.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-DPAksNQp.js → timeline-definition-O6YCAMPW-B45j2q3m.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-Dtlfdt7J.js → vennDiagram-MWXL3ELB-CRkZRDhi.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-B23uRMUC.js → wardleyDiagram-CUQ6CDDI-BekUytZJ.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-DxwHeksW.js → xychartDiagram-N2JHSOCM-BeMqwSgr.js} +1 -1
- package/web/index.html +1 -1
- package/web/assets/agent-D2kLt6Dl.js +0 -597
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
* Field Registry
|
|
3
3
|
*
|
|
4
4
|
* Owner-scoped field/property index extracted from SymbolTable.
|
|
5
|
-
* Stores Property
|
|
5
|
+
* Stores Property / Variable / Const / Static symbols keyed by
|
|
6
|
+
* `ownerNodeId\0fieldName` for O(1) lookup. Supports multiple defs
|
|
7
|
+
* under the same (owner, name) — e.g. legacy Property plus a
|
|
8
|
+
* scope-resolution Variable reconciliation entry.
|
|
6
9
|
*/
|
|
7
10
|
import type { SymbolDefinition } from '../../../_shared/index.js';
|
|
8
11
|
export interface FieldRegistry {
|
|
9
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* First field registered under `(ownerNodeId, fieldName)`, if any.
|
|
14
|
+
* Registration order is first-wins: when a Property and a Variable share
|
|
15
|
+
* an `(owner, simpleName)` key, the earlier `register(...)` call's def is
|
|
16
|
+
* returned. Prefer `lookupAllByOwner` when overloads or duplicate-kind
|
|
17
|
+
* entries under the same name must all be visible.
|
|
18
|
+
*/
|
|
10
19
|
lookupFieldByOwner(ownerNodeId: string, fieldName: string): SymbolDefinition | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Every field registered under `(ownerNodeId, fieldName)` in registration
|
|
22
|
+
* order. Returns `[]` on miss.
|
|
23
|
+
*/
|
|
24
|
+
lookupAllByOwner(ownerNodeId: string, fieldName: string): readonly SymbolDefinition[];
|
|
11
25
|
}
|
|
12
26
|
export interface MutableFieldRegistry extends FieldRegistry {
|
|
13
|
-
/** Register a field
|
|
27
|
+
/** Register a field under its owner. Appends when the key already exists. */
|
|
14
28
|
register(ownerNodeId: string, fieldName: string, def: SymbolDefinition): void;
|
|
15
29
|
/** Clear all entries. */
|
|
16
30
|
clear(): void;
|
|
@@ -2,21 +2,36 @@
|
|
|
2
2
|
* Field Registry
|
|
3
3
|
*
|
|
4
4
|
* Owner-scoped field/property index extracted from SymbolTable.
|
|
5
|
-
* Stores Property
|
|
5
|
+
* Stores Property / Variable / Const / Static symbols keyed by
|
|
6
|
+
* `ownerNodeId\0fieldName` for O(1) lookup. Supports multiple defs
|
|
7
|
+
* under the same (owner, name) — e.g. legacy Property plus a
|
|
8
|
+
* scope-resolution Variable reconciliation entry.
|
|
6
9
|
*/
|
|
10
|
+
const EMPTY = Object.freeze([]);
|
|
7
11
|
// ---------------------------------------------------------------------------
|
|
8
12
|
// Factory
|
|
9
13
|
// ---------------------------------------------------------------------------
|
|
10
14
|
export const createFieldRegistry = () => {
|
|
11
15
|
const fieldByOwner = new Map();
|
|
16
|
+
const lookupAllByOwner = (ownerNodeId, fieldName) => {
|
|
17
|
+
return fieldByOwner.get(`${ownerNodeId}\0${fieldName}`) ?? EMPTY;
|
|
18
|
+
};
|
|
12
19
|
const lookupFieldByOwner = (ownerNodeId, fieldName) => {
|
|
13
|
-
|
|
20
|
+
const pool = lookupAllByOwner(ownerNodeId, fieldName);
|
|
21
|
+
return pool.length === 0 ? undefined : pool[0];
|
|
14
22
|
};
|
|
15
23
|
const register = (ownerNodeId, fieldName, def) => {
|
|
16
|
-
|
|
24
|
+
const key = `${ownerNodeId}\0${fieldName}`;
|
|
25
|
+
const existing = fieldByOwner.get(key);
|
|
26
|
+
if (existing) {
|
|
27
|
+
existing.push(def);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
fieldByOwner.set(key, [def]);
|
|
31
|
+
}
|
|
17
32
|
};
|
|
18
33
|
const clear = () => {
|
|
19
34
|
fieldByOwner.clear();
|
|
20
35
|
};
|
|
21
|
-
return { lookupFieldByOwner, register, clear };
|
|
36
|
+
return { lookupFieldByOwner, lookupAllByOwner, register, clear };
|
|
22
37
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owner-keyed member lookup for Step 2 (RFC #909 / PR #1656).
|
|
3
|
+
*
|
|
4
|
+
* Merges MethodRegistry + FieldRegistry hits for `(ownerDefId, memberName)`
|
|
5
|
+
* in O(1) map time per registry — no `defs.byId` scan. Callers that omit
|
|
6
|
+
* this helper and leave `ownedMembersByOwner` unset fall back to an O(|defs|)
|
|
7
|
+
* compatibility scan inside `lookupCore.collectOwnedMembers`.
|
|
8
|
+
*/
|
|
9
|
+
import type { DefId, SymbolDefinition } from '../../../_shared/index.js';
|
|
10
|
+
import type { SemanticModel } from './semantic-model.js';
|
|
11
|
+
/**
|
|
12
|
+
* Production hook for `RegistryContext.ownedMembersByOwner`.
|
|
13
|
+
* Returns `[]` on miss (authoritative indexed empty) — never `undefined`.
|
|
14
|
+
*
|
|
15
|
+
* Merges hits from all three owner-keyed registries (methods, fields,
|
|
16
|
+
* nested types) under the same `(ownerDefId, memberName)` key. The
|
|
17
|
+
* caller's `acceptedKinds` filter in `lookupCore` picks the right subset.
|
|
18
|
+
*/
|
|
19
|
+
export declare function lookupOwnedMembersByOwner(model: Pick<SemanticModel, 'methods' | 'fields' | 'types'>, ownerDefId: DefId, memberName: string): readonly SymbolDefinition[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owner-keyed member lookup for Step 2 (RFC #909 / PR #1656).
|
|
3
|
+
*
|
|
4
|
+
* Merges MethodRegistry + FieldRegistry hits for `(ownerDefId, memberName)`
|
|
5
|
+
* in O(1) map time per registry — no `defs.byId` scan. Callers that omit
|
|
6
|
+
* this helper and leave `ownedMembersByOwner` unset fall back to an O(|defs|)
|
|
7
|
+
* compatibility scan inside `lookupCore.collectOwnedMembers`.
|
|
8
|
+
*/
|
|
9
|
+
const EMPTY = Object.freeze([]);
|
|
10
|
+
/**
|
|
11
|
+
* Production hook for `RegistryContext.ownedMembersByOwner`.
|
|
12
|
+
* Returns `[]` on miss (authoritative indexed empty) — never `undefined`.
|
|
13
|
+
*
|
|
14
|
+
* Merges hits from all three owner-keyed registries (methods, fields,
|
|
15
|
+
* nested types) under the same `(ownerDefId, memberName)` key. The
|
|
16
|
+
* caller's `acceptedKinds` filter in `lookupCore` picks the right subset.
|
|
17
|
+
*/
|
|
18
|
+
export function lookupOwnedMembersByOwner(model, ownerDefId, memberName) {
|
|
19
|
+
const methods = model.methods.lookupAllByOwner(ownerDefId, memberName);
|
|
20
|
+
const fields = model.fields.lookupAllByOwner(ownerDefId, memberName);
|
|
21
|
+
const nestedTypes = model.types.lookupAllByOwner(ownerDefId, memberName);
|
|
22
|
+
const methodCount = methods.length;
|
|
23
|
+
const fieldCount = fields.length;
|
|
24
|
+
const typeCount = nestedTypes.length;
|
|
25
|
+
const total = methodCount + fieldCount + typeCount;
|
|
26
|
+
if (total === 0)
|
|
27
|
+
return EMPTY;
|
|
28
|
+
if (methodCount === total)
|
|
29
|
+
return methods;
|
|
30
|
+
if (fieldCount === total)
|
|
31
|
+
return fields;
|
|
32
|
+
if (typeCount === total)
|
|
33
|
+
return nestedTypes;
|
|
34
|
+
const merged = new Array(total);
|
|
35
|
+
let i = 0;
|
|
36
|
+
for (let j = 0; j < methodCount; j++)
|
|
37
|
+
merged[i++] = methods[j];
|
|
38
|
+
for (let j = 0; j < fieldCount; j++)
|
|
39
|
+
merged[i++] = fields[j];
|
|
40
|
+
for (let j = 0; j < typeCount; j++)
|
|
41
|
+
merged[i++] = nestedTypes[j];
|
|
42
|
+
return merged;
|
|
43
|
+
}
|
|
@@ -27,12 +27,21 @@ export interface TypeRegistry {
|
|
|
27
27
|
* Returned array is a view into the live index — do not mutate.
|
|
28
28
|
*/
|
|
29
29
|
lookupImplByName(name: string): readonly SymbolDefinition[];
|
|
30
|
+
/**
|
|
31
|
+
* Look up nested-type defs registered under `(ownerNodeId, simpleName)`
|
|
32
|
+
* in registration order. Returns `[]` on miss. Used by Step 2 Receiver/MRO
|
|
33
|
+
* resolution when the receiver's owner declares nested classes/structs/
|
|
34
|
+
* enums/typedefs/etc. that the caller's `acceptedKinds` includes.
|
|
35
|
+
*/
|
|
36
|
+
lookupAllByOwner(ownerNodeId: string, simpleName: string): readonly SymbolDefinition[];
|
|
30
37
|
}
|
|
31
38
|
export interface MutableTypeRegistry extends TypeRegistry {
|
|
32
39
|
/** Register a class-like type by name and qualified name. */
|
|
33
40
|
registerClass(name: string, qualifiedName: string, def: SymbolDefinition): void;
|
|
34
41
|
/** Register a Rust Impl block by name. */
|
|
35
42
|
registerImpl(name: string, def: SymbolDefinition): void;
|
|
43
|
+
/** Register a nested type under its owner. Appends when the key already exists. */
|
|
44
|
+
registerByOwner(ownerNodeId: string, simpleName: string, def: SymbolDefinition): void;
|
|
36
45
|
/** Clear all entries. */
|
|
37
46
|
clear(): void;
|
|
38
47
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Eagerly-populated indexes keyed by symbol name and qualified name.
|
|
6
6
|
* Also includes a separate index for Rust Impl blocks.
|
|
7
7
|
*/
|
|
8
|
+
const EMPTY = Object.freeze([]);
|
|
8
9
|
// ---------------------------------------------------------------------------
|
|
9
10
|
// Factory
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
@@ -12,6 +13,7 @@ export const createTypeRegistry = () => {
|
|
|
12
13
|
const classByName = new Map();
|
|
13
14
|
const classByQualifiedName = new Map();
|
|
14
15
|
const implByName = new Map();
|
|
16
|
+
const nestedByOwner = new Map();
|
|
15
17
|
const lookupClassByName = (name) => {
|
|
16
18
|
return classByName.get(name) ?? [];
|
|
17
19
|
};
|
|
@@ -21,6 +23,9 @@ export const createTypeRegistry = () => {
|
|
|
21
23
|
const lookupImplByName = (name) => {
|
|
22
24
|
return implByName.get(name) ?? [];
|
|
23
25
|
};
|
|
26
|
+
const lookupAllByOwner = (ownerNodeId, simpleName) => {
|
|
27
|
+
return nestedByOwner.get(`${ownerNodeId}\0${simpleName}`) ?? EMPTY;
|
|
28
|
+
};
|
|
24
29
|
const registerClass = (name, qualifiedName, def) => {
|
|
25
30
|
const existing = classByName.get(name);
|
|
26
31
|
if (existing) {
|
|
@@ -46,17 +51,30 @@ export const createTypeRegistry = () => {
|
|
|
46
51
|
implByName.set(name, [def]);
|
|
47
52
|
}
|
|
48
53
|
};
|
|
54
|
+
const registerByOwner = (ownerNodeId, simpleName, def) => {
|
|
55
|
+
const key = `${ownerNodeId}\0${simpleName}`;
|
|
56
|
+
const existing = nestedByOwner.get(key);
|
|
57
|
+
if (existing) {
|
|
58
|
+
existing.push(def);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
nestedByOwner.set(key, [def]);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
49
64
|
const clear = () => {
|
|
50
65
|
classByName.clear();
|
|
51
66
|
classByQualifiedName.clear();
|
|
52
67
|
implByName.clear();
|
|
68
|
+
nestedByOwner.clear();
|
|
53
69
|
};
|
|
54
70
|
return {
|
|
55
71
|
lookupClassByName,
|
|
56
72
|
lookupClassByQualifiedName,
|
|
57
73
|
lookupImplByName,
|
|
74
|
+
lookupAllByOwner,
|
|
58
75
|
registerClass,
|
|
59
76
|
registerImpl,
|
|
77
|
+
registerByOwner,
|
|
60
78
|
clear,
|
|
61
79
|
};
|
|
62
80
|
};
|
|
@@ -37,12 +37,14 @@
|
|
|
37
37
|
* resolution but not emitted as multiple edges; callers that want
|
|
38
38
|
* branch-on-ambiguity behavior should consume the registries directly.
|
|
39
39
|
*/
|
|
40
|
-
import { CLASS_KINDS, FIELD_KINDS, METHOD_KINDS, type ReferenceIndex, type RegistryProviders } from '../../_shared/index.js';
|
|
40
|
+
import { CLASS_KINDS, FIELD_KINDS, METHOD_KINDS, type ReferenceIndex, type RegistryContext, type RegistryProviders } from '../../_shared/index.js';
|
|
41
41
|
import type { ScopeResolutionIndexes } from './model/scope-resolution-indexes.js';
|
|
42
42
|
export interface ResolveReferencesInput {
|
|
43
43
|
readonly scopes: ScopeResolutionIndexes;
|
|
44
44
|
/** Provider hooks consumed by the registries (e.g. `arityCompatibility`). */
|
|
45
45
|
readonly providers?: RegistryProviders;
|
|
46
|
+
/** Required owner-keyed member lookup used by Step 2 receiver/MRO walks. */
|
|
47
|
+
readonly ownedMembersByOwner: RegistryContext['ownedMembersByOwner'];
|
|
46
48
|
}
|
|
47
49
|
export interface ResolveStats {
|
|
48
50
|
readonly sitesProcessed: number;
|
|
@@ -51,6 +51,7 @@ export function resolveReferenceSites(input) {
|
|
|
51
51
|
defs: scopes.defs,
|
|
52
52
|
qualifiedNames: scopes.qualifiedNames,
|
|
53
53
|
moduleScopes: scopes.moduleScopes,
|
|
54
|
+
ownedMembersByOwner: input.ownedMembersByOwner,
|
|
54
55
|
methodDispatch: scopes.methodDispatch,
|
|
55
56
|
providers,
|
|
56
57
|
};
|
|
@@ -135,7 +136,10 @@ function lookupForSite(site, classRegistry, methodRegistry, fieldRegistry) {
|
|
|
135
136
|
case 'write': {
|
|
136
137
|
// Try field first; fall through to method then class so bare-name
|
|
137
138
|
// reads of a function (e.g. `cb = save`) still resolve.
|
|
138
|
-
const
|
|
139
|
+
const fieldOpts = {
|
|
140
|
+
...(site.explicitReceiver !== undefined ? { explicitReceiver: site.explicitReceiver } : {}),
|
|
141
|
+
};
|
|
142
|
+
const fieldHits = fieldRegistry.lookup(site.name, site.inScope, fieldOpts);
|
|
139
143
|
if (fieldHits.length > 0)
|
|
140
144
|
return fieldHits;
|
|
141
145
|
const methodHits = methodRegistry.lookup(site.name, site.inScope);
|
|
@@ -692,6 +692,7 @@ function pass5CollectReferences(matches, positionIndex, filePath, referenceSites
|
|
|
692
692
|
const explicitReceiver = extractExplicitReceiver(match);
|
|
693
693
|
const arity = extractArity(match);
|
|
694
694
|
const argumentTypes = extractArgumentTypes(match);
|
|
695
|
+
const argumentTypeClasses = parseJsonParameterTypeClassesCapture(match['@reference.parameter-type-classes']);
|
|
695
696
|
const site = {
|
|
696
697
|
name: nameCap.text,
|
|
697
698
|
atRange: anchor.range,
|
|
@@ -701,6 +702,7 @@ function pass5CollectReferences(matches, positionIndex, filePath, referenceSites
|
|
|
701
702
|
...(explicitReceiver !== undefined ? { explicitReceiver } : {}),
|
|
702
703
|
...(arity !== undefined ? { arity } : {}),
|
|
703
704
|
...(argumentTypes !== undefined ? { argumentTypes } : {}),
|
|
705
|
+
...(argumentTypeClasses !== undefined ? { argumentTypeClasses } : {}),
|
|
704
706
|
};
|
|
705
707
|
referenceSites.push(site);
|
|
706
708
|
}
|
|
@@ -806,9 +808,11 @@ const KNOWN_SUB_TAGS = new Set([
|
|
|
806
808
|
'@reference.receiver',
|
|
807
809
|
'@reference.arity',
|
|
808
810
|
'@reference.parameter-types',
|
|
811
|
+
'@reference.parameter-type-classes',
|
|
809
812
|
'@declaration.parameter-count',
|
|
810
813
|
'@declaration.required-parameter-count',
|
|
811
814
|
'@declaration.parameter-types',
|
|
815
|
+
'@declaration.parameter-type-classes',
|
|
812
816
|
'@declaration.template-constraints',
|
|
813
817
|
]);
|
|
814
818
|
/**
|
|
@@ -70,6 +70,7 @@ export declare function pickImplicitThisOverload(site: {
|
|
|
70
70
|
readonly name: string;
|
|
71
71
|
readonly arity?: number;
|
|
72
72
|
readonly argumentTypes?: readonly string[];
|
|
73
|
+
readonly argumentTypeClasses?: readonly import('../../../../_shared/index.js').ParameterTypeClass[];
|
|
73
74
|
}, scopes: ScopeResolutionIndexes, workspaceIndex: WorkspaceResolutionIndex, model: SemanticModel, hookCtx?: {
|
|
74
75
|
readonly conversionRankFn?: ConversionRankFn;
|
|
75
76
|
readonly constraintCompatibility?: ScopeResolver['constraintCompatibility'];
|
|
@@ -22,6 +22,11 @@ import { isOverloadAmbiguousAfterNormalization, narrowOverloadCandidates, } from
|
|
|
22
22
|
export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _referenceIndex, handledSites, model, workspaceIndex, options = {}) {
|
|
23
23
|
let emitted = 0;
|
|
24
24
|
const seen = new Set();
|
|
25
|
+
// Build an O(1) simple-name -> callable defs index over scopes.defs once
|
|
26
|
+
// per pass so pickUniqueGlobalCallable doesn't re-scan defs.byId.values()
|
|
27
|
+
// per call site. Same name + callable-kind filter that the previous scan
|
|
28
|
+
// applied (see pickUniqueGlobalCallable JSDoc). Cost: O(|defs|) once.
|
|
29
|
+
const globalCallablesBySimpleName = buildGlobalCallableIndex(scopes);
|
|
25
30
|
for (const parsed of parsedFiles) {
|
|
26
31
|
for (const site of parsed.referenceSites) {
|
|
27
32
|
if (site.kind !== 'call')
|
|
@@ -67,6 +72,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
67
72
|
const allCallables = findAllCallableBindingsInScope(site.inScope, site.name, scopes);
|
|
68
73
|
if (allCallables.length > 1) {
|
|
69
74
|
const narrowed = narrowOverloadCandidates(allCallables, site.arity, site.argumentTypes, {
|
|
75
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
70
76
|
conversionRankFn: options.conversionRankFn,
|
|
71
77
|
constraintCompatibility: options.constraintCompatibility,
|
|
72
78
|
});
|
|
@@ -121,6 +127,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
121
127
|
}
|
|
122
128
|
else {
|
|
123
129
|
const narrowed = narrowOverloadCandidates(ordinary, site.arity, site.argumentTypes, {
|
|
130
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
124
131
|
conversionRankFn: options.conversionRankFn,
|
|
125
132
|
constraintCompatibility: options.constraintCompatibility,
|
|
126
133
|
});
|
|
@@ -159,6 +166,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
159
166
|
push(ordinary);
|
|
160
167
|
push(adl);
|
|
161
168
|
const narrowed = narrowOverloadCandidates(merged, site.arity, site.argumentTypes, {
|
|
169
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
162
170
|
conversionRankFn: options.conversionRankFn,
|
|
163
171
|
constraintCompatibility: options.constraintCompatibility,
|
|
164
172
|
});
|
|
@@ -187,7 +195,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
187
195
|
// the caller does not import the target package. Same-package calls are
|
|
188
196
|
// usually caught by nearest-scope lookup before reaching here.
|
|
189
197
|
if (fnDef === undefined && options.allowGlobalFallback === true) {
|
|
190
|
-
fnDef = pickUniqueGlobalCallable(site.name, model,
|
|
198
|
+
fnDef = pickUniqueGlobalCallable(site.name, model, globalCallablesBySimpleName, parsed.filePath, options.isFileLocalDef, site.arity, options.isCallableVisibleFromCaller !== undefined
|
|
191
199
|
? (candidate) => options.isCallableVisibleFromCaller({
|
|
192
200
|
callerParsed: parsed,
|
|
193
201
|
candidate,
|
|
@@ -227,15 +235,36 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
227
235
|
}
|
|
228
236
|
return emitted;
|
|
229
237
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Build a `simpleName -> callable defs` index from `scopes.defs` once per
|
|
240
|
+
* pass. Mirrors the filter the old per-site scan applied: Function /
|
|
241
|
+
* Method / Constructor, keyed by the last `.`-segment of `qualifiedName`
|
|
242
|
+
* (falling back to the qualifiedName itself when undotted). Used by
|
|
243
|
+
* `pickUniqueGlobalCallable` so every free-call fallback site is O(1)
|
|
244
|
+
* instead of O(|defs|).
|
|
245
|
+
*/
|
|
246
|
+
function buildGlobalCallableIndex(scopes) {
|
|
247
|
+
const out = new Map();
|
|
233
248
|
for (const def of scopes.defs.byId.values()) {
|
|
234
|
-
const simple = def.qualifiedName?.split('.').pop() ?? def.qualifiedName;
|
|
235
|
-
if (simple !== name)
|
|
236
|
-
continue;
|
|
237
249
|
if (def.type !== 'Function' && def.type !== 'Method' && def.type !== 'Constructor')
|
|
238
250
|
continue;
|
|
251
|
+
const qualified = def.qualifiedName;
|
|
252
|
+
if (qualified === undefined || qualified.length === 0)
|
|
253
|
+
continue;
|
|
254
|
+
const dot = qualified.lastIndexOf('.');
|
|
255
|
+
const simple = dot === -1 ? qualified : qualified.slice(dot + 1);
|
|
256
|
+
const bucket = out.get(simple);
|
|
257
|
+
if (bucket)
|
|
258
|
+
bucket.push(def);
|
|
259
|
+
else
|
|
260
|
+
out.set(simple, [def]);
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
function pickUniqueGlobalCallable(name, model, globalCallablesBySimpleName, callerFilePath, isFileLocalDef, callArity, isCallerVisible, callArgTypes, conversionRankFn) {
|
|
265
|
+
const scopeDefs = [];
|
|
266
|
+
const scopeSeen = new Set();
|
|
267
|
+
for (const def of globalCallablesBySimpleName.get(name) ?? []) {
|
|
239
268
|
// Skip file-local defs (e.g. C `static` functions) that live in a
|
|
240
269
|
// different file from the caller — they are logically invisible.
|
|
241
270
|
if (isFileLocalDef !== undefined && def.filePath !== callerFilePath && isFileLocalDef(def)) {
|
|
@@ -401,6 +430,7 @@ export function pickImplicitThisOverload(site, scopes, workspaceIndex, model, ho
|
|
|
401
430
|
// disambiguating signal) leaves the call unresolved rather than
|
|
402
431
|
// routing to an arbitrary first overload by registration order.
|
|
403
432
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
433
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
404
434
|
conversionRankFn: hookCtx?.conversionRankFn,
|
|
405
435
|
constraintCompatibility: hookCtx?.constraintCompatibility,
|
|
406
436
|
});
|
|
@@ -59,6 +59,8 @@ export type ConversionRankFn = (argType: string, paramType: string) => number;
|
|
|
59
59
|
* undefined preserves the legacy arity + exact-type behavior.
|
|
60
60
|
*/
|
|
61
61
|
export interface OverloadNarrowingHookCtx {
|
|
62
|
+
/** Shape-preserving per-argument sidecar aligned with `argTypes`. */
|
|
63
|
+
readonly argumentTypeClasses?: ConstraintContext['argumentTypeClasses'];
|
|
62
64
|
/** Conversion-rank scoring fallback (step 4b). Engages when the
|
|
63
65
|
* exact-type filter rejects every candidate. */
|
|
64
66
|
readonly conversionRankFn?: ConversionRankFn;
|
|
@@ -118,7 +118,14 @@ export function narrowOverloadCandidates(overloads, argCount, argTypes, hookCtx)
|
|
|
118
118
|
// than emitting a wrong edge.
|
|
119
119
|
if (hookCtx?.constraintCompatibility !== undefined && argCount !== undefined) {
|
|
120
120
|
const callsite = { arity: argCount };
|
|
121
|
-
const ctx = argTypes !== undefined
|
|
121
|
+
const ctx = argTypes !== undefined
|
|
122
|
+
? {
|
|
123
|
+
argumentTypes: argTypes,
|
|
124
|
+
...(hookCtx.argumentTypeClasses !== undefined
|
|
125
|
+
? { argumentTypeClasses: hookCtx.argumentTypeClasses }
|
|
126
|
+
: {}),
|
|
127
|
+
}
|
|
128
|
+
: {};
|
|
122
129
|
result = result.filter((def) => {
|
|
123
130
|
if (def.templateConstraints === undefined)
|
|
124
131
|
return true;
|
|
@@ -250,6 +250,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
250
250
|
const methodOverloads = model.methods.lookupAllByOwner(ownerId, memberName);
|
|
251
251
|
if (methodOverloads.length > 0) {
|
|
252
252
|
const narrowed = narrowOverloadCandidates(methodOverloads, site.arity, site.argumentTypes, {
|
|
253
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
253
254
|
conversionRankFn: provider.conversionRankFn,
|
|
254
255
|
constraintCompatibility: provider.constraintCompatibility,
|
|
255
256
|
});
|
|
@@ -532,6 +533,7 @@ function pickOverload(ownerId, memberName, site, model, provider) {
|
|
|
532
533
|
if (overloads.length === 1)
|
|
533
534
|
return overloads[0];
|
|
534
535
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
536
|
+
argumentTypeClasses: site.argumentTypeClasses,
|
|
535
537
|
conversionRankFn: provider.conversionRankFn,
|
|
536
538
|
constraintCompatibility: provider.constraintCompatibility,
|
|
537
539
|
});
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* undefined `ownerId` is reachable via either:
|
|
19
19
|
* - `model.methods.lookupAllByOwner(ownerId, simpleName)` — if the
|
|
20
20
|
* def is a Method / Function / Constructor, OR
|
|
21
|
-
* - `model.fields.
|
|
22
|
-
* def is a Property / Variable.
|
|
21
|
+
* - `model.fields.lookupAllByOwner(ownerId, simpleName)` — if the
|
|
22
|
+
* def is a Property / Variable / Const / Static.
|
|
23
23
|
*
|
|
24
24
|
* This invariant is the foundation of Contract Invariant I9
|
|
25
25
|
* (`contract/scope-resolver.ts`): scope-resolution passes MUST read
|
|
@@ -47,6 +47,8 @@ export interface ReconcileStats {
|
|
|
47
47
|
readonly methodsRegistered: number;
|
|
48
48
|
/** Property/Variable defs registered into FieldRegistry. */
|
|
49
49
|
readonly fieldsRegistered: number;
|
|
50
|
+
/** Class-like nested type defs registered into TypeRegistry by owner. */
|
|
51
|
+
readonly nestedTypesRegistered: number;
|
|
50
52
|
/** Defs already present (idempotent skip). */
|
|
51
53
|
readonly skippedAlreadyPresent: number;
|
|
52
54
|
}
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* undefined `ownerId` is reachable via either:
|
|
19
19
|
* - `model.methods.lookupAllByOwner(ownerId, simpleName)` — if the
|
|
20
20
|
* def is a Method / Function / Constructor, OR
|
|
21
|
-
* - `model.fields.
|
|
22
|
-
* def is a Property / Variable.
|
|
21
|
+
* - `model.fields.lookupAllByOwner(ownerId, simpleName)` — if the
|
|
22
|
+
* def is a Property / Variable / Const / Static.
|
|
23
23
|
*
|
|
24
24
|
* This invariant is the foundation of Contract Invariant I9
|
|
25
25
|
* (`contract/scope-resolver.ts`): scope-resolution passes MUST read
|
|
@@ -41,9 +41,25 @@
|
|
|
41
41
|
* follow-up plan.
|
|
42
42
|
*/
|
|
43
43
|
import { simpleQualifiedName } from '../graph-bridge/ids.js';
|
|
44
|
+
const NESTED_TYPE_KINDS = new Set([
|
|
45
|
+
'Class',
|
|
46
|
+
'Interface',
|
|
47
|
+
'Enum',
|
|
48
|
+
'Struct',
|
|
49
|
+
'Union',
|
|
50
|
+
'Trait',
|
|
51
|
+
'TypeAlias',
|
|
52
|
+
'Typedef',
|
|
53
|
+
'Record',
|
|
54
|
+
'Delegate',
|
|
55
|
+
'Annotation',
|
|
56
|
+
'Template',
|
|
57
|
+
'Namespace',
|
|
58
|
+
]);
|
|
44
59
|
export function reconcileOwnership(parsedFiles, model) {
|
|
45
60
|
let methodsRegistered = 0;
|
|
46
61
|
let fieldsRegistered = 0;
|
|
62
|
+
let nestedTypesRegistered = 0;
|
|
47
63
|
let skippedAlreadyPresent = 0;
|
|
48
64
|
for (const parsed of parsedFiles) {
|
|
49
65
|
for (const def of parsed.localDefs) {
|
|
@@ -62,18 +78,30 @@ export function reconcileOwnership(parsedFiles, model) {
|
|
|
62
78
|
model.methods.register(ownerId, simple, def);
|
|
63
79
|
methodsRegistered++;
|
|
64
80
|
}
|
|
65
|
-
else if (def.type === 'Property' ||
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
else if (def.type === 'Property' ||
|
|
82
|
+
def.type === 'Variable' ||
|
|
83
|
+
def.type === 'Const' ||
|
|
84
|
+
def.type === 'Static') {
|
|
85
|
+
const existing = model.fields.lookupAllByOwner(ownerId, simple);
|
|
86
|
+
if (existing.some((e) => e.nodeId === def.nodeId)) {
|
|
68
87
|
skippedAlreadyPresent++;
|
|
69
88
|
continue;
|
|
70
89
|
}
|
|
71
90
|
model.fields.register(ownerId, simple, def);
|
|
72
91
|
fieldsRegistered++;
|
|
73
92
|
}
|
|
93
|
+
else if (NESTED_TYPE_KINDS.has(def.type)) {
|
|
94
|
+
const existing = model.types.lookupAllByOwner(ownerId, simple);
|
|
95
|
+
if (existing.some((e) => e.nodeId === def.nodeId)) {
|
|
96
|
+
skippedAlreadyPresent++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
model.types.registerByOwner(ownerId, simple, def);
|
|
100
|
+
nestedTypesRegistered++;
|
|
101
|
+
}
|
|
74
102
|
}
|
|
75
103
|
}
|
|
76
|
-
return { methodsRegistered, fieldsRegistered, skippedAlreadyPresent };
|
|
104
|
+
return { methodsRegistered, fieldsRegistered, nestedTypesRegistered, skippedAlreadyPresent };
|
|
77
105
|
}
|
|
78
106
|
/**
|
|
79
107
|
* Debug-mode parity validator. Runs only when
|
|
@@ -111,14 +139,25 @@ export function validateOwnershipParity(parsedFiles, model, onWarn) {
|
|
|
111
139
|
mismatches++;
|
|
112
140
|
}
|
|
113
141
|
}
|
|
114
|
-
else if (def.type === 'Property' ||
|
|
115
|
-
|
|
116
|
-
|
|
142
|
+
else if (def.type === 'Property' ||
|
|
143
|
+
def.type === 'Variable' ||
|
|
144
|
+
def.type === 'Const' ||
|
|
145
|
+
def.type === 'Static') {
|
|
146
|
+
const found = model.fields.lookupAllByOwner(ownerId, simple);
|
|
147
|
+
if (!found.some((d) => d.nodeId === def.nodeId)) {
|
|
117
148
|
onWarn(`semantic-model parity: ${def.type} ${def.nodeId} (${parsed.filePath}) ` +
|
|
118
149
|
`owned by ${ownerId} as "${simple}" not in FieldRegistry`);
|
|
119
150
|
mismatches++;
|
|
120
151
|
}
|
|
121
152
|
}
|
|
153
|
+
else if (NESTED_TYPE_KINDS.has(def.type)) {
|
|
154
|
+
const found = model.types.lookupAllByOwner(ownerId, simple);
|
|
155
|
+
if (!found.some((d) => d.nodeId === def.nodeId)) {
|
|
156
|
+
onWarn(`semantic-model parity: ${def.type} ${def.nodeId} (${parsed.filePath}) ` +
|
|
157
|
+
`owned by ${ownerId} as "${simple}" not in TypeRegistry owner index`);
|
|
158
|
+
mismatches++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
122
161
|
}
|
|
123
162
|
}
|
|
124
163
|
return mismatches;
|
|
@@ -17,6 +17,7 @@ import { javaScopeResolver } from '../../languages/java/scope-resolver.js';
|
|
|
17
17
|
import { cScopeResolver } from '../../languages/c/scope-resolver.js';
|
|
18
18
|
import { cppScopeResolver } from '../../languages/cpp/scope-resolver.js';
|
|
19
19
|
import { phpScopeResolver } from '../../languages/php/scope-resolver.js';
|
|
20
|
+
import { javascriptScopeResolver } from '../../languages/javascript/scope-resolver.js';
|
|
20
21
|
/** Map of `SupportedLanguages` → `ScopeResolver`. The phase iterates
|
|
21
22
|
* this map intersected with `MIGRATED_LANGUAGES` (the per-language
|
|
22
23
|
* flag set) so adding a resolver here without flipping the flag is
|
|
@@ -30,4 +31,5 @@ export const SCOPE_RESOLVERS = new Map([
|
|
|
30
31
|
[SupportedLanguages.C, cScopeResolver],
|
|
31
32
|
[SupportedLanguages.CPlusPlus, cppScopeResolver],
|
|
32
33
|
[SupportedLanguages.PHP, phpScopeResolver],
|
|
34
|
+
[SupportedLanguages.JavaScript, javascriptScopeResolver],
|
|
33
35
|
]);
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* Plan: `docs/plans/2026-04-20-001-refactor-emit-pipeline-generalization-plan.md`.
|
|
24
24
|
*/
|
|
25
|
+
import { lookupOwnedMembersByOwner } from '../../model/owned-members-lookup.js';
|
|
25
26
|
import { reconcileOwnership, validateOwnershipParity } from './reconcile-ownership.js';
|
|
26
27
|
import { validateBindingsImmutability } from './validate-bindings-immutability.js';
|
|
27
28
|
import { extractParsedFile } from '../../scope-extractor-bridge.js';
|
|
@@ -236,6 +237,7 @@ export function runScopeResolution(input, provider) {
|
|
|
236
237
|
const { referenceIndex, stats: resolveStats } = resolveReferenceSites({
|
|
237
238
|
scopes: indexes,
|
|
238
239
|
providers: registryProviders,
|
|
240
|
+
ownedMembersByOwner: (ownerDefId, memberName) => lookupOwnedMembersByOwner(readonlyModel, ownerDefId, memberName),
|
|
239
241
|
});
|
|
240
242
|
const tResolve = PROF ? process.hrtime.bigint() : 0n;
|
|
241
243
|
// ── Phase 4: emit graph edges (LOAD-BEARING ORDER — see I1) ────────────
|
|
@@ -66,7 +66,9 @@ export declare const initLbug: (dbPath: string) => Promise<{
|
|
|
66
66
|
* database is busy (e.g. `gitnexus analyze` holds the write lock).
|
|
67
67
|
* Each retry waits DB_LOCK_RETRY_DELAY_MS * attempt milliseconds.
|
|
68
68
|
*/
|
|
69
|
-
export declare const withLbugDb: <T>(dbPath: string, operation: () => Promise<T
|
|
69
|
+
export declare const withLbugDb: <T>(dbPath: string, operation: () => Promise<T>, options?: {
|
|
70
|
+
readOnly?: boolean;
|
|
71
|
+
}) => Promise<T>;
|
|
70
72
|
export type LbugProgressCallback = (message: string) => void;
|
|
71
73
|
export declare const loadGraphToLbug: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: LbugProgressCallback) => Promise<{
|
|
72
74
|
success: boolean;
|