@dxos/phoenix 0.1.58-main.88ec9da → 0.1.58-main.935caa2

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.
@@ -30,77 +30,110 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // packages/common/phoenix/src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- Phoenix: () => Phoenix,
33
+ DaemonManager: () => DaemonManager,
34
34
  WatchDog: () => WatchDog
35
35
  });
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
38
- // packages/common/phoenix/src/phoenix.ts
38
+ // packages/common/phoenix/src/daemon-manager.ts
39
39
  var import_node_child_process = require("node:child_process");
40
40
  var import_node_fs2 = require("node:fs");
41
+ var import_promises = require("node:fs/promises");
41
42
  var import_node_path = require("node:path");
42
43
  var import_pkg_up = __toESM(require("pkg-up"));
43
44
  var import_invariant = require("@dxos/invariant");
45
+ var import_lock_file2 = require("@dxos/lock-file");
44
46
  var import_log = require("@dxos/log");
45
47
 
46
48
  // packages/common/phoenix/src/utils.ts
47
49
  var import_node_fs = require("node:fs");
48
50
  var import_async = require("@dxos/async");
51
+ var import_lock_file = require("@dxos/lock-file");
49
52
 
50
53
  // packages/common/phoenix/src/defs.ts
51
- var WATCHDOG_START_TIMEOUT = 1e4;
52
- var WATCHDOG_STOP_TIMEOUT = 1e3;
53
- var WATCHDOG_CHECK_INTERVAL = 50;
54
+ var LOCK_TIMEOUT = 1e3;
55
+ var LOCK_CHECK_INTERVAL = 50;
54
56
 
55
57
  // packages/common/phoenix/src/utils.ts
56
- var waitForPidDeletion = async (pidFile) => (0, import_async.waitForCondition)({
57
- condition: () => !(0, import_node_fs.existsSync)(pidFile),
58
- timeout: WATCHDOG_STOP_TIMEOUT,
59
- interval: WATCHDOG_CHECK_INTERVAL
58
+ var waitForLockAcquisition = async (lockFile) => (0, import_async.waitForCondition)({
59
+ condition: async () => await import_lock_file.LockFile.isLocked(lockFile),
60
+ timeout: LOCK_TIMEOUT,
61
+ interval: LOCK_CHECK_INTERVAL,
62
+ error: new Error("Lock file is not being acquired.")
60
63
  });
61
- var waitForPidFileBeingFilledWithInfo = async (pidFile) => (0, import_async.waitForCondition)({
62
- condition: () => (0, import_node_fs.readFileSync)(pidFile, {
64
+ var waitForLockFileBeingFilledWithInfo = async (lockFile) => (0, import_async.waitForCondition)({
65
+ condition: () => (0, import_node_fs.readFileSync)(lockFile, {
63
66
  encoding: "utf-8"
64
67
  }).includes("pid"),
65
- timeout: WATCHDOG_START_TIMEOUT,
66
- interval: WATCHDOG_CHECK_INTERVAL,
68
+ timeout: LOCK_TIMEOUT,
69
+ interval: LOCK_CHECK_INTERVAL,
67
70
  error: new Error("Lock file is not being propagated with info.")
68
71
  });
72
+ var waitForLockRelease = async (lockFile) => (0, import_async.waitForCondition)({
73
+ condition: async () => !await import_lock_file.LockFile.isLocked(lockFile),
74
+ timeout: LOCK_TIMEOUT,
75
+ interval: LOCK_CHECK_INTERVAL,
76
+ error: new Error("Lock file is not being released.")
77
+ });
69
78
 
70
- // packages/common/phoenix/src/phoenix.ts
71
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/phoenix/src/phoenix.ts";
72
- var Phoenix = class _Phoenix {
73
- /**
74
- * Starts detached watchdog process which starts and monitors selected command.
75
- */
76
- static async start(params) {
77
- {
78
- if ((0, import_node_fs2.existsSync)(params.pidFile)) {
79
- await _Phoenix.stop(params.pidFile);
80
- }
81
- await waitForPidDeletion(params.pidFile);
79
+ // packages/common/phoenix/src/daemon-manager.ts
80
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/phoenix/src/daemon-manager.ts";
81
+ var LOCK_FILE_NAME = "lockfile";
82
+ var DaemonManager = class {
83
+ constructor(_rootPath) {
84
+ this._rootPath = _rootPath;
85
+ if (!(0, import_node_fs2.existsSync)((0, import_node_path.join)(_rootPath, "profile"))) {
86
+ (0, import_node_fs2.mkdirSync)((0, import_node_path.join)(_rootPath, "profile"), {
87
+ recursive: true
88
+ });
82
89
  }
90
+ }
91
+ _getConfigFiles(uid) {
92
+ const defaultConfigDir = (0, import_node_path.join)(this._rootPath, "profile", uid);
93
+ if (!(0, import_node_fs2.existsSync)(defaultConfigDir)) {
94
+ (0, import_node_fs2.mkdirSync)(defaultConfigDir, {
95
+ recursive: true
96
+ });
97
+ }
98
+ return {
99
+ lockFile: (0, import_node_path.join)(defaultConfigDir, LOCK_FILE_NAME),
100
+ logFile: (0, import_node_path.join)(defaultConfigDir, "file.log"),
101
+ errFile: (0, import_node_path.join)(defaultConfigDir, "err.log")
102
+ };
103
+ }
104
+ async start(params) {
105
+ (0, import_invariant.invariant)(params.command, "command is required", {
106
+ F: __dxlog_file,
107
+ L: 46,
108
+ S: this,
109
+ A: [
110
+ "params.command",
111
+ "'command is required'"
112
+ ]
113
+ });
114
+ const watchDogParams = {
115
+ ...this._getConfigFiles(params.uid),
116
+ ...params
117
+ };
83
118
  {
84
- [
85
- params.logFile,
86
- params.errFile,
87
- params.pidFile
88
- ].forEach((filename) => {
89
- if (!(0, import_node_fs2.existsSync)(filename)) {
90
- (0, import_node_fs2.mkdirSync)((0, import_node_path.dirname)(filename), {
91
- recursive: true
92
- });
93
- (0, import_node_fs2.writeFileSync)(filename, "", {
94
- encoding: "utf-8"
95
- });
96
- }
119
+ (0, import_node_fs2.mkdirSync)((0, import_node_path.dirname)(watchDogParams.logFile), {
120
+ recursive: true
121
+ });
122
+ (0, import_node_fs2.mkdirSync)((0, import_node_path.dirname)(watchDogParams.errFile), {
123
+ recursive: true
97
124
  });
98
125
  }
126
+ {
127
+ if (await import_lock_file2.LockFile.isLocked(watchDogParams.lockFile)) {
128
+ throw new Error("Lock file is already locked.");
129
+ }
130
+ (0, import_node_fs2.unlinkSync)(watchDogParams.lockFile);
131
+ }
99
132
  const watchdogPath = (0, import_node_path.join)((0, import_node_path.dirname)(import_pkg_up.default.sync({
100
133
  cwd: __dirname
101
134
  })), "bin", "watchdog");
102
135
  const watchDog = (0, import_node_child_process.fork)(watchdogPath, [
103
- JSON.stringify(params)
136
+ JSON.stringify(watchDogParams)
104
137
  ], {
105
138
  detached: true,
106
139
  cwd: __dirname
@@ -112,63 +145,87 @@ var Phoenix = class _Phoenix {
112
145
  signal
113
146
  }, {
114
147
  F: __dxlog_file,
115
- L: 52,
148
+ L: 75,
116
149
  S: this,
117
150
  C: (f, a) => f(...a)
118
151
  });
119
152
  }
120
153
  });
121
- await waitForPidFileBeingFilledWithInfo(params.pidFile);
154
+ await waitForLockAcquisition(watchDogParams.lockFile);
155
+ await waitForLockFileBeingFilledWithInfo(watchDogParams.lockFile);
122
156
  watchDog.disconnect();
123
157
  watchDog.unref();
124
- return _Phoenix.info(params.pidFile);
158
+ return this.getInfo(params.uid);
125
159
  }
126
- /**
127
- * Stops detached watchdog process by PID info written down in PID file.
128
- */
129
- static async stop(pidFile, force = false) {
130
- if (!(0, import_node_fs2.existsSync)(pidFile)) {
131
- throw new Error("PID file does not exist");
132
- }
133
- const fileContent = (0, import_node_fs2.readFileSync)(pidFile, {
160
+ async stop(uid, force) {
161
+ const lockFile = this._getConfigFiles(uid).lockFile;
162
+ const processInfo = JSON.parse((0, import_node_fs2.readFileSync)(lockFile, {
134
163
  encoding: "utf-8"
135
- });
136
- if (!fileContent.includes("pid")) {
137
- throw new Error("Invalid PID file content");
138
- }
139
- const { pid } = JSON.parse(fileContent);
140
- const signal = force ? "SIGKILL" : "SIGINT";
164
+ }));
141
165
  try {
142
- process.kill(pid, signal);
166
+ if (force) {
167
+ process.kill(processInfo.pid, "SIGKILL");
168
+ } else {
169
+ process.kill(processInfo.pid, "SIGINT");
170
+ }
143
171
  } catch (err) {
144
- (0, import_invariant.invariant)(err instanceof Error, "Invalid error type", {
172
+ (0, import_invariant.invariant)(err instanceof Error, "Invalid error type.", {
145
173
  F: __dxlog_file,
146
- L: 81,
174
+ L: 98,
147
175
  S: this,
148
176
  A: [
149
177
  "err instanceof Error",
150
- "'Invalid error type'"
178
+ "'Invalid error type.'"
151
179
  ]
152
180
  });
153
- if (err.message.includes("ESRCH") || err.name.includes("ESRCH")) {
154
- (0, import_node_fs2.unlinkSync)(pidFile);
155
- } else {
181
+ if (!err.name.includes("ESRCH") && !err.message.includes("ESRCH")) {
156
182
  throw err;
157
183
  }
158
184
  }
185
+ await waitForLockRelease(lockFile);
186
+ return this.getInfo(uid);
159
187
  }
160
- static info(pidFile) {
161
- return JSON.parse((0, import_node_fs2.readFileSync)(pidFile, {
162
- encoding: "utf-8"
188
+ async list() {
189
+ const uids = (await (0, import_promises.readdir)((0, import_node_path.join)(this._rootPath, "profile"))).filter((uid) => !uid.startsWith("."));
190
+ return Promise.all(uids.map(async (uid) => {
191
+ return this.getInfo(uid);
163
192
  }));
164
193
  }
194
+ async getInfo(uid) {
195
+ const files = this._getConfigFiles(uid);
196
+ let info = {
197
+ running: await import_lock_file2.LockFile.isLocked(files.lockFile),
198
+ uid,
199
+ ...files
200
+ };
201
+ if ((0, import_node_fs2.existsSync)(files.lockFile)) {
202
+ try {
203
+ info = {
204
+ ...info,
205
+ ...JSON.parse((0, import_node_fs2.readFileSync)(files.lockFile, {
206
+ encoding: "utf-8"
207
+ }))
208
+ };
209
+ } catch (err) {
210
+ }
211
+ }
212
+ return info;
213
+ }
214
+ async isRunning(uid) {
215
+ const lockFile = this._getConfigFiles(uid).lockFile;
216
+ return import_lock_file2.LockFile.isLocked(lockFile);
217
+ }
165
218
  };
166
219
 
167
220
  // packages/common/phoenix/src/watchdog.ts
168
221
  var import_node_child_process2 = require("node:child_process");
169
222
  var import_node_fs3 = require("node:fs");
223
+ var import_node_util = require("node:util");
224
+ var import_ps_tree = __toESM(require("ps-tree"));
170
225
  var import_async2 = require("@dxos/async");
226
+ var import_context = require("@dxos/context");
171
227
  var import_invariant2 = require("@dxos/invariant");
228
+ var import_lock_file3 = require("@dxos/lock-file");
172
229
  var import_log2 = require("@dxos/log");
173
230
  function _ts_decorate(decorators, target, key, desc) {
174
231
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -187,43 +244,79 @@ var WatchDog = class {
187
244
  this._restarts = 0;
188
245
  }
189
246
  async start() {
247
+ await this._acquireLock();
248
+ this._log("Lock acquired.");
190
249
  const { cwd, shell, env, command, args } = {
191
250
  cwd: process.cwd(),
192
251
  ...this._params
193
252
  };
194
- this._log(`Spawning process \`\`\`${command} ${args?.join(" ")}\`\`\``);
253
+ (0, import_invariant2.invariant)(command, "Command is not defined.", {
254
+ F: __dxlog_file2,
255
+ L: 86,
256
+ S: this,
257
+ A: [
258
+ "command",
259
+ "'Command is not defined.'"
260
+ ]
261
+ });
262
+ this._log(`Spawning process ${command} ${args?.join(" ")}`);
195
263
  this._child = (0, import_node_child_process2.spawn)(command, args, {
196
264
  cwd,
197
265
  shell,
198
266
  env,
199
267
  stdio: "pipe"
200
268
  });
269
+ this._processCtx = new import_context.Context();
270
+ const childInfo = {
271
+ pid: process.pid,
272
+ timestamp: Date.now(),
273
+ restarts: this._restarts,
274
+ ...this._params
275
+ };
276
+ (0, import_node_fs3.writeFileSync)(this._params.lockFile, JSON.stringify(childInfo, void 0, 2), {
277
+ encoding: "utf-8"
278
+ });
201
279
  this._child.stdout.on("data", (data) => {
202
280
  this._log(String(data));
203
281
  });
204
282
  this._child.stderr.on("data", (data) => {
205
283
  this._err(data);
206
284
  });
207
- this._child.on("close", async (code, signal) => {
208
- if (code && code !== 0 && signal !== "SIGINT" && signal !== "SIGKILL") {
209
- this._err(`Died unexpectedly with exit code ${code} (signal: ${signal}).`);
210
- await this.restart();
211
- }
285
+ {
286
+ const restartHandler = async (code, signal) => {
287
+ if (code && code !== 0) {
288
+ this._err(`Died unexpectedly with exit code ${code} (signal: ${signal}).`);
289
+ await this.restart();
290
+ }
291
+ };
292
+ this._child.on("close", restartHandler);
293
+ this._processCtx.onDispose(() => {
294
+ this._child.off("close", restartHandler);
295
+ });
296
+ }
297
+ this._child.on("close", (code, signal) => {
212
298
  this._log(`Stopped with exit code ${code} (signal: ${signal}).`);
213
- if ((0, import_node_fs3.existsSync)(this._params.pidFile)) {
214
- (0, import_node_fs3.unlinkSync)(this._params.pidFile);
215
- }
216
299
  });
217
- const childInfo = {
218
- pid: this._child.pid,
219
- started: Date.now(),
220
- restarts: this._restarts,
221
- ...this._params
222
- };
223
- (0, import_node_fs3.writeFileSync)(this._params.pidFile, JSON.stringify(childInfo, void 0, 2), {
224
- encoding: "utf-8"
300
+ (0, import_invariant2.invariant)(this._child.pid, "Child process has no pid.", {
301
+ F: __dxlog_file2,
302
+ L: 129,
303
+ S: this,
304
+ A: [
305
+ "this._child.pid",
306
+ "'Child process has no pid.'"
307
+ ]
225
308
  });
226
- await waitForPidFileBeingFilledWithInfo(this._params.pidFile);
309
+ this._log(`Started with pid ${this._child.pid}.`);
310
+ }
311
+ /**
312
+ * Sends SIGINT to the child process and the tree it spawned (if `killTree` param is `true`).
313
+ */
314
+ async stop() {
315
+ if (!this._child) {
316
+ return;
317
+ }
318
+ await this._killWithSignal("SIGKILL");
319
+ await this._releaseLock();
227
320
  }
228
321
  /**
229
322
  * Sends SIGKILL to the child process and the tree it spawned (if `killTree` param is `true`).
@@ -233,10 +326,7 @@ var WatchDog = class {
233
326
  return;
234
327
  }
235
328
  await this._killWithSignal("SIGKILL");
236
- if ((0, import_node_fs3.existsSync)(this._params.pidFile)) {
237
- (0, import_node_fs3.unlinkSync)(this._params.pidFile);
238
- }
239
- await waitForPidDeletion(this._params.pidFile);
329
+ await this._releaseLock();
240
330
  }
241
331
  async restart() {
242
332
  await this.kill();
@@ -245,7 +335,7 @@ var WatchDog = class {
245
335
  } else {
246
336
  (0, import_log2.log)("Restarting...", void 0, {
247
337
  F: __dxlog_file2,
248
- L: 120,
338
+ L: 166,
249
339
  S: this,
250
340
  C: (f, a) => f(...a)
251
341
  });
@@ -254,9 +344,45 @@ var WatchDog = class {
254
344
  }
255
345
  }
256
346
  async _killWithSignal(signal) {
347
+ (0, import_invariant2.invariant)(this._processCtx, "Process context is not defined.", {
348
+ F: __dxlog_file2,
349
+ L: 173,
350
+ S: this,
351
+ A: [
352
+ "this._processCtx",
353
+ "'Process context is not defined.'"
354
+ ]
355
+ });
356
+ await this._processCtx.dispose();
357
+ if (this._params.killTree) {
358
+ if (process.platform !== "win32") {
359
+ (0, import_invariant2.invariant)(this._child?.pid, "Child process has no pid.", {
360
+ F: __dxlog_file2,
361
+ L: 179,
362
+ S: this,
363
+ A: [
364
+ "this._child?.pid",
365
+ "'Child process has no pid.'"
366
+ ]
367
+ });
368
+ const children = await (0, import_node_util.promisify)(import_ps_tree.default)(this._child.pid);
369
+ children.map((p) => p.PID).forEach((tpid) => {
370
+ (0, import_invariant2.invariant)(tpid, "Process id is not defined.", {
371
+ F: __dxlog_file2,
372
+ L: 184,
373
+ S: this,
374
+ A: [
375
+ "tpid",
376
+ "'Process id is not defined.'"
377
+ ]
378
+ });
379
+ process.kill(Number(tpid), signal);
380
+ });
381
+ }
382
+ }
257
383
  (0, import_invariant2.invariant)(this._child?.pid, "Child process has no pid.", {
258
384
  F: __dxlog_file2,
259
- L: 127,
385
+ L: 190,
260
386
  S: this,
261
387
  A: [
262
388
  "this._child?.pid",
@@ -266,6 +392,27 @@ var WatchDog = class {
266
392
  this._child.kill(signal);
267
393
  this._child = void 0;
268
394
  }
395
+ async _acquireLock() {
396
+ if (await import_lock_file3.LockFile.isLocked(this._params.lockFile)) {
397
+ throw new Error("Lock file is already locked.");
398
+ }
399
+ this._lock = await import_lock_file3.LockFile.acquire(this._params.lockFile);
400
+ await waitForLockAcquisition(this._params.lockFile);
401
+ }
402
+ async _releaseLock() {
403
+ (0, import_invariant2.invariant)(this._lock, "Lock is not defined.", {
404
+ F: __dxlog_file2,
405
+ L: 204,
406
+ S: this,
407
+ A: [
408
+ "this._lock",
409
+ "'Lock is not defined.'"
410
+ ]
411
+ });
412
+ await import_lock_file3.LockFile.release(this._lock);
413
+ await waitForLockRelease(this._params.lockFile);
414
+ this._lock = void 0;
415
+ }
269
416
  _log(message) {
270
417
  (0, import_node_fs3.writeFileSync)(this._params.logFile, message + "\n", {
271
418
  flag: "a+",
@@ -283,12 +430,15 @@ var WatchDog = class {
283
430
  _ts_decorate([
284
431
  import_async2.synchronized
285
432
  ], WatchDog.prototype, "start", null);
433
+ _ts_decorate([
434
+ import_async2.synchronized
435
+ ], WatchDog.prototype, "stop", null);
286
436
  _ts_decorate([
287
437
  import_async2.synchronized
288
438
  ], WatchDog.prototype, "kill", null);
289
439
  // Annotate the CommonJS export names for ESM import in node:
290
440
  0 && (module.exports = {
291
- Phoenix,
441
+ DaemonManager,
292
442
  WatchDog
293
443
  });
294
444
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/index.ts", "../../../src/phoenix.ts", "../../../src/utils.ts", "../../../src/defs.ts", "../../../src/watchdog.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n// Inspired by https://github.com/foreversd/forever\n// Their copyright notice is included below.\n// Copyright (C) 2010 Charlie Robbins & the Contributors\n//\n\nexport * from './phoenix';\nexport * from './watchdog';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { fork } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { waitForPidDeletion, waitForPidFileBeingFilledWithInfo } from './utils';\nimport { ProcessInfo, WatchDogParams } from './watchdog';\n\n/**\n * Utils to start/stop detached process with errors and logs handling.\n */\nexport class Phoenix {\n /**\n * Starts detached watchdog process which starts and monitors selected command.\n */\n static async start(params: WatchDogParams) {\n {\n // Clear stale pid file.\n if (existsSync(params.pidFile)) {\n await Phoenix.stop(params.pidFile);\n }\n\n await waitForPidDeletion(params.pidFile);\n }\n\n {\n // Create log folders.\n [params.logFile, params.errFile, params.pidFile].forEach((filename) => {\n if (!existsSync(filename)) {\n mkdirSync(dirname(filename), { recursive: true });\n writeFileSync(filename, '', { encoding: 'utf-8' });\n }\n });\n }\n\n const watchdogPath = join(dirname(pkgUp.sync({ cwd: __dirname })!), 'bin', 'watchdog');\n\n const watchDog = fork(watchdogPath, [JSON.stringify(params)], {\n detached: true,\n cwd: __dirname,\n });\n\n watchDog.on('exit', (code, signal) => {\n if (code && code !== 0) {\n log.error('Monitor died unexpectedly', { code, signal });\n }\n });\n\n await waitForPidFileBeingFilledWithInfo(params.pidFile);\n\n watchDog.disconnect();\n watchDog.unref();\n\n return Phoenix.info(params.pidFile);\n }\n\n /**\n * Stops detached watchdog process by PID info written down in PID file.\n */\n static async stop(pidFile: string, force = false) {\n if (!existsSync(pidFile)) {\n throw new Error('PID file does not exist');\n }\n const fileContent = readFileSync(pidFile, { encoding: 'utf-8' });\n if (!fileContent.includes('pid')) {\n throw new Error('Invalid PID file content');\n }\n\n const { pid } = JSON.parse(fileContent);\n const signal: NodeJS.Signals = force ? 'SIGKILL' : 'SIGINT';\n try {\n process.kill(pid, signal);\n } catch (err) {\n invariant(err instanceof Error, 'Invalid error type');\n if (err.message.includes('ESRCH') || err.name.includes('ESRCH')) {\n // Process is already dead.\n unlinkSync(pidFile);\n } else {\n throw err;\n }\n }\n }\n\n static info(pidFile: string): ProcessInfo {\n return JSON.parse(readFileSync(pidFile, { encoding: 'utf-8' }));\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { existsSync, readFileSync } from 'node:fs';\n\nimport { waitForCondition } from '@dxos/async';\n\nimport { WATCHDOG_CHECK_INTERVAL, WATCHDOG_START_TIMEOUT, WATCHDOG_STOP_TIMEOUT } from './defs';\n\nexport const waitForPidCreation = async (pidFile: string) =>\n waitForCondition({\n condition: () => existsSync(pidFile),\n timeout: WATCHDOG_START_TIMEOUT,\n interval: WATCHDOG_CHECK_INTERVAL,\n });\n\nexport const waitForPidDeletion = async (pidFile: string) =>\n waitForCondition({\n condition: () => !existsSync(pidFile),\n timeout: WATCHDOG_STOP_TIMEOUT,\n interval: WATCHDOG_CHECK_INTERVAL,\n });\n\nexport const waitForPidFileBeingFilledWithInfo = async (pidFile: string) =>\n waitForCondition({\n condition: () => readFileSync(pidFile, { encoding: 'utf-8' }).includes('pid'),\n timeout: WATCHDOG_START_TIMEOUT,\n interval: WATCHDOG_CHECK_INTERVAL,\n error: new Error('Lock file is not being propagated with info.'),\n });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const LOCK_TIMEOUT = 1_000;\nexport const LOCK_CHECK_INTERVAL = 50;\nexport const WATCHDOG_START_TIMEOUT = 10_000;\nexport const WATCHDOG_STOP_TIMEOUT = 1_000;\nexport const WATCHDOG_CHECK_INTERVAL = 50;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport { existsSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { FileHandle } from 'node:fs/promises';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { waitForPidDeletion, waitForPidFileBeingFilledWithInfo } from './utils';\n\nexport type ProcessInfo = WatchDogParams & {\n pid?: number;\n started?: number;\n restarts?: number;\n running?: boolean;\n};\n\nexport type WatchDogParams = {\n profile?: string; // Human readable process identifier\n pidFile: string; // Path to PID file\n\n //\n // Log files and associated logging options for this instance\n //\n logFile: string; // Path to log output all logs\n errFile: string; // Path to log output from child stderr\n\n //\n // Basic configuration options\n //\n maxRestarts?: number | undefined; // Sets the maximum number of times a given script should run\n killTree?: boolean | undefined; // Kills the entire child process tree on `exit`\n\n //\n // Command to spawn as well as options and other vars\n // (env, cwd, etc) to pass along\n //\n command: string; // Binary to run (default: 'node')\n args?: string[] | undefined; // Additional arguments to pass to the script,\n\n //\n // More specific options to pass along to `child_process.spawn` which\n // will override anything passed to the `spawnWith` option\n //\n env?: NodeJS.ProcessEnv | undefined;\n cwd?: string | undefined;\n shell?: boolean | undefined;\n};\n\nexport class WatchDog {\n private _lock?: FileHandle;\n private _child?: ChildProcessWithoutNullStreams;\n private _restarts = 0;\n\n constructor(private readonly _params: WatchDogParams) {}\n\n @synchronized\n async start() {\n const { cwd, shell, env, command, args } = { cwd: process.cwd(), ...this._params };\n\n this._log(`Spawning process \\`\\`\\`${command} ${args?.join(' ')}\\`\\`\\``);\n this._child = spawn(command, args, { cwd, shell, env, stdio: 'pipe' });\n\n this._child.stdout.on('data', (data: Uint8Array) => {\n this._log(String(data));\n });\n this._child.stderr.on('data', (data: Uint8Array) => {\n this._err(data);\n });\n this._child.on('close', async (code: number, signal: number | NodeJS.Signals) => {\n if (code && code !== 0 && signal !== 'SIGINT' && signal !== 'SIGKILL') {\n this._err(`Died unexpectedly with exit code ${code} (signal: ${signal}).`);\n await this.restart();\n }\n this._log(`Stopped with exit code ${code} (signal: ${signal}).`);\n if (existsSync(this._params.pidFile)) {\n unlinkSync(this._params.pidFile);\n }\n });\n\n const childInfo: ProcessInfo = {\n pid: this._child.pid,\n started: Date.now(),\n restarts: this._restarts,\n ...this._params,\n };\n\n writeFileSync(this._params.pidFile, JSON.stringify(childInfo, undefined, 2), { encoding: 'utf-8' });\n\n await waitForPidFileBeingFilledWithInfo(this._params.pidFile);\n }\n\n /**\n * Sends SIGKILL to the child process and the tree it spawned (if `killTree` param is `true`).\n */\n @synchronized\n async kill() {\n if (!this._child) {\n return;\n }\n\n await this._killWithSignal('SIGKILL');\n\n if (existsSync(this._params.pidFile)) {\n unlinkSync(this._params.pidFile);\n }\n\n await waitForPidDeletion(this._params.pidFile);\n }\n\n async restart() {\n await this.kill();\n if (this._params.maxRestarts !== undefined && this._restarts >= this._params.maxRestarts) {\n this._err('Max restarts number is reached');\n } else {\n log('Restarting...');\n this._restarts++;\n await this.start();\n }\n }\n\n async _killWithSignal(signal: number | NodeJS.Signals) {\n invariant(this._child?.pid, 'Child process has no pid.');\n this._child.kill(signal);\n this._child = undefined;\n }\n\n private _log(message: string | Uint8Array) {\n writeFileSync(this._params.logFile, message + '\\n', {\n flag: 'a+',\n encoding: 'utf-8',\n });\n }\n\n private _err(message: string | Uint8Array) {\n this._log(message);\n writeFileSync(this._params.errFile, message + '\\n', {\n flag: 'a+',\n encoding: 'utf-8',\n });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_node_fs", "WATCHDOG_START_TIMEOUT", "WATCHDOG_STOP_TIMEOUT", "WATCHDOG_CHECK_INTERVAL", "waitForPidDeletion", "pidFile", "waitForCondition", "condition", "existsSync", "timeout", "WATCHDOG_STOP_TIMEOUT", "interval", "WATCHDOG_CHECK_INTERVAL", "waitForPidFileBeingFilledWithInfo", "readFileSync", "encoding", "includes", "WATCHDOG_START_TIMEOUT", "error", "Error", "Phoenix", "start", "params", "existsSync", "pidFile", "stop", "waitForPidDeletion", "logFile", "errFile", "forEach", "filename", "mkdirSync", "dirname", "recursive", "writeFileSync", "encoding", "watchdogPath", "join", "pkgUp", "sync", "cwd", "__dirname", "watchDog", "fork", "JSON", "stringify", "detached", "on", "code", "signal", "log", "error", "waitForPidFileBeingFilledWithInfo", "disconnect", "unref", "info", "force", "Error", "fileContent", "readFileSync", "includes", "pid", "parse", "process", "kill", "err", "invariant", "message", "name", "unlinkSync", "import_node_child_process", "import_node_fs", "import_async", "import_invariant", "import_log", "WatchDog", "constructor", "_params", "_restarts", "start", "cwd", "shell", "env", "command", "args", "process", "_log", "join", "_child", "spawn", "stdio", "stdout", "on", "data", "String", "stderr", "_err", "code", "signal", "restart", "existsSync", "pidFile", "unlinkSync", "childInfo", "pid", "started", "Date", "now", "restarts", "writeFileSync", "JSON", "stringify", "undefined", "encoding", "waitForPidFileBeingFilledWithInfo", "kill", "_killWithSignal", "waitForPidDeletion", "maxRestarts", "log", "invariant", "message", "logFile", "flag", "errFile", "synchronized"]
3
+ "sources": ["../../../src/index.ts", "../../../src/daemon-manager.ts", "../../../src/utils.ts", "../../../src/defs.ts", "../../../src/watchdog.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n// Inspired by https://github.com/foreversd/forever\n// Their copyright notice is included below.\n// Copyright (C) 2010 Charlie Robbins & the Contributors\n//\n\nexport * from './daemon-manager';\nexport * from './watchdog';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { fork } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, unlinkSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { invariant } from '@dxos/invariant';\nimport { LockFile } from '@dxos/lock-file';\nimport { log } from '@dxos/log';\n\nimport { waitForLockAcquisition, waitForLockFileBeingFilledWithInfo, waitForLockRelease } from './utils';\nimport { ChildParams, Logs, Lock, ProcessInfo, WatchDogParams } from './watchdog';\n\nconst LOCK_FILE_NAME = 'lockfile';\n\n/**\n * Params to start a daemon.\n * User have no control over the lock file.\n */\nexport type StartParams = ChildParams & Partial<Logs>;\n\nexport class DaemonManager {\n constructor(private readonly _rootPath: string) {\n if (!existsSync(join(_rootPath, 'profile'))) {\n mkdirSync(join(_rootPath, 'profile'), { recursive: true });\n }\n }\n\n private _getConfigFiles(uid: string): Logs & Lock {\n const defaultConfigDir = join(this._rootPath, 'profile', uid);\n if (!existsSync(defaultConfigDir)) {\n mkdirSync(defaultConfigDir, { recursive: true });\n }\n return {\n lockFile: join(defaultConfigDir, LOCK_FILE_NAME),\n logFile: join(defaultConfigDir, 'file.log'),\n errFile: join(defaultConfigDir, 'err.log'),\n };\n }\n\n async start(params: StartParams) {\n invariant(params.command, 'command is required');\n const watchDogParams: WatchDogParams = {\n ...this._getConfigFiles(params.uid),\n ...params,\n };\n\n {\n // Create log folders.\n mkdirSync(dirname(watchDogParams.logFile), { recursive: true });\n mkdirSync(dirname(watchDogParams.errFile), { recursive: true });\n }\n\n {\n // Clear stale lock file if process is not running.\n if (await LockFile.isLocked(watchDogParams.lockFile)) {\n throw new Error('Lock file is already locked.');\n }\n unlinkSync(watchDogParams.lockFile);\n }\n\n const watchdogPath = join(dirname(pkgUp.sync({ cwd: __dirname })!), 'bin', 'watchdog');\n\n const watchDog = fork(watchdogPath, [JSON.stringify(watchDogParams)], {\n detached: true,\n cwd: __dirname,\n });\n\n watchDog.on('exit', (code, signal) => {\n if (code && code !== 0) {\n log.error('Monitor died unexpectedly', { code, signal });\n }\n });\n\n await waitForLockAcquisition(watchDogParams.lockFile);\n await waitForLockFileBeingFilledWithInfo(watchDogParams.lockFile);\n\n watchDog.disconnect();\n watchDog.unref();\n\n return this.getInfo(params.uid);\n }\n\n async stop(uid: string, force?: boolean) {\n const lockFile = this._getConfigFiles(uid).lockFile;\n const processInfo = JSON.parse(readFileSync(lockFile, { encoding: 'utf-8' }));\n try {\n if (force) {\n process.kill(processInfo.pid, 'SIGKILL');\n } else {\n process.kill(processInfo.pid, 'SIGINT');\n }\n } catch (err) {\n invariant(err instanceof Error, 'Invalid error type.');\n if (!err.name.includes('ESRCH') && !err.message.includes('ESRCH')) {\n throw err;\n }\n }\n await waitForLockRelease(lockFile);\n\n return this.getInfo(uid);\n }\n\n async list(): Promise<ProcessInfo[]> {\n const uids = (await readdir(join(this._rootPath, 'profile'))).filter((uid) => !uid.startsWith('.'));\n\n return Promise.all(\n uids.map(async (uid) => {\n return this.getInfo(uid);\n }),\n );\n }\n\n async getInfo(uid: string): Promise<ProcessInfo> {\n const files = this._getConfigFiles(uid);\n\n let info: ProcessInfo = { running: await LockFile.isLocked(files.lockFile), uid, ...files };\n if (existsSync(files.lockFile)) {\n try {\n info = {\n ...info,\n ...JSON.parse(readFileSync(files.lockFile, { encoding: 'utf-8' })),\n };\n } catch (err) {}\n }\n\n return info;\n }\n\n async isRunning(uid: string): Promise<boolean> {\n const lockFile = this._getConfigFiles(uid).lockFile;\n return LockFile.isLocked(lockFile);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { readFileSync } from 'node:fs';\n\nimport { waitForCondition } from '@dxos/async';\nimport { LockFile } from '@dxos/lock-file';\n\nimport { LOCK_CHECK_INTERVAL, LOCK_TIMEOUT } from './defs';\n\nexport const waitForLockAcquisition = async (lockFile: string) =>\n waitForCondition({\n condition: async () => await LockFile.isLocked(lockFile),\n timeout: LOCK_TIMEOUT,\n interval: LOCK_CHECK_INTERVAL,\n error: new Error('Lock file is not being acquired.'),\n });\n\nexport const waitForLockFileBeingFilledWithInfo = async (lockFile: string) =>\n waitForCondition({\n condition: () => readFileSync(lockFile, { encoding: 'utf-8' }).includes('pid'),\n timeout: LOCK_TIMEOUT,\n interval: LOCK_CHECK_INTERVAL,\n error: new Error('Lock file is not being propagated with info.'),\n });\n\nexport const waitForLockRelease = async (lockFile: string) =>\n waitForCondition({\n condition: async () => !(await LockFile.isLocked(lockFile)),\n timeout: LOCK_TIMEOUT,\n interval: LOCK_CHECK_INTERVAL,\n error: new Error('Lock file is not being released.'),\n });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const LOCK_TIMEOUT = 1_000;\nexport const LOCK_CHECK_INTERVAL = 50;\nexport const DAEMON_START_TIMEOUT = 10_000;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport { writeFileSync } from 'node:fs';\nimport { FileHandle } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport psTree from 'ps-tree';\n\nimport { synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { LockFile } from '@dxos/lock-file';\nimport { log } from '@dxos/log';\n\nimport { waitForLockAcquisition, waitForLockRelease } from './utils';\n\nexport type DaemonInfo = {\n pid: number;\n command: string;\n args: string[];\n cwd: string;\n timestamp: number;\n};\n\nexport type ProcessInfo = WatchDogParams & {\n pid?: number;\n timestamp?: number;\n restarts?: number;\n running?: boolean;\n};\n\nexport type Lock = {\n lockFile: string; // Path to lock file\n};\n\nexport type Logs = {\n //\n // Log files and associated logging options for this instance\n //\n logFile: string; // Path to log output all logs\n errFile: string; // Path to log output from child stderr\n};\n\nexport type ChildParams = {\n uid: string; // Unique identifier for this instance\n\n //\n // Basic configuration options\n //\n maxRestarts?: number | undefined; // Sets the maximum number of times a given script should run\n killTree?: boolean | undefined; // Kills the entire child process tree on `exit`\n\n //\n // Command to spawn as well as options and other vars\n // (env, cwd, etc) to pass along\n //\n command?: string; // Binary to run (default: 'node')\n args?: string[] | undefined; // Additional arguments to pass to the script,\n\n //\n // More specific options to pass along to `child_process.spawn` which\n // will override anything passed to the `spawnWith` option\n //\n env?: NodeJS.ProcessEnv | undefined;\n cwd?: string | undefined;\n shell?: boolean | undefined;\n};\n\nexport type WatchDogParams = ChildParams & Lock & Logs;\n\nexport class WatchDog {\n private _lock?: FileHandle;\n private _child?: ChildProcessWithoutNullStreams;\n private _restarts = 0;\n private _processCtx?: Context;\n\n constructor(private readonly _params: WatchDogParams) {}\n\n @synchronized\n async start() {\n await this._acquireLock();\n this._log('Lock acquired.');\n const { cwd, shell, env, command, args } = { cwd: process.cwd(), ...this._params };\n invariant(command, 'Command is not defined.');\n\n this._log(`Spawning process ${command} ${args?.join(' ')}`);\n this._child = spawn(command, args, { cwd, shell, env, stdio: 'pipe' });\n this._processCtx = new Context();\n\n const childInfo: ProcessInfo = {\n pid: process.pid,\n timestamp: Date.now(),\n restarts: this._restarts,\n ...this._params,\n };\n\n writeFileSync(this._params.lockFile, JSON.stringify(childInfo, undefined, 2), { encoding: 'utf-8' });\n\n this._child.stdout.on('data', (data: Uint8Array) => {\n this._log(String(data));\n });\n this._child.stderr.on('data', (data: Uint8Array) => {\n this._err(data);\n });\n\n // Setup restart handler.\n {\n const restartHandler = async (code: number, signal: number | NodeJS.Signals) => {\n if (code && code !== 0) {\n this._err(`Died unexpectedly with exit code ${code} (signal: ${signal}).`);\n await this.restart();\n }\n };\n\n this._child.on('close', restartHandler);\n\n // We should unsubscribe from the event when the process is killed by us to not try to restart it.\n this._processCtx.onDispose(() => {\n this._child!.off('close', restartHandler);\n });\n }\n\n this._child.on('close', (code: number, signal: number | NodeJS.Signals) => {\n this._log(`Stopped with exit code ${code} (signal: ${signal}).`);\n });\n\n invariant(this._child.pid, 'Child process has no pid.');\n this._log(`Started with pid ${this._child.pid}.`);\n }\n\n /**\n * Sends SIGINT to the child process and the tree it spawned (if `killTree` param is `true`).\n */\n @synchronized\n async stop() {\n if (!this._child) {\n return;\n }\n\n await this._killWithSignal('SIGKILL');\n\n await this._releaseLock();\n }\n\n /**\n * Sends SIGKILL to the child process and the tree it spawned (if `killTree` param is `true`).\n */\n @synchronized\n async kill() {\n if (!this._child) {\n return;\n }\n\n await this._killWithSignal('SIGKILL');\n\n await this._releaseLock();\n }\n\n async restart() {\n await this.kill();\n if (this._params.maxRestarts !== undefined && this._restarts >= this._params.maxRestarts) {\n this._err('Max restarts number is reached');\n } else {\n log('Restarting...');\n this._restarts++;\n await this.start();\n }\n }\n\n async _killWithSignal(signal: number | NodeJS.Signals) {\n invariant(this._processCtx, 'Process context is not defined.');\n await this._processCtx.dispose();\n\n // Kill child process tree.\n if (this._params.killTree) {\n if (process.platform !== 'win32') {\n invariant(this._child?.pid, 'Child process has no pid.');\n const children = await promisify(psTree)(this._child.pid);\n children\n .map((p) => p.PID)\n .forEach((tpid) => {\n invariant(tpid, 'Process id is not defined.');\n process.kill(Number(tpid), signal);\n });\n }\n }\n\n invariant(this._child?.pid, 'Child process has no pid.');\n this._child.kill(signal);\n this._child = undefined;\n }\n\n private async _acquireLock() {\n if (await LockFile.isLocked(this._params.lockFile)) {\n throw new Error('Lock file is already locked.');\n }\n this._lock = await LockFile.acquire(this._params.lockFile);\n await waitForLockAcquisition(this._params.lockFile);\n }\n\n private async _releaseLock() {\n invariant(this._lock, 'Lock is not defined.');\n\n await LockFile.release(this._lock);\n await waitForLockRelease(this._params.lockFile);\n\n this._lock = undefined;\n }\n\n private _log(message: string | Uint8Array) {\n writeFileSync(this._params.logFile, message + '\\n', {\n flag: 'a+',\n encoding: 'utf-8',\n });\n }\n\n private _err(message: string | Uint8Array) {\n this._log(message);\n writeFileSync(this._params.errFile, message + '\\n', {\n flag: 'a+',\n encoding: 'utf-8',\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_node_fs", "import_lock_file", "LOCK_TIMEOUT", "LOCK_CHECK_INTERVAL", "waitForLockAcquisition", "lockFile", "waitForCondition", "condition", "LockFile", "isLocked", "timeout", "LOCK_TIMEOUT", "interval", "LOCK_CHECK_INTERVAL", "error", "Error", "waitForLockFileBeingFilledWithInfo", "readFileSync", "encoding", "includes", "waitForLockRelease", "LOCK_FILE_NAME", "DaemonManager", "constructor", "_rootPath", "existsSync", "join", "mkdirSync", "recursive", "_getConfigFiles", "uid", "defaultConfigDir", "lockFile", "logFile", "errFile", "start", "params", "invariant", "command", "watchDogParams", "dirname", "LockFile", "isLocked", "Error", "unlinkSync", "watchdogPath", "pkgUp", "sync", "cwd", "__dirname", "watchDog", "fork", "JSON", "stringify", "detached", "on", "code", "signal", "log", "error", "waitForLockAcquisition", "waitForLockFileBeingFilledWithInfo", "disconnect", "unref", "getInfo", "stop", "force", "processInfo", "parse", "readFileSync", "encoding", "process", "kill", "pid", "err", "name", "includes", "message", "waitForLockRelease", "list", "uids", "readdir", "filter", "startsWith", "Promise", "all", "map", "files", "info", "running", "isRunning", "import_node_child_process", "import_node_fs", "import_async", "import_invariant", "import_lock_file", "import_log", "WatchDog", "constructor", "_params", "_restarts", "start", "_acquireLock", "_log", "cwd", "shell", "env", "command", "args", "process", "invariant", "join", "_child", "spawn", "stdio", "_processCtx", "Context", "childInfo", "pid", "timestamp", "Date", "now", "restarts", "writeFileSync", "lockFile", "JSON", "stringify", "undefined", "encoding", "stdout", "on", "data", "String", "stderr", "_err", "restartHandler", "code", "signal", "restart", "onDispose", "off", "stop", "_killWithSignal", "_releaseLock", "kill", "maxRestarts", "log", "dispose", "killTree", "platform", "children", "promisify", "psTree", "map", "p", "PID", "forEach", "tpid", "Number", "LockFile", "isLocked", "Error", "_lock", "acquire", "waitForLockAcquisition", "release", "waitForLockRelease", "message", "logFile", "flag", "errFile", "synchronized"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/common/phoenix/src/defs.ts":{"bytes":1201,"imports":[],"format":"esm"},"packages/common/phoenix/src/utils.ts":{"bytes":3673,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/defs.ts","kind":"import-statement","original":"./defs"}],"format":"esm"},"packages/common/phoenix/src/phoenix.ts":{"bytes":10474,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/phoenix/src/watchdog.ts":{"bytes":14340,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/phoenix/src/index.ts":{"bytes":987,"imports":[{"path":"packages/common/phoenix/src/phoenix.ts","kind":"import-statement","original":"./phoenix"},{"path":"packages/common/phoenix/src/watchdog.ts","kind":"import-statement","original":"./watchdog"}],"format":"esm"}},"outputs":{"packages/common/phoenix/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":14468},"packages/common/phoenix/dist/lib/node/index.cjs":{"imports":[{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"node:path","kind":"require-call","external":true},{"path":"pkg-up","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/common/phoenix/src/index.ts","inputs":{"packages/common/phoenix/src/index.ts":{"bytesInOutput":147},"packages/common/phoenix/src/phoenix.ts":{"bytesInOutput":3063},"packages/common/phoenix/src/utils.ts":{"bytesInOutput":646},"packages/common/phoenix/src/defs.ts":{"bytesInOutput":101},"packages/common/phoenix/src/watchdog.ts":{"bytesInOutput":3933}},"bytes":9727}}}
1
+ {"inputs":{"packages/common/phoenix/src/defs.ts":{"bytes":844,"imports":[],"format":"esm"},"packages/common/phoenix/src/utils.ts":{"bytes":4044,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/lock-file","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/defs.ts","kind":"import-statement","original":"./defs"}],"format":"esm"},"packages/common/phoenix/src/daemon-manager.ts":{"bytes":15641,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/lock-file","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/phoenix/src/watchdog.ts":{"bytes":22416,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"ps-tree","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/lock-file","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/phoenix/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/phoenix/src/index.ts":{"bytes":1006,"imports":[{"path":"packages/common/phoenix/src/daemon-manager.ts","kind":"import-statement","original":"./daemon-manager"},{"path":"packages/common/phoenix/src/watchdog.ts","kind":"import-statement","original":"./watchdog"}],"format":"esm"}},"outputs":{"packages/common/phoenix/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":20862},"packages/common/phoenix/dist/lib/node/index.cjs":{"imports":[{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"node:fs/promises","kind":"require-call","external":true},{"path":"node:path","kind":"require-call","external":true},{"path":"pkg-up","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/lock-file","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/lock-file","kind":"require-call","external":true},{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:fs","kind":"require-call","external":true},{"path":"node:util","kind":"require-call","external":true},{"path":"ps-tree","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/context","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/lock-file","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/common/phoenix/src/index.ts","inputs":{"packages/common/phoenix/src/index.ts":{"bytesInOutput":159},"packages/common/phoenix/src/daemon-manager.ts":{"bytesInOutput":4716},"packages/common/phoenix/src/utils.ts":{"bytesInOutput":1027},"packages/common/phoenix/src/defs.ts":{"bytesInOutput":54},"packages/common/phoenix/src/watchdog.ts":{"bytesInOutput":6674}},"bytes":14487}}}
@@ -0,0 +1,17 @@
1
+ import { ChildParams, Logs, ProcessInfo } from './watchdog';
2
+ /**
3
+ * Params to start a daemon.
4
+ * User have no control over the lock file.
5
+ */
6
+ export type StartParams = ChildParams & Partial<Logs>;
7
+ export declare class DaemonManager {
8
+ private readonly _rootPath;
9
+ constructor(_rootPath: string);
10
+ private _getConfigFiles;
11
+ start(params: StartParams): Promise<ProcessInfo>;
12
+ stop(uid: string, force?: boolean): Promise<ProcessInfo>;
13
+ list(): Promise<ProcessInfo[]>;
14
+ getInfo(uid: string): Promise<ProcessInfo>;
15
+ isRunning(uid: string): Promise<boolean>;
16
+ }
17
+ //# sourceMappingURL=daemon-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-manager.d.ts","sourceRoot":"","sources":["../../../src/daemon-manager.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,IAAI,EAAQ,WAAW,EAAkB,MAAM,YAAY,CAAC;AAIlF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtD,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAM9C,OAAO,CAAC,eAAe;IAYjB,KAAK,CAAC,MAAM,EAAE,WAAW;IA2CzB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;IAoBjC,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAU9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAgB1C,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAI/C"}