seer-mcp 0.1.0
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/.vscode/settings.json +3 -0
- package/LICENSE +176 -0
- package/README.md +272 -0
- package/README_dev.md +199 -0
- package/dist/bundle/ci.d.ts +47 -0
- package/dist/bundle/ci.d.ts.map +1 -0
- package/dist/bundle/ci.js +113 -0
- package/dist/bundle/ci.js.map +1 -0
- package/dist/bundle/contract.d.ts +111 -0
- package/dist/bundle/contract.d.ts.map +1 -0
- package/dist/bundle/contract.js +352 -0
- package/dist/bundle/contract.js.map +1 -0
- package/dist/bundle/export.d.ts +36 -0
- package/dist/bundle/export.d.ts.map +1 -0
- package/dist/bundle/export.js +152 -0
- package/dist/bundle/export.js.map +1 -0
- package/dist/bundle/external.d.ts +66 -0
- package/dist/bundle/external.d.ts.map +1 -0
- package/dist/bundle/external.js +238 -0
- package/dist/bundle/external.js.map +1 -0
- package/dist/bundle/format.d.ts +94 -0
- package/dist/bundle/format.d.ts.map +1 -0
- package/dist/bundle/format.js +42 -0
- package/dist/bundle/format.js.map +1 -0
- package/dist/bundle/import.d.ts +49 -0
- package/dist/bundle/import.d.ts.map +1 -0
- package/dist/bundle/import.js +116 -0
- package/dist/bundle/import.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1402 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +48 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +284 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +616 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/store.d.ts +1011 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +3888 -0
- package/dist/db/store.js.map +1 -0
- package/dist/graph/pagerank.d.ts +9 -0
- package/dist/graph/pagerank.d.ts.map +1 -0
- package/dist/graph/pagerank.js +47 -0
- package/dist/graph/pagerank.js.map +1 -0
- package/dist/indexer/architecture.d.ts +72 -0
- package/dist/indexer/architecture.d.ts.map +1 -0
- package/dist/indexer/architecture.js +112 -0
- package/dist/indexer/architecture.js.map +1 -0
- package/dist/indexer/behavior.d.ts +75 -0
- package/dist/indexer/behavior.d.ts.map +1 -0
- package/dist/indexer/behavior.js +395 -0
- package/dist/indexer/behavior.js.map +1 -0
- package/dist/indexer/boundaries.d.ts +60 -0
- package/dist/indexer/boundaries.d.ts.map +1 -0
- package/dist/indexer/boundaries.js +366 -0
- package/dist/indexer/boundaries.js.map +1 -0
- package/dist/indexer/churn.d.ts +15 -0
- package/dist/indexer/churn.d.ts.map +1 -0
- package/dist/indexer/churn.js +49 -0
- package/dist/indexer/churn.js.map +1 -0
- package/dist/indexer/classify.d.ts +9 -0
- package/dist/indexer/classify.d.ts.map +1 -0
- package/dist/indexer/classify.js +90 -0
- package/dist/indexer/classify.js.map +1 -0
- package/dist/indexer/context.d.ts +176 -0
- package/dist/indexer/context.d.ts.map +1 -0
- package/dist/indexer/context.js +193 -0
- package/dist/indexer/context.js.map +1 -0
- package/dist/indexer/continuity.d.ts +67 -0
- package/dist/indexer/continuity.d.ts.map +1 -0
- package/dist/indexer/continuity.js +288 -0
- package/dist/indexer/continuity.js.map +1 -0
- package/dist/indexer/detectchanges.d.ts +32 -0
- package/dist/indexer/detectchanges.d.ts.map +1 -0
- package/dist/indexer/detectchanges.js +74 -0
- package/dist/indexer/detectchanges.js.map +1 -0
- package/dist/indexer/discovery.d.ts +37 -0
- package/dist/indexer/discovery.d.ts.map +1 -0
- package/dist/indexer/discovery.js +136 -0
- package/dist/indexer/discovery.js.map +1 -0
- package/dist/indexer/externaldeps.d.ts +18 -0
- package/dist/indexer/externaldeps.d.ts.map +1 -0
- package/dist/indexer/externaldeps.js +288 -0
- package/dist/indexer/externaldeps.js.map +1 -0
- package/dist/indexer/freshness.d.ts +48 -0
- package/dist/indexer/freshness.d.ts.map +1 -0
- package/dist/indexer/freshness.js +128 -0
- package/dist/indexer/freshness.js.map +1 -0
- package/dist/indexer/git.d.ts +144 -0
- package/dist/indexer/git.d.ts.map +1 -0
- package/dist/indexer/git.js +444 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/index.d.ts +145 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +930 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/modules.d.ts +62 -0
- package/dist/indexer/modules.d.ts.map +1 -0
- package/dist/indexer/modules.js +293 -0
- package/dist/indexer/modules.js.map +1 -0
- package/dist/indexer/preflight.d.ts +154 -0
- package/dist/indexer/preflight.d.ts.map +1 -0
- package/dist/indexer/preflight.js +399 -0
- package/dist/indexer/preflight.js.map +1 -0
- package/dist/indexer/protoScanner.d.ts +34 -0
- package/dist/indexer/protoScanner.d.ts.map +1 -0
- package/dist/indexer/protoScanner.js +133 -0
- package/dist/indexer/protoScanner.js.map +1 -0
- package/dist/indexer/risk.d.ts +115 -0
- package/dist/indexer/risk.d.ts.map +1 -0
- package/dist/indexer/risk.js +194 -0
- package/dist/indexer/risk.js.map +1 -0
- package/dist/indexer/serviceHostScanner.d.ts +25 -0
- package/dist/indexer/serviceHostScanner.d.ts.map +1 -0
- package/dist/indexer/serviceHostScanner.js +95 -0
- package/dist/indexer/serviceHostScanner.js.map +1 -0
- package/dist/indexer/serviceLinks.d.ts +105 -0
- package/dist/indexer/serviceLinks.d.ts.map +1 -0
- package/dist/indexer/serviceLinks.js +509 -0
- package/dist/indexer/serviceLinks.js.map +1 -0
- package/dist/indexer/shapehash.d.ts +98 -0
- package/dist/indexer/shapehash.d.ts.map +1 -0
- package/dist/indexer/shapehash.js +354 -0
- package/dist/indexer/shapehash.js.map +1 -0
- package/dist/indexer/skeleton.d.ts +15 -0
- package/dist/indexer/skeleton.d.ts.map +1 -0
- package/dist/indexer/skeleton.js +136 -0
- package/dist/indexer/skeleton.js.map +1 -0
- package/dist/indexer/symbolhistory.d.ts +41 -0
- package/dist/indexer/symbolhistory.d.ts.map +1 -0
- package/dist/indexer/symbolhistory.js +124 -0
- package/dist/indexer/symbolhistory.js.map +1 -0
- package/dist/indexer/watcher.d.ts +68 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +179 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/server.d.ts +80 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +1610 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parser/index.d.ts +8 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +33 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/languages/cpp.d.ts +3 -0
- package/dist/parser/languages/cpp.d.ts.map +1 -0
- package/dist/parser/languages/cpp.js +350 -0
- package/dist/parser/languages/cpp.js.map +1 -0
- package/dist/parser/languages/csharp.d.ts +3 -0
- package/dist/parser/languages/csharp.d.ts.map +1 -0
- package/dist/parser/languages/csharp.js +239 -0
- package/dist/parser/languages/csharp.js.map +1 -0
- package/dist/parser/languages/go.d.ts +3 -0
- package/dist/parser/languages/go.d.ts.map +1 -0
- package/dist/parser/languages/go.js +259 -0
- package/dist/parser/languages/go.js.map +1 -0
- package/dist/parser/languages/java.d.ts +3 -0
- package/dist/parser/languages/java.d.ts.map +1 -0
- package/dist/parser/languages/java.js +391 -0
- package/dist/parser/languages/java.js.map +1 -0
- package/dist/parser/languages/python.d.ts +3 -0
- package/dist/parser/languages/python.d.ts.map +1 -0
- package/dist/parser/languages/python.js +396 -0
- package/dist/parser/languages/python.js.map +1 -0
- package/dist/parser/languages/rust.d.ts +3 -0
- package/dist/parser/languages/rust.d.ts.map +1 -0
- package/dist/parser/languages/rust.js +159 -0
- package/dist/parser/languages/rust.js.map +1 -0
- package/dist/parser/languages/typescript.d.ts +3 -0
- package/dist/parser/languages/typescript.d.ts.map +1 -0
- package/dist/parser/languages/typescript.js +1442 -0
- package/dist/parser/languages/typescript.js.map +1 -0
- package/dist/parser/parserContext.d.ts +77 -0
- package/dist/parser/parserContext.d.ts.map +1 -0
- package/dist/parser/parserContext.js +354 -0
- package/dist/parser/parserContext.js.map +1 -0
- package/dist/parser/walker.d.ts +81 -0
- package/dist/parser/walker.d.ts.map +1 -0
- package/dist/parser/walker.js +217 -0
- package/dist/parser/walker.js.map +1 -0
- package/dist/parser/worker.d.ts +66 -0
- package/dist/parser/worker.d.ts.map +1 -0
- package/dist/parser/worker.js +129 -0
- package/dist/parser/worker.js.map +1 -0
- package/dist/parser/workerpool.d.ts +107 -0
- package/dist/parser/workerpool.d.ts.map +1 -0
- package/dist/parser/workerpool.js +383 -0
- package/dist/parser/workerpool.js.map +1 -0
- package/dist/scip/format.d.ts +87 -0
- package/dist/scip/format.d.ts.map +1 -0
- package/dist/scip/format.js +31 -0
- package/dist/scip/format.js.map +1 -0
- package/dist/scip/import.d.ts +37 -0
- package/dist/scip/import.d.ts.map +1 -0
- package/dist/scip/import.js +180 -0
- package/dist/scip/import.js.map +1 -0
- package/dist/types.d.ts +392 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/docs/architecture.md +105 -0
- package/docs/benchmarks/methodology.md +134 -0
- package/docs/benchmarks/raw-results.md +71 -0
- package/docs/benchmarks.md +74 -0
- package/docs/cli.md +148 -0
- package/docs/examples/behavior-tests.md +70 -0
- package/docs/examples/change-history.md +85 -0
- package/docs/examples/pre-edit-context.md +81 -0
- package/docs/examples/service-links.md +88 -0
- package/docs/examples.md +80 -0
- package/docs/faq.md +70 -0
- package/docs/internals.md +104 -0
- package/docs/languages.md +70 -0
- package/docs/limits.md +52 -0
- package/docs/mcp.md +199 -0
- package/docs/quickstart.md +119 -0
- package/docs/testing.md +123 -0
- package/docs/tools.md +115 -0
- package/package.json +52 -0
- package/research-codebase.md +578 -0
- package/seer-cli-docs.md +326 -0
- package/seer-master-guide.md +246 -0
- package/src/bundle/ci.ts +141 -0
- package/src/bundle/contract.ts +387 -0
- package/src/bundle/export.ts +175 -0
- package/src/bundle/external.ts +285 -0
- package/src/bundle/format.ts +92 -0
- package/src/bundle/import.ts +157 -0
- package/src/cli/index.ts +1249 -0
- package/src/cli/init.ts +389 -0
- package/src/db/schema.ts +614 -0
- package/src/db/store.ts +4306 -0
- package/src/graph/pagerank.ts +53 -0
- package/src/indexer/architecture.ts +148 -0
- package/src/indexer/behavior.ts +466 -0
- package/src/indexer/boundaries.ts +374 -0
- package/src/indexer/churn.ts +58 -0
- package/src/indexer/classify.ts +96 -0
- package/src/indexer/context.ts +340 -0
- package/src/indexer/continuity.ts +322 -0
- package/src/indexer/detectchanges.ts +94 -0
- package/src/indexer/discovery.ts +176 -0
- package/src/indexer/externaldeps.ts +243 -0
- package/src/indexer/freshness.ts +166 -0
- package/src/indexer/git.ts +453 -0
- package/src/indexer/index.ts +1092 -0
- package/src/indexer/modules.ts +358 -0
- package/src/indexer/preflight.ts +548 -0
- package/src/indexer/protoScanner.ts +147 -0
- package/src/indexer/risk.ts +304 -0
- package/src/indexer/serviceHostScanner.ts +92 -0
- package/src/indexer/serviceLinks.ts +543 -0
- package/src/indexer/shapehash.ts +370 -0
- package/src/indexer/skeleton.ts +169 -0
- package/src/indexer/symbolhistory.ts +172 -0
- package/src/indexer/watcher.ts +206 -0
- package/src/mcp/server.ts +1659 -0
- package/src/parser/index.ts +37 -0
- package/src/parser/languages/cpp.ts +361 -0
- package/src/parser/languages/csharp.ts +235 -0
- package/src/parser/languages/go.ts +259 -0
- package/src/parser/languages/java.ts +382 -0
- package/src/parser/languages/python.ts +370 -0
- package/src/parser/languages/rust.ts +164 -0
- package/src/parser/languages/typescript.ts +1435 -0
- package/src/parser/parserContext.ts +392 -0
- package/src/parser/walker.ts +306 -0
- package/src/parser/worker.ts +181 -0
- package/src/parser/workerpool.ts +448 -0
- package/src/scip/format.ts +83 -0
- package/src/scip/import.ts +216 -0
- package/src/types.ts +457 -0
- package/tests/benchmark-service-links.ts +244 -0
- package/tests/bug-regressions.ts +626 -0
- package/tests/filters.ts +264 -0
- package/tests/fixtures/Counter.tsx +38 -0
- package/tests/fixtures/caller.ts +7 -0
- package/tests/fixtures/collisions.ts +23 -0
- package/tests/fixtures/local_helper.ts +5 -0
- package/tests/fixtures/overloads.java +17 -0
- package/tests/fixtures/remote_helper.ts +4 -0
- package/tests/fixtures/sample.c +15 -0
- package/tests/fixtures/sample.cpp +47 -0
- package/tests/fixtures/sample.cs +62 -0
- package/tests/fixtures/sample.go +68 -0
- package/tests/fixtures/sample.h +30 -0
- package/tests/fixtures/sample.java +85 -0
- package/tests/fixtures/sample.py +46 -0
- package/tests/fixtures/sample.rs +78 -0
- package/tests/fixtures/sample.ts +76 -0
- package/tests/fixtures-service/HttpClients.cs +30 -0
- package/tests/fixtures-service/HttpClients.java +24 -0
- package/tests/fixtures-service/billing.ts +15 -0
- package/tests/fixtures-service/docker-compose.yml +15 -0
- package/tests/fixtures-service/gateway.ts +10 -0
- package/tests/fixtures-service/get_user.ts +11 -0
- package/tests/fixtures-service/graphql_client.ts +63 -0
- package/tests/fixtures-service/graphql_server.ts +30 -0
- package/tests/fixtures-service/grpc_client.go +30 -0
- package/tests/fixtures-service/http_clients.go +23 -0
- package/tests/fixtures-service/http_clients.py +38 -0
- package/tests/fixtures-service/http_clients.ts +49 -0
- package/tests/fixtures-service/k8s/payment-service.yaml +22 -0
- package/tests/fixtures-service/k8s_calls.ts +20 -0
- package/tests/fixtures-service/messaging.ts +87 -0
- package/tests/fixtures-service/trpc_client.ts +39 -0
- package/tests/fixtures-service/trpc_server.ts +39 -0
- package/tests/fixtures-service/user_service.proto +33 -0
- package/tests/fixtures-trackcd/Cargo.toml +11 -0
- package/tests/fixtures-trackcd/SpringController.java +36 -0
- package/tests/fixtures-trackcd/auth_service.ts +19 -0
- package/tests/fixtures-trackcd/complex_module.py +50 -0
- package/tests/fixtures-trackcd/express_app.js +30 -0
- package/tests/fixtures-trackcd/fastapi_app.py +49 -0
- package/tests/fixtures-trackcd/fastify_object_routes.js +32 -0
- package/tests/fixtures-trackcd/go.mod +8 -0
- package/tests/fixtures-trackcd/package.json +15 -0
- package/tests/fixtures-trackcd/requirements.txt +4 -0
- package/tests/fixtures-trackcd/tests/auth_service.test.ts +13 -0
- package/tests/fixtures-tracke/auth/AuthService.ts +23 -0
- package/tests/fixtures-tracke/auth/crypto.ts +7 -0
- package/tests/fixtures-tracke/billing/Billing.ts +20 -0
- package/tests/fixtures-tracke/billing/Invoice.ts +10 -0
- package/tests/fixtures-tracke/billing/server.ts +17 -0
- package/tests/fixtures-tracke/package.json +7 -0
- package/tests/fixtures-tracke/tests/auth.test.ts +23 -0
- package/tests/fixtures-tracke/tests/billing.test.ts +14 -0
- package/tests/fixtures-trackf/package.json +5 -0
- package/tests/fixtures-trackf/src/auth.ts +26 -0
- package/tests/fixtures-trackf/src/handlers.ts +35 -0
- package/tests/fixtures-tracki/billing/routes.ts +12 -0
- package/tests/fixtures-tracki/gateway/client.ts +13 -0
- package/tests/git-features.ts +267 -0
- package/tests/init.ts +141 -0
- package/tests/mcp-jit.ts +130 -0
- package/tests/mcp-smoke.ts +191 -0
- package/tests/mcp-trackcd.ts +169 -0
- package/tests/mcp-tracke.ts +229 -0
- package/tests/mcp-trackf.ts +330 -0
- package/tests/mcp-trackg.ts +219 -0
- package/tests/mcp-tracki.ts +174 -0
- package/tests/mcp-watcher.ts +126 -0
- package/tests/optspec.ts +194 -0
- package/tests/parallel-index.ts +333 -0
- package/tests/parallel-read.ts +125 -0
- package/tests/parallel-recovery.ts +241 -0
- package/tests/perf-callers.ts +145 -0
- package/tests/query-parity.ts +184 -0
- package/tests/query-perf.ts +55 -0
- package/tests/scale-parallel-parity.ts +225 -0
- package/tests/scale-test.ts +523 -0
- package/tests/smoke.ts +396 -0
- package/tests/trackcd.ts +325 -0
- package/tests/tracke-collisions.ts +255 -0
- package/tests/tracke.ts +314 -0
- package/tests/trackf-bugs.ts +406 -0
- package/tests/trackf.ts +390 -0
- package/tests/trackg.ts +1372 -0
- package/tests/tracki-boundaries.ts +202 -0
- package/tests/tracki-continuity.ts +253 -0
- package/tests/tracki-contract-diff.ts +249 -0
- package/tests/tracki-external-bundles.ts +341 -0
- package/tests/tracki-preflight.ts +251 -0
- package/tests/verify-roles.ts +51 -0
- package/tests/worker-parity.ts +286 -0
- package/tests/worker-pool.ts +262 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkerPool parity test (Step 3 of parallel parsing).
|
|
3
|
+
*
|
|
4
|
+
* Verifies that the pool produces results byte-identical to in-process
|
|
5
|
+
* `parseFile()` for every fixture, that the consumer callback is invoked in
|
|
6
|
+
* input order regardless of worker scheduling, that bounded out-of-order
|
|
7
|
+
* buffering works under load, and that shutdown is clean.
|
|
8
|
+
*
|
|
9
|
+
* Crash recovery is exercised lightly here (mismatched expectedHash, missing
|
|
10
|
+
* paths) — the heavier stress and worker-death tests live in Step 5
|
|
11
|
+
* (`tests/parallel-recovery.ts`).
|
|
12
|
+
*
|
|
13
|
+
* Run with: npm run test:worker-pool
|
|
14
|
+
*/
|
|
15
|
+
import fs from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import os from 'os';
|
|
18
|
+
import crypto from 'crypto';
|
|
19
|
+
import { parseFile, detectLanguage } from '../src/parser/index';
|
|
20
|
+
import type { Language } from '../src/types';
|
|
21
|
+
import { WorkerPool, defaultWorkerPath, WorkItem, PoolResult } from '../src/parser/workerpool';
|
|
22
|
+
|
|
23
|
+
const FIXTURES_DIR = path.join(__dirname, 'fixtures');
|
|
24
|
+
const FIXTURES_TRACKCD = path.join(__dirname, 'fixtures-trackcd');
|
|
25
|
+
|
|
26
|
+
let passed = 0;
|
|
27
|
+
let failed = 0;
|
|
28
|
+
|
|
29
|
+
function assert(condition: boolean, message: string): void {
|
|
30
|
+
if (condition) {
|
|
31
|
+
console.log(` ✓ ${message}`);
|
|
32
|
+
passed++;
|
|
33
|
+
} else {
|
|
34
|
+
console.error(` ✗ ${message}`);
|
|
35
|
+
failed++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function sha256Short(content: string): string {
|
|
40
|
+
return crypto.createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 16);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function listFiles(dir: string): string[] {
|
|
44
|
+
const out: string[] = [];
|
|
45
|
+
if (!fs.existsSync(dir)) return out;
|
|
46
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
47
|
+
const p = path.join(dir, entry.name);
|
|
48
|
+
if (entry.isDirectory()) out.push(...listFiles(p));
|
|
49
|
+
else out.push(p);
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function canon(obj: unknown): string {
|
|
55
|
+
return JSON.stringify(obj, (_k, v) => {
|
|
56
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
57
|
+
const sorted: Record<string, unknown> = {};
|
|
58
|
+
for (const k of Object.keys(v as Record<string, unknown>).sort()) {
|
|
59
|
+
sorted[k] = (v as Record<string, unknown>)[k];
|
|
60
|
+
}
|
|
61
|
+
return sorted;
|
|
62
|
+
}
|
|
63
|
+
return v;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── Run ──────────────────────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
async function run(): Promise<void> {
|
|
70
|
+
console.log('\nWorker Pool Parity Test (Step 3)');
|
|
71
|
+
console.log('==================================\n');
|
|
72
|
+
|
|
73
|
+
if (!fs.existsSync(defaultWorkerPath())) {
|
|
74
|
+
console.error(` ✗ ${defaultWorkerPath()} not found — run \`npm run build\` first.`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Build the canonical reference set: serial parseFile for every fixture.
|
|
79
|
+
console.log('Building serial reference set...');
|
|
80
|
+
const allFiles = [...listFiles(FIXTURES_DIR), ...listFiles(FIXTURES_TRACKCD)];
|
|
81
|
+
const items: WorkItem[] = [];
|
|
82
|
+
const referenceCanon: Array<string | null> = [];
|
|
83
|
+
for (const abs of allFiles) {
|
|
84
|
+
const lang = detectLanguage(abs);
|
|
85
|
+
if (!lang) continue;
|
|
86
|
+
const content = fs.readFileSync(abs, 'utf8');
|
|
87
|
+
const ref = await parseFile(content, abs, lang);
|
|
88
|
+
items.push({ abs, lang: lang as Language, expectedHash: null, maxFileBytes: 0 });
|
|
89
|
+
referenceCanon.push(ref ? canon(ref) : null);
|
|
90
|
+
}
|
|
91
|
+
console.log(` ${items.length} fixtures in reference set\n`);
|
|
92
|
+
|
|
93
|
+
// ── 1. Pool dispatch matches serial reference (in-order callback) ─────────
|
|
94
|
+
for (const jobs of [1, 2, 4, 8]) {
|
|
95
|
+
console.log(`── Pool with jobs=${jobs} — per-fixture parity ──`);
|
|
96
|
+
const pool = new WorkerPool({ jobs });
|
|
97
|
+
await pool.ready();
|
|
98
|
+
assert(pool.jobs === jobs, `pool spawned ${jobs} worker(s)`);
|
|
99
|
+
|
|
100
|
+
let inOrder = true;
|
|
101
|
+
let lastSeq = -1;
|
|
102
|
+
const got: PoolResult[] = new Array(items.length);
|
|
103
|
+
await pool.dispatch(items, (seq, result) => {
|
|
104
|
+
if (seq !== lastSeq + 1) inOrder = false;
|
|
105
|
+
lastSeq = seq;
|
|
106
|
+
got[seq] = result;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
assert(inOrder, `callback invoked strictly in input order (jobs=${jobs})`);
|
|
110
|
+
assert(lastSeq === items.length - 1, `every item delivered exactly once (jobs=${jobs})`);
|
|
111
|
+
|
|
112
|
+
let parityHits = 0;
|
|
113
|
+
let parityMisses = 0;
|
|
114
|
+
for (let i = 0; i < items.length; i++) {
|
|
115
|
+
const r = got[i];
|
|
116
|
+
const ref = referenceCanon[i];
|
|
117
|
+
if (r.kind === 'parsed' && ref !== null && canon(r.extraction) === ref) parityHits++;
|
|
118
|
+
else {
|
|
119
|
+
parityMisses++;
|
|
120
|
+
console.error(` miss seq=${i} file=${path.relative(__dirname, items[i].abs)} kind=${r.kind}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
assert(parityMisses === 0, `all ${items.length} fixtures byte-equal to serial (jobs=${jobs})`);
|
|
124
|
+
|
|
125
|
+
await pool.shutdown();
|
|
126
|
+
console.log('');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── 2. Empty dispatch is a no-op (no workers spawned, returns immediately) ─
|
|
130
|
+
console.log('── Empty dispatch ──');
|
|
131
|
+
{
|
|
132
|
+
const pool = new WorkerPool({ jobs: 4 });
|
|
133
|
+
let invoked = 0;
|
|
134
|
+
await pool.dispatch([], () => { invoked++; });
|
|
135
|
+
assert(invoked === 0, 'empty dispatch invokes callback zero times');
|
|
136
|
+
await pool.shutdown();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── 3. Bounded out-of-order buffer holds under load (maxLag tiny) ─────────
|
|
140
|
+
console.log('\n── Bounded out-of-order buffer (maxLag=3, 200 jobs) ──');
|
|
141
|
+
{
|
|
142
|
+
const pool = new WorkerPool({ jobs: 4, maxLag: 3 });
|
|
143
|
+
await pool.ready();
|
|
144
|
+
// Repeat one cheap fixture many times so we get genuine concurrency.
|
|
145
|
+
const tsFixture = path.join(FIXTURES_DIR, 'sample.ts');
|
|
146
|
+
const refContent = fs.readFileSync(tsFixture, 'utf8');
|
|
147
|
+
const ref = await parseFile(refContent, tsFixture, 'typescript');
|
|
148
|
+
const refStr = canon(ref);
|
|
149
|
+
const N = 200;
|
|
150
|
+
const items: WorkItem[] = [];
|
|
151
|
+
for (let i = 0; i < N; i++) {
|
|
152
|
+
items.push({ abs: tsFixture, lang: 'typescript', expectedHash: null, maxFileBytes: 0 });
|
|
153
|
+
}
|
|
154
|
+
let inOrder = true;
|
|
155
|
+
let lastSeq = -1;
|
|
156
|
+
let allMatched = true;
|
|
157
|
+
await pool.dispatch(items, (seq, result) => {
|
|
158
|
+
if (seq !== lastSeq + 1) inOrder = false;
|
|
159
|
+
lastSeq = seq;
|
|
160
|
+
if (result.kind !== 'parsed' || canon(result.extraction) !== refStr) allMatched = false;
|
|
161
|
+
});
|
|
162
|
+
assert(inOrder, '200-job dispatch stays in-order under maxLag=3');
|
|
163
|
+
assert(allMatched, 'every result still byte-equal under bounded backpressure');
|
|
164
|
+
await pool.shutdown();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ── 4. Cached / too-large / io-error route through correctly ──────────────
|
|
168
|
+
console.log('\n── Mixed result kinds route through pool callback ──');
|
|
169
|
+
{
|
|
170
|
+
const pool = new WorkerPool({ jobs: 2 });
|
|
171
|
+
await pool.ready();
|
|
172
|
+
const tsFixture = path.join(FIXTURES_DIR, 'sample.ts');
|
|
173
|
+
const knownHash = sha256Short(fs.readFileSync(tsFixture, 'utf8'));
|
|
174
|
+
const ghost = path.join(os.tmpdir(), 'seer-pool-nonexistent-' + Date.now() + '.ts');
|
|
175
|
+
|
|
176
|
+
const items: WorkItem[] = [
|
|
177
|
+
{ abs: tsFixture, lang: 'typescript', expectedHash: knownHash, maxFileBytes: 0 }, // → cached
|
|
178
|
+
{ abs: tsFixture, lang: 'typescript', expectedHash: null, maxFileBytes: 1 }, // → too-large
|
|
179
|
+
{ abs: ghost, lang: 'typescript', expectedHash: null, maxFileBytes: 0 }, // → io-error
|
|
180
|
+
{ abs: tsFixture, lang: 'typescript', expectedHash: null, maxFileBytes: 0 }, // → parsed
|
|
181
|
+
];
|
|
182
|
+
const kinds: string[] = [];
|
|
183
|
+
await pool.dispatch(items, (seq, result) => { kinds[seq] = result.kind; });
|
|
184
|
+
assert(kinds[0] === 'cached', `seq 0 → cached (got ${kinds[0]})`);
|
|
185
|
+
assert(kinds[1] === 'too-large', `seq 1 → too-large (got ${kinds[1]})`);
|
|
186
|
+
assert(kinds[2] === 'io-error', `seq 2 → io-error (got ${kinds[2]})`);
|
|
187
|
+
assert(kinds[3] === 'parsed', `seq 3 → parsed (got ${kinds[3]})`);
|
|
188
|
+
await pool.shutdown();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ── 5. Clean shutdown leaves no live workers ──────────────────────────────
|
|
192
|
+
console.log('\n── Worker-local WASM reset aggregation ──');
|
|
193
|
+
{
|
|
194
|
+
process.env.SEER_WORKER_TEST_FAKE_WASM_RESET_ON = 'FAKE_WASM_RESET';
|
|
195
|
+
const pool = new WorkerPool({ jobs: 2 });
|
|
196
|
+
try {
|
|
197
|
+
await pool.ready();
|
|
198
|
+
const src = path.join(FIXTURES_DIR, 'sample.ts');
|
|
199
|
+
const resetFixture = path.join(os.tmpdir(), `FAKE_WASM_RESET-${Date.now()}.ts`);
|
|
200
|
+
fs.copyFileSync(src, resetFixture);
|
|
201
|
+
const items: WorkItem[] = [
|
|
202
|
+
{ abs: resetFixture, lang: 'typescript', expectedHash: null, maxFileBytes: 0 },
|
|
203
|
+
{ abs: src, lang: 'typescript', expectedHash: null, maxFileBytes: 0 },
|
|
204
|
+
{ abs: resetFixture, lang: 'typescript', expectedHash: null, maxFileBytes: 0 },
|
|
205
|
+
];
|
|
206
|
+
await pool.dispatch(items, () => {});
|
|
207
|
+
assert(pool.wasmResetCount() === 2, `pool aggregates worker-local wasm resets (got ${pool.wasmResetCount()})`);
|
|
208
|
+
fs.rmSync(resetFixture, { force: true });
|
|
209
|
+
await pool.shutdown();
|
|
210
|
+
} finally {
|
|
211
|
+
delete process.env.SEER_WORKER_TEST_FAKE_WASM_RESET_ON;
|
|
212
|
+
await pool.terminate().catch(() => { /* */ });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── 6. Clean shutdown leaves no live workers ──────────────────────────────
|
|
217
|
+
console.log('\n── Clean shutdown ──');
|
|
218
|
+
{
|
|
219
|
+
const pool = new WorkerPool({ jobs: 4 });
|
|
220
|
+
await pool.ready();
|
|
221
|
+
await pool.shutdown();
|
|
222
|
+
// Second shutdown is a safe no-op (idempotent).
|
|
223
|
+
await pool.shutdown();
|
|
224
|
+
assert(true, 'shutdown() is idempotent');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ── 7. Reject double-dispatch ─────────────────────────────────────────────
|
|
228
|
+
console.log('\n── Reject overlapping dispatch ──');
|
|
229
|
+
{
|
|
230
|
+
const pool = new WorkerPool({ jobs: 2 });
|
|
231
|
+
await pool.ready();
|
|
232
|
+
const tsFixture = path.join(FIXTURES_DIR, 'sample.ts');
|
|
233
|
+
const items: WorkItem[] = new Array(20).fill(null).map(() => ({
|
|
234
|
+
abs: tsFixture, lang: 'typescript' as Language, expectedHash: null, maxFileBytes: 0,
|
|
235
|
+
}));
|
|
236
|
+
const first = pool.dispatch(items, () => {});
|
|
237
|
+
let secondThrew = false;
|
|
238
|
+
try {
|
|
239
|
+
await pool.dispatch(items, () => {});
|
|
240
|
+
} catch {
|
|
241
|
+
secondThrew = true;
|
|
242
|
+
}
|
|
243
|
+
assert(secondThrew, 'overlapping dispatch() rejects');
|
|
244
|
+
await first;
|
|
245
|
+
await pool.shutdown();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ── Done ───────────────────────────────────────────────────────────────────
|
|
249
|
+
console.log('\n══════════════════════════════════════════════════════════════');
|
|
250
|
+
console.log(` Worker-pool results: ${passed} passed, ${failed} failed`);
|
|
251
|
+
if (failed > 0) {
|
|
252
|
+
console.error('\n WORKER-POOL TESTS FAILED\n');
|
|
253
|
+
process.exit(1);
|
|
254
|
+
} else {
|
|
255
|
+
console.log('\n All worker-pool tests passed! ✓\n');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
run().catch(err => {
|
|
260
|
+
console.error('worker-pool test threw:', err);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist", "tests"]
|
|
20
|
+
}
|