-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathopen-context-runtime.ts
94 lines (84 loc) · 3.19 KB
/
open-context-runtime.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import type { Completion } from './autocompleter/autocompleter';
import type { ServiceProvider } from '@mongosh/service-provider-core';
import { ShellApiAutocompleter } from './autocompleter/shell-api-autocompleter';
import type {
Runtime,
RuntimeEvaluationResult,
RuntimeEvaluationListener,
} from './runtime';
import { EventEmitter } from 'events';
import { ShellInstanceState } from '@mongosh/shell-api';
import { ShellEvaluator } from '@mongosh/shell-evaluator';
import type { MongoshBus } from '@mongosh/types';
export type ContextValue = any;
export interface InterpreterEnvironment {
sloppyEval(code: string): ContextValue;
getContextObject(): ContextValue;
}
/**
* This class is the core implementation for a runtime which is not isolated
* from the environment of the presentation layer.
*
* This means that the interaction between the runtime and the execution context (
* service provider, autocompleter, ...), can happen through direct method
* calls rather than requiring event emitter bridges or RPC.
*/
export class OpenContextRuntime implements Runtime {
private interpreterEnvironment: InterpreterEnvironment;
private autocompleter: ShellApiAutocompleter | null = null;
private shellEvaluator: ShellEvaluator;
private instanceState: ShellInstanceState;
private evaluationListener: RuntimeEvaluationListener | null = null;
private updatedConnectionInfoPromise: Promise<void> | null = null;
constructor(
serviceProvider: ServiceProvider,
interpreterEnvironment: InterpreterEnvironment,
messageBus?: MongoshBus
) {
this.interpreterEnvironment = interpreterEnvironment;
this.instanceState = new ShellInstanceState(
serviceProvider as any,
messageBus || new EventEmitter()
);
this.instanceState.isInteractive = true;
this.shellEvaluator = new ShellEvaluator(this.instanceState);
this.instanceState.setCtx(this.interpreterEnvironment.getContextObject());
}
async getCompletions(code: string): Promise<Completion[]> {
if (!this.autocompleter) {
this.autocompleter = new ShellApiAutocompleter(
this.instanceState.getAutocompleteParameters()
);
this.updatedConnectionInfoPromise ??=
this.instanceState.fetchConnectionInfo();
await this.updatedConnectionInfoPromise;
}
return this.autocompleter.getCompletions(code);
}
async evaluate(code: string): Promise<RuntimeEvaluationResult> {
const evalFn = this.interpreterEnvironment.sloppyEval.bind(
this.interpreterEnvironment
);
const { type, printable, source } = await this.shellEvaluator.customEval(
evalFn,
code,
this.interpreterEnvironment.getContextObject(),
''
);
return { type, printable, source };
}
setEvaluationListener(
listener: RuntimeEvaluationListener
): RuntimeEvaluationListener | null {
const prev = this.evaluationListener;
this.evaluationListener = listener;
this.instanceState.setEvaluationListener(listener);
return prev;
}
async getShellPrompt(): Promise<string> {
this.updatedConnectionInfoPromise ??=
this.instanceState.fetchConnectionInfo();
await this.updatedConnectionInfoPromise;
return await this.instanceState.getDefaultPrompt();
}
}