@cjwddz/mirror 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/cli/cli-commands.d.ts +3 -1
  2. package/dist/cli/cli-commands.d.ts.map +1 -1
  3. package/dist/cli/cli-commands.js +113 -102
  4. package/dist/cli/cli-commands.js.map +1 -1
  5. package/dist/cli/index.d.ts +1 -1
  6. package/dist/cli/index.js +51 -72
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/version.d.ts +5 -0
  9. package/dist/cli/version.d.ts.map +1 -0
  10. package/dist/cli/version.js +24 -0
  11. package/dist/cli/version.js.map +1 -0
  12. package/dist/core/http-tunnel-server.d.ts.map +1 -1
  13. package/dist/core/http-tunnel-server.js +4 -4
  14. package/dist/core/http-tunnel-server.js.map +1 -1
  15. package/dist/core/rule-manager.d.ts.map +1 -1
  16. package/dist/core/rule-manager.js +4 -6
  17. package/dist/core/rule-manager.js.map +1 -1
  18. package/package.json +1 -1
  19. package/dist/core/file-sync.d.ts +0 -14
  20. package/dist/core/file-sync.d.ts.map +0 -1
  21. package/dist/core/file-sync.js +0 -34
  22. package/dist/core/file-sync.js.map +0 -1
  23. package/dist/core/output-buffer.d.ts +0 -42
  24. package/dist/core/output-buffer.d.ts.map +0 -1
  25. package/dist/core/output-buffer.js +0 -66
  26. package/dist/core/output-buffer.js.map +0 -1
  27. package/dist/core/protocol.d.ts +0 -83
  28. package/dist/core/protocol.d.ts.map +0 -1
  29. package/dist/core/protocol.js +0 -10
  30. package/dist/core/protocol.js.map +0 -1
  31. package/dist/core/state-machine.d.ts +0 -19
  32. package/dist/core/state-machine.d.ts.map +0 -1
  33. package/dist/core/state-machine.js +0 -39
  34. package/dist/core/state-machine.js.map +0 -1
  35. package/dist/core/token-manager.d.ts +0 -29
  36. package/dist/core/token-manager.d.ts.map +0 -1
  37. package/dist/core/token-manager.js +0 -90
  38. package/dist/core/token-manager.js.map +0 -1
  39. package/dist/core/workspace.d.ts +0 -28
  40. package/dist/core/workspace.d.ts.map +0 -1
  41. package/dist/core/workspace.js +0 -186
  42. package/dist/core/workspace.js.map +0 -1
  43. package/dist/transport/websocket.d.ts +0 -22
  44. package/dist/transport/websocket.d.ts.map +0 -1
  45. package/dist/transport/websocket.js +0 -96
  46. package/dist/transport/websocket.js.map +0 -1
@@ -1,83 +0,0 @@
1
- /**
2
- * Mirror 通信协议定义
3
- */
4
- export type MessageType = 'HELLO' | 'SNAPSHOT_START' | 'FILE' | 'SNAPSHOT_END' | 'READY' | 'FILE_DIFF' | 'EXEC' | 'EXEC_OUTPUT' | 'EXEC_EXIT' | 'EXEC_SIGNAL' | 'FILE_SYNC_STATUS' | 'ERROR';
5
- export interface BaseMessage {
6
- type: MessageType;
7
- }
8
- export interface HelloMessage extends BaseMessage {
9
- type: 'HELLO';
10
- clientId: string;
11
- token: string;
12
- clientVersion: string;
13
- workspacePath?: string;
14
- }
15
- export interface SnapshotStartMessage extends BaseMessage {
16
- type: 'SNAPSHOT_START';
17
- version: number;
18
- totalFiles?: number;
19
- }
20
- export interface FileMessage extends BaseMessage {
21
- type: 'FILE';
22
- path: string;
23
- hash: string;
24
- content: string;
25
- compressed?: boolean;
26
- size?: number;
27
- }
28
- export interface SnapshotEndMessage extends BaseMessage {
29
- type: 'SNAPSHOT_END';
30
- version: number;
31
- }
32
- export interface ReadyMessage extends BaseMessage {
33
- type: 'READY';
34
- message: string;
35
- }
36
- export interface FileDiffMessage extends BaseMessage {
37
- type: 'FILE_DIFF';
38
- version: number;
39
- op: 'update' | 'delete';
40
- path: string;
41
- hash: string;
42
- content?: string;
43
- compressed?: boolean;
44
- size?: number;
45
- }
46
- export interface ExecMessage extends BaseMessage {
47
- type: 'EXEC';
48
- execId: string;
49
- version: number;
50
- command: string;
51
- }
52
- export interface ExecOutputMessage extends BaseMessage {
53
- type: 'EXEC_OUTPUT';
54
- execId: string;
55
- stream: 'stdout' | 'stderr';
56
- data: string;
57
- }
58
- export interface ExecExitMessage extends BaseMessage {
59
- type: 'EXEC_EXIT';
60
- execId: string;
61
- code: number;
62
- }
63
- export interface ExecSignalMessage extends BaseMessage {
64
- type: 'EXEC_SIGNAL';
65
- execId: string;
66
- signal: 'SIGINT' | 'SIGTERM' | 'SIGKILL';
67
- }
68
- export interface FileSyncStatusMessage extends BaseMessage {
69
- type: 'FILE_SYNC_STATUS';
70
- status: 'syncing' | 'synced';
71
- path?: string;
72
- op?: 'update' | 'delete';
73
- totalSynced?: number;
74
- pendingCount?: number;
75
- }
76
- export interface ErrorMessage extends BaseMessage {
77
- type: 'ERROR';
78
- message: string;
79
- code?: string;
80
- }
81
- export type Message = HelloMessage | SnapshotStartMessage | FileMessage | SnapshotEndMessage | ReadyMessage | FileDiffMessage | ExecMessage | ExecOutputMessage | ExecExitMessage | ExecSignalMessage | FileSyncStatusMessage | ErrorMessage;
82
- export declare function isMessage(obj: unknown): obj is Message;
83
- //# sourceMappingURL=protocol.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/core/protocol.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Mirror 通信协议定义
3
- */
4
- export function isMessage(obj) {
5
- return (typeof obj === 'object' &&
6
- obj !== null &&
7
- 'type' in obj &&
8
- typeof obj.type === 'string');
9
- }
10
- //# sourceMappingURL=protocol.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/core/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwHH,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,MAAM,IAAI,GAAG;QACb,OAAQ,GAAyB,CAAC,IAAI,KAAK,QAAQ,CACpD,CAAC;AACJ,CAAC"}
@@ -1,19 +0,0 @@
1
- /**
2
- * Host 状态机(简化版)
3
- * 移除 RUNNING 状态,使用独立标志位跟踪命令执行
4
- * 文件同步和命令执行完全解耦
5
- */
6
- export declare enum HostState {
7
- EMPTY = "EMPTY",// 无 client
8
- SYNCING = "SYNCING",// 初始全量文件同步中
9
- READY = "READY"
10
- }
11
- export declare class StateMachine {
12
- private state;
13
- getState(): HostState;
14
- transitionTo(newState: HostState): void;
15
- canExec(): boolean;
16
- canSync(): boolean;
17
- reset(): void;
18
- }
19
- //# sourceMappingURL=state-machine.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../../src/core/state-machine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAY,SAAS;IACnB,KAAK,UAAU,CAAE,WAAW;IAC5B,OAAO,YAAY,CAAE,YAAY;IACjC,KAAK,UAAU;CAChB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA8B;IAE3C,QAAQ,IAAI,SAAS;IAIrB,YAAY,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAevC,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,OAAO;IAIlB,KAAK,IAAI,IAAI;CAGd"}
@@ -1,39 +0,0 @@
1
- /**
2
- * Host 状态机(简化版)
3
- * 移除 RUNNING 状态,使用独立标志位跟踪命令执行
4
- * 文件同步和命令执行完全解耦
5
- */
6
- export var HostState;
7
- (function (HostState) {
8
- HostState["EMPTY"] = "EMPTY";
9
- HostState["SYNCING"] = "SYNCING";
10
- HostState["READY"] = "READY";
11
- })(HostState || (HostState = {}));
12
- export class StateMachine {
13
- state = HostState.EMPTY;
14
- getState() {
15
- return this.state;
16
- }
17
- transitionTo(newState) {
18
- // 验证状态转换的合法性
19
- const validTransitions = {
20
- [HostState.EMPTY]: [HostState.SYNCING],
21
- [HostState.SYNCING]: [HostState.READY, HostState.EMPTY],
22
- [HostState.READY]: [HostState.SYNCING, HostState.EMPTY],
23
- };
24
- if (!validTransitions[this.state].includes(newState)) {
25
- throw new Error(`无效的状态转换: ${this.state} -> ${newState}`);
26
- }
27
- this.state = newState;
28
- }
29
- canExec() {
30
- return this.state === HostState.READY;
31
- }
32
- canSync() {
33
- return this.state === HostState.READY;
34
- }
35
- reset() {
36
- this.state = HostState.EMPTY;
37
- }
38
- }
39
- //# sourceMappingURL=state-machine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state-machine.js","sourceRoot":"","sources":["../../src/core/state-machine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,4BAAe,CAAA;AACjB,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,OAAO,YAAY;IACf,KAAK,GAAc,SAAS,CAAC,KAAK,CAAC;IAE3C,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,YAAY,CAAC,QAAmB;QAC9B,aAAa;QACb,MAAM,gBAAgB,GAAmC;YACvD,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;YACtC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC;YACvD,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC;SACxD,CAAC;QAEF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;IACxB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC;IACxC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC;IACxC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC/B,CAAC;CACF"}
@@ -1,29 +0,0 @@
1
- /**
2
- * Token 管理器
3
- * 负责持久化存储认证 token
4
- */
5
- export declare class TokenManager {
6
- private tokenFilePath;
7
- constructor();
8
- /**
9
- * 保存 token
10
- */
11
- saveToken(token: string, host: string): Promise<void>;
12
- /**
13
- * 获取 token
14
- */
15
- getToken(host: string): Promise<string | null>;
16
- /**
17
- * 检查 token 是否过期(可选)
18
- */
19
- isTokenExpired(host: string, maxAge?: number): Promise<boolean>;
20
- /**
21
- * 删除 token
22
- */
23
- deleteToken(host: string): Promise<void>;
24
- /**
25
- * 清空所有 tokens
26
- */
27
- clearAllTokens(): Promise<void>;
28
- }
29
- //# sourceMappingURL=token-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../src/core/token-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAS;;IAM9B;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3D;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUpD;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiC,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB/F;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAOtC"}
@@ -1,90 +0,0 @@
1
- /**
2
- * Token 管理器
3
- * 负责持久化存储认证 token
4
- */
5
- import { readFile, writeFile } from 'fs/promises';
6
- import { join } from 'path';
7
- import { homedir } from 'os';
8
- export class TokenManager {
9
- tokenFilePath;
10
- constructor() {
11
- this.tokenFilePath = join(homedir(), '.mirror-tokens.json');
12
- }
13
- /**
14
- * 保存 token
15
- */
16
- async saveToken(token, host) {
17
- let tokens = {};
18
- try {
19
- const content = await readFile(this.tokenFilePath, 'utf-8');
20
- tokens = JSON.parse(content);
21
- }
22
- catch {
23
- // 文件不存在或读取失败,使用空对象
24
- }
25
- tokens[host] = {
26
- token,
27
- host,
28
- createdAt: new Date().toISOString(),
29
- };
30
- await writeFile(this.tokenFilePath, JSON.stringify(tokens, null, 2), 'utf-8');
31
- }
32
- /**
33
- * 获取 token
34
- */
35
- async getToken(host) {
36
- try {
37
- const content = await readFile(this.tokenFilePath, 'utf-8');
38
- const tokens = JSON.parse(content);
39
- return tokens[host]?.token || null;
40
- }
41
- catch {
42
- return null;
43
- }
44
- }
45
- /**
46
- * 检查 token 是否过期(可选)
47
- */
48
- async isTokenExpired(host, maxAge = 30 * 24 * 60 * 60 * 1000) {
49
- try {
50
- const content = await readFile(this.tokenFilePath, 'utf-8');
51
- const tokens = JSON.parse(content);
52
- const tokenData = tokens[host];
53
- if (!tokenData) {
54
- return true;
55
- }
56
- const createdAt = new Date(tokenData.createdAt).getTime();
57
- const now = Date.now();
58
- return now - createdAt > maxAge;
59
- }
60
- catch {
61
- return true;
62
- }
63
- }
64
- /**
65
- * 删除 token
66
- */
67
- async deleteToken(host) {
68
- try {
69
- const content = await readFile(this.tokenFilePath, 'utf-8');
70
- const tokens = JSON.parse(content);
71
- delete tokens[host];
72
- await writeFile(this.tokenFilePath, JSON.stringify(tokens, null, 2), 'utf-8');
73
- }
74
- catch {
75
- // 忽略错误
76
- }
77
- }
78
- /**
79
- * 清空所有 tokens
80
- */
81
- async clearAllTokens() {
82
- try {
83
- await writeFile(this.tokenFilePath, '{}', 'utf-8');
84
- }
85
- catch {
86
- // 忽略错误
87
- }
88
- }
89
- }
90
- //# sourceMappingURL=token-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../src/core/token-manager.ts"],"names":[],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- /**
2
- * Workspace 管理
3
- */
4
- export declare class Workspace {
5
- private path;
6
- private currentVersion;
7
- private metadataPath;
8
- private metadata;
9
- constructor(path: string, metadataDir?: string);
10
- static create(workspaceDir: string, createTemp?: boolean, clientId?: string | null, clientWorkspacePath?: string | null, metadataDir?: string): Promise<Workspace>;
11
- private loadMetadata;
12
- private saveMetadata;
13
- setClientInfo(clientId: string, workspacePath: string | null): Promise<void>;
14
- getClientId(): string | null;
15
- getWorkspacePath(): string | null;
16
- getOldFiles(): Record<string, string>;
17
- updateFileList(files: Record<string, string>): Promise<void>;
18
- getFileHash(path: string): string | undefined;
19
- hasFile(path: string, hash: string): boolean;
20
- getPath(): string;
21
- getCurrentVersion(): number;
22
- setVersion(version: number): void;
23
- writeFile(relativePath: string, content: Buffer): Promise<void>;
24
- deleteFile(relativePath: string): Promise<void>;
25
- cleanup(): Promise<void>;
26
- disconnect(): Promise<void>;
27
- }
28
- //# sourceMappingURL=workspace.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAkC;gBAEtC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;WAoBjC,MAAM,CACjB,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,OAAe,EAC3B,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,mBAAmB,GAAE,MAAM,GAAG,IAAW,EACzC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,SAAS,CAAC;YAmDP,YAAY;YAYZ,YAAY;IAMpB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAelF,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAI/B,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAelE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAI5C,OAAO,IAAI,MAAM;IAIjB,iBAAiB,IAAI,MAAM;IAI3B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAU3B,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAcxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC"}
@@ -1,186 +0,0 @@
1
- /**
2
- * Workspace 管理
3
- */
4
- import { mkdtemp, rm, readdir, readFile } from 'fs/promises';
5
- import { join } from 'path';
6
- import { writeFile, mkdir, unlink } from 'fs/promises';
7
- import { existsSync } from 'fs';
8
- import { createHash } from 'crypto';
9
- import { tmpdir } from 'os';
10
- export class Workspace {
11
- path;
12
- currentVersion = 0;
13
- metadataPath;
14
- metadata = null;
15
- constructor(path, metadataDir) {
16
- this.path = path;
17
- // 元数据文件保存在工作区目录之外,避免污染同步目录
18
- // 基于工作区路径生成唯一的元数据文件名
19
- const hash = createHash('sha256').update(path).digest('hex').substring(0, 16);
20
- if (metadataDir) {
21
- // 使用指定的元数据目录
22
- if (!existsSync(metadataDir)) {
23
- mkdir(metadataDir, { recursive: true }).catch(() => {
24
- // 如果创建失败,使用临时目录作为后备
25
- });
26
- }
27
- this.metadataPath = join(metadataDir, `.mirror-metadata-${hash}.json`);
28
- }
29
- else {
30
- // 后备方案:使用系统临时目录
31
- this.metadataPath = join(tmpdir(), `.mirror-metadata-${hash}.json`);
32
- }
33
- }
34
- static async create(workspaceDir, createTemp = false, clientId = null, clientWorkspacePath = null, metadataDir) {
35
- if (createTemp) {
36
- // 创建临时目录
37
- const workspacePath = await mkdtemp(join(workspaceDir, 'mirror-'));
38
- return new Workspace(workspacePath, metadataDir);
39
- }
40
- else {
41
- // 直接使用 workspaceDir,不需要子目录(服务端只支持单个客户端)
42
- const actualWorkspacePath = workspaceDir;
43
- // 检查目录是否存在
44
- if (!existsSync(actualWorkspacePath)) {
45
- await mkdir(actualWorkspacePath, { recursive: true });
46
- }
47
- const workspace = new Workspace(actualWorkspacePath, metadataDir);
48
- // 尝试加载元数据
49
- await workspace.loadMetadata();
50
- // 如果元数据存在且工作目录路径匹配,复用工作区
51
- if (workspace.metadata &&
52
- workspace.metadata.workspacePath === clientWorkspacePath &&
53
- workspace.metadata.clientId === clientId) {
54
- workspace.currentVersion = workspace.metadata.version;
55
- return workspace;
56
- }
57
- // 如果元数据存在但工作目录路径不匹配,说明是不同的工作目录,清理
58
- if (workspace.metadata && workspace.metadata.workspacePath !== clientWorkspacePath) {
59
- console.log(`检测到不同工作目录: 旧=${workspace.metadata.workspacePath}, 新=${clientWorkspacePath},清理工作区`);
60
- await workspace.cleanup();
61
- await mkdir(actualWorkspacePath, { recursive: true });
62
- workspace.metadata = null;
63
- }
64
- else if (!workspace.metadata) {
65
- // 没有元数据,检查目录是否为空
66
- const entries = await readdir(actualWorkspacePath);
67
- if (entries.length > 0) {
68
- // 目录不为空,清理(可能是旧数据)
69
- await workspace.cleanup();
70
- await mkdir(actualWorkspacePath, { recursive: true });
71
- }
72
- }
73
- return workspace;
74
- }
75
- }
76
- async loadMetadata() {
77
- if (existsSync(this.metadataPath)) {
78
- try {
79
- const content = await readFile(this.metadataPath, 'utf-8');
80
- this.metadata = JSON.parse(content);
81
- }
82
- catch (error) {
83
- // 元数据文件损坏,忽略
84
- this.metadata = null;
85
- }
86
- }
87
- }
88
- async saveMetadata() {
89
- if (this.metadata) {
90
- await writeFile(this.metadataPath, JSON.stringify(this.metadata, null, 2), 'utf-8');
91
- }
92
- }
93
- async setClientInfo(clientId, workspacePath) {
94
- if (!this.metadata) {
95
- this.metadata = {
96
- clientId,
97
- workspacePath,
98
- version: 0,
99
- files: {},
100
- };
101
- }
102
- else {
103
- this.metadata.clientId = clientId;
104
- this.metadata.workspacePath = workspacePath;
105
- }
106
- await this.saveMetadata();
107
- }
108
- getClientId() {
109
- return this.metadata?.clientId || null;
110
- }
111
- getWorkspacePath() {
112
- return this.metadata?.workspacePath || null;
113
- }
114
- getOldFiles() {
115
- return this.metadata?.files || {};
116
- }
117
- async updateFileList(files) {
118
- if (!this.metadata) {
119
- this.metadata = {
120
- clientId: null,
121
- workspacePath: null,
122
- version: this.currentVersion,
123
- files,
124
- };
125
- }
126
- else {
127
- this.metadata.files = files;
128
- this.metadata.version = this.currentVersion;
129
- }
130
- await this.saveMetadata();
131
- }
132
- getFileHash(path) {
133
- return this.metadata?.files[path];
134
- }
135
- hasFile(path, hash) {
136
- return this.metadata?.files[path] === hash;
137
- }
138
- getPath() {
139
- return this.path;
140
- }
141
- getCurrentVersion() {
142
- return this.currentVersion;
143
- }
144
- setVersion(version) {
145
- this.currentVersion = version;
146
- if (this.metadata) {
147
- this.metadata.version = version;
148
- this.saveMetadata().catch(() => {
149
- // 忽略保存错误
150
- });
151
- }
152
- }
153
- async writeFile(relativePath, content) {
154
- const fullPath = join(this.path, relativePath);
155
- const dir = join(fullPath, '..');
156
- if (!existsSync(dir)) {
157
- await mkdir(dir, { recursive: true });
158
- }
159
- await writeFile(fullPath, content);
160
- }
161
- async deleteFile(relativePath) {
162
- const fullPath = join(this.path, relativePath);
163
- if (existsSync(fullPath)) {
164
- await unlink(fullPath);
165
- }
166
- }
167
- async cleanup() {
168
- try {
169
- // 清理工作区目录
170
- await rm(this.path, { recursive: true, force: true });
171
- // 清理元数据文件
172
- if (existsSync(this.metadataPath)) {
173
- await unlink(this.metadataPath);
174
- }
175
- this.metadata = null;
176
- }
177
- catch (error) {
178
- // 忽略清理错误
179
- }
180
- }
181
- async disconnect() {
182
- // 断开连接时保留工作区,只保存元数据
183
- await this.saveMetadata();
184
- }
185
- }
186
- //# sourceMappingURL=workspace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- /**
2
- * WebSocket 传输层
3
- */
4
- import { WebSocket, WebSocketServer } from 'ws';
5
- import type { Message } from '../core/protocol.js';
6
- export declare class WebSocketTransport {
7
- private ws;
8
- private server;
9
- private messageHandlers;
10
- private allMessageHandlers;
11
- private closeHandlers;
12
- createServer(port: number, onConnection: (ws: WebSocket) => void): Promise<WebSocketServer>;
13
- connect(url: string): Promise<WebSocket>;
14
- private setupMessageHandler;
15
- send(message: Message): void;
16
- onMessage(type: string, handler: (message: Message) => void): void;
17
- onAnyMessage(handler: (message: Message) => void): void;
18
- onClose(handler: () => void): void;
19
- getWebSocket(): WebSocket | null;
20
- close(): void;
21
- }
22
- //# sourceMappingURL=websocket.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,aAAa,CAAyB;IAG9C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAiB3F,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAcxC,OAAO,CAAC,mBAAmB;IA8B3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAO5B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIlE,YAAY,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIvD,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,YAAY,IAAI,SAAS,GAAG,IAAI;IAIhC,KAAK,IAAI,IAAI;CAad"}
@@ -1,96 +0,0 @@
1
- /**
2
- * WebSocket 传输层
3
- */
4
- import { WebSocket, WebSocketServer } from 'ws';
5
- export class WebSocketTransport {
6
- ws = null;
7
- server = null;
8
- messageHandlers = new Map();
9
- allMessageHandlers = [];
10
- closeHandlers = [];
11
- // Server side
12
- createServer(port, onConnection) {
13
- return new Promise((resolve, reject) => {
14
- const server = new WebSocketServer({ port }, () => {
15
- resolve(server);
16
- });
17
- server.on('error', reject);
18
- server.on('connection', (ws) => {
19
- this.setupMessageHandler(ws);
20
- onConnection(ws);
21
- });
22
- this.server = server;
23
- });
24
- }
25
- // Client side
26
- connect(url) {
27
- return new Promise((resolve, reject) => {
28
- const ws = new WebSocket(url);
29
- ws.on('open', () => {
30
- this.ws = ws;
31
- this.setupMessageHandler(ws);
32
- resolve(ws);
33
- });
34
- ws.on('error', reject);
35
- });
36
- }
37
- setupMessageHandler(ws) {
38
- ws.on('message', (data) => {
39
- try {
40
- // 正确处理 Buffer 和 string 类型的数据
41
- const messageStr = typeof data === 'string' ? data : data.toString('utf8');
42
- const message = JSON.parse(messageStr);
43
- // 调用特定类型的处理器
44
- const handler = this.messageHandlers.get(message.type);
45
- if (handler) {
46
- handler(message);
47
- }
48
- // 调用所有消息处理器
49
- for (const h of this.allMessageHandlers) {
50
- h(message);
51
- }
52
- }
53
- catch (error) {
54
- console.error('Failed to parse message:', error);
55
- }
56
- });
57
- ws.on('close', () => {
58
- // 调用所有关闭处理器
59
- for (const handler of this.closeHandlers) {
60
- handler();
61
- }
62
- });
63
- }
64
- send(message) {
65
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
66
- throw new Error('WebSocket is not connected');
67
- }
68
- this.ws.send(JSON.stringify(message));
69
- }
70
- onMessage(type, handler) {
71
- this.messageHandlers.set(type, handler);
72
- }
73
- onAnyMessage(handler) {
74
- this.allMessageHandlers.push(handler);
75
- }
76
- onClose(handler) {
77
- this.closeHandlers.push(handler);
78
- }
79
- getWebSocket() {
80
- return this.ws;
81
- }
82
- close() {
83
- if (this.ws) {
84
- this.ws.close();
85
- this.ws = null;
86
- }
87
- if (this.server) {
88
- this.server.close();
89
- this.server = null;
90
- }
91
- this.messageHandlers.clear();
92
- this.allMessageHandlers = [];
93
- this.closeHandlers = [];
94
- }
95
- }
96
- //# sourceMappingURL=websocket.js.map