-
Notifications
You must be signed in to change notification settings - Fork 29.4k
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 "Pure" Renderer API #102644
Comments
I don't understand this, what's missing? Is it the fact that the renderer code wouldn't be loaded until it's needed or something? |
How much will the renderer typings grow? It doesn't really seem worth the trouble to share types between vscode.d.ts and the renderer dts just for Event and Disposable. Also do extensions in serverless get a subset of vscode API? |
Currently, you can render 'static' HTML in the extension host and not have any JavaScript running in the client side. This proposal would make it all client-side, although the actual construction logic could be very similar to a static renderer if the author desires. E.g. you can do whatever building you want in the return value from vscode/src/vs/vscode.proposed.d.ts Lines 1640 to 1645 in 48f23d8
But in the starter (and yeoman template) I render a
The renderer APIs also currently include the NotebookDocument, which brings in a bunch stuff like RelativePattern, which brings in WorkspaceFolder, etc. Have that stuff in two places seems error-prone. |
Notes from sync where I pitched Path 2 as my preferred solution:
Followup for me: looking at the existing renderers to see what developers have done and whether they could be supported in the Path 2 scenario |
Assessment of existing renderers:
With the renderers we have it seems that Path 2 is feasible, however ipywidgets is the not-yet-implemented weird case. Some notes from the sync today:
|
This is an old implemetation. I haven't updated that to use the new API. |
Some undocumented rules/conversion in the renderer/kernel preload scripts API:
|
This removes the initial notebook renderer API and keeps the 'pure' renderer API described in #102644 and hacked-in previously. Remaining work in this area, in no particular order: - Add messaging context to postMessage as requested by Don (API proposal TBA) - Cleanups around how state is managed internally in the backLayerWebView - Deprecate the renderer `viewType` in favor of calling it the `id` or `rendererId` Q: I kept around some of the "transform" functions since the mime type picking happens there, not sure if there's a better place for this to happen now, or whether these methods should simply be renamed.
This is now implemented, and the impure API is removed. |
Problem
With native integration of notebooks into VS Code, we want to foster an ecosystem for notebooks in VS Code. One of the goals is to build notebook renderers that can be reused in other applications, such as Azure Data Studio.
Right now renderers are 'just another' VS Code extension, with full access to the VS Code API, file system, and so on. It is impractical for another consumer like ADS to implement the entire API to ensure that renderers work universally. Renderer authors are only likely to test on one platform, so it's important that the renders can be built in a small surface area that works reliably between products.
Approach
Quick Review
You can take a look the structure of the renderer starter repo to get an idea of what building a renderer entails today.
Module Loading
Currently VS Code loads the extension from the
main
file given in the package.json, which in turn registers the renderer. We'd like renderers to be ship-able in extensions, but loading themain
file will generally require presence of thevscode
module/shim.There are two paths that I'm thinking about here:
Path 1: ExtensionHost-like registration
There's precedent in adding extra entrypoints in the package.json, for example the browser entrypoint or de-facto module fields adopted by Webpack/Rollup/etc. Therefore an additional
notebookRenderer
field is a natural addition:{ "name": "My Cool Renderer", "main": "./out/extension.js", + "notebookRenderer": "./out/renderer.js"
The primary
vscode
API/import should not be accessible to notebook renderers. VS Code provide therequire
function available to renderers, so this is easy to enforce. I suggest moving renderer-only APIs to a separate types package, or a subpath likevscode/notebookRenderer
.Q: There are common classes like
Event
s andUri
s in these APIs. vscode-uri is already a standalone npm module, should we do the same thing for Events or other APIs?Q: Should there be any other
require
imports allowed? Disallowing these will require bundling of the extension, which is good practice anyway, and makes it portable between the extension host and browsers.The registration code in here would then be similar to that in the usual
extension.js
, except with fewer APIs, for instance:./src/renderer.ts
Path 2: Package.json-only registration
Today we have a
contributes
section of the package.json that includes notebook renderers. We could add an additional property here, likeentrypoint
, which links directly to the UI/browser code for the renderer."contributes": { "notebookOutputRenderer": [ { "viewType": "sample-notebook-renderer", "displayName": "Sample Notebook Renderer", + "entrypoint": "./out/rendererUiCode.js" "mimeTypes": [ "application/json" ] } ],
I find this approach attractive as it is much easier to implement outside of VS Code, and also much easier to consume and build with -- there's no pseudo-Node/require based environment, no multiple targets like the renderer starter has, no figuring out how to load your files. You just have a bundle of JavaScript code to be loaded in the UI.
The downside is that this closes the door for what Jackson called "static renderers", and if there is anything that renderers need to do outside the DOM, they cannot do that. Arguably, though, DOM restrictions is a benefit for portability, and making every renderer 'dynamic' reduces the number of concepts/moving parts the user needs to learn.
In-Webview API
The current VS Code notebook renderer API is defined here: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/vscode-notebook-renderer/index.d.ts
This is already a fairly minimal API that neither path will require to change significantly, however moving
Event
s to a separate package would ease implementations.In Path 2, there's no Node side of things to receive the per-renderer
postMessage
events, but the content provider may still receive them.It would make sense to add an additional
product
field in the event that renderers need to distinguish between different products. For example, we support command links from renderer output in VS Code, but those won't work (at least, not with perfect parity) in ADS.cc @rebornix @roblourens @DonJayamanne
The text was updated successfully, but these errors were encountered: