6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
import { experimental , isPromise , json , logging } from '@angular-devkit/core' ;
9
- import { Observable , from , isObservable , of } from 'rxjs' ;
9
+ import { Observable , from , isObservable , of , Observer } from 'rxjs' ;
10
10
import { concatMap , first , map , shareReplay , switchMap , tap } from 'rxjs/operators' ;
11
- import { JobInboundMessageKind , JobOutboundMessageKind } from '../../core/src/experimental/jobs' ;
12
- import { Schema as RealBuilderInput , Target } from './input-schema' ;
11
+ import { JobInboundMessageKind } from '../../core/src/experimental/jobs' ;
12
+ import { Schema as RealBuilderInput , Target as RealTarget } from './input-schema' ;
13
13
import { Schema as RealBuilderOutput } from './output-schema' ;
14
- import { Schema as RealBuilderProgress } from './progress-schema' ;
14
+ import { Schema as RealBuilderProgress , State as BuilderProgressState } from './progress-schema' ;
15
15
16
- export type Target = Target ;
16
+ export type Target = json . JsonObject & RealTarget ;
17
17
18
18
// Type short hands.
19
19
export type BuilderJobHandler <
@@ -27,9 +27,15 @@ export type BuilderRegistry<
27
27
O extends BuilderOutput = BuilderOutput ,
28
28
> = experimental . jobs . Registry < A , I , O > ;
29
29
30
+ export type TypedBuilderProgress =
31
+ { state : BuilderProgressState . Stopped }
32
+ | { state : BuilderProgressState . Error ; error : json . JsonValue ; }
33
+ | { state : BuilderProgressState . Waiting ; status ?: string ; }
34
+ | { state : BuilderProgressState . Running ; status ?: string ; current : number ; total ?: number ; }
35
+
30
36
export type BuilderInput = json . JsonObject & RealBuilderInput ;
31
37
export type BuilderOutput = json . JsonObject & RealBuilderOutput ;
32
- export type BuilderProgress = json . JsonObject & RealBuilderProgress ;
38
+ export type BuilderProgress = RealBuilderProgress & TypedBuilderProgress ;
33
39
34
40
const inputSchema = require ( './input-schema.json' ) ;
35
41
const outputSchema = require ( './output-schema.json' ) ;
@@ -55,7 +61,7 @@ export const VersionSymbol = Symbol.for('@angular-devkit/architect:version');
55
61
56
62
57
63
export interface Builder < OptionT extends json . JsonObject > {
58
- handler : experimental . jobs . JobHandler < boolean , BuilderInput , BuilderOutput > ;
64
+ handler : experimental . jobs . JobHandler < json . JsonObject , BuilderInput , BuilderOutput > ;
59
65
[ BuilderSymbol ] : true ;
60
66
[ VersionSymbol ] : string ;
61
67
}
@@ -79,7 +85,7 @@ export interface BuilderContext {
79
85
// dependencies?: BuilderRun[];
80
86
81
87
// bep: Observer<BuildEventMessage>
82
- // progress: Observer<{ current: number; total: number }> ;
88
+ progress ( progress : BuilderProgress ) : void ;
83
89
84
90
// building: () => void;
85
91
}
@@ -122,6 +128,8 @@ export interface ArchitectHost {
122
128
getWorkspaceRoot ( ) : string ;
123
129
124
130
getOptionsForTarget ( target : Target ) : Promise < json . JsonObject > ;
131
+
132
+ loadBuilder ( info : BuilderInfo ) : Promise < BuilderJobHandler > ;
125
133
}
126
134
127
135
/**
@@ -154,11 +162,17 @@ async function _scheduleTarget(
154
162
reason : 'initial' ,
155
163
options : overrides ,
156
164
target,
157
- } as BuilderInput ) ;
165
+ } ) ;
158
166
}
159
167
} ) ;
160
168
} else {
161
-
169
+ job . input . next ( {
170
+ currentDirectory : options . workspaceRoot ,
171
+ workspaceRoot : options . currentDirectory ,
172
+ reason : 'schedule' ,
173
+ options : overrides ,
174
+ target,
175
+ } ) ;
162
176
}
163
177
164
178
job . outboundBus . subscribe (
@@ -181,70 +195,42 @@ async function _scheduleTarget(
181
195
export function createBuilder < OptT extends json . JsonObject > (
182
196
fn : BuilderHandlerFn < OptT > ,
183
197
) : Builder < OptT > {
184
- function handler (
185
- options : boolean ,
186
- context : experimental . jobs . JobHandlerContext < boolean , BuilderInput , BuilderOutput > ,
187
- ) {
188
- const description = context . description ;
198
+ const cjh = experimental . jobs . createJobHandler ;
199
+ const handler = cjh < json . JsonObject , BuilderInput , BuilderOutput > ( ( options , context ) => {
189
200
const scheduler = context . scheduler ;
190
-
191
- return new Observable < experimental . jobs . JobOutboundMessage < BuilderOutput > > ( observer => {
192
- const logger = new logging . Logger ( 'job' ) ;
193
- logger . subscribe ( entry => {
194
- observer . next ( {
195
- kind : JobOutboundMessageKind . Log ,
196
- description,
197
- entry,
198
- } ) ;
199
- } ) ;
200
-
201
- context . inboundBus . subscribe ( x => {
202
- if ( x . kind === experimental . jobs . JobInboundMessageKind . Input ) {
203
- const i = x . value ;
204
- const context : BuilderContext = {
205
- workspaceRoot : i . workspaceRoot ,
206
- currentDirectory : i . currentDirectory ,
207
- target : i . target ,
208
- logger,
209
- scheduleTarget ( target : Target , overrides : json . JsonObject ) {
210
- return _scheduleTarget ( target , overrides , scheduler , {
211
- logger,
212
- workspaceRoot : i . workspaceRoot ,
213
- currentDirectory : i . currentDirectory ,
214
- } ) ;
215
- } ,
216
- } ;
217
-
218
- let result = fn ( i . options as OptT , context ) ;
219
-
220
- if ( isPromise ( result ) ) {
221
- result = from ( result ) ;
222
- } else if ( ! isObservable ( result ) ) {
223
- result = of ( result ) ;
224
- }
225
-
226
- result . subscribe (
227
- value => observer . next ( {
228
- kind : experimental . jobs . JobOutboundMessageKind . Output ,
229
- description,
230
- value,
231
- } ) ,
232
- err => observer . error ( err ) ,
233
- ( ) => observer . complete ( ) ,
234
- ) ;
201
+ const logger = context . logger ;
202
+
203
+ return new Observable < BuilderOutput > ( observer => {
204
+ context . input . subscribe ( i => {
205
+ const context : BuilderContext = {
206
+ workspaceRoot : i . workspaceRoot ,
207
+ currentDirectory : i . currentDirectory ,
208
+ target : i . target as Target ,
209
+ logger : logger ,
210
+ scheduleTarget ( target : Target , overrides : json . JsonObject ) {
211
+ return _scheduleTarget ( target , overrides , scheduler , {
212
+ logger : logger . createChild ( '' ) ,
213
+ workspaceRoot : i . workspaceRoot ,
214
+ currentDirectory : i . currentDirectory ,
215
+ } ) ;
216
+ } ,
217
+ } ;
218
+
219
+ let result = fn ( i . options as OptT , context ) ;
220
+
221
+ if ( isPromise ( result ) ) {
222
+ result = from ( result ) ;
223
+ } else if ( ! isObservable ( result ) ) {
224
+ result = of ( result ) ;
235
225
}
236
- } ) ;
237
226
238
- // The job is ready to listen.
239
- observer . next ( {
240
- description,
241
- kind : experimental . jobs . JobOutboundMessageKind . Start ,
227
+ return result . subscribe ( observer ) ;
242
228
} ) ;
243
229
} ) ;
244
- }
230
+ } ) ;
245
231
246
232
return {
247
- handler : Object . assign ( handler , { jobDescription : { } } ) ,
233
+ handler,
248
234
[ BuilderSymbol ] : true ,
249
235
[ VersionSymbol ] : require ( '../package.json' ) . version ,
250
236
} ;
@@ -253,6 +239,7 @@ export function createBuilder<OptT extends json.JsonObject>(
253
239
function _createBackwardCompatibleJobHandlerFromBuilderInfo (
254
240
info : BuilderInfo ,
255
241
target : Target | undefined ,
242
+ host : ArchitectHost ,
256
243
registry : json . schema . SchemaRegistry ,
257
244
baseOptions : json . JsonObject ,
258
245
) : Observable < BuilderJobHandler | null > {
@@ -263,6 +250,7 @@ function _createBackwardCompatibleJobHandlerFromBuilderInfo(
263
250
return from ( module . createBackwardCompatibleJobHandlerFromBuilderInfo (
264
251
info ,
265
252
target ,
253
+ host ,
266
254
registry ,
267
255
baseOptions ,
268
256
) ) ;
@@ -273,6 +261,7 @@ function _createBackwardCompatibleJobHandlerFromBuilderInfo(
273
261
function _createJobHandlerFromBuilderInfo (
274
262
info : BuilderInfo ,
275
263
_target : Target | undefined ,
264
+ host : ArchitectHost ,
276
265
registry : json . schema . SchemaRegistry ,
277
266
baseOptions : json . JsonObject ,
278
267
) : Observable < BuilderJobHandler > {
@@ -284,15 +273,6 @@ function _createJobHandlerFromBuilderInfo(
284
273
info,
285
274
} ;
286
275
287
- const loader = async ( ) => {
288
- const builder = ( await import ( info . import ) ) . default ;
289
- if ( builder [ BuilderSymbol ] ) {
290
- return builder . handler ;
291
- }
292
-
293
- throw new Error ( 'Builder is not a builder' ) ;
294
- } ;
295
-
296
276
function handler ( argument : json . JsonObject , context : experimental . jobs . JobHandlerContext ) {
297
277
const inboundBus = context . inboundBus . pipe (
298
278
concatMap ( message => {
@@ -323,7 +303,7 @@ function _createJobHandlerFromBuilderInfo(
323
303
} ) ,
324
304
) ;
325
305
326
- return from ( loader ( ) ) . pipe (
306
+ return from ( host . loadBuilder ( info ) ) . pipe (
327
307
switchMap ( fn => fn ( argument , { ...context , inboundBus } ) ) ,
328
308
) ;
329
309
}
@@ -372,10 +352,17 @@ export class ArchitectBuilderJobRegistry implements BuilderRegistry {
372
352
result = _createBackwardCompatibleJobHandlerFromBuilderInfo (
373
353
info ,
374
354
target ,
355
+ this . _host ,
375
356
this . _registry ,
376
357
options || { } ) ;
377
358
} else {
378
- result = _createJobHandlerFromBuilderInfo ( info , target , this . _registry , options || { } ) ;
359
+ result = _createJobHandlerFromBuilderInfo (
360
+ info ,
361
+ target ,
362
+ this . _host ,
363
+ this . _registry ,
364
+ options || { } ,
365
+ ) ;
379
366
}
380
367
381
368
if ( cache ) {
0 commit comments