Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add storage info #218

Merged
merged 4 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ export default defineConfig({
},
plugins: [
externalizeDepsPlugin({
exclude: ['@holochain/client', 'nanoid', 'appstore-tools', '@spartan-hc/bundles'],
exclude: [
'@holochain/client',
'nanoid',
'appstore-tools',
'@spartan-hc/bundles',
'get-folder-size',
],
}),
],
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"electron-serve": "^1.2.0",
"electron-trpc": "^0.6.1",
"elliptic": "6.5.5",
"get-folder-size": "5.0.0",
"hc-launcher-rust-utils": "file:./rust-utils/dist",
"js-sha256": "^0.11.0",
"nanoid": "5.0.7",
Expand Down
64 changes: 64 additions & 0 deletions src/main/filesystem.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { platform } from '@electron-toolkit/utils';
import { type App, app, session } from 'electron';
import fs from 'fs';
import getFolderSize from 'get-folder-size';
import { nanoid } from 'nanoid';
import path from 'path';

Expand Down Expand Up @@ -74,6 +75,26 @@ type BackupInfo = {
lastPartialbackup?: string;
};

// type StorageInfo = {
// chromium: number;
// logs: number;
// holochain: Record<string, HolochainStorageInfo>;
// lair: number;
// };

type HolochainStorageInfo = {
apps: number;
happs: number;
uis: number;
wasmCache: number;
conductor: number;
authored: number;
cache: number;
dht: number;
p2p: number;
wasm: number;
};

export class LauncherFileSystem {
public profileDataDir: string;
public profileLogsDir: string;
Expand Down Expand Up @@ -202,6 +223,16 @@ export class LauncherFileSystem {
return path.join(this.holochainDataBase(holochainDataRoot), UIS_DIRNAME);
}

/**
* This is the directory in which holochain databases (conductor, authored, cache, ...) are being stored
*
* @param holochainDataRoot
* @returns
*/
dbsDir(holochainDataRoot: HolochainDataRoot) {
return path.join(this.holochainDataBase(holochainDataRoot), CONDUCTOR_ENV_DIRNAME);
}

/**
* Directory where metadata of an app instance is stored. For example which UI
* it currently uses.
Expand Down Expand Up @@ -243,6 +274,39 @@ export class LauncherFileSystem {
return fs.existsSync(path.join(this.keystoreDir, 'lair-keystore-config.yaml'));
};

async getHolochainStorageInfo(
holochainDataRoot: HolochainDataRoot,
): Promise<HolochainStorageInfo> {
if (holochainDataRoot.type !== 'partition')
throw new Error('Cannot get storage info for external holochain.');
const appsStorage = await getFolderSize.loose(this.appsDir(holochainDataRoot));
const happsStorage = await getFolderSize.loose(this.happsDir(holochainDataRoot));
const uisStorage = await getFolderSize.loose(this.uisDir(holochainDataRoot));
const dbsDir = this.dbsDir(holochainDataRoot);
const databasesDir = path.join(dbsDir, 'databases');

const wasmCache = await getFolderSize.loose(path.join(dbsDir, 'wasm-cache'));
const conductor = await getFolderSize.loose(path.join(databasesDir, 'conductor'));
const authored = await getFolderSize.loose(path.join(databasesDir, 'authored'));
const cache = await getFolderSize.loose(path.join(databasesDir, 'cache'));
const dht = await getFolderSize.loose(path.join(databasesDir, 'dht'));
const p2p = await getFolderSize.loose(path.join(databasesDir, 'p2p'));
const wasm = await getFolderSize.loose(path.join(databasesDir, 'wasm'));

return {
apps: appsStorage,
happs: happsStorage,
uis: uisStorage,
wasmCache: wasmCache,
conductor: conductor,
authored: authored,
cache: cache,
dht: dht,
p2p: p2p,
wasm: wasm,
};
}

async factoryReset(keepLogs = false) {
if (keepLogs) throw new Error('Keeping logs across factory reset is currently not supported.');
if (platform.isWindows) {
Expand Down
6 changes: 6 additions & 0 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,12 @@ const router = t.router({

return !isInitializedValidated;
}),
getHolochainStorageInfo: t.procedure.query(() => {
const defaultHolochainManager = HOLOCHAIN_MANAGERS[BREAKING_DEFAULT_HOLOCHAIN_VERSION];
const holochainDataRoot = defaultHolochainManager.holochainDataRoot;
// TODO if required, return storage info for all Holochain versions if there ever are multiple
return LAUNCHER_FILE_SYSTEM.getHolochainStorageInfo(holochainDataRoot);
}),
defaultHolochainVersion: t.procedure.query(
() => HOLOCHAIN_MANAGERS[BREAKING_DEFAULT_HOLOCHAIN_VERSION].version,
),
Expand Down
1 change: 1 addition & 0 deletions src/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@floating-ui/dom": "^1.6.5",
"@shoelace-style/shoelace": "2.15.1",
"@skeletonlabs/skeleton": "2.10.1",
"@skeletonlabs/tw-plugin": "0.4.0",
"@tanstack/svelte-query": "^5.46.1",
Expand Down
54 changes: 38 additions & 16 deletions src/renderer/src/lib/helpers/other.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ import {
} from '$shared/types';
import { AppstoreFilterListsSchema } from '$types/happs';

export function recursiveSum(obj: any): number {
let sum = 0;

for (let key in obj) {
if (typeof obj[key] === 'object') {
sum += recursiveSum(obj[key]);
} else {
sum += obj[key];
}
}

return sum;
}

export function divideObject(obj: any, divider: number) {
const newObj: any = {};
for (let key in obj) {
newObj[key] = obj[key]/divider;
}
return newObj;
}

export const getCellId = (cellInfo: unknown): CellId | undefined => {
const parsedCellInfo = CellInfoSchema.safeParse(cellInfo);

Expand All @@ -28,25 +50,25 @@ export const getCellId = (cellInfo: unknown): CellId | undefined => {
};

export function getCellNetworkSeed(cellInfo: any): string | undefined {
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.dna_modifiers.network_seed;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.dna_modifiers.network_seed;
}
return undefined;
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.dna_modifiers.network_seed;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.dna_modifiers.network_seed;
}
return undefined;
}

export function getCellName(cellInfo: any): string | undefined {
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.name;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.name;
}
if (CellType.Stem in cellInfo) {
return cellInfo.stem.name;
}
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.name;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.name;
}
if (CellType.Stem in cellInfo) {
return cellInfo.stem.name;
}
}

export const isNonEmptyString = (value: unknown): value is string =>
Expand Down
55 changes: 45 additions & 10 deletions src/renderer/src/routes/settings/(menu)/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,53 @@
<script>
import { i18n, trpc } from '$services';
import { divideObject, recursiveSum } from '$helpers';
import { trpc } from '$services';
import PercentageBar from '../components/PercentageBar.svelte';

const client = trpc();
const defaultHolochainVersion = client.defaultHolochainVersion.createQuery();
const storageInfoQuery = client.getHolochainStorageInfo.createQuery();
let fractions;
const labels = [
'UIs',
'happs',
'wasm-cache',
'conductor',
'authored',
'p2p',
'cache',
'dht',
'wasm'
];
</script>

<div class="p-5">
<div>
<h3 class="h3">{$i18n.t('holochainVersion')}</h3>
{#if $defaultHolochainVersion.data}
<p>
{$defaultHolochainVersion.data.type}{#if 'version' in $defaultHolochainVersion.data}: {$defaultHolochainVersion
.data.version}{/if}
</p>
{/if}
<div class="relative flex flex-1 p-5">
<div class="relative flex flex-1 flex-col items-center justify-center overflow-clip">
<img
src="/images/login-background.png"
alt="Holochain Logo"
class="absolute"
style="min-width: 600px; top: 0;"
/>
<div class="absolute flex flex-col items-center" style="top: 275px;">
<span class="text-5xl font-bold">Holochain</span>
<div class="text-xl text-slate-400">
{#if $defaultHolochainVersion.data && $defaultHolochainVersion.data.type === 'built-in'}
{$defaultHolochainVersion.data.version}
{/if}
</div>
</div>
</div>
{#if $storageInfoQuery.data}
{@const storageInfoMB = divideObject($storageInfoQuery.data, 1e6)}
{@const totalStorage = recursiveSum(storageInfoMB)}
<div
class="absolute bottom-8 flex flex-1 flex-col items-center px-4"
style="width: calc(100% - 40px);"
>
<div class="mb-1 text-lg">{Math.round(totalStorage)} MB Used</div>
<div class="w-full">
<PercentageBar values={storageInfoMB} height={20} unit="MB"></PercentageBar>
</div>
</div>
{/if}
</div>
41 changes: 41 additions & 0 deletions src/renderer/src/routes/settings/components/PercentageBar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { recursiveSum } from '$helpers';
import '@shoelace-style/shoelace/dist/components/tooltip/tooltip.js';
export let values: Record<string, number> = {
'alice': 3,
'bob': 5,
'hello': 8
};
export let height: number = 30;
// export let width: string = '100%';
export let unit = '';

const totalSum = recursiveSum(values);

// let colors = ['#e9f44b', '#bf4bf4', '#f44b4b', '#5cf44b', '#4bf4d0', '#4bb6f4', '#4b4bf4'];
let colors = [
'#95a148',
'#7b34a4',
'#4ea499',
'#2e78a6',
'#3336a4',
'#a6552e',
'#a6762e',
'#2ea63d',
'#a62e92',
'#a62e40'
];
</script>

<div
class="relative flex flex-1 flex-row overflow-clip"
style={`height: ${height}px; border-radius: ${height * 0.5}px`}
>
{#each Object.entries(values) as [label, value], idx}
<sl-tooltip hoist content={`${label} (${Math.round(value)}${unit ? ' ' : ''}${unit})`} style={`--sl-tooltip-background-color: ${colors[idx]}; --sl-tooltip-border-radius: 5px; --sl-tooltip-padding: 1px; --sl-tooltip-arrow-size: 6px;`}>
<div
style={`width: ${value/totalSum * 100}%; background-color: ${colors[idx]};`}
></div>
</sl-tooltip>
{/each}
</div>
2 changes: 1 addition & 1 deletion src/shared/types/holochain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const AppInfoSchema = z.object({
status: InstalledAppInfoStatusSchema,
});

const HolochainDataRootSchema = z.union([
export const HolochainDataRootSchema = z.union([
z.object({
type: z.literal('partition'),
name: z.string(),
Expand Down
Loading