@teambit/ipc-events 1.0.1224 → 1.0.1225

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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * an install that runs longer than this is assumed to be hung (or its marker left behind by a process whose pid
3
+ * got reused), so other processes stop waiting for it.
4
+ */
5
+ export declare const INSTALL_MARKER_MAX_AGE_MS: number;
6
+ export type InstallMarker = {
7
+ pid: number;
8
+ startedAt: number;
9
+ };
10
+ export declare function getInstallMarkerPath(scopePath: string): string;
11
+ export declare function writeInstallMarker(scopePath: string): Promise<void>;
12
+ /**
13
+ * removes the marker only when this process wrote it, so a process that finishes after another one started
14
+ * installing doesn't hide the other install.
15
+ */
16
+ export declare function removeInstallMarker(scopePath: string): Promise<void>;
17
+ /**
18
+ * returns the marker of an install that is currently running in a *different* process, or undefined.
19
+ * the marker is ignored when it can't be trusted: the process that wrote it is gone (crashed or killed before
20
+ * removing it), it is older than INSTALL_MARKER_MAX_AGE_MS, or it is unreadable. so a failed install can never
21
+ * leave other processes waiting for it indefinitely.
22
+ */
23
+ export declare function getInstallRunningElsewhere(scopePath: string, isAlive?: (pid: number) => boolean): Promise<InstallMarker | undefined>;
24
+ /**
25
+ * resolves once no install runs in another process. returns the marker of the install it waited for, if any.
26
+ */
27
+ export declare function waitForInstallRunningElsewhere(scopePath: string, pollMs?: number, isAlive?: (pid: number) => boolean): Promise<InstallMarker | undefined>;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.INSTALL_MARKER_MAX_AGE_MS = void 0;
7
+ exports.getInstallMarkerPath = getInstallMarkerPath;
8
+ exports.getInstallRunningElsewhere = getInstallRunningElsewhere;
9
+ exports.removeInstallMarker = removeInstallMarker;
10
+ exports.waitForInstallRunningElsewhere = waitForInstallRunningElsewhere;
11
+ exports.writeInstallMarker = writeInstallMarker;
12
+ function _path() {
13
+ const data = _interopRequireDefault(require("path"));
14
+ _path = function () {
15
+ return data;
16
+ };
17
+ return data;
18
+ }
19
+ function _fsExtra() {
20
+ const data = _interopRequireDefault(require("fs-extra"));
21
+ _fsExtra = function () {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
+ /**
28
+ * an install that runs longer than this is assumed to be hung (or its marker left behind by a process whose pid
29
+ * got reused), so other processes stop waiting for it.
30
+ */
31
+ const INSTALL_MARKER_MAX_AGE_MS = exports.INSTALL_MARKER_MAX_AGE_MS = 30 * 60 * 1000;
32
+ const POLL_MS = 2000;
33
+ function getInstallMarkerPath(scopePath) {
34
+ return _path().default.join(scopePath, 'install-in-progress.json');
35
+ }
36
+ async function writeInstallMarker(scopePath) {
37
+ const marker = {
38
+ pid: process.pid,
39
+ startedAt: Date.now()
40
+ };
41
+ const markerPath = getInstallMarkerPath(scopePath);
42
+ // write-then-rename, so a reader never sees a half-written marker (which it would take as "no install")
43
+ const tmpPath = `${markerPath}.${process.pid}.tmp`;
44
+ await _fsExtra().default.outputJson(tmpPath, marker);
45
+ await _fsExtra().default.rename(tmpPath, markerPath);
46
+ }
47
+
48
+ /**
49
+ * removes the marker only when this process wrote it, so a process that finishes after another one started
50
+ * installing doesn't hide the other install.
51
+ */
52
+ async function removeInstallMarker(scopePath) {
53
+ const marker = await readInstallMarker(scopePath);
54
+ if (marker && marker.pid !== process.pid) return;
55
+ await _fsExtra().default.remove(getInstallMarkerPath(scopePath));
56
+ }
57
+
58
+ /**
59
+ * returns the marker of an install that is currently running in a *different* process, or undefined.
60
+ * the marker is ignored when it can't be trusted: the process that wrote it is gone (crashed or killed before
61
+ * removing it), it is older than INSTALL_MARKER_MAX_AGE_MS, or it is unreadable. so a failed install can never
62
+ * leave other processes waiting for it indefinitely.
63
+ */
64
+ async function getInstallRunningElsewhere(scopePath, isAlive = isProcessAlive) {
65
+ const marker = await readInstallMarker(scopePath);
66
+ if (!marker) return undefined;
67
+ if (marker.pid === process.pid) return undefined; // the in-process install is tracked by workspace.inInstallContext
68
+ // abs: a marker "from the future" (e.g. the clock moved back) shouldn't hold others for longer than the max age
69
+ if (Math.abs(Date.now() - marker.startedAt) > INSTALL_MARKER_MAX_AGE_MS) return undefined;
70
+ if (!isAlive(marker.pid)) return undefined;
71
+ return marker;
72
+ }
73
+
74
+ /**
75
+ * resolves once no install runs in another process. returns the marker of the install it waited for, if any.
76
+ */
77
+ async function waitForInstallRunningElsewhere(scopePath, pollMs = POLL_MS, isAlive) {
78
+ const waitedFor = await getInstallRunningElsewhere(scopePath, isAlive);
79
+ let running = waitedFor;
80
+ while (running) {
81
+ await new Promise(resolve => setTimeout(resolve, pollMs));
82
+ running = await getInstallRunningElsewhere(scopePath, isAlive);
83
+ }
84
+ return waitedFor;
85
+ }
86
+ async function readInstallMarker(scopePath) {
87
+ try {
88
+ const marker = await _fsExtra().default.readJson(getInstallMarkerPath(scopePath));
89
+ if (typeof marker?.pid !== 'number' || typeof marker?.startedAt !== 'number') return undefined;
90
+ return marker;
91
+ } catch {
92
+ return undefined; // missing, or not written by bit
93
+ }
94
+ }
95
+ function isProcessAlive(pid) {
96
+ try {
97
+ process.kill(pid, 0);
98
+ return true;
99
+ } catch (err) {
100
+ // EPERM: the process exists but belongs to another user
101
+ return err.code === 'EPERM';
102
+ }
103
+ }
104
+
105
+ //# sourceMappingURL=install-marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_path","data","_interopRequireDefault","require","_fsExtra","e","__esModule","default","INSTALL_MARKER_MAX_AGE_MS","exports","POLL_MS","getInstallMarkerPath","scopePath","path","join","writeInstallMarker","marker","pid","process","startedAt","Date","now","markerPath","tmpPath","fs","outputJson","rename","removeInstallMarker","readInstallMarker","remove","getInstallRunningElsewhere","isAlive","isProcessAlive","undefined","Math","abs","waitForInstallRunningElsewhere","pollMs","waitedFor","running","Promise","resolve","setTimeout","readJson","kill","err","code"],"sources":["install-marker.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\n\n/**\n * an install that runs longer than this is assumed to be hung (or its marker left behind by a process whose pid\n * got reused), so other processes stop waiting for it.\n */\nexport const INSTALL_MARKER_MAX_AGE_MS = 30 * 60 * 1000;\n\nconst POLL_MS = 2000;\n\nexport type InstallMarker = { pid: number; startedAt: number };\n\nexport function getInstallMarkerPath(scopePath: string): string {\n return path.join(scopePath, 'install-in-progress.json');\n}\n\nexport async function writeInstallMarker(scopePath: string): Promise<void> {\n const marker: InstallMarker = { pid: process.pid, startedAt: Date.now() };\n const markerPath = getInstallMarkerPath(scopePath);\n // write-then-rename, so a reader never sees a half-written marker (which it would take as \"no install\")\n const tmpPath = `${markerPath}.${process.pid}.tmp`;\n await fs.outputJson(tmpPath, marker);\n await fs.rename(tmpPath, markerPath);\n}\n\n/**\n * removes the marker only when this process wrote it, so a process that finishes after another one started\n * installing doesn't hide the other install.\n */\nexport async function removeInstallMarker(scopePath: string): Promise<void> {\n const marker = await readInstallMarker(scopePath);\n if (marker && marker.pid !== process.pid) return;\n await fs.remove(getInstallMarkerPath(scopePath));\n}\n\n/**\n * returns the marker of an install that is currently running in a *different* process, or undefined.\n * the marker is ignored when it can't be trusted: the process that wrote it is gone (crashed or killed before\n * removing it), it is older than INSTALL_MARKER_MAX_AGE_MS, or it is unreadable. so a failed install can never\n * leave other processes waiting for it indefinitely.\n */\nexport async function getInstallRunningElsewhere(\n scopePath: string,\n isAlive: (pid: number) => boolean = isProcessAlive\n): Promise<InstallMarker | undefined> {\n const marker = await readInstallMarker(scopePath);\n if (!marker) return undefined;\n if (marker.pid === process.pid) return undefined; // the in-process install is tracked by workspace.inInstallContext\n // abs: a marker \"from the future\" (e.g. the clock moved back) shouldn't hold others for longer than the max age\n if (Math.abs(Date.now() - marker.startedAt) > INSTALL_MARKER_MAX_AGE_MS) return undefined;\n if (!isAlive(marker.pid)) return undefined;\n return marker;\n}\n\n/**\n * resolves once no install runs in another process. returns the marker of the install it waited for, if any.\n */\nexport async function waitForInstallRunningElsewhere(\n scopePath: string,\n pollMs = POLL_MS,\n isAlive?: (pid: number) => boolean\n): Promise<InstallMarker | undefined> {\n const waitedFor = await getInstallRunningElsewhere(scopePath, isAlive);\n let running = waitedFor;\n while (running) {\n await new Promise((resolve) => setTimeout(resolve, pollMs));\n running = await getInstallRunningElsewhere(scopePath, isAlive);\n }\n return waitedFor;\n}\n\nasync function readInstallMarker(scopePath: string): Promise<InstallMarker | undefined> {\n try {\n const marker = await fs.readJson(getInstallMarkerPath(scopePath));\n if (typeof marker?.pid !== 'number' || typeof marker?.startedAt !== 'number') return undefined;\n return marker;\n } catch {\n return undefined; // missing, or not written by bit\n }\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err: any) {\n // EPERM: the process exists but belongs to another user\n return err.code === 'EPERM';\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+
3
+ function _chai() {
4
+ const data = require("chai");
5
+ _chai = function () {
6
+ return data;
7
+ };
8
+ return data;
9
+ }
10
+ function _fsExtra() {
11
+ const data = _interopRequireDefault(require("fs-extra"));
12
+ _fsExtra = function () {
13
+ return data;
14
+ };
15
+ return data;
16
+ }
17
+ function _os() {
18
+ const data = _interopRequireDefault(require("os"));
19
+ _os = function () {
20
+ return data;
21
+ };
22
+ return data;
23
+ }
24
+ function _path() {
25
+ const data = _interopRequireDefault(require("path"));
26
+ _path = function () {
27
+ return data;
28
+ };
29
+ return data;
30
+ }
31
+ function _installMarker() {
32
+ const data = require("./install-marker");
33
+ _installMarker = function () {
34
+ return data;
35
+ };
36
+ return data;
37
+ }
38
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
39
+ describe('install marker', () => {
40
+ let scopePath;
41
+ const otherPid = process.pid + 1;
42
+ const alive = () => true;
43
+ const dead = () => false;
44
+ beforeEach(async () => {
45
+ scopePath = await _fsExtra().default.mkdtemp(_path().default.join(_os().default.tmpdir(), 'install-marker-'));
46
+ });
47
+ afterEach(async () => {
48
+ await _fsExtra().default.remove(scopePath);
49
+ });
50
+ async function writeMarkerOfAnotherProcess(startedAt = Date.now()) {
51
+ await _fsExtra().default.outputJson((0, _installMarker().getInstallMarkerPath)(scopePath), {
52
+ pid: otherPid,
53
+ startedAt
54
+ });
55
+ }
56
+ it('should report an install running in another process', async () => {
57
+ await writeMarkerOfAnotherProcess();
58
+ const marker = await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive);
59
+ (0, _chai().expect)(marker?.pid).to.equal(otherPid);
60
+ });
61
+ it('should report nothing when no install is running', async () => {
62
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive)).to.be.undefined;
63
+ });
64
+ it('should ignore the install of the current process', async () => {
65
+ await (0, _installMarker().writeInstallMarker)(scopePath);
66
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive)).to.be.undefined;
67
+ });
68
+ it('should ignore a marker left behind by a process that is gone (e.g. a crashed or killed install)', async () => {
69
+ await writeMarkerOfAnotherProcess();
70
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, dead)).to.be.undefined;
71
+ });
72
+ it('should ignore a marker older than the max age, even when its process looks alive (hung install, reused pid)', async () => {
73
+ const startedAt = Date.now() - _installMarker().INSTALL_MARKER_MAX_AGE_MS - 1;
74
+ await writeMarkerOfAnotherProcess(startedAt);
75
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive)).to.be.undefined;
76
+ });
77
+ it('should ignore a marker with a start time far in the future (e.g. the clock moved back)', async () => {
78
+ await writeMarkerOfAnotherProcess(Date.now() + _installMarker().INSTALL_MARKER_MAX_AGE_MS + 60_000);
79
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive)).to.be.undefined;
80
+ });
81
+ it('should ignore a corrupted marker', async () => {
82
+ await _fsExtra().default.outputFile((0, _installMarker().getInstallMarkerPath)(scopePath), '{"pid": ');
83
+ (0, _chai().expect)(await (0, _installMarker().getInstallRunningElsewhere)(scopePath, alive)).to.be.undefined;
84
+ });
85
+ it('should treat the parent process as alive with the default liveness check', async () => {
86
+ await _fsExtra().default.outputJson((0, _installMarker().getInstallMarkerPath)(scopePath), {
87
+ pid: process.ppid,
88
+ startedAt: Date.now()
89
+ });
90
+ (0, _chai().expect)((await (0, _installMarker().getInstallRunningElsewhere)(scopePath))?.pid).to.equal(process.ppid);
91
+ });
92
+ it('should remove the marker it wrote', async () => {
93
+ await (0, _installMarker().writeInstallMarker)(scopePath);
94
+ await (0, _installMarker().removeInstallMarker)(scopePath);
95
+ (0, _chai().expect)(await _fsExtra().default.pathExists((0, _installMarker().getInstallMarkerPath)(scopePath))).to.be.false;
96
+ });
97
+ it('should not remove the marker of an install another process started meanwhile', async () => {
98
+ await writeMarkerOfAnotherProcess();
99
+ await (0, _installMarker().removeInstallMarker)(scopePath);
100
+ (0, _chai().expect)(await _fsExtra().default.pathExists((0, _installMarker().getInstallMarkerPath)(scopePath))).to.be.true;
101
+ });
102
+ it('should not wait when no install runs elsewhere', async () => {
103
+ (0, _chai().expect)(await (0, _installMarker().waitForInstallRunningElsewhere)(scopePath, 1, alive)).to.be.undefined;
104
+ });
105
+ it('should wait until the install elsewhere removes its marker', async () => {
106
+ await writeMarkerOfAnotherProcess();
107
+ let resolved = false;
108
+ const waiting = (0, _installMarker().waitForInstallRunningElsewhere)(scopePath, 5, alive).then(marker => {
109
+ resolved = true;
110
+ return marker;
111
+ });
112
+ await new Promise(resolve => setTimeout(resolve, 30));
113
+ (0, _chai().expect)(resolved).to.be.false;
114
+ await _fsExtra().default.remove((0, _installMarker().getInstallMarkerPath)(scopePath));
115
+ (0, _chai().expect)((await waiting)?.pid).to.equal(otherPid);
116
+ });
117
+ it('should stop waiting when the installing process is gone without removing its marker', async () => {
118
+ await writeMarkerOfAnotherProcess();
119
+ let isInstallerAlive = true;
120
+ const waiting = (0, _installMarker().waitForInstallRunningElsewhere)(scopePath, 5, () => isInstallerAlive);
121
+ await new Promise(resolve => setTimeout(resolve, 30));
122
+ isInstallerAlive = false; // e.g. "kill -9" of the install
123
+ (0, _chai().expect)((await waiting)?.pid).to.equal(otherPid);
124
+ (0, _chai().expect)(await _fsExtra().default.pathExists((0, _installMarker().getInstallMarkerPath)(scopePath))).to.be.true;
125
+ });
126
+ });
127
+
128
+ //# sourceMappingURL=install-marker.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_chai","data","require","_fsExtra","_interopRequireDefault","_os","_path","_installMarker","e","__esModule","default","describe","scopePath","otherPid","process","pid","alive","dead","beforeEach","fs","mkdtemp","path","join","os","tmpdir","afterEach","remove","writeMarkerOfAnotherProcess","startedAt","Date","now","outputJson","getInstallMarkerPath","it","marker","getInstallRunningElsewhere","expect","to","equal","be","undefined","writeInstallMarker","INSTALL_MARKER_MAX_AGE_MS","outputFile","ppid","removeInstallMarker","pathExists","false","true","waitForInstallRunningElsewhere","resolved","waiting","then","Promise","resolve","setTimeout","isInstallerAlive"],"sources":["install-marker.spec.ts"],"sourcesContent":["import { expect } from 'chai';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport path from 'path';\nimport {\n INSTALL_MARKER_MAX_AGE_MS,\n getInstallMarkerPath,\n getInstallRunningElsewhere,\n removeInstallMarker,\n waitForInstallRunningElsewhere,\n writeInstallMarker,\n} from './install-marker';\n\ndescribe('install marker', () => {\n let scopePath: string;\n const otherPid = process.pid + 1;\n const alive = () => true;\n const dead = () => false;\n\n beforeEach(async () => {\n scopePath = await fs.mkdtemp(path.join(os.tmpdir(), 'install-marker-'));\n });\n afterEach(async () => {\n await fs.remove(scopePath);\n });\n\n async function writeMarkerOfAnotherProcess(startedAt = Date.now()) {\n await fs.outputJson(getInstallMarkerPath(scopePath), { pid: otherPid, startedAt });\n }\n\n it('should report an install running in another process', async () => {\n await writeMarkerOfAnotherProcess();\n const marker = await getInstallRunningElsewhere(scopePath, alive);\n expect(marker?.pid).to.equal(otherPid);\n });\n\n it('should report nothing when no install is running', async () => {\n expect(await getInstallRunningElsewhere(scopePath, alive)).to.be.undefined;\n });\n\n it('should ignore the install of the current process', async () => {\n await writeInstallMarker(scopePath);\n expect(await getInstallRunningElsewhere(scopePath, alive)).to.be.undefined;\n });\n\n it('should ignore a marker left behind by a process that is gone (e.g. a crashed or killed install)', async () => {\n await writeMarkerOfAnotherProcess();\n expect(await getInstallRunningElsewhere(scopePath, dead)).to.be.undefined;\n });\n\n it('should ignore a marker older than the max age, even when its process looks alive (hung install, reused pid)', async () => {\n const startedAt = Date.now() - INSTALL_MARKER_MAX_AGE_MS - 1;\n await writeMarkerOfAnotherProcess(startedAt);\n expect(await getInstallRunningElsewhere(scopePath, alive)).to.be.undefined;\n });\n\n it('should ignore a marker with a start time far in the future (e.g. the clock moved back)', async () => {\n await writeMarkerOfAnotherProcess(Date.now() + INSTALL_MARKER_MAX_AGE_MS + 60_000);\n expect(await getInstallRunningElsewhere(scopePath, alive)).to.be.undefined;\n });\n\n it('should ignore a corrupted marker', async () => {\n await fs.outputFile(getInstallMarkerPath(scopePath), '{\"pid\": ');\n expect(await getInstallRunningElsewhere(scopePath, alive)).to.be.undefined;\n });\n\n it('should treat the parent process as alive with the default liveness check', async () => {\n await fs.outputJson(getInstallMarkerPath(scopePath), { pid: process.ppid, startedAt: Date.now() });\n expect((await getInstallRunningElsewhere(scopePath))?.pid).to.equal(process.ppid);\n });\n\n it('should remove the marker it wrote', async () => {\n await writeInstallMarker(scopePath);\n await removeInstallMarker(scopePath);\n expect(await fs.pathExists(getInstallMarkerPath(scopePath))).to.be.false;\n });\n\n it('should not remove the marker of an install another process started meanwhile', async () => {\n await writeMarkerOfAnotherProcess();\n await removeInstallMarker(scopePath);\n expect(await fs.pathExists(getInstallMarkerPath(scopePath))).to.be.true;\n });\n\n it('should not wait when no install runs elsewhere', async () => {\n expect(await waitForInstallRunningElsewhere(scopePath, 1, alive)).to.be.undefined;\n });\n\n it('should wait until the install elsewhere removes its marker', async () => {\n await writeMarkerOfAnotherProcess();\n let resolved = false;\n const waiting = waitForInstallRunningElsewhere(scopePath, 5, alive).then((marker) => {\n resolved = true;\n return marker;\n });\n await new Promise((resolve) => setTimeout(resolve, 30));\n expect(resolved).to.be.false;\n await fs.remove(getInstallMarkerPath(scopePath));\n expect((await waiting)?.pid).to.equal(otherPid);\n });\n\n it('should stop waiting when the installing process is gone without removing its marker', async () => {\n await writeMarkerOfAnotherProcess();\n let isInstallerAlive = true;\n const waiting = waitForInstallRunningElsewhere(scopePath, 5, () => isInstallerAlive);\n await new Promise((resolve) => setTimeout(resolve, 30));\n isInstallerAlive = false; // e.g. \"kill -9\" of the install\n expect((await waiting)?.pid).to.equal(otherPid);\n expect(await fs.pathExists(getInstallMarkerPath(scopePath))).to.be.true;\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  import type { ScopeMain } from '@teambit/scope';
2
2
  import type { SlotRegistry } from '@teambit/harmony';
3
3
  import type { Logger, LoggerMain } from '@teambit/logger';
4
+ import type { InstallMarker } from './install-marker';
4
5
  type EventName = 'onPostInstall' | 'onPostObjectsPersist' | 'onNotifySSE';
5
6
  type GotEvent = (eventName: EventName) => Promise<void>;
6
7
  type GotEventSlot = SlotRegistry<GotEvent>;
@@ -41,6 +42,21 @@ export declare class IpcEventsMain {
41
42
  * and once they get it, they simply send a server-send-event to the clients.
42
43
  */
43
44
  publishIpcOnNotifySseEvent(event: string, data?: Record<string, any>): Promise<void>;
45
+ private installWait?;
46
+ /**
47
+ * an install replaces node_modules, including the injected copies of the workspace components that the compiler
48
+ * writes dists into. a long-running process (e.g. "bit server --compile", "bit watch") that compiles meanwhile writes
49
+ * into dirs the package manager is deleting, and the install fails (ENOTEMPTY). the install marks itself, so these
50
+ * processes can wait for it. unlike the "onPostInstall" event, this doesn't depend on the install succeeding: a
51
+ * marker whose process is gone is ignored.
52
+ */
53
+ markInstallStarted(): Promise<void>;
54
+ markInstallEnded(): Promise<void>;
55
+ getInstallRunningElsewhere(): Promise<InstallMarker | undefined>;
56
+ /**
57
+ * resolves once no install runs in another process. concurrent callers share a single wait.
58
+ */
59
+ waitForInstallRunningElsewhere(): Promise<InstallMarker | undefined>;
44
60
  get eventsDir(): string;
45
61
  static slots: ((registerFn: () => string) => SlotRegistry<GotEventSlot>)[];
46
62
  static dependencies: import("@teambit/harmony").Aspect[];
@@ -60,6 +60,13 @@ function _ipcEvents() {
60
60
  };
61
61
  return data;
62
62
  }
63
+ function _installMarker() {
64
+ const data = require("./install-marker");
65
+ _installMarker = function () {
66
+ return data;
67
+ };
68
+ return data;
69
+ }
63
70
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
64
71
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
65
72
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -86,6 +93,7 @@ class IpcEventsMain {
86
93
  this.scope = scope;
87
94
  this.gotEventSlot = gotEventSlot;
88
95
  this.logger = logger;
96
+ _defineProperty(this, "installWait", void 0);
89
97
  }
90
98
  registerGotEventSlot(fn) {
91
99
  this.gotEventSlot.register(fn);
@@ -121,6 +129,32 @@ class IpcEventsMain {
121
129
  data
122
130
  });
123
131
  }
132
+ /**
133
+ * an install replaces node_modules, including the injected copies of the workspace components that the compiler
134
+ * writes dists into. a long-running process (e.g. "bit server --compile", "bit watch") that compiles meanwhile writes
135
+ * into dirs the package manager is deleting, and the install fails (ENOTEMPTY). the install marks itself, so these
136
+ * processes can wait for it. unlike the "onPostInstall" event, this doesn't depend on the install succeeding: a
137
+ * marker whose process is gone is ignored.
138
+ */
139
+ async markInstallStarted() {
140
+ await (0, _installMarker().writeInstallMarker)(this.scope.path);
141
+ }
142
+ async markInstallEnded() {
143
+ await (0, _installMarker().removeInstallMarker)(this.scope.path);
144
+ }
145
+ async getInstallRunningElsewhere() {
146
+ return (0, _installMarker().getInstallRunningElsewhere)(this.scope.path);
147
+ }
148
+
149
+ /**
150
+ * resolves once no install runs in another process. concurrent callers share a single wait.
151
+ */
152
+ async waitForInstallRunningElsewhere() {
153
+ this.installWait ??= (0, _installMarker().waitForInstallRunningElsewhere)(this.scope.path).finally(() => {
154
+ this.installWait = undefined;
155
+ });
156
+ return this.installWait;
157
+ }
124
158
  get eventsDir() {
125
159
  return _path().default.join(this.scope.path, EVENTS_DIR);
126
160
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_scope","data","require","_harmony","_logger","_pMapSeries","_interopRequireDefault","_harmonyModules","_path","_fsExtra","_ipcEvents","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","EVENTS_DIR","IpcEventsMain","constructor","scope","gotEventSlot","logger","registerGotEventSlot","fn","register","triggerGotEvent","eventName","info","pMapSeries","values","publishIpcEvent","filename","path","join","eventsDir","content","JSON","stringify","undefined","fs","outputFile","publishIpcOnNotifySseEvent","event","provider","loggerMain","_","createLogger","IpcEventsAspect","id","ipcEventsMain","registerOnPostObjectsPersist","debug","legacyScope","objects","clearObjectsFromCache","setStagedSnaps","exports","Slot","withType","ScopeAspect","LoggerAspect","MainRuntime","addRuntime","_default"],"sources":["ipc-events.main.runtime.ts"],"sourcesContent":["import type { ScopeMain } from '@teambit/scope';\nimport { ScopeAspect } from '@teambit/scope';\nimport type { SlotRegistry } from '@teambit/harmony';\nimport { Slot } from '@teambit/harmony';\nimport type { Logger, LoggerMain } from '@teambit/logger';\nimport { LoggerAspect } from '@teambit/logger';\nimport pMapSeries from 'p-map-series';\nimport { MainRuntime } from '@teambit/harmony.modules.runtimes';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { IpcEventsAspect } from './ipc-events.aspect';\n\ntype EventName = 'onPostInstall' | 'onPostObjectsPersist' | 'onNotifySSE';\n\ntype GotEvent = (eventName: EventName) => Promise<void>;\ntype GotEventSlot = SlotRegistry<GotEvent>;\n\nconst EVENTS_DIR = 'events';\n\n/**\n * You might have several processes running in the background (for example, bit watch, bit start, or bit server).\n * When the user runs `bit install`, these processes need to be notified that the installation has completed. One reason\n * is that \"bit start\" in the workspace could remove component-issues related to missing dependencies.\n *\n * To achieve this, an event file is written to the filesystem (e.g., .bit/events/<event-name>), and each background\n * process has a file watcher monitoring these event files. When an event file is created or updated, they can act upon it.\n *\n * For instance, when the user runs bit install, the “install” aspect calls publishIpcEvent, which writes\n * `.bit/events/onPostInstall`. The \"bit start\" process (along with others) detects the file change and invokes\n * `ipcEvents.triggerGotEvent()`. Any aspect subscribed to the gotEventSlot then runs its logic. In this example, the\n * installer aspect is subscribed, so when it recognizes the onPostInstall event, it triggers its own OnPostInstall slot.\n *\n * @see ./example-diagram.md for a visual representation of the above.\n */\nexport class IpcEventsMain {\n constructor(\n private scope: ScopeMain,\n private gotEventSlot: GotEventSlot,\n private logger: Logger\n ) {}\n\n registerGotEventSlot(fn: GotEvent) {\n this.gotEventSlot.register(fn);\n }\n\n /**\n * this gets called from the watcher only.\n * as soon as the watcher finds out that a new event has been written to the filesystem, it triggers this function\n */\n async triggerGotEvent(eventName: EventName) {\n this.logger.info(`triggering got event ${eventName}`);\n await pMapSeries(this.gotEventSlot.values(), (fn) => fn(eventName));\n }\n\n /**\n * write event data into the filesystem, so then other processes, such as \"bit start\", \"bit watch\", could use the\n * watcher to get the event data.\n */\n async publishIpcEvent(eventName: EventName, data?: Record<string, any>) {\n const filename = path.join(this.eventsDir, eventName);\n const content = data ? JSON.stringify(data, undefined, 2) : '';\n await fs.outputFile(filename, content);\n }\n\n /**\n * This is helpful when all we want is to notify the watchers that a new event has been written to the filesystem.\n * It doesn't require the watchers to register to GotEventSlot. The watchers always listen to this onNotifySSE event,\n * and once they get it, they simply send a server-send-event to the clients.\n */\n async publishIpcOnNotifySseEvent(event: string, data?: Record<string, any>) {\n await this.publishIpcEvent('onNotifySSE', { event, data });\n }\n\n get eventsDir() {\n return path.join(this.scope.path, EVENTS_DIR);\n }\n\n static slots = [Slot.withType<GotEventSlot>()];\n static dependencies = [ScopeAspect, LoggerAspect];\n static runtime = MainRuntime;\n\n static async provider([scope, loggerMain]: [ScopeMain, LoggerMain], _, [gotEventSlot]: [GotEventSlot]) {\n const logger = loggerMain.createLogger(IpcEventsAspect.id);\n const ipcEventsMain = new IpcEventsMain(scope, gotEventSlot, logger);\n\n if (scope) {\n // in case commands like \"bit export\" are running from the cli, long-running processes should clear their cache.\n // otherwise, objects like \"ModelComponent\" are out-of-date and could have the wrong head and the \"state\"/\"local\" data.\n scope.registerOnPostObjectsPersist(async () => {\n await ipcEventsMain.publishIpcEvent('onPostObjectsPersist');\n });\n ipcEventsMain.registerGotEventSlot(async (eventName) => {\n if (eventName === 'onPostObjectsPersist') {\n logger.debug('got an event onPostObjectsPersist, clearing the cache and reloading staged-snaps');\n scope.legacyScope.objects.clearObjectsFromCache();\n scope.legacyScope.setStagedSnaps(); // \"bit export\" deletes the staged-snaps file, so it should be reloaded\n }\n });\n }\n\n return ipcEventsMain;\n }\n}\n\nIpcEventsAspect.addRuntime(IpcEventsMain);\n\nexport default IpcEventsMain;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_scope","data","require","_harmony","_logger","_pMapSeries","_interopRequireDefault","_harmonyModules","_path","_fsExtra","_ipcEvents","_installMarker","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","EVENTS_DIR","IpcEventsMain","constructor","scope","gotEventSlot","logger","registerGotEventSlot","fn","register","triggerGotEvent","eventName","info","pMapSeries","values","publishIpcEvent","filename","path","join","eventsDir","content","JSON","stringify","undefined","fs","outputFile","publishIpcOnNotifySseEvent","event","markInstallStarted","writeInstallMarker","markInstallEnded","removeInstallMarker","getInstallRunningElsewhere","waitForInstallRunningElsewhere","installWait","finally","provider","loggerMain","_","createLogger","IpcEventsAspect","id","ipcEventsMain","registerOnPostObjectsPersist","debug","legacyScope","objects","clearObjectsFromCache","setStagedSnaps","exports","Slot","withType","ScopeAspect","LoggerAspect","MainRuntime","addRuntime","_default"],"sources":["ipc-events.main.runtime.ts"],"sourcesContent":["import type { ScopeMain } from '@teambit/scope';\nimport { ScopeAspect } from '@teambit/scope';\nimport type { SlotRegistry } from '@teambit/harmony';\nimport { Slot } from '@teambit/harmony';\nimport type { Logger, LoggerMain } from '@teambit/logger';\nimport { LoggerAspect } from '@teambit/logger';\nimport pMapSeries from 'p-map-series';\nimport { MainRuntime } from '@teambit/harmony.modules.runtimes';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { IpcEventsAspect } from './ipc-events.aspect';\nimport type { InstallMarker } from './install-marker';\nimport {\n getInstallRunningElsewhere,\n removeInstallMarker,\n waitForInstallRunningElsewhere,\n writeInstallMarker,\n} from './install-marker';\n\ntype EventName = 'onPostInstall' | 'onPostObjectsPersist' | 'onNotifySSE';\n\ntype GotEvent = (eventName: EventName) => Promise<void>;\ntype GotEventSlot = SlotRegistry<GotEvent>;\n\nconst EVENTS_DIR = 'events';\n\n/**\n * You might have several processes running in the background (for example, bit watch, bit start, or bit server).\n * When the user runs `bit install`, these processes need to be notified that the installation has completed. One reason\n * is that \"bit start\" in the workspace could remove component-issues related to missing dependencies.\n *\n * To achieve this, an event file is written to the filesystem (e.g., .bit/events/<event-name>), and each background\n * process has a file watcher monitoring these event files. When an event file is created or updated, they can act upon it.\n *\n * For instance, when the user runs bit install, the “install” aspect calls publishIpcEvent, which writes\n * `.bit/events/onPostInstall`. The \"bit start\" process (along with others) detects the file change and invokes\n * `ipcEvents.triggerGotEvent()`. Any aspect subscribed to the gotEventSlot then runs its logic. In this example, the\n * installer aspect is subscribed, so when it recognizes the onPostInstall event, it triggers its own OnPostInstall slot.\n *\n * @see ./example-diagram.md for a visual representation of the above.\n */\nexport class IpcEventsMain {\n constructor(\n private scope: ScopeMain,\n private gotEventSlot: GotEventSlot,\n private logger: Logger\n ) {}\n\n registerGotEventSlot(fn: GotEvent) {\n this.gotEventSlot.register(fn);\n }\n\n /**\n * this gets called from the watcher only.\n * as soon as the watcher finds out that a new event has been written to the filesystem, it triggers this function\n */\n async triggerGotEvent(eventName: EventName) {\n this.logger.info(`triggering got event ${eventName}`);\n await pMapSeries(this.gotEventSlot.values(), (fn) => fn(eventName));\n }\n\n /**\n * write event data into the filesystem, so then other processes, such as \"bit start\", \"bit watch\", could use the\n * watcher to get the event data.\n */\n async publishIpcEvent(eventName: EventName, data?: Record<string, any>) {\n const filename = path.join(this.eventsDir, eventName);\n const content = data ? JSON.stringify(data, undefined, 2) : '';\n await fs.outputFile(filename, content);\n }\n\n /**\n * This is helpful when all we want is to notify the watchers that a new event has been written to the filesystem.\n * It doesn't require the watchers to register to GotEventSlot. The watchers always listen to this onNotifySSE event,\n * and once they get it, they simply send a server-send-event to the clients.\n */\n async publishIpcOnNotifySseEvent(event: string, data?: Record<string, any>) {\n await this.publishIpcEvent('onNotifySSE', { event, data });\n }\n\n private installWait?: Promise<InstallMarker | undefined>;\n\n /**\n * an install replaces node_modules, including the injected copies of the workspace components that the compiler\n * writes dists into. a long-running process (e.g. \"bit server --compile\", \"bit watch\") that compiles meanwhile writes\n * into dirs the package manager is deleting, and the install fails (ENOTEMPTY). the install marks itself, so these\n * processes can wait for it. unlike the \"onPostInstall\" event, this doesn't depend on the install succeeding: a\n * marker whose process is gone is ignored.\n */\n async markInstallStarted() {\n await writeInstallMarker(this.scope.path);\n }\n\n async markInstallEnded() {\n await removeInstallMarker(this.scope.path);\n }\n\n async getInstallRunningElsewhere(): Promise<InstallMarker | undefined> {\n return getInstallRunningElsewhere(this.scope.path);\n }\n\n /**\n * resolves once no install runs in another process. concurrent callers share a single wait.\n */\n async waitForInstallRunningElsewhere(): Promise<InstallMarker | undefined> {\n this.installWait ??= waitForInstallRunningElsewhere(this.scope.path).finally(() => {\n this.installWait = undefined;\n });\n return this.installWait;\n }\n\n get eventsDir() {\n return path.join(this.scope.path, EVENTS_DIR);\n }\n\n static slots = [Slot.withType<GotEventSlot>()];\n static dependencies = [ScopeAspect, LoggerAspect];\n static runtime = MainRuntime;\n\n static async provider([scope, loggerMain]: [ScopeMain, LoggerMain], _, [gotEventSlot]: [GotEventSlot]) {\n const logger = loggerMain.createLogger(IpcEventsAspect.id);\n const ipcEventsMain = new IpcEventsMain(scope, gotEventSlot, logger);\n\n if (scope) {\n // in case commands like \"bit export\" are running from the cli, long-running processes should clear their cache.\n // otherwise, objects like \"ModelComponent\" are out-of-date and could have the wrong head and the \"state\"/\"local\" data.\n scope.registerOnPostObjectsPersist(async () => {\n await ipcEventsMain.publishIpcEvent('onPostObjectsPersist');\n });\n ipcEventsMain.registerGotEventSlot(async (eventName) => {\n if (eventName === 'onPostObjectsPersist') {\n logger.debug('got an event onPostObjectsPersist, clearing the cache and reloading staged-snaps');\n scope.legacyScope.objects.clearObjectsFromCache();\n scope.legacyScope.setStagedSnaps(); // \"bit export\" deletes the staged-snaps file, so it should be reloaded\n }\n });\n }\n\n return ipcEventsMain;\n }\n}\n\nIpcEventsAspect.addRuntime(IpcEventsMain);\n\nexport default IpcEventsMain;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/ipc-events",
3
- "version": "1.0.1224",
3
+ "version": "1.0.1225",
4
4
  "homepage": "https://bit.cloud/teambit/harmony/ipc-events",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.harmony",
8
8
  "name": "ipc-events",
9
- "version": "1.0.1224"
9
+ "version": "1.0.1225"
10
10
  },
11
11
  "dependencies": {
12
12
  "fs-extra": "10.0.0",
@@ -14,14 +14,16 @@
14
14
  "@teambit/harmony": "0.4.12",
15
15
  "@teambit/harmony.modules.runtimes": "0.0.4",
16
16
  "@teambit/logger": "0.0.1499",
17
- "@teambit/scope": "1.0.1224"
17
+ "@teambit/scope": "1.0.1225"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/fs-extra": "9.0.7",
21
21
  "@types/mocha": "9.1.0",
22
22
  "@teambit/harmony.envs.core-aspect-env": "2.1.2"
23
23
  },
24
- "peerDependencies": {},
24
+ "peerDependencies": {
25
+ "chai": "5.2.1"
26
+ },
25
27
  "license": "Apache-2.0",
26
28
  "optionalDependencies": {},
27
29
  "peerDependenciesMeta": {},