adjust types

adjust xconfig.toml
This commit is contained in:
Km.Van
2026-07-09 22:45:05 +08:00
parent e8305e2784
commit f2b7cff70c
28 changed files with 510 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
allowBuilds:
'@parcel/watcher': true
core-js: true
esbuild: true
minimumReleaseAgeExclude:
- ultracite@7.9.2
@@ -0,0 +1,11 @@
export type BootstrapPollDataModel = {
isDev: boolean;
version: string;
appName: string;
appUrl: string;
appConfigUrls: string[];
appConfigUrlDev: string;
authorUrl: string;
authorName: string;
authorization: string;
};
@@ -0,0 +1,14 @@
export type BrowserBenchmarkMarksProps = {
js: number;
dom: number;
canvas: number;
};
export type BrowserBenchmarkProps = {
id: string;
name: string;
version: string;
ua: string;
date: string;
total: number;
detail: BrowserBenchmarkMarksProps;
};
@@ -0,0 +1,9 @@
export const ButtonStatus = {
Error: "error",
Loading: "loading",
Pointer: "pointer",
Warning: "warning",
} as const;
export type ButtonStatusKey = keyof typeof ButtonStatus;
export type ButtonStatusValue =
(typeof ButtonStatus)[keyof typeof ButtonStatus];
+13
View File
@@ -0,0 +1,13 @@
export type ConfigProps = {
APP_VERSION: string;
APP_NAME: string;
APP_URL: string;
AUTHOR_URL: string;
UPDATE_PHP_URLS: string[];
APP_CONFIG_URLS: string[];
BENCHMARKS_URLS: string[];
APP_CONFIG_URL_DEV: string;
AUTHOR_NAME: string;
LATEST_PHP_STABLE_VERSION: string;
LATEST_NGINX_STABLE_VERSION: string;
};
@@ -0,0 +1 @@
export type DatabasePollDataProps = Record<string, string | boolean>;
@@ -0,0 +1,8 @@
export type DiskUsageItemProps = {
id: string;
total: number;
free: number;
};
export type DiskUsagePollDataProps = {
items: DiskUsageItemProps[];
};
@@ -0,0 +1,5 @@
export type LocationProps = {
continent: string;
country: string;
city: string;
};
+11
View File
@@ -0,0 +1,11 @@
import type { FC } from "react";
export type ModuleProps = {
id: string;
content: FC;
nav: FC;
};
export type SortedModuleProps = {
id: string;
priority: number;
};
@@ -0,0 +1,30 @@
import { useMemo } from "react";
import { useShallow } from "zustand/react/shallow";
import { usePollStore } from "@/Components/Poll/components/store.ts";
import type { PollData } from "@/Components/Poll/components/types.ts";
import { presetModules } from "./preset.ts";
import { useModuleStore } from "./store.ts";
import type { ModuleProps } from "./types.ts";
export const useAvailableModules = (): ModuleProps[] => {
// 1. 获取完整的优先级顺序
const priorities = useModuleStore((s) => s.priorities);
// 2. 获取服务端的有效性凭证
const pollData = usePollStore(useShallow((s) => s.pollData));
// 3. 使用 useMemo 缓存计算结果,只有当底层数据改变时才重新计算
const available = useMemo(() => {
if (!pollData) {
return [];
}
const maps = new Map(presetModules.map((item) => [item.id, item]));
return priorities
.map((id) => maps.get(id))
.filter(
(n): n is ModuleProps =>
!!n && Object.hasOwn(pollData as PollData, n.id)
);
}, [priorities, pollData]);
return available;
};
@@ -0,0 +1,5 @@
export type MyInfoPollDataProps = {
ipv4: string;
ipv6: string;
phpLanguage: string;
};
@@ -0,0 +1,9 @@
export type NetworkStatsItemProps = {
id: string;
rx: number;
tx: number;
};
export type NetworkStatsPollDataProps = {
networks: NetworkStatsItemProps[];
timestamp: number;
};
+11
View File
@@ -0,0 +1,11 @@
import type { PollData } from "@/Components/Poll/components/types";
export type NodesItemProps = {
id: string;
loading: boolean;
status: number;
data: PollData | null;
};
export type NodesPollDataProps = {
nodesIds: string[];
};
@@ -0,0 +1,27 @@
export type PhpExtensionsPollDataProps = {
redis: boolean;
sqlite3: boolean;
memcache: boolean;
memcached: boolean;
opcache: boolean;
opcacheEnabled: boolean;
opcacheJitEnabled: boolean;
swoole: boolean;
imagick: boolean;
gmagick: boolean;
exif: boolean;
fileinfo: boolean;
simplexml: boolean;
sockets: boolean;
mysqli: boolean;
zip: boolean;
mbstring: boolean;
phalcon: boolean;
xdebug: boolean;
zendOptimizer: boolean;
ionCube: boolean;
sourceGuardian: boolean;
ldap: boolean;
curl: boolean;
loadedExtensions: string[];
};
@@ -0,0 +1,16 @@
export type PhpInfoPollDataProps = {
phpVersion: string;
sapi: string;
displayErrors: boolean;
errorReporting: number;
memoryLimit: string;
postMaxSize: string;
uploadMaxFilesize: string;
maxInputVars: number;
maxExecutionTime: number;
defaultSocketTimeout: number;
allowUrlFopen: boolean;
smtp: boolean;
disableFunctions: string[];
disableClasses: string[];
};
+8
View File
@@ -0,0 +1,8 @@
export type ServerToBrowserPingItemProps = {
id: string;
time: number;
};
export type ServerToBrowserPingProps = {
location: string;
items: ServerToBrowserPingItemProps[];
};
+27
View File
@@ -0,0 +1,27 @@
import type { ConfigProps } from "@/Components/Config/types";
import type { DatabasePollDataProps } from "@/Components/Database/components/types";
import type { DiskUsagePollDataProps } from "@/Components/DiskUsage/components/types";
import type { MyInfoPollDataProps } from "@/Components/MyInfo/components/types";
import type { NetworkStatsPollDataProps } from "@/Components/NetworkStats/components/types";
import type { NodesPollDataProps } from "@/Components/Nodes/components/types";
import type { PhpExtensionsPollDataProps } from "@/Components/PhpExtensions/components/types";
import type { PhpInfoPollDataProps } from "@/Components/PhpInfo/components/types";
import type { ServerInfoPollDataProps } from "@/Components/ServerInfo/components/types";
import type { ServerStatusPollDataProps } from "@/Components/ServerStatus/components/types";
import type { TemperatureSensorPollDataProps } from "@/Components/TemperatureSensor/components/types";
import type { UserConfigProps } from "@/Components/UserConfig/types";
export type PollData = {
config: ConfigProps | null;
userConfig: UserConfigProps | null;
database: DatabasePollDataProps | null;
myInfo: MyInfoPollDataProps | null;
phpInfo: PhpInfoPollDataProps | null;
diskUsage: DiskUsagePollDataProps | null;
networkStats: NetworkStatsPollDataProps | null;
phpExtensions: PhpExtensionsPollDataProps | null;
serverStatus: ServerStatusPollDataProps | null;
serverInfo: ServerInfoPollDataProps | null;
nodes: NodesPollDataProps | null;
temperatureSensor: TemperatureSensorPollDataProps | null;
};
@@ -0,0 +1,15 @@
export type ServerBenchmarkMarksProps = {
cpu: number;
read: number;
write: number;
};
export type ServerBenchmarkProps = {
id: string;
name: string;
url: string;
date: string;
probeUrl: string;
binUrl: string;
total: number;
detail: ServerBenchmarkMarksProps;
};
@@ -0,0 +1,20 @@
export type ServerInfoUptimeProps = {
days: number;
hours: number;
mins: number;
secs: number;
};
export type ServerInfoPollDataProps = {
serverName: string;
serverUtcTime: string;
serverTime: string;
localIpv4: string;
localIpv6: string;
serverUptime: ServerInfoUptimeProps;
serverIp: string;
serverSoftware: string;
phpVersion: string;
cpuModel: string;
serverOs: string;
scriptPath: string;
};
@@ -0,0 +1,19 @@
export type ServerStatusUsageProps = {
max: number;
value: number;
};
export type ServerStatusCpuUsageProps = {
usage: number;
idle: number;
sys: number;
user: number;
};
export type ServerStatusPollDataProps = {
sysLoad: number[];
cpuUsage: ServerStatusCpuUsageProps;
memRealUsage: ServerStatusUsageProps;
memBuffers: ServerStatusUsageProps;
memCached: ServerStatusUsageProps;
swapUsage: ServerStatusUsageProps;
swapCached: ServerStatusUsageProps;
};
@@ -0,0 +1,8 @@
export type TemperatureSensorItemProps = {
id: string;
name: string;
celsius: number;
};
export type TemperatureSensorPollDataProps = {
items: TemperatureSensorItemProps[];
};
@@ -0,0 +1,32 @@
import { useShallow } from "zustand/react/shallow";
import { useConfigStore } from "@/Components/Config/store";
import { gettext } from "@/Components/Language";
import { template } from "@/Components/Utils/components/template";
import { useUpdaterStore } from "./store";
export const useUpdateNotiText = (): string => {
const { isUpdating, hasUpdateError, targetVersion } = useUpdaterStore(
useShallow((s) => ({
isUpdating: s.isUpdating,
hasUpdateError: s.hasUpdateError,
targetVersion: s.targetVersion,
}))
);
const AppVersion = useConfigStore((s) => s?.pollData?.APP_VERSION ?? "-");
if (isUpdating) {
return gettext("⏳ Updating, please wait a second...");
}
if (hasUpdateError) {
return gettext("❌ Update error, click here to try again?");
}
if (targetVersion) {
return template(
gettext("✨ Found new version: {{oldVersion}} ⇢ {{newVersion}}"),
{
oldVersion: AppVersion,
newVersion: targetVersion,
}
);
}
return "";
};
+26
View File
@@ -0,0 +1,26 @@
export const UserConfigDisableFeature = {
Database: "database",
DiskUsage: "diskUsage",
MyInfo: "myInfo",
MyServerBenchmark: "myServerBenchmark",
NetworkStats: "networkStats",
PhpDisabledClasses: "phpDisabledClasses",
PhpDisabledFunctions: "phpDisabledFunctions",
PhpExtensions: "phpExtensions",
PhpExtensionsLoaded: "phpExtensionsLoaded",
PhpInfo: "phpInfo",
PhpInfoDetail: "phpInfoDetail",
Ping: "ping",
ServerInfo: "serverInfo",
ServerIp: "serverIp",
ServerStatus: "serverStatus",
} as const;
export type UserConfigDisableFeatureKey = keyof typeof UserConfigDisableFeature;
export type UserConfigDisableFeatureValue =
(typeof UserConfigDisableFeature)[keyof typeof UserConfigDisableFeature];
export type UserConfigNodeProps = [nodeName: string, url: string];
export type UserConfigProps = {
serverBenchmarkCd?: number;
nodes?: UserConfigNodeProps[];
disabled?: UserConfigDisableFeatureKey;
};
+113
View File
@@ -0,0 +1,113 @@
<?php
namespace InnStudio\Prober\Components\Utils;
final class UtilsTomlParser
{
public static function parse($toml_string)
{
$result = [];
$lines = explode("\n", $toml_string);
$current_group = &$result;
foreach ($lines as $line_num => $line) {
$line = trim($line);
if ('' === $line || '#' === $line[0]) {
continue;
}
if ('[' === $line[0] && ']' === substr($line, -1)) {
$group_name = substr($line, 1, -1);
$groups = explode('.', $group_name);
$current_group = &$result;
foreach ($groups as $g) {
if ( ! isset($current_group[$g])) {
$current_group[$g] = [];
}
$current_group = &$current_group[$g];
}
continue;
}
if (false !== strpos($line, '=')) {
[$key, $value] = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
$parsed_value = self::parse_value($value);
$current_group[$key] = $parsed_value;
}
}
return $result;
}
public static function parse_value($value)
{
if (preg_match('/^"(.*)"$/', $value, $matches)) {
return str_replace('\\"', '"', $matches[1]);
}
if (preg_match("/^'(.*)'$/", $value, $matches)) {
return $matches[1];
}
if ('true' === $value) {
return true;
}
if ('false' === $value) {
return false;
}
if (preg_match('/^-?\\d+$/', $value)) {
return (int) $value;
}
if (preg_match('/^-?\\d+\\.\\d+$/', $value)) {
return (float) $value;
}
if ('[' === $value[0] && ']' === substr($value, -1)) {
$inner = trim(substr($value, 1, -1));
if ('' === $inner) {
return [];
}
$items = [];
$current = '';
$in_string = false;
$string_char = '';
$i = 0;
$len = \strlen($inner);
while ($i < $len) {
$char = $inner[$i];
if ( ! $in_string && ('"' === $char || "'" === $char)) {
$in_string = true;
$string_char = $char;
$current .= $char;
} elseif ($in_string && $char === $string_char && '\\' !== $inner[$i - 1]) {
$in_string = false;
$current .= $char;
} elseif ( ! $in_string && ',' === $char) {
$items[] = self::parse_value(trim($current));
$current = '';
} else {
$current .= $char;
}
++$i;
}
if ('' !== trim($current)) {
$items[] = self::parse_value(trim($current));
}
return $items;
}
return trim($value, '"\'');
}
}
@@ -0,0 +1 @@
export type FetchStatus = "loading" | "idel" | "error";
@@ -0,0 +1,7 @@
export type WindowConfigProps = {
IS_DEV: boolean;
AUTHORIZATION: string;
};
export type WindowProps = {
GLOBAL_CONFIG: WindowConfigProps;
};
+8
View File
@@ -0,0 +1,8 @@
export const PieChartStatus = {
High: "high",
Low: "low",
Medium: "medium",
} as const;
export type PieChartStatusKey = keyof typeof PieChartStatus;
export type PieChartStatusValue =
(typeof PieChartStatus)[keyof typeof PieChartStatus];
+50
View File
@@ -0,0 +1,50 @@
# =============================================================================
# X-Prober 配置文件 | X-Prober Configuration
# =============================================================================
# -----------------------------------------------------------------------------
# 功能开关 | Feature Toggles
# -----------------------------------------------------------------------------
# 禁用特定功能以增强安全性或减少系统开销。
# Disable specific features to improve security or reduce overhead.
#
# 可用选项 | Available options: serverStatus, diskUsage, networkStats, ping,
# serverInfo, phpInfo, phpInfoDetail, phpDisabledFunctions,
# phpDisabledClasses, phpExtensions, phpExtensionsLoaded, database,
# myServerBenchmark, myInfo, serverIp
#
# disabled = ["serverIp", "phpInfoDetail"]
# -----------------------------------------------------------------------------
# 硬件监控 | Hardware Monitoring
# -----------------------------------------------------------------------------
# 温度传感器接口地址(例如:树莓派传感器)。
# Temperature sensor endpoints (e.g., Raspberry Pi sensors).
#
# 参考文档 | Reference: /extensions/temperature-sensors/raspberrypi.js
#
# temperatureSensors = [
# "http://localhost:4096"
# ]
# -----------------------------------------------------------------------------
# 性能测试 | Performance Testing
# -----------------------------------------------------------------------------
# 服务器基准测试冷却时间(秒),防止频繁测试导致服务器过载。
# Cooldown period between server benchmark runs (in seconds).
# Prevents excessive load from frequent testing.
#
# serverBenchmarkCd = 30
# -----------------------------------------------------------------------------
# 多节点聚合 | Multi-Node Aggregation
# -----------------------------------------------------------------------------
# 定义其他 X-Prober 节点,用于聚合仪表盘展示。
# Define additional X-Prober nodes for aggregated dashboard view.
#
# 格式 | Format: ["显示名称", "节点地址"] | ["display-name", "node-url"]
#
# nodes = [
# ["node-1", "http://localhost:5173"],
# ["node-3", "http://localhost:5173"]
# ]