mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
* Add custom jest resolver to fix requiring "uuid" module Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update dependencies Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce test utils for rendering and running with thrown mobx reactions Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract startable-stoppable to NPM package Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract messaging to NPM package Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using startable-stoppable from NPM package Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using messaging from the Feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove old implementation of messaging Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make setupping app paths happen earlier in renderer Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix typo Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add kludge to make testing-library work properly from test-utils package Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix code style Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add lint:fix -root script Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix unrelated failing unit tests Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Turn of no-floating-promises from typescript linting for being broken Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make linting not happen for dist -directories Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make linting failures appear as failure Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Stop running prettier twice It already gets ran as eslint-plugin. Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make CI run unit tests for all packages by consolidating name of NPM script Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing unit tests for coverage Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Skip coverage for test utils Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove check for coverage in packages which are not ready for it Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Stop collecting coverage from index.ts files them being indirections to the implementation Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Implement sending message to channel in main Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing feature dependencies Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add dummy implementations for requesting in main from renderer Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Re-enable communicating from main to cluster frames Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Ignore trivial files from coverage Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update package-lock Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract message-bridge to separate NPM package to prevent dev dependencies being in the production bundle Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract computed channel to own NPM package for clear dependencies Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate electron related stuff to a directory Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing publish configurations Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Ignore test implementation from coverage being not interesting Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> --------- Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
197 lines
5.6 KiB
TypeScript
197 lines
5.6 KiB
TypeScript
import type { DiContainer } from "@ogre-tools/injectable";
|
|
import type { Channel, MessageChannelHandler, RequestChannelHandler } from "@k8slens/messaging";
|
|
|
|
import {
|
|
enlistMessageChannelListenerInjectionToken,
|
|
enlistRequestChannelListenerInjectionToken,
|
|
RequestFromChannel,
|
|
requestFromChannelInjectionToken,
|
|
sendMessageToChannelInjectionToken,
|
|
} from "@k8slens/messaging";
|
|
|
|
import { pipeline } from "@ogre-tools/fp";
|
|
import { filter, map } from "lodash/fp";
|
|
import asyncFn, { AsyncFnMock } from "@async-fn/jest";
|
|
|
|
export type MessageBridgeFake = {
|
|
involve: (...dis: DiContainer[]) => void;
|
|
messagePropagation: () => Promise<void>;
|
|
messagePropagationRecursive: (callback: any) => any;
|
|
setAsync: (value: boolean) => void;
|
|
};
|
|
|
|
const overrideMessaging = ({
|
|
di,
|
|
messageListenersByDi,
|
|
messagePropagationBuffer,
|
|
getAsyncModeStatus,
|
|
}: {
|
|
di: DiContainer;
|
|
|
|
messageListenersByDi: Map<DiContainer, Map<string, Set<MessageChannelHandler<Channel>>>>;
|
|
|
|
messagePropagationBuffer: Set<{ resolve: () => Promise<void> }>;
|
|
|
|
getAsyncModeStatus: () => boolean;
|
|
}) => {
|
|
const messageHandlersByChannel = new Map<string, Set<MessageChannelHandler<Channel>>>();
|
|
|
|
messageListenersByDi.set(di, messageHandlersByChannel);
|
|
|
|
di.override(sendMessageToChannelInjectionToken, () => (channel, message) => {
|
|
const allOtherDis = [...messageListenersByDi.keys()].filter((x) => x !== di);
|
|
|
|
allOtherDis.forEach((otherDi) => {
|
|
const listeners = messageListenersByDi.get(otherDi);
|
|
|
|
const handlersForChannel = listeners?.get(channel.id);
|
|
|
|
if (!handlersForChannel) {
|
|
return;
|
|
}
|
|
|
|
if (getAsyncModeStatus()) {
|
|
const resolvableHandlePromise = asyncFn();
|
|
|
|
resolvableHandlePromise().then(() => {
|
|
handlersForChannel.forEach((handler) => handler(message, { frameId: 42, processId: 42 }));
|
|
});
|
|
|
|
messagePropagationBuffer.add(resolvableHandlePromise);
|
|
} else {
|
|
handlersForChannel.forEach((handler) => handler(message, { frameId: 42, processId: 42 }));
|
|
}
|
|
});
|
|
});
|
|
|
|
di.override(enlistMessageChannelListenerInjectionToken, () => (listener) => {
|
|
if (!messageHandlersByChannel.has(listener.channel.id)) {
|
|
messageHandlersByChannel.set(listener.channel.id, new Set());
|
|
}
|
|
|
|
const handlerSet = messageHandlersByChannel.get(listener.channel.id);
|
|
|
|
handlerSet?.add(listener.handler);
|
|
|
|
return () => {
|
|
handlerSet?.delete(listener.handler);
|
|
};
|
|
});
|
|
};
|
|
|
|
const overrideRequesting = ({
|
|
di,
|
|
requestListenersByDi,
|
|
}: {
|
|
di: DiContainer;
|
|
|
|
requestListenersByDi: Map<DiContainer, Map<string, Set<RequestChannelHandler<Channel>>>>;
|
|
}) => {
|
|
const requestHandlersByChannel = new Map<string, Set<RequestChannelHandler<Channel>>>();
|
|
|
|
requestListenersByDi.set(di, requestHandlersByChannel);
|
|
|
|
di.override(
|
|
requestFromChannelInjectionToken,
|
|
() =>
|
|
(async (channel, request) =>
|
|
pipeline(
|
|
[...requestListenersByDi.values()],
|
|
map((listenersByChannel) => listenersByChannel?.get(channel.id)),
|
|
filter((x) => !!x),
|
|
|
|
(channelSpecificListeners) => {
|
|
if (channelSpecificListeners.length === 0) {
|
|
throw new Error(
|
|
`Tried to make a request but no listeners for channel "${channel.id}" was discovered in any DIs`,
|
|
);
|
|
}
|
|
|
|
if (channelSpecificListeners.length > 1) {
|
|
throw new Error(
|
|
`Tried to make a request but multiple listeners were discovered for channel "${channel.id}" in multiple DIs.`,
|
|
);
|
|
}
|
|
|
|
const listeners = channelSpecificListeners[0];
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
const [handler] = listeners!;
|
|
|
|
return handler;
|
|
},
|
|
|
|
async (handler) => handler(request),
|
|
)) as RequestFromChannel,
|
|
);
|
|
|
|
di.override(enlistRequestChannelListenerInjectionToken, () => (listener) => {
|
|
if (!requestHandlersByChannel.has(listener.channel.id)) {
|
|
requestHandlersByChannel.set(listener.channel.id, new Set());
|
|
}
|
|
|
|
const handlerSet = requestHandlersByChannel.get(listener.channel.id);
|
|
|
|
handlerSet?.add(listener.handler);
|
|
|
|
return () => {
|
|
handlerSet?.delete(listener.handler);
|
|
};
|
|
});
|
|
};
|
|
|
|
export const getMessageBridgeFake = (): MessageBridgeFake => {
|
|
const messageListenersByDi = new Map<
|
|
DiContainer,
|
|
Map<string, Set<MessageChannelHandler<Channel>>>
|
|
>();
|
|
|
|
const requestListenersByDi = new Map<
|
|
DiContainer,
|
|
Map<string, Set<RequestChannelHandler<Channel>>>
|
|
>();
|
|
|
|
const messagePropagationBuffer = new Set<AsyncFnMock<() => void>>();
|
|
|
|
const messagePropagation = async (wrapper: (callback: any) => any = (callback) => callback()) => {
|
|
const oldMessages = [...messagePropagationBuffer.values()];
|
|
|
|
messagePropagationBuffer.clear();
|
|
await Promise.all(oldMessages.map((x) => wrapper(x.resolve)));
|
|
};
|
|
|
|
const messagePropagationRecursive = async (
|
|
wrapper: (callback: any) => any = (callback) => callback(),
|
|
) => {
|
|
while (messagePropagationBuffer.size) {
|
|
await messagePropagation(wrapper);
|
|
}
|
|
};
|
|
|
|
let asyncModeStatus = false;
|
|
const getAsyncModeStatus = () => asyncModeStatus;
|
|
|
|
return {
|
|
involve: (...dis: DiContainer[]) => {
|
|
dis.forEach((di) => {
|
|
overrideRequesting({ di, requestListenersByDi });
|
|
|
|
overrideMessaging({
|
|
di,
|
|
messageListenersByDi,
|
|
messagePropagationBuffer,
|
|
getAsyncModeStatus,
|
|
});
|
|
});
|
|
},
|
|
|
|
messagePropagation,
|
|
|
|
messagePropagationRecursive,
|
|
|
|
setAsync: (value) => {
|
|
asyncModeStatus = value;
|
|
},
|
|
};
|
|
};
|