mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Extract agnostic and electron-main ways of starting application to separate packages (#7259)
* Introduce an agnostic way to start application is the Feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce directory for application-packages Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove non agnostic timeslots from agnostic application Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce empty package for electron main specific stuff for Application Feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce electron-main specific timeslots Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update injectable version Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update README Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Tweak export names to make them easier to import Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make starting of application synchronous for Electron main Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Tweak versions in package jsons Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate name of feature file Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> --------- Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
a917494e9c
commit
a9bd5ae7e2
2224
package-lock.json
generated
2224
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -130,11 +130,11 @@
|
|||||||
"@k8slens/node-fetch": "^6.5.0-alpha.0",
|
"@k8slens/node-fetch": "^6.5.0-alpha.0",
|
||||||
"@kubernetes/client-node": "^0.18.1",
|
"@kubernetes/client-node": "^0.18.1",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"@ogre-tools/fp": "^15.1.1",
|
"@ogre-tools/fp": "^15.1.2",
|
||||||
"@ogre-tools/injectable": "^15.1.1",
|
"@ogre-tools/injectable": "^15.1.2",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.2",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.2",
|
||||||
"@ogre-tools/injectable-react": "^15.1.1",
|
"@ogre-tools/injectable-react": "^15.1.2",
|
||||||
"@sentry/electron": "^3.0.8",
|
"@sentry/electron": "^3.0.8",
|
||||||
"@sentry/integrations": "^6.19.3",
|
"@sentry/integrations": "^6.19.3",
|
||||||
"@side/jest-runtime": "^1.1.0",
|
"@side/jest-runtime": "^1.1.0",
|
||||||
|
|||||||
@ -196,14 +196,16 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@k8slens/application": "^6.5.0-alpha.0",
|
"@k8slens/application": "^6.5.0-alpha.0",
|
||||||
|
"@k8slens/feature-core": "^6.5.0-alpha.0",
|
||||||
"@k8slens/core": "^6.5.0-alpha.0",
|
"@k8slens/core": "^6.5.0-alpha.0",
|
||||||
"@k8slens/ensure-binaries": "^6.5.0-alpha.0",
|
"@k8slens/ensure-binaries": "^6.5.0-alpha.0",
|
||||||
"@k8slens/generate-tray-icons": "^6.5.0-alpha.0",
|
"@k8slens/generate-tray-icons": "^6.5.0-alpha.0",
|
||||||
"@ogre-tools/fp": "^15.1.1",
|
"@ogre-tools/fp": "^15.1.2",
|
||||||
"@ogre-tools/injectable": "^15.1.1",
|
"@ogre-tools/injectable": "^15.1.2",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.2",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.2",
|
||||||
"@ogre-tools/injectable-react": "^15.1.1",
|
"@ogre-tools/injectable-react": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable-utils": "^15.1.2",
|
||||||
"mobx": "^6.8.0",
|
"mobx": "^6.8.0",
|
||||||
"rimraf": "^4.1.2"
|
"rimraf": "^4.1.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
# @k8slens/application
|
|
||||||
|
|
||||||
This package contains stuff related to creating Lens-applications.
|
|
||||||
|
|
||||||
In the beginning it will contain just the injection tokens used to configure the application.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
```bash
|
|
||||||
$ npm install @k8slens/application
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
As of now, this package doesn't do anything alone. It just provides you way to register implementation for contract.
|
|
||||||
|
|
||||||
Future ambition is that all stuff related to how applications are built will be relocated here.
|
|
||||||
|
|
||||||
39
packages/technical-features/application/agnostic/README.md
Normal file
39
packages/technical-features/application/agnostic/README.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# @k8slens/application
|
||||||
|
|
||||||
|
This package contains stuff related to creating Lens-applications.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install @k8slens/application-for-electron-main
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { applicationFeature, startApplicationInjectionToken } from "@k8slens/application";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
const di = createContainer("some-container");
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeature);
|
||||||
|
|
||||||
|
const startApplication = di.inject(startApplicationInjectionToken);
|
||||||
|
|
||||||
|
startApplication();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
#### Start application
|
||||||
|
`startApplicationInjectionToken`
|
||||||
|
|
||||||
|
Starts the application and calls timeslots in specified order. Check for timeslots for more info.
|
||||||
|
|
||||||
|
## Extendability
|
||||||
|
|
||||||
|
#### Timeslots
|
||||||
|
|
||||||
|
1. `beforeApplicationIsLoadingInjectionToken`
|
||||||
|
2. `onLoadOfApplicationInjectionToken`
|
||||||
|
3. `afterApplicationIsLoadedInjectionToken`
|
||||||
11
packages/technical-features/application/agnostic/index.ts
Normal file
11
packages/technical-features/application/agnostic/index.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export { applicationFeature } from "./src/feature";
|
||||||
|
|
||||||
|
export { onLoadOfApplicationInjectionToken } from "./src/start-application/timeslots/on-load-of-application-injection-token";
|
||||||
|
export { beforeApplicationIsLoadingInjectionToken } from "./src/start-application/timeslots/before-application-is-loading-injection-token";
|
||||||
|
export { afterApplicationIsLoadedInjectionToken } from "./src/start-application/timeslots/after-application-is-loaded-injection-token";
|
||||||
|
|
||||||
|
export type { StartApplication } from "./src/start-application/start-application.injectable";
|
||||||
|
export { startApplicationInjectionToken } from "./src/start-application/start-application.injectable";
|
||||||
|
|
||||||
|
export { applicationInformationToken } from "./src/application-information-token";
|
||||||
|
export type { ApplicationInformation } from "./src/application-information-token";
|
||||||
@ -1,2 +1,2 @@
|
|||||||
module.exports =
|
module.exports =
|
||||||
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;
|
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/lensapp/monorepo.git"
|
"url": "git+https://github.com/lensapp/lens.git"
|
||||||
},
|
},
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
@ -29,8 +29,15 @@
|
|||||||
"test": "jest --coverage --runInBand"
|
"test": "jest --coverage --runInBand"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^15.1.1",
|
"@k8slens/feature-core": "^6.5.0-alpha.0",
|
||||||
"@ogre-tools/injectable": "^15.1.1",
|
"@ogre-tools/fp": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable-utils": "^15.1.2",
|
||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
|
},
|
||||||
|
|
||||||
|
"devDependencies": {
|
||||||
|
"@async-fn/jest": "^1.6.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { getFeature } from "@k8slens/feature-core";
|
||||||
|
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
||||||
|
|
||||||
|
export const applicationFeature = getFeature({
|
||||||
|
id: "application",
|
||||||
|
|
||||||
|
register: (di) => {
|
||||||
|
autoRegister({
|
||||||
|
di,
|
||||||
|
targetModule: module,
|
||||||
|
|
||||||
|
getRequireContexts: () => [
|
||||||
|
require.context("./", true, /\.injectable\.(ts|tsx)$/),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import { runManyFor } from "@ogre-tools/injectable-utils";
|
||||||
|
import { beforeApplicationIsLoadingInjectionToken } from "./timeslots/before-application-is-loading-injection-token";
|
||||||
|
import { onLoadOfApplicationInjectionToken } from "./timeslots/on-load-of-application-injection-token";
|
||||||
|
import { afterApplicationIsLoadedInjectionToken } from "./timeslots/after-application-is-loaded-injection-token";
|
||||||
|
|
||||||
|
export type StartApplication = () => Promise<void>;
|
||||||
|
|
||||||
|
export const startApplicationInjectionToken =
|
||||||
|
getInjectionToken<StartApplication>({
|
||||||
|
id: "start-application-injection-token",
|
||||||
|
});
|
||||||
|
|
||||||
|
const startApplicationInjectable = getInjectable({
|
||||||
|
id: "start-application",
|
||||||
|
|
||||||
|
instantiate: (di): StartApplication => {
|
||||||
|
const runManyAsync = runManyFor(di)
|
||||||
|
|
||||||
|
const beforeApplicationIsLoading = runManyAsync(
|
||||||
|
beforeApplicationIsLoadingInjectionToken
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadOfApplication = runManyAsync(onLoadOfApplicationInjectionToken);
|
||||||
|
|
||||||
|
const afterApplicationIsLoaded = runManyAsync(
|
||||||
|
afterApplicationIsLoadedInjectionToken
|
||||||
|
);
|
||||||
|
|
||||||
|
return async () => {
|
||||||
|
await beforeApplicationIsLoading();
|
||||||
|
|
||||||
|
await onLoadOfApplication();
|
||||||
|
|
||||||
|
await afterApplicationIsLoaded();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: startApplicationInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default startApplicationInjectable;
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
createContainer,
|
||||||
|
DiContainer,
|
||||||
|
getInjectable,
|
||||||
|
} from "@ogre-tools/injectable";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
import { applicationFeature } from "../feature";
|
||||||
|
import { startApplicationInjectionToken } from "./start-application.injectable";
|
||||||
|
import { beforeApplicationIsLoadingInjectionToken } from "./timeslots/before-application-is-loading-injection-token";
|
||||||
|
import asyncFn, { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import { onLoadOfApplicationInjectionToken } from "./timeslots/on-load-of-application-injection-token";
|
||||||
|
import { afterApplicationIsLoadedInjectionToken } from "./timeslots/after-application-is-loaded-injection-token";
|
||||||
|
|
||||||
|
describe("starting-of-application", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
|
||||||
|
let beforeApplicationIsLoadingMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
let onLoadOfApplicationMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
let afterApplicationIsLoadedMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeature);
|
||||||
|
|
||||||
|
beforeApplicationIsLoadingMock = asyncFn();
|
||||||
|
onLoadOfApplicationMock = asyncFn();
|
||||||
|
afterApplicationIsLoadedMock = asyncFn();
|
||||||
|
|
||||||
|
const beforeApplicationIsLoadingInjectable = getInjectable({
|
||||||
|
id: "before-application-is-loading",
|
||||||
|
instantiate: () => ({ run: beforeApplicationIsLoadingMock }),
|
||||||
|
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onLoadOfApplicationInjectable = getInjectable({
|
||||||
|
id: "on-load-of-application",
|
||||||
|
instantiate: () => ({ run: onLoadOfApplicationMock }),
|
||||||
|
injectionToken: onLoadOfApplicationInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const afterApplicationIsLoadedInjectable = getInjectable({
|
||||||
|
id: "after-application-is-loaded",
|
||||||
|
instantiate: () => ({ run: afterApplicationIsLoadedMock }),
|
||||||
|
injectionToken: afterApplicationIsLoadedInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
di.register(
|
||||||
|
beforeApplicationIsLoadingInjectable,
|
||||||
|
onLoadOfApplicationInjectable,
|
||||||
|
afterApplicationIsLoadedInjectable
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when application is started", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const startApplication = di.inject(startApplicationInjectionToken);
|
||||||
|
|
||||||
|
startApplication();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls runnables registered in before application is loading", () => {
|
||||||
|
expect(beforeApplicationIsLoadingMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when runnables in before application is loading resolve", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await beforeApplicationIsLoadingMock.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls runnables registered in on load of application", () => {
|
||||||
|
expect(onLoadOfApplicationMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when runnables in before application is loading resolve, calls runnables registered in after load of application", async () => {
|
||||||
|
await onLoadOfApplicationMock.resolve();
|
||||||
|
|
||||||
|
expect(afterApplicationIsLoadedMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Runnable } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
export const afterApplicationIsLoadedInjectionToken =
|
||||||
|
getInjectionToken<Runnable>({
|
||||||
|
id: "after-application-is-loaded-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Runnable } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
export const beforeApplicationIsLoadingInjectionToken =
|
||||||
|
getInjectionToken<Runnable>({
|
||||||
|
id: "before-application-is-loading-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Runnable } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
export const onLoadOfApplicationInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "on-load-of-application",
|
||||||
|
});
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
# @k8slens/application-for-electron-main
|
||||||
|
|
||||||
|
This Feature extends `@k8slens/application` with Electron specifics.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
```bash
|
||||||
|
$ npm install @k8slens/application-for-electron-main
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { applicationFeature, startApplicationInjectionToken } from "@k8slens/application";
|
||||||
|
import { applicationFeatureForElectronMain } from "@k8slens/application-for-electron-main";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
const di = createContainer("some-container");
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeature, applicationFeatureForElectronMain);
|
||||||
|
|
||||||
|
const startApplication = di.inject(startApplicationInjectionToken);
|
||||||
|
|
||||||
|
startApplication();
|
||||||
|
```
|
||||||
|
|
||||||
|
# Extendability
|
||||||
|
|
||||||
|
### Timeslots
|
||||||
|
|
||||||
|
#### `beforeAnythingInjectionToken`
|
||||||
|
|
||||||
|
Runnables registered here will be called before anything else. **Special requirement** here is that everything here needs to be synchronous.
|
||||||
|
|
||||||
|
#### `beforeElectronIsReadyInjectionToken`
|
||||||
|
|
||||||
|
Runnables registered here will be called right after runnables in `beforeAnythingInjectionToken` but still before we are sure that Electron application is ready (`electron.app.whenReady()`). **Special requirement** here is that everything here needs to be synchronous.
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { overrideSideEffectsWithFakes } from "./src/override-side-effects-with-fakes";
|
||||||
|
|
||||||
|
export { beforeElectronIsReadyInjectionToken } from "./src/start-application/timeslots/before-electron-is-ready-injection-token";
|
||||||
|
export { beforeAnythingInjectionToken } from "./src/start-application/timeslots/before-anything-injection-token";
|
||||||
|
|
||||||
|
export { applicationFeatureForElectronMain } from "./src/feature";
|
||||||
|
|
||||||
|
export const testUtils = { overrideSideEffectsWithFakes }
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
module.exports =
|
||||||
|
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "@k8slens/application-for-electron-main",
|
||||||
|
"private": false,
|
||||||
|
"version": "6.5.0-alpha.0",
|
||||||
|
"description": "Electron's main specifics for creating Lens applications",
|
||||||
|
"type": "commonjs",
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public",
|
||||||
|
"registry": "https://registry.npmjs.org/"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/lensapp/lens.git"
|
||||||
|
},
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"author": {
|
||||||
|
"name": "OpenLens Authors",
|
||||||
|
"email": "info@k8slens.dev"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"dev": "webpack --mode=development --watch",
|
||||||
|
"test": "jest --coverage --runInBand"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@k8slens/feature-core": "^6.5.0-alpha.0",
|
||||||
|
"@k8slens/application": "^6.5.0-alpha.0",
|
||||||
|
"@ogre-tools/injectable": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.2",
|
||||||
|
"@ogre-tools/injectable-utils": "^15.1.2",
|
||||||
|
"electron": "^19.1.9"
|
||||||
|
},
|
||||||
|
|
||||||
|
"devDependencies": {
|
||||||
|
"@async-fn/jest": "^1.6.4",
|
||||||
|
"@ogre-tools/test-utils": "^15.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* 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 { app } from "electron";
|
||||||
|
|
||||||
|
const electronAppInjectable = getInjectable({
|
||||||
|
id: "electron-app",
|
||||||
|
instantiate: () => app,
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default electronAppInjectable;
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import electronAppInjectable from "./electron-app.injectable";
|
||||||
|
import { app } from 'electron';
|
||||||
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
|
import { applicationFeatureForElectronMain } from "../feature";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
|
||||||
|
describe('electron-app', () => {
|
||||||
|
it('is electron app', () => {
|
||||||
|
const di = createContainer('irrelevant');
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeatureForElectronMain)
|
||||||
|
|
||||||
|
const actual = di.inject(electronAppInjectable);
|
||||||
|
|
||||||
|
expect(actual).toBe(app);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { getFeature } from "@k8slens/feature-core";
|
||||||
|
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
||||||
|
import { applicationFeature } from '@k8slens/application';
|
||||||
|
|
||||||
|
export const applicationFeatureForElectronMain = getFeature({
|
||||||
|
id: "application-for-electron-main",
|
||||||
|
|
||||||
|
register: (di) => {
|
||||||
|
autoRegister({
|
||||||
|
di,
|
||||||
|
targetModule: module,
|
||||||
|
|
||||||
|
getRequireContexts: () => [
|
||||||
|
require.context("./", true, /\.injectable\.(ts|tsx)$/),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
dependencies: [
|
||||||
|
applicationFeature
|
||||||
|
]
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import whenAppIsReadyInjectable from "./start-application/when-app-is-ready.injectable";
|
||||||
|
|
||||||
|
export const overrideSideEffectsWithFakes = (di: DiContainer) => {
|
||||||
|
di.override(whenAppIsReadyInjectable, () => () => Promise.resolve())
|
||||||
|
};
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
DiContainer,
|
||||||
|
getInjectable,
|
||||||
|
instantiationDecoratorToken,
|
||||||
|
lifecycleEnum,
|
||||||
|
} from "@ogre-tools/injectable";
|
||||||
|
import { startApplicationInjectionToken } from "@k8slens/application";
|
||||||
|
import whenAppIsReadyInjectable from "./when-app-is-ready.injectable";
|
||||||
|
import { beforeAnythingInjectionToken } from "./timeslots/before-anything-injection-token";
|
||||||
|
import { beforeElectronIsReadyInjectionToken } from "./timeslots/before-electron-is-ready-injection-token";
|
||||||
|
import { runManySyncFor } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
const startElectronApplicationInjectable = getInjectable({
|
||||||
|
id: "start-electron-application",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
decorate:
|
||||||
|
(toBeDecorated: unknown) =>
|
||||||
|
(di: DiContainer, ...args: unknown[]) => {
|
||||||
|
const whenAppIsReady = di.inject(whenAppIsReadyInjectable);
|
||||||
|
const runManySync = runManySyncFor(di);
|
||||||
|
const beforeAnything = runManySync(beforeAnythingInjectionToken);
|
||||||
|
const beforeElectronIsReady = runManySync(
|
||||||
|
beforeElectronIsReadyInjectionToken
|
||||||
|
);
|
||||||
|
|
||||||
|
const typedToBeDecorated = toBeDecorated as (
|
||||||
|
di: DiContainer,
|
||||||
|
...args: unknown[]
|
||||||
|
) => unknown;
|
||||||
|
|
||||||
|
const startApplication = typedToBeDecorated(di, ...args) as (
|
||||||
|
...args: unknown[]
|
||||||
|
) => unknown;
|
||||||
|
|
||||||
|
return (...startApplicationArgs: unknown[]) => {
|
||||||
|
beforeAnything();
|
||||||
|
beforeElectronIsReady();
|
||||||
|
|
||||||
|
return (async () => {
|
||||||
|
await whenAppIsReady();
|
||||||
|
|
||||||
|
return startApplication(...startApplicationArgs);
|
||||||
|
})()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
target: startApplicationInjectionToken,
|
||||||
|
}),
|
||||||
|
|
||||||
|
decorable: false,
|
||||||
|
|
||||||
|
injectionToken: instantiationDecoratorToken,
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.singleton,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default startElectronApplicationInjectable;
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Runnable } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
export const beforeAnythingInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "before-anything",
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Runnable } from "@ogre-tools/injectable-utils";
|
||||||
|
|
||||||
|
export const beforeElectronIsReadyInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "before-electron-is-ready-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import electronAppInjectable from "../electron/electron-app.injectable";
|
||||||
|
|
||||||
|
const whenAppIsReadyInjectable = getInjectable({
|
||||||
|
id: "when-app-is-ready",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const electronApp = di.inject(electronAppInjectable);
|
||||||
|
|
||||||
|
return () => electronApp.whenReady();
|
||||||
|
},
|
||||||
|
|
||||||
|
decorable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default whenAppIsReadyInjectable;
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import { createContainer, DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import { applicationFeatureForElectronMain } from "../../feature";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
import whenAppIsReadyInjectable from "../when-app-is-ready.injectable";
|
||||||
|
import { getPromiseStatus } from "@ogre-tools/test-utils";
|
||||||
|
import electronAppInjectable from "../../electron/electron-app.injectable";
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
|
||||||
|
describe("when-app-is-ready", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let whenReadyMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeatureForElectronMain);
|
||||||
|
|
||||||
|
whenReadyMock = asyncFn();
|
||||||
|
|
||||||
|
di.override(
|
||||||
|
electronAppInjectable,
|
||||||
|
() => ({ whenReady: whenReadyMock } as unknown)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when called", () => {
|
||||||
|
let actualPromise: Promise<void>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const whenAppIsReady = di.inject(whenAppIsReadyInjectable);
|
||||||
|
|
||||||
|
actualPromise = whenAppIsReady();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not resolve yet", async () => {
|
||||||
|
const promiseStatus = await getPromiseStatus(actualPromise);
|
||||||
|
|
||||||
|
expect(promiseStatus.fulfilled).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when app is ready, resolves", async () => {
|
||||||
|
await whenReadyMock.resolve();
|
||||||
|
|
||||||
|
const promiseStatus = await getPromiseStatus(actualPromise);
|
||||||
|
|
||||||
|
expect(promiseStatus.fulfilled).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
import {
|
||||||
|
createContainer,
|
||||||
|
DiContainer,
|
||||||
|
getInjectable,
|
||||||
|
} from "@ogre-tools/injectable";
|
||||||
|
import { registerFeature } from "@k8slens/feature-core";
|
||||||
|
import { applicationFeatureForElectronMain } from "./feature";
|
||||||
|
import {
|
||||||
|
beforeApplicationIsLoadingInjectionToken,
|
||||||
|
startApplicationInjectionToken,
|
||||||
|
} from "@k8slens/application";
|
||||||
|
import asyncFn, { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import whenAppIsReadyInjectable from "./start-application/when-app-is-ready.injectable";
|
||||||
|
import { beforeAnythingInjectionToken } from "./start-application/timeslots/before-anything-injection-token";
|
||||||
|
import { beforeElectronIsReadyInjectionToken } from "./start-application/timeslots/before-electron-is-ready-injection-token";
|
||||||
|
|
||||||
|
describe("starting-of-electron-main-application", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let beforeAnythingMock: jest.Mock;
|
||||||
|
let beforeElectronIsReadyMock: jest.Mock;
|
||||||
|
let beforeApplicationIsLoadingMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
let whenAppIsReadyMock: AsyncFnMock<() => Promise<void>>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
beforeAnythingMock = jest.fn();
|
||||||
|
beforeElectronIsReadyMock = jest.fn();
|
||||||
|
|
||||||
|
beforeApplicationIsLoadingMock = asyncFn();
|
||||||
|
whenAppIsReadyMock = asyncFn();
|
||||||
|
|
||||||
|
registerFeature(di, applicationFeatureForElectronMain);
|
||||||
|
|
||||||
|
const beforeAnythingIsLoadingInjectable = getInjectable({
|
||||||
|
id: "before-anything",
|
||||||
|
instantiate: () => ({ run: beforeAnythingMock }),
|
||||||
|
injectionToken: beforeAnythingInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const beforeElectronIsReadyIsLoadingInjectable = getInjectable({
|
||||||
|
id: "before-electron-is-ready",
|
||||||
|
instantiate: () => ({ run: beforeElectronIsReadyMock }),
|
||||||
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const beforeApplicationIsLoadingInjectable = getInjectable({
|
||||||
|
id: "before-application-is-loading",
|
||||||
|
instantiate: () => ({ run: beforeApplicationIsLoadingMock }),
|
||||||
|
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
di.register(
|
||||||
|
beforeAnythingIsLoadingInjectable,
|
||||||
|
beforeElectronIsReadyIsLoadingInjectable,
|
||||||
|
beforeApplicationIsLoadingInjectable
|
||||||
|
);
|
||||||
|
|
||||||
|
di.override(whenAppIsReadyInjectable, () => whenAppIsReadyMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when application is started", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const startApplication = di.inject(startApplicationInjectionToken);
|
||||||
|
|
||||||
|
startApplication();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls for synchronous runnables for before anything", () => {
|
||||||
|
expect(beforeAnythingMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls for synchronous runnables for before electron is ready", () => {
|
||||||
|
expect(beforeElectronIsReadyMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
it("calls to wait when electron is ready", () => {
|
||||||
|
expect(whenAppIsReadyMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not call runnables for before application is loading yet", () => {
|
||||||
|
expect(beforeApplicationIsLoadingMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when electron is ready", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await whenAppIsReadyMock.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls runnables for before application is loading", () => {
|
||||||
|
expect(beforeApplicationIsLoadingMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "@k8slens/typescript/config/base.json"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
module.exports = require("@k8slens/webpack").configForNode;
|
||||||
@ -1,3 +0,0 @@
|
|||||||
export { applicationInformationToken } from "./src/application-information-token";
|
|
||||||
export type { ApplicationInformation } from "./src/application-information-token";
|
|
||||||
|
|
||||||
@ -31,6 +31,6 @@
|
|||||||
"test": "jest --coverage --runInBand"
|
"test": "jest --coverage --runInBand"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/injectable": "^15.1.1"
|
"@ogre-tools/injectable": "^15.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user