Make notebook renderer activate potentially async (#124647)

* Make notebook renderer activate potentially async

- Allow activate to be `async`
- Make `getRenderer` always return a promise instead of the api result directly

* Add comment on why we use async
This commit is contained in:
Matt Bierner 2021-05-26 09:15:00 -07:00 committed by GitHub
parent 5eb64c54ca
commit 9464d14f31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 12 deletions

View file

@ -6,10 +6,13 @@ import type * as markdownIt from 'markdown-it';
const emoji = require('markdown-it-emoji');
export function activate(ctx: {
export async function activate(ctx: {
getRenderer: (id: string) => any
}) {
const markdownItRenderer = ctx.getRenderer('markdownItRenderer');
const markdownItRenderer = await ctx.getRenderer('markdownItRenderer');
if (!markdownItRenderer) {
throw new Error('Could not load markdownItRenderer');
}
markdownItRenderer.extendMarkdownIt((md: markdownIt.MarkdownIt) => {
return md.use(emoji);

View file

@ -6,10 +6,13 @@ import type * as markdownIt from 'markdown-it';
const styleHref = import.meta.url.replace(/katex.js$/, 'katex.min.css');
export function activate(ctx: {
getRenderer: (id: string) => any
export async function activate(ctx: {
getRenderer: (id: string) => Promise<any | undefined>
}) {
const markdownItRenderer = ctx.getRenderer('markdownItRenderer');
const markdownItRenderer = await ctx.getRenderer('markdownItRenderer');
if (!markdownItRenderer) {
throw new Error('Could not load markdownItRenderer');
}
const link = document.createElement('link');
link.rel = 'stylesheet';

View file

@ -130,13 +130,13 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
interface RendererContext {
getState<T>(): T | undefined;
setState<T>(newState: T): void;
getRenderer(id: string): any | undefined;
getRenderer(id: string): Promise<any | undefined>;
postMessage?(message: unknown): void;
onDidReceiveMessage?: Event<unknown>;
}
interface ScriptModule {
activate: (ctx?: RendererContext) => any;
activate(ctx?: RendererContext): Promise<RendererApi | undefined | any> | RendererApi | undefined | any;
}
const invokeSourceWithGlobals = (functionSrc: string, globals: { [name: string]: unknown }) => {
@ -844,7 +844,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
) { }
private _onMessageEvent = createEmitter();
private _loadPromise: Promise<RendererApi> | undefined;
private _loadPromise?: Promise<RendererApi | undefined>;
private _api: RendererApi | undefined;
public get api() { return this._api; }
@ -869,7 +869,9 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
const state = vscode.getState();
return typeof state === 'object' && state ? state[id] as T : undefined;
},
getRenderer: (id: string) => renderers.getRenderer(id)?.api,
// TODO: This is async so that we can return a promise to the API in the future.
// Currently the API is always resolved before we call `createRendererContext`.
getRenderer: async (id: string) => renderers.getRenderer(id)?.api,
};
if (messaging) {
@ -881,13 +883,13 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
}
/** Inner function cached in the _loadPromise(). */
private async _load() {
private async _load(): Promise<RendererApi | undefined> {
const module = await runRenderScript(this.data.entrypoint, this.data.id);
if (!module) {
return;
}
const api = module.activate(this.createRendererContext());
const api = await module.activate(this.createRendererContext());
this._api = api;
// Squash any errors extends errors. They won't prevent the renderer
@ -902,7 +904,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
}
const kernelPreloads = new class {
private readonly preloads = new Map<string /* uri */, Promise<ScriptModule>>();
private readonly preloads = new Map<string /* uri */, Promise<unknown>>();
/**
* Returns a promise that resolves when the given preload is activated.