@grafema/core 0.2.11 → 0.2.12-beta
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/Orchestrator.d.ts +13 -0
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +84 -2
- package/dist/Orchestrator.js.map +1 -1
- package/dist/ParallelAnalysisRunner.d.ts.map +1 -1
- package/dist/ParallelAnalysisRunner.js +28 -41
- package/dist/ParallelAnalysisRunner.js.map +1 -1
- package/dist/PhaseRunner.d.ts +2 -0
- package/dist/PhaseRunner.d.ts.map +1 -1
- package/dist/PhaseRunner.js +5 -1
- package/dist/PhaseRunner.js.map +1 -1
- package/dist/core/IncrementalReanalyzer.d.ts +3 -3
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -1
- package/dist/core/IncrementalReanalyzer.js +12 -12
- package/dist/core/IncrementalReanalyzer.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +20 -4
- package/dist/plugins/analysis/JSASTAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +8 -0
- package/dist/plugins/analysis/ast/GraphBuilder.js.map +1 -1
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js +4 -2
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js.map +1 -1
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js +2 -1
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js.map +1 -1
- package/dist/plugins/analysis/ast/types.d.ts +3 -0
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +6 -2
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +15 -5
- package/dist/plugins/enrichment/ImportExportLinker.js.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.d.ts +21 -7
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +48 -48
- package/dist/storage/backends/RFDBServerBackend.js.map +1 -1
- package/dist/utils/startRfdbServer.d.ts +44 -0
- package/dist/utils/startRfdbServer.d.ts.map +1 -0
- package/dist/utils/startRfdbServer.js +79 -0
- package/dist/utils/startRfdbServer.js.map +1 -0
- package/package.json +3 -3
- package/src/Orchestrator.ts +91 -2
- package/src/ParallelAnalysisRunner.ts +30 -48
- package/src/PhaseRunner.ts +7 -1
- package/src/core/IncrementalReanalyzer.ts +15 -15
- package/src/index.ts +4 -0
- package/src/plugins/analysis/JSASTAnalyzer.ts +27 -4
- package/src/plugins/analysis/ast/GraphBuilder.ts +9 -0
- package/src/plugins/analysis/ast/builders/ModuleRuntimeBuilder.ts +4 -2
- package/src/plugins/analysis/ast/handlers/NewExpressionHandler.ts +2 -1
- package/src/plugins/analysis/ast/types.ts +3 -0
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +8 -2
- package/src/plugins/enrichment/ImportExportLinker.ts +15 -5
- package/src/storage/backends/RFDBServerBackend.ts +52 -60
- package/src/utils/startRfdbServer.ts +126 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for starting rfdb-server
|
|
3
|
+
*
|
|
4
|
+
* Single authoritative function for spawning rfdb-server. All spawn sites
|
|
5
|
+
* (RFDBServerBackend, CLI server command, ParallelAnalysisRunner) delegate here.
|
|
6
|
+
*
|
|
7
|
+
* Callers are responsible for checking if a server is already running before
|
|
8
|
+
* calling this function. This function always spawns a new server process.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, unlinkSync, writeFileSync } from 'fs';
|
|
12
|
+
import { dirname } from 'path';
|
|
13
|
+
import { spawn, type ChildProcess } from 'child_process';
|
|
14
|
+
import { setTimeout as sleep } from 'timers/promises';
|
|
15
|
+
import { findRfdbBinary } from './findRfdbBinary.js';
|
|
16
|
+
|
|
17
|
+
export interface StartRfdbServerOptions {
|
|
18
|
+
dbPath: string;
|
|
19
|
+
socketPath: string;
|
|
20
|
+
/** Override binary path; if absent, findRfdbBinary() is called */
|
|
21
|
+
binaryPath?: string;
|
|
22
|
+
/** If provided, PID file is written after spawn */
|
|
23
|
+
pidPath?: string;
|
|
24
|
+
/** Socket poll timeout in ms (default: 5000) */
|
|
25
|
+
waitTimeoutMs?: number;
|
|
26
|
+
/** Optional logger for debug messages */
|
|
27
|
+
logger?: { debug(msg: string): void };
|
|
28
|
+
/** Internal: dependency injection for testing */
|
|
29
|
+
_deps?: {
|
|
30
|
+
spawn?: typeof spawn;
|
|
31
|
+
findRfdbBinary?: () => string | null;
|
|
32
|
+
existsSync?: (path: string) => boolean;
|
|
33
|
+
unlinkSync?: (path: string) => void;
|
|
34
|
+
writeFileSync?: (path: string, data: string) => void;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Start an rfdb-server process.
|
|
40
|
+
*
|
|
41
|
+
* 1. Resolve binary (explicit or via findRfdbBinary)
|
|
42
|
+
* 2. Remove stale socket
|
|
43
|
+
* 3. Spawn detached process
|
|
44
|
+
* 4. Write PID file (if pidPath provided)
|
|
45
|
+
* 5. Poll for socket file up to waitTimeoutMs
|
|
46
|
+
* 6. Return ChildProcess (caller decides whether to kill later)
|
|
47
|
+
*/
|
|
48
|
+
export async function startRfdbServer(options: StartRfdbServerOptions): Promise<ChildProcess> {
|
|
49
|
+
const {
|
|
50
|
+
dbPath,
|
|
51
|
+
socketPath,
|
|
52
|
+
pidPath,
|
|
53
|
+
waitTimeoutMs = 5000,
|
|
54
|
+
logger,
|
|
55
|
+
_deps,
|
|
56
|
+
} = options;
|
|
57
|
+
|
|
58
|
+
const _spawn = _deps?.spawn ?? spawn;
|
|
59
|
+
const _findRfdbBinary = _deps?.findRfdbBinary ?? findRfdbBinary;
|
|
60
|
+
const _existsSync = _deps?.existsSync ?? existsSync;
|
|
61
|
+
const _unlinkSync = _deps?.unlinkSync ?? unlinkSync;
|
|
62
|
+
const _writeFileSync = _deps?.writeFileSync ?? writeFileSync;
|
|
63
|
+
|
|
64
|
+
// 1. Resolve binary
|
|
65
|
+
const binaryPath = options.binaryPath || _findRfdbBinary();
|
|
66
|
+
if (!binaryPath) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'RFDB server binary not found.\n' +
|
|
69
|
+
'Install @grafema/rfdb: npm install @grafema/rfdb\n' +
|
|
70
|
+
'Or build from source: cargo build --release --bin rfdb-server'
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 2. Remove stale socket
|
|
75
|
+
if (_existsSync(socketPath)) {
|
|
76
|
+
_unlinkSync(socketPath);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const dataDir = dirname(socketPath);
|
|
80
|
+
logger?.debug(`Starting rfdb-server: ${binaryPath} ${dbPath} --socket ${socketPath} --data-dir ${dataDir}`);
|
|
81
|
+
|
|
82
|
+
// 3. Spawn server (detached, survives parent exit)
|
|
83
|
+
// Mutable container to capture async spawn errors (Dijkstra amendment B)
|
|
84
|
+
const state = { spawnError: null as Error | null };
|
|
85
|
+
|
|
86
|
+
const serverProcess = _spawn(binaryPath, [dbPath, '--socket', socketPath, '--data-dir', dataDir], {
|
|
87
|
+
stdio: ['ignore', 'ignore', 'inherit'],
|
|
88
|
+
detached: true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
serverProcess.unref();
|
|
92
|
+
|
|
93
|
+
// Wire error handler to capture ENOENT and other spawn failures
|
|
94
|
+
serverProcess.on('error', (err: Error) => {
|
|
95
|
+
state.spawnError = err;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// 4. Write PID file if requested and pid is available
|
|
99
|
+
if (pidPath && serverProcess.pid) {
|
|
100
|
+
_writeFileSync(pidPath, String(serverProcess.pid));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 5. Poll for socket file
|
|
104
|
+
const maxAttempts = Math.ceil(waitTimeoutMs / 100);
|
|
105
|
+
let attempts = 0;
|
|
106
|
+
while (!_existsSync(socketPath) && attempts < maxAttempts) {
|
|
107
|
+
if (state.spawnError) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`RFDB server failed to start: ${state.spawnError.message} — check binary: ${binaryPath}`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
await sleep(100);
|
|
113
|
+
attempts++;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 6. Final check
|
|
117
|
+
if (!_existsSync(socketPath)) {
|
|
118
|
+
const detail = state.spawnError ? `: ${state.spawnError.message}` : '';
|
|
119
|
+
throw new Error(
|
|
120
|
+
`RFDB server failed to start after ${waitTimeoutMs}ms${detail} — check binary: ${binaryPath}`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
logger?.debug(`rfdb-server started on ${socketPath}`);
|
|
125
|
+
return serverProcess;
|
|
126
|
+
}
|