first commit

This commit is contained in:
douboer@gmail.com
2026-03-03 13:23:14 +08:00
commit 3b7c1d558a
161 changed files with 28120 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { loadRuntimeConfig } from "@/utils/runtimeConfig";
interface RuntimeSettings {
gatewayUrl: string;
gatewayToken: string;
}
const STORAGE_KEY = "remoteconn:web:settings:v1";
function resolveDefaultGatewayUrl(): string {
const env = (import.meta as ImportMeta & { env?: Record<string, string | undefined> }).env;
const envUrl = env?.VITE_GATEWAY_URL?.trim();
if (envUrl) return envUrl;
if (typeof window === "undefined") return "ws://127.0.0.1:8787/ws/terminal";
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
return `${protocol}//${window.location.host}/ws/terminal`;
}
function resolveDefaultGatewayToken(): string {
const env = (import.meta as ImportMeta & { env?: Record<string, string | undefined> }).env;
const envToken = env?.VITE_GATEWAY_TOKEN?.trim();
if (envToken) return envToken;
return "remoteconn-dev-token";
}
function loadSettings(): RuntimeSettings {
if (typeof window === "undefined") {
return { gatewayUrl: resolveDefaultGatewayUrl(), gatewayToken: resolveDefaultGatewayToken() };
}
try {
const raw = window.localStorage.getItem(STORAGE_KEY);
if (!raw) {
return { gatewayUrl: resolveDefaultGatewayUrl(), gatewayToken: resolveDefaultGatewayToken() };
}
const parsed = JSON.parse(raw) as Partial<RuntimeSettings>;
return {
gatewayUrl: String(parsed.gatewayUrl ?? resolveDefaultGatewayUrl()),
gatewayToken: String(parsed.gatewayToken ?? resolveDefaultGatewayToken())
};
} catch {
return { gatewayUrl: resolveDefaultGatewayUrl(), gatewayToken: resolveDefaultGatewayToken() };
}
}
function persistSettings(settings: RuntimeSettings): void {
if (typeof window === "undefined") return;
try {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
} catch {
// ignore storage unavailability in embedded/private contexts
}
}
export const useSettingsStore = defineStore("settings", () => {
const settings = ref<RuntimeSettings>({
gatewayUrl: resolveDefaultGatewayUrl(),
gatewayToken: resolveDefaultGatewayToken()
});
const loaded = ref(false);
let bootstrapPromise: Promise<void> | null = null;
async function ensureBootstrapped(): Promise<void> {
if (loaded.value) return;
if (bootstrapPromise) {
await bootstrapPromise;
return;
}
bootstrapPromise = (async () => {
const runtimeConfig = await loadRuntimeConfig();
const localSettings = loadSettings();
settings.value = {
gatewayUrl: String(runtimeConfig?.gatewayUrl ?? localSettings.gatewayUrl ?? resolveDefaultGatewayUrl()),
gatewayToken: String(runtimeConfig?.gatewayToken ?? localSettings.gatewayToken ?? resolveDefaultGatewayToken())
};
loaded.value = true;
})();
try {
await bootstrapPromise;
} finally {
bootstrapPromise = null;
}
}
async function bootstrap(): Promise<void> {
await ensureBootstrapped();
}
async function save(next: Partial<RuntimeSettings>): Promise<void> {
settings.value = {
gatewayUrl: String(next.gatewayUrl ?? settings.value.gatewayUrl ?? resolveDefaultGatewayUrl()),
gatewayToken: String(next.gatewayToken ?? settings.value.gatewayToken ?? resolveDefaultGatewayToken())
};
persistSettings(settings.value);
}
const gatewayUrl = computed(() => settings.value.gatewayUrl || resolveDefaultGatewayUrl());
const gatewayToken = computed(() => settings.value.gatewayToken || resolveDefaultGatewayToken());
return {
settings,
gatewayUrl,
gatewayToken,
ensureBootstrapped,
bootstrap,
save
};
});