@teambit/workspace 0.0.755 → 0.0.758

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.
@@ -6,6 +6,14 @@ export declare class EnvsReplaceCmd implements Command {
6
6
  description: string;
7
7
  options: never[];
8
8
  group: string;
9
+ arguments: {
10
+ name: string;
11
+ description: string;
12
+ }[];
13
+ examples: {
14
+ cmd: string;
15
+ description: string;
16
+ }[];
9
17
  constructor(workspace: Workspace);
10
18
  report([oldEnv, env]: [string, string]): Promise<string>;
11
19
  }
@@ -38,6 +38,17 @@ class EnvsReplaceCmd {
38
38
  (0, _defineProperty2().default)(this, "description", 'replace an existing env with another env for all components using the old env');
39
39
  (0, _defineProperty2().default)(this, "options", []);
40
40
  (0, _defineProperty2().default)(this, "group", 'development');
41
+ (0, _defineProperty2().default)(this, "arguments", [{
42
+ name: 'old-env',
43
+ description: 'current environment id'
44
+ }, {
45
+ name: 'new-env',
46
+ description: 'target environment id'
47
+ }]);
48
+ (0, _defineProperty2().default)(this, "examples", [{
49
+ cmd: 'replace teambit.harmony/aspect teambit.harmony/node',
50
+ description: 'all components using aspect env, will be replaced with node env'
51
+ }]);
41
52
  }
42
53
 
43
54
  async report([oldEnv, env]) {
@@ -1 +1 @@
1
- {"version":3,"names":["EnvsReplaceCmd","constructor","workspace","report","oldEnv","env","envId","resolveComponentId","components","getComponentsUsingEnv","componentIds","map","comp","id","setEnvToComponents","chalk","bold","toString","compId","join"],"sources":["envs-replace.cmd.ts"],"sourcesContent":["import { Command } from '@teambit/cli';\nimport chalk from 'chalk';\nimport { Workspace } from '../workspace';\n\nexport class EnvsReplaceCmd implements Command {\n name = 'replace <old-env> <new-env>';\n description = 'replace an existing env with another env for all components using the old env';\n options = [];\n group = 'development';\n\n constructor(private workspace: Workspace) {}\n\n async report([oldEnv, env]: [string, string]) {\n const envId = await this.workspace.resolveComponentId(env);\n const components = await this.workspace.getComponentsUsingEnv(oldEnv, true, true);\n const componentIds = components.map((comp) => comp.id);\n await this.workspace.setEnvToComponents(envId, componentIds);\n return `added ${chalk.bold(envId.toString())} env to the following component(s):\n${componentIds.map((compId) => compId.toString()).join('\\n')}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAGO,MAAMA,cAAN,CAAwC;EAM7CC,WAAW,CAASC,SAAT,EAA+B;IAAA,KAAtBA,SAAsB,GAAtBA,SAAsB;IAAA,8CALnC,6BAKmC;IAAA,qDAJ5B,+EAI4B;IAAA,iDAHhC,EAGgC;IAAA,+CAFlC,aAEkC;EAAE;;EAEhC,MAANC,MAAM,CAAC,CAACC,MAAD,EAASC,GAAT,CAAD,EAAkC;IAC5C,MAAMC,KAAK,GAAG,MAAM,KAAKJ,SAAL,CAAeK,kBAAf,CAAkCF,GAAlC,CAApB;IACA,MAAMG,UAAU,GAAG,MAAM,KAAKN,SAAL,CAAeO,qBAAf,CAAqCL,MAArC,EAA6C,IAA7C,EAAmD,IAAnD,CAAzB;IACA,MAAMM,YAAY,GAAGF,UAAU,CAACG,GAAX,CAAgBC,IAAD,IAAUA,IAAI,CAACC,EAA9B,CAArB;IACA,MAAM,KAAKX,SAAL,CAAeY,kBAAf,CAAkCR,KAAlC,EAAyCI,YAAzC,CAAN;IACA,OAAQ,SAAQK,gBAAA,CAAMC,IAAN,CAAWV,KAAK,CAACW,QAAN,EAAX,CAA6B;AACjD,EAAEP,YAAY,CAACC,GAAb,CAAkBO,MAAD,IAAYA,MAAM,CAACD,QAAP,EAA7B,EAAgDE,IAAhD,CAAqD,IAArD,CAA2D,EADzD;EAED;;AAf4C"}
1
+ {"version":3,"names":["EnvsReplaceCmd","constructor","workspace","name","description","cmd","report","oldEnv","env","envId","resolveComponentId","components","getComponentsUsingEnv","componentIds","map","comp","id","setEnvToComponents","chalk","bold","toString","compId","join"],"sources":["envs-replace.cmd.ts"],"sourcesContent":["import { Command } from '@teambit/cli';\nimport chalk from 'chalk';\nimport { Workspace } from '../workspace';\n\nexport class EnvsReplaceCmd implements Command {\n name = 'replace <old-env> <new-env>';\n description = 'replace an existing env with another env for all components using the old env';\n options = [];\n group = 'development';\n arguments = [\n { name: 'old-env', description: 'current environment id' },\n { name: 'new-env', description: 'target environment id' },\n ];\n examples = [\n {\n cmd: 'replace teambit.harmony/aspect teambit.harmony/node',\n description: 'all components using aspect env, will be replaced with node env',\n },\n ];\n\n constructor(private workspace: Workspace) {}\n\n async report([oldEnv, env]: [string, string]) {\n const envId = await this.workspace.resolveComponentId(env);\n const components = await this.workspace.getComponentsUsingEnv(oldEnv, true, true);\n const componentIds = components.map((comp) => comp.id);\n await this.workspace.setEnvToComponents(envId, componentIds);\n return `added ${chalk.bold(envId.toString())} env to the following component(s):\n${componentIds.map((compId) => compId.toString()).join('\\n')}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAGO,MAAMA,cAAN,CAAwC;EAgB7CC,WAAW,CAASC,SAAT,EAA+B;IAAA,KAAtBA,SAAsB,GAAtBA,SAAsB;IAAA,8CAfnC,6BAemC;IAAA,qDAd5B,+EAc4B;IAAA,iDAbhC,EAagC;IAAA,+CAZlC,aAYkC;IAAA,mDAX9B,CACV;MAAEC,IAAI,EAAE,SAAR;MAAmBC,WAAW,EAAE;IAAhC,CADU,EAEV;MAAED,IAAI,EAAE,SAAR;MAAmBC,WAAW,EAAE;IAAhC,CAFU,CAW8B;IAAA,kDAP/B,CACT;MACEC,GAAG,EAAE,qDADP;MAEED,WAAW,EAAE;IAFf,CADS,CAO+B;EAAE;;EAEhC,MAANE,MAAM,CAAC,CAACC,MAAD,EAASC,GAAT,CAAD,EAAkC;IAC5C,MAAMC,KAAK,GAAG,MAAM,KAAKP,SAAL,CAAeQ,kBAAf,CAAkCF,GAAlC,CAApB;IACA,MAAMG,UAAU,GAAG,MAAM,KAAKT,SAAL,CAAeU,qBAAf,CAAqCL,MAArC,EAA6C,IAA7C,EAAmD,IAAnD,CAAzB;IACA,MAAMM,YAAY,GAAGF,UAAU,CAACG,GAAX,CAAgBC,IAAD,IAAUA,IAAI,CAACC,EAA9B,CAArB;IACA,MAAM,KAAKd,SAAL,CAAee,kBAAf,CAAkCR,KAAlC,EAAyCI,YAAzC,CAAN;IACA,OAAQ,SAAQK,gBAAA,CAAMC,IAAN,CAAWV,KAAK,CAACW,QAAN,EAAX,CAA6B;AACjD,EAAEP,YAAY,CAACC,GAAb,CAAkBO,MAAD,IAAYA,MAAM,CAACD,QAAP,EAA7B,EAAgDE,IAAhD,CAAqD,IAArD,CAA2D,EADzD;EAED;;AAzB4C"}
@@ -31,14 +31,27 @@ function _constants() {
31
31
  return data;
32
32
  }
33
33
 
34
+ function _chalk() {
35
+ const data = _interopRequireDefault(require("chalk"));
36
+
37
+ _chalk = function () {
38
+ return data;
39
+ };
40
+
41
+ return data;
42
+ }
43
+
34
44
  class EnvsUnsetCmd {
35
45
  constructor(workspace) {
36
46
  this.workspace = workspace;
37
- (0, _defineProperty2().default)(this, "name", 'unset <component>');
38
- (0, _defineProperty2().default)(this, "description", 'unset an environment from component(s)');
47
+ (0, _defineProperty2().default)(this, "name", 'unset <pattern>');
48
+ (0, _defineProperty2().default)(this, "description", 'unset an environment from component(s) that was set by "bit env set"');
39
49
  (0, _defineProperty2().default)(this, "options", []);
40
50
  (0, _defineProperty2().default)(this, "group", 'development');
41
- (0, _defineProperty2().default)(this, "extendedDescription", `${(0, _constants().PATTERN_HELP)('env unset')}`);
51
+ (0, _defineProperty2().default)(this, "extendedDescription", `keep in mind that this doesn't remove envs that are set in the variants.
52
+ in only removes envs that appear in the .bitmap file, which were previously configured via "bit env set".
53
+ the purpose of this command is to remove the specific settings and let the the variants in workspace.jsonc to control the env.
54
+ ${(0, _constants().PATTERN_HELP)('env unset')}`);
42
55
  }
43
56
 
44
57
  async report([pattern]) {
@@ -46,6 +59,11 @@ class EnvsUnsetCmd {
46
59
  const {
47
60
  changed
48
61
  } = await this.workspace.unsetEnvFromComponents(componentIds);
62
+
63
+ if (!changed.length) {
64
+ return _chalk().default.yellow(`unable to find any component matching the pattern with env configured in the .bitmap file`);
65
+ }
66
+
49
67
  return `successfully removed env from the following component(s):
50
68
  ${changed.map(id => id.toString()).join('\n')}`;
51
69
  }
@@ -1 +1 @@
1
- {"version":3,"names":["EnvsUnsetCmd","constructor","workspace","PATTERN_HELP","report","pattern","componentIds","idsByPattern","changed","unsetEnvFromComponents","map","id","toString","join"],"sources":["envs-unset.cmd.ts"],"sourcesContent":["import { Command } from '@teambit/cli';\nimport { PATTERN_HELP } from '@teambit/legacy/dist/constants';\nimport { Workspace } from '../workspace';\n\nexport class EnvsUnsetCmd implements Command {\n name = 'unset <component>';\n description = 'unset an environment from component(s)';\n options = [];\n group = 'development';\n extendedDescription = `${PATTERN_HELP('env unset')}`;\n\n constructor(private workspace: Workspace) {}\n\n async report([pattern]: [string]) {\n const componentIds = await this.workspace.idsByPattern(pattern);\n const { changed } = await this.workspace.unsetEnvFromComponents(componentIds);\n return `successfully removed env from the following component(s):\n${changed.map((id) => id.toString()).join('\\n')}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAGO,MAAMA,YAAN,CAAsC;EAO3CC,WAAW,CAASC,SAAT,EAA+B;IAAA,KAAtBA,SAAsB,GAAtBA,SAAsB;IAAA,8CANnC,mBAMmC;IAAA,qDAL5B,wCAK4B;IAAA,iDAJhC,EAIgC;IAAA,+CAHlC,aAGkC;IAAA,6DAFnB,GAAE,IAAAC,yBAAA,EAAa,WAAb,CAA0B,EAET;EAAE;;EAEhC,MAANC,MAAM,CAAC,CAACC,OAAD,CAAD,EAAsB;IAChC,MAAMC,YAAY,GAAG,MAAM,KAAKJ,SAAL,CAAeK,YAAf,CAA4BF,OAA5B,CAA3B;IACA,MAAM;MAAEG;IAAF,IAAc,MAAM,KAAKN,SAAL,CAAeO,sBAAf,CAAsCH,YAAtC,CAA1B;IACA,OAAQ;AACZ,EAAEE,OAAO,CAACE,GAAR,CAAaC,EAAD,IAAQA,EAAE,CAACC,QAAH,EAApB,EAAmCC,IAAnC,CAAwC,IAAxC,CAA8C,EAD5C;EAED;;AAd0C"}
1
+ {"version":3,"names":["EnvsUnsetCmd","constructor","workspace","PATTERN_HELP","report","pattern","componentIds","idsByPattern","changed","unsetEnvFromComponents","length","chalk","yellow","map","id","toString","join"],"sources":["envs-unset.cmd.ts"],"sourcesContent":["import { Command } from '@teambit/cli';\nimport { PATTERN_HELP } from '@teambit/legacy/dist/constants';\nimport chalk from 'chalk';\nimport { Workspace } from '../workspace';\n\nexport class EnvsUnsetCmd implements Command {\n name = 'unset <pattern>';\n description = 'unset an environment from component(s) that was set by \"bit env set\"';\n options = [];\n group = 'development';\n extendedDescription = `keep in mind that this doesn't remove envs that are set in the variants.\nin only removes envs that appear in the .bitmap file, which were previously configured via \"bit env set\".\nthe purpose of this command is to remove the specific settings and let the the variants in workspace.jsonc to control the env.\n${PATTERN_HELP('env unset')}`;\n\n constructor(private workspace: Workspace) {}\n\n async report([pattern]: [string]) {\n const componentIds = await this.workspace.idsByPattern(pattern);\n const { changed } = await this.workspace.unsetEnvFromComponents(componentIds);\n if (!changed.length) {\n return chalk.yellow(`unable to find any component matching the pattern with env configured in the .bitmap file`);\n }\n return `successfully removed env from the following component(s):\n${changed.map((id) => id.toString()).join('\\n')}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAGO,MAAMA,YAAN,CAAsC;EAU3CC,WAAW,CAASC,SAAT,EAA+B;IAAA,KAAtBA,SAAsB,GAAtBA,SAAsB;IAAA,8CATnC,iBASmC;IAAA,qDAR5B,sEAQ4B;IAAA,iDAPhC,EAOgC;IAAA,+CANlC,aAMkC;IAAA,6DALnB;AACzB;AACA;AACA,EAAE,IAAAC,yBAAA,EAAa,WAAb,CAA0B,EAEgB;EAAE;;EAEhC,MAANC,MAAM,CAAC,CAACC,OAAD,CAAD,EAAsB;IAChC,MAAMC,YAAY,GAAG,MAAM,KAAKJ,SAAL,CAAeK,YAAf,CAA4BF,OAA5B,CAA3B;IACA,MAAM;MAAEG;IAAF,IAAc,MAAM,KAAKN,SAAL,CAAeO,sBAAf,CAAsCH,YAAtC,CAA1B;;IACA,IAAI,CAACE,OAAO,CAACE,MAAb,EAAqB;MACnB,OAAOC,gBAAA,CAAMC,MAAN,CAAc,2FAAd,CAAP;IACD;;IACD,OAAQ;AACZ,EAAEJ,OAAO,CAACK,GAAR,CAAaC,EAAD,IAAQA,EAAE,CAACC,QAAH,EAApB,EAAmCC,IAAnC,CAAwC,IAAxC,CAA8C,EAD5C;EAED;;AApB0C"}
@@ -0,0 +1,8 @@
1
+ import PQueue from 'p-queue';
2
+ export declare class WatchQueue {
3
+ private queue;
4
+ constructor(concurrency?: number);
5
+ getQueue(): PQueue<import("p-queue/dist/priority-queue").default, import("p-queue").DefaultAddOptions>;
6
+ add<T>(fn: () => T, priority?: number): Promise<T>;
7
+ onIdle(): Promise<void>;
8
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.WatchQueue = void 0;
9
+
10
+ function _defineProperty2() {
11
+ const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
+
13
+ _defineProperty2 = function () {
14
+ return data;
15
+ };
16
+
17
+ return data;
18
+ }
19
+
20
+ function _pQueue() {
21
+ const data = _interopRequireDefault(require("p-queue"));
22
+
23
+ _pQueue = function () {
24
+ return data;
25
+ };
26
+
27
+ return data;
28
+ }
29
+
30
+ class WatchQueue {
31
+ constructor(concurrency = 1) {
32
+ (0, _defineProperty2().default)(this, "queue", void 0);
33
+ this.queue = new (_pQueue().default)({
34
+ concurrency,
35
+ autoStart: true
36
+ });
37
+ }
38
+
39
+ getQueue() {
40
+ return this.queue;
41
+ }
42
+
43
+ add(fn, priority) {
44
+ return this.queue.add(fn, {
45
+ priority
46
+ });
47
+ }
48
+
49
+ onIdle() {
50
+ return this.queue.onIdle();
51
+ }
52
+
53
+ }
54
+
55
+ exports.WatchQueue = WatchQueue;
56
+
57
+ //# sourceMappingURL=watch-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["WatchQueue","constructor","concurrency","queue","PQueue","autoStart","getQueue","add","fn","priority","onIdle"],"sources":["watch-queue.ts"],"sourcesContent":["import PQueue from 'p-queue';\n\nexport class WatchQueue {\n private queue: PQueue;\n constructor(concurrency = 1) {\n this.queue = new PQueue({ concurrency, autoStart: true });\n }\n getQueue() {\n return this.queue;\n }\n add<T>(fn: () => T, priority?: number): Promise<T> {\n return this.queue.add(fn, { priority });\n }\n onIdle(): Promise<void> {\n return this.queue.onIdle();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAEO,MAAMA,UAAN,CAAiB;EAEtBC,WAAW,CAACC,WAAW,GAAG,CAAf,EAAkB;IAAA;IAC3B,KAAKC,KAAL,GAAa,KAAIC,iBAAJ,EAAW;MAAEF,WAAF;MAAeG,SAAS,EAAE;IAA1B,CAAX,CAAb;EACD;;EACDC,QAAQ,GAAG;IACT,OAAO,KAAKH,KAAZ;EACD;;EACDI,GAAG,CAAIC,EAAJ,EAAiBC,QAAjB,EAAgD;IACjD,OAAO,KAAKN,KAAL,CAAWI,GAAX,CAAeC,EAAf,EAAmB;MAAEC;IAAF,CAAnB,CAAP;EACD;;EACDC,MAAM,GAAkB;IACtB,OAAO,KAAKP,KAAL,CAAWO,MAAX,EAAP;EACD;;AAbqB"}
@@ -38,12 +38,15 @@ export declare class Watcher {
38
38
  private multipleWatchers;
39
39
  private fsWatcher;
40
40
  private changedFilesPerComponent;
41
+ private watchQueue;
42
+ private bitMapChangesInProgress;
41
43
  constructor(workspace: Workspace, pubsub: PubsubMain, trackDirs?: {
42
44
  [dir: PathLinux]: ComponentID;
43
45
  }, verbose?: boolean, multipleWatchers?: WatcherProcessData[]);
44
46
  get consumer(): Consumer;
45
47
  watchAll(opts: WatchOptions): Promise<unknown>;
46
48
  /**
49
+ * *** DEBOUNCING ***
47
50
  * some actions trigger multiple files changes at (almost) the same time. e.g. "git pull".
48
51
  * this causes some performance and instability issues. a debouncing mechanism was implemented to help with this.
49
52
  * the way how it works is that the first file of the same component starts the execution with a delay (e.g. 200ms).
@@ -58,6 +61,24 @@ export declare class Watcher {
58
61
  * B) it debounces the method regardless the param passes to it. so it'll disregard the component-id and will delay
59
62
  * other components undesirably.
60
63
  *
64
+ * *** QUEUE ***
65
+ * the debouncing helps to not execute the same component multiple times concurrently. however, multiple components
66
+ * and .bitmap changes execution can still be processed concurrently.
67
+ * the following example explains why this is an issue.
68
+ * compA is changed in the .bitmap file from version 0.0.1 to 0.0.2. its files were changed as well.
69
+ * all these changes get pulled at the same time by "git pull", as a result, the execution of compA and the .bitmap
70
+ * happen at the same time.
71
+ * during the execution of compA, the component id is parsed as compA@0.0.1, later, it asks for the Workspace for this
72
+ * id. while the workspace is looking for this id, the .bitmap execution reloaded the consumer and changed all versions.
73
+ * after this change, the workspace doesn't have this id anymore, which will trigger an error.
74
+ * to ensure this won't happen, we keep a flag to indicate whether the .bitmap execution is running, and if so, all
75
+ * other executions are paused until the queue is empty (this is done by awaiting for queue.onIdle).
76
+ * once the queue is empty, we know the .bitmap process was done and the workspace has all new ids.
77
+ * in the example above, at this stage, the id will be resolved to compA@0.0.2.
78
+ * one more thing, the queue is configured to have concurrency of 1. to make sure two components are not processed at
79
+ * the same time. (the same way is done when loading all components from the filesystem/scope).
80
+ * this way we can also ensure that if compA was started before the .bitmap execution, it will complete before the
81
+ * .bitmap execution starts.
61
82
  */
62
83
  private handleChange;
63
84
  private sleep;
@@ -145,6 +145,16 @@ function _events() {
145
145
  return data;
146
146
  }
147
147
 
148
+ function _watchQueue() {
149
+ const data = require("./watch-queue");
150
+
151
+ _watchQueue = function () {
152
+ return data;
153
+ };
154
+
155
+ return data;
156
+ }
157
+
148
158
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
149
159
 
150
160
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2().default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -160,6 +170,8 @@ class Watcher {
160
170
  this.multipleWatchers = multipleWatchers;
161
171
  (0, _defineProperty2().default)(this, "fsWatcher", void 0);
162
172
  (0, _defineProperty2().default)(this, "changedFilesPerComponent", {});
173
+ (0, _defineProperty2().default)(this, "watchQueue", new (_watchQueue().WatchQueue)());
174
+ (0, _defineProperty2().default)(this, "bitMapChangesInProgress", false);
163
175
  }
164
176
 
165
177
  get consumer() {
@@ -234,6 +246,7 @@ class Watcher {
234
246
  });
235
247
  }
236
248
  /**
249
+ * *** DEBOUNCING ***
237
250
  * some actions trigger multiple files changes at (almost) the same time. e.g. "git pull".
238
251
  * this causes some performance and instability issues. a debouncing mechanism was implemented to help with this.
239
252
  * the way how it works is that the first file of the same component starts the execution with a delay (e.g. 200ms).
@@ -248,13 +261,33 @@ class Watcher {
248
261
  * B) it debounces the method regardless the param passes to it. so it'll disregard the component-id and will delay
249
262
  * other components undesirably.
250
263
  *
264
+ * *** QUEUE ***
265
+ * the debouncing helps to not execute the same component multiple times concurrently. however, multiple components
266
+ * and .bitmap changes execution can still be processed concurrently.
267
+ * the following example explains why this is an issue.
268
+ * compA is changed in the .bitmap file from version 0.0.1 to 0.0.2. its files were changed as well.
269
+ * all these changes get pulled at the same time by "git pull", as a result, the execution of compA and the .bitmap
270
+ * happen at the same time.
271
+ * during the execution of compA, the component id is parsed as compA@0.0.1, later, it asks for the Workspace for this
272
+ * id. while the workspace is looking for this id, the .bitmap execution reloaded the consumer and changed all versions.
273
+ * after this change, the workspace doesn't have this id anymore, which will trigger an error.
274
+ * to ensure this won't happen, we keep a flag to indicate whether the .bitmap execution is running, and if so, all
275
+ * other executions are paused until the queue is empty (this is done by awaiting for queue.onIdle).
276
+ * once the queue is empty, we know the .bitmap process was done and the workspace has all new ids.
277
+ * in the example above, at this stage, the id will be resolved to compA@0.0.2.
278
+ * one more thing, the queue is configured to have concurrency of 1. to make sure two components are not processed at
279
+ * the same time. (the same way is done when loading all components from the filesystem/scope).
280
+ * this way we can also ensure that if compA was started before the .bitmap execution, it will complete before the
281
+ * .bitmap execution starts.
251
282
  */
252
283
 
253
284
 
254
285
  async handleChange(filePath, initiator) {
255
286
  try {
256
287
  if (filePath.endsWith(_constants().BIT_MAP)) {
257
- const buildResults = await this.handleBitmapChanges();
288
+ this.bitMapChangesInProgress = true;
289
+ const buildResults = await this.watchQueue.add(() => this.handleBitmapChanges());
290
+ this.bitMapChangesInProgress = false;
258
291
 
259
292
  _loader().default.stop();
260
293
 
@@ -264,6 +297,10 @@ class Watcher {
264
297
  };
265
298
  }
266
299
 
300
+ if (this.bitMapChangesInProgress) {
301
+ await this.watchQueue.onIdle();
302
+ }
303
+
267
304
  const componentId = this.getComponentIdByPath(filePath);
268
305
 
269
306
  if (!componentId) {
@@ -297,7 +334,7 @@ class Watcher {
297
334
  await this.sleep(DEBOUNCE_WAIT_MS);
298
335
  const files = this.changedFilesPerComponent[compIdStr];
299
336
  delete this.changedFilesPerComponent[compIdStr];
300
- const buildResults = await this.triggerCompChanges(componentId, files, initiator);
337
+ const buildResults = await this.watchQueue.add(() => this.triggerCompChanges(componentId, files, initiator));
301
338
  const failureMsg = buildResults.length ? undefined : `files ${files.join(', ')} are inside the component ${compIdStr} but configured to be ignored`;
302
339
 
303
340
  _loader().default.stop();
@@ -1 +1 @@
1
- {"version":3,"names":["DEBOUNCE_WAIT_MS","Watcher","constructor","workspace","pubsub","trackDirs","verbose","multipleWatchers","consumer","watchAll","opts","msgs","watchOpts","pathsToWatch","getPathsToWatch","componentIds","Object","values","triggerOnPreWatch","createWatcher","watcher","fsWatcher","onStart","Promise","resolve","reject","process","env","BIT_LOG","onAll","on","onReady","filePath","startTime","Date","getTime","files","results","debounced","failureMsg","handleChange","initiator","duration","onChange","onAdd","p","onUnlink","err","onError","endsWith","BIT_MAP","buildResults","handleBitmapChanges","loader","stop","componentId","getComponentIdByPath","logger","debug","compIdStr","toString","changedFilesPerComponent","push","sleep","triggerCompChanges","length","undefined","join","msg","error","console","message","ms","setTimeout","clearComponentCache","component","get","componentMap","state","_consumer","compFiles","filter","relativeFile","getRelativePathLinux","isCompFile","Boolean","getFilesRelativeToConsumer","find","executeWatchOperationsOnComponent","previewsTrackDirs","_reloadConsumer","setTrackDirs","newDirs","difference","keys","removedDirs","add","addResults","mapSeries","dir","flat","unwatch","executeWatchOperationsOnRemove","chalk","bold","pub","WorkspaceAspect","id","creatOnComponentRemovedEvent","triggerOnComponentRemove","isChange","isComponentWatchedExternally","idStr","creatOnComponentChangeEvent","creatOnComponentAddEvent","triggerOnComponentChange","triggerOnComponentAdd","OnComponentRemovedEvent","now","hook","OnComponentChangeEvent","OnComponentAddEvent","watcherData","m","isEqual","_legacy","compilerId","trackDir","findTrackDirByFilePathRecursively","pathNormalizeToLinux","getPathRelativeToConsumer","parentDir","dirname","chokidar","watch","ignoreInitial","ignored","path","includes","sep","persistent","useFsEvents","componentsFromBitMap","bitMap","getAllComponents","COMPONENT_ORIGINS","AUTHORED","IMPORTED","all","map","bitId","getTrackDir","Error","resolveComponentId","paths","pathsAbsolute","toAbsolutePath"],"sources":["watcher.ts"],"sourcesContent":["import { PubsubMain } from '@teambit/pubsub';\nimport { dirname, sep } from 'path';\nimport { difference } from 'lodash';\nimport { ComponentID } from '@teambit/component';\nimport { BitId } from '@teambit/legacy-bit-id';\nimport loader from '@teambit/legacy/dist/cli/loader';\nimport { BIT_MAP, COMPONENT_ORIGINS } from '@teambit/legacy/dist/constants';\nimport { Consumer } from '@teambit/legacy/dist/consumer';\nimport logger from '@teambit/legacy/dist/logger/logger';\nimport { pathNormalizeToLinux } from '@teambit/legacy/dist/utils';\nimport mapSeries from 'p-map-series';\nimport chalk from 'chalk';\nimport { ChildProcess } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport ComponentMap from '@teambit/legacy/dist/consumer/bit-map/component-map';\nimport { PathLinux, PathOsBasedAbsolute } from '@teambit/legacy/dist/utils/path';\nimport { CompilationInitiator } from '@teambit/compiler';\nimport { WorkspaceAspect } from '../';\nimport { OnComponentChangeEvent, OnComponentAddEvent, OnComponentRemovedEvent } from '../events';\nimport { Workspace } from '../workspace';\nimport { OnComponentEventResult } from '../on-component-events';\nimport { CheckTypes } from './check-types';\n\nexport type WatcherProcessData = { watchProcess: ChildProcess; compilerId: BitId; componentIds: BitId[] };\n\nexport type EventMessages = {\n onAll: Function;\n onStart: Function;\n onReady: Function;\n onChange: Function;\n onAdd: Function;\n onUnlink: Function;\n onError: Function;\n};\n\nexport type WatchOptions = {\n msgs?: EventMessages;\n initiator?: CompilationInitiator;\n verbose?: boolean; // print watch events to the console. (also ts-server events if spawnTSServer is true)\n spawnTSServer?: boolean; // needed for check types and extract API/docs.\n checkTypes?: CheckTypes; // if enabled, the spawnTSServer becomes true.\n preCompile?: boolean; // whether compile all components before start watching\n};\n\nconst DEBOUNCE_WAIT_MS = 100;\n\nexport class Watcher {\n private fsWatcher: FSWatcher;\n private changedFilesPerComponent: { [componentId: string]: string[] } = {};\n constructor(\n private workspace: Workspace,\n private pubsub: PubsubMain,\n private trackDirs: { [dir: PathLinux]: ComponentID } = {},\n private verbose = false,\n private multipleWatchers: WatcherProcessData[] = []\n ) {}\n\n get consumer(): Consumer {\n return this.workspace.consumer;\n }\n\n async watchAll(opts: WatchOptions) {\n const { msgs, ...watchOpts } = opts;\n // TODO: run build in the beginning of process (it's work like this in other envs)\n const pathsToWatch = await this.getPathsToWatch();\n const componentIds = Object.values(this.trackDirs);\n await this.workspace.triggerOnPreWatch(componentIds, watchOpts);\n await this.createWatcher(pathsToWatch);\n const watcher = this.fsWatcher;\n msgs?.onStart(this.workspace);\n\n return new Promise((resolve, reject) => {\n // prefix your command with \"BIT_LOG=*\" to see all watch events\n if (process.env.BIT_LOG) {\n // @ts-ignore\n if (msgs?.onAll) watcher.on('all', msgs?.onAll);\n }\n watcher.on('ready', () => {\n msgs?.onReady(this.workspace, this.trackDirs, this.verbose);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('change', async (filePath) => {\n const startTime = new Date().getTime();\n const { files, results, debounced, failureMsg } = await this.handleChange(filePath, opts?.initiator);\n if (debounced) {\n return;\n }\n const duration = new Date().getTime() - startTime;\n msgs?.onChange(files, results, this.verbose, duration, failureMsg);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('add', async (filePath) => {\n const startTime = new Date().getTime();\n const { files, results, debounced, failureMsg } = await this.handleChange(filePath, opts?.initiator);\n if (debounced) {\n return;\n }\n const duration = new Date().getTime() - startTime;\n msgs?.onAdd(files, results, this.verbose, duration, failureMsg);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('unlink', async (p) => {\n msgs?.onUnlink(p);\n await this.handleChange(p);\n });\n watcher.on('error', (err) => {\n msgs?.onError(err);\n reject(err);\n });\n });\n }\n\n /**\n * some actions trigger multiple files changes at (almost) the same time. e.g. \"git pull\".\n * this causes some performance and instability issues. a debouncing mechanism was implemented to help with this.\n * the way how it works is that the first file of the same component starts the execution with a delay (e.g. 200ms).\n * if, in the meanwhile, another file of the same component was changed, it won't start a new execution, instead,\n * it'll only add the file to `this.changedFilesPerComponent` prop.\n * once the execution starts, it'll delete this component-id from the `this.changedFilesPerComponent` array,\n * indicating the next file-change to start a new execution.\n *\n * implementation wise, `lodash.debounce` doesn't help here, because:\n * A) it doesn't return the results, unless \"leading\" option is true. here, it must be false, otherwise, it'll start\n * the execution immediately.\n * B) it debounces the method regardless the param passes to it. so it'll disregard the component-id and will delay\n * other components undesirably.\n *\n */\n private async handleChange(\n filePath: string,\n initiator?: CompilationInitiator\n ): Promise<{\n results: OnComponentEventResult[];\n files?: string[];\n failureMsg?: string;\n debounced?: boolean;\n }> {\n try {\n if (filePath.endsWith(BIT_MAP)) {\n const buildResults = await this.handleBitmapChanges();\n loader.stop();\n return { results: buildResults, files: [filePath] };\n }\n const componentId = this.getComponentIdByPath(filePath);\n if (!componentId) {\n const failureMsg = `file ${filePath} is not part of any component, ignoring it`;\n logger.debug(failureMsg);\n loader.stop();\n return { results: [], files: [filePath], failureMsg };\n }\n\n const compIdStr = componentId.toString();\n if (this.changedFilesPerComponent[compIdStr]) {\n this.changedFilesPerComponent[compIdStr].push(filePath);\n loader.stop();\n return { results: [], debounced: true };\n }\n this.changedFilesPerComponent[compIdStr] = [filePath];\n await this.sleep(DEBOUNCE_WAIT_MS);\n const files = this.changedFilesPerComponent[compIdStr];\n delete this.changedFilesPerComponent[compIdStr];\n\n const buildResults = await this.triggerCompChanges(componentId, files, initiator);\n const failureMsg = buildResults.length\n ? undefined\n : `files ${files.join(', ')} are inside the component ${compIdStr} but configured to be ignored`;\n loader.stop();\n return { results: buildResults, files, failureMsg };\n } catch (err: any) {\n const msg = `watcher found an error while handling ${filePath}`;\n logger.error(msg, err);\n logger.console(`${msg}, ${err.message}`);\n loader.stop();\n return { results: [], files: [filePath], failureMsg: err.message };\n }\n }\n\n private async sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * if a file was added/remove, once the component is loaded, it changes .bitmap, and then the\n * entire cache is invalidated and the consumer is reloaded.\n * when a file just changed, no need to reload the consumer, it is enough to just delete the\n * component from the cache (both, workspace and consumer)\n */\n private async triggerCompChanges(\n componentId: ComponentID,\n files: string[],\n initiator?: CompilationInitiator\n ): Promise<OnComponentEventResult[]> {\n this.workspace.clearComponentCache(componentId);\n const component = await this.workspace.get(componentId);\n const componentMap: ComponentMap = component.state._consumer.componentMap;\n const compFiles = files.filter((filePath) => {\n const relativeFile = this.getRelativePathLinux(filePath);\n const isCompFile = Boolean(componentMap.getFilesRelativeToConsumer().find((p) => p === relativeFile));\n if (!isCompFile) {\n logger.debug(`file ${filePath} is inside the component ${componentId.toString()} but configured to be ignored`);\n }\n return isCompFile;\n });\n if (!compFiles.length) {\n return [];\n }\n const buildResults = await this.executeWatchOperationsOnComponent(componentId, compFiles, true, initiator);\n return buildResults;\n }\n\n /**\n * if .bitmap changed, it's possible that a new component has been added. trigger onComponentAdd.\n */\n private async handleBitmapChanges(): Promise<OnComponentEventResult[]> {\n const previewsTrackDirs = { ...this.trackDirs };\n await this.workspace._reloadConsumer();\n await this.setTrackDirs();\n const newDirs: string[] = difference(Object.keys(this.trackDirs), Object.keys(previewsTrackDirs));\n const removedDirs: string[] = difference(Object.keys(previewsTrackDirs), Object.keys(this.trackDirs));\n const results: OnComponentEventResult[] = [];\n if (newDirs.length) {\n this.fsWatcher.add(newDirs);\n const addResults = await mapSeries(newDirs, async (dir) =>\n this.executeWatchOperationsOnComponent(this.trackDirs[dir], [], false)\n );\n results.push(...addResults.flat());\n }\n if (removedDirs.length) {\n await this.fsWatcher.unwatch(removedDirs);\n await mapSeries(removedDirs, (dir) => this.executeWatchOperationsOnRemove(previewsTrackDirs[dir]));\n }\n return results;\n }\n\n private async executeWatchOperationsOnRemove(componentId: ComponentID) {\n logger.debug(`running OnComponentRemove hook for ${chalk.bold(componentId.toString())}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentRemovedEvent(componentId.toString()));\n await this.workspace.triggerOnComponentRemove(componentId);\n }\n\n private async executeWatchOperationsOnComponent(\n componentId: ComponentID,\n files: string[],\n isChange = true,\n initiator?: CompilationInitiator\n ): Promise<OnComponentEventResult[]> {\n if (this.isComponentWatchedExternally(componentId)) {\n // update capsule, once done, it automatically triggers the external watcher\n await this.workspace.get(componentId);\n return [];\n }\n const idStr = componentId.toString();\n\n if (isChange) {\n logger.debug(`running OnComponentChange hook for ${chalk.bold(idStr)}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentChangeEvent(idStr, 'OnComponentChange'));\n } else {\n logger.debug(`running OnComponentAdd hook for ${chalk.bold(idStr)}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentAddEvent(idStr, 'OnComponentAdd'));\n }\n\n let buildResults: OnComponentEventResult[];\n try {\n buildResults = isChange\n ? await this.workspace.triggerOnComponentChange(componentId, files, initiator)\n : await this.workspace.triggerOnComponentAdd(componentId);\n } catch (err: any) {\n // do not exit the watch process on errors, just print them\n const msg = `found an issue during onComponentChange or onComponentAdd hooks`;\n logger.error(msg, err);\n logger.console(`\\n${msg}: ${err.message || err}`);\n return [];\n }\n return buildResults;\n }\n\n private creatOnComponentRemovedEvent(idStr) {\n return new OnComponentRemovedEvent(Date.now(), idStr);\n }\n\n private creatOnComponentChangeEvent(idStr, hook) {\n return new OnComponentChangeEvent(Date.now(), idStr, hook);\n }\n\n private creatOnComponentAddEvent(idStr, hook) {\n return new OnComponentAddEvent(Date.now(), idStr, hook);\n }\n\n private isComponentWatchedExternally(componentId: ComponentID) {\n const watcherData = this.multipleWatchers.find((m) => m.componentIds.find((id) => id.isEqual(componentId._legacy)));\n if (watcherData) {\n logger.debug(`${componentId.toString()} is watched by ${watcherData.compilerId.toString()}`);\n return true;\n }\n return false;\n }\n\n private getComponentIdByPath(filePath: string): ComponentID | null {\n const relativeFile = this.getRelativePathLinux(filePath);\n const trackDir = this.findTrackDirByFilePathRecursively(relativeFile);\n if (!trackDir) {\n // the file is not part of any component. If it was a new component, or a new file of\n // existing component, then, handleBitmapChanges() should deal with it.\n return null;\n }\n return this.trackDirs[trackDir];\n }\n\n private getRelativePathLinux(filePath: string) {\n return pathNormalizeToLinux(this.consumer.getPathRelativeToConsumer(filePath));\n }\n\n private findTrackDirByFilePathRecursively(filePath: string): string | null {\n if (this.trackDirs[filePath]) return filePath;\n const parentDir = dirname(filePath);\n if (parentDir === filePath) return null;\n return this.findTrackDirByFilePathRecursively(parentDir);\n }\n\n private async createWatcher(pathsToWatch: string[]) {\n this.fsWatcher = chokidar.watch(pathsToWatch, {\n ignoreInitial: true,\n // Using the function way since the regular way not working as expected\n // It might be solved when upgrading to chokidar > 3.0.0\n // See:\n // https://github.com/paulmillr/chokidar/issues/773\n // https://github.com/paulmillr/chokidar/issues/492\n // https://github.com/paulmillr/chokidar/issues/724\n ignored: (path) => {\n // Ignore package.json temporarily since it cerates endless loop since it's re-written after each build\n if (path.includes(`${sep}node_modules${sep}`) || path.includes(`${sep}package.json`)) {\n return true;\n }\n return false;\n },\n persistent: true,\n useFsEvents: false,\n });\n }\n\n async setTrackDirs() {\n this.trackDirs = {};\n const componentsFromBitMap = this.consumer.bitMap.getAllComponents([\n COMPONENT_ORIGINS.AUTHORED,\n COMPONENT_ORIGINS.IMPORTED,\n ]);\n await Promise.all(\n componentsFromBitMap.map(async (componentMap) => {\n const bitId = componentMap.id;\n const trackDir = componentMap.getTrackDir();\n if (!trackDir) throw new Error(`${bitId.toString()} has no rootDir, which is invalid in Harmony`);\n const componentId = await this.workspace.resolveComponentId(bitId);\n this.trackDirs[trackDir] = componentId;\n })\n );\n }\n\n private async getPathsToWatch(): Promise<PathOsBasedAbsolute[]> {\n await this.setTrackDirs();\n const paths = [...Object.keys(this.trackDirs), BIT_MAP];\n const pathsAbsolute = paths.map((dir) => this.consumer.toAbsolutePath(dir));\n return pathsAbsolute;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["DEBOUNCE_WAIT_MS","Watcher","constructor","workspace","pubsub","trackDirs","verbose","multipleWatchers","WatchQueue","consumer","watchAll","opts","msgs","watchOpts","pathsToWatch","getPathsToWatch","componentIds","Object","values","triggerOnPreWatch","createWatcher","watcher","fsWatcher","onStart","Promise","resolve","reject","process","env","BIT_LOG","onAll","on","onReady","filePath","startTime","Date","getTime","files","results","debounced","failureMsg","handleChange","initiator","duration","onChange","onAdd","p","onUnlink","err","onError","endsWith","BIT_MAP","bitMapChangesInProgress","buildResults","watchQueue","add","handleBitmapChanges","loader","stop","onIdle","componentId","getComponentIdByPath","logger","debug","compIdStr","toString","changedFilesPerComponent","push","sleep","triggerCompChanges","length","undefined","join","msg","error","console","message","ms","setTimeout","clearComponentCache","component","get","componentMap","state","_consumer","compFiles","filter","relativeFile","getRelativePathLinux","isCompFile","Boolean","getFilesRelativeToConsumer","find","executeWatchOperationsOnComponent","previewsTrackDirs","_reloadConsumer","setTrackDirs","newDirs","difference","keys","removedDirs","addResults","mapSeries","dir","flat","unwatch","executeWatchOperationsOnRemove","chalk","bold","pub","WorkspaceAspect","id","creatOnComponentRemovedEvent","triggerOnComponentRemove","isChange","isComponentWatchedExternally","idStr","creatOnComponentChangeEvent","creatOnComponentAddEvent","triggerOnComponentChange","triggerOnComponentAdd","OnComponentRemovedEvent","now","hook","OnComponentChangeEvent","OnComponentAddEvent","watcherData","m","isEqual","_legacy","compilerId","trackDir","findTrackDirByFilePathRecursively","pathNormalizeToLinux","getPathRelativeToConsumer","parentDir","dirname","chokidar","watch","ignoreInitial","ignored","path","includes","sep","persistent","useFsEvents","componentsFromBitMap","bitMap","getAllComponents","COMPONENT_ORIGINS","AUTHORED","IMPORTED","all","map","bitId","getTrackDir","Error","resolveComponentId","paths","pathsAbsolute","toAbsolutePath"],"sources":["watcher.ts"],"sourcesContent":["import { PubsubMain } from '@teambit/pubsub';\nimport { dirname, sep } from 'path';\nimport { difference } from 'lodash';\nimport { ComponentID } from '@teambit/component';\nimport { BitId } from '@teambit/legacy-bit-id';\nimport loader from '@teambit/legacy/dist/cli/loader';\nimport { BIT_MAP, COMPONENT_ORIGINS } from '@teambit/legacy/dist/constants';\nimport { Consumer } from '@teambit/legacy/dist/consumer';\nimport logger from '@teambit/legacy/dist/logger/logger';\nimport { pathNormalizeToLinux } from '@teambit/legacy/dist/utils';\nimport mapSeries from 'p-map-series';\nimport chalk from 'chalk';\nimport { ChildProcess } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport ComponentMap from '@teambit/legacy/dist/consumer/bit-map/component-map';\nimport { PathLinux, PathOsBasedAbsolute } from '@teambit/legacy/dist/utils/path';\nimport { CompilationInitiator } from '@teambit/compiler';\nimport { WorkspaceAspect } from '../';\nimport { OnComponentChangeEvent, OnComponentAddEvent, OnComponentRemovedEvent } from '../events';\nimport { Workspace } from '../workspace';\nimport { OnComponentEventResult } from '../on-component-events';\nimport { CheckTypes } from './check-types';\nimport { WatchQueue } from './watch-queue';\n\nexport type WatcherProcessData = { watchProcess: ChildProcess; compilerId: BitId; componentIds: BitId[] };\n\nexport type EventMessages = {\n onAll: Function;\n onStart: Function;\n onReady: Function;\n onChange: Function;\n onAdd: Function;\n onUnlink: Function;\n onError: Function;\n};\n\nexport type WatchOptions = {\n msgs?: EventMessages;\n initiator?: CompilationInitiator;\n verbose?: boolean; // print watch events to the console. (also ts-server events if spawnTSServer is true)\n spawnTSServer?: boolean; // needed for check types and extract API/docs.\n checkTypes?: CheckTypes; // if enabled, the spawnTSServer becomes true.\n preCompile?: boolean; // whether compile all components before start watching\n};\n\nconst DEBOUNCE_WAIT_MS = 100;\n\nexport class Watcher {\n private fsWatcher: FSWatcher;\n private changedFilesPerComponent: { [componentId: string]: string[] } = {};\n private watchQueue = new WatchQueue();\n private bitMapChangesInProgress = false;\n constructor(\n private workspace: Workspace,\n private pubsub: PubsubMain,\n private trackDirs: { [dir: PathLinux]: ComponentID } = {},\n private verbose = false,\n private multipleWatchers: WatcherProcessData[] = []\n ) {}\n\n get consumer(): Consumer {\n return this.workspace.consumer;\n }\n\n async watchAll(opts: WatchOptions) {\n const { msgs, ...watchOpts } = opts;\n // TODO: run build in the beginning of process (it's work like this in other envs)\n const pathsToWatch = await this.getPathsToWatch();\n const componentIds = Object.values(this.trackDirs);\n await this.workspace.triggerOnPreWatch(componentIds, watchOpts);\n await this.createWatcher(pathsToWatch);\n const watcher = this.fsWatcher;\n msgs?.onStart(this.workspace);\n\n return new Promise((resolve, reject) => {\n // prefix your command with \"BIT_LOG=*\" to see all watch events\n if (process.env.BIT_LOG) {\n // @ts-ignore\n if (msgs?.onAll) watcher.on('all', msgs?.onAll);\n }\n watcher.on('ready', () => {\n msgs?.onReady(this.workspace, this.trackDirs, this.verbose);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('change', async (filePath) => {\n const startTime = new Date().getTime();\n const { files, results, debounced, failureMsg } = await this.handleChange(filePath, opts?.initiator);\n if (debounced) {\n return;\n }\n const duration = new Date().getTime() - startTime;\n msgs?.onChange(files, results, this.verbose, duration, failureMsg);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('add', async (filePath) => {\n const startTime = new Date().getTime();\n const { files, results, debounced, failureMsg } = await this.handleChange(filePath, opts?.initiator);\n if (debounced) {\n return;\n }\n const duration = new Date().getTime() - startTime;\n msgs?.onAdd(files, results, this.verbose, duration, failureMsg);\n });\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n watcher.on('unlink', async (p) => {\n msgs?.onUnlink(p);\n await this.handleChange(p);\n });\n watcher.on('error', (err) => {\n msgs?.onError(err);\n reject(err);\n });\n });\n }\n\n /**\n * *** DEBOUNCING ***\n * some actions trigger multiple files changes at (almost) the same time. e.g. \"git pull\".\n * this causes some performance and instability issues. a debouncing mechanism was implemented to help with this.\n * the way how it works is that the first file of the same component starts the execution with a delay (e.g. 200ms).\n * if, in the meanwhile, another file of the same component was changed, it won't start a new execution, instead,\n * it'll only add the file to `this.changedFilesPerComponent` prop.\n * once the execution starts, it'll delete this component-id from the `this.changedFilesPerComponent` array,\n * indicating the next file-change to start a new execution.\n *\n * implementation wise, `lodash.debounce` doesn't help here, because:\n * A) it doesn't return the results, unless \"leading\" option is true. here, it must be false, otherwise, it'll start\n * the execution immediately.\n * B) it debounces the method regardless the param passes to it. so it'll disregard the component-id and will delay\n * other components undesirably.\n *\n * *** QUEUE ***\n * the debouncing helps to not execute the same component multiple times concurrently. however, multiple components\n * and .bitmap changes execution can still be processed concurrently.\n * the following example explains why this is an issue.\n * compA is changed in the .bitmap file from version 0.0.1 to 0.0.2. its files were changed as well.\n * all these changes get pulled at the same time by \"git pull\", as a result, the execution of compA and the .bitmap\n * happen at the same time.\n * during the execution of compA, the component id is parsed as compA@0.0.1, later, it asks for the Workspace for this\n * id. while the workspace is looking for this id, the .bitmap execution reloaded the consumer and changed all versions.\n * after this change, the workspace doesn't have this id anymore, which will trigger an error.\n * to ensure this won't happen, we keep a flag to indicate whether the .bitmap execution is running, and if so, all\n * other executions are paused until the queue is empty (this is done by awaiting for queue.onIdle).\n * once the queue is empty, we know the .bitmap process was done and the workspace has all new ids.\n * in the example above, at this stage, the id will be resolved to compA@0.0.2.\n * one more thing, the queue is configured to have concurrency of 1. to make sure two components are not processed at\n * the same time. (the same way is done when loading all components from the filesystem/scope).\n * this way we can also ensure that if compA was started before the .bitmap execution, it will complete before the\n * .bitmap execution starts.\n */\n private async handleChange(\n filePath: string,\n initiator?: CompilationInitiator\n ): Promise<{\n results: OnComponentEventResult[];\n files?: string[];\n failureMsg?: string;\n debounced?: boolean;\n }> {\n try {\n if (filePath.endsWith(BIT_MAP)) {\n this.bitMapChangesInProgress = true;\n const buildResults = await this.watchQueue.add(() => this.handleBitmapChanges());\n this.bitMapChangesInProgress = false;\n loader.stop();\n return { results: buildResults, files: [filePath] };\n }\n if (this.bitMapChangesInProgress) {\n await this.watchQueue.onIdle();\n }\n const componentId = this.getComponentIdByPath(filePath);\n if (!componentId) {\n const failureMsg = `file ${filePath} is not part of any component, ignoring it`;\n logger.debug(failureMsg);\n loader.stop();\n return { results: [], files: [filePath], failureMsg };\n }\n const compIdStr = componentId.toString();\n if (this.changedFilesPerComponent[compIdStr]) {\n this.changedFilesPerComponent[compIdStr].push(filePath);\n loader.stop();\n return { results: [], debounced: true };\n }\n this.changedFilesPerComponent[compIdStr] = [filePath];\n await this.sleep(DEBOUNCE_WAIT_MS);\n const files = this.changedFilesPerComponent[compIdStr];\n delete this.changedFilesPerComponent[compIdStr];\n\n const buildResults = await this.watchQueue.add(() => this.triggerCompChanges(componentId, files, initiator));\n const failureMsg = buildResults.length\n ? undefined\n : `files ${files.join(', ')} are inside the component ${compIdStr} but configured to be ignored`;\n loader.stop();\n return { results: buildResults, files, failureMsg };\n } catch (err: any) {\n const msg = `watcher found an error while handling ${filePath}`;\n logger.error(msg, err);\n logger.console(`${msg}, ${err.message}`);\n loader.stop();\n return { results: [], files: [filePath], failureMsg: err.message };\n }\n }\n\n private async sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * if a file was added/remove, once the component is loaded, it changes .bitmap, and then the\n * entire cache is invalidated and the consumer is reloaded.\n * when a file just changed, no need to reload the consumer, it is enough to just delete the\n * component from the cache (both, workspace and consumer)\n */\n private async triggerCompChanges(\n componentId: ComponentID,\n files: string[],\n initiator?: CompilationInitiator\n ): Promise<OnComponentEventResult[]> {\n this.workspace.clearComponentCache(componentId);\n const component = await this.workspace.get(componentId);\n const componentMap: ComponentMap = component.state._consumer.componentMap;\n const compFiles = files.filter((filePath) => {\n const relativeFile = this.getRelativePathLinux(filePath);\n const isCompFile = Boolean(componentMap.getFilesRelativeToConsumer().find((p) => p === relativeFile));\n if (!isCompFile) {\n logger.debug(`file ${filePath} is inside the component ${componentId.toString()} but configured to be ignored`);\n }\n return isCompFile;\n });\n if (!compFiles.length) {\n return [];\n }\n const buildResults = await this.executeWatchOperationsOnComponent(componentId, compFiles, true, initiator);\n return buildResults;\n }\n\n /**\n * if .bitmap changed, it's possible that a new component has been added. trigger onComponentAdd.\n */\n private async handleBitmapChanges(): Promise<OnComponentEventResult[]> {\n const previewsTrackDirs = { ...this.trackDirs };\n await this.workspace._reloadConsumer();\n await this.setTrackDirs();\n const newDirs: string[] = difference(Object.keys(this.trackDirs), Object.keys(previewsTrackDirs));\n const removedDirs: string[] = difference(Object.keys(previewsTrackDirs), Object.keys(this.trackDirs));\n const results: OnComponentEventResult[] = [];\n if (newDirs.length) {\n this.fsWatcher.add(newDirs);\n const addResults = await mapSeries(newDirs, async (dir) =>\n this.executeWatchOperationsOnComponent(this.trackDirs[dir], [], false)\n );\n results.push(...addResults.flat());\n }\n if (removedDirs.length) {\n await this.fsWatcher.unwatch(removedDirs);\n await mapSeries(removedDirs, (dir) => this.executeWatchOperationsOnRemove(previewsTrackDirs[dir]));\n }\n return results;\n }\n\n private async executeWatchOperationsOnRemove(componentId: ComponentID) {\n logger.debug(`running OnComponentRemove hook for ${chalk.bold(componentId.toString())}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentRemovedEvent(componentId.toString()));\n await this.workspace.triggerOnComponentRemove(componentId);\n }\n\n private async executeWatchOperationsOnComponent(\n componentId: ComponentID,\n files: string[],\n isChange = true,\n initiator?: CompilationInitiator\n ): Promise<OnComponentEventResult[]> {\n if (this.isComponentWatchedExternally(componentId)) {\n // update capsule, once done, it automatically triggers the external watcher\n await this.workspace.get(componentId);\n return [];\n }\n const idStr = componentId.toString();\n\n if (isChange) {\n logger.debug(`running OnComponentChange hook for ${chalk.bold(idStr)}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentChangeEvent(idStr, 'OnComponentChange'));\n } else {\n logger.debug(`running OnComponentAdd hook for ${chalk.bold(idStr)}`);\n this.pubsub.pub(WorkspaceAspect.id, this.creatOnComponentAddEvent(idStr, 'OnComponentAdd'));\n }\n\n let buildResults: OnComponentEventResult[];\n try {\n buildResults = isChange\n ? await this.workspace.triggerOnComponentChange(componentId, files, initiator)\n : await this.workspace.triggerOnComponentAdd(componentId);\n } catch (err: any) {\n // do not exit the watch process on errors, just print them\n const msg = `found an issue during onComponentChange or onComponentAdd hooks`;\n logger.error(msg, err);\n logger.console(`\\n${msg}: ${err.message || err}`);\n return [];\n }\n return buildResults;\n }\n\n private creatOnComponentRemovedEvent(idStr) {\n return new OnComponentRemovedEvent(Date.now(), idStr);\n }\n\n private creatOnComponentChangeEvent(idStr, hook) {\n return new OnComponentChangeEvent(Date.now(), idStr, hook);\n }\n\n private creatOnComponentAddEvent(idStr, hook) {\n return new OnComponentAddEvent(Date.now(), idStr, hook);\n }\n\n private isComponentWatchedExternally(componentId: ComponentID) {\n const watcherData = this.multipleWatchers.find((m) => m.componentIds.find((id) => id.isEqual(componentId._legacy)));\n if (watcherData) {\n logger.debug(`${componentId.toString()} is watched by ${watcherData.compilerId.toString()}`);\n return true;\n }\n return false;\n }\n\n private getComponentIdByPath(filePath: string): ComponentID | null {\n const relativeFile = this.getRelativePathLinux(filePath);\n const trackDir = this.findTrackDirByFilePathRecursively(relativeFile);\n if (!trackDir) {\n // the file is not part of any component. If it was a new component, or a new file of\n // existing component, then, handleBitmapChanges() should deal with it.\n return null;\n }\n return this.trackDirs[trackDir];\n }\n\n private getRelativePathLinux(filePath: string) {\n return pathNormalizeToLinux(this.consumer.getPathRelativeToConsumer(filePath));\n }\n\n private findTrackDirByFilePathRecursively(filePath: string): string | null {\n if (this.trackDirs[filePath]) return filePath;\n const parentDir = dirname(filePath);\n if (parentDir === filePath) return null;\n return this.findTrackDirByFilePathRecursively(parentDir);\n }\n\n private async createWatcher(pathsToWatch: string[]) {\n this.fsWatcher = chokidar.watch(pathsToWatch, {\n ignoreInitial: true,\n // Using the function way since the regular way not working as expected\n // It might be solved when upgrading to chokidar > 3.0.0\n // See:\n // https://github.com/paulmillr/chokidar/issues/773\n // https://github.com/paulmillr/chokidar/issues/492\n // https://github.com/paulmillr/chokidar/issues/724\n ignored: (path) => {\n // Ignore package.json temporarily since it cerates endless loop since it's re-written after each build\n if (path.includes(`${sep}node_modules${sep}`) || path.includes(`${sep}package.json`)) {\n return true;\n }\n return false;\n },\n persistent: true,\n useFsEvents: false,\n });\n }\n\n async setTrackDirs() {\n this.trackDirs = {};\n const componentsFromBitMap = this.consumer.bitMap.getAllComponents([\n COMPONENT_ORIGINS.AUTHORED,\n COMPONENT_ORIGINS.IMPORTED,\n ]);\n await Promise.all(\n componentsFromBitMap.map(async (componentMap) => {\n const bitId = componentMap.id;\n const trackDir = componentMap.getTrackDir();\n if (!trackDir) throw new Error(`${bitId.toString()} has no rootDir, which is invalid in Harmony`);\n const componentId = await this.workspace.resolveComponentId(bitId);\n this.trackDirs[trackDir] = componentId;\n })\n );\n }\n\n private async getPathsToWatch(): Promise<PathOsBasedAbsolute[]> {\n await this.setTrackDirs();\n const paths = [...Object.keys(this.trackDirs), BIT_MAP];\n const pathsAbsolute = paths.map((dir) => this.consumer.toAbsolutePath(dir));\n return pathsAbsolute;\n }\n}\n"],"mappings":"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"}
@@ -7,6 +7,16 @@ export class EnvsReplaceCmd implements Command {
7
7
  description = 'replace an existing env with another env for all components using the old env';
8
8
  options = [];
9
9
  group = 'development';
10
+ arguments = [
11
+ { name: 'old-env', description: 'current environment id' },
12
+ { name: 'new-env', description: 'target environment id' },
13
+ ];
14
+ examples = [
15
+ {
16
+ cmd: 'replace teambit.harmony/aspect teambit.harmony/node',
17
+ description: 'all components using aspect env, will be replaced with node env',
18
+ },
19
+ ];
10
20
 
11
21
  constructor(private workspace: Workspace) {}
12
22
 
@@ -1,19 +1,26 @@
1
1
  import { Command } from '@teambit/cli';
2
2
  import { PATTERN_HELP } from '@teambit/legacy/dist/constants';
3
+ import chalk from 'chalk';
3
4
  import { Workspace } from '../workspace';
4
5
 
5
6
  export class EnvsUnsetCmd implements Command {
6
- name = 'unset <component>';
7
- description = 'unset an environment from component(s)';
7
+ name = 'unset <pattern>';
8
+ description = 'unset an environment from component(s) that was set by "bit env set"';
8
9
  options = [];
9
10
  group = 'development';
10
- extendedDescription = `${PATTERN_HELP('env unset')}`;
11
+ extendedDescription = `keep in mind that this doesn't remove envs that are set in the variants.
12
+ in only removes envs that appear in the .bitmap file, which were previously configured via "bit env set".
13
+ the purpose of this command is to remove the specific settings and let the the variants in workspace.jsonc to control the env.
14
+ ${PATTERN_HELP('env unset')}`;
11
15
 
12
16
  constructor(private workspace: Workspace) {}
13
17
 
14
18
  async report([pattern]: [string]) {
15
19
  const componentIds = await this.workspace.idsByPattern(pattern);
16
20
  const { changed } = await this.workspace.unsetEnvFromComponents(componentIds);
21
+ if (!changed.length) {
22
+ return chalk.yellow(`unable to find any component matching the pattern with env configured in the .bitmap file`);
23
+ }
17
24
  return `successfully removed env from the following component(s):
18
25
  ${changed.map((id) => id.toString()).join('\n')}`;
19
26
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/workspace",
3
- "version": "0.0.755",
3
+ "version": "0.0.758",
4
4
  "homepage": "https://bit.dev/teambit/workspace/workspace",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.workspace",
8
8
  "name": "workspace",
9
- "version": "0.0.755"
9
+ "version": "0.0.758"
10
10
  },
11
11
  "dependencies": {
12
12
  "lodash": "4.17.21",
@@ -25,6 +25,7 @@
25
25
  "detect-indent": "5.0.0",
26
26
  "detect-newline": "3.1.0",
27
27
  "stringify-package": "1.0.1",
28
+ "p-queue": "6.6.2",
28
29
  "moment": "2.29.2",
29
30
  "chokidar": "3.5.1",
30
31
  "@react-hook/latest": "1.0.3",
@@ -39,46 +40,46 @@
39
40
  "@teambit/bit-error": "0.0.394",
40
41
  "@teambit/component-id": "0.0.402",
41
42
  "@teambit/legacy-bit-id": "0.0.399",
42
- "@teambit/logger": "0.0.591",
43
- "@teambit/scope": "0.0.755",
44
- "@teambit/cli": "0.0.498",
45
- "@teambit/isolator": "0.0.755",
46
- "@teambit/component-tree": "0.0.543",
43
+ "@teambit/logger": "0.0.594",
44
+ "@teambit/scope": "0.0.758",
45
+ "@teambit/cli": "0.0.501",
46
+ "@teambit/isolator": "0.0.758",
47
+ "@teambit/component-tree": "0.0.546",
47
48
  "@teambit/component.ui.component-status-resolver": "0.0.492",
48
- "@teambit/lanes.ui.lanes": "0.0.65",
49
+ "@teambit/lanes.ui.lanes": "0.0.68",
49
50
  "@teambit/harmony.modules.resolved-component": "0.0.484",
50
- "@teambit/dependency-resolver": "0.0.755",
51
- "@teambit/compiler": "0.0.755",
52
- "@teambit/component": "0.0.755",
53
- "@teambit/graphql": "0.0.755",
54
- "@teambit/aspect-loader": "0.0.755",
55
- "@teambit/bundler": "0.0.755",
56
- "@teambit/community": "0.0.46",
57
- "@teambit/envs": "0.0.755",
58
- "@teambit/pubsub": "0.0.755",
59
- "@teambit/ui": "0.0.755",
60
- "@teambit/variants": "0.0.594",
61
- "@teambit/component-issues": "0.0.53",
62
- "@teambit/config": "0.0.511",
51
+ "@teambit/dependency-resolver": "0.0.758",
52
+ "@teambit/compiler": "0.0.758",
53
+ "@teambit/component": "0.0.758",
54
+ "@teambit/graphql": "0.0.758",
55
+ "@teambit/aspect-loader": "0.0.758",
56
+ "@teambit/bundler": "0.0.758",
57
+ "@teambit/community": "0.0.49",
58
+ "@teambit/envs": "0.0.758",
59
+ "@teambit/pubsub": "0.0.758",
60
+ "@teambit/ui": "0.0.758",
61
+ "@teambit/variants": "0.0.597",
62
+ "@teambit/component-issues": "0.0.54",
63
+ "@teambit/config": "0.0.514",
63
64
  "@teambit/harmony.modules.requireable-component": "0.0.484",
64
- "@teambit/importer": "0.0.184",
65
- "@teambit/lane-id": "0.0.17",
65
+ "@teambit/importer": "0.0.187",
66
+ "@teambit/lane-id": "0.0.20",
66
67
  "@teambit/workspace.modules.match-pattern": "0.0.489",
67
- "@teambit/component.ui.component-drawer": "0.0.44",
68
+ "@teambit/component.ui.component-drawer": "0.0.47",
68
69
  "@teambit/design.ui.tree": "0.0.5",
69
- "@teambit/ui-foundation.ui.side-bar": "0.0.562",
70
- "@teambit/command-bar": "0.0.755",
70
+ "@teambit/ui-foundation.ui.side-bar": "0.0.565",
71
+ "@teambit/command-bar": "0.0.758",
71
72
  "@teambit/component.ui.component-filters": "0.0.5",
72
- "@teambit/graph": "0.0.755",
73
- "@teambit/sidebar": "0.0.755",
73
+ "@teambit/graph": "0.0.758",
74
+ "@teambit/sidebar": "0.0.758",
74
75
  "@teambit/ui-foundation.ui.main-dropdown": "0.0.487",
75
76
  "@teambit/ui-foundation.ui.menu": "0.0.487",
76
77
  "@teambit/ui-foundation.ui.react-router.slot-router": "0.0.490",
77
78
  "@teambit/ui-foundation.ui.tree.drawer": "0.0.499",
78
79
  "@teambit/toolbox.time.time-format": "0.0.483",
79
80
  "@teambit/ui-foundation.ui.hooks.use-data-query": "0.0.487",
80
- "@teambit/component-descriptor": "0.0.60",
81
- "@teambit/deprecation": "0.0.755",
81
+ "@teambit/component-descriptor": "0.0.63",
82
+ "@teambit/deprecation": "0.0.758",
82
83
  "@teambit/ui-foundation.ui.constants.z-indexes": "0.0.487",
83
84
  "@teambit/ui-foundation.ui.buttons.collapser": "0.0.194",
84
85
  "@teambit/ui-foundation.ui.corner": "0.0.498",
@@ -105,7 +106,7 @@
105
106
  "peerDependencies": {
106
107
  "react-router-dom": "^6.0.0",
107
108
  "@apollo/client": "^3.0.0",
108
- "@teambit/legacy": "1.0.278",
109
+ "@teambit/legacy": "1.0.281",
109
110
  "react-dom": "^16.8.0 || ^17.0.0",
110
111
  "react": "^16.8.0 || ^17.0.0"
111
112
  },
@@ -133,7 +134,7 @@
133
134
  "react": "-"
134
135
  },
135
136
  "peerDependencies": {
136
- "@teambit/legacy": "1.0.278",
137
+ "@teambit/legacy": "1.0.281",
137
138
  "react-dom": "^16.8.0 || ^17.0.0",
138
139
  "react": "^16.8.0 || ^17.0.0"
139
140
  }
@@ -1,2 +1,2 @@
1
- export const compositions = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace@0.0.755/dist/workspace.composition.js')]
2
- export const overview = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace@0.0.755/dist/workspace.docs.mdx')]
1
+ export const compositions = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace@0.0.758/dist/workspace.composition.js')]
2
+ export const overview = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace@0.0.758/dist/workspace.docs.mdx')]
@@ -0,0 +1,17 @@
1
+ import PQueue from 'p-queue';
2
+
3
+ export class WatchQueue {
4
+ private queue: PQueue;
5
+ constructor(concurrency = 1) {
6
+ this.queue = new PQueue({ concurrency, autoStart: true });
7
+ }
8
+ getQueue() {
9
+ return this.queue;
10
+ }
11
+ add<T>(fn: () => T, priority?: number): Promise<T> {
12
+ return this.queue.add(fn, { priority });
13
+ }
14
+ onIdle(): Promise<void> {
15
+ return this.queue.onIdle();
16
+ }
17
+ }
package/watch/watcher.ts CHANGED
@@ -20,6 +20,7 @@ import { OnComponentChangeEvent, OnComponentAddEvent, OnComponentRemovedEvent }
20
20
  import { Workspace } from '../workspace';
21
21
  import { OnComponentEventResult } from '../on-component-events';
22
22
  import { CheckTypes } from './check-types';
23
+ import { WatchQueue } from './watch-queue';
23
24
 
24
25
  export type WatcherProcessData = { watchProcess: ChildProcess; compilerId: BitId; componentIds: BitId[] };
25
26
 
@@ -47,6 +48,8 @@ const DEBOUNCE_WAIT_MS = 100;
47
48
  export class Watcher {
48
49
  private fsWatcher: FSWatcher;
49
50
  private changedFilesPerComponent: { [componentId: string]: string[] } = {};
51
+ private watchQueue = new WatchQueue();
52
+ private bitMapChangesInProgress = false;
50
53
  constructor(
51
54
  private workspace: Workspace,
52
55
  private pubsub: PubsubMain,
@@ -111,6 +114,7 @@ export class Watcher {
111
114
  }
112
115
 
113
116
  /**
117
+ * *** DEBOUNCING ***
114
118
  * some actions trigger multiple files changes at (almost) the same time. e.g. "git pull".
115
119
  * this causes some performance and instability issues. a debouncing mechanism was implemented to help with this.
116
120
  * the way how it works is that the first file of the same component starts the execution with a delay (e.g. 200ms).
@@ -125,6 +129,24 @@ export class Watcher {
125
129
  * B) it debounces the method regardless the param passes to it. so it'll disregard the component-id and will delay
126
130
  * other components undesirably.
127
131
  *
132
+ * *** QUEUE ***
133
+ * the debouncing helps to not execute the same component multiple times concurrently. however, multiple components
134
+ * and .bitmap changes execution can still be processed concurrently.
135
+ * the following example explains why this is an issue.
136
+ * compA is changed in the .bitmap file from version 0.0.1 to 0.0.2. its files were changed as well.
137
+ * all these changes get pulled at the same time by "git pull", as a result, the execution of compA and the .bitmap
138
+ * happen at the same time.
139
+ * during the execution of compA, the component id is parsed as compA@0.0.1, later, it asks for the Workspace for this
140
+ * id. while the workspace is looking for this id, the .bitmap execution reloaded the consumer and changed all versions.
141
+ * after this change, the workspace doesn't have this id anymore, which will trigger an error.
142
+ * to ensure this won't happen, we keep a flag to indicate whether the .bitmap execution is running, and if so, all
143
+ * other executions are paused until the queue is empty (this is done by awaiting for queue.onIdle).
144
+ * once the queue is empty, we know the .bitmap process was done and the workspace has all new ids.
145
+ * in the example above, at this stage, the id will be resolved to compA@0.0.2.
146
+ * one more thing, the queue is configured to have concurrency of 1. to make sure two components are not processed at
147
+ * the same time. (the same way is done when loading all components from the filesystem/scope).
148
+ * this way we can also ensure that if compA was started before the .bitmap execution, it will complete before the
149
+ * .bitmap execution starts.
128
150
  */
129
151
  private async handleChange(
130
152
  filePath: string,
@@ -137,10 +159,15 @@ export class Watcher {
137
159
  }> {
138
160
  try {
139
161
  if (filePath.endsWith(BIT_MAP)) {
140
- const buildResults = await this.handleBitmapChanges();
162
+ this.bitMapChangesInProgress = true;
163
+ const buildResults = await this.watchQueue.add(() => this.handleBitmapChanges());
164
+ this.bitMapChangesInProgress = false;
141
165
  loader.stop();
142
166
  return { results: buildResults, files: [filePath] };
143
167
  }
168
+ if (this.bitMapChangesInProgress) {
169
+ await this.watchQueue.onIdle();
170
+ }
144
171
  const componentId = this.getComponentIdByPath(filePath);
145
172
  if (!componentId) {
146
173
  const failureMsg = `file ${filePath} is not part of any component, ignoring it`;
@@ -148,7 +175,6 @@ export class Watcher {
148
175
  loader.stop();
149
176
  return { results: [], files: [filePath], failureMsg };
150
177
  }
151
-
152
178
  const compIdStr = componentId.toString();
153
179
  if (this.changedFilesPerComponent[compIdStr]) {
154
180
  this.changedFilesPerComponent[compIdStr].push(filePath);
@@ -160,7 +186,7 @@ export class Watcher {
160
186
  const files = this.changedFilesPerComponent[compIdStr];
161
187
  delete this.changedFilesPerComponent[compIdStr];
162
188
 
163
- const buildResults = await this.triggerCompChanges(componentId, files, initiator);
189
+ const buildResults = await this.watchQueue.add(() => this.triggerCompChanges(componentId, files, initiator));
164
190
  const failureMsg = buildResults.length
165
191
  ? undefined
166
192
  : `files ${files.join(', ')} are inside the component ${compIdStr} but configured to be ignored`;