From be79c4d0447a7e150809b3bd8085aae01b8ef0a2 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Fri, 17 Mar 2023 09:48:45 +0200 Subject: [PATCH] Fixup Signed-off-by: Janne Savolainen --- .idea/inspectionProfiles/Project_Default.xml | 1 + package-lock.json | 20 +++- ...annel-administration-channel.injectable.ts | 65 +++++++++++++ .../computed-channel.injectable.ts | 93 +------------------ .../computed-channel.test.tsx | 6 +- ...icate-channel-observer-guard.injectable.ts | 42 +++++++++ 6 files changed, 132 insertions(+), 95 deletions(-) create mode 100644 packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel-administration-channel.injectable.ts create mode 100644 packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/duplicate-channel-observer-guard.injectable.ts diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index e4063525ae..15223a3492 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,5 +2,6 @@ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2beb8e16da..277877350a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34595,7 +34595,11 @@ "@k8slens/application": "^6.5.0-alpha.0", "@k8slens/application-for-electron-main": "^6.5.0-alpha.0", "@k8slens/legacy-extensions": "^1.0.0-alpha.0", + "@k8slens/messaging": "^1.0.0-alpha.1", + "@k8slens/messaging-for-main": "^1.0.0-alpha.1", + "@k8slens/messaging-for-renderer": "^1.0.0-alpha.1", "@k8slens/run-many": "^1.0.0-alpha.1", + "@k8slens/startable-stoppable": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", "@types/byline": "^4.2.33", @@ -36661,7 +36665,11 @@ "@k8slens/generate-tray-icons": "^6.5.0-alpha.1", "@k8slens/legacy-extension-example": "^1.0.0-alpha.1", "@k8slens/legacy-extensions": "^1.0.0-alpha.1", + "@k8slens/messaging": "^1.0.0-alpha.1", + "@k8slens/messaging-for-main": "^1.0.0-alpha.1", + "@k8slens/messaging-for-renderer": "^1.0.0-alpha.1", "@k8slens/run-many": "^1.0.0-alpha.1", + "@k8slens/startable-stoppable": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", "@ogre-tools/fp": "^15.1.2", @@ -37231,6 +37239,7 @@ "license": "MIT", "devDependencies": { "@async-fn/jest": "^1.6.4", + "@k8slens/eslint-config": "^6.5.0-alpha.1", "type-fest": "^2.14.0" }, "peerDependencies": { @@ -37249,6 +37258,9 @@ "name": "@k8slens/messaging-for-main", "version": "1.0.0-alpha.1", "license": "MIT", + "devDependencies": { + "@k8slens/eslint-config": "^6.5.0-alpha.1" + }, "peerDependencies": { "@k8slens/application": "^6.5.0-alpha.0", "@k8slens/feature-core": "^6.5.0-alpha.0", @@ -37263,6 +37275,9 @@ "name": "@k8slens/messaging-for-renderer", "version": "1.0.0-alpha.1", "license": "MIT", + "devDependencies": { + "@k8slens/eslint-config": "^6.5.0-alpha.1" + }, "peerDependencies": { "@k8slens/application": "^6.5.0-alpha.0", "@k8slens/messaging": "^1.0.0-alpha.1", @@ -37288,7 +37303,10 @@ "packages/utility-features/startable-stoppable": { "name": "@k8slens/startable-stoppable", "version": "1.0.0-alpha.1", - "license": "MIT" + "license": "MIT", + "devDependencies": { + "@k8slens/eslint-config": "^6.5.0-alpha.1" + } }, "packages/utility-features/test-utils": { "name": "@k8slens/test-utils", diff --git a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel-administration-channel.injectable.ts b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel-administration-channel.injectable.ts new file mode 100644 index 0000000000..3c8860e0f2 --- /dev/null +++ b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel-administration-channel.injectable.ts @@ -0,0 +1,65 @@ +import { reaction } from "mobx"; + +import type { MessageChannel } from "../message/message-channel-listener-injection-token"; +import { getMessageChannelListenerInjectable } from "../message/message-channel-listener-injection-token"; +import { sendMessageToChannelInjectionToken } from "../message/message-to-channel-injection-token.no-coverage"; +import type { JsonPrimitive } from "type-fest"; +import { computedChannelObserverInjectionToken } from "./computed-channel.injectable"; + +export type JsonifiableObject = { [Key in string]?: Jsonifiable } | { toJSON: () => Jsonifiable }; +export type JsonifiableArray = readonly Jsonifiable[]; +export type Jsonifiable = JsonPrimitive | JsonifiableObject | JsonifiableArray; + +export type ComputedChannelAdminMessage = { + channelId: string; + status: "became-observed" | "became-unobserved"; +}; + + +export const computedChannelAdministrationChannel: MessageChannel = { + id: "computed-channel-administration-channel", +}; + +export const computedChannelAdministrationListenerInjectable = getMessageChannelListenerInjectable({ + id: "computed-channel-administration", + getHandler: (di) => { + const sendMessageToChannel = di.inject(sendMessageToChannelInjectionToken); + + const disposersByChannelId = new Map void>(); + + return (message) => { + if (message.status === "became-observed") { + const result = di + .injectMany(computedChannelObserverInjectionToken) + .find((channelObserver) => channelObserver.channel.id === message.channelId); + + if (result === undefined) { + return; + } + + const disposer = reaction( + () => result.observer.get(), + (observed) => + sendMessageToChannel( + { + id: message.channelId, + }, + + observed, + ), + { + fireImmediately: true, + }, + ); + + disposersByChannelId.set(message.channelId, disposer); + } else { + const disposer = disposersByChannelId.get(message.channelId); + + disposer?.(); + } + }; + }, + + channel: computedChannelAdministrationChannel, +}); diff --git a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.injectable.ts b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.injectable.ts index caaa410473..adb09dccb0 100644 --- a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.injectable.ts +++ b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.injectable.ts @@ -7,18 +7,14 @@ import { observable, onBecomeObserved, onBecomeUnobserved, - reaction, runInAction, } from "mobx"; import type { MessageChannel } from "../message/message-channel-listener-injection-token"; import { getMessageChannelListenerInjectable } from "../message/message-channel-listener-injection-token"; import { sendMessageToChannelInjectionToken } from "../message/message-to-channel-injection-token.no-coverage"; -import { onLoadOfApplicationInjectionToken } from "@k8slens/application"; -import { pipeline } from "@ogre-tools/fp"; -import { filter, groupBy, map, nth, toPairs } from "lodash/fp"; -import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; import type { JsonPrimitive } from "type-fest"; +import { computedChannelAdministrationChannel } from "./computed-channel-administration-channel.injectable"; export type JsonifiableObject = { [Key in string]?: Jsonifiable } | { toJSON: () => Jsonifiable }; export type JsonifiableArray = readonly Jsonifiable[]; @@ -37,10 +33,6 @@ export type ChannelObserver = { channel: MessageChannel; observer: IComputedValue; }; -export type ComputedChannelAdminMessage = { - channelId: string; - status: "became-observed" | "became-unobserved"; -}; export const computedChannelObserverInjectionToken = getInjectionToken< ChannelObserver @@ -48,10 +40,6 @@ export const computedChannelObserverInjectionToken = getInjectionToken< id: "computed-channel-observer", }); -export const computedChannelAdministrationChannel: MessageChannel = { - id: "computed-channel-administration-channel", -}; - const computedChannelInjectable = getInjectable({ id: "computed-channel", @@ -119,83 +107,4 @@ const computedChannelInjectable = getInjectable({ injectionToken: computedChannelInjectionToken, }); -export const duplicateChannelObserverGuardInjectable = getInjectable({ - id: "duplicate-channel-observer-guard", - - instantiate: (di) => { - const computedInjectMany = di.inject(computedInjectManyInjectable); - - return { - run: () => { - reaction( - () => computedInjectMany(computedChannelObserverInjectionToken).get(), - (observers) => { - const duplicateObserverChannelIds = pipeline( - observers, - groupBy((observer) => observer.channel.id), - toPairs, - filter(([, channelObservers]) => channelObservers.length > 1), - map(nth(0)), - ); - - if (duplicateObserverChannelIds.length) { - throw new Error( - `Tried to register duplicate channel observer for channels "${duplicateObserverChannelIds.join( - '", "', - )}"`, - ); - } - }, - ); - }, - }; - }, - - injectionToken: onLoadOfApplicationInjectionToken, -}); - -export const computedChannelAdministrationListenerInjectable = getMessageChannelListenerInjectable({ - id: "computed-channel-administration", - getHandler: (di) => { - const sendMessageToChannel = di.inject(sendMessageToChannelInjectionToken); - - const disposersByChannelId = new Map void>(); - - return (message) => { - if (message.status === "became-observed") { - const result = di - .injectMany(computedChannelObserverInjectionToken) - .find((channelObserver) => channelObserver.channel.id === message.channelId); - - if (result === undefined) { - return; - } - - const disposer = reaction( - () => result.observer.get(), - (observed) => - sendMessageToChannel( - { - id: message.channelId, - }, - - observed, - ), - { - fireImmediately: true, - }, - ); - - disposersByChannelId.set(message.channelId, disposer); - } else { - const disposer = disposersByChannelId.get(message.channelId); - - disposer?.(); - } - }; - }, - - channel: computedChannelAdministrationChannel, -}); - export default computedChannelInjectable; diff --git a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.test.tsx b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.test.tsx index d9f9293fe1..4bedeb9e25 100644 --- a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.test.tsx +++ b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/computed-channel.test.tsx @@ -20,13 +20,15 @@ import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx"; import { registerFeature } from "@k8slens/feature-core"; import { messagingFeatureForUnitTesting } from "../../unit-testing"; import { - computedChannelAdministrationChannel, - ComputedChannelAdminMessage, computedChannelInjectionToken, computedChannelObserverInjectionToken, } from "./computed-channel.injectable"; import { runWithThrownMobxReactions, renderFor } from "@k8slens/test-utils"; import { observer } from "mobx-react"; +import { + computedChannelAdministrationChannel, + ComputedChannelAdminMessage, +} from "./computed-channel-administration-channel.injectable"; const testChannel: MessageChannel = { id: "some-channel-id" }; const testChannel2: MessageChannel = { id: "some-other-channel-id" }; diff --git a/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/duplicate-channel-observer-guard.injectable.ts b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/duplicate-channel-observer-guard.injectable.ts new file mode 100644 index 0000000000..42f313ec36 --- /dev/null +++ b/packages/technical-features/messaging/agnostic/src/features/actual/computed-channel/duplicate-channel-observer-guard.injectable.ts @@ -0,0 +1,42 @@ +import { onLoadOfApplicationInjectionToken } from "@k8slens/application"; +import { pipeline } from "@ogre-tools/fp"; +import { getInjectable } from "@ogre-tools/injectable"; +import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; +import { filter, groupBy, nth, map, toPairs } from "lodash/fp"; +import { reaction } from "mobx"; +import { computedChannelObserverInjectionToken } from "./computed-channel.injectable"; + +export const duplicateChannelObserverGuardInjectable = getInjectable({ + id: "duplicate-channel-observer-guard", + + instantiate: (di) => { + const computedInjectMany = di.inject(computedInjectManyInjectable); + + return { + run: () => { + reaction( + () => computedInjectMany(computedChannelObserverInjectionToken).get(), + (observers) => { + const duplicateObserverChannelIds = pipeline( + observers, + groupBy((observer) => observer.channel.id), + toPairs, + filter(([, channelObservers]) => channelObservers.length > 1), + map(nth(0)), + ); + + if (duplicateObserverChannelIds.length) { + throw new Error( + `Tried to register duplicate channel observer for channels "${duplicateObserverChannelIds.join( + '", "', + )}"`, + ); + } + }, + ); + }, + }; + }, + + injectionToken: onLoadOfApplicationInjectionToken, +});