@nu-art/build-and-install 0.204.98 → 0.204.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nu-art/build-and-install",
3
- "version": "0.204.98",
3
+ "version": "0.204.100",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "TacB0sS",
@@ -8,6 +8,7 @@ export declare class PhaseRunnerDispatcher<T, K extends FunctionKeys<T> = Functi
8
8
  addListener(listener: any): void;
9
9
  removeListener(listener: any): void;
10
10
  dispatch(...data: P): void;
11
+ dispatchAsync(...data: P): Promise<void>;
11
12
  }
12
13
  export interface PhaseRunner_OnPhaseChange {
13
14
  __onPhaseChange: (data: Phase<string>) => void;
@@ -23,6 +23,13 @@ class PhaseRunnerDispatcher {
23
23
  (_a = listener[this.method]) === null || _a === void 0 ? void 0 : _a.call(listener, ...data);
24
24
  });
25
25
  }
26
+ async dispatchAsync(...data) {
27
+ await Promise.all(this.listeners.map(async (listener) => {
28
+ var _a;
29
+ // @ts-ignore
30
+ return (_a = listener[this.method]) === null || _a === void 0 ? void 0 : _a.call(listener, ...data);
31
+ }));
32
+ }
26
33
  }
27
34
  exports.PhaseRunnerDispatcher = PhaseRunnerDispatcher;
28
35
  exports.dispatcher_PhaseChange = new PhaseRunnerDispatcher('__onPhaseChange');
@@ -1,6 +1,6 @@
1
- import { ConsoleContainer } from '@nu-art/commando/console/ConsoleContainer';
2
1
  import { AsyncVoidFunction } from '@nu-art/ts-common';
3
- export declare abstract class BAIScreen<State extends {} = {}> extends ConsoleContainer<'screen', State> {
2
+ import { ConsoleScreen } from '@nu-art/commando/console/ConsoleScreen';
3
+ export declare abstract class BAIScreen<State extends {} = {}> extends ConsoleScreen<State> {
4
4
  private onKillCallback?;
5
5
  private logClient;
6
6
  /**
@@ -11,6 +11,7 @@ export declare abstract class BAIScreen<State extends {} = {}> extends ConsoleCo
11
11
  */
12
12
  constructor(logClientKey: string);
13
13
  private createLogClient;
14
+ protected abstract scrollLog(direction: number): void;
14
15
  protected abstract onLogUpdated: () => void;
15
16
  protected getLogs: () => string;
16
17
  startScreen: () => void;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BAIScreen = void 0;
4
- const ConsoleContainer_1 = require("@nu-art/commando/console/ConsoleContainer");
5
4
  const ts_common_1 = require("@nu-art/ts-common");
6
5
  const PhaseRunnerDispatcher_1 = require("../phase-runner/PhaseRunnerDispatcher");
7
- class BAIScreen extends ConsoleContainer_1.ConsoleContainer {
6
+ const ConsoleScreen_1 = require("@nu-art/commando/console/ConsoleScreen");
7
+ class BAIScreen extends ConsoleScreen_1.ConsoleScreen {
8
8
  //######################### Initialization #########################
9
9
  /**
10
10
  * Creates an instance of ConsoleScreen.
@@ -13,10 +13,24 @@ class BAIScreen extends ConsoleContainer_1.ConsoleContainer {
13
13
  * @param {ScreenKeyBinding[]} [keyBinding] - An array of key bindings for the screen widget.
14
14
  */
15
15
  constructor(logClientKey) {
16
- super('screen', { smartCSR: true, title: 'Build and Install' }, [{
16
+ super({ smartCSR: true, title: 'Build and Install' }, [
17
+ {
17
18
  keys: ['escape', 'q', 'C-c'],
18
19
  callback: async () => await this.onKill(),
19
- }]);
20
+ },
21
+ {
22
+ keys: ['up'],
23
+ callback: () => {
24
+ this.scrollLog(-1);
25
+ },
26
+ },
27
+ {
28
+ keys: ['down'],
29
+ callback: () => {
30
+ this.scrollLog(1);
31
+ },
32
+ },
33
+ ]);
20
34
  this.getLogs = () => this.logClient.buffers[0];
21
35
  this.startScreen = () => {
22
36
  //Start listening on dispatchers
@@ -38,6 +52,7 @@ class BAIScreen extends ConsoleContainer_1.ConsoleContainer {
38
52
  this.container.destroy();
39
53
  };
40
54
  this.setOnKillCallback = (cb) => this.onKillCallback = cb;
55
+ this.scrollLog.bind(this);
41
56
  this.createLogClient(logClientKey);
42
57
  }
43
58
  createLogClient(logClientKey) {
@@ -2,16 +2,20 @@ import { BAIScreen } from './BAIScreen';
2
2
  import { BaseUnit } from '../unit/core';
3
3
  import { PhaseRunner_OnUnitsChange } from '../phase-runner/PhaseRunnerDispatcher';
4
4
  export declare class BAIScreen_Launch extends BAIScreen implements PhaseRunner_OnUnitsChange {
5
- private units;
5
+ private allUnits;
6
+ private focusUnits;
6
7
  private gridDimensions;
7
8
  private withRunningLogs;
8
9
  private gridCellWidgets;
9
10
  constructor();
10
11
  __onUnitsChange: (data: BaseUnit[]) => void;
12
+ private rebuildScreens;
11
13
  protected onLogUpdated: () => void;
12
14
  private updateUnits;
13
15
  protected createContent(): void;
16
+ protected scrollLog(direction: number): void;
14
17
  private createGridWidgets;
18
+ private toggleFullScreenMode;
15
19
  private calculateGridDimensions;
16
20
  private getGridWidgetLabel;
17
21
  protected destroyContent(): void;
@@ -4,30 +4,32 @@ exports.BAIScreen_Launch = void 0;
4
4
  const BAIScreen_1 = require("./BAIScreen");
5
5
  const consts_1 = require("../phase-runner/consts");
6
6
  const firebase_units_1 = require("../unit/firebase-units");
7
+ const ts_common_1 = require("@nu-art/ts-common");
7
8
  class BAIScreen_Launch extends BAIScreen_1.BAIScreen {
8
9
  //######################### Lifecycle #########################
9
10
  constructor() {
10
11
  super('bai-launch');
11
12
  //######################### Properties #########################
12
- this.units = [];
13
+ this.allUnits = [];
14
+ this.focusUnits = [];
13
15
  this.gridDimensions = [[{ width: 1, height: 1 }]];
14
16
  this.withRunningLogs = false;
15
17
  //Widgets
16
18
  this.gridCellWidgets = [];
17
19
  this.__onUnitsChange = (data) => {
18
20
  this.updateUnits();
19
- this.createGridWidgets();
20
- this.renderGridWidgets();
21
- this.container.screen.render();
21
+ this.rebuildScreens();
22
22
  };
23
23
  this.onLogUpdated = () => {
24
24
  this.renderGridWidgets();
25
25
  };
26
26
  this.updateUnits = () => {
27
27
  const runner = consts_1.MemKey_PhaseRunner.get();
28
- this.units = runner.getUnits().filter(unit => {
28
+ this.allUnits = runner.getUnits().filter(unit => {
29
29
  return unit.isInstanceOf(firebase_units_1.Unit_FirebaseHostingApp) || unit.isInstanceOf(firebase_units_1.Unit_FirebaseFunctionsApp);
30
30
  });
31
+ if (!this.focusUnits.length)
32
+ this.focusUnits = this.allUnits;
31
33
  };
32
34
  this.createGridWidgets = () => {
33
35
  this.destroyGridWidgets();
@@ -47,27 +49,40 @@ class BAIScreen_Launch extends BAIScreen_1.BAIScreen {
47
49
  label: this.getGridWidgetLabel(widgetIndex),
48
50
  border: { type: 'line' },
49
51
  style: {
50
- border: { fg: 'blue' },
52
+ hover: { border: { fg: 'blue' } },
53
+ border: { fg: 'gray' },
54
+ focus: { border: { fg: 'green' } }
51
55
  },
52
56
  valign: 'top',
53
57
  align: 'left',
54
- mouse: true,
58
+ interactive: true,
59
+ focusable: true,
55
60
  };
56
- this.gridCellWidgets.push(this.createWidget('log', props));
61
+ const logWidget = this.createWidget('log', props);
62
+ let doubleClickTimestamp = 0;
63
+ const unitIndex = widgetIndex;
64
+ logWidget.on('mouse', (event) => {
65
+ if (!(event.button === 'middle' && event.action === 'mouseup'))
66
+ return;
67
+ if ((0, ts_common_1.currentTimeMillis)() - doubleClickTimestamp < 500) {
68
+ return this.toggleFullScreenMode(unitIndex);
69
+ }
70
+ doubleClickTimestamp = (0, ts_common_1.currentTimeMillis)();
71
+ });
72
+ this.gridCellWidgets.push(logWidget);
57
73
  yPos += height; //Assuming all cells in a column have the same height
58
74
  widgetIndex++;
59
75
  });
60
76
  xPos += col[0].width * 100; //Assuming all Cells have the same width
61
77
  });
62
78
  };
63
- this.calculateGridDimensions = () => {
64
- let n = this.units.length;
79
+ this.calculateGridDimensions = (count = this.focusUnits.length) => {
65
80
  //Add 1 more window for running logs
66
81
  if (this.withRunningLogs)
67
- n++;
82
+ count++;
68
83
  const grid = [];
69
- const columns = Math.ceil(Math.sqrt(n)); // Calculate number of columns
70
- let remainingItems = n;
84
+ const columns = Math.ceil(Math.sqrt(count)); // Calculate number of columns
85
+ let remainingItems = count;
71
86
  for (let col = 0; col < columns; col++) {
72
87
  const column = [];
73
88
  const itemsInThisColumn = Math.ceil(remainingItems / (columns - col));
@@ -82,22 +97,25 @@ class BAIScreen_Launch extends BAIScreen_1.BAIScreen {
82
97
  };
83
98
  this.getGridWidgetLabel = (index) => {
84
99
  if (!this.withRunningLogs)
85
- return this.units[index].config.label;
86
- return index === this.units.length ? 'Running Logs' : this.units[index].config.label;
100
+ return this.focusUnits[index].config.label;
101
+ return index === this.focusUnits.length ? 'Running Logs' : this.focusUnits[index].config.label;
87
102
  };
88
103
  this.destroyGridWidgets = () => {
89
104
  this.gridCellWidgets.forEach(widget => widget.destroy());
105
+ this.gridCellWidgets.length = 0;
90
106
  };
91
107
  this.getContentForWidget = (widgetIndex) => {
92
108
  var _a, _b;
93
109
  if (!this.withRunningLogs) {
94
- const unit = this.units[widgetIndex];
110
+ const unit = this.focusUnits[widgetIndex];
111
+ if (!unit)
112
+ throw new ts_common_1.WhoCallThisException(`focusedUnits: ${this.focusUnits.length}[${widgetIndex}]`);
95
113
  return (_a = unit.getLogs()) !== null && _a !== void 0 ? _a : `No logs for unit ${unit.config.label}`;
96
114
  }
97
115
  //With running logs, last index should return the running logs
98
- if (widgetIndex === this.units.length)
116
+ if (widgetIndex === this.focusUnits.length)
99
117
  return this.getLogs();
100
- const unit = this.units[widgetIndex];
118
+ const unit = this.focusUnits[widgetIndex];
101
119
  return (_b = unit.getLogs()) !== null && _b !== void 0 ? _b : `No logs for unit ${unit.config.label}`;
102
120
  };
103
121
  this.renderGridWidgets = () => {
@@ -111,11 +129,29 @@ class BAIScreen_Launch extends BAIScreen_1.BAIScreen {
111
129
  //######################### Options #########################
112
130
  this.setWithRunningLogs = (val) => this.withRunningLogs = val;
113
131
  }
132
+ rebuildScreens() {
133
+ this.createGridWidgets();
134
+ this.renderGridWidgets();
135
+ this.container.screen.render();
136
+ }
114
137
  //######################### Content Creation #########################
115
138
  createContent() {
116
139
  this.updateUnits();
117
140
  this.createGridWidgets();
118
141
  }
142
+ scrollLog(direction) {
143
+ var _a;
144
+ const focusedWidget = this.getFocusedWidget();
145
+ // @ts-ignore
146
+ (_a = this.gridCellWidgets.find(log => log._label.content === focusedWidget._label.content)) === null || _a === void 0 ? void 0 : _a.scroll(direction);
147
+ }
148
+ toggleFullScreenMode(unitIndex) {
149
+ if (this.focusUnits.length !== this.allUnits.length)
150
+ this.focusUnits = this.allUnits;
151
+ else
152
+ this.focusUnits = [this.allUnits[unitIndex]];
153
+ this.rebuildScreens();
154
+ }
119
155
  //######################### Content Destruction #########################
120
156
  destroyContent() {
121
157
  this.destroyGridWidgets();
@@ -124,7 +160,7 @@ class BAIScreen_Launch extends BAIScreen_1.BAIScreen {
124
160
  render() {
125
161
  this.renderGridWidgets();
126
162
  this.logInfo('GRID DIMENSIONS', this.gridDimensions);
127
- this.logInfo('UNITS', this.units.map(unit => unit.config.label));
163
+ this.logInfo('UNITS', this.focusUnits.map(unit => unit.config.label));
128
164
  this.logInfo('RUNNER UNITS', consts_1.MemKey_PhaseRunner.get().getUnits().map(unit => unit.config.label));
129
165
  }
130
166
  }
@@ -17,6 +17,7 @@ export declare class BAIScreen_UnitList extends BAIScreen<State> implements Phas
17
17
  __onUnitStatusChange(unit: BaseUnit): void;
18
18
  __onUnitsChange(data: BaseUnit[]): void;
19
19
  protected onLogUpdated: () => void;
20
+ protected scrollLog(direction: number): void;
20
21
  protected destroyContent(): void;
21
22
  private destroyPhaseWidget;
22
23
  private destroyUnitListWidget;
@@ -28,6 +28,14 @@ class BAIScreen_UnitList extends BAIScreen_1.BAIScreen {
28
28
  this.createUnitListWidget();
29
29
  this.renderUnitList();
30
30
  }
31
+ scrollLog(direction) {
32
+ // const focusedWidget = this.getFocusedWidget();
33
+ // @ts-ignore
34
+ // console.log(`ZEVEL ${focusedWidget.type}`);
35
+ // if (focusedWidget !== this.logWidget)
36
+ // return;
37
+ this.logWidget.scroll(direction);
38
+ }
31
39
  //######################### Content Destruction #########################
32
40
  destroyContent() {
33
41
  this.destroyPhaseWidget();
@@ -69,7 +77,6 @@ class BAIScreen_UnitList extends BAIScreen_1.BAIScreen {
69
77
  },
70
78
  align: 'center',
71
79
  label: 'phase',
72
- mouse: true
73
80
  };
74
81
  this.phaseWidget = this.createWidget('text', props);
75
82
  this.phaseWidget.on('mouse', (event) => {
@@ -142,9 +149,16 @@ class BAIScreen_UnitList extends BAIScreen_1.BAIScreen {
142
149
  style: {
143
150
  border: { fg: 'blue' }
144
151
  },
145
- valign: 'top',
146
- align: 'left',
147
- mouse: true,
152
+ scrollbar: {
153
+ ch: ' ',
154
+ track: {
155
+ bg: 'grey',
156
+ },
157
+ style: {
158
+ inverse: true,
159
+ },
160
+ },
161
+ interactive: true // This is typically required for focus management
148
162
  };
149
163
  this.logWidget = this.createWidget('log', props);
150
164
  }
@@ -172,10 +186,10 @@ class BAIScreen_UnitList extends BAIScreen_1.BAIScreen {
172
186
  });
173
187
  }
174
188
  renderLogs() {
175
- const scrollPosition = this.logWidget.getScroll();
189
+ var _a, _b;
176
190
  const content = this.state.selectedUnit ? this.state.selectedUnit.getLogs() : this.getLogs();
191
+ this.logWidget.setLabel(` ${(_b = (_a = this.state.selectedUnit) === null || _a === void 0 ? void 0 : _a.config.label) !== null && _b !== void 0 ? _b : 'All Logs'} `);
177
192
  this.logWidget.setContent(content);
178
- this.logWidget.setScroll(scrollPosition);
179
193
  }
180
194
  //######################### Events #########################
181
195
  onUnitSelect(unit, index) {
@@ -186,3 +200,4 @@ class BAIScreen_UnitList extends BAIScreen_1.BAIScreen {
186
200
  }
187
201
  }
188
202
  exports.BAIScreen_UnitList = BAIScreen_UnitList;
203
+ // /Users/tacb0ss/.nvm/versions/node/v18.15.0/bin/ts-node -P /Users/tacb0ss/dev/quai/test/quai-web/_thunderstorm/commando/src/test/tsconfig.json /Users/tacb0ss/dev/quai/test/quai-web/_thunderstorm/commando/src/test/console/controlled-scroll/run.ts
@@ -100,9 +100,11 @@ class BaseUnit extends ts_common_1.Logger {
100
100
  async kill() {
101
101
  if (!this.processTerminator.length)
102
102
  return this.setStatus('Killed');
103
+ const processTerminator = [...this.processTerminator];
104
+ this.processTerminator.length = 0;
103
105
  this.setStatus('Killing');
104
106
  try {
105
- await Promise.all(this.processTerminator.map(toTerminate => toTerminate()));
107
+ await Promise.all(processTerminator.map(toTerminate => toTerminate()));
106
108
  }
107
109
  finally {
108
110
  this.setStatus('Killed');
@@ -60,7 +60,12 @@ class Unit_Typescript extends BaseUnit_1.BaseUnit {
60
60
  const templatePath = `${unitRootPath}/${consts_1.CONST_PackageJSONTemplate}`;
61
61
  if (!fs.existsSync(templatePath))
62
62
  throw new ts_common_1.BadImplementationException(`Missing __package.json file in root for unit ${this.config.label}`);
63
- this.packageJson.template = JSON.parse(await fs_1.promises.readFile(templatePath, 'utf-8'));
63
+ try {
64
+ this.packageJson.template = JSON.parse(await fs_1.promises.readFile(templatePath, 'utf-8'));
65
+ }
66
+ catch (e) {
67
+ throw new ts_common_1.BadImplementationException(`There is an issue in the __package.json file in root for unit ${this.config.label}`);
68
+ }
64
69
  }
65
70
  /**
66
71
  * Create a packageJson object for each target key
@@ -1,7 +1,7 @@
1
1
  import { Unit_Typescript, Unit_Typescript_Config, Unit_Typescript_RuntimeConfig } from './Unit_Typescript';
2
- import { UnitPhaseImplementor, WatchEventType } from '../types';
2
+ import { UnitPhaseImplementor } from '../types';
3
3
  import { Phase_CheckCyclicImports, Phase_Compile, Phase_Lint, Phase_PreCompile, Phase_PrintDependencyTree, Phase_Purge } from '../../phase';
4
- import { OnWatchEvent } from '../runner-dispatchers';
4
+ import { OnWatchReady } from '../runner-dispatchers';
5
5
  export type Unit_TypescriptLib_Config = Unit_Typescript_Config & {
6
6
  customTSConfig?: boolean;
7
7
  output: string;
@@ -19,23 +19,26 @@ export declare class Unit_TypescriptLib<C extends Unit_TypescriptLib_Config = Un
19
19
  Phase_CheckCyclicImports,
20
20
  Phase_Purge,
21
21
  Phase_Lint
22
- ]>, OnWatchEvent {
23
- private debounceWatch?;
22
+ ]>, OnWatchReady {
24
23
  constructor(config: Unit_TypescriptLib<C, RTC>['config']);
25
- __onWatchEvent(type: WatchEventType, path?: string): Promise<void>;
24
+ __onWatchReady(): Promise<void>;
26
25
  protected init(setInitialized?: boolean): Promise<void>;
27
26
  protected resolveTSConfig(): Promise<void>;
28
27
  protected clearOutputDir(): Promise<void>;
29
28
  protected compileImpl(): Promise<void>;
30
29
  protected copyAssetsToOutput(): Promise<void>;
31
30
  protected copyPackageJSONToOutput(): Promise<void>;
32
- protected handleWatchChange(path: string, shouldRemoveDist?: boolean): Promise<void>;
31
+ /**
32
+ * Watch compile actions, use this to perform all necessary compile actions for watch.
33
+ * watch compile is a subset of the general watch action
34
+ */
35
+ watchCompile(): Promise<void>;
33
36
  /**
34
37
  * Remove the deleted file/folder from the dist folder on watch remove file event
35
38
  * @param path The path of the currently removed file/folder
36
39
  * @private
37
40
  */
38
- private removeSpecificFileFromDist;
41
+ removeSpecificFileFromDist(path: string): Promise<void>;
39
42
  preCompile(): Promise<void>;
40
43
  compile(): Promise<void>;
41
44
  purge(): Promise<void>;
@@ -32,7 +32,6 @@ const RunnerParams_1 = require("../../phase-runner/RunnerParams");
32
32
  const consts_1 = require("../../../core/consts");
33
33
  const params_1 = require("../../../core/params/params");
34
34
  const runner_dispatchers_1 = require("../runner-dispatchers");
35
- const consts_2 = require("../consts");
36
35
  const CliError_1 = require("@nu-art/commando/shell/core/CliError");
37
36
  const nvm_1 = require("@nu-art/commando/shell/plugins/nvm");
38
37
  const basic_1 = require("@nu-art/commando/shell/plugins/basic");
@@ -52,17 +51,12 @@ class Unit_TypescriptLib extends Unit_Typescript_1.Unit_Typescript {
52
51
  super(config);
53
52
  this.addToClassStack(Unit_TypescriptLib);
54
53
  }
55
- async __onWatchEvent(type, path) {
56
- if (type === consts_2.WatchEvent_Ready)
57
- return this.setStatus('Watching');
58
- if (this.debounceWatch)
59
- delete this.debounceWatch;
60
- this.debounceWatch = (0, ts_common_1.debounce)(() => this.handleWatchChange(path, [consts_2.WatchEvent_RemoveFile, consts_2.WatchEvent_RemoveDir].includes(type)), ts_common_1.Second * 2, ts_common_1.Second * 10);
61
- this.debounceWatch();
54
+ async __onWatchReady() {
55
+ return this.setStatus('Watching');
62
56
  }
63
57
  async init(setInitialized = true) {
64
58
  await super.init(false);
65
- runner_dispatchers_1.dispatcher_WatchEvent.addListener(this);
59
+ runner_dispatchers_1.dispatcher_WatchReady.addListener(this);
66
60
  this.runtime.pathTo.output = this.runtime.pathTo.pkg + `/${this.config.output}`;
67
61
  if (setInitialized)
68
62
  this.setStatus('Initialized');
@@ -131,15 +125,13 @@ class Unit_TypescriptLib extends Unit_Typescript_1.Unit_Typescript {
131
125
  const fileContent = JSON.stringify(this.packageJson.dist, null, 2);
132
126
  await fs_1.promises.writeFile(targetPath, fileContent, { encoding: 'utf-8' });
133
127
  }
134
- async handleWatchChange(path, shouldRemoveDist = false) {
135
- // ignore if path doesn't related to unit
136
- if (!path.startsWith(this.config.pathToPackage))
137
- return;
128
+ /**
129
+ * Watch compile actions, use this to perform all necessary compile actions for watch.
130
+ * watch compile is a subset of the general watch action
131
+ */
132
+ async watchCompile() {
138
133
  try {
139
134
  this.setStatus('Compiling', 'start');
140
- // check if dist folder must be cleared
141
- if (shouldRemoveDist)
142
- await this.removeSpecificFileFromDist(path);
143
135
  // perform all watch actions
144
136
  await this.compileImpl();
145
137
  await this.copyAssetsToOutput();
@@ -148,8 +140,6 @@ class Unit_TypescriptLib extends Unit_Typescript_1.Unit_Typescript {
148
140
  catch (e) {
149
141
  this.setStatus(`Watching with error`, e);
150
142
  }
151
- // dispatch unit post compile
152
- runner_dispatchers_1.dispatcher_UnitWatchCompile.dispatch(this);
153
143
  }
154
144
  /**
155
145
  * Remove the deleted file/folder from the dist folder on watch remove file event
@@ -157,6 +147,7 @@ class Unit_TypescriptLib extends Unit_Typescript_1.Unit_Typescript {
157
147
  * @private
158
148
  */
159
149
  async removeSpecificFileFromDist(path) {
150
+ this.setStatus('Removing files from dist', 'start');
160
151
  const distPathBase = path.replace('src/main', 'dist').replace(/\.ts$/, '');
161
152
  const pathsToDelete = [
162
153
  `${distPathBase}.js`,
@@ -172,6 +163,7 @@ class Unit_TypescriptLib extends Unit_Typescript_1.Unit_Typescript {
172
163
  }
173
164
  await fs_1.promises.rm(path, { recursive: true, force: true });
174
165
  }
166
+ this.setStatus('Files Removed and watching', 'end');
175
167
  }
176
168
  //######################### Phase Implementations #########################
177
169
  async preCompile() {
@@ -7,6 +7,7 @@ type Unit_TypescriptProject_Config = Unit_Typescript_Config & {
7
7
  };
8
8
  type Unit_TypescriptProject_RuntimeConfig = Unit_Typescript_RuntimeConfig & {};
9
9
  export declare class Unit_TypescriptProject<C extends Unit_TypescriptProject_Config = Unit_TypescriptProject_Config, RTC extends Unit_TypescriptProject_RuntimeConfig = Unit_TypescriptProject_RuntimeConfig> extends Unit_Typescript<C, RTC> implements UnitPhaseImplementor<[Phase_Install, Phase_Watch]> {
10
+ private watchDebounce;
10
11
  private readonly suffixesToWatch;
11
12
  constructor(config: Unit_TypescriptProject<C>['config']);
12
13
  private installGlobals;
@@ -22,6 +23,7 @@ export declare class Unit_TypescriptProject<C extends Unit_TypescriptProject_Con
22
23
  * @private
23
24
  */
24
25
  private initWatch;
26
+ private findUnit;
25
27
  private watchImpl;
26
28
  install(): Promise<void>;
27
29
  watch(): Promise<void>;
@@ -30,7 +30,6 @@ const ts_common_1 = require("@nu-art/ts-common");
30
30
  const consts_1 = require("../../phase-runner/consts");
31
31
  const chokidar = __importStar(require("chokidar"));
32
32
  const runner_dispatchers_1 = require("../runner-dispatchers");
33
- const consts_2 = require("../consts");
34
33
  const Unit_TypescriptLib_1 = require("./Unit_TypescriptLib");
35
34
  const firebase_units_1 = require("../firebase-units");
36
35
  const nvm_1 = require("@nu-art/commando/shell/plugins/nvm");
@@ -46,6 +45,13 @@ class Unit_TypescriptProject extends Unit_Typescript_1.Unit_Typescript {
46
45
  'json',
47
46
  'svg'
48
47
  ];
48
+ this.findUnit = (pathDeclarations, currentPath) => {
49
+ var _a;
50
+ const unitToReturn = (_a = pathDeclarations.find(declaration => currentPath.startsWith(declaration.pathToPackage))) === null || _a === void 0 ? void 0 : _a.unit;
51
+ if (!unitToReturn)
52
+ throw new ts_common_1.MUSTNeverHappenException(`current path doesnt match any declared unit, current path: ${currentPath}`);
53
+ return unitToReturn;
54
+ };
49
55
  this.addToClassStack(Unit_TypescriptProject);
50
56
  }
51
57
  //######################### Internal Logic #########################
@@ -86,8 +92,12 @@ class Unit_TypescriptProject extends Unit_Typescript_1.Unit_Typescript {
86
92
  .filter(unit => unit.isInstanceOf(Unit_TypescriptLib_1.Unit_TypescriptLib) && cantBeInstanceOf.every(_instance => !unit.isInstanceOf(_instance)));
87
93
  //return all paths to watch
88
94
  return projectLibs.map(lib => {
89
- const sourceFolder = `${lib.config.pathToPackage}/src/main`;
90
- return { paths: this.suffixesToWatch.map(suffix => `${sourceFolder}/**/*.${suffix}`), unit: lib };
95
+ const sourceFolder = `${lib.runtime.pathTo.pkg}/src/main`;
96
+ return {
97
+ paths: this.suffixesToWatch.map(suffix => `${sourceFolder}/**/*.${suffix}`),
98
+ unit: lib,
99
+ pathToPackage: lib.runtime.pathTo.pkg
100
+ };
91
101
  });
92
102
  }
93
103
  /**
@@ -101,25 +111,65 @@ class Unit_TypescriptProject extends Unit_Typescript_1.Unit_Typescript {
101
111
  // set all events to watch and handle them
102
112
  return new Promise((resolve, error) => {
103
113
  this.logInfo('Starting the watcher...');
114
+ const units = new Set();
115
+ const pathsToDelete = [];
116
+ const onUnitChange = (path) => {
117
+ const unit = this.findUnit(pathDeclarations, path);
118
+ // @ts-ignore - FIXME: should be a better way
119
+ unit.setStatus('dirty');
120
+ //add unit to set
121
+ units.add(unit);
122
+ return unit;
123
+ };
124
+ // set the debounce event
125
+ this.watchDebounce = (0, ts_common_1.queuedDebounce)(async () => {
126
+ const _pathsToDelete = [...pathsToDelete];
127
+ const unitsToCompile = Array.from(units.values());
128
+ // clear values in order to start collecting values for next debounce
129
+ (0, ts_common_1.clearArrayInstance)(pathsToDelete);
130
+ units.clear();
131
+ // fire all delete events
132
+ await (0, ts_common_1.Promise_all_sequentially)(_pathsToDelete.map(path => {
133
+ return async () => path.unit.removeSpecificFileFromDist(path.path);
134
+ }));
135
+ // fire all compile events
136
+ await (0, ts_common_1.Promise_all_sequentially)(unitsToCompile.map(unit => {
137
+ return async () => unit.watchCompile();
138
+ }));
139
+ //dispatch post debounce event to parent
140
+ await runner_dispatchers_1.dispatcher_UnitWatchCompile.dispatchAsync(unitsToCompile);
141
+ }, 2 * ts_common_1.Second, 10 * ts_common_1.Second);
104
142
  watcher
105
143
  .on('error', (error) => {
106
144
  this.logError('Error while watching', error);
107
145
  })
108
146
  .on('ready', () => {
109
147
  this.logInfo('Watching...');
110
- runner_dispatchers_1.dispatcher_WatchEvent.dispatch(consts_2.WatchEvent_Ready);
148
+ runner_dispatchers_1.dispatcher_WatchReady.dispatch();
111
149
  watcher
112
150
  .on('add', (path) => {
113
- runner_dispatchers_1.dispatcher_WatchEvent.dispatch(consts_2.WatchEvent_Add, path);
151
+ onUnitChange(path);
152
+ //trigger debounce
153
+ this.watchDebounce();
114
154
  })
115
155
  .on('change', (path) => {
116
- runner_dispatchers_1.dispatcher_WatchEvent.dispatch(consts_2.WatchEvent_Update, path);
156
+ onUnitChange(path);
157
+ //trigger debounce
158
+ this.watchDebounce();
117
159
  })
118
160
  .on('unlinkDir', (path) => {
119
- runner_dispatchers_1.dispatcher_WatchEvent.dispatch(consts_2.WatchEvent_RemoveDir, path);
161
+ const unit = onUnitChange(path);
162
+ //update paths to delete
163
+ pathsToDelete.push({ path, unit });
164
+ //trigger debounce
165
+ this.watchDebounce();
120
166
  })
121
167
  .on('unlink', (path) => {
122
- runner_dispatchers_1.dispatcher_WatchEvent.dispatch(consts_2.WatchEvent_RemoveFile, path);
168
+ const unit = onUnitChange(path);
169
+ //update paths to delete
170
+ pathsToDelete.push({ path, unit });
171
+ //trigger debounce
172
+ this.watchDebounce();
123
173
  });
124
174
  });
125
175
  const terminatable = async () => {
@@ -9,7 +9,7 @@ export type Unit_FirebaseFunctionsApp_Config = Unit_TypescriptLib_Config & {
9
9
  };
10
10
  export declare class Unit_FirebaseFunctionsApp<C extends Unit_FirebaseFunctionsApp_Config = Unit_FirebaseFunctionsApp_Config> extends Unit_TypescriptLib<C> implements UnitPhaseImplementor<[Phase_ResolveConfigs, Phase_Launch, Phase_DeployBackend]>, OnUnitWatchCompiled {
11
11
  static staggerCount: number;
12
- __onUnitWatchCompiled(unit: BaseUnit): Promise<void>;
12
+ __onUnitWatchCompiled(units: BaseUnit[]): Promise<void>;
13
13
  constructor(config: Unit_FirebaseFunctionsApp<C>['config']);
14
14
  protected init(setInitialized?: boolean): Promise<void>;
15
15
  resolveConfigs(): Promise<void>;
@@ -13,8 +13,8 @@ const runner_dispatchers_1 = require("../runner-dispatchers");
13
13
  const nvm_1 = require("@nu-art/commando/shell/plugins/nvm");
14
14
  const CONST_VersionApp = 'version-app.json';
15
15
  class Unit_FirebaseFunctionsApp extends core_1.Unit_TypescriptLib {
16
- async __onUnitWatchCompiled(unit) {
17
- if (this.runtime.unitDependencyNames.includes(unit.runtime.dependencyName)) {
16
+ async __onUnitWatchCompiled(units) {
17
+ if (units.some(unit => this.runtime.unitDependencyNames.includes(unit.runtime.dependencyName))) {
18
18
  this.setStatus('Compiling', 'start');
19
19
  try {
20
20
  await this.compileImpl();
@@ -36,7 +36,7 @@ class Unit_FirebaseFunctionsApp extends core_1.Unit_TypescriptLib {
36
36
  async init(setInitialized = true) {
37
37
  await super.init(false);
38
38
  // only sign on listeners when the unit is being initialized
39
- runner_dispatchers_1.dispatcher_WatchEvent.removeListener(this);
39
+ runner_dispatchers_1.dispatcher_WatchReady.removeListener(this);
40
40
  runner_dispatchers_1.dispatcher_UnitWatchCompile.addListener(this);
41
41
  if (setInitialized)
42
42
  this.setStatus('Initialized');
@@ -19,7 +19,7 @@ class Unit_FirebaseHostingApp extends core_1.Unit_TypescriptLib {
19
19
  }
20
20
  async init(setInitialized = true) {
21
21
  await super.init(setInitialized);
22
- runner_dispatchers_1.dispatcher_WatchEvent.removeListener(this);
22
+ runner_dispatchers_1.dispatcher_WatchReady.removeListener(this);
23
23
  if (!this.config.firebaseConfig.hostingPort)
24
24
  throw new ts_common_1.BadImplementationException(`Unit ${this.config.label} missing hosting port in firebaseConfig`);
25
25
  }
@@ -1,11 +1,10 @@
1
1
  import { PhaseRunnerDispatcher } from '../phase-runner/PhaseRunnerDispatcher';
2
- import { WatchEventType } from './types';
3
2
  import { BaseUnit } from './core';
4
- export interface OnWatchEvent {
5
- __onWatchEvent: (type: WatchEventType, path?: string) => void;
3
+ export interface OnWatchReady {
4
+ __onWatchReady: () => void;
6
5
  }
7
- export declare const dispatcher_WatchEvent: PhaseRunnerDispatcher<OnWatchEvent, "__onWatchEvent", [type: WatchEventType, path?: string | undefined]>;
6
+ export declare const dispatcher_WatchReady: PhaseRunnerDispatcher<OnWatchReady, "__onWatchReady", []>;
8
7
  export interface OnUnitWatchCompiled {
9
- __onUnitWatchCompiled: (init: BaseUnit) => void;
8
+ __onUnitWatchCompiled: (units: BaseUnit[]) => void;
10
9
  }
11
- export declare const dispatcher_UnitWatchCompile: PhaseRunnerDispatcher<OnUnitWatchCompiled, "__onUnitWatchCompiled", [init: BaseUnit<import("./core").BaseUnit_Config, import("./core").BaseUnit_RuntimeConfig>]>;
10
+ export declare const dispatcher_UnitWatchCompile: PhaseRunnerDispatcher<OnUnitWatchCompiled, "__onUnitWatchCompiled", [units: BaseUnit<import("./core").BaseUnit_Config, import("./core").BaseUnit_RuntimeConfig>[]]>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dispatcher_UnitWatchCompile = exports.dispatcher_WatchEvent = void 0;
3
+ exports.dispatcher_UnitWatchCompile = exports.dispatcher_WatchReady = void 0;
4
4
  const PhaseRunnerDispatcher_1 = require("../phase-runner/PhaseRunnerDispatcher");
5
- exports.dispatcher_WatchEvent = new PhaseRunnerDispatcher_1.PhaseRunnerDispatcher('__onWatchEvent');
5
+ exports.dispatcher_WatchReady = new PhaseRunnerDispatcher_1.PhaseRunnerDispatcher('__onWatchReady');
6
6
  exports.dispatcher_UnitWatchCompile = new PhaseRunnerDispatcher_1.PhaseRunnerDispatcher('__onUnitWatchCompiled');