@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.
Files changed (62) hide show
  1. package/dist/Orchestrator.d.ts +13 -0
  2. package/dist/Orchestrator.d.ts.map +1 -1
  3. package/dist/Orchestrator.js +84 -2
  4. package/dist/Orchestrator.js.map +1 -1
  5. package/dist/ParallelAnalysisRunner.d.ts.map +1 -1
  6. package/dist/ParallelAnalysisRunner.js +28 -41
  7. package/dist/ParallelAnalysisRunner.js.map +1 -1
  8. package/dist/PhaseRunner.d.ts +2 -0
  9. package/dist/PhaseRunner.d.ts.map +1 -1
  10. package/dist/PhaseRunner.js +5 -1
  11. package/dist/PhaseRunner.js.map +1 -1
  12. package/dist/core/IncrementalReanalyzer.d.ts +3 -3
  13. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -1
  14. package/dist/core/IncrementalReanalyzer.js +12 -12
  15. package/dist/core/IncrementalReanalyzer.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +2 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  21. package/dist/plugins/analysis/JSASTAnalyzer.js +20 -4
  22. package/dist/plugins/analysis/JSASTAnalyzer.js.map +1 -1
  23. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  24. package/dist/plugins/analysis/ast/GraphBuilder.js +8 -0
  25. package/dist/plugins/analysis/ast/GraphBuilder.js.map +1 -1
  26. package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.d.ts.map +1 -1
  27. package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js +4 -2
  28. package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js.map +1 -1
  29. package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.d.ts.map +1 -1
  30. package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js +2 -1
  31. package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js.map +1 -1
  32. package/dist/plugins/analysis/ast/types.d.ts +3 -0
  33. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  34. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  35. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +6 -2
  36. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js.map +1 -1
  37. package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
  38. package/dist/plugins/enrichment/ImportExportLinker.js +15 -5
  39. package/dist/plugins/enrichment/ImportExportLinker.js.map +1 -1
  40. package/dist/storage/backends/RFDBServerBackend.d.ts +21 -7
  41. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  42. package/dist/storage/backends/RFDBServerBackend.js +48 -48
  43. package/dist/storage/backends/RFDBServerBackend.js.map +1 -1
  44. package/dist/utils/startRfdbServer.d.ts +44 -0
  45. package/dist/utils/startRfdbServer.d.ts.map +1 -0
  46. package/dist/utils/startRfdbServer.js +79 -0
  47. package/dist/utils/startRfdbServer.js.map +1 -0
  48. package/package.json +3 -3
  49. package/src/Orchestrator.ts +91 -2
  50. package/src/ParallelAnalysisRunner.ts +30 -48
  51. package/src/PhaseRunner.ts +7 -1
  52. package/src/core/IncrementalReanalyzer.ts +15 -15
  53. package/src/index.ts +4 -0
  54. package/src/plugins/analysis/JSASTAnalyzer.ts +27 -4
  55. package/src/plugins/analysis/ast/GraphBuilder.ts +9 -0
  56. package/src/plugins/analysis/ast/builders/ModuleRuntimeBuilder.ts +4 -2
  57. package/src/plugins/analysis/ast/handlers/NewExpressionHandler.ts +2 -1
  58. package/src/plugins/analysis/ast/types.ts +3 -0
  59. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +8 -2
  60. package/src/plugins/enrichment/ImportExportLinker.ts +15 -5
  61. package/src/storage/backends/RFDBServerBackend.ts +52 -60
  62. 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
+ }