Skip to content

Commit

Permalink
fix: keep storage to server and move evaluation to renderer
Browse files Browse the repository at this point in the history
Signed-off-by: lstocchi <lstocchi@redhat.com>
  • Loading branch information
lstocchi committed Jul 11, 2023
1 parent 396e4bf commit fb48a34
Show file tree
Hide file tree
Showing 21 changed files with 587 additions and 387 deletions.
9 changes: 9 additions & 0 deletions packages/extension-api/src/extension-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2118,4 +2118,13 @@ declare module '@podman-desktop/api' {
*/
writeText(value: string): Promise<void>;
}

export type ContextKeyValue =
| null
| undefined
| boolean
| number
| string
| Array<null | undefined | boolean | number | string>
| Record<string, null | undefined | boolean | number | string>;
}
29 changes: 29 additions & 0 deletions packages/main/src/plugin/api/context-into.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type { ContextKeyValue } from '@podman-desktop/api';
import type { Context } from '../context/context.js';

export interface IContext {
getValue<T extends ContextKeyValue = ContextKeyValue>(key: string): T | undefined;
}

export interface ContextInfo {
readonly id: number;
readonly parent?: Context | null;
readonly extension: string | null;
}
6 changes: 5 additions & 1 deletion packages/main/src/plugin/api/view-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
export interface ViewContribution {
id: string;
when: string | null | undefined;
icon: string;
}

export interface ViewInfoUI extends ViewContribution {
extensionId: string;
viewId: string;
}
24 changes: 0 additions & 24 deletions packages/main/src/plugin/container-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ import { Emitter } from './events/emitter.js';
import fs from 'node:fs';
import { pipeline } from 'node:stream/promises';
import type { ApiSenderType } from './api.js';
import { ContextKeyService } from './contextkey/contextKeyService.js';
import { ContextKeyExpr } from './contextkey/contextKey.js';
import type { ViewRegistry } from './view-registry.js';
export interface InternalContainerProvider {
name: string;
id: string;
Expand Down Expand Up @@ -82,7 +79,6 @@ export class ContainerProviderRegistry {
private apiSender: ApiSenderType,
private imageRegistry: ImageRegistry,
private telemetryService: Telemetry,
private viewRegistry: ViewRegistry,
) {
const libPodDockerode = new LibpodDockerode();
libPodDockerode.enhancePrototypeWithLibPod();
Expand Down Expand Up @@ -271,8 +267,6 @@ export class ContainerProviderRegistry {

async listContainers(): Promise<ContainerInfo[]> {
let telemetryOptions = {};
const viewContribution = this.viewRegistry.getViewContribution('icons/containersList');
const containerContext = new ContextKeyService();
const containers = await Promise.all(
Array.from(this.internalProviders.values()).map(async provider => {
try {
Expand Down Expand Up @@ -319,22 +313,6 @@ export class ContainerProviderRegistry {
StartedAt = '';
}

// it prepares the context for the icon contributions
const contextId = containerContext.createChildContext();
const context = containerContext.getContextValuesContainer(contextId);
context.setValue('containerLabelKeys', Object.keys(container.Labels));
let icon;

// it checks if someone contributed to the containerlist view
viewContribution.every(contribution => {
const contextExprDeserialized = ContextKeyExpr.deserialize(contribution.when);
if (contextExprDeserialized?.evaluate(context)) {
icon = contribution.icon;
return false;
}
return true;
});

// do we have a matching pod for this container ?
let pod;
const matchingPod = pods.find(pod =>
Expand All @@ -355,7 +333,6 @@ export class ContainerProviderRegistry {
engineId: provider.id,
engineType: provider.connection.type,
StartedAt,
icon,
};
return containerInfo;
}),
Expand All @@ -367,7 +344,6 @@ export class ContainerProviderRegistry {
}
}),
);
containerContext.dispose();
const flatttenedContainers = containers.flat();
this.telemetryService
.track('listContainers', Object.assign({ total: flatttenedContainers.length }, telemetryOptions))
Expand Down
69 changes: 69 additions & 0 deletions packages/main/src/plugin/context-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type { ApiSenderType } from './api.js';
import type { ContextInfo } from './api/context-into.js';
import { Context } from './context/context.js';

export class ContextRegistry {
private contexts: Map<string, Context>;

constructor(private apiSender: ApiSenderType) {
this.contexts = new Map();
}

registerContext(extension: string): void {
if (!this.contexts.has(extension)) {
const ctx = new Context(this.contexts.size, null, extension, this.apiSender);
this.contexts.set(extension, ctx);
}
}

unregisterContext(extension: string): void {
const ctx = this.contexts.get(extension);
ctx?.dispose();
this.contexts.delete(extension);
}

getContext(extension: string): Context | undefined {
return this.contexts.get(extension);
}

listContextInfos(): ContextInfo[] {
const contexts: ContextInfo[] = [];
Array.from(this.contexts.values()).forEach(value => {
contexts.push({
extension: value.extension,
id: value.id,
parent: value.parent,
});
});
return contexts;
}

getContextInfo(extension: string): ContextInfo {
const context = this.contexts.get(extension);
if (!context) {
throw new Error(`no context found for extension ${extension}`);
}
return {
extension: context.extension,
id: context.id,
parent: context.parent,
};
}
}
104 changes: 104 additions & 0 deletions packages/main/src/plugin/context/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ApiSenderType } from '../api.js';
import type { IContext } from '../api/context-into.js';

export class Context implements IContext {
private _value: Record<string, any>;

constructor(
private _id: number,
private _parent: Context | null,
private _extension: string | null,
private apiSender: ApiSenderType,
) {
this._value = Object.create(null);
this._value['_contextId'] = _id;
}

get id(): number {
return this._id;
}

get parent(): Context | null {
return this._parent;
}

get extension(): string | null {
return this._extension;
}

get value(): Record<string, any> {
return { ...this._value };
}

setValue(key: string, value: any): boolean {
if (this._value[key] !== value) {
this._value[key] = value;
this.apiSender.send('context-value-updated', {
extension: this._extension,
key,
value,
});
return true;
}
return false;
}

removeValue(key: string): boolean {
if (key in this._value) {
delete this._value[key];
this.apiSender.send('context-key-removed', {
extension: this._extension,
key,
});
return true;
}
return false;
}

getValue<T>(key: string): T | undefined {
const ret = this._value[key];
if (typeof ret === 'undefined' && this._parent) {
return this._parent.getValue<T>(key);
}
return ret;
}

updateParent(parent: Context): void {
this._parent = parent;
this.apiSender.send('context-parent-updated', {
extension: this._extension,
pid: parent._id,
pextension: parent._extension,
pp: parent.parent,
});
}

collectAllValues(): Record<string, any> {
let result = this._parent ? this._parent.collectAllValues() : Object.create(null);
result = { ...result, ...this._value };
delete result['_contextId'];
return result;
}

dispose(): void {
this._parent = null;
}
}

0 comments on commit fb48a34

Please sign in to comment.