mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix dock-store.test.ts test by overriding createStorage to not touch file system
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
35e49fe6e6
commit
199f142559
@ -7,7 +7,7 @@ import { action, observable, reaction, when, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
||||
import type { Cluster, ClusterApi } from "../../../../common/k8s-api/endpoints";
|
||||
import { getMetricsByNodeNames, type ClusterMetricData } from "../../../../common/k8s-api/endpoints";
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { StorageLayer } from "../../../utils";
|
||||
import { autoBind } from "../../../utils";
|
||||
import { type IMetricsReqParams, normalizeMetrics } from "../../../../common/k8s-api/endpoints/metrics.api";
|
||||
import { nodesStore } from "../../+nodes/nodes.store";
|
||||
@ -28,7 +28,7 @@ export interface ClusterOverviewStorageState {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
storage: StorageHelper<ClusterOverviewStorageState>;
|
||||
storage: StorageLayer<ClusterOverviewStorageState>;
|
||||
}
|
||||
|
||||
export class ClusterOverviewStore extends KubeObjectStore<Cluster, ClusterApi> implements ClusterOverviewStorageState {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
import type { IReactionDisposer } from "mobx";
|
||||
import { action, comparer, computed, makeObservable, reaction } from "mobx";
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { StorageLayer } from "../../../utils";
|
||||
import { autoBind, noop, toggle } from "../../../utils";
|
||||
import type { KubeObjectStoreLoadingParams } from "../../../../common/k8s-api/kube-object.store";
|
||||
import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
||||
@ -13,7 +13,7 @@ import type { NamespaceApi } from "../../../../common/k8s-api/endpoints/namespac
|
||||
import { Namespace } from "../../../../common/k8s-api/endpoints/namespaces.api";
|
||||
|
||||
interface Dependencies {
|
||||
storage: StorageHelper<string[] | undefined>;
|
||||
storage: StorageLayer<string[] | undefined>;
|
||||
}
|
||||
|
||||
export class NamespaceStore extends KubeObjectStore<Namespace, NamespaceApi> {
|
||||
@ -70,7 +70,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace, NamespaceApi> {
|
||||
* @private
|
||||
* The current value (list of namespaces names) in the storage layer
|
||||
*/
|
||||
@computed private get selectedNamespaces(): string[] {
|
||||
@computed private get selectedNamespaces() {
|
||||
return this.dependencies.storage.get() ?? [];
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace, NamespaceApi> {
|
||||
/**
|
||||
* The list of selected namespace names (for filtering)
|
||||
*/
|
||||
@computed get contextNamespaces(): string[] {
|
||||
@computed get contextNamespaces() {
|
||||
if (!this.selectedNamespaces.length) {
|
||||
return this.allowedNamespaces; // show all namespaces when nothing selected
|
||||
}
|
||||
|
||||
@ -3,12 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import hostedClusterIdInjectable from "../../../../common/cluster-store/hosted-cluster-id.injectable";
|
||||
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { DockStore, DockTab } from "../dock/store";
|
||||
import { TabKind } from "../dock/store";
|
||||
import dockStoreInjectable from "../dock/store.injectable";
|
||||
import fse from "fs-extra";
|
||||
|
||||
const initialTabs: DockTab[] = [
|
||||
{ id: "terminal", kind: TabKind.TERMINAL, title: "Terminal", pinned: false },
|
||||
@ -24,20 +23,11 @@ describe("DockStore", () => {
|
||||
beforeEach(async () => {
|
||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
di.override(
|
||||
directoryForUserDataInjectable,
|
||||
() => "some-test-suite-specific-directory-for-user-data",
|
||||
);
|
||||
di.override(hostedClusterIdInjectable, () => "some-cluster-id");
|
||||
|
||||
await di.runSetups();
|
||||
|
||||
dockStore = di.inject(dockStoreInjectable);
|
||||
|
||||
await dockStore.whenReady;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fse.remove("some-test-suite-specific-directory-for-user-data");
|
||||
dockStore.closeAllTabs();
|
||||
});
|
||||
|
||||
it("closes tab and selects one from right", () => {
|
||||
|
||||
@ -4,8 +4,9 @@
|
||||
*/
|
||||
|
||||
import { action, observable, reaction } from "mobx";
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { StorageLayer } from "../../../utils";
|
||||
import { autoBind, toJS } from "../../../utils";
|
||||
import type { CreateStorage } from "../../../utils/create-storage/create-storage";
|
||||
import type { TabId } from "../dock/store";
|
||||
|
||||
export interface DockTabStoreOptions {
|
||||
@ -16,11 +17,11 @@ export interface DockTabStoreOptions {
|
||||
export type DockTabStorageState<T> = Record<TabId, T>;
|
||||
|
||||
interface DockTabStoreDependencies {
|
||||
createStorage: <T>(storageKey: string, options: DockTabStorageState<T>) => StorageHelper<DockTabStorageState<T>>;
|
||||
createStorage: CreateStorage;
|
||||
}
|
||||
|
||||
export class DockTabStore<T> {
|
||||
protected storage?: StorageHelper<DockTabStorageState<T>>;
|
||||
protected storage?: StorageLayer<DockTabStorageState<T>>;
|
||||
private data = observable.map<TabId, T>();
|
||||
|
||||
constructor(protected dependencies: DockTabStoreDependencies, protected options: DockTabStoreOptions) {
|
||||
@ -41,7 +42,7 @@ export class DockTabStore<T> {
|
||||
|
||||
// auto-save to local-storage
|
||||
if (storageKey) {
|
||||
const storage = this.storage = this.dependencies.createStorage<T>(storageKey, {});
|
||||
const storage = this.storage = this.dependencies.createStorage(storageKey, {});
|
||||
|
||||
storage.whenReady.then(() => {
|
||||
this.data.replace(storage.value);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
import * as uuid from "uuid";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction, runInAction } from "mobx";
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { StorageLayer } from "../../../utils";
|
||||
import { autoBind } from "../../../utils";
|
||||
import throttle from "lodash/throttle";
|
||||
|
||||
@ -99,7 +99,7 @@ export interface DockTabCloseEvent {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
readonly storage: StorageHelper<DockStorageState>;
|
||||
readonly storage: StorageLayer<DockStorageState>;
|
||||
readonly tabDataClearers: Record<TabKind, (tabId: TabId) => void>;
|
||||
readonly tabDataValidator: Partial<Record<TabKind, (tabId: TabId) => boolean>>;
|
||||
}
|
||||
|
||||
@ -3,11 +3,10 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { DockTabStorageState } from "../dock-tab-store/dock-tab.store";
|
||||
import { DockTabStore } from "../dock-tab-store/dock-tab.store";
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { TabId } from "../dock/store";
|
||||
import { logTabDataValidator } from "./log-tab-data.validator";
|
||||
import type { CreateStorage } from "../../../utils/create-storage/create-storage";
|
||||
|
||||
export interface LogTabOwnerRef {
|
||||
/**
|
||||
@ -58,7 +57,7 @@ export interface LogTabData {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
createStorage: <T>(storageKey: string, options: DockTabStorageState<T>) => StorageHelper<DockTabStorageState<T>>;
|
||||
createStorage: CreateStorage;
|
||||
}
|
||||
|
||||
export class LogTabStore extends DockTabStore<LogTabData> {
|
||||
|
||||
@ -8,7 +8,7 @@ import "./drawer.scss";
|
||||
import React from "react";
|
||||
import { clipboard } from "electron";
|
||||
import { createPortal } from "react-dom";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { cssNames, noop } from "../../utils";
|
||||
import { Icon } from "../icon";
|
||||
import type { AnimateName } from "../animate";
|
||||
@ -63,7 +63,7 @@ export const resizingAnchorProps: Record<DrawerPosition, [ResizeDirection, Resiz
|
||||
|
||||
interface Dependencies {
|
||||
history: History;
|
||||
drawerStorage: StorageHelper<{ width: number }>;
|
||||
drawerStorage: StorageLayer<{ width: number }>;
|
||||
}
|
||||
|
||||
class NonInjectedDrawer extends React.Component<DrawerProps & Dependencies & typeof defaultProps, State> {
|
||||
|
||||
@ -10,7 +10,7 @@ import React from "react";
|
||||
import { computed, makeObservable, untracked } from "mobx";
|
||||
import type { ConfirmDialogParams } from "../confirm-dialog";
|
||||
import type { TableCellProps, TableProps, TableRowProps, TableSortCallbacks } from "../table";
|
||||
import type { IClassName, SingleOrMany, StorageHelper } from "../../utils";
|
||||
import type { IClassName, SingleOrMany, StorageLayer } from "../../utils";
|
||||
import { autoBind, cssNames, noop } from "../../utils";
|
||||
import type { AddRemoveButtonsProps } from "../add-remove-buttons";
|
||||
import type { ItemObject } from "../../../common/item.store";
|
||||
@ -65,7 +65,7 @@ export type ItemListStore<I extends ItemObject, PreLoadStores extends boolean> =
|
||||
}) & (
|
||||
PreLoadStores extends true
|
||||
? {
|
||||
loadAll: (selectedNamespaces: string[]) => Promise<void>;
|
||||
loadAll: (selectedNamespaces: readonly string[]) => Promise<void>;
|
||||
}
|
||||
: {
|
||||
loadAll?: unknown;
|
||||
@ -149,9 +149,13 @@ const defaultProps: Partial<ItemListLayoutProps<ItemObject, true>> = {
|
||||
failedToLoadMessage: "Failed to load items",
|
||||
};
|
||||
|
||||
export interface ItemListLayoutStorage {
|
||||
showFilters: boolean;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
namespaceStore: NamespaceStore;
|
||||
itemListLayoutStorage: StorageHelper<{ showFilters: boolean }>;
|
||||
itemListLayoutStorage: StorageLayer<ItemListLayoutStorage>;
|
||||
}
|
||||
|
||||
@observer
|
||||
|
||||
@ -7,16 +7,13 @@ import styles from "./main-layout.module.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { ErrorBoundary } from "../error-boundary";
|
||||
import { ResizeDirection, ResizeGrowthDirection, ResizeSide, ResizingAnchor } from "../resizing-anchor";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type {
|
||||
SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable, {
|
||||
defaultSidebarWidth,
|
||||
} from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable, { defaultSidebarWidth } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
|
||||
export interface MainLayoutProps {
|
||||
sidebar: React.ReactNode;
|
||||
@ -31,7 +28,7 @@ export interface MainLayoutProps {
|
||||
*/
|
||||
|
||||
interface Dependencies {
|
||||
sidebarStorage: StorageHelper<SidebarStorageState>;
|
||||
sidebarStorage: StorageLayer<SidebarStorageState>;
|
||||
}
|
||||
|
||||
@observer
|
||||
|
||||
@ -7,20 +7,18 @@ import "./sidebar-item.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { observer } from "mobx-react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { Icon } from "../icon";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type {
|
||||
SidebarStorageState,
|
||||
} from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
sidebarStorage: StorageHelper<SidebarStorageState>;
|
||||
sidebarStorage: StorageLayer<SidebarStorageState>;
|
||||
}
|
||||
|
||||
export interface SidebarItemProps {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { StorageHelper } from "../../../utils";
|
||||
import type { StorageLayer } from "../../../utils";
|
||||
import type { TableSortParams } from "../table";
|
||||
|
||||
export interface TableStorageModel {
|
||||
@ -12,7 +12,7 @@ export interface TableStorageModel {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
storage: StorageHelper<TableStorageModel>;
|
||||
storage: StorageLayer<TableStorageModel>;
|
||||
}
|
||||
|
||||
export class TableModel {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import glob from "glob";
|
||||
import { memoize, noop } from "lodash/fp";
|
||||
import { isEqual, isPlainObject, memoize, noop } from "lodash/fp";
|
||||
import { createContainer } from "@ogre-tools/injectable";
|
||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import getValueFromRegisteredChannelInjectable from "./app-paths/get-value-from-registered-channel/get-value-from-registered-channel.injectable";
|
||||
@ -35,6 +35,10 @@ import { joinPathsFake } from "../common/test-utils/join-paths-fake";
|
||||
import hotbarStoreInjectable from "../common/hotbar-store.injectable";
|
||||
import terminalSpawningPoolInjectable from "./components/dock/terminal/terminal-spawning-pool.injectable";
|
||||
import hostedClusterIdInjectable from "../common/cluster-store/hosted-cluster-id.injectable";
|
||||
import createStorageInjectable from "./utils/create-storage/create-storage.injectable";
|
||||
import { observable, toJS } from "mobx";
|
||||
import type { Draft } from "immer";
|
||||
import { produce, isDraft } from "immer";
|
||||
|
||||
export const getDiForUnitTesting = (
|
||||
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
||||
@ -59,7 +63,41 @@ export const getDiForUnitTesting = (
|
||||
di.override(isWindowsInjectable, () => false);
|
||||
di.override(isLinuxInjectable, () => false);
|
||||
|
||||
di.override(terminalSpawningPoolInjectable, () => new HTMLElement());
|
||||
di.override(terminalSpawningPoolInjectable, () => document.createElement("div"));
|
||||
di.override(createStorageInjectable, () => function <MockT>(key: string, defaultValue: MockT) {
|
||||
const srcValue = observable.box(defaultValue);
|
||||
|
||||
return {
|
||||
get: () => srcValue.get(),
|
||||
isDefaultValue: val => isEqual(val, defaultValue),
|
||||
merge: (value: Partial<MockT> | ((draft: Draft<MockT>) => void | Partial<MockT>)) => {
|
||||
const nextValue = produce(toJS(srcValue.get()), (draft) => {
|
||||
|
||||
if (typeof value == "function") {
|
||||
const newValue = value(draft);
|
||||
|
||||
// merge returned plain objects from `value-as-callback` usage
|
||||
// otherwise `draft` can be just modified inside a callback without returning any value (void)
|
||||
if (newValue && !isDraft(newValue)) {
|
||||
Object.assign(draft, newValue);
|
||||
}
|
||||
} else if (isPlainObject(value)) {
|
||||
Object.assign(draft, value);
|
||||
}
|
||||
|
||||
return draft;
|
||||
});
|
||||
|
||||
srcValue.set(nextValue);
|
||||
},
|
||||
reset: () => srcValue.set(defaultValue),
|
||||
set: (val: MockT) => srcValue.set(val),
|
||||
get value() {
|
||||
return srcValue.get();
|
||||
},
|
||||
whenReady: Promise.resolve(),
|
||||
};
|
||||
});
|
||||
di.override(hostedClusterIdInjectable, () => undefined);
|
||||
|
||||
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
import { action, makeObservable, observable, reaction } from "mobx";
|
||||
import { ItemStore } from "../../../common/item.store";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { autoBind, disposer } from "../../utils";
|
||||
import type { ForwardedPort } from "../port-forward-item";
|
||||
import { PortForwardItem } from "../port-forward-item";
|
||||
@ -14,7 +14,7 @@ import { waitUntilFree } from "tcp-port-used";
|
||||
import logger from "../../../common/logger";
|
||||
|
||||
interface Dependencies {
|
||||
storage: StorageHelper<ForwardedPort[] | undefined>;
|
||||
storage: StorageLayer<ForwardedPort[] | undefined>;
|
||||
notifyErrorPortForwarding: (message: string) => void;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
import { observable, reaction } from "mobx";
|
||||
import { StorageHelper } from "../storageHelper";
|
||||
import { delay } from "../../../common/utils/delay";
|
||||
import { toJS } from "../../../common/utils";
|
||||
|
||||
interface StorageModel {
|
||||
[prop: string]: any /*json-serializable*/;
|
||||
@ -131,7 +132,7 @@ describe("renderer/utils/StorageHelper", () => {
|
||||
it("storage.get() is observable", () => {
|
||||
expect(storageHelper.get()).toEqual(defaultValue);
|
||||
|
||||
reaction(() => storageHelper.toJSON(), change => {
|
||||
reaction(() => toJS(storageHelper.get()), change => {
|
||||
observedChanges.push(change);
|
||||
});
|
||||
|
||||
|
||||
@ -15,20 +15,19 @@ import hostedClusterIdInjectable from "../../../common/cluster-store/hosted-clus
|
||||
const createStorageInjectable = getInjectable({
|
||||
id: "create-storage",
|
||||
|
||||
instantiate: (di) =>
|
||||
createStorage({
|
||||
storage: observable({
|
||||
initialized: false,
|
||||
loaded: false,
|
||||
data: {} as Record<string /*key*/, any>, // json-serializable
|
||||
}),
|
||||
readJsonFile: di.inject(readJsonFileInjectable),
|
||||
writeJsonFile: di.inject(writeJsonFileInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
directoryForLensLocalStorage: di.inject(directoryForLensLocalStorageInjectable),
|
||||
getAbsolutePath: di.inject(getAbsolutePathInjectable),
|
||||
hostedClusterId: di.inject(hostedClusterIdInjectable),
|
||||
instantiate: (di) => createStorage({
|
||||
storage: observable({
|
||||
initialized: false,
|
||||
loaded: false,
|
||||
data: {},
|
||||
}),
|
||||
readJsonFile: di.inject(readJsonFileInjectable),
|
||||
writeJsonFile: di.inject(writeJsonFileInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
directoryForLensLocalStorage: di.inject(directoryForLensLocalStorageInjectable),
|
||||
getAbsolutePath: di.inject(getAbsolutePathInjectable),
|
||||
hostedClusterId: di.inject(hostedClusterIdInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default createStorageInjectable;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
// Keeps window.localStorage state in external JSON-files.
|
||||
// Because app creates random port between restarts => storage session wiped out each time.
|
||||
import { comparer, reaction, toJS, when } from "mobx";
|
||||
import type { StorageLayer } from "../storageHelper";
|
||||
import { StorageHelper } from "../storageHelper";
|
||||
import { isTestEnv } from "../../../common/vars";
|
||||
import type { JsonObject, JsonValue } from "type-fest";
|
||||
@ -22,6 +23,8 @@ interface Dependencies {
|
||||
hostedClusterId: string | undefined;
|
||||
}
|
||||
|
||||
export type CreateStorage = <T>(key: string, defaultValue: T) => StorageLayer<T>;
|
||||
|
||||
/**
|
||||
* Creates a helper for saving data under the "key" intended for window.localStorage
|
||||
*/
|
||||
@ -33,7 +36,7 @@ export const createStorage = ({
|
||||
readJsonFile,
|
||||
writeJsonFile,
|
||||
hostedClusterId,
|
||||
}: Dependencies) => <T>(key: string, defaultValue: T) => {
|
||||
}: Dependencies): CreateStorage => (key, defaultValue) => {
|
||||
const { logPrefix } = StorageHelper;
|
||||
|
||||
if (!storage.initialized) {
|
||||
@ -78,7 +81,7 @@ export const createStorage = ({
|
||||
.catch(error => logger.error(`${logPrefix} Failed to initialize storage: ${error}`));
|
||||
}
|
||||
|
||||
return new StorageHelper<T>(key, {
|
||||
return new StorageHelper(key, {
|
||||
autoInit: true,
|
||||
defaultValue,
|
||||
storage: {
|
||||
|
||||
@ -24,7 +24,17 @@ export interface StorageHelperOptions<T> {
|
||||
defaultValue: T;
|
||||
}
|
||||
|
||||
export class StorageHelper<T> {
|
||||
export interface StorageLayer<T> {
|
||||
isDefaultValue(val: T): boolean;
|
||||
get(): T;
|
||||
readonly value: T;
|
||||
readonly whenReady: Promise<void>;
|
||||
set(value: T): void;
|
||||
reset(): void;
|
||||
merge(value: Partial<T> | ((draft: Draft<T>) => Partial<T> | void)): void;
|
||||
}
|
||||
|
||||
export class StorageHelper<T> implements StorageLayer<T> {
|
||||
static logPrefix = "[StorageHelper]:";
|
||||
readonly storage: StorageAdapter<T>;
|
||||
|
||||
@ -140,7 +150,7 @@ export class StorageHelper<T> {
|
||||
|
||||
@action
|
||||
merge(value: Partial<T> | ((draft: Draft<T>) => Partial<T> | void)) {
|
||||
const nextValue = produce<T>(this.toJSON(), (draft: Draft<T>) => {
|
||||
const nextValue = produce<T>(toJS(this.get()), (draft) => {
|
||||
|
||||
if (typeof value == "function") {
|
||||
const newValue = value(draft);
|
||||
@ -159,8 +169,4 @@ export class StorageHelper<T> {
|
||||
|
||||
this.set(nextValue);
|
||||
}
|
||||
|
||||
toJSON(): T {
|
||||
return toJS(this.get());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user