mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Synchronize initial values of sync boxes when window starts
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
9a733883f6
commit
f3e41954c5
@ -13,7 +13,7 @@ export type ApplicationUpdateStatusEventId =
|
||||
| "download-for-update-failed";
|
||||
|
||||
export interface ApplicationUpdateStatusChannelMessage { eventId: ApplicationUpdateStatusEventId; version?: string }
|
||||
export type ApplicationUpdateStatusChannel = Channel<ApplicationUpdateStatusChannelMessage>;
|
||||
export type ApplicationUpdateStatusChannel = Channel<ApplicationUpdateStatusChannelMessage, never>;
|
||||
|
||||
const applicationUpdateStatusChannelInjectable = getInjectable({
|
||||
id: "application-update-status-channel",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import createSyncBoxInjectable from "../../sync-box/create-sync-box.injectable";
|
||||
import type { UpdateChannel } from "../update-channels";
|
||||
import { syncBoxInjectionToken } from "../../sync-box/sync-box-injection-token";
|
||||
|
||||
const discoveredUpdateVersionInjectable = getInjectable({
|
||||
id: "discovered-update-version",
|
||||
@ -16,6 +17,8 @@ const discoveredUpdateVersionInjectable = getInjectable({
|
||||
"discovered-update-version",
|
||||
);
|
||||
},
|
||||
|
||||
injectionToken: syncBoxInjectionToken,
|
||||
});
|
||||
|
||||
export default discoveredUpdateVersionInjectable;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import createSyncBoxInjectable from "../../sync-box/create-sync-box.injectable";
|
||||
import { syncBoxInjectionToken } from "../../sync-box/sync-box-injection-token";
|
||||
|
||||
const progressOfUpdateDownloadInjectable = getInjectable({
|
||||
id: "progress-of-update-download-state",
|
||||
@ -13,6 +14,8 @@ const progressOfUpdateDownloadInjectable = getInjectable({
|
||||
|
||||
return createSyncBox<number>("progress-of-update-download");
|
||||
},
|
||||
|
||||
injectionToken: syncBoxInjectionToken,
|
||||
});
|
||||
|
||||
export default progressOfUpdateDownloadInjectable;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import createSyncBoxInjectable from "../../sync-box/create-sync-box.injectable";
|
||||
import { syncBoxInjectionToken } from "../../sync-box/sync-box-injection-token";
|
||||
|
||||
const updateIsBeingDownloadedInjectable = getInjectable({
|
||||
id: "update-is-being-downloaded",
|
||||
@ -13,6 +14,8 @@ const updateIsBeingDownloadedInjectable = getInjectable({
|
||||
|
||||
return createSyncBox<boolean>("update-is-being-downloaded");
|
||||
},
|
||||
|
||||
injectionToken: syncBoxInjectionToken,
|
||||
});
|
||||
|
||||
export default updateIsBeingDownloadedInjectable;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import createSyncBoxInjectable from "../../sync-box/create-sync-box.injectable";
|
||||
import { syncBoxInjectionToken } from "../../sync-box/sync-box-injection-token";
|
||||
|
||||
const updatesAreBeingDiscoveredInjectable = getInjectable({
|
||||
id: "updates-are-being-discovered",
|
||||
@ -13,6 +14,8 @@ const updatesAreBeingDiscoveredInjectable = getInjectable({
|
||||
|
||||
return createSyncBox<boolean>("updates-are-being-discovered");
|
||||
},
|
||||
|
||||
injectionToken: syncBoxInjectionToken,
|
||||
});
|
||||
|
||||
export default updatesAreBeingDiscoveredInjectable;
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { computed } from "mobx";
|
||||
import syncBoxChannelInjectable from "./sync-box-channel.injectable";
|
||||
import { sendToAgnosticChannelInjectionToken } from "../channel/send-to-agnostic-channel-injection-token";
|
||||
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
||||
import type { SyncBox } from "./sync-box-injection-token";
|
||||
|
||||
const createSyncBoxInjectable = getInjectable({
|
||||
id: "create-sync-box",
|
||||
@ -37,8 +37,3 @@ const createSyncBoxInjectable = getInjectable({
|
||||
|
||||
export default createSyncBoxInjectable;
|
||||
|
||||
export interface SyncBox<TValue> {
|
||||
id: string;
|
||||
value: IComputedValue<TValue>;
|
||||
set: (value: TValue) => void;
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 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 type { Channel } from "../channel/channel-injection-token";
|
||||
import { channelInjectionToken } from "../channel/channel-injection-token";
|
||||
|
||||
export type SyncBoxInitialValueChannel = Channel<never, { id: string; value: unknown }[]>;
|
||||
|
||||
const syncBoxInitialValueChannelInjectable = getInjectable({
|
||||
id: "sync-box-initial-value-channel",
|
||||
|
||||
instantiate: (): SyncBoxInitialValueChannel => ({
|
||||
id: "sync-box-initial-value-channel",
|
||||
}),
|
||||
|
||||
injectionToken: channelInjectionToken,
|
||||
});
|
||||
|
||||
export default syncBoxInitialValueChannelInjectable;
|
||||
16
src/common/sync-box/sync-box-injection-token.ts
Normal file
16
src/common/sync-box/sync-box-injection-token.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
|
||||
export interface SyncBox<TValue> {
|
||||
id: string;
|
||||
value: IComputedValue<TValue>;
|
||||
set: (value: TValue) => void;
|
||||
}
|
||||
|
||||
export const syncBoxInjectionToken = getInjectionToken<SyncBox<any>>({
|
||||
id: "sync-box",
|
||||
});
|
||||
@ -6,47 +6,99 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { observe, runInAction } from "mobx";
|
||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import type { SyncBox } from "./create-sync-box.injectable";
|
||||
import createSyncBoxInjectable from "./create-sync-box.injectable";
|
||||
import applicationWindowInjectable from "../../main/start-main-application/lens-window/application-window/application-window.injectable";
|
||||
import { flushPromises } from "../test-utils/flush-promises";
|
||||
import type { SyncBox } from "./sync-box-injection-token";
|
||||
|
||||
describe("sync-box", () => {
|
||||
let syncBoxInMain: SyncBox<string>;
|
||||
let syncBoxInRenderer: SyncBox<string>;
|
||||
let applicationBuilder: ApplicationBuilder;
|
||||
|
||||
beforeEach(() => {
|
||||
applicationBuilder = getApplicationBuilder();
|
||||
|
||||
const someInjectable = getInjectable({
|
||||
id: "some-injectable",
|
||||
|
||||
instantiate: (di) => {
|
||||
const createSyncBox = di.inject(createSyncBoxInjectable);
|
||||
|
||||
return createSyncBox<string>("some-state");
|
||||
},
|
||||
});
|
||||
|
||||
applicationBuilder.dis.mainDi.register(someInjectable);
|
||||
applicationBuilder.dis.rendererDi.register(someInjectable);
|
||||
|
||||
syncBoxInMain = applicationBuilder.dis.mainDi.inject(someInjectable);
|
||||
syncBoxInRenderer = applicationBuilder.dis.rendererDi.inject(someInjectable);
|
||||
});
|
||||
|
||||
describe("when application starts", () => {
|
||||
beforeEach(() => {
|
||||
describe("given application is started, when value is set in main", () => {
|
||||
let valueInMain: string;
|
||||
let syncBoxInMain: SyncBox<string>;
|
||||
|
||||
beforeEach(async () => {
|
||||
syncBoxInMain = applicationBuilder.dis.mainDi.inject(someInjectable);
|
||||
// await applicationBuilder.start();
|
||||
|
||||
observe(syncBoxInMain.value, ({ newValue }) => {
|
||||
valueInMain = newValue as string;
|
||||
}, true);
|
||||
|
||||
runInAction(() => {
|
||||
syncBoxInMain.set("some-value-from-main");
|
||||
});
|
||||
});
|
||||
|
||||
it("", () => {
|
||||
|
||||
it("knows value in main", () => {
|
||||
expect(valueInMain).toBe("some-value-from-main");
|
||||
});
|
||||
|
||||
describe("when window starts", () => {
|
||||
it("", () => {
|
||||
let valueInRenderer: string;
|
||||
let syncBoxInRenderer: SyncBox<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
// applicationBuilder.
|
||||
|
||||
syncBoxInRenderer = applicationBuilder.dis.rendererDi.inject(someInjectable);
|
||||
|
||||
observe(syncBoxInRenderer.value, ({ newValue }) => {
|
||||
valueInRenderer = newValue as string;
|
||||
}, true);
|
||||
});
|
||||
|
||||
it("does not have the initial value yet", () => {
|
||||
expect(valueInRenderer).toBe(undefined);
|
||||
});
|
||||
|
||||
describe("when getting initial value resolves", () => {
|
||||
beforeEach(async () => {
|
||||
await flushPromises();
|
||||
});
|
||||
|
||||
it("has value in renderer", () => {
|
||||
expect(valueInRenderer).toBe("some-value-from-main");
|
||||
});
|
||||
|
||||
describe("when value is set from renderer", () => {
|
||||
beforeEach(() => {
|
||||
runInAction(() => {
|
||||
syncBoxInRenderer.set("some-value-from-renderer");
|
||||
});
|
||||
});
|
||||
|
||||
it("has value in main", () => {
|
||||
expect(valueInMain).toBe("some-value-from-renderer");
|
||||
});
|
||||
|
||||
it("has value in renderer", () => {
|
||||
expect(valueInRenderer).toBe("some-value-from-renderer");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when value is set from renderer before getting initial value from main resolves", () => {
|
||||
beforeEach(() => {
|
||||
runInAction(() => {
|
||||
syncBoxInRenderer.set("some-value-from-renderer");
|
||||
});
|
||||
});
|
||||
|
||||
it("has value in main", () => {
|
||||
expect(valueInMain).toBe("some-value-from-renderer");
|
||||
});
|
||||
|
||||
it("has value in renderer", () => {
|
||||
expect(valueInRenderer).toBe("some-value-from-renderer");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -54,16 +106,15 @@ describe("sync-box", () => {
|
||||
describe("when application starts with a window", () => {
|
||||
let valueInRenderer: string;
|
||||
let valueInMain: string;
|
||||
let syncBoxInMain: SyncBox<string>;
|
||||
let syncBoxInRenderer: SyncBox<string>;
|
||||
|
||||
beforeEach(async () => {
|
||||
syncBoxInMain = applicationBuilder.dis.mainDi.inject(someInjectable);
|
||||
syncBoxInRenderer = applicationBuilder.dis.rendererDi.inject(someInjectable);
|
||||
|
||||
await applicationBuilder.render();
|
||||
|
||||
const applicationWindow = applicationBuilder.dis.mainDi.inject(
|
||||
applicationWindowInjectable,
|
||||
);
|
||||
|
||||
await applicationWindow.show();
|
||||
|
||||
observe(syncBoxInRenderer.value, ({ newValue }) => {
|
||||
valueInRenderer = newValue as string;
|
||||
}, true);
|
||||
@ -73,11 +124,11 @@ describe("sync-box", () => {
|
||||
}, true);
|
||||
});
|
||||
|
||||
it("does not know default value in main", () => {
|
||||
it("does not know initial value in main", () => {
|
||||
expect(valueInMain).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not know default value in renderer", () => {
|
||||
it("does not know initial value in renderer", () => {
|
||||
expect(valueInRenderer).toBeUndefined();
|
||||
});
|
||||
|
||||
@ -114,3 +165,13 @@ describe("sync-box", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const someInjectable = getInjectable({
|
||||
id: "some-injectable",
|
||||
|
||||
instantiate: (di) => {
|
||||
const createSyncBox = di.inject(createSyncBoxInjectable);
|
||||
|
||||
return createSyncBox<string>("some-state");
|
||||
},
|
||||
});
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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 { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token";
|
||||
import syncBoxInitialValueChannelInjectable from "../../common/sync-box/sync-box-initial-value-channel.injectable";
|
||||
import { syncBoxInjectionToken } from "../../common/sync-box/sync-box-injection-token";
|
||||
|
||||
const syncBoxInitialValueChannelListenerInjectable = getInjectable({
|
||||
id: "sync-box-initial-value-channel-listener",
|
||||
|
||||
instantiate: (di) => {
|
||||
const channel = di.inject(syncBoxInitialValueChannelInjectable);
|
||||
const syncBoxes = di.injectMany(syncBoxInjectionToken);
|
||||
|
||||
return {
|
||||
channel,
|
||||
|
||||
handler: () =>
|
||||
syncBoxes.map((box) => ({
|
||||
id: box.id,
|
||||
value: box.value.get(),
|
||||
})),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: channelListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default syncBoxInitialValueChannelListenerInjectable;
|
||||
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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 { beforeFrameStartsInjectionToken } from "../before-frame-starts/before-frame-starts-injection-token";
|
||||
import { syncBoxInjectionToken } from "../../common/sync-box/sync-box-injection-token";
|
||||
import getValueFromChannelInjectable from "../channel/get-value-from-channel.injectable";
|
||||
import syncBoxInitialValueChannelInjectable from "../../common/sync-box/sync-box-initial-value-channel.injectable";
|
||||
import assert from "assert";
|
||||
|
||||
const provideInitialValuesForSyncBoxesInjectable = getInjectable({
|
||||
id: "provide-initial-values-for-sync-boxes",
|
||||
|
||||
instantiate: (di) => {
|
||||
const syncBoxes = di.injectMany(syncBoxInjectionToken);
|
||||
const getValueFromChannel = di.inject(getValueFromChannelInjectable);
|
||||
const syncBoxInitialValueChannel = di.inject(syncBoxInitialValueChannelInjectable);
|
||||
|
||||
return {
|
||||
run: async () => {
|
||||
const initialValues = await getValueFromChannel(syncBoxInitialValueChannel);
|
||||
|
||||
assert(initialValues);
|
||||
|
||||
initialValues.forEach(({ id, value }) => {
|
||||
const targetBox = syncBoxes.find(box => box.id === id);
|
||||
|
||||
if (targetBox) {
|
||||
targetBox.set(value);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeFrameStartsInjectionToken,
|
||||
});
|
||||
|
||||
export default provideInitialValuesForSyncBoxesInjectable;
|
||||
Loading…
Reference in New Issue
Block a user