mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-10 22:26:32 +00:00
Various library/platform index update fixes
- IDE2 can start if the package index download fails. Closes #1084 - Split the lib and platform index update. Closes #1156 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
945a8f4841
commit
0c20ae0e28
@ -158,7 +158,11 @@
|
|||||||
],
|
],
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"cli": {
|
"cli": {
|
||||||
"version": "0.27.1"
|
"version": {
|
||||||
|
"owner": "cmaglie",
|
||||||
|
"repo": "arduino-cli",
|
||||||
|
"commitish": "download_progress_refactor"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"fwuploader": {
|
"fwuploader": {
|
||||||
"version": "2.2.0"
|
"version": "2.2.0"
|
||||||
|
@ -332,6 +332,7 @@ import { OutputEditorFactory } from './theia/output/output-editor-factory';
|
|||||||
import { StartupTaskProvider } from '../electron-common/startup-task';
|
import { StartupTaskProvider } from '../electron-common/startup-task';
|
||||||
import { DeleteSketch } from './contributions/delete-sketch';
|
import { DeleteSketch } from './contributions/delete-sketch';
|
||||||
import { UserFields } from './contributions/user-fields';
|
import { UserFields } from './contributions/user-fields';
|
||||||
|
import { UpdateIndexes } from './contributions/update-indexes';
|
||||||
|
|
||||||
const registerArduinoThemes = () => {
|
const registerArduinoThemes = () => {
|
||||||
const themes: MonacoThemeJson[] = [
|
const themes: MonacoThemeJson[] = [
|
||||||
@ -744,6 +745,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
Contribution.configure(bind, CheckForUpdates);
|
Contribution.configure(bind, CheckForUpdates);
|
||||||
Contribution.configure(bind, UserFields);
|
Contribution.configure(bind, UserFields);
|
||||||
Contribution.configure(bind, DeleteSketch);
|
Contribution.configure(bind, DeleteSketch);
|
||||||
|
Contribution.configure(bind, UpdateIndexes);
|
||||||
|
|
||||||
bindContributionProvider(bind, StartupTaskProvider);
|
bindContributionProvider(bind, StartupTaskProvider);
|
||||||
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window
|
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window
|
||||||
|
@ -132,7 +132,7 @@ export class BoardsConfig extends React.Component<
|
|||||||
this.props.notificationCenter.onPlatformDidUninstall(() =>
|
this.props.notificationCenter.onPlatformDidUninstall(() =>
|
||||||
this.updateBoards(this.state.query)
|
this.updateBoards(this.state.query)
|
||||||
),
|
),
|
||||||
this.props.notificationCenter.onIndexDidUpdate(() =>
|
this.props.notificationCenter.onIndexUpdateDidComplete(() =>
|
||||||
this.updateBoards(this.state.query)
|
this.updateBoards(this.state.query)
|
||||||
),
|
),
|
||||||
this.props.notificationCenter.onDaemonDidStart(() =>
|
this.props.notificationCenter.onDaemonDidStart(() =>
|
||||||
|
@ -16,7 +16,7 @@ export class IndexesUpdateProgress extends Contribution {
|
|||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
override onStart(): void {
|
override onStart(): void {
|
||||||
this.notificationCenter.onIndexWillUpdate((progressId) =>
|
this.notificationCenter.onIndexUpdateWillStart(({ progressId }) =>
|
||||||
this.getOrCreateProgress(progressId)
|
this.getOrCreateProgress(progressId)
|
||||||
);
|
);
|
||||||
this.notificationCenter.onIndexUpdateDidProgress((progress) => {
|
this.notificationCenter.onIndexUpdateDidProgress((progress) => {
|
||||||
@ -24,7 +24,7 @@ export class IndexesUpdateProgress extends Contribution {
|
|||||||
delegate.report(progress)
|
delegate.report(progress)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
this.notificationCenter.onIndexDidUpdate((progressId) => {
|
this.notificationCenter.onIndexUpdateDidComplete(({ progressId }) => {
|
||||||
this.cancelProgress(progressId);
|
this.cancelProgress(progressId);
|
||||||
});
|
});
|
||||||
this.notificationCenter.onIndexUpdateDidFail(({ progressId, message }) => {
|
this.notificationCenter.onIndexUpdateDidFail(({ progressId, message }) => {
|
||||||
|
@ -0,0 +1,193 @@
|
|||||||
|
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
|
||||||
|
import { nls } from '@theia/core/lib/common/nls';
|
||||||
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||||
|
import { CoreService, IndexType } from '../../common/protocol';
|
||||||
|
import { NotificationCenter } from '../notification-center';
|
||||||
|
import { WindowServiceExt } from '../theia/core/window-service-ext';
|
||||||
|
import { Command, CommandRegistry, Contribution } from './contribution';
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class UpdateIndexes extends Contribution {
|
||||||
|
@inject(WindowServiceExt)
|
||||||
|
private readonly windowService: WindowServiceExt;
|
||||||
|
@inject(LocalStorageService)
|
||||||
|
private readonly localStorage: LocalStorageService;
|
||||||
|
@inject(CoreService)
|
||||||
|
private readonly coreService: CoreService;
|
||||||
|
@inject(NotificationCenter)
|
||||||
|
private readonly notificationCenter: NotificationCenter;
|
||||||
|
|
||||||
|
protected override init(): void {
|
||||||
|
super.init();
|
||||||
|
this.notificationCenter.onIndexUpdateDidComplete(({ summary }) =>
|
||||||
|
Promise.all(
|
||||||
|
Object.entries(summary).map(([type, updatedAt]) =>
|
||||||
|
this.setLastUpdateDateTime(type as IndexType, updatedAt)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onReady(): void {
|
||||||
|
this.checkForUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
override registerCommands(registry: CommandRegistry): void {
|
||||||
|
registry.registerCommand(UpdateIndexes.Commands.UPDATE_INDEXES, {
|
||||||
|
execute: () => this.updateIndexes(IndexType.All, true),
|
||||||
|
});
|
||||||
|
registry.registerCommand(UpdateIndexes.Commands.UPDATE_PLATFORM_INDEX, {
|
||||||
|
execute: () => this.updateIndexes(['platform'], true),
|
||||||
|
});
|
||||||
|
registry.registerCommand(UpdateIndexes.Commands.UPDATE_LIBRARY_INDEX, {
|
||||||
|
execute: () => this.updateIndexes(['library'], true),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkForUpdates(): Promise<void> {
|
||||||
|
const checkForUpdates = this.preferences['arduino.checkForUpdates'];
|
||||||
|
if (!checkForUpdates) {
|
||||||
|
console.debug(
|
||||||
|
'[update-indexes]: `arduino.checkForUpdates` is `false`. Skipping updating the indexes.'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await this.windowService.isFirstWindow()) {
|
||||||
|
const summary = await this.coreService.indexUpdateSummaryBeforeInit();
|
||||||
|
if (summary.message) {
|
||||||
|
this.messageService.error(summary.message);
|
||||||
|
}
|
||||||
|
const typesToCheck = IndexType.All.filter((type) => !(type in summary));
|
||||||
|
if (Object.keys(summary).length) {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Detected an index update summary before the core gRPC client initialization. Updating local storage with ${JSON.stringify(
|
||||||
|
summary
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.debug(
|
||||||
|
'[update-indexes]: No index update summary was available before the core gRPC client initialization. Checking the status of the all the index types.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await Promise.allSettled([
|
||||||
|
...Object.entries(summary).map(([type, updatedAt]) =>
|
||||||
|
this.setLastUpdateDateTime(type as IndexType, updatedAt)
|
||||||
|
),
|
||||||
|
this.updateIndexes(typesToCheck),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async updateIndexes(
|
||||||
|
types: IndexType[],
|
||||||
|
force = false
|
||||||
|
): Promise<void> {
|
||||||
|
const updatedAt = new Date().toISOString();
|
||||||
|
return Promise.all(
|
||||||
|
types.map((type) => this.needsIndexUpdate(type, updatedAt, force))
|
||||||
|
).then((needsIndexUpdateResults) => {
|
||||||
|
const typesToUpdate = needsIndexUpdateResults.filter(IndexType.is);
|
||||||
|
if (typesToUpdate.length) {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Requesting the index update of type: ${JSON.stringify(
|
||||||
|
typesToUpdate
|
||||||
|
)} with date time: ${updatedAt}.`
|
||||||
|
);
|
||||||
|
return this.coreService.updateIndex({ types: typesToUpdate });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async needsIndexUpdate(
|
||||||
|
type: IndexType,
|
||||||
|
now: string,
|
||||||
|
force = false
|
||||||
|
): Promise<IndexType | false> {
|
||||||
|
if (force) {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Update for index type: '${type}' was forcefully requested.`
|
||||||
|
);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
const lastUpdateIsoDateTime = await this.getLastUpdateDateTime(type);
|
||||||
|
if (!lastUpdateIsoDateTime) {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: No last update date time was persisted for index type: '${type}'. Index update is required.`
|
||||||
|
);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
const lastUpdateDateTime = Date.parse(lastUpdateIsoDateTime);
|
||||||
|
if (Number.isNaN(lastUpdateDateTime)) {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Invalid last update date time was persisted for index type: '${type}'. Last update date time was: ${lastUpdateDateTime}. Index update is required.`
|
||||||
|
);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
const diff = new Date(now).getTime() - lastUpdateDateTime;
|
||||||
|
const needsIndexUpdate = diff >= this.threshold;
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Update for index type '${type}' is ${
|
||||||
|
needsIndexUpdate ? '' : 'not '
|
||||||
|
}required. Now: ${now}, Last index update date time: ${new Date(
|
||||||
|
lastUpdateDateTime
|
||||||
|
).toISOString()}, diff: ${diff} ms, threshold: ${this.threshold} ms.`
|
||||||
|
);
|
||||||
|
return needsIndexUpdate ? type : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getLastUpdateDateTime(
|
||||||
|
type: IndexType
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
const key = this.storageKeyOf(type);
|
||||||
|
return this.localStorage.getData<string>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async setLastUpdateDateTime(
|
||||||
|
type: IndexType,
|
||||||
|
updatedAt: string
|
||||||
|
): Promise<void> {
|
||||||
|
const key = this.storageKeyOf(type);
|
||||||
|
return this.localStorage.setData<string>(key, updatedAt).finally(() => {
|
||||||
|
console.debug(
|
||||||
|
`[update-indexes]: Updated the last index update date time of '${type}' to ${updatedAt}.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private storageKeyOf(type: IndexType): string {
|
||||||
|
return `index-last-update-time--${type}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get threshold(): number {
|
||||||
|
return 4 * 60 * 60 * 1_000; // four hours in millis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export namespace UpdateIndexes {
|
||||||
|
export namespace Commands {
|
||||||
|
export const UPDATE_INDEXES: Command & { label: string } = {
|
||||||
|
id: 'arduino-update-indexes',
|
||||||
|
label: nls.localize(
|
||||||
|
'arduino/updateIndexes/updateIndexes',
|
||||||
|
'Update Indexes'
|
||||||
|
),
|
||||||
|
category: 'Arduino',
|
||||||
|
};
|
||||||
|
export const UPDATE_PLATFORM_INDEX: Command & { label: string } = {
|
||||||
|
id: 'arduino-update-package-index',
|
||||||
|
label: nls.localize(
|
||||||
|
'arduino/updateIndexes/updatePackageIndex',
|
||||||
|
'Update Package Index'
|
||||||
|
),
|
||||||
|
category: 'Arduino',
|
||||||
|
};
|
||||||
|
export const UPDATE_LIBRARY_INDEX: Command & { label: string } = {
|
||||||
|
id: 'arduino-update-library-index',
|
||||||
|
label: nls.localize(
|
||||||
|
'arduino/updateIndexes/updateLibraryIndex',
|
||||||
|
'Update Library Index'
|
||||||
|
),
|
||||||
|
category: 'Arduino',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,9 @@ import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
|
|||||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
||||||
import {
|
import {
|
||||||
|
IndexUpdateDidCompleteParams,
|
||||||
|
IndexUpdateDidFailParams,
|
||||||
|
IndexUpdateWillStartParams,
|
||||||
NotificationServiceClient,
|
NotificationServiceClient,
|
||||||
NotificationServiceServer,
|
NotificationServiceServer,
|
||||||
} from '../common/protocol/notification-service';
|
} from '../common/protocol/notification-service';
|
||||||
@ -29,48 +32,48 @@ export class NotificationCenter
|
|||||||
implements NotificationServiceClient, FrontendApplicationContribution
|
implements NotificationServiceClient, FrontendApplicationContribution
|
||||||
{
|
{
|
||||||
@inject(NotificationServiceServer)
|
@inject(NotificationServiceServer)
|
||||||
protected readonly server: JsonRpcProxy<NotificationServiceServer>;
|
private readonly server: JsonRpcProxy<NotificationServiceServer>;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
@inject(FrontendApplicationStateService)
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
private readonly appStateService: FrontendApplicationStateService;
|
||||||
|
|
||||||
protected readonly indexDidUpdateEmitter = new Emitter<string>();
|
private readonly indexUpdateDidCompleteEmitter =
|
||||||
protected readonly indexWillUpdateEmitter = new Emitter<string>();
|
new Emitter<IndexUpdateDidCompleteParams>();
|
||||||
protected readonly indexUpdateDidProgressEmitter =
|
private readonly indexUpdateWillStartEmitter =
|
||||||
|
new Emitter<IndexUpdateWillStartParams>();
|
||||||
|
private readonly indexUpdateDidProgressEmitter =
|
||||||
new Emitter<ProgressMessage>();
|
new Emitter<ProgressMessage>();
|
||||||
protected readonly indexUpdateDidFailEmitter = new Emitter<{
|
private readonly indexUpdateDidFailEmitter =
|
||||||
progressId: string;
|
new Emitter<IndexUpdateDidFailParams>();
|
||||||
message: string;
|
private readonly daemonDidStartEmitter = new Emitter<string>();
|
||||||
}>();
|
private readonly daemonDidStopEmitter = new Emitter<void>();
|
||||||
protected readonly daemonDidStartEmitter = new Emitter<string>();
|
private readonly configDidChangeEmitter = new Emitter<{
|
||||||
protected readonly daemonDidStopEmitter = new Emitter<void>();
|
|
||||||
protected readonly configDidChangeEmitter = new Emitter<{
|
|
||||||
config: Config | undefined;
|
config: Config | undefined;
|
||||||
}>();
|
}>();
|
||||||
protected readonly platformDidInstallEmitter = new Emitter<{
|
private readonly platformDidInstallEmitter = new Emitter<{
|
||||||
item: BoardsPackage;
|
item: BoardsPackage;
|
||||||
}>();
|
}>();
|
||||||
protected readonly platformDidUninstallEmitter = new Emitter<{
|
private readonly platformDidUninstallEmitter = new Emitter<{
|
||||||
item: BoardsPackage;
|
item: BoardsPackage;
|
||||||
}>();
|
}>();
|
||||||
protected readonly libraryDidInstallEmitter = new Emitter<{
|
private readonly libraryDidInstallEmitter = new Emitter<{
|
||||||
item: LibraryPackage;
|
item: LibraryPackage;
|
||||||
}>();
|
}>();
|
||||||
protected readonly libraryDidUninstallEmitter = new Emitter<{
|
private readonly libraryDidUninstallEmitter = new Emitter<{
|
||||||
item: LibraryPackage;
|
item: LibraryPackage;
|
||||||
}>();
|
}>();
|
||||||
protected readonly attachedBoardsDidChangeEmitter =
|
private readonly attachedBoardsDidChangeEmitter =
|
||||||
new Emitter<AttachedBoardsChangeEvent>();
|
new Emitter<AttachedBoardsChangeEvent>();
|
||||||
protected readonly recentSketchesChangedEmitter = new Emitter<{
|
private readonly recentSketchesChangedEmitter = new Emitter<{
|
||||||
sketches: Sketch[];
|
sketches: Sketch[];
|
||||||
}>();
|
}>();
|
||||||
private readonly onAppStateDidChangeEmitter =
|
private readonly onAppStateDidChangeEmitter =
|
||||||
new Emitter<FrontendApplicationState>();
|
new Emitter<FrontendApplicationState>();
|
||||||
|
|
||||||
protected readonly toDispose = new DisposableCollection(
|
private readonly toDispose = new DisposableCollection(
|
||||||
this.indexWillUpdateEmitter,
|
this.indexUpdateWillStartEmitter,
|
||||||
this.indexUpdateDidProgressEmitter,
|
this.indexUpdateDidProgressEmitter,
|
||||||
this.indexDidUpdateEmitter,
|
this.indexUpdateDidCompleteEmitter,
|
||||||
this.indexUpdateDidFailEmitter,
|
this.indexUpdateDidFailEmitter,
|
||||||
this.daemonDidStartEmitter,
|
this.daemonDidStartEmitter,
|
||||||
this.daemonDidStopEmitter,
|
this.daemonDidStopEmitter,
|
||||||
@ -82,8 +85,8 @@ export class NotificationCenter
|
|||||||
this.attachedBoardsDidChangeEmitter
|
this.attachedBoardsDidChangeEmitter
|
||||||
);
|
);
|
||||||
|
|
||||||
readonly onIndexDidUpdate = this.indexDidUpdateEmitter.event;
|
readonly onIndexUpdateDidComplete = this.indexUpdateDidCompleteEmitter.event;
|
||||||
readonly onIndexWillUpdate = this.indexDidUpdateEmitter.event;
|
readonly onIndexUpdateWillStart = this.indexUpdateWillStartEmitter.event;
|
||||||
readonly onIndexUpdateDidProgress = this.indexUpdateDidProgressEmitter.event;
|
readonly onIndexUpdateDidProgress = this.indexUpdateDidProgressEmitter.event;
|
||||||
readonly onIndexUpdateDidFail = this.indexUpdateDidFailEmitter.event;
|
readonly onIndexUpdateDidFail = this.indexUpdateDidFailEmitter.event;
|
||||||
readonly onDaemonDidStart = this.daemonDidStartEmitter.event;
|
readonly onDaemonDidStart = this.daemonDidStartEmitter.event;
|
||||||
@ -112,26 +115,20 @@ export class NotificationCenter
|
|||||||
this.toDispose.dispose();
|
this.toDispose.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexWillUpdate(progressId: string): void {
|
notifyIndexUpdateWillStart(params: IndexUpdateWillStartParams): void {
|
||||||
this.indexWillUpdateEmitter.fire(progressId);
|
this.indexUpdateWillStartEmitter.fire(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
|
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
|
||||||
this.indexUpdateDidProgressEmitter.fire(progressMessage);
|
this.indexUpdateDidProgressEmitter.fire(progressMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexDidUpdate(progressId: string): void {
|
notifyIndexUpdateDidComplete(params: IndexUpdateDidCompleteParams): void {
|
||||||
this.indexDidUpdateEmitter.fire(progressId);
|
this.indexUpdateDidCompleteEmitter.fire(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexUpdateDidFail({
|
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void {
|
||||||
progressId,
|
this.indexUpdateDidFailEmitter.fire(params);
|
||||||
message,
|
|
||||||
}: {
|
|
||||||
progressId: string;
|
|
||||||
message: string;
|
|
||||||
}): void {
|
|
||||||
this.indexUpdateDidFailEmitter.fire({ progressId, message });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDaemonDidStart(port: string): void {
|
notifyDaemonDidStart(port: string): void {
|
||||||
|
@ -68,7 +68,7 @@ export abstract class ListWidget<
|
|||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected init(): void {
|
protected init(): void {
|
||||||
this.toDispose.pushAll([
|
this.toDispose.pushAll([
|
||||||
this.notificationCenter.onIndexDidUpdate(() => this.refresh(undefined)),
|
this.notificationCenter.onIndexUpdateDidComplete(() => this.refresh(undefined)),
|
||||||
this.notificationCenter.onDaemonDidStart(() => this.refresh(undefined)),
|
this.notificationCenter.onDaemonDidStart(() => this.refresh(undefined)),
|
||||||
this.notificationCenter.onDaemonDidStop(() => this.refresh(undefined)),
|
this.notificationCenter.onDaemonDidStop(() => this.refresh(undefined)),
|
||||||
]);
|
]);
|
||||||
|
@ -11,6 +11,7 @@ import type {
|
|||||||
} from '../../common/protocol/boards-service';
|
} from '../../common/protocol/boards-service';
|
||||||
import type { Programmer } from './boards-service';
|
import type { Programmer } from './boards-service';
|
||||||
import type { Sketch } from './sketches-service';
|
import type { Sketch } from './sketches-service';
|
||||||
|
import { IndexUpdateSummary } from './notification-service';
|
||||||
|
|
||||||
export const CompilerWarningLiterals = [
|
export const CompilerWarningLiterals = [
|
||||||
'None',
|
'None',
|
||||||
@ -112,6 +113,33 @@ export interface CoreService {
|
|||||||
* Refreshes the underling core gRPC client for the Arduino CLI.
|
* Refreshes the underling core gRPC client for the Arduino CLI.
|
||||||
*/
|
*/
|
||||||
refresh(): Promise<void>;
|
refresh(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* Updates the index of the given index types and refreshes (`init`) the underlying core gRPC client.
|
||||||
|
* If `types` is empty, only the refresh part will be executed.
|
||||||
|
*/
|
||||||
|
updateIndex({ types }: { types: IndexType[] }): Promise<void>;
|
||||||
|
/**
|
||||||
|
* If the IDE2 detects invalid or missing indexes on core client init,
|
||||||
|
* IDE2 tries to update the indexes before the first frontend connects.
|
||||||
|
* Use this method to determine whether the backend has already updated
|
||||||
|
* the indexes before updating them.
|
||||||
|
*
|
||||||
|
* If yes, the connected frontend can update the local storage with the most
|
||||||
|
* recent index update date-time for a particular index type,
|
||||||
|
* and IDE2 can avoid the double indexes update.
|
||||||
|
*/
|
||||||
|
indexUpdateSummaryBeforeInit(): Promise<Readonly<IndexUpdateSummary>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IndexTypeLiterals = ['platform', 'library'] as const;
|
||||||
|
export type IndexType = typeof IndexTypeLiterals[number];
|
||||||
|
export namespace IndexType {
|
||||||
|
export function is(arg: unknown): arg is IndexType {
|
||||||
|
return (
|
||||||
|
typeof arg === 'string' && IndexTypeLiterals.includes(arg as IndexType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export const All: IndexType[] = IndexTypeLiterals.filter(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace CoreService {
|
export namespace CoreService {
|
||||||
|
@ -5,27 +5,62 @@ import type {
|
|||||||
Config,
|
Config,
|
||||||
ProgressMessage,
|
ProgressMessage,
|
||||||
Sketch,
|
Sketch,
|
||||||
|
IndexType,
|
||||||
} from '../protocol';
|
} from '../protocol';
|
||||||
import type { LibraryPackage } from './library-service';
|
import type { LibraryPackage } from './library-service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values are [ISO 8601](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
|
||||||
|
* strings representing the date-time when the update of the index has been completed.
|
||||||
|
*/
|
||||||
|
export type IndexUpdateSummary = {
|
||||||
|
[T in IndexType]: string;
|
||||||
|
} & { message?: string };
|
||||||
|
export interface IndexUpdateParams {
|
||||||
|
/**
|
||||||
|
* Application unique ID of the progress.
|
||||||
|
*/
|
||||||
|
readonly progressId: string;
|
||||||
|
/**
|
||||||
|
* The type of the index is which is being updated.
|
||||||
|
*/
|
||||||
|
readonly types: IndexType[];
|
||||||
|
}
|
||||||
|
export type IndexUpdateWillStartParams = IndexUpdateParams;
|
||||||
|
export interface IndexUpdateDidCompleteParams
|
||||||
|
extends Omit<IndexUpdateParams, 'types'> {
|
||||||
|
readonly summary: IndexUpdateSummary;
|
||||||
|
}
|
||||||
|
export interface IndexUpdateDidFailParams extends IndexUpdateParams {
|
||||||
|
/**
|
||||||
|
* Describes the reason of the index update failure.
|
||||||
|
*/
|
||||||
|
readonly message: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface NotificationServiceClient {
|
export interface NotificationServiceClient {
|
||||||
notifyIndexWillUpdate(progressId: string): void;
|
// Index
|
||||||
|
notifyIndexUpdateWillStart(params: IndexUpdateWillStartParams): void;
|
||||||
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void;
|
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void;
|
||||||
notifyIndexDidUpdate(progressId: string): void;
|
notifyIndexUpdateDidComplete(params: IndexUpdateDidCompleteParams): void;
|
||||||
notifyIndexUpdateDidFail({
|
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void;
|
||||||
progressId,
|
|
||||||
message,
|
// Daemon
|
||||||
}: {
|
|
||||||
progressId: string;
|
|
||||||
message: string;
|
|
||||||
}): void;
|
|
||||||
notifyDaemonDidStart(port: string): void;
|
notifyDaemonDidStart(port: string): void;
|
||||||
notifyDaemonDidStop(): void;
|
notifyDaemonDidStop(): void;
|
||||||
|
|
||||||
|
// CLI config
|
||||||
notifyConfigDidChange(event: { config: Config | undefined }): void;
|
notifyConfigDidChange(event: { config: Config | undefined }): void;
|
||||||
|
|
||||||
|
// Platforms
|
||||||
notifyPlatformDidInstall(event: { item: BoardsPackage }): void;
|
notifyPlatformDidInstall(event: { item: BoardsPackage }): void;
|
||||||
notifyPlatformDidUninstall(event: { item: BoardsPackage }): void;
|
notifyPlatformDidUninstall(event: { item: BoardsPackage }): void;
|
||||||
|
|
||||||
|
// Libraries
|
||||||
notifyLibraryDidInstall(event: { item: LibraryPackage }): void;
|
notifyLibraryDidInstall(event: { item: LibraryPackage }): void;
|
||||||
notifyLibraryDidUninstall(event: { item: LibraryPackage }): void;
|
notifyLibraryDidUninstall(event: { item: LibraryPackage }): void;
|
||||||
|
|
||||||
|
// Boards discovery
|
||||||
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void;
|
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void;
|
||||||
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void;
|
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { deepClone } from '@theia/core/lib/common/objects';
|
|||||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
import { BackendApplicationContribution } from '@theia/core/lib/node';
|
import { BackendApplicationContribution } from '@theia/core/lib/node';
|
||||||
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
||||||
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
|
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { Unknown } from '../common/nls';
|
import { Unknown } from '../common/nls';
|
||||||
import {
|
import {
|
||||||
@ -78,14 +78,6 @@ export class BoardDiscovery
|
|||||||
|
|
||||||
onStart(): void {
|
onStart(): void {
|
||||||
this.start();
|
this.start();
|
||||||
this.onClientDidRefresh(() => this.restart());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async restart(): Promise<void> {
|
|
||||||
this.logger.info('restarting before stop');
|
|
||||||
await this.stop();
|
|
||||||
this.logger.info('restarting after stop');
|
|
||||||
return this.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onStop(): void {
|
onStop(): void {
|
||||||
|
@ -220,6 +220,9 @@ export class UpdateIndexRequest extends jspb.Message {
|
|||||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UpdateIndexRequest;
|
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UpdateIndexRequest;
|
||||||
|
|
||||||
|
getIgnoreCustomPackageIndexes(): boolean;
|
||||||
|
setIgnoreCustomPackageIndexes(value: boolean): UpdateIndexRequest;
|
||||||
|
|
||||||
|
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): UpdateIndexRequest.AsObject;
|
toObject(includeInstance?: boolean): UpdateIndexRequest.AsObject;
|
||||||
@ -234,6 +237,7 @@ export class UpdateIndexRequest extends jspb.Message {
|
|||||||
export namespace UpdateIndexRequest {
|
export namespace UpdateIndexRequest {
|
||||||
export type AsObject = {
|
export type AsObject = {
|
||||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||||
|
ignoreCustomPackageIndexes: boolean,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1811,7 +1811,8 @@ proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.prototype.toObject = functio
|
|||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.toObject = function(includeInstance, msg) {
|
proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.toObject = function(includeInstance, msg) {
|
||||||
var f, obj = {
|
var f, obj = {
|
||||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f)
|
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||||
|
ignoreCustomPackageIndexes: jspb.Message.getBooleanFieldWithDefault(msg, 2, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeInstance) {
|
if (includeInstance) {
|
||||||
@ -1853,6 +1854,10 @@ proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.deserializeBinaryFromReader
|
|||||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
||||||
msg.setInstance(value);
|
msg.setInstance(value);
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
var value = /** @type {boolean} */ (reader.readBool());
|
||||||
|
msg.setIgnoreCustomPackageIndexes(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
reader.skipField();
|
reader.skipField();
|
||||||
break;
|
break;
|
||||||
@ -1890,6 +1895,13 @@ proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.serializeBinaryToWriter = fu
|
|||||||
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
f = message.getIgnoreCustomPackageIndexes();
|
||||||
|
if (f) {
|
||||||
|
writer.writeBool(
|
||||||
|
2,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1930,6 +1942,24 @@ proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.prototype.hasInstance = func
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional bool ignore_custom_package_indexes = 2;
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.prototype.getIgnoreCustomPackageIndexes = function() {
|
||||||
|
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} value
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.UpdateIndexRequest} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.UpdateIndexRequest.prototype.setIgnoreCustomPackageIndexes = function(value) {
|
||||||
|
return jspb.Message.setProto3BooleanField(this, 2, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,21 +28,26 @@ export namespace Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DownloadProgress extends jspb.Message {
|
export class DownloadProgress extends jspb.Message {
|
||||||
getUrl(): string;
|
|
||||||
setUrl(value: string): DownloadProgress;
|
|
||||||
|
|
||||||
getFile(): string;
|
hasStart(): boolean;
|
||||||
setFile(value: string): DownloadProgress;
|
clearStart(): void;
|
||||||
|
getStart(): DownloadProgressStart | undefined;
|
||||||
|
setStart(value?: DownloadProgressStart): DownloadProgress;
|
||||||
|
|
||||||
getTotalSize(): number;
|
|
||||||
setTotalSize(value: number): DownloadProgress;
|
|
||||||
|
|
||||||
getDownloaded(): number;
|
hasUpdate(): boolean;
|
||||||
setDownloaded(value: number): DownloadProgress;
|
clearUpdate(): void;
|
||||||
|
getUpdate(): DownloadProgressUpdate | undefined;
|
||||||
|
setUpdate(value?: DownloadProgressUpdate): DownloadProgress;
|
||||||
|
|
||||||
getCompleted(): boolean;
|
|
||||||
setCompleted(value: boolean): DownloadProgress;
|
|
||||||
|
|
||||||
|
hasEnd(): boolean;
|
||||||
|
clearEnd(): void;
|
||||||
|
getEnd(): DownloadProgressEnd | undefined;
|
||||||
|
setEnd(value?: DownloadProgressEnd): DownloadProgress;
|
||||||
|
|
||||||
|
|
||||||
|
getMessageCase(): DownloadProgress.MessageCase;
|
||||||
|
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): DownloadProgress.AsObject;
|
toObject(includeInstance?: boolean): DownloadProgress.AsObject;
|
||||||
@ -55,12 +60,97 @@ export class DownloadProgress extends jspb.Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export namespace DownloadProgress {
|
export namespace DownloadProgress {
|
||||||
|
export type AsObject = {
|
||||||
|
start?: DownloadProgressStart.AsObject,
|
||||||
|
update?: DownloadProgressUpdate.AsObject,
|
||||||
|
end?: DownloadProgressEnd.AsObject,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum MessageCase {
|
||||||
|
MESSAGE_NOT_SET = 0,
|
||||||
|
|
||||||
|
START = 1,
|
||||||
|
|
||||||
|
UPDATE = 2,
|
||||||
|
|
||||||
|
END = 3,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DownloadProgressStart extends jspb.Message {
|
||||||
|
getUrl(): string;
|
||||||
|
setUrl(value: string): DownloadProgressStart;
|
||||||
|
|
||||||
|
getLabel(): string;
|
||||||
|
setLabel(value: string): DownloadProgressStart;
|
||||||
|
|
||||||
|
|
||||||
|
serializeBinary(): Uint8Array;
|
||||||
|
toObject(includeInstance?: boolean): DownloadProgressStart.AsObject;
|
||||||
|
static toObject(includeInstance: boolean, msg: DownloadProgressStart): DownloadProgressStart.AsObject;
|
||||||
|
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||||
|
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||||
|
static serializeBinaryToWriter(message: DownloadProgressStart, writer: jspb.BinaryWriter): void;
|
||||||
|
static deserializeBinary(bytes: Uint8Array): DownloadProgressStart;
|
||||||
|
static deserializeBinaryFromReader(message: DownloadProgressStart, reader: jspb.BinaryReader): DownloadProgressStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DownloadProgressStart {
|
||||||
export type AsObject = {
|
export type AsObject = {
|
||||||
url: string,
|
url: string,
|
||||||
file: string,
|
label: string,
|
||||||
totalSize: number,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DownloadProgressUpdate extends jspb.Message {
|
||||||
|
getDownloaded(): number;
|
||||||
|
setDownloaded(value: number): DownloadProgressUpdate;
|
||||||
|
|
||||||
|
getTotalSize(): number;
|
||||||
|
setTotalSize(value: number): DownloadProgressUpdate;
|
||||||
|
|
||||||
|
|
||||||
|
serializeBinary(): Uint8Array;
|
||||||
|
toObject(includeInstance?: boolean): DownloadProgressUpdate.AsObject;
|
||||||
|
static toObject(includeInstance: boolean, msg: DownloadProgressUpdate): DownloadProgressUpdate.AsObject;
|
||||||
|
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||||
|
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||||
|
static serializeBinaryToWriter(message: DownloadProgressUpdate, writer: jspb.BinaryWriter): void;
|
||||||
|
static deserializeBinary(bytes: Uint8Array): DownloadProgressUpdate;
|
||||||
|
static deserializeBinaryFromReader(message: DownloadProgressUpdate, reader: jspb.BinaryReader): DownloadProgressUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DownloadProgressUpdate {
|
||||||
|
export type AsObject = {
|
||||||
downloaded: number,
|
downloaded: number,
|
||||||
completed: boolean,
|
totalSize: number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DownloadProgressEnd extends jspb.Message {
|
||||||
|
getSuccess(): boolean;
|
||||||
|
setSuccess(value: boolean): DownloadProgressEnd;
|
||||||
|
|
||||||
|
getMessage(): string;
|
||||||
|
setMessage(value: string): DownloadProgressEnd;
|
||||||
|
|
||||||
|
|
||||||
|
serializeBinary(): Uint8Array;
|
||||||
|
toObject(includeInstance?: boolean): DownloadProgressEnd.AsObject;
|
||||||
|
static toObject(includeInstance: boolean, msg: DownloadProgressEnd): DownloadProgressEnd.AsObject;
|
||||||
|
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||||
|
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||||
|
static serializeBinaryToWriter(message: DownloadProgressEnd, writer: jspb.BinaryWriter): void;
|
||||||
|
static deserializeBinary(bytes: Uint8Array): DownloadProgressEnd;
|
||||||
|
static deserializeBinaryFromReader(message: DownloadProgressEnd, reader: jspb.BinaryReader): DownloadProgressEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DownloadProgressEnd {
|
||||||
|
export type AsObject = {
|
||||||
|
success: boolean,
|
||||||
|
message: string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ var global = Function('return this')();
|
|||||||
|
|
||||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Board', null, global);
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Board', null, global);
|
||||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgress', null, global);
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgress', null, global);
|
||||||
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgress.MessageCase', null, global);
|
||||||
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgressEnd', null, global);
|
||||||
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgressStart', null, global);
|
||||||
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate', null, global);
|
||||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.InstalledPlatformReference', null, global);
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.InstalledPlatformReference', null, global);
|
||||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Instance', null, global);
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Instance', null, global);
|
||||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Platform', null, global);
|
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Platform', null, global);
|
||||||
@ -55,7 +59,7 @@ if (goog.DEBUG && !COMPILED) {
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress = function(opt_data) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgress = function(opt_data) {
|
||||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_);
|
||||||
};
|
};
|
||||||
goog.inherits(proto.cc.arduino.cli.commands.v1.DownloadProgress, jspb.Message);
|
goog.inherits(proto.cc.arduino.cli.commands.v1.DownloadProgress, jspb.Message);
|
||||||
if (goog.DEBUG && !COMPILED) {
|
if (goog.DEBUG && !COMPILED) {
|
||||||
@ -65,6 +69,69 @@ if (goog.DEBUG && !COMPILED) {
|
|||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.displayName = 'proto.cc.arduino.cli.commands.v1.DownloadProgress';
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.displayName = 'proto.cc.arduino.cli.commands.v1.DownloadProgress';
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Generated by JsPbCodeGenerator.
|
||||||
|
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||||
|
* server response, or constructed directly in Javascript. The array is used
|
||||||
|
* in place and becomes part of the constructed object. It is not cloned.
|
||||||
|
* If no data is provided, the constructed object will be empty, but still
|
||||||
|
* valid.
|
||||||
|
* @extends {jspb.Message}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart = function(opt_data) {
|
||||||
|
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||||
|
};
|
||||||
|
goog.inherits(proto.cc.arduino.cli.commands.v1.DownloadProgressStart, jspb.Message);
|
||||||
|
if (goog.DEBUG && !COMPILED) {
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.displayName = 'proto.cc.arduino.cli.commands.v1.DownloadProgressStart';
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generated by JsPbCodeGenerator.
|
||||||
|
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||||
|
* server response, or constructed directly in Javascript. The array is used
|
||||||
|
* in place and becomes part of the constructed object. It is not cloned.
|
||||||
|
* If no data is provided, the constructed object will be empty, but still
|
||||||
|
* valid.
|
||||||
|
* @extends {jspb.Message}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate = function(opt_data) {
|
||||||
|
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||||
|
};
|
||||||
|
goog.inherits(proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate, jspb.Message);
|
||||||
|
if (goog.DEBUG && !COMPILED) {
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.displayName = 'proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate';
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generated by JsPbCodeGenerator.
|
||||||
|
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||||
|
* server response, or constructed directly in Javascript. The array is used
|
||||||
|
* in place and becomes part of the constructed object. It is not cloned.
|
||||||
|
* If no data is provided, the constructed object will be empty, but still
|
||||||
|
* valid.
|
||||||
|
* @extends {jspb.Message}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd = function(opt_data) {
|
||||||
|
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||||
|
};
|
||||||
|
goog.inherits(proto.cc.arduino.cli.commands.v1.DownloadProgressEnd, jspb.Message);
|
||||||
|
if (goog.DEBUG && !COMPILED) {
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.displayName = 'proto.cc.arduino.cli.commands.v1.DownloadProgressEnd';
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Generated by JsPbCodeGenerator.
|
* Generated by JsPbCodeGenerator.
|
||||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||||
@ -322,6 +389,33 @@ proto.cc.arduino.cli.commands.v1.Instance.prototype.setId = function(value) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oneof group definitions for this message. Each group defines the field
|
||||||
|
* numbers belonging to that group. When of these fields' value is set, all
|
||||||
|
* other fields in the group are cleared. During deserialization, if multiple
|
||||||
|
* fields are encountered for a group, only the last value seen will be kept.
|
||||||
|
* @private {!Array<!Array<number>>}
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_ = [[1,2,3]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.MessageCase = {
|
||||||
|
MESSAGE_NOT_SET: 0,
|
||||||
|
START: 1,
|
||||||
|
UPDATE: 2,
|
||||||
|
END: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {proto.cc.arduino.cli.commands.v1.DownloadProgress.MessageCase}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getMessageCase = function() {
|
||||||
|
return /** @type {proto.cc.arduino.cli.commands.v1.DownloadProgress.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_[0]));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||||
@ -353,11 +447,9 @@ proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.toObject = function(
|
|||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.toObject = function(includeInstance, msg) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.toObject = function(includeInstance, msg) {
|
||||||
var f, obj = {
|
var f, obj = {
|
||||||
url: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
start: (f = msg.getStart()) && proto.cc.arduino.cli.commands.v1.DownloadProgressStart.toObject(includeInstance, f),
|
||||||
file: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
update: (f = msg.getUpdate()) && proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.toObject(includeInstance, f),
|
||||||
totalSize: jspb.Message.getFieldWithDefault(msg, 3, 0),
|
end: (f = msg.getEnd()) && proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.toObject(includeInstance, f)
|
||||||
downloaded: jspb.Message.getFieldWithDefault(msg, 4, 0),
|
|
||||||
completed: jspb.Message.getBooleanFieldWithDefault(msg, 5, false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeInstance) {
|
if (includeInstance) {
|
||||||
@ -395,24 +487,19 @@ proto.cc.arduino.cli.commands.v1.DownloadProgress.deserializeBinaryFromReader =
|
|||||||
var field = reader.getFieldNumber();
|
var field = reader.getFieldNumber();
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case 1:
|
case 1:
|
||||||
var value = /** @type {string} */ (reader.readString());
|
var value = new proto.cc.arduino.cli.commands.v1.DownloadProgressStart;
|
||||||
msg.setUrl(value);
|
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.DownloadProgressStart.deserializeBinaryFromReader);
|
||||||
|
msg.setStart(value);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
var value = /** @type {string} */ (reader.readString());
|
var value = new proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate;
|
||||||
msg.setFile(value);
|
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.deserializeBinaryFromReader);
|
||||||
|
msg.setUpdate(value);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
var value = /** @type {number} */ (reader.readInt64());
|
var value = new proto.cc.arduino.cli.commands.v1.DownloadProgressEnd;
|
||||||
msg.setTotalSize(value);
|
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.deserializeBinaryFromReader);
|
||||||
break;
|
msg.setEnd(value);
|
||||||
case 4:
|
|
||||||
var value = /** @type {number} */ (reader.readInt64());
|
|
||||||
msg.setDownloaded(value);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
var value = /** @type {boolean} */ (reader.readBool());
|
|
||||||
msg.setCompleted(value);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
reader.skipField();
|
reader.skipField();
|
||||||
@ -442,6 +529,251 @@ proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.serializeBinary = fu
|
|||||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.serializeBinaryToWriter = function(message, writer) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.serializeBinaryToWriter = function(message, writer) {
|
||||||
|
var f = undefined;
|
||||||
|
f = message.getStart();
|
||||||
|
if (f != null) {
|
||||||
|
writer.writeMessage(
|
||||||
|
1,
|
||||||
|
f,
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.serializeBinaryToWriter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = message.getUpdate();
|
||||||
|
if (f != null) {
|
||||||
|
writer.writeMessage(
|
||||||
|
2,
|
||||||
|
f,
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.serializeBinaryToWriter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = message.getEnd();
|
||||||
|
if (f != null) {
|
||||||
|
writer.writeMessage(
|
||||||
|
3,
|
||||||
|
f,
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.serializeBinaryToWriter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional DownloadProgressStart start = 1;
|
||||||
|
* @return {?proto.cc.arduino.cli.commands.v1.DownloadProgressStart}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getStart = function() {
|
||||||
|
return /** @type{?proto.cc.arduino.cli.commands.v1.DownloadProgressStart} */ (
|
||||||
|
jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.DownloadProgressStart, 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?proto.cc.arduino.cli.commands.v1.DownloadProgressStart|undefined} value
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setStart = function(value) {
|
||||||
|
return jspb.Message.setOneofWrapperField(this, 1, proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_[0], value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the message field making it undefined.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.clearStart = function() {
|
||||||
|
return this.setStart(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this field is set.
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.hasStart = function() {
|
||||||
|
return jspb.Message.getField(this, 1) != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional DownloadProgressUpdate update = 2;
|
||||||
|
* @return {?proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getUpdate = function() {
|
||||||
|
return /** @type{?proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} */ (
|
||||||
|
jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate, 2));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate|undefined} value
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setUpdate = function(value) {
|
||||||
|
return jspb.Message.setOneofWrapperField(this, 2, proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_[0], value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the message field making it undefined.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.clearUpdate = function() {
|
||||||
|
return this.setUpdate(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this field is set.
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.hasUpdate = function() {
|
||||||
|
return jspb.Message.getField(this, 2) != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional DownloadProgressEnd end = 3;
|
||||||
|
* @return {?proto.cc.arduino.cli.commands.v1.DownloadProgressEnd}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getEnd = function() {
|
||||||
|
return /** @type{?proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} */ (
|
||||||
|
jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.DownloadProgressEnd, 3));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?proto.cc.arduino.cli.commands.v1.DownloadProgressEnd|undefined} value
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setEnd = function(value) {
|
||||||
|
return jspb.Message.setOneofWrapperField(this, 3, proto.cc.arduino.cli.commands.v1.DownloadProgress.oneofGroups_[0], value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the message field making it undefined.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.clearEnd = function() {
|
||||||
|
return this.setEnd(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this field is set.
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.hasEnd = function() {
|
||||||
|
return jspb.Message.getField(this, 3) != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||||
|
/**
|
||||||
|
* Creates an object representation of this proto.
|
||||||
|
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||||
|
* Optional fields that are not set will be set to undefined.
|
||||||
|
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||||
|
* For the list of reserved names please see:
|
||||||
|
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||||
|
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||||
|
* JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.toObject = function(opt_includeInstance) {
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressStart.toObject(opt_includeInstance, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static version of the {@see toObject} method.
|
||||||
|
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||||
|
* the JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart} msg The msg instance to transform.
|
||||||
|
* @return {!Object}
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.toObject = function(includeInstance, msg) {
|
||||||
|
var f, obj = {
|
||||||
|
url: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||||
|
label: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (includeInstance) {
|
||||||
|
obj.$jspbMessageInstance = msg;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format).
|
||||||
|
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.deserializeBinary = function(bytes) {
|
||||||
|
var reader = new jspb.BinaryReader(bytes);
|
||||||
|
var msg = new proto.cc.arduino.cli.commands.v1.DownloadProgressStart;
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressStart.deserializeBinaryFromReader(msg, reader);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format) from the
|
||||||
|
* given reader into the given message object.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart} msg The message object to deserialize into.
|
||||||
|
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.deserializeBinaryFromReader = function(msg, reader) {
|
||||||
|
while (reader.nextField()) {
|
||||||
|
if (reader.isEndGroup()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var field = reader.getFieldNumber();
|
||||||
|
switch (field) {
|
||||||
|
case 1:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setUrl(value);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setLabel(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.skipField();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message to binary data (in protobuf wire format).
|
||||||
|
* @return {!Uint8Array}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.serializeBinary = function() {
|
||||||
|
var writer = new jspb.BinaryWriter();
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.serializeBinaryToWriter(this, writer);
|
||||||
|
return writer.getResultBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the given message to binary data (in protobuf wire
|
||||||
|
* format), writing to the given BinaryWriter.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart} message
|
||||||
|
* @param {!jspb.BinaryWriter} writer
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.serializeBinaryToWriter = function(message, writer) {
|
||||||
var f = undefined;
|
var f = undefined;
|
||||||
f = message.getUrl();
|
f = message.getUrl();
|
||||||
if (f.length > 0) {
|
if (f.length > 0) {
|
||||||
@ -450,34 +782,13 @@ proto.cc.arduino.cli.commands.v1.DownloadProgress.serializeBinaryToWriter = func
|
|||||||
f
|
f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
f = message.getFile();
|
f = message.getLabel();
|
||||||
if (f.length > 0) {
|
if (f.length > 0) {
|
||||||
writer.writeString(
|
writer.writeString(
|
||||||
2,
|
2,
|
||||||
f
|
f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
f = message.getTotalSize();
|
|
||||||
if (f !== 0) {
|
|
||||||
writer.writeInt64(
|
|
||||||
3,
|
|
||||||
f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
f = message.getDownloaded();
|
|
||||||
if (f !== 0) {
|
|
||||||
writer.writeInt64(
|
|
||||||
4,
|
|
||||||
f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
f = message.getCompleted();
|
|
||||||
if (f) {
|
|
||||||
writer.writeBool(
|
|
||||||
5,
|
|
||||||
f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -485,89 +796,355 @@ proto.cc.arduino.cli.commands.v1.DownloadProgress.serializeBinaryToWriter = func
|
|||||||
* optional string url = 1;
|
* optional string url = 1;
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getUrl = function() {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.getUrl = function() {
|
||||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart} returns this
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setUrl = function(value) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.setUrl = function(value) {
|
||||||
return jspb.Message.setProto3StringField(this, 1, value);
|
return jspb.Message.setProto3StringField(this, 1, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* optional string file = 2;
|
* optional string label = 2;
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getFile = function() {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.getLabel = function() {
|
||||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressStart} returns this
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setFile = function(value) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressStart.prototype.setLabel = function(value) {
|
||||||
return jspb.Message.setProto3StringField(this, 2, value);
|
return jspb.Message.setProto3StringField(this, 2, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||||
/**
|
/**
|
||||||
* optional int64 total_size = 3;
|
* Creates an object representation of this proto.
|
||||||
|
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||||
|
* Optional fields that are not set will be set to undefined.
|
||||||
|
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||||
|
* For the list of reserved names please see:
|
||||||
|
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||||
|
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||||
|
* JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.toObject = function(opt_includeInstance) {
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.toObject(opt_includeInstance, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static version of the {@see toObject} method.
|
||||||
|
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||||
|
* the JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} msg The msg instance to transform.
|
||||||
|
* @return {!Object}
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.toObject = function(includeInstance, msg) {
|
||||||
|
var f, obj = {
|
||||||
|
downloaded: jspb.Message.getFieldWithDefault(msg, 1, 0),
|
||||||
|
totalSize: jspb.Message.getFieldWithDefault(msg, 2, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (includeInstance) {
|
||||||
|
obj.$jspbMessageInstance = msg;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format).
|
||||||
|
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.deserializeBinary = function(bytes) {
|
||||||
|
var reader = new jspb.BinaryReader(bytes);
|
||||||
|
var msg = new proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate;
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.deserializeBinaryFromReader(msg, reader);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format) from the
|
||||||
|
* given reader into the given message object.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} msg The message object to deserialize into.
|
||||||
|
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.deserializeBinaryFromReader = function(msg, reader) {
|
||||||
|
while (reader.nextField()) {
|
||||||
|
if (reader.isEndGroup()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var field = reader.getFieldNumber();
|
||||||
|
switch (field) {
|
||||||
|
case 1:
|
||||||
|
var value = /** @type {number} */ (reader.readInt64());
|
||||||
|
msg.setDownloaded(value);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var value = /** @type {number} */ (reader.readInt64());
|
||||||
|
msg.setTotalSize(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.skipField();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message to binary data (in protobuf wire format).
|
||||||
|
* @return {!Uint8Array}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.serializeBinary = function() {
|
||||||
|
var writer = new jspb.BinaryWriter();
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.serializeBinaryToWriter(this, writer);
|
||||||
|
return writer.getResultBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the given message to binary data (in protobuf wire
|
||||||
|
* format), writing to the given BinaryWriter.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} message
|
||||||
|
* @param {!jspb.BinaryWriter} writer
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.serializeBinaryToWriter = function(message, writer) {
|
||||||
|
var f = undefined;
|
||||||
|
f = message.getDownloaded();
|
||||||
|
if (f !== 0) {
|
||||||
|
writer.writeInt64(
|
||||||
|
1,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = message.getTotalSize();
|
||||||
|
if (f !== 0) {
|
||||||
|
writer.writeInt64(
|
||||||
|
2,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional int64 downloaded = 1;
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getTotalSize = function() {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.getDownloaded = function() {
|
||||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
|
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} value
|
* @param {number} value
|
||||||
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} returns this
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setTotalSize = function(value) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.setDownloaded = function(value) {
|
||||||
return jspb.Message.setProto3IntField(this, 3, value);
|
return jspb.Message.setProto3IntField(this, 1, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* optional int64 downloaded = 4;
|
* optional int64 total_size = 2;
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getDownloaded = function() {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.getTotalSize = function() {
|
||||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
|
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} value
|
* @param {number} value
|
||||||
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate} returns this
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setDownloaded = function(value) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressUpdate.prototype.setTotalSize = function(value) {
|
||||||
return jspb.Message.setProto3IntField(this, 4, value);
|
return jspb.Message.setProto3IntField(this, 2, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||||
|
/**
|
||||||
|
* Creates an object representation of this proto.
|
||||||
|
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||||
|
* Optional fields that are not set will be set to undefined.
|
||||||
|
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||||
|
* For the list of reserved names please see:
|
||||||
|
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||||
|
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||||
|
* JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.toObject = function(opt_includeInstance) {
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.toObject(opt_includeInstance, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* optional bool completed = 5;
|
* Static version of the {@see toObject} method.
|
||||||
|
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||||
|
* the JSPB instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} msg The msg instance to transform.
|
||||||
|
* @return {!Object}
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.toObject = function(includeInstance, msg) {
|
||||||
|
var f, obj = {
|
||||||
|
success: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
|
||||||
|
message: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (includeInstance) {
|
||||||
|
obj.$jspbMessageInstance = msg;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format).
|
||||||
|
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.deserializeBinary = function(bytes) {
|
||||||
|
var reader = new jspb.BinaryReader(bytes);
|
||||||
|
var msg = new proto.cc.arduino.cli.commands.v1.DownloadProgressEnd;
|
||||||
|
return proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.deserializeBinaryFromReader(msg, reader);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format) from the
|
||||||
|
* given reader into the given message object.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} msg The message object to deserialize into.
|
||||||
|
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.deserializeBinaryFromReader = function(msg, reader) {
|
||||||
|
while (reader.nextField()) {
|
||||||
|
if (reader.isEndGroup()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var field = reader.getFieldNumber();
|
||||||
|
switch (field) {
|
||||||
|
case 1:
|
||||||
|
var value = /** @type {boolean} */ (reader.readBool());
|
||||||
|
msg.setSuccess(value);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setMessage(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.skipField();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message to binary data (in protobuf wire format).
|
||||||
|
* @return {!Uint8Array}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.serializeBinary = function() {
|
||||||
|
var writer = new jspb.BinaryWriter();
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.serializeBinaryToWriter(this, writer);
|
||||||
|
return writer.getResultBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the given message to binary data (in protobuf wire
|
||||||
|
* format), writing to the given BinaryWriter.
|
||||||
|
* @param {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} message
|
||||||
|
* @param {!jspb.BinaryWriter} writer
|
||||||
|
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.serializeBinaryToWriter = function(message, writer) {
|
||||||
|
var f = undefined;
|
||||||
|
f = message.getSuccess();
|
||||||
|
if (f) {
|
||||||
|
writer.writeBool(
|
||||||
|
1,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = message.getMessage();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
2,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional bool success = 1;
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.getCompleted = function() {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.getSuccess = function() {
|
||||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
|
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} value
|
* @param {boolean} value
|
||||||
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgress} returns this
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} returns this
|
||||||
*/
|
*/
|
||||||
proto.cc.arduino.cli.commands.v1.DownloadProgress.prototype.setCompleted = function(value) {
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.setSuccess = function(value) {
|
||||||
return jspb.Message.setProto3BooleanField(this, 5, value);
|
return jspb.Message.setProto3BooleanField(this, 1, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string message = 2;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.getMessage = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} value
|
||||||
|
* @return {!proto.cc.arduino.cli.commands.v1.DownloadProgressEnd} returns this
|
||||||
|
*/
|
||||||
|
proto.cc.arduino.cli.commands.v1.DownloadProgressEnd.prototype.setMessage = function(value) {
|
||||||
|
return jspb.Message.setProto3StringField(this, 2, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
injectable,
|
injectable,
|
||||||
postConstruct,
|
postConstruct,
|
||||||
} from '@theia/core/shared/inversify';
|
} from '@theia/core/shared/inversify';
|
||||||
import { Emitter, Event } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
||||||
import { Instance } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
|
import { Instance } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
|
||||||
import {
|
import {
|
||||||
@ -19,8 +19,15 @@ import {
|
|||||||
UpdateLibrariesIndexResponse,
|
UpdateLibrariesIndexResponse,
|
||||||
} from './cli-protocol/cc/arduino/cli/commands/v1/commands_pb';
|
} from './cli-protocol/cc/arduino/cli/commands/v1/commands_pb';
|
||||||
import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
||||||
import { NotificationServiceServer } from '../common/protocol';
|
import {
|
||||||
import { Deferred, retry } from '@theia/core/lib/common/promise-util';
|
IndexType,
|
||||||
|
IndexUpdateDidCompleteParams,
|
||||||
|
IndexUpdateSummary,
|
||||||
|
IndexUpdateDidFailParams,
|
||||||
|
IndexUpdateWillStartParams,
|
||||||
|
NotificationServiceServer,
|
||||||
|
} from '../common/protocol';
|
||||||
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
import {
|
import {
|
||||||
Status as RpcStatus,
|
Status as RpcStatus,
|
||||||
Status,
|
Status,
|
||||||
@ -32,6 +39,7 @@ import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
|
|||||||
import {
|
import {
|
||||||
IndexesUpdateProgressHandler,
|
IndexesUpdateProgressHandler,
|
||||||
ExecuteWithProgress,
|
ExecuteWithProgress,
|
||||||
|
DownloadResult,
|
||||||
} from './grpc-progressible';
|
} from './grpc-progressible';
|
||||||
import type { DefaultCliConfig } from './cli-config';
|
import type { DefaultCliConfig } from './cli-config';
|
||||||
import { ServiceError } from './service-error';
|
import { ServiceError } from './service-error';
|
||||||
@ -45,16 +53,19 @@ export class CoreClientProvider {
|
|||||||
@inject(NotificationServiceServer)
|
@inject(NotificationServiceServer)
|
||||||
private readonly notificationService: NotificationServiceServer;
|
private readonly notificationService: NotificationServiceServer;
|
||||||
|
|
||||||
private ready = new Deferred<void>();
|
/**
|
||||||
private pending: Deferred<CoreClientProvider.Client> | undefined;
|
* See `CoreService#indexUpdateSummaryBeforeInit`.
|
||||||
private _client: CoreClientProvider.Client | undefined;
|
*/
|
||||||
private readonly toDisposeBeforeCreate = new DisposableCollection();
|
private readonly beforeInitSummary = {} as IndexUpdateSummary;
|
||||||
|
private readonly toDisposeOnCloseClient = new DisposableCollection();
|
||||||
private readonly toDisposeAfterDidCreate = new DisposableCollection();
|
private readonly toDisposeAfterDidCreate = new DisposableCollection();
|
||||||
private readonly onClientReadyEmitter =
|
private readonly onClientReadyEmitter =
|
||||||
new Emitter<CoreClientProvider.Client>();
|
new Emitter<CoreClientProvider.Client>();
|
||||||
private readonly onClientReady = this.onClientReadyEmitter.event;
|
private readonly onClientReady = this.onClientReadyEmitter.event;
|
||||||
private readonly onClientDidRefreshEmitter =
|
|
||||||
new Emitter<CoreClientProvider.Client>();
|
private ready = new Deferred<void>();
|
||||||
|
private pending: Deferred<CoreClientProvider.Client> | undefined;
|
||||||
|
private _client: CoreClientProvider.Client | undefined;
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected init(): void {
|
protected init(): void {
|
||||||
@ -65,7 +76,9 @@ export class CoreClientProvider {
|
|||||||
});
|
});
|
||||||
this.daemon.onDaemonStarted((port) => this.create(port));
|
this.daemon.onDaemonStarted((port) => this.create(port));
|
||||||
this.daemon.onDaemonStopped(() => this.closeClient());
|
this.daemon.onDaemonStopped(() => this.closeClient());
|
||||||
this.configService.onConfigChange(() => this.refreshIndexes());
|
this.configService.onConfigChange(
|
||||||
|
() => this.client.then((client) => this.updateIndex(client, ['platform'])) // Assuming 3rd party URL changes. No library index update is required.
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get tryGetClient(): CoreClientProvider.Client | undefined {
|
get tryGetClient(): CoreClientProvider.Client | undefined {
|
||||||
@ -80,7 +93,7 @@ export class CoreClientProvider {
|
|||||||
if (!this.pending) {
|
if (!this.pending) {
|
||||||
this.pending = new Deferred();
|
this.pending = new Deferred();
|
||||||
this.toDisposeAfterDidCreate.pushAll([
|
this.toDisposeAfterDidCreate.pushAll([
|
||||||
Disposable.create(() => (this.pending = undefined)),
|
Disposable.create(() => (this.pending = undefined)), // TODO: reject all pending requests before unsetting the ref?
|
||||||
this.onClientReady((client) => {
|
this.onClientReady((client) => {
|
||||||
this.pending?.resolve(client);
|
this.pending?.resolve(client);
|
||||||
this.toDisposeAfterDidCreate.dispose();
|
this.toDisposeAfterDidCreate.dispose();
|
||||||
@ -90,10 +103,6 @@ export class CoreClientProvider {
|
|||||||
return this.pending.promise;
|
return this.pending.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
get onClientDidRefresh(): Event<CoreClientProvider.Client> {
|
|
||||||
return this.onClientDidRefreshEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
async refresh(): Promise<void> {
|
async refresh(): Promise<void> {
|
||||||
const client = await this.client;
|
const client = await this.client;
|
||||||
await this.initInstance(client);
|
await this.initInstance(client);
|
||||||
@ -106,7 +115,7 @@ export class CoreClientProvider {
|
|||||||
this.closeClient();
|
this.closeClient();
|
||||||
const address = this.address(port);
|
const address = this.address(port);
|
||||||
const client = await this.createClient(address);
|
const client = await this.createClient(address);
|
||||||
this.toDisposeBeforeCreate.pushAll([
|
this.toDisposeOnCloseClient.pushAll([
|
||||||
Disposable.create(() => client.client.close()),
|
Disposable.create(() => client.client.close()),
|
||||||
Disposable.create(() => {
|
Disposable.create(() => {
|
||||||
this.ready.reject(
|
this.ready.reject(
|
||||||
@ -118,7 +127,6 @@ export class CoreClientProvider {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
await this.initInstanceWithFallback(client);
|
await this.initInstanceWithFallback(client);
|
||||||
setTimeout(async () => this.refreshIndexes(), 10_000); // Update the indexes asynchronously
|
|
||||||
return this.useClient(client);
|
return this.useClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,12 +149,17 @@ export class CoreClientProvider {
|
|||||||
try {
|
try {
|
||||||
await this.initInstance(client);
|
await this.initInstance(client);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof IndexUpdateRequiredBeforeInitError) {
|
if (err instanceof MustUpdateIndexesBeforeInitError) {
|
||||||
console.error(
|
console.error(
|
||||||
'The primary packages indexes are missing. Running indexes update before initializing the core gRPC client',
|
'The primary packages indexes are missing. Running indexes update before initializing the core gRPC client',
|
||||||
err.message
|
err.message
|
||||||
);
|
);
|
||||||
await this.updateIndexes(client); // TODO: this should run without the 3rd party URLs
|
await this.updateIndex(client, Array.from(err.indexTypesToUpdate));
|
||||||
|
const updatedAt = new Date().toISOString();
|
||||||
|
// Clients will ask for it after they connect.
|
||||||
|
err.indexTypesToUpdate.forEach(
|
||||||
|
(type) => (this.beforeInitSummary[type] = updatedAt)
|
||||||
|
);
|
||||||
await this.initInstance(client);
|
await this.initInstance(client);
|
||||||
console.info(
|
console.info(
|
||||||
`Downloaded the primary package indexes, and successfully initialized the core gRPC client.`
|
`Downloaded the primary package indexes, and successfully initialized the core gRPC client.`
|
||||||
@ -170,7 +183,7 @@ export class CoreClientProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private closeClient(): void {
|
private closeClient(): void {
|
||||||
return this.toDisposeBeforeCreate.dispose();
|
return this.toDisposeOnCloseClient.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createClient(
|
private async createClient(
|
||||||
@ -253,45 +266,66 @@ export class CoreClientProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates all indexes and runs an init to [reload the indexes](https://github.com/arduino/arduino-cli/pull/1274#issue-866154638).
|
* `update3rdPartyPlatforms` has not effect if `types` is `['library']`.
|
||||||
*/
|
*/
|
||||||
private async refreshIndexes(): Promise<void> {
|
async updateIndex(
|
||||||
const client = this._client;
|
client: CoreClientProvider.Client,
|
||||||
if (client) {
|
types: IndexType[]
|
||||||
const progressHandler = this.createProgressHandler();
|
): Promise<void> {
|
||||||
try {
|
let error: unknown | undefined = undefined;
|
||||||
await this.updateIndexes(client, progressHandler);
|
const progressHandler = this.createProgressHandler(types);
|
||||||
|
try {
|
||||||
|
const updates: Promise<void>[] = [];
|
||||||
|
if (types.includes('platform')) {
|
||||||
|
updates.push(this.updatePlatformIndex(client, progressHandler));
|
||||||
|
}
|
||||||
|
if (types.includes('library')) {
|
||||||
|
updates.push(this.updateLibraryIndex(client, progressHandler));
|
||||||
|
}
|
||||||
|
await Promise.all(updates);
|
||||||
|
} catch (err) {
|
||||||
|
// This is suboptimal but the core client must be re-initialized even if the index update has failed and the request was rejected.
|
||||||
|
error = err;
|
||||||
|
} finally {
|
||||||
|
// IDE2 reloads the index only and if only at least one download success is available.
|
||||||
|
if (
|
||||||
|
progressHandler.results.some(
|
||||||
|
(result) => !DownloadResult.isError(result)
|
||||||
|
)
|
||||||
|
) {
|
||||||
await this.initInstance(client);
|
await this.initInstance(client);
|
||||||
// notify clients about the index update only after the client has been "re-initialized" and the new content is available.
|
// notify clients about the index update only after the client has been "re-initialized" and the new content is available.
|
||||||
progressHandler.reportEnd();
|
progressHandler.reportEnd();
|
||||||
this.onClientDidRefreshEmitter.fire(client);
|
}
|
||||||
} catch (err) {
|
if (error) {
|
||||||
console.error('Failed to update indexes', err);
|
console.error(`Failed to update ${types.join(', ')} indexes.`, error);
|
||||||
progressHandler.reportError(
|
const downloadErrors = progressHandler.results
|
||||||
ServiceError.is(err) ? err.details : String(err)
|
.filter(DownloadResult.isError)
|
||||||
);
|
.map(({ url, message }) => `${message}: ${url}`)
|
||||||
|
.join(' ');
|
||||||
|
const message = ServiceError.is(error)
|
||||||
|
? `${error.details}${downloadErrors ? ` ${downloadErrors}` : ''}`
|
||||||
|
: String(error);
|
||||||
|
// IDE2 keeps only the most recent error message. Previous errors might have been fixed with the fallback initialization.
|
||||||
|
this.beforeInitSummary.message = message;
|
||||||
|
// Toast the error message, so tha the user has chance to fix it if it was a client error (HTTP 4xx).
|
||||||
|
progressHandler.reportError(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateIndexes(
|
get indexUpdateSummaryBeforeInit(): IndexUpdateSummary {
|
||||||
client: CoreClientProvider.Client,
|
return { ...this.beforeInitSummary };
|
||||||
progressHandler?: IndexesUpdateProgressHandler
|
|
||||||
): Promise<void> {
|
|
||||||
await Promise.all([
|
|
||||||
this.updateIndex(client, progressHandler),
|
|
||||||
this.updateLibraryIndex(client, progressHandler),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateIndex(
|
private async updatePlatformIndex(
|
||||||
client: CoreClientProvider.Client,
|
client: CoreClientProvider.Client,
|
||||||
progressHandler?: IndexesUpdateProgressHandler
|
progressHandler?: IndexesUpdateProgressHandler
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.doUpdateIndex(
|
return this.doUpdateIndex(
|
||||||
() =>
|
() =>
|
||||||
client.client.updateIndex(
|
client.client.updateIndex(
|
||||||
new UpdateIndexRequest().setInstance(client.instance)
|
new UpdateIndexRequest().setInstance(client.instance) // Always updates both the primary and the 3rd party package indexes.
|
||||||
),
|
),
|
||||||
progressHandler,
|
progressHandler,
|
||||||
'platform-index'
|
'platform-index'
|
||||||
@ -323,50 +357,45 @@ export class CoreClientProvider {
|
|||||||
task?: string
|
task?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const progressId = progressHandler?.progressId;
|
const progressId = progressHandler?.progressId;
|
||||||
return retry(
|
return new Promise<void>((resolve, reject) => {
|
||||||
() =>
|
responseProvider()
|
||||||
new Promise<void>((resolve, reject) => {
|
.on(
|
||||||
responseProvider()
|
'data',
|
||||||
.on(
|
ExecuteWithProgress.createDataCallback({
|
||||||
'data',
|
responseService: {
|
||||||
ExecuteWithProgress.createDataCallback({
|
appendToOutput: ({ chunk: message }) => {
|
||||||
responseService: {
|
console.log(
|
||||||
appendToOutput: ({ chunk: message }) => {
|
`core-client-provider${task ? ` [${task}]` : ''}`,
|
||||||
console.log(
|
message
|
||||||
`core-client-provider${task ? ` [${task}]` : ''}`,
|
);
|
||||||
message
|
progressHandler?.reportProgress(message);
|
||||||
);
|
},
|
||||||
progressHandler?.reportProgress(message);
|
reportResult: (result) => progressHandler?.reportResult(result),
|
||||||
},
|
},
|
||||||
},
|
progressId,
|
||||||
progressId,
|
})
|
||||||
})
|
)
|
||||||
)
|
.on('error', reject)
|
||||||
.on('error', reject)
|
.on('end', resolve);
|
||||||
.on('end', resolve);
|
});
|
||||||
}),
|
|
||||||
50,
|
|
||||||
3
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createProgressHandler(): IndexesUpdateProgressHandler {
|
private createProgressHandler(
|
||||||
|
types: IndexType[]
|
||||||
|
): IndexesUpdateProgressHandler {
|
||||||
const additionalUrlsCount =
|
const additionalUrlsCount =
|
||||||
this.configService.cliConfiguration?.board_manager?.additional_urls
|
this.configService.cliConfiguration?.board_manager?.additional_urls
|
||||||
?.length ?? 0;
|
?.length ?? 0;
|
||||||
return new IndexesUpdateProgressHandler(
|
return new IndexesUpdateProgressHandler(types, additionalUrlsCount, {
|
||||||
additionalUrlsCount,
|
onProgress: (progressMessage) =>
|
||||||
(progressMessage) =>
|
|
||||||
this.notificationService.notifyIndexUpdateDidProgress(progressMessage),
|
this.notificationService.notifyIndexUpdateDidProgress(progressMessage),
|
||||||
({ progressId, message }) =>
|
onError: (params: IndexUpdateDidFailParams) =>
|
||||||
this.notificationService.notifyIndexUpdateDidFail({
|
this.notificationService.notifyIndexUpdateDidFail(params),
|
||||||
progressId,
|
onStart: (params: IndexUpdateWillStartParams) =>
|
||||||
message,
|
this.notificationService.notifyIndexUpdateWillStart(params),
|
||||||
}),
|
onComplete: (params: IndexUpdateDidCompleteParams) =>
|
||||||
(progressId) =>
|
this.notificationService.notifyIndexUpdateDidComplete(params),
|
||||||
this.notificationService.notifyIndexWillUpdate(progressId),
|
});
|
||||||
(progressId) => this.notificationService.notifyIndexDidUpdate(progressId)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private address(port: string): string {
|
private address(port: string): string {
|
||||||
@ -410,6 +439,7 @@ export namespace CoreClientProvider {
|
|||||||
export abstract class CoreClientAware {
|
export abstract class CoreClientAware {
|
||||||
@inject(CoreClientProvider)
|
@inject(CoreClientProvider)
|
||||||
private readonly coreClientProvider: CoreClientProvider;
|
private readonly coreClientProvider: CoreClientProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns with a promise that resolves when the core client is initialized and ready.
|
* Returns with a promise that resolves when the core client is initialized and ready.
|
||||||
*/
|
*/
|
||||||
@ -417,8 +447,17 @@ export abstract class CoreClientAware {
|
|||||||
return this.coreClientProvider.client;
|
return this.coreClientProvider.client;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get onClientDidRefresh(): Event<CoreClientProvider.Client> {
|
/**
|
||||||
return this.coreClientProvider.onClientDidRefresh;
|
* Updates the index of the given `type` and returns with a promise which resolves when the core gPRC client has been reinitialized.
|
||||||
|
*/
|
||||||
|
async updateIndex({ types }: { types: IndexType[] }): Promise<void> {
|
||||||
|
const client = await this.coreClient;
|
||||||
|
return this.coreClientProvider.updateIndex(client, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
async indexUpdateSummaryBeforeInit(): Promise<IndexUpdateSummary> {
|
||||||
|
await this.coreClient;
|
||||||
|
return this.coreClientProvider.indexUpdateSummaryBeforeInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh(): Promise<void> {
|
refresh(): Promise<void> {
|
||||||
@ -426,15 +465,20 @@ export abstract class CoreClientAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IndexUpdateRequiredBeforeInitError extends Error {
|
class MustUpdateIndexesBeforeInitError extends Error {
|
||||||
constructor(causes: RpcStatus.AsObject[]) {
|
readonly indexTypesToUpdate: Set<IndexType>;
|
||||||
|
constructor(causes: [RpcStatus.AsObject, IndexType][]) {
|
||||||
super(`The index of the cores and libraries must be updated before initializing the core gRPC client.
|
super(`The index of the cores and libraries must be updated before initializing the core gRPC client.
|
||||||
The following problems were detected during the gRPC client initialization:
|
The following problems were detected during the gRPC client initialization:
|
||||||
${causes
|
${causes
|
||||||
.map(({ code, message }) => ` - code: ${code}, message: ${message}`)
|
.map(
|
||||||
|
([{ code, message }, type]) =>
|
||||||
|
`[${type}-index] - code: ${code}, message: ${message}`
|
||||||
|
)
|
||||||
.join('\n')}
|
.join('\n')}
|
||||||
`);
|
`);
|
||||||
Object.setPrototypeOf(this, IndexUpdateRequiredBeforeInitError.prototype);
|
Object.setPrototypeOf(this, MustUpdateIndexesBeforeInitError.prototype);
|
||||||
|
this.indexTypesToUpdate = new Set(causes.map(([, type]) => type));
|
||||||
if (!causes.length) {
|
if (!causes.length) {
|
||||||
throw new Error(`expected non-empty 'causes'`);
|
throw new Error(`expected non-empty 'causes'`);
|
||||||
}
|
}
|
||||||
@ -444,41 +488,66 @@ ${causes
|
|||||||
function isIndexUpdateRequiredBeforeInit(
|
function isIndexUpdateRequiredBeforeInit(
|
||||||
status: RpcStatus[],
|
status: RpcStatus[],
|
||||||
cliConfig: DefaultCliConfig
|
cliConfig: DefaultCliConfig
|
||||||
): IndexUpdateRequiredBeforeInitError | undefined {
|
): MustUpdateIndexesBeforeInitError | undefined {
|
||||||
const causes = status
|
const causes = status.reduce((acc, curr) => {
|
||||||
.filter((s) =>
|
for (const [predicate, type] of IndexUpdateRequiredPredicates) {
|
||||||
IndexUpdateRequiredBeforeInit.map((predicate) =>
|
if (predicate(curr, cliConfig)) {
|
||||||
predicate(s, cliConfig)
|
acc.push([curr.toObject(false), type]);
|
||||||
).some(Boolean)
|
return acc;
|
||||||
)
|
}
|
||||||
.map((s) => RpcStatus.toObject(false, s));
|
}
|
||||||
|
return acc;
|
||||||
|
}, [] as [RpcStatus.AsObject, IndexType][]);
|
||||||
return causes.length
|
return causes.length
|
||||||
? new IndexUpdateRequiredBeforeInitError(causes)
|
? new MustUpdateIndexesBeforeInitError(causes)
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
const IndexUpdateRequiredBeforeInit = [
|
interface Predicate {
|
||||||
isPackageIndexMissingStatus,
|
(
|
||||||
isDiscoveryNotFoundStatus,
|
status: RpcStatus,
|
||||||
|
{
|
||||||
|
directories: { data },
|
||||||
|
}: DefaultCliConfig
|
||||||
|
): boolean;
|
||||||
|
}
|
||||||
|
const IndexUpdateRequiredPredicates: [Predicate, IndexType][] = [
|
||||||
|
[isPrimaryPackageIndexMissingStatus, 'platform'],
|
||||||
|
[isDiscoveryNotFoundStatus, 'platform'],
|
||||||
|
[isLibraryIndexMissingStatus, 'library'],
|
||||||
];
|
];
|
||||||
function isPackageIndexMissingStatus(
|
// Loading index file: loading json index file /path/to/package_index.json: open /path/to/package_index.json: no such file or directory
|
||||||
|
function isPrimaryPackageIndexMissingStatus(
|
||||||
status: RpcStatus,
|
status: RpcStatus,
|
||||||
{ directories: { data } }: DefaultCliConfig
|
{ directories: { data } }: DefaultCliConfig
|
||||||
): boolean {
|
): boolean {
|
||||||
const predicate = ({ message }: RpcStatus.AsObject) =>
|
const predicate = ({ message }: RpcStatus.AsObject) =>
|
||||||
message.includes('loading json index file') &&
|
message.includes('loading json index file') &&
|
||||||
(message.includes(join(data, 'package_index.json')) ||
|
message.includes(join(data, 'package_index.json'));
|
||||||
message.includes(join(data, 'library_index.json')));
|
|
||||||
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/package_manager.go#L247
|
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/package_manager.go#L247
|
||||||
return evaluate(status, predicate);
|
return evaluate(status, predicate);
|
||||||
}
|
}
|
||||||
|
// Error loading hardware platform: discovery $TOOL_NAME not found
|
||||||
function isDiscoveryNotFoundStatus(status: RpcStatus): boolean {
|
function isDiscoveryNotFoundStatus(status: RpcStatus): boolean {
|
||||||
const predicate = ({ message }: RpcStatus.AsObject) =>
|
const predicate = ({ message }: RpcStatus.AsObject) =>
|
||||||
message.includes('discovery') &&
|
message.includes('discovery') &&
|
||||||
(message.includes('not found') || message.includes('not installed'));
|
(message.includes('not found') ||
|
||||||
|
message.includes('loading hardware platform'));
|
||||||
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/loader.go#L740
|
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/loader.go#L740
|
||||||
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/loader.go#L744
|
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/loader.go#L744
|
||||||
return evaluate(status, predicate);
|
return evaluate(status, predicate);
|
||||||
}
|
}
|
||||||
|
// Loading index file: reading library_index.json: open /path/to/library_index.json: no such file or directory
|
||||||
|
function isLibraryIndexMissingStatus(
|
||||||
|
status: RpcStatus,
|
||||||
|
{ directories: { data } }: DefaultCliConfig
|
||||||
|
): boolean {
|
||||||
|
const predicate = ({ message }: RpcStatus.AsObject) =>
|
||||||
|
message.includes('index file') &&
|
||||||
|
message.includes('reading') &&
|
||||||
|
message.includes(join(data, 'library_index.json'));
|
||||||
|
// https://github.com/arduino/arduino-cli/blob/f0245bc2da6a56fccea7b2c9ea09e85fdcc52cb8/arduino/cores/packagemanager/package_manager.go#L247
|
||||||
|
return evaluate(status, predicate);
|
||||||
|
}
|
||||||
function evaluate(
|
function evaluate(
|
||||||
subject: RpcStatus,
|
subject: RpcStatus,
|
||||||
predicate: (error: RpcStatus.AsObject) => boolean
|
predicate: (error: RpcStatus.AsObject) => boolean
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
import {
|
||||||
|
IndexType,
|
||||||
|
IndexUpdateDidCompleteParams,
|
||||||
|
IndexUpdateDidFailParams,
|
||||||
|
IndexUpdateSummary,
|
||||||
|
IndexUpdateWillStartParams,
|
||||||
|
} from '../common/protocol';
|
||||||
import {
|
import {
|
||||||
ProgressMessage,
|
ProgressMessage,
|
||||||
ResponseService,
|
ResponseService,
|
||||||
@ -11,6 +18,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
DownloadProgress,
|
DownloadProgress,
|
||||||
TaskProgress,
|
TaskProgress,
|
||||||
|
DownloadProgressStart,
|
||||||
|
DownloadProgressUpdate,
|
||||||
|
DownloadProgressEnd,
|
||||||
} from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
|
} from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
|
||||||
import { CompileResponse } from './cli-protocol/cc/arduino/cli/commands/v1/compile_pb';
|
import { CompileResponse } from './cli-protocol/cc/arduino/cli/commands/v1/compile_pb';
|
||||||
import {
|
import {
|
||||||
@ -81,7 +91,9 @@ namespace IndexProgressResponse {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
export function workUnit(response: IndexProgressResponse): UnitOfWork {
|
export function workUnit(response: IndexProgressResponse): UnitOfWork {
|
||||||
return { download: response.getDownloadProgress() };
|
return {
|
||||||
|
download: response.getDownloadProgress(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -151,7 +163,9 @@ export namespace ExecuteWithProgress {
|
|||||||
* _unknown_ progress if falsy.
|
* _unknown_ progress if falsy.
|
||||||
*/
|
*/
|
||||||
readonly progressId?: string;
|
readonly progressId?: string;
|
||||||
readonly responseService: Partial<ResponseService>;
|
readonly responseService: Partial<
|
||||||
|
ResponseService & { reportResult: (result: DownloadResult) => void }
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDataCallback<R extends ProgressResponse>({
|
export function createDataCallback<R extends ProgressResponse>({
|
||||||
@ -159,19 +173,21 @@ export namespace ExecuteWithProgress {
|
|||||||
progressId,
|
progressId,
|
||||||
}: ExecuteWithProgress.Options): (response: R) => void {
|
}: ExecuteWithProgress.Options): (response: R) => void {
|
||||||
const uuid = v4();
|
const uuid = v4();
|
||||||
let localFile = '';
|
let message = '';
|
||||||
let localTotalSize = Number.NaN;
|
let url = '';
|
||||||
return (response: R) => {
|
return (response: R) => {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const json = toJson(response);
|
const json = toJson(response);
|
||||||
if (json) {
|
if (json) {
|
||||||
console.log(`Progress response [${uuid}]: ${json}`);
|
console.debug(`[gRPC progress] Progress response [${uuid}]: ${json}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const unitOfWork = resolve(response);
|
const unitOfWork = resolve(response);
|
||||||
const { task, download } = unitOfWork;
|
const { task, download } = unitOfWork;
|
||||||
if (!download && !task) {
|
if (!download && !task) {
|
||||||
// report a fake unknown progress.
|
// Report a fake unknown progress if progress ID is available.
|
||||||
|
// When a progress ID is available, a connected client is setting the progress ID.
|
||||||
|
// Hence, it's listening to progress updates.
|
||||||
if (unitOfWork === UnitOfWork.Unknown && progressId) {
|
if (unitOfWork === UnitOfWork.Unknown && progressId) {
|
||||||
if (progressId) {
|
if (progressId) {
|
||||||
responseService.reportProgress?.({
|
responseService.reportProgress?.({
|
||||||
@ -187,7 +203,7 @@ export namespace ExecuteWithProgress {
|
|||||||
// Technically, it does not cause an error, but could mess up the progress reporting.
|
// Technically, it does not cause an error, but could mess up the progress reporting.
|
||||||
// See an example of an empty object `{}` repose here: https://github.com/arduino/arduino-ide/issues/906#issuecomment-1171145630.
|
// See an example of an empty object `{}` repose here: https://github.com/arduino/arduino-ide/issues/906#issuecomment-1171145630.
|
||||||
console.warn(
|
console.warn(
|
||||||
"Implementation error. Neither 'download' nor 'task' is available."
|
`Implementation error. None of the following properties were available on the response: 'task', 'download'`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -219,43 +235,32 @@ export namespace ExecuteWithProgress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (download) {
|
} else if (download) {
|
||||||
if (download.getFile() && !localFile) {
|
const phase = phaseOf(download);
|
||||||
localFile = download.getFile();
|
if (phase instanceof DownloadProgressStart) {
|
||||||
}
|
message = phase.getLabel();
|
||||||
if (download.getTotalSize() > 0 && Number.isNaN(localTotalSize)) {
|
url = phase.getUrl();
|
||||||
localTotalSize = download.getTotalSize();
|
responseService.appendToOutput?.({ chunk: `${message}\n` });
|
||||||
}
|
} else if (phase instanceof DownloadProgressUpdate) {
|
||||||
|
if (progressId && message) {
|
||||||
// This happens only once per file download.
|
|
||||||
if (download.getTotalSize() && localFile) {
|
|
||||||
responseService.appendToOutput?.({ chunk: `${localFile}\n` });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progressId && localFile) {
|
|
||||||
let work: ProgressMessage.Work | undefined = undefined;
|
|
||||||
if (download.getDownloaded() > 0 && !Number.isNaN(localTotalSize)) {
|
|
||||||
work = {
|
|
||||||
total: localTotalSize,
|
|
||||||
done: download.getDownloaded(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
responseService.reportProgress?.({
|
|
||||||
progressId,
|
|
||||||
message: `Downloading ${localFile}`,
|
|
||||||
work,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (download.getCompleted()) {
|
|
||||||
// Discard local state.
|
|
||||||
if (progressId && !Number.isNaN(localTotalSize)) {
|
|
||||||
responseService.reportProgress?.({
|
responseService.reportProgress?.({
|
||||||
progressId,
|
progressId,
|
||||||
message: '',
|
message,
|
||||||
work: { done: Number.NaN, total: Number.NaN },
|
work: {
|
||||||
|
total: phase.getTotalSize(),
|
||||||
|
done: phase.getDownloaded(),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
localFile = '';
|
} else if (phase instanceof DownloadProgressEnd) {
|
||||||
localTotalSize = Number.NaN;
|
if (url) {
|
||||||
|
responseService.reportResult?.({
|
||||||
|
url,
|
||||||
|
message: phase.getMessage(),
|
||||||
|
success: phase.getSuccess(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
message = '';
|
||||||
|
url = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -274,31 +279,40 @@ export namespace ExecuteWithProgress {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
function toJson(response: ProgressResponse): string | undefined {
|
function toJson(response: ProgressResponse): string | undefined {
|
||||||
let object: Record<string, unknown> | undefined = undefined;
|
return JSON.stringify(response.toObject(false));
|
||||||
if (response instanceof LibraryInstallResponse) {
|
}
|
||||||
object = LibraryInstallResponse.toObject(false, response);
|
function phaseOf(
|
||||||
} else if (response instanceof LibraryUninstallResponse) {
|
download: DownloadProgress
|
||||||
object = LibraryUninstallResponse.toObject(false, response);
|
): DownloadProgressStart | DownloadProgressUpdate | DownloadProgressEnd {
|
||||||
} else if (response instanceof ZipLibraryInstallResponse) {
|
let start: undefined | DownloadProgressStart = undefined;
|
||||||
object = ZipLibraryInstallResponse.toObject(false, response);
|
let update: undefined | DownloadProgressUpdate = undefined;
|
||||||
} else if (response instanceof PlatformInstallResponse) {
|
let end: undefined | DownloadProgressEnd = undefined;
|
||||||
object = PlatformInstallResponse.toObject(false, response);
|
if (download.hasStart()) {
|
||||||
} else if (response instanceof PlatformUninstallResponse) {
|
start = download.getStart();
|
||||||
object = PlatformUninstallResponse.toObject(false, response);
|
} else if (download.hasUpdate()) {
|
||||||
} else if (response instanceof UpdateIndexResponse) {
|
update = download.getUpdate();
|
||||||
object = UpdateIndexResponse.toObject(false, response);
|
} else if (download.hasEnd()) {
|
||||||
} else if (response instanceof UpdateLibrariesIndexResponse) {
|
end = download.getEnd();
|
||||||
object = UpdateLibrariesIndexResponse.toObject(false, response);
|
} else {
|
||||||
} else if (response instanceof UpdateCoreLibrariesIndexResponse) {
|
throw new Error(
|
||||||
object = UpdateCoreLibrariesIndexResponse.toObject(false, response);
|
`Download progress does not have a 'start', 'update', and 'end'. ${JSON.stringify(
|
||||||
} else if (response instanceof CompileResponse) {
|
download.toObject(false)
|
||||||
object = CompileResponse.toObject(false, response);
|
)}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!object) {
|
if (start) {
|
||||||
console.warn('Unhandled gRPC response', response);
|
return start;
|
||||||
return undefined;
|
} else if (update) {
|
||||||
|
return update;
|
||||||
|
} else if (end) {
|
||||||
|
return end;
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Download progress does not have a 'start', 'update', and 'end'. ${JSON.stringify(
|
||||||
|
download.toObject(false)
|
||||||
|
)}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return JSON.stringify(object);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,33 +320,39 @@ export class IndexesUpdateProgressHandler {
|
|||||||
private done = 0;
|
private done = 0;
|
||||||
private readonly total: number;
|
private readonly total: number;
|
||||||
readonly progressId: string;
|
readonly progressId: string;
|
||||||
|
readonly results: DownloadResult[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private types: IndexType[],
|
||||||
additionalUrlsCount: number,
|
additionalUrlsCount: number,
|
||||||
private readonly onProgress: (progressMessage: ProgressMessage) => void,
|
private readonly options: {
|
||||||
private readonly onError?: ({
|
onProgress: (progressMessage: ProgressMessage) => void;
|
||||||
progressId,
|
onError?: (params: IndexUpdateDidFailParams) => void;
|
||||||
message,
|
onStart?: (params: IndexUpdateWillStartParams) => void;
|
||||||
}: {
|
onComplete?: (params: IndexUpdateDidCompleteParams) => void;
|
||||||
progressId: string;
|
}
|
||||||
message: string;
|
|
||||||
}) => void,
|
|
||||||
private readonly onStart?: (progressId: string) => void,
|
|
||||||
private readonly onEnd?: (progressId: string) => void
|
|
||||||
) {
|
) {
|
||||||
this.progressId = v4();
|
this.progressId = v4();
|
||||||
this.total = IndexesUpdateProgressHandler.total(additionalUrlsCount);
|
this.results = [];
|
||||||
|
this.total = IndexesUpdateProgressHandler.total(types, additionalUrlsCount);
|
||||||
// Note: at this point, the IDE2 backend might not have any connected clients, so this notification is not delivered to anywhere
|
// Note: at this point, the IDE2 backend might not have any connected clients, so this notification is not delivered to anywhere
|
||||||
// Hence, clients must handle gracefully when no `willUpdate` is received before any `didProgress`.
|
// Hence, clients must handle gracefully when no `willStart` event is received before any `didProgress`.
|
||||||
this.onStart?.(this.progressId);
|
this.options.onStart?.({ progressId: this.progressId, types });
|
||||||
}
|
}
|
||||||
|
|
||||||
reportEnd(): void {
|
reportEnd(): void {
|
||||||
this.onEnd?.(this.progressId);
|
const updatedAt = new Date().toISOString();
|
||||||
|
this.options.onComplete?.({
|
||||||
|
progressId: this.progressId,
|
||||||
|
summary: this.types.reduce((summary, type) => {
|
||||||
|
summary[type] = updatedAt;
|
||||||
|
return summary;
|
||||||
|
}, {} as IndexUpdateSummary),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reportProgress(message: string): void {
|
reportProgress(message: string): void {
|
||||||
this.onProgress({
|
this.options.onProgress({
|
||||||
message,
|
message,
|
||||||
progressId: this.progressId,
|
progressId: this.progressId,
|
||||||
work: { total: this.total, done: ++this.done },
|
work: { total: this.total, done: ++this.done },
|
||||||
@ -340,15 +360,44 @@ export class IndexesUpdateProgressHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reportError(message: string): void {
|
reportError(message: string): void {
|
||||||
this.onError?.({ progressId: this.progressId, message });
|
this.options.onError?.({
|
||||||
|
progressId: this.progressId,
|
||||||
|
message,
|
||||||
|
types: this.types,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static total(additionalUrlsCount: number): number {
|
reportResult(result: DownloadResult): void {
|
||||||
// +1 for the `package_index.tar.bz2` when updating the platform index.
|
this.results.push(result);
|
||||||
const totalPlatformIndexCount = additionalUrlsCount + 1;
|
}
|
||||||
// The `library_index.json.gz` and `library_index.json.sig` when running the library index update.
|
|
||||||
const totalLibraryIndexCount = 2;
|
private static total(
|
||||||
|
types: IndexType[],
|
||||||
|
additionalUrlsCount: number
|
||||||
|
): number {
|
||||||
|
let total = 0;
|
||||||
|
if (types.includes('library')) {
|
||||||
|
// The `library_index.json.gz` and `library_index.json.sig` when running the library index update.
|
||||||
|
total += 2;
|
||||||
|
}
|
||||||
|
if (types.includes('platform')) {
|
||||||
|
// +1 for the `package_index.tar.bz2` when updating the platform index.
|
||||||
|
total += additionalUrlsCount + 1;
|
||||||
|
}
|
||||||
// +1 for the `initInstance` call after the index update (`reportEnd`)
|
// +1 for the `initInstance` call after the index update (`reportEnd`)
|
||||||
return totalPlatformIndexCount + totalLibraryIndexCount + 1;
|
return total + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DownloadResult {
|
||||||
|
readonly url: string;
|
||||||
|
readonly success: boolean;
|
||||||
|
readonly message?: string;
|
||||||
|
}
|
||||||
|
export namespace DownloadResult {
|
||||||
|
export function isError(
|
||||||
|
arg: DownloadResult
|
||||||
|
): arg is DownloadResult & { message: string } {
|
||||||
|
return !!arg.message && !arg.success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ import type {
|
|||||||
Config,
|
Config,
|
||||||
Sketch,
|
Sketch,
|
||||||
ProgressMessage,
|
ProgressMessage,
|
||||||
|
IndexUpdateWillStartParams,
|
||||||
|
IndexUpdateDidCompleteParams,
|
||||||
|
IndexUpdateDidFailParams,
|
||||||
} from '../common/protocol';
|
} from '../common/protocol';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@ -16,8 +19,8 @@ export class NotificationServiceServerImpl
|
|||||||
{
|
{
|
||||||
private readonly clients: NotificationServiceClient[] = [];
|
private readonly clients: NotificationServiceClient[] = [];
|
||||||
|
|
||||||
notifyIndexWillUpdate(progressId: string): void {
|
notifyIndexUpdateWillStart(params: IndexUpdateWillStartParams): void {
|
||||||
this.clients.forEach((client) => client.notifyIndexWillUpdate(progressId));
|
this.clients.forEach((client) => client.notifyIndexUpdateWillStart(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
|
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
|
||||||
@ -26,20 +29,14 @@ export class NotificationServiceServerImpl
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexDidUpdate(progressId: string): void {
|
notifyIndexUpdateDidComplete(params: IndexUpdateDidCompleteParams): void {
|
||||||
this.clients.forEach((client) => client.notifyIndexDidUpdate(progressId));
|
this.clients.forEach((client) =>
|
||||||
|
client.notifyIndexUpdateDidComplete(params)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIndexUpdateDidFail({
|
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void {
|
||||||
progressId,
|
this.clients.forEach((client) => client.notifyIndexUpdateDidFail(params));
|
||||||
message,
|
|
||||||
}: {
|
|
||||||
progressId: string;
|
|
||||||
message: string;
|
|
||||||
}): void {
|
|
||||||
this.clients.forEach((client) =>
|
|
||||||
client.notifyIndexUpdateDidFail({ progressId, message })
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDaemonDidStart(port: string): void {
|
notifyDaemonDidStart(port: string): void {
|
||||||
|
@ -408,6 +408,11 @@
|
|||||||
"dismissSurvey": "Don't show again",
|
"dismissSurvey": "Don't show again",
|
||||||
"surveyMessage": "Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better."
|
"surveyMessage": "Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better."
|
||||||
},
|
},
|
||||||
|
"updateIndexes": {
|
||||||
|
"updateIndexes": "Update Indexes",
|
||||||
|
"updateLibraryIndex": "Update Library Index",
|
||||||
|
"updatePackageIndex": "Update Package Index"
|
||||||
|
},
|
||||||
"upload": {
|
"upload": {
|
||||||
"error": "{0} error: {1}"
|
"error": "{0} error: {1}"
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user