Skip to content

Commit

Permalink
[Expressions] Update expressions public API to expose partial results…
Browse files Browse the repository at this point in the history
… support (#102403)

* Add partial result flag to the execution result
* Update expressions plugin run method to return observable
* Update data getter in the execution contract to return observable
* Update the expression loader to take into account the partial results flag
  • Loading branch information
dokmic authored Jul 1, 2021
1 parent 6e74040 commit 975e361
Show file tree
Hide file tree
Showing 43 changed files with 370 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
interpret<T>(ast: ExpressionAstNode, input: T): Observable<unknown>;
interpret<T>(ast: ExpressionAstNode, input: T): Observable<ExecutionResult<unknown>>;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ interpret<T>(ast: ExpressionAstNode, input: T): Observable<unknown>;

<b>Returns:</b>

`Observable<unknown>`
`Observable<ExecutionResult<unknown>>`

Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export declare class Execution<Input = unknown, Output = unknown, InspectorAdapt
| [expression](./kibana-plugin-plugins-expressions-public.execution.expression.md) | | <code>string</code> | |
| [input](./kibana-plugin-plugins-expressions-public.execution.input.md) | | <code>Input</code> | Initial input of the execution.<!-- -->N.B. It is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |
| [inspectorAdapters](./kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md) | | <code>InspectorAdapters</code> | |
| [result](./kibana-plugin-plugins-expressions-public.execution.result.md) | | <code>Observable&lt;Output &#124; ExpressionValueError&gt;</code> | Future that tracks result or error of this execution. |
| [state](./kibana-plugin-plugins-expressions-public.execution.state.md) | | <code>ExecutionContainer&lt;Output &#124; ExpressionValueError&gt;</code> | Dynamic state of the execution. |
| [result](./kibana-plugin-plugins-expressions-public.execution.result.md) | | <code>Observable&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Future that tracks result or error of this execution. |
| [state](./kibana-plugin-plugins-expressions-public.execution.state.md) | | <code>ExecutionContainer&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Dynamic state of the execution. |

## Methods

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Future that tracks result or error of this execution.
<b>Signature:</b>

```typescript
readonly result: Observable<Output | ExpressionValueError>;
readonly result: Observable<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons
<b>Signature:</b>

```typescript
start(input?: Input): Observable<Output | ExpressionValueError>;
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
```

## Parameters
Expand All @@ -22,5 +22,5 @@ start(input?: Input): Observable<Output | ExpressionValueError>;

<b>Returns:</b>

`Observable<Output | ExpressionValueError>`
`Observable<ExecutionResult<Output | ExpressionValueError>>`

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Dynamic state of the execution.
<b>Signature:</b>

```typescript
readonly state: ExecutionContainer<Output | ExpressionValueError>;
readonly state: ExecutionContainer<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Returns the final output of expression, if any error happens still wraps that er
<b>Signature:</b>

```typescript
getData: () => Promise<Output | ExpressionValueError>;
getData: () => Observable<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export declare class ExecutionContract<Input = unknown, Output = unknown, Inspec
| [cancel](./kibana-plugin-plugins-expressions-public.executioncontract.cancel.md) | | <code>() =&gt; void</code> | Cancel the execution of the expression. This will set abort signal (available in execution context) to aborted state, letting expression functions to stop their execution. |
| [execution](./kibana-plugin-plugins-expressions-public.executioncontract.execution.md) | | <code>Execution&lt;Input, Output, InspectorAdapters&gt;</code> | |
| [getAst](./kibana-plugin-plugins-expressions-public.executioncontract.getast.md) | | <code>() =&gt; ExpressionAstExpression</code> | Get AST used to execute the expression. |
| [getData](./kibana-plugin-plugins-expressions-public.executioncontract.getdata.md) | | <code>() =&gt; Promise&lt;Output &#124; ExpressionValueError&gt;</code> | Returns the final output of expression, if any error happens still wraps that error into <code>ExpressionValueError</code> type and returns that. This function never throws. |
| [getData](./kibana-plugin-plugins-expressions-public.executioncontract.getdata.md) | | <code>() =&gt; Observable&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Returns the final output of expression, if any error happens still wraps that error into <code>ExpressionValueError</code> type and returns that. This function never throws. |
| [getExpression](./kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md) | | <code>() =&gt; string</code> | Get string representation of the expression. Returns the original string if execution was started from a string. If execution was started from an AST this method returns a string generated from AST. |
| [inspect](./kibana-plugin-plugins-expressions-public.executioncontract.inspect.md) | | <code>() =&gt; InspectorAdapters</code> | Get Inspector adapters provided to all functions of expression through execution context. |
| [isPending](./kibana-plugin-plugins-expressions-public.executioncontract.ispending.md) | | <code>boolean</code> | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Execute expression and return result.
<b>Signature:</b>

```typescript
run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams): Observable<Output | ExpressionValueError>;
run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams): Observable<ExecutionResult<Output | ExpressionValueError>>;
```

## Parameters
Expand All @@ -22,5 +22,5 @@ run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?:

<b>Returns:</b>

`Observable<Output | ExpressionValueError>`
`Observable<ExecutionResult<Output | ExpressionValueError>>`

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface ExpressionsServiceStart
| [getFunction](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md) | <code>(name: string) =&gt; ReturnType&lt;Executor['getFunction']&gt;</code> | Get a registered <code>ExpressionFunction</code> by its name, which was registered using the <code>registerFunction</code> method. The returned <code>ExpressionFunction</code> instance is an internal representation of the function in Expressions service - do not mutate that object. |
| [getRenderer](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md) | <code>(name: string) =&gt; ReturnType&lt;ExpressionRendererRegistry['get']&gt;</code> | Get a registered <code>ExpressionRenderer</code> by its name, which was registered using the <code>registerRenderer</code> method. The returned <code>ExpressionRenderer</code> instance is an internal representation of the renderer in Expressions service - do not mutate that object. |
| [getType](./kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md) | <code>(name: string) =&gt; ReturnType&lt;Executor['getType']&gt;</code> | Get a registered <code>ExpressionType</code> by its name, which was registered using the <code>registerType</code> method. The returned <code>ExpressionType</code> instance is an internal representation of the type in Expressions service - do not mutate that object. |
| [run](./kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md) | <code>&lt;Input, Output&gt;(ast: string &#124; ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams) =&gt; Promise&lt;Output&gt;</code> | Executes expression string or a parsed expression AST and immediately returns the result.<!-- -->Below example will execute <code>sleep 100 &#124; clog</code> expression with <code>123</code> initial input to the first function.
| [run](./kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md) | <code>&lt;Input, Output&gt;(ast: string &#124; ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams) =&gt; Observable&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Executes expression string or a parsed expression AST and immediately returns the result.<!-- -->Below example will execute <code>sleep 100 &#124; clog</code> expression with <code>123</code> initial input to the first function.
```ts
expressions.run('sleep 100 | clog', 123);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ expressions.run('...', null, { elasticsearchClient });
<b>Signature:</b>

```typescript
run: <Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams) => Promise<Output>;
run: <Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams) => Observable<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IExpressionLoaderParams
| [hasCompatibleActions](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.hascompatibleactions.md) | <code>ExpressionRenderHandlerParams['hasCompatibleActions']</code> | |
| [inspectorAdapters](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md) | <code>Adapters</code> | |
| [onRenderError](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md) | <code>RenderErrorHandlerFnType</code> | |
| [partial](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.partial.md) | <code>boolean</code> | |
| [renderMode](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.rendermode.md) | <code>RenderMode</code> | |
| [searchContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md) | <code>SerializableState</code> | |
| [searchSessionId](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchsessionid.md) | <code>string</code> | |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) &gt; [partial](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.partial.md)

## IExpressionLoaderParams.partial property

<b>Signature:</b>

```typescript
partial?: boolean;
```
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams
| [dataAttrs](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md) | <code>string[]</code> | |
| [debounce](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md) | <code>number</code> | |
| [expression](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md) | <code>string &#124; ExpressionAstExpression</code> | |
| [onData$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md) | <code>&lt;TData, TInspectorAdapters&gt;(data: TData, adapters?: TInspectorAdapters) =&gt; void</code> | |
| [onData$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md) | <code>&lt;TData, TInspectorAdapters&gt;(data: TData, adapters?: TInspectorAdapters, partial?: boolean) =&gt; void</code> | |
| [onEvent](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md) | <code>(event: ExpressionRendererEvent) =&gt; void</code> | |
| [padding](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md) | <code>'xs' &#124; 's' &#124; 'm' &#124; 'l' &#124; 'xl'</code> | |
| [reload$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md) | <code>Observable&lt;unknown&gt;</code> | An observable which can be used to re-run the expression without destroying the component |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
<b>Signature:</b>

```typescript
onData$?: <TData, TInspectorAdapters>(data: TData, adapters?: TInspectorAdapters) => void;
onData$?: <TData, TInspectorAdapters>(data: TData, adapters?: TInspectorAdapters, partial?: boolean) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
interpret<T>(ast: ExpressionAstNode, input: T): Observable<unknown>;
interpret<T>(ast: ExpressionAstNode, input: T): Observable<ExecutionResult<unknown>>;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ interpret<T>(ast: ExpressionAstNode, input: T): Observable<unknown>;

<b>Returns:</b>

`Observable<unknown>`
`Observable<ExecutionResult<unknown>>`

Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export declare class Execution<Input = unknown, Output = unknown, InspectorAdapt
| [expression](./kibana-plugin-plugins-expressions-server.execution.expression.md) | | <code>string</code> | |
| [input](./kibana-plugin-plugins-expressions-server.execution.input.md) | | <code>Input</code> | Initial input of the execution.<!-- -->N.B. It is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |
| [inspectorAdapters](./kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md) | | <code>InspectorAdapters</code> | |
| [result](./kibana-plugin-plugins-expressions-server.execution.result.md) | | <code>Observable&lt;Output &#124; ExpressionValueError&gt;</code> | Future that tracks result or error of this execution. |
| [state](./kibana-plugin-plugins-expressions-server.execution.state.md) | | <code>ExecutionContainer&lt;Output &#124; ExpressionValueError&gt;</code> | Dynamic state of the execution. |
| [result](./kibana-plugin-plugins-expressions-server.execution.result.md) | | <code>Observable&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Future that tracks result or error of this execution. |
| [state](./kibana-plugin-plugins-expressions-server.execution.state.md) | | <code>ExecutionContainer&lt;ExecutionResult&lt;Output &#124; ExpressionValueError&gt;&gt;</code> | Dynamic state of the execution. |

## Methods

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Future that tracks result or error of this execution.
<b>Signature:</b>

```typescript
readonly result: Observable<Output | ExpressionValueError>;
readonly result: Observable<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons
<b>Signature:</b>

```typescript
start(input?: Input): Observable<Output | ExpressionValueError>;
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
```

## Parameters
Expand All @@ -22,5 +22,5 @@ start(input?: Input): Observable<Output | ExpressionValueError>;

<b>Returns:</b>

`Observable<Output | ExpressionValueError>`
`Observable<ExecutionResult<Output | ExpressionValueError>>`

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Dynamic state of the execution.
<b>Signature:</b>

```typescript
readonly state: ExecutionContainer<Output | ExpressionValueError>;
readonly state: ExecutionContainer<ExecutionResult<Output | ExpressionValueError>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Execute expression and return result.
<b>Signature:</b>

```typescript
run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams): Observable<Output | ExpressionValueError>;
run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?: ExpressionExecutionParams): Observable<ExecutionResult<Output | ExpressionValueError>>;
```

## Parameters
Expand All @@ -22,5 +22,5 @@ run<Input, Output>(ast: string | ExpressionAstExpression, input: Input, params?:

<b>Returns:</b>

`Observable<Output | ExpressionValueError>`
`Observable<ExecutionResult<Output | ExpressionValueError>>`

19 changes: 8 additions & 11 deletions examples/expressions_explorer/public/run_expressions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import React, { useState, useEffect, useMemo } from 'react';
import { pluck } from 'rxjs/operators';
import {
EuiCodeBlock,
EuiFlexItem,
Expand Down Expand Up @@ -35,7 +36,7 @@ interface Props {

export function RunExpressionsExample({ expressions, inspector }: Props) {
const [expression, updateExpression] = useState('markdown "## expressions explorer"');
const [result, updateResult] = useState({});
const [result, updateResult] = useState<unknown>({});

const expressionChanged = (value: string) => {
updateExpression(value);
Expand All @@ -49,17 +50,13 @@ export function RunExpressionsExample({ expressions, inspector }: Props) {
);

useEffect(() => {
const runExpression = async () => {
const execution = expressions.execute(expression, null, {
debug: true,
inspectorAdapters,
});
const execution = expressions.execute(expression, null, {
debug: true,
inspectorAdapters,
});
const subscription = execution.getData().pipe(pluck('result')).subscribe(updateResult);

const data: any = await execution.getData();
updateResult(data);
};

runExpression();
return () => subscription.unsubscribe();
}, [expression, expressions, inspectorAdapters]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* Side Public License, v 1.
*/

import { first } from 'rxjs/operators';
import { waitFor } from '@testing-library/react';
import { Execution } from './execution';
import { parseExpression } from '../ast';
Expand Down Expand Up @@ -40,9 +39,9 @@ describe('Execution abortion tests', () => {
execution.start();
execution.cancel();

const result = await execution.result.pipe(first()).toPromise();
const result = await execution.result.toPromise();

expect(result).toMatchObject({
expect(result).toHaveProperty('result', {
type: 'error',
error: {
message: 'The expression was aborted.',
Expand All @@ -58,9 +57,9 @@ describe('Execution abortion tests', () => {
jest.advanceTimersByTime(100);
execution.cancel();

const result = await execution.result.pipe(first()).toPromise();
const result = await execution.result.toPromise();

expect(result).toMatchObject({
expect(result).toHaveProperty('result', {
type: 'error',
error: {
message: 'The expression was aborted.',
Expand All @@ -76,7 +75,7 @@ describe('Execution abortion tests', () => {

execution.start();

const result = await execution.result.pipe(first()).toPromise();
const { result } = await execution.result.toPromise();

execution.cancel();

Expand Down Expand Up @@ -136,7 +135,7 @@ describe('Execution abortion tests', () => {
await waitFor(() => expect(started).toHaveBeenCalledTimes(1));

execution.cancel();
const result = await execution.result.pipe(first()).toPromise();
const { result } = await execution.result.toPromise();
expect(result).toMatchObject({
type: 'error',
error: {
Expand Down
Loading

0 comments on commit 975e361

Please sign in to comment.