flashq 0.3.3 → 0.3.4
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/client/connection.d.ts +113 -9
- package/dist/client/connection.d.ts.map +1 -1
- package/dist/client/connection.js +148 -51
- package/dist/client/connection.js.map +1 -1
- package/dist/client/reconnect.d.ts +100 -0
- package/dist/client/reconnect.d.ts.map +1 -0
- package/dist/client/reconnect.js +154 -0
- package/dist/client/reconnect.js.map +1 -0
- package/dist/client/tcp/handler.d.ts +106 -0
- package/dist/client/tcp/handler.d.ts.map +1 -0
- package/dist/client/tcp/handler.js +155 -0
- package/dist/client/tcp/handler.js.map +1 -0
- package/dist/client/tcp/index.d.ts +5 -0
- package/dist/client/tcp/index.d.ts.map +1 -0
- package/dist/client/tcp/index.js +14 -0
- package/dist/client/tcp/index.js.map +1 -0
- package/dist/client/validation.d.ts +77 -0
- package/dist/client/validation.d.ts.map +1 -0
- package/dist/client/validation.js +112 -0
- package/dist/client/validation.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reconnection logic for FlashQ client.
|
|
3
|
+
*
|
|
4
|
+
* Implements exponential backoff with jitter for automatic reconnection
|
|
5
|
+
* after connection loss.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import type { Logger } from '../utils/logger';
|
|
9
|
+
/** Connection state machine states */
|
|
10
|
+
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'closed';
|
|
11
|
+
/** Configuration for reconnection behavior */
|
|
12
|
+
export interface ReconnectConfig {
|
|
13
|
+
/** Whether auto-reconnect is enabled */
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
/** Maximum number of reconnection attempts (0 = unlimited) */
|
|
16
|
+
maxAttempts: number;
|
|
17
|
+
/** Initial delay between reconnection attempts (ms) */
|
|
18
|
+
initialDelay: number;
|
|
19
|
+
/** Maximum delay between reconnection attempts (ms) */
|
|
20
|
+
maxDelay: number;
|
|
21
|
+
}
|
|
22
|
+
/** Event data emitted during reconnection */
|
|
23
|
+
export interface ReconnectEventData {
|
|
24
|
+
/** Current attempt number */
|
|
25
|
+
attempt: number;
|
|
26
|
+
/** Delay before this attempt (ms) */
|
|
27
|
+
delay: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Manages reconnection state and scheduling.
|
|
31
|
+
*
|
|
32
|
+
* Implements exponential backoff with jitter:
|
|
33
|
+
* delay = min(initialDelay * 2^attempt, maxDelay) + random jitter
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const manager = new ReconnectManager(config, logger, emitter);
|
|
38
|
+
*
|
|
39
|
+
* manager.schedule(async () => {
|
|
40
|
+
* await connect();
|
|
41
|
+
* manager.reset();
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class ReconnectManager {
|
|
46
|
+
private readonly config;
|
|
47
|
+
private readonly logger;
|
|
48
|
+
private readonly emitter;
|
|
49
|
+
/** Current reconnection attempt number */
|
|
50
|
+
private attempts;
|
|
51
|
+
/** Timer handle for scheduled reconnection */
|
|
52
|
+
private timer;
|
|
53
|
+
/** Whether reconnection was cancelled */
|
|
54
|
+
private cancelled;
|
|
55
|
+
constructor(config: ReconnectConfig, logger: Logger, emitter: EventEmitter);
|
|
56
|
+
/**
|
|
57
|
+
* Calculates the delay for the next reconnection attempt.
|
|
58
|
+
*
|
|
59
|
+
* Uses exponential backoff with 30% jitter to prevent
|
|
60
|
+
* thundering herd problems.
|
|
61
|
+
*
|
|
62
|
+
* @param attempt - Current attempt number (1-based)
|
|
63
|
+
* @returns Delay in milliseconds
|
|
64
|
+
*/
|
|
65
|
+
calculateDelay(attempt: number): number;
|
|
66
|
+
/**
|
|
67
|
+
* Checks if more reconnection attempts are allowed.
|
|
68
|
+
*
|
|
69
|
+
* @returns true if another attempt can be made
|
|
70
|
+
*/
|
|
71
|
+
canRetry(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Schedules a reconnection attempt.
|
|
74
|
+
*
|
|
75
|
+
* @param connectFn - Async function that performs the connection
|
|
76
|
+
*/
|
|
77
|
+
schedule(connectFn: () => Promise<void>): void;
|
|
78
|
+
/**
|
|
79
|
+
* Resets the reconnection state after successful connection.
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Cancels any pending reconnection attempt.
|
|
84
|
+
*/
|
|
85
|
+
cancel(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Gets the current attempt count.
|
|
88
|
+
*/
|
|
89
|
+
getAttempts(): number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Waits for a reconnection to complete.
|
|
93
|
+
*
|
|
94
|
+
* @param emitter - Event emitter that fires reconnection events
|
|
95
|
+
* @param timeout - Maximum time to wait (ms)
|
|
96
|
+
* @returns Promise that resolves when reconnected
|
|
97
|
+
* @throws ConnectionError if reconnection fails or times out
|
|
98
|
+
*/
|
|
99
|
+
export declare function waitForReconnection(emitter: EventEmitter, timeout: number): Promise<void>;
|
|
100
|
+
//# sourceMappingURL=reconnect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/client/reconnect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,sCAAsC;AACtC,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,YAAY,GACZ,WAAW,GACX,cAAc,GACd,QAAQ,CAAC;AAEb,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IASzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAV1B,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAK;IACrB,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAA8C;IAC3D,yCAAyC;IACzC,OAAO,CAAC,SAAS,CAAS;gBAGP,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY;IAGxC;;;;;;;;OAQG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IASvC;;;;OAIG;IACH,QAAQ,IAAI,OAAO;IAMnB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAgC9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;OAEG;IACH,WAAW,IAAI,MAAM;CAGtB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBzF"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Reconnection logic for FlashQ client.
|
|
4
|
+
*
|
|
5
|
+
* Implements exponential backoff with jitter for automatic reconnection
|
|
6
|
+
* after connection loss.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ReconnectManager = void 0;
|
|
10
|
+
exports.waitForReconnection = waitForReconnection;
|
|
11
|
+
const errors_1 = require("../errors");
|
|
12
|
+
/**
|
|
13
|
+
* Manages reconnection state and scheduling.
|
|
14
|
+
*
|
|
15
|
+
* Implements exponential backoff with jitter:
|
|
16
|
+
* delay = min(initialDelay * 2^attempt, maxDelay) + random jitter
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const manager = new ReconnectManager(config, logger, emitter);
|
|
21
|
+
*
|
|
22
|
+
* manager.schedule(async () => {
|
|
23
|
+
* await connect();
|
|
24
|
+
* manager.reset();
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
class ReconnectManager {
|
|
29
|
+
config;
|
|
30
|
+
logger;
|
|
31
|
+
emitter;
|
|
32
|
+
/** Current reconnection attempt number */
|
|
33
|
+
attempts = 0;
|
|
34
|
+
/** Timer handle for scheduled reconnection */
|
|
35
|
+
timer = null;
|
|
36
|
+
/** Whether reconnection was cancelled */
|
|
37
|
+
cancelled = false;
|
|
38
|
+
constructor(config, logger, emitter) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.logger = logger;
|
|
41
|
+
this.emitter = emitter;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Calculates the delay for the next reconnection attempt.
|
|
45
|
+
*
|
|
46
|
+
* Uses exponential backoff with 30% jitter to prevent
|
|
47
|
+
* thundering herd problems.
|
|
48
|
+
*
|
|
49
|
+
* @param attempt - Current attempt number (1-based)
|
|
50
|
+
* @returns Delay in milliseconds
|
|
51
|
+
*/
|
|
52
|
+
calculateDelay(attempt) {
|
|
53
|
+
const baseDelay = Math.min(this.config.initialDelay * Math.pow(2, attempt - 1), this.config.maxDelay);
|
|
54
|
+
// Add 0-30% jitter
|
|
55
|
+
return baseDelay + Math.random() * 0.3 * baseDelay;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Checks if more reconnection attempts are allowed.
|
|
59
|
+
*
|
|
60
|
+
* @returns true if another attempt can be made
|
|
61
|
+
*/
|
|
62
|
+
canRetry() {
|
|
63
|
+
if (!this.config.enabled || this.cancelled)
|
|
64
|
+
return false;
|
|
65
|
+
if (this.config.maxAttempts === 0)
|
|
66
|
+
return true; // Unlimited
|
|
67
|
+
return this.attempts < this.config.maxAttempts;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Schedules a reconnection attempt.
|
|
71
|
+
*
|
|
72
|
+
* @param connectFn - Async function that performs the connection
|
|
73
|
+
*/
|
|
74
|
+
schedule(connectFn) {
|
|
75
|
+
if (!this.canRetry()) {
|
|
76
|
+
this.logger.error('Max reconnection attempts reached', { attempts: this.attempts });
|
|
77
|
+
this.emitter.emit('reconnect_failed', new errors_1.ConnectionError('Max reconnection attempts reached', 'RECONNECTION_FAILED'));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.attempts++;
|
|
81
|
+
const delay = this.calculateDelay(this.attempts);
|
|
82
|
+
this.logger.info('Scheduling reconnection', { attempt: this.attempts, delay: Math.round(delay) });
|
|
83
|
+
this.emitter.emit('reconnecting', { attempt: this.attempts, delay });
|
|
84
|
+
this.timer = setTimeout(async () => {
|
|
85
|
+
try {
|
|
86
|
+
await connectFn();
|
|
87
|
+
this.logger.info('Reconnected successfully', { attempt: this.attempts });
|
|
88
|
+
this.emitter.emit('reconnected');
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
this.logger.warn('Reconnection attempt failed', {
|
|
92
|
+
attempt: this.attempts,
|
|
93
|
+
error: error instanceof Error ? error.message : error,
|
|
94
|
+
});
|
|
95
|
+
// Schedule next attempt
|
|
96
|
+
this.schedule(connectFn);
|
|
97
|
+
}
|
|
98
|
+
}, delay);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resets the reconnection state after successful connection.
|
|
102
|
+
*/
|
|
103
|
+
reset() {
|
|
104
|
+
this.attempts = 0;
|
|
105
|
+
this.cancelled = false;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Cancels any pending reconnection attempt.
|
|
109
|
+
*/
|
|
110
|
+
cancel() {
|
|
111
|
+
this.cancelled = true;
|
|
112
|
+
if (this.timer) {
|
|
113
|
+
clearTimeout(this.timer);
|
|
114
|
+
this.timer = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Gets the current attempt count.
|
|
119
|
+
*/
|
|
120
|
+
getAttempts() {
|
|
121
|
+
return this.attempts;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.ReconnectManager = ReconnectManager;
|
|
125
|
+
/**
|
|
126
|
+
* Waits for a reconnection to complete.
|
|
127
|
+
*
|
|
128
|
+
* @param emitter - Event emitter that fires reconnection events
|
|
129
|
+
* @param timeout - Maximum time to wait (ms)
|
|
130
|
+
* @returns Promise that resolves when reconnected
|
|
131
|
+
* @throws ConnectionError if reconnection fails or times out
|
|
132
|
+
*/
|
|
133
|
+
function waitForReconnection(emitter, timeout) {
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const timer = setTimeout(() => {
|
|
136
|
+
emitter.removeListener('reconnected', onReconnect);
|
|
137
|
+
emitter.removeListener('reconnect_failed', onFailed);
|
|
138
|
+
reject(new errors_1.ConnectionError('Reconnection timeout', 'RECONNECTION_FAILED'));
|
|
139
|
+
}, timeout);
|
|
140
|
+
const onReconnect = () => {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
emitter.removeListener('reconnect_failed', onFailed);
|
|
143
|
+
resolve();
|
|
144
|
+
};
|
|
145
|
+
const onFailed = (err) => {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
emitter.removeListener('reconnected', onReconnect);
|
|
148
|
+
reject(err);
|
|
149
|
+
};
|
|
150
|
+
emitter.once('reconnected', onReconnect);
|
|
151
|
+
emitter.once('reconnect_failed', onFailed);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=reconnect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/client/reconnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TCP protocol handler for FlashQ client.
|
|
3
|
+
*
|
|
4
|
+
* Handles buffer management, message framing, and protocol serialization
|
|
5
|
+
* for both JSON (newline-delimited) and binary (MessagePack) protocols.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Pending request tracking for async responses.
|
|
9
|
+
*/
|
|
10
|
+
export interface PendingRequest {
|
|
11
|
+
/** Resolves with the response data */
|
|
12
|
+
resolve: (value: unknown) => void;
|
|
13
|
+
/** Rejects with an error */
|
|
14
|
+
reject: (error: Error) => void;
|
|
15
|
+
/** Timeout timer handle */
|
|
16
|
+
timer: ReturnType<typeof setTimeout>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Handles JSON protocol buffer parsing.
|
|
20
|
+
*
|
|
21
|
+
* Accumulates incoming data chunks and extracts complete
|
|
22
|
+
* newline-delimited JSON messages.
|
|
23
|
+
*/
|
|
24
|
+
export declare class JsonBufferHandler {
|
|
25
|
+
/** Accumulated string chunks waiting to be joined */
|
|
26
|
+
private chunks;
|
|
27
|
+
/** Partial line from previous parse */
|
|
28
|
+
private remainder;
|
|
29
|
+
/**
|
|
30
|
+
* Appends new data to the buffer.
|
|
31
|
+
*
|
|
32
|
+
* @param data - Raw data from socket
|
|
33
|
+
*/
|
|
34
|
+
append(data: Buffer | string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts all complete lines from the buffer.
|
|
37
|
+
*
|
|
38
|
+
* Complete lines are separated by newlines. Any partial line
|
|
39
|
+
* at the end is kept for the next call.
|
|
40
|
+
*
|
|
41
|
+
* @returns Array of complete JSON strings
|
|
42
|
+
*/
|
|
43
|
+
extractLines(): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Resets the buffer state.
|
|
46
|
+
*/
|
|
47
|
+
reset(): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Handles binary (MessagePack) protocol buffer parsing.
|
|
51
|
+
*
|
|
52
|
+
* Each message is framed with a 4-byte big-endian length prefix
|
|
53
|
+
* followed by the MessagePack-encoded payload.
|
|
54
|
+
*/
|
|
55
|
+
export declare class BinaryBufferHandler {
|
|
56
|
+
/** Accumulated binary data */
|
|
57
|
+
private buffer;
|
|
58
|
+
/**
|
|
59
|
+
* Appends new data to the buffer.
|
|
60
|
+
*
|
|
61
|
+
* @param data - Raw data from socket
|
|
62
|
+
*/
|
|
63
|
+
append(data: Buffer): void;
|
|
64
|
+
/**
|
|
65
|
+
* Extracts all complete frames from the buffer.
|
|
66
|
+
*
|
|
67
|
+
* Frame format: [4-byte length BE][payload]
|
|
68
|
+
*
|
|
69
|
+
* @returns Array of decoded message objects
|
|
70
|
+
*/
|
|
71
|
+
extractFrames(): Record<string, unknown>[];
|
|
72
|
+
/**
|
|
73
|
+
* Resets the buffer state.
|
|
74
|
+
*/
|
|
75
|
+
reset(): void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Encodes a command for TCP transmission.
|
|
79
|
+
*
|
|
80
|
+
* @param command - Command object to encode
|
|
81
|
+
* @param reqId - Request ID to include
|
|
82
|
+
* @param useBinary - Whether to use MessagePack encoding
|
|
83
|
+
* @returns Buffer ready for socket.write()
|
|
84
|
+
*/
|
|
85
|
+
export declare function encodeCommand(command: Record<string, unknown>, reqId: string, useBinary: boolean): Buffer;
|
|
86
|
+
/**
|
|
87
|
+
* Parses a JSON response from a string.
|
|
88
|
+
*
|
|
89
|
+
* @param line - JSON string to parse
|
|
90
|
+
* @returns Parsed response object or null if invalid
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseJsonResponse(line: string): Record<string, unknown> | null;
|
|
93
|
+
/**
|
|
94
|
+
* Generates a unique request ID.
|
|
95
|
+
*
|
|
96
|
+
* Format: "r{incrementing number}"
|
|
97
|
+
*
|
|
98
|
+
* @returns Unique request ID string
|
|
99
|
+
*/
|
|
100
|
+
export declare function generateRequestId(): string;
|
|
101
|
+
/**
|
|
102
|
+
* Resets the request ID counter.
|
|
103
|
+
* Primarily used for testing.
|
|
104
|
+
*/
|
|
105
|
+
export declare function resetRequestIdCounter(): void;
|
|
106
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/client/tcp/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,4BAA4B;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,2BAA2B;IAC3B,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAgB;IAC9B,uCAAuC;IACvC,OAAO,CAAC,SAAS,CAAM;IAEvB;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC;;;;;;;OAOG;IACH,YAAY,IAAI,MAAM,EAAE;IAWxB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC9B,8BAA8B;IAC9B,OAAO,CAAC,MAAM,CAA2B;IAEzC;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1B;;;;;;OAMG;IACH,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAgB1C;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,OAAO,GACjB,MAAM,CAYR;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAM9E;AAKD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TCP protocol handler for FlashQ client.
|
|
4
|
+
*
|
|
5
|
+
* Handles buffer management, message framing, and protocol serialization
|
|
6
|
+
* for both JSON (newline-delimited) and binary (MessagePack) protocols.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.BinaryBufferHandler = exports.JsonBufferHandler = void 0;
|
|
10
|
+
exports.encodeCommand = encodeCommand;
|
|
11
|
+
exports.parseJsonResponse = parseJsonResponse;
|
|
12
|
+
exports.generateRequestId = generateRequestId;
|
|
13
|
+
exports.resetRequestIdCounter = resetRequestIdCounter;
|
|
14
|
+
const msgpack_1 = require("@msgpack/msgpack");
|
|
15
|
+
/**
|
|
16
|
+
* Handles JSON protocol buffer parsing.
|
|
17
|
+
*
|
|
18
|
+
* Accumulates incoming data chunks and extracts complete
|
|
19
|
+
* newline-delimited JSON messages.
|
|
20
|
+
*/
|
|
21
|
+
class JsonBufferHandler {
|
|
22
|
+
/** Accumulated string chunks waiting to be joined */
|
|
23
|
+
chunks = [];
|
|
24
|
+
/** Partial line from previous parse */
|
|
25
|
+
remainder = '';
|
|
26
|
+
/**
|
|
27
|
+
* Appends new data to the buffer.
|
|
28
|
+
*
|
|
29
|
+
* @param data - Raw data from socket
|
|
30
|
+
*/
|
|
31
|
+
append(data) {
|
|
32
|
+
this.chunks.push(typeof data === 'string' ? data : data.toString());
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extracts all complete lines from the buffer.
|
|
36
|
+
*
|
|
37
|
+
* Complete lines are separated by newlines. Any partial line
|
|
38
|
+
* at the end is kept for the next call.
|
|
39
|
+
*
|
|
40
|
+
* @returns Array of complete JSON strings
|
|
41
|
+
*/
|
|
42
|
+
extractLines() {
|
|
43
|
+
// Join chunks only when processing (more efficient than += on each chunk)
|
|
44
|
+
const fullBuffer = this.remainder + this.chunks.join('');
|
|
45
|
+
this.chunks.length = 0; // Clear array without reallocating
|
|
46
|
+
const lines = fullBuffer.split('\n');
|
|
47
|
+
this.remainder = lines.pop() ?? '';
|
|
48
|
+
return lines.filter((line) => line.trim());
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resets the buffer state.
|
|
52
|
+
*/
|
|
53
|
+
reset() {
|
|
54
|
+
this.chunks.length = 0;
|
|
55
|
+
this.remainder = '';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.JsonBufferHandler = JsonBufferHandler;
|
|
59
|
+
/**
|
|
60
|
+
* Handles binary (MessagePack) protocol buffer parsing.
|
|
61
|
+
*
|
|
62
|
+
* Each message is framed with a 4-byte big-endian length prefix
|
|
63
|
+
* followed by the MessagePack-encoded payload.
|
|
64
|
+
*/
|
|
65
|
+
class BinaryBufferHandler {
|
|
66
|
+
/** Accumulated binary data */
|
|
67
|
+
buffer = Buffer.alloc(0);
|
|
68
|
+
/**
|
|
69
|
+
* Appends new data to the buffer.
|
|
70
|
+
*
|
|
71
|
+
* @param data - Raw data from socket
|
|
72
|
+
*/
|
|
73
|
+
append(data) {
|
|
74
|
+
this.buffer = Buffer.concat([this.buffer, data]);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extracts all complete frames from the buffer.
|
|
78
|
+
*
|
|
79
|
+
* Frame format: [4-byte length BE][payload]
|
|
80
|
+
*
|
|
81
|
+
* @returns Array of decoded message objects
|
|
82
|
+
*/
|
|
83
|
+
extractFrames() {
|
|
84
|
+
const frames = [];
|
|
85
|
+
while (this.buffer.length >= 4) {
|
|
86
|
+
const len = this.buffer.readUInt32BE(0);
|
|
87
|
+
if (this.buffer.length < 4 + len)
|
|
88
|
+
break;
|
|
89
|
+
const frameData = this.buffer.subarray(4, 4 + len);
|
|
90
|
+
this.buffer = this.buffer.subarray(4 + len);
|
|
91
|
+
frames.push((0, msgpack_1.decode)(frameData));
|
|
92
|
+
}
|
|
93
|
+
return frames;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resets the buffer state.
|
|
97
|
+
*/
|
|
98
|
+
reset() {
|
|
99
|
+
this.buffer = Buffer.alloc(0);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.BinaryBufferHandler = BinaryBufferHandler;
|
|
103
|
+
/**
|
|
104
|
+
* Encodes a command for TCP transmission.
|
|
105
|
+
*
|
|
106
|
+
* @param command - Command object to encode
|
|
107
|
+
* @param reqId - Request ID to include
|
|
108
|
+
* @param useBinary - Whether to use MessagePack encoding
|
|
109
|
+
* @returns Buffer ready for socket.write()
|
|
110
|
+
*/
|
|
111
|
+
function encodeCommand(command, reqId, useBinary) {
|
|
112
|
+
const payload = { ...command, reqId };
|
|
113
|
+
if (useBinary) {
|
|
114
|
+
const encoded = (0, msgpack_1.encode)(payload);
|
|
115
|
+
const frame = Buffer.alloc(4 + encoded.length);
|
|
116
|
+
frame.writeUInt32BE(encoded.length, 0);
|
|
117
|
+
frame.set(encoded, 4);
|
|
118
|
+
return frame;
|
|
119
|
+
}
|
|
120
|
+
return Buffer.from(JSON.stringify(payload) + '\n');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Parses a JSON response from a string.
|
|
124
|
+
*
|
|
125
|
+
* @param line - JSON string to parse
|
|
126
|
+
* @returns Parsed response object or null if invalid
|
|
127
|
+
*/
|
|
128
|
+
function parseJsonResponse(line) {
|
|
129
|
+
try {
|
|
130
|
+
return JSON.parse(line);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Counter for generating unique request IDs */
|
|
137
|
+
let requestIdCounter = 0;
|
|
138
|
+
/**
|
|
139
|
+
* Generates a unique request ID.
|
|
140
|
+
*
|
|
141
|
+
* Format: "r{incrementing number}"
|
|
142
|
+
*
|
|
143
|
+
* @returns Unique request ID string
|
|
144
|
+
*/
|
|
145
|
+
function generateRequestId() {
|
|
146
|
+
return `r${++requestIdCounter}`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resets the request ID counter.
|
|
150
|
+
* Primarily used for testing.
|
|
151
|
+
*/
|
|
152
|
+
function resetRequestIdCounter() {
|
|
153
|
+
requestIdCounter = 0;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/client/tcp/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/tcp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,KAAK,cAAc,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resetRequestIdCounter = exports.generateRequestId = exports.parseJsonResponse = exports.encodeCommand = exports.BinaryBufferHandler = exports.JsonBufferHandler = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* TCP protocol module exports.
|
|
6
|
+
*/
|
|
7
|
+
var handler_1 = require("./handler");
|
|
8
|
+
Object.defineProperty(exports, "JsonBufferHandler", { enumerable: true, get: function () { return handler_1.JsonBufferHandler; } });
|
|
9
|
+
Object.defineProperty(exports, "BinaryBufferHandler", { enumerable: true, get: function () { return handler_1.BinaryBufferHandler; } });
|
|
10
|
+
Object.defineProperty(exports, "encodeCommand", { enumerable: true, get: function () { return handler_1.encodeCommand; } });
|
|
11
|
+
Object.defineProperty(exports, "parseJsonResponse", { enumerable: true, get: function () { return handler_1.parseJsonResponse; } });
|
|
12
|
+
Object.defineProperty(exports, "generateRequestId", { enumerable: true, get: function () { return handler_1.generateRequestId; } });
|
|
13
|
+
Object.defineProperty(exports, "resetRequestIdCounter", { enumerable: true, get: function () { return handler_1.resetRequestIdCounter; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/tcp/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,qCAQmB;AANjB,4GAAA,iBAAiB,OAAA;AACjB,8GAAA,mBAAmB,OAAA;AACnB,wGAAA,aAAa,OAAA;AACb,4GAAA,iBAAiB,OAAA;AACjB,4GAAA,iBAAiB,OAAA;AACjB,gHAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation utilities for FlashQ client.
|
|
3
|
+
*
|
|
4
|
+
* Provides validation functions for queue names, job data sizes,
|
|
5
|
+
* and batch operation limits.
|
|
6
|
+
*/
|
|
7
|
+
/** Maximum allowed job data size in bytes (1MB) */
|
|
8
|
+
export declare const MAX_JOB_DATA_SIZE: number;
|
|
9
|
+
/** Maximum number of jobs per batch operation */
|
|
10
|
+
export declare const MAX_BATCH_SIZE = 1000;
|
|
11
|
+
/**
|
|
12
|
+
* Validates a queue name against naming rules.
|
|
13
|
+
*
|
|
14
|
+
* Queue names must:
|
|
15
|
+
* - Be non-empty strings
|
|
16
|
+
* - Contain only alphanumeric characters, underscores, hyphens, or dots
|
|
17
|
+
* - Be between 1 and 256 characters long
|
|
18
|
+
*
|
|
19
|
+
* @param queue - The queue name to validate
|
|
20
|
+
* @throws ValidationError if the queue name is invalid
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* validateQueueName('my-queue'); // OK
|
|
25
|
+
* validateQueueName('queue.name'); // OK
|
|
26
|
+
* validateQueueName('queue name'); // Throws: contains space
|
|
27
|
+
* validateQueueName(''); // Throws: empty
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateQueueName(queue: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Validates that job data does not exceed the maximum allowed size.
|
|
33
|
+
*
|
|
34
|
+
* The size is calculated by JSON-stringifying the data and measuring
|
|
35
|
+
* the resulting string length in bytes.
|
|
36
|
+
*
|
|
37
|
+
* @param data - The job data to validate
|
|
38
|
+
* @throws ValidationError if the data exceeds MAX_JOB_DATA_SIZE
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* validateJobDataSize({ small: 'data' }); // OK
|
|
43
|
+
* validateJobDataSize(largeBuffer); // Throws if > 1MB
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateJobDataSize(data: unknown): void;
|
|
47
|
+
/**
|
|
48
|
+
* Validates batch operation size.
|
|
49
|
+
*
|
|
50
|
+
* @param count - Number of items in the batch
|
|
51
|
+
* @param operation - Name of the operation for error messages
|
|
52
|
+
* @throws ValidationError if count exceeds MAX_BATCH_SIZE
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* validateBatchSize(100, 'push'); // OK
|
|
57
|
+
* validateBatchSize(1500, 'push'); // Throws: exceeds 1000
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function validateBatchSize(count: number, operation: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Validates a job ID is a positive integer.
|
|
63
|
+
*
|
|
64
|
+
* @param jobId - The job ID to validate
|
|
65
|
+
* @throws ValidationError if jobId is not a positive integer
|
|
66
|
+
*/
|
|
67
|
+
export declare function validateJobId(jobId: number): void;
|
|
68
|
+
/**
|
|
69
|
+
* Validates a timeout value is within acceptable bounds.
|
|
70
|
+
*
|
|
71
|
+
* @param timeout - Timeout in milliseconds
|
|
72
|
+
* @param min - Minimum allowed value (default: 0)
|
|
73
|
+
* @param max - Maximum allowed value (default: 10 minutes)
|
|
74
|
+
* @throws ValidationError if timeout is out of bounds
|
|
75
|
+
*/
|
|
76
|
+
export declare function validateTimeout(timeout: number, min?: number, max?: number): void;
|
|
77
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/client/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,QAAc,CAAC;AAE7C,iDAAiD;AACjD,eAAO,MAAM,cAAc,OAAO,CAAC;AAKnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAUrD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAQvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAOxE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAI,EAAE,GAAG,SAAS,GAAG,IAAI,CAO5E"}
|