Browse Source

Avoids needing completionId on params

Changes `sendCommandWithCompletion` to return a promise
main
Eric Amodio 2 years ago
parent
commit
8f437a12bd
6 changed files with 43 additions and 30 deletions
  1. +14
    -12
      src/webviews/apps/shared/appBase.ts
  2. +4
    -5
      src/webviews/apps/shared/appWithConfigBase.ts
  3. +1
    -1
      src/webviews/protocol.ts
  4. +10
    -4
      src/webviews/webviewBase.ts
  5. +9
    -4
      src/webviews/webviewViewBase.ts
  6. +5
    -4
      src/webviews/webviewWithConfigBase.ts

+ 14
- 12
src/webviews/apps/shared/appBase.ts View File

@ -89,31 +89,33 @@ export abstract class App {
const id = nextIpcId(); const id = nextIpcId();
this.log(`${this.appName}.sendCommand(${id}): name=${command.method}`); this.log(`${this.appName}.sendCommand(${id}): name=${command.method}`);
return this.postMessage({ id: id, method: command.method, params: params });
this.postMessage({ id: id, method: command.method, params: params });
} }
protected sendCommandWithCompletion<
protected async sendCommandWithCompletion<
TCommand extends IpcCommandType<any>, TCommand extends IpcCommandType<any>,
TCompletion extends IpcNotificationType<{ completionId: string }>,
TCompletion extends IpcNotificationType<any>,
>( >(
command: TCommand, command: TCommand,
params: IpcMessageParams<TCommand>, params: IpcMessageParams<TCommand>,
completion: TCompletion, completion: TCompletion,
callback: (params: IpcMessageParams<TCompletion>) => void,
): void {
): Promise<IpcMessageParams<TCompletion>> {
const id = nextIpcId(); const id = nextIpcId();
this.log(`${this.appName}.sendCommandWithCompletion(${id}): name=${command.method}`); this.log(`${this.appName}.sendCommandWithCompletion(${id}): name=${command.method}`);
const disposable = DOM.on(window, 'message', e => {
onIpc(completion, e.data as IpcMessage, params => {
if (params.completionId === id) {
disposable.dispose();
callback(params);
}
const promise = new Promise<IpcMessageParams<TCompletion>>(resolve => {
const disposable = DOM.on(window, 'message', (e: MessageEvent<IpcMessage>) => {
onIpc(completion, e.data, params => {
if (e.data.completionId === id) {
disposable.dispose();
resolve(params);
}
});
}); });
}); });
return this.postMessage({ id: id, method: command.method, params: params });
this.postMessage({ id: id, method: command.method, params: params, completionId: id });
return promise;
} }
protected setState(state: State) { protected setState(state: State) {

+ 4
- 5
src/webviews/apps/shared/appWithConfigBase.ts View File

@ -570,7 +570,7 @@ export abstract class AppWithConfig extends Ap
return; return;
} }
this.sendCommandWithCompletion(
void this.sendCommandWithCompletion(
GenerateConfigurationPreviewCommandType, GenerateConfigurationPreviewCommandType,
{ {
key: el.dataset.settingPreview!, key: el.dataset.settingPreview!,
@ -578,10 +578,9 @@ export abstract class AppWithConfig extends Ap
format: value, format: value,
}, },
DidGenerateConfigurationPreviewNotificationType, DidGenerateConfigurationPreviewNotificationType,
params => {
el.innerText = params.preview ?? '';
},
);
).then(params => {
el.innerText = params.preview ?? '';
});
break; break;
} }

+ 1
- 1
src/webviews/protocol.ts View File

@ -4,6 +4,7 @@ export interface IpcMessage {
id: string; id: string;
method: string; method: string;
params?: unknown; params?: unknown;
completionId?: string;
} }
abstract class IpcMessageType<Params = void> { abstract class IpcMessageType<Params = void> {
@ -73,7 +74,6 @@ export const DidChangeConfigurationNotificationType = new IpcNotificationType
); );
export interface DidGenerateConfigurationPreviewParams { export interface DidGenerateConfigurationPreviewParams {
completionId: string;
preview: string; preview: string;
} }

+ 10
- 4
src/webviews/webviewBase.ts View File

@ -216,7 +216,7 @@ export abstract class WebviewBase implements Disposable {
const html = content.replace( const html = content.replace(
/#{(head|body|endOfBody|placement|cspSource|cspNonce|root|webroot)}/g, /#{(head|body|endOfBody|placement|cspSource|cspNonce|root|webroot)}/g,
(_substring, token) => {
(_substring: string, token: string) => {
switch (token) { switch (token) {
case 'head': case 'head':
return head ?? ''; return head ?? '';
@ -249,12 +249,18 @@ export abstract class WebviewBase implements Disposable {
return html; return html;
} }
protected notify<T extends IpcNotificationType<any>>(type: T, params: IpcMessageParams<T>): Thenable<boolean> {
return this.postMessage({ id: nextIpcId(), method: type.method, params: params });
protected notify<T extends IpcNotificationType<any>>(
type: T,
params: IpcMessageParams<T>,
completionId?: string,
): Thenable<boolean> {
return this.postMessage({ id: nextIpcId(), method: type.method, params: params, completionId: completionId });
} }
@serialize() @serialize()
@debug<WebviewBase<State>['postMessage']>({ args: { 0: m => `(id=${m.id}, method=${m.method})` } })
@debug<WebviewBase<State>['postMessage']>({
args: { 0: m => `(id=${m.id}, method=${m.method}${m.completionId ? `, completionId=${m.completionId}` : ''})` },
})
private postMessage(message: IpcMessage): Promise<boolean> { private postMessage(message: IpcMessage): Promise<boolean> {
if (this._panel == null) return Promise.resolve(false); if (this._panel == null) return Promise.resolve(false);

+ 9
- 4
src/webviews/webviewViewBase.ts View File

@ -17,7 +17,6 @@ import { serialize } from '../system/decorators/serialize';
import type { TrackedUsageFeatures } from '../usageTracker'; import type { TrackedUsageFeatures } from '../usageTracker';
import type { IpcMessage, IpcMessageParams, IpcNotificationType } from './protocol'; import type { IpcMessage, IpcMessageParams, IpcNotificationType } from './protocol';
import { ExecuteCommandType, onIpc, WebviewReadyCommandType } from './protocol'; import { ExecuteCommandType, onIpc, WebviewReadyCommandType } from './protocol';
import type { WebviewBase } from './webviewBase';
const maxSmallIntegerV8 = 2 ** 30; // Max number that can be stored in V8's smis (small integers) const maxSmallIntegerV8 = 2 ** 30; // Max number that can be stored in V8's smis (small integers)
@ -243,12 +242,18 @@ export abstract class WebviewViewBase implements
return html; return html;
} }
protected notify<T extends IpcNotificationType<any>>(type: T, params: IpcMessageParams<T>): Thenable<boolean> {
return this.postMessage({ id: nextIpcId(), method: type.method, params: params });
protected notify<T extends IpcNotificationType<any>>(
type: T,
params: IpcMessageParams<T>,
completionId?: string,
): Thenable<boolean> {
return this.postMessage({ id: nextIpcId(), method: type.method, params: params, completionId: completionId });
} }
@serialize() @serialize()
@debug<WebviewBase<State>['postMessage']>({ args: { 0: m => `(id=${m.id}, method=${m.method})` } })
@debug<WebviewViewBase<State>['postMessage']>({
args: { 0: m => `(id=${m.id}, method=${m.method}${m.completionId ? `, completionId=${m.completionId}` : ''})` },
})
protected postMessage(message: IpcMessage) { protected postMessage(message: IpcMessage) {
if (this._view == null) return Promise.resolve(false); if (this._view == null) return Promise.resolve(false);

+ 5
- 4
src/webviews/webviewWithConfigBase.ts View File

@ -172,10 +172,11 @@ export abstract class WebviewWithConfigBase extends WebviewBase {
preview = 'Invalid format'; preview = 'Invalid format';
} }
await this.notify(DidGenerateConfigurationPreviewNotificationType, {
completionId: e.id,
preview: preview,
});
await this.notify(
DidGenerateConfigurationPreviewNotificationType,
{ preview: preview },
e.completionId,
);
} }
} }
}); });

Loading…
Cancel
Save