From dbd8e3bebc2e2692ecffc9445ef56da44ce16a24 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Mon, 12 Sep 2022 11:21:22 -0400 Subject: [PATCH] Introduce and use AsyncSyncBox Signed-off-by: Sebastian Malton --- src/common/async-sync/create.ts | 53 +++++++++++++++++++ .../vars/build-version/box.injectable.ts | 19 +++++++ .../build-version/build-version.injectable.ts | 19 +++++++ .../vars/build-version/init.injectable.ts | 21 ++++++++ .../vars/setup-build-version.injectable.ts | 33 ------------ 5 files changed, 112 insertions(+), 33 deletions(-) create mode 100644 src/common/async-sync/create.ts create mode 100644 src/renderer/vars/build-version/box.injectable.ts create mode 100644 src/renderer/vars/build-version/build-version.injectable.ts create mode 100644 src/renderer/vars/build-version/init.injectable.ts delete mode 100644 src/renderer/vars/setup-build-version.injectable.ts diff --git a/src/common/async-sync/create.ts b/src/common/async-sync/create.ts new file mode 100644 index 0000000000..19adeb2bd4 --- /dev/null +++ b/src/common/async-sync/create.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type { DiContainerForInjection } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; + +export interface CreateAsyncSyncBoxArgs { + id: string; + init: (di: DiContainerForInjection) => Promise; +} + +type AsyncSyncBoxValue = { set: false } | { set: true; value: T }; + +export function createAsyncSyncBox(args: CreateAsyncSyncBoxArgs) { + const { id, init } = args; + + return getInjectable({ + id, + instantiate: (di) => { + let box: AsyncSyncBoxValue = { + set: false, + }; + let initCalled = false; + + return { + init: async () => { + if (initCalled) { + throw new Error(`Cannot initialized AsyncSyncBox ${id}) more than once`); + } + + initCalled = true; + box = { + set: true, + value: await init(di), + }; + }, + get: () => { + if (!initCalled) { + throw new Error(`AsyncSyncBox(${id}) has not been initialized yet`); + } + + if (!box.set) { + throw new Error(`AsyncSyncBox(${id}) has not finished initializing`); + } + + return box.value; + }, + }; + }, + }); +} diff --git a/src/renderer/vars/build-version/box.injectable.ts b/src/renderer/vars/build-version/box.injectable.ts new file mode 100644 index 0000000000..f6fc67380b --- /dev/null +++ b/src/renderer/vars/build-version/box.injectable.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { createAsyncSyncBox } from "../../../common/async-sync/create"; +import { requestFromChannelInjectionToken } from "../../../common/utils/channel/request-from-channel-injection-token"; +import { buildVersionChannel } from "../../../common/vars/build-semantic-version.injectable"; + +const buildVersionAsyncSyncBoxInjectable = createAsyncSyncBox({ + id: "build-version", + init: (di) => { + const requestFromChannel = di.inject(requestFromChannelInjectionToken); + + return requestFromChannel(buildVersionChannel); + }, +}); + +export default buildVersionAsyncSyncBoxInjectable; diff --git a/src/renderer/vars/build-version/build-version.injectable.ts b/src/renderer/vars/build-version/build-version.injectable.ts new file mode 100644 index 0000000000..2ad705dffa --- /dev/null +++ b/src/renderer/vars/build-version/build-version.injectable.ts @@ -0,0 +1,19 @@ +/** + * 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 { buildVersionInjectionToken } from "../../../common/vars/build-semantic-version.injectable"; +import buildVersionAsyncSyncBoxInjectable from "./box.injectable"; + +const buildVersionInjectable = getInjectable({ + id: "build-version", + instantiate: (di) => { + const buildVersionAsyncSyncBox = di.inject(buildVersionAsyncSyncBoxInjectable); + + return buildVersionAsyncSyncBox.get(); + }, + injectionToken: buildVersionInjectionToken, +}); + +export default buildVersionInjectable; diff --git a/src/renderer/vars/build-version/init.injectable.ts b/src/renderer/vars/build-version/init.injectable.ts new file mode 100644 index 0000000000..c31eec3527 --- /dev/null +++ b/src/renderer/vars/build-version/init.injectable.ts @@ -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 { beforeFrameStartsInjectionToken } from "../../before-frame-starts/before-frame-starts-injection-token"; +import buildVersionAsyncSyncBoxInjectable from "./box.injectable"; + +const initializeBuildVersionAsyncSyncBoxInjectable = getInjectable({ + id: "initialize-build-version-async-sync-box", + instantiate: (di) => { + const buildVersionAsyncSyncBox = di.inject(buildVersionAsyncSyncBoxInjectable); + + return { + run: () => buildVersionAsyncSyncBox.init(), + }; + }, + injectionToken: beforeFrameStartsInjectionToken, +}); + +export default initializeBuildVersionAsyncSyncBoxInjectable; diff --git a/src/renderer/vars/setup-build-version.injectable.ts b/src/renderer/vars/setup-build-version.injectable.ts deleted file mode 100644 index 6a40341388..0000000000 --- a/src/renderer/vars/setup-build-version.injectable.ts +++ /dev/null @@ -1,33 +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 { runInAction } from "mobx"; -import { requestFromChannelInjectionToken } from "../../common/utils/channel/request-from-channel-injection-token"; -import { buildVersionChannel, buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable"; -import { beforeFrameStartsInjectionToken } from "../before-frame-starts/before-frame-starts-injection-token"; - -const setupBuildVersionInjectable = getInjectable({ - id: "setup-build-version", - instantiate: (di) => { - const requestFromChannel = di.inject(requestFromChannelInjectionToken); - - return { - run: async () => { - const buildVersion = await requestFromChannel(buildVersionChannel); - - runInAction(() => { - di.register(getInjectable({ - id: "build-version", - instantiate: () => buildVersion, - injectionToken: buildVersionInjectionToken, - })); - }); - }, - }; - }, - injectionToken: beforeFrameStartsInjectionToken, -}); - -export default setupBuildVersionInjectable;