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.
- package/CHANGELOG.md +40 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1678 -643
- package/dist/index.umd.js +1 -1
- package/dist/types/adapters/BaseAdapter.d.ts +4 -4
- package/dist/types/core/BluetoothPrinter.d.ts +16 -17
- package/dist/types/core/EventEmitter.d.ts +38 -1
- package/dist/types/services/CommandBuilder.d.ts +73 -0
- package/dist/types/services/ConnectionManager.d.ts +53 -0
- package/dist/types/services/PrintJobManager.d.ts +82 -0
- package/dist/types/services/interfaces/index.d.ts +161 -0
- package/dist/types/utils/encoding.d.ts +25 -1
- package/dist/types/utils/logger.d.ts +67 -10
- package/dist/types/utils/platform.d.ts +1 -1
- package/package.json +4 -2
- package/src/adapters/AdapterFactory.ts +4 -4
- package/src/adapters/AlipayAdapter.ts +76 -17
- package/src/adapters/BaiduAdapter.ts +74 -17
- package/src/adapters/BaseAdapter.ts +9 -15
- package/src/adapters/ByteDanceAdapter.ts +78 -17
- package/src/adapters/TaroAdapter.ts +69 -12
- package/src/core/BluetoothPrinter.ts +150 -158
- package/src/core/EventEmitter.ts +114 -8
- package/src/drivers/EscPos.ts +4 -4
- package/src/services/CommandBuilder.ts +135 -0
- package/src/services/ConnectionManager.ts +133 -0
- package/src/services/PrintJobManager.ts +300 -0
- package/src/services/interfaces/index.ts +188 -0
- package/src/types.ts +10 -10
- package/src/utils/encoding.ts +34 -4
- package/src/utils/image.ts +9 -7
- package/src/utils/logger.ts +143 -37
- package/src/utils/platform.ts +27 -13
|
@@ -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
|
|
30
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
77
|
-
info: (message: string, ...args:
|
|
78
|
-
warn: (message: string, ...args:
|
|
79
|
-
error: (message: string, ...args:
|
|
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():
|
|
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.
|
|
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
|
-
|
|
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:
|
|
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:
|
|
305
|
+
(c: AlipayBLECharacteristic) => c.properties.write || c.properties.writeWithoutResponse
|
|
247
306
|
);
|
|
248
307
|
|
|
249
308
|
if (writeChar) {
|