@alfe.ai/remote 0.0.0 → 0.1.1

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.d.cts CHANGED
@@ -16,9 +16,15 @@
16
16
  * • viewer → plugin: SESSION_OPEN, SESSION_CLOSE, SCREENCAST_ACK, INPUT_*,
17
17
  * RESIZE, TAKEOVER_REQUEST, RELEASE_CONTROL, TERMINAL_INPUT, TERMINAL_RESIZE
18
18
  *
19
- * Keep this file byte-identical with `services/remote/src/remote-protocol.ts`.
19
+ * Keep agent-facing frame values byte-compatible with
20
+ * `services/remote/src/remote-protocol.ts`. The relay may define private frame
21
+ * types that it consumes without forwarding them to the agent.
20
22
  */
21
23
  declare const REMOTE_HEADER_SIZE = 5;
24
+ /** Maximum complete WebSocket message size, including the five-byte header. */
25
+ declare const REMOTE_MAX_PAYLOAD: number;
26
+ /** Control payloads are deliberately much smaller than media/terminal frames. */
27
+ declare const REMOTE_MAX_JSON_PAYLOAD: number;
22
28
  declare const RemoteFrameType: {
23
29
  /** viewer→plugin: a viewer attached. Payload: SessionOpenPayload. */
24
30
  readonly SESSION_OPEN: 1;
@@ -116,13 +122,14 @@ interface TerminalResizePayload {
116
122
  cols: number;
117
123
  rows: number;
118
124
  }
125
+ declare function isRemoteFrameType(value: unknown): value is RemoteFrameType;
126
+ declare function isRelayToAgentFrameType(value: unknown): value is RemoteFrameType;
127
+ declare function isAgentToRelayFrameType(value: unknown): value is RemoteFrameType;
119
128
  declare function isRemoteFrame(data: Buffer): boolean;
120
129
  declare function encodeFrame(type: RemoteFrameType, sessionId: number, payload?: Buffer): Buffer;
121
130
  declare function decodeFrame(buf: Buffer): RemoteFrame;
122
131
  declare function encodeJsonFrame(type: RemoteFrameType, sessionId: number, obj: unknown): Buffer;
123
- /** Best-effort JSON decode returns null on a malformed payload so a single
124
- * corrupt frame can't crash the per-session handler. Callers assert the shape
125
- * (e.g. `decodeJson(p) as SessionOpenPayload | null`). */
132
+ /** Best-effort bounded JSON decode. Shape-specific callers use the decoders below. */
126
133
  declare function decodeJson(payload: Buffer): unknown;
127
134
  /** Encode a screencast frame: [metaLen:u16BE][meta JSON][raw JPEG]. The JPEG is
128
135
  * forwarded raw (already base64-decoded from CDP) to avoid base64 bloat. */
@@ -131,8 +138,15 @@ declare function decodeScreencastFrame(payload: Buffer): {
131
138
  meta: ScreencastFrameMeta;
132
139
  jpeg: Buffer;
133
140
  } | null;
134
- /** Maximum WS message size (must align across daemon plugin and relay). */
135
- declare const REMOTE_MAX_PAYLOAD: number;
141
+ declare function decodeSessionOpenPayload(payload: Buffer): SessionOpenPayload | null;
142
+ declare function decodeScreencastAckPayload(payload: Buffer): {
143
+ frameSeq: number;
144
+ } | null;
145
+ declare function decodeResizePayload(payload: Buffer): ResizePayload | null;
146
+ declare function decodeMouseInputPayload(payload: Buffer): MouseInputPayload | null;
147
+ declare function decodeWheelInputPayload(payload: Buffer): WheelInputPayload | null;
148
+ declare function decodeKeyInputPayload(payload: Buffer): KeyInputPayload | null;
149
+ declare function decodeTerminalResizePayload(payload: Buffer): TerminalResizePayload | null;
136
150
  //#endregion
137
151
  //#region src/surface.d.ts
138
152
  interface SurfaceHandler {
@@ -163,9 +177,9 @@ interface RemoteServiceClientOptions {
163
177
  * dispatches by `frame.sessionId` to the owning surface handler. Kept on the
164
178
  * transport as a single callback so this package stays surface-agnostic.
165
179
  */
166
- onFrame: (frame: RemoteFrame) => void;
180
+ onFrame: (frame: RemoteFrame) => void | Promise<void>;
167
181
  /** Called when the WS connection state changes. */
168
- onConnectionChange?: (connected: boolean) => void;
182
+ onConnectionChange?: (connected: boolean) => void | Promise<void>;
169
183
  /** Optional logger (defaults to console). */
170
184
  logger?: Logger;
171
185
  }
@@ -176,27 +190,31 @@ declare class RemoteServiceClient {
176
190
  private ws;
177
191
  private stopped;
178
192
  private connected;
193
+ private generation;
179
194
  private retryCount;
180
195
  private retryTimer;
181
196
  private heartbeatTimer;
182
197
  private isAlive;
183
198
  private readonly log;
199
+ private readonly relayUrl;
200
+ private readonly endpointLabel;
184
201
  constructor(options: RemoteServiceClientOptions);
185
202
  get isConnected(): boolean;
186
203
  /** Backpressure signal for the screencast pump — bytes queued but not flushed. */
187
204
  get bufferedAmount(): number;
205
+ /** Start one connection lifecycle. Repeated starts in the same lifecycle are no-ops. */
188
206
  start(): void;
207
+ /** Stop the current lifecycle and invalidate every callback owned by it. */
189
208
  stop(): void;
190
- /** Send a pre-encoded binary frame. No-op if the socket isn't open. */
209
+ /** Send a validated pre-encoded agent→relay frame when the socket is open. */
191
210
  sendFrame(buf: Buffer): void;
192
211
  private doConnect;
193
212
  private scheduleReconnect;
194
- /**
195
- * Detect a silently-dropped connection. Each tick: if no inbound liveness
196
- * (pong/ping/message) was seen since the last tick, force-close so the
197
- * `close` handler reconnects; otherwise send a fresh ping and arm the next.
198
- */
199
213
  private startHeartbeat;
214
+ private setConnected;
215
+ private isActive;
216
+ private isCurrent;
217
+ private clearRetry;
200
218
  private clearHeartbeat;
201
219
  }
202
220
  //#endregion
@@ -240,4 +258,4 @@ declare class TurnController {
240
258
  private setOwner;
241
259
  }
242
260
  //#endregion
243
- export { KeyInputPayload, type Logger, MouseInputPayload, REMOTE_HEADER_SIZE, REMOTE_MAX_PAYLOAD, RemoteFrame, RemoteFrameType, RemoteServiceClient, type RemoteServiceClientOptions, RemoteSurface, ResizePayload, ScreencastFrameMeta, SessionOpenPayload, SessionStatePayload, type SurfaceHandler, TerminalResizePayload, TurnController, type TurnControllerOptions, type TurnOwner, WheelInputPayload, decodeFrame, decodeJson, decodeScreencastFrame, encodeFrame, encodeJsonFrame, encodeScreencastFrame, isRemoteFrame };
261
+ export { KeyInputPayload, type Logger, MouseInputPayload, REMOTE_HEADER_SIZE, REMOTE_MAX_JSON_PAYLOAD, REMOTE_MAX_PAYLOAD, RemoteFrame, RemoteFrameType, RemoteServiceClient, type RemoteServiceClientOptions, RemoteSurface, ResizePayload, ScreencastFrameMeta, SessionOpenPayload, SessionStatePayload, type SurfaceHandler, TerminalResizePayload, TurnController, type TurnControllerOptions, type TurnOwner, WheelInputPayload, decodeFrame, decodeJson, decodeKeyInputPayload, decodeMouseInputPayload, decodeResizePayload, decodeScreencastAckPayload, decodeScreencastFrame, decodeSessionOpenPayload, decodeTerminalResizePayload, decodeWheelInputPayload, encodeFrame, encodeJsonFrame, encodeScreencastFrame, isAgentToRelayFrameType, isRelayToAgentFrameType, isRemoteFrame, isRemoteFrameType };
package/dist/index.d.ts CHANGED
@@ -16,9 +16,15 @@
16
16
  * • viewer → plugin: SESSION_OPEN, SESSION_CLOSE, SCREENCAST_ACK, INPUT_*,
17
17
  * RESIZE, TAKEOVER_REQUEST, RELEASE_CONTROL, TERMINAL_INPUT, TERMINAL_RESIZE
18
18
  *
19
- * Keep this file byte-identical with `services/remote/src/remote-protocol.ts`.
19
+ * Keep agent-facing frame values byte-compatible with
20
+ * `services/remote/src/remote-protocol.ts`. The relay may define private frame
21
+ * types that it consumes without forwarding them to the agent.
20
22
  */
21
23
  declare const REMOTE_HEADER_SIZE = 5;
24
+ /** Maximum complete WebSocket message size, including the five-byte header. */
25
+ declare const REMOTE_MAX_PAYLOAD: number;
26
+ /** Control payloads are deliberately much smaller than media/terminal frames. */
27
+ declare const REMOTE_MAX_JSON_PAYLOAD: number;
22
28
  declare const RemoteFrameType: {
23
29
  /** viewer→plugin: a viewer attached. Payload: SessionOpenPayload. */
24
30
  readonly SESSION_OPEN: 1;
@@ -116,13 +122,14 @@ interface TerminalResizePayload {
116
122
  cols: number;
117
123
  rows: number;
118
124
  }
125
+ declare function isRemoteFrameType(value: unknown): value is RemoteFrameType;
126
+ declare function isRelayToAgentFrameType(value: unknown): value is RemoteFrameType;
127
+ declare function isAgentToRelayFrameType(value: unknown): value is RemoteFrameType;
119
128
  declare function isRemoteFrame(data: Buffer): boolean;
120
129
  declare function encodeFrame(type: RemoteFrameType, sessionId: number, payload?: Buffer): Buffer;
121
130
  declare function decodeFrame(buf: Buffer): RemoteFrame;
122
131
  declare function encodeJsonFrame(type: RemoteFrameType, sessionId: number, obj: unknown): Buffer;
123
- /** Best-effort JSON decode returns null on a malformed payload so a single
124
- * corrupt frame can't crash the per-session handler. Callers assert the shape
125
- * (e.g. `decodeJson(p) as SessionOpenPayload | null`). */
132
+ /** Best-effort bounded JSON decode. Shape-specific callers use the decoders below. */
126
133
  declare function decodeJson(payload: Buffer): unknown;
127
134
  /** Encode a screencast frame: [metaLen:u16BE][meta JSON][raw JPEG]. The JPEG is
128
135
  * forwarded raw (already base64-decoded from CDP) to avoid base64 bloat. */
@@ -131,8 +138,15 @@ declare function decodeScreencastFrame(payload: Buffer): {
131
138
  meta: ScreencastFrameMeta;
132
139
  jpeg: Buffer;
133
140
  } | null;
134
- /** Maximum WS message size (must align across daemon plugin and relay). */
135
- declare const REMOTE_MAX_PAYLOAD: number;
141
+ declare function decodeSessionOpenPayload(payload: Buffer): SessionOpenPayload | null;
142
+ declare function decodeScreencastAckPayload(payload: Buffer): {
143
+ frameSeq: number;
144
+ } | null;
145
+ declare function decodeResizePayload(payload: Buffer): ResizePayload | null;
146
+ declare function decodeMouseInputPayload(payload: Buffer): MouseInputPayload | null;
147
+ declare function decodeWheelInputPayload(payload: Buffer): WheelInputPayload | null;
148
+ declare function decodeKeyInputPayload(payload: Buffer): KeyInputPayload | null;
149
+ declare function decodeTerminalResizePayload(payload: Buffer): TerminalResizePayload | null;
136
150
  //#endregion
137
151
  //#region src/surface.d.ts
138
152
  interface SurfaceHandler {
@@ -163,9 +177,9 @@ interface RemoteServiceClientOptions {
163
177
  * dispatches by `frame.sessionId` to the owning surface handler. Kept on the
164
178
  * transport as a single callback so this package stays surface-agnostic.
165
179
  */
166
- onFrame: (frame: RemoteFrame) => void;
180
+ onFrame: (frame: RemoteFrame) => void | Promise<void>;
167
181
  /** Called when the WS connection state changes. */
168
- onConnectionChange?: (connected: boolean) => void;
182
+ onConnectionChange?: (connected: boolean) => void | Promise<void>;
169
183
  /** Optional logger (defaults to console). */
170
184
  logger?: Logger;
171
185
  }
@@ -176,27 +190,31 @@ declare class RemoteServiceClient {
176
190
  private ws;
177
191
  private stopped;
178
192
  private connected;
193
+ private generation;
179
194
  private retryCount;
180
195
  private retryTimer;
181
196
  private heartbeatTimer;
182
197
  private isAlive;
183
198
  private readonly log;
199
+ private readonly relayUrl;
200
+ private readonly endpointLabel;
184
201
  constructor(options: RemoteServiceClientOptions);
185
202
  get isConnected(): boolean;
186
203
  /** Backpressure signal for the screencast pump — bytes queued but not flushed. */
187
204
  get bufferedAmount(): number;
205
+ /** Start one connection lifecycle. Repeated starts in the same lifecycle are no-ops. */
188
206
  start(): void;
207
+ /** Stop the current lifecycle and invalidate every callback owned by it. */
189
208
  stop(): void;
190
- /** Send a pre-encoded binary frame. No-op if the socket isn't open. */
209
+ /** Send a validated pre-encoded agent→relay frame when the socket is open. */
191
210
  sendFrame(buf: Buffer): void;
192
211
  private doConnect;
193
212
  private scheduleReconnect;
194
- /**
195
- * Detect a silently-dropped connection. Each tick: if no inbound liveness
196
- * (pong/ping/message) was seen since the last tick, force-close so the
197
- * `close` handler reconnects; otherwise send a fresh ping and arm the next.
198
- */
199
213
  private startHeartbeat;
214
+ private setConnected;
215
+ private isActive;
216
+ private isCurrent;
217
+ private clearRetry;
200
218
  private clearHeartbeat;
201
219
  }
202
220
  //#endregion
@@ -240,4 +258,4 @@ declare class TurnController {
240
258
  private setOwner;
241
259
  }
242
260
  //#endregion
243
- export { KeyInputPayload, type Logger, MouseInputPayload, REMOTE_HEADER_SIZE, REMOTE_MAX_PAYLOAD, RemoteFrame, RemoteFrameType, RemoteServiceClient, type RemoteServiceClientOptions, RemoteSurface, ResizePayload, ScreencastFrameMeta, SessionOpenPayload, SessionStatePayload, type SurfaceHandler, TerminalResizePayload, TurnController, type TurnControllerOptions, type TurnOwner, WheelInputPayload, decodeFrame, decodeJson, decodeScreencastFrame, encodeFrame, encodeJsonFrame, encodeScreencastFrame, isRemoteFrame };
261
+ export { KeyInputPayload, type Logger, MouseInputPayload, REMOTE_HEADER_SIZE, REMOTE_MAX_JSON_PAYLOAD, REMOTE_MAX_PAYLOAD, RemoteFrame, RemoteFrameType, RemoteServiceClient, type RemoteServiceClientOptions, RemoteSurface, ResizePayload, ScreencastFrameMeta, SessionOpenPayload, SessionStatePayload, type SurfaceHandler, TerminalResizePayload, TurnController, type TurnControllerOptions, type TurnOwner, WheelInputPayload, decodeFrame, decodeJson, decodeKeyInputPayload, decodeMouseInputPayload, decodeResizePayload, decodeScreencastAckPayload, decodeScreencastFrame, decodeSessionOpenPayload, decodeTerminalResizePayload, decodeWheelInputPayload, encodeFrame, encodeJsonFrame, encodeScreencastFrame, isAgentToRelayFrameType, isRelayToAgentFrameType, isRemoteFrame, isRemoteFrameType };