taro-bluetooth-print 2.3.0 → 2.4.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +73 -195
  2. package/README.md +134 -386
  3. package/dist/index.cjs.js +1 -1
  4. package/dist/index.es.js +1 -1
  5. package/dist/index.umd.js +1 -1
  6. package/dist/types/config/PrinterConfigManager.d.ts +206 -0
  7. package/dist/types/config/index.d.ts +8 -0
  8. package/dist/types/core/BluetoothPrinter.d.ts +1 -1
  9. package/dist/types/core/EventEmitter.d.ts +6 -26
  10. package/dist/types/core/index.d.ts +6 -0
  11. package/dist/types/device/MultiPrinterManager.d.ts +164 -0
  12. package/dist/types/device/index.d.ts +2 -0
  13. package/dist/types/drivers/CpclDriver.d.ts +304 -0
  14. package/dist/types/drivers/GPrinterDriver.d.ts +63 -0
  15. package/dist/types/drivers/ZplDriver.d.ts +325 -0
  16. package/dist/types/drivers/index.d.ts +9 -0
  17. package/dist/types/encoding/gbk-lite.d.ts +8 -0
  18. package/dist/types/encoding/gbk-table.d.ts +8 -30
  19. package/dist/types/index.d.ts +12 -8
  20. package/dist/types/services/BatchPrintManager.d.ts +205 -0
  21. package/dist/types/services/ConnectionManager.d.ts +1 -1
  22. package/dist/types/services/PrintHistory.d.ts +142 -0
  23. package/dist/types/services/PrintJobManager.d.ts +28 -4
  24. package/dist/types/services/PrinterStatus.d.ts +97 -0
  25. package/dist/types/services/index.d.ts +11 -0
  26. package/package.json +25 -7
  27. package/src/adapters/AlipayAdapter.ts +1 -0
  28. package/src/adapters/BaiduAdapter.ts +1 -0
  29. package/src/adapters/BaseAdapter.ts +6 -8
  30. package/src/adapters/ByteDanceAdapter.ts +1 -0
  31. package/src/adapters/TaroAdapter.ts +1 -0
  32. package/src/adapters/WebBluetoothAdapter.ts +1 -1
  33. package/src/config/PrinterConfigManager.ts +519 -0
  34. package/src/config/index.ts +15 -0
  35. package/src/core/BluetoothPrinter.ts +15 -15
  36. package/src/core/EventEmitter.ts +15 -15
  37. package/src/core/index.ts +7 -0
  38. package/src/device/MultiPrinterManager.ts +470 -0
  39. package/src/device/index.ts +8 -0
  40. package/src/drivers/CpclDriver.ts +549 -0
  41. package/src/drivers/GPrinterDriver.ts +115 -0
  42. package/src/drivers/TsplDriver.ts +9 -21
  43. package/src/drivers/ZplDriver.ts +543 -0
  44. package/src/drivers/index.ts +37 -0
  45. package/src/encoding/gbk-lite.ts +113 -0
  46. package/src/encoding/gbk-table.ts +80 -58
  47. package/src/index.ts +40 -35
  48. package/src/plugins/PluginManager.ts +3 -1
  49. package/src/plugins/builtin/LoggingPlugin.ts +4 -2
  50. package/src/plugins/builtin/RetryPlugin.ts +8 -14
  51. package/src/services/BatchPrintManager.ts +500 -0
  52. package/src/services/ConnectionManager.ts +25 -22
  53. package/src/services/PrintHistory.ts +336 -0
  54. package/src/services/PrintJobManager.ts +69 -9
  55. package/src/services/PrinterStatus.ts +267 -0
  56. package/src/services/index.ts +22 -0
  57. package/src/template/TemplateEngine.ts +4 -1
@@ -0,0 +1,500 @@
1
+ /**
2
+ * Batch Print Manager
3
+ *
4
+ * Optimizes printing multiple jobs by:
5
+ * - Merging small jobs into larger chunks
6
+ * - Reducing Bluetooth communication overhead
7
+ * - Prioritizing urgent jobs
8
+ * - Batching similar content for efficiency
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const batchManager = new BatchPrintManager();
13
+ *
14
+ * // Add print jobs
15
+ * batchManager.addJob({ data: buffer1, priority: 1 });
16
+ * batchManager.addJob({ data: buffer2, priority: 2 });
17
+ *
18
+ * // Process batch when ready
19
+ * await batchManager.processBatch();
20
+ * ```
21
+ */
22
+
23
+ import { Logger } from '@/utils/logger';
24
+ import { BluetoothPrintError, ErrorCode } from '@/errors/BluetoothError';
25
+
26
+ /**
27
+ * Batch job entry
28
+ */
29
+ export interface BatchJob {
30
+ /** Unique job ID */
31
+ id: string;
32
+ /** Print data */
33
+ data: Uint8Array;
34
+ /** Priority (higher = more urgent) */
35
+ priority: number;
36
+ /** Timestamp when added */
37
+ addedAt: number;
38
+ /** Metadata */
39
+ metadata?: Record<string, unknown>;
40
+ }
41
+
42
+ /**
43
+ * Batch configuration
44
+ */
45
+ export interface BatchConfig {
46
+ /** Maximum batch size in bytes */
47
+ maxBatchSize: number;
48
+ /** Maximum wait time before processing in ms */
49
+ maxWaitTime: number;
50
+ /** Minimum jobs before batching */
51
+ minBatchSize: number;
52
+ /** Merge similar content */
53
+ enableMerging: boolean;
54
+ /** Auto-process interval in ms (0 = disabled) */
55
+ autoProcessInterval: number;
56
+ }
57
+
58
+ /**
59
+ * Batch statistics
60
+ */
61
+ export interface BatchStats {
62
+ /** Total jobs added */
63
+ totalJobs: number;
64
+ /** Total bytes processed */
65
+ totalBytes: number;
66
+ /** Batches processed */
67
+ batchesProcessed: number;
68
+ /** Average batch size */
69
+ avgBatchSize: number;
70
+ /** Merged jobs count */
71
+ mergedJobs: number;
72
+ }
73
+
74
+ /**
75
+ * Batch events
76
+ */
77
+ export interface BatchEvents {
78
+ 'batch-ready': (data: BatchJob[]) => void;
79
+ 'batch-processed': (data: { jobCount: number; bytes: number }) => void;
80
+ 'job-added': (data: BatchJob) => void;
81
+ 'job-rejected': (data: { reason: string }) => void;
82
+ }
83
+
84
+ /**
85
+ * Event handler map type
86
+ */
87
+ type BatchEventHandlerMap = {
88
+ [K in keyof BatchEvents]: Set<BatchEvents[K]>;
89
+ };
90
+
91
+ /**
92
+ * Default batch configuration
93
+ */
94
+ const DEFAULT_CONFIG: BatchConfig = {
95
+ maxBatchSize: 1024 * 50, // 50KB max per batch
96
+ maxWaitTime: 1000, // 1 second max wait
97
+ minBatchSize: 1, // Process even single jobs
98
+ enableMerging: true, // Enable content merging
99
+ autoProcessInterval: 500, // Check every 500ms
100
+ };
101
+
102
+ /**
103
+ * Batch Print Manager
104
+ *
105
+ * Collects print jobs and processes them in optimized batches.
106
+ * Reduces Bluetooth communication overhead by combining small jobs.
107
+ */
108
+ export class BatchPrintManager {
109
+ private readonly logger = Logger.scope('BatchPrintManager');
110
+ private readonly jobs: BatchJob[] = [];
111
+ private readonly listeners: BatchEventHandlerMap = {
112
+ 'batch-ready': new Set(),
113
+ 'batch-processed': new Set(),
114
+ 'job-added': new Set(),
115
+ 'job-rejected': new Set(),
116
+ };
117
+ private config: BatchConfig;
118
+ private isProcessing = false;
119
+ private waitTimer: ReturnType<typeof setTimeout> | null = null;
120
+ private autoProcessTimer: ReturnType<typeof setInterval> | null = null;
121
+ private stats: BatchStats = {
122
+ totalJobs: 0,
123
+ totalBytes: 0,
124
+ batchesProcessed: 0,
125
+ avgBatchSize: 0,
126
+ mergedJobs: 0,
127
+ };
128
+
129
+ /**
130
+ * Creates a new BatchPrintManager instance
131
+ */
132
+ constructor(config: Partial<BatchConfig> = {}) {
133
+ this.config = { ...DEFAULT_CONFIG, ...config };
134
+ }
135
+
136
+ /**
137
+ * Register event listener
138
+ */
139
+ on<K extends keyof BatchEvents>(
140
+ event: K,
141
+ callback: BatchEvents[K]
142
+ ): void {
143
+ this.listeners[event].add(callback);
144
+ }
145
+
146
+ /**
147
+ * Remove event listener
148
+ */
149
+ off<K extends keyof BatchEvents>(
150
+ event: K,
151
+ callback: BatchEvents[K]
152
+ ): void {
153
+ this.listeners[event].delete(callback);
154
+ }
155
+
156
+ /**
157
+ * Emit an event
158
+ */
159
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
+ private emit<K extends keyof BatchEvents>(event: K, data: any): void {
161
+ this.listeners[event].forEach(handler => {
162
+ try {
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ (handler as any)(data);
165
+ } catch (error) {
166
+ this.logger.error(`Error in event handler for "${event}":`, error);
167
+ }
168
+ });
169
+ }
170
+
171
+ /**
172
+ * Add a job to the batch queue
173
+ *
174
+ * @param data - Print data
175
+ * @param priority - Job priority (higher = more urgent)
176
+ * @param metadata - Optional metadata
177
+ * @returns Job ID
178
+ */
179
+ addJob(
180
+ data: Uint8Array,
181
+ priority = 1,
182
+ metadata?: Record<string, unknown>
183
+ ): string {
184
+ const id = this.generateId();
185
+ const job: BatchJob = {
186
+ id,
187
+ data,
188
+ priority,
189
+ addedAt: Date.now(),
190
+ metadata,
191
+ };
192
+
193
+ this.jobs.push(job);
194
+ this.stats.totalJobs++;
195
+
196
+ // Sort by priority (descending)
197
+ this.jobs.sort((a, b) => b.priority - a.priority);
198
+
199
+ this.emit('job-added', job);
200
+ this.logger.debug(`Job added: ${id} (priority: ${priority}, queue size: ${this.jobs.length})`);
201
+
202
+ // Start/restart wait timer
203
+ this.startWaitTimer();
204
+
205
+ // Check if we should process immediately
206
+ if (this.shouldProcessImmediately()) {
207
+ this.emit('batch-ready', [...this.jobs]);
208
+ }
209
+
210
+ // Start auto-process if enabled
211
+ this.startAutoProcess();
212
+
213
+ return id;
214
+ }
215
+
216
+ /**
217
+ * Add multiple jobs at once
218
+ */
219
+ addJobs(jobs: Array<{ data: Uint8Array; priority?: number; metadata?: Record<string, unknown> }>): string[] {
220
+ return jobs.map(job => this.addJob(job.data, job.priority, job.metadata));
221
+ }
222
+
223
+ /**
224
+ * Cancel a job by ID
225
+ */
226
+ cancelJob(id: string): boolean {
227
+ const index = this.jobs.findIndex(j => j.id === id);
228
+ if (index === -1) {
229
+ return false;
230
+ }
231
+
232
+ this.jobs.splice(index, 1);
233
+ this.logger.debug(`Job cancelled: ${id}`);
234
+ return true;
235
+ }
236
+
237
+ /**
238
+ * Cancel all jobs
239
+ */
240
+ cancelAll(): void {
241
+ const count = this.jobs.length;
242
+ this.jobs.length = 0;
243
+ this.clearTimers();
244
+ this.logger.info(`Cancelled ${count} jobs`);
245
+ }
246
+
247
+ /**
248
+ * Get pending job count
249
+ */
250
+ get pendingCount(): number {
251
+ return this.jobs.length;
252
+ }
253
+
254
+ /**
255
+ * Get pending jobs
256
+ */
257
+ getPendingJobs(): BatchJob[] {
258
+ return [...this.jobs];
259
+ }
260
+
261
+ /**
262
+ * Get current statistics
263
+ */
264
+ getStats(): BatchStats {
265
+ return { ...this.stats };
266
+ }
267
+
268
+ /**
269
+ * Update configuration
270
+ */
271
+ updateConfig(updates: Partial<BatchConfig>): void {
272
+ this.config = { ...this.config, ...updates };
273
+ this.logger.debug('Configuration updated');
274
+ }
275
+
276
+ /**
277
+ * Process the current batch
278
+ *
279
+ * @param processor - Function to send batch data to printer
280
+ * @returns Number of jobs processed
281
+ */
282
+ async processBatch(
283
+ processor: (data: Uint8Array) => Promise<void>
284
+ ): Promise<number> {
285
+ if (this.isProcessing) {
286
+ throw new BluetoothPrintError(
287
+ ErrorCode.PRINT_JOB_IN_PROGRESS,
288
+ 'Batch processing already in progress'
289
+ );
290
+ }
291
+
292
+ if (this.jobs.length === 0) {
293
+ this.logger.debug('No jobs to process');
294
+ return 0;
295
+ }
296
+
297
+ this.isProcessing = true;
298
+ this.clearTimers();
299
+
300
+ try {
301
+ // Get jobs for this batch
302
+ const batchJobs = this.prepareBatch();
303
+ const mergedData = this.mergeJobs(batchJobs);
304
+
305
+ this.logger.info(`Processing batch: ${batchJobs.length} jobs, ${mergedData.length} bytes`);
306
+
307
+ // Emit batch ready event
308
+ this.emit('batch-ready', batchJobs);
309
+
310
+ // Process the merged data
311
+ await processor(mergedData);
312
+
313
+ // Update stats
314
+ this.stats.totalBytes += mergedData.length;
315
+ this.stats.batchesProcessed++;
316
+ this.stats.avgBatchSize =
317
+ (this.stats.avgBatchSize * (this.stats.batchesProcessed - 1) + mergedData.length) /
318
+ this.stats.batchesProcessed;
319
+
320
+ // Remove processed jobs
321
+ this.jobs.splice(0, batchJobs.length);
322
+
323
+ this.emit('batch-processed', { jobCount: batchJobs.length, bytes: mergedData.length });
324
+ this.logger.info(`Batch processed: ${batchJobs.length} jobs`);
325
+
326
+ return batchJobs.length;
327
+ } finally {
328
+ this.isProcessing = false;
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Prepare batch from pending jobs
334
+ */
335
+ private prepareBatch(): BatchJob[] {
336
+ const batch: BatchJob[] = [];
337
+ let totalSize = 0;
338
+
339
+ for (const job of this.jobs) {
340
+ // Check if adding this job would exceed max batch size
341
+ if (batch.length > 0 && totalSize + job.data.length > this.config.maxBatchSize) {
342
+ // Don't add if it would exceed, and we already have some jobs
343
+ if (batch.length >= this.config.minBatchSize) {
344
+ break;
345
+ }
346
+ }
347
+
348
+ batch.push(job);
349
+ totalSize += job.data.length;
350
+ }
351
+
352
+ return batch;
353
+ }
354
+
355
+ /**
356
+ * Merge multiple jobs into a single buffer
357
+ */
358
+ private mergeJobs(jobs: BatchJob[]): Uint8Array {
359
+ if (!this.config.enableMerging || jobs.length === 1) {
360
+ return jobs[0]?.data ?? new Uint8Array(0);
361
+ }
362
+
363
+ // Calculate total size
364
+ let totalSize = 0;
365
+ for (const job of jobs) {
366
+ totalSize += job.data.length;
367
+ }
368
+
369
+ // Merge into single buffer
370
+ const result = new Uint8Array(totalSize);
371
+ let offset = 0;
372
+
373
+ for (const job of jobs) {
374
+ result.set(job.data, offset);
375
+ offset += job.data.length;
376
+ this.stats.mergedJobs++;
377
+ }
378
+
379
+ this.logger.debug(`Merged ${jobs.length} jobs into ${totalSize} bytes`);
380
+ return result;
381
+ }
382
+
383
+ /**
384
+ * Check if we should process immediately
385
+ */
386
+ private shouldProcessImmediately(): boolean {
387
+ if (this.jobs.length === 0) {
388
+ return false;
389
+ }
390
+
391
+ // Large single job
392
+ const firstJob = this.jobs[0];
393
+ if (this.jobs.length === 1 && firstJob && firstJob.data.length >= this.config.maxBatchSize * 0.8) {
394
+ return true;
395
+ }
396
+
397
+ // Queue is full
398
+ const totalSize = this.jobs.reduce((sum, j) => sum + j.data.length, 0);
399
+ if (totalSize >= this.config.maxBatchSize) {
400
+ return true;
401
+ }
402
+
403
+ return false;
404
+ }
405
+
406
+ /**
407
+ * Start the wait timer
408
+ */
409
+ private startWaitTimer(): void {
410
+ this.clearWaitTimer();
411
+
412
+ if (this.config.maxWaitTime <= 0) {
413
+ return;
414
+ }
415
+
416
+ this.waitTimer = setTimeout(() => {
417
+ this.logger.debug('Wait timer expired, batch ready');
418
+ this.emit('batch-ready', [...this.jobs]);
419
+ }, this.config.maxWaitTime);
420
+ }
421
+
422
+ /**
423
+ * Clear wait timer
424
+ */
425
+ private clearWaitTimer(): void {
426
+ if (this.waitTimer) {
427
+ clearTimeout(this.waitTimer);
428
+ this.waitTimer = null;
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Start auto-process timer
434
+ */
435
+ private startAutoProcess(): void {
436
+ if (this.autoProcessTimer || this.config.autoProcessInterval <= 0) {
437
+ return;
438
+ }
439
+
440
+ this.autoProcessTimer = setInterval(() => {
441
+ // Check if batch is ready
442
+ if (this.shouldProcessImmediately()) {
443
+ this.emit('batch-ready', [...this.jobs]);
444
+ }
445
+ }, this.config.autoProcessInterval);
446
+ }
447
+
448
+ /**
449
+ * Stop auto-process timer
450
+ */
451
+ private stopAutoProcess(): void {
452
+ if (this.autoProcessTimer) {
453
+ clearInterval(this.autoProcessTimer);
454
+ this.autoProcessTimer = null;
455
+ }
456
+ }
457
+
458
+ /**
459
+ * Clear all timers
460
+ */
461
+ private clearTimers(): void {
462
+ this.clearWaitTimer();
463
+ this.stopAutoProcess();
464
+ }
465
+
466
+ /**
467
+ * Generate unique job ID
468
+ */
469
+ private generateId(): string {
470
+ return `batch_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
471
+ }
472
+
473
+ /**
474
+ * Reset statistics
475
+ */
476
+ resetStats(): void {
477
+ this.stats = {
478
+ totalJobs: 0,
479
+ totalBytes: 0,
480
+ batchesProcessed: 0,
481
+ avgBatchSize: 0,
482
+ mergedJobs: 0,
483
+ };
484
+ }
485
+
486
+ /**
487
+ * Destroy the manager
488
+ */
489
+ destroy(): void {
490
+ this.cancelAll();
491
+ // Clear all listeners
492
+ for (const key of Object.keys(this.listeners) as (keyof BatchEventHandlerMap)[]) {
493
+ this.listeners[key].clear();
494
+ }
495
+ this.logger.info('BatchPrintManager destroyed');
496
+ }
497
+ }
498
+
499
+ // Export singleton for convenience
500
+ export const batchPrintManager = new BatchPrintManager();
@@ -71,7 +71,7 @@ export class ConnectionManager
71
71
  private adapter: IPrinterAdapter;
72
72
  private deviceId: string | null = null;
73
73
  private state: PrinterState = PrinterState.DISCONNECTED;
74
- private readonly logger = Logger.scope('ConnectionManager');
74
+ private readonly connLogger = Logger.scope('ConnectionManager');
75
75
  private readonly config: Required<ConnectionManagerConfig>;
76
76
 
77
77
  // Heartbeat state
@@ -102,7 +102,7 @@ export class ConnectionManager
102
102
  private handleStateChange(newState: PrinterState): void {
103
103
  const previousState = this.state;
104
104
  this.state = newState;
105
- this.logger.debug('State changed:', { from: previousState, to: newState });
105
+ this.connLogger.debug('State changed:', { from: previousState, to: newState });
106
106
  this.emit('state-change', newState);
107
107
 
108
108
  // Handle unexpected disconnection
@@ -112,7 +112,7 @@ export class ConnectionManager
112
112
  this.deviceId &&
113
113
  !this.isReconnecting
114
114
  ) {
115
- this.logger.warn('Unexpected disconnection detected');
115
+ this.connLogger.warn('Unexpected disconnection detected');
116
116
  this.emit('disconnected', this.deviceId);
117
117
  this.stopHeartbeat();
118
118
 
@@ -127,7 +127,7 @@ export class ConnectionManager
127
127
  * Connects to a Bluetooth device
128
128
  */
129
129
  async connect(deviceId: string, options?: { retries?: number; timeout?: number }): Promise<void> {
130
- this.logger.info('Connecting to device:', deviceId);
130
+ this.connLogger.info('Connecting to device:', deviceId);
131
131
 
132
132
  const { retries = 0, timeout = this.config.connectionTimeout } = options || {};
133
133
  let attempts = 0;
@@ -159,7 +159,7 @@ export class ConnectionManager
159
159
  this.state = PrinterState.CONNECTED;
160
160
  this.emit('state-change', PrinterState.CONNECTED);
161
161
  this.emit('connected', deviceId);
162
- this.logger.info('Connected successfully');
162
+ this.connLogger.info('Connected successfully');
163
163
 
164
164
  // Start heartbeat if enabled
165
165
  if (this.config.heartbeatEnabled) {
@@ -181,11 +181,14 @@ export class ConnectionManager
181
181
  `Connection failed after ${attempts} attempts`,
182
182
  error as Error
183
183
  );
184
- this.logger.error('Connection failed:', printError);
184
+ this.connLogger.error('Connection failed:', printError);
185
185
  this.emit('error', printError);
186
186
  throw printError;
187
187
  }
188
- this.logger.warn(`Connection attempt ${attempts}/${retries} failed, retrying...`, error);
188
+ this.connLogger.warn(
189
+ `Connection attempt ${attempts}/${retries} failed, retrying...`,
190
+ error
191
+ );
189
192
  await new Promise(resolve => setTimeout(resolve, 1000));
190
193
  }
191
194
  }
@@ -200,12 +203,12 @@ export class ConnectionManager
200
203
  this.isReconnecting = false;
201
204
 
202
205
  if (!this.deviceId) {
203
- this.logger.warn('Disconnect called but no device connected');
206
+ this.connLogger.warn('Disconnect called but no device connected');
204
207
  return;
205
208
  }
206
209
 
207
210
  const deviceId = this.deviceId;
208
- this.logger.info('Disconnecting from device:', deviceId);
211
+ this.connLogger.info('Disconnecting from device:', deviceId);
209
212
 
210
213
  try {
211
214
  await this.adapter.disconnect(deviceId);
@@ -213,14 +216,14 @@ export class ConnectionManager
213
216
  this.state = PrinterState.DISCONNECTED;
214
217
  this.emit('state-change', PrinterState.DISCONNECTED);
215
218
  this.emit('disconnected', deviceId);
216
- this.logger.info('Disconnected successfully');
219
+ this.connLogger.info('Disconnected successfully');
217
220
  } catch (error) {
218
221
  const printError = new BluetoothPrintError(
219
222
  ErrorCode.DEVICE_DISCONNECTED,
220
223
  'Disconnect failed',
221
224
  error as Error
222
225
  );
223
- this.logger.error('Disconnect failed:', printError);
226
+ this.connLogger.error('Disconnect failed:', printError);
224
227
  this.emit('error', printError);
225
228
  throw printError;
226
229
  }
@@ -236,7 +239,7 @@ export class ConnectionManager
236
239
  this.checkHeartbeat();
237
240
  }, this.config.heartbeatInterval);
238
241
 
239
- this.logger.debug('Heartbeat started with interval:', this.config.heartbeatInterval);
242
+ this.connLogger.debug('Heartbeat started with interval:', this.config.heartbeatInterval);
240
243
  }
241
244
 
242
245
  /**
@@ -246,7 +249,7 @@ export class ConnectionManager
246
249
  if (this.heartbeatTimer) {
247
250
  clearInterval(this.heartbeatTimer);
248
251
  this.heartbeatTimer = null;
249
- this.logger.debug('Heartbeat stopped');
252
+ this.connLogger.debug('Heartbeat stopped');
250
253
  }
251
254
  }
252
255
 
@@ -262,12 +265,12 @@ export class ConnectionManager
262
265
  const isConnected = this.isConnected();
263
266
 
264
267
  if (isConnected) {
265
- this.logger.debug('Heartbeat OK');
268
+ this.connLogger.debug('Heartbeat OK');
266
269
  } else {
267
270
  this.handleHeartbeatLost();
268
271
  }
269
272
  } catch (error) {
270
- this.logger.warn('Heartbeat check failed:', error);
273
+ this.connLogger.warn('Heartbeat check failed:', error);
271
274
  this.handleHeartbeatLost();
272
275
  }
273
276
  }
@@ -278,7 +281,7 @@ export class ConnectionManager
278
281
  private handleHeartbeatLost(): void {
279
282
  if (!this.deviceId) return;
280
283
 
281
- this.logger.warn('Heartbeat lost for device:', this.deviceId);
284
+ this.connLogger.warn('Heartbeat lost for device:', this.deviceId);
282
285
  this.emit('heartbeat-lost', this.deviceId);
283
286
  this.stopHeartbeat();
284
287
 
@@ -317,7 +320,7 @@ export class ConnectionManager
317
320
  const deviceId = this.deviceId;
318
321
 
319
322
  if (this.reconnectAttempts > this.config.maxReconnectAttempts) {
320
- this.logger.error('Max reconnect attempts reached');
323
+ this.connLogger.error('Max reconnect attempts reached');
321
324
  this.isReconnecting = false;
322
325
  this.emit('reconnect-failed', {
323
326
  deviceId,
@@ -330,7 +333,7 @@ export class ConnectionManager
330
333
  return;
331
334
  }
332
335
 
333
- this.logger.info(
336
+ this.connLogger.info(
334
337
  `Reconnect attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts}`
335
338
  );
336
339
  this.emit('reconnecting', {
@@ -345,7 +348,7 @@ export class ConnectionManager
345
348
  this.adapter
346
349
  .connect(deviceId)
347
350
  .then(() => {
348
- this.logger.info('Reconnected successfully');
351
+ this.connLogger.info('Reconnected successfully');
349
352
  this.isReconnecting = false;
350
353
  this.reconnectAttempts = 0;
351
354
  this.state = PrinterState.CONNECTED;
@@ -357,7 +360,7 @@ export class ConnectionManager
357
360
  }
358
361
  })
359
362
  .catch(error => {
360
- this.logger.warn(`Reconnect attempt ${this.reconnectAttempts} failed:`, error);
363
+ this.connLogger.warn(`Reconnect attempt ${this.reconnectAttempts} failed:`, error);
361
364
 
362
365
  this.reconnectTimer = setTimeout(() => {
363
366
  this.attemptReconnect();
@@ -434,7 +437,7 @@ export class ConnectionManager
434
437
  }
435
438
 
436
439
  if (this.isReconnecting) {
437
- this.logger.warn('Reconnect already in progress');
440
+ this.connLogger.warn('Reconnect already in progress');
438
441
  return;
439
442
  }
440
443
 
@@ -448,7 +451,7 @@ export class ConnectionManager
448
451
  this.clearReconnectTimer();
449
452
  this.isReconnecting = false;
450
453
  this.reconnectAttempts = 0;
451
- this.logger.info('Reconnect stopped');
454
+ this.connLogger.info('Reconnect stopped');
452
455
  }
453
456
 
454
457
  /**