Skip to content

Commit

Permalink
Refactor runningServices usecase into serviceManager
Browse files Browse the repository at this point in the history
  • Loading branch information
garronej committed Oct 5, 2023
1 parent 5d3508e commit e6e78a6
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 215 deletions.
2 changes: 0 additions & 2 deletions web/src/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ export async function createCore(params: CoreParams) {
);
}

core.dispatch(usecases.runningService.protectedThunks.initialize());

return core;
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/core/usecases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as launcher from "./launcher";
import * as projectConfigs from "./projectConfigs";
import * as publicIp from "./publicIp";
import * as restorablePackageConfigs from "./restorablePackageConfigs";
import * as runningService from "./runningService";
import * as serviceManager from "./serviceManager";
import * as userAuthentication from "./userAuthentication";
import * as userConfigs from "./userConfigs";
import * as secretsEditor from "./secretsEditor";
Expand All @@ -24,7 +24,7 @@ export const usecases = {
projectConfigs,
publicIp,
restorablePackageConfigs,
runningService,
serviceManager,
userAuthentication,
userConfigs,
secretsEditor,
Expand Down
3 changes: 3 additions & 0 deletions web/src/core/usecases/serviceManager/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./state";
export * from "./thunks";
export * from "./selectors";
44 changes: 44 additions & 0 deletions web/src/core/usecases/serviceManager/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { State as RootState } from "core/core";
import { createSelector } from "@reduxjs/toolkit";

import { name, type RunningService } from "./state";

const runningServices = (rootState: RootState): RunningService[] | undefined => {
const { runningServices } = rootState[name];

if (runningServices === undefined) {
return undefined;
}

return [...runningServices].sort((a, b) => b.startedAt - a.startedAt);
};

const isUpdating = (rootState: RootState): boolean => {
const { isUpdating } = rootState[name];
return isUpdating;
};

const deletableRunningServices = createSelector(runningServices, runningServices =>
(runningServices ?? []).filter(({ isOwned }) => isOwned)
);

const isThereNonOwnedServices = createSelector(
runningServices,
runningServices =>
(runningServices ?? []).find(({ isOwned }) => !isOwned) !== undefined
);

const isThereOwnedSharedServices = createSelector(
runningServices,
runningServices =>
(runningServices ?? []).find(({ isOwned, isShared }) => isOwned && isShared) !==
undefined
);

export const selectors = {
runningServices,
deletableRunningServices,
isUpdating,
isThereNonOwnedServices,
isThereOwnedSharedServices
};
104 changes: 104 additions & 0 deletions web/src/core/usecases/serviceManager/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { assert } from "tsafe/assert";
import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
import { id } from "tsafe/id";

type State = {
isUpdating: boolean;
runningServices: undefined | RunningService[];
};

export type RunningService = RunningService.Owned | RunningService.NotOwned;

export declare namespace RunningService {
export type Common = {
id: string;
packageName: string;
friendlyName: string;
logoUrl: string | undefined;
monitoringUrl: string | undefined;
isStarting: boolean;
startedAt: number;
/** Undefined if the service don't use the token */
vaultTokenExpirationTime: number | undefined;
s3TokenExpirationTime: number | undefined;
urls: string[];
postInstallInstructions: string | undefined;
env: Record<string, string>;
};

export type Owned = Common & {
isShared: boolean;
isOwned: true;
};

export type NotOwned = Common & {
isShared: true;
isOwned: false;
ownerUsername: string;
};
}

export const name = "serviceManager";

export const { reducer, actions } = createSlice({
name,
"initialState": id<State>({
"isUpdating": false,
"runningServices": undefined
}),
"reducers": {
"updateStarted": state => {
state.isUpdating = true;
},
"updateCompleted": (
_state,
{ payload }: PayloadAction<{ runningServices: RunningService[] }>
) => {
const { runningServices } = payload;

return id<State>({
"isUpdating": false,
runningServices
});
},
"serviceStarted": (
state,
{
payload
}: PayloadAction<{
serviceId: string;
doOverwriteStaredAtToNow: boolean;
}>
) => {
const { serviceId, doOverwriteStaredAtToNow } = payload;
const { runningServices } = state;

assert(runningServices !== undefined);

const runningService = runningServices.find(({ id }) => id === serviceId);

if (runningService === undefined) {
return;
}

runningService.isStarting = false;

if (doOverwriteStaredAtToNow) {
//NOTE: Harmless hack to improve UI readability.
runningService.startedAt = Date.now();
}
},
"serviceStopped": (state, { payload }: PayloadAction<{ serviceId: string }>) => {
const { serviceId } = payload;

const { runningServices } = state;
assert(runningServices !== undefined);

runningServices.splice(
runningServices.findIndex(({ id }) => id === serviceId),
1
);
}
}
});
Loading

0 comments on commit e6e78a6

Please sign in to comment.