/* * CloudBeaver - Cloud Database Manager * Copyright (C) 2020-2022 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ import type { IAsyncContextLoader, IContextLoader, IExecutionContext, ISyncContextLoader } from './IExecutionContext'; export class ExecutionContext implements IExecutionContext { readonly contexts: Map, any>; readonly contextCreators: Map, IContextLoader>; constructor(private readonly data: TData, context?: IExecutionContext) { this.contexts = context?.contexts || new Map(); this.contextCreators = context?.contextCreators ?? new Map(); } addContextCreators( creators: [IContextLoader, IContextLoader][] ): void { for (const [key, value] of creators) { this.contextCreators.set(key, value); } } hasContext(loader: IContextLoader): boolean { return this.contextCreators.has(loader) || this.contexts.has(loader); } getContext(token: ISyncContextLoader): T; getContext(token: IAsyncContextLoader): Promise; getContext(token: IContextLoader): Promise | T { if (this.contexts.has(token)) { return this.contexts.get(token); } let value: T | Promise; if (this.contextCreators.has(token)) { value = this.contextCreators.get(token)!(this, this.data); } else { value = token(this, this.data); } if (value instanceof Promise) { return this.getAsyncContext(token, value); } this.setContext(token, value); return value; } private async getAsyncContext(token: IContextLoader, promise: Promise) { const value = await promise; this.setContext(token, value); return value; } private setContext(token: IContextLoader, value: T) { if (value !== null && value !== undefined) { this.contexts.set(token, value); } } }