pmxtjs 1.0.1 → 1.0.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/dist/esm/pmxt/client.js +9 -1
- package/dist/esm/pmxt/server-manager.d.ts +4 -1
- package/dist/esm/pmxt/server-manager.js +87 -5
- package/dist/pmxt/client.js +9 -1
- package/dist/pmxt/server-manager.d.ts +4 -1
- package/dist/pmxt/server-manager.js +86 -4
- package/generated/package.json +1 -1
- package/package.json +4 -1
- package/pmxt/client.ts +10 -1
- package/pmxt/server-manager.ts +92 -6
package/dist/esm/pmxt/client.js
CHANGED
|
@@ -136,8 +136,16 @@ export class Exchange {
|
|
|
136
136
|
// (may differ from default if default port was busy)
|
|
137
137
|
const actualPort = this.serverManager.getRunningPort();
|
|
138
138
|
const newBaseUrl = `http://localhost:${actualPort}`;
|
|
139
|
+
const accessToken = this.serverManager.getAccessToken();
|
|
140
|
+
const headers = {};
|
|
141
|
+
if (accessToken) {
|
|
142
|
+
headers['x-pmxt-access-token'] = accessToken;
|
|
143
|
+
}
|
|
139
144
|
// Update API client with actual base URL
|
|
140
|
-
const newConfig = new Configuration({
|
|
145
|
+
const newConfig = new Configuration({
|
|
146
|
+
basePath: newBaseUrl,
|
|
147
|
+
headers
|
|
148
|
+
});
|
|
141
149
|
this.api = new DefaultApi(newConfig);
|
|
142
150
|
}
|
|
143
151
|
catch (error) {
|
|
@@ -28,8 +28,9 @@ export declare class ServerManager {
|
|
|
28
28
|
*/
|
|
29
29
|
getRunningPort(): number;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Get the access token from the lock file.
|
|
32
32
|
*/
|
|
33
|
+
getAccessToken(): string | undefined;
|
|
33
34
|
/**
|
|
34
35
|
* Check if the server is running.
|
|
35
36
|
*/
|
|
@@ -42,4 +43,6 @@ export declare class ServerManager {
|
|
|
42
43
|
* Ensure the server is running, starting it if necessary.
|
|
43
44
|
*/
|
|
44
45
|
ensureServerRunning(): Promise<void>;
|
|
46
|
+
private isVersionMismatch;
|
|
47
|
+
private killOldServer;
|
|
45
48
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { DefaultApi, Configuration } from "../generated/src/index.js";
|
|
7
7
|
import { readFileSync, existsSync } from "fs";
|
|
8
8
|
import { homedir } from "os";
|
|
9
|
-
import { join } from "path";
|
|
9
|
+
import { join, dirname } from "path";
|
|
10
10
|
export class ServerManager {
|
|
11
11
|
baseUrl;
|
|
12
12
|
maxRetries;
|
|
@@ -48,8 +48,12 @@ export class ServerManager {
|
|
|
48
48
|
return info?.port || ServerManager.DEFAULT_PORT;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* Get the access token from the lock file.
|
|
52
52
|
*/
|
|
53
|
+
getAccessToken() {
|
|
54
|
+
const info = this.getServerInfo();
|
|
55
|
+
return info?.accessToken;
|
|
56
|
+
}
|
|
53
57
|
/**
|
|
54
58
|
* Check if the server is running.
|
|
55
59
|
*/
|
|
@@ -86,14 +90,40 @@ export class ServerManager {
|
|
|
86
90
|
* Ensure the server is running, starting it if necessary.
|
|
87
91
|
*/
|
|
88
92
|
async ensureServerRunning() {
|
|
89
|
-
// Check
|
|
93
|
+
// Check for force restart
|
|
94
|
+
if (process.env.PMXT_ALWAYS_RESTART === '1') {
|
|
95
|
+
await this.killOldServer();
|
|
96
|
+
}
|
|
97
|
+
// Check if already running and version matches
|
|
90
98
|
if (await this.isServerRunning()) {
|
|
91
|
-
|
|
99
|
+
if (await this.isVersionMismatch()) {
|
|
100
|
+
await this.killOldServer();
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Locate pmxt-ensure-server
|
|
107
|
+
let launcherPath = 'pmxt-ensure-server'; // Default to PATH
|
|
108
|
+
try {
|
|
109
|
+
// Try to resolve from pmxt-core dependency
|
|
110
|
+
// For CommonJS build (which is primary), we can use require directly
|
|
111
|
+
// For ESM build, this will be transpiled appropriately
|
|
112
|
+
const corePackageJson = require.resolve('pmxt-core/package.json');
|
|
113
|
+
const coreDir = dirname(corePackageJson);
|
|
114
|
+
const binPath = join(coreDir, 'bin', 'pmxt-ensure-server');
|
|
115
|
+
if (existsSync(binPath)) {
|
|
116
|
+
launcherPath = binPath;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
// If resolution fails, fall back to PATH
|
|
121
|
+
// This could happen in dev environments where pmxt-core is globally installed
|
|
92
122
|
}
|
|
93
123
|
// Try to start the server using pmxt-ensure-server
|
|
94
124
|
const { spawn } = await import("child_process");
|
|
95
125
|
try {
|
|
96
|
-
const proc = spawn(
|
|
126
|
+
const proc = spawn(launcherPath, [], {
|
|
97
127
|
detached: true,
|
|
98
128
|
stdio: "ignore",
|
|
99
129
|
});
|
|
@@ -107,4 +137,56 @@ export class ServerManager {
|
|
|
107
137
|
`Or start the server manually: pmxt-server`);
|
|
108
138
|
}
|
|
109
139
|
}
|
|
140
|
+
async isVersionMismatch() {
|
|
141
|
+
const info = this.getServerInfo();
|
|
142
|
+
if (!info || !info.version) {
|
|
143
|
+
return true; // Old server without version
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// 1. Try to find package.json relative to the installed location (Production)
|
|
147
|
+
let corePackageJsonPath;
|
|
148
|
+
try {
|
|
149
|
+
corePackageJsonPath = require.resolve('pmxt-core/package.json');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// 2. Try dev path (Monorepo)
|
|
153
|
+
const devPath = join(dirname(__dirname), '../../core/package.json');
|
|
154
|
+
if (existsSync(devPath)) {
|
|
155
|
+
corePackageJsonPath = devPath;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (corePackageJsonPath && existsSync(corePackageJsonPath)) {
|
|
159
|
+
const content = readFileSync(corePackageJsonPath, 'utf-8');
|
|
160
|
+
const pkg = JSON.parse(content);
|
|
161
|
+
// Check if running version starts with package version
|
|
162
|
+
// (Server version might have extra hash in dev mode)
|
|
163
|
+
if (pkg.version && !info.version.startsWith(pkg.version)) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Ignore errors
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
async killOldServer() {
|
|
174
|
+
const info = this.getServerInfo();
|
|
175
|
+
if (info && info.pid) {
|
|
176
|
+
try {
|
|
177
|
+
process.kill(info.pid, 'SIGTERM');
|
|
178
|
+
// Brief wait
|
|
179
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Ignore
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Remove lock file (best effort)
|
|
186
|
+
try {
|
|
187
|
+
const { unlinkSync } = await import('fs');
|
|
188
|
+
unlinkSync(this.lockPath);
|
|
189
|
+
}
|
|
190
|
+
catch { }
|
|
191
|
+
}
|
|
110
192
|
}
|
package/dist/pmxt/client.js
CHANGED
|
@@ -139,8 +139,16 @@ class Exchange {
|
|
|
139
139
|
// (may differ from default if default port was busy)
|
|
140
140
|
const actualPort = this.serverManager.getRunningPort();
|
|
141
141
|
const newBaseUrl = `http://localhost:${actualPort}`;
|
|
142
|
+
const accessToken = this.serverManager.getAccessToken();
|
|
143
|
+
const headers = {};
|
|
144
|
+
if (accessToken) {
|
|
145
|
+
headers['x-pmxt-access-token'] = accessToken;
|
|
146
|
+
}
|
|
142
147
|
// Update API client with actual base URL
|
|
143
|
-
const newConfig = new index_js_1.Configuration({
|
|
148
|
+
const newConfig = new index_js_1.Configuration({
|
|
149
|
+
basePath: newBaseUrl,
|
|
150
|
+
headers
|
|
151
|
+
});
|
|
144
152
|
this.api = new index_js_1.DefaultApi(newConfig);
|
|
145
153
|
}
|
|
146
154
|
catch (error) {
|
|
@@ -28,8 +28,9 @@ export declare class ServerManager {
|
|
|
28
28
|
*/
|
|
29
29
|
getRunningPort(): number;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Get the access token from the lock file.
|
|
32
32
|
*/
|
|
33
|
+
getAccessToken(): string | undefined;
|
|
33
34
|
/**
|
|
34
35
|
* Check if the server is running.
|
|
35
36
|
*/
|
|
@@ -42,4 +43,6 @@ export declare class ServerManager {
|
|
|
42
43
|
* Ensure the server is running, starting it if necessary.
|
|
43
44
|
*/
|
|
44
45
|
ensureServerRunning(): Promise<void>;
|
|
46
|
+
private isVersionMismatch;
|
|
47
|
+
private killOldServer;
|
|
45
48
|
}
|
|
@@ -84,8 +84,12 @@ class ServerManager {
|
|
|
84
84
|
return info?.port || ServerManager.DEFAULT_PORT;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
87
|
+
* Get the access token from the lock file.
|
|
88
88
|
*/
|
|
89
|
+
getAccessToken() {
|
|
90
|
+
const info = this.getServerInfo();
|
|
91
|
+
return info?.accessToken;
|
|
92
|
+
}
|
|
89
93
|
/**
|
|
90
94
|
* Check if the server is running.
|
|
91
95
|
*/
|
|
@@ -122,14 +126,40 @@ class ServerManager {
|
|
|
122
126
|
* Ensure the server is running, starting it if necessary.
|
|
123
127
|
*/
|
|
124
128
|
async ensureServerRunning() {
|
|
125
|
-
// Check
|
|
129
|
+
// Check for force restart
|
|
130
|
+
if (process.env.PMXT_ALWAYS_RESTART === '1') {
|
|
131
|
+
await this.killOldServer();
|
|
132
|
+
}
|
|
133
|
+
// Check if already running and version matches
|
|
126
134
|
if (await this.isServerRunning()) {
|
|
127
|
-
|
|
135
|
+
if (await this.isVersionMismatch()) {
|
|
136
|
+
await this.killOldServer();
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Locate pmxt-ensure-server
|
|
143
|
+
let launcherPath = 'pmxt-ensure-server'; // Default to PATH
|
|
144
|
+
try {
|
|
145
|
+
// Try to resolve from pmxt-core dependency
|
|
146
|
+
// For CommonJS build (which is primary), we can use require directly
|
|
147
|
+
// For ESM build, this will be transpiled appropriately
|
|
148
|
+
const corePackageJson = require.resolve('pmxt-core/package.json');
|
|
149
|
+
const coreDir = (0, path_1.dirname)(corePackageJson);
|
|
150
|
+
const binPath = (0, path_1.join)(coreDir, 'bin', 'pmxt-ensure-server');
|
|
151
|
+
if ((0, fs_1.existsSync)(binPath)) {
|
|
152
|
+
launcherPath = binPath;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// If resolution fails, fall back to PATH
|
|
157
|
+
// This could happen in dev environments where pmxt-core is globally installed
|
|
128
158
|
}
|
|
129
159
|
// Try to start the server using pmxt-ensure-server
|
|
130
160
|
const { spawn } = await Promise.resolve().then(() => __importStar(require("child_process")));
|
|
131
161
|
try {
|
|
132
|
-
const proc = spawn(
|
|
162
|
+
const proc = spawn(launcherPath, [], {
|
|
133
163
|
detached: true,
|
|
134
164
|
stdio: "ignore",
|
|
135
165
|
});
|
|
@@ -143,5 +173,57 @@ class ServerManager {
|
|
|
143
173
|
`Or start the server manually: pmxt-server`);
|
|
144
174
|
}
|
|
145
175
|
}
|
|
176
|
+
async isVersionMismatch() {
|
|
177
|
+
const info = this.getServerInfo();
|
|
178
|
+
if (!info || !info.version) {
|
|
179
|
+
return true; // Old server without version
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
// 1. Try to find package.json relative to the installed location (Production)
|
|
183
|
+
let corePackageJsonPath;
|
|
184
|
+
try {
|
|
185
|
+
corePackageJsonPath = require.resolve('pmxt-core/package.json');
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// 2. Try dev path (Monorepo)
|
|
189
|
+
const devPath = (0, path_1.join)((0, path_1.dirname)(__dirname), '../../core/package.json');
|
|
190
|
+
if ((0, fs_1.existsSync)(devPath)) {
|
|
191
|
+
corePackageJsonPath = devPath;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (corePackageJsonPath && (0, fs_1.existsSync)(corePackageJsonPath)) {
|
|
195
|
+
const content = (0, fs_1.readFileSync)(corePackageJsonPath, 'utf-8');
|
|
196
|
+
const pkg = JSON.parse(content);
|
|
197
|
+
// Check if running version starts with package version
|
|
198
|
+
// (Server version might have extra hash in dev mode)
|
|
199
|
+
if (pkg.version && !info.version.startsWith(pkg.version)) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Ignore errors
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
async killOldServer() {
|
|
210
|
+
const info = this.getServerInfo();
|
|
211
|
+
if (info && info.pid) {
|
|
212
|
+
try {
|
|
213
|
+
process.kill(info.pid, 'SIGTERM');
|
|
214
|
+
// Brief wait
|
|
215
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// Ignore
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Remove lock file (best effort)
|
|
222
|
+
try {
|
|
223
|
+
const { unlinkSync } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
224
|
+
unlinkSync(this.lockPath);
|
|
225
|
+
}
|
|
226
|
+
catch { }
|
|
227
|
+
}
|
|
146
228
|
}
|
|
147
229
|
exports.ServerManager = ServerManager;
|
package/generated/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Unified prediction market data API - The ccxt for prediction markets",
|
|
5
5
|
"author": "PMXT Contributors",
|
|
6
6
|
"repository": {
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
"api",
|
|
42
42
|
"unified"
|
|
43
43
|
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"pmxt-core": "1.0.4"
|
|
46
|
+
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@types/jest": "^30.0.0",
|
|
46
49
|
"@types/node": "^20.0.0",
|
package/pmxt/client.ts
CHANGED
|
@@ -203,8 +203,17 @@ export abstract class Exchange {
|
|
|
203
203
|
const actualPort = this.serverManager.getRunningPort();
|
|
204
204
|
const newBaseUrl = `http://localhost:${actualPort}`;
|
|
205
205
|
|
|
206
|
+
const accessToken = this.serverManager.getAccessToken();
|
|
207
|
+
const headers: any = {};
|
|
208
|
+
if (accessToken) {
|
|
209
|
+
headers['x-pmxt-access-token'] = accessToken;
|
|
210
|
+
}
|
|
211
|
+
|
|
206
212
|
// Update API client with actual base URL
|
|
207
|
-
const newConfig = new Configuration({
|
|
213
|
+
const newConfig = new Configuration({
|
|
214
|
+
basePath: newBaseUrl,
|
|
215
|
+
headers
|
|
216
|
+
});
|
|
208
217
|
this.api = new DefaultApi(newConfig);
|
|
209
218
|
} catch (error) {
|
|
210
219
|
throw new Error(
|
package/pmxt/server-manager.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { DefaultApi, Configuration } from "../generated/src/index.js";
|
|
8
8
|
import { readFileSync, existsSync } from "fs";
|
|
9
9
|
import { homedir } from "os";
|
|
10
|
-
import { join } from "path";
|
|
10
|
+
import { join, dirname } from "path";
|
|
11
11
|
|
|
12
12
|
export interface ServerManagerOptions {
|
|
13
13
|
baseUrl?: string;
|
|
@@ -18,6 +18,8 @@ export interface ServerManagerOptions {
|
|
|
18
18
|
interface ServerLockInfo {
|
|
19
19
|
port: number;
|
|
20
20
|
pid: number;
|
|
21
|
+
accessToken?: string;
|
|
22
|
+
version?: string;
|
|
21
23
|
timestamp: number;
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -66,8 +68,13 @@ export class ServerManager {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/**
|
|
69
|
-
*
|
|
71
|
+
* Get the access token from the lock file.
|
|
70
72
|
*/
|
|
73
|
+
getAccessToken(): string | undefined {
|
|
74
|
+
const info = this.getServerInfo();
|
|
75
|
+
return info?.accessToken;
|
|
76
|
+
}
|
|
77
|
+
|
|
71
78
|
/**
|
|
72
79
|
* Check if the server is running.
|
|
73
80
|
*/
|
|
@@ -108,16 +115,44 @@ export class ServerManager {
|
|
|
108
115
|
* Ensure the server is running, starting it if necessary.
|
|
109
116
|
*/
|
|
110
117
|
async ensureServerRunning(): Promise<void> {
|
|
111
|
-
// Check
|
|
118
|
+
// Check for force restart
|
|
119
|
+
if (process.env.PMXT_ALWAYS_RESTART === '1') {
|
|
120
|
+
await this.killOldServer();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check if already running and version matches
|
|
112
124
|
if (await this.isServerRunning()) {
|
|
113
|
-
|
|
125
|
+
if (await this.isVersionMismatch()) {
|
|
126
|
+
await this.killOldServer();
|
|
127
|
+
} else {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Locate pmxt-ensure-server
|
|
133
|
+
let launcherPath = 'pmxt-ensure-server'; // Default to PATH
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Try to resolve from pmxt-core dependency
|
|
137
|
+
// For CommonJS build (which is primary), we can use require directly
|
|
138
|
+
// For ESM build, this will be transpiled appropriately
|
|
139
|
+
const corePackageJson = require.resolve('pmxt-core/package.json');
|
|
140
|
+
const coreDir = dirname(corePackageJson);
|
|
141
|
+
const binPath = join(coreDir, 'bin', 'pmxt-ensure-server');
|
|
142
|
+
|
|
143
|
+
if (existsSync(binPath)) {
|
|
144
|
+
launcherPath = binPath;
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// If resolution fails, fall back to PATH
|
|
148
|
+
// This could happen in dev environments where pmxt-core is globally installed
|
|
114
149
|
}
|
|
115
150
|
|
|
116
151
|
// Try to start the server using pmxt-ensure-server
|
|
117
152
|
const { spawn } = await import("child_process");
|
|
118
153
|
|
|
119
154
|
try {
|
|
120
|
-
const proc = spawn(
|
|
155
|
+
const proc = spawn(launcherPath, [], {
|
|
121
156
|
detached: true,
|
|
122
157
|
stdio: "ignore",
|
|
123
158
|
});
|
|
@@ -133,5 +168,56 @@ export class ServerManager {
|
|
|
133
168
|
);
|
|
134
169
|
}
|
|
135
170
|
}
|
|
136
|
-
}
|
|
137
171
|
|
|
172
|
+
private async isVersionMismatch(): Promise<boolean> {
|
|
173
|
+
const info = this.getServerInfo();
|
|
174
|
+
if (!info || !info.version) {
|
|
175
|
+
return true; // Old server without version
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
// 1. Try to find package.json relative to the installed location (Production)
|
|
180
|
+
let corePackageJsonPath: string | undefined;
|
|
181
|
+
try {
|
|
182
|
+
corePackageJsonPath = require.resolve('pmxt-core/package.json');
|
|
183
|
+
} catch {
|
|
184
|
+
// 2. Try dev path (Monorepo)
|
|
185
|
+
const devPath = join(dirname(__dirname), '../../core/package.json');
|
|
186
|
+
if (existsSync(devPath)) {
|
|
187
|
+
corePackageJsonPath = devPath;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (corePackageJsonPath && existsSync(corePackageJsonPath)) {
|
|
192
|
+
const content = readFileSync(corePackageJsonPath, 'utf-8');
|
|
193
|
+
const pkg = JSON.parse(content);
|
|
194
|
+
// Check if running version starts with package version
|
|
195
|
+
// (Server version might have extra hash in dev mode)
|
|
196
|
+
if (pkg.version && !info.version.startsWith(pkg.version)) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} catch {
|
|
201
|
+
// Ignore errors
|
|
202
|
+
}
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private async killOldServer(): Promise<void> {
|
|
207
|
+
const info = this.getServerInfo();
|
|
208
|
+
if (info && info.pid) {
|
|
209
|
+
try {
|
|
210
|
+
process.kill(info.pid, 'SIGTERM');
|
|
211
|
+
// Brief wait
|
|
212
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
213
|
+
} catch {
|
|
214
|
+
// Ignore
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Remove lock file (best effort)
|
|
218
|
+
try {
|
|
219
|
+
const { unlinkSync } = await import('fs');
|
|
220
|
+
unlinkSync(this.lockPath);
|
|
221
|
+
} catch { }
|
|
222
|
+
}
|
|
223
|
+
}
|