1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Refactor listening of different channel kinds

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-10-12 12:01:50 -04:00
parent 6bd55d3d0c
commit f0aad35f30
7 changed files with 54 additions and 65 deletions

View File

@ -8,20 +8,18 @@ import { disposer } from "../index";
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token"; import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
import { enlistMessageChannelListenerInjectionToken } from "./enlist-message-channel-listener-injection-token"; import { enlistMessageChannelListenerInjectionToken } from "./enlist-message-channel-listener-injection-token";
const listeningOfChannelsInjectable = getInjectable({ const listeningOnMessageChannelsInjectable = getInjectable({
id: "listening-of-channels", id: "listening-on-message-channels",
instantiate: (di) => { instantiate: (di) => {
const enlistMessageChannelListener = di.inject(enlistMessageChannelListenerInjectionToken); const enlistMessageChannelListener = di.inject(enlistMessageChannelListenerInjectionToken);
const messageChannelListeners = di.injectMany(messageChannelListenerInjectionToken); const messageChannelListeners = di.injectMany(messageChannelListenerInjectionToken);
return getStartableStoppable("listening-of-channels", () => { return getStartableStoppable("listening-on-channels", () => (
const messageChannelDisposers = messageChannelListeners.map(enlistMessageChannelListener); disposer(messageChannelListeners.map(enlistMessageChannelListener))
));
return disposer(...messageChannelDisposers);
});
}, },
}); });
export default listeningOfChannelsInjectable; export default listeningOnMessageChannelsInjectable;

View File

@ -3,6 +3,8 @@
* 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 { SingleOrMany } from "./types";
export interface Disposer { export interface Disposer {
@ -17,9 +19,9 @@ export interface ExtendableDisposer extends Disposer {
push(...vals: (Disposer | ExtendableDisposer | Disposable)[]): void; push(...vals: (Disposer | ExtendableDisposer | Disposable)[]): void;
} }
export function disposer(...items: (Disposer | Disposable | undefined | null)[]): ExtendableDisposer { export function disposer(...items: SingleOrMany<Disposer | Disposable | undefined | null>[]): ExtendableDisposer {
return Object.assign(() => { return Object.assign(() => {
for (const item of items) { for (const item of items.flat()) {
if (!item) { if (!item) {
continue; continue;
} }

View File

@ -11,7 +11,6 @@ interface Iterator<T> {
find(fn: (val: T) => unknown): T | undefined; find(fn: (val: T) => unknown): T | undefined;
collect<U>(fn: (values: Iterable<T>) => U): U; collect<U>(fn: (values: Iterable<T>) => U): U;
map<U>(fn: (val: T) => U): Iterator<U>; map<U>(fn: (val: T) => U): Iterator<U>;
tap(fn: (val: T) => void): Iterator<T>;
flatMap<U>(fn: (val: T) => U[]): Iterator<U>; flatMap<U>(fn: (val: T) => U[]): Iterator<U>;
join(sep?: string): string; join(sep?: string): string;
} }
@ -22,7 +21,6 @@ export function pipeline<T>(src: IterableIterator<T>): Iterator<T> {
filterMap: (fn) => pipeline(filterMap(src, fn)), filterMap: (fn) => pipeline(filterMap(src, fn)),
map: (fn) => pipeline(map(src, fn)), map: (fn) => pipeline(map(src, fn)),
flatMap: (fn) => pipeline(flatMap(src, fn)), flatMap: (fn) => pipeline(flatMap(src, fn)),
tap: (fn) => pipeline(tap(src, fn)),
find: (fn) => find(src, fn), find: (fn) => find(src, fn),
join: (sep) => join(src, sep), join: (sep) => join(src, sep),
collect: (fn) => fn(src), collect: (fn) => fn(src),
@ -35,13 +33,6 @@ export function pipeline<T>(src: IterableIterator<T>): Iterator<T> {
*/ */
export function* newEmpty<T>(): IterableIterator<T> {} export function* newEmpty<T>(): IterableIterator<T> {}
export function* tap<T>(src: Iterable<T>, fn: (val: T) => void): IterableIterator<T> {
for (const val of src) {
fn(val);
yield val;
}
}
/** /**
* Creates a new `Iterable` that yields at most n items from src. * Creates a new `Iterable` that yields at most n items from src.
* Does not modify `src` which can be used later. * Does not modify `src` which can be used later.

View File

@ -3,34 +3,32 @@
* 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 { disposer, iter } from "../../../../common/utils"; import { disposer } from "../../../../common/utils";
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token"; import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
import { getStartableStoppable } from "../../../../common/utils/get-startable-stoppable"; import { getStartableStoppable } from "../../../../common/utils/get-startable-stoppable";
import enlistRequestChannelListenerInjectable from "./enlist-request-channel-listener.injectable"; import enlistRequestChannelListenerInjectable from "./enlist-request-channel-listener.injectable";
import { requestChannelListenerInjectionToken } from "./listener-tokens"; import { requestChannelListenerInjectionToken } from "./listener-tokens";
const listenerOfRequestChannelsInjectable = getInjectable({ const listeningOnRequestChannelsInjectable = getInjectable({
id: "listener-of-request-channels", id: "listening-on-request-channels",
instantiate: (di) => { instantiate: (di) => {
const enlistRequestChannelListener = di.inject(enlistRequestChannelListenerInjectable); const enlistRequestChannelListener = di.inject(enlistRequestChannelListenerInjectable);
const requestChannelListeners = di.injectMany(requestChannelListenerInjectionToken); const requestChannelListeners = di.injectMany(requestChannelListenerInjectionToken);
return getStartableStoppable("listening-of-request-channels", () => { return getStartableStoppable("listening-on-request-channels", () => {
const seenChannels = new Set<RequestChannel<unknown, unknown>>(); const seenChannels = new Set<RequestChannel<unknown, unknown>>();
const requestChannelDisposers = iter.pipeline(requestChannelListeners.values())
.tap(listener => {
if (seenChannels.has(listener.channel)) {
throw new Error(`Trying to register a multiple channel handlers for "${listener.channel.id}", which is an error`);
}
seenChannels.add(listener.channel); for (const listener of requestChannelListeners) {
}) if (seenChannels.has(listener.channel)) {
.map(enlistRequestChannelListener) throw new Error(`Tried to register a multiple channel handlers for "${listener.channel.id}", only one handler is supported for a request channel.`);
.collect(v => Array.from(v)); }
return disposer(...requestChannelDisposers); seenChannels.add(listener.channel);
}
return disposer(requestChannelListeners.map(enlistRequestChannelListener));
}); });
}, },
}); });
export default listenerOfRequestChannelsInjectable; export default listeningOnRequestChannelsInjectable;

View File

@ -1,29 +0,0 @@
/**
* 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 { onLoadOfApplicationInjectionToken } from "../../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
import listeningOfChannelsInjectable from "../../../../common/utils/channel/listening-of-channels.injectable";
import listenerOfRequestChannelsInjectable from "./handling-of-channels.injectable";
const startListeningOfChannelsInjectable = getInjectable({
id: "start-listening-of-channels-main",
instantiate: (di) => {
const listeningOfChannels = di.inject(listeningOfChannelsInjectable);
const listenerOfRequestChannels = di.inject(listenerOfRequestChannelsInjectable);
return {
id: "start-listening-of-channels-main",
run: async () => {
await listeningOfChannels.start();
await listenerOfRequestChannels.start();
},
};
},
injectionToken: onLoadOfApplicationInjectionToken,
});
export default startListeningOfChannelsInjectable;

View File

@ -0,0 +1,29 @@
/**
* 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 { onLoadOfApplicationInjectionToken } from "../../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
import listeningOnMessageChannelsInjectable from "../../../../common/utils/channel/listening-on-message-channels.injectable";
import listeningOnRequestChannelsInjectable from "./listening-on-request-channels.injectable";
const startListeningOnChannelsInjectable = getInjectable({
id: "start-listening-on-channels-main",
instantiate: (di) => {
const listeningOnMessageChannels = di.inject(listeningOnMessageChannelsInjectable);
const listeningOnRequestChannels = di.inject(listeningOnRequestChannelsInjectable);
return {
id: "start-listening-on-channels-main",
run: async () => {
await listeningOnMessageChannels.start();
await listeningOnRequestChannels.start();
},
};
},
injectionToken: onLoadOfApplicationInjectionToken,
});
export default startListeningOnChannelsInjectable;

View File

@ -4,13 +4,13 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { beforeFrameStartsInjectionToken } from "../../../before-frame-starts/before-frame-starts-injection-token"; import { beforeFrameStartsInjectionToken } from "../../../before-frame-starts/before-frame-starts-injection-token";
import listeningOfChannelsInjectable from "../../../../common/utils/channel/listening-of-channels.injectable"; import listeningOnMessageChannelsInjectable from "../../../../common/utils/channel/listening-on-message-channels.injectable";
const startListeningOfChannelsInjectable = getInjectable({ const startListeningOfChannelsInjectable = getInjectable({
id: "start-listening-of-channels-renderer", id: "start-listening-of-channels-renderer",
instantiate: (di) => { instantiate: (di) => {
const listeningOfChannels = di.inject(listeningOfChannelsInjectable); const listeningOfChannels = di.inject(listeningOnMessageChannelsInjectable);
return { return {
id: "start-listening-of-channels-renderer", id: "start-listening-of-channels-renderer",