sverklo 0.12.2 → 0.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 +15 -9
- package/dist/src/search/boost.d.ts +32 -0
- package/dist/src/search/boost.js +120 -0
- package/dist/src/search/boost.js.map +1 -0
- package/dist/src/search/hybrid-search.d.ts +7 -0
- package/dist/src/search/hybrid-search.js +7 -1
- package/dist/src/search/hybrid-search.js.map +1 -1
- package/dist/src/server/audit-html.js +12 -1
- package/dist/src/server/audit-html.js.map +1 -1
- package/dist/src/server/tools/search.d.ts +4 -0
- package/dist/src/server/tools/search.js +8 -0
- package/dist/src/server/tools/search.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/indexer/embedding-providers.test.d.ts +0 -1
- package/dist/src/indexer/embedding-providers.test.js +0 -83
- package/dist/src/indexer/embedding-providers.test.js.map +0 -1
- package/dist/src/indexer/indexer-freshness.test.d.ts +0 -1
- package/dist/src/indexer/indexer-freshness.test.js +0 -109
- package/dist/src/indexer/indexer-freshness.test.js.map +0 -1
- package/dist/src/indexer/indexer-provider-integration.test.d.ts +0 -1
- package/dist/src/indexer/indexer-provider-integration.test.js +0 -142
- package/dist/src/indexer/indexer-provider-integration.test.js.map +0 -1
- package/dist/src/indexer/migration.test.d.ts +0 -1
- package/dist/src/indexer/migration.test.js +0 -144
- package/dist/src/indexer/migration.test.js.map +0 -1
- package/dist/src/indexer/parser.test.d.ts +0 -1
- package/dist/src/indexer/parser.test.js +0 -128
- package/dist/src/indexer/parser.test.js.map +0 -1
- package/dist/src/indexer/symbol-extractor.test.d.ts +0 -1
- package/dist/src/indexer/symbol-extractor.test.js +0 -88
- package/dist/src/indexer/symbol-extractor.test.js.map +0 -1
- package/dist/src/memory/git-state.test.d.ts +0 -1
- package/dist/src/memory/git-state.test.js +0 -105
- package/dist/src/memory/git-state.test.js.map +0 -1
- package/dist/src/memory/journal.test.d.ts +0 -1
- package/dist/src/memory/journal.test.js +0 -98
- package/dist/src/memory/journal.test.js.map +0 -1
- package/dist/src/modes.test.d.ts +0 -1
- package/dist/src/modes.test.js +0 -48
- package/dist/src/modes.test.js.map +0 -1
- package/dist/src/registry/registry.test.d.ts +0 -1
- package/dist/src/registry/registry.test.js +0 -79
- package/dist/src/registry/registry.test.js.map +0 -1
- package/dist/src/search/cluster.test.d.ts +0 -1
- package/dist/src/search/cluster.test.js +0 -168
- package/dist/src/search/cluster.test.js.map +0 -1
- package/dist/src/search/hybrid-search.test.d.ts +0 -1
- package/dist/src/search/hybrid-search.test.js +0 -112
- package/dist/src/search/hybrid-search.test.js.map +0 -1
- package/dist/src/server/audit-html.test.d.ts +0 -1
- package/dist/src/server/audit-html.test.js +0 -80
- package/dist/src/server/audit-html.test.js.map +0 -1
- package/dist/src/server/tool-overrides.test.d.ts +0 -1
- package/dist/src/server/tool-overrides.test.js +0 -124
- package/dist/src/server/tool-overrides.test.js.map +0 -1
- package/dist/src/server/tools/context-budget.test.d.ts +0 -1
- package/dist/src/server/tools/context-budget.test.js +0 -150
- package/dist/src/server/tools/context-budget.test.js.map +0 -1
- package/dist/src/server/tools/diff-heuristics.test.d.ts +0 -1
- package/dist/src/server/tools/diff-heuristics.test.js +0 -151
- package/dist/src/server/tools/diff-heuristics.test.js.map +0 -1
- package/dist/src/server/tools/find-references.test.d.ts +0 -1
- package/dist/src/server/tools/find-references.test.js +0 -98
- package/dist/src/server/tools/find-references.test.js.map +0 -1
- package/dist/src/server/tools/index-status.test.d.ts +0 -1
- package/dist/src/server/tools/index-status.test.js +0 -111
- package/dist/src/server/tools/index-status.test.js.map +0 -1
- package/dist/src/server/tools/lookup.test.d.ts +0 -1
- package/dist/src/server/tools/lookup.test.js +0 -110
- package/dist/src/server/tools/lookup.test.js.map +0 -1
- package/dist/src/server/tools/recall.test.d.ts +0 -1
- package/dist/src/server/tools/recall.test.js +0 -116
- package/dist/src/server/tools/recall.test.js.map +0 -1
- package/dist/src/server/tools/search.test.d.ts +0 -1
- package/dist/src/server/tools/search.test.js +0 -118
- package/dist/src/server/tools/search.test.js.map +0 -1
- package/dist/src/storage/chunk-store.test.d.ts +0 -1
- package/dist/src/storage/chunk-store.test.js +0 -69
- package/dist/src/storage/chunk-store.test.js.map +0 -1
- package/dist/src/utils/budget.test.d.ts +0 -1
- package/dist/src/utils/budget.test.js +0 -75
- package/dist/src/utils/budget.test.js.map +0 -1
- package/dist/src/utils/config-file.test.d.ts +0 -1
- package/dist/src/utils/config-file.test.js +0 -130
- package/dist/src/utils/config-file.test.js.map +0 -1
- package/dist/src/utils/trace.test.d.ts +0 -1
- package/dist/src/utils/trace.test.js +0 -95
- package/dist/src/utils/trace.test.js.map +0 -1
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
-
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { Indexer } from "./indexer.js";
|
|
6
|
-
import { getProjectConfig } from "../utils/config.js";
|
|
7
|
-
// Tests for the freshness cache contract (issue #6). The cache exists
|
|
8
|
-
// to keep sverklo_status fast — the disk walk costs ~95ms on a small
|
|
9
|
-
// repo and agents can call status repeatedly in one session. The
|
|
10
|
-
// contract:
|
|
11
|
-
//
|
|
12
|
-
// 1. Result is cached for FRESHNESS_CACHE_MS (2s) after the first
|
|
13
|
-
// computation.
|
|
14
|
-
// 2. The cache is invalidated by explicit reindex / clearIndex.
|
|
15
|
-
// 3. The file watcher also invalidates on change events (tested via
|
|
16
|
-
// direct invalidateFreshnessCache() call since we don't want to
|
|
17
|
-
// stand up chokidar in a unit test).
|
|
18
|
-
describe("Indexer freshness cache", () => {
|
|
19
|
-
let tmpRoot;
|
|
20
|
-
let indexer;
|
|
21
|
-
beforeEach(async () => {
|
|
22
|
-
tmpRoot = mkdtempSync(join(tmpdir(), "sverklo-freshness-"));
|
|
23
|
-
// Minimal real repo: one TypeScript file. Indexing this should
|
|
24
|
-
// take well under a second.
|
|
25
|
-
mkdirSync(join(tmpRoot, "src"), { recursive: true });
|
|
26
|
-
writeFileSync(join(tmpRoot, "src", "foo.ts"), "export function foo() { return 42; }\n", "utf-8");
|
|
27
|
-
const cfg = getProjectConfig(tmpRoot);
|
|
28
|
-
indexer = new Indexer(cfg);
|
|
29
|
-
await indexer.index();
|
|
30
|
-
});
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
try {
|
|
33
|
-
indexer.close();
|
|
34
|
-
}
|
|
35
|
-
catch { }
|
|
36
|
-
try {
|
|
37
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
38
|
-
}
|
|
39
|
-
catch { }
|
|
40
|
-
});
|
|
41
|
-
it("returns a freshness result with ageSeconds and dirty/missing lists", () => {
|
|
42
|
-
const result = indexer.getFreshness();
|
|
43
|
-
expect(result).toBeDefined();
|
|
44
|
-
expect(Array.isArray(result.dirtyFiles)).toBe(true);
|
|
45
|
-
expect(Array.isArray(result.missingFiles)).toBe(true);
|
|
46
|
-
// Either a number or null — never undefined
|
|
47
|
-
expect(result.ageSeconds === null || typeof result.ageSeconds === "number").toBe(true);
|
|
48
|
-
});
|
|
49
|
-
it("serves from cache on rapid successive calls", () => {
|
|
50
|
-
// First call: compute. Second call within TTL: serve from cache.
|
|
51
|
-
// We can't directly observe "did it re-walk?" without instrumentation,
|
|
52
|
-
// but we can observe that the second call returns the *same*
|
|
53
|
-
// dirtyFiles array reference if we patch it — or more simply,
|
|
54
|
-
// measure that 100 calls in a row take negligible time (the cache
|
|
55
|
-
// hit path is O(1)). A perf threshold works as a regression guard.
|
|
56
|
-
const t0 = Date.now();
|
|
57
|
-
for (let i = 0; i < 100; i++) {
|
|
58
|
-
indexer.getFreshness();
|
|
59
|
-
}
|
|
60
|
-
const elapsed = Date.now() - t0;
|
|
61
|
-
// 100 cached reads should complete in <50ms on any machine that
|
|
62
|
-
// isn't actively on fire. Real disk walks would take 100× longer.
|
|
63
|
-
expect(elapsed).toBeLessThan(500);
|
|
64
|
-
});
|
|
65
|
-
it("reflects filesystem changes after invalidateFreshnessCache()", () => {
|
|
66
|
-
const first = indexer.getFreshness();
|
|
67
|
-
expect(first.dirtyFiles.length).toBe(0);
|
|
68
|
-
// Add a new file on disk (bypassing the watcher so we control timing)
|
|
69
|
-
writeFileSync(join(tmpRoot, "src", "bar.ts"), "export const bar = 1;\n", "utf-8");
|
|
70
|
-
// Without invalidation, the cached result persists for up to 2s.
|
|
71
|
-
// With invalidation, the next call sees the new file.
|
|
72
|
-
indexer.invalidateFreshnessCache();
|
|
73
|
-
const second = indexer.getFreshness();
|
|
74
|
-
expect(second.dirtyFiles.some((p) => p.includes("bar.ts"))).toBe(true);
|
|
75
|
-
});
|
|
76
|
-
it("clearIndex() invalidates the cache", () => {
|
|
77
|
-
// Establish a cached result first
|
|
78
|
-
const beforeClear = indexer.getFreshness();
|
|
79
|
-
expect(beforeClear).toBeDefined();
|
|
80
|
-
// clearIndex nukes the database and reinitializes. The cache must
|
|
81
|
-
// be cleared or sverklo_status would report stale dirty/missing
|
|
82
|
-
// lists against the (now empty) index.
|
|
83
|
-
indexer.clearIndex();
|
|
84
|
-
// After clear, the indexed file count is 0 — so the freshness
|
|
85
|
-
// result should show all on-disk files as dirty (new to the index).
|
|
86
|
-
const afterClear = indexer.getFreshness();
|
|
87
|
-
expect(afterClear.dirtyFiles.length).toBeGreaterThan(0);
|
|
88
|
-
expect(afterClear.missingFiles.length).toBe(0);
|
|
89
|
-
});
|
|
90
|
-
it("updates ageSeconds even when serving from cache", () => {
|
|
91
|
-
// The cache stores the expensive disk-walk result but still
|
|
92
|
-
// recomputes ageSeconds on every call (wall clock moves on).
|
|
93
|
-
const first = indexer.getFreshness();
|
|
94
|
-
const firstAge = first.ageSeconds;
|
|
95
|
-
expect(typeof firstAge).toBe("number");
|
|
96
|
-
// Wait a moment and call again. Age should advance even though
|
|
97
|
-
// the dirty/missing lists are cached.
|
|
98
|
-
vi.useFakeTimers();
|
|
99
|
-
vi.advanceTimersByTime(1500);
|
|
100
|
-
const second = indexer.getFreshness();
|
|
101
|
-
vi.useRealTimers();
|
|
102
|
-
// Age on the second call should be higher than the first (by ~1s).
|
|
103
|
-
// Allow some slack for the test harness timing.
|
|
104
|
-
if (typeof firstAge === "number" && typeof second.ageSeconds === "number") {
|
|
105
|
-
expect(second.ageSeconds).toBeGreaterThanOrEqual(firstAge);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
//# sourceMappingURL=indexer-freshness.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"indexer-freshness.test.js","sourceRoot":"","sources":["../../../src/indexer/indexer-freshness.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,sEAAsE;AACtE,qEAAqE;AACrE,iEAAiE;AACjE,YAAY;AACZ,EAAE;AACF,oEAAoE;AACpE,oBAAoB;AACpB,kEAAkE;AAClE,sEAAsE;AACtE,qEAAqE;AACrE,0CAA0C;AAE1C,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAI,OAAe,CAAC;IACpB,IAAI,OAAgB,CAAC;IAErB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAE5D,+DAA+D;QAC/D,4BAA4B;QAC5B,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,EAC9B,wCAAwC,EACxC,OAAO,CACR,CAAC;QAEF,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC;YACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,4CAA4C;QAC5C,MAAM,CAAC,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,iEAAiE;QACjE,uEAAuE;QACvE,6DAA6D;QAC7D,8DAA8D;QAC9D,kEAAkE;QAClE,mEAAmE;QACnE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7B,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAChC,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAExC,sEAAsE;QACtE,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,yBAAyB,EAAE,OAAO,CAAC,CAAC;QAElF,iEAAiE;QACjE,sDAAsD;QACtD,OAAO,CAAC,wBAAwB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,kCAAkC;QAClC,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAElC,kEAAkE;QAClE,gEAAgE;QAChE,uCAAuC;QACvC,OAAO,CAAC,UAAU,EAAE,CAAC;QAErB,8DAA8D;QAC9D,oEAAoE;QACpE,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,4DAA4D;QAC5D,6DAA6D;QAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC;QAClC,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,+DAA+D;QAC/D,sCAAsC;QACtC,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACtC,EAAE,CAAC,aAAa,EAAE,CAAC;QAEnB,mEAAmE;QACnE,gDAAgD;QAChD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC1E,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
-
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { Indexer } from "./indexer.js";
|
|
6
|
-
import { getProjectConfig } from "../utils/config.js";
|
|
7
|
-
// Integration test that would have caught the issue #9 wiring gap:
|
|
8
|
-
// the provider factory existed and its unit tests passed, but the
|
|
9
|
-
// Indexer never actually called the factory — it imported legacyEmbed
|
|
10
|
-
// directly from ./embedder.js and used it everywhere. Users setting
|
|
11
|
-
// SVERKLO_EMBEDDING_PROVIDER=openai silently got the bundled ONNX
|
|
12
|
-
// model and no visible error.
|
|
13
|
-
//
|
|
14
|
-
// The fix was to lazily initialize the provider on the first index()
|
|
15
|
-
// call and expose it via `indexer.embed()` / `indexer.embeddingProviderName`.
|
|
16
|
-
// These tests lock that wiring in so a refactor can't silently break
|
|
17
|
-
// it again.
|
|
18
|
-
//
|
|
19
|
-
// We don't hit real OpenAI / Ollama endpoints here. The point isn't
|
|
20
|
-
// to prove the providers work (their own unit tests do that). The
|
|
21
|
-
// point is to prove the indexer *uses* whichever provider the env
|
|
22
|
-
// vars selected, instead of always defaulting.
|
|
23
|
-
describe("Indexer + embedding provider integration", () => {
|
|
24
|
-
let tmpRoot;
|
|
25
|
-
const originalEnv = { ...process.env };
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
tmpRoot = mkdtempSync(join(tmpdir(), "sverklo-provider-int-"));
|
|
28
|
-
mkdirSync(join(tmpRoot, "src"), { recursive: true });
|
|
29
|
-
writeFileSync(join(tmpRoot, "src", "a.ts"), "export function hello() { return 'world'; }\n", "utf-8");
|
|
30
|
-
});
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
try {
|
|
33
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
34
|
-
}
|
|
35
|
-
catch { }
|
|
36
|
-
// Restore env so tests don't leak into each other.
|
|
37
|
-
for (const key of Object.keys(process.env)) {
|
|
38
|
-
if (key.startsWith("SVERKLO_") && !(key in originalEnv)) {
|
|
39
|
-
delete process.env[key];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
for (const [k, v] of Object.entries(originalEnv)) {
|
|
43
|
-
if (k.startsWith("SVERKLO_"))
|
|
44
|
-
process.env[k] = v;
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
it("defaults to the bundled provider when no env var is set", async () => {
|
|
48
|
-
delete process.env.SVERKLO_EMBEDDING_PROVIDER;
|
|
49
|
-
const indexer = new Indexer(getProjectConfig(tmpRoot));
|
|
50
|
-
try {
|
|
51
|
-
await indexer.index();
|
|
52
|
-
expect(indexer.embeddingProviderName).toBe("default");
|
|
53
|
-
expect(indexer.embeddingDimensions).toBe(384);
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
indexer.close();
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
it("selects the OpenAI provider when SVERKLO_EMBEDDING_PROVIDER=openai and key is set", async () => {
|
|
60
|
-
// We can't actually call OpenAI in a test — patch fetch to a
|
|
61
|
-
// deterministic stub so the provider init succeeds. The indexer
|
|
62
|
-
// then commits to the openai provider for the rest of its life.
|
|
63
|
-
process.env.SVERKLO_EMBEDDING_PROVIDER = "openai";
|
|
64
|
-
process.env.SVERKLO_OPENAI_API_KEY = "sk-test";
|
|
65
|
-
// Mock fetch so the embedder calls look successful and return
|
|
66
|
-
// the right number of dimensions per request.
|
|
67
|
-
const originalFetch = global.fetch;
|
|
68
|
-
global.fetch = vi.fn(async (_url, init) => {
|
|
69
|
-
const body = JSON.parse(init.body);
|
|
70
|
-
const input = Array.isArray(body.input) ? body.input : [body.input];
|
|
71
|
-
return new Response(JSON.stringify({
|
|
72
|
-
data: input.map((_, i) => ({
|
|
73
|
-
index: i,
|
|
74
|
-
embedding: new Array(1536).fill(0),
|
|
75
|
-
})),
|
|
76
|
-
}), { status: 200 });
|
|
77
|
-
});
|
|
78
|
-
try {
|
|
79
|
-
const indexer = new Indexer(getProjectConfig(tmpRoot));
|
|
80
|
-
try {
|
|
81
|
-
await indexer.index();
|
|
82
|
-
expect(indexer.embeddingProviderName).toContain("openai");
|
|
83
|
-
expect(indexer.embeddingDimensions).toBe(1536);
|
|
84
|
-
}
|
|
85
|
-
finally {
|
|
86
|
-
indexer.close();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
finally {
|
|
90
|
-
global.fetch = originalFetch;
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
it("falls back to default when OpenAI is requested but the API key is missing", async () => {
|
|
94
|
-
process.env.SVERKLO_EMBEDDING_PROVIDER = "openai";
|
|
95
|
-
delete process.env.SVERKLO_OPENAI_API_KEY;
|
|
96
|
-
const indexer = new Indexer(getProjectConfig(tmpRoot));
|
|
97
|
-
try {
|
|
98
|
-
await indexer.index();
|
|
99
|
-
// Factory init() throws on missing key → factory falls back to
|
|
100
|
-
// default. The whole point of the wiring is that this fallback
|
|
101
|
-
// is visible, not silent.
|
|
102
|
-
expect(indexer.embeddingProviderName).toBe("default");
|
|
103
|
-
}
|
|
104
|
-
finally {
|
|
105
|
-
indexer.close();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
it("initializes the provider lazily on first embed() if index() hasn't run yet", async () => {
|
|
109
|
-
delete process.env.SVERKLO_EMBEDDING_PROVIDER;
|
|
110
|
-
const indexer = new Indexer(getProjectConfig(tmpRoot));
|
|
111
|
-
try {
|
|
112
|
-
// Call embed() without first calling index(). The embed method
|
|
113
|
-
// should fall back to the legacy path and still return vectors
|
|
114
|
-
// — this covers agents that hit search/recall before the first
|
|
115
|
-
// index cycle completes.
|
|
116
|
-
const vecs = await indexer.embed(["hello world"]);
|
|
117
|
-
expect(Array.isArray(vecs)).toBe(true);
|
|
118
|
-
expect(vecs.length).toBe(1);
|
|
119
|
-
expect(vecs[0]).toBeInstanceOf(Float32Array);
|
|
120
|
-
}
|
|
121
|
-
finally {
|
|
122
|
-
indexer.close();
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
it("reuses the same provider across multiple index() calls", async () => {
|
|
126
|
-
delete process.env.SVERKLO_EMBEDDING_PROVIDER;
|
|
127
|
-
const indexer = new Indexer(getProjectConfig(tmpRoot));
|
|
128
|
-
try {
|
|
129
|
-
await indexer.index();
|
|
130
|
-
const firstName = indexer.embeddingProviderName;
|
|
131
|
-
// Write a new file and reindex
|
|
132
|
-
writeFileSync(join(tmpRoot, "src", "b.ts"), "export function goodbye() { return 'world'; }\n", "utf-8");
|
|
133
|
-
await indexer.index();
|
|
134
|
-
// Provider identity stays stable — reindex should not reselect.
|
|
135
|
-
expect(indexer.embeddingProviderName).toBe(firstName);
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
indexer.close();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
//# sourceMappingURL=indexer-provider-integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"indexer-provider-integration.test.js","sourceRoot":"","sources":["../../../src/indexer/indexer-provider-integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { Indexer } from "./indexer.js";
|
|
6
|
-
import { getProjectConfig } from "../utils/config.js";
|
|
7
|
-
import { createDatabase, getDataVersion, setDataVersion, CURRENT_DATA_VERSION, } from "../storage/database.js";
|
|
8
|
-
// Tests for the data-version migration runner (issue #13 rollout).
|
|
9
|
-
//
|
|
10
|
-
// Scenario: a user upgrades from v0.2.13 (where symbol_refs rows
|
|
11
|
-
// were lossy due to chunk-wide dedupe) to v0.2.14 (where the bug
|
|
12
|
-
// is fixed). Their existing index is still lossy until we re-extract
|
|
13
|
-
// references from the chunks we already have.
|
|
14
|
-
//
|
|
15
|
-
// The migration:
|
|
16
|
-
// 1. runs on Indexer construction if stored data_version < 2
|
|
17
|
-
// 2. drops all symbol_refs rows
|
|
18
|
-
// 3. re-runs extractReferences over every chunk.content already in the db
|
|
19
|
-
// 4. stamps data_version = 2 so subsequent constructions are a no-op
|
|
20
|
-
describe("data-version migration", () => {
|
|
21
|
-
let tmpRoot;
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
tmpRoot = mkdtempSync(join(tmpdir(), "sverklo-migration-"));
|
|
24
|
-
mkdirSync(join(tmpRoot, "src"), { recursive: true });
|
|
25
|
-
// A file with a symbol called twice in the same function.
|
|
26
|
-
// Under v0.2.13, extractReferences would produce ONE symbol_ref
|
|
27
|
-
// row for 'helper' from this function, not two.
|
|
28
|
-
//
|
|
29
|
-
// Note: we use `declare function` for helper rather than a real
|
|
30
|
-
// definition because the current chunker only chunks the first
|
|
31
|
-
// top-level function when a file has multiple — that's a
|
|
32
|
-
// separate bug worth filing, but not blocking the migration
|
|
33
|
-
// tests here.
|
|
34
|
-
writeFileSync(join(tmpRoot, "src", "a.ts"), [
|
|
35
|
-
"declare function helper(): number;",
|
|
36
|
-
"export function run() {",
|
|
37
|
-
" const a = helper();",
|
|
38
|
-
" const b = helper();",
|
|
39
|
-
" return a + b;",
|
|
40
|
-
"}",
|
|
41
|
-
].join("\n"), "utf-8");
|
|
42
|
-
});
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
try {
|
|
45
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
46
|
-
}
|
|
47
|
-
catch { }
|
|
48
|
-
});
|
|
49
|
-
it("fresh database stamps data_version = CURRENT_DATA_VERSION on first index", async () => {
|
|
50
|
-
const cfg = getProjectConfig(tmpRoot);
|
|
51
|
-
const indexer = new Indexer(cfg);
|
|
52
|
-
try {
|
|
53
|
-
await indexer.index();
|
|
54
|
-
const v = getDataVersion(indexer.db);
|
|
55
|
-
expect(v).toBe(CURRENT_DATA_VERSION);
|
|
56
|
-
}
|
|
57
|
-
finally {
|
|
58
|
-
indexer.close();
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
it("upgrading from v1 re-extracts symbol refs", async () => {
|
|
62
|
-
// Step 1: build an index the "old" way. We create a database,
|
|
63
|
-
// set data_version = 1, and insert a single lossy symbol_ref
|
|
64
|
-
// row for 'helper' on the first call site only. This simulates
|
|
65
|
-
// what v0.2.13 would have produced.
|
|
66
|
-
const cfg = getProjectConfig(tmpRoot);
|
|
67
|
-
{
|
|
68
|
-
const indexer = new Indexer(cfg);
|
|
69
|
-
await indexer.index();
|
|
70
|
-
indexer.close();
|
|
71
|
-
}
|
|
72
|
-
// Simulate an old (v0.2.13) index by:
|
|
73
|
-
// - manually deleting all symbol_refs
|
|
74
|
-
// - inserting ONE lossy row for helper at the first call site
|
|
75
|
-
// - setting data_version = 1
|
|
76
|
-
{
|
|
77
|
-
const db = createDatabase(cfg.dbPath);
|
|
78
|
-
db.exec("DELETE FROM symbol_refs");
|
|
79
|
-
// Find the chunk id of the `run` function
|
|
80
|
-
const runChunk = db
|
|
81
|
-
.prepare("SELECT id FROM chunks WHERE name = 'run'")
|
|
82
|
-
.get();
|
|
83
|
-
if (runChunk) {
|
|
84
|
-
db.prepare("INSERT INTO symbol_refs (source_chunk_id, target_name, line) VALUES (?, ?, ?)").run(runChunk.id, "helper", 2);
|
|
85
|
-
}
|
|
86
|
-
setDataVersion(db, 1);
|
|
87
|
-
db.close();
|
|
88
|
-
}
|
|
89
|
-
// Step 2: open the index with a new Indexer. The migration
|
|
90
|
-
// should run and re-extract all references.
|
|
91
|
-
const indexer2 = new Indexer(cfg);
|
|
92
|
-
try {
|
|
93
|
-
const db = indexer2.db;
|
|
94
|
-
// data_version should now be CURRENT
|
|
95
|
-
expect(getDataVersion(db)).toBe(CURRENT_DATA_VERSION);
|
|
96
|
-
// symbol_refs should now include BOTH helper calls, not just one
|
|
97
|
-
const helperRefs = db
|
|
98
|
-
.prepare("SELECT COUNT(*) as c FROM symbol_refs WHERE target_name = 'helper'")
|
|
99
|
-
.get();
|
|
100
|
-
expect(helperRefs.c).toBeGreaterThanOrEqual(2);
|
|
101
|
-
}
|
|
102
|
-
finally {
|
|
103
|
-
indexer2.close();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
it("a second Indexer construction on a current database is a no-op", async () => {
|
|
107
|
-
const cfg = getProjectConfig(tmpRoot);
|
|
108
|
-
{
|
|
109
|
-
const indexer = new Indexer(cfg);
|
|
110
|
-
await indexer.index();
|
|
111
|
-
indexer.close();
|
|
112
|
-
}
|
|
113
|
-
// Capture the symbol_refs count after the initial index
|
|
114
|
-
const db = createDatabase(cfg.dbPath);
|
|
115
|
-
const initial = db.prepare("SELECT COUNT(*) as c FROM symbol_refs").get().c;
|
|
116
|
-
db.close();
|
|
117
|
-
// Construct again — migration should skip
|
|
118
|
-
const indexer2 = new Indexer(cfg);
|
|
119
|
-
try {
|
|
120
|
-
const db2 = indexer2.db;
|
|
121
|
-
const after = db2.prepare("SELECT COUNT(*) as c FROM symbol_refs").get().c;
|
|
122
|
-
// Same count — no rebuild happened
|
|
123
|
-
expect(after).toBe(initial);
|
|
124
|
-
}
|
|
125
|
-
finally {
|
|
126
|
-
indexer2.close();
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
it("migration handles an empty database (no chunks) without erroring", () => {
|
|
130
|
-
// Case: someone installs sverklo, opens a project, but no files
|
|
131
|
-
// have been indexed yet. Database is empty. Migration should
|
|
132
|
-
// still stamp the version and return cleanly.
|
|
133
|
-
const cfg = getProjectConfig(tmpRoot);
|
|
134
|
-
const emptyIndexer = new Indexer(cfg);
|
|
135
|
-
try {
|
|
136
|
-
const db = emptyIndexer.db;
|
|
137
|
-
expect(getDataVersion(db)).toBe(CURRENT_DATA_VERSION);
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
emptyIndexer.close();
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
//# sourceMappingURL=migration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration.test.js","sourceRoot":"","sources":["../../../src/indexer/migration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { parseFile } from "./parser.js";
|
|
3
|
-
// Regression tests for github.com/sverklo/sverklo/issues/16.
|
|
4
|
-
//
|
|
5
|
-
// The TSJS parser used to assign `i = chunk.endLine` after pushing a
|
|
6
|
-
// chunk, but chunk.endLine is 1-indexed (set by extractChunk) while
|
|
7
|
-
// the loop's `i` is 0-indexed. After the `for (i++)`, the loop
|
|
8
|
-
// skipped one line past the chunk — which was the declaration of
|
|
9
|
-
// the NEXT top-level function in real files. So any file with two
|
|
10
|
-
// adjacent functions only ever got the first one indexed.
|
|
11
|
-
//
|
|
12
|
-
// The fix is `i = chunk.endLine - 1`. These tests cover the shape
|
|
13
|
-
// of codebases where the bug would bite: multiple adjacent top-level
|
|
14
|
-
// symbols, mixed types, and edge cases around blank lines and
|
|
15
|
-
// single-line functions.
|
|
16
|
-
describe("parseFile — TSJS multi-top-level regression (issue #16)", () => {
|
|
17
|
-
it("indexes two adjacent single-line functions", () => {
|
|
18
|
-
const content = [
|
|
19
|
-
"function helper() { return 1; }",
|
|
20
|
-
"export function run() { return helper(); }",
|
|
21
|
-
].join("\n");
|
|
22
|
-
const result = parseFile(content, "typescript");
|
|
23
|
-
const names = result.chunks.map((c) => c.name);
|
|
24
|
-
expect(names).toContain("helper");
|
|
25
|
-
expect(names).toContain("run");
|
|
26
|
-
});
|
|
27
|
-
it("indexes a function followed by a class", () => {
|
|
28
|
-
const content = [
|
|
29
|
-
"function helper() { return 1; }",
|
|
30
|
-
"export class Service {",
|
|
31
|
-
" handle() { return 42; }",
|
|
32
|
-
"}",
|
|
33
|
-
].join("\n");
|
|
34
|
-
const result = parseFile(content, "typescript");
|
|
35
|
-
const names = result.chunks.map((c) => c.name);
|
|
36
|
-
expect(names).toContain("helper");
|
|
37
|
-
expect(names).toContain("Service");
|
|
38
|
-
});
|
|
39
|
-
it("indexes a class followed by an interface", () => {
|
|
40
|
-
const content = [
|
|
41
|
-
"class A { run() {} }",
|
|
42
|
-
"export interface B {",
|
|
43
|
-
" name: string;",
|
|
44
|
-
"}",
|
|
45
|
-
].join("\n");
|
|
46
|
-
const result = parseFile(content, "typescript");
|
|
47
|
-
const names = result.chunks.map((c) => c.name);
|
|
48
|
-
expect(names).toContain("A");
|
|
49
|
-
expect(names).toContain("B");
|
|
50
|
-
});
|
|
51
|
-
it("indexes three sequential functions (helper, mid, end)", () => {
|
|
52
|
-
// The original failure case is pairs. This catches any regression
|
|
53
|
-
// where the fix accidentally only advances correctly once.
|
|
54
|
-
const content = [
|
|
55
|
-
"function helper() { return 1; }",
|
|
56
|
-
"function mid() { return 2; }",
|
|
57
|
-
"export function end() { return 3; }",
|
|
58
|
-
].join("\n");
|
|
59
|
-
const result = parseFile(content, "typescript");
|
|
60
|
-
const names = result.chunks.map((c) => c.name);
|
|
61
|
-
expect(names).toEqual(expect.arrayContaining(["helper", "mid", "end"]));
|
|
62
|
-
expect(result.chunks.length).toBeGreaterThanOrEqual(3);
|
|
63
|
-
});
|
|
64
|
-
it("handles blank lines between top-level declarations", () => {
|
|
65
|
-
const content = [
|
|
66
|
-
"function one() { return 1; }",
|
|
67
|
-
"",
|
|
68
|
-
"",
|
|
69
|
-
"function two() { return 2; }",
|
|
70
|
-
"",
|
|
71
|
-
"function three() { return 3; }",
|
|
72
|
-
].join("\n");
|
|
73
|
-
const result = parseFile(content, "typescript");
|
|
74
|
-
const names = result.chunks.map((c) => c.name);
|
|
75
|
-
expect(names).toEqual(expect.arrayContaining(["one", "two", "three"]));
|
|
76
|
-
});
|
|
77
|
-
it("preserves each chunk's own content without leaking neighbors", () => {
|
|
78
|
-
const content = [
|
|
79
|
-
"function alpha() { return 'a'; }",
|
|
80
|
-
"function beta() { return 'b'; }",
|
|
81
|
-
].join("\n");
|
|
82
|
-
const result = parseFile(content, "typescript");
|
|
83
|
-
const alpha = result.chunks.find((c) => c.name === "alpha");
|
|
84
|
-
const beta = result.chunks.find((c) => c.name === "beta");
|
|
85
|
-
expect(alpha?.content).toContain("'a'");
|
|
86
|
-
expect(alpha?.content).not.toContain("'b'");
|
|
87
|
-
expect(beta?.content).toContain("'b'");
|
|
88
|
-
expect(beta?.content).not.toContain("'a'");
|
|
89
|
-
});
|
|
90
|
-
it("handles multi-line functions correctly without skipping the next one", () => {
|
|
91
|
-
const content = [
|
|
92
|
-
"function first() {",
|
|
93
|
-
" const x = 1;",
|
|
94
|
-
" const y = 2;",
|
|
95
|
-
" return x + y;",
|
|
96
|
-
"}",
|
|
97
|
-
"function second() {",
|
|
98
|
-
" return 'hello';",
|
|
99
|
-
"}",
|
|
100
|
-
].join("\n");
|
|
101
|
-
const result = parseFile(content, "typescript");
|
|
102
|
-
const names = result.chunks.map((c) => c.name);
|
|
103
|
-
expect(names).toContain("first");
|
|
104
|
-
expect(names).toContain("second");
|
|
105
|
-
});
|
|
106
|
-
it("handles arrow functions followed by function declarations", () => {
|
|
107
|
-
const content = [
|
|
108
|
-
"export const fetch = async () => { return null; };",
|
|
109
|
-
"export function process() { return 42; }",
|
|
110
|
-
].join("\n");
|
|
111
|
-
const result = parseFile(content, "typescript");
|
|
112
|
-
const names = result.chunks.map((c) => c.name);
|
|
113
|
-
expect(names).toContain("fetch");
|
|
114
|
-
expect(names).toContain("process");
|
|
115
|
-
});
|
|
116
|
-
it("javascript (not just typescript) gets the fix", () => {
|
|
117
|
-
// Same regex pipeline, same bug in v0.2.13 and earlier. Cover both.
|
|
118
|
-
const content = [
|
|
119
|
-
"function alpha() { return 1; }",
|
|
120
|
-
"function beta() { return 2; }",
|
|
121
|
-
].join("\n");
|
|
122
|
-
const result = parseFile(content, "javascript");
|
|
123
|
-
const names = result.chunks.map((c) => c.name);
|
|
124
|
-
expect(names).toContain("alpha");
|
|
125
|
-
expect(names).toContain("beta");
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
//# sourceMappingURL=parser.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../../../src/indexer/parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,6DAA6D;AAC7D,EAAE;AACF,qEAAqE;AACrE,oEAAoE;AACpE,+DAA+D;AAC/D,iEAAiE;AACjE,kEAAkE;AAClE,0DAA0D;AAC1D,EAAE;AACF,kEAAkE;AAClE,qEAAqE;AACrE,8DAA8D;AAC9D,yBAAyB;AAEzB,QAAQ,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACvE,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,OAAO,GAAG;YACd,iCAAiC;YACjC,4CAA4C;SAC7C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,OAAO,GAAG;YACd,iCAAiC;YACjC,wBAAwB;YACxB,2BAA2B;YAC3B,GAAG;SACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,OAAO,GAAG;YACd,sBAAsB;YACtB,sBAAsB;YACtB,iBAAiB;YACjB,GAAG;SACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,kEAAkE;QAClE,2DAA2D;QAC3D,MAAM,OAAO,GAAG;YACd,iCAAiC;YACjC,8BAA8B;YAC9B,qCAAqC;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,OAAO,GAAG;YACd,8BAA8B;YAC9B,EAAE;YACF,EAAE;YACF,8BAA8B;YAC9B,EAAE;YACF,gCAAgC;SACjC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,OAAO,GAAG;YACd,kCAAkC;YAClC,iCAAiC;SAClC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAE1D,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,OAAO,GAAG;YACd,oBAAoB;YACpB,gBAAgB;YAChB,gBAAgB;YAChB,iBAAiB;YACjB,GAAG;YACH,qBAAqB;YACrB,mBAAmB;YACnB,GAAG;SACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,OAAO,GAAG;YACd,oDAAoD;YACpD,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,oEAAoE;QACpE,MAAM,OAAO,GAAG;YACd,gCAAgC;YAChC,+BAA+B;SAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|