@jay-framework/editor-client 0.6.0 → 0.6.2

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.
package/dist/index.cjs CHANGED
@@ -19,37 +19,39 @@ class ConnectionManager {
19
19
  __publicField(this, "editorId");
20
20
  __publicField(this, "autoReconnect");
21
21
  __publicField(this, "reconnectDelay");
22
- __publicField(this, "maxReconnectAttempts");
23
- __publicField(this, "reconnectAttempts", 0);
24
22
  __publicField(this, "reconnectTimer", null);
25
23
  __publicField(this, "isManualDisconnect", false);
24
+ __publicField(this, "isConnecting", false);
26
25
  __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
26
+ __publicField(this, "stateChangeCallbacks", /* @__PURE__ */ new Set());
27
27
  this.portRange = options.portRange || [3101, 3200];
28
28
  this.scanTimeout = options.scanTimeout || 5e3;
29
29
  this.retryAttempts = options.retryAttempts || 3;
30
30
  this.editorId = options.editorId || uuid.v4();
31
31
  this.autoReconnect = options.autoReconnect ?? true;
32
32
  this.reconnectDelay = options.reconnectDelay ?? 1e3;
33
- this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
34
33
  }
35
34
  async connect() {
36
- if (this.connectionState === "connected") {
35
+ if (this.connectionState === "connected" || this.isConnecting) {
37
36
  return;
38
37
  }
39
38
  this.isManualDisconnect = false;
40
- this.reconnectAttempts = 0;
41
- this.connectionState = "connecting";
39
+ this.isConnecting = true;
40
+ this.updateConnectionState("connecting");
42
41
  try {
43
42
  const serverPort = await this.discoverServer();
44
43
  await this.establishConnection(serverPort);
45
- this.connectionState = "connected";
44
+ this.updateConnectionState("connected");
46
45
  } catch (error) {
47
- this.connectionState = "error";
46
+ this.updateConnectionState("error");
48
47
  throw error;
48
+ } finally {
49
+ this.isConnecting = false;
49
50
  }
50
51
  }
51
52
  async disconnect() {
52
53
  this.isManualDisconnect = true;
54
+ this.isConnecting = false;
53
55
  if (this.reconnectTimer) {
54
56
  clearTimeout(this.reconnectTimer);
55
57
  this.reconnectTimer = null;
@@ -58,11 +60,17 @@ class ConnectionManager {
58
60
  this.socket.disconnect();
59
61
  this.socket = null;
60
62
  }
61
- this.connectionState = "disconnected";
63
+ this.updateConnectionState("disconnected");
62
64
  }
63
65
  getConnectionState() {
64
66
  return this.connectionState;
65
67
  }
68
+ onConnectionStateChange(callback) {
69
+ this.stateChangeCallbacks.add(callback);
70
+ return () => {
71
+ this.stateChangeCallbacks.delete(callback);
72
+ };
73
+ }
66
74
  async sendMessage(message) {
67
75
  if (this.connectionState !== "connected") {
68
76
  throw new Error("Not connected to editor server");
@@ -82,15 +90,30 @@ class ConnectionManager {
82
90
  this.socket.emit("protocol-message", protocolMessage);
83
91
  });
84
92
  }
85
- onConnectionStateChange(callback) {
86
- const checkState = () => {
87
- const currentState = this.getConnectionState();
88
- callback(currentState);
89
- if (currentState === "disconnected" && this.autoReconnect && !this.isManualDisconnect) {
90
- this.attemptReconnect();
93
+ updateConnectionState(newState) {
94
+ if (this.connectionState !== newState) {
95
+ this.connectionState;
96
+ this.connectionState = newState;
97
+ this.stateChangeCallbacks.forEach((callback) => {
98
+ try {
99
+ callback(newState);
100
+ } catch (error) {
101
+ console.error("Error in connection state callback:", error);
102
+ }
103
+ });
104
+ if (newState === "disconnected" && this.autoReconnect && !this.isManualDisconnect) {
105
+ this.scheduleReconnect();
91
106
  }
92
- };
93
- setInterval(checkState, 1e3);
107
+ }
108
+ }
109
+ scheduleReconnect() {
110
+ if (this.isManualDisconnect || this.reconnectTimer) {
111
+ return;
112
+ }
113
+ this.reconnectTimer = setTimeout(() => {
114
+ this.reconnectTimer = null;
115
+ this.attemptReconnect();
116
+ }, this.reconnectDelay);
94
117
  }
95
118
  async discoverServer() {
96
119
  const [startPort, endPort] = this.portRange;
@@ -154,7 +177,7 @@ class ConnectionManager {
154
177
  });
155
178
  this.socket.on("disconnect", () => {
156
179
  console.log("Disconnected from editor server");
157
- this.connectionState = "disconnected";
180
+ this.updateConnectionState("disconnected");
158
181
  });
159
182
  });
160
183
  }
@@ -174,26 +197,16 @@ class ConnectionManager {
174
197
  });
175
198
  }
176
199
  async attemptReconnect() {
177
- if (this.isManualDisconnect || this.reconnectAttempts >= this.maxReconnectAttempts) {
200
+ if (this.isManualDisconnect || this.isConnecting) {
178
201
  return;
179
202
  }
180
- this.reconnectAttempts++;
181
- console.log(
182
- `Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
183
- );
203
+ console.log("Attempting to reconnect...");
184
204
  try {
185
205
  await this.connect();
186
- this.reconnectAttempts = 0;
187
206
  console.log("Reconnected successfully");
188
207
  } catch (error) {
189
208
  console.error("Reconnection failed:", error);
190
- if (this.reconnectAttempts < this.maxReconnectAttempts) {
191
- this.reconnectTimer = setTimeout(() => {
192
- this.attemptReconnect();
193
- }, this.reconnectDelay * this.reconnectAttempts);
194
- } else {
195
- console.error("Max reconnection attempts reached");
196
- }
209
+ this.scheduleReconnect();
197
210
  }
198
211
  }
199
212
  }
package/dist/index.d.ts CHANGED
@@ -8,8 +8,8 @@ interface ConnectionManagerOptions {
8
8
  editorId?: string;
9
9
  autoReconnect?: boolean;
10
10
  reconnectDelay?: number;
11
- maxReconnectAttempts?: number;
12
11
  }
12
+ type ConnectionStateCallback = (state: ConnectionState) => void;
13
13
  declare class ConnectionManager {
14
14
  private socket;
15
15
  private connectionState;
@@ -19,17 +19,19 @@ declare class ConnectionManager {
19
19
  private editorId;
20
20
  private autoReconnect;
21
21
  private reconnectDelay;
22
- private maxReconnectAttempts;
23
- private reconnectAttempts;
24
22
  private reconnectTimer;
25
23
  private isManualDisconnect;
24
+ private isConnecting;
26
25
  private pendingRequests;
26
+ private stateChangeCallbacks;
27
27
  constructor(options?: ConnectionManagerOptions);
28
28
  connect(): Promise<void>;
29
29
  disconnect(): Promise<void>;
30
30
  getConnectionState(): ConnectionState;
31
+ onConnectionStateChange(callback: ConnectionStateCallback): () => void;
31
32
  sendMessage<T extends PublishMessage | SaveImageMessage | HasImageMessage>(message: T): Promise<T extends PublishMessage ? PublishResponse : T extends SaveImageMessage ? SaveImageResponse : T extends HasImageMessage ? HasImageResponse : never>;
32
- onConnectionStateChange(callback: (state: ConnectionState) => void): void;
33
+ private updateConnectionState;
34
+ private scheduleReconnect;
33
35
  private discoverServer;
34
36
  private checkPort;
35
37
  private establishConnection;
@@ -46,7 +48,7 @@ declare class EditorClient implements EditorProtocol {
46
48
  connect(): Promise<void>;
47
49
  disconnect(): Promise<void>;
48
50
  getConnectionState(): _jay_framework_editor_protocol.ConnectionState;
49
- onConnectionStateChange(callback: (state: any) => void): void;
51
+ onConnectionStateChange(callback: ConnectionStateCallback): () => void;
50
52
  publish(params: PublishMessage): Promise<PublishResponse>;
51
53
  saveImage(params: SaveImageMessage): Promise<SaveImageResponse>;
52
54
  hasImage(params: HasImageMessage): Promise<HasImageResponse>;
@@ -55,4 +57,4 @@ declare class EditorClient implements EditorProtocol {
55
57
  declare function createEditorClient(options?: EditorClientOptions): EditorClient;
56
58
  declare function createEditorClientWithConnectionManager(connectionManager: ConnectionManager): EditorClient;
57
59
 
58
- export { ConnectionManager, type ConnectionManagerOptions, EditorClient, type EditorClientOptions, createConnectionManager, createEditorClient, createEditorClientWithConnectionManager };
60
+ export { ConnectionManager, type ConnectionManagerOptions, type ConnectionStateCallback, EditorClient, type EditorClientOptions, createConnectionManager, createEditorClient, createEditorClientWithConnectionManager };
package/dist/index.js CHANGED
@@ -17,37 +17,39 @@ class ConnectionManager {
17
17
  __publicField(this, "editorId");
18
18
  __publicField(this, "autoReconnect");
19
19
  __publicField(this, "reconnectDelay");
20
- __publicField(this, "maxReconnectAttempts");
21
- __publicField(this, "reconnectAttempts", 0);
22
20
  __publicField(this, "reconnectTimer", null);
23
21
  __publicField(this, "isManualDisconnect", false);
22
+ __publicField(this, "isConnecting", false);
24
23
  __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
24
+ __publicField(this, "stateChangeCallbacks", /* @__PURE__ */ new Set());
25
25
  this.portRange = options.portRange || [3101, 3200];
26
26
  this.scanTimeout = options.scanTimeout || 5e3;
27
27
  this.retryAttempts = options.retryAttempts || 3;
28
28
  this.editorId = options.editorId || v4();
29
29
  this.autoReconnect = options.autoReconnect ?? true;
30
30
  this.reconnectDelay = options.reconnectDelay ?? 1e3;
31
- this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
32
31
  }
33
32
  async connect() {
34
- if (this.connectionState === "connected") {
33
+ if (this.connectionState === "connected" || this.isConnecting) {
35
34
  return;
36
35
  }
37
36
  this.isManualDisconnect = false;
38
- this.reconnectAttempts = 0;
39
- this.connectionState = "connecting";
37
+ this.isConnecting = true;
38
+ this.updateConnectionState("connecting");
40
39
  try {
41
40
  const serverPort = await this.discoverServer();
42
41
  await this.establishConnection(serverPort);
43
- this.connectionState = "connected";
42
+ this.updateConnectionState("connected");
44
43
  } catch (error) {
45
- this.connectionState = "error";
44
+ this.updateConnectionState("error");
46
45
  throw error;
46
+ } finally {
47
+ this.isConnecting = false;
47
48
  }
48
49
  }
49
50
  async disconnect() {
50
51
  this.isManualDisconnect = true;
52
+ this.isConnecting = false;
51
53
  if (this.reconnectTimer) {
52
54
  clearTimeout(this.reconnectTimer);
53
55
  this.reconnectTimer = null;
@@ -56,11 +58,17 @@ class ConnectionManager {
56
58
  this.socket.disconnect();
57
59
  this.socket = null;
58
60
  }
59
- this.connectionState = "disconnected";
61
+ this.updateConnectionState("disconnected");
60
62
  }
61
63
  getConnectionState() {
62
64
  return this.connectionState;
63
65
  }
66
+ onConnectionStateChange(callback) {
67
+ this.stateChangeCallbacks.add(callback);
68
+ return () => {
69
+ this.stateChangeCallbacks.delete(callback);
70
+ };
71
+ }
64
72
  async sendMessage(message) {
65
73
  if (this.connectionState !== "connected") {
66
74
  throw new Error("Not connected to editor server");
@@ -80,15 +88,30 @@ class ConnectionManager {
80
88
  this.socket.emit("protocol-message", protocolMessage);
81
89
  });
82
90
  }
83
- onConnectionStateChange(callback) {
84
- const checkState = () => {
85
- const currentState = this.getConnectionState();
86
- callback(currentState);
87
- if (currentState === "disconnected" && this.autoReconnect && !this.isManualDisconnect) {
88
- this.attemptReconnect();
91
+ updateConnectionState(newState) {
92
+ if (this.connectionState !== newState) {
93
+ this.connectionState;
94
+ this.connectionState = newState;
95
+ this.stateChangeCallbacks.forEach((callback) => {
96
+ try {
97
+ callback(newState);
98
+ } catch (error) {
99
+ console.error("Error in connection state callback:", error);
100
+ }
101
+ });
102
+ if (newState === "disconnected" && this.autoReconnect && !this.isManualDisconnect) {
103
+ this.scheduleReconnect();
89
104
  }
90
- };
91
- setInterval(checkState, 1e3);
105
+ }
106
+ }
107
+ scheduleReconnect() {
108
+ if (this.isManualDisconnect || this.reconnectTimer) {
109
+ return;
110
+ }
111
+ this.reconnectTimer = setTimeout(() => {
112
+ this.reconnectTimer = null;
113
+ this.attemptReconnect();
114
+ }, this.reconnectDelay);
92
115
  }
93
116
  async discoverServer() {
94
117
  const [startPort, endPort] = this.portRange;
@@ -152,7 +175,7 @@ class ConnectionManager {
152
175
  });
153
176
  this.socket.on("disconnect", () => {
154
177
  console.log("Disconnected from editor server");
155
- this.connectionState = "disconnected";
178
+ this.updateConnectionState("disconnected");
156
179
  });
157
180
  });
158
181
  }
@@ -172,26 +195,16 @@ class ConnectionManager {
172
195
  });
173
196
  }
174
197
  async attemptReconnect() {
175
- if (this.isManualDisconnect || this.reconnectAttempts >= this.maxReconnectAttempts) {
198
+ if (this.isManualDisconnect || this.isConnecting) {
176
199
  return;
177
200
  }
178
- this.reconnectAttempts++;
179
- console.log(
180
- `Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
181
- );
201
+ console.log("Attempting to reconnect...");
182
202
  try {
183
203
  await this.connect();
184
- this.reconnectAttempts = 0;
185
204
  console.log("Reconnected successfully");
186
205
  } catch (error) {
187
206
  console.error("Reconnection failed:", error);
188
- if (this.reconnectAttempts < this.maxReconnectAttempts) {
189
- this.reconnectTimer = setTimeout(() => {
190
- this.attemptReconnect();
191
- }, this.reconnectDelay * this.reconnectAttempts);
192
- } else {
193
- console.error("Max reconnection attempts reached");
194
- }
207
+ this.scheduleReconnect();
195
208
  }
196
209
  }
197
210
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/editor-client",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -27,14 +27,14 @@
27
27
  "test:watch": "vitest"
28
28
  },
29
29
  "dependencies": {
30
- "@jay-framework/editor-protocol": "^0.6.0",
30
+ "@jay-framework/editor-protocol": "^0.6.2",
31
31
  "get-port": "^7.0.0",
32
32
  "socket.io-client": "^4.7.4",
33
33
  "uuid": "^9.0.1"
34
34
  },
35
35
  "devDependencies": {
36
- "@jay-framework/dev-environment": "^0.6.0",
37
- "@jay-framework/jay-cli": "^0.6.0",
36
+ "@jay-framework/dev-environment": "^0.6.2",
37
+ "@jay-framework/jay-cli": "^0.6.2",
38
38
  "@types/node": "^22.15.21",
39
39
  "@types/uuid": "^9.0.7",
40
40
  "rimraf": "^5.0.5",