Introduce directory for application-packages

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen committed 2023-03-02 08:47:02 +02:00
1 parent 24aedf4fad
commit 1a1ce8ee6c
18 files changed

No files matched your search

@@ -0,0 +1,18 @@
# @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.
@@ -0,0 +1,23 @@
export { feature } 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 { beforeAnythingInjectionToken } from "./src/start-application/timeslots/before-anything-injection-token";
export { afterBeforeAnythingInjectionToken } from "./src/start-application/timeslots/after-before-anything-injection-token";
export { afterApplicationIsLoadedInjectionToken } from "./src/start-application/timeslots/after-application-is-loaded-injection-token";
export { untilReadyToStartInjectionToken } from "./src/start-application/triggers/until-ready-to-start-injection-token";
export type { UntilReadyToStart } from "./src/start-application/triggers/until-ready-to-start-injection-token";
export { untilApplicationIsShownInjectionToken } from "./src/start-application/triggers/until-application-is-shown-injection-token";
export type { UntilApplicationIsShown } from "./src/start-application/triggers/until-application-is-shown-injection-token";
export { untilApplicationIsReadyToLoadInjectionToken } from "./src/start-application/triggers/until-application-is-ready-to-load-injection-token";
export type { UntilApplicationIsReadyToLoad } from "./src/start-application/triggers/until-application-is-ready-to-load-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";
@@ -0,0 +1,2 @@
module.exports =
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;
@@ -0,0 +1,43 @@
{
"name": "@k8slens/application",
"private": false,
"version": "6.4.0-beta.13",
"description": "Package 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/monorepo.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": "^0.0.1",
"@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
"@ogre-tools/injectable-utils": "^15.1.1",
"lodash": "^4.17.15"
},
"devDependencies": {
"@async-fn/jest": "^1.6.4"
}
}
@@ -0,0 +1,24 @@
/**
* 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";
export type ApplicationInformation = {
name: string;
version: string;
productName: string;
copyright: string;
description: string;
k8sProxyVersion: string,
bundledKubectlVersion: string,
bundledHelmVersion: string,
sentryDsn: string,
contentSecurityPolicy: string,
welcomeRoute: string,
updatingIsEnabled: boolean;
}
export const applicationInformationToken = getInjectionToken<ApplicationInformation>({
id: "application-information-token",
});
@@ -0,0 +1,17 @@
import { getFeature } from "@k8slens/feature-core";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
export const feature = getFeature({
id: "application",
register: (di) => {
autoRegister({
di,
targetModule: module,
getRequireContexts: () => [
require.context("./", true, /\.injectable\.(ts|tsx)$/),
],
});
},
});
@@ -0,0 +1,75 @@
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
import { runManySyncFor, runManyFor } from "@ogre-tools/injectable-utils";
import { beforeAnythingInjectionToken } from "./timeslots/before-anything-injection-token";
import {
afterBeforeAnythingInjectionToken
} from "./timeslots/after-before-anything-injection-token";
import { untilReadyToStartInjectionToken } from "./triggers/until-ready-to-start-injection-token";
import {
beforeApplicationIsLoadingInjectionToken
} from "./timeslots/before-application-is-loading-injection-token";
import { untilApplicationIsReadyToLoadInjectionToken } from "./triggers/until-application-is-ready-to-load-injection-token";
import {
onLoadOfApplicationInjectionToken
} from "./timeslots/on-load-of-application-injection-token";
import {
afterApplicationIsLoadedInjectionToken
} from "./timeslots/after-application-is-loaded-injection-token";
import { untilApplicationIsShownInjectionToken } from "./triggers/until-application-is-shown-injection-token";
export type StartApplication = () => void;
export const startApplicationInjectionToken =
getInjectionToken<StartApplication>({
id: "start-application-injection-token",
});
const startApplicationInjectable = getInjectable({
id: "start-application",
instantiate: (di): StartApplication => {
const untilReadyToStart = di.inject(untilReadyToStartInjectionToken);
const untilApplicationIsReadyToLoad = di.inject(untilApplicationIsReadyToLoadInjectionToken);
const untilApplicationIsShown = di.inject(untilApplicationIsShownInjectionToken);
const runManyAsync = runManyFor(di)
const runManySync = runManySyncFor(di)
const beforeAnything = runManySync(
beforeAnythingInjectionToken
);
const afterBeforeAnything = runManySync(
afterBeforeAnythingInjectionToken
);
const beforeApplicationIsLoading = runManyAsync(
beforeApplicationIsLoadingInjectionToken
);
const onLoadOfApplication = runManyAsync(onLoadOfApplicationInjectionToken);
const afterApplicationIsLoaded = runManyAsync(
afterApplicationIsLoadedInjectionToken
);
return async () => {
beforeAnything();
afterBeforeAnything();
await untilReadyToStart()
await beforeApplicationIsLoading();
await untilApplicationIsReadyToLoad();
await onLoadOfApplication();
await untilApplicationIsShown();
await afterApplicationIsLoaded();
};
},
injectionToken: startApplicationInjectionToken,
});
export default startApplicationInjectable;
@@ -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,6 @@
import { getInjectionToken } from "@ogre-tools/injectable";
import type { Runnable } from "@ogre-tools/injectable-utils";
export const afterBeforeAnythingInjectionToken = getInjectionToken<Runnable>({
id: "after-before-anything",
});
@@ -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,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,8 @@
import { getInjectionToken } from "@ogre-tools/injectable";
export type UntilApplicationIsReadyToLoad = () => Promise<void>;
export const untilApplicationIsReadyToLoadInjectionToken =
getInjectionToken<UntilApplicationIsReadyToLoad>({
id: "until-application-is-ready-to-load-injection-token",
});
@@ -0,0 +1,8 @@
import { getInjectionToken } from "@ogre-tools/injectable";
export type UntilApplicationIsShown = () => Promise<void>;
export const untilApplicationIsShownInjectionToken =
getInjectionToken<UntilApplicationIsShown>({
id: "until-application-is-shown-injection-token",
});
@@ -0,0 +1,8 @@
import { getInjectionToken } from "@ogre-tools/injectable";
export type UntilReadyToStart = () => Promise<void>;
export const untilReadyToStartInjectionToken =
getInjectionToken<UntilReadyToStart>({
id: "until-ready-to-start-injection-token",
});
@@ -0,0 +1,192 @@
import {
createContainer,
DiContainer,
getInjectable,
} from "@ogre-tools/injectable";
import { registerFeature } from "@k8slens/feature-core";
import { feature } from "./feature";
import { startApplicationInjectionToken } from "./start-application/start-application.injectable";
import { beforeAnythingInjectionToken } from "./start-application/timeslots/before-anything-injection-token";
import { afterBeforeAnythingInjectionToken } from "./start-application/timeslots/after-before-anything-injection-token";
import { beforeApplicationIsLoadingInjectionToken } from "./start-application/timeslots/before-application-is-loading-injection-token";
import { untilReadyToStartInjectionToken } from "./start-application/triggers/until-ready-to-start-injection-token";
import asyncFn, { AsyncFnMock } from "@async-fn/jest";
import { untilApplicationIsReadyToLoadInjectionToken } from "./start-application/triggers/until-application-is-ready-to-load-injection-token";
import { onLoadOfApplicationInjectionToken } from "./start-application/timeslots/on-load-of-application-injection-token";
import { untilApplicationIsShownInjectionToken } from "./start-application/triggers/until-application-is-shown-injection-token";
import { afterApplicationIsLoadedInjectionToken } from "./start-application/timeslots/after-application-is-loaded-injection-token";
describe("starting-application", () => {
let di: DiContainer;
let untilReadyToStartMock: AsyncFnMock<() => Promise<void>>;
let untilApplicationIsReadyToLoadMock: AsyncFnMock<() => Promise<void>>;
let untilApplicationIsShownMock: AsyncFnMock<() => Promise<void>>;
let beforeAnythingMock: jest.Mock;
let afterBeforeAnythingMock: jest.Mock;
let beforeApplicationIsLoadingMock: AsyncFnMock<() => Promise<void>>;
let onLoadOfApplicationMock: AsyncFnMock<() => Promise<void>>;
let afterApplicationIsLoadedMock: AsyncFnMock<() => Promise<void>>;
beforeEach(() => {
di = createContainer("irrelevant");
registerFeature(di, feature);
untilReadyToStartMock = asyncFn();
untilApplicationIsReadyToLoadMock = asyncFn();
untilApplicationIsShownMock = asyncFn();
beforeAnythingMock = jest.fn();
afterBeforeAnythingMock = jest.fn();
beforeApplicationIsLoadingMock = asyncFn();
onLoadOfApplicationMock = asyncFn();
afterApplicationIsLoadedMock = asyncFn();
const beforeAnythingInjectable = getInjectable({
id: "before-anything",
instantiate: () => ({ run: beforeAnythingMock }),
injectionToken: beforeAnythingInjectionToken,
});
const afterBeforeAnythingInjectable = getInjectable({
id: "after-before-anything",
instantiate: () => ({ run: afterBeforeAnythingMock }),
injectionToken: afterBeforeAnythingInjectionToken,
});
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,
});
const untilReadyToStartInjectable = getInjectable({
id: "until-ready-to-start",
instantiate: () => untilReadyToStartMock,
injectionToken: untilReadyToStartInjectionToken,
});
const untilApplicationIsReadyToLoadInjectable = getInjectable({
id: "until-application-is-ready-to-load",
instantiate: () => untilApplicationIsReadyToLoadMock,
injectionToken: untilApplicationIsReadyToLoadInjectionToken,
});
const untilApplicationIsShownInjectable = getInjectable({
id: "until-application-is-shown",
instantiate: () => untilApplicationIsShownMock,
injectionToken: untilApplicationIsShownInjectionToken,
});
di.register(
untilReadyToStartInjectable,
untilApplicationIsReadyToLoadInjectable,
untilApplicationIsShownInjectable,
beforeAnythingInjectable,
afterBeforeAnythingInjectable,
beforeApplicationIsLoadingInjectable,
onLoadOfApplicationInjectable,
afterApplicationIsLoadedInjectable
);
});
describe("when application is started", () => {
beforeEach(() => {
const startApplication = di.inject(startApplicationInjectionToken);
startApplication();
});
it("calls the runnable registered in the before anything timeslot", () => {
expect(beforeAnythingMock).toHaveBeenCalled();
});
it("calls the runnable registered in the after before anything timeslot", () => {
expect(afterBeforeAnythingMock).toHaveBeenCalled();
});
it("does not call runnables registered in before application is loading yet", () => {
expect(beforeApplicationIsLoadingMock).not.toHaveBeenCalled();
});
it("calls the trigger for when application is ready to start", () => {
expect(untilReadyToStartMock).toHaveBeenCalled();
});
describe("when application is ready to be started", () => {
beforeEach(async () => {
await untilReadyToStartMock.resolve();
});
it("calls runnables registered in before application is loading", () => {
expect(beforeApplicationIsLoadingMock).toHaveBeenCalled();
});
it("does not call the trigger for until application is ready to load yet", () => {
expect(untilApplicationIsReadyToLoadMock).not.toHaveBeenCalled();
});
describe("when runnables in before application is loading resolve", () => {
beforeEach(async () => {
await beforeApplicationIsLoadingMock.resolve();
});
it("calls the trigger for until application is ready to load", () => {
expect(untilApplicationIsReadyToLoadMock).toHaveBeenCalled();
});
it("does not call runnables registered in on load of application yet", () => {
expect(onLoadOfApplicationMock).not.toHaveBeenCalled();
});
describe("when until application is ready to load resolves", () => {
beforeEach(async () => {
await untilApplicationIsReadyToLoadMock.resolve();
});
it("calls runnables registered in on load of application", () => {
expect(onLoadOfApplicationMock).toHaveBeenCalled();
});
it("does not call the trigger for until application is shown yet", () => {
expect(untilApplicationIsShownMock).not.toHaveBeenCalled();
});
describe("when runnables in before application is loading resolve", () => {
beforeEach(async () => {
await onLoadOfApplicationMock.resolve();
});
it("calls the trigger for until application is shown", () => {
expect(untilApplicationIsShownMock).toHaveBeenCalled();
});
it("does not call runnables registered in after load of application yet", () => {
expect(afterApplicationIsLoadedMock).not.toHaveBeenCalled();
});
it('when until application is shown resolves, calls runnables registered in after load of application', async () => {
await untilApplicationIsShownMock.resolve();
expect(afterApplicationIsLoadedMock).toHaveBeenCalled();
});
});
});
});
});
});
});
@@ -0,0 +1,3 @@
{
"extends": "@k8slens/typescript/config/base.json"
}
@@ -0,0 +1 @@
module.exports = require("@k8slens/webpack").configForNode;