| /** |
| * @license |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| import {Finalizable} from '../../services/registry'; |
| import {Observable, Subject} from 'rxjs'; |
| import { |
| CheckResult, |
| CheckRun, |
| ChecksApiConfig, |
| ChecksProvider, |
| } from '../../api/checks'; |
| import {Model} from '../model'; |
| import {define} from '../dependency'; |
| import {select} from '../../utils/observable-util'; |
| |
| export interface ChecksPlugin { |
| pluginName: string; |
| provider: ChecksProvider; |
| config: ChecksApiConfig; |
| } |
| |
| export interface ChecksUpdate { |
| pluginName: string; |
| run: CheckRun; |
| result: CheckResult; |
| } |
| |
| /** Application wide state of plugins. */ |
| interface PluginsState { |
| /** |
| * List of plugins that have called checks().register(). |
| */ |
| checksPlugins: ChecksPlugin[]; |
| } |
| |
| export const pluginsModelToken = define<PluginsModel>('plugins-model'); |
| |
| export class PluginsModel extends Model<PluginsState> implements Finalizable { |
| /** Private version of the event bus below. */ |
| private checksAnnounceSubject$ = new Subject<ChecksPlugin>(); |
| |
| /** Event bus for telling the checks models that announce() was called. */ |
| public checksAnnounce$: Observable<ChecksPlugin> = |
| this.checksAnnounceSubject$.asObservable(); |
| |
| /** Private version of the event bus below. */ |
| private checksUpdateSubject$ = new Subject<ChecksUpdate>(); |
| |
| /** Event bus for telling the checks models that updateResult() was called. */ |
| public checksUpdate$: Observable<ChecksUpdate> = |
| this.checksUpdateSubject$.asObservable(); |
| |
| public checksPlugins$ = select(this.state$, state => state.checksPlugins); |
| |
| constructor() { |
| super({ |
| checksPlugins: [], |
| }); |
| } |
| |
| finalize() { |
| this.subject$.complete(); |
| } |
| |
| checksRegister(plugin: ChecksPlugin) { |
| const nextState = {...this.subject$.getValue()}; |
| nextState.checksPlugins = [...nextState.checksPlugins]; |
| const alreadysRegistered = nextState.checksPlugins.some( |
| p => p.pluginName === plugin.pluginName |
| ); |
| if (alreadysRegistered) { |
| console.warn( |
| `${plugin.pluginName} tried to register twice as a checks provider. Ignored.` |
| ); |
| return; |
| } |
| nextState.checksPlugins.push(plugin); |
| this.subject$.next(nextState); |
| } |
| |
| checksUpdate(update: ChecksUpdate) { |
| const plugins = this.subject$.getValue().checksPlugins; |
| const plugin = plugins.find(p => p.pluginName === update.pluginName); |
| if (!plugin) { |
| console.warn( |
| `Plugin '${update.pluginName}' not found. checksUpdate() ignored.` |
| ); |
| return; |
| } |
| this.checksUpdateSubject$.next(update); |
| } |
| |
| checksAnnounce(pluginName: string) { |
| const plugins = this.subject$.getValue().checksPlugins; |
| const plugin = plugins.find(p => p.pluginName === pluginName); |
| if (!plugin) { |
| console.warn( |
| `Plugin '${pluginName}' not found. checksAnnounce() ignored.` |
| ); |
| return; |
| } |
| this.checksAnnounceSubject$.next(plugin); |
| } |
| } |