mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Extract BaseStore deps into constructor argument
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
1c277a96fb
commit
3dce6f916e
@ -4,12 +4,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import mockFs from "mock-fs";
|
import mockFs from "mock-fs";
|
||||||
|
import type { BaseStoreDependencies } from "../base-store";
|
||||||
import { BaseStore } from "../base-store";
|
import { BaseStore } from "../base-store";
|
||||||
import { action, comparer, makeObservable, observable, toJS } from "mobx";
|
import { action, comparer, makeObservable, observable, toJS } from "mobx";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
||||||
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
||||||
|
|
||||||
jest.mock("electron", () => ({
|
jest.mock("electron", () => ({
|
||||||
ipcMain: {
|
ipcMain: {
|
||||||
@ -29,8 +32,8 @@ class TestStore extends BaseStore<TestStoreModel> {
|
|||||||
@observable b = "";
|
@observable b = "";
|
||||||
@observable c = "";
|
@observable c = "";
|
||||||
|
|
||||||
constructor() {
|
constructor(deps: BaseStoreDependencies) {
|
||||||
super({
|
super(deps, {
|
||||||
configName: "test-store",
|
configName: "test-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
syncOptions: {
|
syncOptions: {
|
||||||
@ -90,7 +93,12 @@ describe("BaseStore", () => {
|
|||||||
|
|
||||||
mockFs(mockOpts);
|
mockFs(mockOpts);
|
||||||
|
|
||||||
store = new TestStore();
|
store = new TestStore({
|
||||||
|
directoryForUserData: mainDi.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: mainDi.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: mainDi.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: mainDi.inject(storeMigrationVersionInjectable),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
@ -10,22 +10,26 @@ import { ipcMain, ipcRenderer } from "electron";
|
|||||||
import type { IEqualsComparer } from "mobx";
|
import type { IEqualsComparer } from "mobx";
|
||||||
import { makeObservable, reaction, runInAction } from "mobx";
|
import { makeObservable, reaction, runInAction } from "mobx";
|
||||||
import type { Disposer } from "./utils";
|
import type { Disposer } from "./utils";
|
||||||
import { toJS } from "./utils";
|
import { isPromiseLike, toJS } from "./utils";
|
||||||
import logger from "../main/logger";
|
|
||||||
import { broadcastMessage, ipcMainOn, ipcRendererOn } from "./ipc";
|
import { broadcastMessage, ipcMainOn, ipcRendererOn } from "./ipc";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import { isTestEnv } from "./vars";
|
|
||||||
import { kebabCase } from "lodash";
|
import { kebabCase } from "lodash";
|
||||||
import { getLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import type { GetConfigurationFileModel } from "./get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
import directoryForUserDataInjectable from "./app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import type { Logger } from "./logger";
|
||||||
import getConfigurationFileModelInjectable from "./get-configuration-file-model/get-configuration-file-model.injectable";
|
|
||||||
import storeMigrationVersionInjectable from "./vars/store-migration-version.injectable";
|
|
||||||
|
|
||||||
export interface BaseStoreParams<T> extends ConfOptions<T> {
|
export interface BaseStoreParams<T> extends ConfOptions<T> {
|
||||||
syncOptions?: {
|
syncOptions?: {
|
||||||
fireImmediately?: boolean;
|
fireImmediately?: boolean;
|
||||||
equals?: IEqualsComparer<T>;
|
equals?: IEqualsComparer<T>;
|
||||||
};
|
};
|
||||||
|
configName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseStoreDependencies {
|
||||||
|
readonly logger: Logger;
|
||||||
|
readonly storeMigrationVersion: string;
|
||||||
|
readonly directoryForUserData: string;
|
||||||
|
getConfigurationFileModel: GetConfigurationFileModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,13 +39,18 @@ export abstract class BaseStore<T extends object> {
|
|||||||
protected storeConfig?: Config<T>;
|
protected storeConfig?: Config<T>;
|
||||||
protected syncDisposers: Disposer[] = [];
|
protected syncDisposers: Disposer[] = [];
|
||||||
|
|
||||||
readonly displayName: string = this.constructor.name;
|
readonly displayName: string;
|
||||||
|
|
||||||
protected constructor(protected params: BaseStoreParams<T>) {
|
protected constructor(
|
||||||
|
protected readonly dependencies: BaseStoreDependencies,
|
||||||
|
protected readonly params: BaseStoreParams<T>,
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
|
|
||||||
|
this.displayName = this.params.configName;
|
||||||
|
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
params.migrations = undefined; // don't run migrations on renderer
|
this.params.migrations = undefined; // don't run migrations on renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,32 +58,22 @@ export abstract class BaseStore<T extends object> {
|
|||||||
* This must be called after the last child's constructor is finished (or just before it finishes)
|
* This must be called after the last child's constructor is finished (or just before it finishes)
|
||||||
*/
|
*/
|
||||||
load() {
|
load() {
|
||||||
if (!isTestEnv) {
|
this.dependencies.logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADING ...`);
|
||||||
logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADING from ${this.path} ...`);
|
this.storeConfig = this.dependencies.getConfigurationFileModel({
|
||||||
}
|
|
||||||
|
|
||||||
const di = getLegacyGlobalDiForExtensionApi();
|
|
||||||
|
|
||||||
const getConfigurationFileModel = di.inject(getConfigurationFileModelInjectable);
|
|
||||||
|
|
||||||
this.storeConfig = getConfigurationFileModel({
|
|
||||||
projectName: "lens",
|
projectName: "lens",
|
||||||
projectVersion: di.inject(storeMigrationVersionInjectable),
|
projectVersion: this.dependencies.storeMigrationVersion,
|
||||||
cwd: this.cwd(),
|
cwd: this.cwd(),
|
||||||
...this.params,
|
...this.params,
|
||||||
});
|
});
|
||||||
|
|
||||||
const res: any = this.fromStore(this.storeConfig.store);
|
const res = this.fromStore(this.storeConfig.store);
|
||||||
|
|
||||||
if (res instanceof Promise || (typeof res === "object" && res && typeof res.then === "function")) {
|
if (isPromiseLike(res)) {
|
||||||
console.error(`${this.displayName} extends BaseStore<T>'s fromStore method returns a Promise or promise-like object. This is an error and must be fixed.`);
|
this.dependencies.logger.error(`${this.displayName} extends BaseStore<T>'s fromStore method returns a Promise or promise-like object. This is an error and must be fixed.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.enableSync();
|
this.enableSync();
|
||||||
|
this.dependencies.logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADED from ${this.path}`);
|
||||||
if (!isTestEnv) {
|
|
||||||
logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADED from ${this.path}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
@ -94,13 +93,11 @@ export abstract class BaseStore<T extends object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected cwd() {
|
protected cwd() {
|
||||||
const di = getLegacyGlobalDiForExtensionApi();
|
return this.dependencies.directoryForUserData;
|
||||||
|
|
||||||
return di.inject(directoryForUserDataInjectable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected saveToFile(model: T) {
|
protected saveToFile(model: T) {
|
||||||
logger.info(`[STORE]: SAVING ${this.path}`);
|
this.dependencies.logger.info(`[STORE]: SAVING ${this.path}`);
|
||||||
|
|
||||||
// todo: update when fixed https://github.com/sindresorhus/conf/issues/114
|
// todo: update when fixed https://github.com/sindresorhus/conf/issues/114
|
||||||
if (this.storeConfig) {
|
if (this.storeConfig) {
|
||||||
@ -121,14 +118,14 @@ export abstract class BaseStore<T extends object> {
|
|||||||
|
|
||||||
if (ipcMain) {
|
if (ipcMain) {
|
||||||
this.syncDisposers.push(ipcMainOn(this.syncMainChannel, (event, model: T) => {
|
this.syncDisposers.push(ipcMainOn(this.syncMainChannel, (event, model: T) => {
|
||||||
logger.silly(`[STORE]: SYNC ${this.name} from renderer`, { model });
|
this.dependencies.logger.silly(`[STORE]: SYNC ${this.name} from renderer`, { model });
|
||||||
this.onSync(model);
|
this.onSync(model);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
this.syncDisposers.push(ipcRendererOn(this.syncRendererChannel, (event, model: T) => {
|
this.syncDisposers.push(ipcRendererOn(this.syncRendererChannel, (event, model: T) => {
|
||||||
logger.silly(`[STORE]: SYNC ${this.name} from main`, { model });
|
this.dependencies.logger.silly(`[STORE]: SYNC ${this.name} from main`, { model });
|
||||||
this.onSyncFromMain(model);
|
this.onSyncFromMain(model);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,10 @@ import { ClusterStore } from "./cluster-store";
|
|||||||
import { createClusterInjectionToken } from "../cluster/create-cluster-injection-token";
|
import { createClusterInjectionToken } from "../cluster/create-cluster-injection-token";
|
||||||
import readClusterConfigSyncInjectable from "./read-cluster-config.injectable";
|
import readClusterConfigSyncInjectable from "./read-cluster-config.injectable";
|
||||||
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
||||||
|
|
||||||
const clusterStoreInjectable = getInjectable({
|
const clusterStoreInjectable = getInjectable({
|
||||||
id: "cluster-store",
|
id: "cluster-store",
|
||||||
@ -15,9 +19,11 @@ const clusterStoreInjectable = getInjectable({
|
|||||||
createCluster: di.inject(createClusterInjectionToken),
|
createCluster: di.inject(createClusterInjectionToken),
|
||||||
readClusterConfigSync: di.inject(readClusterConfigSyncInjectable),
|
readClusterConfigSync: di.inject(readClusterConfigSyncInjectable),
|
||||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
causesSideEffects: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default clusterStoreInjectable;
|
export default clusterStoreInjectable;
|
||||||
|
|||||||
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
import { ipcMain, ipcRenderer, webFrame } from "electron";
|
import { ipcMain, ipcRenderer, webFrame } from "electron";
|
||||||
import { action, comparer, computed, makeObservable, observable, reaction } from "mobx";
|
import { action, comparer, computed, makeObservable, observable, reaction } from "mobx";
|
||||||
|
import type { BaseStoreDependencies } from "../base-store";
|
||||||
import { BaseStore } from "../base-store";
|
import { BaseStore } from "../base-store";
|
||||||
import { Cluster } from "../cluster/cluster";
|
import { Cluster } from "../cluster/cluster";
|
||||||
import migrations from "../../migrations/cluster-store";
|
import migrations from "../../migrations/cluster-store";
|
||||||
import logger from "../../main/logger";
|
|
||||||
import { disposer, toJS } from "../utils";
|
import { disposer, toJS } from "../utils";
|
||||||
import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types";
|
import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types";
|
||||||
import { requestInitialClusterStates } from "../../renderer/ipc";
|
import { requestInitialClusterStates } from "../../renderer/ipc";
|
||||||
@ -21,7 +21,7 @@ export interface ClusterStoreModel {
|
|||||||
clusters?: ClusterModel[];
|
clusters?: ClusterModel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies extends BaseStoreDependencies {
|
||||||
createCluster: CreateCluster;
|
createCluster: CreateCluster;
|
||||||
readClusterConfigSync: ReadClusterConfigSync;
|
readClusterConfigSync: ReadClusterConfigSync;
|
||||||
emitAppEvent: EmitAppEvent;
|
emitAppEvent: EmitAppEvent;
|
||||||
@ -29,12 +29,12 @@ interface Dependencies {
|
|||||||
|
|
||||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||||
readonly displayName = "ClusterStore";
|
readonly displayName = "ClusterStore";
|
||||||
clusters = observable.map<ClusterId, Cluster>();
|
readonly clusters = observable.map<ClusterId, Cluster>();
|
||||||
|
|
||||||
protected disposer = disposer();
|
protected disposer = disposer();
|
||||||
|
|
||||||
constructor(private readonly dependencies: Dependencies) {
|
constructor(protected readonly dependencies: Dependencies) {
|
||||||
super({
|
super(dependencies, {
|
||||||
configName: "lens-cluster-store",
|
configName: "lens-cluster-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
syncOptions: {
|
syncOptions: {
|
||||||
@ -49,7 +49,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadInitialOnRenderer() {
|
async loadInitialOnRenderer() {
|
||||||
logger.info("[CLUSTER-STORE] requesting initial state sync");
|
this.dependencies.logger.info("[CLUSTER-STORE] requesting initial state sync");
|
||||||
|
|
||||||
for (const { id, state } of await requestInitialClusterStates()) {
|
for (const { id, state } of await requestInitialClusterStates()) {
|
||||||
this.getById(id)?.setState(state);
|
this.getById(id)?.setState(state);
|
||||||
@ -65,7 +65,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerIpcListener() {
|
registerIpcListener() {
|
||||||
logger.info(`[CLUSTER-STORE] start to listen (${webFrame.routingId})`);
|
this.dependencies.logger.info(`[CLUSTER-STORE] start to listen (${webFrame.routingId})`);
|
||||||
const ipc = ipcMain ?? ipcRenderer;
|
const ipc = ipcMain ?? ipcRenderer;
|
||||||
|
|
||||||
ipc?.on("cluster:state", (event, clusterId: ClusterId, state: ClusterState) => {
|
ipc?.on("cluster:state", (event, clusterId: ClusterId, state: ClusterState) => {
|
||||||
@ -139,7 +139,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
}
|
}
|
||||||
newClusters.set(clusterModel.id, cluster);
|
newClusters.set(clusterModel.id, cluster);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(`[CLUSTER-STORE]: Failed to update/create a cluster: ${error}`);
|
this.dependencies.logger.warn(`[CLUSTER-STORE]: Failed to update/create a cluster: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,13 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import Config from "conf";
|
import Config from "conf";
|
||||||
import type { BaseStoreParams } from "../base-store";
|
import type { Options as ConfOptions } from "conf/dist/source/types";
|
||||||
|
|
||||||
|
export type GetConfigurationFileModel = <T extends object>(content: ConfOptions<T>) => Config<T>;
|
||||||
|
|
||||||
const getConfigurationFileModelInjectable = getInjectable({
|
const getConfigurationFileModelInjectable = getInjectable({
|
||||||
id: "get-configuration-file-model",
|
id: "get-configuration-file-model",
|
||||||
instantiate: () => <T extends object>(content: BaseStoreParams<T>) => new Config(content),
|
instantiate: (): GetConfigurationFileModel => (content) => new Config(content),
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,9 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import catalogCatalogEntityInjectable from "../catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
|
import catalogCatalogEntityInjectable from "../catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
|
||||||
import { HotbarStore } from "./store";
|
import { HotbarStore } from "./store";
|
||||||
import loggerInjectable from "../logger.injectable";
|
import loggerInjectable from "../logger.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
||||||
|
|
||||||
const hotbarStoreInjectable = getInjectable({
|
const hotbarStoreInjectable = getInjectable({
|
||||||
id: "hotbar-store",
|
id: "hotbar-store",
|
||||||
@ -13,9 +16,10 @@ const hotbarStoreInjectable = getInjectable({
|
|||||||
instantiate: (di) => new HotbarStore({
|
instantiate: (di) => new HotbarStore({
|
||||||
catalogCatalogEntity: di.inject(catalogCatalogEntityInjectable),
|
catalogCatalogEntity: di.inject(catalogCatalogEntityInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
causesSideEffects: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default hotbarStoreInjectable;
|
export default hotbarStoreInjectable;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { action, comparer, observable, makeObservable, computed } from "mobx";
|
import { action, comparer, observable, makeObservable, computed } from "mobx";
|
||||||
|
import type { BaseStoreDependencies } from "../base-store";
|
||||||
import { BaseStore } from "../base-store";
|
import { BaseStore } from "../base-store";
|
||||||
import migrations from "../../migrations/hotbar-store";
|
import migrations from "../../migrations/hotbar-store";
|
||||||
import { toJS } from "../utils";
|
import { toJS } from "../utils";
|
||||||
@ -21,7 +22,7 @@ export interface HotbarStoreModel {
|
|||||||
activeHotbarId: string;
|
activeHotbarId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies extends BaseStoreDependencies {
|
||||||
readonly catalogCatalogEntity: GeneralEntity;
|
readonly catalogCatalogEntity: GeneralEntity;
|
||||||
readonly logger: Logger;
|
readonly logger: Logger;
|
||||||
}
|
}
|
||||||
@ -31,8 +32,8 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
|||||||
@observable hotbars: Hotbar[] = [];
|
@observable hotbars: Hotbar[] = [];
|
||||||
@observable private _activeHotbarId!: string;
|
@observable private _activeHotbarId!: string;
|
||||||
|
|
||||||
constructor(private readonly dependencies: Dependencies) {
|
constructor(protected readonly dependencies: Dependencies) {
|
||||||
super({
|
super(dependencies, {
|
||||||
configName: "lens-hotbar-store",
|
configName: "lens-hotbar-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
syncOptions: {
|
syncOptions: {
|
||||||
@ -148,7 +149,7 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
|||||||
const index = this.hotbars.findIndex((hotbar) => hotbar.id === id);
|
const index = this.hotbars.findIndex((hotbar) => hotbar.id === id);
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return void console.warn(
|
return this.dependencies.logger.warn(
|
||||||
`[HOTBAR-STORE]: cannot setHotbarName: unknown id`,
|
`[HOTBAR-STORE]: cannot setHotbarName: unknown id`,
|
||||||
{ id },
|
{ id },
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,6 +6,10 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { UserStore } from "./user-store";
|
import { UserStore } from "./user-store";
|
||||||
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||||
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
||||||
|
|
||||||
const userStoreInjectable = getInjectable({
|
const userStoreInjectable = getInjectable({
|
||||||
id: "user-store",
|
id: "user-store",
|
||||||
@ -13,9 +17,11 @@ const userStoreInjectable = getInjectable({
|
|||||||
instantiate: (di) => new UserStore({
|
instantiate: (di) => new UserStore({
|
||||||
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
||||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
causesSideEffects: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default userStoreInjectable;
|
export default userStoreInjectable;
|
||||||
|
|||||||
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import { action, observable, reaction, makeObservable, isObservableArray, isObservableSet, isObservableMap } from "mobx";
|
import { action, observable, reaction, makeObservable, isObservableArray, isObservableSet, isObservableMap } from "mobx";
|
||||||
|
import type { BaseStoreDependencies } from "../base-store";
|
||||||
import { BaseStore } from "../base-store";
|
import { BaseStore } from "../base-store";
|
||||||
import migrations from "../../migrations/user-store";
|
import migrations from "../../migrations/user-store";
|
||||||
import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
||||||
import { DESCRIPTORS } from "./preferences-helpers";
|
import { DESCRIPTORS } from "./preferences-helpers";
|
||||||
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
||||||
import logger from "../../main/logger";
|
|
||||||
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
// TODO: Remove coupling with Feature
|
// TODO: Remove coupling with Feature
|
||||||
@ -22,7 +22,7 @@ export interface UserStoreModel {
|
|||||||
preferences: UserPreferencesModel;
|
preferences: UserPreferencesModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies extends BaseStoreDependencies {
|
||||||
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
||||||
emitAppEvent: EmitAppEvent;
|
emitAppEvent: EmitAppEvent;
|
||||||
}
|
}
|
||||||
@ -30,8 +30,8 @@ interface Dependencies {
|
|||||||
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
||||||
readonly displayName = "UserStore";
|
readonly displayName = "UserStore";
|
||||||
|
|
||||||
constructor(private readonly dependencies: Dependencies) {
|
constructor(protected readonly dependencies: Dependencies) {
|
||||||
super({
|
super(dependencies, {
|
||||||
configName: "lens-user-store",
|
configName: "lens-user-store",
|
||||||
migrations,
|
migrations,
|
||||||
});
|
});
|
||||||
@ -138,7 +138,7 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
protected fromStore({ lastSeenAppVersion, preferences }: Partial<UserStoreModel> = {}) {
|
protected fromStore({ lastSeenAppVersion, preferences }: Partial<UserStoreModel> = {}) {
|
||||||
logger.debug("UserStore.fromStore()", { lastSeenAppVersion, preferences });
|
this.dependencies.logger.debug("UserStore.fromStore()", { lastSeenAppVersion, preferences });
|
||||||
|
|
||||||
if (lastSeenAppVersion) {
|
if (lastSeenAppVersion) {
|
||||||
this.lastSeenAppVersion = lastSeenAppVersion;
|
this.lastSeenAppVersion = lastSeenAppVersion;
|
||||||
|
|||||||
@ -123,6 +123,10 @@ export function isDefined<T>(val: T | undefined | null): val is T {
|
|||||||
return val != null;
|
return val != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFunction(val: unknown): val is (...args: unknown[]) => unknown {
|
||||||
|
return typeof val === "function";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the value in the second position is non-nullable
|
* Checks if the value in the second position is non-nullable
|
||||||
*/
|
*/
|
||||||
@ -146,6 +150,15 @@ export function hasDefiniteField<Field extends keyof T, T>(field: Field): (val:
|
|||||||
return (val): val is T & { [f in Field]-?: NonNullable<T[Field]> } => val[field] != null;
|
return (val): val is T & { [f in Field]-?: NonNullable<T[Field]> } => val[field] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isPromiseLike(res: unknown): res is (Promise<unknown> | { then: () => unknown }) {
|
||||||
|
if (res instanceof Promise) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isObject(res)
|
||||||
|
&& hasTypedProperty(res, "then", isFunction);
|
||||||
|
}
|
||||||
|
|
||||||
export function isPromiseSettledRejected<T>(result: PromiseSettledResult<T>): result is PromiseRejectedResult {
|
export function isPromiseSettledRejected<T>(result: PromiseSettledResult<T>): result is PromiseRejectedResult {
|
||||||
return result.status === "rejected";
|
return result.status === "rejected";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,20 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import directoryForUserDataInjectable from "./app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "./get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "./logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "./vars/store-migration-version.injectable";
|
||||||
import { WeblinkStore } from "./weblink-store";
|
import { WeblinkStore } from "./weblink-store";
|
||||||
|
|
||||||
const weblinkStoreInjectable = getInjectable({
|
const weblinkStoreInjectable = getInjectable({
|
||||||
id: "weblink-store",
|
id: "weblink-store",
|
||||||
instantiate: () => new WeblinkStore(),
|
instantiate: (di) => new WeblinkStore({
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default weblinkStoreInjectable;
|
export default weblinkStoreInjectable;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { action, comparer, observable, makeObservable } from "mobx";
|
import { action, comparer, observable, makeObservable } from "mobx";
|
||||||
|
import type { BaseStoreDependencies } from "./base-store";
|
||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import migrations from "../migrations/weblinks-store";
|
import migrations from "../migrations/weblinks-store";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
@ -30,8 +31,8 @@ export class WeblinkStore extends BaseStore<WeblinkStoreModel> {
|
|||||||
readonly displayName = "WeblinkStore";
|
readonly displayName = "WeblinkStore";
|
||||||
@observable weblinks: WeblinkData[] = [];
|
@observable weblinks: WeblinkData[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor(deps: BaseStoreDependencies) {
|
||||||
super({
|
super(deps, {
|
||||||
configName: "lens-weblink-store",
|
configName: "lens-weblink-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
syncOptions: {
|
syncOptions: {
|
||||||
|
|||||||
@ -8,6 +8,10 @@ import directoryForExtensionDataInjectable from "./directory-for-extension-data.
|
|||||||
import ensureDirectoryInjectable from "../../../common/fs/ensure-dir.injectable";
|
import ensureDirectoryInjectable from "../../../common/fs/ensure-dir.injectable";
|
||||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||||
import randomBytesInjectable from "../../../common/utils/random-bytes.injectable";
|
import randomBytesInjectable from "../../../common/utils/random-bytes.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../../../common/vars/store-migration-version.injectable";
|
||||||
|
|
||||||
const fileSystemProvisionerStoreInjectable = getInjectable({
|
const fileSystemProvisionerStoreInjectable = getInjectable({
|
||||||
id: "file-system-provisioner-store",
|
id: "file-system-provisioner-store",
|
||||||
@ -17,6 +21,10 @@ const fileSystemProvisionerStoreInjectable = getInjectable({
|
|||||||
ensureDirectory: di.inject(ensureDirectoryInjectable),
|
ensureDirectory: di.inject(ensureDirectoryInjectable),
|
||||||
joinPaths: di.inject(joinPathsInjectable),
|
joinPaths: di.inject(joinPathsInjectable),
|
||||||
randomBytes: di.inject(randomBytesInjectable),
|
randomBytes: di.inject(randomBytesInjectable),
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import { SHA256 } from "crypto-js";
|
import { SHA256 } from "crypto-js";
|
||||||
import { action, makeObservable, observable } from "mobx";
|
import { action, makeObservable, observable } from "mobx";
|
||||||
|
import type { BaseStoreDependencies } from "../../../common/base-store";
|
||||||
import { BaseStore } from "../../../common/base-store";
|
import { BaseStore } from "../../../common/base-store";
|
||||||
import type { LensExtensionId } from "../../lens-extension";
|
import type { LensExtensionId } from "../../lens-extension";
|
||||||
import { getOrInsertWithAsync, toJS } from "../../../common/utils";
|
import { getOrInsertWithAsync, toJS } from "../../../common/utils";
|
||||||
@ -16,7 +17,7 @@ interface FSProvisionModel {
|
|||||||
extensions: Record<string, string>; // extension names to paths
|
extensions: Record<string, string>; // extension names to paths
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies extends BaseStoreDependencies {
|
||||||
readonly directoryForExtensionData: string;
|
readonly directoryForExtensionData: string;
|
||||||
ensureDirectory: EnsureDirectory;
|
ensureDirectory: EnsureDirectory;
|
||||||
joinPaths: JoinPaths;
|
joinPaths: JoinPaths;
|
||||||
@ -27,8 +28,8 @@ export class FileSystemProvisionerStore extends BaseStore<FSProvisionModel> {
|
|||||||
readonly displayName = "FilesystemProvisionerStore";
|
readonly displayName = "FilesystemProvisionerStore";
|
||||||
readonly registeredExtensions = observable.map<LensExtensionId, string>();
|
readonly registeredExtensions = observable.map<LensExtensionId, string>();
|
||||||
|
|
||||||
constructor(private readonly dependencies: Dependencies) {
|
constructor(protected readonly dependencies: Dependencies) {
|
||||||
super({
|
super(dependencies, {
|
||||||
configName: "lens-filesystem-provisioner-store",
|
configName: "lens-filesystem-provisioner-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,12 +3,18 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { BaseStoreParams } from "../common/base-store";
|
||||||
import { BaseStore } from "../common/base-store";
|
import { BaseStore } from "../common/base-store";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import type { LensExtension } from "./lens-extension";
|
import type { LensExtension } from "./lens-extension";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import type { StaticThis } from "../common/utils";
|
import type { StaticThis } from "../common/utils";
|
||||||
import { getOrInsertWith } from "../common/utils";
|
import { getOrInsertWith } from "../common/utils";
|
||||||
|
import { getLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
|
import directoryForUserDataInjectable from "../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../common/logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../common/vars/store-migration-version.injectable";
|
||||||
|
|
||||||
export abstract class ExtensionStore<T extends object> extends BaseStore<T> {
|
export abstract class ExtensionStore<T extends object> extends BaseStore<T> {
|
||||||
private static readonly instances = new WeakMap<object, ExtensionStore<object>>();
|
private static readonly instances = new WeakMap<object, ExtensionStore<object>>();
|
||||||
@ -33,6 +39,17 @@ export abstract class ExtensionStore<T extends object> extends BaseStore<T> {
|
|||||||
return ExtensionStore.instances.get(this) as (T | undefined);
|
return ExtensionStore.instances.get(this) as (T | undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(params: BaseStoreParams<T>) {
|
||||||
|
const di = getLegacyGlobalDiForExtensionApi();
|
||||||
|
|
||||||
|
super({
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
|
}, params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated This is a form of global shared state. Just call `new Store(...)`
|
* @deprecated This is a form of global shared state. Just call `new Store(...)`
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -3,11 +3,20 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import getConfigurationFileModelInjectable from "../../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
||||||
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
|
import storeMigrationVersionInjectable from "../../common/vars/store-migration-version.injectable";
|
||||||
import { ExtensionsStore } from "./extensions-store";
|
import { ExtensionsStore } from "./extensions-store";
|
||||||
|
|
||||||
const extensionsStoreInjectable = getInjectable({
|
const extensionsStoreInjectable = getInjectable({
|
||||||
id: "extensions-store",
|
id: "extensions-store",
|
||||||
instantiate: () => new ExtensionsStore(),
|
instantiate: (di) => new ExtensionsStore({
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default extensionsStoreInjectable;
|
export default extensionsStoreInjectable;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
import type { LensExtensionId } from "../lens-extension";
|
import type { LensExtensionId } from "../lens-extension";
|
||||||
import { action, computed, makeObservable, observable } from "mobx";
|
import { action, computed, makeObservable, observable } from "mobx";
|
||||||
import { toJS } from "../../common/utils";
|
import { toJS } from "../../common/utils";
|
||||||
|
import type { BaseStoreDependencies } from "../../common/base-store";
|
||||||
import { BaseStore } from "../../common/base-store";
|
import { BaseStore } from "../../common/base-store";
|
||||||
|
|
||||||
export interface LensExtensionsStoreModel {
|
export interface LensExtensionsStoreModel {
|
||||||
@ -24,8 +25,8 @@ export interface IsEnabledExtensionDescriptor {
|
|||||||
|
|
||||||
export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
||||||
readonly displayName = "ExtensionsStore";
|
readonly displayName = "ExtensionsStore";
|
||||||
constructor() {
|
constructor(deps: BaseStoreDependencies) {
|
||||||
super({
|
super(deps, {
|
||||||
configName: "lens-extensions",
|
configName: "lens-extensions",
|
||||||
});
|
});
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user