Files
NetMesh/infrastructure/services/vaultImportWorkerClient.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

120 lines
3.5 KiB
TypeScript

import type {
VaultImportFormat,
VaultImportResult,
} from "../../domain/vaultImport";
import type { VaultImportFileEncoding } from "./vaultImportFile";
export type VaultImportWorkerStage = "reading" | "parsing";
export interface VaultImportWorkerProgress {
stage: VaultImportWorkerStage;
percent: number;
completedFiles?: number;
totalFiles?: number;
currentFileName?: string;
}
export type VaultImportWorkerRequest = {
type: "import";
format: VaultImportFormat;
files: File[];
relativePaths: string[];
encoding: VaultImportFileEncoding | undefined;
masterPassword?: string;
};
export type VaultImportWorkerResponse =
| { type: "progress"; progress: VaultImportWorkerProgress }
| { type: "result"; result: VaultImportResult }
| { type: "error"; message: string };
type VaultImportWorkerEvent = MessageEvent<VaultImportWorkerResponse> | ErrorEvent;
type VaultImportWorkerListener = (event: VaultImportWorkerEvent) => void;
export interface VaultImportWorkerLike {
addEventListener(type: "message" | "error", listener: VaultImportWorkerListener): void;
removeEventListener(type: "message" | "error", listener: VaultImportWorkerListener): void;
postMessage(message: VaultImportWorkerRequest): void;
terminate(): void;
}
interface ImportVaultHostsInWorkerOptions {
format: VaultImportFormat;
files: File[];
encoding?: VaultImportFileEncoding;
masterPassword?: string;
signal?: AbortSignal;
createWorker?: () => VaultImportWorkerLike;
onProgress?: (progress: VaultImportWorkerProgress) => void;
}
const createVaultImportWorker = (): VaultImportWorkerLike => (
new Worker(new URL("../workers/vaultImport.worker.ts", import.meta.url), {
type: "module",
})
);
export function importVaultHostsInWorker({
format,
files,
encoding,
masterPassword,
signal,
createWorker = createVaultImportWorker,
onProgress,
}: ImportVaultHostsInWorkerOptions): Promise<VaultImportResult> {
if (signal?.aborted) {
return Promise.reject(new DOMException("Vault import cancelled.", "AbortError"));
}
const worker = createWorker();
return new Promise((resolve, reject) => {
const cleanup = () => {
worker.removeEventListener("message", handleMessage);
worker.removeEventListener("error", handleWorkerError);
signal?.removeEventListener("abort", handleAbort);
worker.terminate();
};
const handleAbort = () => {
cleanup();
reject(new DOMException("Vault import cancelled.", "AbortError"));
};
const handleMessage: VaultImportWorkerListener = (event) => {
const message = (event as MessageEvent<VaultImportWorkerResponse>).data;
if (message.type === "progress") {
onProgress?.(message.progress);
return;
}
cleanup();
if (message.type === "result") {
resolve(message.result);
return;
}
reject(new Error(message.message));
};
const handleWorkerError: VaultImportWorkerListener = (event) => {
cleanup();
const message = event instanceof ErrorEvent && event.message
? event.message
: "Vault import worker failed.";
reject(new Error(message));
};
worker.addEventListener("message", handleMessage);
worker.addEventListener("error", handleWorkerError);
signal?.addEventListener("abort", handleAbort, { once: true });
worker.postMessage({
type: "import",
format,
files,
relativePaths: files.map((file) => file.webkitRelativePath),
encoding,
...(masterPassword ? { masterPassword } : {}),
});
});
}