mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Move ExtensionsStore to new format
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
42fd7839fa
commit
bd594e12d5
@ -4,9 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type Config from "conf";
|
import type Config from "conf";
|
||||||
import type { Migrations, Options as ConfOptions } from "conf/dist/source/types";
|
import type { Options as ConfOptions } from "conf/dist/source/types";
|
||||||
import type { IEqualsComparer } from "mobx";
|
import type { IEqualsComparer } from "mobx";
|
||||||
import { makeObservable, reaction } from "mobx";
|
import { reaction } from "mobx";
|
||||||
import { disposer, isPromiseLike } from "@k8slens/utilities";
|
import { disposer, isPromiseLike } from "@k8slens/utilities";
|
||||||
import { broadcastMessage } from "../ipc";
|
import { broadcastMessage } from "../ipc";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
@ -18,12 +18,31 @@ import type { GetBasenameOfPath } from "../path/get-basename.injectable";
|
|||||||
import type { EnlistMessageChannelListener } from "@k8slens/messaging";
|
import type { EnlistMessageChannelListener } from "@k8slens/messaging";
|
||||||
import { toJS } from "../utils";
|
import { toJS } from "../utils";
|
||||||
|
|
||||||
export interface BaseStoreParams<T> extends Omit<ConfOptions<T>, "migrations"> {
|
export interface BaseStoreParams<T> extends ConfOptions<T> {
|
||||||
syncOptions?: {
|
syncOptions?: {
|
||||||
fireImmediately?: boolean;
|
fireImmediately?: boolean;
|
||||||
equals?: IEqualsComparer<T>;
|
equals?: IEqualsComparer<T>;
|
||||||
};
|
};
|
||||||
configName: string;
|
readonly configName: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fromStore is called internally when a child class syncs with the file
|
||||||
|
* system.
|
||||||
|
*
|
||||||
|
* Note: This function **must** be synchronous.
|
||||||
|
*
|
||||||
|
* @param data the parsed information read from the stored JSON file
|
||||||
|
*/
|
||||||
|
fromStore(data: T): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toJSON is called when syncing the store to the filesystem. It should
|
||||||
|
* produce a JSON serializable object representation of the current state.
|
||||||
|
*
|
||||||
|
* It is recommended that a round trip is valid. Namely, calling
|
||||||
|
* `this.fromStore(this.toJSON())` shouldn't change the state.
|
||||||
|
*/
|
||||||
|
toJSON(): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IpcChannelPrefixes {
|
export interface IpcChannelPrefixes {
|
||||||
@ -33,9 +52,7 @@ export interface IpcChannelPrefixes {
|
|||||||
|
|
||||||
export interface BaseStoreDependencies {
|
export interface BaseStoreDependencies {
|
||||||
readonly logger: Logger;
|
readonly logger: Logger;
|
||||||
readonly storeMigrationVersion: string;
|
|
||||||
readonly directoryForUserData: string;
|
readonly directoryForUserData: string;
|
||||||
readonly migrations: Migrations<Record<string, unknown>>;
|
|
||||||
readonly ipcChannelPrefixes: IpcChannelPrefixes;
|
readonly ipcChannelPrefixes: IpcChannelPrefixes;
|
||||||
readonly shouldDisableSyncInListener: boolean;
|
readonly shouldDisableSyncInListener: boolean;
|
||||||
getConfigurationFileModel: GetConfigurationFileModel;
|
getConfigurationFileModel: GetConfigurationFileModel;
|
||||||
@ -47,22 +64,16 @@ export interface BaseStoreDependencies {
|
|||||||
/**
|
/**
|
||||||
* Note: T should only contain base JSON serializable types.
|
* Note: T should only contain base JSON serializable types.
|
||||||
*/
|
*/
|
||||||
export abstract class BaseStore<T extends object> {
|
export class BaseStore<T extends object> {
|
||||||
private readonly syncDisposers = disposer();
|
private readonly syncDisposers = disposer();
|
||||||
|
|
||||||
readonly displayName = kebabCase(this.params.configName).toUpperCase();
|
readonly displayName = kebabCase(this.params.configName).toUpperCase();
|
||||||
|
|
||||||
/**
|
constructor(
|
||||||
* @ignore
|
protected readonly dependencies: BaseStoreDependencies,
|
||||||
*/
|
|
||||||
protected readonly dependencies: BaseStoreDependencies;
|
|
||||||
|
|
||||||
protected constructor(
|
|
||||||
dependencies: BaseStoreDependencies,
|
|
||||||
protected readonly params: BaseStoreParams<T>,
|
protected readonly params: BaseStoreParams<T>,
|
||||||
) {
|
) {
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
makeObservable(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,13 +84,11 @@ export abstract class BaseStore<T extends object> {
|
|||||||
|
|
||||||
const config = this.dependencies.getConfigurationFileModel({
|
const config = this.dependencies.getConfigurationFileModel({
|
||||||
projectName: "lens",
|
projectName: "lens",
|
||||||
projectVersion: this.dependencies.storeMigrationVersion,
|
|
||||||
cwd: this.cwd(),
|
cwd: this.cwd(),
|
||||||
...this.params,
|
...this.params,
|
||||||
migrations: this.dependencies.migrations as Migrations<T>,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = this.fromStore(config.store);
|
const res = this.params.fromStore(config.store);
|
||||||
|
|
||||||
if (isPromiseLike(res)) {
|
if (isPromiseLike(res)) {
|
||||||
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.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.`);
|
||||||
@ -100,14 +109,14 @@ export abstract class BaseStore<T extends object> {
|
|||||||
const enableSync = () => {
|
const enableSync = () => {
|
||||||
this.syncDisposers.push(
|
this.syncDisposers.push(
|
||||||
reaction(
|
reaction(
|
||||||
() => toJS(this.toJSON()), // unwrap possible observables and react to everything
|
() => toJS(this.params.toJSON()), // unwrap possible observables and react to everything
|
||||||
model => {
|
model => {
|
||||||
this.dependencies.persistStateToConfig(config, model);
|
this.dependencies.persistStateToConfig(config, model);
|
||||||
broadcastMessage(`${this.dependencies.ipcChannelPrefixes.remote}:${config.path}`, model);
|
broadcastMessage(`${this.dependencies.ipcChannelPrefixes.remote}:${config.path}`, model);
|
||||||
},
|
},
|
||||||
this.params.syncOptions,
|
this.params.syncOptions,
|
||||||
),
|
),
|
||||||
this.dependencies.enlistMessageChannelListener({
|
this.dependencies.enlistMessageChannelListener<T>({
|
||||||
id: this.displayName,
|
id: this.displayName,
|
||||||
channel: {
|
channel: {
|
||||||
id: `${this.dependencies.ipcChannelPrefixes.local}:${config.path}`,
|
id: `${this.dependencies.ipcChannelPrefixes.local}:${config.path}`,
|
||||||
@ -120,8 +129,8 @@ export abstract class BaseStore<T extends object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo: use "resourceVersion" if merge required (to avoid equality checks => better performance)
|
// todo: use "resourceVersion" if merge required (to avoid equality checks => better performance)
|
||||||
if (!isEqual(this.toJSON(), model)) {
|
if (!isEqual(this.params.toJSON(), model)) {
|
||||||
this.fromStore(model as T);
|
this.params.fromStore(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.dependencies.shouldDisableSyncInListener) {
|
if (this.dependencies.shouldDisableSyncInListener) {
|
||||||
@ -134,23 +143,4 @@ export abstract class BaseStore<T extends object> {
|
|||||||
|
|
||||||
enableSync();
|
enableSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fromStore is called internally when a child class syncs with the file
|
|
||||||
* system.
|
|
||||||
*
|
|
||||||
* Note: This function **must** be synchronous.
|
|
||||||
*
|
|
||||||
* @param data the parsed information read from the stored JSON file
|
|
||||||
*/
|
|
||||||
protected abstract fromStore(data: T): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* toJSON is called when syncing the store to the filesystem. It should
|
|
||||||
* produce a JSON serializable object representation of the current state.
|
|
||||||
*
|
|
||||||
* It is recommended that a round trip is valid. Namely, calling
|
|
||||||
* `this.fromStore(this.toJSON())` shouldn't change the state.
|
|
||||||
*/
|
|
||||||
abstract toJSON(): T;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
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 getBasenameOfPathInjectable from "../path/get-basename.injectable";
|
||||||
|
import { enlistMessageChannelListenerInjectionToken } from "@k8slens/messaging";
|
||||||
|
import type { BaseStoreDependencies, BaseStoreParams } from "./base-store";
|
||||||
|
import { BaseStore } from "./base-store";
|
||||||
|
import { baseStoreIpcChannelPrefixesInjectionToken } from "./channel-prefix";
|
||||||
|
import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "./disable-sync";
|
||||||
|
import { persistStateToConfigInjectionToken } from "./save-to-file";
|
||||||
|
|
||||||
|
export type CreateBaseStore = <T extends object>(params: BaseStoreParams<T>) => BaseStore<T>;
|
||||||
|
|
||||||
|
const createBaseStoreInjectable = getInjectable({
|
||||||
|
id: "create-base-store",
|
||||||
|
instantiate: (di): CreateBaseStore => {
|
||||||
|
const deps: BaseStoreDependencies = {
|
||||||
|
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||||
|
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
||||||
|
ipcChannelPrefixes: di.inject(baseStoreIpcChannelPrefixesInjectionToken),
|
||||||
|
persistStateToConfig: di.inject(persistStateToConfigInjectionToken),
|
||||||
|
enlistMessageChannelListener: di.inject(enlistMessageChannelListenerInjectionToken),
|
||||||
|
shouldDisableSyncInListener: di.inject(shouldBaseStoreDisableSyncInIpcListenerInjectionToken),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (params) => new BaseStore(deps, params);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createBaseStoreInjectable;
|
||||||
@ -8,21 +8,22 @@ import isLinuxInjectable from "../../common/vars/is-linux.injectable";
|
|||||||
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
||||||
import isSnapPackageInjectable from "../../common/vars/is-snap-package.injectable";
|
import isSnapPackageInjectable from "../../common/vars/is-snap-package.injectable";
|
||||||
import isWindowsInjectable from "../../common/vars/is-windows.injectable";
|
import isWindowsInjectable from "../../common/vars/is-windows.injectable";
|
||||||
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
|
||||||
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
import getEnabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable";
|
|
||||||
import { issuesTrackerUrl } from "../../common/vars";
|
import { issuesTrackerUrl } from "../../common/vars";
|
||||||
import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable";
|
import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable";
|
||||||
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||||
|
import enabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable";
|
||||||
|
|
||||||
const userStore = asLegacyGlobalForExtensionApi(userStoreInjectable);
|
const userStore = asLegacyGlobalForExtensionApi(userStoreInjectable);
|
||||||
|
|
||||||
|
const enabledExtensions = asLegacyGlobalForExtensionApi(enabledExtensionsInjectable);
|
||||||
|
|
||||||
export const App = {
|
export const App = {
|
||||||
Preferences: {
|
Preferences: {
|
||||||
getKubectlPath: () => userStore.kubectlBinariesPath,
|
getKubectlPath: () => userStore.kubectlBinariesPath,
|
||||||
},
|
},
|
||||||
getEnabledExtensions: asLegacyGlobalFunctionForExtensionApi(getEnabledExtensionsInjectable),
|
getEnabledExtensions: () => enabledExtensions.get(),
|
||||||
get version() {
|
get version() {
|
||||||
const di = getLegacyGlobalDiForExtensionApi();
|
const di = getLegacyGlobalDiForExtensionApi();
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ export const App = {
|
|||||||
return di.inject(isLinuxInjectable);
|
return di.inject(isLinuxInjectable);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @deprecated This value is now `""` and is left here for backwards compatability.
|
* @deprecated This value is now `""` and is left here for backwards compatibility.
|
||||||
*/
|
*/
|
||||||
slackUrl: "",
|
slackUrl: "",
|
||||||
issuesTrackerUrl,
|
issuesTrackerUrl,
|
||||||
|
|||||||
@ -5,11 +5,9 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import extensionsStoreInjectable from "../../extensions-store/extensions-store.injectable";
|
import extensionsStoreInjectable from "../../extensions-store/extensions-store.injectable";
|
||||||
|
|
||||||
const getEnabledExtensionsInjectable = getInjectable({
|
const enabledExtensionsInjectable = getInjectable({
|
||||||
id: "get-enabled-extensions",
|
id: "enabled-extensions",
|
||||||
|
instantiate: (di) => di.inject(extensionsStoreInjectable).enabledExtensions,
|
||||||
instantiate: (di) => () =>
|
|
||||||
di.inject(extensionsStoreInjectable).enabledExtensions,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default getEnabledExtensionsInjectable;
|
export default enabledExtensionsInjectable;
|
||||||
|
|||||||
@ -3,30 +3,15 @@
|
|||||||
* 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 createBaseStoreInjectable from "../../common/base-store/create-base-store.injectable";
|
||||||
import { baseStoreIpcChannelPrefixesInjectionToken } from "../../common/base-store/channel-prefix";
|
|
||||||
import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "../../common/base-store/disable-sync";
|
|
||||||
import { persistStateToConfigInjectionToken } from "../../common/base-store/save-to-file";
|
|
||||||
import getConfigurationFileModelInjectable from "../../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
|
||||||
import loggerInjectable from "../../common/logger.injectable";
|
|
||||||
import getBasenameOfPathInjectable from "../../common/path/get-basename.injectable";
|
|
||||||
import { enlistMessageChannelListenerInjectionToken } from "@k8slens/messaging";
|
|
||||||
import storeMigrationVersionInjectable from "../../common/vars/store-migration-version.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: (di) => new ExtensionsStore({
|
instantiate: (di) => new ExtensionsStore({
|
||||||
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
|
||||||
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
|
||||||
logger: di.inject(loggerInjectable),
|
|
||||||
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||||
migrations: {},
|
createBaseStore: di.inject(createBaseStoreInjectable),
|
||||||
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
|
||||||
ipcChannelPrefixes: di.inject(baseStoreIpcChannelPrefixesInjectionToken),
|
|
||||||
persistStateToConfig: di.inject(persistStateToConfigInjectionToken),
|
|
||||||
enlistMessageChannelListener: di.inject(enlistMessageChannelListenerInjectionToken),
|
|
||||||
shouldDisableSyncInListener: di.inject(shouldBaseStoreDisableSyncInIpcListenerInjectionToken),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -4,12 +4,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { LensExtensionId } from "@k8slens/legacy-extensions";
|
import type { LensExtensionId } from "@k8slens/legacy-extensions";
|
||||||
import { action, computed, makeObservable, observable } from "mobx";
|
import { action, computed, observable } from "mobx";
|
||||||
import type { BaseStoreDependencies } from "../../common/base-store/base-store";
|
import type { BaseStore } from "../../common/base-store/base-store";
|
||||||
import { BaseStore } from "../../common/base-store/base-store";
|
import type { CreateBaseStore } from "../../common/base-store/create-base-store.injectable";
|
||||||
|
|
||||||
export interface LensExtensionsStoreModel {
|
export interface LensExtensionsStoreModel {
|
||||||
extensions: Record<LensExtensionId, LensExtensionState>;
|
extensions?: Record<LensExtensionId, LensExtensionState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LensExtensionState {
|
export interface LensExtensionState {
|
||||||
@ -22,23 +22,35 @@ export interface IsEnabledExtensionDescriptor {
|
|||||||
isBundled: boolean;
|
isBundled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
export interface ExtensionsStoreDependencies {
|
||||||
constructor(deps: BaseStoreDependencies) {
|
createBaseStore: CreateBaseStore;
|
||||||
super(deps, {
|
readonly storeMigrationVersion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExtensionsStore {
|
||||||
|
private readonly store: BaseStore<LensExtensionsStoreModel>;
|
||||||
|
|
||||||
|
constructor(private readonly dependencies: ExtensionsStoreDependencies) {
|
||||||
|
this.store = this.dependencies.createBaseStore({
|
||||||
configName: "lens-extensions",
|
configName: "lens-extensions",
|
||||||
|
fromStore: action(({ extensions = {}}) => {
|
||||||
|
this.state.merge(extensions);
|
||||||
|
}),
|
||||||
|
toJSON: () => ({
|
||||||
|
extensions: Object.fromEntries(this.state),
|
||||||
|
}),
|
||||||
|
projectVersion: this.dependencies.storeMigrationVersion,
|
||||||
});
|
});
|
||||||
makeObservable(this);
|
this.store.load();
|
||||||
this.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
readonly enabledExtensions = computed(() => (
|
||||||
get enabledExtensions() {
|
Array.from(this.state.values())
|
||||||
return Array.from(this.state.values())
|
|
||||||
.filter(({ enabled }) => enabled)
|
.filter(({ enabled }) => enabled)
|
||||||
.map(({ name }) => name);
|
.map(({ name }) => name)
|
||||||
}
|
));
|
||||||
|
|
||||||
protected state = observable.map<LensExtensionId, LensExtensionState>();
|
protected readonly state = observable.map<LensExtensionId, LensExtensionState>();
|
||||||
|
|
||||||
isEnabled({ id, isBundled }: IsEnabledExtensionDescriptor): boolean {
|
isEnabled({ id, isBundled }: IsEnabledExtensionDescriptor): boolean {
|
||||||
// By default false, so that copied extensions are disabled by default.
|
// By default false, so that copied extensions are disabled by default.
|
||||||
@ -49,15 +61,4 @@ export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
|||||||
mergeState = action((extensionsState: Record<LensExtensionId, LensExtensionState> | [LensExtensionId, LensExtensionState][]) => {
|
mergeState = action((extensionsState: Record<LensExtensionId, LensExtensionState> | [LensExtensionId, LensExtensionState][]) => {
|
||||||
this.state.merge(extensionsState);
|
this.state.merge(extensionsState);
|
||||||
});
|
});
|
||||||
|
|
||||||
@action
|
|
||||||
protected fromStore({ extensions }: LensExtensionsStoreModel) {
|
|
||||||
this.state.merge(extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(): LensExtensionsStoreModel {
|
|
||||||
return {
|
|
||||||
extensions: Object.fromEntries(this.state.toJSON()),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import type { Disposer } from "@k8slens/utilities";
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@ -5,9 +6,9 @@ import type {
|
|||||||
MessageChannelListener,
|
MessageChannelListener,
|
||||||
} from "./message-channel-listener-injection-token";
|
} from "./message-channel-listener-injection-token";
|
||||||
|
|
||||||
export type EnlistMessageChannelListener = (
|
export type EnlistMessageChannelListener = <T>(
|
||||||
listener: MessageChannelListener<MessageChannel<unknown>>,
|
listener: MessageChannelListener<MessageChannel<T>>,
|
||||||
) => () => void;
|
) => Disposer;
|
||||||
|
|
||||||
export const enlistMessageChannelListenerInjectionToken =
|
export const enlistMessageChannelListenerInjectionToken =
|
||||||
getInjectionToken<EnlistMessageChannelListener>({
|
getInjectionToken<EnlistMessageChannelListener>({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user