1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/packages/core/src/extensions/base-extension-store.ts
Sebastian Malton 49f0a1af9c
Remove BaseStore<T> and replace with composition of dependencies (#7002)
* Rename ExtensionStore -> BaseExtensionStore
- The name was too close to ExtensionsStore

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move ExtensionsStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move ClusterStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move UserStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Cleanup types to remove multiple cast locations

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move HotbarStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move WeblinkStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Move FileSystemProvisionerStore to new format

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Clean up impl and rename to better describe intent

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix remaining type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fully split apart the enabled extensions storage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fully split apart the clusters storage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fully split apart the hotbar storage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fully split apart the weblinks storage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fully split apart the user preferences storage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix crashing

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests and snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix integration test failures

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Improve typing to prevent errors in the future.

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Cleanup @k8slens/messaging and friends

- To fix type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix lint issue

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix global override not being complete enough causing tests to fail

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Bump memory for unit tests on CI

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Attempt to fix memory issue on CI again

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fixup test because of new injectables

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Upgrade Jest

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix unit tests falling over

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Back out jest config change

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove console log

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshot

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests by matching equality instead of snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests by forcing specific snapshot style

- Ubuntu CI seems to format arrays in snapshots differently than macOS locally

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2023-03-28 17:54:25 +03:00

104 lines
3.8 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import * as path from "path";
import type { LensExtension } from "./lens-extension";
import type { StaticThis } from "../common/utils/singleton";
import { getOrInsertWith } from "@k8slens/utilities";
import { getLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import type { PersistentStorage, PersistentStorageParams } from "../common/persistent-storage/create.injectable";
import createPersistentStorageInjectable from "../common/persistent-storage/create.injectable";
import directoryForUserDataInjectable from "../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import assert from "assert";
import type { Options } from "conf";
import type { Migrations } from "../common/persistent-storage/migrations.injectable";
export interface ExtensionStoreParams<T extends object> extends Omit<PersistentStorageParams<T>, "migrations" | "cwd" | "fromStore" | "toJSON"> {
migrations?: Options<T>["migrations"];
cwd?: string;
}
export abstract class BaseExtensionStore<T extends object> {
private static readonly instances = new WeakMap<object, any>();
/**
* @deprecated This is a form of global shared state. Just call `new Store(...)`
*/
static createInstance<T, R extends any[]>(this: StaticThis<T, R>, ...args: R): T {
return getOrInsertWith(BaseExtensionStore.instances, this, () => new this(...args)) as T;
}
/**
* @deprecated This is a form of global shared state. Just call `new Store(...)`
*/
static getInstance<T, R extends any[]>(this: StaticThis<T, R>, strict?: true): T;
static getInstance<T, R extends any[]>(this: StaticThis<T, R>, strict: false): T | undefined;
static getInstance<T, R extends any[]>(this: StaticThis<T, R>, strict = true): T | undefined {
if (!BaseExtensionStore.instances.has(this) && strict) {
throw new TypeError(`instance of ${this.name} is not created`);
}
return BaseExtensionStore.instances.get(this) as (T | undefined);
}
protected persistentStorage?: PersistentStorage;
private readonly dependencies = (() => {
const di = getLegacyGlobalDiForExtensionApi();
return {
createPersistentStorage: di.inject(createPersistentStorageInjectable),
directoryForUserData: di.inject(directoryForUserDataInjectable),
} as const;
})();
constructor(protected readonly rawParams: ExtensionStoreParams<T>) { }
/**
* @deprecated This is a form of global shared state. Just call `new Store(...)`
*/
static resetInstance() {
BaseExtensionStore.instances.delete(this);
}
protected extension?: LensExtension;
loadExtension(extension: LensExtension) {
this.extension = extension;
const {
projectVersion = this.extension.version,
cwd: _cwd, // This is ignored to maintain backwards compatibility
migrations = {},
...params
} = this.rawParams;
this.persistentStorage = this.dependencies.createPersistentStorage({
...params,
cwd: this.cwd(),
projectVersion,
migrations: migrations as Migrations,
fromStore: (data) => this.fromStore(data),
toJSON: () => this.toJSON(),
});
this.persistentStorage.loadAndStartSyncing();
}
/**
* @deprecated Never use this method. Instead call {@link BaseExtensionStore.loadExtension}
*/
load() {
this.persistentStorage?.loadAndStartSyncing();
}
protected cwd() {
assert(this.extension, "cwd can only be called in loadExtension");
return this.rawParams.cwd ?? path.join(this.dependencies.directoryForUserData, "extension-store", this.extension.storeName);
}
abstract fromStore(data: Partial<T>): void;
abstract toJSON(): T;
}