-
Notifications
You must be signed in to change notification settings - Fork 29.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notebook renderer: state persistence #95361
Comments
This works. In some cases I think consumers may prefer to acquire the API based on the cell URI if they are building them as self-contained 'apps'. For instance in the flame graph extension I would want to store the view position on a per-graph level and don't need an extension-level state. This API would not prevent renderers from doing that. |
@connor4312 makes sense, renderers can build an id from the cell uri. To archive that, the renderer needs to read the uri from the cell when it converts render(document: NotebookDocument, output: CellDisplayOutput, mimeType: string): string {
const id = output.uri.toString();
...
} |
@rebornix I believe your proposal to use One other point about the api proposal: we may need a way to clean up the state of cells that no longer exist |
I'm not sure how this could be done safely (allowing for async calls) without something like Zone.js, which can be a difficult can of worms to deal with. I'll look into this some more when I do the work renderer iteration but I think string-scoped APIs are a good basis to work on. |
This leads me to an API something like this: interface IState<T> {
retrieve(): T | undefined;
retrieve(defaultValue: T): T;
store(state: T): Promise<void>; // or void? technically the postMessage to store is async
}
interface IRendererApi<CellState, NotebookState> {
cellState: IState<CellState>; // per-cell
notebookState: IState<NotebookState>; // per-renderer in the notebook
postMessage(msg: unknown): void;
}
declare function acquireNotebookRendererApi<CellState = any, NotebookState = any>():
IRendererApi<CellState, NotebookState>; Q: is the cell state cleared when the user re-evaluates the cell? It could be useful if the user is, for example, zoomed in on a graph. The caveat is that |
Followup from call: cell state is probably unnecessary given two things:
That would make the API something like this: interface IRendererApi<State> {
// mostly-existing on the webview api:
setState(value: T): void;
getState(): T | undefined;
getState(defaultValue: T): T | undefined;
postMessage(msg: unknown): void;
// new:
readonly onCellWillUnmount: Event<string /* cell uri */>;
}
declare function acquireNotebookRendererApi<State = any>(): IRendererApi<State>;
Q:
|
I don't think that's required, we can wrap the renderer scripts in an IIFE that provides the right function under that name
I think it's better to reimplement this stuff since otherwise you'll pull in all of |
To do this we need to intercept the script. We might be able to do that for our own URIs but in development the files can load from http://localhost. It also would not make them available to anything outside the file, like hot-module-loaded code or code-split paths. One way might be to allow users to call |
Initial implementation:
Other observations:
|
I like those ideas but I wouldn't use react lingo but something that's more familiar in pure html terms |
First of all, good work and I like the shape of the API in overall.
Not a fan of using
Currently we support rendering multiple outputs for a single cell (we might still have some layout issue with this) so we may need
Similarly, we need
The challenge is we need to inline the scripts in the HTML template as Webview iframes are hosted in another domain.
This can work and we did that for |
Thanks for the feedback! Updated my PR:
|
Closing with the merged PR. We can continue discussion and iteration in a clean issue for next month. |
Issue Type: Feature Request
When building a regular webview extenison or a custom editor, extension authors can follow the existing guidance https://code.visualstudio.com/api/extension-guides/webview#persistence for intermediate state persistence. Extensions will use the
vscodeAPI
to communicate with the extension and also get/set its intermediate state for recovery. The API is as belowacquireVsCodeAPI
can only be run once, which ensures that it's not being used unexpectedly. However in Notebook world, there are multiple layers who want to access this APIscroll
andsizeChange
events.To allow renderers to communite with its coresponding extension, we relaxed it a bit to allow
acquireVSCodeAPI
to be run multiple times. However it's a bad idea as renderers now don't know how to save/restore states correctly, asvscode.setState
can be run by any code.One solution is creating vscodeAPI object for every indidual player
acquireVsCodeApi
with the sameid
can only be invoked once. This way each renderer can have its own communication channel with its extension and also its own state restoration.Particularly for ipywidgets, it should always
setState
before it sends states to the kernel side and read state when it's being restored.cc @kieferrm @mjbvz @connor4312
VS Code version: Code - Insiders 1.45.0-insider (44c5185, 2020-04-10T19:43:46.226Z)
OS version: Darwin x64 19.2.0
The text was updated successfully, but these errors were encountered: