@dxos/phoenix 0.1.58-main.60c63b5 → 0.1.58-main.6b4aa57

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,115 +30,78 @@ 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
- DaemonManager: () => DaemonManager,
33
+ Phoenix: () => Phoenix,
34
34
  WatchDog: () => WatchDog
35
35
  });
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
38
- // packages/common/phoenix/src/daemon-manager.ts
38
+ // packages/common/phoenix/src/phoenix.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");
42
41
  var import_node_path = require("node:path");
43
42
  var import_pkg_up = __toESM(require("pkg-up"));
44
- var import_async2 = require("@dxos/async");
45
43
  var import_invariant = require("@dxos/invariant");
46
- var import_keys = require("@dxos/keys");
47
- var import_lock_file2 = require("@dxos/lock-file");
48
44
  var import_log = require("@dxos/log");
49
45
 
50
- // packages/common/phoenix/src/defs.ts
51
- var LOCK_TIMEOUT = 1e3;
52
- var LOCK_CHECK_INTERVAL = 50;
53
- var DAEMON_START_TIMEOUT = 1e4;
54
-
55
46
  // packages/common/phoenix/src/utils.ts
56
47
  var import_node_fs = require("node:fs");
57
48
  var import_async = require("@dxos/async");
58
- var import_lock_file = require("@dxos/lock-file");
59
- var waitForLockAcquisition = async (lockFile) => (0, import_async.waitForCondition)({
60
- condition: async () => await import_lock_file.LockFile.isLocked(lockFile),
61
- timeout: LOCK_TIMEOUT,
62
- interval: LOCK_CHECK_INTERVAL,
63
- error: new Error("Lock file is not being acquired.")
49
+
50
+ // 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
+
55
+ // 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
64
60
  });
65
- var waitForLockFileBeingFilledWithInfo = async (lockFile) => (0, import_async.waitForCondition)({
66
- condition: () => (0, import_node_fs.readFileSync)(lockFile, {
61
+ var waitForPidFileBeingFilledWithInfo = async (pidFile) => (0, import_async.waitForCondition)({
62
+ condition: () => (0, import_node_fs.readFileSync)(pidFile, {
67
63
  encoding: "utf-8"
68
64
  }).includes("pid"),
69
- timeout: LOCK_TIMEOUT,
70
- interval: LOCK_CHECK_INTERVAL,
65
+ timeout: WATCHDOG_START_TIMEOUT,
66
+ interval: WATCHDOG_CHECK_INTERVAL,
71
67
  error: new Error("Lock file is not being propagated with info.")
72
68
  });
73
- var waitForLockRelease = async (lockFile) => (0, import_async.waitForCondition)({
74
- condition: async () => !await import_lock_file.LockFile.isLocked(lockFile),
75
- timeout: LOCK_TIMEOUT,
76
- interval: LOCK_CHECK_INTERVAL,
77
- error: new Error("Lock file is not being released.")
78
- });
79
69
 
80
- // packages/common/phoenix/src/daemon-manager.ts
81
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/phoenix/src/daemon-manager.ts";
82
- var LOCK_FILE_NAME = "lockfile";
83
- var DaemonManager = class {
84
- constructor(_rootPath) {
85
- this._rootPath = _rootPath;
86
- if (!(0, import_node_fs2.existsSync)((0, import_node_path.join)(_rootPath, "profile"))) {
87
- (0, import_node_fs2.mkdirSync)((0, import_node_path.join)(_rootPath, "profile"), {
88
- recursive: true
89
- });
90
- }
91
- }
92
- _getConfigFiles(uid) {
93
- const defaultConfigDir = (0, import_node_path.join)(this._rootPath, "profile", uid);
94
- if (!(0, import_node_fs2.existsSync)(defaultConfigDir)) {
95
- (0, import_node_fs2.mkdirSync)(defaultConfigDir, {
96
- recursive: true
97
- });
98
- }
99
- return {
100
- lockFile: (0, import_node_path.join)(defaultConfigDir, LOCK_FILE_NAME),
101
- logFile: (0, import_node_path.join)(defaultConfigDir, "file.log"),
102
- errFile: (0, import_node_path.join)(defaultConfigDir, "err.log")
103
- };
104
- }
105
- async start(params) {
106
- (0, import_invariant.invariant)(params.command, "command is required", {
107
- F: __dxlog_file,
108
- L: 49,
109
- S: this,
110
- A: [
111
- "params.command",
112
- "'command is required'"
113
- ]
114
- });
115
- const watchdogId = import_keys.PublicKey.random().toHex();
116
- const watchDogParams = {
117
- watchdogId,
118
- ...this._getConfigFiles(params.uid),
119
- ...params
120
- };
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) {
121
77
  {
122
- (0, import_node_fs2.mkdirSync)((0, import_node_path.dirname)(watchDogParams.logFile), {
123
- recursive: true
124
- });
125
- (0, import_node_fs2.mkdirSync)((0, import_node_path.dirname)(watchDogParams.errFile), {
126
- recursive: true
127
- });
78
+ if ((0, import_node_fs2.existsSync)(params.pidFile)) {
79
+ await _Phoenix.stop(params.pidFile);
80
+ }
81
+ await waitForPidDeletion(params.pidFile);
128
82
  }
129
83
  {
130
- if (await import_lock_file2.LockFile.isLocked(watchDogParams.lockFile)) {
131
- throw new Error("Lock file is already locked.");
132
- }
133
- (0, import_node_fs2.unlinkSync)(watchDogParams.lockFile);
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
+ }
97
+ });
134
98
  }
135
99
  const watchdogPath = (0, import_node_path.join)((0, import_node_path.dirname)(import_pkg_up.default.sync({
136
100
  cwd: __dirname
137
101
  })), "bin", "watchdog");
138
102
  const watchDog = (0, import_node_child_process.fork)(watchdogPath, [
139
- JSON.stringify(watchDogParams)
103
+ JSON.stringify(params)
140
104
  ], {
141
- stdio: "pipe",
142
105
  detached: true,
143
106
  cwd: __dirname
144
107
  });
@@ -149,94 +112,63 @@ var DaemonManager = class {
149
112
  signal
150
113
  }, {
151
114
  F: __dxlog_file,
152
- L: 81,
115
+ L: 52,
153
116
  S: this,
154
117
  C: (f, a) => f(...a)
155
118
  });
156
119
  }
157
120
  });
158
- const started = new import_async2.Trigger();
159
- watchDog.stdout.on("data", (data) => {
160
- if (String(data).includes(watchdogId)) {
161
- started.wake();
162
- }
163
- });
164
- await (0, import_async2.asyncTimeout)(started.wait(), DAEMON_START_TIMEOUT);
165
- await waitForLockAcquisition(watchDogParams.lockFile);
166
- await waitForLockFileBeingFilledWithInfo(watchDogParams.lockFile);
121
+ await waitForPidFileBeingFilledWithInfo(params.pidFile);
167
122
  watchDog.disconnect();
168
123
  watchDog.unref();
169
- return this.getInfo(params.uid);
124
+ return _Phoenix.info(params.pidFile);
170
125
  }
171
- async stop(uid, force) {
172
- const lockFile = this._getConfigFiles(uid).lockFile;
173
- const processInfo = JSON.parse((0, import_node_fs2.readFileSync)(lockFile, {
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, {
174
134
  encoding: "utf-8"
175
- }));
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";
176
141
  try {
177
- if (force) {
178
- process.kill(processInfo.pid, "SIGKILL");
179
- } else {
180
- process.kill(processInfo.pid, "SIGINT");
181
- }
142
+ process.kill(pid, signal);
182
143
  } catch (err) {
183
- (0, import_invariant.invariant)(err instanceof Error, "Invalid error type.", {
144
+ (0, import_invariant.invariant)(err instanceof Error, "Invalid error type", {
184
145
  F: __dxlog_file,
185
- L: 112,
146
+ L: 81,
186
147
  S: this,
187
148
  A: [
188
149
  "err instanceof Error",
189
- "'Invalid error type.'"
150
+ "'Invalid error type'"
190
151
  ]
191
152
  });
192
- if (!err.name.includes("ESRCH") && !err.message.includes("ESRCH")) {
153
+ if (err.message.includes("ESRCH") || err.name.includes("ESRCH")) {
154
+ (0, import_node_fs2.unlinkSync)(pidFile);
155
+ } else {
193
156
  throw err;
194
157
  }
195
158
  }
196
- await waitForLockRelease(lockFile);
197
- return this.getInfo(uid);
198
159
  }
199
- async list() {
200
- const uids = await (0, import_promises.readdir)((0, import_node_path.join)(this._rootPath, "profile"));
201
- return Promise.all(uids.map(async (uid) => {
202
- return this.getInfo(uid);
160
+ static info(pidFile) {
161
+ return JSON.parse((0, import_node_fs2.readFileSync)(pidFile, {
162
+ encoding: "utf-8"
203
163
  }));
204
164
  }
205
- async getInfo(uid) {
206
- const files = this._getConfigFiles(uid);
207
- let info = {
208
- running: await import_lock_file2.LockFile.isLocked(files.lockFile),
209
- uid,
210
- ...files
211
- };
212
- if ((0, import_node_fs2.existsSync)(files.lockFile)) {
213
- try {
214
- info = {
215
- ...info,
216
- ...JSON.parse((0, import_node_fs2.readFileSync)(files.lockFile, {
217
- encoding: "utf-8"
218
- }))
219
- };
220
- } catch (err) {
221
- }
222
- }
223
- return info;
224
- }
225
- async isRunning(uid) {
226
- const lockFile = this._getConfigFiles(uid).lockFile;
227
- return import_lock_file2.LockFile.isLocked(lockFile);
228
- }
229
165
  };
230
166
 
231
167
  // packages/common/phoenix/src/watchdog.ts
232
168
  var import_node_child_process2 = require("node:child_process");
233
169
  var import_node_fs3 = require("node:fs");
234
- var import_node_util = require("node:util");
235
- var import_ps_tree = __toESM(require("ps-tree"));
236
- var import_async3 = require("@dxos/async");
237
- var import_context = require("@dxos/context");
170
+ var import_async2 = require("@dxos/async");
238
171
  var import_invariant2 = require("@dxos/invariant");
239
- var import_lock_file3 = require("@dxos/lock-file");
240
172
  var import_log2 = require("@dxos/log");
241
173
  function _ts_decorate(decorators, target, key, desc) {
242
174
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -255,79 +187,43 @@ var WatchDog = class {
255
187
  this._restarts = 0;
256
188
  }
257
189
  async start() {
258
- await this._acquireLock();
259
- this._log("Lock acquired.");
260
190
  const { cwd, shell, env, command, args } = {
261
191
  cwd: process.cwd(),
262
192
  ...this._params
263
193
  };
264
- (0, import_invariant2.invariant)(command, "Command is not defined.", {
265
- F: __dxlog_file2,
266
- L: 86,
267
- S: this,
268
- A: [
269
- "command",
270
- "'Command is not defined.'"
271
- ]
272
- });
273
- this._log(`Spawning process ${command} ${args?.join(" ")}`);
194
+ this._log(`Spawning process \`\`\`${command} ${args?.join(" ")}\`\`\``);
274
195
  this._child = (0, import_node_child_process2.spawn)(command, args, {
275
196
  cwd,
276
197
  shell,
277
198
  env,
278
199
  stdio: "pipe"
279
200
  });
280
- this._processCtx = new import_context.Context();
281
- const childInfo = {
282
- pid: process.pid,
283
- timestamp: Date.now(),
284
- restarts: this._restarts,
285
- ...this._params
286
- };
287
- (0, import_node_fs3.writeFileSync)(this._params.lockFile, JSON.stringify(childInfo, void 0, 2), {
288
- encoding: "utf-8"
289
- });
290
201
  this._child.stdout.on("data", (data) => {
291
202
  this._log(String(data));
292
203
  });
293
204
  this._child.stderr.on("data", (data) => {
294
205
  this._err(data);
295
206
  });
296
- {
297
- const restartHandler = async (code, signal) => {
298
- if (code && code !== 0) {
299
- this._err(`Died unexpectedly with exit code ${code} (signal: ${signal}).`);
300
- await this.restart();
301
- }
302
- };
303
- this._child.on("close", restartHandler);
304
- this._processCtx.onDispose(() => {
305
- this._child.off("close", restartHandler);
306
- });
307
- }
308
- this._child.on("close", (code, signal) => {
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
+ }
309
212
  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
+ }
310
216
  });
311
- (0, import_invariant2.invariant)(this._child.pid, "Child process has no pid.", {
312
- F: __dxlog_file2,
313
- L: 129,
314
- S: this,
315
- A: [
316
- "this._child.pid",
317
- "'Child process has no pid.'"
318
- ]
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"
319
225
  });
320
- this._log(`Started with pid ${this._child.pid}.`);
321
- }
322
- /**
323
- * Sends SIGINT to the child process and the tree it spawned (if `killTree` param is `true`).
324
- */
325
- async stop() {
326
- if (!this._child) {
327
- return;
328
- }
329
- await this._killWithSignal("SIGKILL");
330
- await this._releaseLock();
226
+ await waitForPidFileBeingFilledWithInfo(this._params.pidFile);
331
227
  }
332
228
  /**
333
229
  * Sends SIGKILL to the child process and the tree it spawned (if `killTree` param is `true`).
@@ -337,7 +233,10 @@ var WatchDog = class {
337
233
  return;
338
234
  }
339
235
  await this._killWithSignal("SIGKILL");
340
- await this._releaseLock();
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);
341
240
  }
342
241
  async restart() {
343
242
  await this.kill();
@@ -346,7 +245,7 @@ var WatchDog = class {
346
245
  } else {
347
246
  (0, import_log2.log)("Restarting...", void 0, {
348
247
  F: __dxlog_file2,
349
- L: 166,
248
+ L: 120,
350
249
  S: this,
351
250
  C: (f, a) => f(...a)
352
251
  });
@@ -355,45 +254,9 @@ var WatchDog = class {
355
254
  }
356
255
  }
357
256
  async _killWithSignal(signal) {
358
- (0, import_invariant2.invariant)(this._processCtx, "Process context is not defined.", {
359
- F: __dxlog_file2,
360
- L: 173,
361
- S: this,
362
- A: [
363
- "this._processCtx",
364
- "'Process context is not defined.'"
365
- ]
366
- });
367
- await this._processCtx.dispose();
368
- if (this._params.killTree) {
369
- if (process.platform !== "win32") {
370
- (0, import_invariant2.invariant)(this._child?.pid, "Child process has no pid.", {
371
- F: __dxlog_file2,
372
- L: 179,
373
- S: this,
374
- A: [
375
- "this._child?.pid",
376
- "'Child process has no pid.'"
377
- ]
378
- });
379
- const children = await (0, import_node_util.promisify)(import_ps_tree.default)(this._child.pid);
380
- children.map((p) => p.PID).forEach((tpid) => {
381
- (0, import_invariant2.invariant)(tpid, "Process id is not defined.", {
382
- F: __dxlog_file2,
383
- L: 184,
384
- S: this,
385
- A: [
386
- "tpid",
387
- "'Process id is not defined.'"
388
- ]
389
- });
390
- process.kill(Number(tpid), signal);
391
- });
392
- }
393
- }
394
257
  (0, import_invariant2.invariant)(this._child?.pid, "Child process has no pid.", {
395
258
  F: __dxlog_file2,
396
- L: 190,
259
+ L: 127,
397
260
  S: this,
398
261
  A: [
399
262
  "this._child?.pid",
@@ -403,27 +266,6 @@ var WatchDog = class {
403
266
  this._child.kill(signal);
404
267
  this._child = void 0;
405
268
  }
406
- async _acquireLock() {
407
- if (await import_lock_file3.LockFile.isLocked(this._params.lockFile)) {
408
- throw new Error("Lock file is already locked.");
409
- }
410
- this._lock = await import_lock_file3.LockFile.acquire(this._params.lockFile);
411
- await waitForLockAcquisition(this._params.lockFile);
412
- }
413
- async _releaseLock() {
414
- (0, import_invariant2.invariant)(this._lock, "Lock is not defined.", {
415
- F: __dxlog_file2,
416
- L: 204,
417
- S: this,
418
- A: [
419
- "this._lock",
420
- "'Lock is not defined.'"
421
- ]
422
- });
423
- await import_lock_file3.LockFile.release(this._lock);
424
- await waitForLockRelease(this._params.lockFile);
425
- this._lock = void 0;
426
- }
427
269
  _log(message) {
428
270
  (0, import_node_fs3.writeFileSync)(this._params.logFile, message + "\n", {
429
271
  flag: "a+",
@@ -439,17 +281,14 @@ var WatchDog = class {
439
281
  }
440
282
  };
441
283
  _ts_decorate([
442
- import_async3.synchronized
284
+ import_async2.synchronized
443
285
  ], WatchDog.prototype, "start", null);
444
286
  _ts_decorate([
445
- import_async3.synchronized
446
- ], WatchDog.prototype, "stop", null);
447
- _ts_decorate([
448
- import_async3.synchronized
287
+ import_async2.synchronized
449
288
  ], WatchDog.prototype, "kill", null);
450
289
  // Annotate the CommonJS export names for ESM import in node:
451
290
  0 && (module.exports = {
452
- DaemonManager,
291
+ Phoenix,
453
292
  WatchDog
454
293
  });
455
294
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/index.ts", "../../../src/daemon-manager.ts", "../../../src/defs.ts", "../../../src/utils.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 { Trigger, asyncTimeout } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { LockFile } from '@dxos/lock-file';\nimport { log } from '@dxos/log';\n\nimport { DAEMON_START_TIMEOUT } from './defs';\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 watchdogId = PublicKey.random().toHex();\n const watchDogParams: WatchDogParams & { watchdogId: string } = {\n watchdogId,\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 stdio: 'pipe',\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 const started = new Trigger();\n watchDog.stdout!.on('data', (data) => {\n if (String(data).includes(watchdogId)) {\n started.wake();\n }\n });\n\n await asyncTimeout(started.wait(), DAEMON_START_TIMEOUT);\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'));\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\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 { 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\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_async", "import_lock_file", "LOCK_TIMEOUT", "LOCK_CHECK_INTERVAL", "DAEMON_START_TIMEOUT", "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", "watchdogId", "PublicKey", "random", "toHex", "watchDogParams", "dirname", "LockFile", "isLocked", "Error", "unlinkSync", "watchdogPath", "pkgUp", "sync", "cwd", "__dirname", "watchDog", "fork", "JSON", "stringify", "stdio", "detached", "on", "code", "signal", "log", "error", "started", "Trigger", "stdout", "data", "String", "includes", "wake", "asyncTimeout", "wait", "DAEMON_START_TIMEOUT", "waitForLockAcquisition", "waitForLockFileBeingFilledWithInfo", "disconnect", "unref", "getInfo", "stop", "force", "processInfo", "parse", "readFileSync", "encoding", "process", "kill", "pid", "err", "name", "message", "waitForLockRelease", "list", "uids", "readdir", "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"]
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"]
7
7
  }
@@ -1 +1 @@
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":17255,"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/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","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/defs.ts","kind":"import-statement","original":"./defs"},{"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":21757},"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/async","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/keys","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":5124},"packages/common/phoenix/src/defs.ts":{"bytesInOutput":86},"packages/common/phoenix/src/utils.ts":{"bytesInOutput":1027},"packages/common/phoenix/src/watchdog.ts":{"bytesInOutput":6674}},"bytes":14886}}}
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}}}