@technoculture/data-bridge 0.1.1 → 0.1.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.
Files changed (50) hide show
  1. package/CMakeLists.txt +10 -2
  2. package/deps/include/data_bridge/config.hpp +69 -0
  3. package/deps/include/data_bridge/protocol/crc16.hpp +8 -0
  4. package/deps/include/data_bridge/protocol/crc32.hpp +19 -0
  5. package/deps/include/data_bridge/protocol/packet.hpp +175 -0
  6. package/deps/include/data_bridge/protocol/reassembler.hpp +80 -0
  7. package/deps/include/data_bridge/transport/factory.hpp +0 -0
  8. package/deps/include/data_bridge/transport/iserial_port.hpp +15 -0
  9. package/deps/include/data_bridge/transport/serial_port.hpp +28 -0
  10. package/deps/src/CMakeLists.txt +18 -0
  11. package/deps/src/protocol/crc16.cpp +19 -0
  12. package/deps/src/protocol/packet.cpp +1 -0
  13. package/deps/src/transport/platform/linux/linux_serial.cpp +53 -0
  14. package/deps/src/transport/platform/windows/windows_serial.cpp +51 -0
  15. package/dist/index.d.mts +41 -72
  16. package/dist/index.d.ts +41 -72
  17. package/dist/index.js +196 -102
  18. package/dist/index.mjs +194 -103
  19. package/lib/index.ts +12 -160
  20. package/lib/native.ts +71 -0
  21. package/lib/reliable.ts +234 -0
  22. package/lib/resilient.ts +30 -6
  23. package/package.json +6 -4
  24. package/prebuilds/darwin-arm64/Release/data_bridge_node.node +0 -0
  25. package/src/addon.cpp +248 -137
  26. package/prebuilds/darwin-arm64/.ninja_deps +0 -0
  27. package/prebuilds/darwin-arm64/.ninja_log +0 -6
  28. package/prebuilds/darwin-arm64/CMakeCache.txt +0 -398
  29. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeCCompiler.cmake +0 -84
  30. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake +0 -104
  31. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeDetermineCompilerABI_C.bin +0 -0
  32. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeDetermineCompilerABI_CXX.bin +0 -0
  33. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeSystem.cmake +0 -15
  34. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/CMakeCCompilerId.c +0 -905
  35. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/a.out +0 -0
  36. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/apple-sdk.c +0 -1
  37. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/CMakeCXXCompilerId.cpp +0 -920
  38. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/a.out +0 -0
  39. package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/apple-sdk.cpp +0 -1
  40. package/prebuilds/darwin-arm64/CMakeFiles/CMakeConfigureLog.yaml +0 -531
  41. package/prebuilds/darwin-arm64/CMakeFiles/InstallScripts.json +0 -7
  42. package/prebuilds/darwin-arm64/CMakeFiles/TargetDirectories.txt +0 -3
  43. package/prebuilds/darwin-arm64/CMakeFiles/cmake.check_cache +0 -1
  44. package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/Users/satyamtiwary/Documents/Python-Things/data-bridge/src/protocol/crc16.cpp.o +0 -0
  45. package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/Users/satyamtiwary/Documents/Python-Things/data-bridge/src/transport/platform/linux/linux_serial.cpp.o +0 -0
  46. package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/src/addon.cpp.o +0 -0
  47. package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/src/serial_wrapper.cpp.o +0 -0
  48. package/prebuilds/darwin-arm64/CMakeFiles/rules.ninja +0 -64
  49. package/prebuilds/darwin-arm64/build.ninja +0 -192
  50. package/prebuilds/darwin-arm64/cmake_install.cmake +0 -61
package/dist/index.mjs CHANGED
@@ -5,13 +5,188 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
5
5
  throw Error('Dynamic require of "' + x + '" is not supported');
6
6
  });
7
7
 
8
- // lib/index.ts
9
- import { EventEmitter as EventEmitter2 } from "events";
8
+ // lib/reliable.ts
9
+ import { EventEmitter } from "events";
10
+
11
+ // lib/native.ts
10
12
  import path from "path";
13
+ function loadAddon() {
14
+ const possiblePaths = [
15
+ `../prebuilds/${process.platform}-${process.arch}/data_bridge_node.node`,
16
+ "../build/Release/data_bridge_node.node"
17
+ ];
18
+ for (const p of possiblePaths) {
19
+ try {
20
+ return __require(path.join(__dirname, p));
21
+ } catch {
22
+ continue;
23
+ }
24
+ }
25
+ throw new Error("Failed to load native addon. Run `npm run build` first.");
26
+ }
27
+ var addon = loadAddon();
28
+ var SerialPort = addon.SerialPort;
29
+ var Packet = addon.Packet;
30
+ var Reassembler = addon.Reassembler;
31
+
32
+ // lib/reliable.ts
33
+ var ReliableDataBridge = class _ReliableDataBridge extends EventEmitter {
34
+ serial;
35
+ reassembler;
36
+ isOpen_ = false;
37
+ // Config
38
+ options;
39
+ // State
40
+ seqId = 0;
41
+ rxBuffer = Buffer.alloc(0);
42
+ // ARQ State
43
+ // We only process one send at a time (Stop-and-Wait)
44
+ // Map of seqId -> { resolve, reject } (though we only have one really)
45
+ pendingAcks = /* @__PURE__ */ new Map();
46
+ constructor(options = {}) {
47
+ super();
48
+ this.serial = new SerialPort();
49
+ this.reassembler = new Reassembler();
50
+ this.options = {
51
+ baudRate: options.baudRate ?? 115200,
52
+ maxRetries: options.maxRetries ?? 10,
53
+ ackTimeoutMs: options.ackTimeoutMs ?? 500,
54
+ fragmentSize: options.fragmentSize ?? 200
55
+ };
56
+ }
57
+ static async open(port, baudOrOptions, cb) {
58
+ let opts = {};
59
+ if (typeof baudOrOptions === "number") {
60
+ opts.baudRate = baudOrOptions;
61
+ } else if (baudOrOptions) {
62
+ opts = baudOrOptions;
63
+ }
64
+ const bridge = new _ReliableDataBridge(opts);
65
+ if (cb) bridge.on("data", cb);
66
+ await bridge.open(port);
67
+ return bridge;
68
+ }
69
+ async open(port, baud) {
70
+ if (this.isOpen_) return true;
71
+ const baudRate = baud ?? this.options.baudRate;
72
+ const success = this.serial.open(port, baudRate, (data) => {
73
+ this.onData(data);
74
+ });
75
+ if (success) {
76
+ this.isOpen_ = true;
77
+ return true;
78
+ }
79
+ throw new Error(`Failed to open ${port}`);
80
+ }
81
+ async close() {
82
+ if (this.isOpen_) {
83
+ this.serial.close();
84
+ this.isOpen_ = false;
85
+ this.emit("close");
86
+ }
87
+ }
88
+ get isOpen() {
89
+ return this.isOpen_;
90
+ }
91
+ async send(data) {
92
+ if (!this.isOpen_) throw new Error("Port not open");
93
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
94
+ const fragments = [];
95
+ for (let i = 0; i < buf.length; i += this.options.fragmentSize) {
96
+ fragments.push(buf.subarray(i, i + this.options.fragmentSize));
97
+ }
98
+ const totalFrags = fragments.length;
99
+ const seq = this.seqId;
100
+ this.seqId = (this.seqId + 1) % 256;
101
+ for (let fragId = 0; fragId < totalFrags; fragId++) {
102
+ const payload = fragments[fragId];
103
+ const packet = Packet.serialize(
104
+ Packet.TYPE_DATA,
105
+ seq,
106
+ payload,
107
+ fragId,
108
+ totalFrags
109
+ );
110
+ await this.sendWithRetry(packet, seq, fragId);
111
+ }
112
+ }
113
+ async sendWithRetry(packet, seq, fragId) {
114
+ let retries = 0;
115
+ while (retries <= this.options.maxRetries) {
116
+ const ackPromise = new Promise((resolve, reject) => {
117
+ const handler = (ackedFragId) => {
118
+ if (ackedFragId === fragId) resolve();
119
+ };
120
+ this.pendingAcks.set(seq, handler);
121
+ setTimeout(() => {
122
+ if (this.pendingAcks.has(seq)) {
123
+ this.pendingAcks.delete(seq);
124
+ reject(new Error("Timeout"));
125
+ }
126
+ }, this.options.ackTimeoutMs);
127
+ });
128
+ this.serial.write(packet);
129
+ try {
130
+ await ackPromise;
131
+ return;
132
+ } catch (e) {
133
+ retries++;
134
+ }
135
+ }
136
+ throw new Error(`Send failed after ${this.options.maxRetries} retries`);
137
+ }
138
+ onData(chunk) {
139
+ this.rxBuffer = Buffer.concat([this.rxBuffer, chunk]);
140
+ while (true) {
141
+ const { frame, remaining } = Packet.deserialize(this.rxBuffer);
142
+ if (!frame.valid) {
143
+ if (remaining.length === this.rxBuffer.length) {
144
+ break;
145
+ }
146
+ this.rxBuffer = Buffer.from(remaining);
147
+ continue;
148
+ }
149
+ this.rxBuffer = Buffer.from(remaining);
150
+ if (frame.header.type === Packet.TYPE_ACK) {
151
+ const seq = frame.header.seq_id;
152
+ const frag = frame.header.fragment_id;
153
+ if (this.pendingAcks.has(seq)) {
154
+ this.pendingAcks.get(seq)(frag);
155
+ }
156
+ } else if (frame.header.type === Packet.TYPE_DATA) {
157
+ let shouldAck = false;
158
+ if (this.reassembler.processFragment(frame)) {
159
+ shouldAck = true;
160
+ if (this.reassembler.isComplete(frame)) {
161
+ try {
162
+ const data = this.reassembler.getData();
163
+ this.emit("data", data);
164
+ } catch (e) {
165
+ console.error("Error in data emission:", e);
166
+ }
167
+ }
168
+ } else if (this.reassembler.isDuplicate(frame)) {
169
+ shouldAck = true;
170
+ }
171
+ if (shouldAck) {
172
+ const ackParams = Packet.serialize(
173
+ Packet.TYPE_ACK,
174
+ frame.header.seq_id,
175
+ Buffer.alloc(0),
176
+ frame.header.fragment_id,
177
+ frame.header.total_frags
178
+ );
179
+ this.serial.write(ackParams);
180
+ }
181
+ }
182
+ }
183
+ }
184
+ };
11
185
 
12
186
  // lib/resilient.ts
13
- import { EventEmitter } from "events";
14
- var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
187
+ import { EventEmitter as EventEmitter2 } from "events";
188
+ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter2 {
189
+ // Use DataBridge type from index (which is reliable now)
15
190
  bridge = null;
16
191
  port;
17
192
  options;
@@ -26,6 +201,9 @@ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
26
201
  this.port = port;
27
202
  this.options = {
28
203
  baudRate: options.baudRate ?? 115200,
204
+ maxRetries: options.maxRetries ?? 10,
205
+ ackTimeoutMs: options.ackTimeoutMs ?? 500,
206
+ fragmentSize: options.fragmentSize ?? 200,
29
207
  reconnect: options.reconnect ?? true,
30
208
  reconnectDelay: options.reconnectDelay ?? 1e3,
31
209
  maxReconnectDelay: options.maxReconnectDelay ?? 3e4,
@@ -45,9 +223,8 @@ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
45
223
  }
46
224
  async connect() {
47
225
  try {
48
- this.bridge = await DataBridge.open(this.port, {
49
- baudRate: this.options.baudRate
50
- });
226
+ this.bridge = new ReliableDataBridge(this.options);
227
+ await this.bridge.open(this.port);
51
228
  this.isConnected = true;
52
229
  this.reconnectAttempt = 0;
53
230
  this.bridge.on("data", (data) => {
@@ -55,6 +232,11 @@ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
55
232
  });
56
233
  this.bridge.on("error", (err) => {
57
234
  this.emit("error", err);
235
+ if (!this.bridge?.isOpen) {
236
+ this.handleDisconnect();
237
+ }
238
+ });
239
+ this.bridge.on("close", () => {
58
240
  this.handleDisconnect();
59
241
  });
60
242
  if (this.isReconnecting) {
@@ -110,10 +292,11 @@ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
110
292
  */
111
293
  async send(data) {
112
294
  const buffer = typeof data === "string" ? Buffer.from(data) : data;
113
- if (this.isConnected && this.bridge) {
295
+ if (this.isConnected && this.bridge && this.bridge.isOpen) {
114
296
  try {
115
297
  await this.bridge.send(buffer);
116
298
  } catch (err) {
299
+ this.handleDisconnect();
117
300
  return this.queueMessage(buffer);
118
301
  }
119
302
  } else {
@@ -186,100 +369,8 @@ var ResilientDataBridge = class _ResilientDataBridge extends EventEmitter {
186
369
  return super.emit(event, ...args);
187
370
  }
188
371
  };
189
-
190
- // lib/index.ts
191
- var addon;
192
- function loadAddon() {
193
- const possiblePaths = [
194
- // Prebuilt binaries
195
- `../prebuilds/${process.platform}-${process.arch}/data_bridge_node.node`,
196
- // Local build
197
- "../build/Release/data_bridge_node.node"
198
- ];
199
- for (const p of possiblePaths) {
200
- try {
201
- return __require(path.join(__dirname, p));
202
- } catch {
203
- continue;
204
- }
205
- }
206
- throw new Error("Failed to load native addon. Run `npm run build` first.");
207
- }
208
- addon = loadAddon();
209
- var DataBridge = class _DataBridge extends EventEmitter2 {
210
- native;
211
- _isOpen = false;
212
- constructor() {
213
- super();
214
- this.native = new addon.DataBridge();
215
- }
216
- /**
217
- * Open a serial port with guaranteed reliable communication.
218
- *
219
- * @param port - Serial port path (e.g., '/dev/ttyUSB0' or 'COM3')
220
- * @param options - Configuration options
221
- * @returns Promise resolving to a DataBridge instance
222
- */
223
- static async open(port, options = {}) {
224
- const instance = new _DataBridge();
225
- const baud = options.baudRate ?? 115200;
226
- const onData = (data) => {
227
- instance.emit("data", data);
228
- };
229
- try {
230
- await instance.native.open(port, baud, onData);
231
- instance._isOpen = true;
232
- return instance;
233
- } catch (err) {
234
- throw new Error(`Failed to open ${port}: ${err instanceof Error ? err.message : err}`);
235
- }
236
- }
237
- /**
238
- * Send data with guaranteed delivery.
239
- *
240
- * The data will be fragmented if necessary, checksummed, and
241
- * retransmitted until acknowledged by the receiver.
242
- *
243
- * @param data - Data to send (Buffer or string)
244
- * @returns Promise resolving when data is acknowledged
245
- */
246
- async send(data) {
247
- if (!this._isOpen) {
248
- throw new Error("Port not open");
249
- }
250
- const buffer = typeof data === "string" ? Buffer.from(data) : data;
251
- await this.native.send(buffer);
252
- }
253
- /**
254
- * Close the serial port.
255
- */
256
- async close() {
257
- if (this._isOpen) {
258
- this.native.close();
259
- this._isOpen = false;
260
- this.emit("close");
261
- }
262
- }
263
- /**
264
- * Check if the port is currently open.
265
- */
266
- get isOpen() {
267
- return this._isOpen && this.native.isOpen();
268
- }
269
- // Type-safe event emitter methods
270
- on(event, listener) {
271
- return super.on(event, listener);
272
- }
273
- once(event, listener) {
274
- return super.once(event, listener);
275
- }
276
- emit(event, ...args) {
277
- return super.emit(event, ...args);
278
- }
279
- };
280
- var index_default = DataBridge;
281
372
  export {
282
- DataBridge,
283
- ResilientDataBridge,
284
- index_default as default
373
+ ReliableDataBridge as DataBridge,
374
+ SerialPort as RawSerialPort,
375
+ ResilientDataBridge
285
376
  };
package/lib/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  /**
2
3
  * Data Bridge - Guaranteed Reliable Serial Communication
3
4
  *
@@ -5,167 +6,18 @@
5
6
  * Provides a clean, async-friendly API for Electron applications.
6
7
  */
7
8
 
8
- import { EventEmitter } from 'events';
9
- import path from 'path';
10
-
11
- // Load native addon - works in both ESM and CJS
12
- let addon: NativeAddon;
13
-
14
- function loadAddon (): NativeAddon {
15
- const possiblePaths = [
16
- // Prebuilt binaries
17
- `../prebuilds/${process.platform}-${process.arch}/data_bridge_node.node`,
18
- // Local build
19
- '../build/Release/data_bridge_node.node',
20
- ];
21
-
22
- for (const p of possiblePaths)
23
- {
24
- try
25
- {
26
- // Use require for native addons (works in both ESM and CJS)
27
- return require(path.join(__dirname, p));
28
- } catch
29
- {
30
- continue;
31
- }
32
- }
33
-
34
- throw new Error('Failed to load native addon. Run `npm run build` first.');
35
- }
36
-
37
- addon = loadAddon();
38
-
39
- interface NativeAddon {
40
- DataBridge: new () => NativeDataBridge;
41
- }
42
-
43
- interface NativeDataBridge {
44
- open (port: string, baud: number, callback?: (data: Buffer) => void): Promise<boolean>;
45
- send (data: Buffer | string): Promise<number>;
46
- close (): boolean;
47
- isOpen (): boolean;
48
- }
49
-
50
- export interface DataBridgeOptions {
51
- baudRate?: number;
52
- }
53
-
54
- export interface DataBridgeEvents {
55
- data: (data: Buffer) => void;
56
- error: (error: Error) => void;
57
- close: () => void;
58
- }
59
-
60
- /**
61
- * DataBridge provides guaranteed reliable serial communication.
62
- *
63
- * Features:
64
- * - Automatic retransmission on packet loss
65
- * - CRC32 integrity checking
66
- * - COBS framing for robust delimitation
67
- * - Fragmentation for large messages
68
- *
69
- * @example
70
- * ```typescript
71
- * const bridge = await DataBridge.open('/dev/ttyUSB0');
72
- *
73
- * bridge.on('data', (data) => {
74
- * console.log('Received:', data.toString());
75
- * });
76
- *
77
- * await bridge.send('Hello, World!');
78
- * await bridge.close();
79
- * ```
80
- */
81
- export class DataBridge extends EventEmitter {
82
- private native: NativeDataBridge;
83
- private _isOpen = false;
84
-
85
- private constructor() {
86
- super();
87
- this.native = new addon.DataBridge();
88
- }
89
-
90
- /**
91
- * Open a serial port with guaranteed reliable communication.
92
- *
93
- * @param port - Serial port path (e.g., '/dev/ttyUSB0' or 'COM3')
94
- * @param options - Configuration options
95
- * @returns Promise resolving to a DataBridge instance
96
- */
97
- static async open (port: string, options: DataBridgeOptions = {}): Promise<DataBridge> {
98
- const instance = new DataBridge();
99
- const baud = options.baudRate ?? 115200;
100
-
101
- const onData = (data: Buffer) => {
102
- instance.emit('data', data);
103
- };
104
-
105
- try
106
- {
107
- await instance.native.open(port, baud, onData);
108
- instance._isOpen = true;
109
- return instance;
110
- } catch (err)
111
- {
112
- throw new Error(`Failed to open ${port}: ${err instanceof Error ? err.message : err}`);
113
- }
114
- }
115
-
116
- /**
117
- * Send data with guaranteed delivery.
118
- *
119
- * The data will be fragmented if necessary, checksummed, and
120
- * retransmitted until acknowledged by the receiver.
121
- *
122
- * @param data - Data to send (Buffer or string)
123
- * @returns Promise resolving when data is acknowledged
124
- */
125
- async send (data: Buffer | string): Promise<void> {
126
- if (!this._isOpen)
127
- {
128
- throw new Error('Port not open');
129
- }
130
-
131
- const buffer = typeof data === 'string' ? Buffer.from(data) : data;
132
- await this.native.send(buffer);
133
- }
134
-
135
- /**
136
- * Close the serial port.
137
- */
138
- async close (): Promise<void> {
139
- if (this._isOpen)
140
- {
141
- this.native.close();
142
- this._isOpen = false;
143
- this.emit('close');
144
- }
145
- }
146
-
147
- /**
148
- * Check if the port is currently open.
149
- */
150
- get isOpen (): boolean {
151
- return this._isOpen && this.native.isOpen();
152
- }
153
-
154
- // Type-safe event emitter methods
155
- on<K extends keyof DataBridgeEvents> (event: K, listener: DataBridgeEvents[K]): this {
156
- return super.on(event, listener);
157
- }
158
-
159
- once<K extends keyof DataBridgeEvents> (event: K, listener: DataBridgeEvents[K]): this {
160
- return super.once(event, listener);
161
- }
9
+ import { ReliableDataBridge, DataBridgeOptions } from './reliable';
10
+ import { SerialPort } from './native';
162
11
 
163
- emit<K extends keyof DataBridgeEvents> (event: K, ...args: Parameters<DataBridgeEvents[K]>): boolean {
164
- return super.emit(event, ...args);
165
- }
166
- }
12
+ // Export the Reliable implementation as the default DataBridge
13
+ export { ReliableDataBridge as DataBridge };
14
+ export { DataBridgeOptions };
167
15
 
168
- export default DataBridge;
16
+ // Export Raw SerialPort for advanced users
17
+ export { SerialPort as RawSerialPort };
169
18
 
170
- // Re-export resilient wrapper
19
+ // Export Resilient wrapper (connection resilience)
20
+ // Note: ResilientDataBridge wraps DataBridge.
21
+ // If DataBridge is now Reliable, ResilientDataBridge will hold a ReliableDataBridge.
22
+ // This gives us Connection Resilience + Data Reliability.
171
23
  export { ResilientDataBridge, ResilientOptions, ResilientEvents } from './resilient';
package/lib/native.ts ADDED
@@ -0,0 +1,71 @@
1
+
2
+ import path from 'path';
3
+
4
+ // Load native addon
5
+ function loadAddon (): any {
6
+ const possiblePaths = [
7
+ `../prebuilds/${process.platform}-${process.arch}/data_bridge_node.node`,
8
+ '../build/Release/data_bridge_node.node',
9
+ ];
10
+
11
+ for (const p of possiblePaths)
12
+ {
13
+ try
14
+ {
15
+ return require(path.join(__dirname, p));
16
+ } catch
17
+ {
18
+ continue;
19
+ }
20
+ }
21
+ throw new Error('Failed to load native addon. Run `npm run build` first.');
22
+ }
23
+
24
+ const addon = loadAddon();
25
+
26
+ export interface SerialPort {
27
+ open (port: string, baud: number, callback: (data: Buffer) => void): boolean;
28
+ write (data: Buffer): number;
29
+ close (): boolean;
30
+ isOpen (): boolean;
31
+ }
32
+
33
+ export const SerialPort: {
34
+ new(): SerialPort;
35
+ } = addon.SerialPort;
36
+
37
+ export interface Frame {
38
+ valid: boolean;
39
+ header: {
40
+ type: number;
41
+ seq_id: number;
42
+ fragment_id: number;
43
+ total_frags: number;
44
+ payload_len: number;
45
+ crc32: number;
46
+ };
47
+ payload: Buffer;
48
+ }
49
+
50
+ export interface PacketHelper {
51
+ serialize (type: number, seq: number, payload: string | Buffer, frag_id?: number, total_frags?: number): Buffer;
52
+ deserialize (buffer: Buffer): { frame: Frame; remaining: Buffer; };
53
+ TYPE_DATA: number;
54
+ TYPE_ACK: number;
55
+ TYPE_NACK: number;
56
+ TYPE_SYN: number;
57
+ }
58
+
59
+ export const Packet: PacketHelper = addon.Packet;
60
+
61
+ export interface Reassembler {
62
+ processFragment (frame: Frame): boolean;
63
+ isComplete (frame: Frame): boolean;
64
+ getData (): Buffer;
65
+ isDuplicate (frame: Frame): boolean;
66
+ getBufferedSize (): number;
67
+ }
68
+
69
+ export const Reassembler: {
70
+ new(): Reassembler;
71
+ } = addon.Reassembler;