Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeStall authored Nov 25, 2021
1 parent d1fd4ea commit 63ae373
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions Samples/WebDemo/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
# Introduction
Demonstrates a web page hosting the Power Fx Formula Bar and doing evaluation.
The formula bar is a client-side react control that wraps the[ Monaco editor](https://microsoft.github.io/monaco-editor/) to provide features like error squiggles, completion suggestions, and function tool tips.

![image](https://user-images.githubusercontent.com/1538900/143385087-c086a26c-9f0d-4989-b5b5-0fe489ebc314.png)

# Consuming the formula bar

# Architecture
The formula bar is a client-side react control that wraps the[ Monaco editor](https://microsoft.github.io/monaco-editor/).
The Power Fx formula bar is provided via a react control in the [@microsoft/power-fx-formulabar](https://www.npmjs.com/package/@microsoft/power-fx-formulabar) npm package.

It makes network calls to the server-side component which implements the [Language Service Protocol](https://docs.microsoft.com/en-us/visualstudio/extensibility/language-server-protocol) on top of Power Fx to provide IDE features like completion suggestions, error squiggles, and inline help. The LSP work is done in the `Microsoft.PowerFx.LanguageServerProtocol` nuget package.
```
<PowerFxFormulaEditor
getDocumentUriAsync={this._getDocumentUriAsync}
defaultValue={''}
messageProcessor={this._messageProcessor}
maxLineCount={4}
minLineCount={4}
onChange={(newValue: string): void => {
this.setState({ expression: newValue, hasErrors: false });
this._evalAsync(context, newValue);
}}
onEditorDidMount={(editor, _): void => { this._editor = editor }}
lspConfig={{
enableSignatureHelpRequest: true
}}
/>
```

`getDocumentUriAsync` is used to provide a string with context for this formula bar which will get passed to the language server and used to recreate a `RecalcEngine` with appropriate symbols and context. This context can be any arbitrary uri string (including query parameters) and so it enables multiple formula bars as well as passing in client-side state.

`messageProcessor` is used to communicate to the LSP. The Power Fx compiler is implemented in C# and so the client-side formula bar must make network requests to consume the server-side LSP. That could be any network channel such as web sockets, signal R, or rest.

## Flow for intellisense:

1. The client page instantiates a <PowerFxFormulaEditor> control and provides context via getDocumentUriAsync.
1. User edits text in the <PowerFxFormulaEditor> control.
1. The control sends a LSP message via `messageProcessor`
1. That message is received server side by the ASP controller [LanguageServerController.HandleRequest](https://github.com/microsoft/power-fx-host-samples/blob/main/Samples/WebDemo/service/Controllers/LanguageServerController.cs).
1. The controller is just a lightweight controller that passes the message through to the [LanguageServer](https://github.com/microsoft/Power-Fx/blob/main/src/libraries/Microsoft.PowerFx.LanguageServerProtocol/LanguageServer/LanguageServer.cs) instance, which was implemented by the PowerFx.LSP package.
1. the `LanguageServer` class is sealed and ultimately calls back on the `RecalcEngine` instance to access symbols. It gets this instance via a [IPowerFxScopeFactory](https://github.com/microsoft/Power-Fx/blob/main/src/libraries/Microsoft.PowerFx.LanguageServerProtocol/LanguageServer/IPowerFxScopeFactory.cs) passed to the ctor. The `IPowerFxScopeFactory` maps the getDocumentUriAsync value back to a [IPowerFxScope](https://github.com/microsoft/Power-Fx/blob/main/src/libraries/Microsoft.PowerFx.Core/Public/IPowerFxScope.cs) instance. This scope instance includes the `RecalcEngine` instance and captures the context from getDocumentUriAsync. In this sample, that context is the json state variables.
1. The `LanguageServer` calls methods on `IPowerFxScope` to do intellisense and returns the results back over the network channel according to the LSP.
1. The client control renders the results.

The test site also makes calls to the server to evaluate the power fx expressions using the Power Fx interpreter in `Microsoft.PowerFx.Interpreter`.

# Getting Started
Dependencies:
Expand Down Expand Up @@ -38,3 +69,4 @@ This will produce static build files in the `.\app\build` directory.
Copy these to the wwwroot.

2. Deploy the service to the same site.

0 comments on commit 63ae373

Please sign in to comment.