@technoculture/data-bridge 0.1.0
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/CMakeLists.txt +57 -0
- package/README.md +77 -0
- package/dist/index.d.mts +148 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.js +314 -0
- package/dist/index.mjs +285 -0
- package/lib/index.ts +171 -0
- package/lib/resilient.ts +276 -0
- package/package.json +75 -0
- package/prebuilds/darwin-arm64/.ninja_deps +0 -0
- package/prebuilds/darwin-arm64/.ninja_log +6 -0
- package/prebuilds/darwin-arm64/CMakeCache.txt +398 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeCCompiler.cmake +84 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake +104 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeDetermineCompilerABI_C.bin +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CMakeSystem.cmake +15 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/CMakeCCompilerId.c +905 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/a.out +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdC/apple-sdk.c +1 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/CMakeCXXCompilerId.cpp +920 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/a.out +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/4.0.3/CompilerIdCXX/apple-sdk.cpp +1 -0
- package/prebuilds/darwin-arm64/CMakeFiles/CMakeConfigureLog.yaml +531 -0
- package/prebuilds/darwin-arm64/CMakeFiles/InstallScripts.json +7 -0
- package/prebuilds/darwin-arm64/CMakeFiles/TargetDirectories.txt +3 -0
- package/prebuilds/darwin-arm64/CMakeFiles/cmake.check_cache +1 -0
- package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/Users/satyamtiwary/Documents/Python-Things/data-bridge/src/protocol/crc16.cpp.o +0 -0
- 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
- package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/src/addon.cpp.o +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/data_bridge_node.dir/src/serial_wrapper.cpp.o +0 -0
- package/prebuilds/darwin-arm64/CMakeFiles/rules.ninja +64 -0
- package/prebuilds/darwin-arm64/Release/data_bridge_node.node +0 -0
- package/prebuilds/darwin-arm64/build.ninja +192 -0
- package/prebuilds/darwin-arm64/cmake_install.cmake +61 -0
- package/src/addon.cpp +219 -0
- package/src/serial_wrapper.cpp +8 -0
package/lib/index.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Bridge - Guaranteed Reliable Serial Communication
|
|
3
|
+
*
|
|
4
|
+
* TypeScript wrapper for the native Node-API addon.
|
|
5
|
+
* Provides a clean, async-friendly API for Electron applications.
|
|
6
|
+
*/
|
|
7
|
+
|
|
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
|
+
}
|
|
162
|
+
|
|
163
|
+
emit<K extends keyof DataBridgeEvents> (event: K, ...args: Parameters<DataBridgeEvents[K]>): boolean {
|
|
164
|
+
return super.emit(event, ...args);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export default DataBridge;
|
|
169
|
+
|
|
170
|
+
// Re-export resilient wrapper
|
|
171
|
+
export { ResilientDataBridge, ResilientOptions, ResilientEvents } from './resilient';
|
package/lib/resilient.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResilientDataBridge - Connection-resilient wrapper
|
|
3
|
+
*
|
|
4
|
+
* Guarantees message delivery across USB disconnections by:
|
|
5
|
+
* 1. Auto-reconnection with exponential backoff
|
|
6
|
+
* 2. Message queue for pending sends during disconnect
|
|
7
|
+
* 3. Automatic re-handshake and queue flush on reconnect
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
import { DataBridge, DataBridgeOptions } from './index';
|
|
12
|
+
|
|
13
|
+
export interface ResilientOptions extends DataBridgeOptions {
|
|
14
|
+
/** Enable auto-reconnection (default: true) */
|
|
15
|
+
reconnect?: boolean;
|
|
16
|
+
/** Initial reconnect delay in ms (default: 1000) */
|
|
17
|
+
reconnectDelay?: number;
|
|
18
|
+
/** Maximum reconnect delay in ms (default: 30000) */
|
|
19
|
+
maxReconnectDelay?: number;
|
|
20
|
+
/** Maximum queue size before dropping old messages (default: 1000) */
|
|
21
|
+
maxQueueSize?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ResilientEvents {
|
|
25
|
+
data: (data: Buffer) => void;
|
|
26
|
+
error: (error: Error) => void;
|
|
27
|
+
close: () => void;
|
|
28
|
+
disconnect: () => void;
|
|
29
|
+
reconnecting: (attempt: number, delay: number) => void;
|
|
30
|
+
reconnected: () => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface QueuedMessage {
|
|
34
|
+
data: Buffer;
|
|
35
|
+
resolve: () => void;
|
|
36
|
+
reject: (err: Error) => void;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class ResilientDataBridge extends EventEmitter {
|
|
41
|
+
private bridge: DataBridge | null = null;
|
|
42
|
+
private port: string;
|
|
43
|
+
private options: Required<ResilientOptions>;
|
|
44
|
+
private messageQueue: QueuedMessage[] = [];
|
|
45
|
+
private isConnected = false;
|
|
46
|
+
private isReconnecting = false;
|
|
47
|
+
private shouldReconnect = true;
|
|
48
|
+
private reconnectAttempt = 0;
|
|
49
|
+
private reconnectTimeout: NodeJS.Timeout | null = null;
|
|
50
|
+
|
|
51
|
+
private constructor(port: string, options: ResilientOptions) {
|
|
52
|
+
super();
|
|
53
|
+
this.port = port;
|
|
54
|
+
this.options = {
|
|
55
|
+
baudRate: options.baudRate ?? 115200,
|
|
56
|
+
reconnect: options.reconnect ?? true,
|
|
57
|
+
reconnectDelay: options.reconnectDelay ?? 1000,
|
|
58
|
+
maxReconnectDelay: options.maxReconnectDelay ?? 30000,
|
|
59
|
+
maxQueueSize: options.maxQueueSize ?? 1000,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Open a resilient serial connection.
|
|
65
|
+
*
|
|
66
|
+
* @param port - Serial port path
|
|
67
|
+
* @param options - Configuration including reconnection settings
|
|
68
|
+
*/
|
|
69
|
+
static async open (port: string, options: ResilientOptions = {}): Promise<ResilientDataBridge> {
|
|
70
|
+
const instance = new ResilientDataBridge(port, options);
|
|
71
|
+
await instance.connect();
|
|
72
|
+
return instance;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private async connect (): Promise<void> {
|
|
76
|
+
try
|
|
77
|
+
{
|
|
78
|
+
this.bridge = await DataBridge.open(this.port, {
|
|
79
|
+
baudRate: this.options.baudRate,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.isConnected = true;
|
|
83
|
+
this.reconnectAttempt = 0;
|
|
84
|
+
|
|
85
|
+
// Forward data events
|
|
86
|
+
this.bridge.on('data', (data) => {
|
|
87
|
+
this.emit('data', data);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Handle errors and detect disconnection
|
|
91
|
+
this.bridge.on('error', (err) => {
|
|
92
|
+
this.emit('error', err);
|
|
93
|
+
this.handleDisconnect();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// If we're reconnecting, emit event and flush queue
|
|
97
|
+
if (this.isReconnecting)
|
|
98
|
+
{
|
|
99
|
+
this.isReconnecting = false;
|
|
100
|
+
this.emit('reconnected');
|
|
101
|
+
await this.flushQueue();
|
|
102
|
+
}
|
|
103
|
+
} catch (err)
|
|
104
|
+
{
|
|
105
|
+
this.isConnected = false;
|
|
106
|
+
if (this.shouldReconnect && this.options.reconnect)
|
|
107
|
+
{
|
|
108
|
+
this.scheduleReconnect();
|
|
109
|
+
} else
|
|
110
|
+
{
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private handleDisconnect (): void {
|
|
117
|
+
if (!this.isConnected) return;
|
|
118
|
+
|
|
119
|
+
this.isConnected = false;
|
|
120
|
+
this.bridge = null;
|
|
121
|
+
this.emit('disconnect');
|
|
122
|
+
|
|
123
|
+
if (this.shouldReconnect && this.options.reconnect)
|
|
124
|
+
{
|
|
125
|
+
this.scheduleReconnect();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private scheduleReconnect (): void {
|
|
130
|
+
if (this.reconnectTimeout) return;
|
|
131
|
+
|
|
132
|
+
this.isReconnecting = true;
|
|
133
|
+
this.reconnectAttempt++;
|
|
134
|
+
|
|
135
|
+
// Exponential backoff with jitter
|
|
136
|
+
const baseDelay = this.options.reconnectDelay;
|
|
137
|
+
const maxDelay = this.options.maxReconnectDelay;
|
|
138
|
+
const delay = Math.min(
|
|
139
|
+
baseDelay * Math.pow(2, this.reconnectAttempt - 1) + Math.random() * 1000,
|
|
140
|
+
maxDelay
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
this.emit('reconnecting', this.reconnectAttempt, delay);
|
|
144
|
+
|
|
145
|
+
this.reconnectTimeout = setTimeout(async () => {
|
|
146
|
+
this.reconnectTimeout = null;
|
|
147
|
+
try
|
|
148
|
+
{
|
|
149
|
+
await this.connect();
|
|
150
|
+
} catch
|
|
151
|
+
{
|
|
152
|
+
// connect() will schedule another attempt if needed
|
|
153
|
+
}
|
|
154
|
+
}, delay);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Send data with guaranteed delivery.
|
|
159
|
+
*
|
|
160
|
+
* If disconnected, the message is queued and will be sent
|
|
161
|
+
* automatically when the connection is restored.
|
|
162
|
+
*
|
|
163
|
+
* @param data - Data to send
|
|
164
|
+
* @returns Promise that resolves when data is acknowledged
|
|
165
|
+
*/
|
|
166
|
+
async send (data: Buffer | string): Promise<void> {
|
|
167
|
+
const buffer = typeof data === 'string' ? Buffer.from(data) : data;
|
|
168
|
+
|
|
169
|
+
if (this.isConnected && this.bridge)
|
|
170
|
+
{
|
|
171
|
+
// Connected - send immediately
|
|
172
|
+
try
|
|
173
|
+
{
|
|
174
|
+
await this.bridge.send(buffer);
|
|
175
|
+
} catch (err)
|
|
176
|
+
{
|
|
177
|
+
// Send failed - queue it and handle disconnect
|
|
178
|
+
return this.queueMessage(buffer);
|
|
179
|
+
}
|
|
180
|
+
} else
|
|
181
|
+
{
|
|
182
|
+
// Disconnected - queue the message
|
|
183
|
+
return this.queueMessage(buffer);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private queueMessage (data: Buffer): Promise<void> {
|
|
188
|
+
return new Promise((resolve, reject) => {
|
|
189
|
+
// Enforce max queue size (drop oldest)
|
|
190
|
+
while (this.messageQueue.length >= this.options.maxQueueSize)
|
|
191
|
+
{
|
|
192
|
+
const dropped = this.messageQueue.shift();
|
|
193
|
+
dropped?.reject(new Error('Message dropped: queue overflow'));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this.messageQueue.push({
|
|
197
|
+
data,
|
|
198
|
+
resolve,
|
|
199
|
+
reject,
|
|
200
|
+
timestamp: Date.now(),
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private async flushQueue (): Promise<void> {
|
|
206
|
+
while (this.messageQueue.length > 0 && this.isConnected && this.bridge)
|
|
207
|
+
{
|
|
208
|
+
const msg = this.messageQueue.shift()!;
|
|
209
|
+
try
|
|
210
|
+
{
|
|
211
|
+
await this.bridge.send(msg.data);
|
|
212
|
+
msg.resolve();
|
|
213
|
+
} catch (err)
|
|
214
|
+
{
|
|
215
|
+
// Put it back at the front and stop flushing
|
|
216
|
+
this.messageQueue.unshift(msg);
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Close the connection permanently.
|
|
224
|
+
* Rejects all pending queued messages.
|
|
225
|
+
*/
|
|
226
|
+
async close (): Promise<void> {
|
|
227
|
+
this.shouldReconnect = false;
|
|
228
|
+
|
|
229
|
+
if (this.reconnectTimeout)
|
|
230
|
+
{
|
|
231
|
+
clearTimeout(this.reconnectTimeout);
|
|
232
|
+
this.reconnectTimeout = null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Reject all queued messages
|
|
236
|
+
for (const msg of this.messageQueue)
|
|
237
|
+
{
|
|
238
|
+
msg.reject(new Error('Connection closed'));
|
|
239
|
+
}
|
|
240
|
+
this.messageQueue = [];
|
|
241
|
+
|
|
242
|
+
if (this.bridge)
|
|
243
|
+
{
|
|
244
|
+
await this.bridge.close();
|
|
245
|
+
this.bridge = null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
this.isConnected = false;
|
|
249
|
+
this.emit('close');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Current connection state */
|
|
253
|
+
get connected (): boolean {
|
|
254
|
+
return this.isConnected;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Number of messages waiting in queue */
|
|
258
|
+
get queueLength (): number {
|
|
259
|
+
return this.messageQueue.length;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Type-safe event emitter
|
|
263
|
+
on<K extends keyof ResilientEvents> (event: K, listener: ResilientEvents[K]): this {
|
|
264
|
+
return super.on(event, listener);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
once<K extends keyof ResilientEvents> (event: K, listener: ResilientEvents[K]): this {
|
|
268
|
+
return super.once(event, listener);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
emit<K extends keyof ResilientEvents> (event: K, ...args: Parameters<ResilientEvents[K]>): boolean {
|
|
272
|
+
return super.emit(event, ...args);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export default ResilientDataBridge;
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@technoculture/data-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Guaranteed reliable serial communication for Node.js and Electron",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"install": "prebuild-install || cmake-js compile",
|
|
17
|
+
"build": "npm run build:native && npm run build:ts",
|
|
18
|
+
"build:native": "cmake-js compile",
|
|
19
|
+
"build:ts": "tsup lib/index.ts --format cjs,esm --dts",
|
|
20
|
+
"prebuild": "cmake-js compile -O prebuilds/$(node -p \"process.platform + '-' + process.arch\")",
|
|
21
|
+
"prepublishOnly": "npm run build:ts",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"clean": "cmake-js clean && rm -rf dist prebuilds"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"prebuilds",
|
|
28
|
+
"src",
|
|
29
|
+
"lib",
|
|
30
|
+
"CMakeLists.txt"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"node-addon-api": "^7.0.0",
|
|
34
|
+
"prebuild-install": "^7.1.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.10.0",
|
|
38
|
+
"cmake-js": "^7.3.0",
|
|
39
|
+
"tsup": "^8.0.0",
|
|
40
|
+
"typescript": "^5.3.0",
|
|
41
|
+
"vitest": "^1.0.0"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"os": [
|
|
47
|
+
"win32",
|
|
48
|
+
"linux",
|
|
49
|
+
"darwin"
|
|
50
|
+
],
|
|
51
|
+
"cpu": [
|
|
52
|
+
"x64",
|
|
53
|
+
"arm64",
|
|
54
|
+
"ia32"
|
|
55
|
+
],
|
|
56
|
+
"binary": {
|
|
57
|
+
"napi_versions": [
|
|
58
|
+
8
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://github.com/aspect-labs/data-bridge"
|
|
64
|
+
},
|
|
65
|
+
"keywords": [
|
|
66
|
+
"serial",
|
|
67
|
+
"uart",
|
|
68
|
+
"reliable",
|
|
69
|
+
"medical",
|
|
70
|
+
"embedded",
|
|
71
|
+
"electron",
|
|
72
|
+
"napi"
|
|
73
|
+
],
|
|
74
|
+
"license": "MIT"
|
|
75
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ninja log v6
|
|
2
|
+
1 42 1767813639052166764 CMakeFiles/data_bridge_node.dir/Users/satyamtiwary/Documents/Python-Things/data-bridge/src/protocol/crc16.cpp.o 44a8848073165fd4
|
|
3
|
+
1 286 1767813639052016345 CMakeFiles/data_bridge_node.dir/src/serial_wrapper.cpp.o 9b7a8f38fa1f98b2
|
|
4
|
+
1 301 1767813639052311933 CMakeFiles/data_bridge_node.dir/Users/satyamtiwary/Documents/Python-Things/data-bridge/src/transport/platform/linux/linux_serial.cpp.o 1a4595fea1e208f8
|
|
5
|
+
1 698 1767813639051708840 CMakeFiles/data_bridge_node.dir/src/addon.cpp.o 7d74cb8705ae44b7
|
|
6
|
+
698 745 1767813639749307606 Release/data_bridge_node.node 1305e389db74efac
|