@nu-art/build-and-install 0.400.14 → 0.401.1
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/BuildAndInstall.d.ts +40 -0
- package/BuildAndInstall.js +155 -0
- package/build-and-install-v3.d.ts +1 -32
- package/build-and-install-v3.js +1 -154
- package/build-and-install.js +11 -11
- package/config/consts.d.ts +43 -0
- package/config/consts.js +42 -0
- package/{core → config}/package/consts.d.ts +1 -1
- package/{core → config}/types/project-config.d.ts +3 -0
- package/core/FilesCache.d.ts +50 -0
- package/core/FilesCache.js +76 -0
- package/core/Unit_HelpPrinter.d.ts +16 -0
- package/core/Unit_HelpPrinter.js +47 -0
- package/core/params/params.d.ts +1 -41
- package/core/params/params.js +1 -334
- package/core/params.d.ts +50 -0
- package/core/params.js +441 -0
- package/{v3/core → core}/types.d.ts +1 -1
- package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.d.ts +21 -1
- package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.js +26 -3
- package/dependencies/types.d.ts +1 -0
- package/dependencies/types.js +1 -0
- package/exceptions/PhaseAggregatedException.d.ts +34 -0
- package/{core/exceptions → exceptions}/PhaseAggregatedException.js +26 -0
- package/exceptions/UnitPhaseException.d.ts +20 -0
- package/exceptions/UnitPhaseException.js +21 -0
- package/exports/ExportIndexCache.d.ts +25 -0
- package/exports/ExportIndexCache.js +115 -0
- package/exports/ExportMapper.d.ts +43 -0
- package/exports/ExportMapper.js +519 -0
- package/exports/IndicesMcpServer.d.ts +22 -0
- package/exports/IndicesMcpServer.js +220 -0
- package/exports/types.js +3 -0
- package/package.json +20 -9
- package/phases/PhaseManager.d.ts +130 -0
- package/phases/PhaseManager.js +267 -0
- package/{v3/phase → phases/definitions}/consts.d.ts +36 -0
- package/{v3/phase → phases/definitions}/consts.js +45 -2
- package/phases/definitions/types.d.ts +40 -0
- package/phases/index.d.ts +2 -0
- package/phases/index.js +2 -0
- package/run.js +10 -0
- package/runtime/RunningStatusHandler.d.ts +104 -0
- package/runtime/RunningStatusHandler.js +153 -0
- package/runtime/types.d.ts +1 -0
- package/runtime/types.js +2 -0
- package/{defaults → templates}/consts.d.ts +9 -0
- package/{defaults → templates}/consts.js +12 -2
- package/templates/firebase/functions/cloudbuild.yaml +17 -0
- package/templates/firebase/functions/dockerfile +19 -0
- package/templates/firebase/functions/service.yaml +49 -0
- package/{v3/units → units/base}/BaseUnit.d.ts +35 -3
- package/{v3/units → units/base}/BaseUnit.js +22 -2
- package/units/base/ProjectUnit.d.ts +32 -0
- package/units/base/ProjectUnit.js +25 -0
- package/units/base/types.js +1 -0
- package/units/discovery/UnitsMapper.d.ts +69 -0
- package/{v3/UnitsMapper → units/discovery}/UnitsMapper.js +51 -3
- package/units/discovery/resolvers/UnitMapper_Base.d.ts +65 -0
- package/units/discovery/resolvers/UnitMapper_Base.js +46 -0
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseFunction.d.ts +5 -3
- package/units/discovery/resolvers/UnitMapper_FirebaseFunction.js +105 -0
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.d.ts +3 -2
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.js +14 -10
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.d.ts +1 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.js +2 -2
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.d.ts +24 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.js +24 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.d.ts +22 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.js +22 -1
- package/units/discovery/types.js +1 -0
- package/units/implementations/Unit_NodeProject.d.ts +59 -0
- package/{v3/units → units/implementations}/Unit_NodeProject.js +67 -6
- package/units/implementations/Unit_PackageJson.d.ts +56 -0
- package/{v3/units → units/implementations}/Unit_PackageJson.js +39 -3
- package/{v3/units → units/implementations}/Unit_TypescriptLib.d.ts +40 -4
- package/{v3/units → units/implementations}/Unit_TypescriptLib.js +167 -17
- package/units/implementations/firebase/Unit_FirebaseFunctionsApp.d.ts +233 -0
- package/units/implementations/firebase/Unit_FirebaseFunctionsApp.js +804 -0
- package/units/implementations/firebase/Unit_FirebaseHostingApp.d.ts +113 -0
- package/units/implementations/firebase/Unit_FirebaseHostingApp.js +320 -0
- package/units/implementations/firebase/common.d.ts +26 -0
- package/units/implementations/firebase/common.js +65 -0
- package/units/index.d.ts +6 -0
- package/units/index.js +6 -0
- package/v3/core/Unit_HelpPrinter.d.ts +1 -16
- package/v3/core/Unit_HelpPrinter.js +1 -47
- package/workspace/Workspace.d.ts +95 -0
- package/workspace/Workspace.js +192 -0
- package/core/consts.d.ts +0 -13
- package/core/consts.js +0 -12
- package/core/exceptions/PhaseAggregatedException.d.ts +0 -8
- package/core/exceptions/UnitPhaseException.d.ts +0 -5
- package/core/exceptions/UnitPhaseException.js +0 -6
- package/old/PhaseRunnerDispatcher.d.ts +0 -24
- package/old/PhaseRunnerDispatcher.js +0 -32
- package/old/runner-dispatchers.d.ts +0 -10
- package/old/runner-dispatchers.js +0 -3
- package/v3/PhaseManager.d.ts +0 -26
- package/v3/PhaseManager.js +0 -158
- package/v3/RunningStatusHandler.d.ts +0 -18
- package/v3/RunningStatusHandler.js +0 -67
- package/v3/UnitsMapper/UnitsMapper.d.ts +0 -21
- package/v3/UnitsMapper/resolvers/UnitMapper_Base.d.ts +0 -23
- package/v3/UnitsMapper/resolvers/UnitMapper_Base.js +0 -16
- package/v3/UnitsMapper/resolvers/UnitMapper_FirebaseFunction.js +0 -66
- package/v3/core/FilesCache.d.ts +0 -7
- package/v3/core/FilesCache.js +0 -33
- package/v3/phase/types.d.ts +0 -9
- package/v3/units/ProjectUnit.d.ts +0 -18
- package/v3/units/ProjectUnit.js +0 -11
- package/v3/units/Unit_NodeProject.d.ts +0 -30
- package/v3/units/Unit_PackageJson.d.ts +0 -17
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.d.ts +0 -64
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.js +0 -306
- package/v3/units/firebase/Unit_FirebaseHostingApp.d.ts +0 -49
- package/v3/units/firebase/Unit_FirebaseHostingApp.js +0 -114
- package/v3/units/firebase/common.d.ts +0 -3
- package/v3/units/firebase/common.js +0 -13
- package/v3/units/index.d.ts +0 -6
- package/v3/units/index.js +0 -6
- /package/{core → config}/package/consts.js +0 -0
- /package/{core → config}/types/configs/firebasejson.d.ts +0 -0
- /package/{core → config}/types/configs/firebasejson.js +0 -0
- /package/{core → config}/types/configs/firebaserc.d.ts +0 -0
- /package/{core → config}/types/configs/firebaserc.js +0 -0
- /package/{core → config}/types/configs/index.d.ts +0 -0
- /package/{core → config}/types/configs/index.js +0 -0
- /package/{core → config}/types/configs/package-json.d.ts +0 -0
- /package/{core → config}/types/configs/package-json.js +0 -0
- /package/{core → config}/types/core.d.ts +0 -0
- /package/{core → config}/types/core.js +0 -0
- /package/{core → config}/types/index.d.ts +0 -0
- /package/{core → config}/types/index.js +0 -0
- /package/{core → config}/types/package/index.d.ts +0 -0
- /package/{core → config}/types/package/index.js +0 -0
- /package/{core → config}/types/package/package.d.ts +0 -0
- /package/{core → config}/types/package/package.js +0 -0
- /package/{core → config}/types/package/runtime-package.d.ts +0 -0
- /package/{core → config}/types/package/runtime-package.js +0 -0
- /package/{core → config}/types/project-config.js +0 -0
- /package/{v3/core → core}/types.js +0 -0
- /package/{v3/UnitsMapper/types.js → exports/types.d.ts} +0 -0
- /package/{v3/phase → phases/definitions}/index.d.ts +0 -0
- /package/{v3/phase → phases/definitions}/index.js +0 -0
- /package/{v3/phase → phases/definitions}/types.js +0 -0
- /package/{v3/units/types.js → run.d.ts} +0 -0
- /package/{defaults/backend-proxy → templates/backend/proxy}/proxy._ts +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/database.rules.json +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/firestore.indexes.json +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/firestore.rules +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/storage.rules +0 -0
- /package/{v3/units → units/base}/types.d.ts +0 -0
- /package/{v3/UnitsMapper → units/discovery}/resolvers/index.d.ts +0 -0
- /package/{v3/UnitsMapper → units/discovery}/resolvers/index.js +0 -0
- /package/{v3/UnitsMapper → units/discovery}/types.d.ts +0 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { addItemToArray, BadImplementationException, exists, flatArray, Logger, removeItemFromArray, timeCounter } from '@nu-art/ts-common';
|
|
2
|
+
import { PhaseAggregatedException } from '../exceptions/PhaseAggregatedException.js';
|
|
3
|
+
import { UnitPhaseException } from '../exceptions/UnitPhaseException.js';
|
|
4
|
+
/**
|
|
5
|
+
* Manages phase execution across units in dependency order.
|
|
6
|
+
*
|
|
7
|
+
* **Execution Model**:
|
|
8
|
+
* - **Phase Groups**: Phases that can run in parallel (e.g., [prepare, compile])
|
|
9
|
+
* - **Unit Layers**: Units grouped by dependency level (dependencies first)
|
|
10
|
+
* - **Steps**: Combinations of phase groups × unit layers
|
|
11
|
+
*
|
|
12
|
+
* **Execution Flow**:
|
|
13
|
+
* 1. `calculateExecutionSteps()`: Plans which phases run on which units
|
|
14
|
+
* 2. `execute()`: Executes steps sequentially, phases in parallel within steps
|
|
15
|
+
* 3. Units in same layer run phases in parallel (Promise.all)
|
|
16
|
+
*
|
|
17
|
+
* **Eligibility Rules**:
|
|
18
|
+
* - Unit must implement the phase method (e.g., `compile()`, `test()`)
|
|
19
|
+
* - Unit must be in active/project units (based on phase.unitCategory)
|
|
20
|
+
* - Phase filter (if present) must pass runtime params
|
|
21
|
+
*
|
|
22
|
+
* **Error Handling**:
|
|
23
|
+
* - First failure stops execution (sets `killed = true`)
|
|
24
|
+
* - Aggregates all errors into `PhaseAggregatedException`
|
|
25
|
+
* - Tracks running units for graceful shutdown
|
|
26
|
+
*
|
|
27
|
+
* **Resume Support**:
|
|
28
|
+
* - Skips completed steps (via `runningStatus.startIndex`)
|
|
29
|
+
* - Skips completed units within steps (via `runningStatus.isCompleted()`)
|
|
30
|
+
*
|
|
31
|
+
* **Validation**:
|
|
32
|
+
* - Constructor validates no duplicate units or phases
|
|
33
|
+
* - Throws `BadImplementationException` on duplicates
|
|
34
|
+
*/
|
|
35
|
+
export class PhaseManager extends Logger {
|
|
36
|
+
phases;
|
|
37
|
+
units;
|
|
38
|
+
runningUnits = [];
|
|
39
|
+
killed = false;
|
|
40
|
+
runningStatus;
|
|
41
|
+
activeUnits;
|
|
42
|
+
projectUnitKeys;
|
|
43
|
+
keyToPhaseMap;
|
|
44
|
+
constructor(runningStatus, phases, units, activeUnits, projectUnitKeys) {
|
|
45
|
+
super();
|
|
46
|
+
this.phases = phases;
|
|
47
|
+
this.units = units;
|
|
48
|
+
this.runningStatus = runningStatus;
|
|
49
|
+
this.activeUnits = activeUnits;
|
|
50
|
+
this.projectUnitKeys = projectUnitKeys;
|
|
51
|
+
const unitsSet = new Set();
|
|
52
|
+
for (const unit of flatArray(this.units)) {
|
|
53
|
+
if (unitsSet.has(unit.config.key))
|
|
54
|
+
throw new BadImplementationException(`Found duplicate unit: '${unit.config.key}' in the project`);
|
|
55
|
+
unitsSet.add(unit.config.key);
|
|
56
|
+
}
|
|
57
|
+
const phasesSet = new Set();
|
|
58
|
+
const flatPhases = flatArray(this.phases);
|
|
59
|
+
for (const phase of flatPhases) {
|
|
60
|
+
if (phasesSet.has(phase.key))
|
|
61
|
+
throw new BadImplementationException(`Found duplicate phase '${phase.key}' in the project`);
|
|
62
|
+
phasesSet.add(phase.key);
|
|
63
|
+
}
|
|
64
|
+
this.keyToPhaseMap = flatPhases.reduce((acc, phase) => {
|
|
65
|
+
acc[phase.key] = phase;
|
|
66
|
+
return acc;
|
|
67
|
+
}, {});
|
|
68
|
+
}
|
|
69
|
+
//######################### Initialization #########################
|
|
70
|
+
/**
|
|
71
|
+
* Calculates the execution plan: which phases run on which units.
|
|
72
|
+
*
|
|
73
|
+
* **Algorithm**:
|
|
74
|
+
* 1. For each phase group (phases that can run together)
|
|
75
|
+
* 2. Filter phases by runtime params (if phase.filter exists)
|
|
76
|
+
* 3. For each unit layer (dependency level)
|
|
77
|
+
* 4. Find units eligible for at least one phase in the group
|
|
78
|
+
* 5. Group units by which phases they support
|
|
79
|
+
* 6. Create steps: phase combinations × unit groups
|
|
80
|
+
*
|
|
81
|
+
* **Phase Grouping**: Units that support the same set of phases are grouped
|
|
82
|
+
* together in a step (identified by phase keys joined with '|').
|
|
83
|
+
*
|
|
84
|
+
* **Unit Eligibility**:
|
|
85
|
+
* - Unit must implement phase method
|
|
86
|
+
* - Unit must be in active/project units (based on phase.unitCategory)
|
|
87
|
+
*
|
|
88
|
+
* @returns Array of scheduled steps (phases and unit keys)
|
|
89
|
+
*/
|
|
90
|
+
async calculateExecutionSteps() {
|
|
91
|
+
const steps = [];
|
|
92
|
+
this.logDebug('Calculating execution steps for phases: ', this.phases.map(phases => phases.map(phase => phase.key)));
|
|
93
|
+
this.logDebug('Active Units: ', this.activeUnits);
|
|
94
|
+
this.logDebug('Project Units: ', this.projectUnitKeys);
|
|
95
|
+
for (let phaseGroup of this.phases) {
|
|
96
|
+
phaseGroup = phaseGroup.filter(phase => !exists(phase.filter) || phase.filter(this.runningStatus.runtimeParams));
|
|
97
|
+
for (const layer of this.units) {
|
|
98
|
+
// Determine eligible units for this phase group
|
|
99
|
+
// A unit is eligible if it's eligible for at least one phase in the group
|
|
100
|
+
const eligibleUnitKeys = new Set();
|
|
101
|
+
for (const phase of phaseGroup) {
|
|
102
|
+
const unitCategory = phase.unitCategory ?? "active";
|
|
103
|
+
const phaseEligibleKeys = unitCategory === "project" ? this.projectUnitKeys : this.activeUnits;
|
|
104
|
+
phaseEligibleKeys.forEach(key => eligibleUnitKeys.add(key));
|
|
105
|
+
}
|
|
106
|
+
const layerUnits = layer.filter(u => eligibleUnitKeys.has(u.config.key));
|
|
107
|
+
if (layerUnits.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
const phaseMap = new Map();
|
|
110
|
+
for (const unit of layerUnits) {
|
|
111
|
+
// Find phases this unit supports and is eligible for
|
|
112
|
+
const supportedPhases = phaseGroup.filter(phase => {
|
|
113
|
+
if (!(phase.method in unit && typeof unit[phase.method] === 'function'))
|
|
114
|
+
return false;
|
|
115
|
+
// Check if unit is eligible for this specific phase
|
|
116
|
+
const unitCategory = phase.unitCategory ?? "active";
|
|
117
|
+
const phaseEligibleKeys = unitCategory === "project" ? this.projectUnitKeys : this.activeUnits;
|
|
118
|
+
return phaseEligibleKeys.includes(unit.config.key);
|
|
119
|
+
});
|
|
120
|
+
if (supportedPhases.length === 0)
|
|
121
|
+
continue;
|
|
122
|
+
const key = phaseGroup
|
|
123
|
+
.filter(phase => supportedPhases.find(p => p.key === phase.key))
|
|
124
|
+
.map(p => p.key)
|
|
125
|
+
.join('|');
|
|
126
|
+
if (!phaseMap.has(key))
|
|
127
|
+
phaseMap.set(key, []);
|
|
128
|
+
phaseMap.get(key).push(unit);
|
|
129
|
+
}
|
|
130
|
+
for (const [phaseKeyCombo, groupedUnits] of phaseMap.entries()) {
|
|
131
|
+
steps.push({
|
|
132
|
+
phases: phaseKeyCombo.split('|'),
|
|
133
|
+
units: groupedUnits.map(u => u.config.key),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
this.logVerbose('Calculated execution steps: ', steps);
|
|
139
|
+
return steps;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Executes the planned steps sequentially.
|
|
143
|
+
*
|
|
144
|
+
* **Execution Model**:
|
|
145
|
+
* - Steps run sequentially (one after another)
|
|
146
|
+
* - Units within a step run phases in parallel (Promise.all)
|
|
147
|
+
* - Phases for a unit run sequentially (in phase group order)
|
|
148
|
+
*
|
|
149
|
+
* **Resume Support**:
|
|
150
|
+
* - Starts from `runningStatus.startIndex` (if --continue)
|
|
151
|
+
* - Skips units marked as completed
|
|
152
|
+
*
|
|
153
|
+
* **Dry Run**: If `--dry-run`, only logs phase/unit names without executing.
|
|
154
|
+
*
|
|
155
|
+
* **Error Handling**:
|
|
156
|
+
* - First error stops execution (sets `killed = true`)
|
|
157
|
+
* - All errors aggregated into `PhaseAggregatedException`
|
|
158
|
+
* - Running units tracked for graceful shutdown
|
|
159
|
+
*
|
|
160
|
+
* **Performance**: Logs operation duration if > 1.5 seconds.
|
|
161
|
+
*
|
|
162
|
+
* @param _steps - Scheduled steps to execute
|
|
163
|
+
* @throws PhaseAggregatedException if any phase fails
|
|
164
|
+
*/
|
|
165
|
+
async execute(_steps) {
|
|
166
|
+
this.runningUnits = [];
|
|
167
|
+
for (let i = this.runningStatus.startIndex; i < _steps.length; i++) {
|
|
168
|
+
if (this.killed)
|
|
169
|
+
break;
|
|
170
|
+
const scheduledStep = _steps[i];
|
|
171
|
+
const step = this.mapStep(scheduledStep);
|
|
172
|
+
await this.runningStatus.onStepStarted(i);
|
|
173
|
+
this.logDebug(`Executing step #${i + 1}/${_steps.length}`);
|
|
174
|
+
this.logVerbose(scheduledStep);
|
|
175
|
+
const errors = [];
|
|
176
|
+
let failedStep;
|
|
177
|
+
await Promise.all(step.units.map(async (unit) => {
|
|
178
|
+
if (this.runningStatus.isCompleted(unit.config.key))
|
|
179
|
+
return;
|
|
180
|
+
let failed = false;
|
|
181
|
+
for (const phase of step.phases) {
|
|
182
|
+
if (this.killed)
|
|
183
|
+
break;
|
|
184
|
+
if (this.runningStatus.runtimeParams.dryRun) {
|
|
185
|
+
this.logInfo(`[${phase.key}] - ${unit.config.key}`);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
addItemToArray(this.runningUnits, unit);
|
|
189
|
+
const dtCounter = timeCounter();
|
|
190
|
+
try {
|
|
191
|
+
this.logInfo(`Phase(${phase.name}) - Running - ${unit.config.key}`);
|
|
192
|
+
if (typeof unit[phase.method] === 'function')
|
|
193
|
+
await unit[phase.method].call(unit);
|
|
194
|
+
let operationDuration = '';
|
|
195
|
+
if (dtCounter.dt() > 1500)
|
|
196
|
+
operationDuration = ` (${dtCounter.format('mm:ss')})`;
|
|
197
|
+
this.logInfo(`Phase(${phase.name}) - Completed${operationDuration} - ${unit.config.key}`);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
this.logError(`Phase(${phase.name}) - Error - ${unit.config.key}`, error);
|
|
201
|
+
errors.push(new UnitPhaseException(error, unit, phase.key));
|
|
202
|
+
failedStep = scheduledStep;
|
|
203
|
+
this.killed = true;
|
|
204
|
+
failed = true;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
removeItemFromArray(this.runningUnits, unit);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (!failed)
|
|
212
|
+
await this.runningStatus.onUnitCompleted(unit.config.key);
|
|
213
|
+
}));
|
|
214
|
+
if (failedStep && errors.length) {
|
|
215
|
+
throw new PhaseAggregatedException(errors, failedStep);
|
|
216
|
+
}
|
|
217
|
+
await this.runningStatus.onStepEnded();
|
|
218
|
+
}
|
|
219
|
+
this.logInfo('All steps completed.');
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Gracefully stops execution and kills all running units.
|
|
223
|
+
*
|
|
224
|
+
* Called on SIGINT (Ctrl+C). Sets `killed = true` to stop further execution,
|
|
225
|
+
* then calls `kill()` on all currently running units.
|
|
226
|
+
*
|
|
227
|
+
* @returns Promise that resolves when all units are killed
|
|
228
|
+
*/
|
|
229
|
+
break() {
|
|
230
|
+
this.killed = true;
|
|
231
|
+
return Promise.all(this.runningUnits.map(unit => unit.kill()));
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Maps scheduled step (with string keys) to execution step (with actual instances).
|
|
235
|
+
*
|
|
236
|
+
* **Mapping Process**:
|
|
237
|
+
* - Maps phase keys to Phase instances using `keyToPhaseMap`
|
|
238
|
+
* - Maps unit keys to BaseUnit instances by searching through unit layers
|
|
239
|
+
*
|
|
240
|
+
* **Performance Note**: Unit lookup iterates through all layers (O(n) complexity).
|
|
241
|
+
* Consider using a lookup map for O(1) access in large workspaces.
|
|
242
|
+
*
|
|
243
|
+
* @param scheduledStep - Scheduled step with phase/unit keys
|
|
244
|
+
* @returns Execution step with phase/unit instances
|
|
245
|
+
* @throws Error if phase or unit not found
|
|
246
|
+
*/
|
|
247
|
+
mapStep(scheduledStep) {
|
|
248
|
+
const mappedPhases = scheduledStep.phases.map(phaseKey => {
|
|
249
|
+
const phase = this.keyToPhaseMap[phaseKey];
|
|
250
|
+
if (!phase)
|
|
251
|
+
throw new Error(`Phase '${phaseKey}' not found in PhaseManager.phases`);
|
|
252
|
+
return phase;
|
|
253
|
+
});
|
|
254
|
+
const mappedUnits = scheduledStep.units.map(unitKey => {
|
|
255
|
+
for (const layer of this.units) {
|
|
256
|
+
const unit = layer.find(u => u.config.key === unitKey);
|
|
257
|
+
if (unit)
|
|
258
|
+
return unit;
|
|
259
|
+
}
|
|
260
|
+
throw new Error(`Unit '${unitKey}' not found in PhaseManager.units`);
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
phases: mappedPhases,
|
|
264
|
+
units: mappedUnits
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase definitions for the build system.
|
|
3
|
+
*
|
|
4
|
+
* **Phase Groups**:
|
|
5
|
+
* - `phases_Terminating`: Phases that terminate execution after completion
|
|
6
|
+
* - `phases_Build`: Main build phases (purge, prepare, install, compile, test, etc.)
|
|
7
|
+
* - `phases_Launch`: Launch phases (start applications)
|
|
8
|
+
* - `phases_Deploy`: Deployment phases
|
|
9
|
+
*
|
|
10
|
+
* **Phase Execution Order**:
|
|
11
|
+
* 1. Build phases run first (prepare, install, compile, test)
|
|
12
|
+
* 2. Terminating phases can stop execution early
|
|
13
|
+
* 3. Launch phases start applications
|
|
14
|
+
* 4. Deploy phases publish/deploy
|
|
15
|
+
*
|
|
16
|
+
* **Phase Filters**: Most phases have filters based on runtime params (e.g., `--lint`, `--test`).
|
|
17
|
+
* Phases only run if their filter returns true (or no filter is present).
|
|
18
|
+
*
|
|
19
|
+
* **Dependency Phases**: Some phases depend on others (e.g., `compile` depends on `preCompile`).
|
|
20
|
+
* Dependencies are automatically resolved by PhaseManager.
|
|
21
|
+
*/
|
|
1
22
|
import { Phase } from './types.js';
|
|
2
23
|
export type Phase_PrintDependencyTree = typeof phase_PrintDependencyTree;
|
|
3
24
|
export declare const phaseKey_PrintDependencyTree = "print-dependency-tree";
|
|
@@ -24,6 +45,12 @@ export declare const phase_Lint: Phase<'lint'>;
|
|
|
24
45
|
export type Phase_PreCompile = typeof phase_PreCompile;
|
|
25
46
|
export declare const phaseKey_PreCompile = "preCompile";
|
|
26
47
|
export declare const phase_PreCompile: Phase<'preCompile'>;
|
|
48
|
+
export type Phase_ExtractDynamicDeps = typeof phase_ExtractDynamicDeps;
|
|
49
|
+
export declare const phaseKey_ExtractDynamicDeps = "extract-dynamic-deps";
|
|
50
|
+
export declare const phase_ExtractDynamicDeps: Phase<'extractDynamicDeps'>;
|
|
51
|
+
export type Phase_MapExports = typeof phase_MapExports;
|
|
52
|
+
export declare const phaseKey_MapExports = "map-exports";
|
|
53
|
+
export declare const phase_MapExports: Phase<'mapExports'>;
|
|
27
54
|
export type Phase_Compile = typeof phase_Compile;
|
|
28
55
|
export declare const phaseKey_Compile = "compile";
|
|
29
56
|
export declare const phase_Compile: Phase<'compile'>;
|
|
@@ -40,6 +67,9 @@ export declare const phases_Build: Phase<string>[][];
|
|
|
40
67
|
export type Phase_Launch = typeof phase_Launch;
|
|
41
68
|
export declare const phaseKey_Launch = "launch";
|
|
42
69
|
export declare const phase_Launch: Phase<'launch'>;
|
|
70
|
+
export type Phase_IndicesMcpServer = typeof phase_IndicesMcpServer;
|
|
71
|
+
export declare const phaseKey_IndicesMcpServer = "indices-mcp-server";
|
|
72
|
+
export declare const phase_IndicesMcpServer: Phase<'indicesMcpServer'>;
|
|
43
73
|
export declare const phases_Launch: Phase<string>[][];
|
|
44
74
|
export type Phase_Publish = typeof phase_Publish;
|
|
45
75
|
export declare const phaseKey_Publish = "publish";
|
|
@@ -50,4 +80,10 @@ export declare const phase_PostPublish: Phase<'postPublish'>;
|
|
|
50
80
|
export type Phase_Deploy = typeof phase_Deploy;
|
|
51
81
|
export declare const phaseKey_Deploy = "deploy";
|
|
52
82
|
export declare const phase_Deploy: Phase<'deploy'>;
|
|
83
|
+
export type Phase_BuildPushImage = typeof phase_BuildPushImage;
|
|
84
|
+
export declare const phaseKey_BuildPushImage = "build-push-image";
|
|
85
|
+
export declare const phase_BuildPushImage: Phase<'buildPushImage'>;
|
|
86
|
+
export type Phase_DeployImage = typeof phase_DeployImage;
|
|
87
|
+
export declare const phaseKey_DeployImage = "deploy-image";
|
|
88
|
+
export declare const phase_DeployImage: Phase<'deployImage'>;
|
|
53
89
|
export declare const phases_Deploy: Phase<string>[][];
|
|
@@ -38,6 +38,7 @@ export const phase_Prepare = {
|
|
|
38
38
|
name: 'Prepare',
|
|
39
39
|
method: 'prepare',
|
|
40
40
|
filter: (baiParams) => baiParams.prepare,
|
|
41
|
+
unitCategory: "project", // All project units need to be prepared
|
|
41
42
|
};
|
|
42
43
|
export const phaseKey_Install = 'install';
|
|
43
44
|
export const phase_Install = {
|
|
@@ -61,6 +62,20 @@ export const phase_PreCompile = {
|
|
|
61
62
|
method: 'preCompile',
|
|
62
63
|
filter: (baiParams) => !baiParams.noBuild,
|
|
63
64
|
};
|
|
65
|
+
export const phaseKey_ExtractDynamicDeps = 'extract-dynamic-deps';
|
|
66
|
+
export const phase_ExtractDynamicDeps = {
|
|
67
|
+
key: phaseKey_ExtractDynamicDeps,
|
|
68
|
+
name: 'Extract Dynamic Dependencies',
|
|
69
|
+
method: 'extractDynamicDeps',
|
|
70
|
+
filter: (baiParams) => baiParams.extractDynamicDeps,
|
|
71
|
+
};
|
|
72
|
+
export const phaseKey_MapExports = 'map-exports';
|
|
73
|
+
export const phase_MapExports = {
|
|
74
|
+
key: phaseKey_MapExports,
|
|
75
|
+
name: 'Map Exports',
|
|
76
|
+
method: 'mapExports',
|
|
77
|
+
filter: (baiParams) => baiParams.mapExports,
|
|
78
|
+
};
|
|
64
79
|
export const phaseKey_Compile = 'compile';
|
|
65
80
|
export const phase_Compile = {
|
|
66
81
|
key: phaseKey_Compile,
|
|
@@ -94,7 +109,7 @@ export const phases_Build = [
|
|
|
94
109
|
[phase_Purge, phase_Prepare],
|
|
95
110
|
[phase_ToESM],
|
|
96
111
|
[phase_Install],
|
|
97
|
-
[phase_Lint, phase_PreCompile, phase_Compile, phase_Test,],
|
|
112
|
+
[phase_Lint, phase_PreCompile, phase_ExtractDynamicDeps, phase_MapExports, phase_Compile, phase_Test,],
|
|
98
113
|
[phase_Watch]
|
|
99
114
|
];
|
|
100
115
|
export const phaseKey_Launch = 'launch';
|
|
@@ -104,8 +119,16 @@ export const phase_Launch = {
|
|
|
104
119
|
method: 'launch',
|
|
105
120
|
filter: (baiParams) => !!baiParams.launch,
|
|
106
121
|
};
|
|
122
|
+
export const phaseKey_IndicesMcpServer = 'indices-mcp-server';
|
|
123
|
+
export const phase_IndicesMcpServer = {
|
|
124
|
+
key: phaseKey_IndicesMcpServer,
|
|
125
|
+
name: 'Export Indices MCP Server',
|
|
126
|
+
method: 'indicesMcpServer',
|
|
127
|
+
filter: (baiParams) => baiParams.indicesMcpServer,
|
|
128
|
+
};
|
|
107
129
|
export const phases_Launch = [[
|
|
108
130
|
phase_Launch,
|
|
131
|
+
phase_IndicesMcpServer,
|
|
109
132
|
]];
|
|
110
133
|
export const phaseKey_Publish = 'publish';
|
|
111
134
|
export const phase_Publish = {
|
|
@@ -128,4 +151,24 @@ export const phase_Deploy = {
|
|
|
128
151
|
method: 'deploy',
|
|
129
152
|
filter: (baiParams) => !!baiParams.deploy,
|
|
130
153
|
};
|
|
131
|
-
export const
|
|
154
|
+
export const phaseKey_BuildPushImage = 'build-push-image';
|
|
155
|
+
export const phase_BuildPushImage = {
|
|
156
|
+
key: phaseKey_BuildPushImage,
|
|
157
|
+
name: 'Build & Push Container Image',
|
|
158
|
+
method: 'buildPushImage',
|
|
159
|
+
filter: (baiParams) => !!baiParams.buildPushImage,
|
|
160
|
+
};
|
|
161
|
+
export const phaseKey_DeployImage = 'deploy-image';
|
|
162
|
+
export const phase_DeployImage = {
|
|
163
|
+
key: phaseKey_DeployImage,
|
|
164
|
+
name: 'Deploy Container Image',
|
|
165
|
+
method: 'deployImage',
|
|
166
|
+
filter: (baiParams) => !!baiParams.deployImage,
|
|
167
|
+
dependencyPhase: [phase_BuildPushImage],
|
|
168
|
+
};
|
|
169
|
+
export const phases_Deploy = [
|
|
170
|
+
[phase_BuildPushImage],
|
|
171
|
+
[phase_DeployImage],
|
|
172
|
+
[phase_Publish, phase_Deploy],
|
|
173
|
+
[phase_PostPublish]
|
|
174
|
+
];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BaiParams } from '../../core/params.js';
|
|
2
|
+
/**
|
|
3
|
+
* Phase definition for build system execution.
|
|
4
|
+
*
|
|
5
|
+
* **Phase Structure**:
|
|
6
|
+
* - Phases are grouped into phase groups (arrays of phases)
|
|
7
|
+
* - Phases in a group can run in parallel
|
|
8
|
+
* - Phase groups run sequentially
|
|
9
|
+
*
|
|
10
|
+
* **Key Properties**:
|
|
11
|
+
* - `key`: Unique identifier for the phase
|
|
12
|
+
* - `method`: Method name that units must implement (e.g., 'compile', 'test')
|
|
13
|
+
* - `filter`: Optional function to determine if phase should run based on runtime params
|
|
14
|
+
* - `unitCategory`: Which units participate ('active' or 'project')
|
|
15
|
+
* - `dependencyPhase`: Phases that must complete before this phase runs
|
|
16
|
+
* - `terminateAfterPhase`: If true, stops execution after this phase completes
|
|
17
|
+
*
|
|
18
|
+
* **Unit Participation**:
|
|
19
|
+
* - Units must implement the phase method to participate
|
|
20
|
+
* - Units must be in the correct category (active/project)
|
|
21
|
+
* - Phase filter must pass (if present)
|
|
22
|
+
*
|
|
23
|
+
* **Examples**: See `phase/consts.ts` for all phase definitions.
|
|
24
|
+
*/
|
|
25
|
+
export type Phase<PhaseMethod extends string> = {
|
|
26
|
+
/** Unique identifier for the phase */
|
|
27
|
+
key: string;
|
|
28
|
+
/** Display name for the phase */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Method name that units must implement */
|
|
31
|
+
method: PhaseMethod;
|
|
32
|
+
/** Optional filter to determine if phase should run based on runtime params */
|
|
33
|
+
filter?: (params: BaiParams) => boolean;
|
|
34
|
+
/** If true, terminates execution after this phase completes */
|
|
35
|
+
terminateAfterPhase?: boolean;
|
|
36
|
+
/** Phases that must complete before this phase runs */
|
|
37
|
+
dependencyPhase?: Phase<string>[];
|
|
38
|
+
/** Unit category: 'project' = all project units (active + dependencies), 'active' = only active units (default) */
|
|
39
|
+
unitCategory?: "project" | "active";
|
|
40
|
+
};
|
package/phases/index.js
ADDED
package/run.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BuildAndInstall } from './BuildAndInstall.js';
|
|
2
|
+
(async () => {
|
|
3
|
+
const buildAndInstall = new BuildAndInstall();
|
|
4
|
+
await buildAndInstall.build();
|
|
5
|
+
await buildAndInstall.run();
|
|
6
|
+
})()
|
|
7
|
+
.catch((err) => {
|
|
8
|
+
process.exit(2);
|
|
9
|
+
})
|
|
10
|
+
.then(() => process.exit(0));
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Logger } from '@nu-art/ts-common';
|
|
2
|
+
import { BaiParams } from '../core/params.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages execution state persistence for resume support.
|
|
5
|
+
*
|
|
6
|
+
* **Purpose**: Enables `--continue` flag to resume from last completed step.
|
|
7
|
+
*
|
|
8
|
+
* **State Management**:
|
|
9
|
+
* - **startIndex**: Current step index (0-based)
|
|
10
|
+
* - **completedUnits**: Units completed in current step
|
|
11
|
+
* - **runtimeParams**: Runtime parameters (for state validation)
|
|
12
|
+
*
|
|
13
|
+
* **Persistence**:
|
|
14
|
+
* - Saves state to `.trash/output/running-status.json` after each step/unit
|
|
15
|
+
* - Loads state on init if `--continue` flag is set
|
|
16
|
+
* - State includes: index, runtimeParams, completedUnits
|
|
17
|
+
*
|
|
18
|
+
* **Isolation Mode**: When isolated, skips saving state (useful for tests).
|
|
19
|
+
*
|
|
20
|
+
* **Usage Flow**:
|
|
21
|
+
* 1. `init()` - Loads state if `--continue`
|
|
22
|
+
* 2. `onStepStarted()` - Saves current step index
|
|
23
|
+
* 3. `onUnitCompleted()` - Marks unit as completed, saves state
|
|
24
|
+
* 4. `onStepEnded()` - Clears completed units for next step
|
|
25
|
+
* 5. `isCompleted()` - Checks if unit already completed (for resume)
|
|
26
|
+
*/
|
|
27
|
+
export declare class RunningStatusHandler extends Logger {
|
|
28
|
+
private isolated;
|
|
29
|
+
private readonly outputFolder;
|
|
30
|
+
private completedUnits;
|
|
31
|
+
runtimeParams: BaiParams;
|
|
32
|
+
startIndex: number;
|
|
33
|
+
constructor(outputFolder: string, runtimeParams: BaiParams);
|
|
34
|
+
/**
|
|
35
|
+
* Initializes the status handler.
|
|
36
|
+
*
|
|
37
|
+
* **Actions**:
|
|
38
|
+
* - Creates output folder if missing
|
|
39
|
+
* - Loads saved state if `--continue` flag is set
|
|
40
|
+
* - Merges loaded runtime params with current params (loaded params take precedence)
|
|
41
|
+
*/
|
|
42
|
+
init(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Enables isolation mode (skips saving state).
|
|
45
|
+
*
|
|
46
|
+
* Useful for tests or when state persistence is not desired.
|
|
47
|
+
*
|
|
48
|
+
* @returns This instance for chaining
|
|
49
|
+
*/
|
|
50
|
+
isolate(): RunningStatusHandler;
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a unit has already been completed (for resume).
|
|
53
|
+
*
|
|
54
|
+
* @param unitKey - Unit key to check
|
|
55
|
+
* @returns True if unit is marked as completed
|
|
56
|
+
*/
|
|
57
|
+
isCompleted(unitKey: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Marks a unit as completed and saves state.
|
|
60
|
+
*
|
|
61
|
+
* Called after a unit successfully completes all its phases.
|
|
62
|
+
*
|
|
63
|
+
* @param unitKey - Unit key that completed
|
|
64
|
+
*/
|
|
65
|
+
onUnitCompleted(unitKey: string): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Called when a step completes successfully.
|
|
68
|
+
*
|
|
69
|
+
* Clears completed units list for the next step.
|
|
70
|
+
*/
|
|
71
|
+
onStepEnded(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Called when a step starts.
|
|
74
|
+
*
|
|
75
|
+
* Updates start index and saves state (unless isolated).
|
|
76
|
+
*
|
|
77
|
+
* @param index - Step index (0-based)
|
|
78
|
+
*/
|
|
79
|
+
onStepStarted(index: number): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Saves current state to disk.
|
|
82
|
+
*
|
|
83
|
+
* Writes to `.trash/output/running-status.json` with:
|
|
84
|
+
* - Current step index
|
|
85
|
+
* - Runtime params (for validation)
|
|
86
|
+
* - Completed units in current step
|
|
87
|
+
*
|
|
88
|
+
* Called after each step start and unit completion.
|
|
89
|
+
*/
|
|
90
|
+
private saveStatus;
|
|
91
|
+
/**
|
|
92
|
+
* Loads saved state from disk.
|
|
93
|
+
*
|
|
94
|
+
* **Behavior**:
|
|
95
|
+
* - Reads from `.trash/output/running-status.json`
|
|
96
|
+
* - Restores step index, completed units, and runtime params
|
|
97
|
+
* - Returns undefined if file doesn't exist or parse fails (logs error)
|
|
98
|
+
*
|
|
99
|
+
* **Note**: Runtime params from file override current params (for consistency).
|
|
100
|
+
*
|
|
101
|
+
* @returns Promise resolving to step index, or undefined if load fails
|
|
102
|
+
*/
|
|
103
|
+
load(): Promise<any>;
|
|
104
|
+
}
|