Skip to content

Commit

Permalink
implement async fetching of extensions
Browse files Browse the repository at this point in the history
This commit allows the fetching of the verified status to be performed
asynchronously during the search to avoid causing a performance hit. The
verified (or unverified) icons will pop in asynchronously when the
fetching is done.

The following has been added:
- `verified-filled` icon for verified extensions
- `verified` icon for unverified extensions (unfilled verified)
- `question` icon for extensions with an unknown verification status (appears before the fetching is completed)

A small cleanup has also been performed with the creation of the
following functions:
- `fetchVerifiedStatus`
- `updateExtensions`

Signed-off-by: Vlad Arama <vlad.arama@ericsson.com>
  • Loading branch information
vladarama committed Nov 23, 2023
1 parent bad15a4 commit da67994
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 24 deletions.
8 changes: 7 additions & 1 deletion packages/vsx-registry/src/browser/vsx-extension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,13 @@ export class VSXExtensionComponent<Props extends VSXExtensionComponent.Props = V
<div className='noWrapInfo theia-vsx-extension-description'>{description}</div>
<div className='theia-vsx-extension-action-bar'>
<div className='theia-vsx-extension-publisher-container'>
{verified ? <i className={codicon('verified-filled')} /> : undefined}
{verified === true ? (
<i className={codicon('verified-filled')} />
) : verified === false ? (
<i className={codicon('verified')} />
) : (
<i className={codicon('question')} />
)}
<span className='noWrapInfo theia-vsx-extension-publisher'>{publisher}</span>
</div>
{this.renderAction(this.props.host)}
Expand Down
68 changes: 45 additions & 23 deletions packages/vsx-registry/src/browser/vsx-extensions-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { PreferenceInspectionScope, PreferenceService } from '@theia/core/lib/br
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { RecommendedExtensions } from './recommended-extensions/recommended-extensions-preference-contribution';
import URI from '@theia/core/lib/common/uri';
import { VSXExtensionRaw, VSXResponseError, VSXSearchOptions } from '@theia/ovsx-client/lib/ovsx-types';
import { OVSXClient, VSXAllVersions, VSXExtensionRaw, VSXResponseError, VSXSearchEntry, VSXSearchOptions } from '@theia/ovsx-client/lib/ovsx-types';
import { OVSXClientProvider } from '../common/ovsx-client-provider';
import { RequestContext, RequestService } from '@theia/core/shared/@theia/request';
import { OVSXApiFilter } from '@theia/ovsx-client';
Expand Down Expand Up @@ -213,11 +213,11 @@ export class VSXExtensionsModel {
});
}

protected doUpdateSearchResult(param: VSXSearchOptions, token: CancellationToken): Promise<void> {
protected async doUpdateSearchResult(param: VSXSearchOptions, token: CancellationToken): Promise<void> {
return this.doChange(async () => {
const searchResult = new Set<string>();
const fetchPromisesArray: Promise<void>[] = [];
this._searchResult = new Set<string>();
if (!param.query) {
this._searchResult = searchResult;
return;
}
const client = await this.clientProvider();
Expand All @@ -232,30 +232,52 @@ export class VSXExtensionsModel {
if (!allVersions) {
continue;
}
const res = await client.query({ extensionId: id, extensionVersion: allVersions.version, includeAllVersions: true });
let verified = res.extensions?.[0].verified;
if (!verified) {
if (res.extensions?.[0].publishedBy.loginName === 'open-vsx') {
verified = true;
}
}
if (!this.preferences.get('extensions.onlyShowVerifiedExtensions') || verified) {
this.setExtension(id).update(Object.assign(data, {
publisher: data.namespace,
downloadUrl: data.files.download,
iconUrl: data.files.icon,
readmeUrl: data.files.readme,
licenseUrl: data.files.license,
version: allVersions.version,
verified: verified
}));
searchResult.add(id);
if (this.preferences.get('extensions.onlyShowVerifiedExtensions')) {
const verified = await this.fetchVerifiedStatus(id, client, allVersions);
this.updateExtensions(data, id, allVersions, !!verified);
} else {
this.updateExtensions(data, id, allVersions);
const fetchPromise = this.fetchVerifiedStatus(id, client, allVersions).then(verified => {
let extension = this.getExtension(id);
extension = this.setExtension(id);
extension.update(Object.assign({
verified: verified
}));
});
fetchPromisesArray.push(fetchPromise);
}
}
this._searchResult = searchResult;
Promise.all(fetchPromisesArray).then(async () => this.doChange(async () => {
await this.initialized;
}));
}, token);
}

protected async fetchVerifiedStatus(id: string, client: OVSXClient, allVersions: VSXAllVersions): Promise<boolean | undefined> {
const res = await client.query({ extensionId: id, extensionVersion: allVersions.version, includeAllVersions: true });
let verified = res.extensions?.[0].verified;
if (!verified && res.extensions?.[0].publishedBy.loginName === 'open-vsx') {
verified = true;
}
return verified;
}

protected updateExtensions(data: VSXSearchEntry, id: string, allVersions: VSXAllVersions, verified?: boolean): void {
if (!this.preferences.get('extensions.onlyShowVerifiedExtensions') || verified) {
const extension = this.setExtension(id);
extension.update(Object.assign(data, {
publisher: data.namespace,
downloadUrl: data.files.download,
iconUrl: data.files.icon,
readmeUrl: data.files.readme,
licenseUrl: data.files.license,
version: allVersions.version,
verified: verified
}));
this._searchResult.add(id);
}
}

protected async updateInstalled(): Promise<void> {
const prevInstalled = this._installed;
return this.doChange(async () => {
Expand Down

0 comments on commit da67994

Please sign in to comment.