taro-bluetooth-print 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ import { IAdapterOptions, IQrOptions, PrinterState, IPrinterAdapter } from '../../types';
2
+
3
+ /**
4
+ * Connection Manager Interface
5
+ *
6
+ * Manages Bluetooth device connections
7
+ */
8
+ export interface IConnectionManager {
9
+ /**
10
+ * Connects to a Bluetooth device
11
+ *
12
+ * @param deviceId - Bluetooth device ID
13
+ * @returns Promise<void>
14
+ */
15
+ connect(deviceId: string): Promise<void>;
16
+ /**
17
+ * Disconnects from the current device
18
+ *
19
+ * @returns Promise<void>
20
+ */
21
+ disconnect(): Promise<void>;
22
+ /**
23
+ * Checks if a device is connected
24
+ *
25
+ * @returns boolean - True if connected, false otherwise
26
+ */
27
+ isConnected(): boolean;
28
+ /**
29
+ * Gets the current device ID
30
+ *
31
+ * @returns string | null - Device ID or null if not connected
32
+ */
33
+ getDeviceId(): string | null;
34
+ /**
35
+ * Gets the current connection state
36
+ *
37
+ * @returns PrinterState - Current state
38
+ */
39
+ getState(): PrinterState;
40
+ /**
41
+ * Gets the printer adapter instance
42
+ *
43
+ * @returns IPrinterAdapter - Printer adapter
44
+ */
45
+ getAdapter(): IPrinterAdapter;
46
+ }
47
+ /**
48
+ * Print Job Manager Interface
49
+ *
50
+ * Manages print jobs, including pause/resume/cancel functionality
51
+ */
52
+ export interface IPrintJobManager {
53
+ /**
54
+ * Starts a print job
55
+ *
56
+ * @param buffer - Print data buffer
57
+ * @returns Promise<void>
58
+ */
59
+ start(buffer: Uint8Array): Promise<void>;
60
+ /**
61
+ * Pauses the current print job
62
+ */
63
+ pause(): void;
64
+ /**
65
+ * Resumes a paused print job
66
+ *
67
+ * @returns Promise<void>
68
+ */
69
+ resume(): Promise<void>;
70
+ /**
71
+ * Cancels the current print job
72
+ */
73
+ cancel(): void;
74
+ /**
75
+ * Gets the number of bytes remaining to print
76
+ *
77
+ * @returns number - Bytes remaining
78
+ */
79
+ remaining(): number;
80
+ /**
81
+ * Checks if the print job is paused
82
+ *
83
+ * @returns boolean - True if paused, false otherwise
84
+ */
85
+ isPaused(): boolean;
86
+ /**
87
+ * Checks if a print job is in progress
88
+ *
89
+ * @returns boolean - True if in progress, false otherwise
90
+ */
91
+ isInProgress(): boolean;
92
+ /**
93
+ * Sets adapter options for write operations
94
+ *
95
+ * @param options - Adapter options
96
+ */
97
+ setOptions(options: IAdapterOptions): void;
98
+ }
99
+ /**
100
+ * Command Builder Interface
101
+ *
102
+ * Builds print commands using the printer driver
103
+ */
104
+ export interface ICommandBuilder {
105
+ /**
106
+ * Adds text to the print queue
107
+ *
108
+ * @param content - Text content
109
+ * @param encoding - Text encoding
110
+ * @returns this - For method chaining
111
+ */
112
+ text(content: string, encoding?: string): this;
113
+ /**
114
+ * Adds line feeds to the print queue
115
+ *
116
+ * @param lines - Number of lines to feed
117
+ * @returns this - For method chaining
118
+ */
119
+ feed(lines?: number): this;
120
+ /**
121
+ * Adds a paper cut command to the print queue
122
+ *
123
+ * @returns this - For method chaining
124
+ */
125
+ cut(): this;
126
+ /**
127
+ * Adds an image to the print queue
128
+ *
129
+ * @param data - Image data as Uint8Array
130
+ * @param width - Image width
131
+ * @param height - Image height
132
+ * @returns this - For method chaining
133
+ */
134
+ image(data: Uint8Array, width: number, height: number): this;
135
+ /**
136
+ * Adds a QR code to the print queue
137
+ *
138
+ * @param content - QR code content
139
+ * @param options - QR code options
140
+ * @returns this - For method chaining
141
+ */
142
+ qr(content: string, options?: IQrOptions): this;
143
+ /**
144
+ * Clears the print queue
145
+ *
146
+ * @returns this - For method chaining
147
+ */
148
+ clear(): this;
149
+ /**
150
+ * Gets the current buffer
151
+ *
152
+ * @returns Uint8Array - Current print buffer
153
+ */
154
+ getBuffer(): Uint8Array;
155
+ /**
156
+ * Gets the total number of bytes in the buffer
157
+ *
158
+ * @returns number - Total bytes
159
+ */
160
+ getTotalBytes(): number;
161
+ }
@@ -2,6 +2,13 @@
2
2
  * Text encoding utilities
3
3
  * Handles conversion between strings and byte arrays with various encodings
4
4
  */
5
+ /**
6
+ * Encoding configuration options
7
+ */
8
+ export interface EncodingConfig {
9
+ /** Whether to show warnings for unsupported encodings */
10
+ showWarnings?: boolean;
11
+ }
5
12
  /**
6
13
  * Text encoding utility class
7
14
  *
@@ -10,6 +17,9 @@
10
17
  *
11
18
  * @example
12
19
  * ```typescript
20
+ * // Configure encoding to disable warnings
21
+ * Encoding.configure({ showWarnings: false });
22
+ *
13
23
  * const bytes = Encoding.encode('Hello World', 'UTF-8');
14
24
  * const gbkBytes = Encoding.encode('你好世界', 'GBK');
15
25
  * ```
@@ -17,6 +27,20 @@
17
27
  export declare class Encoding {
18
28
  private static utf8Encoder;
19
29
  private static warningShown;
30
+ private static config;
31
+ /**
32
+ * Configures the encoding utility
33
+ *
34
+ * @param config - Configuration options
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * Encoding.configure({
39
+ * showWarnings: false
40
+ * });
41
+ * ```
42
+ */
43
+ static configure(config: Partial<EncodingConfig>): void;
20
44
  /**
21
45
  * Encodes a string to a Uint8Array using the specified encoding
22
46
  *
@@ -27,7 +51,7 @@ export declare class Encoding {
27
51
  * @remarks
28
52
  * Note: Native TextEncoder only supports UTF-8.
29
53
  * For GBK encoding, a third-party library or polyfill is recommended.
30
- * Currently falls back to UTF-8 with a warning.
54
+ * Currently falls back to UTF-8 with a warning (configurable).
31
55
  *
32
56
  * @example
33
57
  * ```typescript
@@ -1,6 +1,23 @@
1
1
  /**
2
2
  * Logging utilities for debugging and monitoring
3
3
  */
4
+ /**
5
+ * Log entry structure
6
+ */
7
+ export interface LogEntry {
8
+ /** Log level */
9
+ level: LogLevel;
10
+ /** Log message */
11
+ message: string;
12
+ /** Additional arguments */
13
+ args: unknown[];
14
+ /** Timestamp */
15
+ timestamp: Date;
16
+ /** Scope name (if any) */
17
+ scope?: string;
18
+ /** Formatted log string */
19
+ formatted: string;
20
+ }
4
21
  /**
5
22
  * Log levels in order of severity
6
23
  */
@@ -11,6 +28,21 @@ export declare enum LogLevel {
11
28
  ERROR = 3,
12
29
  NONE = 4
13
30
  }
31
+ /**
32
+ * Custom log handler function type
33
+ */
34
+ export type LogHandler = (entry: LogEntry) => void;
35
+ /**
36
+ * Logger configuration options
37
+ */
38
+ export interface LoggerConfig {
39
+ /** Minimum log level to output */
40
+ level: LogLevel;
41
+ /** Global prefix for all log messages */
42
+ prefix: string;
43
+ /** Custom log handler function */
44
+ handler?: LogHandler;
45
+ }
14
46
  /**
15
47
  * Logger class for consistent logging across the library
16
48
  *
@@ -19,6 +51,14 @@ export declare enum LogLevel {
19
51
  * // Enable debug logging
20
52
  * Logger.setLevel(LogLevel.DEBUG);
21
53
  *
54
+ * // Configure custom log handler
55
+ * Logger.configure({
56
+ * handler: (entry) => {
57
+ * // Send logs to a custom logging service
58
+ * console.log(entry.formatted);
59
+ * }
60
+ * });
61
+ *
22
62
  * Logger.debug('Connecting to device', deviceId);
23
63
  * Logger.info('Print job started');
24
64
  * Logger.warn('Retry attempt', { attempt: 2, maxRetries: 3 });
@@ -26,8 +66,13 @@ export declare enum LogLevel {
26
66
  * ```
27
67
  */
28
68
  export declare class Logger {
29
- private static level;
30
- private static prefix;
69
+ private static config;
70
+ /**
71
+ * Configures the logger
72
+ *
73
+ * @param config - Configuration options
74
+ */
75
+ static configure(config: Partial<LoggerConfig>): void;
31
76
  /**
32
77
  * Sets the global log level
33
78
  *
@@ -38,34 +83,46 @@ export declare class Logger {
38
83
  * Gets the current log level
39
84
  */
40
85
  static getLevel(): LogLevel;
86
+ /**
87
+ * Formats the log prefix
88
+ */
89
+ private static formatPrefix;
90
+ /**
91
+ * Formats a complete log message for custom handlers
92
+ */
93
+ private static formatMessage;
94
+ /**
95
+ * Logs a message with the specified level
96
+ */
97
+ private static log;
41
98
  /**
42
99
  * Logs a debug message (only in DEBUG level)
43
100
  *
44
101
  * @param message - Message to log
45
102
  * @param args - Additional arguments to log
46
103
  */
47
- static debug(message: string, ...args: any[]): void;
104
+ static debug(message: string, ...args: unknown[]): void;
48
105
  /**
49
106
  * Logs an info message (DEBUG and INFO levels)
50
107
  *
51
108
  * @param message - Message to log
52
109
  * @param args - Additional arguments to log
53
110
  */
54
- static info(message: string, ...args: any[]): void;
111
+ static info(message: string, ...args: unknown[]): void;
55
112
  /**
56
113
  * Logs a warning message (DEBUG, INFO, and WARN levels)
57
114
  *
58
115
  * @param message - Message to log
59
116
  * @param args - Additional arguments to log
60
117
  */
61
- static warn(message: string, ...args: any[]): void;
118
+ static warn(message: string, ...args: unknown[]): void;
62
119
  /**
63
120
  * Logs an error message (all levels except NONE)
64
121
  *
65
122
  * @param message - Message to log
66
123
  * @param args - Additional arguments to log
67
124
  */
68
- static error(message: string, ...args: any[]): void;
125
+ static error(message: string, ...args: unknown[]): void;
69
126
  /**
70
127
  * Creates a scoped logger with a specific prefix
71
128
  *
@@ -73,9 +130,9 @@ export declare class Logger {
73
130
  * @returns Scoped logger instance
74
131
  */
75
132
  static scope(scope: string): {
76
- debug: (message: string, ...args: any[]) => void;
77
- info: (message: string, ...args: any[]) => void;
78
- warn: (message: string, ...args: any[]) => void;
79
- error: (message: string, ...args: any[]) => void;
133
+ debug: (message: string, ...args: unknown[]) => void;
134
+ info: (message: string, ...args: unknown[]) => void;
135
+ warn: (message: string, ...args: unknown[]) => void;
136
+ error: (message: string, ...args: unknown[]) => void;
80
137
  };
81
138
  }
@@ -31,7 +31,7 @@ export declare function detectPlatform(): PlatformType;
31
31
  *
32
32
  * @returns The platform-specific global object or null if unknown
33
33
  */
34
- export declare function getPlatformGlobal(): any;
34
+ export declare function getPlatformGlobal(): unknown;
35
35
  /**
36
36
  * Checks if the current platform is supported
37
37
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taro-bluetooth-print",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Taro 蓝牙打印库 v2.1 - 轻量级、高性能、跨平台支持微信、支付宝、百度、字节跳动小程序",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
@@ -50,7 +50,9 @@
50
50
  "author": "Agions",
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
- "@tarojs/taro": "^3.6.0"
53
+ "@tarojs/taro": "^3.6.0",
54
+ "reflect-metadata": "^0.2.2",
55
+ "typedi": "^0.10.0"
54
56
  },
55
57
  "devDependencies": {
56
58
  "@types/jest": "^29.5.11",
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Adapter Factory
3
- *
3
+ *
4
4
  * Creates and returns the appropriate adapter based on the detected platform
5
5
  */
6
6
 
@@ -18,13 +18,13 @@ import { BluetoothPrintError, ErrorCode } from '@/errors/BluetoothError';
18
18
  export class AdapterFactory {
19
19
  /**
20
20
  * Creates an adapter instance based on the detected platform
21
- *
21
+ *
22
22
  * @returns An instance of the appropriate adapter for the current platform
23
23
  * @throws BluetoothPrintError if the platform is not supported
24
24
  */
25
25
  static create(): IPrinterAdapter {
26
26
  const platform = detectPlatform();
27
-
27
+
28
28
  switch (platform) {
29
29
  case PlatformType.WECHAT:
30
30
  return new TaroAdapter();
@@ -44,7 +44,7 @@ export class AdapterFactory {
44
44
 
45
45
  /**
46
46
  * Creates an adapter instance for a specific platform
47
- *
47
+ *
48
48
  * @param platform - The platform type to create an adapter for
49
49
  * @returns An instance of the appropriate adapter for the specified platform
50
50
  * @throws BluetoothPrintError if the platform is not supported
@@ -8,7 +8,66 @@ import { BaseAdapter } from './BaseAdapter';
8
8
  import { BluetoothPrintError, ErrorCode } from '@/errors/BluetoothError';
9
9
 
10
10
  // Declare Alipay global for TypeScript
11
- declare const my: any;
11
+ interface AlipayBLEService {
12
+ uuid: string;
13
+ }
14
+
15
+ interface AlipayBLECharacteristicProperties {
16
+ write?: boolean;
17
+ writeWithoutResponse?: boolean;
18
+ read?: boolean;
19
+ notify?: boolean;
20
+ indicate?: boolean;
21
+ }
22
+
23
+ interface AlipayBLECharacteristic {
24
+ uuid: string;
25
+ properties: AlipayBLECharacteristicProperties;
26
+ }
27
+
28
+ interface AlipayBLEDeviceServicesResult {
29
+ services: AlipayBLEService[];
30
+ }
31
+
32
+ interface AlipayBLEDeviceCharacteristicsResult {
33
+ characteristics: AlipayBLECharacteristic[];
34
+ }
35
+
36
+ interface AlipayBLEConnectionStateResult {
37
+ connected: boolean;
38
+ }
39
+
40
+ interface AlipayBLEConnectionOptions {
41
+ deviceId: string;
42
+ }
43
+
44
+ interface AlipayBLEWriteOptions {
45
+ deviceId: string;
46
+ serviceId: string;
47
+ characteristicId: string;
48
+ value: ArrayBuffer;
49
+ }
50
+
51
+ interface AlipayBLEConnectionStateChangeCallback {
52
+ (res: { deviceId: string; connected: boolean }): void;
53
+ }
54
+
55
+ interface AlipayGlobal {
56
+ createBLEConnection(options: AlipayBLEConnectionOptions): Promise<void>;
57
+ closeBLEConnection(options: AlipayBLEConnectionOptions): Promise<void>;
58
+ getBLEConnectionState(
59
+ options: AlipayBLEConnectionOptions
60
+ ): Promise<AlipayBLEConnectionStateResult>;
61
+ writeBLECharacteristicValue(options: AlipayBLEWriteOptions): Promise<void>;
62
+ getBLEDeviceServices(options: AlipayBLEConnectionOptions): Promise<AlipayBLEDeviceServicesResult>;
63
+ getBLEDeviceCharacteristics(options: {
64
+ deviceId: string;
65
+ serviceId: string;
66
+ }): Promise<AlipayBLEDeviceCharacteristicsResult>;
67
+ onBLEConnectionStateChange(callback: AlipayBLEConnectionStateChangeCallback): void;
68
+ }
69
+
70
+ declare const my: AlipayGlobal;
12
71
 
13
72
  /**
14
73
  * Alipay Bluetooth Low Energy adapter
@@ -22,7 +81,6 @@ declare const my: any;
22
81
  * ```
23
82
  */
24
83
  export class AlipayAdapter extends BaseAdapter {
25
-
26
84
  /**
27
85
  * Connects to a Bluetooth device and discovers services
28
86
  *
@@ -44,17 +102,21 @@ export class AlipayAdapter extends BaseAdapter {
44
102
 
45
103
  try {
46
104
  // Add connection timeout handling
105
+ let timeoutId: NodeJS.Timeout | undefined;
47
106
  const connectionPromise = my.createBLEConnection({
48
- deviceId
107
+ deviceId,
49
108
  });
50
-
109
+
51
110
  const timeoutPromise = new Promise((_, reject) => {
52
- setTimeout(() => {
111
+ timeoutId = setTimeout(() => {
53
112
  reject(new Error('Connection timeout after 10 seconds'));
54
113
  }, 10000);
55
114
  });
56
115
 
57
116
  await Promise.race([connectionPromise, timeoutPromise]);
117
+ if (timeoutId) {
118
+ clearTimeout(timeoutId); // Clear timeout after successful connection
119
+ }
58
120
  this.logger.info('BLE connection established');
59
121
 
60
122
  // Discover and cache services
@@ -64,7 +126,7 @@ export class AlipayAdapter extends BaseAdapter {
64
126
  this.logger.info('Device connected successfully');
65
127
 
66
128
  // Listen for connection state changes
67
- my.onBLEConnectionStateChange((res: any) => {
129
+ my.onBLEConnectionStateChange((res: { deviceId: string; connected: boolean }) => {
68
130
  if (res.deviceId === deviceId && !res.connected) {
69
131
  this.logger.warn('Device disconnected unexpectedly');
70
132
  this.updateState(PrinterState.DISCONNECTED);
@@ -74,7 +136,7 @@ export class AlipayAdapter extends BaseAdapter {
74
136
  } catch (error) {
75
137
  this.updateState(PrinterState.DISCONNECTED);
76
138
  this.logger.error('Connection failed:', error);
77
-
139
+
78
140
  // Return more specific error codes based on error message
79
141
  const errorMessage = (error as Error).message || '';
80
142
  if (errorMessage.includes('timeout')) {
@@ -90,7 +152,7 @@ export class AlipayAdapter extends BaseAdapter {
90
152
  error as Error
91
153
  );
92
154
  }
93
-
155
+
94
156
  throw new BluetoothPrintError(
95
157
  ErrorCode.CONNECTION_FAILED,
96
158
  `Failed to connect to device ${deviceId}`,
@@ -111,7 +173,7 @@ export class AlipayAdapter extends BaseAdapter {
111
173
 
112
174
  try {
113
175
  await my.closeBLEConnection({
114
- deviceId
176
+ deviceId,
115
177
  });
116
178
  this.cleanupDevice(deviceId);
117
179
  this.updateState(PrinterState.DISCONNECTED);
@@ -141,14 +203,11 @@ export class AlipayAdapter extends BaseAdapter {
141
203
  // Validate device is still connected
142
204
  try {
143
205
  const state = await my.getBLEConnectionState({
144
- deviceId
206
+ deviceId,
145
207
  });
146
208
  if (!state.connected) {
147
209
  this.cleanupDevice(deviceId);
148
- throw new BluetoothPrintError(
149
- ErrorCode.DEVICE_DISCONNECTED,
150
- 'Device disconnected'
151
- );
210
+ throw new BluetoothPrintError(ErrorCode.DEVICE_DISCONNECTED, 'Device disconnected');
152
211
  }
153
212
  } catch (error) {
154
213
  this.cleanupDevice(deviceId);
@@ -185,7 +244,7 @@ export class AlipayAdapter extends BaseAdapter {
185
244
  characteristicId: serviceInfo.characteristicId,
186
245
  value: chunk.buffer,
187
246
  });
188
-
247
+
189
248
  const timeoutPromise = new Promise((_, reject) => {
190
249
  setTimeout(() => {
191
250
  reject(new Error('Write timeout after 5 seconds'));
@@ -233,7 +292,7 @@ export class AlipayAdapter extends BaseAdapter {
233
292
 
234
293
  try {
235
294
  const services = await my.getBLEDeviceServices({
236
- deviceId
295
+ deviceId,
237
296
  });
238
297
 
239
298
  for (const service of services.services) {
@@ -243,7 +302,7 @@ export class AlipayAdapter extends BaseAdapter {
243
302
  });
244
303
 
245
304
  const writeChar = chars.characteristics.find(
246
- (c: any) => c.properties.write || c.properties.writeWithoutResponse
305
+ (c: AlipayBLECharacteristic) => c.properties.write || c.properties.writeWithoutResponse
247
306
  );
248
307
 
249
308
  if (writeChar) {