taro-bluetooth-print 2.2.0 → 2.3.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/CHANGELOG.md +38 -0
- package/README.md +128 -22
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -6995
- package/dist/index.umd.js +1 -1
- package/dist/types/adapters/AdapterFactory.d.ts +0 -1
- package/dist/types/adapters/AlipayAdapter.d.ts +6 -34
- package/dist/types/adapters/BaiduAdapter.d.ts +6 -34
- package/dist/types/adapters/BaseAdapter.d.ts +112 -1
- package/dist/types/adapters/ByteDanceAdapter.d.ts +6 -34
- package/dist/types/adapters/TaroAdapter.d.ts +6 -34
- package/dist/types/adapters/WebBluetoothAdapter.d.ts +0 -1
- package/dist/types/config/PrinterConfig.d.ts +0 -1
- package/dist/types/core/BluetoothPrinter.d.ts +0 -1
- package/dist/types/drivers/EscPos.d.ts +0 -1
- package/dist/types/drivers/TsplDriver.d.ts +251 -0
- package/dist/types/encoding/gbk-data.d.ts +12 -0
- package/dist/types/encoding/gbk-table.d.ts +5 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/plugins/PluginManager.d.ts +87 -0
- package/dist/types/plugins/builtin/LoggingPlugin.d.ts +14 -0
- package/dist/types/plugins/builtin/RetryPlugin.d.ts +18 -0
- package/dist/types/plugins/index.d.ts +7 -0
- package/dist/types/plugins/types.d.ts +97 -0
- package/dist/types/services/CommandBuilder.d.ts +6 -1
- package/dist/types/services/ConnectionManager.d.ts +0 -1
- package/dist/types/services/PrintJobManager.d.ts +6 -2
- package/dist/types/services/interfaces/index.d.ts +0 -1
- package/dist/types/template/TemplateEngine.d.ts +0 -1
- package/package.json +16 -18
- package/src/adapters/AlipayAdapter.ts +8 -314
- package/src/adapters/BaiduAdapter.ts +8 -312
- package/src/adapters/BaseAdapter.ts +366 -0
- package/src/adapters/ByteDanceAdapter.ts +8 -316
- package/src/adapters/TaroAdapter.ts +8 -367
- package/src/core/EventEmitter.ts +9 -6
- package/src/drivers/TsplDriver.ts +417 -0
- package/src/encoding/gbk-data.ts +1911 -0
- package/src/encoding/gbk-table.ts +22 -498
- package/src/index.ts +14 -0
- package/src/plugins/PluginManager.ts +193 -0
- package/src/plugins/builtin/LoggingPlugin.ts +97 -0
- package/src/plugins/builtin/RetryPlugin.ts +109 -0
- package/src/plugins/index.ts +10 -0
- package/src/plugins/types.ts +119 -0
- package/src/preview/PreviewRenderer.ts +7 -1
- package/src/queue/PrintQueue.ts +10 -6
- package/src/services/CommandBuilder.ts +30 -0
- package/src/services/PrintJobManager.ts +51 -35
|
@@ -3,73 +3,19 @@
|
|
|
3
3
|
* Implements the IPrinterAdapter interface for Taro framework
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { BaseAdapter } from './BaseAdapter';
|
|
8
|
-
import { BluetoothPrintError, ErrorCode } from '@/errors/BluetoothError';
|
|
6
|
+
import { MiniProgramAdapter, MiniProgramBLEApi } from './BaseAdapter';
|
|
9
7
|
|
|
10
8
|
// Declare Taro global for TypeScript
|
|
11
|
-
interface
|
|
12
|
-
uuid: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface TaroBLECharacteristicProperties {
|
|
16
|
-
write?: boolean;
|
|
17
|
-
writeWithoutResponse?: boolean;
|
|
18
|
-
read?: boolean;
|
|
19
|
-
notify?: boolean;
|
|
20
|
-
indicate?: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface TaroBLECharacteristic {
|
|
24
|
-
uuid: string;
|
|
25
|
-
properties: TaroBLECharacteristicProperties;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface TaroBLEDeviceServicesResult {
|
|
29
|
-
services: TaroBLEService[];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface TaroBLEDeviceCharacteristicsResult {
|
|
33
|
-
characteristics: TaroBLECharacteristic[];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface TaroBLEConnectionStateResult {
|
|
37
|
-
connected: boolean;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface TaroBLEConnectionOptions {
|
|
41
|
-
deviceId: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface TaroBLEWriteOptions {
|
|
45
|
-
deviceId: string;
|
|
46
|
-
serviceId: string;
|
|
47
|
-
characteristicId: string;
|
|
48
|
-
value: ArrayBuffer;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
interface TaroBLEConnectionStateChangeCallback {
|
|
52
|
-
(res: { deviceId: string; connected: boolean }): void;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface TaroGlobal {
|
|
56
|
-
createBLEConnection(options: TaroBLEConnectionOptions): Promise<void>;
|
|
57
|
-
closeBLEConnection(options: TaroBLEConnectionOptions): Promise<void>;
|
|
58
|
-
getBLEConnectionState(options: TaroBLEConnectionOptions): Promise<TaroBLEConnectionStateResult>;
|
|
59
|
-
writeBLECharacteristicValue(options: TaroBLEWriteOptions): Promise<void>;
|
|
60
|
-
getBLEDeviceServices(options: TaroBLEConnectionOptions): Promise<TaroBLEDeviceServicesResult>;
|
|
61
|
-
getBLEDeviceCharacteristics(options: {
|
|
62
|
-
deviceId: string;
|
|
63
|
-
serviceId: string;
|
|
64
|
-
}): Promise<TaroBLEDeviceCharacteristicsResult>;
|
|
65
|
-
onBLEConnectionStateChange(callback: TaroBLEConnectionStateChangeCallback): void;
|
|
66
|
-
}
|
|
9
|
+
interface TaroGlobal extends MiniProgramBLEApi {}
|
|
67
10
|
|
|
68
11
|
declare const Taro: TaroGlobal;
|
|
69
12
|
|
|
70
13
|
/**
|
|
71
14
|
* Taro Bluetooth Low Energy adapter
|
|
72
15
|
*
|
|
16
|
+
* Uses the Taro framework's BLE APIs (compatible with WeChat mini-program).
|
|
17
|
+
* All connection, write, and service discovery logic is inherited from MiniProgramAdapter.
|
|
18
|
+
*
|
|
73
19
|
* @example
|
|
74
20
|
* ```typescript
|
|
75
21
|
* const adapter = new TaroAdapter();
|
|
@@ -78,313 +24,8 @@ declare const Taro: TaroGlobal;
|
|
|
78
24
|
* await adapter.disconnect('device-id-123');
|
|
79
25
|
* ```
|
|
80
26
|
*/
|
|
81
|
-
export class TaroAdapter extends
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
*
|
|
85
|
-
* @param deviceId - Bluetooth device ID
|
|
86
|
-
* @throws {BluetoothPrintError} When connection fails
|
|
87
|
-
*/
|
|
88
|
-
async connect(deviceId: string): Promise<void> {
|
|
89
|
-
this.validateDeviceId(deviceId);
|
|
90
|
-
|
|
91
|
-
// 检查是否已连接
|
|
92
|
-
if (this.isDeviceConnected(deviceId)) {
|
|
93
|
-
this.logger.warn('Device already connected:', deviceId);
|
|
94
|
-
this.updateState(PrinterState.CONNECTED);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
this.updateState(PrinterState.CONNECTING);
|
|
99
|
-
this.logger.debug('Connecting to device:', deviceId);
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
// 添加连接超时处理
|
|
103
|
-
let timeoutId: NodeJS.Timeout | undefined;
|
|
104
|
-
const connectionPromise = Taro.createBLEConnection({ deviceId });
|
|
105
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
106
|
-
timeoutId = setTimeout(() => {
|
|
107
|
-
reject(new Error('Connection timeout after 10 seconds'));
|
|
108
|
-
}, 10000);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
await Promise.race([connectionPromise, timeoutPromise]);
|
|
112
|
-
if (timeoutId) {
|
|
113
|
-
clearTimeout(timeoutId); // Clear timeout after successful connection
|
|
114
|
-
}
|
|
115
|
-
this.logger.info('BLE connection established');
|
|
116
|
-
|
|
117
|
-
// Discover and cache services
|
|
118
|
-
await this.discoverServices(deviceId);
|
|
119
|
-
|
|
120
|
-
this.updateState(PrinterState.CONNECTED);
|
|
121
|
-
this.logger.info('Device connected successfully');
|
|
122
|
-
|
|
123
|
-
// Listen for connection state changes
|
|
124
|
-
Taro.onBLEConnectionStateChange((res: { deviceId: string; connected: boolean }) => {
|
|
125
|
-
if (res.deviceId === deviceId && !res.connected) {
|
|
126
|
-
this.logger.warn('Device disconnected unexpectedly');
|
|
127
|
-
this.updateState(PrinterState.DISCONNECTED);
|
|
128
|
-
this.cleanupDevice(deviceId);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
} catch (error) {
|
|
132
|
-
this.updateState(PrinterState.DISCONNECTED);
|
|
133
|
-
this.logger.error('Connection failed:', error);
|
|
134
|
-
|
|
135
|
-
// 根据错误类型返回更具体的错误代码
|
|
136
|
-
const errorMessage = (error as Error).message || '';
|
|
137
|
-
if (errorMessage.includes('timeout')) {
|
|
138
|
-
throw new BluetoothPrintError(
|
|
139
|
-
ErrorCode.CONNECTION_TIMEOUT,
|
|
140
|
-
`Connection to device ${deviceId} timed out`,
|
|
141
|
-
error as Error
|
|
142
|
-
);
|
|
143
|
-
} else if (errorMessage.includes('not found')) {
|
|
144
|
-
throw new BluetoothPrintError(
|
|
145
|
-
ErrorCode.DEVICE_NOT_FOUND,
|
|
146
|
-
`Device ${deviceId} not found`,
|
|
147
|
-
error as Error
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
throw new BluetoothPrintError(
|
|
152
|
-
ErrorCode.CONNECTION_FAILED,
|
|
153
|
-
`Failed to connect to device ${deviceId}`,
|
|
154
|
-
error as Error
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Disconnects from a Bluetooth device
|
|
161
|
-
*
|
|
162
|
-
* @param deviceId - Bluetooth device ID
|
|
163
|
-
*/
|
|
164
|
-
async disconnect(deviceId: string): Promise<void> {
|
|
165
|
-
this.validateDeviceId(deviceId);
|
|
166
|
-
this.updateState(PrinterState.DISCONNECTING);
|
|
167
|
-
this.logger.debug('Disconnecting from device:', deviceId);
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
await Taro.closeBLEConnection({ deviceId });
|
|
171
|
-
this.cleanupDevice(deviceId);
|
|
172
|
-
this.updateState(PrinterState.DISCONNECTED);
|
|
173
|
-
this.logger.info('Device disconnected successfully');
|
|
174
|
-
} catch (error) {
|
|
175
|
-
// Ignore error on disconnect, but log it
|
|
176
|
-
this.logger.warn('Disconnect error (ignored):', error);
|
|
177
|
-
this.cleanupDevice(deviceId);
|
|
178
|
-
this.updateState(PrinterState.DISCONNECTED);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Writes data to the Bluetooth device in chunks with retry logic
|
|
184
|
-
*
|
|
185
|
-
* @param deviceId - Bluetooth device ID
|
|
186
|
-
* @param buffer - Data to write as ArrayBuffer
|
|
187
|
-
* @param options - Write options (chunk size, delay, retries)
|
|
188
|
-
* @throws {BluetoothPrintError} When write fails after retries
|
|
189
|
-
*/
|
|
190
|
-
async write(deviceId: string, buffer: ArrayBuffer, options?: IAdapterOptions): Promise<void> {
|
|
191
|
-
this.validateDeviceId(deviceId);
|
|
192
|
-
this.validateBuffer(buffer);
|
|
193
|
-
const serviceInfo = this.getServiceInfo(deviceId);
|
|
194
|
-
const validatedOptions = this.validateOptions(options);
|
|
195
|
-
|
|
196
|
-
// 验证设备是否仍处于连接状态
|
|
197
|
-
try {
|
|
198
|
-
const state = await Taro.getBLEConnectionState({ deviceId });
|
|
199
|
-
if (!state.connected) {
|
|
200
|
-
this.cleanupDevice(deviceId);
|
|
201
|
-
throw new BluetoothPrintError(ErrorCode.DEVICE_DISCONNECTED, 'Device disconnected');
|
|
202
|
-
}
|
|
203
|
-
} catch (error) {
|
|
204
|
-
this.cleanupDevice(deviceId);
|
|
205
|
-
throw new BluetoothPrintError(
|
|
206
|
-
ErrorCode.DEVICE_DISCONNECTED,
|
|
207
|
-
'Device disconnected',
|
|
208
|
-
error as Error
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
let { chunkSize } = validatedOptions;
|
|
213
|
-
const { delay, retries } = validatedOptions;
|
|
214
|
-
const data = new Uint8Array(buffer);
|
|
215
|
-
let totalChunks = Math.ceil(data.length / chunkSize);
|
|
216
|
-
|
|
217
|
-
this.logger.debug(`Writing ${data.length} bytes in ${totalChunks} chunks`);
|
|
218
|
-
|
|
219
|
-
// 如果没有数据要写入,直接返回
|
|
220
|
-
if (data.length === 0) {
|
|
221
|
-
this.logger.warn('No data to write');
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// 网络状况监控变量
|
|
226
|
-
let successCount = 0;
|
|
227
|
-
let failureCount = 0;
|
|
228
|
-
let consecutiveFailures = 0;
|
|
229
|
-
const minChunkSize = 10; // 最小块大小
|
|
230
|
-
const maxChunkSize = 256; // 最大块大小
|
|
231
|
-
let baseDelay = delay; // 基础延迟
|
|
232
|
-
const maxDelay = 200; // 最大延迟
|
|
233
|
-
const connectionCheckInterval = 5; // 每5个块检查一次连接状态
|
|
234
|
-
|
|
235
|
-
for (let i = 0; i < data.length; i += chunkSize) {
|
|
236
|
-
// 定期检查连接状态
|
|
237
|
-
if (i > 0 && Math.floor(i / chunkSize) % connectionCheckInterval === 0) {
|
|
238
|
-
try {
|
|
239
|
-
const state = await Taro.getBLEConnectionState({ deviceId });
|
|
240
|
-
if (!state.connected) {
|
|
241
|
-
this.cleanupDevice(deviceId);
|
|
242
|
-
throw new BluetoothPrintError(ErrorCode.DEVICE_DISCONNECTED, 'Device disconnected');
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
this.cleanupDevice(deviceId);
|
|
246
|
-
throw new BluetoothPrintError(
|
|
247
|
-
ErrorCode.DEVICE_DISCONNECTED,
|
|
248
|
-
'Device disconnected',
|
|
249
|
-
error as Error
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const chunk = data.slice(i, i + chunkSize);
|
|
255
|
-
const chunkNum = Math.floor(i / chunkSize) + 1;
|
|
256
|
-
let attempt = 0;
|
|
257
|
-
let writeSuccess = false;
|
|
258
|
-
|
|
259
|
-
while (attempt <= retries) {
|
|
260
|
-
try {
|
|
261
|
-
// 根据块大小动态调整超时时间 (1秒基础时间 + 每字节5ms)
|
|
262
|
-
const timeoutMs = Math.max(1000, Math.min(10000, 1000 + chunk.length * 5));
|
|
263
|
-
|
|
264
|
-
// 添加写入超时处理
|
|
265
|
-
const writePromise = Taro.writeBLECharacteristicValue({
|
|
266
|
-
deviceId,
|
|
267
|
-
serviceId: serviceInfo.serviceId,
|
|
268
|
-
characteristicId: serviceInfo.characteristicId,
|
|
269
|
-
value: chunk.buffer,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
273
|
-
setTimeout(() => {
|
|
274
|
-
reject(new Error(`Write timeout after ${timeoutMs} milliseconds`));
|
|
275
|
-
}, timeoutMs);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
await Promise.race([writePromise, timeoutPromise]);
|
|
279
|
-
|
|
280
|
-
this.logger.debug(`Chunk ${chunkNum}/${totalChunks} written successfully`);
|
|
281
|
-
writeSuccess = true;
|
|
282
|
-
break; // Success
|
|
283
|
-
} catch (error) {
|
|
284
|
-
attempt++;
|
|
285
|
-
if (attempt > retries) {
|
|
286
|
-
this.logger.error(`Chunk ${chunkNum} failed after ${retries} retries`);
|
|
287
|
-
throw new BluetoothPrintError(
|
|
288
|
-
ErrorCode.WRITE_FAILED,
|
|
289
|
-
`Failed to write chunk ${chunkNum}/${totalChunks}`,
|
|
290
|
-
error as Error
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
this.logger.warn(`Chunk ${chunkNum} write failed, retry ${attempt}/${retries}`);
|
|
294
|
-
|
|
295
|
-
// 使用指数退避算法,重试间隔随重试次数增加而增加
|
|
296
|
-
const retryDelay = baseDelay * Math.pow(2, attempt - 1);
|
|
297
|
-
await new Promise(r => setTimeout(r, Math.min(retryDelay, maxDelay)));
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// 动态调整块大小和延迟
|
|
302
|
-
if (writeSuccess) {
|
|
303
|
-
successCount++;
|
|
304
|
-
consecutiveFailures = 0;
|
|
305
|
-
failureCount = Math.max(0, failureCount - 1);
|
|
306
|
-
|
|
307
|
-
// 网络状况改善,增加块大小,减少延迟
|
|
308
|
-
if (successCount % 3 === 0 && chunkSize < maxChunkSize) {
|
|
309
|
-
chunkSize = Math.min(maxChunkSize, chunkSize + 5);
|
|
310
|
-
baseDelay = Math.max(baseDelay / 1.2, validatedOptions.delay);
|
|
311
|
-
totalChunks = Math.ceil((data.length - i - chunkSize) / chunkSize) + chunkNum;
|
|
312
|
-
this.logger.debug(`Increased chunk size to ${chunkSize}, delay to ${baseDelay}`);
|
|
313
|
-
}
|
|
314
|
-
} else {
|
|
315
|
-
failureCount++;
|
|
316
|
-
consecutiveFailures++;
|
|
317
|
-
successCount = Math.max(0, successCount - 1);
|
|
318
|
-
|
|
319
|
-
// 网络状况恶化,减少块大小,增加延迟
|
|
320
|
-
if (consecutiveFailures >= 2 && chunkSize > minChunkSize) {
|
|
321
|
-
chunkSize = Math.max(minChunkSize, chunkSize - 5);
|
|
322
|
-
baseDelay = Math.min(baseDelay * 1.5, maxDelay);
|
|
323
|
-
totalChunks = Math.ceil((data.length - i - chunkSize) / chunkSize) + chunkNum;
|
|
324
|
-
this.logger.debug(`Decreased chunk size to ${chunkSize}, delay to ${baseDelay}`);
|
|
325
|
-
consecutiveFailures = 0;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Small delay to prevent congestion
|
|
330
|
-
if (i + chunkSize < data.length) {
|
|
331
|
-
await new Promise(r => setTimeout(r, baseDelay));
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
this.logger.info(`Successfully wrote ${data.length} bytes`);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Discovers services and characteristics for a device
|
|
340
|
-
* Caches the writeable characteristic for future writes
|
|
341
|
-
*
|
|
342
|
-
* @param deviceId - Bluetooth device ID
|
|
343
|
-
* @throws {BluetoothPrintError} When no writeable characteristic is found
|
|
344
|
-
*/
|
|
345
|
-
private async discoverServices(deviceId: string): Promise<void> {
|
|
346
|
-
this.logger.debug('Discovering services for device:', deviceId);
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
const services = await Taro.getBLEDeviceServices({ deviceId });
|
|
350
|
-
|
|
351
|
-
for (const service of services.services) {
|
|
352
|
-
const chars = await Taro.getBLEDeviceCharacteristics({
|
|
353
|
-
deviceId,
|
|
354
|
-
serviceId: service.uuid,
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
const writeChar = chars.characteristics.find(
|
|
358
|
-
(c: TaroBLECharacteristic) => c.properties.write || c.properties.writeWithoutResponse
|
|
359
|
-
);
|
|
360
|
-
|
|
361
|
-
if (writeChar) {
|
|
362
|
-
this.serviceCache.set(deviceId, {
|
|
363
|
-
serviceId: service.uuid,
|
|
364
|
-
characteristicId: writeChar.uuid,
|
|
365
|
-
});
|
|
366
|
-
this.logger.info('Found writeable characteristic:', {
|
|
367
|
-
service: service.uuid,
|
|
368
|
-
characteristic: writeChar.uuid,
|
|
369
|
-
});
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// No writeable characteristic found
|
|
375
|
-
throw new BluetoothPrintError(
|
|
376
|
-
ErrorCode.CHARACTERISTIC_NOT_FOUND,
|
|
377
|
-
'No writeable characteristic found. Make sure the device is a supported printer.'
|
|
378
|
-
);
|
|
379
|
-
} catch (error) {
|
|
380
|
-
if (error instanceof BluetoothPrintError) {
|
|
381
|
-
throw error;
|
|
382
|
-
}
|
|
383
|
-
throw new BluetoothPrintError(
|
|
384
|
-
ErrorCode.SERVICE_DISCOVERY_FAILED,
|
|
385
|
-
'Failed to discover device services',
|
|
386
|
-
error as Error
|
|
387
|
-
);
|
|
388
|
-
}
|
|
27
|
+
export class TaroAdapter extends MiniProgramAdapter {
|
|
28
|
+
protected getApi(): MiniProgramBLEApi {
|
|
29
|
+
return Taro;
|
|
389
30
|
}
|
|
390
31
|
}
|
package/src/core/EventEmitter.ts
CHANGED
|
@@ -222,22 +222,25 @@ export class EventEmitter<T> {
|
|
|
222
222
|
|
|
223
223
|
handlersCopy.forEach(handler => {
|
|
224
224
|
promises.push(
|
|
225
|
-
|
|
225
|
+
(async () => {
|
|
226
226
|
try {
|
|
227
227
|
// 根据事件类型决定是否传递数据
|
|
228
|
+
let result: unknown;
|
|
228
229
|
if (data === undefined || data === null) {
|
|
229
230
|
// @ts-expect-error - 类型安全由调用方保证
|
|
230
|
-
handler();
|
|
231
|
+
result = handler();
|
|
231
232
|
} else {
|
|
232
|
-
handler(data);
|
|
233
|
+
result = handler(data);
|
|
234
|
+
}
|
|
235
|
+
// 等待异步 handler 完成
|
|
236
|
+
if (result instanceof Promise) {
|
|
237
|
+
await result;
|
|
233
238
|
}
|
|
234
239
|
} catch (error) {
|
|
235
240
|
// 捕获并处理事件处理程序中的错误,避免影响其他监听器
|
|
236
241
|
console.error(`Error in event handler for "${String(event)}":`, error);
|
|
237
|
-
} finally {
|
|
238
|
-
resolve();
|
|
239
242
|
}
|
|
240
|
-
})
|
|
243
|
+
})()
|
|
241
244
|
);
|
|
242
245
|
});
|
|
243
246
|
|