fMichaleczek / PowerShellLab

11 stars 0 forks source link

actual source #16

Open klumsy opened 1 month ago

klumsy commented 1 month ago

this looks like the rendered version, do you have the source of the blazor so we could extend things.. i want to work on the xterm console interactions some, and the PShost - so its not just coerced to strings.. and then i also want to plumb some browser host stuff as functions into the PowerShell (eg so we can use it to do AJAX calls out) , and when running in hosts (such as a web browser control in an iphone app) be able to plumb through JAvascript native abilities, including to play into the IOS workflow/Shortcut schedule, much like Pyto/Pythonista does.

fMichaleczek commented 1 month ago

It's a long story... PowerShell needs 2 threads to await an async method and this makes it impossible to exit/communicate with the only available client httpclient.

Microsoft has postponed multithreading for Blazor for net10. I have a PoC that is based on the dotnet SDK instead of AspNetCore and one of the preview versions was functional. However, I advise you to read the designs if you want to understand the complexity. The dotnet team is sweating on the subject and we shouldn't ask too much because it's moving forward but with pain. I contacted the main dev on the subject but he cannot confirm anything.

Currently the JitInterpreter has been disabled for 2 or 3 previews. I got fed up with the overlapping SDK issues between dotnet and aspnetcore.

There is no Terminal on Browser, Android. XTerm.js is not mobile compatible, neither is Monaco Editor, but Code Mirror is! Best bet is to wait for Avalonia's multithreaded support and create a control terminal and push it everywhere. But that's more for next year.

I'm not working on Wasm in the end but rather on the Mono VM. There is currently a prototype from the Labs runtime which allows you to host the Linq interpreter on iPhone using a statically compiled mono runtime.

If you can come back around September 15 to see the status of the dotnet 9.0 Preview and see if we are good.

https://twitter.com/_Flavien/status/1777099099956793727

fMichaleczek commented 1 month ago

https://github.com/dotnet/runtime/issues/85592

klumsy commented 1 month ago

Thanks for taking the time to answer me. I understand that. Though i still think there is value.. what things need the multiple threads? Obviously the HTTPclient, likely used by invoke-command , likely also start-job stuff etc, the workflow stuff, and remoting… but i presume that the vast majority of language stuff works fine in this Sandbox. If this is true, then i feel we can use other mechanisms to break free from the sandbox. If we can bridge from powershell (and into Powershell) calls to WASM or JavaScript in the host, then we can make functions that use the browser to do HTTP calls, and then more if the web browser is hosted in an app which also plumbs in native OS stuff (like hosting a web browser control in IOS) also - the XtermJS limitations don’t concern me too much, as I’d be happy with something that doesn’t have to be a true console.. Much like with Powershell ISE, and also when i first built PowerShell Analyzer back in the day.. Additionally for a rich editor, there are many options that can be hosted in a web browser, we just need to be able to plumb the calls back and forth between JavaScript and the blazor app.

fMichaleczek commented 1 month ago

You are missing a lot of small details that constrain the WASM environment.

Let's take an example, I can't await an Async method at runtime. This causes an error because of the browser's threading model The code live in a loop within the UI Thead

image

This model is supportable if you are in compiled dotnet, where it is possible to program everything asynchronously.

For PowerShell? It's complicated, I am able to execute the System.Management.Automation.PowerShell Invoke asynchronously (through APM 2 Task). But it blocks the UI thread and I still can not await any async method to use the low level API bring by WASM dotnet ( the webclient is different from the standard one)

The only way out of this is for dotnet to manage WASM multithreading so that I can launch a thread outside the UI thread (which will be executed by a webworker) At the same time, this repairs the async method problem, the UI thread problem and also the HTTP client (but there is also more restriction for the CORS Part : Cross-Origin-Embedder-Policy: require-corp + Cross-Origin-Opener-Policy: same-origin)

Mono VM has his own Thread State Machine implementation that differ from CoreCLR https://github.com/dotnet/runtime/blob/main/docs/design/mono/mono-thread-state-machine.md

On the basis of your ideas we are in the same perspective. It will be Avalonia which will make it possible to code the PSSISEModel2.0. I ask if we could have more code from PowerShellISE and it's not possible at all. (the editor includes some code from VS ) The terminal from AvalonStudio is MIT and could be reused (but the whole app is GPLv3, so :/) https://github.com/VitalElement/AvalonStudio

On the other hand, it is difficult for me to tell the whole story from dotnet7.0 to 9.0 on the subject. it no longer need Blazor and that's the main thing, it's the dotnet SDK, not Asp.Net.Core and it should be possible to discuss to include code with the PowerShell team (they will refuse a dependency to AspNetCore SDK)

This feature is actually broken in the latest preview and I need it for the first preview because it helps a lot (without means at least x10 slower than powershell ) image https://github.com/dotnet/runtime/blob/main/docs/design/mono/jiterpreter.md

There is also a new format to replace DLL https://github.com/dotnet/runtime/blob/main/docs/design/mono/webcil.md

The most critical thing isn't there, it's more how am I going to package the application? We have nothing at all as a build chain to produce Web assets. You will have to choose between webpack, yarn etc...

The last point is the worst, it's debugging. By doing without Blazor, we will have to create a mechanism to communicate with the browser debug protocol

https://code-maze.com/wp-content/uploads/2020/06/18-Debugging-in-action.png https://code-maze.com/blazor-components/

There is absolutely nothing impossible, there are simply external factors such as the dotnet team which is pushing back multithreaded Blazor WASM for the 4th consecutive year. We are lucky I think that the dotnet team has finished its work on the subject and that it is now up to the ASP team to implement the APIs (they have a significant blockage which requires reviewing their boot model).

Sorry if that's a messy answer :)

klumsy commented 1 month ago

no thanks for the lots of details, it is helpful. I'm still trying to wrap my head around while something may not be possible though.. When i was talking about ISE i wasn't mean USING it, but rather something like it, where you have just a text editor, that then inside the RUnspace, runs pipelines, and processes the output somewhere. Similar to your "Query" part in PowershellLab.. ISE was like that, as well as also my original PowerShell Analyzer.(https://youtu.be/isJ0VN8tARI?t=226).. I'm really thinking of something like PowerShell Analyzer but in the browser, where PowerShell is just a single threaded (thus no jobs, invoke-webcommand (unless we make our own function to do it) "sandboxed" PowerShell. So I'm thinking of an editor in the browser, native JS/HTML and not Blazor, when then just does calls into Blazor to run the pipelines.. and presuming we don't need to do any async await (like not using HTTPClient), then it would all be orchestrated though that one thread.. all we just need is a way from inside PowerShell to do some Synchronous interop back to JavaScript to do various things... even if its blocking the UI thread while it is operating... , as for the interop back to JavaScript (by which (taking into consideration CORS policies) we could interact with both the host, and functions to do Ajax Http calls with something like the following.

window.ajaxCallSync = function (url, method, dotNetObject) {
    var xhr = new XMLHttpRequest();
    xhr.open(method, url, false); // Note: synchronous mode is being deprecated and should be avoided
    xhr.send();

    if (xhr.status === 200) {
        dotNetObject.invokeMethodAsync('ReceiveData', xhr.responseText);
    } else {
        dotNetObject.invokeMethodAsync('ReceiveData', null);
    }
};

and

@page "/fetchdata"
@inject IJSRuntime JSRuntime

<h3>Fetch Data</h3>

<button @onclick="FetchData">Fetch Data</button>

@if (!string.IsNullOrEmpty(data))
{
    <p>@data</p>
}

@code {
    private string data;

    [JSInvokable]
    public void ReceiveData(string response)
    {
        data = response;
        InvokeAsync(StateHasChanged);
    }

    private void FetchData()
    {
        JSRuntime.InvokeVoidAsync("ajaxCallSync", "https://jsonplaceholder.typicode.com/posts/1", "GET", DotNetObjectReference.Create(this));
    }
}

is there any reason that you can see why something like this may not be possible?

fMichaleczek commented 1 month ago

Firstly, can you confirm to me that you have seen my Twitter link with all the screenshots of the features that I can get to work in dotnet 9.0 preview 2? I have the impression that you haven't seen the current state. (I can post them here if you need) (I work on the subject occasionally, last time I took a week of vacation to concentrate)

I was talking about the ISE Script Model more than ISE (https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/ise/object-model/purpose-of-the-windows-powershell-ise-scripting-object-model?view=powershell-7.4)

You will not be able to communicate with the single-threaded browser APIs since the APIs are asynchronous. I racked my brains over this and I admit that I don't want to think more about it, because it's a dotnet problem that could be solved at the framework level. (don’t forget that WASM also requires specific CORS anyway because SharedArray) There is a probability that the addition of the WASM multithreaded APIs and the improvements to the dispatcher will make it possible to operate in singlethread, but that means starting to type in the Mono Low Level APIs (which should be feasible)

We will soon reach the limit of technical conversation, and I find it interesting because you have things to say and share. However, I have one foot in the future (dotnet9.0) and you have one foot in the past (Blazor), so we have to be able to synchronize (I say that with humor). We have the same goal, however, I have planned an intermediate step which is first to port PowerShell as is, because there are a lot of code to change in the PowerShell code & Toolchain, and It's not going to be easy with the PowerShell team (this is why I favor certain scenarios, because I also need them to be interested/included)

Could you study these samples and read the associated docs? (you would understand better what I studied) https://github.com/dotnet/runtime/tree/main/src/mono/sample/wasm

https://github.com/dotnet/runtime/tree/main/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript

https://learn.microsoft.com/en-us/aspnet/core/client-side/dotnet-interop?view=aspnetcore-9.0#javascript-interop-on- image

What I'm waiting for is the stability of the new code and they still have a little work to do between now and November image

You don't ask about WASI, but the problem is in the same league : https://github.com/dotnet/runtime/issues/102894

I chose "BootShell" as the project name because my goal is to boot PowerShell + Mono on anything https://github.com/BootShell image

Sorry if I don't answer all the questions, I think we should focus on the simple scenario without Blazor. Then it will be possible to think of all the slightly more complicated scenarios.

klumsy commented 1 month ago

no i hadn't seen that tweet, but did now... from the gist of it.. you got something to work with an older preview of dotnet9, but they have since removed something you depended on, and you just have to wait to see how it all shapes out? As for without Blazor, i wasn't aware there was any other way to run dotnet/ Powershell inside a browser.. i'll take a deeper look

klumsy commented 1 month ago

thanks.. this is really interesting.. i was missing what you were saying.. when we were talking about WASM i thought it was in the context of interop between blazor stuff and other third party WASM assets (just like with JavaScript) i wasn't aware that with dotnet9 there is a possibility to do dotnet WASM without Blazor, and that it has the potential to host and run PowerShell in it. I was thinking you were saying "we just have to wait and see what happens in dotnet10" so I was trying to brainstorm approaches of how we might hack getting SOMETHING working in the meantime. but it already sounds like you have gotten a bead on getting something working. I was mostly just asking if there were sources so i could experiment around with it, without having, but i think the plan now will be to wait and see until mid septemember and see where you are at with it.. Good work all around

fMichaleczek commented 1 month ago

The difficulties that made me stop and decide to wait: