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:
parent
5eb64c54ca
commit
9464d14f31
3 changed files with 20 additions and 12 deletions
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue