diff --git a/docs/extensions/guides/stores.md b/docs/extensions/guides/stores.md index 0319ee0aab..ea27a502cd 100644 --- a/docs/extensions/guides/stores.md +++ b/docs/extensions/guides/stores.md @@ -42,8 +42,6 @@ export class ExamplePreferencesStore extends Store.ExtensionStore { return toJS({ activeCluster: this.activeCluster, clusters: this.clustersList.map(cluster => cluster.toJSON()), - }, { - recurseEverything: true }); } } diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts index 42cdc0a8b1..11f4bfc301 100644 --- a/src/common/hotbar-store.ts +++ b/src/common/hotbar-store.ts @@ -54,12 +54,8 @@ export class HotbarStore extends BaseStore { } toJSON(): HotbarStoreModel { - const model: HotbarStoreModel = { + return toJS({ hotbars: this.hotbars - }; - - return toJS(model, { - recurseEverything: true, }); } } diff --git a/src/common/ipc/ipc.ts b/src/common/ipc/ipc.ts index b104b31f4a..78a5233dd0 100644 --- a/src/common/ipc/ipc.ts +++ b/src/common/ipc/ipc.ts @@ -18,7 +18,7 @@ export async function requestMain(channel: string, ...args: any[]) { } function getSubFrames(): ClusterFrameInfo[] { - return toJS(Array.from(clusterFrameMap.values()), { recurseEverything: true }); + return toJS(Array.from(clusterFrameMap.values())); } export async function broadcastMessage(channel: string, ...args: any[]) { diff --git a/src/common/user-store.ts b/src/common/user-store.ts index c7ad21f988..ad2ff5de5c 100644 --- a/src/common/user-store.ts +++ b/src/common/user-store.ts @@ -175,15 +175,11 @@ export class UserStore extends BaseStore { } toJSON(): UserStoreModel { - const model: UserStoreModel = { + return toJS({ kubeConfigPath: this.kubeConfigPath, lastSeenAppVersion: this.lastSeenAppVersion, seenContexts: Array.from(this.seenContexts), preferences: this.preferences, - }; - - return toJS(model, { - recurseEverything: true, }); } } diff --git a/src/extensions/extension-discovery.ts b/src/extensions/extension-discovery.ts index 0994f89995..a963918ffc 100644 --- a/src/extensions/extension-discovery.ts +++ b/src/extensions/extension-discovery.ts @@ -453,8 +453,6 @@ export class ExtensionDiscovery { toJSON(): ExtensionDiscoveryChannelMessage { return toJS({ isLoaded: this.isLoaded - }, { - recurseEverything: true }); } diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index bc4b5e6407..26dee5aa05 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -319,10 +319,7 @@ export class ExtensionLoader { } toJSON(): Map { - return toJS(this.extensions, { - exportMapsAsObjects: false, - recurseEverything: true, - }); + return toJS(this.extensions); } broadcastExtensions(main = true) { diff --git a/src/extensions/extensions-store.ts b/src/extensions/extensions-store.ts index 8e88d22f38..d0852779e5 100644 --- a/src/extensions/extensions-store.ts +++ b/src/extensions/extensions-store.ts @@ -47,9 +47,7 @@ export class ExtensionsStore extends BaseStore { toJSON(): LensExtensionsStoreModel { return toJS({ - extensions: this.state.toJSON(), - }, { - recurseEverything: true + extensions: Object.fromEntries(this.state), }); } } diff --git a/src/extensions/registries/command-registry.ts b/src/extensions/registries/command-registry.ts index 45af9121a1..fdb76487e7 100644 --- a/src/extensions/registries/command-registry.ts +++ b/src/extensions/registries/command-registry.ts @@ -1,7 +1,7 @@ // Extensions API -> Commands import { BaseRegistry } from "./base-registry"; -import { action, observable } from "mobx"; +import { observable } from "mobx"; import { LensExtension } from "../lens-extension"; import { CatalogEntity } from "../../common/catalog-entity"; @@ -20,7 +20,6 @@ export interface CommandRegistration { export class CommandRegistry extends BaseRegistry { @observable activeEntity: CatalogEntity; - @action add(items: CommandRegistration | CommandRegistration[], extension?: LensExtension) { const itemArray = [items].flat(); diff --git a/src/main/catalog-pusher.ts b/src/main/catalog-pusher.ts index ffe8cc17d0..62860cccaf 100644 --- a/src/main/catalog-pusher.ts +++ b/src/main/catalog-pusher.ts @@ -27,6 +27,6 @@ export class CatalogPusher { } broadcast() { - broadcastMessage("catalog:items", toJS(this.catalog.items, { recurseEverything: true })); + broadcastMessage("catalog:items", toJS(this.catalog.items)); } } diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 047fb0ca95..4a484fdff2 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -31,7 +31,7 @@ export class ClusterManager extends Singleton { }, { fireImmediately: true }); - reaction(() => toJS(clusterStore.enabledClustersList, { recurseEverything: true }), () => { + reaction(() => toJS(clusterStore.enabledClustersList), () => { this.updateCatalogSource(clusterStore.enabledClustersList); }, { fireImmediately: true }); diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 7a02c3e0c9..c1485d6337 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -240,9 +240,7 @@ export class Cluster implements ClusterModel, ClusterState { @computed get prometheusPreferences(): ClusterPrometheusPreferences { const { prometheus, prometheusProvider } = this.preferences; - return toJS({ prometheus, prometheusProvider }, { - recurseEverything: true, - }); + return toJS({ prometheus, prometheusProvider }); } /** @@ -616,9 +614,7 @@ export class Cluster implements ClusterModel, ClusterState { accessibleNamespaces: this.accessibleNamespaces, }; - return toJS(model, { - recurseEverything: true - }); + return toJS(model); } /** @@ -640,9 +636,7 @@ export class Cluster implements ClusterModel, ClusterState { isGlobalWatchEnabled: this.isGlobalWatchEnabled, }; - return toJS(state, { - recurseEverything: true - }); + return toJS(state); } /** diff --git a/src/main/extension-filesystem.ts b/src/main/extension-filesystem.ts index eddb7b747f..311369da86 100644 --- a/src/main/extension-filesystem.ts +++ b/src/main/extension-filesystem.ts @@ -50,9 +50,7 @@ export class FilesystemProvisionerStore extends BaseStore { toJSON(): FSProvisionModel { return toJS({ - extensions: this.registeredExtensions.toJSON(), - }, { - recurseEverything: true + extensions: Object.fromEntries(this.registeredExtensions.toJSON()), }); } } diff --git a/src/renderer/api/endpoints/configmap.api.ts b/src/renderer/api/endpoints/configmap.api.ts index 042fb59d86..94d8a9de50 100644 --- a/src/renderer/api/endpoints/configmap.api.ts +++ b/src/renderer/api/endpoints/configmap.api.ts @@ -3,6 +3,8 @@ import { KubeJsonApiData } from "../kube-json-api"; import { autobind } from "../../utils"; import { KubeApi } from "../kube-api"; +export type ConfigMapData = Record; + @autobind() export class ConfigMap extends KubeObject { static kind = "ConfigMap"; @@ -14,9 +16,7 @@ export class ConfigMap extends KubeObject { this.data = this.data || {}; } - data: { - [param: string]: string; - }; + data: ConfigMapData; getKeys(): string[] { return Object.keys(this.data); diff --git a/src/renderer/components/+config-maps/config-map-details.tsx b/src/renderer/components/+config-maps/config-map-details.tsx index 540a44c450..f33d32c7e5 100644 --- a/src/renderer/components/+config-maps/config-map-details.tsx +++ b/src/renderer/components/+config-maps/config-map-details.tsx @@ -1,7 +1,7 @@ import "./config-map-details.scss"; import React from "react"; -import { autorun, observable } from "mobx"; +import { observable, reaction } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import { DrawerTitle } from "../drawer"; import { Notifications } from "../notifications"; @@ -10,7 +10,7 @@ import { Button } from "../button"; import { KubeEventDetails } from "../+events/kube-event-details"; import { configMapsStore } from "./config-maps.store"; import { KubeObjectDetailsProps } from "../kube-object"; -import { ConfigMap } from "../../api/endpoints"; +import { ConfigMap, ConfigMapData } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; @@ -20,26 +20,21 @@ interface Props extends KubeObjectDetailsProps { @observer export class ConfigMapDetails extends React.Component { @observable isSaving = false; - @observable data = observable.map(); + @observable data: ConfigMapData = {}; - async componentDidMount() { - disposeOnUnmount(this, [ - autorun(() => { - const { object: configMap } = this.props; - - if (configMap) { - this.data.replace(configMap.data); // refresh - } - }) - ]); - } + @disposeOnUnmount + autoCopyData = reaction(() => this.props.object, configMap => { + this.data = configMap?.data ?? {}; // copy-or-update config-map's data for editing + }, { + fireImmediately: true, + }); save = async () => { const { object: configMap } = this.props; try { this.isSaving = true; - await configMapsStore.update(configMap, { ...configMap, data: this.data.toJSON() }); + await configMapsStore.update(configMap, { ...configMap, data: this.data }); Notifications.ok(

<>ConfigMap {configMap.getName()} successfully updated. @@ -53,18 +48,21 @@ export class ConfigMapDetails extends React.Component { render() { const { object: configMap } = this.props; - if (!configMap) return null; - const data = Object.entries(this.data.toJSON()); + if (!configMap) { + return null; + } + + const dataEntries = Object.entries(this.data); return (

{ - data.length > 0 && ( + dataEntries.length > 0 && ( <> { - data.map(([name, value]) => { + dataEntries.map(([name, value]) => { return (
{name}
@@ -74,7 +72,7 @@ export class ConfigMapDetails extends React.Component { theme="round-black" className="box grow" value={value} - onChange={v => this.data.set(name, v)} + onChange={v => this.data[name] = v} />
diff --git a/src/renderer/components/dock/dock-tab.store.ts b/src/renderer/components/dock/dock-tab.store.ts index 34a9b647bb..f3c083d234 100644 --- a/src/renderer/components/dock/dock-tab.store.ts +++ b/src/renderer/components/dock/dock-tab.store.ts @@ -54,7 +54,7 @@ export class DockTabStore { } protected getStorableData(): DockTabStorageState { - const allTabsData = toJS(this.data, { recurseEverything: true }); + const allTabsData = toJS(this.data); return Object.fromEntries( Object.entries(allTabsData).map(([tabId, tabData]) => { diff --git a/src/renderer/kube-object.store.ts b/src/renderer/kube-object.store.ts index 987112a25c..bd6313e7cb 100644 --- a/src/renderer/kube-object.store.ts +++ b/src/renderer/kube-object.store.ts @@ -349,7 +349,7 @@ export abstract class KubeObjectStore extends ItemSt @action protected updateFromEventsBuffer() { - const items = this.items.toJS(); + const items = this.items.toJSON(); for (const { type, object } of this.eventsBuffer.clear()) { const index = items.findIndex(item => item.getId() === object.metadata?.uid); diff --git a/src/renderer/utils/storageHelper.ts b/src/renderer/utils/storageHelper.ts index bfcc1b1da7..98df93814e 100755 --- a/src/renderer/utils/storageHelper.ts +++ b/src/renderer/utils/storageHelper.ts @@ -1,9 +1,8 @@ // Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) -import type { CreateObservableOptions } from "mobx"; -import { action, comparer, observable, toJS, when } from "mobx"; +import { action, comparer, CreateObservableOptions, IObservableValue, observable, reaction, toJS, when } from "mobx"; import produce, { Draft, enableMapSet, setAutoFreeze } from "immer"; -import { isEqual, isFunction, isPlainObject } from "lodash"; +import { isEqual, isFunction, isPlainObject, merge } from "lodash"; import logger from "../../main/logger"; setAutoFreeze(false); // allow to merge observables @@ -33,7 +32,7 @@ export class StorageHelper { } }; - @observable private data = observable.box(); + private data: IObservableValue; @observable initialized = false; whenReady = when(() => this.initialized); @@ -46,9 +45,8 @@ export class StorageHelper { } constructor(readonly key: string, private options: StorageHelperOptions) { - this.options = { ...StorageHelper.defaultOptions, ...options }; - this.configureObservable(); - this.reset(); + this.options = merge({}, StorageHelper.defaultOptions, options); + this.observeData(); if (this.options.autoInit) { this.init(); @@ -99,17 +97,17 @@ export class StorageHelper { return isEqual(value, this.defaultValue); } - @action - private configureObservable(options = this.options.observable) { - this.data = observable.box(this.data.get(), { + private observeData(value = this.options.defaultValue) { + const observableOptions: CreateObservableOptions = { ...StorageHelper.defaultOptions.observable, // inherit default observability options - ...(options ?? {}), - }); - this.data.observe(change => { - const { newValue, oldValue } = toJS(change, { recurseEverything: true }); + ...this.options.observable, + }; + this.data = observable.box(value, observableOptions); + + return reaction(() => toJS(this.data.get()), (newValue, oldValue) => { this.onChange(newValue, oldValue); - }); + }, observableOptions); } protected onChange(value: T, oldValue?: T) { @@ -158,6 +156,6 @@ export class StorageHelper { } toJS() { - return toJS(this.get(), { recurseEverything: true }); + return toJS(this.get()); } } diff --git a/yarn.lock b/yarn.lock index ab234d7c5c..80314c745f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9495,17 +9495,17 @@ mobx-observable-history@^1.0.3: history "^4.10.1" mobx "^5.15.4" -mobx-react-lite@>=2.2.0: +mobx-react-lite@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz#87c217dc72b4e47b22493daf155daf3759f868a6" integrity sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg== mobx-react@^6.2.2: - version "6.3.0" - resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.3.0.tgz#7d11799f988bbdadc49e725081993b18baa20329" - integrity sha512-C14yya2nqEBRSEiJjPkhoWJLlV8pcCX3m2JRV7w1KivwANJqipoiPx9UMH4pm6QNMbqDdvJqoyl+LqNu9AhvEQ== + version "6.3.1" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.3.1.tgz#204f9756e42e19d91cb6598837063b7e7de87c52" + integrity sha512-IOxdJGnRSNSJrL2uGpWO5w9JH5q5HoxEqwOF4gye1gmZYdjoYkkMzSGMDnRCUpN/BNzZcFoMdHXrjvkwO7KgaQ== dependencies: - mobx-react-lite ">=2.2.0" + mobx-react-lite "^2.2.0" mobx@^5.15.4: version "5.15.4"