taro-bluetooth-print 2.7.0 → 2.8.3

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.
@@ -1,43 +1,51 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-argument */
2
+ /**
3
+ * @fileoverview DiscoveryService uses dynamic adapter loading for platform-specific Bluetooth operations.
4
+ * The platformAdapter field is typed as `BaseAdapter | undefined` because different adapters
5
+ * (TaroAdapter, WebBluetoothAdapter, ReactNativeAdapter, etc.) are loaded based on runtime platform detection.
6
+ */
7
+
1
8
  /**
2
9
  * DiscoveryService - Enhanced printer discovery service
3
10
  * Supports filtering, sorting, auto-retry, and device caching
4
11
  */
5
12
 
6
13
  import { EventEmitter } from '../core/EventEmitter';
14
+ import { IPrinterAdapter } from '../types';
7
15
 
8
16
  export interface DiscoveredDevice {
9
17
  id: string;
10
18
  name: string;
11
- deviceId: string; // 原始设备 ID
12
- rssi?: number; // 信号强度
13
- appearance?: number; // 设备类型外观
19
+ deviceId: string; // 原始设备 ID
20
+ rssi?: number; // 信号强度
21
+ appearance?: number; // 设备类型外观
14
22
  manufacturerData?: DataView; // 厂商数据
15
23
  serviceData?: Map<string, DataView>; // 服务数据
16
- txPowerLevel?: number; // 发射功率
17
- lastSeen: number; // 最后发现时间
18
- discoveredCount: number; // 被发现次数
24
+ txPowerLevel?: number; // 发射功率
25
+ lastSeen: number; // 最后发现时间
26
+ discoveredCount: number; // 被发现次数
19
27
  }
20
28
 
21
29
  export interface DiscoveryOptions {
22
30
  filters?: DeviceFilter[];
23
31
  sortBy?: SortOption[];
24
- timeout?: number; // 发现超时 (ms)
25
- maxDevices?: number; // 最大设备数
26
- enableCache?: boolean; // 启用设备缓存
27
- cacheExpiry?: number; // 缓存过期时间 (ms)
28
- autoRetry?: boolean; // 自动重试
29
- retryInterval?: number; // 重试间隔 (ms)
30
- maxRetries?: number; // 最大重试次数
32
+ timeout?: number; // 发现超时 (ms)
33
+ maxDevices?: number; // 最大设备数
34
+ enableCache?: boolean; // 启用设备缓存
35
+ cacheExpiry?: number; // 缓存过期时间 (ms)
36
+ autoRetry?: boolean; // 自动重试
37
+ retryInterval?: number; // 重试间隔 (ms)
38
+ maxRetries?: number; // 最大重试次数
31
39
  }
32
40
 
33
41
  export interface DeviceFilter {
34
- name?: string | string[]; // 设备名称 (支持通配符 * 或正则)
35
- namePattern?: RegExp; // 名称正则
36
- rssiThreshold?: number; // 最低信号强度
37
- manufacturerId?: number; // 厂商 ID
42
+ name?: string | string[]; // 设备名称 (支持通配符 * 或正则)
43
+ namePattern?: RegExp; // 名称正则
44
+ rssiThreshold?: number; // 最低信号强度
45
+ manufacturerId?: number; // 厂商 ID
38
46
  manufacturerDataPrefix?: Uint8Array; // 厂商数据前缀匹配
39
- serviceUUIDs?: string[]; // 必需的服务 UUID
40
- appearance?: number[]; // 设备外观类型
47
+ serviceUUIDs?: string[]; // 必需的服务 UUID
48
+ appearance?: number[]; // 设备外观类型
41
49
  }
42
50
 
43
51
  export type SortOption = 'rssi' | 'name' | 'lastSeen' | 'discoveredCount';
@@ -50,7 +58,7 @@ export interface DiscoveryEvents {
50
58
  'discovery-stop': void;
51
59
  'discovery-complete': DiscoveredDevice[];
52
60
  'discovery-error': Error;
53
- 'retry': { attempt: number; maxRetries: number };
61
+ retry: { attempt: number; maxRetries: number };
54
62
  }
55
63
 
56
64
  /**
@@ -134,7 +142,7 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
134
142
  private options: Required<DiscoveryOptions>;
135
143
  private isDiscovering: boolean = false;
136
144
  private stopTimeout: ReturnType<typeof setTimeout> | null = null;
137
- private platformAdapter?: any; // Platform-specific Bluetooth adapter
145
+ private platformAdapter?: IPrinterAdapter; // Platform-specific Bluetooth adapter
138
146
 
139
147
  constructor(options: DiscoveryOptions = {}) {
140
148
  super();
@@ -154,7 +162,7 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
154
162
  /**
155
163
  * 设置平台适配器
156
164
  */
157
- setPlatformAdapter(adapter: any): void {
165
+ setPlatformAdapter(adapter: IPrinterAdapter): void {
158
166
  this.platformAdapter = adapter;
159
167
  }
160
168
 
@@ -175,7 +183,8 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
175
183
  }
176
184
 
177
185
  try {
178
- const devices = await this.platformAdapter?.requestDevices?.() ?? [];
186
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
+ const devices = (await (this.platformAdapter as any)?.requestDevices?.()) ?? [];
179
188
  this.processDevices(devices);
180
189
  } catch (error) {
181
190
  this.emit('discovery-error', error as Error);
@@ -198,7 +207,7 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
198
207
  this.stopTimeout = null;
199
208
  }
200
209
 
201
- this.platformAdapter?.stopDiscovery?.();
210
+ void this.platformAdapter?.stopDiscovery?.();
202
211
 
203
212
  if (this.isDiscovering) {
204
213
  this.isDiscovering = false;
@@ -219,6 +228,7 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
219
228
  /**
220
229
  * 处理单个设备
221
230
  */
231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
222
232
  private processDevice(deviceInfo: any): void {
223
233
  const deviceId = deviceInfo.deviceId || deviceInfo.id;
224
234
  const now = Date.now();
@@ -401,8 +411,11 @@ export class DiscoveryService extends EventEmitter<DiscoveryEvents> {
401
411
  /**
402
412
  * 等待发现指定设备
403
413
  */
404
- async waitForDevice(predicate: (device: DiscoveredDevice) => boolean, timeout?: number): Promise<DiscoveredDevice | null> {
405
- return new Promise((resolve) => {
414
+ async waitForDevice(
415
+ predicate: (device: DiscoveredDevice) => boolean,
416
+ timeout?: number
417
+ ): Promise<DiscoveredDevice | null> {
418
+ return new Promise(resolve => {
406
419
  const checkTimeout = timeout ?? this.options.timeout;
407
420
 
408
421
  const checkDevice = (device: DiscoveredDevice) => {
@@ -0,0 +1,163 @@
1
+ /**
2
+ * SprtDriver (思普瑞特) Driver
3
+ *
4
+ * 思普瑞特热敏打印机兼容 ESC/POS 指令集
5
+ * 官网:https://www.sprt-printer.com/
6
+ *
7
+ * 思普瑞特特点:
8
+ * - 移动蓝牙打印机为主
9
+ * - 低功耗优化
10
+ * - 自动休眠/唤醒
11
+ * - 小票据打印优化
12
+ */
13
+
14
+ import { EscPos, type EscPosOptions } from './EscPos';
15
+
16
+ /**
17
+ * SprtDriver options (same as EscPosOptions)
18
+ */
19
+ export type SprtDriverOptions = EscPosOptions;
20
+
21
+ /**
22
+ * SprtDriver for Sprt (思普瑞特) thermal printers
23
+ *
24
+ * 思普瑞特打印机基于 ESC/POS 指令集,此驱动扩展了标准 EscPos
25
+ * 添加了思普瑞特特定的命令支持,特别是低功耗相关的功能
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { SprtDriver } from 'taro-bluetooth-print';
30
+ *
31
+ * const driver = new SprtDriver();
32
+ * let commands = driver.init();
33
+ * commands = driver.text('Hello 思普瑞特!', 'GBK');
34
+ * commands = driver.cut();
35
+ * ```
36
+ */
37
+ export class SprtDriver extends EscPos {
38
+ /**
39
+ * 思普瑞特特定: 进入低功耗/休眠模式
40
+ * @returns Array of command buffers
41
+ */
42
+ sleep(): Uint8Array[] {
43
+ // ESC = (0x1B 0x3D 0x01) - 设置外设
44
+ return [new Uint8Array([0x1b, 0x3d, 0x01])];
45
+ }
46
+
47
+ /**
48
+ * 思普瑞特特定: 唤醒打印机
49
+ * 发送空字符或特定序列唤醒休眠中的打印机
50
+ * @returns Array of command buffers
51
+ */
52
+ wakeUp(): Uint8Array[] {
53
+ // 发送空字符唤醒
54
+ return [new Uint8Array([0x00])];
55
+ }
56
+
57
+ /**
58
+ * 思普瑞特特定: 深度唤醒
59
+ * 使用完整的初始化序列唤醒打印机
60
+ * @returns Array of command buffers
61
+ */
62
+ wakeUpDeep(): Uint8Array[] {
63
+ // 发送多次空字符确保唤醒
64
+ const commands: Uint8Array[] = [];
65
+ for (let i = 0; i < 5; i++) {
66
+ commands.push(new Uint8Array([0x00]));
67
+ }
68
+ // 发送初始化命令
69
+ commands.push(new Uint8Array([0x1b, 0x40])); // ESC @
70
+ return commands;
71
+ }
72
+
73
+ /**
74
+ * 思普瑞特特定: 打开钱箱
75
+ * @param pin 钱箱引脚 (0 或 1, 默认 0)
76
+ * @returns Array of command buffers
77
+ */
78
+ openCashDrawer(pin = 0): Uint8Array[] {
79
+ // ESC p m t1 t2
80
+ // m = 0 or 1 (pin)
81
+ // t1 = 50 (on time)
82
+ // t2 = 200 (off time)
83
+ return [new Uint8Array([0x1b, 0x70, pin, 50, 200])];
84
+ }
85
+
86
+ /**
87
+ * 思普瑞特特定: 发送声响警报
88
+ * @param times 次数 (1-9)
89
+ * @param duration 持续时间 (ms)
90
+ * @returns Array of command buffers
91
+ */
92
+ beep(times = 3, duration = 50): Uint8Array[] {
93
+ // ESC B n t
94
+ return [new Uint8Array([0x1b, 0x42, times, duration])];
95
+ }
96
+
97
+ /**
98
+ * 思普瑞特特定: 打印自检页
99
+ * @returns Array of command buffers
100
+ */
101
+ selfTest(): Uint8Array[] {
102
+ // ESC i (0x1B 0x69) - 自检并返回状态
103
+ return [new Uint8Array([0x1b, 0x69])];
104
+ }
105
+
106
+ /**
107
+ * 思普瑞特特定: 获取打印机状态
108
+ * @returns Array of command buffers
109
+ */
110
+ getStatus(): Uint8Array[] {
111
+ // DLE EOT n (n = 1-4 获取不同状态)
112
+ // 状态 1: 打印机状态
113
+ // 状态 2: 脱机状态
114
+ // 状态 3: 错误状态
115
+ // 状态 4: 纸张状态
116
+ const buffers: Uint8Array[] = [];
117
+ for (let i = 1; i <= 4; i++) {
118
+ buffers.push(new Uint8Array([0x10, 0x04, i]));
119
+ }
120
+ return buffers;
121
+ }
122
+
123
+ /**
124
+ * 思普瑞特特定: 设置字符代码页
125
+ * @param codePage 代码页编号 (0-255)
126
+ * @returns Array of command buffers
127
+ */
128
+ setCodePage(codePage: number): Uint8Array[] {
129
+ // ESC t n
130
+ return [new Uint8Array([0x1b, 0x74, codePage])];
131
+ }
132
+
133
+ /**
134
+ * 思普瑞特特定: 设置左边界
135
+ * @param n 左边界字符数
136
+ * @returns Array of command buffers
137
+ */
138
+ setLeftMargin(n: number): Uint8Array[] {
139
+ // ESC l n
140
+ return [new Uint8Array([0x1b, 0x6c, n])];
141
+ }
142
+
143
+ /**
144
+ * 思普瑞特特定: 设置打印区域宽度
145
+ * @param n 宽度 (字符数)
146
+ * @returns Array of command buffers
147
+ */
148
+ setPrintWidth(n: number): Uint8Array[] {
149
+ // ESC W n
150
+ return [new Uint8Array([0x1b, 0x57, n])];
151
+ }
152
+
153
+ /**
154
+ * 思普瑞特特定: 使能/禁止自动休眠
155
+ * @param enable true=使能自动休眠, false=禁止自动休眠
156
+ * @returns Array of command buffers
157
+ */
158
+ setAutoSleep(enable: boolean): Uint8Array[] {
159
+ // ESC = n (设置外设)
160
+ // n = 0x01 使能, 0x00 禁止
161
+ return [new Uint8Array([0x1b, 0x3d, enable ? 0x01 : 0x00])];
162
+ }
163
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Xprinter (芯烨) Driver
3
+ *
4
+ * 芯烨热敏打印机兼容 ESC/POS 指令集
5
+ * 官网:http://www.xprinter.net/
6
+ *
7
+ * 芯烨特点:
8
+ * - 兼容标准 ESC/POS
9
+ * - 支持钱箱驱动
10
+ * - 支持状态自动检测
11
+ * - 部分型号有特殊初始化序列
12
+ */
13
+
14
+ import { EscPos, type EscPosOptions } from './EscPos';
15
+
16
+ /**
17
+ * Xprinter options (same as EscPosOptions)
18
+ */
19
+ export type XprinterOptions = EscPosOptions;
20
+
21
+ /**
22
+ * XprinterDriver for Xprinter (芯烨) thermal printers
23
+ *
24
+ * 芯烨打印机基于 ESC/POS 指令集,此驱动扩展了标准 EscPos
25
+ * 添加了芯烨特定的命令支持
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { XprinterDriver } from 'taro-bluetooth-print';
30
+ *
31
+ * const driver = new XprinterDriver();
32
+ * let commands = driver.init();
33
+ * commands = driver.text('Hello 芯烨!', 'GBK');
34
+ * commands = driver.cut();
35
+ * ```
36
+ */
37
+ export class XprinterDriver extends EscPos {
38
+ /**
39
+ * 芯烨打印机特定: 增强初始化
40
+ * 添加芯烨特定的初始化序列
41
+ *
42
+ * @returns Array of command buffers
43
+ */
44
+ init(): Uint8Array[] {
45
+ const commands = super.init();
46
+ // 添加芯烨特定初始化
47
+ // ESC @ (0x1B 0x40) - 初始化打印机已在父类实现
48
+ // 这里可以添加芯烨特定的初始化命令
49
+ return commands;
50
+ }
51
+
52
+ /**
53
+ * 芯烨打印机特定: 打开钱箱
54
+ * @param pin 钱箱引脚 (0 或 1, 默认 0)
55
+ * @returns Array of command buffers
56
+ */
57
+ openCashDrawer(pin = 0): Uint8Array[] {
58
+ // ESC p m t1 t2
59
+ // m = 0 or 1 (pin)
60
+ // t1 = 50 (on time)
61
+ // t2 = 200 (off time)
62
+ return [new Uint8Array([0x1b, 0x70, pin, 50, 200])];
63
+ }
64
+
65
+ /**
66
+ * 芯烨打印机特定: 发送声响警报
67
+ * @param times 次数 (1-9)
68
+ * @param duration 持续时间 (ms)
69
+ * @returns Array of command buffers
70
+ */
71
+ beep(times = 3, duration = 50): Uint8Array[] {
72
+ // ESC B n t
73
+ return [new Uint8Array([0x1b, 0x42, times, duration])];
74
+ }
75
+
76
+ /**
77
+ * 芯烨打印机特定: 打印自检页
78
+ * @returns Array of command buffers
79
+ */
80
+ selfTest(): Uint8Array[] {
81
+ // ESC i (0x1B 0x69) - 自检并返回状态
82
+ return [new Uint8Array([0x1b, 0x69])];
83
+ }
84
+
85
+ /**
86
+ * 芯烨打印机特定: 获取打印机状态
87
+ * 返回打印机状态字节
88
+ * @returns Array of command buffers
89
+ */
90
+ getStatus(): Uint8Array[] {
91
+ // ESC i (0x1B 0x69) - 自检并返回状态
92
+ return [new Uint8Array([0x1b, 0x69])];
93
+ }
94
+
95
+ /**
96
+ * 芯烨打印机特定: 获取详细状态
97
+ * 使用 DLE EOT 命令获取不同类型的状态
98
+ * @returns Array of command buffers (4 status queries)
99
+ */
100
+ getDetailedStatus(): Uint8Array[] {
101
+ // DLE EOT n (n = 1-4 获取不同状态)
102
+ // 状态 1: 打印机状态
103
+ // 状态 2: 脱机状态
104
+ // 状态 3: 错误状态
105
+ // 状态 4: 纸张状态
106
+ const buffers: Uint8Array[] = [];
107
+ for (let i = 1; i <= 4; i++) {
108
+ buffers.push(new Uint8Array([0x10, 0x04, i]));
109
+ }
110
+ return buffers;
111
+ }
112
+
113
+ /**
114
+ * 芯烨打印机特定: 设置字符代码页
115
+ * @param codePage 代码页编号 (0-255)
116
+ * @returns Array of command buffers
117
+ */
118
+ setCodePage(codePage: number): Uint8Array[] {
119
+ // ESC t n
120
+ return [new Uint8Array([0x1b, 0x74, codePage])];
121
+ }
122
+
123
+ /**
124
+ * 芯烨打印机特定: 设置左边界
125
+ * @param n 左边界字符数
126
+ * @returns Array of command buffers
127
+ */
128
+ setLeftMargin(n: number): Uint8Array[] {
129
+ // ESC l n
130
+ return [new Uint8Array([0x1b, 0x6c, n])];
131
+ }
132
+
133
+ /**
134
+ * 芯烨打印机特定: 设置打印区域宽度
135
+ * @param n 宽度 (字符数)
136
+ * @returns Array of command buffers
137
+ */
138
+ setPrintWidth(n: number): Uint8Array[] {
139
+ // ESC W n
140
+ return [new Uint8Array([0x1b, 0x57, n])];
141
+ }
142
+
143
+ /**
144
+ * 芯烨打印机特定: 进纸并切割
145
+ * @param lines 进纸行数
146
+ * @returns Array of command buffers
147
+ */
148
+ feedAndCut(lines: number): Uint8Array[] {
149
+ // 先进纸
150
+ const feedCmd = new Uint8Array([0x1b, 0x64, lines]); // ESC d n
151
+ // 再切割
152
+ const cutCmd = new Uint8Array([0x1d, 0x56, 0x00]); // GS V 0
153
+ return [feedCmd, cutCmd];
154
+ }
155
+ }
@@ -7,6 +7,10 @@ export { EscPos, type EscPosOptions } from './EscPos';
7
7
 
8
8
  export { GPrinterDriver, type GPrinterOptions } from './GPrinterDriver';
9
9
 
10
+ export { XprinterDriver, type XprinterOptions } from './XprinterDriver';
11
+
12
+ export { SprtDriver, type SprtDriverOptions } from './SprtDriver';
13
+
10
14
  export {
11
15
  TsplDriver,
12
16
  type LabelSize,