1
- import { BehaviorSubject , combineLatest , Observable , Unsubscribable } from 'rxjs'
2
- import { distinctUntilChanged , map } from 'rxjs/operators'
1
+ import { BehaviorSubject , combineLatest , isObservable , Observable , of , Unsubscribable } from 'rxjs'
2
+ import { distinctUntilChanged , map , switchMap } from 'rxjs/operators'
3
3
import {
4
4
ActionContribution ,
5
5
ActionItem ,
@@ -8,16 +8,22 @@ import {
8
8
MenuContributions ,
9
9
MenuItemContribution ,
10
10
} from '../../protocol'
11
- import { isEqual } from '../../util'
11
+ import { flatten , isEqual } from '../../util'
12
12
import { getComputedContextProperty } from '../context/context'
13
13
import { ComputedContext , evaluate , evaluateTemplate } from '../context/expr/evaluator'
14
14
import { TEMPLATE_BEGIN } from '../context/expr/lexer'
15
15
import { Environment } from '../environment'
16
16
17
17
/** A registered set of contributions from an extension in the registry. */
18
18
export interface ContributionsEntry {
19
- /** The contributions. */
20
- contributions : Contributions
19
+ /**
20
+ * The contributions, either as a value or an observable.
21
+ *
22
+ * If an observable is used, it should be a cold Observable and emit (e.g., its current value) upon
23
+ * subscription. The {@link ContributionRegistry#contributions} observable blocks until all observables have
24
+ * emitted.
25
+ */
26
+ contributions : Contributions | Observable < Contributions | Contributions [ ] >
21
27
}
22
28
23
29
/**
@@ -70,10 +76,21 @@ export class ContributionRegistry {
70
76
public readonly contributions : Observable < Contributions > = this . getContributions ( this . _entries )
71
77
72
78
protected getContributions ( entries : Observable < ContributionsEntry [ ] > ) : Observable < Contributions > {
73
- return combineLatest ( entries , this . environment ) . pipe (
74
- map ( ( [ entries , environment ] ) => {
79
+ return combineLatest (
80
+ entries . pipe (
81
+ switchMap ( entries =>
82
+ combineLatest (
83
+ ...entries . map (
84
+ entry => ( isObservable ( entry . contributions ) ? entry . contributions : of ( entry . contributions ) )
85
+ )
86
+ )
87
+ )
88
+ ) ,
89
+ this . environment
90
+ ) . pipe (
91
+ map ( ( [ multiContributions , environment ] ) => {
75
92
const computedContext = { get : ( key : string ) => getComputedContextProperty ( environment , key ) }
76
- return entries . map ( ( { contributions } ) => {
93
+ return flatten ( multiContributions ) . map ( contributions => {
77
94
try {
78
95
return evaluateContributions (
79
96
computedContext ,
0 commit comments